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 (
|
from core.ast.midas import (
|
||||||
ConstraintExpr,
|
BinaryExpr,
|
||||||
ConstraintStmt,
|
ComplexTypeStmt,
|
||||||
Expr,
|
Expr,
|
||||||
|
ExtendStmt,
|
||||||
|
GetExpr,
|
||||||
|
GroupingExpr,
|
||||||
LiteralExpr,
|
LiteralExpr,
|
||||||
|
LogicalExpr,
|
||||||
OpStmt,
|
OpStmt,
|
||||||
|
PredicateStmt,
|
||||||
PropertyStmt,
|
PropertyStmt,
|
||||||
|
SimpleTypeExpr,
|
||||||
|
SimpleTypeStmt,
|
||||||
Stmt,
|
Stmt,
|
||||||
TypeBodyExpr,
|
TemplateExpr,
|
||||||
TypeExpr,
|
TypeExpr,
|
||||||
TypeStmt,
|
UnaryExpr,
|
||||||
|
VariableExpr,
|
||||||
WildcardExpr,
|
WildcardExpr,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -19,42 +29,29 @@ class AstJsonSerializer(Stmt.Visitor[dict], Expr.Visitor[dict]):
|
|||||||
def serialize(self, stmts: list[Stmt]) -> list[dict]:
|
def serialize(self, stmts: list[Stmt]) -> list[dict]:
|
||||||
return [stmt.accept(self) for stmt in stmts]
|
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 {
|
return {
|
||||||
"_type": "TypeStmt",
|
"_type": "SimpleTypeStmt",
|
||||||
|
"template": self._serialize_optional(stmt.template),
|
||||||
"name": stmt.name.lexeme,
|
"name": stmt.name.lexeme,
|
||||||
"bases": [base.accept(self) for base in stmt.bases],
|
"base": stmt.base.accept(self),
|
||||||
"body": stmt.body.accept(self) if stmt.body is not None else None,
|
"constraint": self._serialize_optional(stmt.constraint),
|
||||||
}
|
}
|
||||||
|
|
||||||
def visit_type_expr(self, expr: TypeExpr) -> dict:
|
def visit_complex_type_stmt(self, stmt: ComplexTypeStmt) -> dict:
|
||||||
return {
|
return {
|
||||||
"_type": "TypeExpr",
|
"_type": "ComplexTypeStmt",
|
||||||
"name": expr.name.lexeme,
|
"name": stmt.name.lexeme,
|
||||||
"constraints": [constraint.accept(self) for constraint in expr.constraints],
|
"template": self._serialize_optional(stmt.template),
|
||||||
}
|
"properties": self._serialize_list(stmt.properties),
|
||||||
|
|
||||||
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],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def visit_property_stmt(self, stmt: PropertyStmt) -> dict:
|
def visit_property_stmt(self, stmt: PropertyStmt) -> dict:
|
||||||
@@ -62,20 +59,101 @@ class AstJsonSerializer(Stmt.Visitor[dict], Expr.Visitor[dict]):
|
|||||||
"_type": "PropertyStmt",
|
"_type": "PropertyStmt",
|
||||||
"name": stmt.name.lexeme,
|
"name": stmt.name.lexeme,
|
||||||
"type": stmt.type.accept(self),
|
"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:
|
def visit_op_stmt(self, stmt: OpStmt) -> dict:
|
||||||
return {
|
return {
|
||||||
"_type": "OpStmt",
|
"_type": "OpStmt",
|
||||||
"left": stmt.left.accept(self),
|
"name": stmt.name.lexeme,
|
||||||
"op": stmt.op.lexeme,
|
"operand": stmt.operand.accept(self),
|
||||||
"right": stmt.right.accept(self),
|
|
||||||
"result": stmt.result.accept(self),
|
"result": stmt.result.accept(self),
|
||||||
}
|
}
|
||||||
|
|
||||||
def visit_constraint_stmt(self, stmt: ConstraintStmt) -> dict:
|
def visit_predicate_stmt(self, stmt: PredicateStmt) -> dict:
|
||||||
return {
|
return {
|
||||||
"_type": "ConstraintStmt",
|
"_type": "PredicateStmt",
|
||||||
"name": stmt.name.lexeme,
|
"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
|
// Simple custom type derived from float
|
||||||
type Latitude<float>
|
type Custom(float)
|
||||||
type Longitude<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
|
// Complex custom type, containing two values accessible through properties
|
||||||
type GeoLocation<Latitude, Longitude> {
|
type GeoLocation {
|
||||||
lat: Latitude
|
lat: Latitude
|
||||||
lon: Longitude
|
lon: Longitude
|
||||||
}
|
}
|
||||||
|
|
||||||
type LatitudeDiff<float>
|
// Define operations on our custom type
|
||||||
type LongitudeDiff<float>
|
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
|
// Simple operation defined on our custom types
|
||||||
op <Latitude> - <Latitude> = <LatitudeDiff>
|
extend Latitude {
|
||||||
op <Longitude> - <Longitude> = <LongitudeDiff>
|
op __sub__(Latitude) -> Difference[Latitude]
|
||||||
|
}
|
||||||
|
|
||||||
// Simple custom type with a constraint
|
extend Longitude {
|
||||||
type Age<int + (0 <= _) + (_ < 150)>
|
op __sub__(Longitude) -> Difference[Longitude]
|
||||||
|
}
|
||||||
|
|
||||||
// Predefined custom constraints that can be referenced in other definitions
|
// Predefined custom predicates that can be referenced in other definitions
|
||||||
constraint Positive = _ >= 0
|
predicate Positive(v: float) = v >= 0
|
||||||
constraint StrictlyPositive = _ > 0
|
predicate StrictlyPositive(v: float) = v > 0
|
||||||
//constraint Even = _ % 2 == 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