rvalues!
This commit is contained in:
parent
9d43ebe2aa
commit
a415ec31c0
3 changed files with 504 additions and 81 deletions
540
04b/in03
540
04b/in03
|
@ -4,7 +4,8 @@ D=:global_variables
|
|||
8C=D
|
||||
; initialize static_memory_end
|
||||
C=:static_memory_end
|
||||
D=x500000
|
||||
; 0x40000 = 256KB for code
|
||||
D=x440000
|
||||
8C=D
|
||||
; initialize labels_end
|
||||
C=:labels_end
|
||||
|
@ -150,6 +151,12 @@ D=A
|
|||
?D!0:exit_success
|
||||
; set 2nd pass to 1
|
||||
1C=d1
|
||||
; make sure output file is large enough for static memory
|
||||
; we'll use the ftruncate syscall to set the size of the file
|
||||
J=d4
|
||||
I=:static_memory_end
|
||||
I=8I
|
||||
syscall x4d
|
||||
; seek both files back to start
|
||||
J=d3
|
||||
I=d0
|
||||
|
@ -192,12 +199,13 @@ align
|
|||
call :ident_lookup
|
||||
C=A
|
||||
?C!0:local_redeclaration
|
||||
|
||||
C=:local_variable_name
|
||||
I=8C
|
||||
|
||||
J=:local_variables_end
|
||||
J=8J
|
||||
call :ident_copy
|
||||
|
||||
; increase stack_end, store it in J
|
||||
C=:stack_end
|
||||
D=4C
|
||||
|
@ -207,6 +215,7 @@ align
|
|||
J+=d4
|
||||
; store null terminator
|
||||
1J=0
|
||||
|
||||
; update :local_variables_end
|
||||
I=:local_variables_end
|
||||
8I=J
|
||||
|
@ -349,7 +358,7 @@ align
|
|||
|
||||
I=:line
|
||||
I+=d1
|
||||
J=:global_variables
|
||||
J=:labels
|
||||
call :ident_lookup
|
||||
C=A
|
||||
?C!0:label_redefinition
|
||||
|
@ -386,7 +395,7 @@ align
|
|||
; "return " is 7 chars long
|
||||
I+=d7
|
||||
|
||||
call :set_rax_to_term
|
||||
call :set_rax_to_rvalue
|
||||
|
||||
J=d4
|
||||
I=:function_epilogue
|
||||
|
@ -477,72 +486,341 @@ align
|
|||
?B=A:return_1
|
||||
!:return_0
|
||||
|
||||
; set rax to the term in rsi
|
||||
; set <rax> to the term in rsi
|
||||
:set_rax_to_term
|
||||
R=I
|
||||
|
||||
C=1I
|
||||
D=''
|
||||
?C=D:term_char
|
||||
|
||||
C=1I
|
||||
D='.
|
||||
?C=D:term_label
|
||||
D=d58
|
||||
?C<D:term_number
|
||||
|
||||
; (fallthrough)
|
||||
; set <rax> to the variable in rsi
|
||||
:set_rax_to_variable
|
||||
; variable
|
||||
call :set_rax_to_address_of_variable
|
||||
call :set_rbx_to_rax
|
||||
call :set_rax_to_[rbx]
|
||||
return
|
||||
|
||||
:term_label
|
||||
C=:second_pass
|
||||
C=1C
|
||||
; skip looking up label on first pass; just use whatever's in rsi
|
||||
?C=0:set_rax_to_immediate
|
||||
; move past .
|
||||
I+=d1
|
||||
J=:labels
|
||||
call :ident_lookup
|
||||
C=A
|
||||
?C=0:bad_label
|
||||
; set rax to label value
|
||||
I=4C
|
||||
!:set_rax_to_immediate
|
||||
|
||||
align
|
||||
:rvalue
|
||||
reserve d8
|
||||
|
||||
; set <rax> to the rvalue in rsi
|
||||
:set_rax_to_rvalue
|
||||
; store pointer to rvalue
|
||||
C=:rvalue
|
||||
8C=I
|
||||
|
||||
C=1I
|
||||
D='&
|
||||
?C=D:rvalue_addressof
|
||||
|
||||
D='~
|
||||
?C=D:rvalue_bitwise_not
|
||||
|
||||
D='*
|
||||
?C=D:rvalue_dereference
|
||||
|
||||
J=I
|
||||
:rvalue_loop
|
||||
C=1J
|
||||
D='(
|
||||
?C=D:rvalue_function
|
||||
D=x20
|
||||
?C=D:rvalue_binary_op
|
||||
D=xa
|
||||
; no space or opening bracket; this must be a term
|
||||
?C=D:set_rax_to_term
|
||||
J+=d1
|
||||
!:rvalue_loop
|
||||
|
||||
:rvalue_function
|
||||
xcc
|
||||
|
||||
:binary_op
|
||||
reserve d1
|
||||
:rvalue_binary_op
|
||||
; move past ' '
|
||||
J+=d1
|
||||
; store binary op
|
||||
D=1J
|
||||
C=:binary_op
|
||||
1C=D
|
||||
|
||||
; make sure space follows operator
|
||||
J+=d1
|
||||
C=1J
|
||||
D=x20
|
||||
?C!D:bad_term
|
||||
; set rsi to second operand
|
||||
J+=d1
|
||||
I=J
|
||||
call :set_rax_to_term
|
||||
call :set_rsi_to_rax
|
||||
|
||||
; now set rax to first operand
|
||||
I=:rvalue
|
||||
I=8I
|
||||
call :set_rax_to_term
|
||||
|
||||
; and combine
|
||||
C=:binary_op
|
||||
C=1C
|
||||
|
||||
D='+
|
||||
?C=D:rvalue_add
|
||||
|
||||
D='-
|
||||
?C=D:rvalue_sub
|
||||
|
||||
D='*
|
||||
?C=D:rvalue_mul
|
||||
|
||||
D='/
|
||||
?C=D:rvalue_div
|
||||
|
||||
D='%
|
||||
?C=D:rvalue_rem
|
||||
|
||||
D='&
|
||||
?C=D:rvalue_and
|
||||
|
||||
D='|
|
||||
?C=D:rvalue_or
|
||||
|
||||
D='^
|
||||
?C=D:rvalue_xor
|
||||
|
||||
D='<
|
||||
?C=D:rvalue_shl
|
||||
|
||||
D='>
|
||||
?C=D:rvalue_shr
|
||||
|
||||
!:bad_term
|
||||
|
||||
:rvalue_add
|
||||
call :set_rbx_to_rsi
|
||||
J=d4
|
||||
I=:add_rax_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:add_rax_rbx
|
||||
x48
|
||||
x01
|
||||
xd8
|
||||
|
||||
:rvalue_sub
|
||||
call :set_rbx_to_rsi
|
||||
J=d4
|
||||
I=:sub_rax_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:sub_rax_rbx
|
||||
x48
|
||||
x29
|
||||
xd8
|
||||
|
||||
:rvalue_mul
|
||||
call :set_rbx_to_rsi
|
||||
J=d4
|
||||
I=:imul_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:imul_rbx
|
||||
x48
|
||||
xf7
|
||||
xeb
|
||||
|
||||
:rvalue_div
|
||||
call :set_rbx_to_rsi
|
||||
call :zero_rdx
|
||||
J=d4
|
||||
I=:idiv_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:idiv_rbx
|
||||
x48
|
||||
xf7
|
||||
xfb
|
||||
|
||||
:rvalue_rem
|
||||
call :set_rbx_to_rsi
|
||||
call :zero_rdx
|
||||
J=d4
|
||||
I=:idiv_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
call :set_rax_to_rdx
|
||||
return
|
||||
|
||||
:rvalue_and
|
||||
call :set_rbx_to_rsi
|
||||
J=d4
|
||||
I=:and_rax_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:and_rax_rbx
|
||||
x48
|
||||
x21
|
||||
xd8
|
||||
|
||||
:rvalue_or
|
||||
call :set_rbx_to_rsi
|
||||
J=d4
|
||||
I=:or_rax_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:or_rax_rbx
|
||||
x48
|
||||
x09
|
||||
xd8
|
||||
|
||||
:rvalue_xor
|
||||
call :set_rbx_to_rsi
|
||||
J=d4
|
||||
I=:xor_rax_rbx
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:xor_rax_rbx
|
||||
x48
|
||||
x31
|
||||
xd8
|
||||
|
||||
:rvalue_shl
|
||||
call :set_rcx_to_rsi
|
||||
J=d4
|
||||
I=:shl_rax_cl
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:shl_rax_cl
|
||||
x48
|
||||
xd3
|
||||
xe0
|
||||
|
||||
:rvalue_shr
|
||||
call :set_rcx_to_rsi
|
||||
J=d4
|
||||
I=:shr_rax_cl
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:shr_rax_cl
|
||||
x48
|
||||
xd3
|
||||
xe8
|
||||
|
||||
:rvalue_addressof
|
||||
I+=d1
|
||||
!:set_rax_to_address_of_variable
|
||||
|
||||
:rvalue_bitwise_not
|
||||
I+=d1
|
||||
call :set_rax_to_term
|
||||
J=d4
|
||||
I=:not_rax
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:not_rax
|
||||
x48
|
||||
xf7
|
||||
xd0
|
||||
|
||||
:rvalue_dereference_size
|
||||
reserve d1
|
||||
|
||||
:rvalue_dereference
|
||||
I+=d1
|
||||
D=1I
|
||||
C=:rvalue_dereference_size
|
||||
1C=D
|
||||
I+=d1
|
||||
call :set_rax_to_variable
|
||||
call :set_rbx_to_rax
|
||||
call :zero_rax
|
||||
C=:rvalue_dereference_size
|
||||
C=1C
|
||||
|
||||
D='1
|
||||
?C=D:set_al_to_[rbx]
|
||||
D='2
|
||||
?C=D:set_ax_to_[rbx]
|
||||
D='4
|
||||
?C=D:set_eax_to_[rbx]
|
||||
D='8
|
||||
?C=D:set_rax_to_[rbx]
|
||||
|
||||
!:bad_term
|
||||
|
||||
|
||||
; set <rax> to address of variable in rsi
|
||||
:set_rax_to_address_of_variable
|
||||
J=:local_variables
|
||||
call :ident_lookup
|
||||
C=A
|
||||
?C=0:rax2term_try_global
|
||||
?C=0:try_global
|
||||
; it's a local variable
|
||||
; read the offset from rbp
|
||||
; read the offset from <rbp>
|
||||
D=4C
|
||||
; put negated offset in rcx
|
||||
C=d0
|
||||
C-=D
|
||||
; store negated offset in :rax2term_addr
|
||||
D=:rax2term_addr
|
||||
4D=C
|
||||
; put negated offset in rbp
|
||||
R=d0
|
||||
R-=D
|
||||
|
||||
; lea rax, [rbp+
|
||||
J=d4
|
||||
I=:load_rbp_offset_prefix
|
||||
I=:lea_rax_rbp_offset_prefix
|
||||
D=d3
|
||||
syscall x1
|
||||
|
||||
; offset]
|
||||
J=d4
|
||||
I=:rax2term_addr
|
||||
I=:imm64
|
||||
4I=R
|
||||
D=d4
|
||||
syscall x1
|
||||
|
||||
return
|
||||
|
||||
:rax2term_try_global
|
||||
:try_global
|
||||
J=:global_variables
|
||||
call :ident_lookup
|
||||
C=A
|
||||
?C=0:bad_term
|
||||
?C=0:bad_variable
|
||||
; it's a global variable
|
||||
; get its address
|
||||
C=4C
|
||||
D=:rax2term_addr
|
||||
4D=C
|
||||
|
||||
; put address in rbx
|
||||
J=d4
|
||||
I=:mov_ebx_imm32_prefix
|
||||
D=d1
|
||||
syscall x1
|
||||
J=d4
|
||||
I=:rax2term_addr
|
||||
D=d4
|
||||
syscall x1
|
||||
|
||||
; now load [rbx] into rax
|
||||
J=d4
|
||||
I=:mov_rax_[rbx]
|
||||
D=d3
|
||||
syscall x1
|
||||
|
||||
return
|
||||
; put address in rax
|
||||
I=C
|
||||
!:set_rax_to_immediate
|
||||
|
||||
:term_char
|
||||
I+=d1
|
||||
|
@ -553,23 +831,29 @@ align
|
|||
reserve d1
|
||||
|
||||
:term_number
|
||||
call :read_number
|
||||
I=A
|
||||
!:set_rax_to_immediate
|
||||
|
||||
; set rax to the number in the string at rsi
|
||||
:read_number
|
||||
C=1I
|
||||
D='-
|
||||
; set rdx to 0 if number is positive, 1 if negative
|
||||
?C=D:term_number_negative
|
||||
?C=D:read_number_negative
|
||||
D=d0
|
||||
!:term_number_cont
|
||||
:term_number_negative
|
||||
!:read_number_cont
|
||||
:read_number_negative
|
||||
D=d1
|
||||
I+=d1
|
||||
:term_number_cont
|
||||
:read_number_cont
|
||||
; store away negativity
|
||||
C=:number_is_negative
|
||||
1C=D
|
||||
|
||||
C=1I
|
||||
D='0
|
||||
?C=D:term_hex_number
|
||||
?C=D:read_hex_number
|
||||
; it's a decimal number
|
||||
; rbp will store the number
|
||||
R=d0
|
||||
|
@ -591,14 +875,14 @@ align
|
|||
I+=d1
|
||||
!:decimal_number_loop
|
||||
:decimal_number_loop_end
|
||||
!:term_number_output
|
||||
!:read_number_output
|
||||
|
||||
:term_hex_number
|
||||
:read_hex_number
|
||||
I+=d1
|
||||
C=1I
|
||||
D='x
|
||||
; 0 followed by something other than x
|
||||
?C!D:bad_term
|
||||
?C!D:bad_number
|
||||
I+=d1
|
||||
; rbp will store the number
|
||||
R=d0
|
||||
|
@ -626,10 +910,18 @@ align
|
|||
I+=d1
|
||||
!:hex_number_loop
|
||||
:hex_number_loop_end
|
||||
!:term_number_output
|
||||
!:read_number_output
|
||||
|
||||
:term_number_output
|
||||
; we now have the *unsigned* number in rbp. first, take the sign into consideration
|
||||
:read_number_output
|
||||
; first, make sure number is followed by space or newline
|
||||
C=1I
|
||||
D=x20
|
||||
?C=D:read_number_valid
|
||||
D=xa
|
||||
?C=D:read_number_valid
|
||||
!:bad_number
|
||||
:read_number_valid
|
||||
; we now have the *unsigned* number in rbp. take the sign into consideration
|
||||
C=:number_is_negative
|
||||
D=1C
|
||||
?D=0:number_not_negative
|
||||
|
@ -638,8 +930,9 @@ align
|
|||
R=d0
|
||||
R-=C
|
||||
:number_not_negative
|
||||
I=R
|
||||
!:set_rax_to_immediate
|
||||
; finally, return
|
||||
A=R
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
@ -661,12 +954,113 @@ align
|
|||
syscall x1
|
||||
return
|
||||
|
||||
align
|
||||
:rax2term_addr
|
||||
reserve d4
|
||||
:zero_rax
|
||||
J=d4
|
||||
I=:xor_eax_eax
|
||||
D=d2
|
||||
syscall x1
|
||||
return
|
||||
:xor_eax_eax
|
||||
x31
|
||||
xc0
|
||||
|
||||
:zero_rdx
|
||||
J=d4
|
||||
I=:xor_edx_edx
|
||||
D=d2
|
||||
syscall x1
|
||||
return
|
||||
:xor_edx_edx
|
||||
x31
|
||||
xd2
|
||||
|
||||
:set_rbx_to_rax
|
||||
J=d4
|
||||
I=:mov_rbx_rax
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:mov_rbx_rax
|
||||
B=A
|
||||
|
||||
:set_rbx_to_rsi
|
||||
J=d4
|
||||
I=:mov_rbx_rsi
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:mov_rbx_rsi
|
||||
B=I
|
||||
|
||||
:set_rcx_to_rsi
|
||||
J=d4
|
||||
I=:mov_rcx_rsi
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:mov_rcx_rsi
|
||||
C=I
|
||||
|
||||
:set_rax_to_rdx
|
||||
J=d4
|
||||
I=:mov_rax_rdx
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:mov_rax_rdx
|
||||
A=D
|
||||
|
||||
:set_rsi_to_rax
|
||||
J=d4
|
||||
I=:mov_rsi_rax
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:mov_rsi_rax
|
||||
I=A
|
||||
|
||||
:set_rax_to_[rbx]
|
||||
J=d4
|
||||
I=:mov_rax_[rbx]
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:mov_rax_[rbx]
|
||||
x48
|
||||
x8b
|
||||
x03
|
||||
|
||||
:set_eax_to_[rbx]
|
||||
J=d4
|
||||
I=:mov_eax_[rbx]
|
||||
D=d2
|
||||
syscall x1
|
||||
return
|
||||
:mov_eax_[rbx]
|
||||
x8b
|
||||
x03
|
||||
|
||||
:set_ax_to_[rbx]
|
||||
J=d4
|
||||
I=:mov_ax_[rbx]
|
||||
D=d3
|
||||
syscall x1
|
||||
return
|
||||
:mov_ax_[rbx]
|
||||
x66
|
||||
x8b
|
||||
x03
|
||||
|
||||
:set_al_to_[rbx]
|
||||
J=d4
|
||||
I=:mov_al_[rbx]
|
||||
D=d2
|
||||
syscall x1
|
||||
return
|
||||
:mov_al_[rbx]
|
||||
x8a
|
||||
x03
|
||||
|
||||
:mov_ebx_imm32_prefix
|
||||
xbb
|
||||
|
||||
:mov_rax_imm64_prefix
|
||||
x48
|
||||
|
@ -675,15 +1069,11 @@ align
|
|||
align
|
||||
:imm64
|
||||
reserve d8
|
||||
:mov_rax_[rbx]
|
||||
x48
|
||||
x8b
|
||||
x03
|
||||
|
||||
; prefix for mov rax, [rbp+IMM32]
|
||||
:load_rbp_offset_prefix
|
||||
; prefix for lea rax, [rbp+IMM32]
|
||||
:lea_rax_rbp_offset_prefix
|
||||
x48
|
||||
x8b
|
||||
x8d
|
||||
x85
|
||||
|
||||
:input_filename
|
||||
|
@ -730,6 +1120,24 @@ align
|
|||
xa
|
||||
x0
|
||||
|
||||
:bad_variable
|
||||
B=:bad_variable_error_message
|
||||
!:program_error
|
||||
|
||||
:bad_variable_error_message
|
||||
str No such variable.
|
||||
xa
|
||||
x0
|
||||
|
||||
:bad_number
|
||||
B=:bad_number_error_message
|
||||
!:program_error
|
||||
|
||||
:bad_number_error_message
|
||||
str Bad number.
|
||||
xa
|
||||
x0
|
||||
|
||||
:bad_term
|
||||
B=:bad_term_error_message
|
||||
!:program_error
|
||||
|
@ -964,6 +1372,8 @@ align
|
|||
:"function"
|
||||
str function
|
||||
xa
|
||||
:zero
|
||||
x0
|
||||
|
||||
; 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)
|
||||
|
|
27
04b/in04b
27
04b/in04b
|
@ -1,9 +1,7 @@
|
|||
:test
|
||||
return -0x3874f
|
||||
|
||||
; declaration:
|
||||
; global <type> <name>
|
||||
; local <type> <name>
|
||||
; global <name>
|
||||
; local <name>
|
||||
; argument <name>
|
||||
; :<label>
|
||||
; statement:
|
||||
; <declaration>
|
||||
|
@ -16,8 +14,10 @@
|
|||
; return <rvalue>
|
||||
; string <str>
|
||||
; byte <number>
|
||||
; reserve <number>
|
||||
; term:
|
||||
; <var>
|
||||
; .<label>
|
||||
; <number>
|
||||
; number:
|
||||
; 'c
|
||||
|
@ -25,12 +25,12 @@
|
|||
; 0xabc
|
||||
; lvalue:
|
||||
; <var>
|
||||
; *1 <var> / *2 <var> / *4 <var> / *8 <var>
|
||||
; *1<var> / *2<var> / *4<var> / *8<var>
|
||||
; rvalue:
|
||||
; <var>
|
||||
; <term>
|
||||
; &<var>
|
||||
; *1 <var> / *2 <var> / *4 <var> / *8 <var>
|
||||
; ~<var>
|
||||
; *1<var> / *2<var> / *4<var> / *8<var>
|
||||
; ~<term>
|
||||
; <function>(<term>, <term>, ...)
|
||||
; <term> + <term>
|
||||
; <term> - <term>
|
||||
|
@ -49,6 +49,15 @@ main() ; hello
|
|||
global x
|
||||
global y ;123
|
||||
global z
|
||||
:test
|
||||
function
|
||||
local eee
|
||||
local fff
|
||||
local ggg
|
||||
return *2fff
|
||||
:test2
|
||||
function
|
||||
return -123
|
||||
|
||||
:syscall
|
||||
function
|
||||
|
|
|
@ -9,6 +9,8 @@ mov rax, imm64
|
|||
>48 b8 IMM64
|
||||
xor eax, eax (sets rax to 0, much shorter than mov rax, 0)
|
||||
>31 c0
|
||||
xor edx, edx
|
||||
>31 d2
|
||||
mov rdest, rsrc
|
||||
ax bx cx dx sp bp si di
|
||||
0 3 1 2 4 5 6 7
|
||||
|
@ -51,6 +53,8 @@ neg rax
|
|||
>48 f7 d8
|
||||
add rax, rbx
|
||||
>48 01 d8
|
||||
sub rax, rbx
|
||||
>48 29 d8
|
||||
imul rbx
|
||||
>48 f7 eb
|
||||
idiv rbx
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue