From 61b36ee50fede921d5a399b85381c517838ec1be Mon Sep 17 00:00:00 2001 From: LordBaryhobal Date: Thu, 14 May 2026 02:44:21 +0200 Subject: [PATCH] feat(parser): parse constraint statements --- core/ast/midas.py | 12 ++++++++++++ core/ast/printer.py | 9 +++++++++ parser/midas.py | 11 +++++++++-- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/core/ast/midas.py b/core/ast/midas.py index 6f64b57..6d1b035 100644 --- a/core/ast/midas.py +++ b/core/ast/midas.py @@ -27,6 +27,9 @@ class Stmt(ABC): @abstractmethod def visit_op_stmt(self, stmt: OpStmt) -> T: ... + @abstractmethod + def visit_constraint_stmt(self, stmt: ConstraintStmt) -> T: ... + @dataclass(frozen=True) class TypeStmt(Stmt): @@ -58,6 +61,15 @@ class OpStmt(Stmt): return visitor.visit_op_stmt(self) +@dataclass(frozen=True) +class ConstraintStmt(Stmt): + name: Token + constraint: ConstraintExpr + + def accept(self, visitor: Stmt.Visitor[T]) -> T: + return visitor.visit_constraint_stmt(self) + + # Expressions diff --git a/core/ast/printer.py b/core/ast/printer.py index c745221..859de7b 100644 --- a/core/ast/printer.py +++ b/core/ast/printer.py @@ -179,6 +179,15 @@ class MidasAstPrinter(AstPrinter, m.Expr.Visitor[None], m.Stmt.Visitor[None]): self._mark_last() stmt.result.accept(self) + def visit_constraint_stmt(self, stmt: m.ConstraintStmt): + self._write_line("ConstraintStmt") + with self._child_level(): + self._write_line(f'name: "{stmt.name.lexeme}"') + self._write_line("constraint", last=True) + with self._child_level(): + self._mark_last() + stmt.constraint.accept(self) + def visit_type_expr(self, expr: m.TypeExpr): self._write_line("TypeExpr") with self._child_level(): diff --git a/parser/midas.py b/parser/midas.py index bcf1477..c056038 100644 --- a/parser/midas.py +++ b/parser/midas.py @@ -2,6 +2,7 @@ from typing import Optional from core.ast.midas import ( ConstraintExpr, + ConstraintStmt, OpStmt, PropertyStmt, Stmt, @@ -42,8 +43,8 @@ class MidasParser(Parser): return self.type_declaration() if self.match(TokenType.OP): return self.op_declaration() - # if self.match(TokenType.CONSTRAINT): - # return self.constraint_declaration() + if self.match(TokenType.CONSTRAINT): + return self.constraint_declaration() except ParsingError: self.synchronize() return None @@ -109,3 +110,9 @@ class MidasParser(Parser): self.consume(TokenType.GREATER, "Expected '>' after result type") return OpStmt(left=left, op=op, right=right, result=result) + + def constraint_declaration(self) -> ConstraintStmt: + name: Token = self.consume(TokenType.IDENTIFIER, "Expected constraint name") + self.consume(TokenType.EQUAL, "Expected '=' after constraint name") + constraint: ConstraintExpr = self.constraint_expr() + return ConstraintStmt(name=name, constraint=constraint)