예제 #1
0
def test_call_push_frame() -> None:
    call = GuestCall(
        definition_environment=test_environment(),
        definition_block=SyntaxBlock(
            [SyntaxExpression([SyntaxIdentifier("g")])]),
    )
    block = SyntaxBlock([SyntaxExpression([SyntaxIdentifier("f")])])
    frame_stack = init_test_frame_stack(
        block,
        MachineExpressionStack([MachineNumber(int32(9))]),
    )
    call(frame_stack)
    assert len(frame_stack) == 2
    assert (frame_stack.frames[0] == init_test_frame_stack(
        block,
        MachineExpressionStack([MachineNumber(int32(9))]),
        term_index=1,
    ).frames[0])
    assert frame_stack.frames[1] == MachineFrame(
        instruction_pointer=MachineInstructionPointer(
            block=call.definition_block,
            statement_index=0,
            term_index=0,
        ),
        environment=test_environment().extend(),
        expression_stack=MachineExpressionStack([MachineNumber(int32(9))]),
    )
예제 #2
0
def test_interpret_assignment_2_exit() -> None:
    statement = SyntaxAssignment(
        terms=[
            SyntaxNumber(int32(300)),
            SyntaxNumber(int32(400)),
        ],
        bindings=[
            SyntaxIdentifier("abc"),
            SyntaxIdentifier("def"),
        ],
    )
    frame_stack = init_test_frame_stack(
        init_statement_block(statement),
        MachineExpressionStack([]),
    )
    interpret_statement(frame_stack)
    interpret_statement(frame_stack)
    interpret_statement(frame_stack)
    assert frame_stack == init_frame_stack(
        init_statement_block(statement),
        MachineExpressionStack([]),
        test_environment({
            "abc": MachineNumber(int32(300)),
            "def": MachineNumber(int32(400)),
        }),
        statement_index=1,
    )
예제 #3
0
def test_call_delegate_to_host_call() -> None:
    call = GuestCall(
        definition_environment=test_environment(),
        definition_block=SyntaxBlock(
            [SyntaxExpression([SyntaxIdentifier("sqrt")])]),
    )
    block = SyntaxBlock([SyntaxExpression([SyntaxIdentifier("f")])])
    expression_stack = MachineExpressionStack([MachineNumber(int32(16))])
    environment = test_environment({"f": call})
    interpret(block, expression_stack, environment)
    assert expression_stack == MachineExpressionStack(
        [MachineNumber(int32(4))])
예제 #4
0
def call_test(
    binding: MachineBinding,
    args: list[MachineValue],
    results: list[MachineValue],
) -> None:
    term = SyntaxIdentifier(binding.name)
    block = SyntaxBlock([SyntaxExpression([term])])
    expression_stack = MachineExpressionStack(args)
    environment = test_environment()
    interpret(block, expression_stack, environment)
    assert expression_stack == MachineExpressionStack(results)
예제 #5
0
def parse_one_term(term: GroupTerm) -> SyntaxTerm:
    if isinstance(term, GroupNumber):
        return SyntaxNumber(term.value)
    elif isinstance(term, GroupIdentifier):
        return SyntaxIdentifier(term.name)
    elif isinstance(term, GroupComment):
        return SyntaxComment(term.text)
    elif isinstance(term, Group):
        return parse_statements_block(term)
    else:
        raise AssertionError(term)
예제 #6
0
def test_interpret_method_definition_exit() -> None:
    statement = SyntaxMethodDefinition(
        binding=SyntaxIdentifier("f"),
        definition=SyntaxExpression([SyntaxIdentifier("sqrt")]),
    )
    frame_stack = init_test_frame_stack(
        init_statement_block(statement),
        MachineExpressionStack([]),
    )
    interpret_statement(frame_stack)
    environment = frame_stack.current.environment
    assert frame_stack == init_frame_stack(
        init_statement_block(statement),
        MachineExpressionStack([]),
        environment,
        statement_index=1,
    )
    assert environment.base == test_environment().base
    assert environment.bindings == {
        "f": GuestCall(environment, statement.definition_block)
    }
예제 #7
0
def test_interpret_identifier_call() -> None:
    term = SyntaxIdentifier(sqrt.name)
    expression_stack = MachineExpressionStack(
        [MachineNumber(int32(16))]
    )
    frame_stack = init_test_frame_stack(
        init_term_block(term), expression_stack
    )
    interpret_term(frame_stack)
    assert frame_stack == init_test_frame_stack(
        init_term_block(term),
        MachineExpressionStack([MachineNumber(int32(4))]),
        term_index=1,
    )
예제 #8
0
def test_interpret_identifier_value() -> None:
    term = SyntaxIdentifier(PI.name)
    expression_stack = MachineExpressionStack([])
    frame_stack = init_test_frame_stack(
        init_term_block(term), expression_stack
    )
    interpret_term(frame_stack)
    assert frame_stack == init_test_frame_stack(
        init_term_block(term),
        MachineExpressionStack(
            [cast(MachineValue, PI.value_or_call)]
        ),
        term_index=1,
    )
예제 #9
0
def test_interpret_assignment_1_exit() -> None:
    statement = SyntaxAssignment(
        terms=[SyntaxNumber(int32(3))],
        bindings=[SyntaxIdentifier("x")],
    )
    frame_stack = init_test_frame_stack(
        init_statement_block(statement),
        MachineExpressionStack([MachineNumber(int32(4))]),
    )
    interpret_statement(frame_stack)
    interpret_statement(frame_stack)
    assert frame_stack == init_frame_stack(
        init_statement_block(statement),
        MachineExpressionStack([MachineNumber(int32(4))]),
        test_environment({"x": MachineNumber(int32(3))}),
        statement_index=1,
    )
예제 #10
0
def test_interpret_assignment_1_enter() -> None:
    statement = SyntaxAssignment(
        terms=[SyntaxNumber(int32(3))],
        bindings=[SyntaxIdentifier("x")],
    )
    frame_stack = init_test_frame_stack(
        init_statement_block(statement),
        MachineExpressionStack([MachineNumber(int32(4))]),
    )
    interpret_statement(frame_stack)
    assert len(frame_stack) == 2
    assert (frame_stack.frames[1].instruction_pointer is
            frame_stack.frames[0].instruction_pointer)
    assert (frame_stack.frames[1].environment is
            frame_stack.frames[0].environment)
    assert (frame_stack.current.expression_stack == MachineExpressionStack(
        [MachineNumber(int32(3))]))
예제 #11
0
def params_parse() -> Iterable[tuple[str, SyntaxBlock]]:
    yield "0x123xiw", SyntaxBlock(
        [SyntaxExpression([SyntaxNumber(int32(0x123))])])
    yield "abc", SyntaxBlock([SyntaxExpression([SyntaxIdentifier("abc")])])
    yield "a-b-c", SyntaxBlock([SyntaxExpression([SyntaxIdentifier("a-b-c")])])
    yield "123 abc ", SyntaxBlock([
        SyntaxExpression([
            SyntaxNumber(int32(123)),
            SyntaxIdentifier("abc"),
        ])
    ])
    yield "123 abc -- de", SyntaxBlock([
        SyntaxExpression([
            SyntaxNumber(int32(123)),
            SyntaxIdentifier("abc"),
            SyntaxComment(" de"),
        ])
    ])
    yield "abc def  =    10   20", SyntaxBlock([
        SyntaxAssignment(
            terms=[
                SyntaxNumber(int32(10)),
                SyntaxNumber(int32(20)),
            ],
            bindings=[
                SyntaxIdentifier("abc"),
                SyntaxIdentifier("def"),
            ],
        )
    ])
    yield "123 abc\n456 def", SyntaxBlock([
        SyntaxExpression([
            SyntaxNumber(int32(123)),
            SyntaxIdentifier("abc"),
        ]),
        SyntaxExpression([
            SyntaxNumber(int32(456)),
            SyntaxIdentifier("def"),
        ]),
    ])
예제 #12
0
def parse_one_statement(terms: list[GroupTerm], ) -> SyntaxStatement:
    bindings: list[SyntaxIdentifier] = []
    for term in terms:
        if isinstance(term, GroupIdentifier):
            if term.name == "=":
                return SyntaxAssignment(
                    terms=parse_terms(terms[len(bindings) + 1:]),
                    bindings=bindings,
                )
            elif term.name == "/=":
                assert len(bindings) == 1
                return SyntaxMethodDefinition(
                    binding=bindings[0],
                    definition=parse_one_statement(terms[2:]),
                )
            else:
                bindings.append(SyntaxIdentifier(term.name))
        else:
            break
    return SyntaxExpression(parse_terms(terms))
예제 #13
0
def test_call_generate_values() -> None:
    call = GuestCall(
        definition_environment=test_environment(),
        definition_block=SyntaxBlock([
            SyntaxExpression([
                SyntaxNumber(int32(2)),
                SyntaxNumber(int32(3)),
                SyntaxNumber(int32(4)),
            ])
        ]),
    )
    block = SyntaxBlock([SyntaxExpression([SyntaxIdentifier("seq")])])
    expression_stack = MachineExpressionStack([MachineNumber(int32(1))])
    environment = test_environment({"seq": call})
    interpret(block, expression_stack, environment)
    assert expression_stack == MachineExpressionStack([
        MachineNumber(int32(1)),
        MachineNumber(int32(2)),
        MachineNumber(int32(3)),
        MachineNumber(int32(4)),
    ])
예제 #14
0
def params_statements() -> Iterable[tuple[Group, SyntaxBlock]]:
    # Expression
    yield Group([GroupLine([GroupIdentifier("abc")])
                 ]), SyntaxBlock([SyntaxExpression([SyntaxIdentifier("abc")])])

    # Comment in group
    yield Group([
        GroupLine([
            GroupNumber(int32(0)),
            GroupComment(" txt"),
            Group([GroupLine([GroupNumber(int32(1))])]),
        ])
    ]), SyntaxBlock([
        SyntaxExpression([
            SyntaxNumber(int32(0)),
            SyntaxComment(" txt"),
            SyntaxBlock([SyntaxExpression([SyntaxNumber(int32(1))])]),
        ])
    ])

    # Simple assignment
    yield Group([
        GroupLine([
            GroupIdentifier("x"),
            GroupIdentifier("="),
            GroupIdentifier("y"),
        ])
    ]), SyntaxBlock([
        SyntaxAssignment(
            terms=[SyntaxIdentifier("y")],
            bindings=[SyntaxIdentifier("x")],
        )
    ])

    # Nested assignment
    yield Group([
        GroupLine([
            GroupIdentifier("a"),
            GroupIdentifier("b"),
            GroupIdentifier("="),
            GroupIdentifier("c"),
            Group([
                GroupLine([
                    GroupIdentifier("d"),
                    GroupIdentifier("="),
                    GroupIdentifier("e"),
                ]),
                GroupLine([
                    GroupIdentifier("f"),
                    GroupIdentifier("g"),
                ]),
            ]),
        ])
    ]), SyntaxBlock([
        SyntaxAssignment(
            terms=[
                SyntaxIdentifier("c"),
                SyntaxBlock([
                    SyntaxAssignment(
                        terms=[SyntaxIdentifier("e")],
                        bindings=[SyntaxIdentifier("d")],
                    ),
                    SyntaxExpression([
                        SyntaxIdentifier("f"),
                        SyntaxIdentifier("g"),
                    ]),
                ]),
            ],
            bindings=[
                SyntaxIdentifier("a"),
                SyntaxIdentifier("b"),
            ],
        )
    ])

    # Simple method definition
    yield Group([
        GroupLine([
            GroupIdentifier("a1"),
            GroupIdentifier("/="),
            GroupIdentifier("b2"),
        ])
    ]), SyntaxBlock([
        SyntaxMethodDefinition(
            binding=SyntaxIdentifier("a1"),
            definition=SyntaxExpression([SyntaxIdentifier("b2")]),
        )
    ])

    # Block method definition
    yield Group([
        GroupLine([
            GroupIdentifier("add"),
            GroupIdentifier("/="),
            Group([
                GroupLine([
                    GroupIdentifier("x"),
                    GroupIdentifier("y"),
                    GroupIdentifier("+"),
                ])
            ]),
        ])
    ]), SyntaxBlock([
        SyntaxMethodDefinition(
            binding=SyntaxIdentifier("add"),
            definition=SyntaxExpression([
                SyntaxBlock([
                    SyntaxExpression([
                        SyntaxIdentifier("x"),
                        SyntaxIdentifier("y"),
                        SyntaxIdentifier("+"),
                    ])
                ])
            ]),
        )
    ])