diff options
Diffstat (limited to '05')
-rw-r--r-- | 05/constants.b | 6 | ||||
-rw-r--r-- | 05/main.c | 2 | ||||
-rw-r--r-- | 05/parse.b | 173 |
3 files changed, 169 insertions, 12 deletions
diff --git a/05/constants.b b/05/constants.b index bd5c57a..24fd005 100644 --- a/05/constants.b +++ b/05/constants.b @@ -21,7 +21,7 @@ ; c + - ; d * / % ; e8 cast -; e unary prefixes ++ -- & * + - ~ ! +; e sizeof, unary prefixes ++ -- & * + - ~ ! ; f . -> () [] postfix ++ -- ; highest ; NB: for equal precedence, operators are applied left-to-right except for assignment operators (precedence 2) @@ -174,8 +174,8 @@ #define EXPRESSION_BITWISE_AND 233 #define EXPRESSION_BITWISE_XOR 234 #define EXPRESSION_BITWISE_OR 235 -#define EXPRESSION_AND 236 -#define EXPRESSION_OR 237 +#define EXPRESSION_LOGICAL_AND 236 +#define EXPRESSION_LOGICAL_OR 237 ; e.g. x == 5 ? 6 : 7 #define EXPRESSION_CONDITIONAL 238 #define EXPRESSION_ASSIGN 239 @@ -1 +1 @@ -(3+5)*6 +34 @@ -79,9 +79,43 @@ function parse_expression depth -= 1 goto expr_find_operator_loop :expr_find_operator_loop_end - putn(*1best) - goto unrecognized_expression + if best == 0 goto unrecognized_expression + 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 + *1out = binop_symbol_to_expression_type(c) + out += 8 + parse_expression(tokens, best, out) ; first operand + if c == SYMBOL_DOT goto parse_expr_member + if c == SYMBOL_ARROW goto parse_expr_member + p = best + 16 + parse_expression(p, tokens_end, out) ; second operand + + ;@TODO: casts + + + :parse_expr_unary + if c == KEYWORD_SIZEOF goto parse_expr_sizeof + byte 0xcc ; @TODO + + :parse_expr_sizeof + byte 0xcc ; @TODO + + :parse_expr_member ; -> or . + byte 0xcc ; @TODO + + :parse_conditional + byte 0xcc ; @TODO + + :parse_postincrement + byte 0xcc ; @TODO + :parse_postdecrement + byte 0xcc ; @TODO :single_token_expression in = tokens @@ -220,6 +254,7 @@ function operator_precedence return 0xffff :operator_precedence_unary + if op == KEYWORD_SIZEOF goto return_0xe0 if op == SYMBOL_PLUS_PLUS goto return_0xe0 if op == SYMBOL_MINUS_MINUS goto return_0xe0 if op == SYMBOL_AND goto return_0xe0 @@ -239,6 +274,105 @@ function operator_right_associative if op > SYMBOL_OR_EQ goto return_0 goto return_1 +:binop_table + byte SYMBOL_COMMA + byte EXPRESSION_COMMA + byte SYMBOL_EQ + byte EXPRESSION_ASSIGN + byte SYMBOL_PLUS_EQ + byte EXPRESSION_ASSIGN_ADD + byte SYMBOL_MINUS_EQ + byte EXPRESSION_ASSIGN_SUB + byte SYMBOL_TIMES_EQ + byte EXPRESSION_ASSIGN_MUL + byte SYMBOL_DIV_EQ + byte EXPRESSION_ASSIGN_DIV + byte SYMBOL_PERCENT_EQ + byte EXPRESSION_ASSIGN_REMAINDER + byte SYMBOL_LSHIFT_EQ + byte EXPRESSION_ASSIGN_LSHIFT + byte SYMBOL_RSHIFT_EQ + byte EXPRESSION_ASSIGN_RSHIFT + byte SYMBOL_AND_EQ + byte EXPRESSION_ASSIGN_AND + byte SYMBOL_OR_EQ + byte EXPRESSION_ASSIGN_OR + byte SYMBOL_XOR_EQ + byte EXPRESSION_ASSIGN_XOR + byte SYMBOL_OR_OR + byte EXPRESSION_LOGICAL_OR + byte SYMBOL_AND_AND + byte EXPRESSION_LOGICAL_AND + byte SYMBOL_OR + byte EXPRESSION_BITWISE_OR + byte SYMBOL_XOR + byte EXPRESSION_BITWISE_XOR + byte SYMBOL_AND + byte EXPRESSION_BITWISE_AND + byte SYMBOL_EQ_EQ + byte EXPRESSION_EQ + byte SYMBOL_NOT_EQ + byte EXPRESSION_NEQ + byte SYMBOL_LT + byte EXPRESSION_LT + byte SYMBOL_GT + byte EXPRESSION_GT + byte SYMBOL_LT_EQ + byte EXPRESSION_LEQ + byte SYMBOL_GT_EQ + byte EXPRESSION_GEQ + byte SYMBOL_LSHIFT + byte EXPRESSION_LSHIFT + byte SYMBOL_RSHIFT + byte EXPRESSION_RSHIFT + byte SYMBOL_PLUS + byte EXPRESSION_ADD + byte SYMBOL_MINUS + byte EXPRESSION_SUB + byte SYMBOL_TIMES + byte EXPRESSION_MUL + byte SYMBOL_DIV + byte EXPRESSION_DIV + byte SYMBOL_PERCENT + byte EXPRESSION_REMAINDER + byte SYMBOL_ARROW + byte EXPRESSION_ARROW + byte SYMBOL_DOT + byte EXPRESSION_DOT + byte SYMBOL_LSQUARE + byte EXPRESSION_SUBSCRIPT + byte 0 + byte 0 + +function binop_symbol_to_expression_type + argument op + local p + p = .binop_table + :binop_symbol_to_expression_type_loop + if *1p == op goto binop_symbol_to_expression_type_found + p += 2 + if *1p != 0 goto binop_symbol_to_expression_type_loop + return 0 + :binop_symbol_to_expression_type_found + p += 1 + return *1p + +function binop_expression_type_to_symbol + argument exprtype + local p + p = .binop_table + :binop_expr2symb_type_loop + p += 1 + if *1p == exprtype goto binop_expr2symb_type_found + p += 1 + if *1p != 0 goto binop_expr2symb_type_loop + return 0 + :binop_expr2symb_type_found + p -= 1 + return *1p + + + function int_suffix_to_type argument suffix if suffix == NUMBER_SUFFIX_L goto return_type_long @@ -258,10 +392,13 @@ function int_value_to_type if value [ 0x8000000000000000 goto return_type_long goto return_type_unsigned_long -function print_expression - argument expression +function print_p_expression + argument p_expression local c + local b local p + local expression + expression = *8p_expression p = expression + 4 putc(40) print_type(*4p) @@ -271,22 +408,42 @@ function print_expression if c == EXPRESSION_CONSTANT_INT goto print_expr_int if c == EXPRESSION_CONSTANT_FLOAT goto print_expr_float if c == EXPRESSION_STRING_LITERAL goto print_expr_str + b = binop_expression_type_to_symbol(c) + if b != 0 goto print_expr_binop byte 0xcc :print_expr_int expression += 8 putn(*8expression) - return + expression += 8 + goto print_p_expression_ret :print_expr_float expression += 8 putx64(*8expression) - return + expression += 8 + goto print_p_expression_ret :print_expr_str expression += 8 putc('0) putc('x) putx32(*8expression) - return - + expression += 8 + goto print_p_expression_ret + :print_expr_binop + expression += 8 + print_p_expression(&expression) ; 1st operand + b = get_keyword_str(b) + puts(b) + print_expression(expression) ; 2nd operand + goto print_p_expression_ret + :print_p_expression_ret + *8p_expression = expression + return + +function print_expression + argument expression + print_p_expression(&expression) + return + ; 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 |