feat(parser)!: add new Midas AST nodes
This commit is contained in:
58
gen/midas.py
58
gen/midas.py
@@ -13,40 +13,38 @@ from midas.lexer.token import Token
|
|||||||
|
|
||||||
|
|
||||||
###> Stmt | Statements
|
###> Stmt | Statements
|
||||||
class SimpleTypeStmt:
|
class TypeStmt:
|
||||||
name: Token
|
name: Token
|
||||||
template: Optional[TemplateExpr]
|
params: list[Param]
|
||||||
base: TypeExpr
|
type: Type
|
||||||
constraint: Optional[Expr]
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True, kw_only=True)
|
||||||
class ComplexTypeStmt:
|
class Param:
|
||||||
name: Token
|
location: Location
|
||||||
template: Optional[TemplateExpr]
|
name: Token
|
||||||
properties: list[PropertyStmt]
|
bound: Optional[Type]
|
||||||
|
|
||||||
|
|
||||||
class PropertyStmt:
|
class PropertyStmt:
|
||||||
name: Token
|
name: Token
|
||||||
type: TypeExpr
|
type: Type
|
||||||
constraint: Optional[Expr]
|
|
||||||
|
|
||||||
|
|
||||||
class ExtendStmt:
|
class ExtendStmt:
|
||||||
type: TypeExpr
|
type: Type
|
||||||
operations: list[OpStmt]
|
operations: list[OpStmt]
|
||||||
|
|
||||||
|
|
||||||
class OpStmt:
|
class OpStmt:
|
||||||
name: Token
|
name: Token
|
||||||
operand: TypeExpr
|
operand: Type
|
||||||
result: TypeExpr
|
result: Type
|
||||||
|
|
||||||
|
|
||||||
class PredicateStmt:
|
class PredicateStmt:
|
||||||
name: Token
|
name: Token
|
||||||
subject: Token
|
subject: Token
|
||||||
type: TypeExpr
|
type: Type
|
||||||
condition: Expr
|
condition: Expr
|
||||||
|
|
||||||
|
|
||||||
@@ -54,9 +52,6 @@ class PredicateStmt:
|
|||||||
|
|
||||||
|
|
||||||
###> Expr | Expressions
|
###> Expr | Expressions
|
||||||
class SimpleTypeExpr:
|
|
||||||
name: Token
|
|
||||||
optional: bool
|
|
||||||
|
|
||||||
|
|
||||||
class LogicalExpr:
|
class LogicalExpr:
|
||||||
@@ -97,14 +92,31 @@ class WildcardExpr:
|
|||||||
token: Token
|
token: Token
|
||||||
|
|
||||||
|
|
||||||
class TemplateExpr:
|
###<
|
||||||
type: TypeExpr
|
|
||||||
|
###> Type | Types
|
||||||
|
|
||||||
|
|
||||||
class TypeExpr:
|
class NamedType:
|
||||||
name: Token
|
name: Token
|
||||||
template: Optional[TemplateExpr]
|
|
||||||
optional: bool
|
|
||||||
|
class GenericType:
|
||||||
|
type: Type
|
||||||
|
params: list[Type]
|
||||||
|
|
||||||
|
|
||||||
|
class ConstraintType:
|
||||||
|
type: Type
|
||||||
|
constraint: Expr
|
||||||
|
|
||||||
|
|
||||||
|
class UnionType:
|
||||||
|
types: list[Type]
|
||||||
|
|
||||||
|
|
||||||
|
class ComplexType:
|
||||||
|
properties: list[PropertyStmt]
|
||||||
|
|
||||||
|
|
||||||
###<
|
###<
|
||||||
|
|||||||
@@ -28,10 +28,7 @@ class Stmt(ABC):
|
|||||||
|
|
||||||
class Visitor(ABC, Generic[T]):
|
class Visitor(ABC, Generic[T]):
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def visit_simple_type_stmt(self, stmt: SimpleTypeStmt) -> T: ...
|
def visit_type_stmt(self, stmt: TypeStmt) -> T: ...
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def visit_complex_type_stmt(self, stmt: ComplexTypeStmt) -> T: ...
|
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def visit_property_stmt(self, stmt: PropertyStmt) -> T: ...
|
def visit_property_stmt(self, stmt: PropertyStmt) -> T: ...
|
||||||
@@ -47,31 +44,25 @@ class Stmt(ABC):
|
|||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class SimpleTypeStmt(Stmt):
|
class TypeStmt(Stmt):
|
||||||
name: Token
|
name: Token
|
||||||
template: Optional[TemplateExpr]
|
params: list[Param]
|
||||||
base: TypeExpr
|
type: Type
|
||||||
constraint: Optional[Expr]
|
|
||||||
|
@dataclass(frozen=True, kw_only=True)
|
||||||
|
class Param:
|
||||||
|
location: Location
|
||||||
|
name: Token
|
||||||
|
bound: Optional[Type]
|
||||||
|
|
||||||
def accept(self, visitor: Stmt.Visitor[T]) -> T:
|
def accept(self, visitor: Stmt.Visitor[T]) -> T:
|
||||||
return visitor.visit_simple_type_stmt(self)
|
return visitor.visit_type_stmt(self)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class ComplexTypeStmt(Stmt):
|
|
||||||
name: Token
|
|
||||||
template: Optional[TemplateExpr]
|
|
||||||
properties: list[PropertyStmt]
|
|
||||||
|
|
||||||
def accept(self, visitor: Stmt.Visitor[T]) -> T:
|
|
||||||
return visitor.visit_complex_type_stmt(self)
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class PropertyStmt(Stmt):
|
class PropertyStmt(Stmt):
|
||||||
name: Token
|
name: Token
|
||||||
type: TypeExpr
|
type: Type
|
||||||
constraint: Optional[Expr]
|
|
||||||
|
|
||||||
def accept(self, visitor: Stmt.Visitor[T]) -> T:
|
def accept(self, visitor: Stmt.Visitor[T]) -> T:
|
||||||
return visitor.visit_property_stmt(self)
|
return visitor.visit_property_stmt(self)
|
||||||
@@ -79,7 +70,7 @@ class PropertyStmt(Stmt):
|
|||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class ExtendStmt(Stmt):
|
class ExtendStmt(Stmt):
|
||||||
type: TypeExpr
|
type: Type
|
||||||
operations: list[OpStmt]
|
operations: list[OpStmt]
|
||||||
|
|
||||||
def accept(self, visitor: Stmt.Visitor[T]) -> T:
|
def accept(self, visitor: Stmt.Visitor[T]) -> T:
|
||||||
@@ -89,8 +80,8 @@ class ExtendStmt(Stmt):
|
|||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class OpStmt(Stmt):
|
class OpStmt(Stmt):
|
||||||
name: Token
|
name: Token
|
||||||
operand: TypeExpr
|
operand: Type
|
||||||
result: TypeExpr
|
result: Type
|
||||||
|
|
||||||
def accept(self, visitor: Stmt.Visitor[T]) -> T:
|
def accept(self, visitor: Stmt.Visitor[T]) -> T:
|
||||||
return visitor.visit_op_stmt(self)
|
return visitor.visit_op_stmt(self)
|
||||||
@@ -100,7 +91,7 @@ class OpStmt(Stmt):
|
|||||||
class PredicateStmt(Stmt):
|
class PredicateStmt(Stmt):
|
||||||
name: Token
|
name: Token
|
||||||
subject: Token
|
subject: Token
|
||||||
type: TypeExpr
|
type: Type
|
||||||
condition: Expr
|
condition: Expr
|
||||||
|
|
||||||
def accept(self, visitor: Stmt.Visitor[T]) -> T:
|
def accept(self, visitor: Stmt.Visitor[T]) -> T:
|
||||||
@@ -120,9 +111,6 @@ class Expr(ABC):
|
|||||||
def accept(self, visitor: Visitor[T]) -> T: ...
|
def accept(self, visitor: Visitor[T]) -> T: ...
|
||||||
|
|
||||||
class Visitor(ABC, Generic[T]):
|
class Visitor(ABC, Generic[T]):
|
||||||
@abstractmethod
|
|
||||||
def visit_simple_type_expr(self, expr: SimpleTypeExpr) -> T: ...
|
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def visit_logical_expr(self, expr: LogicalExpr) -> T: ...
|
def visit_logical_expr(self, expr: LogicalExpr) -> T: ...
|
||||||
|
|
||||||
@@ -147,21 +135,6 @@ class Expr(ABC):
|
|||||||
@abstractmethod
|
@abstractmethod
|
||||||
def visit_wildcard_expr(self, expr: WildcardExpr) -> T: ...
|
def visit_wildcard_expr(self, expr: WildcardExpr) -> T: ...
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def visit_template_expr(self, expr: TemplateExpr) -> T: ...
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def visit_type_expr(self, expr: TypeExpr) -> T: ...
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class SimpleTypeExpr(Expr):
|
|
||||||
name: Token
|
|
||||||
optional: bool
|
|
||||||
|
|
||||||
def accept(self, visitor: Expr.Visitor[T]) -> T:
|
|
||||||
return visitor.visit_simple_type_expr(self)
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class LogicalExpr(Expr):
|
class LogicalExpr(Expr):
|
||||||
@@ -233,19 +206,72 @@ class WildcardExpr(Expr):
|
|||||||
return visitor.visit_wildcard_expr(self)
|
return visitor.visit_wildcard_expr(self)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
#########
|
||||||
class TemplateExpr(Expr):
|
# Types #
|
||||||
type: TypeExpr
|
#########
|
||||||
|
|
||||||
def accept(self, visitor: Expr.Visitor[T]) -> T:
|
|
||||||
return visitor.visit_template_expr(self)
|
@dataclass(frozen=True, kw_only=True)
|
||||||
|
class Type(ABC):
|
||||||
|
location: Location
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def accept(self, visitor: Visitor[T]) -> T: ...
|
||||||
|
|
||||||
|
class Visitor(ABC, Generic[T]):
|
||||||
|
@abstractmethod
|
||||||
|
def visit_named_type(self, type: NamedType) -> T: ...
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def visit_generic_type(self, type: GenericType) -> T: ...
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def visit_constraint_type(self, type: ConstraintType) -> T: ...
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def visit_union_type(self, type: UnionType) -> T: ...
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def visit_complex_type(self, type: ComplexType) -> T: ...
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class TypeExpr(Expr):
|
class NamedType(Type):
|
||||||
name: Token
|
name: Token
|
||||||
template: Optional[TemplateExpr]
|
|
||||||
optional: bool
|
|
||||||
|
|
||||||
def accept(self, visitor: Expr.Visitor[T]) -> T:
|
def accept(self, visitor: Type.Visitor[T]) -> T:
|
||||||
return visitor.visit_type_expr(self)
|
return visitor.visit_named_type(self)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class GenericType(Type):
|
||||||
|
type: Type
|
||||||
|
params: list[Type]
|
||||||
|
|
||||||
|
def accept(self, visitor: Type.Visitor[T]) -> T:
|
||||||
|
return visitor.visit_generic_type(self)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class ConstraintType(Type):
|
||||||
|
type: Type
|
||||||
|
constraint: Expr
|
||||||
|
|
||||||
|
def accept(self, visitor: Type.Visitor[T]) -> T:
|
||||||
|
return visitor.visit_constraint_type(self)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class UnionType(Type):
|
||||||
|
types: list[Type]
|
||||||
|
|
||||||
|
def accept(self, visitor: Type.Visitor[T]) -> T:
|
||||||
|
return visitor.visit_union_type(self)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class ComplexType(Type):
|
||||||
|
properties: list[PropertyStmt]
|
||||||
|
|
||||||
|
def accept(self, visitor: Type.Visitor[T]) -> T:
|
||||||
|
return visitor.visit_complex_type(self)
|
||||||
|
|||||||
@@ -85,40 +85,39 @@ class AstPrinter(Generic[T]):
|
|||||||
child.accept(self)
|
child.accept(self)
|
||||||
|
|
||||||
|
|
||||||
class MidasAstPrinter(AstPrinter, m.Expr.Visitor[None], m.Stmt.Visitor[None]):
|
class MidasAstPrinter(
|
||||||
|
AstPrinter, m.Expr.Visitor[None], m.Stmt.Visitor[None], m.Type.Visitor[None]
|
||||||
|
):
|
||||||
# Statements
|
# Statements
|
||||||
|
|
||||||
def visit_simple_type_stmt(self, stmt: m.SimpleTypeStmt):
|
def visit_type_stmt(self, stmt: m.TypeStmt) -> None:
|
||||||
self._write_line("SimpleTypeStmt")
|
self._write_line("TypeStmt")
|
||||||
with self._child_level():
|
with self._child_level():
|
||||||
self._write_line(f'name: "{stmt.name.lexeme}"')
|
self._write_line(f'name: "{stmt.name.lexeme}"')
|
||||||
self._write_optional_child("template", stmt.template)
|
self._write_line("params")
|
||||||
self._write_line("base")
|
|
||||||
with self._child_level(single=True):
|
|
||||||
stmt.base.accept(self)
|
|
||||||
self._write_optional_child("constraint", stmt.constraint, last=True)
|
|
||||||
|
|
||||||
def visit_complex_type_stmt(self, stmt: m.ComplexTypeStmt):
|
|
||||||
self._write_line("ComplexTypeStmt")
|
|
||||||
with self._child_level():
|
|
||||||
self._write_line(f'name: "{stmt.name.lexeme}"')
|
|
||||||
self._write_optional_child("template", stmt.template)
|
|
||||||
self._write_line("properties", last=True)
|
|
||||||
with self._child_level():
|
with self._child_level():
|
||||||
for i, prop in enumerate(stmt.properties):
|
for i, param in enumerate(stmt.params):
|
||||||
self._idx = i
|
self._idx = i
|
||||||
if i == len(stmt.properties) - 1:
|
if i == len(stmt.params) - 1:
|
||||||
self._mark_last()
|
self._mark_last()
|
||||||
prop.accept(self)
|
self._print_type_stmt_param(param)
|
||||||
|
self._write_line("type", last=True)
|
||||||
|
with self._child_level(single=True):
|
||||||
|
stmt.type.accept(self)
|
||||||
|
|
||||||
|
def _print_type_stmt_param(self, param: m.TypeStmt.Param) -> None:
|
||||||
|
self._write_line("Param")
|
||||||
|
with self._child_level():
|
||||||
|
self._write_line(f'name: "{param.name.lexeme}"')
|
||||||
|
self._write_optional_child("bound", param.bound, last=True)
|
||||||
|
|
||||||
def visit_property_stmt(self, stmt: m.PropertyStmt):
|
def visit_property_stmt(self, stmt: m.PropertyStmt):
|
||||||
self._write_line("PropertyStmt")
|
self._write_line("PropertyStmt")
|
||||||
with self._child_level():
|
with self._child_level():
|
||||||
self._write_line(f'name: "{stmt.name.lexeme}"')
|
self._write_line(f'name: "{stmt.name.lexeme}"')
|
||||||
self._write_line("type")
|
self._write_line("type", last=True)
|
||||||
with self._child_level(single=True):
|
with self._child_level(single=True):
|
||||||
stmt.type.accept(self)
|
stmt.type.accept(self)
|
||||||
self._write_optional_child("constraint", stmt.constraint, last=True)
|
|
||||||
|
|
||||||
def visit_extend_stmt(self, stmt: m.ExtendStmt) -> None:
|
def visit_extend_stmt(self, stmt: m.ExtendStmt) -> None:
|
||||||
self._write_line("ExtendStmt")
|
self._write_line("ExtendStmt")
|
||||||
@@ -161,12 +160,6 @@ class MidasAstPrinter(AstPrinter, m.Expr.Visitor[None], m.Stmt.Visitor[None]):
|
|||||||
|
|
||||||
# Expressions
|
# Expressions
|
||||||
|
|
||||||
def visit_simple_type_expr(self, expr: m.SimpleTypeExpr):
|
|
||||||
self._write_line("SimpleTypeExpr")
|
|
||||||
with self._child_level():
|
|
||||||
self._write_line(f'name: "{expr.name.lexeme}"')
|
|
||||||
self._write_line(f"optional: {expr.optional}", last=True)
|
|
||||||
|
|
||||||
def visit_logical_expr(self, expr: m.LogicalExpr):
|
def visit_logical_expr(self, expr: m.LogicalExpr):
|
||||||
self._write_line("LogicalExpr")
|
self._write_line("LogicalExpr")
|
||||||
with self._child_level():
|
with self._child_level():
|
||||||
@@ -230,22 +223,59 @@ class MidasAstPrinter(AstPrinter, m.Expr.Visitor[None], m.Stmt.Visitor[None]):
|
|||||||
def visit_wildcard_expr(self, expr: m.WildcardExpr) -> None:
|
def visit_wildcard_expr(self, expr: m.WildcardExpr) -> None:
|
||||||
self._write_line("WildcardExpr")
|
self._write_line("WildcardExpr")
|
||||||
|
|
||||||
def visit_template_expr(self, expr: m.TemplateExpr) -> None:
|
def visit_named_type(self, type: m.NamedType) -> None:
|
||||||
self._write_line("TemplateExpr")
|
self._write_line("NamedType")
|
||||||
with self._child_level(single=True):
|
with self._child_level():
|
||||||
|
self._write_line(f'name: "{type.name.lexeme}"', last=True)
|
||||||
|
|
||||||
|
def visit_generic_type(self, type: m.GenericType) -> None:
|
||||||
|
self._write_line("GenericType")
|
||||||
|
with self._child_level():
|
||||||
|
self._write_line("type")
|
||||||
|
with self._child_level():
|
||||||
|
type.type.accept(self)
|
||||||
|
self._write_line("params", last=True)
|
||||||
|
with self._child_level():
|
||||||
|
for i, param in enumerate(type.params):
|
||||||
|
self._idx = i
|
||||||
|
if i == len(type.params) - 1:
|
||||||
|
self._mark_last()
|
||||||
|
param.accept(self)
|
||||||
|
|
||||||
|
def visit_constraint_type(self, type: m.ConstraintType) -> None:
|
||||||
|
self._write_line("ConstraintType")
|
||||||
|
with self._child_level():
|
||||||
self._write_line("type")
|
self._write_line("type")
|
||||||
with self._child_level(single=True):
|
with self._child_level(single=True):
|
||||||
expr.type.accept(self)
|
type.type.accept(self)
|
||||||
|
self._write_line("constraint", last=True)
|
||||||
|
with self._child_level(single=True):
|
||||||
|
type.constraint.accept(self)
|
||||||
|
|
||||||
def visit_type_expr(self, expr: m.TypeExpr):
|
def visit_union_type(self, type: m.UnionType) -> None:
|
||||||
self._write_line("TypeExpr")
|
self._write_line("UnionType")
|
||||||
with self._child_level():
|
with self._child_level():
|
||||||
self._write_line(f'name: "{expr.name.lexeme}"')
|
self._write_line("types", last=True)
|
||||||
self._write_optional_child("template", expr.template)
|
with self._child_level():
|
||||||
self._write_line(f"optional: {expr.optional}", last=True)
|
for i, type_ in enumerate(type.types):
|
||||||
|
self._idx = i
|
||||||
|
if i == len(type.types) - 1:
|
||||||
|
self._mark_last()
|
||||||
|
type_.accept(self)
|
||||||
|
|
||||||
|
def visit_complex_type(self, type: m.ComplexType) -> None:
|
||||||
|
self._write_line("ComplexType")
|
||||||
|
with self._child_level():
|
||||||
|
self._write_line("properties", last=True)
|
||||||
|
with self._child_level():
|
||||||
|
for i, prop in enumerate(type.properties):
|
||||||
|
self._idx = i
|
||||||
|
if i == len(type.properties) - 1:
|
||||||
|
self._mark_last()
|
||||||
|
prop.accept(self)
|
||||||
|
|
||||||
|
|
||||||
class MidasPrinter(m.Expr.Visitor[str], m.Stmt.Visitor[str]):
|
class MidasPrinter(m.Expr.Visitor[str], m.Stmt.Visitor[str], m.Type.Visitor[str]):
|
||||||
def __init__(self, indent: int = 4):
|
def __init__(self, indent: int = 4):
|
||||||
self.indent: int = indent
|
self.indent: int = indent
|
||||||
self.level: int = 0
|
self.level: int = 0
|
||||||
@@ -257,29 +287,24 @@ class MidasPrinter(m.Expr.Visitor[str], m.Stmt.Visitor[str]):
|
|||||||
self.level = 0
|
self.level = 0
|
||||||
return expr.accept(self)
|
return expr.accept(self)
|
||||||
|
|
||||||
def visit_simple_type_stmt(self, stmt: m.SimpleTypeStmt):
|
def visit_type_stmt(self, stmt: m.TypeStmt) -> str:
|
||||||
template: str = stmt.template.accept(self) if stmt.template is not None else ""
|
template: str = ""
|
||||||
res: str = f"type {stmt.name.lexeme}{template}({stmt.base.accept(self)})"
|
if len(stmt.params) != 0:
|
||||||
if stmt.constraint is not None:
|
params: list[str] = [
|
||||||
res += " where " + stmt.constraint.accept(self)
|
self._print_type_template_param(param) for param in stmt.params
|
||||||
|
]
|
||||||
|
template = f"[{', '.join(params)}]"
|
||||||
|
res: str = f"type {stmt.name.lexeme}{template} = {stmt.type.accept(self)}"
|
||||||
return self.indented(res)
|
return self.indented(res)
|
||||||
|
|
||||||
def visit_complex_type_stmt(self, stmt: m.ComplexTypeStmt):
|
def _print_type_template_param(self, param: m.TypeStmt.Param) -> str:
|
||||||
template: str = stmt.template.accept(self) if stmt.template is not None else ""
|
res: str = param.name.lexeme
|
||||||
res: str = self.indented(f"type {stmt.name.lexeme}{template}")
|
if param.bound is not None:
|
||||||
res += " {\n"
|
res += "<:" + param.bound.accept(self)
|
||||||
self.level += 1
|
|
||||||
for prop in stmt.properties:
|
|
||||||
res += prop.accept(self)
|
|
||||||
res += "\n"
|
|
||||||
self.level -= 1
|
|
||||||
res += self.indented("}")
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def visit_property_stmt(self, stmt: m.PropertyStmt):
|
def visit_property_stmt(self, stmt: m.PropertyStmt):
|
||||||
res: str = f"{stmt.name.lexeme}: {stmt.type.accept(self)}"
|
res: str = f"{stmt.name.lexeme}: {stmt.type.accept(self)}"
|
||||||
if stmt.constraint is not None:
|
|
||||||
res += " where " + stmt.constraint.accept(self)
|
|
||||||
return self.indented(res)
|
return self.indented(res)
|
||||||
|
|
||||||
def visit_extend_stmt(self, stmt: m.ExtendStmt):
|
def visit_extend_stmt(self, stmt: m.ExtendStmt):
|
||||||
@@ -304,9 +329,6 @@ class MidasPrinter(m.Expr.Visitor[str], m.Stmt.Visitor[str]):
|
|||||||
condition: str = stmt.condition.accept(self)
|
condition: str = stmt.condition.accept(self)
|
||||||
return self.indented(f"predicate {name}({subject}: {type}) = {condition}")
|
return self.indented(f"predicate {name}({subject}: {type}) = {condition}")
|
||||||
|
|
||||||
def visit_simple_type_expr(self, expr: m.SimpleTypeExpr):
|
|
||||||
return f"{expr.name.lexeme}{'?' if expr.optional else ''}"
|
|
||||||
|
|
||||||
def visit_logical_expr(self, expr: m.LogicalExpr):
|
def visit_logical_expr(self, expr: m.LogicalExpr):
|
||||||
left: str = expr.left.accept(self)
|
left: str = expr.left.accept(self)
|
||||||
operator: str = expr.operator.lexeme
|
operator: str = expr.operator.lexeme
|
||||||
@@ -342,12 +364,34 @@ class MidasPrinter(m.Expr.Visitor[str], m.Stmt.Visitor[str]):
|
|||||||
def visit_wildcard_expr(self, expr: m.WildcardExpr):
|
def visit_wildcard_expr(self, expr: m.WildcardExpr):
|
||||||
return "_"
|
return "_"
|
||||||
|
|
||||||
def visit_template_expr(self, expr: m.TemplateExpr):
|
def visit_named_type(self, type: m.NamedType) -> str:
|
||||||
return f"[{expr.type.accept(self)}]"
|
return type.name.lexeme
|
||||||
|
|
||||||
def visit_type_expr(self, expr: m.TypeExpr):
|
def visit_generic_type(self, type: m.GenericType) -> str:
|
||||||
template: str = expr.template.accept(self) if expr.template is not None else ""
|
res: str = type.type.accept(self)
|
||||||
return f"{expr.name.lexeme}{template}{'?' if expr.optional else ''}"
|
if len(type.params) != 0:
|
||||||
|
params: list[str] = [param.accept(self) for param in type.params]
|
||||||
|
res += f"[{', '.join(params)}]"
|
||||||
|
return res
|
||||||
|
|
||||||
|
def visit_constraint_type(self, type: m.ConstraintType) -> str:
|
||||||
|
res: str = type.type.accept(self)
|
||||||
|
res += " where " + type.constraint.accept(self)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def visit_union_type(self, type: m.UnionType) -> str:
|
||||||
|
types: list[str] = [type_.accept(self) for type_ in type.types]
|
||||||
|
return " | ".join(types)
|
||||||
|
|
||||||
|
def visit_complex_type(self, type: m.ComplexType) -> str:
|
||||||
|
res: str = "{\n"
|
||||||
|
self.level += 1
|
||||||
|
for prop in type.properties:
|
||||||
|
res += prop.accept(self)
|
||||||
|
res += "\n"
|
||||||
|
self.level -= 1
|
||||||
|
res += self.indented("}")
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
class PythonAstPrinter(
|
class PythonAstPrinter(
|
||||||
|
|||||||
Reference in New Issue
Block a user