add evaluate_operand, fix operator tokenising
This commit is contained in:
BIN
twasm/.bootle/disk
Normal file
BIN
twasm/.bootle/disk
Normal file
Binary file not shown.
@@ -578,8 +578,8 @@ tokenise:
|
||||
pop rsi
|
||||
|
||||
push rax
|
||||
mov dword [.pending_operator], 0 ; zero pending operator
|
||||
xor eax, eax ; eax = number of bytes in operator
|
||||
xor eax, eax ; eax = number of bytes in operator
|
||||
mov [.pending_operator], eax ; zero pending operator
|
||||
|
||||
.operator_loop:
|
||||
; TODO give this its own error
|
||||
@@ -606,35 +606,19 @@ tokenise:
|
||||
jmp .operator_loop ; and loop
|
||||
|
||||
.operator_break:
|
||||
pop rax
|
||||
; rax already pushed from .operator
|
||||
push rdi
|
||||
|
||||
push rcx
|
||||
mov rcx, tokens.operators ; rcx -> entry in lookup table
|
||||
mov edi, [.pending_operator] ; edi = operator to be searched
|
||||
call identify_operator
|
||||
; ax = operator's token ID
|
||||
mov cx, ax ; cx = operator's token ID for safe keeping
|
||||
|
||||
.operator_id_loop:
|
||||
cmp rcx, tokens.operators_end ; check if index still in range
|
||||
; TODO give own error
|
||||
jg .unexpected_operator ; if not, error
|
||||
pop rdi ; rdi = byte counter
|
||||
pop rax ; rax = tokens processed
|
||||
|
||||
; TODO use something other than r8 and r9
|
||||
mov r8d, [rcx]
|
||||
mov r9d, [.pending_operator]
|
||||
cmp r8d, r9d
|
||||
je .found_id
|
||||
|
||||
add rcx, 6 ; next entry
|
||||
|
||||
jmp .operator_id_loop
|
||||
|
||||
.found_id:
|
||||
push rdx
|
||||
mov dx, [rcx + 4] ; dx = token id
|
||||
|
||||
mov [TOKEN_TABLE_ADDR + rax * TOKEN_TABLE_ENTRY_SIZE], dx ; write to token
|
||||
inc rax ; table
|
||||
|
||||
pop rdx
|
||||
pop rcx
|
||||
mov [TOKEN_TABLE_ADDR + rax * TOKEN_TABLE_ENTRY_SIZE], cx
|
||||
inc rax ; plus 1 token processed
|
||||
|
||||
mov byte [.expecting], E_COMMENT | E_NEWLINE | E_WHITESPACE | E_OPERAND
|
||||
jmp .loop
|
||||
@@ -650,6 +634,7 @@ tokenise:
|
||||
|
||||
test byte [.expecting], E_OPERAND ; make sure an operand was expected
|
||||
jz .unexpected_operand ; if not, error
|
||||
|
||||
.operand_loop:
|
||||
mov dl, [rdi]
|
||||
|
||||
@@ -720,6 +705,67 @@ tokenise:
|
||||
.msg_operand db "operand.", 0x0A, 0x00
|
||||
.pending_operator dd 0 ; the operator token that is pending processing
|
||||
|
||||
; ------------------------------------------------------------------------------
|
||||
; evaluate_operand
|
||||
;
|
||||
; description:
|
||||
; takes the location and length of an operand and evaluates it into binary data
|
||||
; and a return code to interpret the binary data.
|
||||
;
|
||||
; | code | rsi contents | notes |
|
||||
; |------|----------------------|-------|
|
||||
; | 0x00 | token ID of register | |
|
||||
; | 0xFF | - | error |
|
||||
;
|
||||
; parameters:
|
||||
; rdi -> first byte of operand
|
||||
; rsi = size of operand in bytes
|
||||
;
|
||||
; returned:
|
||||
; rax = binary data corresponding to the operand
|
||||
; dl = return code
|
||||
; ------------------------------------------------------------------------------
|
||||
|
||||
evaluate_operand:
|
||||
cmp rsi, 4
|
||||
jg .unrecognised
|
||||
|
||||
.register:
|
||||
push rdi
|
||||
mov edi, [rdi] ; edi = register to be searched
|
||||
|
||||
; TODO figure out how to mask elegantly :/
|
||||
; mask edi for lower rsi bits
|
||||
cmp rsi, 4
|
||||
je .register4
|
||||
cmp rsi, 3
|
||||
je .register3
|
||||
cmp rsi, 2
|
||||
je .register2
|
||||
cmp rsi, 1
|
||||
je .register1
|
||||
.register1:
|
||||
and edi, 0xFF
|
||||
.register2:
|
||||
and edi, 0xFFFF
|
||||
.register3:
|
||||
and edi, 0xFFFFFF
|
||||
.register4:
|
||||
|
||||
call identify_register
|
||||
; ax = register's token ID or UNRECOGNISED_TOKEN_ID
|
||||
pop rdi
|
||||
|
||||
cmp ax, UNRECOGNISED_TOKEN_ID
|
||||
je .unrecognised
|
||||
|
||||
mov dl, 0x00
|
||||
ret
|
||||
|
||||
.unrecognised:
|
||||
mov dl, 0xFF
|
||||
ret
|
||||
|
||||
; ------------------------------------------------------------------------------
|
||||
; evaluate_constant
|
||||
;
|
||||
|
||||
@@ -40,6 +40,9 @@ run_tests:
|
||||
call clear_test_arena
|
||||
call test_identify_operator
|
||||
|
||||
call clear_test_arena
|
||||
call test_evaluate_operand
|
||||
|
||||
ret
|
||||
.msg db "running test suite...", 0x0A, 0x00
|
||||
|
||||
@@ -499,6 +502,52 @@ test_identify_operator:
|
||||
ret
|
||||
.msg db "test_identify_operator...", 0x00
|
||||
|
||||
; ------------------------------------------------------------------------------
|
||||
; test_evaluate_operand
|
||||
;
|
||||
; description:
|
||||
; tests evaluate_operand described funtionality
|
||||
; ------------------------------------------------------------------------------
|
||||
|
||||
test_evaluate_operand:
|
||||
mov rsi, .msg
|
||||
call print.test
|
||||
|
||||
mov rdi, .case0
|
||||
mov rsi, 3
|
||||
call evaluate_operand
|
||||
cmp dl, 0x00
|
||||
jne .fail
|
||||
cmp ax, 0x0000
|
||||
jne .fail
|
||||
|
||||
mov rdi, .case1
|
||||
mov rsi, 0
|
||||
call evaluate_operand
|
||||
cmp dl, 0xFF
|
||||
jne .fail
|
||||
|
||||
mov rdi, .case2
|
||||
mov rsi, 3
|
||||
call evaluate_operand
|
||||
cmp dl, 0x00
|
||||
jne .fail
|
||||
cmp ax, 0x0003
|
||||
jne .fail
|
||||
|
||||
.pass:
|
||||
mov rsi, msg_pass
|
||||
call print
|
||||
ret
|
||||
.fail:
|
||||
mov rsi, msg_fail
|
||||
call print
|
||||
ret
|
||||
.case0 db "rax"
|
||||
.case1: ; intentionally blank
|
||||
.case2 db "rdx"
|
||||
.msg db "test_evaluate_operand...", 0x00
|
||||
|
||||
msg_pass:
|
||||
db 0x0A
|
||||
times (TEST_LINE_LENGTH + .start - .end) db " ", ; right align
|
||||
|
||||
Reference in New Issue
Block a user