---
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
from compiler.assembly_generator import Locals, generate_assembly
|
||||
from compiler.ir import IRVar, LoadIntConst, LoadBoolConst, Copy, CondJump, Label, Instruction, Call
|
||||
from compiler.tokenizer import L
|
||||
from typing import List
|
||||
|
||||
def test_assembly_generator_locals_initialization() -> None:
|
||||
variables = [IRVar('x'), IRVar('y'), IRVar('z')]
|
||||
locals = Locals(variables)
|
||||
|
||||
assert locals.get_ref(variables[0]) == '-8(%rbp)'
|
||||
assert locals.get_ref(variables[1]) == '-16(%rbp)'
|
||||
assert locals.get_ref(variables[2]) == '-24(%rbp)'
|
||||
|
||||
assert locals.stack_used() == 24 # 3 variables * 8 bytes
|
||||
|
||||
# def test_assembly_generator_load_int_const() -> None:
|
||||
# ir_var = IRVar('x')
|
||||
# instructions: List[Instruction] = [
|
||||
# LoadIntConst(L, 42, ir_var)
|
||||
# ]
|
||||
|
||||
# asm = generate_assembly(instructions)
|
||||
# assert 'movq $42, -8(%rbp)' in asm
|
||||
|
||||
# def test_assembly_generator_load_bool_const() -> None:
|
||||
# instructions: List[Instruction] = [
|
||||
# LoadBoolConst(L, True, IRVar('a')),
|
||||
# LoadBoolConst(L, False, IRVar('b'))
|
||||
# ]
|
||||
|
||||
# asm = generate_assembly(instructions)
|
||||
# assert 'movq $1, -8(%rbp)' in asm # True
|
||||
# assert 'movq $0, -16(%rbp)' in asm # False
|
||||
|
||||
# def test_assembly_generator_copy() -> None:
|
||||
# src = IRVar('src')
|
||||
# dest = IRVar('dest')
|
||||
# instructions: List[Instruction] = [
|
||||
# Copy(L, src, dest)
|
||||
# ]
|
||||
|
||||
# asm = generate_assembly(instructions)
|
||||
# assert 'movq -8(%rbp), %rax' in asm
|
||||
# assert 'movq %rax, -16(%rbp)' in asm
|
||||
|
||||
# def test_assembly_generator_cond_jump() -> None:
|
||||
# cond_var = IRVar('cond')
|
||||
# then_label = Label(L, 'Lthen')
|
||||
# else_label = Label(L, 'Lelse')
|
||||
# instructions: List[Instruction] = [
|
||||
# CondJump(L, cond_var, then_label, else_label)
|
||||
# ]
|
||||
|
||||
# asm = generate_assembly(instructions)
|
||||
# assert 'cmpq $0, -8(%rbp)' in asm
|
||||
# assert 'jne .LLthen' in asm
|
||||
# assert 'jmp .LLelse' in asm
|
||||
|
||||
# def test_assembly_generator_function_prologue_epilogue() -> None:
|
||||
# instructions: List[Instruction] = [
|
||||
# LoadIntConst(L, 0, IRVar('dummy'))
|
||||
# ]
|
||||
|
||||
# asm = generate_assembly(instructions)
|
||||
# assert 'pushq %rbp' in asm
|
||||
# assert 'movq %rsp, %rbp' in asm
|
||||
# assert 'subq $8, %rsp' in asm
|
||||
# assert 'movq %rbp, %rsp' in asm
|
||||
# assert 'popq %rbp' in asm
|
||||
# assert 'ret' in asm
|
||||
|
||||
# def test_assembly_generator_intrinsic_plus() -> None:
|
||||
# # IR: Call('+', [x, y], result)
|
||||
# x = IRVar('x')
|
||||
# y = IRVar('y')
|
||||
# result = IRVar('result')
|
||||
# instructions = [
|
||||
# LoadIntConst(L, 3, x),
|
||||
# LoadIntConst(L, 5, y),
|
||||
# Call(L, IRVar('+'), [x, y], result)
|
||||
# ]
|
||||
# asm = generate_assembly(instructions)
|
||||
# assert 'addq' in asm
|
||||
# assert 'movq' in asm
|
||||
# assert 'callq' not in asm # Intrinsic should not use call
|
||||
|
||||
# def test_assembly_generator_intrinsic_divide() -> None:
|
||||
# # IR: Call('/', [a, b], result)
|
||||
# a = IRVar('a')
|
||||
# b = IRVar('b')
|
||||
# instructions = [
|
||||
# LoadIntConst(L, 10, a),
|
||||
# LoadIntConst(L, 2, b),
|
||||
# Call(L, IRVar('/'), [a, b], IRVar('result'))
|
||||
# ]
|
||||
# asm = generate_assembly(instructions)
|
||||
# assert 'idivq' in asm
|
||||
# assert 'cqto' in asm
|
||||
|
||||
# def test_assembly_generator_function_call_one_arg() -> None:
|
||||
# # IR: Call(print_int, [x], _)
|
||||
# x = IRVar('x')
|
||||
# instructions = [
|
||||
# LoadIntConst(L, 42, x),
|
||||
# Call(L, IRVar('print_int'), [x], IRVar('unused'))
|
||||
# ]
|
||||
# asm = generate_assembly(instructions)
|
||||
# assert 'movq -8(%rbp), %rdi' in asm # Assuming x is at -8(%rbp)
|
||||
# assert 'callq print_int' in asm
|
||||
|
||||
# def test_assembly_generator_function_call_six_args() -> None:
|
||||
# # IR: Call(func, [a,b,c,d,e,f], _)
|
||||
# args = [IRVar(f'arg{i}') for i in range(6)]
|
||||
# instructions = [
|
||||
# *[LoadIntConst(L, i, arg) for i, arg in enumerate(args)],
|
||||
# Call(L, IRVar('func'), args, IRVar('result'))
|
||||
# ]
|
||||
# asm = generate_assembly(instructions)
|
||||
# expected_regs = ['%rdi', '%rsi', '%rdx', '%rcx', '%r8', '%r9']
|
||||
# for i, reg in enumerate(expected_regs):
|
||||
# assert f'movq -{8*(i+1)}(%rbp), {reg}' in asm
|
||||
# assert 'callq func' in asm
|
||||
|
||||
# def test_assembly_generator_comparison_intrinsic() -> None:
|
||||
# # IR: Call('==', [x, y], result)
|
||||
# x = IRVar('x')
|
||||
# y = IRVar('y')
|
||||
# instructions = [
|
||||
# LoadIntConst(L, 5, x),
|
||||
# LoadIntConst(L, 5, y),
|
||||
# Call(L, IRVar('=='), [x, y], IRVar('result'))
|
||||
# ]
|
||||
# asm = generate_assembly(instructions)
|
||||
# assert 'cmpq' in asm
|
||||
# assert 'sete' in asm
|
||||
Reference in New Issue
Block a user