summaryrefslogtreecommitdiff
path: root/04b
diff options
context:
space:
mode:
Diffstat (limited to '04b')
-rw-r--r--04b/in03304
-rw-r--r--04b/in04b31
2 files changed, 303 insertions, 32 deletions
diff --git a/04b/in03 b/04b/in03
index dbc78e4..8b2da5b 100644
--- a/04b/in03
+++ b/04b/in03
@@ -29,6 +29,12 @@ A=d3
J=A
?J<0:output_file_error
+; write ELF header
+J=d4
+I=:ELF_header
+D=x78
+syscall x1
+
:read_line
; increment line number
D=:line_number
@@ -54,7 +60,7 @@ R=:line
; check if the character was a tab:
D=x9
; if so, don't increment rbp
- ?C=D:read_line
+ ?C=D:read_line_loop
; check if the character was a semicolon:
D=';
; if so, it's a comment
@@ -105,6 +111,33 @@ call :string=
D=A
?D!0:handle_global
+I=:line
+J=:"local"
+C=x20
+call :string=
+D=A
+?D!0:handle_local
+I=:line
+J=:"argument"
+C=x20
+call :string=
+D=A
+?D!0:handle_local
+
+I=:line
+J=:"return"
+C=x20
+call :string=
+D=A
+?D!0:handle_return
+
+C=xa
+I=:line
+J=:"function"
+call :string=
+D=A
+?D!0:handle_function
+
!:read_line
@@ -112,10 +145,58 @@ D=A
J=d0
syscall x3c
+:handle_local
+ R=I
+
+ ; emit sub rsp, 8
+ J=d4
+ I=:sub_rsp_8
+ D=d7
+ syscall x1
+
+ I=R
+ ; skip ' '
+ I+=d1
+ call :read_type
+ R=A
+ I+=d1
+ J=:local_variables_end
+ J=8J
+ call :ident_copy
+ ; store type
+ 1J=R
+ J+=d1
+ ; store address
+ D=:stack_end
+ D=8D
+ 8J=D
+ J+=d8
+ ; store null terminator
+ 1J=0
+ ; update :stack_end
+ D=:stack_end
+ C=8D
+ C+=d8
+ 8D=C
+ ; update :local_variables_end
+ I=:local_variables_end
+ 8I=J
+ ; read the next line
+ !:read_line
+
+:sub_rsp_8
+ x48
+ x81
+ xec
+ x08
+ x00
+ x00
+ x00
+
:handle_global
- I=:line
- ; skip "global "
- I+=d7
+ ; @TODO: check if already exists
+ ; skip ' '
+ I+=d1
call :read_type
; put type in R
R=A
@@ -131,6 +212,9 @@ D=A
D=:static_memory_end
D=8D
8J=D
+ J+=d8
+ ; store null terminator
+ 1J=0
; update :static_memory_end
D=:static_memory_end
C=8D
@@ -142,9 +226,49 @@ D=A
; go read the next line
!:read_line
-:"global"
- str global
- x20
+:handle_function
+ ; emit "mov rbp, rsp"
+ J=d4
+ I=:mov_rbp_rsp
+ D=d3
+ syscall x1
+
+ ; reset local variable table
+ D=:local_variables
+ 1D=0
+ C=:local_variables_end
+ 8C=D
+
+ ; go read the next line
+ !:read_line
+
+:mov_rbp_rsp
+ R=S
+
+:handle_return
+ ; @TODO: handle argument
+
+
+ ; emit "mov rsp, rbp"
+ J=d4
+ I=:mov_rsp_rbp
+ D=d3
+ syscall x1
+
+ ; emit "ret"
+ J=d4
+ I=:ret
+ D=d1
+ syscall x1
+
+ ; go read the next lines
+ !:read_line
+
+:mov_rsp_rbp
+ S=R
+
+:ret
+ return
; copy the newline-terminated identifier from rsi to rdi
:ident_copy
@@ -237,19 +361,6 @@ D=A
?D!0:return_8
!:bad_type
-:"char"
- str char
- x20
-:"short"
- str short
- x20
-:"int"
- str int
- x20
-:"long"
- str long
- x20
-
:usage_error
B=:usage_error_message
@@ -467,6 +578,36 @@ D=A
D-=d1
!:memcpy
+
+:"char"
+ str char
+ x20
+:"short"
+ str short
+ x20
+:"int"
+ str int
+ x20
+:"long"
+ str long
+ x20
+
+:"global"
+ str global
+ x20
+:"argument"
+ str argument
+ x20
+:"local"
+ str local
+ x20
+:"return"
+ str return
+ x20
+:"function"
+ str function
+ xa
+
; put a 0 byte before the line (this is important for removing whitespace at the end of the line,
; specifically, we don't want this to be a space character)
x0
@@ -478,10 +619,129 @@ align
reserve d8
:static_memory_end
reserve d8
+:local_variables_end
+ reserve d8
+:stack_end
+ reserve d8
:line_number
reserve d8
:global_variables
reserve d50000
-
-; we shouldn't end the file with a reserve; we don't handle that properly
+:local_variables
+ reserve d20000
+:label_table
+ reserve d200000
+
+:ELF_header
+x7f
+x45
+x4c
+x46
+x02
+x01
+x01
+
+reserve d9
+
+x02
+x00
+
+x3e
+x00
+
+x01
+x00
+x00
+x00
+
+x78
+x00
+x40
+x00
+x00
+x00
+x00
+x00
+
+x40
+x00
+x00
+x00
+x00
+x00
+x00
+x00
+
+reserve d12
+
+x40
+x00
+x38
+x00
+x01
+x00
+x00
+x00
+x00
+x00
+x00
+x00
+
+x01
+x00
x00
+x00
+
+x07
+x00
+x00
+x00
+
+x78
+x00
+x00
+x00
+x00
+x00
+x00
+x00
+
+x78
+x00
+x40
+x00
+x00
+x00
+x00
+x00
+
+reserve d8
+
+x00
+x00
+x20
+x00
+x00
+x00
+x00
+x00
+
+x00
+x00
+x20
+x00
+x00
+x00
+x00
+x00
+
+x00
+x10
+x00
+x00
+x00
+x00
+x00
+x00
+
+; NOTE: we shouldn't end the file with a reserve; we don't handle that properly
diff --git a/04b/in04b b/04b/in04b
index f312b54..d208fb7 100644
--- a/04b/in04b
+++ b/04b/in04b
@@ -52,38 +52,49 @@ global char x
global short y ;123
global long z
-function strlen(*char s)
+:strlen
+function
+ argument *char s
local long len
local char c
len = 0
- :strlen.loop
+ :strlen_loop
c = s[len]
- if c == 0 goto strlen.loop_end
+ if c == 0 goto strlen_loop_end
len += 1
- goto strlen.loop
- :strlen.loop_end
+ goto strlen_loop
+ :strlen_loop_end
return len
-function putc(char c)
- local char *p
+:putc
+function
+ argument char c
+ local *char p
p = &c
syscall(1, 1, p, 1, 0, 0, 0, 0)
return
-function puts(*char s)
+:puts
+function
+ argument *char s
local long len
len = strlen(s)
syscall(1, 1, s, len, 0, 0, 0, 0)
return
-function main()
+:main
+function
local *char hello
hello = `Hello, world!
`
puts(hello)
syscall(0x3c, 0, 0, 0, 0, 0, 0, 0)
-function f(*long x, *long y)
+
+:f
+function
+ argument *long x
+ argument *long y
local long v
local *long p
v = *x