diff --git a/defs.inc b/defs.inc index c1dd6ee..586023f 100644 --- a/defs.inc +++ b/defs.inc @@ -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 diff --git a/linux.inc b/linux.inc index 1bcd7c2..a473e17 100644 --- a/linux.inc +++ b/linux.inc @@ -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 diff --git a/parser.inc b/parser.inc new file mode 100644 index 0000000..165ad5b --- /dev/null +++ b/parser.inc @@ -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 diff --git a/parser_test.asm b/parser_test.asm new file mode 100644 index 0000000..804e8c0 --- /dev/null +++ b/parser_test.asm @@ -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' diff --git a/test.mk b/test.mk index e31238d..c0abcc3 100644 --- a/test.mk +++ b/test.mk @@ -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 ""