Files
corelang/parse_expr.c
2022-05-02 09:49:22 +02:00

286 lines
7.0 KiB
C

function Expr* parse_expr(Parser* p);
function Expr* parse_list_expr(Parser* p);
function Expr*
parse_atom_expr(Parser* p){
Expr* result = 0;
if (token_is(p, TK_Identifier) ||
token_is(p, TK_StringLit) ||
token_is(p, TK_U8Lit) ||
token_is(p, TK_Int)){
result = expr_atom(p, token_next(p));
}
else if (token_match(p, TK_OpenParen)){
result = parse_list_expr(p);
token_expect(p, TK_CloseParen);
}
else {
parser_push_error(p, token_next(p), "Invalid expression token");
}
return result;
}
function Expr*
parse_postfix_expr(Parser* p){
Expr* result = parse_atom_expr(p);
while (token_is(p, TK_Dot)
|| token_is(p, TK_Arrow)
|| token_is(p, TK_DoubleColon)
|| token_is(p, TK_OpenParen)
|| token_is(p, TK_OpenBracket)
|| token_is(p, TK_Decrement)
|| token_is(p, TK_Increment)){
Token *op = token_get(p);
if (token_match(p, TK_Arrow)
|| token_match(p, TK_DoubleColon)
|| token_match(p, TK_Dot)){
Expr* r = parse_atom_expr(p);
result = expr_binary(p, op, result, r);
}
else if (token_match(p, TK_OpenParen)){
Expr* list = 0;
if (!token_match(p, TK_CloseParen)){
list = parse_list_expr(p);
token_expect(p, TK_CloseParen);
}
result = expr_call(p, op, result, list);
}
else if (token_match(p, TK_OpenBracket)){
Expr* list = 0;
if (!token_match(p, TK_CloseBracket)){
list = parse_list_expr(p);
token_match(p, TK_CloseBracket);
}
result = expr_index(p, op, result, list);
}
else {
assert(op->kind == TK_Increment || op->kind == TK_Decrement);
token_next(p);
if (op->kind == TK_Increment) op->kind = TK_PostIncrement;
else if (op->kind == TK_Decrement) op->kind = TK_PostDecrement;
result = expr_unary(p, op, result);
}
}
return result;
}
function
Expr* parse_unary_expr(Parser* p) {
Expr* result = 0;
if (token_is(p, TK_Sub)
|| token_is(p, TK_Add)
|| token_is(p, TK_Mul)
|| token_is(p, TK_BitAnd)
|| token_is(p, TK_Not)
|| token_is(p, TK_Neg)
|| token_is(p, TK_Increment)
|| token_is(p, TK_Decrement)) {
Token *op = token_next(p);
result = parse_unary_expr(p);
result = expr_unary(p, op, result);
}
else if (token_is_keyword(p, keyword_sizeof)) {
Token *token = token_next(p);
result = parse_unary_expr(p);
result = expr_unary(p, token, result);
}
/*
else if (token_is(p, TK_OpenParen)) { // cast requires lookahead
Token *token = token_peek(p, 1);
if (token->kind == TK_Identifier) {
AST_Node *type = symbol_lookup_type(p, token->intern_val);
if(type){
token_next(p);
token_next(p);
// @Todo(Krzosa): Parse pointer types
token_expect(p, TK_CloseParen);
result = parse_unary_expr(p);
result = expr_cast(p, token, type, result);
}
else {
result = parse_postfix_expr(p);
}
}
else {
result = parse_postfix_expr(p);
}
}
*/
else {
result = parse_postfix_expr(p);
}
return result;
}
function
Expr* parse_mul_expr(Parser* p) {
Expr* result = parse_unary_expr(p);
while (token_is(p, TK_Mul)
|| token_is(p, TK_Div)
|| token_is(p, TK_Mod)) {
Token *op = token_next(p);
Expr* r = parse_unary_expr(p);
result = expr_binary(p, op, result, r);
}
return result;
}
function
Expr* parse_add_expr(Parser* p) {
Expr* result = parse_mul_expr(p);
while (token_is(p, TK_Add)
|| token_is(p, TK_Sub)) {
Token *op = token_next(p);
Expr* right = parse_mul_expr(p);
result = expr_binary(p, op, result, right);
}
return result;
}
function
Expr* parse_shift_expr(Parser* p) {
Expr* result = parse_add_expr(p);
while (token_is(p, TK_RightShift)
|| token_is(p, TK_LeftShift)) {
Token *op = token_next(p);
Expr* r = parse_add_expr(p);
result = expr_binary(p, op, result, r);
}
return result;
}
function
Expr* parse_compare_expr(Parser* p) {
Expr* result = parse_shift_expr(p);
while (token_is(p, TK_LesserThen)
|| token_is(p, TK_GreaterThen)
|| token_is(p, TK_LesserThenOrEqual)
|| token_is(p, TK_GreaterThenOrEqual)) {
Token *op = token_next(p);
Expr* r = parse_shift_expr(p);
result = expr_binary(p, op, result, r);
}
return result;
}
function
Expr* parse_equality_expr(Parser* p) {
Expr* result = parse_compare_expr(p);
while (token_is(p, TK_Equals)
|| token_is(p, TK_NotEquals)) {
Token *op = token_next(p);
Expr* r = parse_compare_expr(p);
result = expr_binary(p, op, result, r);
}
return result;
}
function
Expr* parse_bit_and_expr(Parser* p) {
Expr* result = parse_equality_expr(p);
while (token_is(p, TK_BitAnd)) {
Token *op = token_next(p);
Expr* r = parse_equality_expr(p);
result = expr_binary(p, op, result, r);
}
return result;
}
function
Expr* parse_bit_xor_expr(Parser* p) {
Expr* result = parse_bit_and_expr(p);
while (token_is(p, TK_BitXor)) {
Token *op = token_next(p);
Expr* r = parse_bit_and_expr(p);
result = expr_binary(p, op, result, r);
}
return result;
}
function
Expr* parse_bit_or_expr(Parser* p) {
Expr* result = parse_bit_xor_expr(p);
while (token_is(p, TK_BitOr)) {
Token *op = token_next(p);
Expr* r = parse_bit_xor_expr(p);
result = expr_binary(p, op, result, r);
}
return result;
}
function
Expr* parse_and_expr(Parser* p) {
Expr* result = parse_bit_or_expr(p);
while (token_is(p, TK_And)) {
Token *op = token_next(p);
Expr* r = parse_bit_or_expr(p);
result = expr_binary(p, op, result, r);
}
return result;
}
function
Expr* parse_or_expr(Parser* p) {
Expr* result = parse_and_expr(p);
while (token_is(p, TK_Or)) {
Token *op = token_next(p);
Expr* r = parse_and_expr(p);
result = expr_binary(p, op, result, r);
}
return result;
}
function
Expr* parse_ternary_expr(Parser* p) {
Expr* result = parse_or_expr(p);
if (token_is(p, TK_Question)) {
Token *token = token_next(p);
Expr* on_true = parse_ternary_expr(p);
token_expect(p, TK_Colon);
Expr* on_false = parse_ternary_expr(p);
result = expr_ternary(p, token, result, on_true, on_false);
}
return result;
}
function
Expr* parse_assign_expr(Parser* p) {
Expr* result = parse_ternary_expr(p);
if (token_is_assignment(p)) {
Token *op = token_next(p);
Expr* right = parse_assign_expr(p);
result = expr_binary(p, op, result, right);
}
return result;
}
function
Expr* parse_list_expr(Parser* p) {
Expr* result = parse_assign_expr(p);
if (token_is(p, TK_Comma)) {
Expr *list = expr_list(p, token_get(p));
expr_list_push(list, result);
result = list;
}
while (token_is(p, TK_Comma)) {
Token *token = token_next(p);
Expr* expr = parse_assign_expr(p);
expr_list_push(result, expr);
}
return result;
}
function Expr*
parse_expr(Parser* p) {
return parse_assign_expr(p);
}