language: Add closure expressions

This commit is contained in:
James Westman 2022-12-24 21:46:03 -06:00
parent 5cf9b63547
commit 59aa054c4c
No known key found for this signature in database
GPG key ID: CE2DBA0ADB654EA6
10 changed files with 96 additions and 7 deletions

View file

@ -1,5 +1,5 @@
from .attributes import BaseAttribute, BaseTypedAttribute
from .expression import CastExpr, IdentExpr, LookupOp, ExprChain
from .expression import CastExpr, ClosureExpr, Expr, ExprChain, IdentExpr, LookupOp
from .gobject_object import Object, ObjectContent
from .gobject_property import Property
from .gobject_signal import Signal

View file

@ -25,13 +25,24 @@ from .types import TypeName
expr = Pratt()
class Expr:
class Expr(AstNode):
@property
def type(self) -> T.Optional[GirType]:
raise NotImplementedError()
@property
def rhs(self) -> T.Optional["Expr"]:
if isinstance(self.parent, ExprChain):
children = list(self.parent.children)
if children.index(self) + 1 < len(children):
return children[children.index(self) + 1]
else:
return self.parent.rhs
else:
return None
class ExprChain(Expr, AstNode):
class ExprChain(Expr):
grammar = expr
@property
@ -43,14 +54,14 @@ class ExprChain(Expr, AstNode):
return self.last.type
class InfixExpr(Expr, AstNode):
class InfixExpr(Expr):
@property
def lhs(self):
children = list(self.parent_by_type(ExprChain).children)
return children[children.index(self) - 1]
class IdentExpr(Expr, AstNode):
class IdentExpr(Expr):
grammar = UseIdent("ident")
@property
@ -124,7 +135,45 @@ class CastExpr(InfixExpr):
)
class ClosureExpr(Expr):
grammar = [
Optional(["$", UseLiteral("extern", True)]),
UseIdent("name"),
"(",
Delimited(ExprChain, ","),
")",
]
@property
def type(self) -> T.Optional[GirType]:
if isinstance(self.rhs, CastExpr):
return self.rhs.type
else:
return None
@property
def closure_name(self) -> str:
return self.tokens["name"]
@property
def args(self) -> T.List[ExprChain]:
return self.children[ExprChain]
@validate()
def cast_to_return_type(self):
if not isinstance(self.rhs, CastExpr):
raise CompileError(
"Closure expression must be cast to the closure's return type"
)
@validate()
def builtin_exists(self):
if not self.tokens["extern"]:
raise CompileError(f"{self.closure_name} is not a builtin function")
expr.children = [
Prefix(ClosureExpr),
Prefix(IdentExpr),
Prefix(["(", ExprChain, ")"]),
Infix(10, LookupOp),