diff --git a/midas/ast/printer/midas.py b/midas/ast/printer/midas.py index 56d7ce8..f064751 100644 --- a/midas/ast/printer/midas.py +++ b/midas/ast/printer/midas.py @@ -1,6 +1,9 @@ +from typing import final + import midas.ast.midas as m +@final class MidasPrinter( m.Expr.Visitor[str], m.Stmt.Visitor[str], diff --git a/midas/ast/printer/midas_ast.py b/midas/ast/printer/midas_ast.py index d2e5daf..2e8103b 100644 --- a/midas/ast/printer/midas_ast.py +++ b/midas/ast/printer/midas_ast.py @@ -1,7 +1,10 @@ +from typing import final + import midas.ast.midas as m from midas.ast.printer.base import AstPrinter +@final class MidasAstPrinter( AstPrinter, m.Expr.Visitor[None], diff --git a/midas/ast/printer/python_ast.py b/midas/ast/printer/python_ast.py index d2214e0..d7de89c 100644 --- a/midas/ast/printer/python_ast.py +++ b/midas/ast/printer/python_ast.py @@ -1,9 +1,11 @@ import ast +from typing import final import midas.ast.python as p from midas.ast.printer.base import AstPrinter +@final class PythonAstPrinter( AstPrinter, p.MidasType.Visitor[None], @@ -115,6 +117,24 @@ class PythonAstPrinter( stmt.iterator.accept(self) self._write_sequence("body", stmt.body, last=True) + def visit_import_stmt(self, stmt: p.ImportStmt) -> None: + self._write_line("ImportStmt") + with self._child_level(single=True): + self._write_sequence("imports", stmt.imports, print_func=self._print_import) + + def visit_from_import_stmt(self, stmt: p.FromImportStmt) -> None: + self._write_line("FromImportStmt") + with self._child_level(): + self._write_line(f'module: "{stmt.module}"') + self._write_sequence("imports", stmt.imports, print_func=self._print_import) + self._write_line(f"level: {stmt.level}", last=True) + + def _print_import(self, import_: p.ImportAlias) -> None: + self._write_line("ImportAlias") + with self._child_level(): + self._write_line(f'name: "{import_.name}"') + self._write_line(f'alias: "{import_.alias}"') + def visit_raw_stmt(self, stmt: p.RawStmt) -> None: self._write_line("RawStmt") with self._child_level(single=True): diff --git a/midas/checker/evaluator.py b/midas/checker/evaluator.py index 79dc9c1..a3b4f96 100644 --- a/midas/checker/evaluator.py +++ b/midas/checker/evaluator.py @@ -1,5 +1,5 @@ from dataclasses import dataclass -from typing import Any, Callable, Optional +from typing import Any, Callable, Optional, final import midas.ast.midas as m from midas.ast.location import Location @@ -18,6 +18,7 @@ class PartialPredicate(Predicate): """A dictionary of already applied parameters""" +@final class Evaluator(m.Expr.Visitor[Any]): """Helper class to evaluate an expression diff --git a/midas/checker/midas.py b/midas/checker/midas.py index cfa881d..4ec4f73 100644 --- a/midas/checker/midas.py +++ b/midas/checker/midas.py @@ -1,6 +1,6 @@ import logging from pathlib import Path -from typing import Optional +from typing import Optional, final import midas.ast.midas as m from midas.ast.location import Location @@ -30,6 +30,7 @@ from midas.lexer.token import Token, TokenType from midas.parser.midas import MidasParser +@final class MidasTyper(m.Stmt.Visitor[None], m.Expr.Visitor[Type], m.Type.Visitor[Type]): """A resolver which evaluates Midas type definitions and build a registry""" @@ -110,7 +111,7 @@ class MidasTyper(m.Stmt.Visitor[None], m.Expr.Visitor[Type], m.Type.Visitor[Type return self._local_variables[name] return self.types.get_type(name) - def get_variable(self, name: str) -> Type: + def get_variable(self, location: Location, name: str) -> Type: """Get the type of a variable This function will first look into the current predicate's parameters if @@ -118,11 +119,9 @@ class MidasTyper(m.Stmt.Visitor[None], m.Expr.Visitor[Type], m.Type.Visitor[Type The the variable is looked up in the preamble (i.e. global environment) Args: + location (Location): the location of the variable reference name (str): the name of the variable - Raises: - NameError: if the variable cannot be found - Returns: Type: the type of the variable """ @@ -136,7 +135,8 @@ class MidasTyper(m.Stmt.Visitor[None], m.Expr.Visitor[Type], m.Type.Visitor[Type if global_ is not None: return global_ - raise NameError(f"Unknown variable '{name}'") + self.reporter.error(location, f"Unknown variable '{name}'") + return UnknownType() def resolve(self, stmts: list[m.Stmt]): """Process a sequence of statements @@ -293,6 +293,9 @@ class MidasTyper(m.Stmt.Visitor[None], m.Expr.Visitor[Type], m.Type.Visitor[Type return result.result def visit_unary_expr(self, expr: m.UnaryExpr) -> Type: + # First evaluate operand to surface all errors + operand: Type = self.type_of(expr.right) + # Special case because there is no __not__ dunder method match expr.operator: case Token(type=TokenType.BANG): @@ -306,7 +309,6 @@ class MidasTyper(m.Stmt.Visitor[None], m.Expr.Visitor[Type], m.Type.Visitor[Type ) return UnknownType() - operand: Type = self.type_of(expr.right) operation: Optional[Type] = self.types.lookup_member(operand, method) if operation is None: self.reporter.error( @@ -350,7 +352,7 @@ class MidasTyper(m.Stmt.Visitor[None], m.Expr.Visitor[Type], m.Type.Visitor[Type return member def visit_variable_expr(self, expr: m.VariableExpr) -> Type: - return self.get_variable(expr.name.lexeme) + return self.get_variable(expr.location, expr.name.lexeme) def visit_grouping_expr(self, expr: m.GroupingExpr) -> Type: return expr.expr.accept(self) @@ -365,12 +367,14 @@ class MidasTyper(m.Stmt.Visitor[None], m.Expr.Visitor[Type], m.Type.Visitor[Type return self.types.get_type("float") case str(): return self.types.get_type("str") + case None: + return self.types.get_type("None") case _: self.reporter.warning(expr.location, f"Unknown literal {expr}") return UnknownType() def visit_wildcard_expr(self, expr: m.WildcardExpr) -> Type: - return self.get_variable("_") + return self.get_variable(expr.location, "_") def visit_named_type(self, type: m.NamedType) -> Type: name: str = type.name.lexeme @@ -409,7 +413,7 @@ class MidasTyper(m.Stmt.Visitor[None], m.Expr.Visitor[Type], m.Type.Visitor[Type self._predicate_params = {} if not self.types.is_subtype(constraint_type, self._bool): self.reporter.error( - type.location, + type.constraint.location, f"Constraint must evaluate to a boolean, got {constraint_type}", ) diff --git a/midas/checker/python.py b/midas/checker/python.py index 15f4b62..b2995d0 100644 --- a/midas/checker/python.py +++ b/midas/checker/python.py @@ -1,6 +1,6 @@ import ast import logging -from typing import Any, Optional +from typing import Any, Optional, final import midas.ast.python as p from midas.ast.location import Location @@ -55,6 +55,7 @@ class UndefinedMethodException(Exception): pass +@final class PythonTyper( p.Stmt.Visitor[None], p.Expr.Visitor[Type], diff --git a/midas/checker/resolver.py b/midas/checker/resolver.py index 7c9e4e4..70747e9 100644 --- a/midas/checker/resolver.py +++ b/midas/checker/resolver.py @@ -1,3 +1,5 @@ +from typing import final + import midas.ast.python as p from midas.ast.location import Location from midas.checker.reporter import FileReporter @@ -6,6 +8,7 @@ from midas.checker.reporter import FileReporter class ResolverError(Exception): ... +@final class Resolver(p.Stmt.Visitor[None], p.Expr.Visitor[None]): """A variable assignment and reference resolver diff --git a/midas/cli/highlighter.py b/midas/cli/highlighter.py index 4929b0c..81cc444 100644 --- a/midas/cli/highlighter.py +++ b/midas/cli/highlighter.py @@ -3,7 +3,7 @@ from __future__ import annotations from abc import ABC, abstractmethod from dataclasses import dataclass from pathlib import Path -from typing import Generic, Optional, Protocol, TextIO, TypeVar +from typing import Generic, Optional, Protocol, TextIO, TypeVar, final import midas.ast.midas as m import midas.ast.python as p @@ -121,6 +121,7 @@ class Highlighter(ABC): self.openings.setdefault((l + 1, 0), []).append(opening) +@final class PythonHighlighter( Highlighter, p.MidasType.Visitor[None], @@ -197,6 +198,10 @@ class PythonHighlighter( for body_stmt in stmt.body: body_stmt.accept(self) + def visit_import_stmt(self, stmt: p.ImportStmt) -> None: ... + + def visit_from_import_stmt(self, stmt: p.FromImportStmt) -> None: ... + def visit_binary_expr(self, expr: p.BinaryExpr) -> None: ... def visit_compare_expr(self, expr: p.CompareExpr) -> None: ... @@ -255,6 +260,7 @@ class PythonHighlighter( def visit_raw_stmt(self, stmt: p.RawStmt) -> None: ... +@final class MidasHighlighter( Highlighter, m.Stmt.Visitor[None], m.Expr.Visitor[None], m.Type.Visitor[None] ): @@ -263,6 +269,11 @@ class MidasHighlighter( def highlight(self, node: Highlightable[MidasHighlighter]): node.accept(self) + def visit_alias_stmt(self, stmt: m.AliasStmt) -> None: + self.wrap(stmt, "alias-stmt") + self.wrap(LocatableToken(stmt.name), "type-name") + stmt.type.accept(self) + def visit_type_stmt(self, stmt: m.TypeStmt) -> None: self.wrap(stmt, "type-stmt") self.wrap(LocatableToken(stmt.name), "type-name") @@ -352,6 +363,7 @@ class MidasHighlighter( self.wrap(column, "column") +@final class DiagnosticsHighlighter(Highlighter): EXTRA_CSS_PATH: Optional[Path] = Path(__file__).parent / "hl_diagnostic.css" diff --git a/midas/generator/constraints.py b/midas/generator/constraints.py index 75c9a15..b663a9a 100644 --- a/midas/generator/constraints.py +++ b/midas/generator/constraints.py @@ -1,5 +1,5 @@ import ast -from typing import Optional +from typing import Optional, final import midas.ast.midas as m from midas.checker.registry import TypesRegistry @@ -39,6 +39,7 @@ COMPARISON_OPERATORS: dict[TokenType, type[ast.cmpop]] = { } +@final class ConstraintGenerator(m.Expr.Visitor[ast.expr]): """Class to generate Python code for constraint expressions""" diff --git a/midas/generator/generator.py b/midas/generator/generator.py index 3cf2423..fe3b92e 100644 --- a/midas/generator/generator.py +++ b/midas/generator/generator.py @@ -3,7 +3,7 @@ import logging import shutil from dataclasses import dataclass, field from pathlib import Path -from typing import Optional, assert_never +from typing import Optional, assert_never, final import midas.ast.midas as m import midas.ast.python as p @@ -47,6 +47,7 @@ class Scope: """A list of aliases defined in the scope, that can be discard afterwards""" +@final class Generator(p.Stmt.Visitor[ast.stmt], p.Expr.Visitor[ast.expr]): """ A class to translate the custom Python AST back into raw `ast` nodes diff --git a/tests/cases/checker/11_function_subtyping.py b/tests/cases/checker/11_function_subtyping.py new file mode 100644 index 0000000..86119c9 --- /dev/null +++ b/tests/cases/checker/11_function_subtyping.py @@ -0,0 +1,44 @@ +def a1(param: int) -> float: ... +def a2(param: float) -> int: ... + + +a = a1 +a = a2 + + +def b1(a: int, /) -> float: ... +def b2(b: float, /) -> int: ... + + +b = b1 +b = b2 + + +def c1(a: int) -> None: ... +def c2(p: float = 0, /, *, a: float = 0) -> None: ... + + +c = c1 +c = c2 + +# Invalid subtypes + + +def d1(a: int) -> float: ... +def d2(a: str) -> float: ... +def d3(a: int) -> str: ... + + +d = d1 +d = d2 +d = d3 + + +def e1(*, a: int = 0) -> None: ... +def e2(*, a: int) -> None: ... +def e3(*, a: int = 0, b: int) -> None: ... + + +e = e1 +e = e2 +e = e3 diff --git a/tests/cases/checker/11_function_subtyping.py.ref.json b/tests/cases/checker/11_function_subtyping.py.ref.json new file mode 100644 index 0000000..54ac38b --- /dev/null +++ b/tests/cases/checker/11_function_subtyping.py.ref.json @@ -0,0 +1,881 @@ +{ + "diagnostics": [ + { + "type": "Warning", + "location": { + "start": [ + 1, + 29 + ], + "end": [ + 1, + 32 + ] + }, + "message": "Unknown literal LiteralExpr(location=Location(lineno=1, col_offset=29, end_lineno=1, end_col_offset=32), value=Ellipsis)" + }, + { + "type": "Error", + "location": { + "start": [ + 1, + 22 + ], + "end": [ + 1, + 27 + ] + }, + "message": "Return type mismatch, annotated float but returns None" + }, + { + "type": "Warning", + "location": { + "start": [ + 2, + 29 + ], + "end": [ + 2, + 32 + ] + }, + "message": "Unknown literal LiteralExpr(location=Location(lineno=2, col_offset=29, end_lineno=2, end_col_offset=32), value=Ellipsis)" + }, + { + "type": "Error", + "location": { + "start": [ + 2, + 24 + ], + "end": [ + 2, + 27 + ] + }, + "message": "Return type mismatch, annotated int but returns None" + }, + { + "type": "Warning", + "location": { + "start": [ + 9, + 28 + ], + "end": [ + 9, + 31 + ] + }, + "message": "Unknown literal LiteralExpr(location=Location(lineno=9, col_offset=28, end_lineno=9, end_col_offset=31), value=Ellipsis)" + }, + { + "type": "Error", + "location": { + "start": [ + 9, + 21 + ], + "end": [ + 9, + 26 + ] + }, + "message": "Return type mismatch, annotated float but returns None" + }, + { + "type": "Warning", + "location": { + "start": [ + 10, + 28 + ], + "end": [ + 10, + 31 + ] + }, + "message": "Unknown literal LiteralExpr(location=Location(lineno=10, col_offset=28, end_lineno=10, end_col_offset=31), value=Ellipsis)" + }, + { + "type": "Error", + "location": { + "start": [ + 10, + 23 + ], + "end": [ + 10, + 26 + ] + }, + "message": "Return type mismatch, annotated int but returns None" + }, + { + "type": "Warning", + "location": { + "start": [ + 17, + 24 + ], + "end": [ + 17, + 27 + ] + }, + "message": "Unknown literal LiteralExpr(location=Location(lineno=17, col_offset=24, end_lineno=17, end_col_offset=27), value=Ellipsis)" + }, + { + "type": "Warning", + "location": { + "start": [ + 18, + 50 + ], + "end": [ + 18, + 53 + ] + }, + "message": "Unknown literal LiteralExpr(location=Location(lineno=18, col_offset=50, end_lineno=18, end_col_offset=53), value=Ellipsis)" + }, + { + "type": "Warning", + "location": { + "start": [ + 27, + 25 + ], + "end": [ + 27, + 28 + ] + }, + "message": "Unknown literal LiteralExpr(location=Location(lineno=27, col_offset=25, end_lineno=27, end_col_offset=28), value=Ellipsis)" + }, + { + "type": "Error", + "location": { + "start": [ + 27, + 18 + ], + "end": [ + 27, + 23 + ] + }, + "message": "Return type mismatch, annotated float but returns None" + }, + { + "type": "Warning", + "location": { + "start": [ + 28, + 25 + ], + "end": [ + 28, + 28 + ] + }, + "message": "Unknown literal LiteralExpr(location=Location(lineno=28, col_offset=25, end_lineno=28, end_col_offset=28), value=Ellipsis)" + }, + { + "type": "Error", + "location": { + "start": [ + 28, + 18 + ], + "end": [ + 28, + 23 + ] + }, + "message": "Return type mismatch, annotated float but returns None" + }, + { + "type": "Warning", + "location": { + "start": [ + 29, + 23 + ], + "end": [ + 29, + 26 + ] + }, + "message": "Unknown literal LiteralExpr(location=Location(lineno=29, col_offset=23, end_lineno=29, end_col_offset=26), value=Ellipsis)" + }, + { + "type": "Error", + "location": { + "start": [ + 29, + 18 + ], + "end": [ + 29, + 21 + ] + }, + "message": "Return type mismatch, annotated str but returns None" + }, + { + "type": "Error", + "location": { + "start": [ + 33, + 0 + ], + "end": [ + 33, + 6 + ] + }, + "message": "Cannot assign (a: str) -> float to variable 'd' of type (a: int) -> float" + }, + { + "type": "Error", + "location": { + "start": [ + 34, + 0 + ], + "end": [ + 34, + 6 + ] + }, + "message": "Cannot assign (a: int) -> str to variable 'd' of type (a: int) -> float" + }, + { + "type": "Warning", + "location": { + "start": [ + 37, + 31 + ], + "end": [ + 37, + 34 + ] + }, + "message": "Unknown literal LiteralExpr(location=Location(lineno=37, col_offset=31, end_lineno=37, end_col_offset=34), value=Ellipsis)" + }, + { + "type": "Warning", + "location": { + "start": [ + 38, + 27 + ], + "end": [ + 38, + 30 + ] + }, + "message": "Unknown literal LiteralExpr(location=Location(lineno=38, col_offset=27, end_lineno=38, end_col_offset=30), value=Ellipsis)" + }, + { + "type": "Warning", + "location": { + "start": [ + 39, + 39 + ], + "end": [ + 39, + 42 + ] + }, + "message": "Unknown literal LiteralExpr(location=Location(lineno=39, col_offset=39, end_lineno=39, end_col_offset=42), value=Ellipsis)" + }, + { + "type": "Error", + "location": { + "start": [ + 43, + 0 + ], + "end": [ + 43, + 6 + ] + }, + "message": "Cannot assign (*, a: int) -> None to variable 'e' of type (*, a: int?) -> None" + }, + { + "type": "Error", + "location": { + "start": [ + 44, + 0 + ], + "end": [ + 44, + 6 + ] + }, + "message": "Cannot assign (*, a: int?, b: int) -> None to variable 'e' of type (*, a: int?) -> None" + } + ], + "judgments": [ + { + "location": { + "from": "L1:29", + "to": "L1:32" + }, + "expr": { + "_type": "LiteralExpr", + "value": "..." + }, + "type": {} + }, + { + "location": { + "from": "L2:29", + "to": "L2:32" + }, + "expr": { + "_type": "LiteralExpr", + "value": "..." + }, + "type": {} + }, + { + "location": { + "from": "L5:4", + "to": "L5:6" + }, + "expr": { + "_type": "VariableExpr", + "name": "a1" + }, + "type": { + "params": { + "pos": [], + "mixed": [ + { + "pos": 0, + "name": "param", + "type": { + "name": "int" + }, + "required": true, + "unsupported": false + } + ], + "kw": [] + }, + "returns": { + "name": "float" + } + } + }, + { + "location": { + "from": "L6:4", + "to": "L6:6" + }, + "expr": { + "_type": "VariableExpr", + "name": "a2" + }, + "type": { + "params": { + "pos": [], + "mixed": [ + { + "pos": 0, + "name": "param", + "type": { + "name": "float" + }, + "required": true, + "unsupported": false + } + ], + "kw": [] + }, + "returns": { + "name": "int" + } + } + }, + { + "location": { + "from": "L9:28", + "to": "L9:31" + }, + "expr": { + "_type": "LiteralExpr", + "value": "..." + }, + "type": {} + }, + { + "location": { + "from": "L10:28", + "to": "L10:31" + }, + "expr": { + "_type": "LiteralExpr", + "value": "..." + }, + "type": {} + }, + { + "location": { + "from": "L13:4", + "to": "L13:6" + }, + "expr": { + "_type": "VariableExpr", + "name": "b1" + }, + "type": { + "params": { + "pos": [ + { + "pos": 0, + "name": "a", + "type": { + "name": "int" + }, + "required": true, + "unsupported": false + } + ], + "mixed": [], + "kw": [] + }, + "returns": { + "name": "float" + } + } + }, + { + "location": { + "from": "L14:4", + "to": "L14:6" + }, + "expr": { + "_type": "VariableExpr", + "name": "b2" + }, + "type": { + "params": { + "pos": [ + { + "pos": 0, + "name": "b", + "type": { + "name": "float" + }, + "required": true, + "unsupported": false + } + ], + "mixed": [], + "kw": [] + }, + "returns": { + "name": "int" + } + } + }, + { + "location": { + "from": "L17:24", + "to": "L17:27" + }, + "expr": { + "_type": "LiteralExpr", + "value": "..." + }, + "type": {} + }, + { + "location": { + "from": "L18:18", + "to": "L18:19" + }, + "expr": { + "_type": "LiteralExpr", + "value": 0 + }, + "type": { + "name": "int" + } + }, + { + "location": { + "from": "L18:38", + "to": "L18:39" + }, + "expr": { + "_type": "LiteralExpr", + "value": 0 + }, + "type": { + "name": "int" + } + }, + { + "location": { + "from": "L18:50", + "to": "L18:53" + }, + "expr": { + "_type": "LiteralExpr", + "value": "..." + }, + "type": {} + }, + { + "location": { + "from": "L21:4", + "to": "L21:6" + }, + "expr": { + "_type": "VariableExpr", + "name": "c1" + }, + "type": { + "params": { + "pos": [], + "mixed": [ + { + "pos": 0, + "name": "a", + "type": { + "name": "int" + }, + "required": true, + "unsupported": false + } + ], + "kw": [] + }, + "returns": {} + } + }, + { + "location": { + "from": "L22:4", + "to": "L22:6" + }, + "expr": { + "_type": "VariableExpr", + "name": "c2" + }, + "type": { + "params": { + "pos": [ + { + "pos": 0, + "name": "p", + "type": { + "name": "float" + }, + "required": false, + "unsupported": false + } + ], + "mixed": [], + "kw": [ + { + "pos": 1, + "name": "a", + "type": { + "name": "float" + }, + "required": false, + "unsupported": false + } + ] + }, + "returns": {} + } + }, + { + "location": { + "from": "L27:25", + "to": "L27:28" + }, + "expr": { + "_type": "LiteralExpr", + "value": "..." + }, + "type": {} + }, + { + "location": { + "from": "L28:25", + "to": "L28:28" + }, + "expr": { + "_type": "LiteralExpr", + "value": "..." + }, + "type": {} + }, + { + "location": { + "from": "L29:23", + "to": "L29:26" + }, + "expr": { + "_type": "LiteralExpr", + "value": "..." + }, + "type": {} + }, + { + "location": { + "from": "L32:4", + "to": "L32:6" + }, + "expr": { + "_type": "VariableExpr", + "name": "d1" + }, + "type": { + "params": { + "pos": [], + "mixed": [ + { + "pos": 0, + "name": "a", + "type": { + "name": "int" + }, + "required": true, + "unsupported": false + } + ], + "kw": [] + }, + "returns": { + "name": "float" + } + } + }, + { + "location": { + "from": "L33:4", + "to": "L33:6" + }, + "expr": { + "_type": "VariableExpr", + "name": "d2" + }, + "type": { + "params": { + "pos": [], + "mixed": [ + { + "pos": 0, + "name": "a", + "type": { + "name": "str" + }, + "required": true, + "unsupported": false + } + ], + "kw": [] + }, + "returns": { + "name": "float" + } + } + }, + { + "location": { + "from": "L34:4", + "to": "L34:6" + }, + "expr": { + "_type": "VariableExpr", + "name": "d3" + }, + "type": { + "params": { + "pos": [], + "mixed": [ + { + "pos": 0, + "name": "a", + "type": { + "name": "int" + }, + "required": true, + "unsupported": false + } + ], + "kw": [] + }, + "returns": { + "name": "str" + } + } + }, + { + "location": { + "from": "L37:19", + "to": "L37:20" + }, + "expr": { + "_type": "LiteralExpr", + "value": 0 + }, + "type": { + "name": "int" + } + }, + { + "location": { + "from": "L37:31", + "to": "L37:34" + }, + "expr": { + "_type": "LiteralExpr", + "value": "..." + }, + "type": {} + }, + { + "location": { + "from": "L38:27", + "to": "L38:30" + }, + "expr": { + "_type": "LiteralExpr", + "value": "..." + }, + "type": {} + }, + { + "location": { + "from": "L39:19", + "to": "L39:20" + }, + "expr": { + "_type": "LiteralExpr", + "value": 0 + }, + "type": { + "name": "int" + } + }, + { + "location": { + "from": "L39:39", + "to": "L39:42" + }, + "expr": { + "_type": "LiteralExpr", + "value": "..." + }, + "type": {} + }, + { + "location": { + "from": "L42:4", + "to": "L42:6" + }, + "expr": { + "_type": "VariableExpr", + "name": "e1" + }, + "type": { + "params": { + "pos": [], + "mixed": [], + "kw": [ + { + "pos": 0, + "name": "a", + "type": { + "name": "int" + }, + "required": false, + "unsupported": false + } + ] + }, + "returns": {} + } + }, + { + "location": { + "from": "L43:4", + "to": "L43:6" + }, + "expr": { + "_type": "VariableExpr", + "name": "e2" + }, + "type": { + "params": { + "pos": [], + "mixed": [], + "kw": [ + { + "pos": 0, + "name": "a", + "type": { + "name": "int" + }, + "required": true, + "unsupported": false + } + ] + }, + "returns": {} + } + }, + { + "location": { + "from": "L44:4", + "to": "L44:6" + }, + "expr": { + "_type": "VariableExpr", + "name": "e3" + }, + "type": { + "params": { + "pos": [], + "mixed": [], + "kw": [ + { + "pos": 0, + "name": "a", + "type": { + "name": "int" + }, + "required": false, + "unsupported": false + }, + { + "pos": 1, + "name": "b", + "type": { + "name": "int" + }, + "required": true, + "unsupported": false + } + ] + }, + "returns": {} + } + } + ] +} \ No newline at end of file diff --git a/tests/cases/generator/03_simple_syntax.py b/tests/cases/generator/03_simple_syntax.py new file mode 100644 index 0000000..9bf70f5 --- /dev/null +++ b/tests/cases/generator/03_simple_syntax.py @@ -0,0 +1,49 @@ +# type: ignore +# ruff: disable[F821] + +import module1 +import module2 as alias2 +from module3 import submodule3 +from module4 import submodule4 as alias4 + +a: int +b: Generic[int] +c: Generic2[int, float] +d: Frame[a:int, b:float] + +e = 3 +f: int = 4 +g = [] +h = [1, 0.1, " ", None, False, True] +i = {} +j = {"a": 1, "b": 2} +k = {"c": 3, **j} +l = cast(int, a) +m = unsafe_cast(int, a) + + +def n(a: int, /, b: float, *, c: str) -> Any: + return + + +def o(a: int = 1, /, b: float = 2.0, *, c: str = "") -> Any: + return 1 + + +for i in h: + pass + +if e == f: + pass +elif f == g: + pass +else: + pass + +p = +a + -b - ~c * d / e**f +q = not (a and b) or c +r = a & b | c ^ d + +s = a.b.c +t = a[b][c, d][e:f] +u = a(b)(c=d) diff --git a/tests/cases/generator/03_simple_syntax.py.ref.txt b/tests/cases/generator/03_simple_syntax.py.ref.txt new file mode 100644 index 0000000..4c67e28 --- /dev/null +++ b/tests/cases/generator/03_simple_syntax.py.ref.txt @@ -0,0 +1,249 @@ +Module( + body=[ + Import( + names=[ + alias(name='module1')]), + Import( + names=[ + alias(name='module2', asname='alias2')]), + ImportFrom( + module='module3', + names=[ + alias(name='submodule3')], + level=0), + ImportFrom( + module='module4', + names=[ + alias(name='submodule4', asname='alias4')], + level=0), + Assign( + targets=[ + Name(id='e')], + value=Constant(value=3)), + Assign( + targets=[ + Name(id='f')], + value=Constant(value=4)), + Assign( + targets=[ + Name(id='g')], + value=List(elts=[])), + Assign( + targets=[ + Name(id='h')], + value=List( + elts=[ + Constant(value=1), + Constant(value=0.1), + Constant(value=' '), + Constant(value=None), + Constant(value=False), + Constant(value=True)])), + Assign( + targets=[ + Name(id='i')], + value=Dict(keys=[], values=[])), + Assign( + targets=[ + Name(id='j')], + value=Dict( + keys=[ + Constant(value='a'), + Constant(value='b')], + values=[ + Constant(value=1), + Constant(value=2)])), + Assign( + targets=[ + Name(id='k')], + value=Dict( + keys=[ + Constant(value='c'), + None], + values=[ + Constant(value=3), + Name(id='j')])), + Assign( + targets=[ + Name(id='__midas_a0__')], + value=Name(id='a')), + Assert( + test=Call( + func=Name(id='isinstance'), + args=[ + Name(id='__midas_a0__'), + Name(id='int')], + keywords=[]), + msg=JoinedStr( + values=[ + Constant(value='03_simple_syntax.py:L21:5: CastError: Cannot cast '), + FormattedValue( + value=Attribute( + value=Call( + func=Name(id='type'), + args=[ + Name(id='__midas_a0__')], + keywords=[]), + attr='__name__'), + conversion=-1), + Constant(value=' to int')])), + Assign( + targets=[ + Name(id='l')], + value=Name(id='__midas_a0__')), + Delete( + targets=[ + Name(id='__midas_a0__')]), + Assign( + targets=[ + Name(id='m')], + value=Name(id='a')), + FunctionDef( + name='n', + args=arguments( + posonlyargs=[ + arg(arg='a')], + args=[ + arg(arg='b')], + kwonlyargs=[ + arg(arg='c')], + kw_defaults=[ + None], + defaults=[]), + body=[ + Return()], + decorator_list=[]), + FunctionDef( + name='o', + args=arguments( + posonlyargs=[ + arg(arg='a')], + args=[ + arg(arg='b')], + kwonlyargs=[ + arg(arg='c')], + kw_defaults=[ + Constant(value='')], + defaults=[ + Constant(value=1), + Constant(value=2.0)]), + body=[ + Return( + value=Constant(value=1))], + decorator_list=[]), + For( + target=Name(id='i'), + iter=Name(id='h'), + body=[ + Pass()], + orelse=[]), + If( + test=Compare( + left=Name(id='e'), + ops=[ + Eq()], + comparators=[ + Name(id='f')]), + body=[ + Pass()], + orelse=[ + If( + test=Compare( + left=Name(id='f'), + ops=[ + Eq()], + comparators=[ + Name(id='g')]), + body=[ + Pass()], + orelse=[])]), + Assign( + targets=[ + Name(id='p')], + value=BinOp( + left=BinOp( + left=UnaryOp( + op=UAdd(), + operand=Name(id='a')), + op=Add(), + right=UnaryOp( + op=USub(), + operand=Name(id='b'))), + op=Sub(), + right=BinOp( + left=BinOp( + left=UnaryOp( + op=Invert(), + operand=Name(id='c')), + op=Mult(), + right=Name(id='d')), + op=Div(), + right=BinOp( + left=Name(id='e'), + op=Pow(), + right=Name(id='f'))))), + Assign( + targets=[ + Name(id='q')], + value=BoolOp( + op=Or(), + values=[ + UnaryOp( + op=Not(), + operand=BoolOp( + op=And(), + values=[ + Name(id='a'), + Name(id='b')])), + Name(id='c')])), + Assign( + targets=[ + Name(id='r')], + value=BinOp( + left=BinOp( + left=Name(id='a'), + op=BitAnd(), + right=Name(id='b')), + op=BitOr(), + right=BinOp( + left=Name(id='c'), + op=BitXor(), + right=Name(id='d')))), + Assign( + targets=[ + Name(id='s')], + value=Attribute( + value=Attribute( + value=Name(id='a'), + attr='b'), + attr='c')), + Assign( + targets=[ + Name(id='t')], + value=Subscript( + value=Subscript( + value=Subscript( + value=Name(id='a'), + slice=Name(id='b')), + slice=Tuple( + elts=[ + Name(id='c'), + Name(id='d')])), + slice=Slice( + lower=Name(id='e'), + upper=Name(id='f')))), + Assign( + targets=[ + Name(id='u')], + value=Call( + func=Call( + func=Name(id='a'), + args=[ + Name(id='b')], + keywords=[]), + args=[], + keywords=[ + keyword( + arg='c', + value=Name(id='d'))]))], + type_ignores=[]) \ No newline at end of file diff --git a/tests/cases/generator/04_frames.midas b/tests/cases/generator/04_frames.midas new file mode 100644 index 0000000..09b4ae4 --- /dev/null +++ b/tests/cases/generator/04_frames.midas @@ -0,0 +1,15 @@ +predicate is_positive(v: float) = v >= 0 +type Positive = float where is_positive(_) + +alias T1 = Frame[ + a: int +] + +alias T2 = Frame[ + a: int, + b: str, + c: Positive, + d: float where is_positive(_) +] + +alias Positives = Column[Positive] \ No newline at end of file diff --git a/tests/cases/generator/04_frames.py b/tests/cases/generator/04_frames.py new file mode 100644 index 0000000..a4f7f83 --- /dev/null +++ b/tests/cases/generator/04_frames.py @@ -0,0 +1,13 @@ +from typing import Any + +from midas import T1, T2, Column, Positive, Positives, cast + +o: Any = object() + +df1 = cast(T1, o) +df2 = cast(T2, o) + +df1 + df2 + +col1: Positives = df2["c"] +col2 = cast(Column[Positive], col1) diff --git a/tests/cases/generator/04_frames.py.ref.txt b/tests/cases/generator/04_frames.py.ref.txt new file mode 100644 index 0000000..4b37201 --- /dev/null +++ b/tests/cases/generator/04_frames.py.ref.txt @@ -0,0 +1,731 @@ +Module( + body=[ + FunctionDef( + name='__midas_column_same_length__', + args=arguments( + posonlyargs=[], + args=[ + arg(arg='column1'), + arg(arg='column2')], + kwonlyargs=[], + kw_defaults=[], + defaults=[]), + body=[ + Return( + value=Compare( + left=Call( + func=Name(id='len'), + args=[ + Attribute( + value=Name(id='column1'), + attr='index')], + keywords=[]), + ops=[ + Eq()], + comparators=[ + Call( + func=Name(id='len'), + args=[ + Attribute( + value=Name(id='column2'), + attr='index')], + keywords=[])]))], + decorator_list=[]), + FunctionDef( + name='__midas_frame_same_length__', + args=arguments( + posonlyargs=[], + args=[ + arg(arg='frame1'), + arg(arg='frame2')], + kwonlyargs=[], + kw_defaults=[], + defaults=[]), + body=[ + Return( + value=Compare( + left=Call( + func=Name(id='len'), + args=[ + Attribute( + value=Name(id='frame1'), + attr='index')], + keywords=[]), + ops=[ + Eq()], + comparators=[ + Call( + func=Name(id='len'), + args=[ + Attribute( + value=Name(id='frame2'), + attr='index')], + keywords=[])]))], + decorator_list=[]), + FunctionDef( + name='__midas_is_column__', + args=arguments( + posonlyargs=[ + arg(arg='obj')], + args=[], + kwonlyargs=[], + kw_defaults=[], + defaults=[]), + body=[ + Import( + names=[ + alias(name='pandas', asname='pd')]), + Return( + value=Call( + func=Name(id='isinstance'), + args=[ + Name(id='obj'), + Attribute( + value=Name(id='pd'), + attr='Series')], + keywords=[]))], + decorator_list=[], + returns=Name(id='bool')), + FunctionDef( + name='__midas_is_dataframe__', + args=arguments( + posonlyargs=[ + arg(arg='obj')], + args=[], + kwonlyargs=[], + kw_defaults=[], + defaults=[]), + body=[ + Import( + names=[ + alias(name='pandas', asname='pd')]), + Return( + value=Call( + func=Name(id='isinstance'), + args=[ + Name(id='obj'), + Attribute( + value=Name(id='pd'), + attr='DataFrame')], + keywords=[]))], + decorator_list=[], + returns=Name(id='bool')), + FunctionDef( + name='__midas_is_positive__', + args=arguments( + posonlyargs=[], + args=[ + arg( + arg='v', + annotation=Constant(value='float'))], + kwonlyargs=[], + kw_defaults=[], + defaults=[]), + body=[ + Return( + value=Compare( + left=Name(id='v'), + ops=[ + GtE()], + comparators=[ + Constant(value=0)]))], + decorator_list=[], + returns=Constant(value='bool')), + FunctionDef( + name='__midas_p0__', + args=arguments( + posonlyargs=[], + args=[ + arg( + arg='_', + annotation=Constant(value='Any'))], + kwonlyargs=[], + kw_defaults=[], + defaults=[]), + body=[ + Return( + value=Call( + func=Name(id='__midas_is_positive__'), + args=[ + Name(id='_')], + keywords=[]))], + decorator_list=[], + returns=Constant(value='bool')), + FunctionDef( + name='__midas_p1__', + args=arguments( + posonlyargs=[], + args=[ + arg( + arg='_', + annotation=Constant(value='Any'))], + kwonlyargs=[], + kw_defaults=[], + defaults=[]), + body=[ + Return( + value=Call( + func=Name(id='__midas_is_positive__'), + args=[ + Name(id='_')], + keywords=[]))], + decorator_list=[], + returns=Constant(value='bool')), + ImportFrom( + module='typing', + names=[ + alias(name='Any')], + level=0), + ImportFrom( + module='midas', + names=[ + alias(name='T1'), + alias(name='T2'), + alias(name='Column'), + alias(name='Positive'), + alias(name='Positives'), + alias(name='cast')], + level=0), + Assign( + targets=[ + Name(id='o')], + value=Call( + func=Name(id='object'), + args=[], + keywords=[])), + Assign( + targets=[ + Name(id='__midas_a0__')], + value=Name(id='o')), + Assert( + test=Call( + func=Name(id='__midas_is_dataframe__'), + args=[ + Name(id='__midas_a0__')], + keywords=[]), + msg=JoinedStr( + values=[ + Constant(value='04_frames.py:L7:7: CastError: Cannot cast '), + FormattedValue( + value=Attribute( + value=Call( + func=Name(id='type'), + args=[ + Name(id='__midas_a0__')], + keywords=[]), + attr='__name__'), + conversion=-1), + Constant(value=' to Frame[a: Column[int]]: Not a dataframe')])), + Assert( + test=Compare( + left=Constant(value='a'), + ops=[ + In()], + comparators=[ + Name(id='__midas_a0__')]), + msg=JoinedStr( + values=[ + Constant(value='04_frames.py:L7:7: CastError: Cannot cast '), + FormattedValue( + value=Attribute( + value=Call( + func=Name(id='type'), + args=[ + Name(id='__midas_a0__')], + keywords=[]), + attr='__name__'), + conversion=-1), + Constant(value=" to Frame[a: Column[int]]: Missing column 'a'")])), + Assert( + test=Call( + func=Name(id='__midas_is_column__'), + args=[ + Subscript( + value=Name(id='__midas_a0__'), + slice=Constant(value='a'))], + keywords=[]), + msg=JoinedStr( + values=[ + Constant(value='04_frames.py:L7:7: CastError: Cannot cast '), + FormattedValue( + value=Attribute( + value=Call( + func=Name(id='type'), + args=[ + Subscript( + value=Name(id='__midas_a0__'), + slice=Constant(value='a'))], + keywords=[]), + attr='__name__'), + conversion=-1), + Constant(value=" to Column[int], in column 'a': Not a column")])), + For( + target=Name(id='value'), + iter=Subscript( + value=Name(id='__midas_a0__'), + slice=Constant(value='a')), + body=[ + Assert( + test=Call( + func=Name(id='isinstance'), + args=[ + Name(id='value'), + Name(id='int')], + keywords=[]), + msg=JoinedStr( + values=[ + Constant(value='04_frames.py:L7:7: CastError: Cannot cast '), + FormattedValue( + value=Attribute( + value=Call( + func=Name(id='type'), + args=[ + Name(id='value')], + keywords=[]), + attr='__name__'), + conversion=-1), + Constant(value=" to int, in column 'a'")]))], + orelse=[]), + Assign( + targets=[ + Name(id='df1')], + value=Name(id='__midas_a0__')), + Delete( + targets=[ + Name(id='__midas_a0__')]), + Assign( + targets=[ + Name(id='__midas_a1__')], + value=Name(id='o')), + Assert( + test=Call( + func=Name(id='__midas_is_dataframe__'), + args=[ + Name(id='__midas_a1__')], + keywords=[]), + msg=JoinedStr( + values=[ + Constant(value='04_frames.py:L8:7: CastError: Cannot cast '), + FormattedValue( + value=Attribute( + value=Call( + func=Name(id='type'), + args=[ + Name(id='__midas_a1__')], + keywords=[]), + attr='__name__'), + conversion=-1), + Constant(value=' to Frame[a: Column[int], b: Column[str], c: Column[Positive], d: Column[float where is_positive(_)]]: Not a dataframe')])), + Assert( + test=Compare( + left=Constant(value='a'), + ops=[ + In()], + comparators=[ + Name(id='__midas_a1__')]), + msg=JoinedStr( + values=[ + Constant(value='04_frames.py:L8:7: CastError: Cannot cast '), + FormattedValue( + value=Attribute( + value=Call( + func=Name(id='type'), + args=[ + Name(id='__midas_a1__')], + keywords=[]), + attr='__name__'), + conversion=-1), + Constant(value=" to Frame[a: Column[int], b: Column[str], c: Column[Positive], d: Column[float where is_positive(_)]]: Missing column 'a'")])), + Assert( + test=Call( + func=Name(id='__midas_is_column__'), + args=[ + Subscript( + value=Name(id='__midas_a1__'), + slice=Constant(value='a'))], + keywords=[]), + msg=JoinedStr( + values=[ + Constant(value='04_frames.py:L8:7: CastError: Cannot cast '), + FormattedValue( + value=Attribute( + value=Call( + func=Name(id='type'), + args=[ + Subscript( + value=Name(id='__midas_a1__'), + slice=Constant(value='a'))], + keywords=[]), + attr='__name__'), + conversion=-1), + Constant(value=" to Column[int], in column 'a': Not a column")])), + For( + target=Name(id='value'), + iter=Subscript( + value=Name(id='__midas_a1__'), + slice=Constant(value='a')), + body=[ + Assert( + test=Call( + func=Name(id='isinstance'), + args=[ + Name(id='value'), + Name(id='int')], + keywords=[]), + msg=JoinedStr( + values=[ + Constant(value='04_frames.py:L8:7: CastError: Cannot cast '), + FormattedValue( + value=Attribute( + value=Call( + func=Name(id='type'), + args=[ + Name(id='value')], + keywords=[]), + attr='__name__'), + conversion=-1), + Constant(value=" to int, in column 'a'")]))], + orelse=[]), + Assert( + test=Compare( + left=Constant(value='b'), + ops=[ + In()], + comparators=[ + Name(id='__midas_a1__')]), + msg=JoinedStr( + values=[ + Constant(value='04_frames.py:L8:7: CastError: Cannot cast '), + FormattedValue( + value=Attribute( + value=Call( + func=Name(id='type'), + args=[ + Name(id='__midas_a1__')], + keywords=[]), + attr='__name__'), + conversion=-1), + Constant(value=" to Frame[a: Column[int], b: Column[str], c: Column[Positive], d: Column[float where is_positive(_)]]: Missing column 'b'")])), + Assert( + test=Call( + func=Name(id='__midas_is_column__'), + args=[ + Subscript( + value=Name(id='__midas_a1__'), + slice=Constant(value='b'))], + keywords=[]), + msg=JoinedStr( + values=[ + Constant(value='04_frames.py:L8:7: CastError: Cannot cast '), + FormattedValue( + value=Attribute( + value=Call( + func=Name(id='type'), + args=[ + Subscript( + value=Name(id='__midas_a1__'), + slice=Constant(value='b'))], + keywords=[]), + attr='__name__'), + conversion=-1), + Constant(value=" to Column[str], in column 'b': Not a column")])), + For( + target=Name(id='value'), + iter=Subscript( + value=Name(id='__midas_a1__'), + slice=Constant(value='b')), + body=[ + Assert( + test=Call( + func=Name(id='isinstance'), + args=[ + Name(id='value'), + Name(id='str')], + keywords=[]), + msg=JoinedStr( + values=[ + Constant(value='04_frames.py:L8:7: CastError: Cannot cast '), + FormattedValue( + value=Attribute( + value=Call( + func=Name(id='type'), + args=[ + Name(id='value')], + keywords=[]), + attr='__name__'), + conversion=-1), + Constant(value=" to str, in column 'b'")]))], + orelse=[]), + Assert( + test=Compare( + left=Constant(value='c'), + ops=[ + In()], + comparators=[ + Name(id='__midas_a1__')]), + msg=JoinedStr( + values=[ + Constant(value='04_frames.py:L8:7: CastError: Cannot cast '), + FormattedValue( + value=Attribute( + value=Call( + func=Name(id='type'), + args=[ + Name(id='__midas_a1__')], + keywords=[]), + attr='__name__'), + conversion=-1), + Constant(value=" to Frame[a: Column[int], b: Column[str], c: Column[Positive], d: Column[float where is_positive(_)]]: Missing column 'c'")])), + Assert( + test=Call( + func=Name(id='__midas_is_column__'), + args=[ + Subscript( + value=Name(id='__midas_a1__'), + slice=Constant(value='c'))], + keywords=[]), + msg=JoinedStr( + values=[ + Constant(value='04_frames.py:L8:7: CastError: Cannot cast '), + FormattedValue( + value=Attribute( + value=Call( + func=Name(id='type'), + args=[ + Subscript( + value=Name(id='__midas_a1__'), + slice=Constant(value='c'))], + keywords=[]), + attr='__name__'), + conversion=-1), + Constant(value=" to Column[Positive], in column 'c': Not a column")])), + For( + target=Name(id='value'), + iter=Subscript( + value=Name(id='__midas_a1__'), + slice=Constant(value='c')), + body=[ + Assert( + test=Call( + func=Name(id='isinstance'), + args=[ + Name(id='value'), + Name(id='float')], + keywords=[]), + msg=JoinedStr( + values=[ + Constant(value='04_frames.py:L8:7: CastError: Cannot cast '), + FormattedValue( + value=Attribute( + value=Call( + func=Name(id='type'), + args=[ + Name(id='value')], + keywords=[]), + attr='__name__'), + conversion=-1), + Constant(value=" to float, in column 'c'")])), + Assert( + test=Call( + func=Name(id='__midas_p0__'), + args=[ + Name(id='value')], + keywords=[]), + msg=Constant(value="04_frames.py:L8:7: ConstraintError: Value does not fit constraint 'is_positive(_)', in column 'c'"))], + orelse=[]), + Assert( + test=Compare( + left=Constant(value='d'), + ops=[ + In()], + comparators=[ + Name(id='__midas_a1__')]), + msg=JoinedStr( + values=[ + Constant(value='04_frames.py:L8:7: CastError: Cannot cast '), + FormattedValue( + value=Attribute( + value=Call( + func=Name(id='type'), + args=[ + Name(id='__midas_a1__')], + keywords=[]), + attr='__name__'), + conversion=-1), + Constant(value=" to Frame[a: Column[int], b: Column[str], c: Column[Positive], d: Column[float where is_positive(_)]]: Missing column 'd'")])), + Assert( + test=Call( + func=Name(id='__midas_is_column__'), + args=[ + Subscript( + value=Name(id='__midas_a1__'), + slice=Constant(value='d'))], + keywords=[]), + msg=JoinedStr( + values=[ + Constant(value='04_frames.py:L8:7: CastError: Cannot cast '), + FormattedValue( + value=Attribute( + value=Call( + func=Name(id='type'), + args=[ + Subscript( + value=Name(id='__midas_a1__'), + slice=Constant(value='d'))], + keywords=[]), + attr='__name__'), + conversion=-1), + Constant(value=" to Column[float where is_positive(_)], in column 'd': Not a column")])), + For( + target=Name(id='value'), + iter=Subscript( + value=Name(id='__midas_a1__'), + slice=Constant(value='d')), + body=[ + Assert( + test=Call( + func=Name(id='isinstance'), + args=[ + Name(id='value'), + Name(id='float')], + keywords=[]), + msg=JoinedStr( + values=[ + Constant(value='04_frames.py:L8:7: CastError: Cannot cast '), + FormattedValue( + value=Attribute( + value=Call( + func=Name(id='type'), + args=[ + Name(id='value')], + keywords=[]), + attr='__name__'), + conversion=-1), + Constant(value=" to float, in column 'd'")])), + Assert( + test=Call( + func=Name(id='__midas_p1__'), + args=[ + Name(id='value')], + keywords=[]), + msg=Constant(value="04_frames.py:L8:7: ConstraintError: Value does not fit constraint 'is_positive(_)', in column 'd'"))], + orelse=[]), + Assign( + targets=[ + Name(id='df2')], + value=Name(id='__midas_a1__')), + Delete( + targets=[ + Name(id='__midas_a1__')]), + Assign( + targets=[ + Name(id='__midas_a2__')], + value=Name(id='df1')), + Assign( + targets=[ + Name(id='__midas_a3__')], + value=Name(id='df2')), + Assert( + test=Call( + func=Name(id='__midas_column_same_length__'), + args=[ + Name(id='__midas_a2__'), + Name(id='__midas_a3__')], + keywords=[]), + msg=Constant(value='04_frames.py:L10:1: AssertionError: Columns must have the same length')), + Assign( + targets=[ + Name(id='__midas_a4__')], + value=Name(id='__midas_a2__')), + Assign( + targets=[ + Name(id='__midas_a5__')], + value=Name(id='__midas_a3__')), + Assert( + test=Call( + func=Name(id='__midas_frame_same_length__'), + args=[ + Name(id='__midas_a4__'), + Name(id='__midas_a5__')], + keywords=[]), + msg=Constant(value='04_frames.py:L10:1: AssertionError: DataFrames must have the same length')), + Expr( + value=BinOp( + left=Name(id='__midas_a2__'), + op=Add(), + right=Name(id='__midas_a3__'))), + Delete( + targets=[ + Name(id='__midas_a2__'), + Name(id='__midas_a3__'), + Name(id='__midas_a4__'), + Name(id='__midas_a5__')]), + Assign( + targets=[ + Name(id='col1')], + value=Subscript( + value=Name(id='df2'), + slice=Constant(value='c'))), + Assign( + targets=[ + Name(id='__midas_a6__')], + value=Name(id='col1')), + Assert( + test=Call( + func=Name(id='__midas_is_column__'), + args=[ + Name(id='__midas_a6__')], + keywords=[]), + msg=JoinedStr( + values=[ + Constant(value='04_frames.py:L13:8: CastError: Cannot cast '), + FormattedValue( + value=Attribute( + value=Call( + func=Name(id='type'), + args=[ + Name(id='__midas_a6__')], + keywords=[]), + attr='__name__'), + conversion=-1), + Constant(value=' to Column[Positive]: Not a column')])), + For( + target=Name(id='value'), + iter=Name(id='__midas_a6__'), + body=[ + Assert( + test=Call( + func=Name(id='isinstance'), + args=[ + Name(id='value'), + Name(id='float')], + keywords=[]), + msg=JoinedStr( + values=[ + Constant(value='04_frames.py:L13:8: CastError: Cannot cast '), + FormattedValue( + value=Attribute( + value=Call( + func=Name(id='type'), + args=[ + Name(id='value')], + keywords=[]), + attr='__name__'), + conversion=-1), + Constant(value=' to float')])), + Assert( + test=Call( + func=Name(id='__midas_p0__'), + args=[ + Name(id='value')], + keywords=[]), + msg=Constant(value="04_frames.py:L13:8: ConstraintError: Value does not fit constraint 'is_positive(_)'"))], + orelse=[]), + Assign( + targets=[ + Name(id='col2')], + value=Name(id='__midas_a6__')), + Delete( + targets=[ + Name(id='__midas_a6__')])], + type_ignores=[]) \ No newline at end of file diff --git a/tests/cases/midas-parser/02_all_syntax.midas b/tests/cases/midas-parser/02_all_syntax.midas new file mode 100644 index 0000000..4127813 --- /dev/null +++ b/tests/cases/midas-parser/02_all_syntax.midas @@ -0,0 +1,35 @@ +// Alias declaration +alias A = object + +// Type declaration +type B = object + +// Generic declaration +type C[T] = object +type D[T <: A] = object +type E[T, U] = object + +// Type expressions +type F[T] = T +type G = A where predicate(_) +type H = A where _ > 0 & _.attr < 1.0 & +_ + 4.0 >= "string" & !(-_ - 4.0 <= 0 & _ == none & _ != false) +type I = fn() -> Any +type J = fn(a: int, /, b: float, *, c: bool) -> Any +type K = fn(a: int, /, b: float, *, c: bool?) -> Any +type L = fn(a: int, /, b: float?, *, c: bool?) -> Any +type M = fn(a: int?, /, b: float?, *, c: bool?) -> Any + +// Extend +extend N {} +extend O { + prop a: int + def b: fn(int, /) -> int + def b: fn(float, /) -> float +} + +// Predicate +predicate P = true +predicate Q(v: float) = v > 0 +predicate R(a: float, b: float)(v: float) = a < v & v < b +predicate S = R(0.0, 1.0) +predicate T = R(a=0.0, b=1.0) \ No newline at end of file diff --git a/tests/cases/midas-parser/02_all_syntax.midas.ref.json b/tests/cases/midas-parser/02_all_syntax.midas.ref.json new file mode 100644 index 0000000..e06c477 --- /dev/null +++ b/tests/cases/midas-parser/02_all_syntax.midas.ref.json @@ -0,0 +1,3620 @@ +{ + "tokens": [ + { + "type": "COMMENT", + "lexeme": "// Alias declaration", + "line": 1, + "column": 1 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 1, + "column": 21 + }, + { + "type": "ALIAS", + "lexeme": "alias", + "line": 2, + "column": 1 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 2, + "column": 6 + }, + { + "type": "IDENTIFIER", + "lexeme": "A", + "line": 2, + "column": 7 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 2, + "column": 8 + }, + { + "type": "EQUAL", + "lexeme": "=", + "line": 2, + "column": 9 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 2, + "column": 10 + }, + { + "type": "IDENTIFIER", + "lexeme": "object", + "line": 2, + "column": 11 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 2, + "column": 17 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 3, + "column": 1 + }, + { + "type": "COMMENT", + "lexeme": "// Type declaration", + "line": 4, + "column": 1 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 4, + "column": 20 + }, + { + "type": "TYPE", + "lexeme": "type", + "line": 5, + "column": 1 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 5, + "column": 5 + }, + { + "type": "IDENTIFIER", + "lexeme": "B", + "line": 5, + "column": 6 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 5, + "column": 7 + }, + { + "type": "EQUAL", + "lexeme": "=", + "line": 5, + "column": 8 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 5, + "column": 9 + }, + { + "type": "IDENTIFIER", + "lexeme": "object", + "line": 5, + "column": 10 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 5, + "column": 16 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 6, + "column": 1 + }, + { + "type": "COMMENT", + "lexeme": "// Generic declaration", + "line": 7, + "column": 1 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 7, + "column": 23 + }, + { + "type": "TYPE", + "lexeme": "type", + "line": 8, + "column": 1 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 8, + "column": 5 + }, + { + "type": "IDENTIFIER", + "lexeme": "C", + "line": 8, + "column": 6 + }, + { + "type": "LEFT_BRACKET", + "lexeme": "[", + "line": 8, + "column": 7 + }, + { + "type": "IDENTIFIER", + "lexeme": "T", + "line": 8, + "column": 8 + }, + { + "type": "RIGHT_BRACKET", + "lexeme": "]", + "line": 8, + "column": 9 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 8, + "column": 10 + }, + { + "type": "EQUAL", + "lexeme": "=", + "line": 8, + "column": 11 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 8, + "column": 12 + }, + { + "type": "IDENTIFIER", + "lexeme": "object", + "line": 8, + "column": 13 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 8, + "column": 19 + }, + { + "type": "TYPE", + "lexeme": "type", + "line": 9, + "column": 1 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 9, + "column": 5 + }, + { + "type": "IDENTIFIER", + "lexeme": "D", + "line": 9, + "column": 6 + }, + { + "type": "LEFT_BRACKET", + "lexeme": "[", + "line": 9, + "column": 7 + }, + { + "type": "IDENTIFIER", + "lexeme": "T", + "line": 9, + "column": 8 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 9, + "column": 9 + }, + { + "type": "LESS", + "lexeme": "<", + "line": 9, + "column": 10 + }, + { + "type": "COLON", + "lexeme": ":", + "line": 9, + "column": 11 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 9, + "column": 12 + }, + { + "type": "IDENTIFIER", + "lexeme": "A", + "line": 9, + "column": 13 + }, + { + "type": "RIGHT_BRACKET", + "lexeme": "]", + "line": 9, + "column": 14 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 9, + "column": 15 + }, + { + "type": "EQUAL", + "lexeme": "=", + "line": 9, + "column": 16 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 9, + "column": 17 + }, + { + "type": "IDENTIFIER", + "lexeme": "object", + "line": 9, + "column": 18 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 9, + "column": 24 + }, + { + "type": "TYPE", + "lexeme": "type", + "line": 10, + "column": 1 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 10, + "column": 5 + }, + { + "type": "IDENTIFIER", + "lexeme": "E", + "line": 10, + "column": 6 + }, + { + "type": "LEFT_BRACKET", + "lexeme": "[", + "line": 10, + "column": 7 + }, + { + "type": "IDENTIFIER", + "lexeme": "T", + "line": 10, + "column": 8 + }, + { + "type": "COMMA", + "lexeme": ",", + "line": 10, + "column": 9 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 10, + "column": 10 + }, + { + "type": "IDENTIFIER", + "lexeme": "U", + "line": 10, + "column": 11 + }, + { + "type": "RIGHT_BRACKET", + "lexeme": "]", + "line": 10, + "column": 12 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 10, + "column": 13 + }, + { + "type": "EQUAL", + "lexeme": "=", + "line": 10, + "column": 14 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 10, + "column": 15 + }, + { + "type": "IDENTIFIER", + "lexeme": "object", + "line": 10, + "column": 16 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 10, + "column": 22 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 11, + "column": 1 + }, + { + "type": "COMMENT", + "lexeme": "// Type expressions", + "line": 12, + "column": 1 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 12, + "column": 20 + }, + { + "type": "TYPE", + "lexeme": "type", + "line": 13, + "column": 1 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 13, + "column": 5 + }, + { + "type": "IDENTIFIER", + "lexeme": "F", + "line": 13, + "column": 6 + }, + { + "type": "LEFT_BRACKET", + "lexeme": "[", + "line": 13, + "column": 7 + }, + { + "type": "IDENTIFIER", + "lexeme": "T", + "line": 13, + "column": 8 + }, + { + "type": "RIGHT_BRACKET", + "lexeme": "]", + "line": 13, + "column": 9 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 13, + "column": 10 + }, + { + "type": "EQUAL", + "lexeme": "=", + "line": 13, + "column": 11 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 13, + "column": 12 + }, + { + "type": "IDENTIFIER", + "lexeme": "T", + "line": 13, + "column": 13 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 13, + "column": 14 + }, + { + "type": "TYPE", + "lexeme": "type", + "line": 14, + "column": 1 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 14, + "column": 5 + }, + { + "type": "IDENTIFIER", + "lexeme": "G", + "line": 14, + "column": 6 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 14, + "column": 7 + }, + { + "type": "EQUAL", + "lexeme": "=", + "line": 14, + "column": 8 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 14, + "column": 9 + }, + { + "type": "IDENTIFIER", + "lexeme": "A", + "line": 14, + "column": 10 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 14, + "column": 11 + }, + { + "type": "WHERE", + "lexeme": "where", + "line": 14, + "column": 12 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 14, + "column": 17 + }, + { + "type": "PREDICATE", + "lexeme": "predicate", + "line": 14, + "column": 18 + }, + { + "type": "LEFT_PAREN", + "lexeme": "(", + "line": 14, + "column": 27 + }, + { + "type": "UNDERSCORE", + "lexeme": "_", + "line": 14, + "column": 28 + }, + { + "type": "RIGHT_PAREN", + "lexeme": ")", + "line": 14, + "column": 29 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 14, + "column": 30 + }, + { + "type": "TYPE", + "lexeme": "type", + "line": 15, + "column": 1 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 5 + }, + { + "type": "IDENTIFIER", + "lexeme": "H", + "line": 15, + "column": 6 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 7 + }, + { + "type": "EQUAL", + "lexeme": "=", + "line": 15, + "column": 8 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 9 + }, + { + "type": "IDENTIFIER", + "lexeme": "A", + "line": 15, + "column": 10 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 11 + }, + { + "type": "WHERE", + "lexeme": "where", + "line": 15, + "column": 12 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 17 + }, + { + "type": "UNDERSCORE", + "lexeme": "_", + "line": 15, + "column": 18 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 19 + }, + { + "type": "GREATER", + "lexeme": ">", + "line": 15, + "column": 20 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 21 + }, + { + "type": "NUMBER", + "lexeme": "0", + "line": 15, + "column": 22 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 23 + }, + { + "type": "AND", + "lexeme": "&", + "line": 15, + "column": 24 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 25 + }, + { + "type": "IDENTIFIER", + "lexeme": "_", + "line": 15, + "column": 26 + }, + { + "type": "DOT", + "lexeme": ".", + "line": 15, + "column": 27 + }, + { + "type": "IDENTIFIER", + "lexeme": "attr", + "line": 15, + "column": 28 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 32 + }, + { + "type": "LESS", + "lexeme": "<", + "line": 15, + "column": 33 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 34 + }, + { + "type": "NUMBER", + "lexeme": "1.0", + "line": 15, + "column": 35 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 38 + }, + { + "type": "AND", + "lexeme": "&", + "line": 15, + "column": 39 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 40 + }, + { + "type": "PLUS", + "lexeme": "+", + "line": 15, + "column": 41 + }, + { + "type": "UNDERSCORE", + "lexeme": "_", + "line": 15, + "column": 42 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 43 + }, + { + "type": "PLUS", + "lexeme": "+", + "line": 15, + "column": 44 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 45 + }, + { + "type": "NUMBER", + "lexeme": "4.0", + "line": 15, + "column": 46 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 49 + }, + { + "type": "GREATER_EQUAL", + "lexeme": ">=", + "line": 15, + "column": 50 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 52 + }, + { + "type": "STRING", + "lexeme": "\"string\"", + "line": 15, + "column": 53 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 61 + }, + { + "type": "AND", + "lexeme": "&", + "line": 15, + "column": 62 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 63 + }, + { + "type": "BANG", + "lexeme": "!", + "line": 15, + "column": 64 + }, + { + "type": "LEFT_PAREN", + "lexeme": "(", + "line": 15, + "column": 65 + }, + { + "type": "MINUS", + "lexeme": "-", + "line": 15, + "column": 66 + }, + { + "type": "UNDERSCORE", + "lexeme": "_", + "line": 15, + "column": 67 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 68 + }, + { + "type": "MINUS", + "lexeme": "-", + "line": 15, + "column": 69 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 70 + }, + { + "type": "NUMBER", + "lexeme": "4.0", + "line": 15, + "column": 71 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 74 + }, + { + "type": "LESS_EQUAL", + "lexeme": "<=", + "line": 15, + "column": 75 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 77 + }, + { + "type": "NUMBER", + "lexeme": "0", + "line": 15, + "column": 78 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 79 + }, + { + "type": "AND", + "lexeme": "&", + "line": 15, + "column": 80 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 81 + }, + { + "type": "UNDERSCORE", + "lexeme": "_", + "line": 15, + "column": 82 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 83 + }, + { + "type": "EQUAL_EQUAL", + "lexeme": "==", + "line": 15, + "column": 84 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 86 + }, + { + "type": "NONE", + "lexeme": "none", + "line": 15, + "column": 87 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 91 + }, + { + "type": "AND", + "lexeme": "&", + "line": 15, + "column": 92 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 93 + }, + { + "type": "UNDERSCORE", + "lexeme": "_", + "line": 15, + "column": 94 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 95 + }, + { + "type": "BANG_EQUAL", + "lexeme": "!=", + "line": 15, + "column": 96 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 15, + "column": 98 + }, + { + "type": "FALSE", + "lexeme": "false", + "line": 15, + "column": 99 + }, + { + "type": "RIGHT_PAREN", + "lexeme": ")", + "line": 15, + "column": 104 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 15, + "column": 105 + }, + { + "type": "TYPE", + "lexeme": "type", + "line": 16, + "column": 1 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 16, + "column": 5 + }, + { + "type": "IDENTIFIER", + "lexeme": "I", + "line": 16, + "column": 6 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 16, + "column": 7 + }, + { + "type": "EQUAL", + "lexeme": "=", + "line": 16, + "column": 8 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 16, + "column": 9 + }, + { + "type": "FUNC", + "lexeme": "fn", + "line": 16, + "column": 10 + }, + { + "type": "LEFT_PAREN", + "lexeme": "(", + "line": 16, + "column": 12 + }, + { + "type": "RIGHT_PAREN", + "lexeme": ")", + "line": 16, + "column": 13 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 16, + "column": 14 + }, + { + "type": "ARROW", + "lexeme": "->", + "line": 16, + "column": 15 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 16, + "column": 17 + }, + { + "type": "IDENTIFIER", + "lexeme": "Any", + "line": 16, + "column": 18 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 16, + "column": 21 + }, + { + "type": "TYPE", + "lexeme": "type", + "line": 17, + "column": 1 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 17, + "column": 5 + }, + { + "type": "IDENTIFIER", + "lexeme": "J", + "line": 17, + "column": 6 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 17, + "column": 7 + }, + { + "type": "EQUAL", + "lexeme": "=", + "line": 17, + "column": 8 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 17, + "column": 9 + }, + { + "type": "FUNC", + "lexeme": "fn", + "line": 17, + "column": 10 + }, + { + "type": "LEFT_PAREN", + "lexeme": "(", + "line": 17, + "column": 12 + }, + { + "type": "IDENTIFIER", + "lexeme": "a", + "line": 17, + "column": 13 + }, + { + "type": "COLON", + "lexeme": ":", + "line": 17, + "column": 14 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 17, + "column": 15 + }, + { + "type": "IDENTIFIER", + "lexeme": "int", + "line": 17, + "column": 16 + }, + { + "type": "COMMA", + "lexeme": ",", + "line": 17, + "column": 19 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 17, + "column": 20 + }, + { + "type": "SLASH", + "lexeme": "/", + "line": 17, + "column": 21 + }, + { + "type": "COMMA", + "lexeme": ",", + "line": 17, + "column": 22 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 17, + "column": 23 + }, + { + "type": "IDENTIFIER", + "lexeme": "b", + "line": 17, + "column": 24 + }, + { + "type": "COLON", + "lexeme": ":", + "line": 17, + "column": 25 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 17, + "column": 26 + }, + { + "type": "IDENTIFIER", + "lexeme": "float", + "line": 17, + "column": 27 + }, + { + "type": "COMMA", + "lexeme": ",", + "line": 17, + "column": 32 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 17, + "column": 33 + }, + { + "type": "STAR", + "lexeme": "*", + "line": 17, + "column": 34 + }, + { + "type": "COMMA", + "lexeme": ",", + "line": 17, + "column": 35 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 17, + "column": 36 + }, + { + "type": "IDENTIFIER", + "lexeme": "c", + "line": 17, + "column": 37 + }, + { + "type": "COLON", + "lexeme": ":", + "line": 17, + "column": 38 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 17, + "column": 39 + }, + { + "type": "IDENTIFIER", + "lexeme": "bool", + "line": 17, + "column": 40 + }, + { + "type": "RIGHT_PAREN", + "lexeme": ")", + "line": 17, + "column": 44 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 17, + "column": 45 + }, + { + "type": "ARROW", + "lexeme": "->", + "line": 17, + "column": 46 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 17, + "column": 48 + }, + { + "type": "IDENTIFIER", + "lexeme": "Any", + "line": 17, + "column": 49 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 17, + "column": 52 + }, + { + "type": "TYPE", + "lexeme": "type", + "line": 18, + "column": 1 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 18, + "column": 5 + }, + { + "type": "IDENTIFIER", + "lexeme": "K", + "line": 18, + "column": 6 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 18, + "column": 7 + }, + { + "type": "EQUAL", + "lexeme": "=", + "line": 18, + "column": 8 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 18, + "column": 9 + }, + { + "type": "FUNC", + "lexeme": "fn", + "line": 18, + "column": 10 + }, + { + "type": "LEFT_PAREN", + "lexeme": "(", + "line": 18, + "column": 12 + }, + { + "type": "IDENTIFIER", + "lexeme": "a", + "line": 18, + "column": 13 + }, + { + "type": "COLON", + "lexeme": ":", + "line": 18, + "column": 14 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 18, + "column": 15 + }, + { + "type": "IDENTIFIER", + "lexeme": "int", + "line": 18, + "column": 16 + }, + { + "type": "COMMA", + "lexeme": ",", + "line": 18, + "column": 19 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 18, + "column": 20 + }, + { + "type": "SLASH", + "lexeme": "/", + "line": 18, + "column": 21 + }, + { + "type": "COMMA", + "lexeme": ",", + "line": 18, + "column": 22 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 18, + "column": 23 + }, + { + "type": "IDENTIFIER", + "lexeme": "b", + "line": 18, + "column": 24 + }, + { + "type": "COLON", + "lexeme": ":", + "line": 18, + "column": 25 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 18, + "column": 26 + }, + { + "type": "IDENTIFIER", + "lexeme": "float", + "line": 18, + "column": 27 + }, + { + "type": "COMMA", + "lexeme": ",", + "line": 18, + "column": 32 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 18, + "column": 33 + }, + { + "type": "STAR", + "lexeme": "*", + "line": 18, + "column": 34 + }, + { + "type": "COMMA", + "lexeme": ",", + "line": 18, + "column": 35 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 18, + "column": 36 + }, + { + "type": "IDENTIFIER", + "lexeme": "c", + "line": 18, + "column": 37 + }, + { + "type": "COLON", + "lexeme": ":", + "line": 18, + "column": 38 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 18, + "column": 39 + }, + { + "type": "IDENTIFIER", + "lexeme": "bool", + "line": 18, + "column": 40 + }, + { + "type": "QMARK", + "lexeme": "?", + "line": 18, + "column": 44 + }, + { + "type": "RIGHT_PAREN", + "lexeme": ")", + "line": 18, + "column": 45 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 18, + "column": 46 + }, + { + "type": "ARROW", + "lexeme": "->", + "line": 18, + "column": 47 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 18, + "column": 49 + }, + { + "type": "IDENTIFIER", + "lexeme": "Any", + "line": 18, + "column": 50 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 18, + "column": 53 + }, + { + "type": "TYPE", + "lexeme": "type", + "line": 19, + "column": 1 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 19, + "column": 5 + }, + { + "type": "IDENTIFIER", + "lexeme": "L", + "line": 19, + "column": 6 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 19, + "column": 7 + }, + { + "type": "EQUAL", + "lexeme": "=", + "line": 19, + "column": 8 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 19, + "column": 9 + }, + { + "type": "FUNC", + "lexeme": "fn", + "line": 19, + "column": 10 + }, + { + "type": "LEFT_PAREN", + "lexeme": "(", + "line": 19, + "column": 12 + }, + { + "type": "IDENTIFIER", + "lexeme": "a", + "line": 19, + "column": 13 + }, + { + "type": "COLON", + "lexeme": ":", + "line": 19, + "column": 14 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 19, + "column": 15 + }, + { + "type": "IDENTIFIER", + "lexeme": "int", + "line": 19, + "column": 16 + }, + { + "type": "COMMA", + "lexeme": ",", + "line": 19, + "column": 19 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 19, + "column": 20 + }, + { + "type": "SLASH", + "lexeme": "/", + "line": 19, + "column": 21 + }, + { + "type": "COMMA", + "lexeme": ",", + "line": 19, + "column": 22 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 19, + "column": 23 + }, + { + "type": "IDENTIFIER", + "lexeme": "b", + "line": 19, + "column": 24 + }, + { + "type": "COLON", + "lexeme": ":", + "line": 19, + "column": 25 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 19, + "column": 26 + }, + { + "type": "IDENTIFIER", + "lexeme": "float", + "line": 19, + "column": 27 + }, + { + "type": "QMARK", + "lexeme": "?", + "line": 19, + "column": 32 + }, + { + "type": "COMMA", + "lexeme": ",", + "line": 19, + "column": 33 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 19, + "column": 34 + }, + { + "type": "STAR", + "lexeme": "*", + "line": 19, + "column": 35 + }, + { + "type": "COMMA", + "lexeme": ",", + "line": 19, + "column": 36 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 19, + "column": 37 + }, + { + "type": "IDENTIFIER", + "lexeme": "c", + "line": 19, + "column": 38 + }, + { + "type": "COLON", + "lexeme": ":", + "line": 19, + "column": 39 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 19, + "column": 40 + }, + { + "type": "IDENTIFIER", + "lexeme": "bool", + "line": 19, + "column": 41 + }, + { + "type": "QMARK", + "lexeme": "?", + "line": 19, + "column": 45 + }, + { + "type": "RIGHT_PAREN", + "lexeme": ")", + "line": 19, + "column": 46 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 19, + "column": 47 + }, + { + "type": "ARROW", + "lexeme": "->", + "line": 19, + "column": 48 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 19, + "column": 50 + }, + { + "type": "IDENTIFIER", + "lexeme": "Any", + "line": 19, + "column": 51 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 19, + "column": 54 + }, + { + "type": "TYPE", + "lexeme": "type", + "line": 20, + "column": 1 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 20, + "column": 5 + }, + { + "type": "IDENTIFIER", + "lexeme": "M", + "line": 20, + "column": 6 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 20, + "column": 7 + }, + { + "type": "EQUAL", + "lexeme": "=", + "line": 20, + "column": 8 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 20, + "column": 9 + }, + { + "type": "FUNC", + "lexeme": "fn", + "line": 20, + "column": 10 + }, + { + "type": "LEFT_PAREN", + "lexeme": "(", + "line": 20, + "column": 12 + }, + { + "type": "IDENTIFIER", + "lexeme": "a", + "line": 20, + "column": 13 + }, + { + "type": "COLON", + "lexeme": ":", + "line": 20, + "column": 14 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 20, + "column": 15 + }, + { + "type": "IDENTIFIER", + "lexeme": "int", + "line": 20, + "column": 16 + }, + { + "type": "QMARK", + "lexeme": "?", + "line": 20, + "column": 19 + }, + { + "type": "COMMA", + "lexeme": ",", + "line": 20, + "column": 20 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 20, + "column": 21 + }, + { + "type": "SLASH", + "lexeme": "/", + "line": 20, + "column": 22 + }, + { + "type": "COMMA", + "lexeme": ",", + "line": 20, + "column": 23 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 20, + "column": 24 + }, + { + "type": "IDENTIFIER", + "lexeme": "b", + "line": 20, + "column": 25 + }, + { + "type": "COLON", + "lexeme": ":", + "line": 20, + "column": 26 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 20, + "column": 27 + }, + { + "type": "IDENTIFIER", + "lexeme": "float", + "line": 20, + "column": 28 + }, + { + "type": "QMARK", + "lexeme": "?", + "line": 20, + "column": 33 + }, + { + "type": "COMMA", + "lexeme": ",", + "line": 20, + "column": 34 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 20, + "column": 35 + }, + { + "type": "STAR", + "lexeme": "*", + "line": 20, + "column": 36 + }, + { + "type": "COMMA", + "lexeme": ",", + "line": 20, + "column": 37 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 20, + "column": 38 + }, + { + "type": "IDENTIFIER", + "lexeme": "c", + "line": 20, + "column": 39 + }, + { + "type": "COLON", + "lexeme": ":", + "line": 20, + "column": 40 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 20, + "column": 41 + }, + { + "type": "IDENTIFIER", + "lexeme": "bool", + "line": 20, + "column": 42 + }, + { + "type": "QMARK", + "lexeme": "?", + "line": 20, + "column": 46 + }, + { + "type": "RIGHT_PAREN", + "lexeme": ")", + "line": 20, + "column": 47 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 20, + "column": 48 + }, + { + "type": "ARROW", + "lexeme": "->", + "line": 20, + "column": 49 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 20, + "column": 51 + }, + { + "type": "IDENTIFIER", + "lexeme": "Any", + "line": 20, + "column": 52 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 20, + "column": 55 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 21, + "column": 1 + }, + { + "type": "COMMENT", + "lexeme": "// Extend", + "line": 22, + "column": 1 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 22, + "column": 10 + }, + { + "type": "EXTEND", + "lexeme": "extend", + "line": 23, + "column": 1 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 23, + "column": 7 + }, + { + "type": "IDENTIFIER", + "lexeme": "N", + "line": 23, + "column": 8 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 23, + "column": 9 + }, + { + "type": "LEFT_BRACE", + "lexeme": "{", + "line": 23, + "column": 10 + }, + { + "type": "RIGHT_BRACE", + "lexeme": "}", + "line": 23, + "column": 11 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 23, + "column": 12 + }, + { + "type": "EXTEND", + "lexeme": "extend", + "line": 24, + "column": 1 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 24, + "column": 7 + }, + { + "type": "IDENTIFIER", + "lexeme": "O", + "line": 24, + "column": 8 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 24, + "column": 9 + }, + { + "type": "LEFT_BRACE", + "lexeme": "{", + "line": 24, + "column": 10 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 24, + "column": 11 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 25, + "column": 1 + }, + { + "type": "PROP", + "lexeme": "prop", + "line": 25, + "column": 5 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 25, + "column": 9 + }, + { + "type": "IDENTIFIER", + "lexeme": "a", + "line": 25, + "column": 10 + }, + { + "type": "COLON", + "lexeme": ":", + "line": 25, + "column": 11 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 25, + "column": 12 + }, + { + "type": "IDENTIFIER", + "lexeme": "int", + "line": 25, + "column": 13 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 25, + "column": 16 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 26, + "column": 1 + }, + { + "type": "DEF", + "lexeme": "def", + "line": 26, + "column": 5 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 26, + "column": 8 + }, + { + "type": "IDENTIFIER", + "lexeme": "b", + "line": 26, + "column": 9 + }, + { + "type": "COLON", + "lexeme": ":", + "line": 26, + "column": 10 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 26, + "column": 11 + }, + { + "type": "FUNC", + "lexeme": "fn", + "line": 26, + "column": 12 + }, + { + "type": "LEFT_PAREN", + "lexeme": "(", + "line": 26, + "column": 14 + }, + { + "type": "IDENTIFIER", + "lexeme": "int", + "line": 26, + "column": 15 + }, + { + "type": "COMMA", + "lexeme": ",", + "line": 26, + "column": 18 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 26, + "column": 19 + }, + { + "type": "SLASH", + "lexeme": "/", + "line": 26, + "column": 20 + }, + { + "type": "RIGHT_PAREN", + "lexeme": ")", + "line": 26, + "column": 21 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 26, + "column": 22 + }, + { + "type": "ARROW", + "lexeme": "->", + "line": 26, + "column": 23 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 26, + "column": 25 + }, + { + "type": "IDENTIFIER", + "lexeme": "int", + "line": 26, + "column": 26 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 26, + "column": 29 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 27, + "column": 1 + }, + { + "type": "DEF", + "lexeme": "def", + "line": 27, + "column": 5 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 27, + "column": 8 + }, + { + "type": "IDENTIFIER", + "lexeme": "b", + "line": 27, + "column": 9 + }, + { + "type": "COLON", + "lexeme": ":", + "line": 27, + "column": 10 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 27, + "column": 11 + }, + { + "type": "FUNC", + "lexeme": "fn", + "line": 27, + "column": 12 + }, + { + "type": "LEFT_PAREN", + "lexeme": "(", + "line": 27, + "column": 14 + }, + { + "type": "IDENTIFIER", + "lexeme": "float", + "line": 27, + "column": 15 + }, + { + "type": "COMMA", + "lexeme": ",", + "line": 27, + "column": 20 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 27, + "column": 21 + }, + { + "type": "SLASH", + "lexeme": "/", + "line": 27, + "column": 22 + }, + { + "type": "RIGHT_PAREN", + "lexeme": ")", + "line": 27, + "column": 23 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 27, + "column": 24 + }, + { + "type": "ARROW", + "lexeme": "->", + "line": 27, + "column": 25 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 27, + "column": 27 + }, + { + "type": "IDENTIFIER", + "lexeme": "float", + "line": 27, + "column": 28 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 27, + "column": 33 + }, + { + "type": "RIGHT_BRACE", + "lexeme": "}", + "line": 28, + "column": 1 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 28, + "column": 2 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 29, + "column": 1 + }, + { + "type": "COMMENT", + "lexeme": "// Predicate", + "line": 30, + "column": 1 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 30, + "column": 13 + }, + { + "type": "PREDICATE", + "lexeme": "predicate", + "line": 31, + "column": 1 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 31, + "column": 10 + }, + { + "type": "IDENTIFIER", + "lexeme": "P", + "line": 31, + "column": 11 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 31, + "column": 12 + }, + { + "type": "EQUAL", + "lexeme": "=", + "line": 31, + "column": 13 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 31, + "column": 14 + }, + { + "type": "TRUE", + "lexeme": "true", + "line": 31, + "column": 15 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 31, + "column": 19 + }, + { + "type": "PREDICATE", + "lexeme": "predicate", + "line": 32, + "column": 1 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 32, + "column": 10 + }, + { + "type": "IDENTIFIER", + "lexeme": "Q", + "line": 32, + "column": 11 + }, + { + "type": "LEFT_PAREN", + "lexeme": "(", + "line": 32, + "column": 12 + }, + { + "type": "IDENTIFIER", + "lexeme": "v", + "line": 32, + "column": 13 + }, + { + "type": "COLON", + "lexeme": ":", + "line": 32, + "column": 14 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 32, + "column": 15 + }, + { + "type": "IDENTIFIER", + "lexeme": "float", + "line": 32, + "column": 16 + }, + { + "type": "RIGHT_PAREN", + "lexeme": ")", + "line": 32, + "column": 21 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 32, + "column": 22 + }, + { + "type": "EQUAL", + "lexeme": "=", + "line": 32, + "column": 23 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 32, + "column": 24 + }, + { + "type": "IDENTIFIER", + "lexeme": "v", + "line": 32, + "column": 25 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 32, + "column": 26 + }, + { + "type": "GREATER", + "lexeme": ">", + "line": 32, + "column": 27 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 32, + "column": 28 + }, + { + "type": "NUMBER", + "lexeme": "0", + "line": 32, + "column": 29 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 32, + "column": 30 + }, + { + "type": "PREDICATE", + "lexeme": "predicate", + "line": 33, + "column": 1 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 33, + "column": 10 + }, + { + "type": "IDENTIFIER", + "lexeme": "R", + "line": 33, + "column": 11 + }, + { + "type": "LEFT_PAREN", + "lexeme": "(", + "line": 33, + "column": 12 + }, + { + "type": "IDENTIFIER", + "lexeme": "a", + "line": 33, + "column": 13 + }, + { + "type": "COLON", + "lexeme": ":", + "line": 33, + "column": 14 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 33, + "column": 15 + }, + { + "type": "IDENTIFIER", + "lexeme": "float", + "line": 33, + "column": 16 + }, + { + "type": "COMMA", + "lexeme": ",", + "line": 33, + "column": 21 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 33, + "column": 22 + }, + { + "type": "IDENTIFIER", + "lexeme": "b", + "line": 33, + "column": 23 + }, + { + "type": "COLON", + "lexeme": ":", + "line": 33, + "column": 24 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 33, + "column": 25 + }, + { + "type": "IDENTIFIER", + "lexeme": "float", + "line": 33, + "column": 26 + }, + { + "type": "RIGHT_PAREN", + "lexeme": ")", + "line": 33, + "column": 31 + }, + { + "type": "LEFT_PAREN", + "lexeme": "(", + "line": 33, + "column": 32 + }, + { + "type": "IDENTIFIER", + "lexeme": "v", + "line": 33, + "column": 33 + }, + { + "type": "COLON", + "lexeme": ":", + "line": 33, + "column": 34 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 33, + "column": 35 + }, + { + "type": "IDENTIFIER", + "lexeme": "float", + "line": 33, + "column": 36 + }, + { + "type": "RIGHT_PAREN", + "lexeme": ")", + "line": 33, + "column": 41 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 33, + "column": 42 + }, + { + "type": "EQUAL", + "lexeme": "=", + "line": 33, + "column": 43 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 33, + "column": 44 + }, + { + "type": "IDENTIFIER", + "lexeme": "a", + "line": 33, + "column": 45 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 33, + "column": 46 + }, + { + "type": "LESS", + "lexeme": "<", + "line": 33, + "column": 47 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 33, + "column": 48 + }, + { + "type": "IDENTIFIER", + "lexeme": "v", + "line": 33, + "column": 49 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 33, + "column": 50 + }, + { + "type": "AND", + "lexeme": "&", + "line": 33, + "column": 51 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 33, + "column": 52 + }, + { + "type": "IDENTIFIER", + "lexeme": "v", + "line": 33, + "column": 53 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 33, + "column": 54 + }, + { + "type": "LESS", + "lexeme": "<", + "line": 33, + "column": 55 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 33, + "column": 56 + }, + { + "type": "IDENTIFIER", + "lexeme": "b", + "line": 33, + "column": 57 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 33, + "column": 58 + }, + { + "type": "PREDICATE", + "lexeme": "predicate", + "line": 34, + "column": 1 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 34, + "column": 10 + }, + { + "type": "IDENTIFIER", + "lexeme": "S", + "line": 34, + "column": 11 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 34, + "column": 12 + }, + { + "type": "EQUAL", + "lexeme": "=", + "line": 34, + "column": 13 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 34, + "column": 14 + }, + { + "type": "IDENTIFIER", + "lexeme": "R", + "line": 34, + "column": 15 + }, + { + "type": "LEFT_PAREN", + "lexeme": "(", + "line": 34, + "column": 16 + }, + { + "type": "NUMBER", + "lexeme": "0.0", + "line": 34, + "column": 17 + }, + { + "type": "COMMA", + "lexeme": ",", + "line": 34, + "column": 20 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 34, + "column": 21 + }, + { + "type": "NUMBER", + "lexeme": "1.0", + "line": 34, + "column": 22 + }, + { + "type": "RIGHT_PAREN", + "lexeme": ")", + "line": 34, + "column": 25 + }, + { + "type": "NEWLINE", + "lexeme": "\n", + "line": 34, + "column": 26 + }, + { + "type": "PREDICATE", + "lexeme": "predicate", + "line": 35, + "column": 1 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 35, + "column": 10 + }, + { + "type": "IDENTIFIER", + "lexeme": "T", + "line": 35, + "column": 11 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 35, + "column": 12 + }, + { + "type": "EQUAL", + "lexeme": "=", + "line": 35, + "column": 13 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 35, + "column": 14 + }, + { + "type": "IDENTIFIER", + "lexeme": "R", + "line": 35, + "column": 15 + }, + { + "type": "LEFT_PAREN", + "lexeme": "(", + "line": 35, + "column": 16 + }, + { + "type": "IDENTIFIER", + "lexeme": "a", + "line": 35, + "column": 17 + }, + { + "type": "EQUAL", + "lexeme": "=", + "line": 35, + "column": 18 + }, + { + "type": "NUMBER", + "lexeme": "0.0", + "line": 35, + "column": 19 + }, + { + "type": "COMMA", + "lexeme": ",", + "line": 35, + "column": 22 + }, + { + "type": "WHITESPACE", + "lexeme": " ", + "line": 35, + "column": 23 + }, + { + "type": "IDENTIFIER", + "lexeme": "b", + "line": 35, + "column": 24 + }, + { + "type": "EQUAL", + "lexeme": "=", + "line": 35, + "column": 25 + }, + { + "type": "NUMBER", + "lexeme": "1.0", + "line": 35, + "column": 26 + }, + { + "type": "RIGHT_PAREN", + "lexeme": ")", + "line": 35, + "column": 29 + }, + { + "type": "EOF", + "lexeme": "", + "line": 35, + "column": 30 + } + ], + "stmts": [ + { + "_type": "AliasStmt", + "name": "A", + "type": { + "_type": "NamedType", + "name": "object" + } + }, + { + "_type": "TypeStmt", + "name": "B", + "params": [], + "type": { + "_type": "NamedType", + "name": "object" + } + }, + { + "_type": "TypeStmt", + "name": "C", + "params": [ + { + "name": "T", + "bound": null + } + ], + "type": { + "_type": "NamedType", + "name": "object" + } + }, + { + "_type": "TypeStmt", + "name": "D", + "params": [ + { + "name": "T", + "bound": { + "_type": "NamedType", + "name": "A" + } + } + ], + "type": { + "_type": "NamedType", + "name": "object" + } + }, + { + "_type": "TypeStmt", + "name": "E", + "params": [ + { + "name": "T", + "bound": null + }, + { + "name": "U", + "bound": null + } + ], + "type": { + "_type": "NamedType", + "name": "object" + } + }, + { + "_type": "TypeStmt", + "name": "F", + "params": [ + { + "name": "T", + "bound": null + } + ], + "type": { + "_type": "NamedType", + "name": "T" + } + }, + { + "_type": "TypeStmt", + "name": "G", + "params": [], + "type": { + "_type": "ConstraintType", + "type": { + "_type": "NamedType", + "name": "A" + }, + "constraint": { + "_type": "CallExpr", + "callee": { + "_type": "VariableExpr", + "name": "predicate" + }, + "arguments": [ + { + "_type": "WildcardExpr" + } + ], + "keywords": {} + } + } + }, + { + "_type": "TypeStmt", + "name": "H", + "params": [], + "type": { + "_type": "ConstraintType", + "type": { + "_type": "NamedType", + "name": "A" + }, + "constraint": { + "_type": "LogicalExpr", + "left": { + "_type": "LogicalExpr", + "left": { + "_type": "LogicalExpr", + "left": { + "_type": "BinaryExpr", + "left": { + "_type": "WildcardExpr" + }, + "operator": ">", + "right": { + "_type": "LiteralExpr", + "value": 0 + } + }, + "operator": "&", + "right": { + "_type": "BinaryExpr", + "left": { + "_type": "GetExpr", + "expr": { + "_type": "VariableExpr", + "name": "_" + }, + "name": "attr" + }, + "operator": "<", + "right": { + "_type": "LiteralExpr", + "value": 1.0 + } + } + }, + "operator": "&", + "right": { + "_type": "BinaryExpr", + "left": { + "_type": "BinaryExpr", + "left": { + "_type": "UnaryExpr", + "operator": "+", + "right": { + "_type": "WildcardExpr" + } + }, + "operator": "+", + "right": { + "_type": "LiteralExpr", + "value": 4.0 + } + }, + "operator": ">=", + "right": { + "_type": "LiteralExpr", + "value": "string" + } + } + }, + "operator": "&", + "right": { + "_type": "UnaryExpr", + "operator": "!", + "right": { + "_type": "GroupingExpr", + "expr": { + "_type": "LogicalExpr", + "left": { + "_type": "LogicalExpr", + "left": { + "_type": "BinaryExpr", + "left": { + "_type": "BinaryExpr", + "left": { + "_type": "UnaryExpr", + "operator": "-", + "right": { + "_type": "WildcardExpr" + } + }, + "operator": "-", + "right": { + "_type": "LiteralExpr", + "value": 4.0 + } + }, + "operator": "<=", + "right": { + "_type": "LiteralExpr", + "value": 0 + } + }, + "operator": "&", + "right": { + "_type": "BinaryExpr", + "left": { + "_type": "WildcardExpr" + }, + "operator": "==", + "right": { + "_type": "LiteralExpr", + "value": null + } + } + }, + "operator": "&", + "right": { + "_type": "BinaryExpr", + "left": { + "_type": "WildcardExpr" + }, + "operator": "!=", + "right": { + "_type": "LiteralExpr", + "value": false + } + } + } + } + } + } + } + }, + { + "_type": "TypeStmt", + "name": "I", + "params": [], + "type": { + "_type": "FunctionType", + "params": { + "_type": "ParamSpec", + "pos": [], + "mixed": [], + "kw": [] + }, + "returns": { + "_type": "NamedType", + "name": "Any" + } + } + }, + { + "_type": "TypeStmt", + "name": "J", + "params": [], + "type": { + "_type": "FunctionType", + "params": { + "_type": "ParamSpec", + "pos": [ + { + "name": "a", + "type": { + "_type": "NamedType", + "name": "int" + }, + "required": true + } + ], + "mixed": [ + { + "name": "b", + "type": { + "_type": "NamedType", + "name": "float" + }, + "required": true + } + ], + "kw": [ + { + "name": "c", + "type": { + "_type": "NamedType", + "name": "bool" + }, + "required": true + } + ] + }, + "returns": { + "_type": "NamedType", + "name": "Any" + } + } + }, + { + "_type": "TypeStmt", + "name": "K", + "params": [], + "type": { + "_type": "FunctionType", + "params": { + "_type": "ParamSpec", + "pos": [ + { + "name": "a", + "type": { + "_type": "NamedType", + "name": "int" + }, + "required": true + } + ], + "mixed": [ + { + "name": "b", + "type": { + "_type": "NamedType", + "name": "float" + }, + "required": true + } + ], + "kw": [ + { + "name": "c", + "type": { + "_type": "NamedType", + "name": "bool" + }, + "required": false + } + ] + }, + "returns": { + "_type": "NamedType", + "name": "Any" + } + } + }, + { + "_type": "TypeStmt", + "name": "L", + "params": [], + "type": { + "_type": "FunctionType", + "params": { + "_type": "ParamSpec", + "pos": [ + { + "name": "a", + "type": { + "_type": "NamedType", + "name": "int" + }, + "required": true + } + ], + "mixed": [ + { + "name": "b", + "type": { + "_type": "NamedType", + "name": "float" + }, + "required": false + } + ], + "kw": [ + { + "name": "c", + "type": { + "_type": "NamedType", + "name": "bool" + }, + "required": false + } + ] + }, + "returns": { + "_type": "NamedType", + "name": "Any" + } + } + }, + { + "_type": "TypeStmt", + "name": "M", + "params": [], + "type": { + "_type": "FunctionType", + "params": { + "_type": "ParamSpec", + "pos": [ + { + "name": "a", + "type": { + "_type": "NamedType", + "name": "int" + }, + "required": false + } + ], + "mixed": [ + { + "name": "b", + "type": { + "_type": "NamedType", + "name": "float" + }, + "required": false + } + ], + "kw": [ + { + "name": "c", + "type": { + "_type": "NamedType", + "name": "bool" + }, + "required": false + } + ] + }, + "returns": { + "_type": "NamedType", + "name": "Any" + } + } + }, + { + "_type": "ExtendStmt", + "name": "N", + "params": [], + "members": [] + }, + { + "_type": "ExtendStmt", + "name": "O", + "params": [], + "members": [ + { + "_type": "MemberStmt", + "kind": "PROPERTY", + "name": "a", + "type": { + "_type": "NamedType", + "name": "int" + } + }, + { + "_type": "MemberStmt", + "kind": "METHOD", + "name": "b", + "type": { + "_type": "FunctionType", + "params": { + "_type": "ParamSpec", + "pos": [ + { + "name": null, + "type": { + "_type": "NamedType", + "name": "int" + }, + "required": true + } + ], + "mixed": [], + "kw": [] + }, + "returns": { + "_type": "NamedType", + "name": "int" + } + } + }, + { + "_type": "MemberStmt", + "kind": "METHOD", + "name": "b", + "type": { + "_type": "FunctionType", + "params": { + "_type": "ParamSpec", + "pos": [ + { + "name": null, + "type": { + "_type": "NamedType", + "name": "float" + }, + "required": true + } + ], + "mixed": [], + "kw": [] + }, + "returns": { + "_type": "NamedType", + "name": "float" + } + } + } + ] + }, + { + "_type": "PredicateStmt", + "name": "P", + "params": [], + "body": { + "_type": "LiteralExpr", + "value": true + } + }, + { + "_type": "PredicateStmt", + "name": "Q", + "params": [ + { + "_type": "ParamSpec", + "pos": [], + "mixed": [ + { + "name": "v", + "type": { + "_type": "NamedType", + "name": "float" + }, + "required": true + } + ], + "kw": [] + } + ], + "body": { + "_type": "BinaryExpr", + "left": { + "_type": "VariableExpr", + "name": "v" + }, + "operator": ">", + "right": { + "_type": "LiteralExpr", + "value": 0 + } + } + }, + { + "_type": "PredicateStmt", + "name": "R", + "params": [ + { + "_type": "ParamSpec", + "pos": [], + "mixed": [ + { + "name": "a", + "type": { + "_type": "NamedType", + "name": "float" + }, + "required": true + }, + { + "name": "b", + "type": { + "_type": "NamedType", + "name": "float" + }, + "required": true + } + ], + "kw": [] + }, + { + "_type": "ParamSpec", + "pos": [], + "mixed": [ + { + "name": "v", + "type": { + "_type": "NamedType", + "name": "float" + }, + "required": true + } + ], + "kw": [] + } + ], + "body": { + "_type": "LogicalExpr", + "left": { + "_type": "BinaryExpr", + "left": { + "_type": "VariableExpr", + "name": "a" + }, + "operator": "<", + "right": { + "_type": "VariableExpr", + "name": "v" + } + }, + "operator": "&", + "right": { + "_type": "BinaryExpr", + "left": { + "_type": "VariableExpr", + "name": "v" + }, + "operator": "<", + "right": { + "_type": "VariableExpr", + "name": "b" + } + } + } + }, + { + "_type": "PredicateStmt", + "name": "S", + "params": [], + "body": { + "_type": "CallExpr", + "callee": { + "_type": "VariableExpr", + "name": "R" + }, + "arguments": [ + { + "_type": "LiteralExpr", + "value": 0.0 + }, + { + "_type": "LiteralExpr", + "value": 1.0 + } + ], + "keywords": {} + } + }, + { + "_type": "PredicateStmt", + "name": "T", + "params": [], + "body": { + "_type": "CallExpr", + "callee": { + "_type": "VariableExpr", + "name": "R" + }, + "arguments": [], + "keywords": { + "a": { + "_type": "LiteralExpr", + "value": 0.0 + }, + "b": { + "_type": "LiteralExpr", + "value": 1.0 + } + } + } + } + ], + "errors": [] +} \ No newline at end of file diff --git a/tests/cases/python-parser/04_all_syntax.py b/tests/cases/python-parser/04_all_syntax.py new file mode 100644 index 0000000..9bf70f5 --- /dev/null +++ b/tests/cases/python-parser/04_all_syntax.py @@ -0,0 +1,49 @@ +# type: ignore +# ruff: disable[F821] + +import module1 +import module2 as alias2 +from module3 import submodule3 +from module4 import submodule4 as alias4 + +a: int +b: Generic[int] +c: Generic2[int, float] +d: Frame[a:int, b:float] + +e = 3 +f: int = 4 +g = [] +h = [1, 0.1, " ", None, False, True] +i = {} +j = {"a": 1, "b": 2} +k = {"c": 3, **j} +l = cast(int, a) +m = unsafe_cast(int, a) + + +def n(a: int, /, b: float, *, c: str) -> Any: + return + + +def o(a: int = 1, /, b: float = 2.0, *, c: str = "") -> Any: + return 1 + + +for i in h: + pass + +if e == f: + pass +elif f == g: + pass +else: + pass + +p = +a + -b - ~c * d / e**f +q = not (a and b) or c +r = a & b | c ^ d + +s = a.b.c +t = a[b][c, d][e:f] +u = a(b)(c=d) diff --git a/tests/cases/python-parser/04_all_syntax.py.ref.json b/tests/cases/python-parser/04_all_syntax.py.ref.json new file mode 100644 index 0000000..b04b839 --- /dev/null +++ b/tests/cases/python-parser/04_all_syntax.py.ref.json @@ -0,0 +1,725 @@ +{ + "stmts": [ + { + "_type": "ImportStmt", + "imports": [ + { + "_type": "ImportAlias", + "name": "module1", + "alias": null + } + ] + }, + { + "_type": "ImportStmt", + "imports": [ + { + "_type": "ImportAlias", + "name": "module2", + "alias": "alias2" + } + ] + }, + { + "_type": "FromImportStmt", + "module": "module3", + "imports": [ + { + "_type": "ImportAlias", + "name": "submodule3", + "alias": null + } + ], + "level": 0 + }, + { + "_type": "FromImportStmt", + "module": "module4", + "imports": [ + { + "_type": "ImportAlias", + "name": "submodule4", + "alias": "alias4" + } + ], + "level": 0 + }, + { + "_type": "TypeAssign", + "name": "a", + "type": { + "_type": "BaseType", + "base": "int", + "args": [] + } + }, + { + "_type": "TypeAssign", + "name": "b", + "type": { + "_type": "BaseType", + "base": "Generic", + "args": [ + { + "_type": "BaseType", + "base": "int", + "args": [] + } + ] + } + }, + { + "_type": "TypeAssign", + "name": "c", + "type": { + "_type": "BaseType", + "base": "Generic2", + "args": [ + { + "_type": "BaseType", + "base": "int", + "args": [] + }, + { + "_type": "BaseType", + "base": "float", + "args": [] + } + ] + } + }, + { + "_type": "TypeAssign", + "name": "d", + "type": { + "_type": "FrameType", + "columns": [ + { + "_type": "FrameColumn", + "name": "a", + "type": { + "_type": "BaseType", + "base": "int", + "args": [] + } + }, + { + "_type": "FrameColumn", + "name": "b", + "type": { + "_type": "BaseType", + "base": "float", + "args": [] + } + } + ] + } + }, + { + "_type": "AssignStmt", + "targets": [ + { + "_type": "VariableExpr", + "name": "e" + } + ], + "value": { + "_type": "LiteralExpr", + "value": 3 + } + }, + { + "_type": "TypeAssign", + "name": "f", + "type": { + "_type": "BaseType", + "base": "int", + "args": [] + } + }, + { + "_type": "AssignStmt", + "targets": [ + { + "_type": "VariableExpr", + "name": "f" + } + ], + "value": { + "_type": "LiteralExpr", + "value": 4 + } + }, + { + "_type": "AssignStmt", + "targets": [ + { + "_type": "VariableExpr", + "name": "g" + } + ], + "value": { + "_type": "ListExpr", + "items": [] + } + }, + { + "_type": "AssignStmt", + "targets": [ + { + "_type": "VariableExpr", + "name": "h" + } + ], + "value": { + "_type": "ListExpr", + "items": [ + { + "_type": "LiteralExpr", + "value": 1 + }, + { + "_type": "LiteralExpr", + "value": 0.1 + }, + { + "_type": "LiteralExpr", + "value": " " + }, + { + "_type": "LiteralExpr", + "value": null + }, + { + "_type": "LiteralExpr", + "value": false + }, + { + "_type": "LiteralExpr", + "value": true + } + ] + } + }, + { + "_type": "AssignStmt", + "targets": [ + { + "_type": "VariableExpr", + "name": "i" + } + ], + "value": { + "_type": "DictExpr", + "keys": [], + "values": [] + } + }, + { + "_type": "AssignStmt", + "targets": [ + { + "_type": "VariableExpr", + "name": "j" + } + ], + "value": { + "_type": "DictExpr", + "keys": [ + { + "_type": "LiteralExpr", + "value": "a" + }, + { + "_type": "LiteralExpr", + "value": "b" + } + ], + "values": [ + { + "_type": "LiteralExpr", + "value": 1 + }, + { + "_type": "LiteralExpr", + "value": 2 + } + ] + } + }, + { + "_type": "AssignStmt", + "targets": [ + { + "_type": "VariableExpr", + "name": "k" + } + ], + "value": { + "_type": "DictExpr", + "keys": [ + { + "_type": "LiteralExpr", + "value": "c" + }, + null + ], + "values": [ + { + "_type": "LiteralExpr", + "value": 3 + }, + { + "_type": "VariableExpr", + "name": "j" + } + ] + } + }, + { + "_type": "AssignStmt", + "targets": [ + { + "_type": "VariableExpr", + "name": "l" + } + ], + "value": { + "_type": "CastExpr", + "type": { + "_type": "BaseType", + "base": "int", + "args": [] + }, + "expr": { + "_type": "VariableExpr", + "name": "a" + }, + "unsafe": false + } + }, + { + "_type": "AssignStmt", + "targets": [ + { + "_type": "VariableExpr", + "name": "m" + } + ], + "value": { + "_type": "CastExpr", + "type": { + "_type": "BaseType", + "base": "int", + "args": [] + }, + "expr": { + "_type": "VariableExpr", + "name": "a" + }, + "unsafe": true + } + }, + { + "_type": "Function", + "name": "n", + "params": { + "_type": "ParamSpec", + "pos": [ + { + "name": "a", + "type": { + "_type": "BaseType", + "base": "int", + "args": [] + }, + "default": null + } + ], + "mixed": [ + { + "name": "b", + "type": { + "_type": "BaseType", + "base": "float", + "args": [] + }, + "default": null + } + ], + "kw": [ + { + "name": "c", + "type": { + "_type": "BaseType", + "base": "str", + "args": [] + }, + "default": null + } + ] + }, + "returns": { + "_type": "BaseType", + "base": "Any", + "args": [] + }, + "body": [ + { + "_type": "ReturnStmt", + "value": null + } + ] + }, + { + "_type": "Function", + "name": "o", + "params": { + "_type": "ParamSpec", + "pos": [ + { + "name": "a", + "type": { + "_type": "BaseType", + "base": "int", + "args": [] + }, + "default": { + "_type": "LiteralExpr", + "value": 1 + } + } + ], + "mixed": [ + { + "name": "b", + "type": { + "_type": "BaseType", + "base": "float", + "args": [] + }, + "default": { + "_type": "LiteralExpr", + "value": 2.0 + } + } + ], + "kw": [ + { + "name": "c", + "type": { + "_type": "BaseType", + "base": "str", + "args": [] + }, + "default": { + "_type": "LiteralExpr", + "value": "" + } + } + ] + }, + "returns": { + "_type": "BaseType", + "base": "Any", + "args": [] + }, + "body": [ + { + "_type": "ReturnStmt", + "value": { + "_type": "LiteralExpr", + "value": 1 + } + } + ] + }, + { + "_type": "ForStmt", + "target": { + "_type": "VariableExpr", + "name": "i" + }, + "iterator": { + "_type": "VariableExpr", + "name": "h" + }, + "body": [] + }, + { + "_type": "IfStmt", + "test": { + "_type": "CompareExpr", + "left": { + "_type": "VariableExpr", + "name": "e" + }, + "operator": "==", + "right": { + "_type": "VariableExpr", + "name": "f" + } + }, + "body": [], + "orelse": [ + { + "_type": "IfStmt", + "test": { + "_type": "CompareExpr", + "left": { + "_type": "VariableExpr", + "name": "f" + }, + "operator": "==", + "right": { + "_type": "VariableExpr", + "name": "g" + } + }, + "body": [], + "orelse": [] + } + ] + }, + { + "_type": "AssignStmt", + "targets": [ + { + "_type": "VariableExpr", + "name": "p" + } + ], + "value": { + "_type": "BinaryExpr", + "left": { + "_type": "BinaryExpr", + "left": { + "_type": "UnaryExpr", + "operator": "+", + "right": { + "_type": "VariableExpr", + "name": "a" + } + }, + "operator": "+", + "right": { + "_type": "UnaryExpr", + "operator": "-", + "right": { + "_type": "VariableExpr", + "name": "b" + } + } + }, + "operator": "-", + "right": { + "_type": "BinaryExpr", + "left": { + "_type": "BinaryExpr", + "left": { + "_type": "UnaryExpr", + "operator": "~", + "right": { + "_type": "VariableExpr", + "name": "c" + } + }, + "operator": "*", + "right": { + "_type": "VariableExpr", + "name": "d" + } + }, + "operator": "/", + "right": { + "_type": "BinaryExpr", + "left": { + "_type": "VariableExpr", + "name": "e" + }, + "operator": "**", + "right": { + "_type": "VariableExpr", + "name": "f" + } + } + } + } + }, + { + "_type": "AssignStmt", + "targets": [ + { + "_type": "VariableExpr", + "name": "q" + } + ], + "value": { + "_type": "LogicalExpr", + "left": { + "_type": "UnaryExpr", + "operator": "not", + "right": { + "_type": "LogicalExpr", + "left": { + "_type": "VariableExpr", + "name": "a" + }, + "operator": "and", + "right": { + "_type": "VariableExpr", + "name": "b" + } + } + }, + "operator": "or", + "right": { + "_type": "VariableExpr", + "name": "c" + } + } + }, + { + "_type": "AssignStmt", + "targets": [ + { + "_type": "VariableExpr", + "name": "r" + } + ], + "value": { + "_type": "BinaryExpr", + "left": { + "_type": "BinaryExpr", + "left": { + "_type": "VariableExpr", + "name": "a" + }, + "operator": "&", + "right": { + "_type": "VariableExpr", + "name": "b" + } + }, + "operator": "|", + "right": { + "_type": "BinaryExpr", + "left": { + "_type": "VariableExpr", + "name": "c" + }, + "operator": "^", + "right": { + "_type": "VariableExpr", + "name": "d" + } + } + } + }, + { + "_type": "AssignStmt", + "targets": [ + { + "_type": "VariableExpr", + "name": "s" + } + ], + "value": { + "_type": "GetExpr", + "object": { + "_type": "GetExpr", + "object": { + "_type": "VariableExpr", + "name": "a" + }, + "name": "b" + }, + "name": "c" + } + }, + { + "_type": "AssignStmt", + "targets": [ + { + "_type": "VariableExpr", + "name": "t" + } + ], + "value": { + "_type": "SubscriptExpr", + "object": { + "_type": "SubscriptExpr", + "object": { + "_type": "SubscriptExpr", + "object": { + "_type": "VariableExpr", + "name": "a" + }, + "index": { + "_type": "VariableExpr", + "name": "b" + } + }, + "index": { + "_type": "TupleExpr", + "items": [ + { + "_type": "VariableExpr", + "name": "c" + }, + { + "_type": "VariableExpr", + "name": "d" + } + ] + } + }, + "index": { + "_type": "SliceExpr", + "lower": { + "_type": "VariableExpr", + "name": "e" + }, + "upper": { + "_type": "VariableExpr", + "name": "f" + }, + "step": null + } + } + }, + { + "_type": "AssignStmt", + "targets": [ + { + "_type": "VariableExpr", + "name": "u" + } + ], + "value": { + "_type": "CallExpr", + "callee": { + "_type": "CallExpr", + "callee": { + "_type": "VariableExpr", + "name": "a" + }, + "arguments": [ + { + "_type": "VariableExpr", + "name": "b" + } + ], + "keywords": {} + }, + "arguments": [], + "keywords": { + "c": { + "_type": "VariableExpr", + "name": "d" + } + } + } + } + ] +} \ No newline at end of file diff --git a/tests/checker.py b/tests/checker.py index 3ceb34e..7a630c5 100644 --- a/tests/checker.py +++ b/tests/checker.py @@ -1,3 +1,4 @@ +import ast import json from dataclasses import asdict, dataclass, field from pathlib import Path @@ -6,17 +7,30 @@ import midas.ast.python as p from midas.checker.checker import TypeChecker from midas.checker.diagnostic import Diagnostic from midas.checker.types import Type +from midas.lexer.token import TokenType from tests.base import Tester from tests.serializer.python import PythonAstJsonSerializer +class CustomEncoder(json.JSONEncoder): + def default(self, o): + if isinstance(o, ast.AST): + return ast.dump(o) + if isinstance(o, TokenType): + return o.name + if o == ...: + return "..." + + return super().default(o) + + @dataclass class CaseResult: diagnostics: list[dict] = field(default_factory=list) judgments: list = field(default_factory=list) def dumps(self) -> str: - return json.dumps(asdict(self), indent=2) + return json.dumps(asdict(self), indent=2, cls=CustomEncoder) class CheckerTester(Tester): diff --git a/tests/generator.py b/tests/generator.py index f04992b..e272fe6 100644 --- a/tests/generator.py +++ b/tests/generator.py @@ -3,7 +3,6 @@ from dataclasses import dataclass from pathlib import Path from midas.checker.checker import TypeChecker -from midas.checker.diagnostic import DiagnosticType from midas.generator.generator import Generator from midas.utils import TypedAST from tests.base import Tester @@ -44,10 +43,11 @@ class GeneratorTester(Tester): typed_ast: TypedAST = checker.type_check(path) - if not any(d.type == DiagnosticType.ERROR for d in checker.diagnostics): - generator = Generator(workdir=path.parent, types=checker.types) - generator.set_src_path(path) - result.compiled_ast = generator.generate_ast(typed_ast) + # Ignore errors and generate anyway, easier here and errors should be + # covered by checker tests + generator = Generator(workdir=path.parent, types=checker.types) + generator.set_src_path(path) + result.compiled_ast = generator.generate_ast(typed_ast) return result diff --git a/tests/serializer/midas.py b/tests/serializer/midas.py index 599482b..38640f6 100644 --- a/tests/serializer/midas.py +++ b/tests/serializer/midas.py @@ -1,4 +1,4 @@ -from typing import Optional, Sequence +from typing import Optional, Sequence, final from midas.ast.midas import ( AliasStmt, @@ -28,6 +28,7 @@ from midas.ast.midas import ( ) +@final class MidasAstJsonSerializer( Stmt.Visitor[dict], Expr.Visitor[dict], Type.Visitor[dict] ): diff --git a/tests/serializer/python.py b/tests/serializer/python.py index 89a097c..dca4cb2 100644 --- a/tests/serializer/python.py +++ b/tests/serializer/python.py @@ -1,5 +1,5 @@ import ast -from typing import Optional, Sequence, Type +from typing import Optional, Sequence, Type, final from midas.ast.python import ( AssignStmt, @@ -78,6 +78,7 @@ boolean_ops: dict[Type[ast.boolop], str] = { } +@final class PythonAstJsonSerializer( Stmt.Visitor[dict], Expr.Visitor[dict], MidasType.Visitor[dict] ):