def Loop_through_default_range_function___test(): env = PepEnvironment( None ) builtins.add_builtins( env ) loop_stmt1 = FakeStatement( "i" ) loop_stmt2 = FakeStatement( "i" ) stmt = PepFor( PepSymbol('int'), PepSymbol('i'), PepFunctionCall( PepSymbol( 'range' ), ( PepInt('0'), PepInt('4'), PepInt('1') ), ), ( loop_stmt1, loop_stmt2, ) ) stmt.evaluate( env ) assert_equal( ["0", "1", "2", "3"], loop_stmt1.evals ) assert_equal( ["0", "1", "2", "3"], loop_stmt2.evals )
def test_Define_and_call_fn_returning_void_unknown(): env = PepEnvironment( PepCppRenderer() ) add_builtins( env ) env.namespace["othernum"] = PepVariable( PepType( PepInt ), "othernum" ) fndecl = PepDef( PepSymbol( "void" ), PepSymbol( "myfunc" ), ( ( PepSymbol( "int" ), PepSymbol( "x" ) ), ( PepSymbol( "int" ), PepSymbol( "y" ) ) ), ( PepSymbol( "pass" ), ) ) assert_equal( render_evald( fndecl, env ), "" ) value = PepFunctionCall( PepSymbol( "myfunc" ), ( PepInt( "3" ), PepSymbol( "othernum" ) ) ) assert_equal( render_evald( value, env ), "myfunc( 3, othernum )" ) assert_multiline_equal( env.renderer._functions["myfunc"].values()[0][1], """void myfunc( int x, int y ) { } """ )
def Optional_arg_of_wrong_type_is_an_error___test(): env = PepEnvironment( PepCppRenderer() ) add_builtins( env ) def define_and_eval(): fndecl = PepDef( PepType( PepInt ), PepSymbol( "myfunc" ), ( ( PepType( PepInt ), PepSymbol( "x" ) ), ( PepType( PepInt ), PepSymbol( "y" ) ), ( PepType( PepInt ), PepSymbol( "z" ), PepString( "foo" ) ), ), ( PepReturn( PepSymbol( "z" ) ), ) ) fndecl.evaluate( env ) expected_error = ( r"""In function 'myfunc', the default for argument 'z' should be """ + r"""int, but it is string.""" ) # This is what we are testing: should throw as the default arg # has the wrong type assert_raises_regexp( PepUserErrorException, expected_error, define_and_eval )
def test_Call_fn_with_wrong_arg_type(): env = PepEnvironment( PepCppRenderer() ) add_builtins( env ) fndecl = PepDef( PepType( PepInt ), PepSymbol( "myfunc" ), ( ( PepType( PepInt ), PepSymbol( "x" ) ), ), ( PepPass(), ) ) assert_equal( render_evald( fndecl, env ), "" ) value = PepFunctionCall( PepSymbol( "myfunc" ), ( PepString( "zzz" ), ) ) expected_error = ( r"""For function 'myfunc', argument 'x' should be int, not string.""" ) # This is what we are testing: should throw as string is not int assert_raises_regexp( PepUserErrorException, expected_error, lambda: render_evald( value, env ) )
def test_Can_get_names_of_member_variables_from_def_init(): env = PepEnvironment( PepCppRenderer() ) add_builtins( env ) definit = PepDefInit( ( ( PepSymbol( "MyClass" ), PepSymbol( 'fooself' ) ), ), ( ( PepVar( ( PepInit( PepSymbol( "int" ), PepSymbol( "fooself.member_one" ), PepInt( 0 ) ), PepInit( PepSymbol( "float" ), PepSymbol( "fooself.member_two" ), PepFloat( 0.1 ) ), ) ), ) ), ).evaluate( env ) assert_equal( str( [ ( PepSymbol( "int" ).evaluate( env ), "member_one" ), ( PepSymbol( "float" ).evaluate( env ), "member_two" ) ] ), str( definit.get_member_variables( env ) ) )
def While_loop___test(): env = PepEnvironment( None ) builtins.add_builtins( env ) loop_stmt = FakeStatement( "k1" ) stmt1 = PepInit( PepSymbol('int'), PepSymbol('k1'), PepInt('1') ) stmt2 = PepWhile( PepLessThan( PepSymbol('k1'), PepInt('4') ), ( loop_stmt, PepModification( # Note: have to use a PepVariable here to make # PepModification work right. Needs more thought. PepSymbol('k1'), PepInt('1') ), ) ) stmt1.evaluate( env ) stmt2.evaluate( env ) assert_equal( ["1", "2", "3"], loop_stmt.evals )
def test_Not_allowed_non_self_inits_in_var(): env = PepEnvironment( PepCppRenderer() ) add_builtins( env ) definit = PepDefInit( ( ( PepSymbol( "MyClass" ), PepSymbol( 'barself' ) ), ), ( ( PepVar( ( PepInit( PepSymbol( "int" ), PepSymbol( "my_var" ), PepInt( 0 ) ), ) ), ) ), ) exception_caught = False try: definit.get_member_variables( env ) except PepUserErrorException, e: exception_caught = True assert_contains( str( e ), "'my_var' does not start with 'barself.'" )
def test_Must_provide_nonempty_variable_name_in_var(): env = PepEnvironment( PepCppRenderer() ) add_builtins( env ) definit = PepDefInit( ( ( PepSymbol( "MyClass" ), PepSymbol( 'self' ) ), ), ( ( PepVar( ( PepInit( PepSymbol( "int" ), PepSymbol( "self." ), PepInt( 0 ) ), ) ), ) ), ) exception_caught = False try: definit.get_member_variables( env ) except PepUserErrorException, e: exception_caught = True assert_contains( str( e ), "You must provide a variable name, not just 'self.'" )
def eval_program( prog ): env = PepEnvironment( PepCppRenderer() ) builtins.add_builtins( env ) res = None for ln in prog: res = env.render_value( ln.evaluate( env ) ) return res
def test_Print_string_renders_as_printf(): env = PepEnvironment( PepCppRenderer() ) builtins.add_builtins( env ) value = PepFunctionCall( PepSymbol( "print" ), ( PepString( "hello" ), ) ) assert_equal( value.render( env ), 'printf( "hello\\n" )' ) assert_equal( env.renderer._headers, [ "stdio.h" ] )
def Adding_floats_renders_as_plusequals___test(): env = PepEnvironment(PepCppRenderer()) builtins.add_builtins(env) PepInit(PepSymbol("float"), PepSymbol("z"), PepVariable(PepType(PepFloat), "z")).evaluate(env) stmt = PepModification(PepSymbol("z"), PepFloat("4.2")) assert_equal("z += 4.2", stmt.render(env))
def test_Overloaded_functions_supply_correct_return_type_based_on_args(): env = PepEnvironment( PepCppRenderer() ) add_builtins( env ) # Make a function taking ints, and another taking strings, with different # return types int_function = PepUserFunction( "int_function", PepType( PepFloat ), ( ( PepSymbol( "int" ), PepSymbol( "a1" ) ), ( PepSymbol( "int" ), PepSymbol( "a2" ) ), ), ( PepPass(), ) ) string_function = PepUserFunction( "string_function", PepType( PepInt ), ( ( PepSymbol( "string" ), PepSymbol( "b1" ) ), ( PepSymbol( "string" ), PepSymbol( "b2" ) ), ), ( PepPass(), ) ) # Make an overload list that consists of these 2 functions overload = PepFunctionOverloadList( [ int_function, string_function ] ) # Set up some variables to use as arguments env.namespace["i1"] = PepInt( "3" ) env.namespace["i2"] = PepInt( "4" ) env.namespace["s1"] = PepString( "s1" ) env.namespace["s2"] = PepString( "s2" ) s_i1 = PepSymbol( "i1" ) s_i2 = PepSymbol( "i2" ) s_s1 = PepSymbol( "s1" ) s_s2 = PepSymbol( "s2" ) # This is what we are testing: ask for the overload's return type, # supplying arguments to disambiguate which function we really mean assert_equal( PepType( PepFloat ), overload.return_type( ( s_i1, s_i2 ), env ) ) assert_equal( PepType( PepInt ), overload.return_type( ( s_s1, s_s2 ), env ) )
def assert_rendered_cpp_equals(expected, code_input): env = PepEnvironment(PepCppRenderer()) builtins.add_builtins(env) # make sys available eval_statement(env, "import sys") st = parse_statement(code_input) actual = st.render(env) assert_equal(expected, actual)
def Function_type_evaluates_to_PepFunctionType__test(): env = PepEnvironment( PepCppRenderer() ) builtins.add_builtins( env ) ans = eval_statement( env, "function( float, ( string, int ) )" ) assert_equal( PepFunctionType, ans.__class__ ) assert_equal( PepType( PepFloat ), ans.return_type ) assert_equal( PepTuple, ans.arg_types.__class__ ) assert_equal( PepType( PepString ), ans.arg_types.items[0] ) assert_equal( PepType( PepInt ), ans.arg_types.items[1] )
def test_Known_plus_argv(): env = PepEnvironment( PepCppRenderer() ) builtins.add_builtins( env ) value = PepFunctionCall( PepSymbol( "print" ), ( PepPlus( PepString( "known" ), PepArrayLookup( PepSysArgv(), PepInt( "1" ) ) ), ) ) assert_equal( value.render( env ), 'printf( "known%s\\n", argv[1] )' )
def PlusEquals_increases_int_value___test(): env = PepEnvironment( None ) builtins.add_builtins( env ) PepInit( PepSymbol('int'), PepSymbol('x'), PepInt('7') ).evaluate( env ) # Sanity assert_equal( "7", PepSymbol('x').evaluate( env ).value ) PepModification( PepSymbol('x'), PepInt('3') ).evaluate( env ) assert_equal( "10", PepSymbol('x').evaluate( env ).value )
def Builtin_implements_method_does_not_break_implements_check__test(): # At one point checking for an "implements" method was actually failing # because a global "implements" function existed - this test fails if # that happens. env = PepEnvironment( None ) add_builtins( env ) PepUserClass( name=PepSymbol( "MyClass" ), base_classes=(), body_stmts=( PepPass(), ) ).evaluate( env )
def test_Print_unknown_float_renders_as_percent_f(): env = PepEnvironment( PepCppRenderer() ) builtins.add_builtins( env ) init = PepInit( PepType( PepFloat ), PepSymbol( "f" ), PepVariable( PepType( PepFloat ), "f" ) ) init.evaluate( env ) value = PepFunctionCall( PepSymbol( "print" ), ( PepSymbol( "f" ), ) ) assert_equal( value.render( env ), 'printf( "%f\\n", f )' )
def test_single_statement_if(): env = PepEnvironment( PepCppRenderer() ) builtins.add_builtins( env ) # import sys # # if len( sys.argv ) > 1: # print sys.argv[1] impt = PepImport( "sys" ) ifstmt = PepIf( PepGreaterThan( PepFunctionCall( PepSymbol( "len" ), ( PepSymbol( "sys.argv" ), ) ), PepInt( "1" ) ), ( PepFunctionCall( PepSymbol( "print" ), ( PepArrayLookup( PepSymbol( "sys.argv" ), PepInt( "1" ) ), ), ), ), None ) program = ( impt, ifstmt ) assert_multiline_equal( env.render_exe( program ), """#include <stdio.h> int main( int argc, char* argv[] ) { if( (argc > 1) ) { printf( "%s\\n", argv[1] ); } return 0; } """ )
def PlusEquals_increases_float_value___test(): env = PepEnvironment( None ) builtins.add_builtins( env ) PepInit( PepSymbol('float'), PepSymbol('x'), PepFloat('7.2') ).evaluate( env ) # Sanity assert_equal( "7.2", PepSymbol('x').evaluate( env ).value ) PepModification( PepSymbol('x'), PepFloat('0.3') ).evaluate( env ) assert_equal( "7.5", PepSymbol('x').evaluate( env ).value )
def test_Print_unknown_bool_renders_as_percent_s_colon_op(): env = PepEnvironment( PepCppRenderer() ) builtins.add_builtins( env ) init = PepInit( PepType( PepBool ), PepSymbol( "b" ), PepVariable( PepType( PepBool ), "b" ) ) init.evaluate( env ) value = PepFunctionCall( PepSymbol( "print" ), ( PepSymbol( "b" ), ) ) assert_equal( value.render( env ), 'printf( "%s\\n", (b ? "True" : "False") )' )
def test_Init_with_arg_returns_new_instance_constructed_with_arg(): env = PepEnvironment( PepCppRenderer() ) add_builtins( env ) decl = PepClass( name=PepSymbol( "MyClass" ), base_classes=(), body_stmts=( PepDefInit( ( ( PepSymbol( "MyClass" ), PepSymbol( 'self' ) ), ( PepSymbol( "int" ), PepSymbol( 'a' ) ), ), ( ( PepVar( ( PepInit( PepSymbol( "int" ), PepSymbol( "self.x" ), PepSymbol( "a" ) ), ) ), ) ), ), ) ) assert_equal( "", render_evald( decl, env ) ) make_instance = PepInit( PepSymbol( "MyClass" ), PepSymbol( "my_instance" ), PepFunctionCall( PepSymbol( "MyClass.init" ), ( PepInt( "3" ), ) ) ) assert_equal( "", render_evald( make_instance, env ) ) value = PepSymbol( "my_instance.x" ) assert_equal( "3", render_evald( value, env ) )
def test_Hello_World(): env = PepEnvironment( PepCppRenderer() ) builtins.add_builtins( env ) value = PepFunctionCall( PepSymbol( "print" ), ( PepString( "Hello, World!" ), ) ) assert_multiline_equal( env.render_exe( ( value, ) ), """#include <stdio.h> int main( int argc, char* argv[] ) { printf( "Hello, World!\\n" ); return 0; } """ )
def Function_can_take_implements_MyInterface_as_param_type__test(): env = PepEnvironment( None ) builtins.add_builtins( env ) nmclass = make_nonmatching_class( env, "MyNmClass" ).evaluate( env ) mclass = make_matching_class( env ).evaluate( env ) myinterface = make_interface( env ).evaluate( env ) fn = PepUserFunction( "myfunc", PepType( PepVoid ), ( ( PepFunctionCall( PepSymbol( "implements" ), (PepSymbol( "MyInterface" ),) ), PepSymbol( "x" ) ), ), ( PepPass(), ) ).evaluate( env ) PepInit( PepSymbol( "MyNmClass" ), PepSymbol( "nm" ), PepFunctionCall( PepSymbol( 'MyNmClass.init' ), () ) ).evaluate( env ) PepInit( PepSymbol( "MyClass" ), PepSymbol( "m" ), PepFunctionCall( PepSymbol( 'MyClass.init' ), () ) ).evaluate( env ) # An instance of the non-matching class is not a valid argument assert_false( fn.args_match( ( PepSymbol("nm").evaluate( env ),), env ) ) # But an instance of the matching class is assert_true( fn.args_match( ( PepSymbol("m").evaluate( env ),), env ) )
def test_Echo_arg1(): env = PepEnvironment( PepCppRenderer() ) builtins.add_builtins( env ) # import sys # # def string getname( string name ): # return name # # print sys.argv[1] impt = PepImport( "sys" ) # fndef = PepDefine( PepSymbol( "getname" ), # PepUserFunction( # "getname", # PepType( PepString ), # ( # ( PepType( PepString ), PepSymbol( "name" ) ), # ), # ( # PepReturn( PepSymbol( "name" ) ), # ) # ) # ) fncall = PepFunctionCall( PepSymbol( "print" ), ( PepArrayLookup( PepSymbol( "sys.argv" ), PepInt( "1" ) ), ) ) program = ( impt, fncall ) assert_multiline_equal( env.render_exe( program ), """#include <stdio.h> int main( int argc, char* argv[] ) { printf( "%s\\n", argv[1] ); return 0; } """ )
def test_Call_overloaded_fn_with_wrong_num_args(): env = PepEnvironment( PepCppRenderer() ) add_builtins( env ) fndecl1 = PepDef( PepType( PepVoid ), PepSymbol( "myfunc" ), ( ( PepType( PepInt ), PepSymbol( "x" ) ), ), ( PepPass(), ) ) fndecl2 = PepDef( PepType( PepVoid ), PepSymbol( "myfunc" ), ( ( PepType( PepFloat ), PepSymbol( "x" ) ), ( PepType( PepFloat ), PepSymbol( "y" ) ), ), ( PepPass(), ) ) render_evald( fndecl1, env ) render_evald( fndecl2, env ) value = PepFunctionCall( PepSymbol( "myfunc" ), () ) expected_error = r"""No overload of function myfunc matches the supplied arguments. You supplied: \(\) but the only allowed argument lists are: \(int x\) \(float x, float y\) """ # This is what we are testing: should throw as no args supplied assert_raises_regexp( PepUserErrorException, expected_error, lambda: render_evald( value, env ) )
def test_Can_get_names_of_member_variables_from_class(): env = PepEnvironment( PepCppRenderer() ) add_builtins( env ) cls = PepUserClass( name="MyClass", base_classes=(), body_stmts=( PepDefInit( ( ( PepSymbol( "MyClass" ), PepSymbol( 'self' ) ), ), ( ( PepVar( ( PepInit( PepSymbol( "int" ), PepSymbol( "self.member_one" ), PepInt( 0 ) ), PepInit( PepSymbol( "float" ), PepSymbol( "self.member_two" ), PepFloat( 0.1 ) ), ) ), ) ), ), ) ).evaluate( env ) assert_equal( str( [ ( PepSymbol( "int" ).evaluate( env ), "member_one" ), ( PepSymbol( "float" ).evaluate( env ), "member_two" ) ] ), str( cls.member_variables ) )
def Loop_through_stepped_range_function___test(): env = PepEnvironment( None ) builtins.add_builtins( env ) loop_stmt = FakeStatement( "k1" ) stmt = PepFor( PepSymbol('int'), PepSymbol('k1'), PepFunctionCall( PepSymbol( 'range' ), ( PepInt('0'), PepInt('4'), PepInt('2') ), ), ( loop_stmt, ) ) stmt.evaluate( env ) assert_equal( ["0", "2"], loop_stmt.evals )
def test_evaluate_method_call_unquotes(): env = PepEnvironment( PepCppRenderer() ) add_builtins( env ) # code mycode = quote: # 98 quoting_stmt = PepInit( PepSymbol('code'), PepSymbol('mycode'), PepQuote( ( PepInt('98'), ) ) ) # mycode.evaluate() unquoting_stmt = PepFunctionCall( PepSymbol( "mycode.evaluate" ), () ) quoting_stmt.evaluate( env ) ans = unquoting_stmt.evaluate( env ) assert_equal( PepInt, type( ans ) ) assert_equal( '98', ans.value )
def Signature_with_types_that_need_evaluating_matches_args_that_dont___test(): env = PepEnvironment( PepCppRenderer() ) add_builtins( env ) fn = PepUserFunction( "myfn", PepSymbol( "float" ), ( ( PepSymbol( "int" ), PepSymbol( "a1" ) ), ( PepType( PepInt ), PepSymbol( "a2" ) ), ), ( PepPass(), ) ) overloads = PepFunctionOverloadList( ( fn, ) ) args = ( ( PepType( PepInt ), "z1" ), ( PepSymbol( "int" ), "z2" ), ) assert_true( fn.signature_matches( PepType( PepFloat ), args, env ) )