def test_meta_remove_slot_shift_map_pointers(): first = PrimitiveStrObject("first") second = PrimitiveStrObject("second") third = PrimitiveStrObject("third") o = Object() assert not o._slot_values o.meta_add_slot("first", first) o.meta_add_slot("second", second) o.meta_add_slot("third", third) assert o.get_slot("first") is first assert o.get_slot("second") is second assert o.get_slot("third") is third o.meta_remove_slot("first") assert len(o._slot_values) == 2 assert len(o.map._slots) == 2 assert o.map._slots["second"] == 0 assert o.map._slots["third"] == 1 assert o.get_slot("first") is None assert o.get_slot("second") == second assert o.get_slot("third") == third
def test_meta_add_parent_structural_change_creates_new_map_add(): o = Object() o.meta_add_parent("a", PrimitiveStrObject("value")) x = o.clone() assert o.map == x.map x.meta_add_parent("*", PrimitiveStrObject("another")) assert o.map != x.map assert o != x
def test_meta_add_parent_cloned_objects_dont_change_when_parent_is_changed(): o = Object() o.meta_add_parent("a", PrimitiveStrObject("value")) x = o.clone() assert o.map == x.map x.meta_add_parent("a", PrimitiveStrObject("another")) assert o.map == x.map assert o != x
def test_meta_add_slot_do_check_duplicates(): xx = PrimitiveStrObject("xx") zz = PrimitiveStrObject("zz") o = Object() assert not o._slot_values o.meta_add_slot("xx", xx) o.meta_add_slot("zz", zz) assert len(o._slot_values) == 2 o.meta_add_slot("xx2", xx, check_duplicates=True) assert len(o._slot_values) == 2
def slot_lookup(): val = PrimitiveStrObject("it is xex!") flat = PrimitiveStrObject("it is flat") p = Object() p.meta_add_slot("xex", val) o = Object() o.meta_add_parent("p", p) o.meta_add_parent("p", flat) assert o.get_slot("xex") is None assert o.slot_lookup("xex") is val assert o.slot_lookup("flat") is flat
def test_parent_lookup_from_parent_tree(): """ Based on real case. """ value = PrimitiveStrObject("value") o1 = Object() o2 = Object() o3 = o2.clone() o4 = Object() o5 = Object() o1.scope_parent = o2 o2.scope_parent = o3 o2.meta_add_parent("*", o5) o3.scope_parent = o4 o3.meta_add_parent("*", o5) o4.scope_parent = o5 o4.meta_add_slot("value", value) assert o1.get_slot("value") is None assert o1.parent_lookup("value") is value
def test_PrimitiveIntObject_as_primitive_string(): o = PrimitiveIntObject(2) plus_slot = o.slot_lookup("asString") assert plus_slot.map.primitive_code result = plus_slot.map.primitive_code(None, o, []) assert result == PrimitiveStrObject("2")
def _do_push_literal(self, bc_index, code_obj): literal_type = ord(code_obj.bytecodes[bc_index + 1]) literal_index = ord(code_obj.bytecodes[bc_index + 2]) boxed_literal = code_obj.literals[literal_index] if literal_type == LITERAL_TYPE_NIL: obj = NIL elif literal_type == LITERAL_TYPE_ASSIGNMENT: obj = AssignmentPrimitive() elif literal_type == LITERAL_TYPE_INT: assert isinstance(boxed_literal, IntBox) obj = PrimitiveIntObject(boxed_literal.value) elif literal_type == LITERAL_TYPE_FLOAT: assert isinstance(boxed_literal, FloatBox) obj = PrimitiveFloatObject(boxed_literal.value) elif literal_type == LITERAL_TYPE_STR: assert isinstance(boxed_literal, StrBox) obj = PrimitiveStrObject(boxed_literal.value) elif literal_type == LITERAL_TYPE_OBJ: assert isinstance(boxed_literal, ObjBox) obj = boxed_literal.value.clone() if self.process.frame.self is None: self.process.frame.self = obj elif literal_type == LITERAL_TYPE_BLOCK: assert isinstance(boxed_literal, ObjBox) block = boxed_literal.value.clone() obj = add_block_trait(block) block.is_block = True block.scope_parent = self.process.frame.pop() else: raise ValueError("Unknown literal type; %s" % literal_type) self.process.frame.push(obj) return THREE_BYTECODES_LONG
def test_get_slot_from_several_parents(): """ o.parents | |-- p <-- cycle, yay --, | |-- x -> Object() | | |-- y -> Object() | | `-- z -> p --------' | `-- p3 `-- x -> p2 | `-- xex """ val = PrimitiveStrObject("it is xex!") p = Object() p.meta_add_slot("x", Object()) p.meta_add_slot("y", Object()) p.meta_add_slot("z", p) # cycle, yay! p2 = Object() p.meta_add_slot("xex", val) p3 = Object() p.meta_add_slot("x", p2) o = Object() o.meta_add_parent("p", p) o.meta_add_parent("p3", p3) assert o.get_slot("xex") is None assert o.parent_lookup("xex") is val
def test_meta_add_slot(): val = PrimitiveStrObject("xe") o = Object() assert not o._slot_values o.meta_add_slot("test", val) assert o._slot_values[0] == val
def test_meta_add_parent_cloned_objects_use_same_map(): o = Object() o.meta_add_parent("a", PrimitiveStrObject("value")) x = o.clone() assert "a" in o.parent_slot_keys assert o.map == x.map
def test_meta_remove_parent(): a_slot = PrimitiveStrObject("value a") b_slot = PrimitiveStrObject("value b") o = Object() o.meta_add_parent("a", a_slot) o.meta_add_parent("b", b_slot) assert "a" in o.parent_slot_keys assert "b" in o.parent_slot_keys assert o.meta_get_parent("a") is a_slot assert o.meta_get_parent("b") is b_slot o.meta_remove_parent("a") assert o.meta_get_parent("b") is b_slot assert len(o._parent_slot_values) == 1
def test_slot_lookup_from_scope_parent(): p = Object() val = PrimitiveStrObject("it is xex!") p.meta_add_slot("xex", val) o = Object() o.scope_parent = p assert o.get_slot("xex") is None assert o.slot_lookup("xex") is val
def test_get_slot_from_one_parent(): val = PrimitiveStrObject("it is xex!") p = Object() p.meta_add_slot("xex", val) o = Object() o.meta_add_parent("p", p) assert o.get_slot("xex") is None assert o.parent_lookup("xex") is val
def test_meta_insert_slot(): first = PrimitiveStrObject("first") second = PrimitiveStrObject("second") third = PrimitiveStrObject("third") o = Object() assert not o._slot_values o.meta_add_slot("first", first) o.meta_add_slot("third", third) assert o.get_slot("first") is first assert o.get_slot("third") is third o.meta_insert_slot(1, "second", second) assert o.map._slots.keys() == ["first", "second", "third"] # make sure that objects didn't shifted assert o.get_slot("first") is first assert o.get_slot("second") is second assert o.get_slot("third") is third
def test_meta_add_parent_structural_change_creates_new_map_remove(): o = Object() o.meta_add_parent("a", PrimitiveStrObject("value")) x = o.clone() assert o.map == x.map x.meta_remove_parent("a") assert o.map != x.map assert o != x assert "a" in o.parent_slot_keys
def test_slot_lookup_from_scope_parent_and_then_parents(): p = Object() val = PrimitiveStrObject("it is xex!") p.meta_add_slot("a", val) interobj = Object() interobj.scope_parent = p o = Object() o.scope_parent = Object() o.scope_parent.meta_add_parent("*", interobj) assert o.slot_lookup("a") is val
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_mirror(): o = Object() m = Mirror(o) assert not o.slot_lookup("v") add_primitive = m.slot_lookup("toSlot:Add:") assert add_primitive.map.primitive_code result = add_primitive.map.primitive_code( None, m, [PrimitiveStrObject("v"), PrimitiveIntObject(1)]) assert result == o assert o.slot_lookup("v") == 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 test_get_slot(): o = Object() val = PrimitiveStrObject("xe") o.meta_add_slot("test", val) assert o.get_slot("test") is val
def test_set_slot(): o = Object() o.meta_add_slot("test", PrimitiveStrObject("xe")) assert o.set_slot("test", PrimitiveStrObject("xax")) assert not o.set_slot("bad_slot", PrimitiveStrObject("x"))
def interpret(self): while self.process_count > 0: frame = self.process.frame code_obj = frame.code_context bytecode = ord(code_obj.bytecodes[frame.bc_index]) bc_len = 0 if bytecode == BYTECODE_SEND: bc_len = self._do_send(frame.bc_index, code_obj) elif bytecode == BYTECODE_PUSH_SELF: bc_len = self._do_push_self(frame.bc_index, code_obj) elif bytecode == BYTECODE_PUSH_LITERAL: bc_len = self._do_push_literal(frame.bc_index, code_obj) elif bytecode == BYTECODE_RETURN_TOP or \ bytecode == BYTECODE_RETURN_IMPLICIT: if not self.process.is_nested_call(): result = self.process.frame.pop_or_nil() process = self.remove_active_process() process.result = result process.finished = True if not self.has_processes_to_run(): self.process = process return if bytecode == BYTECODE_RETURN_IMPLICIT: self._handle_nonlocal_return() self.process.pop_down_and_cleanup_frame() self.next_process() continue elif bytecode == BYTECODE_ADD_SLOT: bc_len = self._do_add_slot(frame.bc_index, code_obj) # elif bytecode == BYTECODE_SELF_SEND: # self._do_selfSend(bc_index, code_obj, frame) else: self.process.result = ErrorObject( PrimitiveStrObject("Unknown bytecode: %s!" % bytecode), self.process ) self.process.finished = True self.process.finished_with_errors = True process = self.remove_active_process() if not self.has_processes_to_run(): self.process = process return continue frame.bc_index += bc_len jitdriver.jit_merge_point( bc_index=frame.bc_index, bytecode=bytecode, code_obj=code_obj, frame=frame, self=self, ) if (frame.bc_index % 10) == 0: self.next_process()