tests(parser): update snapshot with new syntax
This commit is contained in:
@@ -1,14 +1,24 @@
|
||||
from typing import Optional, Sequence
|
||||
|
||||
from core.ast.midas import (
|
||||
ConstraintExpr,
|
||||
ConstraintStmt,
|
||||
BinaryExpr,
|
||||
ComplexTypeStmt,
|
||||
Expr,
|
||||
ExtendStmt,
|
||||
GetExpr,
|
||||
GroupingExpr,
|
||||
LiteralExpr,
|
||||
LogicalExpr,
|
||||
OpStmt,
|
||||
PredicateStmt,
|
||||
PropertyStmt,
|
||||
SimpleTypeExpr,
|
||||
SimpleTypeStmt,
|
||||
Stmt,
|
||||
TypeBodyExpr,
|
||||
TemplateExpr,
|
||||
TypeExpr,
|
||||
TypeStmt,
|
||||
UnaryExpr,
|
||||
VariableExpr,
|
||||
WildcardExpr,
|
||||
)
|
||||
|
||||
@@ -19,42 +29,29 @@ class AstJsonSerializer(Stmt.Visitor[dict], Expr.Visitor[dict]):
|
||||
def serialize(self, stmts: list[Stmt]) -> list[dict]:
|
||||
return [stmt.accept(self) for stmt in stmts]
|
||||
|
||||
def visit_type_stmt(self, stmt: TypeStmt) -> dict:
|
||||
def _serialize_optional(self, element: Optional[Stmt | Expr]) -> Optional[dict]:
|
||||
if element is None:
|
||||
return None
|
||||
return element.accept(self)
|
||||
|
||||
def _serialize_list(self, elements: Sequence[Stmt | Expr]) -> list[dict]:
|
||||
return [element.accept(self) for element in elements]
|
||||
|
||||
def visit_simple_type_stmt(self, stmt: SimpleTypeStmt) -> dict:
|
||||
return {
|
||||
"_type": "TypeStmt",
|
||||
"_type": "SimpleTypeStmt",
|
||||
"template": self._serialize_optional(stmt.template),
|
||||
"name": stmt.name.lexeme,
|
||||
"bases": [base.accept(self) for base in stmt.bases],
|
||||
"body": stmt.body.accept(self) if stmt.body is not None else None,
|
||||
"base": stmt.base.accept(self),
|
||||
"constraint": self._serialize_optional(stmt.constraint),
|
||||
}
|
||||
|
||||
def visit_type_expr(self, expr: TypeExpr) -> dict:
|
||||
def visit_complex_type_stmt(self, stmt: ComplexTypeStmt) -> dict:
|
||||
return {
|
||||
"_type": "TypeExpr",
|
||||
"name": expr.name.lexeme,
|
||||
"constraints": [constraint.accept(self) for constraint in expr.constraints],
|
||||
}
|
||||
|
||||
def visit_constraint_expr(self, expr: ConstraintExpr) -> dict:
|
||||
return {
|
||||
"_type": "ConstraintExpr",
|
||||
"left": expr.left.accept(self),
|
||||
"op": expr.op.lexeme,
|
||||
"right": expr.right.accept(self),
|
||||
}
|
||||
|
||||
def visit_wildcard_expr(self, expr: WildcardExpr) -> dict:
|
||||
return {"_type": "WildcardExpr"}
|
||||
|
||||
def visit_literal_expr(self, expr: LiteralExpr) -> dict:
|
||||
return {
|
||||
"_type": "LiteralExpr",
|
||||
"value": expr.value,
|
||||
}
|
||||
|
||||
def visit_type_body_expr(self, expr: TypeBodyExpr) -> dict:
|
||||
return {
|
||||
"_type": "TypeBodyExpr",
|
||||
"properties": [prop.accept(self) for prop in expr.properties],
|
||||
"_type": "ComplexTypeStmt",
|
||||
"name": stmt.name.lexeme,
|
||||
"template": self._serialize_optional(stmt.template),
|
||||
"properties": self._serialize_list(stmt.properties),
|
||||
}
|
||||
|
||||
def visit_property_stmt(self, stmt: PropertyStmt) -> dict:
|
||||
@@ -62,20 +59,101 @@ class AstJsonSerializer(Stmt.Visitor[dict], Expr.Visitor[dict]):
|
||||
"_type": "PropertyStmt",
|
||||
"name": stmt.name.lexeme,
|
||||
"type": stmt.type.accept(self),
|
||||
"constraint": self._serialize_optional(stmt.constraint),
|
||||
}
|
||||
|
||||
def visit_extend_stmt(self, stmt: ExtendStmt) -> dict:
|
||||
return {
|
||||
"_type": "ExtendStmt",
|
||||
"type": stmt.type.accept(self),
|
||||
"operations": self._serialize_list(stmt.operations),
|
||||
}
|
||||
|
||||
def visit_op_stmt(self, stmt: OpStmt) -> dict:
|
||||
return {
|
||||
"_type": "OpStmt",
|
||||
"left": stmt.left.accept(self),
|
||||
"op": stmt.op.lexeme,
|
||||
"right": stmt.right.accept(self),
|
||||
"name": stmt.name.lexeme,
|
||||
"operand": stmt.operand.accept(self),
|
||||
"result": stmt.result.accept(self),
|
||||
}
|
||||
|
||||
def visit_constraint_stmt(self, stmt: ConstraintStmt) -> dict:
|
||||
def visit_predicate_stmt(self, stmt: PredicateStmt) -> dict:
|
||||
return {
|
||||
"_type": "ConstraintStmt",
|
||||
"_type": "PredicateStmt",
|
||||
"name": stmt.name.lexeme,
|
||||
"constraint": stmt.constraint.accept(self),
|
||||
"subject": stmt.subject.lexeme,
|
||||
"type": stmt.type.accept(self),
|
||||
"condition": stmt.condition.accept(self),
|
||||
}
|
||||
|
||||
def visit_simple_type_expr(self, expr: SimpleTypeExpr) -> dict:
|
||||
return {
|
||||
"_type": "SimpleTypeExpr",
|
||||
"name": expr.name.lexeme,
|
||||
"optional": expr.optional,
|
||||
}
|
||||
|
||||
def visit_logical_expr(self, expr: LogicalExpr) -> dict:
|
||||
return {
|
||||
"_type": "LogicalExpr",
|
||||
"left": expr.left.accept(self),
|
||||
"operator": expr.operator.lexeme,
|
||||
"right": expr.right.accept(self),
|
||||
}
|
||||
|
||||
def visit_binary_expr(self, expr: BinaryExpr) -> dict:
|
||||
return {
|
||||
"_type": "BinaryExpr",
|
||||
"left": expr.left.accept(self),
|
||||
"operator": expr.operator.lexeme,
|
||||
"right": expr.right.accept(self),
|
||||
}
|
||||
|
||||
def visit_unary_expr(self, expr: UnaryExpr) -> dict:
|
||||
return {
|
||||
"_type": "UnaryExpr",
|
||||
"operator": expr.operator.lexeme,
|
||||
"right": expr.right.accept(self),
|
||||
}
|
||||
|
||||
def visit_get_expr(self, expr: GetExpr) -> dict:
|
||||
return {
|
||||
"_type": "GetExpr",
|
||||
"expr": expr.expr.accept(self),
|
||||
"name": expr.name.lexeme,
|
||||
}
|
||||
|
||||
def visit_variable_expr(self, expr: VariableExpr) -> dict:
|
||||
return {
|
||||
"_type": "VariableExpr",
|
||||
"name": expr.name.lexeme,
|
||||
}
|
||||
|
||||
def visit_grouping_expr(self, expr: GroupingExpr) -> dict:
|
||||
return {
|
||||
"_type": "GroupingExpr",
|
||||
"expr": expr.expr.accept(self),
|
||||
}
|
||||
|
||||
def visit_literal_expr(self, expr: LiteralExpr) -> dict:
|
||||
return {
|
||||
"_type": "LiteralExpr",
|
||||
"value": expr.value,
|
||||
}
|
||||
|
||||
def visit_wildcard_expr(self, expr: WildcardExpr) -> dict:
|
||||
return {"_type": "WildcardExpr"}
|
||||
|
||||
def visit_template_expr(self, expr: TemplateExpr) -> dict:
|
||||
return {
|
||||
"_type": "TemplateExpr",
|
||||
"type": expr.type.accept(self),
|
||||
}
|
||||
|
||||
def visit_type_expr(self, expr: TypeExpr) -> dict:
|
||||
return {
|
||||
"_type": "TypeExpr",
|
||||
"name": expr.name.lexeme,
|
||||
"template": self._serialize_optional(expr.template),
|
||||
"optional": expr.optional,
|
||||
}
|
||||
|
||||
@@ -1,24 +1,57 @@
|
||||
// Simple custom type derived from floats
|
||||
type Latitude<float>
|
||||
type Longitude<float>
|
||||
// Simple custom type derived from float
|
||||
type Custom(float)
|
||||
|
||||
// Simple custom types with constraints
|
||||
type Latitude(float) where (-90 <= _ <= 90)
|
||||
type Longitude(float) where (-180 <= _ <= 180)
|
||||
|
||||
// Generic custom type (a Difference of T is derived from T, e.g. a difference of floats is a float
|
||||
type Difference[T](T)
|
||||
|
||||
// Complex custom type, containing two values accessible through properties
|
||||
type GeoLocation<Latitude, Longitude> {
|
||||
type GeoLocation {
|
||||
lat: Latitude
|
||||
lon: Longitude
|
||||
}
|
||||
|
||||
type LatitudeDiff<float>
|
||||
type LongitudeDiff<float>
|
||||
// Define operations on our custom type
|
||||
extend GeoLocation {
|
||||
// This type is compatible with the `-` operation with another GeoLocation
|
||||
// i.e. you can subtract a GeoLocation from another GeoLocation, resulting
|
||||
// in a Difference of GeoLocations
|
||||
op __sub__(GeoLocation) -> Difference[GeoLocation]
|
||||
}
|
||||
|
||||
// For complex generics, you need to specify how the genericity the properties
|
||||
// are handled
|
||||
type Difference[GeoLocation] {
|
||||
lat: Difference[Latitude]
|
||||
lon: Difference[Longitude]
|
||||
}
|
||||
|
||||
// Simple operation defined on our custom types
|
||||
op <Latitude> - <Latitude> = <LatitudeDiff>
|
||||
op <Longitude> - <Longitude> = <LongitudeDiff>
|
||||
extend Latitude {
|
||||
op __sub__(Latitude) -> Difference[Latitude]
|
||||
}
|
||||
|
||||
// Simple custom type with a constraint
|
||||
type Age<int + (0 <= _) + (_ < 150)>
|
||||
extend Longitude {
|
||||
op __sub__(Longitude) -> Difference[Longitude]
|
||||
}
|
||||
|
||||
// Predefined custom constraints that can be referenced in other definitions
|
||||
constraint Positive = _ >= 0
|
||||
constraint StrictlyPositive = _ > 0
|
||||
//constraint Even = _ % 2 == 0
|
||||
// Predefined custom predicates that can be referenced in other definitions
|
||||
predicate Positive(v: float) = v >= 0
|
||||
predicate StrictlyPositive(v: float) = v > 0
|
||||
predicate Equatorial(loc: GeoLocation) = (-10 <= loc.lat <= 10)
|
||||
predicate Arctic(loc: GeoLocation) = (loc.lat >= 66)
|
||||
|
||||
type Person {
|
||||
name: str
|
||||
|
||||
// Property with an inline constraint
|
||||
age: int? where (0 <= _ < 150)
|
||||
|
||||
// Property referencing a predicate
|
||||
height: float where StrictlyPositive
|
||||
|
||||
home: GeoLocation
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user