feat(parser): add more nodes for constraint parsing

This commit is contained in:
2026-05-21 13:54:58 +02:00
parent c1c50a448e
commit 8f9ec8d73b
3 changed files with 71 additions and 7 deletions

View File

@@ -47,7 +47,7 @@ class Stmt(ABC):
class SimpleTypeStmt(Stmt):
name: Token
template: Optional[TemplateExpr]
base: SimpleTypeExpr
base: TypeExpr
constraint: Optional[Expr]
def accept(self, visitor: Stmt.Visitor[T]) -> T:
@@ -68,6 +68,7 @@ class ComplexTypeStmt(Stmt):
class PropertyStmt(Stmt):
name: Token
type: TypeExpr
constraint: Optional[Expr]
def accept(self, visitor: Stmt.Visitor[T]) -> T:
return visitor.visit_property_stmt(self)
@@ -117,12 +118,24 @@ class Expr(ABC):
@abstractmethod
def visit_simple_type_expr(self, expr: SimpleTypeExpr) -> T: ...
@abstractmethod
def visit_logical_expr(self, expr: LogicalExpr) -> T: ...
@abstractmethod
def visit_binary_expr(self, expr: BinaryExpr) -> T: ...
@abstractmethod
def visit_unary_expr(self, expr: UnaryExpr) -> T: ...
@abstractmethod
def visit_get_expr(self, expr: GetExpr) -> T: ...
@abstractmethod
def visit_variable_expr(self, expr: VariableExpr) -> T: ...
@abstractmethod
def visit_grouping_expr(self, expr: GroupingExpr) -> T: ...
@abstractmethod
def visit_literal_expr(self, expr: LiteralExpr) -> T: ...
@@ -145,6 +158,16 @@ class SimpleTypeExpr(Expr):
return visitor.visit_simple_type_expr(self)
@dataclass(frozen=True)
class LogicalExpr(Expr):
left: Expr
operator: Token
right: Expr
def accept(self, visitor: Expr.Visitor[T]) -> T:
return visitor.visit_logical_expr(self)
@dataclass(frozen=True)
class BinaryExpr(Expr):
left: Expr
@@ -164,6 +187,31 @@ class UnaryExpr(Expr):
return visitor.visit_unary_expr(self)
@dataclass(frozen=True)
class GetExpr(Expr):
expr: Expr
name: Token
def accept(self, visitor: Expr.Visitor[T]) -> T:
return visitor.visit_get_expr(self)
@dataclass(frozen=True)
class VariableExpr(Expr):
name: Token
def accept(self, visitor: Expr.Visitor[T]) -> T:
return visitor.visit_variable_expr(self)
@dataclass(frozen=True)
class GroupingExpr(Expr):
expr: Expr
def accept(self, visitor: Expr.Visitor[T]) -> T:
return visitor.visit_grouping_expr(self)
@dataclass(frozen=True)
class LiteralExpr(Expr):
value: Any
@@ -174,7 +222,7 @@ class LiteralExpr(Expr):
@dataclass(frozen=True)
class WildcardExpr(Expr):
pass
token: Token
def accept(self, visitor: Expr.Visitor[T]) -> T:
return visitor.visit_wildcard_expr(self)

View File

@@ -1,13 +1,18 @@
class SimpleTypeStmt:
name: Token
template: Optional[TemplateExpr]
base: SimpleTypeExpr
base: TypeExpr
constraint: Optional[Expr]
class SimpleTypeExpr:
name: Token
optional: bool
class LogicalExpr:
left: Expr
operator: Token
right: Expr
class BinaryExpr:
left: Expr
operator: Token
@@ -17,11 +22,21 @@ class UnaryExpr:
operator: Token
right: Expr
class GetExpr:
expr: Expr
name: Token
class VariableExpr:
name: Token
class GroupingExpr:
expr: Expr
class LiteralExpr:
value: Any
class WildcardExpr:
pass
token: Token
class TemplateExpr:
type: TypeExpr
@@ -39,6 +54,7 @@ class ComplexTypeStmt:
class PropertyStmt:
name: Token
type: TypeExpr
constraint: Optional[Expr]
class ExtendStmt:
type: TypeExpr

View File

@@ -77,7 +77,7 @@ def make_visitor_method(cls: str, param: str):
)
return method.strip("\n")
def make_class(name: str, cls: str, base: str, param: str):
def make_class(name: str, cls: str, base: str):
body: str = cls.split("\n", 1)[1]
func_name: str = snake_case(name)
cls_def: str = CLASS_TEMPLATE.format(
@@ -101,10 +101,10 @@ def generate(src: str):
print(f"Processing {name}")
if name.endswith("Stmt"):
stmt_visitor_methods.append(make_visitor_method(name, "stmt"))
statements.append(make_class(name, cls, "Stmt", "stmt"))
statements.append(make_class(name, cls, "Stmt"))
elif name.endswith("Expr"):
expr_visitor_methods.append(make_visitor_method(name, "expr"))
expressions.append(make_class(name, cls, "Expr", "expr"))
expressions.append(make_class(name, cls, "Expr"))
return TEMPLATE.format(
header=HEADER,