diff options
author | pommicket <pommicket@gmail.com> | 2022-01-14 10:08:02 -0500 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2022-01-14 10:08:02 -0500 |
commit | 39b51014901ce769f2df4d66b5d13652a3daba89 (patch) | |
tree | e06728ba66b2f453a3acf59dcab7277932a0026b /05 | |
parent | 05cbc582997e2da9c291f093700b6e42438b135e (diff) |
unary ops mostly working
Diffstat (limited to '05')
-rw-r--r-- | 05/constants.b | 2 | ||||
-rw-r--r-- | 05/main.c | 2 | ||||
-rw-r--r-- | 05/parse.b | 112 |
3 files changed, 110 insertions, 6 deletions
diff --git a/05/constants.b b/05/constants.b index c97eb9f..bb77909 100644 --- a/05/constants.b +++ b/05/constants.b @@ -155,7 +155,7 @@ #define EXPRESSION_UNARY_PLUS 214 #define EXPRESSION_UNARY_MINUS 215 #define EXPRESSION_BITWISE_NOT 216 -#define EXPRESSION_NOT 217 +#define EXPRESSION_LOGICAL_NOT 217 #define EXPRESSION_SIZEOF 218 #define EXPRESSION_CAST 219 #define EXPRESSION_MUL 220 @@ -1 +1 @@ -(3+6).c*5---8--/3l->blah++ +5 + *7 @@ -1,3 +1,4 @@ +; @TODO: fix 5 * *x being interpreted as (5*) * x function parse_expression argument tokens argument tokens_end @@ -84,10 +85,12 @@ function parse_expression :expr_find_operator_loop_end if best == 0 goto unrecognized_expression + + c = *1best + if best == tokens goto parse_expr_unary ; it's a binary expression. - c = *1best if c == SYMBOL_PLUS_PLUS goto parse_postincrement if c == SYMBOL_MINUS_MINUS goto parse_postdecrement if c == SYMBOL_QUESTION goto parse_conditional @@ -104,7 +107,11 @@ function parse_expression :parse_expr_unary if c == KEYWORD_SIZEOF goto parse_expr_sizeof - byte 0xcc ; @TODO + *1out = unary_op_to_expression_type(c) + out += 8 + p = tokens + 16 + out = parse_expression(p, tokens_end, out) + return out :parse_expr_sizeof byte 0xcc ; @TODO @@ -292,7 +299,37 @@ function operator_precedence if op == SYMBOL_NOT goto return_0xe0 return 0xffff - + +function unary_op_to_expression_type + argument op + if op == SYMBOL_PLUS_PLUS goto return_EXPRESSION_PRE_INCREMENT + if op == SYMBOL_MINUS_MINUS goto return_EXPRESSION_PRE_DECREMENT + if op == SYMBOL_AND goto return_EXPRESSION_ADDRESS_OF + if op == SYMBOL_TIMES goto return_EXPRESSION_DEREFERENCE + if op == SYMBOL_PLUS goto return_EXPRESSION_UNARY_PLUS + if op == SYMBOL_MINUS goto return_EXPRESSION_UNARY_MINUS + if op == SYMBOL_TILDE goto return_EXPRESSION_BITWISE_NOT + if op == SYMBOL_NOT goto return_EXPRESSION_LOGICAL_NOT + return 0 + +:return_EXPRESSION_PRE_INCREMENT + return EXPRESSION_PRE_INCREMENT +:return_EXPRESSION_PRE_DECREMENT + return EXPRESSION_PRE_INCREMENT +:return_EXPRESSION_ADDRESS_OF + return EXPRESSION_ADDRESS_OF +:return_EXPRESSION_DEREFERENCE + return EXPRESSION_DEREFERENCE +:return_EXPRESSION_UNARY_PLUS + return EXPRESSION_UNARY_PLUS +:return_EXPRESSION_UNARY_MINUS + return EXPRESSION_UNARY_MINUS +:return_EXPRESSION_BITWISE_NOT + return EXPRESSION_BITWISE_NOT +:return_EXPRESSION_LOGICAL_NOT + return EXPRESSION_LOGICAL_NOT + + ; is this operator right-associative? most C operators are left associative, ; but += / -= / etc. are not function operator_right_associative @@ -440,6 +477,15 @@ function print_expression if c == EXPRESSION_POST_DECREMENT goto print_post_decrement if c == EXPRESSION_DOT goto print_expr_dot if c == EXPRESSION_ARROW goto print_expr_arrow + if c == EXPRESSION_PRE_INCREMENT goto print_pre_increment + if c == EXPRESSION_PRE_DECREMENT goto print_pre_decrement + if c == EXPRESSION_ADDRESS_OF goto print_address_of + if c == EXPRESSION_DEREFERENCE goto print_dereference + if c == EXPRESSION_UNARY_PLUS goto print_unary_plus + if c == EXPRESSION_UNARY_MINUS goto print_unary_minus + if c == EXPRESSION_BITWISE_NOT goto print_bitwise_not + if c == EXPRESSION_LOGICAL_NOT goto print_logical_not + b = binop_expression_type_to_symbol(c) if b != 0 goto print_expr_binop @@ -513,7 +559,65 @@ function print_expression putc('-) putc(41) return expression - + :print_pre_increment + putc(40) + putc('+) + putc('+) + expression += 8 + expression = print_expression(expression) + putc(41) + return expression + :print_pre_decrement + putc(40) + putc('-) + putc('-) + expression += 8 + expression = print_expression(expression) + putc(41) + return expression + :print_address_of + putc(40) + putc('&) + expression += 8 + expression = print_expression(expression) + putc(41) + return expression + :print_dereference + putc(40) + putc('*) + expression += 8 + expression = print_expression(expression) + putc(41) + return expression + :print_unary_plus + putc(40) + putc('+) + expression += 8 + expression = print_expression(expression) + putc(41) + return expression + :print_unary_minus + putc(40) + putc('-) + expression += 8 + expression = print_expression(expression) + putc(41) + return expression + :print_bitwise_not + putc(40) + putc('~) + expression += 8 + expression = print_expression(expression) + putc(41) + return expression + :print_logical_not + putc(40) + putc('!) + expression += 8 + expression = print_expression(expression) + 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 function print_type |