def function_factory(name, args, defaults, flag=0, doc=None): """create and initialize a astng Function node""" func = Function(name, args, defaults, flag, doc, None) del func.code func.body = [] args_compiler_to_ast(func) return func
def function_factory(name, args, defaults, flag=0, doc=None): """create and initialize a astng Function node""" # first argument is now a list of decorators func = Function(Decorators([]), name, args, defaults, flag, doc, None) del func.code func.body = [] args_compiler_to_ast(func) return func
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_trait_with_functions(): source = """ trait List { function length(self: List): i32; function sum(self: List): i32; } """ 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=[], functions=[], ), )
def test_function_call_with_no_arguments(): source = """ import System::Output; function sayNumber(): void { println(value=1337); } export function Main(): void { sayNumber(); } """ result = get_ast(source) assert_equal_programs( result, Program( imports=[Import(value="System::Output")], traits=[], data_defs=[], functions=[ Function( name="sayNumber", is_exported=False, params=[], type=types.Placeholder(text="void"), body=[ FunctionCall( name="println", arguments=[ Argument(name="value", value=Number(1337)) ], ) ], ), Function( name="Main", is_exported=True, params=[], type=types.Placeholder(text="void"), body=[FunctionCall(name="sayNumber", arguments=[])], ), ], ), )
def test_if_else_statement(): source = """ import System::Output; export function Main(): void { if (5 < 10) { println(value=1); } else { println(value=0); } } """ result = get_ast(source) assert_equal_programs( result, Program( imports=[Import(value="System::Output")], traits=[], data_defs=[], functions=[ Function( name="Main", is_exported=True, params=[], type=types.Placeholder(text="void"), body=[ If( condition=BinaryOperation( operator=BinaryOperator.LESS_THAN, left=Number(5), right=Number(10), ), then_statements=[ FunctionCall( name="println", arguments=[ Argument(name="value", value=(Number(1))) ], ) ], else_statements=[ FunctionCall( name="println", arguments=[ Argument(name="value", value=(Number(0))) ], ) ], ) ], ) ], ), )
def parse_function(self): self.match("fun") self.expect("id") name = self.previous_token["data"] self.expect("lparen") params = [] if self.match("id"): params.append(self.previous_token["data"]) while self.match("comma"): self.expect("id") params.append(self.previous_token["data"]) ### send only id self.expect("rparen") statements = self.parse_block() return Function(name, params, statements)
def test_simple_expression(): source = """ import System::Output; export function Main(): void { println(value=1 + 2 * 3); } """ result = get_ast(source) assert_equal_programs( result, Program( imports=[Import(value="System::Output")], traits=[], data_defs=[], functions=[ Function( name="Main", is_exported=True, params=[], type=types.Placeholder(text="void"), body=[ FunctionCall( name="println", arguments=[ Argument( name="value", value=BinaryOperation( operator=BinaryOperator.ADD, left=Number(value=1), right=BinaryOperation( operator=BinaryOperator.MULTIPLY, left=Number(value=2), right=Number(value=3), ), ), ) ], ) ], ) ], ), )
def test_simple_assignment(): source = """ import System::Output; export function Main(): void { let a = 5; let b = 10; println(value=a + b); } """ result = get_ast(source) assert_equal_programs( result, Program( imports=[Import(value="System::Output")], traits=[], data_defs=[], functions=[ Function( name="Main", is_exported=True, params=[], type=types.Placeholder(text="void"), body=[ Let(name="a", value=Number(5)), Let(name="b", value=Number(10)), FunctionCall( name="println", arguments=[ Argument( name="value", value=BinaryOperation( operator=BinaryOperator.ADD, left=Variable(name="a"), right=Variable(name="b"), ), ) ], ), ], ) ], ), )
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_function(self, function: ast.Function): """ Visit the function definition, populating the return and param type information. During this stage the function body is skipped, as it may depend on types defined later within the file """ param_types = [] for param in function.params: param.type = types.Param( name=param.name, type=as_language_type(param.type, self.symbol_table) ) param_types.append(param.type) function.type = types.Function( name=function.name, result=as_language_type(function.type, self.symbol_table), params=param_types, ) function_symbol = Symbol( name=function.name, type=function.type, kind=SymbolKind.FUNC ) self.symbol_table.add(function_symbol) return function
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_factorial(): source = """ import System::Output; function factorial(n: i32): i32 { if (n == 1) { return 1; } else { return n * factorial(n=n-1); } } export function Main(): void { println(value=factorial(n=5)); } """ result = get_ast(source) assert_equal_programs( result, Program( imports=[Import(value="System::Output")], traits=[], data_defs=[], functions=[ Function( name="factorial", is_exported=False, params=[ Param(name="n", type=types.Placeholder(text="i32")) ], type=types.Placeholder(text="i32"), body=[ If( condition=BinaryOperation( operator=BinaryOperator.EQUALS, left=Variable("n"), right=Number(1), ), then_statements=[Return(value=Number(value=1))], else_statements=[ Return(value=BinaryOperation( operator=BinaryOperator.MULTIPLY, left=Variable(name="n"), right=FunctionCall( name="factorial", arguments=[ Argument( name="n", value=BinaryOperation( operator=BinaryOperator. SUBTRACT, left=Variable(name="n"), right=Number(value=1), ), ) ], ), )) ], ) ], ), Function( name="Main", is_exported=True, params=[], type=types.Placeholder(text="void"), body=[ FunctionCall( name="println", arguments=[ Argument( name="value", value=FunctionCall( name="factorial", arguments=[ Argument(name="n", value=(Number(5))) ], ), ) ], ) ], ), ], ), )
def __get_ast(self): from compiler.ast import Module, Stmt, Assign, AssName, Const, Function, For, Getattr,\ TryFinally, TryExcept, If, Import, AssAttr, Name, CallFunc,\ Class, Compare, Raise, And, Mod, Tuple, Pass, Not, Exec, List,\ Discard, Keyword, Return, Dict, Break, AssTuple, Subscript,\ Printnl, From, Lambda preppyNodes = self.__parse() if self._defSeen == 1: fixargs = self._fnc_argnames defaults = list(self._fnc_defaults) if self._fnc_kwargs: spargs = [fixargs[-1]] fixargs = fixargs[:-1] else: spargs = ['__kwds__'] if self._fnc_varargs: spargs.insert(0, fixargs[-1]) fixargs = fixargs[:-1] kwargs = fixargs[-len(defaults):] fixargs = fixargs[:-len(defaults)] flags = self._fnc_flags #construct the getOutput function nodes = [ Assign([AssName('__lquoteFunc__', 'OP_ASSIGN')], CallFunc(Getattr(Name(spargs[-1]), 'setdefault'), [Const('__lquoteFunc__'), Name('str')], None, None)), Discard( CallFunc(Getattr(Name(spargs[-1]), 'pop'), [Const('__lquoteFunc__')], None, None)), Assign([AssName('__quoteFunc__', 'OP_ASSIGN')], CallFunc(Getattr(Name(spargs[-1]), 'setdefault'), [Const('__quoteFunc__'), Name('str')], None, None)), Discard( CallFunc(Getattr(Name(spargs[-1]), 'pop'), [Const('__quoteFunc__')], None, None)) ] if not self._fnc_kwargs: nodes += [ If([(Name(spargs[-1]), Stmt([ Raise( CallFunc(Name('TypeError'), [ Const('get: unexpected keyword arguments') ], None, None), None, None) ]))], None) ] nodes += [ Assign([AssName('__append__', 'OP_ASSIGN')], Getattr(List(()), 'append')), Assign([AssName('__write__', 'OP_ASSIGN')], Lambda(['x'], [], 0, CallFunc(Name('__append__'), [ CallFunc(Name('__lquoteFunc__'), [Name('x')], None, None) ], None, None))), Assign([AssName('__swrite__', 'OP_ASSIGN')], Lambda(['x'], [], 0, CallFunc(Name('__append__'), [ CallFunc(Name('__quoteFunc__'), [Name('x')], None, None) ], None, None))) ] for n in nodes: _denumber(n, self._fnc_lineno) preppyNodes = nodes + preppyNodes + [ Return( CallFunc(Getattr(Const(''), 'join'), [Getattr(Name('__append__'), '__self__')], None, None)) ] argnames = list(fixargs) + list(kwargs) + list(spargs) FA = ('get', argnames, defaults, flags | 8, None, Stmt(preppyNodes)) global _newPreambleAst if not _newPreambleAst: _newPreambleAst = self._cparse(_newPreamble).node.nodes map(_denumber, _newPreambleAst) extraAst = _newPreambleAst else: global _preambleAst, _localizer if not _preambleAst: _preambleAst = self._cparse(_preamble).node.nodes map(_denumber, _preambleAst) _localizer = [ Assign([AssName('__d__', 'OP_ASSIGN')], Name('dictionary')), Discard( CallFunc( Getattr(CallFunc(Name('globals'), [], None, None), 'update'), [Name('__d__')], None, None)) ] preppyNodes = _localizer + preppyNodes FA = ('__code__', [ 'dictionary', 'outputfile', '__write__', '__swrite__', '__save_sys_stdout__' ], (), 0, None, Stmt(preppyNodes)) extraAst = _preambleAst if sys.hexversion >= 0x2040000: FA = (None, ) + FA return Module( self.filename, Stmt([ Assign([AssName('__checksum__', 'OP_ASSIGN')], Const(getattr(self, 'sourcechecksum'))), Function(*FA), ] + extraAst))
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=[], ), )
def func(state, p): return Function(self.cg, state, p[0], p[2], p[4])
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_function_call_with_arguments(): source = """ import System::Output; function add(x: i32, y: i32): i32 { x + y; } export function Main(): void { println(value=add(a=5, b=15)); } """ result = get_ast(source) assert_equal_programs( result, Program( imports=[Import(value="System::Output")], traits=[], data_defs=[], functions=[ Function( name="add", is_exported=False, params=[ Param(name="x", type=types.Placeholder(text="i32")), Param(name="y", type=types.Placeholder(text="i32")), ], type=types.Placeholder(text="i32"), body=[ BinaryOperation( operator=BinaryOperator.ADD, left=Variable("x"), right=Variable("y"), ) ], ), Function( name="Main", is_exported=True, params=[], type=types.Placeholder(text="void"), body=[ FunctionCall( name="println", arguments=[ Argument( name="value", value=(FunctionCall( name="add", arguments=[ Argument(name="a", value=Number(value=5)), Argument(name="b", value=Number(value=15)), ], )), ) ], ) ], ), ], ), )