expressions: Add closure expressions

This commit is contained in:
James Westman 2022-04-30 13:27:54 -05:00
parent 762a29b705
commit cc1d2ab78f
No known key found for this signature in database
GPG key ID: CE2DBA0ADB654EA6
6 changed files with 69 additions and 0 deletions

View file

@ -64,6 +64,30 @@ class IdentExpr(AstNode):
self.parent_by_type(Scope).variables[self.tokens["ident"]].emit_xml(xml) self.parent_by_type(Scope).variables[self.tokens["ident"]].emit_xml(xml)
class ClosureExpr(AstNode):
grammar = [
UseIdent("function"),
"(",
Delimited(Expr, ",").expected("closure arguments"),
Match(")").expected(),
]
@validate()
def is_cast_to_return_val(self):
if not isinstance(self.parent.parent, CastExpr):
raise CompileError(f"Closure expression needs to be cast to {self.tokens['function']}'s return type")
@property
def gir_type(self):
return self.parent.parent.gir_type
def emit_xml(self, xml: XmlEmitter):
xml.start_tag("closure", function=self.tokens["function"], type=self.gir_type)
for child in self.children[Expr]:
child.emit_xml(xml)
xml.end_tag()
class LookupOp(InfixExpr): class LookupOp(InfixExpr):
grammar = [".", UseIdent("property")] grammar = [".", UseIdent("property")]
@ -92,6 +116,7 @@ class CastExpr(AstNode):
expr.children = [ expr.children = [
Prefix(ClosureExpr),
Prefix(IdentExpr), Prefix(IdentExpr),
Prefix(CastExpr), Prefix(CastExpr),
Prefix(["(", Expr, ")"]), Prefix(["(", Expr, ")"]),

View file

@ -0,0 +1,5 @@
using Gtk 4.0;
Label {
label: bind my_func();
}

View file

@ -0,0 +1 @@
4,15,9,Closure expression needs to be cast to my_func's return type

View file

@ -0,0 +1,11 @@
using Gtk 4.0;
Box {
Box box {
}
}
Stack {
visible-child: bind ((Gtk.Button)my_closure(box.parent)).parent;
visible: bind (bool) my_other_closure(box);
}

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<object class="GtkBox">
<child>
<object class="GtkBox" id="box"></object>
</child>
</object>
<object class="GtkStack">
<binding name="visible-child">
<lookup name="parent" type="GtkButton">
<closure function="my_closure" type="GtkButton">
<lookup name="parent">
<constant>box</constant>
</lookup>
</closure>
</lookup>
</binding>
<binding name="visible">
<closure function="my_other_closure" type="gboolean">
<constant>box</constant>
</closure>
</binding>
</object>
</interface>

View file

@ -136,6 +136,7 @@ class TestSamples(unittest.TestCase):
self.assert_sample("combo_box_text") self.assert_sample("combo_box_text")
self.assert_sample("comments") self.assert_sample("comments")
self.assert_sample("enum") self.assert_sample("enum")
self.assert_sample("expr_closure")
self.assert_sample("expr_lookup") self.assert_sample("expr_lookup")
self.assert_sample("file_filter") self.assert_sample("file_filter")
self.assert_sample("flags") self.assert_sample("flags")
@ -179,6 +180,7 @@ class TestSamples(unittest.TestCase):
self.assert_sample_error("children") self.assert_sample_error("children")
self.assert_sample_error("class_assign") self.assert_sample_error("class_assign")
self.assert_sample_error("class_dne") self.assert_sample_error("class_dne")
self.assert_sample_error("closure_not_cast")
self.assert_sample_error("consecutive_unexpected_tokens") self.assert_sample_error("consecutive_unexpected_tokens")
self.assert_sample_error("does_not_implement") self.assert_sample_error("does_not_implement")
self.assert_sample_error("duplicate_obj_id") self.assert_sample_error("duplicate_obj_id")