summaryrefslogtreecommitdiff
path: root/05
diff options
context:
space:
mode:
Diffstat (limited to '05')
-rw-r--r--05/constants.b4
-rw-r--r--05/main.c2
-rw-r--r--05/parse.b57
3 files changed, 54 insertions, 9 deletions
diff --git a/05/constants.b b/05/constants.b
index 8e2f20c..93c2f5f 100644
--- a/05/constants.b
+++ b/05/constants.b
@@ -140,7 +140,7 @@
; the format of expression headers is:
; uchar kind (one of the constants below)
-; uchar info
+; uchar (padding)
; ushort (padding)
; uint type
; immediately following the header in memory are the arguments of the expression
@@ -155,7 +155,7 @@
; - for the operators . and ->, the first argument is the expression on the left-hand side, and the second argument is a 64-bit offset.
; we could use a 32-bit offset but that would cause things to be unaligned.
; - for the ternary operator ? :, the first followed by the second followed by the third
-; - for function calls, the function, followed by each of the arguments to the function — info indicates the number of arguments
+; - for function calls, the function, followed by each of the arguments to the function, followed by 8 bytes of zeros
; File/line number are not stored in expressions.
; Note that string literals are stored as constant integers (you can check the type to know what it is)
#define EXPRESSION_FUNCTION 198
diff --git a/05/main.c b/05/main.c
index 57eba24..17e4404 100644
--- a/05/main.c
+++ b/05/main.c
@@ -3,7 +3,7 @@
int main() {
int a = exit;
int b[] = {1,2,3};
- exit(1);
+ exit(1, 17, a+b);
}
/* int f(int x, int y[3]) { */
diff --git a/05/parse.b b/05/parse.b
index b1f8b90..3cdbb41 100644
--- a/05/parse.b
+++ b/05/parse.b
@@ -653,7 +653,7 @@ function parse_statement
:local_decl_initializer
token += 16
if *1token == SYMBOL_LBRACE goto local_init_lbrace
- n = token_next_semicolon_or_comma_not_in_brackets(token)
+ n = token_next_semicolon_comma_rbracket(token)
out += 24
p = expressions_end
*8out = p
@@ -1512,8 +1512,9 @@ function token_next_semicolon_not_in_brackets
byte 0
-; return the next semicolon or comma not in parentheses, square brackets, or braces.
-function token_next_semicolon_or_comma_not_in_brackets
+; return the next semicolon or comma not in parentheses, square brackets, or braces;
+; or the next unmatched right bracket (of any type)
+function token_next_semicolon_comma_rbracket
argument token0
local token
@@ -1542,13 +1543,16 @@ function token_next_semicolon_or_comma_not_in_brackets
goto next_semicomma_loop
:next_semicomma_decdepth
depth -= 1
+ if depth < 0 goto next_semicomma_loop_end_dectoken
goto next_semicomma_loop
+ :next_semicomma_loop_end_dectoken
+ token -= 16
:next_semicomma_loop_end
return token
:next_semicomma_eof
token_error(token0, .str_next_semicomma_eof)
:str_next_semicomma_eof
- string End of file found while searching for semicolon or comma.
+ string End of file found while searching for semicolon/comma/closing bracket.
byte 0
@@ -2547,8 +2551,33 @@ function parse_expression
bad_types_to_operator(tokens, *4a, *4b)
:parse_call
- byte 0xcc ; @TODO
-
+ *4type = TYPE_INT ; @TODO: proper typing
+ :call_args_loop
+ if *1p == SYMBOL_RPAREN goto call_args_loop_end
+ n = token_next_semicolon_comma_rbracket(p)
+ print_tokens(p, n)
+ out = parse_expression(p, n, out)
+ p = n
+ if *1p == SYMBOL_RPAREN goto call_args_loop_end
+ if *1p != SYMBOL_COMMA goto bad_call
+ p += 16
+ goto call_args_loop
+ :call_args_loop_end
+ p += 16
+ if p != tokens_end goto stuff_after_call
+ *8out = 0
+ out += 8
+ return out
+ :bad_call
+ token_error(p, .str_bad_call)
+ :str_bad_call
+ string Bad function call.
+ byte 0
+ :stuff_after_call
+ token_error(p, .str_stuff_after_call)
+ :str_stuff_after_call
+ string Unexpected stuff after function call.
+ byte 0
:parse_expr_unary
if c == KEYWORD_SIZEOF goto parse_sizeof
*1out = unary_op_to_expression_type(c)
@@ -3818,6 +3847,7 @@ function print_expression
if c == EXPRESSION_BITWISE_NOT goto print_bitwise_not
if c == EXPRESSION_LOGICAL_NOT goto print_logical_not
if c == EXPRESSION_CAST goto print_cast
+ if c == EXPRESSION_CALL goto print_call
b = binop_expression_type_to_symbol(c)
if b != 0 goto print_expr_binop
@@ -3969,6 +3999,21 @@ function print_expression
expression = print_expression(expression)
putc(41)
return expression
+ :print_call
+ putc(40)
+ expression += 8
+ expression = print_expression(expression) ; function name
+ putc(40)
+ :print_call_loop
+ if *1expression == 0 goto print_call_loop_end
+ expression = print_expression(expression)
+ putc(44)
+ goto print_call_loop
+ :print_call_loop_end
+ putc(41)
+ expression += 8
+ putc(41)
+ return expression
; NOTE: to make things easier, the format which this outputs isn't the same as C's, specifically we have
; *int for pointer to int and [5]int for array of 5 ints