def test_parallelism(): one_plus_one_ast = lex_and_parse("""(| add = (|| 1 + 1) |) add""") two_plus_two_ast = lex_and_parse("""(| add = (|| 2 + 2) |) add""") one_plus_one_ctx = one_plus_one_ast[0].compile(CodeContext()) two_plus_two_ctx = two_plus_two_ast[0].compile(CodeContext()) interpreter = Interpreter(universe=get_primitives()) one_plus_one_process = interpreter.add_process(one_plus_one_ctx) two_plus_two_process = interpreter.add_process(two_plus_two_ctx) assert not one_plus_one_process.finished assert not one_plus_one_process.result assert not two_plus_two_process.finished assert not two_plus_two_process.result interpreter.interpret() assert one_plus_one_process.finished assert one_plus_one_process.result == PrimitiveIntObject(2) assert two_plus_two_process.finished assert two_plus_two_process.result == PrimitiveIntObject(4)
def test_loop(self): source = """ (| benchmark = (| i <- 0. | [i < 1000] whileTrue: [ i: i + 1. ]. ). |) benchmark. """ universe = Object() universe.meta_add_slot("primitives", get_primitives()) interpreter = Interpreter(universe) run_stdlib(interpreter, stdlib_source) ast = lex_and_parse_as_root(source) if not ast: return None, interpreter code = ast.compile(CodeContext()) interpreter.add_process(code.finalize()) def f(): interpreter.interpret() return 0 #res = f() #assert res == 0 res = self.meta_interp(f, [], listops=True, listcomp=True, backendopt=True) assert res == 0
def compile(self, context): obj = ObjectRepresentation() obj.meta_set_ast(self) obj.meta_set_parameters(self.params) index = context.add_literal_obj(obj) context.add_bytecode(BYTECODE_PUSH_LITERAL) context.add_bytecode(LITERAL_TYPE_OBJ) context.add_bytecode(index) for name, value in self.slots.iteritems(): self._add_slot_to_bytecode(context, name, value) context.add_bytecode(SLOT_NORMAL) for name, value in self.parents.iteritems(): self._add_slot_to_bytecode(context, name, value) context.add_bytecode(SLOT_PARENT) if self.code: new_context = CodeContext() obj.meta_set_code_context(new_context) for item in self.code: item.compile(new_context) obj.map.code_context = new_context return context
def run_interactive(): _, interpreter = virtual_machine("()") while True: line = stdin_readline(":> ") if len(line) == 0 or line.strip() == "exit": writeln() return 0 try: for expr in lex_and_parse(line): code = expr.compile(CodeContext()) process = interpreter.add_process(code) interpreter.interpret() if process.finished_with_error: print "Error:", process.result.__str__() print print "Code object:" print print code.debug_repr() else: if process.result != NIL: print process.result.__str__() except ParsingError as e: ewriteln("Parse error.") if e.message: ewriteln(e.message) continue return 0
def compile(self, context): block = ObjectRepresentation() block.meta_set_ast(self) block.meta_set_parameters(self.params) # push current scope context.add_bytecode(BYTECODE_PUSH_SELF) index = context.add_literal_obj(block) context.add_bytecode(BYTECODE_PUSH_LITERAL) context.add_bytecode(LITERAL_TYPE_BLOCK) context.add_bytecode(index) for name, value in self.slots.iteritems(): self._add_slot_to_bytecode(context, name, value) context.add_bytecode(SLOT_NORMAL) for name, value in self.parents.iteritems(): self._add_slot_to_bytecode(context, name, value) context.add_bytecode(SLOT_PARENT) new_context = CodeContext() block.meta_set_code_context(new_context) for item in self.code: item.compile(new_context) block.map.code_context = new_context return context
def _restore_process(interpreter, _, parameters): obj = parameters[0] assert isinstance(obj, Object) if not isinstance(obj, ErrorObject): raise ValueError("This is not instance of error object!") obj.process_stack.push_frame(CodeContext(), NIL) # it is immediatelly poped anyway interpreter.restore_process(obj.process_stack) return None
def test_process_cycler(): c1 = CodeContext() pc = ProcessCycler(c1) assert pc.has_processes_to_run() pc.next_process() assert pc.process.frame.code_context is c1 pc.next_process() assert pc.process.frame.code_context is c1
def test_process_cycler_multiple_processes(): c1 = CodeContext() c2 = CodeContext() pc = ProcessCycler() assert not pc.has_processes_to_run() pc.add_process(c1) pc.add_process(c2) assert pc.has_processes_to_run() assert pc.process.frame.code_context is c1 pc.next_process() assert pc.process.frame.code_context is c1 pc.next_process() assert pc.process.frame.code_context is c2 pc.next_process() assert pc.process.frame.code_context is c1 pc.next_process() assert pc.process.frame.code_context is c2
def test_int_and_float(): ast = lex_and_parse("""(| add = (|| 1 + 1.5 ) |) add""") context = ast[0].compile(CodeContext()) interpreter = Interpreter(universe=get_primitives(), code_context=context) interpreter.interpret() assert interpreter.process.result == PrimitiveFloatObject(2.5)
def test_process_cycler_multiple_processes_remove_process(): c1 = CodeContext() c2 = CodeContext() pc = ProcessCycler() pc.add_process(c1) pc.add_process(c2) assert pc.process.frame.code_context is c1 pc.next_process() assert pc.process.frame.code_context is c1 pc.next_process() assert pc.process.frame.code_context is c2 pc.next_process() assert pc.process.frame.code_context is c1 pc.next_process() assert pc.process.frame.code_context is c2 pc.remove_active_process() assert pc.process.frame.code_context is c1
def test_resend_keyword(): ast = lex_and_parse("""(| p* = (| xex: a = (|| 1). |). q* = (| xex: a = (|| a). |). fetchXex = (|| q.xex: 2) |) fetchXex""") context = ast[0].compile(CodeContext()) interpreter = Interpreter(universe=get_primitives(), code_context=context) interpreter.interpret() assert interpreter.process.result == PrimitiveIntObject(2)
def test_interpreter(): ast = lex_and_parse("""(| a <- 1. add: b = (|| (a + 1) + b ) |) add: 2""") context = ast[0].compile(CodeContext()) interpreter = Interpreter(universe=get_primitives(), code_context=context) interpreter.interpret() assert interpreter.process.result == PrimitiveIntObject(4)
def test_setting_of_error_handler_works(): ast = lex_and_parse("""(| test = (|| primitives interpreter setErrorHandler: [:obj. :stack | obj printString. ] ) |) test""") context = ast[0].compile(CodeContext()) interpreter = Interpreter(universe=get_primitives(), code_context=context) interpreter.interpret()
def test_object_compilation(): ast = lex_and_parse(""" (| a = (| :var | var printLine. var). b <- nil. | nil.) """) assert len(ast) == 1 context = CodeContext() ast[0].compile(context)
def test_assignment_primitive(): ast = lex_and_parse("""(| a <- 0. incA = (|| a: 1. ^a ) |) incA""") context = ast[0].compile(CodeContext()) interpreter = Interpreter(universe=get_primitives(), code_context=context) interpreter.interpret() assert interpreter.process.result == PrimitiveIntObject(1)
def test_unhandled_error(): ast = lex_and_parse("""(| test = (|| primitives interpreter error: 'Test' ) |) test""") context = ast[0].compile(CodeContext()) interpreter = Interpreter(universe=get_primitives(), code_context=context) interpreter.interpret() assert interpreter.process.finished assert interpreter.process.finished_with_error assert interpreter.process.result == PrimitiveStrObject("Test")
def compile_file(path): with open(path) as f: try: ast = lex_and_parse_as_root(f.read()) code = ast.compile(CodeContext()) code.finalize() except ParsingError as e: ewriteln("Parse error.") if e.message: ewriteln(e.message) return 1 print code.debug_repr() return 0
def run_stdlib(interpreter, stdlib_source): stdlib_ast = lex_and_parse_as_root(stdlib_source) code = stdlib_ast.compile(CodeContext()) stdlib_process = interpreter.add_process(code.finalize()) interpreter.interpret() if stdlib_process.finished_with_error: ewriteln("Couldn't initialize stdlib:") ewriteln(stdlib_process.result.__str__()) ewriteln("\n") return False return True
def test_running_self_unittest_file(): universe = Object() universe.meta_add_slot("primitives", get_primitives()) dirname = os.path.dirname(__file__) source_file_path = os.path.join(dirname, "..", "scripts", "unittest.self") with open(source_file_path) as source_file: ast = lex_and_parse(source_file.read()) interpreter = Interpreter(universe) for item in ast: process = interpreter.add_process(item.compile(CodeContext())) interpreter.interpret() assert process.finished assert not process.finished_with_error
def test_set_error_handler_and_handle_error(): ast = lex_and_parse("""(| raiseError = (|| primitives interpreter error: 'Test'.). test = (|| primitives interpreter setErrorHandler: [:msg. :err | primitives interpreter restoreProcess: err With: 1. ]. ^ 1 + raiseError. ) |) test""") context = ast[0].compile(CodeContext()) interpreter = Interpreter(universe=get_primitives(), code_context=context) interpreter.interpret() assert interpreter.process.finished assert not interpreter.process.finished_with_error result = interpreter.process.result assert result == PrimitiveIntObject(2)
def test_block(): ast = lex_and_parse("""(| a <- 0. addTenToBlk: blk = (|| 10 + (blk value). ). add = (| tmp = 3. tmp_block. | tmp_block: [a + tmp]. a: 1. # block should reflect current scopes 2 + addTenToBlk: tmp_block. ) |) add""") context = ast[0].compile(CodeContext()) interpreter = Interpreter(universe=get_primitives(), code_context=context) interpreter.interpret() assert interpreter.process.result == PrimitiveIntObject(16)
def test_block_with_argument(): ast = lex_and_parse("""(| a <- 0. giveOneToBlock: blk = (|| blk with: 1 ). shouldBeThree = (| tmp = 1. block. | block: [| :x | a + tmp + x]. a: 1. giveOneToBlock: block. ) |) shouldBeThree""") context = ast[0].compile(CodeContext()) interpreter = Interpreter(universe=get_primitives(), code_context=context) interpreter.interpret() assert interpreter.process.result == PrimitiveIntObject(3)
def virtual_machine(source, stdlib_source=""): universe = Object() universe.meta_add_slot("primitives", get_primitives()) interpreter = Interpreter(universe) if stdlib_source: if not run_stdlib(interpreter, stdlib_source): return None, interpreter ast = lex_and_parse_as_root(source) if not ast: return None, interpreter code = ast.compile(CodeContext()) process = interpreter.add_process(code.finalize()) interpreter.interpret() return process, interpreter
def _run_script(interpreter, scope_parent, parameters): path = parameters[0] assert isinstance(path, Object) if not isinstance(path, PrimitiveStrObject): return _raise_error( interpreter, scope_parent, [PrimitiveStrObject("runScript: str parameter expected")] ) try: with open(path.value) as f: source = f.read() except Exception as e: return _raise_error( interpreter, scope_parent, [PrimitiveStrObject("runScript: %s" % str(e))] ) ast_root = lex_and_parse_as_root(source) if not ast_root.ast: return code = ast_root.compile(CodeContext()) code.finalize() method_obj = Object() method_obj.code_context = code interpreter._push_code_obj_for_interpretation( next_bytecode=0, # disable TCO scope_parent=scope_parent, method_obj=method_obj, parameters=[], )
def test_process_stack_push_frame_behavior(): ps = ProcessStack() ps.frame.push(PrimitiveIntObject(1)) assert not ps.is_nested_call() cc = CodeContext() method = Object() ps.push_frame(cc, method) assert ps.is_nested_call() assert ps.frame.code_context == cc retval = Object() ps.frame.push(retval) assert ps._length == 2 assert ps.frame._stack.obj == retval assert ps.frame.prev_stack._stack.obj != retval ps.pop_down_and_cleanup_frame() assert ps._length == 1 assert ps.frame._stack.obj == retval assert ps.frame.prev_stack is None
def test_has_code(): o = Object() assert not o.has_code o.map.code_context = CodeContext() assert o.has_code