Skip to content

Commit

Permalink
Parser (#48)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbirddog authored Jun 20, 2024
1 parent 3185b4d commit 8abc1af
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 1 deletion.
8 changes: 8 additions & 0 deletions defs.inc
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@

_blue:
.tib dq 1
.tib_len dd 1
.tib_in dd 1
.word_len db 1
.word rb 255
.mode db 1
_code_buffer:
.length = 4096
.base dq 1
Expand Down
4 changes: 4 additions & 0 deletions linux.inc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ PROT_RWX = PROT_RW or PROT_EXEC
MAP_ANONYMOUS = 32
MAP_PRIVATE = 2

STDIN_FILENO = 0
STDOUT_FILENO = 1
STDERR_FILENO = 2

;
; expects
; - buffer length in esi
Expand Down
59 changes: 59 additions & 0 deletions parser.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

;
; expects
; - properly configured _blue structure
;
parser_next_word:
mov [_blue.word_len], 0

mov ecx, [_blue.tib_len]
test ecx, ecx
jz .done

mov eax, [_blue.tib_in]
sub ecx, eax
jng .done

and ecx, 0xFF
push rcx

mov rsi, [_blue.tib]
add esi, eax
mov rdi, _blue.word

call _skip_ws

test ecx, ecx
jz .set_tib_in

.loop:
cmp byte [esi], 32
jle .loop_done
movsb
dec ecx
jnz .loop
.loop_done:
sub rdi, _blue.word
mov [_blue.word_len], dil

.set_tib_in:
pop rax
sub eax, ecx
add [_blue.tib_in], eax
.done:
ret
_skip_ws:
cmp byte [esi], 32
jg .done

inc rsi
dec ecx
jnz _skip_ws

.done:
ret
112 changes: 112 additions & 0 deletions parser_test.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
format elf64 executable 3

macro tc2 word_in, word_len {
call parser_next_word

inc [test_num]
xor eax, eax
mov al, [_blue.word_len]
cmp al, word_len
jne failure

mov ecx, eax
mov eax, word_in
call check_word
}

macro tc1 tib, tib_len, word_in, word_len {
mov [_blue.tib], tib
mov [_blue.tib_len], tib_len
mov [_blue.tib_in], 0

tc2 word_in, word_len
}

segment readable writeable

include "defs.inc"

test_num db 1

segment readable executable

include "linux.inc"
include "parser.inc"

entry $
mov [test_num], 0

tc1 nothing, 0, 0, 0
tc1 space, 1, 0, 0
tc1 tab, 1, 0, 0
tc1 newline, 1, 0, 0
tc1 spaces, 2, 0, 0
tc1 ws_4, 4, 0, 0

tc1 six, 1, 0, 1
tc1 space_a, 2, 1, 1
tc1 a_space, 2, 0, 1
tc1 abc, 3, 0, 3
tc1 ws_abc_ws, 7, 2, 3

tc1 toks_2, 3, 0, 1
tc2 2, 1

tc1 toks_3, 20, 3, 4
tc2 9, 4
tc2 14, 6

xor edi, edi

exit:
mov eax, 60
syscall

failure:
mov dil, [test_num]
jmp exit

failure2:
mov dil, [test_num]
add dil, 100
jmp exit

;
; expects
; - word_len in ecx
; - word_in in al
;
check_word:
test cl, cl
jz .done

mov rsi, [_blue.tib]
add esi, eax
mov rdi, _blue.word

.loop:
cmpsb
jne failure2

dec ecx
jnz .loop
.done:
ret

segment readable

nothing db 0
space db 32
tab db 9
newline db 10
spaces db 32, 32
ws_4 db 32, 9, 10, 32
six db '6'
space_a db ' a'
a_space db 'a '
abc db 'abc'
ws_abc_ws db 10, 32, 'abc', 9, 10
toks_2 db 'a b'
toks_3 db ' some more tokens'
3 changes: 2 additions & 1 deletion test.mk
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@

TESTS := \
code_buffer_test \
parser_test \
elf_test \
elf_test_hello_world

$(TESTS):
echo "Testing $@... " && \
@echo "Testing $@... " && \
make WHAT=$@ compile run && \
rm -f $@ && \
echo ""
Expand Down

0 comments on commit 8abc1af

Please sign in to comment.