feat(parser): parse type body

This commit is contained in:
2026-05-14 02:29:08 +02:00
parent 6482e06bca
commit 3b40abaa2b
2 changed files with 32 additions and 5 deletions

View File

@@ -50,7 +50,9 @@ class AstPrinter(Generic[T]):
if self._levels:
self._levels[-1] = _Level.LAST
def _write_line(self, text: str):
def _write_line(self, text: str, *, last: bool = False):
if last:
self._mark_last()
indent: str = self._build_indent()
if self._idx is not None:
text = f"[{self._idx}] {text}"
@@ -152,15 +154,16 @@ class MidasAstPrinter(AstPrinter, m.Expr.Visitor[None], m.Stmt.Visitor[None]):
self._write_line("PropertyStmt")
with self._child_level():
self._write_line(f'name: "{stmt.name.lexeme}"')
self._write_line("type")
self._write_line("type", last=True)
with self._child_level():
self._mark_last()
stmt.type.accept(self)
def visit_type_expr(self, expr: m.TypeExpr):
self._write_line("TypeExpr")
with self._child_level():
self._write_line(f'name: "{expr.name.lexeme}"')
self._write_line("constraints")
self._write_line("constraints", last=True)
with self._child_level():
for i, constraint in enumerate(expr.constraints):
self._idx = i
@@ -174,7 +177,7 @@ class MidasAstPrinter(AstPrinter, m.Expr.Visitor[None], m.Stmt.Visitor[None]):
def visit_type_body_expr(self, expr: m.TypeBodyExpr):
self._write_line("TypeBodyExpr")
with self._child_level():
self._write_line("properties")
self._write_line("properties", last=True)
with self._child_level():
for i, property in enumerate(expr.properties):
self._idx = i

View File

@@ -1,6 +1,13 @@
from typing import Optional
from core.ast.midas import ConstraintExpr, Stmt, TypeBodyExpr, TypeExpr, TypeStmt
from core.ast.midas import (
ConstraintExpr,
PropertyStmt,
Stmt,
TypeBodyExpr,
TypeExpr,
TypeStmt,
)
from lexer.token import Token, TokenType
from parser.base import Parser
from parser.errors import ParsingError
@@ -51,6 +58,9 @@ class MidasParser(Parser):
self.consume(TokenType.GREATER, "Expected '>' after base type")
body: Optional[TypeBodyExpr] = None
if self.check(TokenType.LEFT_BRACE):
body = self.type_body_expr()
return TypeStmt(name=name, bases=bases, body=body)
def type_expr(self) -> TypeExpr:
@@ -65,3 +75,17 @@ class MidasParser(Parser):
def constraint_expr(self) -> ConstraintExpr:
# TODO
return ConstraintExpr()
def type_body_expr(self) -> TypeBodyExpr:
self.consume(TokenType.LEFT_BRACE, "Expected '{' to start type body")
properties: list[PropertyStmt] = []
while not self.check(TokenType.RIGHT_BRACE) and not self.is_at_end():
properties.append(self.property_stmt())
self.consume(TokenType.RIGHT_BRACE, "Unclosed type body")
return TypeBodyExpr(properties=properties)
def property_stmt(self) -> PropertyStmt:
name: Token = self.consume(TokenType.IDENTIFIER, "Expected property name")
self.consume(TokenType.COLON, "Expected ':' after property name")
type: TypeExpr = self.type_expr()
return PropertyStmt(name=name, type=type)