} Parser;
Parser make_parser(Tokens tokens);
-bool parser_match_token(Parser *p, const Token_type t);
+bool parser_match(Parser *p, const Token_type t);
bool parser_check_token(Parser *p, const Token_type t);
Token parser_advance(Parser *p);
Token parser_previous(Parser *p);
} break;
case EXPR_UNARY: {
- ASSERT(false, "UNIMPLEMENTED!");
+ fprintf(f, " %s ", token_type_as_str(e.unary_expr->operator.type));
+ fprintf(f, "(");
+ print_expression_as_value(f, *e.unary_expr->operand);
+ fprintf(f, ")");
} break;
case EXPR_PRIMARY: {
print_primary_expression(f, e.prim_expr);
* v
* HIGH
*
- * NAME | OP | ASSOCIATE
- * -------------+----------------+-----------
- * Equality | == != | Left
- * -------------+----------------+-----------
- * Comparision | > >= < <= | Left
- * -------------+----------------+-----------
- * Term | - + | Left
- * -------------+----------------+-----------
- * Factor | / * | Left
- * -------------+----------------+-----------
- * Unary | ! - | Right
- * -------------+----------------+-----------
- * Primary | NUMBERS (expr) | -
+ * NAME | OP | ASSOCIATE
+ * -------------+-----------------------+-----------
+ * Equality | == != | Left
+ * -------------+-----------------------+-----------
+ * Comparision | > >= < <= | Left
+ * -------------+-----------------------+-----------
+ * Term | - + | Left
+ * -------------+-----------------------+-----------
+ * Factor | / * | Left
+ * -------------+-----------------------+-----------
+ * Unary | ! - | Right
+ * -------------+-----------------------+-----------
+ * Primary | IDENTS NUMBERS (expr) | -
*
*/
case TK_STRING: return "STRING";
case TK_BOOL: return "BOOL";
case TK_NULL: return "NULL";
- case TK_LEFT_PAREN: return "LEFT_PAREN";
- case TK_RIGHT_PAREN: return "RIGHT_PAREN";
- case TK_MINUS: return "MINUS";
- case TK_MINUS_MINUS: return "MINUS_MINUS";
- case TK_MINUS_EQUAL: return "MINUS_EQUAL";
- case TK_PLUS: return "PLUS";
- case TK_PLUS_PLUS: return "PLUS_PLUS";
- case TK_PLUS_EQUAL: return "PLUS_EQUAL";
- case TK_RETURNER: return "RETURNER";
- case TK_LEFT_BRACE: return "LEFT_BRACE";
- case TK_RIGHT_BRACE: return "RIGHT_BRACE";
+ case TK_LEFT_PAREN: return "(";
+ case TK_RIGHT_PAREN: return ")";
+ case TK_MINUS: return "-";
+ case TK_MINUS_MINUS: return "--";
+ case TK_MINUS_EQUAL: return "-=";
+ case TK_PLUS: return "+";
+ case TK_PLUS_PLUS: return "++";
+ case TK_PLUS_EQUAL: return "+=";
+ case TK_RETURNER: return "->";
+ case TK_LEFT_BRACE: return "{";
+ case TK_RIGHT_BRACE: return "}";
case TK_DIVIDE: return "/";
- case TK_DIVIDE_EQUAL: return "DIVIDE_EQUAL";
+ case TK_DIVIDE_EQUAL: return "/=";
case TK_MULTIPLY: return "*";
- case TK_MULTIPLY_EQUAL: return "MULTIPLY_EQUAL";
- case TK_MODULUS: return "MODULUS";
- case TK_MODULUS_EQUAL: return "MODULUS_EQUAL";
- case TK_POWER: return "POWER";
- case TK_EQUAL: return "EQUAL";
- case TK_NOT: return "NOT";
- case TK_NOT_EQUAL: return "NOT_EQUAL";
- case TK_EQUAL_EQUAL: return "EQUAL_EQUAL";
- case TK_GT: return "GT";
- case TK_LT: return "LT";
- case TK_GTE: return "GTE";
- case TK_LTE: return "LTE";
- case TK_COMMA: return "COMMA";
- case TK_COLON: return "COLON";
- case TK_SEMICOLON: return "SEMICOLON";
- case TK_DOT: return "DOT";
- case TK_HASH: return "HASH";
- case TK_LEFT_SQUARE_BRACE: return "LEFT_SQUARE_BRACE";
- case TK_RIGHT_SQUARE_BRACE: return "RIGHT_SQUARE_BRACE";
+ case TK_MULTIPLY_EQUAL: return "*=";
+ case TK_MODULUS: return "%";
+ case TK_MODULUS_EQUAL: return "%=";
+ case TK_POWER: return "**";
+ case TK_EQUAL: return "=";
+ case TK_NOT: return "!";
+ case TK_NOT_EQUAL: return "!=";
+ case TK_EQUAL_EQUAL: return "==";
+ case TK_GT: return ">";
+ case TK_LT: return "<";
+ case TK_GTE: return ">=";
+ case TK_LTE: return "<=";
+ case TK_COMMA: return ",";
+ case TK_COLON: return ":";
+ case TK_SEMICOLON: return ";";
+ case TK_DOT: return ".";
+ case TK_HASH: return "#";
+ case TK_LEFT_SQUARE_BRACE: return "[";
+ case TK_RIGHT_SQUARE_BRACE: return "]";
case TK_INT: return "INT";
case TK_FLOAT: return "FLOAT";
- case TK_BITWISE_AND: return "BITWISE_AND";
- case TK_BITWISE_AND_EQUAL: return "BITWISE_AND_EQUAL";
- case TK_BITWISE_NOT: return "BITWISE_NOT";
- case TK_BITWISE_OR: return "BITWISE_OR";
- case TK_BITWISE_OR_EQUAL: return "BITWISE_OR_EQUAL";
- case TK_BITWISE_XOR: return "BITWISE_XOR";
- case TK_BITWISE_XOR_EQUAL: return "BITWISE_XOR_EQUAL";
- case TK_BITWISE_SHIFT_LEFT: return "BITWISE_SHIFT_LEFT";
- case TK_BITWISE_SHIFT_RIGHT: return "BITWISE_SHIFT_RIGHT";
- case TK_LOGICAL_AND: return "LOGICAL_AND";
- case TK_LOGICAL_OR: return "LOGICAL_OR";
+ case TK_BITWISE_AND: return "&";
+ case TK_BITWISE_AND_EQUAL: return "&=";
+ case TK_BITWISE_NOT: return "~";
+ case TK_BITWISE_OR: return "|";
+ case TK_BITWISE_OR_EQUAL: return "|=";
+ case TK_BITWISE_XOR: return "^";
+ case TK_BITWISE_XOR_EQUAL: return "^=";
+ case TK_BITWISE_SHIFT_LEFT: return "<<";
+ case TK_BITWISE_SHIFT_RIGHT: return ">>";
+ case TK_LOGICAL_AND: return "&&";
+ case TK_LOGICAL_OR: return "||";
case TK_EOF: return "EOF";
case TK_COUNT:
default: {
fprintf(f, " [%s] '"SV_FMT"'", token_type_as_str(t.type), SV_ARG(t.lexeme));
}
-bool parser_match_token(Parser *p, const Token_type t) {
+bool parser_match(Parser *p, const Token_type t) {
if (parser_check_token(p, t)) {
parser_advance(p);
return true;
ASSERT(false, "UNIMPLEMENTED");
} else if (t.type == TK_LEFT_PAREN) {
/*parser_advance(p); // Skip (*/
- Expression *expr = factor(arena, p);
+ Expression *expr = expression(arena, p);
parser_advance(p); // Skip )
return expr;
}
Expression *unary(Arena *arena, Parser *p) {
Token t = parser_peek(p);
- Expression *expr = (Expression *)arena_alloc(arena, sizeof(Expression));
- expr->loc = t.loc;
- expr->unary_expr = (Unary_expression *)arena_alloc(arena, sizeof(Unary_expression));
-
if (t.type == TK_NOT || t.type == TK_MINUS) {
+ Expression *expr = (Expression *)arena_alloc(arena, sizeof(Expression));
+ expr->loc = t.loc;
+ expr->unary_expr = (Unary_expression *)arena_alloc(arena, sizeof(Unary_expression));
expr->kind = EXPR_UNARY;
Unary_expression *unary_expr = expr->unary_expr;
unary_expr->operator = parser_advance(p);
Expression *factor(Arena *arena, Parser *p) {
Expression *expr = unary(arena, p);
- while (parser_match_token(p, TK_DIVIDE) || parser_match_token(p, TK_MULTIPLY)) {
+ while (parser_match(p, TK_DIVIDE) || parser_match(p, TK_MULTIPLY)) {
Token op = parser_previous(p);
Expression *rhs = unary(arena, p);
}
Expression *term(Arena *arena, Parser *p) {
- Tokens tokens = p->tokens;
- Token t = da_shift(tokens);
-
- Expression *expr = (Expression *)arena_alloc(arena, sizeof(Expression));
- expr->loc = t.loc;
- expr->bin_expr = (Binary_expression *)arena_alloc(arena, sizeof(Binary_expression));
-
- if (t.type == TK_MINUS || t.type == TK_PLUS) {
- expr->bin_expr->operator = t;
- // TODO: Somehow i need to get the last expression parsed.
- // bin_expr->lhs =
- expr->bin_expr->rhs = expression(arena, p);
- return expr;
+ Expression *expr = factor(arena, p);
+
+ while (parser_match(p, TK_MINUS) || parser_match(p, TK_PLUS)) {
+ Token operator = parser_previous(p);
+
+ Expression *rhs = factor(arena, p);
+
+ Expression *new_expr = (Expression *)arena_alloc(arena, sizeof(Expression));
+ new_expr->kind = EXPR_BINARY;
+ new_expr->loc = expr->loc;
+ new_expr->bin_expr = (Binary_expression *)arena_alloc(arena, sizeof(Binary_expression));
+ new_expr->bin_expr->lhs = expr;
+ new_expr->bin_expr->operator = operator;
+ new_expr->bin_expr->rhs = rhs;
+
+ expr = new_expr;
}
- return factor(arena, p);
+ return expr;
}
Expression *comparision(Arena *arena, Parser *p) {
- Tokens tokens = p->tokens;
- Token t = da_shift(tokens);
-
- Expression *expr = (Expression *)arena_alloc(arena, sizeof(Expression));
- expr->loc = t.loc;
- expr->bin_expr = (Binary_expression *)arena_alloc(arena, sizeof(Binary_expression));
-
- if (t.type == TK_GT || t.type == TK_GTE ||
- t.type == TK_LT || t.type == TK_LTE) {
- expr->bin_expr->operator = t;
- // TODO: Somehow i need to get the last expression parsed.
- // bin_expr->lhs =
- expr->bin_expr->rhs = expression(arena, p);
- return expr;
+ Expression *expr = term(arena, p);
+
+ while (parser_match(p, TK_GT) || parser_match(p, TK_GTE) ||
+ parser_match(p, TK_LT) || parser_match(p, TK_LTE)) {
+ Token operator = parser_previous(p);
+
+ Expression *rhs = term(arena, p);
+
+ Expression *new_expr = (Expression *)arena_alloc(arena, sizeof(Expression));
+ new_expr->kind = EXPR_BINARY;
+ new_expr->loc = expr->loc;
+ new_expr->bin_expr = (Binary_expression *)arena_alloc(arena, sizeof(Binary_expression));
+ new_expr->bin_expr->lhs = expr;
+ new_expr->bin_expr->operator = operator;
+ new_expr->bin_expr->rhs = rhs;
+
+ expr = new_expr;
}
- return term(arena, p);
+ return expr;
}
Expression *equality(Arena *arena, Parser *p) {
- Tokens tokens = p->tokens;
- Token t = da_shift(tokens);
+ Expression *expr = comparision(arena, p);
- Expression *expr = (Expression *)arena_alloc(arena, sizeof(Expression));
- expr->loc = t.loc;
- expr->bin_expr = (Binary_expression *)arena_alloc(arena, sizeof(Binary_expression));
+ while (parser_match(p, TK_NOT_EQUAL) || parser_match(p, TK_EQUAL_EQUAL)) {
+ Token operator = parser_previous(p);
- if (t.type == TK_EQUAL_EQUAL || t.type == TK_NOT_EQUAL) {
- expr->bin_expr->operator = t;
- // TODO: Somehow i need to get the last expression parsed.
- // bin_expr->lhs =
- expr->bin_expr->rhs = expression(arena, p);
+ Expression *rhs = comparision(arena, p);
- return expr;
+ Expression *new_expr = (Expression *)arena_alloc(arena, sizeof(Expression));
+ new_expr->kind = EXPR_BINARY;
+ new_expr->loc = expr->loc;
+ new_expr->bin_expr = (Binary_expression *)arena_alloc(arena, sizeof(Binary_expression));
+ new_expr->bin_expr->lhs = expr;
+ new_expr->bin_expr->operator = operator;
+ new_expr->bin_expr->rhs = rhs;
+
+ expr = new_expr;
}
- return comparision(arena, p);
+ return expr;
}
Expression *expression(Arena *arena, Parser *p) {
Arena expr_arena = arena_make(0);
- Expression *expr = factor(&expr_arena, &p);
+ Expression *expr = expression(&expr_arena, &p);
print_expression(stdout, *expr); printf("\n");