function calls
This commit is contained in:
parent
a415ec31c0
commit
b66a2dbe6b
3 changed files with 177 additions and 12 deletions
179
04b/in03
179
04b/in03
|
@ -142,6 +142,21 @@ call :string=
|
|||
D=A
|
||||
?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
|
||||
|
||||
|
@ -166,6 +181,9 @@ D=A
|
|||
I=d0
|
||||
D=d0
|
||||
syscall x8
|
||||
; set line number to 0
|
||||
C=:line_number
|
||||
8C=0
|
||||
|
||||
!:second_pass_starting_point
|
||||
|
||||
|
@ -176,6 +194,16 @@ D=A
|
|||
align
|
||||
:local_variable_name
|
||||
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
|
||||
R=I
|
||||
|
@ -545,7 +573,7 @@ align
|
|||
:rvalue_loop
|
||||
C=1J
|
||||
D='(
|
||||
?C=D:rvalue_function
|
||||
?C=D:rvalue_function_call
|
||||
D=x20
|
||||
?C=D:rvalue_binary_op
|
||||
D=xa
|
||||
|
@ -554,9 +582,112 @@ align
|
|||
J+=d1
|
||||
!:rvalue_loop
|
||||
|
||||
:rvalue_function
|
||||
xcc
|
||||
align
|
||||
: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
|
||||
reserve d1
|
||||
:rvalue_binary_op
|
||||
|
@ -852,8 +983,11 @@ align
|
|||
1C=D
|
||||
|
||||
C=1I
|
||||
D='9
|
||||
?C>D:bad_number
|
||||
D='0
|
||||
?C=D:read_hex_number
|
||||
?C<D:bad_number
|
||||
?C=D:number_starting_with0
|
||||
; it's a decimal number
|
||||
; rbp will store the number
|
||||
R=d0
|
||||
|
@ -876,11 +1010,18 @@ align
|
|||
!:decimal_number_loop
|
||||
:decimal_number_loop_end
|
||||
!:read_number_output
|
||||
|
||||
:read_hex_number
|
||||
|
||||
:number_starting_with0
|
||||
I+=d1
|
||||
C=1I
|
||||
C=1I
|
||||
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
|
||||
?C!D:bad_number
|
||||
I+=d1
|
||||
|
@ -913,10 +1054,14 @@ align
|
|||
!: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
|
||||
D=x20
|
||||
?C=D:read_number_valid
|
||||
D=',
|
||||
?C=D:read_number_valid
|
||||
D=')
|
||||
?C=D:read_number_valid
|
||||
D=xa
|
||||
?C=D:read_number_valid
|
||||
!:bad_number
|
||||
|
@ -1129,6 +1274,15 @@ align
|
|||
xa
|
||||
x0
|
||||
|
||||
:bad_function
|
||||
B=:bad_function_error_message
|
||||
!:program_error
|
||||
|
||||
:bad_function_error_message
|
||||
str No such function.
|
||||
xa
|
||||
x0
|
||||
|
||||
:bad_number
|
||||
B=:bad_number_error_message
|
||||
!:program_error
|
||||
|
@ -1146,6 +1300,15 @@ align
|
|||
str Bad term.
|
||||
xa
|
||||
x0
|
||||
|
||||
:bad_call
|
||||
B=:bad_call_error_message
|
||||
!:program_error
|
||||
|
||||
:bad_call_error_message
|
||||
str Bad function call.
|
||||
xa
|
||||
x0
|
||||
|
||||
:label_redefinition
|
||||
B=:label_redefinition_error_message
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
; return <rvalue>
|
||||
; string <str>
|
||||
; byte <number>
|
||||
; reserve <number>
|
||||
; term:
|
||||
; <var>
|
||||
; .<label>
|
||||
|
@ -44,7 +43,7 @@
|
|||
; <term> < <term> (left shift)
|
||||
; <term> > <term> (unsigned right shift)
|
||||
|
||||
main() ; hello
|
||||
main(46) ; hello
|
||||
|
||||
global x
|
||||
global y ;123
|
||||
|
@ -54,7 +53,8 @@ function
|
|||
local eee
|
||||
local fff
|
||||
local ggg
|
||||
return *2fff
|
||||
return test2(eee, 0x223, ggg)
|
||||
|
||||
:test2
|
||||
function
|
||||
return -123
|
||||
|
@ -99,7 +99,7 @@ function
|
|||
|
||||
:main
|
||||
function
|
||||
puts(str_hello_world)
|
||||
puts(.str_hello_world)
|
||||
syscall(0x3c, 0)
|
||||
:str_hello_world
|
||||
string Hello, world!
|
||||
|
|
|
@ -43,6 +43,8 @@ mov rax, qword [rbp+imm32]
|
|||
>48 8b 85 IMM32 (note: imm may be negative)
|
||||
mov qword [rbp+imm32], rax
|
||||
>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
|
||||
>48 89 2c 24
|
||||
mov rbp, qword [rsp]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue