parsing calls, mostly
This commit is contained in:
parent
bbd9eb17e0
commit
c2377fa40f
3 changed files with 54 additions and 9 deletions
|
@ -140,7 +140,7 @@
|
||||||
|
|
||||||
; the format of expression headers is:
|
; the format of expression headers is:
|
||||||
; uchar kind (one of the constants below)
|
; uchar kind (one of the constants below)
|
||||||
; uchar info
|
; uchar (padding)
|
||||||
; ushort (padding)
|
; ushort (padding)
|
||||||
; uint type
|
; uint type
|
||||||
; immediately following the header in memory are the arguments of the expression
|
; 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.
|
; - 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.
|
; 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 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.
|
; 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)
|
; Note that string literals are stored as constant integers (you can check the type to know what it is)
|
||||||
#define EXPRESSION_FUNCTION 198
|
#define EXPRESSION_FUNCTION 198
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
int main() {
|
int main() {
|
||||||
int a = exit;
|
int a = exit;
|
||||||
int b[] = {1,2,3};
|
int b[] = {1,2,3};
|
||||||
exit(1);
|
exit(1, 17, a+b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* int f(int x, int y[3]) { */
|
/* int f(int x, int y[3]) { */
|
||||||
|
|
57
05/parse.b
57
05/parse.b
|
@ -653,7 +653,7 @@ function parse_statement
|
||||||
:local_decl_initializer
|
:local_decl_initializer
|
||||||
token += 16
|
token += 16
|
||||||
if *1token == SYMBOL_LBRACE goto local_init_lbrace
|
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
|
out += 24
|
||||||
p = expressions_end
|
p = expressions_end
|
||||||
*8out = p
|
*8out = p
|
||||||
|
@ -1512,8 +1512,9 @@ function token_next_semicolon_not_in_brackets
|
||||||
byte 0
|
byte 0
|
||||||
|
|
||||||
|
|
||||||
; return the next semicolon or comma not in parentheses, square brackets, or braces.
|
; return the next semicolon or comma not in parentheses, square brackets, or braces;
|
||||||
function token_next_semicolon_or_comma_not_in_brackets
|
; or the next unmatched right bracket (of any type)
|
||||||
|
function token_next_semicolon_comma_rbracket
|
||||||
argument token0
|
argument token0
|
||||||
|
|
||||||
local token
|
local token
|
||||||
|
@ -1542,13 +1543,16 @@ function token_next_semicolon_or_comma_not_in_brackets
|
||||||
goto next_semicomma_loop
|
goto next_semicomma_loop
|
||||||
:next_semicomma_decdepth
|
:next_semicomma_decdepth
|
||||||
depth -= 1
|
depth -= 1
|
||||||
|
if depth < 0 goto next_semicomma_loop_end_dectoken
|
||||||
goto next_semicomma_loop
|
goto next_semicomma_loop
|
||||||
|
:next_semicomma_loop_end_dectoken
|
||||||
|
token -= 16
|
||||||
:next_semicomma_loop_end
|
:next_semicomma_loop_end
|
||||||
return token
|
return token
|
||||||
:next_semicomma_eof
|
:next_semicomma_eof
|
||||||
token_error(token0, .str_next_semicomma_eof)
|
token_error(token0, .str_next_semicomma_eof)
|
||||||
: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
|
byte 0
|
||||||
|
|
||||||
|
|
||||||
|
@ -2547,8 +2551,33 @@ function parse_expression
|
||||||
bad_types_to_operator(tokens, *4a, *4b)
|
bad_types_to_operator(tokens, *4a, *4b)
|
||||||
|
|
||||||
:parse_call
|
: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
|
:parse_expr_unary
|
||||||
if c == KEYWORD_SIZEOF goto parse_sizeof
|
if c == KEYWORD_SIZEOF goto parse_sizeof
|
||||||
*1out = unary_op_to_expression_type(c)
|
*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_BITWISE_NOT goto print_bitwise_not
|
||||||
if c == EXPRESSION_LOGICAL_NOT goto print_logical_not
|
if c == EXPRESSION_LOGICAL_NOT goto print_logical_not
|
||||||
if c == EXPRESSION_CAST goto print_cast
|
if c == EXPRESSION_CAST goto print_cast
|
||||||
|
if c == EXPRESSION_CALL goto print_call
|
||||||
|
|
||||||
b = binop_expression_type_to_symbol(c)
|
b = binop_expression_type_to_symbol(c)
|
||||||
if b != 0 goto print_expr_binop
|
if b != 0 goto print_expr_binop
|
||||||
|
@ -3969,6 +3999,21 @@ function print_expression
|
||||||
expression = print_expression(expression)
|
expression = print_expression(expression)
|
||||||
putc(41)
|
putc(41)
|
||||||
return expression
|
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
|
; 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
|
; *int for pointer to int and [5]int for array of 5 ints
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue