def test_interesting(self): func = function_lit( any_type(), infer_all(), match_op(dereference("argument"), [ prepared_function( object_type({"foo": int_type()}), return_op( addition_op(dereference("argument.foo"), literal_op(3)))), prepared_function(any_type(), return_op(literal_op("invalid"))) ])) _, result = bootstrap_function(func, argument=PythonObject( {"foo": 39}, bind=UniversalObjectType( {"foo": IntegerType()}))) self.assertEquals(result.caught_break_mode, "return") self.assertEquals(result.value, 42) _, result = bootstrap_function(func, argument=PythonObject({"foo": "hello"})) self.assertEquals(result.caught_break_mode, "return") self.assertEquals(result.value, "invalid")
def test_infer_all(self): _, result = bootstrap_function( function_lit(no_value_type(), infer_all(), return_op(literal_op(42)))) self.assertEquals(result.caught_break_mode, "return") self.assertEquals(result.value, 42)
def test_infer_exception(self): _, result = bootstrap_function(function_lit( no_value_type(), infer_all(), addition_op(literal_op("hello"), literal_op(5))), check_safe_exit=False) self.assertEquals(result.caught_break_mode, "exception") self.assertEquals(result.value.type, "TypeError")
def test_basic_with_inferred_local_type(self): _, result = bootstrap_function( function_lit( no_value_type(), infer_all(), inferred_type(), close_op( static_op( prepare_op( literal_op( function_lit(no_value_type(), infer_all(), return_op(literal_op(42)))))), context_op()), return_op( invoke_op( dereference_op(context_op(), literal_op("local"), True))))) self.assertEquals(result.caught_break_mode, "return") self.assertEquals(result.value, 42)
def test_unbound_reference_to_locals_and_arguments(self): _, result = bootstrap_function(function_lit( object_type({"foo": int_type()}), infer_all(), object_type({"bar": int_type()}), object_template_op({"bar": literal_op(3)}), return_op( addition_op(unbound_dereference("foo"), unbound_dereference("bar")))), argument=PythonObject({"foo": 39})) self.assertEquals(result.caught_break_mode, "return") self.assertEquals(result.value, 42)
def test_misc1(self): _, result = bootstrap_function( function_lit( no_value_type(), infer_all(), object_type({ "foo": int_type(), "bar": int_type() }), object_template_op({ "foo": literal_op(39), "bar": literal_op(3) }), return_op( addition_op(dereference("local.foo"), dereference("local.bar"))))) self.assertEquals(result.caught_break_mode, "return") self.assertEquals(result.value, 42)
def get_default_global_context(): return PythonObject( { "static": PythonObject( { "any": PythonObject({"type": "Any"}, debug_reason="default-global-context"), "int": PythonObject({"type": "Integer"}, debug_reason="default-global-context"), "bool": PythonObject({"type": "Boolean"}, debug_reason="default-global-context"), "string": PythonObject({"type": "String"}, debug_reason="default-global-context"), "void": PythonObject({"type": "NoValue"}, debug_reason="default-global-context"), "var": PythonObject({"type": "Inferred"}, debug_reason="default-global-context"), "range": prepare( function_lit( list_type([int_type(), int_type()], None), infer_all(), int_type(), dereference("argument.0"), prepared_function( loop_op( condition_op( binary_integer_op( "lt", dereference("outer.local"), dereference("outer.argument.1")), comma_op( shift_op( dereference("outer.local"), no_value_type()), assignment_op( dereference("outer"), literal_op("local"), addition_op( dereference("outer.local"), literal_op(1)))), transform_op("break"))))), NO_VALUE, FrameManager()).close(NO_VALUE), "list": prepare( function_lit( list_type([ function_type( no_value_type(), { "yield": list_template_op([ object_template_op( { "in": no_value_type(), "out": int_type() }) ]), "value": list_template_op([ object_template_op( {"out": no_value_type()}) ]), }), ], None), infer_all(), inferred_type(), dereference("argument.0"), loop_op( invoke_op( local_function( transform( ("yield", "value"), ("value", "end"), reset_op( dereference("outer.local"), nop())), comma_op( assignment_op( dereference("outer"), literal_op("local"), dereference( "local.continuation")), transform_op( "value", "continue", dereference("local.value")))))) ), NO_VALUE, FrameManager()).close(NO_VALUE), "max": prepare( function_lit( list_type([int_type()], int_type()), infer_all(), inferred_type(), dereference("argument.0"), comma_op( map_op( dereference("argument"), prepared_function( int_type(), condition_op( binary_integer_op( "gt", dereference("argument"), dereference("outer.local")), assignment_op( dereference("outer"), literal_op("local"), dereference("argument")), nop()))), dereference("local"))), NO_VALUE, FrameManager()).close(NO_VALUE), }, debug_reason="default-global-context") }, bind=DEFAULT_READONLY_COMPOSITE_TYPE, debug_reason="default-global-context")
def create(self, output_mode, debug_info): if output_mode not in ("first-class-function", "second-class-function", "expression"): raise FatalError() code_expressions = default(self.code_expressions, MISSING, []) for c in code_expressions: if not is_opcode(c): raise FatalError() if not self.requires_function() and output_mode == "expression": return combine_opcodes(code_expressions) if self.argument_type_expression is not MISSING: argument_type = self.argument_type_expression else: argument_type = no_value_type() if self.local_variable_type is not MISSING: local_type = self.local_variable_type else: local_type = object_type( {}) # For future python local variables... if self.local_initializer is not MISSING: local_initializer = self.local_initializer else: local_initializer = object_template_op({}) if self.breaks_types is not MISSING: break_types = self.breaks_types else: break_types = infer_all() if self.extra_statics is not MISSING: extra_statics = self.extra_statics else: extra_statics = {} if output_mode == "first-class-function": # A function created by the user, which mangles returns as expected code = transform_op("return", "value", combine_opcodes(code_expressions), **debug_info) return function_lit(extra_statics, argument_type, break_types, local_type, local_initializer, code, **debug_info) if output_mode == "second-class-function": # A function created by the environment, which leaves returns unmangled code = combine_opcodes(code_expressions) return function_lit(extra_statics, argument_type, break_types, local_type, local_initializer, code, **debug_info) elif output_mode == "expression": return invoke_op( prepare_function_lit( function_lit(extra_statics, argument_type, break_types, local_type, local_initializer, combine_opcodes(code_expressions), **debug_info), **debug_info), **debug_info)