feat(parser): parse type body
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user