first commit
This commit is contained in:
commit
26c2bec61a
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
vgcore*
|
||||
debug
|
||||
obj
|
||||
*.o
|
||||
4
.project.gf
Normal file
4
.project.gf
Normal file
@ -0,0 +1,4 @@
|
||||
[executable]
|
||||
path=/home/victor/git/ctools/lang/debug
|
||||
arguments=
|
||||
ask_directory=1
|
||||
78
Makefile
Normal file
78
Makefile
Normal file
@ -0,0 +1,78 @@
|
||||
SRCDIR := src
|
||||
COREDIR := $(SRCDIR)/core
|
||||
MATHDIR := $(COREDIR)/math
|
||||
STRDIR := $(COREDIR)/string
|
||||
PRINTDIR := $(COREDIR)/print
|
||||
MEMDIR := $(COREDIR)/mem
|
||||
SYSCALLDIR := $(COREDIR)/syscall
|
||||
FILEDIR := $(COREDIR)/file
|
||||
PARSEDIR := $(SRCDIR)/parse
|
||||
|
||||
# Define source files
|
||||
MATHSRC := $(addprefix $(MATHDIR)/, $(addsuffix .s, \
|
||||
operators \
|
||||
))
|
||||
STRSRC := $(addprefix $(STRDIR)/, $(addsuffix .s, \
|
||||
strlen split strcpy substr is_num strcmp\
|
||||
))
|
||||
MEMSRC := $(addprefix $(MEMDIR)/, $(addsuffix .s, \
|
||||
malloc memchr \
|
||||
))
|
||||
PRINTSRC := $(addprefix $(PRINTDIR)/, $(addsuffix .s, \
|
||||
print putnumber \
|
||||
))
|
||||
FILESRC := $(addprefix $(FILEDIR)/, $(addsuffix .s, \
|
||||
read_file get_file_content \
|
||||
))
|
||||
SYSCALLSRC := $(addprefix $(SYSCALLDIR)/, $(addsuffix .s, \
|
||||
exit file_ops syscall_err\
|
||||
))
|
||||
PARSESRC := $(addprefix $(PARSEDIR)/, $(addsuffix .s, \
|
||||
parse debug_token create_expressions expression debug_expression \
|
||||
))
|
||||
|
||||
# Collect all source files - now using the file variables, not directory variables
|
||||
SRC := $(SRCDIR)/start.s $(MATHSRC) $(STRSRC) $(PRINTSRC) $(FILESRC) $(PARSESRC) $(SYSCALLSRC) $(MEMSRC)
|
||||
|
||||
OBJDIR := obj
|
||||
OBJ := $(patsubst %.s,$(OBJDIR)/%.o,$(notdir $(SRC)))
|
||||
|
||||
all: debug
|
||||
|
||||
debug: $(OBJDIR) $(OBJ)
|
||||
ld -o $@ $(OBJ) -nostdlib -static
|
||||
|
||||
# Pattern rules for object files - added the missing rules for string and print
|
||||
$(OBJDIR)/%.o: $(SRCDIR)/%.s
|
||||
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):
|
||||
mkdir -p $@
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJDIR) debug
|
||||
|
||||
re: clean all
|
||||
|
||||
.PHONY: all clean re
|
||||
17
src/core/file/get_file_content.s
Normal file
17
src/core/file/get_file_content.s
Normal file
@ -0,0 +1,17 @@
|
||||
section .text
|
||||
global get_file_content
|
||||
extern open
|
||||
extern read_file
|
||||
extern close
|
||||
|
||||
get_file_content: ; rax: char *(rdi: char*)
|
||||
mov rsi, 0
|
||||
call open
|
||||
mov rdi, rax
|
||||
push rax
|
||||
call read_file
|
||||
mov rsi, rax
|
||||
pop rdi
|
||||
call close
|
||||
mov rax, rsi
|
||||
ret
|
||||
48
src/core/file/read_file.s
Normal file
48
src/core/file/read_file.s
Normal file
@ -0,0 +1,48 @@
|
||||
|
||||
section .text
|
||||
global read_file
|
||||
extern err_lseek
|
||||
extern err_malloc
|
||||
extern malloc
|
||||
extern read
|
||||
extern lseek
|
||||
extern get_file_size
|
||||
|
||||
read_file: ; rax: char * (rdi: int fd)
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
sub rsp, 32
|
||||
|
||||
mov [rbp - 24], rdi ; fd
|
||||
call get_file_size
|
||||
|
||||
inc rax
|
||||
mov [rbp - 8], rax
|
||||
|
||||
mov rdi, rax
|
||||
call malloc
|
||||
cmp rax, 0
|
||||
jz err_malloc
|
||||
|
||||
mov [rbp - 16], rax
|
||||
|
||||
mov rdi, [rbp - 24]
|
||||
mov rsi, 0
|
||||
mov rdx, 0
|
||||
call lseek
|
||||
|
||||
cmp rax, 0
|
||||
jnz err_lseek
|
||||
|
||||
mov rdi, [rbp - 24]
|
||||
mov rdx, [rbp - 8]
|
||||
mov rsi, [rbp - 16]
|
||||
call read
|
||||
|
||||
mov byte [rsi + rax], 0
|
||||
|
||||
mov rsp, rbp
|
||||
pop rbp
|
||||
|
||||
mov rax, rsi
|
||||
ret
|
||||
0
src/core/math/operators.s
Normal file
0
src/core/math/operators.s
Normal file
88
src/core/mem/malloc.s
Normal file
88
src/core/mem/malloc.s
Normal file
@ -0,0 +1,88 @@
|
||||
section .data
|
||||
heap_break: dq 0
|
||||
heap_start: dq 0
|
||||
failure: db "[MALLOC] ERROR rax address: ", 0
|
||||
success: db "[MALLOC] INFO new address: ", 0
|
||||
str_allocated: db " allocated ", 0
|
||||
str_bytecnt: db " bytes", 0
|
||||
rdi_addr: db "rdx address: "
|
||||
|
||||
section .text
|
||||
global malloc
|
||||
global brk_find_break
|
||||
|
||||
extern putstr
|
||||
extern putchar
|
||||
extern putnumber
|
||||
extern putendl
|
||||
|
||||
brk_find_break: ; RAX: long brk(0)
|
||||
mov rdi, 0x0
|
||||
mov rax, 0xC ; sys_brk
|
||||
syscall
|
||||
ret
|
||||
|
||||
malloc: ; RAX: long basic_malloc(RDI: size_t n)
|
||||
push rbx
|
||||
mov rbx, rdi
|
||||
mov r8, [heap_break]
|
||||
cmp r8, 0
|
||||
jne .allocate ; allocate normally if exists
|
||||
|
||||
call brk_find_break
|
||||
mov [heap_start], rax ; get heap beginning
|
||||
mov [heap_break], rax ; get heap beginning
|
||||
|
||||
.allocate:
|
||||
add rbx, 7
|
||||
and rbx, ~7
|
||||
|
||||
mov rdi, [heap_break]
|
||||
add rdi, rbx
|
||||
|
||||
mov rax, 0xC ; sys_brk
|
||||
syscall
|
||||
|
||||
cmp rax, rdi
|
||||
jne .print_failure
|
||||
|
||||
mov [heap_break], rax
|
||||
mov r8, rdi
|
||||
push rdi
|
||||
|
||||
mov rdi, success
|
||||
call putstr
|
||||
mov rdi, r8
|
||||
call putnumber
|
||||
|
||||
mov rdi, str_allocated
|
||||
call putstr
|
||||
|
||||
mov rdi, rbx
|
||||
call putnumber
|
||||
mov rdi, str_bytecnt
|
||||
call putendl
|
||||
|
||||
pop rax
|
||||
sub rax, rbx
|
||||
pop rbx
|
||||
|
||||
ret
|
||||
|
||||
.print_failure:
|
||||
push rdi
|
||||
mov rdi, failure
|
||||
call putstr
|
||||
mov rdi, rax
|
||||
call putnumber
|
||||
mov rdi, 0xa
|
||||
call putchar
|
||||
mov rdi, rdi_addr
|
||||
call putstr
|
||||
pop rdi
|
||||
call putnumber
|
||||
|
||||
xor rax, rax ; Return NULL on failure
|
||||
pop rbx
|
||||
|
||||
ret
|
||||
31
src/core/mem/memchr.s
Normal file
31
src/core/mem/memchr.s
Normal file
@ -0,0 +1,31 @@
|
||||
global memchr
|
||||
|
||||
section .text
|
||||
|
||||
memchr: ; rax: void *(rdi: void *, rsi: int find, rdx: size_t size)
|
||||
cmp rdi, 0
|
||||
je .fail
|
||||
|
||||
cmp rdx, 0
|
||||
je .no_size
|
||||
|
||||
xor rcx, rcx
|
||||
.loop:
|
||||
cmp byte [rdi + rcx], sil
|
||||
je .done
|
||||
cmp byte [rdi + rcx], 0
|
||||
je .done
|
||||
inc rcx
|
||||
jmp .loop
|
||||
|
||||
.fail:
|
||||
xor rax, rax
|
||||
ret
|
||||
|
||||
.no_size:
|
||||
mov rax, rdi
|
||||
ret
|
||||
|
||||
.done:
|
||||
lea rax, [rdi + rcx]
|
||||
ret
|
||||
58
src/core/print/print.s
Normal file
58
src/core/print/print.s
Normal file
@ -0,0 +1,58 @@
|
||||
|
||||
section .text
|
||||
extern strlen
|
||||
global putstr
|
||||
global putchar
|
||||
global print_split
|
||||
global putendl
|
||||
|
||||
print_split: ; print_split(rdi: char **)
|
||||
xor rcx, rcx
|
||||
.loop:
|
||||
cmp qword [rdi], 0
|
||||
je .done
|
||||
push rdi
|
||||
mov r8, [rdi]
|
||||
mov rdi, r8
|
||||
push rcx
|
||||
call putendl
|
||||
pop rcx
|
||||
pop rdi
|
||||
add rdi, 8
|
||||
inc rcx
|
||||
jmp .loop
|
||||
.done:
|
||||
mov rax, rcx
|
||||
ret
|
||||
|
||||
write: ; RAX: int write(RDI: int fd, RSI: char *buf, RDX: size_t n)
|
||||
mov rax, 1 ; sys_write
|
||||
syscall
|
||||
ret
|
||||
|
||||
putchar:
|
||||
sub rsp, 16 ; create stack var
|
||||
mov [rsp], dil ; move lower byte of tdi into stack
|
||||
mov rsi, rsp
|
||||
mov rdx, 1
|
||||
mov rdi, 1
|
||||
call write
|
||||
add rsp, 16
|
||||
ret
|
||||
|
||||
putstr: ; print_string(RDI: char *string)
|
||||
call strlen
|
||||
|
||||
mov rdx, rax ; string length
|
||||
mov rsi, rdi ; mov buffer
|
||||
mov rdi, 1 ; stdout
|
||||
|
||||
call write
|
||||
|
||||
ret
|
||||
|
||||
putendl:
|
||||
call putstr
|
||||
mov rdi, 0xa
|
||||
call putchar
|
||||
ret
|
||||
49
src/core/print/putnumber.s
Normal file
49
src/core/print/putnumber.s
Normal file
@ -0,0 +1,49 @@
|
||||
global putnumber
|
||||
global putnumberendl
|
||||
|
||||
section .text
|
||||
extern putchar
|
||||
|
||||
putnumberendl:
|
||||
call putnumber
|
||||
mov rdi, 0xa
|
||||
call putchar
|
||||
ret
|
||||
|
||||
putnumber: ; void put_number(RDI: int c)
|
||||
push rbx
|
||||
xor rcx, rcx
|
||||
|
||||
.start:
|
||||
inc rcx
|
||||
cmp rdi, 10
|
||||
jl .print
|
||||
push rdi
|
||||
mov rax, rdi
|
||||
xor rdx, rdx
|
||||
mov rbx, 10
|
||||
idiv rbx
|
||||
mov rdi, rax
|
||||
jmp .start
|
||||
|
||||
.print:
|
||||
mov rax, rdi
|
||||
xor rdx, rdx
|
||||
mov rbx, 10
|
||||
idiv rbx
|
||||
mov rdi, rdx
|
||||
mov rdx, 0x30
|
||||
add rdi, rdx
|
||||
push rcx
|
||||
call putchar
|
||||
pop rcx
|
||||
dec rcx
|
||||
cmp rcx, 0
|
||||
je .done
|
||||
pop rdi
|
||||
jmp .print
|
||||
|
||||
.done:
|
||||
pop rbx
|
||||
xor rcx, rcx
|
||||
ret
|
||||
0
src/core/string/is_alpha.s
Normal file
0
src/core/string/is_alpha.s
Normal file
31
src/core/string/is_num.s
Normal file
31
src/core/string/is_num.s
Normal file
@ -0,0 +1,31 @@
|
||||
section .text
|
||||
global is_num
|
||||
global is_num_str
|
||||
|
||||
is_num: ; rax: bool (rdi: int c)
|
||||
cmp rdi, 48
|
||||
jl not_num
|
||||
cmp rdi, 57
|
||||
jg not_num
|
||||
mov rax, 1
|
||||
ret
|
||||
not_num:
|
||||
mov rax, 0
|
||||
ret
|
||||
|
||||
is_num_str: ; rax: bool (rdi: char *)
|
||||
xor rcx, rcx
|
||||
mov r8, rdi
|
||||
.loop:
|
||||
mov dil, byte [r8 + rcx]
|
||||
cmp dil, 0
|
||||
je .done
|
||||
call is_num
|
||||
cmp rax, 0
|
||||
je not_num
|
||||
inc rcx
|
||||
jmp .loop
|
||||
|
||||
.done:
|
||||
mov rax, 1
|
||||
ret
|
||||
4
src/core/string/replace_all.s
Normal file
4
src/core/string/replace_all.s
Normal file
@ -0,0 +1,4 @@
|
||||
section .text
|
||||
global replace_all
|
||||
|
||||
replace_all: ; rax: char *(rdi: char *, rsi: int c)
|
||||
147
src/core/string/split.s
Normal file
147
src/core/string/split.s
Normal file
@ -0,0 +1,147 @@
|
||||
section .text
|
||||
global split
|
||||
global get_split_count
|
||||
extern malloc
|
||||
extern putstr
|
||||
extern putnumber
|
||||
extern strcpy
|
||||
extern memchr
|
||||
extern substr
|
||||
extern strlen
|
||||
|
||||
get_split_count: ; rax: uint (rdi: char **)
|
||||
xor rcx, rcx
|
||||
.loop:
|
||||
cmp qword [rdi + rcx * 8], 0
|
||||
jz .done
|
||||
inc rcx
|
||||
jmp .loop
|
||||
.done:
|
||||
mov rax, rcx
|
||||
ret
|
||||
|
||||
count_splits: ; RAX: int count_splits(RDI: char *, RSI: int c)
|
||||
push rbx
|
||||
xor rcx, rcx
|
||||
xor rbx, rbx
|
||||
.loop:
|
||||
cmp byte [rdi + rcx], 0
|
||||
jz .done
|
||||
cmp byte [rdi + rcx], sil
|
||||
jne .skip
|
||||
.while_is_c:
|
||||
inc rcx
|
||||
cmp byte [rdi + rcx], 0
|
||||
jz .done
|
||||
cmp byte [rdi + rcx], sil
|
||||
jz .while_is_c
|
||||
inc rbx
|
||||
.skip:
|
||||
inc rcx
|
||||
jmp .loop
|
||||
.done:
|
||||
mov rax, rbx
|
||||
pop rbx
|
||||
inc rax
|
||||
ret
|
||||
|
||||
split: ; RAX: char ** split(RDI: char *, RSI: int)
|
||||
push rbx
|
||||
push r12
|
||||
push r13
|
||||
|
||||
push rbp
|
||||
mov rbp, rsp ; save base pointer
|
||||
; int count = [ rbp - 4 ]
|
||||
; char **split = [ rbp - 8 ]
|
||||
|
||||
sub rsp, 16 ; allocate local vars
|
||||
mov [rbp - 8], rdi
|
||||
call count_splits
|
||||
mov rcx, 8
|
||||
mov rbx, rax
|
||||
inc rax
|
||||
mul rcx
|
||||
push rdi
|
||||
push rsi
|
||||
mov rdi, rax
|
||||
call malloc
|
||||
pop rsi
|
||||
pop rdi
|
||||
cmp rax, 0
|
||||
je .fail
|
||||
|
||||
|
||||
|
||||
mov qword [rax + rbx * 8], 0
|
||||
|
||||
mov [rbp - 16], rax
|
||||
mov rcx, rax
|
||||
|
||||
cmp rbx, 1
|
||||
je .no_match
|
||||
|
||||
call strlen
|
||||
mov r13, rax
|
||||
mov r12, rdi
|
||||
.loop:
|
||||
mov rdi, r12
|
||||
cmp rbx, 0
|
||||
je .done
|
||||
|
||||
mov rdx, r13
|
||||
push rcx
|
||||
call memchr
|
||||
pop rcx
|
||||
xor r9, r9
|
||||
jmp .skip_matches
|
||||
.after_skip:
|
||||
|
||||
lea rdx, [rax]
|
||||
sub rdx, rdi
|
||||
sub r13, rdx
|
||||
|
||||
mov r12, rax
|
||||
add r12, r9
|
||||
|
||||
push rsi
|
||||
push rcx
|
||||
mov rsi, 0
|
||||
call substr
|
||||
pop rcx
|
||||
pop rsi
|
||||
lea r8, [rax]
|
||||
mov [rcx], r8
|
||||
add rcx, 8
|
||||
dec rbx
|
||||
jmp .loop
|
||||
|
||||
.fail:
|
||||
xor rax, rax
|
||||
jmp .cleanup
|
||||
.no_match:
|
||||
push rcx
|
||||
call strcpy
|
||||
pop rcx
|
||||
mov [rcx], rax
|
||||
.done:
|
||||
mov rax, [rbp - 16]
|
||||
.cleanup:
|
||||
add rsp, 16
|
||||
mov rsp, rbp
|
||||
pop rbp
|
||||
pop r13
|
||||
pop r12
|
||||
pop rbx
|
||||
ret
|
||||
|
||||
.skip_matches:
|
||||
cmp byte [rax + r9], 0
|
||||
jz .after_skip
|
||||
cmp byte [rax + r9], sil
|
||||
jnz .after_skip
|
||||
inc r9
|
||||
dec r13
|
||||
jmp .skip_matches
|
||||
|
||||
|
||||
57
src/core/string/strcmp.s
Normal file
57
src/core/string/strcmp.s
Normal file
@ -0,0 +1,57 @@
|
||||
section .text
|
||||
global strcmp
|
||||
|
||||
strcmp: ; rax: int (rdi: char *, rsi: char *)
|
||||
; Check for NULL pointers first
|
||||
test rdi, rdi ; Check if first string is NULL
|
||||
jz .handle_null
|
||||
test rsi, rsi ; Check if second string is NULL
|
||||
jz .handle_null
|
||||
|
||||
xor rcx, rcx ; initialize counter to 0
|
||||
|
||||
.loop:
|
||||
; Load characters safely using registers
|
||||
movzx r9, byte [rdi + rcx] ; load current char from first string
|
||||
movzx r10, byte [rsi + rcx] ; load current char from second string
|
||||
|
||||
; Check if we've reached the end of either string
|
||||
test r9, r9 ; check if we reached end of first string
|
||||
jz .check_second ; if so, jump to check second string
|
||||
|
||||
test r10, r10 ; check if we reached end of second string
|
||||
jz .greater ; if second string ends first, first string is greater
|
||||
|
||||
; Compare the characters
|
||||
cmp r9, r10 ; compare characters
|
||||
jl .less ; if first char < second char, first string is less
|
||||
jg .greater ; if first char > second char, first string is greater
|
||||
|
||||
; Characters are equal, continue to next character
|
||||
inc rcx ; increment counter
|
||||
jmp .loop ; continue loop
|
||||
|
||||
.check_second:
|
||||
test r10, r10 ; if first string ended, check if second ended too
|
||||
jz .equal ; if both ended at same position, strings are equal
|
||||
jmp .less ; if only first ended, first string is less
|
||||
|
||||
.handle_null:
|
||||
; Handle NULL pointer case (implementation-dependent, could also raise error)
|
||||
; Here we'll follow standard C behavior: if both are NULL, equal; otherwise compare addresses
|
||||
cmp rdi, rsi
|
||||
je .equal
|
||||
jl .less
|
||||
jmp .greater
|
||||
|
||||
.less:
|
||||
mov rax, -1 ; return -1 if first string is less
|
||||
ret
|
||||
|
||||
.greater:
|
||||
mov rax, 1 ; return 1 if first string is greater
|
||||
ret
|
||||
|
||||
.equal:
|
||||
xor rax, rax ; return 0 if strings are equal
|
||||
ret
|
||||
28
src/core/string/strcpy.s
Normal file
28
src/core/string/strcpy.s
Normal file
@ -0,0 +1,28 @@
|
||||
global strcpy
|
||||
|
||||
section .text
|
||||
extern malloc
|
||||
extern strlen
|
||||
|
||||
strcpy: ; rax: char *(rdi: char *)
|
||||
push rbx
|
||||
push rcx
|
||||
call strlen
|
||||
mov r9, rdi ; r9 contains arg
|
||||
mov r8, rax
|
||||
mov rdi, rax
|
||||
inc rdi
|
||||
call malloc
|
||||
xor rcx, rcx
|
||||
.loop:
|
||||
cmp byte [r9 + rcx], 0
|
||||
je .done
|
||||
mov bl, [r9 + rcx]
|
||||
mov [rax + rcx], bl
|
||||
inc rcx
|
||||
jmp .loop
|
||||
.done:
|
||||
mov byte [rax + rcx], 0
|
||||
pop rcx
|
||||
pop rbx
|
||||
ret
|
||||
16
src/core/string/strlen.s
Normal file
16
src/core/string/strlen.s
Normal file
@ -0,0 +1,16 @@
|
||||
global strlen
|
||||
|
||||
section .text
|
||||
strlen: ; strlen(RDI: char *str)
|
||||
push rcx ; save counter
|
||||
xor rcx, rcx
|
||||
.loop: ; loop until '\0' character
|
||||
cmp byte [rdi + rcx], 0
|
||||
jz .done
|
||||
inc rcx
|
||||
jmp .loop
|
||||
.done:
|
||||
mov rax, rcx ; mov return value to rax
|
||||
pop rcx ; restore counter
|
||||
ret
|
||||
|
||||
47
src/core/string/substr.s
Normal file
47
src/core/string/substr.s
Normal file
@ -0,0 +1,47 @@
|
||||
global substr
|
||||
|
||||
section .text
|
||||
extern strlen
|
||||
extern malloc
|
||||
|
||||
substr: ; rax: char*(rdi: char*, rsi: size_t begin, rdx: size_t end)
|
||||
cmp rdi, 0
|
||||
je .fail
|
||||
|
||||
cmp rsi, rdx
|
||||
jg .fail
|
||||
|
||||
call strlen
|
||||
|
||||
cmp rax, rsi
|
||||
jl .fail
|
||||
|
||||
cmp rax, rdx
|
||||
jl .fail
|
||||
|
||||
push rdi
|
||||
push rsi
|
||||
push rdx
|
||||
mov rdi, rax
|
||||
add rdi, 1
|
||||
call malloc
|
||||
pop rdx
|
||||
pop rsi
|
||||
pop rdi
|
||||
|
||||
|
||||
.loop:
|
||||
cmp rsi, rdx
|
||||
je .done
|
||||
mov r9b, [rdi + rsi]
|
||||
mov [rax + rsi], r9b
|
||||
inc rsi
|
||||
jmp .loop
|
||||
|
||||
.done:
|
||||
mov byte [rax + rdx], 0
|
||||
ret
|
||||
|
||||
.fail:
|
||||
xor rax, rax
|
||||
ret
|
||||
12
src/core/syscall/exit.s
Normal file
12
src/core/syscall/exit.s
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
section .text
|
||||
global exit
|
||||
global exit_err
|
||||
|
||||
exit:
|
||||
mov rax, 60
|
||||
syscall
|
||||
|
||||
exit_err:
|
||||
mov rdi, 1
|
||||
call exit
|
||||
38
src/core/syscall/file_ops.s
Normal file
38
src/core/syscall/file_ops.s
Normal file
@ -0,0 +1,38 @@
|
||||
|
||||
section .text
|
||||
global open
|
||||
global close
|
||||
global read
|
||||
global get_file_size
|
||||
global lseek
|
||||
|
||||
open: ; rax: int fd (rdi: char *name, rsi: int flags)
|
||||
mov rax, 2 ; sys_open
|
||||
syscall
|
||||
ret
|
||||
|
||||
close:
|
||||
mov rax, 3 ; sys_close
|
||||
syscall
|
||||
ret
|
||||
|
||||
read: ; read(RDI: int fd, RSI: char *buffer, RDX: size_t size)
|
||||
mov rax, 0 ; sys_read
|
||||
syscall ;
|
||||
ret
|
||||
|
||||
get_file_size: ;rax: size_t(rdi: int fd)
|
||||
mov rax, 8 ; sys_lseek
|
||||
mov rsi, 0 ; offset 0
|
||||
mov rdx, 2
|
||||
syscall
|
||||
ret
|
||||
|
||||
lseek: ; rax: uint (rdi: int fd, rsi: offset, rdx: int whence)
|
||||
; whence: SEEK_SET 0 = set cursor to offset
|
||||
; SEEK_CUR 1 = set cursor to current_pos + offset
|
||||
; SEEK_END 2 = set cursor to end
|
||||
; return = current offset
|
||||
mov rax, 8
|
||||
syscall
|
||||
ret
|
||||
26
src/core/syscall/syscall_err.s
Normal file
26
src/core/syscall/syscall_err.s
Normal file
@ -0,0 +1,26 @@
|
||||
section .data
|
||||
EARGCNT: db "[ERROR] Invalid arg count: expected 1", 0xa, 0
|
||||
EMALLOC: db "[ERROR] Malloc fialed!", 0xa, 0
|
||||
ELSEEK: db "[ERROR] lseek failed!", 0xa, 0
|
||||
|
||||
section .text
|
||||
global err_args
|
||||
global err_malloc
|
||||
global err_lseek
|
||||
extern exit_err
|
||||
extern putstr
|
||||
|
||||
err_args:
|
||||
mov rdi, EARGCNT
|
||||
call putstr
|
||||
jmp exit_err
|
||||
|
||||
err_malloc:
|
||||
mov rdi, EMALLOC
|
||||
call putstr
|
||||
jmp exit_err
|
||||
|
||||
err_lseek:
|
||||
mov rdi, ELSEEK
|
||||
call putstr
|
||||
jmp exit_err
|
||||
7
src/inc/macros.inc
Normal file
7
src/inc/macros.inc
Normal file
@ -0,0 +1,7 @@
|
||||
%define EXPR_SIZE 32
|
||||
|
||||
%define EXPR_TYPE 0
|
||||
|
||||
%define EXPR_TOK_CNT 8
|
||||
|
||||
%define EXPR_TOK 16
|
||||
121
src/parse/create_expressions.s
Normal file
121
src/parse/create_expressions.s
Normal file
@ -0,0 +1,121 @@
|
||||
%include "./lang/src/inc/macros.inc"
|
||||
|
||||
section .text
|
||||
global create_expressions
|
||||
extern split
|
||||
extern get_split_count
|
||||
extern malloc
|
||||
extern err_malloc
|
||||
extern parse
|
||||
extern print_tokens
|
||||
extern print_expression
|
||||
|
||||
|
||||
create_expressions: ; rax: exp* (rdi: char *filecontent)
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
sub rsp, 32 ; allocate stack
|
||||
|
||||
mov rsi, 0x0a
|
||||
call split
|
||||
|
||||
mov rdi, rax
|
||||
push rdi
|
||||
call get_split_count
|
||||
mov [rbp - 24], rax ; store split count
|
||||
inc rax
|
||||
mov rcx, 8
|
||||
mul rcx
|
||||
mov rdi, rax
|
||||
call malloc
|
||||
cmp rax, 0
|
||||
mov r14, rax
|
||||
je err_malloc
|
||||
|
||||
mov [rbp - 8], rax ; char *** tok
|
||||
|
||||
xor rcx, rcx
|
||||
pop rdi
|
||||
mov r13, rdi
|
||||
mov r12, [rbp - 24]
|
||||
|
||||
.split_splits:
|
||||
mov rsi, 0x20
|
||||
cmp rcx, r12
|
||||
je .splitting_done
|
||||
mov rbx, rcx
|
||||
mov rdi, [r13 + rcx * 8]
|
||||
call split
|
||||
mov rcx, rbx
|
||||
mov rbx, [rbp - 8]
|
||||
mov [rbx + rcx * 8], rax
|
||||
inc rcx
|
||||
jmp .split_splits
|
||||
|
||||
.splitting_done:
|
||||
|
||||
; allocate expressions
|
||||
mov rax, [expr_size]
|
||||
mul rcx ; rcx contains the amount of splits aka expr count
|
||||
mov rdi, rax
|
||||
call malloc
|
||||
cmp rax, 0
|
||||
je err_malloc
|
||||
|
||||
mov [rbp - 16], rax ; store expr* on stack
|
||||
|
||||
xor rcx, rcx
|
||||
.loop_expressions:
|
||||
|
||||
; create the actual expressions
|
||||
mov rbx, [rbp - 24] ; expr count
|
||||
cmp rcx, rbx
|
||||
je .expressions_done
|
||||
mov rbx, [rbp - 8]
|
||||
mov rdi, [rbx + rcx * 8]
|
||||
push rcx
|
||||
push rdi
|
||||
call get_split_count
|
||||
pop rdi
|
||||
push rax
|
||||
|
||||
call parse
|
||||
pop rdi
|
||||
pop rcx
|
||||
push rax
|
||||
mov rbx, [rbp - 16] ; mov expr* into rax
|
||||
mov rax, EXPR_SIZE
|
||||
mul rcx
|
||||
lea rax, [rbx + rax]
|
||||
pop rbx
|
||||
mov rdx, [expr_tok]
|
||||
mov [rax + rdx], rbx
|
||||
mov rdx, [expr_tok_cnt]
|
||||
mov [rax + rdx], rdi
|
||||
inc rcx
|
||||
jmp .loop_expressions
|
||||
|
||||
.expressions_done:
|
||||
; print expressions debug
|
||||
xor rcx, rcx
|
||||
|
||||
.expr_loop_print:
|
||||
mov rbx, [rbp - 24]
|
||||
cmp rcx, rbx
|
||||
je .done
|
||||
mov rbx, [rbp - 16]
|
||||
mov rax, EXPR_SIZE
|
||||
mul rcx
|
||||
lea rdi, [rbx + rax]
|
||||
push rcx
|
||||
call print_expression
|
||||
pop rcx
|
||||
inc rcx
|
||||
jmp .expr_loop_print
|
||||
|
||||
.done:
|
||||
mov rax, [rbp - 16]
|
||||
add rsp, 32
|
||||
mov rsp, rbp
|
||||
pop rbp
|
||||
ret
|
||||
30
src/parse/debug_expression.s
Normal file
30
src/parse/debug_expression.s
Normal file
@ -0,0 +1,30 @@
|
||||
section .data
|
||||
header: db 0xa, "---------", 0xa, "Expr ", 0xa, "---------", 0
|
||||
type: db 0xa, "type: ", 0
|
||||
section .text
|
||||
extern print_tokens
|
||||
extern expr_type
|
||||
extern expr_tok
|
||||
extern expr_tok_cnt
|
||||
extern putendl
|
||||
|
||||
global print_expression
|
||||
print_expression: ; (rdi: expr*)
|
||||
push r12
|
||||
push rbx
|
||||
|
||||
push rdi
|
||||
mov rdi, header
|
||||
call putendl
|
||||
pop rdi
|
||||
|
||||
mov rbx, [expr_tok_cnt]
|
||||
mov rsi, [rdi + rbx]
|
||||
add rdi, [expr_tok] ; tok**
|
||||
mov r12, [rdi] ; r12 = tok*
|
||||
mov rdi, r12
|
||||
call print_tokens
|
||||
|
||||
pop rbx
|
||||
pop r12
|
||||
ret
|
||||
76
src/parse/debug_token.s
Normal file
76
src/parse/debug_token.s
Normal file
@ -0,0 +1,76 @@
|
||||
section .data
|
||||
token: db 0xa, "Token ", 0
|
||||
type: db "type = ", 0
|
||||
value: db "value = ", 0
|
||||
|
||||
section .text
|
||||
global print_tokens
|
||||
extern putstr
|
||||
extern putendl
|
||||
extern putchar
|
||||
extern putnumberendl
|
||||
extern get_split_count
|
||||
|
||||
|
||||
|
||||
; struct token
|
||||
; .type 0
|
||||
; .value +8
|
||||
|
||||
print_tokens: ; (rdi: tok*, rsi: tok_count)
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
|
||||
sub rsp, 16
|
||||
|
||||
push r12
|
||||
push r13
|
||||
push r14
|
||||
push rbx
|
||||
|
||||
mov r14, rsi
|
||||
|
||||
mov [rbp - 8], rdi
|
||||
|
||||
mov rbx, rdi
|
||||
xor rcx, rcx
|
||||
.loop:
|
||||
cmp rcx, r14
|
||||
je .done
|
||||
mov r12, rcx
|
||||
mov rdi, token
|
||||
call putstr
|
||||
mov rdi, r12
|
||||
call putnumberendl
|
||||
|
||||
mov rdi, type
|
||||
call putstr
|
||||
mov rax, 16
|
||||
mul r12
|
||||
mov rbx, [rbp - 8]
|
||||
lea r13, [rbx + rax]
|
||||
mov rdi, [r13]
|
||||
push rax
|
||||
call putnumberendl
|
||||
|
||||
mov rdi, value
|
||||
call putstr
|
||||
pop rax
|
||||
|
||||
mov rbx, [rbp - 8]
|
||||
lea r13, [rbx + rax]
|
||||
mov rdi, [r13 + 8]
|
||||
|
||||
call putendl
|
||||
mov rcx, r12
|
||||
inc rcx
|
||||
jmp .loop
|
||||
|
||||
.done:
|
||||
pop rbx
|
||||
pop r14
|
||||
pop r13
|
||||
pop r12
|
||||
mov rsp, rbp
|
||||
pop rbp
|
||||
ret
|
||||
9
src/parse/expression.s
Normal file
9
src/parse/expression.s
Normal file
@ -0,0 +1,9 @@
|
||||
section .data
|
||||
|
||||
|
||||
%define EXPR_SIZE 32
|
||||
|
||||
; struct expression size = 32
|
||||
; .type
|
||||
; .tok_count + 8
|
||||
; .tokens + 16
|
||||
8
src/parse/lexer.s
Normal file
8
src/parse/lexer.s
Normal file
@ -0,0 +1,8 @@
|
||||
section .text
|
||||
|
||||
; struct lexer
|
||||
; .cnt 0
|
||||
; .expr* 8
|
||||
|
||||
global lex
|
||||
lex: ; (rdi: expr*, rsi: cnt)
|
||||
129
src/parse/parse.s
Normal file
129
src/parse/parse.s
Normal file
@ -0,0 +1,129 @@
|
||||
%define SIZE_TOK 16
|
||||
%define TOK_ASSIGN 0
|
||||
%define TOK_ADD 1
|
||||
%define TOK_PRINT 2
|
||||
%define TOK_VAR 3
|
||||
%define TOK_CONST 4
|
||||
|
||||
section .data
|
||||
OP_ASSIGN: db "=", 0
|
||||
OP_ADD: db "+", 0
|
||||
OP_PRINT: db "print", 0
|
||||
|
||||
section .text
|
||||
global parse
|
||||
extern strcmp
|
||||
extern malloc
|
||||
extern err_malloc
|
||||
extern is_num_str
|
||||
extern putendl
|
||||
extern putnumberendl
|
||||
extern get_split_count
|
||||
|
||||
|
||||
; struct token
|
||||
; .type 0
|
||||
; .value +8
|
||||
|
||||
|
||||
token_alloc: ; rax: tok* (rdi: int cnt)
|
||||
mov rax, rdi
|
||||
mov rdi, SIZE_TOK
|
||||
mul rdi
|
||||
mov rdi, rax
|
||||
call malloc
|
||||
cmp rax, 0
|
||||
je err_malloc
|
||||
ret
|
||||
|
||||
parse: ; rax: tok* (rdi: char**)
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
sub rsp, 16
|
||||
mov [rbp - 8], rdi
|
||||
|
||||
push r12
|
||||
push rbx
|
||||
call get_split_count
|
||||
mov r12, rax
|
||||
mov rdi, rax
|
||||
|
||||
call token_alloc
|
||||
mov [rbp - 16], rax ; store token array in stack
|
||||
|
||||
xor rcx, rcx
|
||||
.loop:
|
||||
push rcx
|
||||
mov rdi, [rbp - 8]
|
||||
mov rdi, [rdi + rcx * 8]
|
||||
cmp qword rdi, 0
|
||||
je .done
|
||||
|
||||
mov rsi, OP_ASSIGN
|
||||
call strcmp
|
||||
cmp rax, 0
|
||||
je .is_assign
|
||||
mov rsi, OP_ADD
|
||||
call strcmp
|
||||
cmp rax, 0
|
||||
je .is_add
|
||||
mov rsi, OP_PRINT
|
||||
call strcmp
|
||||
cmp rax, 0
|
||||
je .is_print
|
||||
push rdi
|
||||
call is_num_str
|
||||
pop rdi
|
||||
cmp rax, 1
|
||||
je .is_const
|
||||
jmp .is_var
|
||||
|
||||
.is_assign:
|
||||
pop rcx
|
||||
push rdi
|
||||
mov rdi, TOK_ASSIGN
|
||||
jmp .set_token
|
||||
|
||||
.is_add:
|
||||
pop rcx
|
||||
push rdi
|
||||
mov rdi, TOK_ADD
|
||||
jmp .set_token
|
||||
|
||||
.is_print:
|
||||
pop rcx
|
||||
push rdi
|
||||
mov rdi, TOK_PRINT
|
||||
jmp .set_token
|
||||
|
||||
.is_const:
|
||||
pop rcx
|
||||
push rdi
|
||||
mov rdi, TOK_CONST
|
||||
jmp .set_token
|
||||
|
||||
.is_var:
|
||||
pop rcx
|
||||
push rdi
|
||||
mov rdi, TOK_VAR
|
||||
jmp .set_token
|
||||
|
||||
.set_token:
|
||||
mov r8, [rbp - 16]
|
||||
mov rax, SIZE_TOK
|
||||
mul rcx
|
||||
mov [r8 + rax], rdi
|
||||
pop rdi
|
||||
mov [r8 + rax + 8], rdi
|
||||
inc rcx
|
||||
jmp .loop
|
||||
|
||||
.done:
|
||||
pop rcx
|
||||
mov rax, [rbp - 16]
|
||||
pop rbx
|
||||
pop r12
|
||||
mov rsp, rbp
|
||||
pop rbp
|
||||
ret
|
||||
|
||||
51
src/start.s
Normal file
51
src/start.s
Normal file
@ -0,0 +1,51 @@
|
||||
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
|
||||
|
||||
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, rax
|
||||
call create_expressions
|
||||
mov [rbp - 8], rax
|
||||
|
||||
mov rsp, rbp
|
||||
pop rbp
|
||||
|
||||
done:
|
||||
xor rdi, rdi
|
||||
call exit
|
||||
11
test.c
Normal file
11
test.c
Normal file
@ -0,0 +1,11 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "../libft/libft.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]));
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user