예제 #1
0
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
예제 #2
0
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
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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
예제 #6
0
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
예제 #7
0
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")
예제 #8
0
    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
예제 #9
0
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
예제 #10
0
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
예제 #11
0
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
예제 #12
0
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
예제 #13
0
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
예제 #14
0
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
예제 #15
0
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
예제 #16
0
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
예제 #17
0
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
예제 #18
0
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=[],
    )
예제 #19
0
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)
예제 #20
0
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")
예제 #21
0
def test_get_slot():
    o = Object()

    val = PrimitiveStrObject("xe")
    o.meta_add_slot("test", val)
    assert o.get_slot("test") is val
예제 #22
0
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"))
예제 #23
0
    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()