mork work on 04b compiler
This commit is contained in:
parent
9760d898b7
commit
dfd0610698
2 changed files with 303 additions and 32 deletions
302
04b/in03
302
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
|
||||
:local_variables
|
||||
reserve d20000
|
||||
:label_table
|
||||
reserve d200000
|
||||
|
||||
; we shouldn't end the file with a reserve; we don't handle that properly
|
||||
: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
|
||||
|
|
31
04b/in04b
31
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue