def test_alloc_size_1_with_label(self): instructions = [move_opcode+constantp_address+a_address, Token(Label.Name, 'var', 1), jump_opcode + unused_opcode + constant_address, Token(Label.Name, 'start', 2) ] labels = {'start': 0} variables = {'var': 1} linked = link(instructions, labels, variables) assert linked == [dec_to_bin(15), # Length of program dec_to_bin(1), # Allocated memory # Loader pop_opcode + a_address + spp_address, move_opcode + b_address + constant_address, # move b literal dec_to_bin(10), # location of var access alu_opcode + alu_add + b_address + a_address, # add b a alu_opcode + alu_add + bp_address + a_address, # add [b] a move_opcode + b_address + constant_address, # move b literal dec_to_bin(12), # location of jump to start alu_opcode + alu_add + b_address + a_address, # add b a alu_opcode + alu_add + bp_address + a_address, # add [b] a # Program move_opcode+constantp_address+a_address, dec_to_bin(13), # accessing var jump_opcode + unused_opcode + constant_address, dec_to_bin(9) # jump to label start ]
def test_jump_to_label(self, lexer): line = 'jump abc' tokens = lexer.scan(line) assert tokens == [ Token(Keyword.Jump, 'jump', 1), Token(Label.Name, 'abc', 1) ]
def test_jump(self, lexer): line = 'jump 2675' tokens = lexer.scan(line) assert tokens == [ Token(Keyword.Jump, 'jump', 1), Token(Literal.Int, 2675, 1) ]
def test_call_function_by_label(self, lexer): line = 'call func' tokens = lexer.scan(line) assert tokens == [ Token(Keyword.Call, 'call', 1), Token(Label.Name, 'func', 1) ]
def test_multiple_calls(self): instructions = [jump_opcode + unused_opcode + constant_address, Token(Label.Name, 'end', 1), move_opcode + a_address + constant_address, dec_to_bin(1), jump_opcode + unused_opcode + constant_address, Token(Label.Name, 'end', 2), ] labels = {'end': 4} variables = {} linked = link(instructions, labels, variables) assert linked == [dec_to_bin(17), # Program length dec_to_bin(0), # ALlocated space # Loader pop_opcode+a_address+spp_address, move_opcode + b_address + constant_address, # move b literal dec_to_bin(10), # location of first jump to end alu_opcode + alu_add + b_address + a_address, # add b a alu_opcode + alu_add + bp_address + a_address, # add [b] a move_opcode + b_address + constant_address, # move b literal dec_to_bin(14), # location of second jump to end alu_opcode + alu_add + b_address + a_address, # add b a alu_opcode + alu_add + bp_address + a_address, # add [b] a # Program jump_opcode + unused_opcode + constant_address, dec_to_bin(13), # jump to end move_opcode + a_address + constant_address, dec_to_bin(1), # literal jump_opcode + unused_opcode + constant_address, dec_to_bin(13) # jump to end ]
def test_call_function_by_register(self, lexer): line = 'call a' tokens = lexer.scan(line) assert tokens == [ Token(Keyword.Call, 'call', 1), Token(Keyword.a, 'a', 1) ]
def test_jump_overflow(self, lexer): line = 'jump_overflow 11' tokens = lexer.scan(line) assert tokens == [ Token(Keyword.JumpIfOverflow, 'jump_overflow', 1), Token(Literal.Int, 11, 1) ]
def test_double_alloc_size_2(self): instructions = [move_opcode+constantp_address+a_address, Token(Label.Name, 'var_1', 1), move_opcode + constantp_address + b_address, Token(Label.Name, 'var_2', 2) ] labels = {} variables = {'var_1': 2, 'var_2': 2} linked = link(instructions, labels, variables) assert linked == [dec_to_bin(15), # Length of program dec_to_bin(4), # Allocated memory # Loader pop_opcode + a_address + spp_address, move_opcode + b_address + constant_address, # move b literal dec_to_bin(10), # location of var_1 access alu_opcode + alu_add + b_address + a_address, # add b a alu_opcode + alu_add + bp_address + a_address, # add [b] a move_opcode + b_address + constant_address, # move b literal dec_to_bin(12), # location of var_2 access alu_opcode + alu_add + b_address + a_address, # add b a alu_opcode + alu_add + bp_address + a_address, # add [b] a # Program move_opcode+constantp_address+a_address, dec_to_bin(13), # Accessing var_1 move_opcode + constantp_address + b_address, dec_to_bin(15), # Accessing var_2 ]
def test_jump_neg(self, lexer): line = 'jump_neg 123786432' tokens = lexer.scan(line) assert tokens == [ Token(Keyword.JumpIfNeg, 'jump_neg', 1), Token(Literal.Int, 123786432, 1) ]
def test_jump_zero(self, lexer): line = 'jump_zero 345' tokens = lexer.scan(line) assert tokens == [ Token(Keyword.JumpIfZero, 'jump_zero', 1), Token(Literal.Int, 345, 1) ]
def test_call_function_by_literal(self, lexer): line = 'call 1024' tokens = lexer.scan(line) assert tokens == [ Token(Keyword.Call, 'call', 1), Token(Literal.Int, 1024, 1) ]
def test_move_lots_of_whitespace(self, lexer): line = ' move b sp' tokens = lexer.scan(line) assert tokens == [ Token(Keyword.Move, 'move', 1), Token(Keyword.b, 'b', 1), Token(Keyword.sp, 'sp', 1) ]
def test_binary_number(self, lexer, binary, dec): line = f'move a {binary}' tokens = lexer.scan(line) assert tokens == [ Token(Keyword.Move, 'move', 1), Token(Keyword.a, 'a', 1), Token(Literal.Int, dec, 1) ]
def test_hdd(self, lexer, command, token): line = f'{command} a b' tokens = lexer.scan(line) assert tokens == [ Token(token, command, 1), Token(Keyword.a, 'a', 1), Token(Keyword.b, 'b', 1) ]
def test_arithmetic_two_parameters(self, lexer, command, token): line = f'{command} a 1' tokens = lexer.scan(line) assert tokens == [ Token(token, command, 1), Token(Keyword.a, 'a', 1), Token(Literal.Int, 1, 1) ]
def test_tab(self, lexer): line = '\tmove\t\ta\t\t\tb' tokens = lexer.scan(line) assert tokens == [ Token(Keyword.Move, 'move', 1), Token(Keyword.a, 'a', 1), Token(Keyword.b, 'b', 1) ]
def test_move_register_to_register(self, lexer): line = 'move c d' tokens = lexer.scan(line) assert tokens == [ Token(Keyword.Move, 'move', 1), Token(Keyword.c, 'c', 1), Token(Keyword.d, 'd', 1) ]
def test_hex_number(self, lexer, hexdec, dec): line = f'move a {hexdec}' tokens = lexer.scan(line) assert tokens == [ Token(Keyword.Move, 'move', 1), Token(Keyword.a, 'a', 1), Token(Literal.Int, dec, 1) ]
def test_comment_two_lines_1(self, lexer): line = 'move c b\n% move a b\n%add c 3' tokens = lexer.scan(line) assert tokens == [ Token(Keyword.Move, 'move', 1), Token(Keyword.c, 'c', 1), Token(Keyword.b, 'b', 1) ]
def test_declare_variable(self, lexer, name, size): line = f'alloc {name} {size}' tokens = lexer.scan(line) assert tokens == [ Token(Keyword.Alloc, 'alloc', 1), Token(Label.Name, name, 1), Token(Literal.Int, size, 1) ]
def test_call_function_by_pointer(self, lexer): line = 'call [a]' tokens = lexer.scan(line) assert tokens == [ Token(Keyword.Call, 'call', 1), Token(Delimiter.LeftBracket, '[', 1), Token(Keyword.a, 'a', 1), Token(Delimiter.RightBracket, ']', 1) ]
def test_stack_ops(self, lexer): line = 'push 10 pop a' tokens = lexer.scan(line) assert tokens == [ Token(Keyword.Push, 'push', 1), Token(Literal.Int, 10, 1), Token(Keyword.Pop, 'pop', 1), Token(Keyword.a, 'a', 1) ]
def test_alloc(self, parser, name, size): tokens = [ Token(Keyword.Alloc, 'alloc', 1), Token(Label.Name, name, 1), Token(Literal.Int, size, 1) ] instructions = parser.parse(tokens) assert instructions == [] assert parser.variables[name] == size
def test_move_literal_to_register(self, lexer, literal, register, register_token): line = f'move {register} {literal}' tokens = lexer.scan(line) assert tokens == [ Token(Keyword.Move, 'move', 1), Token(register_token, register, 1), Token(Literal.Int, literal, 1) ]
def test_move_pointer(self, lexer): line = 'move a [b]' tokens = lexer.scan(line) assert tokens == [ Token(Keyword.Move, 'move', 1), Token(Keyword.a, 'a', 1), Token(Delimiter.LeftBracket, '[', 1), Token(Keyword.b, 'b', 1), Token(Delimiter.RightBracket, ']', 1) ]
def test_line_break(self, lexer): line = '\nmove a b\n push a' tokens = lexer.scan(line) assert tokens == [ Token(Keyword.Move, 'move', 2), Token(Keyword.a, 'a', 2), Token(Keyword.b, 'b', 2), Token(Keyword.Push, 'push', 3), Token(Keyword.a, 'a', 3) ]
def test_declare_label(self, lexer): line = ':start move a b' tokens = lexer.scan(line) assert tokens == [ Token(Delimiter.Colon, ':', 1), Token(Label.Name, 'start', 1), Token(Keyword.Move, 'move', 1), Token(Keyword.a, 'a', 1), Token(Keyword.b, 'b', 1) ]
def test_SCREEN_pointer(self, lexer): line = 'move a [SCREEN]' tokens = lexer.scan(line) assert tokens == [ Token(Keyword.Move, 'move', 1), Token(Keyword.a, 'a', 1), Token(Delimiter.LeftBracket, '[', 1), Token(Label.Name, 'SCREEN', 1), Token(Delimiter.RightBracket, ']', 1), ]
def test_jump_to_label_at_start(self, parser): tokens = [ token_colon, Token(Label.Name, 'start', 1), token_jump, Token(Label.Name, 'start', 2) ] instructions = parser.parse(tokens) assert instructions == [ jump_opcode + unused_opcode + constant_address, Token(Label.Name, 'start', 2) ]
def test_use_alloc_data(self, parser): tokens = [ token_alloc, Token(Label.Name, 'var', 1), Token(Literal.Int, 1, 1), token_move, token_a, Token(Literal.Int, 0, 2), token_move, token_left_bracket, Token(Label.Name, 'var', 3), token_right_bracket, token_a ] instructions = parser.parse(tokens) assert instructions == [ move_opcode + a_address + constant_address, dec_to_bin(0), move_opcode + constantp_address + a_address, Token(Label.Name, 'var', 3) ]