def test_data_vector_with_simple_function(): source = """ import System::Output; export data Vector(x: i32, y: i32) { function length(): i32 { 42; } } export function Main(): void { } """ result = get_ast(source) assert_equal_programs( result, Program( imports=[Import(value="System::Output")], traits=[], data_defs=[ DataDef( name="Vector", implements=[], type=types.Placeholder(text="Vector"), is_exported=True, params=[ Param(name="x", type=types.Placeholder(text="i32")), Param(name="y", type=types.Placeholder(text="i32")), ], functions=[ Function( name="length", is_exported=False, params=[], type=types.Placeholder(text="i32"), body=[Number(value=42)], ) ], ) ], functions=[ Function( name="Main", is_exported=True, params=[], type=types.Placeholder(text="void"), body=[], ) ], ), )
def test_empty_data(): source = """ import System::Output; export data Empty() export function Main(): void { } """ result = get_ast(source) assert_equal_programs( result, Program( imports=[Import(value="System::Output")], traits=[], data_defs=[ DataDef( name="Empty", implements=[], type=types.Placeholder(text="Empty"), is_exported=True, params=[], functions=[], ) ], functions=[ Function( name="Main", is_exported=True, params=[], type=types.Placeholder(text="void"), body=[], ) ], ), )
def visit_data_def(self, data: ast.DataDef): implements = [] for implement in data.implements: implements.append(types.TypeRef(name=implement)) data_def_type = types.Data( name=data.name, implements=implements, fields=[], functions=[] ) data.type = data_def_type self.symbol_table.add( Symbol(name=data.name, type=data_def_type, kind=SymbolKind.DATA) ) for field in data.params: field.type = types.Field( name=field.name, type=as_language_type(field.type, self.symbol_table) ) data_def_type.fields.append(field.type) self.symbol_table = self.symbol_table.enter_scope() for function in data.functions: function.accept(self) self.symbol_table = self.symbol_table.exit_scope() return data
def test_trait_with_single_implementation(): source = """ trait List { function length(self: List): i32; function sum(self: List): i32; } data EmptyList() implements List { function length(self: List): i32 { 0; } function sum(self: List): i32 { 0; } } """ result = get_ast(source) assert_equal_programs( result, Program( imports=[], traits=[ Trait( name="List", is_exported=False, type=types.Placeholder("List"), functions=[ Function( name="length", is_exported=False, params=[ Param(name="self", type=types.Placeholder(text="List")) ], type=types.Placeholder(text="i32"), body=None, ), Function( name="sum", is_exported=False, params=[ Param(name="self", type=types.Placeholder(text="List")) ], type=types.Placeholder(text="i32"), body=None, ), ], ) ], data_defs=[ DataDef( name="EmptyList", is_exported=False, implements=["List"], params=[], functions=[ Function( name="length", is_exported=False, params=[ Param(name="self", type=types.Placeholder(text="List")) ], type=types.Placeholder(text="i32"), body=[Number(value=0)], ), Function( name="sum", is_exported=False, params=[ Param(name="self", type=types.Placeholder(text="List")) ], type=types.Placeholder(text="i32"), body=[Number(value=0)], ), ], type=types.Placeholder(text="EmptyList"), ) ], functions=[], ), )
def test_data_vector_with_complex_function(): source = """ import System::Output; export data Vector(x: i32, y: i32) { function add(self: Vector, other: Vector): Vector { Vector(x = self.x + other.x, y = self.y + other.y); } } export function Main(): void { } """ result = get_ast(source) assert_equal_programs( result, Program( imports=[Import(value="System::Output")], traits=[], data_defs=[ DataDef( name="Vector", implements=[], type=types.Placeholder(text="Vector"), is_exported=True, params=[ Param(name="x", type=types.Placeholder(text="i32")), Param(name="y", type=types.Placeholder(text="i32")), ], functions=[ Function( name="add", is_exported=False, params=[ Param(name="self", type=types.Placeholder(text="Vector")), Param(name="other", type=types.Placeholder(text="Vector")), ], type=types.Placeholder(text="Vector"), body=[ FunctionCall( name="Vector", arguments=[ Argument( name="x", value=BinaryOperation( operator=BinaryOperator.ADD, left=MemberAccess( value=Variable("self"), member="x"), right=MemberAccess( value=Variable("other"), member="x"), ), ), Argument( name="y", value=BinaryOperation( operator=BinaryOperator.ADD, left=MemberAccess( value=Variable("self"), member="y"), right=MemberAccess( value=Variable("other"), member="y"), ), ), ], ) ], ) ], ) ], functions=[ Function( name="Main", is_exported=True, params=[], type=types.Placeholder(text="void"), body=[], ) ], ), )
def test_data_vector_with_simple_function_call(): source = """ import System::Output; export data Vector(x: i32, y: i32) { function length(): i32 { 42; } } export function Main(): void { let vector = Vector(x=10, y=20); println(value=vector.length()); } """ result = get_ast(source) assert_equal_programs( result, Program( imports=[Import(value="System::Output")], traits=[], data_defs=[ DataDef( name="Vector", implements=[], type=types.Placeholder(text="Vector"), is_exported=True, params=[ Param(name="x", type=types.Placeholder(text="i32")), Param(name="y", type=types.Placeholder(text="i32")), ], functions=[ Function( name="length", is_exported=False, params=[], type=types.Placeholder(text="i32"), body=[Number(value=42)], ) ], ) ], functions=[ Function( name="Main", is_exported=True, params=[], type=types.Placeholder(text="void"), body=[ Let( name="vector", value=FunctionCall( name="Vector", arguments=[ Argument(name="x", value=Number(value=10)), Argument(name="y", value=Number(value=20)), ], ), ), FunctionCall( name="println", arguments=[ Argument( name="value", value=FunctionCall(name="vector.length", arguments=[]), ) ], ), ], ) ], ), )
def test_trait_with_multiple_implementations(): source = """ trait List { function length(self: List): i32; function sum(self: List): i32; } data EmptyList() implements List { function length(self: List): i32 { 0; } function sum(self: List): i32 { 0; } } data Cons(head: i32, tail: List) implements List { function length(self: List): i32 { 1 + self.tail.length(); } function sum(self: List): i32 { self.head + self.tail.sum(); } } """ result = get_ast(source) assert_equal_programs( result, Program( imports=[], traits=[ Trait( name="List", is_exported=False, functions=[ Function( name="length", is_exported=False, params=[ Param(name="self", type=types.Placeholder(text="List")) ], type=types.Placeholder(text="i32"), body=None, ), Function( name="sum", is_exported=False, params=[ Param(name="self", type=types.Placeholder(text="List")) ], type=types.Placeholder(text="i32"), body=None, ), ], type=types.Placeholder(text="List"), ) ], data_defs=[ DataDef( name="EmptyList", is_exported=False, implements=["List"], params=[], functions=[ Function( name="length", is_exported=False, params=[ Param(name="self", type=types.Placeholder(text="List")) ], type=types.Placeholder(text="i32"), body=[Number(value=0)], ), Function( name="sum", is_exported=False, params=[ Param(name="self", type=types.Placeholder(text="List")) ], type=types.Placeholder(text="i32"), body=[Number(value=0)], ), ], type=types.Placeholder(text="EmptyList"), ), DataDef( name="Cons", is_exported=False, implements=["List"], params=[ Param(name="head", type=types.Placeholder(text="i32")), Param(name="tail", type=types.Placeholder(text="List")), ], functions=[ Function( name="length", is_exported=False, params=[ Param(name="self", type=types.Placeholder(text="List")) ], type=types.Placeholder(text="i32"), body=[ BinaryOperation( operator=BinaryOperator.ADD, left=Number(value=1), right=FunctionCall(name="self.tail.length", arguments=[]), ) ], ), Function( name="sum", is_exported=False, params=[ Param(name="self", type=types.Placeholder(text="List")) ], type=types.Placeholder(text="i32"), body=[ BinaryOperation( operator=BinaryOperator.ADD, left=MemberAccess( value=Variable(name="self"), member="head"), right=FunctionCall(name="self.tail.sum", arguments=[]), ) ], ), ], type=types.Placeholder(text="Cons"), ), ], functions=[], ), )