mirror of
https://gitlab.gnome.org/jwestman/blueprint-compiler.git
synced 2025-05-04 15:59:08 -04:00
expressions: Add casts
These are sometimes necessary. In the future the compiler should be able to detect when they will be necessary so we don't have to find out at runtime.
This commit is contained in:
parent
fc497ac9e6
commit
207255897b
3 changed files with 30 additions and 3 deletions
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
|
|
||||||
from .common import *
|
from .common import *
|
||||||
|
from .types import ClassName, TypeName
|
||||||
|
|
||||||
|
|
||||||
expr = Pratt()
|
expr = Pratt()
|
||||||
|
@ -27,6 +28,10 @@ expr = Pratt()
|
||||||
class Expr(AstNode):
|
class Expr(AstNode):
|
||||||
grammar = expr
|
grammar = expr
|
||||||
|
|
||||||
|
@property
|
||||||
|
def gir_type(self):
|
||||||
|
return self.children[-1].gir_type
|
||||||
|
|
||||||
def emit_xml(self, xml: XmlEmitter):
|
def emit_xml(self, xml: XmlEmitter):
|
||||||
self.children[-1].emit_xml(xml)
|
self.children[-1].emit_xml(xml)
|
||||||
|
|
||||||
|
@ -45,6 +50,13 @@ class IdentExpr(AstNode):
|
||||||
def is_this(self):
|
def is_this(self):
|
||||||
return self.parent_by_type(Scope).this_name == self.tokens["ident"]
|
return self.parent_by_type(Scope).this_name == self.tokens["ident"]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def gir_type(self):
|
||||||
|
if self.is_this:
|
||||||
|
return self.parent_by_type(Scope).this_type
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
def emit_xml(self, xml: XmlEmitter):
|
def emit_xml(self, xml: XmlEmitter):
|
||||||
if self.is_this:
|
if self.is_this:
|
||||||
raise CompilerBugError()
|
raise CompilerBugError()
|
||||||
|
@ -57,18 +69,33 @@ class IdentExpr(AstNode):
|
||||||
class LookupOp(InfixExpr):
|
class LookupOp(InfixExpr):
|
||||||
grammar = [".", UseIdent("property")]
|
grammar = [".", UseIdent("property")]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def gir_type(self):
|
||||||
|
return None
|
||||||
|
|
||||||
def emit_xml(self, xml: XmlEmitter):
|
def emit_xml(self, xml: XmlEmitter):
|
||||||
if isinstance(self.lhs, IdentExpr) and self.lhs.is_this:
|
if isinstance(self.lhs, IdentExpr) and self.lhs.is_this:
|
||||||
xml.put_self_closing("lookup", name=self.tokens["property"], type=self.parent_by_type(Scope).this_type)
|
xml.put_self_closing("lookup", name=self.tokens["property"], type=self.parent_by_type(Scope).this_type)
|
||||||
else:
|
else:
|
||||||
xml.start_tag("lookup", name=self.tokens["property"])
|
xml.start_tag("lookup", name=self.tokens["property"], type=self.lhs.gir_type)
|
||||||
self.lhs.emit_xml(xml)
|
self.lhs.emit_xml(xml)
|
||||||
xml.end_tag()
|
xml.end_tag()
|
||||||
|
|
||||||
|
|
||||||
|
class CastExpr(AstNode):
|
||||||
|
grammar = ["(", TypeName, ")", Expr]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def gir_type(self):
|
||||||
|
return self.children[TypeName][0].gir_type
|
||||||
|
|
||||||
|
def emit_xml(self, xml: XmlEmitter):
|
||||||
|
self.children[Expr][0].emit_xml(xml)
|
||||||
|
|
||||||
|
|
||||||
expr.children = [
|
expr.children = [
|
||||||
Prefix(IdentExpr),
|
Prefix(IdentExpr),
|
||||||
|
Prefix(CastExpr),
|
||||||
Prefix(["(", Expr, ")"]),
|
Prefix(["(", Expr, ")"]),
|
||||||
Infix(10, LookupOp),
|
Infix(10, LookupOp),
|
||||||
]
|
]
|
||||||
|
|
|
@ -5,5 +5,5 @@ Overlay {
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
label: bind (label.parent).child.label;
|
label: bind ((Label) label.parent.child).label;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<binding name="label">
|
<binding name="label">
|
||||||
<lookup name="label">
|
<lookup name="label" type="GtkLabel">
|
||||||
<lookup name="child">
|
<lookup name="child">
|
||||||
<lookup name="parent">
|
<lookup name="parent">
|
||||||
<constant>label</constant>
|
<constant>label</constant>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue