diff --git a/Makefile b/Makefile index 7ce8111..58dfed1 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,12 @@ +TARGET := langc + + +AFLAGS = -felf64 -F dwarf -g + +ifdef DEBUG + AFLAGS += -DDEBUG_BUILD +endif + SRCDIR := src COREDIR := $(SRCDIR)/core MATHDIR := $(COREDIR)/math @@ -43,7 +52,8 @@ EXPRSRC := $(addprefix $(EXPRDIR)/, $(addsuffix .s, \ create_expressions debug_expression \ )) LEXSRC := $(addprefix $(LEXDIR)/, $(addsuffix .s, \ - lexer lex_err lex_load lex_func \ + lexer lex_err lex_load lex_func program_prologue \ + func_boiler_plate \ )) VARSRC := $(addprefix $(VARDIR)/, $(addsuffix .s, \ get_vars insert_var \ @@ -59,26 +69,35 @@ SRC := $(SRCDIR)/start.s $(MATHSRC) $(STRSRC) $(PRINTSRC) $(FILESRC) $(VARSRC) $ OBJDIR := obj OBJ := $(patsubst $(SRCDIR)/%.s,$(OBJDIR)/%.o,$(SRC)) -all: debug +LIBOBJ := $(filter-out start.o, $(OBJ)) +LIBNAME := core.lang + +all: $(TARGET) + +lib: $(OBJ) + ar rcs $(LIBNAME) $(LIBOBJ) # Create output directories $(OBJDIR)/core/math $(OBJDIR)/core/string $(OBJDIR)/core/print $(OBJDIR)/core/mem $(OBJDIR)/core/syscall $(OBJDIR)/core/file $(OBJDIR)/parse/expression $(OBJDIR)/parse/token $(OBJDIR)/lexer $(OBJDIR)/lexer/vars $(OBJDIR)/global: mkdir -p $@ # Main target -debug: $(OBJDIR) $(OBJDIR)/core/math $(OBJDIR)/core/string $(OBJDIR)/core/print $(OBJDIR)/core/mem $(OBJDIR)/core/syscall $(OBJDIR)/core/file $(OBJDIR)/parse/expression $(OBJDIR)/parse/token $(OBJDIR)/lexer $(OBJDIR)/lexer/vars $(OBJDIR)/global $(OBJ) +$(TARGET): $(OBJDIR) $(OBJDIR)/core/math $(OBJDIR)/core/string $(OBJDIR)/core/print $(OBJDIR)/core/mem $(OBJDIR)/core/syscall $(OBJDIR)/core/file $(OBJDIR)/parse/expression $(OBJDIR)/parse/token $(OBJDIR)/lexer $(OBJDIR)/lexer/vars $(OBJDIR)/global $(OBJ) ld -g -o $@ $(OBJ) -nostdlib -static # Fix: Use a more specific pattern rule that preserves paths $(OBJDIR)/%.o: $(SRCDIR)/%.s mkdir -p $(dir $@) - nasm -felf64 -F dwarf -g $< -o $@ + nasm $(AFLAGS) $< -o $@ $(OBJDIR): mkdir -p $@ clean: - rm -rf $(OBJDIR) debug + rm -rf $(OBJDIR) + +fclean: clean + rm -rf $(TARGET) re: clean all diff --git a/core.lang b/core.lang new file mode 100644 index 0000000..1d30553 Binary files /dev/null and b/core.lang differ diff --git a/src/core/mem/malloc.s b/src/core/mem/malloc.s index 3688f44..736c6d0 100644 --- a/src/core/mem/malloc.s +++ b/src/core/mem/malloc.s @@ -50,6 +50,7 @@ malloc: ; RAX: long basic_malloc(RDI: size_t n) mov r8, rdi push rdi +%ifdef DEBUG_BUILD mov rdi, success call putstr mov rdi, r8 @@ -63,6 +64,7 @@ malloc: ; RAX: long basic_malloc(RDI: size_t n) mov rdi, str_bytecnt call putendl +%endif pop rax sub rax, rbx pop rbx diff --git a/src/core/string/atoi.s b/src/core/string/atoi.s new file mode 100644 index 0000000..2924bbd --- /dev/null +++ b/src/core/string/atoi.s @@ -0,0 +1,15 @@ +section .text + extern strlen + +atoi: ; rax: int (rdi: str*) + push rbp + mov rbp, rsp + sub rsp, 16 + xor rax, rax + xor rcx, rcx + push rdi + call strlen + mov [rbp - 8], rax +.loop: + +.done: diff --git a/src/global/function_table.s b/src/global/function_table.s index 31d416e..3794311 100644 --- a/src/global/function_table.s +++ b/src/global/function_table.s @@ -1,16 +1,17 @@ section .data - func_syms: db \ - "putnumber", 0 \ + putnumber_func: db "putnumber", 0 + exit_func: db "exit", 0 global ftable - ftable: dq 1, \ - func_syms - global func_prologue - func_prologue: db "push rdi", 0 + ftable: dq 2, \ + putnumber_func, \ + exit_func + + global func_call_prologue + func_call_prologue: db " push rdi", 0 global func_call - func_call: db "call ", 0 - - global func_epilogue - func_epilogue: db "pop rdi", 0 + func_call: db " call ", 0 + global func_call_epilogue + func_call_epilogue: db " pop rdi", 0 diff --git a/src/inc/expression.s b/src/inc/expression.s index 0fc591a..6129ba3 100644 --- a/src/inc/expression.s +++ b/src/inc/expression.s @@ -4,8 +4,8 @@ %define EXPR_TOK_CNT 8 %define EXPR_TOK 16 - ; struct expression size = 32 ; .type ; .tok_count + 8 ; .tokens + 16 + diff --git a/src/inc/function_table.s b/src/inc/function_table.s index 531853a..1f58460 100644 --- a/src/inc/function_table.s +++ b/src/inc/function_table.s @@ -1,5 +1,5 @@ %define FTABLE_SIZE 16 -%define FTABLE_COUNT 0 +%define FTABLE_COUNT 2 %define FTABLE_SYM 8 ; struct func_table diff --git a/src/lexer/func_boiler_plate.s b/src/lexer/func_boiler_plate.s new file mode 100644 index 0000000..bf74706 --- /dev/null +++ b/src/lexer/func_boiler_plate.s @@ -0,0 +1,26 @@ +section .text + extern putstr + extern putnumberendl + + func_stack_alloc: db " push rbp", 0xa, " mov rbp, rsp", 0xa, " sub rsp, ", 0 + func_stack_dealloc: db " mov rsp, rbp", 0xa, " pop rbp", 0xa, 0 + ret_inst: db " ret", 0xa, 0 + +global func_prologue +func_prologue: ; (rdi: var_count) + mov rax, 8 + imul rax, rdi + push rax + mov rdi, func_stack_alloc + call putstr + pop rdi + call putnumberendl + ret + +global func_epilogue +func_epilogue: ; + mov rdi, func_stack_dealloc + call putstr + mov rdi, ret_inst + call putstr + ret diff --git a/src/lexer/lex_func.s b/src/lexer/lex_func.s index 8ae5dcc..0a8d581 100644 --- a/src/lexer/lex_func.s +++ b/src/lexer/lex_func.s @@ -8,8 +8,8 @@ section .data err_func_args_message: db FUNC_ERR, "invalid argument", 0 extern func_call - extern func_prologue - extern func_epilogue + extern func_call_prologue + extern func_call_epilogue extern REG_RDI section .text @@ -19,12 +19,14 @@ section .text extern lex_eundefined extern putstr extern putendl + extern putnumberendl extern exit extern look_up_var extern insert_mov extern load_var_reg + extern load_const_reg -insert_func: ; (rdi: name*, rsi: arg*) +insert_func_with_const: ; (rdi: name*, rsi: arg*) push rbp mov rbp, rsp sub rsp, 16 @@ -32,7 +34,32 @@ insert_func: ; (rdi: name*, rsi: arg*) mov [rbp - 8], rdi ; store name mov [rbp - 16], rsi ; store arg - mov rdi, func_prologue + mov rdi, func_call_prologue + call putendl + + mov rdi, [rbp - 16] + mov rsi, REG_RDI + call load_const_reg + mov rdi, func_call + call putstr + mov rdi, [rbp - 8] + call putendl + mov rdi, func_call_epilogue + call putendl + + mov rsp, rbp + pop rbp + ret + +insert_func_with_var: ; (rdi: name*, rsi: arg*) + push rbp + mov rbp, rsp + sub rsp, 16 + + mov [rbp - 8], rdi ; store name + mov [rbp - 16], rsi ; store arg + + mov rdi, func_call_prologue call putendl mov rdi, [rbp - 16] @@ -42,7 +69,7 @@ insert_func: ; (rdi: name*, rsi: arg*) call putstr mov rdi, [rbp - 8] call putendl - mov rdi, func_epilogue + mov rdi, func_call_epilogue call putendl mov rsp, rbp @@ -59,8 +86,7 @@ err_func_args: global look_up_func look_up_func: ; (rdi: name*) push rbx - lea rdx, [ftable] - mov rbx, [rdx + FTABLE_COUNT] + mov rbx, FTABLE_COUNT xor rcx, rcx .search_func: @@ -68,9 +94,14 @@ look_up_func: ; (rdi: name*) je .done_false ; rdi still contains name - mov rsi, [rdx + FTABLE_SYM] + push rcx + mov rax, FTABLE_SYM + inc rcx + imul rax, rcx + mov rsi, [ftable + rax] call strcmp test rax, rax + pop rcx jz .done_true inc rcx @@ -132,6 +163,10 @@ lex_func_call: ; rax: bool (rdi :lex *) call err_func_args .arg_const: + mov rdi, [rbp - 24] + mov rsi, [rsi + TOK_VALUE] + call insert_func_with_const + jmp .done .arg_var: mov rdi, [rbp - 8] @@ -139,7 +174,7 @@ lex_func_call: ; rax: bool (rdi :lex *) call look_up_var mov rsi, rax mov rdi, [rbp - 24] - call insert_func + call insert_func_with_var .done: diff --git a/src/lexer/lexer.s b/src/lexer/lexer.s index 19f92ac..465c1d2 100644 --- a/src/lexer/lexer.s +++ b/src/lexer/lexer.s @@ -8,15 +8,19 @@ section .text extern err_malloc extern exit extern putstr + extern putendl extern create_expressions extern strcmp extern get_vars extern lex_load extern lex_func_call - extern lex_eundefined + extern func_prologue + extern func_epilogue + + extern program_prologue global lex lex: ; rax: lex* (rdi: char *file_content) @@ -42,11 +46,19 @@ lex: ; rax: lex* (rdi: char *file_content) mov rdi, [rbp - 24] mov [rdi + LEX_EXPR], rax - mov rax, [rbp - 16] - mov [rdi + LEX_EXPR_CNT], rax + mov eax, dword [rbp - 16] + mov dword [rdi + LEX_EXPR_CNT], eax call get_vars + mov rdi, [rbp - 24] + call program_prologue + + mov rdi, [rbp - 24] + mov edi, dword [rdi + LEX_VAR_CNT] + + call func_prologue + mov rax, [rbp - 24] lea rcx, [rax + LEX_EXPR_IDX] @@ -71,6 +83,7 @@ lex: ; rax: lex* (rdi: char *file_content) jmp .process_expressions .done: + call func_epilogue pop rbx mov rsp, rbp pop rbp diff --git a/src/lexer/program_prologue.s b/src/lexer/program_prologue.s new file mode 100644 index 0000000..e56e3bb --- /dev/null +++ b/src/lexer/program_prologue.s @@ -0,0 +1,96 @@ +%include "./src/inc/lexer.s" +%include "./src/inc/token.s" +%include "./src/inc/expression.s" + +section .data + section_text: db "section .text", 0xa, 0 + program_start: db "global _start", 0xa, "_start:", 0xa, 0 + extern_str: db "extern ", 0 + + +section .text + extern putendl + extern putstr + + global program_prologue + +print_section_text: + mov rdi, section_text + call putstr + ret + +print_program_start: + mov rdi, program_start + call putendl + ret + +declare_extern: ; (rdi: func_name*) + push rdi + mov rdi, extern_str + call putstr + pop rdi + call putendl + ret + +declare_extern_func: ;(rdi: lex*) + push rbp + mov rbp, rsp + + sub rsp, 16 + + push rbx + xor rcx, rcx + + mov rax, [rdi + LEX_EXPR] + mov [rbp - 8], rax + mov eax, dword [rdi + LEX_EXPR_CNT] + mov [rbp - 12], eax +.loop: + cmp ecx, [rbp - 12] + je .loop_end + mov rbx, [rbp - 8] + mov rax, EXPR_SIZE + imul rax, rcx + lea rbx, [rbx + rax] + mov r8, [rbx + EXPR_TOK_CNT] + mov rbx, [rbx + EXPR_TOK] + push rcx + xor rcx, rcx +.loop_tokens: + cmp rcx, r8 + je .loop_tokens_end + mov rax, SIZE_TOK + imul rax, rcx + lea rax, [rbx + rax] + mov rdx, TOK_FUNC + cmp rdx, qword [rax + TOK_TYPE] + jne .dont_print + mov rdi, [rax + TOK_VALUE] + push rcx + push r8 + call declare_extern + pop r8 + pop rcx +.dont_print: + inc rcx + jmp .loop_tokens +.loop_tokens_end: + pop rcx + inc rcx + jmp .loop + +.loop_end: + pop rbx + + mov rsp, rbp + pop rbp + ret + +program_prologue: ;(rdi: lex*) + push rdi + mov rdi, section_text + call putendl + pop rdi + call declare_extern_func + call print_program_start + ret diff --git a/src/lexer/vars/get_vars.s b/src/lexer/vars/get_vars.s index 8d93305..d71c1ff 100644 --- a/src/lexer/vars/get_vars.s +++ b/src/lexer/vars/get_vars.s @@ -124,7 +124,8 @@ get_vars: ; (rdi: lex*) push rcx .loop_expr: pop rcx - cmp ecx, dword [rdi + LEX_EXPR_CNT] + mov ebx, dword [rbp - 8] + cmp ecx, ebx je .done mov rax, EXPR_SIZE mul rcx @@ -156,7 +157,9 @@ get_vars: ; (rdi: lex*) pop rcx pop rdi cmp rax, 1 + pop rax je .skip_alloc + push rax mov rax, VAR_SIZE mul r9 lea rbx, [rbx + rax] diff --git a/src/lexer/vars/insert_var.s b/src/lexer/vars/insert_var.s index 1dd99c4..4762477 100644 --- a/src/lexer/vars/insert_var.s +++ b/src/lexer/vars/insert_var.s @@ -2,10 +2,10 @@ section .data - INST_MOV: db "mov ", 0 - INST_ADD: db "add ", 0 - INST_SUB: db "sub ", 0 - INST_XOR: db "xor ", 0 + INST_MOV: db " mov ", 0 + INST_ADD: db " add ", 0 + INST_SUB: db " sub ", 0 + INST_XOR: db " xor ", 0 OPEN_STACK_VAR: db "[rbp-", 0 CLOSE_STACK_VAR: db "]", 0 @@ -14,6 +14,7 @@ section .data section .text extern putstr extern putnumber + extern putnumberendl extern putchar extern putendl extern VAL_CONST @@ -25,7 +26,6 @@ section .text extern REG_RAX extern REG_RDI - global insert_xor insert_xor: mov rdi, INST_XOR @@ -86,6 +86,24 @@ load_reg_var: ; (rdi: OFF_S, rsi: REG*) ret +global load_const_reg +load_const_reg: ; (rdi: const*, rsi: REG*) + push rdi + push rsi + + call insert_mov + + pop rdi + call putstr + + mov rdi, SEP_INST + call putstr + + pop rdi + call insert_const_endl + + ret + global load_var_reg load_var_reg: ; (rdi: OFF_S, rsi: REG*) push rdi @@ -237,7 +255,13 @@ sub_rax_var: ; (rdi: OFF_S) ret -global insert_var +insert_const_endl: ; (rdi: const*) + push rdi + call putendl + pop rdi + + ret + insert_var_endl: ; (rdi: OFF_S) push rdi mov rdi, OPEN_STACK_VAR diff --git a/src/parse/expression/create_expressions.s b/src/parse/expression/create_expressions.s index 07541d9..ab6f36b 100644 --- a/src/parse/expression/create_expressions.s +++ b/src/parse/expression/create_expressions.s @@ -107,9 +107,11 @@ create_expressions: ; rax: exp* (rdi: char *filecontent, rsi: *cnt) mov rax, EXPR_SIZE mul rcx lea rdi, [rbx + rax] +%ifdef DEBUG_BUILD push rcx call print_expression pop rcx +%endif inc rcx jmp .expr_loop_print diff --git a/src/parse/tokenizer.s b/src/parse/tokenizer.s index 2f9e2ee..b87dfd2 100644 --- a/src/parse/tokenizer.s +++ b/src/parse/tokenizer.s @@ -1,9 +1,9 @@ section .text is_space: ; rax: bool (rdi: c) - cmp c, 8 + cmp rdi, 8 jl .false - cmp c, 13 + cmp rdi, 13 je .false .true: mov rax, 1 diff --git a/src/start.s b/src/start.s index 5a1d8e5..6e20e0f 100644 --- a/src/start.s +++ b/src/start.s @@ -19,68 +19,24 @@ print_usage: call putstr _start: + pop rdi + cmp rdi, 2 + jne err_args + mov rdi, [rsp + 8] ; argv[1] push rbp mov rbp, rsp + sub rsp, 16 - mov rdi, 1 - call vec_create + call get_file_content mov rdi, rax + mov [rbp - 8], rax - xor rcx, rcx - mov rbx, 90 - mov r8, ' ' + mov rdi, rax + call lex -.loop: - cmp rcx, rbx - je .done - push rcx - push r8 - mov byte [rbp - 4], r8b - lea rsi, [rbp - 4] - push rdi - call vec_push - pop rdi - pop r8 - pop rcx - inc r8 - inc rcx - jmp .loop -.done: - push rdi - call vec_pop - pop rdi - push rdi - mov rdi, [rdi + 16] - call putstr - pop rdi - lea rsi, [rbp - 1] - mov rdx, 88 - call vec_get - test rax, rax - jz done - - mov dil, byte [rbp - 1] - call putchar - -; pop rdi -; cmp rdi, 2 -; jne err_args -; mov rdi, [rsp + 8] ; argv[1] -; push rbp -; mov rbp, rsp -; -; sub rsp, 16 -; -; call get_file_content -; mov rdi, rax -; mov [rbp - 8], rax -; -; mov rdi, rax -; call lex -; -; mov rsp, rbp -; pop rbp + mov rsp, rbp + pop rbp done: xor rdi, rdi diff --git a/test.c b/test.c deleted file mode 100644 index 50090b9..0000000 --- a/test.c +++ /dev/null @@ -1,24 +0,0 @@ -#include - -int main(int argc, char **argv) { - - int a = 17; - - switch (a) { - case 1: - break ; - case 2: - break ; - case 3: - break ; - case 4: - break ; - case 5: - break ; - case 6: - break ; - case 17: - a = 0xfffaaaaf; - break ; - } -} diff --git a/test.lang b/test.lang index fe95113..352d7b3 100644 --- a/test.lang +++ b/test.lang @@ -1,3 +1,7 @@ a = 6 b = 5 - 2 + 6 + a putnumber b +c = b + a +putnumber c +a = 0 +exit 1