function calls
This commit is contained in:
parent
a415ec31c0
commit
b66a2dbe6b
3 changed files with 177 additions and 12 deletions
175
04b/in03
175
04b/in03
|
@ -142,6 +142,21 @@ call :string=
|
||||||
D=A
|
D=A
|
||||||
?D!0:handle_function
|
?D!0:handle_function
|
||||||
|
|
||||||
|
; check if this is a function call (where we discard the return value)
|
||||||
|
I=:line
|
||||||
|
; (check for an opening bracket not preceded by a space)
|
||||||
|
:call_check_loop
|
||||||
|
C=1I
|
||||||
|
D=x20
|
||||||
|
?C=D:call_check_loop_end
|
||||||
|
D=xa
|
||||||
|
?C=D:call_check_loop_end
|
||||||
|
D='(
|
||||||
|
?C=D:handle_call
|
||||||
|
I+=d1
|
||||||
|
!:call_check_loop
|
||||||
|
:call_check_loop_end
|
||||||
|
|
||||||
|
|
||||||
!:read_line
|
!:read_line
|
||||||
|
|
||||||
|
@ -166,6 +181,9 @@ D=A
|
||||||
I=d0
|
I=d0
|
||||||
D=d0
|
D=d0
|
||||||
syscall x8
|
syscall x8
|
||||||
|
; set line number to 0
|
||||||
|
C=:line_number
|
||||||
|
8C=0
|
||||||
|
|
||||||
!:second_pass_starting_point
|
!:second_pass_starting_point
|
||||||
|
|
||||||
|
@ -177,6 +195,16 @@ align
|
||||||
:local_variable_name
|
:local_variable_name
|
||||||
reserve d8
|
reserve d8
|
||||||
|
|
||||||
|
:handle_call
|
||||||
|
J=I
|
||||||
|
; just use the rvalue function call code
|
||||||
|
C=:rvalue
|
||||||
|
D=:line
|
||||||
|
8C=D
|
||||||
|
I=:line
|
||||||
|
call :rvalue_function_call
|
||||||
|
!:read_line
|
||||||
|
|
||||||
:handle_local
|
:handle_local
|
||||||
R=I
|
R=I
|
||||||
|
|
||||||
|
@ -545,7 +573,7 @@ align
|
||||||
:rvalue_loop
|
:rvalue_loop
|
||||||
C=1J
|
C=1J
|
||||||
D='(
|
D='(
|
||||||
?C=D:rvalue_function
|
?C=D:rvalue_function_call
|
||||||
D=x20
|
D=x20
|
||||||
?C=D:rvalue_binary_op
|
?C=D:rvalue_binary_op
|
||||||
D=xa
|
D=xa
|
||||||
|
@ -554,8 +582,111 @@ align
|
||||||
J+=d1
|
J+=d1
|
||||||
!:rvalue_loop
|
!:rvalue_loop
|
||||||
|
|
||||||
:rvalue_function
|
align
|
||||||
xcc
|
:rvalue_function_arg
|
||||||
|
reserve d8
|
||||||
|
:rvalue_function_arg_offset
|
||||||
|
reserve d4
|
||||||
|
|
||||||
|
:rvalue_function_call
|
||||||
|
I=J
|
||||||
|
I+=d1
|
||||||
|
C=1I
|
||||||
|
D=')
|
||||||
|
?C=D:function_call_no_arguments
|
||||||
|
|
||||||
|
C=:rvalue_function_arg_offset
|
||||||
|
; set arg offset to -16 (to skip over stack space for return address and rbp)
|
||||||
|
D=xfffffffffffffff0
|
||||||
|
4C=D
|
||||||
|
|
||||||
|
:rvalue_function_loop
|
||||||
|
C=:rvalue_function_arg
|
||||||
|
8C=I
|
||||||
|
; set <rax> to argument
|
||||||
|
call :set_rax_to_term
|
||||||
|
; set <[rsp-arg_offset]> to rax
|
||||||
|
; first, output prefix
|
||||||
|
J=d4
|
||||||
|
I=:mov_[rsp_offset]_rax_prefix
|
||||||
|
D=d4
|
||||||
|
syscall x1
|
||||||
|
; now decrement offset, and output it
|
||||||
|
I=:rvalue_function_arg_offset
|
||||||
|
C=4I
|
||||||
|
C-=d8
|
||||||
|
4I=C
|
||||||
|
J=d4
|
||||||
|
D=d4
|
||||||
|
syscall x1
|
||||||
|
|
||||||
|
C=:rvalue_function_arg
|
||||||
|
I=8C
|
||||||
|
; skip over argument
|
||||||
|
:rvalue_function_arg_loop
|
||||||
|
C=1I
|
||||||
|
D=',
|
||||||
|
?C=D:rvalue_function_next_arg
|
||||||
|
D=')
|
||||||
|
?C=D:rvalue_function_loop_end
|
||||||
|
D=xa
|
||||||
|
; no closing bracket
|
||||||
|
?C=D:bad_call
|
||||||
|
I+=d1
|
||||||
|
!:rvalue_function_arg_loop
|
||||||
|
:rvalue_function_next_arg
|
||||||
|
; skip comma
|
||||||
|
I+=d1
|
||||||
|
C=1I
|
||||||
|
D=x20
|
||||||
|
; make sure there's a space after the comma
|
||||||
|
?C!D:bad_call
|
||||||
|
; skip space
|
||||||
|
I+=d1
|
||||||
|
|
||||||
|
; handle the next argument
|
||||||
|
!:rvalue_function_loop
|
||||||
|
:rvalue_function_loop_end
|
||||||
|
:function_call_no_arguments
|
||||||
|
|
||||||
|
I+=d1
|
||||||
|
C=1I
|
||||||
|
D=xa
|
||||||
|
; make sure there's nothing after the closing bracket
|
||||||
|
?C!D:bad_term
|
||||||
|
|
||||||
|
C=:second_pass
|
||||||
|
C=1C
|
||||||
|
?C=0:ignore_function_address
|
||||||
|
; look up function name
|
||||||
|
I=:rvalue
|
||||||
|
I=8I
|
||||||
|
J=:labels
|
||||||
|
call :ident_lookup
|
||||||
|
C=A
|
||||||
|
?C=0:bad_function
|
||||||
|
; read address
|
||||||
|
I=4C
|
||||||
|
:ignore_function_address
|
||||||
|
call :set_rax_to_immediate
|
||||||
|
; write call rax
|
||||||
|
J=d4
|
||||||
|
I=:call_rax
|
||||||
|
D=d2
|
||||||
|
syscall x1
|
||||||
|
; we're done!
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
:mov_[rsp_offset]_rax_prefix
|
||||||
|
x48
|
||||||
|
x89
|
||||||
|
x84
|
||||||
|
x24
|
||||||
|
|
||||||
|
:call_rax
|
||||||
|
xff
|
||||||
|
xd0
|
||||||
|
|
||||||
:binary_op
|
:binary_op
|
||||||
reserve d1
|
reserve d1
|
||||||
|
@ -852,8 +983,11 @@ align
|
||||||
1C=D
|
1C=D
|
||||||
|
|
||||||
C=1I
|
C=1I
|
||||||
|
D='9
|
||||||
|
?C>D:bad_number
|
||||||
D='0
|
D='0
|
||||||
?C=D:read_hex_number
|
?C<D:bad_number
|
||||||
|
?C=D:number_starting_with0
|
||||||
; it's a decimal number
|
; it's a decimal number
|
||||||
; rbp will store the number
|
; rbp will store the number
|
||||||
R=d0
|
R=d0
|
||||||
|
@ -877,10 +1011,17 @@ align
|
||||||
:decimal_number_loop_end
|
:decimal_number_loop_end
|
||||||
!:read_number_output
|
!:read_number_output
|
||||||
|
|
||||||
:read_hex_number
|
:number_starting_with0
|
||||||
I+=d1
|
I+=d1
|
||||||
C=1I
|
C=1I
|
||||||
D='x
|
D='x
|
||||||
|
?C=D:read_hex_number
|
||||||
|
; otherwise, it should just be 0
|
||||||
|
R=d0
|
||||||
|
!:read_number_output
|
||||||
|
|
||||||
|
|
||||||
|
:read_hex_number
|
||||||
; 0 followed by something other than x
|
; 0 followed by something other than x
|
||||||
?C!D:bad_number
|
?C!D:bad_number
|
||||||
I+=d1
|
I+=d1
|
||||||
|
@ -913,10 +1054,14 @@ align
|
||||||
!:read_number_output
|
!:read_number_output
|
||||||
|
|
||||||
:read_number_output
|
:read_number_output
|
||||||
; first, make sure number is followed by space or newline
|
; first, make sure number is followed by space/newline/appropriate punctuation
|
||||||
C=1I
|
C=1I
|
||||||
D=x20
|
D=x20
|
||||||
?C=D:read_number_valid
|
?C=D:read_number_valid
|
||||||
|
D=',
|
||||||
|
?C=D:read_number_valid
|
||||||
|
D=')
|
||||||
|
?C=D:read_number_valid
|
||||||
D=xa
|
D=xa
|
||||||
?C=D:read_number_valid
|
?C=D:read_number_valid
|
||||||
!:bad_number
|
!:bad_number
|
||||||
|
@ -1129,6 +1274,15 @@ align
|
||||||
xa
|
xa
|
||||||
x0
|
x0
|
||||||
|
|
||||||
|
:bad_function
|
||||||
|
B=:bad_function_error_message
|
||||||
|
!:program_error
|
||||||
|
|
||||||
|
:bad_function_error_message
|
||||||
|
str No such function.
|
||||||
|
xa
|
||||||
|
x0
|
||||||
|
|
||||||
:bad_number
|
:bad_number
|
||||||
B=:bad_number_error_message
|
B=:bad_number_error_message
|
||||||
!:program_error
|
!:program_error
|
||||||
|
@ -1147,6 +1301,15 @@ align
|
||||||
xa
|
xa
|
||||||
x0
|
x0
|
||||||
|
|
||||||
|
:bad_call
|
||||||
|
B=:bad_call_error_message
|
||||||
|
!:program_error
|
||||||
|
|
||||||
|
:bad_call_error_message
|
||||||
|
str Bad function call.
|
||||||
|
xa
|
||||||
|
x0
|
||||||
|
|
||||||
:label_redefinition
|
:label_redefinition
|
||||||
B=:label_redefinition_error_message
|
B=:label_redefinition_error_message
|
||||||
!:program_error
|
!:program_error
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
; return <rvalue>
|
; return <rvalue>
|
||||||
; string <str>
|
; string <str>
|
||||||
; byte <number>
|
; byte <number>
|
||||||
; reserve <number>
|
|
||||||
; term:
|
; term:
|
||||||
; <var>
|
; <var>
|
||||||
; .<label>
|
; .<label>
|
||||||
|
@ -44,7 +43,7 @@
|
||||||
; <term> < <term> (left shift)
|
; <term> < <term> (left shift)
|
||||||
; <term> > <term> (unsigned right shift)
|
; <term> > <term> (unsigned right shift)
|
||||||
|
|
||||||
main() ; hello
|
main(46) ; hello
|
||||||
|
|
||||||
global x
|
global x
|
||||||
global y ;123
|
global y ;123
|
||||||
|
@ -54,7 +53,8 @@ function
|
||||||
local eee
|
local eee
|
||||||
local fff
|
local fff
|
||||||
local ggg
|
local ggg
|
||||||
return *2fff
|
return test2(eee, 0x223, ggg)
|
||||||
|
|
||||||
:test2
|
:test2
|
||||||
function
|
function
|
||||||
return -123
|
return -123
|
||||||
|
@ -99,7 +99,7 @@ function
|
||||||
|
|
||||||
:main
|
:main
|
||||||
function
|
function
|
||||||
puts(str_hello_world)
|
puts(.str_hello_world)
|
||||||
syscall(0x3c, 0)
|
syscall(0x3c, 0)
|
||||||
:str_hello_world
|
:str_hello_world
|
||||||
string Hello, world!
|
string Hello, world!
|
||||||
|
|
|
@ -43,6 +43,8 @@ mov rax, qword [rbp+imm32]
|
||||||
>48 8b 85 IMM32 (note: imm may be negative)
|
>48 8b 85 IMM32 (note: imm may be negative)
|
||||||
mov qword [rbp+imm32], rax
|
mov qword [rbp+imm32], rax
|
||||||
>48 89 85 IMM32 (note: imm may be negative)
|
>48 89 85 IMM32 (note: imm may be negative)
|
||||||
|
mov qword [rsp+imm32], rax
|
||||||
|
>48 89 84 24 IMM32 (note: imm may be negative)
|
||||||
mov qword [rsp], rbp
|
mov qword [rsp], rbp
|
||||||
>48 89 2c 24
|
>48 89 2c 24
|
||||||
mov rbp, qword [rsp]
|
mov rbp, qword [rsp]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue