From b66a2dbe6b87e75fbb54beda05c00c9f13f84f2c Mon Sep 17 00:00:00 2001 From: pommicket Date: Thu, 6 Jan 2022 13:13:12 -0500 Subject: function calls --- 04b/in03 | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 04b/in04b | 8 +-- instructions.txt | 2 + 3 files changed, 177 insertions(+), 12 deletions(-) diff --git a/04b/in03 b/04b/in03 index 9709513..f03c08a 100644 --- a/04b/in03 +++ b/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 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