Compare commits

6 Commits

9 changed files with 824 additions and 569 deletions

View File

@@ -10,6 +10,8 @@ from midas.checker.types import (
ColumnType, ColumnType,
DataFrameType, DataFrameType,
Function, Function,
OverloadedFunction,
TopType,
Type, Type,
UnknownType, UnknownType,
unfold_type, unfold_type,
@@ -85,6 +87,9 @@ class MethodRegistry(metaclass=_MethodRegistryMeta):
self, self,
call: Call, call: Call,
) -> Type: ) -> Type:
# TODO: support add with scalar, sequence, Series, dict
# TODO: check operation exists on inner column types
new_columns: list[DataFrameType.Column] = [] new_columns: list[DataFrameType.Column] = []
by_name: dict[str, DataFrameType.Column] = {} by_name: dict[str, DataFrameType.Column] = {}
@@ -151,3 +156,43 @@ class MethodRegistry(metaclass=_MethodRegistryMeta):
) )
or UnknownType() or UnknownType()
) )
@frame_method()
def mean(self, call: Call) -> Type:
with_axis = Function(
kw_args=[
Function.Argument(
pos=0,
name="axis",
type=self.types.get_type("int"),
required=False,
)
],
returns=ColumnType(type=TopType()),
)
without_axis = Function(
kw_args=[
Function.Argument(
pos=0,
name="axis",
type=self.types.get_type("None"),
required=True,
)
],
returns=TopType(),
)
overload = OverloadedFunction(
overloads=[
with_axis,
without_axis,
]
)
return (
self.typer._get_call_result(
location=call.location,
callee=overload,
positional=call.positional,
keywords=call.keywords,
)
or UnknownType()
)

View File

@@ -47,6 +47,10 @@ class ReturnException(Exception):
pass pass
class UndefinedMethodException(Exception):
pass
@dataclass(frozen=True, kw_only=True) @dataclass(frozen=True, kw_only=True)
class MappedArgument: class MappedArgument:
expr: p.Expr expr: p.Expr
@@ -195,6 +199,36 @@ class PythonTyper(
return self.env.get_at(distance, name) return self.env.get_at(distance, name)
return self.global_env.get(name) return self.global_env.get(name)
def call_method(
self,
location: Location,
obj: Type,
method_name: str,
positional: list[TypedExpr],
keywords: dict[str, TypedExpr],
) -> Optional[Type]:
unfolded: Type = unfold_type(obj)
match unfolded:
case DataFrameType():
return self.frame_mgr.call(
method=method_name,
location=location,
frame=unfolded,
positional=positional,
keywords=keywords,
)
method: Optional[Type] = self.types.lookup_member(obj, method_name)
if method is None:
raise UndefinedMethodException
return self._get_call_result(
location,
method,
positional,
keywords,
)
def is_subtype(self, type1: Type, type2: Type) -> bool: def is_subtype(self, type1: Type, type2: Type) -> bool:
return self.types.is_subtype(type1, type2) return self.types.is_subtype(type1, type2)
@@ -468,20 +502,16 @@ class PythonTyper(
left: Type = self.type_of(left_expr) left: Type = self.type_of(left_expr)
right: Type = self.type_of(right_expr) right: Type = self.type_of(right_expr)
operation: Optional[Type] = self.types.lookup_member(left, method) result: Optional[Type]
if operation is None: try:
result = self.call_method(location, left, method, [(right_expr, right)], {})
except UndefinedMethodException:
self.reporter.error( self.reporter.error(
location, location,
f"Undefined operation {method} between {left} and {right}", f"Undefined operation {method} between {left} and {right}",
) )
return UnknownType() return UnknownType()
result: Optional[Type] = self._get_call_result(
location,
operation,
[(right_expr, right)],
{},
)
return result or UnknownType() return result or UnknownType()
def visit_unary_expr(self, expr: p.UnaryExpr) -> Type: def visit_unary_expr(self, expr: p.UnaryExpr) -> Type:
@@ -494,20 +524,17 @@ class PythonTyper(
return UnknownType() return UnknownType()
operand: Type = self.type_of(expr.right) operand: Type = self.type_of(expr.right)
operation: Optional[Type] = self.types.lookup_member(operand, method)
if operation is None: result: Optional[Type]
try:
result = self.call_method(expr.location, operand, method, [], {})
except UndefinedMethodException:
self.reporter.error( self.reporter.error(
expr.location, expr.location,
f"Undefined operation {method} for {operand}", f"Undefined operation {method} for {operand}",
) )
return UnknownType() return UnknownType()
result: Optional[Type] = self._get_call_result(
expr.location,
operation,
[],
{},
)
return result or UnknownType() return result or UnknownType()
def visit_call_expr(self, expr: p.CallExpr) -> Type: def visit_call_expr(self, expr: p.CallExpr) -> Type:
@@ -567,6 +594,8 @@ class PythonTyper(
return self.types.get_type("float") return self.types.get_type("float")
case str(): case str():
return self.types.get_type("str") return self.types.get_type("str")
case None:
return self.types.get_type("None")
case _: case _:
self.reporter.warning(expr.location, f"Unknown literal {expr}") self.reporter.warning(expr.location, f"Unknown literal {expr}")
return UnknownType() return UnknownType()
@@ -638,7 +667,7 @@ class PythonTyper(
if len(item_types) == 1: if len(item_types) == 1:
item_type: Type = item_types[0] item_type: Type = item_types[0]
return self.types.apply_generic(list_type, [item_type]) return self.types.apply_generic(list_type, [item_type])
self.reporter.error( self.reporter.warning(
expr.location, expr.location,
f"Heterogeneous list items: [{', '.join(map(str, item_types))}]", f"Heterogeneous list items: [{', '.join(map(str, item_types))}]",
) )
@@ -670,7 +699,7 @@ class PythonTyper(
if len(key_types) == 1: if len(key_types) == 1:
key_type = key_types[0] key_type = key_types[0]
else: else:
self.reporter.error( self.reporter.warning(
expr.location, expr.location,
f"Heterogeneous dict keys: [{', '.join(map(str, key_types))}]", f"Heterogeneous dict keys: [{', '.join(map(str, key_types))}]",
) )
@@ -678,7 +707,7 @@ class PythonTyper(
if len(value_types) == 1: if len(value_types) == 1:
value_type = value_types[0] value_type = value_types[0]
else: else:
self.reporter.error( self.reporter.warning(
expr.location, expr.location,
f"Heterogeneous dict values: [{', '.join(map(str, value_types))}]", f"Heterogeneous dict values: [{', '.join(map(str, value_types))}]",
) )
@@ -1277,6 +1306,12 @@ class PythonTyper(
return False return False
return True return True
case DataFrameType() | ColumnType():
self.reporter.error(
expr.location, f"Cannot cast {lit_value!r} to {target_type}"
)
return False
case _: case _:
self.reporter.info( self.reporter.info(
expr.location, f"Cannot evaluate cast to {target_type} statically" expr.location, f"Cannot evaluate cast to {target_type} statically"

View File

@@ -40,6 +40,9 @@ class Scope:
class Generator(p.Stmt.Visitor[ast.stmt], p.Expr.Visitor[ast.expr]): class Generator(p.Stmt.Visitor[ast.stmt], p.Expr.Visitor[ast.expr]):
IS_DATAFRAME_FUNC = "__midas_is_dataframe__"
IS_COLUMN_FUNC = "__midas_is_column__"
def __init__(self, workdir: Path, types: TypesRegistry) -> None: def __init__(self, workdir: Path, types: TypesRegistry) -> None:
self.workdir: Path = workdir.resolve() self.workdir: Path = workdir.resolve()
self.build_dir: Path = self.workdir / "build" / "midas" self.build_dir: Path = self.workdir / "build" / "midas"
@@ -58,12 +61,24 @@ class Generator(p.Stmt.Visitor[ast.stmt], p.Expr.Visitor[ast.expr]):
self._constraint_generator: ConstraintGenerator = ConstraintGenerator(types) self._constraint_generator: ConstraintGenerator = ConstraintGenerator(types)
self._constraints: list[tuple[m.Expr, ast.expr]] = [] self._constraints: list[tuple[m.Expr, ast.expr]] = []
self.define_is_dataframe: bool = False
self.define_is_column: bool = False
def generate_ast(self, typed_ast: TypedAST, src_path: Path) -> ast.AST: def generate_ast(self, typed_ast: TypedAST, src_path: Path) -> ast.AST:
self.rel_src_path = src_path.resolve().relative_to(self.workdir) self.rel_src_path = src_path.resolve().relative_to(self.workdir)
self._typed_ast = typed_ast self._typed_ast = typed_ast
body: list[ast.stmt] = self._visit_body(typed_ast.stmts) body: list[ast.stmt] = self._visit_body(typed_ast.stmts)
predicates: list[ast.stmt] = self._constraint_generator.get_definitions() predicates: list[ast.stmt] = self._constraint_generator.get_definitions()
module = ast.Module(body=predicates + body, type_ignores=[])
body = predicates + body
if self.define_is_dataframe:
body = [self._is_dataframe_definition()] + body
if self.define_is_column:
body = [self._is_column_definition()] + body
module = ast.Module(body=body, type_ignores=[])
module = ast.fix_missing_locations(module) module = ast.fix_missing_locations(module)
return module return module
@@ -350,6 +365,51 @@ class Generator(p.Stmt.Visitor[ast.stmt], p.Expr.Visitor[ast.expr]):
for item, item_type in zip(expr.elts, items): for item, item_type in zip(expr.elts, items):
self._make_cast_asserts(src_location, item, item_type) self._make_cast_asserts(src_location, item, item_type)
case DataFrameType(columns=columns):
self.define_is_dataframe = True
self._add_assert(
ast.Call(
func=ast.Name(id=self.IS_DATAFRAME_FUNC),
args=[expr],
keywords=[],
),
self._make_cast_assert_message(
src_location, expr, type, ": Not a dataframe"
),
)
for column in columns:
self._add_assert(
ast.Compare(
left=ast.Constant(value=column.name),
ops=[ast.In()],
comparators=[expr],
),
self._make_cast_assert_message(
src_location, expr, type, f": Missing column {column.name}"
),
)
self._make_cast_asserts(
src_location,
ast.Subscript(
value=expr, slice=ast.Constant(value=column.name)
),
column.type,
)
case ColumnType(type=inner):
self.define_is_column = True
self._add_assert(
ast.Call(
func=ast.Name(id=self.IS_COLUMN_FUNC),
args=[expr],
keywords=[],
),
self._make_cast_assert_message(
src_location, expr, type, ": Not a column"
),
)
# TODO: check value type
case ( case (
TopType() TopType()
| Function() | Function()
@@ -357,8 +417,6 @@ class Generator(p.Stmt.Visitor[ast.stmt], p.Expr.Visitor[ast.expr]):
| ComplexType() | ComplexType()
| ExtensionType() | ExtensionType()
| GenericType() | GenericType()
| ColumnType()
| DataFrameType()
): ):
self.logger.warning(f"Can't make assertion for type {type}") self.logger.warning(f"Can't make assertion for type {type}")
@@ -367,7 +425,11 @@ class Generator(p.Stmt.Visitor[ast.stmt], p.Expr.Visitor[ast.expr]):
assert_never(type) assert_never(type)
def _make_cast_assert_message( def _make_cast_assert_message(
self, location: Location, expr: ast.expr, type: Type self,
location: Location,
expr: ast.expr,
type: Type,
extra: Optional[str] = None,
) -> ast.expr: ) -> ast.expr:
loc_str: str = f"{self.rel_src_path}:L{location.lineno}:{location.col_offset+1}" loc_str: str = f"{self.rel_src_path}:L{location.lineno}:{location.col_offset+1}"
# f"file.py:L1:1: CastError: Cannot cast {type(expr).__name__} to Type" # f"file.py:L1:1: CastError: Cannot cast {type(expr).__name__} to Type"
@@ -385,7 +447,7 @@ class Generator(p.Stmt.Visitor[ast.stmt], p.Expr.Visitor[ast.expr]):
), ),
conversion=-1, conversion=-1,
), ),
ast.Constant(f" to {type}"), ast.Constant(f" to {type}{extra or ''}"),
] ]
) )
@@ -421,3 +483,75 @@ class Generator(p.Stmt.Visitor[ast.stmt], p.Expr.Visitor[ast.expr]):
constraint: ast.expr = self._constraint_generator.generate(expr) constraint: ast.expr = self._constraint_generator.generate(expr)
self._constraints.append((expr, constraint)) self._constraints.append((expr, constraint))
return constraint return constraint
def _is_dataframe_definition(self) -> ast.stmt:
"""
def IS_DATAFRAME_FUNC(obj) -> bool:
import pandas as pd
return isinstance(obj, pd.DataFrame)
"""
return ast.FunctionDef(
name=self.IS_DATAFRAME_FUNC,
args=ast.arguments(
posonlyargs=[ast.arg(arg="obj")],
args=[],
kwonlyargs=[],
defaults=[],
kw_defaults=[],
),
body=[
ast.Import(names=[ast.alias(name="pandas", asname="pd")]),
ast.Return(
value=ast.Call(
func=ast.Name(id="isinstance"),
args=[
ast.Name(id="obj"),
ast.Attribute(
value=ast.Name(id="pd"),
attr="DataFrame",
),
],
keywords=[],
)
),
],
decorator_list=[],
returns=ast.Name(id="bool"),
)
def _is_column_definition(self) -> ast.stmt:
"""
def IS_COLUMN_FUNC(obj) -> bool:
import pandas as pd
return isinstance(obj, pd.Series)
"""
return ast.FunctionDef(
name=self.IS_COLUMN_FUNC,
args=ast.arguments(
posonlyargs=[ast.arg(arg="obj")],
args=[],
kwonlyargs=[],
defaults=[],
kw_defaults=[],
),
body=[
ast.Import(names=[ast.alias(name="pandas", asname="pd")]),
ast.Return(
value=ast.Call(
func=ast.Name(id="isinstance"),
args=[
ast.Name(id="obj"),
ast.Attribute(
value=ast.Name(id="pd"),
attr="Series",
),
],
keywords=[],
)
),
],
decorator_list=[],
returns=ast.Name(id="bool"),
)

View File

@@ -4,7 +4,35 @@
"type": "Warning", "type": "Warning",
"location": { "location": {
"start": [ "start": [
6, 8,
12
],
"end": [
8,
43
]
},
"message": "ConstraintType not yet supported"
},
{
"type": "Warning",
"location": {
"start": [
10,
10
],
"end": [
10,
18
]
},
"message": "Unknown type 'datetime'"
},
{
"type": "Warning",
"location": {
"start": [
13,
4 4
], ],
"end": [ "end": [
@@ -12,7 +40,7 @@
5 5
] ]
}, },
"message": "FrameType not yet supported" "message": "Unknown type '_'"
} }
], ],
"judgments": [] "judgments": []

View File

@@ -328,6 +328,19 @@
}, },
"type": {} "type": {}
}, },
{
"location": {
"from": "L6:9",
"to": "L6:10"
},
"expr": {
"_type": "LiteralExpr",
"value": 1
},
"type": {
"name": "int"
}
},
{ {
"location": { "location": {
"from": "L6:5", "from": "L6:5",
@@ -373,19 +386,6 @@
} }
} }
}, },
{
"location": {
"from": "L6:9",
"to": "L6:10"
},
"expr": {
"_type": "LiteralExpr",
"value": 1
},
"type": {
"name": "int"
}
},
{ {
"location": { "location": {
"from": "L6:5", "from": "L6:5",
@@ -407,6 +407,32 @@
}, },
"type": {} "type": {}
}, },
{
"location": {
"from": "L7:9",
"to": "L7:10"
},
"expr": {
"_type": "LiteralExpr",
"value": 1
},
"type": {
"name": "int"
}
},
{
"location": {
"from": "L7:12",
"to": "L7:15"
},
"expr": {
"_type": "LiteralExpr",
"value": 2.0
},
"type": {
"name": "float"
}
},
{ {
"location": { "location": {
"from": "L7:5", "from": "L7:5",
@@ -452,32 +478,6 @@
} }
} }
}, },
{
"location": {
"from": "L7:9",
"to": "L7:10"
},
"expr": {
"_type": "LiteralExpr",
"value": 1
},
"type": {
"name": "int"
}
},
{
"location": {
"from": "L7:12",
"to": "L7:15"
},
"expr": {
"_type": "LiteralExpr",
"value": 2.0
},
"type": {
"name": "float"
}
},
{ {
"location": { "location": {
"from": "L7:5", "from": "L7:5",
@@ -503,6 +503,32 @@
}, },
"type": {} "type": {}
}, },
{
"location": {
"from": "L8:9",
"to": "L8:10"
},
"expr": {
"_type": "LiteralExpr",
"value": 1
},
"type": {
"name": "int"
}
},
{
"location": {
"from": "L8:14",
"to": "L8:17"
},
"expr": {
"_type": "LiteralExpr",
"value": 2.0
},
"type": {
"name": "float"
}
},
{ {
"location": { "location": {
"from": "L8:5", "from": "L8:5",
@@ -548,32 +574,6 @@
} }
} }
}, },
{
"location": {
"from": "L8:9",
"to": "L8:10"
},
"expr": {
"_type": "LiteralExpr",
"value": 1
},
"type": {
"name": "int"
}
},
{
"location": {
"from": "L8:14",
"to": "L8:17"
},
"expr": {
"_type": "LiteralExpr",
"value": 2.0
},
"type": {
"name": "float"
}
},
{ {
"location": { "location": {
"from": "L8:5", "from": "L8:5",
@@ -600,6 +600,45 @@
}, },
"type": {} "type": {}
}, },
{
"location": {
"from": "L9:9",
"to": "L9:10"
},
"expr": {
"_type": "LiteralExpr",
"value": 1
},
"type": {
"name": "int"
}
},
{
"location": {
"from": "L9:12",
"to": "L9:15"
},
"expr": {
"_type": "LiteralExpr",
"value": 2.0
},
"type": {
"name": "float"
}
},
{
"location": {
"from": "L9:17",
"to": "L9:23"
},
"expr": {
"_type": "LiteralExpr",
"value": "test"
},
"type": {
"name": "str"
}
},
{ {
"location": { "location": {
"from": "L9:5", "from": "L9:5",
@@ -645,45 +684,6 @@
} }
} }
}, },
{
"location": {
"from": "L9:9",
"to": "L9:10"
},
"expr": {
"_type": "LiteralExpr",
"value": 1
},
"type": {
"name": "int"
}
},
{
"location": {
"from": "L9:12",
"to": "L9:15"
},
"expr": {
"_type": "LiteralExpr",
"value": 2.0
},
"type": {
"name": "float"
}
},
{
"location": {
"from": "L9:17",
"to": "L9:23"
},
"expr": {
"_type": "LiteralExpr",
"value": "test"
},
"type": {
"name": "str"
}
},
{ {
"location": { "location": {
"from": "L9:5", "from": "L9:5",
@@ -713,6 +713,45 @@
}, },
"type": {} "type": {}
}, },
{
"location": {
"from": "L10:9",
"to": "L10:10"
},
"expr": {
"_type": "LiteralExpr",
"value": 1
},
"type": {
"name": "int"
}
},
{
"location": {
"from": "L10:12",
"to": "L10:15"
},
"expr": {
"_type": "LiteralExpr",
"value": 2.0
},
"type": {
"name": "float"
}
},
{
"location": {
"from": "L10:19",
"to": "L10:22"
},
"expr": {
"_type": "LiteralExpr",
"value": 3.0
},
"type": {
"name": "float"
}
},
{ {
"location": { "location": {
"from": "L10:5", "from": "L10:5",
@@ -758,45 +797,6 @@
} }
} }
}, },
{
"location": {
"from": "L10:9",
"to": "L10:10"
},
"expr": {
"_type": "LiteralExpr",
"value": 1
},
"type": {
"name": "int"
}
},
{
"location": {
"from": "L10:12",
"to": "L10:15"
},
"expr": {
"_type": "LiteralExpr",
"value": 2.0
},
"type": {
"name": "float"
}
},
{
"location": {
"from": "L10:19",
"to": "L10:22"
},
"expr": {
"_type": "LiteralExpr",
"value": 3.0
},
"type": {
"name": "float"
}
},
{ {
"location": { "location": {
"from": "L10:5", "from": "L10:5",
@@ -827,6 +827,19 @@
}, },
"type": {} "type": {}
}, },
{
"location": {
"from": "L11:11",
"to": "L11:12"
},
"expr": {
"_type": "LiteralExpr",
"value": 1
},
"type": {
"name": "int"
}
},
{ {
"location": { "location": {
"from": "L11:5", "from": "L11:5",
@@ -872,19 +885,6 @@
} }
} }
}, },
{
"location": {
"from": "L11:11",
"to": "L11:12"
},
"expr": {
"_type": "LiteralExpr",
"value": 1
},
"type": {
"name": "int"
}
},
{ {
"location": { "location": {
"from": "L11:5", "from": "L11:5",
@@ -906,6 +906,19 @@
}, },
"type": {} "type": {}
}, },
{
"location": {
"from": "L12:11",
"to": "L12:17"
},
"expr": {
"_type": "LiteralExpr",
"value": "test"
},
"type": {
"name": "str"
}
},
{ {
"location": { "location": {
"from": "L12:5", "from": "L12:5",
@@ -951,19 +964,6 @@
} }
} }
}, },
{
"location": {
"from": "L12:11",
"to": "L12:17"
},
"expr": {
"_type": "LiteralExpr",
"value": "test"
},
"type": {
"name": "str"
}
},
{ {
"location": { "location": {
"from": "L12:5", "from": "L12:5",
@@ -985,6 +985,45 @@
}, },
"type": {} "type": {}
}, },
{
"location": {
"from": "L14:10",
"to": "L14:11"
},
"expr": {
"_type": "LiteralExpr",
"value": 1
},
"type": {
"name": "int"
}
},
{
"location": {
"from": "L14:13",
"to": "L14:16"
},
"expr": {
"_type": "LiteralExpr",
"value": 2.0
},
"type": {
"name": "float"
}
},
{
"location": {
"from": "L14:20",
"to": "L14:26"
},
"expr": {
"_type": "LiteralExpr",
"value": "test"
},
"type": {
"name": "str"
}
},
{ {
"location": { "location": {
"from": "L14:6", "from": "L14:6",
@@ -1030,45 +1069,6 @@
} }
} }
}, },
{
"location": {
"from": "L14:10",
"to": "L14:11"
},
"expr": {
"_type": "LiteralExpr",
"value": 1
},
"type": {
"name": "int"
}
},
{
"location": {
"from": "L14:13",
"to": "L14:16"
},
"expr": {
"_type": "LiteralExpr",
"value": 2.0
},
"type": {
"name": "float"
}
},
{
"location": {
"from": "L14:20",
"to": "L14:26"
},
"expr": {
"_type": "LiteralExpr",
"value": "test"
},
"type": {
"name": "str"
}
},
{ {
"location": { "location": {
"from": "L14:6", "from": "L14:6",
@@ -1101,6 +1101,45 @@
"name": "bool" "name": "bool"
} }
}, },
{
"location": {
"from": "L15:10",
"to": "L15:11"
},
"expr": {
"_type": "LiteralExpr",
"value": 1
},
"type": {
"name": "int"
}
},
{
"location": {
"from": "L15:15",
"to": "L15:18"
},
"expr": {
"_type": "LiteralExpr",
"value": 2.0
},
"type": {
"name": "float"
}
},
{
"location": {
"from": "L15:22",
"to": "L15:28"
},
"expr": {
"_type": "LiteralExpr",
"value": "test"
},
"type": {
"name": "str"
}
},
{ {
"location": { "location": {
"from": "L15:6", "from": "L15:6",
@@ -1146,45 +1185,6 @@
} }
} }
}, },
{
"location": {
"from": "L15:10",
"to": "L15:11"
},
"expr": {
"_type": "LiteralExpr",
"value": 1
},
"type": {
"name": "int"
}
},
{
"location": {
"from": "L15:15",
"to": "L15:18"
},
"expr": {
"_type": "LiteralExpr",
"value": 2.0
},
"type": {
"name": "float"
}
},
{
"location": {
"from": "L15:22",
"to": "L15:28"
},
"expr": {
"_type": "LiteralExpr",
"value": "test"
},
"type": {
"name": "str"
}
},
{ {
"location": { "location": {
"from": "L15:6", "from": "L15:6",
@@ -1217,6 +1217,45 @@
"name": "bool" "name": "bool"
} }
}, },
{
"location": {
"from": "L16:10",
"to": "L16:11"
},
"expr": {
"_type": "LiteralExpr",
"value": 1
},
"type": {
"name": "int"
}
},
{
"location": {
"from": "L16:15",
"to": "L16:21"
},
"expr": {
"_type": "LiteralExpr",
"value": "test"
},
"type": {
"name": "str"
}
},
{
"location": {
"from": "L16:25",
"to": "L16:28"
},
"expr": {
"_type": "LiteralExpr",
"value": 2.0
},
"type": {
"name": "float"
}
},
{ {
"location": { "location": {
"from": "L16:6", "from": "L16:6",
@@ -1262,45 +1301,6 @@
} }
} }
}, },
{
"location": {
"from": "L16:10",
"to": "L16:11"
},
"expr": {
"_type": "LiteralExpr",
"value": 1
},
"type": {
"name": "int"
}
},
{
"location": {
"from": "L16:15",
"to": "L16:21"
},
"expr": {
"_type": "LiteralExpr",
"value": "test"
},
"type": {
"name": "str"
}
},
{
"location": {
"from": "L16:25",
"to": "L16:28"
},
"expr": {
"_type": "LiteralExpr",
"value": 2.0
},
"type": {
"name": "float"
}
},
{ {
"location": { "location": {
"from": "L16:6", "from": "L16:6",
@@ -1333,6 +1333,45 @@
"name": "bool" "name": "bool"
} }
}, },
{
"location": {
"from": "L18:10",
"to": "L18:13"
},
"expr": {
"_type": "LiteralExpr",
"value": "a"
},
"type": {
"name": "str"
}
},
{
"location": {
"from": "L18:15",
"to": "L18:16"
},
"expr": {
"_type": "LiteralExpr",
"value": 3
},
"type": {
"name": "int"
}
},
{
"location": {
"from": "L18:20",
"to": "L18:25"
},
"expr": {
"_type": "LiteralExpr",
"value": false
},
"type": {
"name": "bool"
}
},
{ {
"location": { "location": {
"from": "L18:6", "from": "L18:6",
@@ -1378,45 +1417,6 @@
} }
} }
}, },
{
"location": {
"from": "L18:10",
"to": "L18:13"
},
"expr": {
"_type": "LiteralExpr",
"value": "a"
},
"type": {
"name": "str"
}
},
{
"location": {
"from": "L18:15",
"to": "L18:16"
},
"expr": {
"_type": "LiteralExpr",
"value": 3
},
"type": {
"name": "int"
}
},
{
"location": {
"from": "L18:20",
"to": "L18:25"
},
"expr": {
"_type": "LiteralExpr",
"value": false
},
"type": {
"name": "bool"
}
},
{ {
"location": { "location": {
"from": "L18:6", "from": "L18:6",

View File

@@ -100,6 +100,32 @@
"name": "float" "name": "float"
} }
}, },
{
"location": {
"from": "L11:13",
"to": "L11:15"
},
"expr": {
"_type": "VariableExpr",
"name": "v1"
},
"type": {
"name": "int"
}
},
{
"location": {
"from": "L11:17",
"to": "L11:19"
},
"expr": {
"_type": "VariableExpr",
"name": "v2"
},
"type": {
"name": "float"
}
},
{ {
"location": { "location": {
"from": "L11:5", "from": "L11:5",
@@ -135,32 +161,6 @@
} }
} }
}, },
{
"location": {
"from": "L11:13",
"to": "L11:15"
},
"expr": {
"_type": "VariableExpr",
"name": "v1"
},
"type": {
"name": "int"
}
},
{
"location": {
"from": "L11:17",
"to": "L11:19"
},
"expr": {
"_type": "VariableExpr",
"name": "v2"
},
"type": {
"name": "float"
}
},
{ {
"location": { "location": {
"from": "L11:5", "from": "L11:5",

View File

@@ -72,29 +72,6 @@
} }
], ],
"judgments": [ "judgments": [
{
"location": {
"from": "L26:0",
"to": "L26:5"
},
"expr": {
"_type": "VariableExpr",
"name": "print"
},
"type": {
"pos_args": [
{
"pos": 0,
"name": "object",
"type": {},
"required": true
}
],
"args": [],
"kw_args": [],
"returns": {}
}
},
{ {
"location": { "location": {
"from": "L27:4", "from": "L27:4",
@@ -325,6 +302,29 @@
} }
} }
}, },
{
"location": {
"from": "L26:0",
"to": "L26:5"
},
"expr": {
"_type": "VariableExpr",
"name": "print"
},
"type": {
"pos_args": [
{
"pos": 0,
"name": "object",
"type": {},
"required": true
}
],
"args": [],
"kw_args": [],
"returns": {}
}
},
{ {
"location": { "location": {
"from": "L26:0", "from": "L26:0",

View File

@@ -63,31 +63,6 @@
"name": "float" "name": "float"
} }
}, },
{
"location": {
"from": "L6:11",
"to": "L6:15"
},
"expr": {
"_type": "VariableExpr",
"name": "bool"
},
"type": {
"pos_args": [
{
"pos": 0,
"name": "object",
"type": {},
"required": false
}
],
"args": [],
"kw_args": [],
"returns": {
"name": "bool"
}
}
},
{ {
"location": { "location": {
"from": "L6:16", "from": "L6:16",
@@ -135,6 +110,31 @@
"name": "int" "name": "int"
} }
}, },
{
"location": {
"from": "L6:11",
"to": "L6:15"
},
"expr": {
"_type": "VariableExpr",
"name": "bool"
},
"type": {
"pos_args": [
{
"pos": 0,
"name": "object",
"type": {},
"required": false
}
],
"args": [],
"kw_args": [],
"returns": {
"name": "bool"
}
}
},
{ {
"location": { "location": {
"from": "L6:11", "from": "L6:11",
@@ -367,6 +367,54 @@
} }
} }
}, },
{
"location": {
"from": "L12:21",
"to": "L12:27"
},
"expr": {
"_type": "VariableExpr",
"name": "double"
},
"type": {
"pos_args": [],
"args": [
{
"pos": 0,
"name": "value",
"type": {
"name": "float"
},
"required": true
}
],
"kw_args": [],
"returns": {
"name": "float"
}
}
},
{
"location": {
"from": "L12:29",
"to": "L12:35"
},
"expr": {
"_type": "VariableExpr",
"name": "floats"
},
"type": {
"name": "list",
"args": [
{
"name": "float"
}
],
"body": {
"name": "list"
}
}
},
{ {
"location": { "location": {
"from": "L12:17", "from": "L12:17",
@@ -455,54 +503,6 @@
} }
} }
}, },
{
"location": {
"from": "L12:21",
"to": "L12:27"
},
"expr": {
"_type": "VariableExpr",
"name": "double"
},
"type": {
"pos_args": [],
"args": [
{
"pos": 0,
"name": "value",
"type": {
"name": "float"
},
"required": true
}
],
"kw_args": [],
"returns": {
"name": "float"
}
}
},
{
"location": {
"from": "L12:29",
"to": "L12:35"
},
"expr": {
"_type": "VariableExpr",
"name": "floats"
},
"type": {
"name": "list",
"args": [
{
"name": "float"
}
],
"body": {
"name": "list"
}
}
},
{ {
"location": { "location": {
"from": "L12:17", "from": "L12:17",
@@ -538,6 +538,54 @@
} }
} }
}, },
{
"location": {
"from": "L13:19",
"to": "L13:25"
},
"expr": {
"_type": "VariableExpr",
"name": "double"
},
"type": {
"pos_args": [],
"args": [
{
"pos": 0,
"name": "value",
"type": {
"name": "float"
},
"required": true
}
],
"kw_args": [],
"returns": {
"name": "float"
}
}
},
{
"location": {
"from": "L13:27",
"to": "L13:31"
},
"expr": {
"_type": "VariableExpr",
"name": "ints"
},
"type": {
"name": "list",
"args": [
{
"name": "int"
}
],
"body": {
"name": "list"
}
}
},
{ {
"location": { "location": {
"from": "L13:15", "from": "L13:15",
@@ -626,54 +674,6 @@
} }
} }
}, },
{
"location": {
"from": "L13:19",
"to": "L13:25"
},
"expr": {
"_type": "VariableExpr",
"name": "double"
},
"type": {
"pos_args": [],
"args": [
{
"pos": 0,
"name": "value",
"type": {
"name": "float"
},
"required": true
}
],
"kw_args": [],
"returns": {
"name": "float"
}
}
},
{
"location": {
"from": "L13:27",
"to": "L13:31"
},
"expr": {
"_type": "VariableExpr",
"name": "ints"
},
"type": {
"name": "list",
"args": [
{
"name": "int"
}
],
"body": {
"name": "list"
}
}
},
{ {
"location": { "location": {
"from": "L13:15", "from": "L13:15",
@@ -699,6 +699,54 @@
}, },
"type": {} "type": {}
}, },
{
"location": {
"from": "L14:15",
"to": "L14:21"
},
"expr": {
"_type": "VariableExpr",
"name": "is_odd"
},
"type": {
"pos_args": [],
"args": [
{
"pos": 0,
"name": "value",
"type": {
"name": "int"
},
"required": true
}
],
"kw_args": [],
"returns": {
"name": "bool"
}
}
},
{
"location": {
"from": "L14:23",
"to": "L14:27"
},
"expr": {
"_type": "VariableExpr",
"name": "ints"
},
"type": {
"name": "list",
"args": [
{
"name": "int"
}
],
"body": {
"name": "list"
}
}
},
{ {
"location": { "location": {
"from": "L14:11", "from": "L14:11",
@@ -787,54 +835,6 @@
} }
} }
}, },
{
"location": {
"from": "L14:15",
"to": "L14:21"
},
"expr": {
"_type": "VariableExpr",
"name": "is_odd"
},
"type": {
"pos_args": [],
"args": [
{
"pos": 0,
"name": "value",
"type": {
"name": "int"
},
"required": true
}
],
"kw_args": [],
"returns": {
"name": "bool"
}
}
},
{
"location": {
"from": "L14:23",
"to": "L14:27"
},
"expr": {
"_type": "VariableExpr",
"name": "ints"
},
"type": {
"name": "list",
"args": [
{
"name": "int"
}
],
"body": {
"name": "list"
}
}
},
{ {
"location": { "location": {
"from": "L14:11", "from": "L14:11",

View File

@@ -8,6 +8,7 @@ from midas.ast.midas import (
Expr, Expr,
ExtendStmt, ExtendStmt,
ExtensionType, ExtensionType,
FrameType,
FunctionType, FunctionType,
GenericType, GenericType,
GetExpr, GetExpr,
@@ -197,3 +198,15 @@ class MidasAstJsonSerializer(
"base": type.base.accept(self), "base": type.base.accept(self),
"extension": type.extension.accept(self), "extension": type.extension.accept(self),
} }
def visit_frame_type(self, type: FrameType) -> dict:
return {
"_type": "FrameType",
"columns": [self._serialize_column(col) for col in type.columns],
}
def _serialize_column(self, column: FrameType.Column):
return {
"name": column.name.lexeme,
"type": column.type.accept(self),
}