simple vector type

This commit is contained in:
Victor Vobis 2025-04-30 18:33:40 +02:00
parent aac7ef9fbc
commit f3cb1d5858
28 changed files with 596 additions and 114 deletions

BIN
.nfs00000000113621d400000ffd Executable file

Binary file not shown.

View File

@ -1,3 +1,4 @@
[executable]
path=/home/victor/git/lang/debug
arguments=/home/victor/git/lang/test.lang
path=/sgoinfre/vvobis/git/personal/lang/debug
arguments=/sgoinfre/vvobis/git/personal/lang/test.lang
ask_directory=1

View File

@ -1,13 +1,18 @@
SRCDIR := src
COREDIR := $(SRCDIR)/core
MATHDIR := $(COREDIR)/math
VECDIR := $(COREDIR)/vector
STRDIR := $(COREDIR)/string
PRINTDIR := $(COREDIR)/print
MEMDIR := $(COREDIR)/mem
SYSCALLDIR := $(COREDIR)/syscall
FILEDIR := $(COREDIR)/file
PARSEDIR := $(SRCDIR)/parse
VARDIR := $(PARSEDIR)/vars
EXPRDIR := $(PARSEDIR)/expression
TOKDIR := $(PARSEDIR)/token
LEXDIR := $(SRCDIR)/lexer
VARDIR := $(LEXDIR)/vars
GLOBALDIR := $(SRCDIR)/global
# Define source files
MATHSRC := $(addprefix $(MATHDIR)/, $(addsuffix .s, \
@ -17,7 +22,10 @@ STRSRC := $(addprefix $(STRDIR)/, $(addsuffix .s, \
strlen split strcpy substr is_num strcmp is_alpha \
))
MEMSRC := $(addprefix $(MEMDIR)/, $(addsuffix .s, \
malloc memchr \
malloc memchr memcpy \
))
VECSRC := $(addprefix $(VECDIR)/, $(addsuffix .s, \
vec_create vec_push vec_get\
))
PRINTSRC := $(addprefix $(PRINTDIR)/, $(addsuffix .s, \
print putnumber \
@ -28,55 +36,45 @@ FILESRC := $(addprefix $(FILEDIR)/, $(addsuffix .s, \
SYSCALLSRC := $(addprefix $(SYSCALLDIR)/, $(addsuffix .s, \
exit file_ops syscall_err\
))
PARSESRC := $(addprefix $(PARSEDIR)/, $(addsuffix .s, \
parse debug_token create_expressions debug_expression \
lexer lex_load lex_err \
TOKSRC := $(addprefix $(TOKDIR)/, $(addsuffix .s, \
parse_tokens debug_token \
))
EXPRSRC := $(addprefix $(EXPRDIR)/, $(addsuffix .s, \
create_expressions debug_expression \
))
LEXSRC := $(addprefix $(LEXDIR)/, $(addsuffix .s, \
lexer lex_err lex_load lex_func \
))
VARSRC := $(addprefix $(VARDIR)/, $(addsuffix .s, \
get_vars insert_var \
get_vars insert_var \
))
GLOBALSRC := $(addprefix $(GLOBALDIR)/, $(addsuffix .s, \
function_table regs \
))
# Collect all source files - now using the file variables, not directory variables
SRC := $(SRCDIR)/start.s $(MATHSRC) $(STRSRC) $(PRINTSRC) $(FILESRC) $(VARSRC) $(PARSESRC) $(SYSCALLSRC) $(MEMSRC)
# Collect all source files
SRC := $(SRCDIR)/start.s $(MATHSRC) $(STRSRC) $(PRINTSRC) $(FILESRC) $(VARSRC) $(SYSCALLSRC) $(MEMSRC) $(TOKSRC) $(EXPRSRC) $(LEXSRC) $(GLOBALSRC) $(VECSRC)
# Fix: Preserve directory structure in object files
OBJDIR := obj
OBJ := $(patsubst %.s,$(OBJDIR)/%.o,$(notdir $(SRC)))
OBJ := $(patsubst $(SRCDIR)/%.s,$(OBJDIR)/%.o,$(SRC))
all: debug
debug: $(OBJDIR) $(OBJ)
ld -o $@ $(OBJ) -nostdlib -static
# 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 $@
# Pattern rules for object files - added the missing rules for string and print
# 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)
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 $@
$(OBJDIR)/%.o: $(MATHDIR)/%.s
nasm -felf64 -F dwarf -g $< -o $@
$(OBJDIR)/%.o: $(STRDIR)/%.s
nasm -felf64 -F dwarf -g $< -o $@
$(OBJDIR)/%.o: $(MEMDIR)/%.s
nasm -felf64 -F dwarf -g $< -o $@
$(OBJDIR)/%.o: $(SYSCALLDIR)/%.s
nasm -felf64 -F dwarf -g $< -o $@
$(OBJDIR)/%.o: $(PRINTDIR)/%.s
nasm -felf64 -F dwarf -g $< -o $@
$(OBJDIR)/%.o: $(FILEDIR)/%.s
nasm -felf64 -F dwarf -g $< -o $@
$(OBJDIR)/%.o: $(PARSEDIR)/%.s
nasm -felf64 -F dwarf -g $< -o $@
$(OBJDIR)/%.o: $(VARDIR)/%.s
nasm -felf64 -F dwarf -g $< -o $@
$(OBJDIR):
$(OBJDIR):
mkdir -p $@
clean:

BIN
a.out Executable file

Binary file not shown.

18
src/core/mem/memcpy.s Normal file
View File

@ -0,0 +1,18 @@
section .text
global memcpy
memcpy: ; (rdi: dst*, rsi: src*, rdx: len)
xor rcx, rcx
push rbx
.copy:
cmp rcx, rdx
je .done
mov bl, byte [rsi + rcx]
mov byte [rdi + rcx], bl
inc rcx
jmp .copy
.done:
pop rbx
ret

View File

@ -0,0 +1,41 @@
%include "./src/core/vector/vector.inc"
section .text
extern malloc
extern err_malloc
extern memcpy
global vec_create
vec_create: ; rax: vec* (rdi: member_size)
push rbp
mov rbp, rsp
sub rsp, 16
; allocate vector ptr
push rdi
mov rdi, VEC_SIZE
call malloc
test rax, rax
jz err_malloc
pop rdi
mov [rbp - 8], rax ; store vec
mov dword [rax + VEC_COUNT], 0
mov dword [rax + VEC_CAP], VEC_DEFAULT_CAP
mov dword [rax + VEC_MEMBER_SIZE], edi
; allocate initial vector capacity
imul rdi, VEC_DEFAULT_CAP
call malloc
test rax, rax
jz err_malloc
mov rdi, [rbp - 8]
mov [rdi + VEC_MEM], rax
mov rax, rdi
mov rsp, rbp
pop rbp
ret

36
src/core/vector/vec_get.s Normal file
View File

@ -0,0 +1,36 @@
%include "./src/core/vector/vector.inc"
section .text
extern memcpy
global vec_get
vec_get: ; rax: bool (rdi: vec*, rsi: dest*, rdx: idx)
push rbp
mov rbp, rsp
sub rsp, 16
mov eax, dword [rdi + VEC_COUNT]
cmp eax, edx
jl .not_found
push rsi
mov rax, rdx
mov rsi, [rdi + VEC_MEM]
imul eax, dword [rdi + VEC_MEMBER_SIZE]
add rsi, rax
mov edx, dword [rdi + VEC_MEMBER_SIZE]
pop rdi
call memcpy
mov rax, 1
jmp .done
.not_found:
xor rax, rax
.done:
mov rsp, rbp
pop rbp
ret

View File

@ -0,0 +1,65 @@
%include "./src/core/vector/vector.inc"
section .text
extern malloc
extern err_malloc
extern memcpy
global vec_push
vec_push: ; (rdi: vec*, rsi: mem*)
push rbp
mov rbp, rsp
sub rsp, 48
mov eax, dword [rdi + VEC_COUNT]
mov dword [rbp - 4], eax
mov eax, dword [rdi + VEC_CAP]
mov dword [rbp - 8], eax
mov eax, dword [rdi + VEC_MEMBER_SIZE]
mov dword [rbp - 12], eax
mov [rbp - 24], rdi ; store vec
mov rax, [rdi + VEC_MEM]
mov [rbp - 32], rax
mov [rbp - 40], rsi
mov eax, dword [rbp - 4]
cmp eax, dword [rbp - 8]
je .reallocate
.push:
mov rsi, [rbp - 40]
mov rdi, [rbp - 24]
mov eax, dword [rdi + VEC_MEMBER_SIZE]
imul eax, dword [rbp - 4]
mov rdi, [rdi + VEC_MEM]
add rdi, rax
mov edx, dword [rbp - 12]
call memcpy
mov rdi, [rbp - 24]
inc dword [rdi + VEC_COUNT]
.done:
mov rsp, rbp
pop rbp
ret
.reallocate:
imul eax, 2
mov edi, eax
push rax
call malloc
test rax, rax
jz err_malloc
mov rdi, rax
mov rsi, [rbp - 32]
mov edx, dword [rbp - 4]
call memcpy
pop rax
mov rdx, [rbp - 24]
mov [rdx + VEC_MEM], rdi
mov dword [rdx + VEC_CAP], eax
jmp .push

View File

@ -0,0 +1,13 @@
%define VEC_SIZE 32
%define VEC_DEFAULT_CAP 64
%define VEC_COUNT 0
%define VEC_CAP 4
%define VEC_MEMBER_SIZE 8
%define VEC_MEM 16
; struct vec
; .count 0
; .cap 4
; .member_size 8
; .mem 16

View File

@ -0,0 +1,16 @@
section .data
func_syms: db \
"putnumber", 0 \
global ftable
ftable: dq 1, \
func_syms
global func_prologue
func_prologue: db "push rdi", 0
global func_call
func_call: db "call ", 0
global func_epilogue
func_epilogue: db "pop rdi", 0

6
src/global/regs.s Normal file
View File

@ -0,0 +1,6 @@
section .data
global REG_RDI
REG_RDI: db "rdi", 0
global REG_RAX
REG_RAX: db "rax", 0

7
src/inc/function_table.s Normal file
View File

@ -0,0 +1,7 @@
%define FTABLE_SIZE 16
%define FTABLE_COUNT 0
%define FTABLE_SYM 8
; struct func_table
; .count 0
; .symbols 8

View File

@ -1,3 +0,0 @@
section .data
REG_RAX: db "rax", 0

150
src/lexer/lex_func.s Normal file
View File

@ -0,0 +1,150 @@
%include "./src/inc/lexer.s"
%include "./src/inc/expression.s"
%include "./src/inc/function_table.s"
%include "./src/inc/token.s"
%define FUNC_ERR "[FUNC_ERROR]"
section .data
err_func_args_message: db FUNC_ERR, "invalid argument", 0
extern func_call
extern func_prologue
extern func_epilogue
extern REG_RDI
section .text
global lex_func_call
extern ftable
extern strcmp
extern lex_eundefined
extern putstr
extern putendl
extern exit
extern look_up_var
extern insert_mov
extern load_var_reg
insert_func: ; (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_prologue
call putendl
mov rdi, [rbp - 16]
mov rsi, REG_RDI
call load_var_reg
mov rdi, func_call
call putstr
mov rdi, [rbp - 8]
call putendl
mov rdi, func_epilogue
call putendl
mov rsp, rbp
pop rbp
ret
err_func_args:
mov rdi, err_func_args_message
call putendl
mov rdi, 1
call exit
; does not change rdi
global look_up_func
look_up_func: ; (rdi: name*)
push rbx
lea rdx, [ftable]
mov rbx, [rdx + FTABLE_COUNT]
xor rcx, rcx
.search_func:
cmp rcx, rbx
je .done_false
; rdi still contains name
mov rsi, [rdx + FTABLE_SYM]
call strcmp
test rax, rax
jz .done_true
inc rcx
jmp .search_func
.done_true:
mov rax, 1
jmp .done
.done_false:
xor rax, rax
.done:
pop rbx
ret
lex_func_call: ; rax: bool (rdi :lex *)
push rbp
mov rbp, rsp
sub rsp, 32
mov [rbp - 8], rdi ; store lex
; store expression based on lexer expression index
mov rsi, [rdi + LEX_EXPR]
mov rax, [rdi + LEX_EXPR_IDX]
imul rax, EXPR_SIZE
lea rsi, [rsi + rax]
mov [rbp - 16], rsi
mov rdi, [rsi + EXPR_TOK_CNT]
mov rax, [rsi + EXPR_TOK]
cmp qword [rax + TOK_TYPE], TOK_FUNC
jne .done
cmp rdi, 2
jne err_func_args
mov rdi, [rax + TOK_VALUE]
push rdi
call look_up_func
test rax, rax
pop rdi
jz lex_eundefined
mov [rbp - 24], rdi
mov rdi, [rbp - 16]
mov rsi, [rdi + EXPR_TOK]
lea rsi, [rsi + SIZE_TOK]
cmp qword [rsi + TOK_TYPE], TOK_CONST
je .arg_const
cmp qword [rsi + TOK_TYPE], TOK_VAR
je .arg_var
call err_func_args
.arg_const:
.arg_var:
mov rdi, [rbp - 8]
mov rsi, [rsi + TOK_VALUE]
call look_up_var
mov rsi, rax
mov rdi, [rbp - 24]
call insert_func
.done:
mov rsp, rbp
pop rbp
ret

View File

@ -1,7 +1,6 @@
%include "./src/inc/lexer.s"
%include "./src/inc/expression.s"
%include "./src/inc/token.s"
%include "./src/inc/regs.s"
section .text
extern malloc
@ -27,6 +26,8 @@ section .text
extern xor_reg
extern look_up_var
extern REG_RAX
extern lex_eexpect
extern lex_eundefined
@ -80,9 +81,13 @@ process_token: ; rax: new_last_tok_type (rdi: lex*, rsi: *tok, rdx: last_to
jmp .done
.process_const:
mov rsi, [rsi + TOK_VALUE]
push rdi
mov rdi, [rsi + TOK_VALUE]
mov rsi, rdx
call op_const_rax
pop rdi
mov rax, TOK_CONST
jmp .done
@ -103,7 +108,7 @@ process_token: ; rax: new_last_tok_type (rdi: lex*, rsi: *tok, rdx: last_to
.done:
ret
is_assignment: ; rax: OFF_S (rdi: expr*)
is_load: ; rax: OFF_S (rdi: expr*)
xor rax, rax
mov rcx, [rdi + EXPR_TOK_CNT]
@ -120,7 +125,7 @@ is_assignment: ; rax: OFF_S (rdi: expr*)
.done:
ret
lex_load: ; (rdi: lex*)
lex_load: ; rax: bool (rdi: lex*)
push rbp
mov rbp, rsp
sub rsp, 48
@ -144,7 +149,7 @@ lex_load: ; (rdi: lex*)
mov rdi, [rbp - 16]
push rdi
call is_assignment
call is_load
test rax, rax
jz .done_false
@ -166,6 +171,7 @@ lex_load: ; (rdi: lex*)
pop rdi
; advance token ptr
mov rdi, [rbp - 16]
mov rsi, [rdi + EXPR_TOK]
xor rcx, rcx
@ -195,7 +201,11 @@ lex_load: ; (rdi: lex*)
mov rdi, [rbp - 40]
call load_rax_var
mov rax, 1
.done_false:
mov rsp, rbp
pop rbp
ret
.done_false:
mov rax, 0
mov rsp, rbp
pop rbp
ret

View File

@ -2,33 +2,19 @@
%include "./src/inc/lexer.s"
%include "./src/inc/expression.s"
%include "./src/inc/asm_output.s"
%include "./src/inc/regs.s"
section .text
extern malloc
extern err_malloc
extern exit
extern putstr
extern create_expressions
extern strcmp
extern VAL_OP_LOAD
extern VAL_OP_ADD
extern VAL_VAR
extern VAL_CONST
extern putchar
extern putnumber
extern putendl
extern get_vars
extern insert_var
extern insert_mov
extern load_var_rax
extern load_rax_var
extern add_const_rax
extern add_var_rax
extern sub_const_rax
extern sub_var_rax
extern xor_reg
extern lex_load
extern lex_func_call
extern lex_eundefined
@ -73,9 +59,14 @@ lex: ; rax: lex* (rdi: char *file_content)
push rcx
call lex_load
test rax, rax
jnz .loop_epilog
mov rdi, [rbp - 24]
call lex_func_call
jnz .loop_epilog
.loop_epilog:
pop rcx
inc dword [rcx]
jmp .process_expressions
@ -85,8 +76,6 @@ lex: ; rax: lex* (rdi: char *file_content)
pop rbp
ret
global look_up_var
look_up_var: ; rax: bool (rdi: lex*, rsi: name*)
push rbp

View File

@ -118,7 +118,7 @@ get_vars: ; (rdi: lex*)
mov eax, dword [rdi + LEX_EXPR_CNT]
mov [rbp - 8], eax
mov rax, [rdi + LEX_EXPR]
mov [rbp - 16], rax
mov [rbp - 16], rax ; store expr*
xor rcx, rcx
push rcx

View File

@ -1,7 +1,7 @@
%include "./src/inc/token.s"
%include "./src/inc/regs.s"
section .data
INST_MOV: db "mov ", 0
INST_ADD: db "add ", 0
INST_SUB: db "sub ", 0
@ -11,7 +11,6 @@ section .data
CLOSE_STACK_VAR: db "]", 0
SEP_INST: db ", ", 0
section .text
extern putstr
extern putnumber
@ -23,6 +22,8 @@ section .text
extern VAL_OP_SUB
extern VAL_OP_LOAD
extern VAL_FUNC
extern REG_RAX
extern REG_RDI
global insert_xor
@ -68,6 +69,41 @@ xor_reg: ; rdi: char*
pop rbx
ret
global load_reg_var
load_reg_var: ; (rdi: OFF_S, rsi: REG*)
push rsi
push rdi
call insert_mov
pop rdi
call insert_var
mov rdi, SEP_INST
call putstr
pop rdi
call putendl
ret
global load_var_reg
load_var_reg: ; (rdi: OFF_S, rsi: REG*)
push rdi
push rsi
call insert_mov
pop rdi
call putstr
mov rdi, SEP_INST
call putstr
pop rdi
call insert_var_endl
ret
global load_rax_var
load_rax_var: ; (rdi: OFF_S)
push rdi

View File

@ -33,7 +33,7 @@ section .text
extern putendl
extern putnumberendl
extern get_split_count
extern look_up_func
token_alloc: ; rax: tok* (rdi: int cnt)
mov rax, rdi
@ -80,10 +80,9 @@ parse: ; rax: tok* (rdi: char**)
call strcmp
cmp rax, 0
je .is_add
mov rsi, OP_PRINT
call strcmp
cmp rax, 0
je .is_print
call look_up_func
cmp rax, 1
je .is_func
push rdi
call is_num_str
pop rdi
@ -109,7 +108,7 @@ parse: ; rax: tok* (rdi: char**)
mov rdi, TOK_ADD
jmp .set_token
.is_print:
.is_func:
pop rcx
push rdi
mov rdi, TOK_FUNC

33
src/parse/tokenizer.s Normal file
View File

@ -0,0 +1,33 @@
section .text
is_space: ; rax: bool (rdi: c)
cmp c, 8
jl .false
cmp c, 13
je .false
.true:
mov rax, 1
ret
.false:
xor rax, rax
ret
tokenize: ; (rdi: char *)
push rbp
mov rbp, rsp
sub rsp, 32
mov [rbp - 8], rdi
xor rcx, rcx
mov rsi, rdi
.loop_char:
mov rdi, [rsi + rcx]
call is_space
test rax, rax
jnz .end_tok
.end_tok:
jmp .loop_char

View File

@ -1,53 +1,82 @@
section .data
usage: db "Usage: ./debug <file>.lang", 0xa, 0
section .text
global _start
extern exit
extern split
extern print_split
extern putchar
extern putstr
extern putnumber
extern open
extern close
extern read
extern get_file_size
extern malloc
extern lseek
extern read_file
extern err_args
extern putendl
extern parse
extern print_tokens
extern err_malloc
extern get_file_content
extern create_expressions
extern putstr
extern lex
extern vec_create
extern vec_push
extern vec_get
extern putchar
print_usage:
mov rdi, 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
call get_file_content
mov rdi, 1
call vec_create
mov rdi, rax
mov [rbp - 8], rax
mov rdi, rax
call lex
xor rcx, rcx
mov rbx, 95
mov r8, ' '
mov rsp, rbp
pop rbp
.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
mov rdi, [rdi + 16]
call putstr
pop rdi
lea rsi, [rbp - 1]
mov rdx, 94
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
done:
xor rdi, rdi

27
test.c
View File

@ -1,11 +1,24 @@
#include <string.h>
#include <unistd.h>
#include "../libft/libft.h"
#include <stdio.h>
int main(int argc, char **argv) {
ft_split(argv[1], *argv[2]);
for (int i = 0; i < 2; i++)
{
write(1, argv[i + 1], strlen(argv[i + 1]));
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 ;
}
}

View File

@ -1,2 +1,3 @@
a = 6
b = 5 - 2 + 6 + a
putnumber b

24
test.s Normal file
View File

@ -0,0 +1,24 @@
section .text
global _start
extern putnumber
_start:
push rbp
mov rbp, rsp
sub rsp, 16
xor rax, rax
add rax, 6
mov [rbp-8], rax
xor rax, rax
add rax, 5
sub rax, 2
add rax, 6
add rax, [rbp-8]
mov [rbp-16], rax
push rdi
mov rdi, [rbp-16]
call putnumber
pop rdi
mov rsp, rbp
pop rbp
ret