summaryrefslogtreecommitdiff
path: root/twasm/asm/main.asm
diff options
context:
space:
mode:
authorandromeda <andromeda@lenovo>2026-03-15 21:55:16 +0100
committerandromeda <andromeda@lenovo>2026-03-15 21:55:16 +0100
commitc05adee382fec7b28a971cc6460d81e486bd3684 (patch)
tree8040cab48bec9882c2a92bba64d12a5fa54e76fb /twasm/asm/main.asm
parent64d3e4f6359b77a0ba96a858250af9ea13829010 (diff)
add octal
Diffstat (limited to 'twasm/asm/main.asm')
-rw-r--r--twasm/asm/main.asm64
1 files changed, 49 insertions, 15 deletions
diff --git a/twasm/asm/main.asm b/twasm/asm/main.asm
index 5c41239..069e3f3 100644
--- a/twasm/asm/main.asm
+++ b/twasm/asm/main.asm
@@ -626,7 +626,7 @@ tokenise:
jmp .operator_id_loop
- .found_id
+ .found_id:
push rdx
mov dx, [rcx + 4] ; dx = token id
@@ -730,6 +730,7 @@ tokenise:
; | type | p. | description |
; |------|----|--------------|
; | 0x00 | 0x | hexidecimal |
+; | 0x01 | 0b | octal |
; | 0xFF | | unrecognised |
;
; where `p.` is the prefix
@@ -744,24 +745,38 @@ tokenise:
; ------------------------------------------------------------------------------
evaluate_constant:
+ ; rsi = number of bytes left
+ ; rdi -> current byte of constant
+ xor eax, eax ; rax = value of constant
+
; TODO fix this cheap trick xD
mov dl, [rdi]
- cmp dl, '0'
- jne .unrecognised
dec rsi ; one fewer byte left
inc rdi ; point to next byte
+ cmp dl, '0'
+ jne .unrecognised
mov dl, [rdi]
- cmp dl, 'x'
- jne .unrecognised
dec rsi ; one fewer byte left
inc rdi ; point to next byte
- ; rsi = number of bytes left
- ; rdi -> current byte of constant
- xor eax, eax ; rax = value in hex of constant
+ ; hex case
+ mov rcx, 0x00
+ push rcx
+ cmp dl, 'x'
+ je .hex_loop
+ pop rcx
- .loop:
+ ; octal case
+ mov rcx, 0x01
+ push rcx
+ cmp dl, 'q'
+ je .oct_loop
+ pop rcx
+
+ jmp .unrecognised
+
+ .hex_loop:
cmp rsi, 0 ; make sure we're in range
je .break ; if not, break
@@ -772,24 +787,43 @@ evaluate_constant:
sub dl, '0' ; dl = if digit: digit; else :shrug:
cmp dl, 9 ; if !digit:
- jg .alpha ; letter
- jmp .continue ; else loop
+ jg .hex_alpha ; letter
+ jmp .hex_continue ; else loop
- .alpha
+ .hex_alpha:
sub dl, 7 ; map [('A'-'0')..('F'-'0')] to [0xA..0xF]
cmp dl, 0xF ; if not in the range [0xA..0xF]
jg .unrecognised ; then unrecognised
- .continue
+ .hex_continue:
and dl, 0x0F ; mask
or al, dl ; and add newest nibble
dec rsi ; one fewer byte left
inc rdi ; point to next byte
- jmp .loop ; and loop
+ jmp .hex_loop ; and loop
+
+ .oct_loop:
+ cmp rsi, 0 ; make sure we're in range
+ je .break ; if not, break
+
+ shl rax, 3 ; make room for next octal digit
+
+ mov dl, [rdi] ; dl = next byte of constant
+
+ sub dl, '0'
+ cmp dl, 7
+ jg .unrecognised
+
+ and dl, 7 ; mask
+ or al, dl ; and add newest 3-bit group
+
+ dec rsi ; one fewer byte left
+ inc rdi ; point to next byte
+ jmp .oct_loop ; and loop
.break:
- mov rdx, 0x00 ; hex type
+ pop rdx
ret
.unrecognised: