diff options
Diffstat (limited to 'src/parser/parser_expr.c')
| -rw-r--r-- | src/parser/parser_expr.c | 375 |
1 files changed, 188 insertions, 187 deletions
diff --git a/src/parser/parser_expr.c b/src/parser/parser_expr.c index e12c837..469d623 100644 --- a/src/parser/parser_expr.c +++ b/src/parser/parser_expr.c @@ -1,10 +1,10 @@ +#include "../zen/zen_facts.h" +#include "parser.h" +#include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <ctype.h> -#include "parser.h" -#include "../zen/zen_facts.h" Type *get_field_type(ParserContext *ctx, Type *struct_type, const char *field_name); @@ -1411,7 +1411,8 @@ ASTNode *parse_primary(ParserContext *ctx, Lexer *l) Type *st = type_new(TYPE_STRUCT); st->name = xstrdup(struct_name); node->type_info = st; - return node; // Struct init cannot be called/indexed usually, return early + return node; // Struct init cannot be called/indexed usually, return + // early } } @@ -1456,7 +1457,6 @@ ASTNode *parse_primary(ParserContext *ctx, Lexer *l) else { // readln(vars...) -> _z_scan_helper("fmt", &vars...) - // 1. Build Format String char fmt[256]; fmt[0] = 0; for (int i = 0; i < ac; i++) @@ -1505,14 +1505,12 @@ ASTNode *parse_primary(ParserContext *ctx, Lexer *l) } } - // 2. Build Call Node node = ast_create(NODE_EXPR_CALL); ASTNode *callee = ast_create(NODE_EXPR_VAR); callee->var_ref.name = xstrdup("_z_scan_helper"); node->call.callee = callee; node->type_info = type_new(TYPE_INT); // Returns count - // 3. Build Args List: "fmt" then &arg1, &arg2... ASTNode *fmt_node = ast_create(NODE_EXPR_LITERAL); fmt_node->literal.type_kind = 2; // string fmt_node->literal.string_val = xstrdup(fmt); @@ -1532,218 +1530,216 @@ ASTNode *parse_primary(ParserContext *ctx, Lexer *l) node->call.args = head; } free(acc); - } - else - if (sig && lexer_peek(l).type == TOK_LPAREN) - { - lexer_next(l); - ASTNode *head = NULL, *tail = NULL; - int args_provided = 0; - char **arg_names = NULL; - int has_named = 0; + else if (sig && lexer_peek(l).type == TOK_LPAREN) + { + lexer_next(l); + ASTNode *head = NULL, *tail = NULL; + int args_provided = 0; + char **arg_names = NULL; + int has_named = 0; - if (lexer_peek(l).type != TOK_RPAREN) + if (lexer_peek(l).type != TOK_RPAREN) + { + while (1) { - while (1) - { - char *arg_name = NULL; + char *arg_name = NULL; - Token t1 = lexer_peek(l); - if (t1.type == TOK_IDENT) + Token t1 = lexer_peek(l); + if (t1.type == TOK_IDENT) + { + Token t2 = lexer_peek2(l); + if (t2.type == TOK_COLON) { - Token t2 = lexer_peek2(l); - if (t2.type == TOK_COLON) - { - arg_name = token_strdup(t1); - has_named = 1; - lexer_next(l); - lexer_next(l); - } + arg_name = token_strdup(t1); + has_named = 1; + lexer_next(l); + lexer_next(l); } + } - ASTNode *arg = parse_expression(ctx, l); - if (!head) - { - head = arg; - } - else - { - tail->next = arg; - } - tail = arg; - args_provided++; + ASTNode *arg = parse_expression(ctx, l); + if (!head) + { + head = arg; + } + else + { + tail->next = arg; + } + tail = arg; + args_provided++; - arg_names = xrealloc(arg_names, args_provided * sizeof(char *)); - arg_names[args_provided - 1] = arg_name; + arg_names = xrealloc(arg_names, args_provided * sizeof(char *)); + arg_names[args_provided - 1] = arg_name; - arg_names = xrealloc(arg_names, args_provided * sizeof(char *)); - arg_names[args_provided - 1] = arg_name; + arg_names = xrealloc(arg_names, args_provided * sizeof(char *)); + arg_names[args_provided - 1] = arg_name; - if (lexer_peek(l).type == TOK_COMMA) - { - lexer_next(l); - } - else - { - break; - } + if (lexer_peek(l).type == TOK_COMMA) + { + lexer_next(l); } - } - if (lexer_next(l).type != TOK_RPAREN) - { - zpanic("Expected )"); - } - for (int i = args_provided; i < sig->total_args; i++) - { - if (sig->defaults[i]) + else { - ASTNode *def = ast_create(NODE_RAW_STMT); - def->raw_stmt.content = xstrdup(sig->defaults[i]); - if (!head) - { - head = def; - } - else - { - tail->next = def; - } - tail = def; + break; } } - node = ast_create(NODE_EXPR_CALL); - node->token = t; // Set source token - ASTNode *callee = ast_create(NODE_EXPR_VAR); - callee->var_ref.name = acc; - node->call.callee = callee; - node->call.args = head; - node->call.arg_names = has_named ? arg_names : NULL; - node->call.arg_count = args_provided; - if (sig) - { - node->definition_token = sig->decl_token; - } - if (sig->is_async) - { - Type *async_type = type_new(TYPE_STRUCT); - async_type->name = xstrdup("Async"); - node->type_info = async_type; - node->resolved_type = xstrdup("Async"); - } - else if (sig->ret_type) - { - node->type_info = sig->ret_type; - node->resolved_type = type_to_string(sig->ret_type); - } - else + } + if (lexer_next(l).type != TOK_RPAREN) + { + zpanic("Expected )"); + } + for (int i = args_provided; i < sig->total_args; i++) + { + if (sig->defaults[i]) { - node->resolved_type = xstrdup("void"); + ASTNode *def = ast_create(NODE_RAW_STMT); + def->raw_stmt.content = xstrdup(sig->defaults[i]); + if (!head) + { + head = def; + } + else + { + tail->next = def; + } + tail = def; } } - else if (!sig && !find_symbol_entry(ctx, acc) && lexer_peek(l).type == TOK_LPAREN) + node = ast_create(NODE_EXPR_CALL); + node->token = t; // Set source token + ASTNode *callee = ast_create(NODE_EXPR_VAR); + callee->var_ref.name = acc; + node->call.callee = callee; + node->call.args = head; + node->call.arg_names = has_named ? arg_names : NULL; + node->call.arg_count = args_provided; + if (sig) { - lexer_next(l); // eat ( - ASTNode *head = NULL, *tail = NULL; - char **arg_names = NULL; - int args_provided = 0; - int has_named = 0; + node->definition_token = sig->decl_token; + } + if (sig->is_async) + { + Type *async_type = type_new(TYPE_STRUCT); + async_type->name = xstrdup("Async"); + node->type_info = async_type; + node->resolved_type = xstrdup("Async"); + } + else if (sig->ret_type) + { + node->type_info = sig->ret_type; + node->resolved_type = type_to_string(sig->ret_type); + } + else + { + node->resolved_type = xstrdup("void"); + } + } + else if (!sig && !find_symbol_entry(ctx, acc) && lexer_peek(l).type == TOK_LPAREN) + { + lexer_next(l); // eat ( + ASTNode *head = NULL, *tail = NULL; + char **arg_names = NULL; + int args_provided = 0; + int has_named = 0; - if (lexer_peek(l).type != TOK_RPAREN) + if (lexer_peek(l).type != TOK_RPAREN) + { + while (1) { - while (1) - { - char *arg_name = NULL; + char *arg_name = NULL; - // Check for named argument: name: value - Token t1 = lexer_peek(l); - if (t1.type == TOK_IDENT) + // Check for named argument: name: value + Token t1 = lexer_peek(l); + if (t1.type == TOK_IDENT) + { + Token t2 = lexer_peek2(l); + if (t2.type == TOK_COLON) { - Token t2 = lexer_peek2(l); - if (t2.type == TOK_COLON) - { - arg_name = token_strdup(t1); - has_named = 1; - lexer_next(l); - lexer_next(l); - } + arg_name = token_strdup(t1); + has_named = 1; + lexer_next(l); + lexer_next(l); } + } - ASTNode *arg = parse_expression(ctx, l); - if (!head) - { - head = arg; - } - else - { - tail->next = arg; - } - tail = arg; - args_provided++; + ASTNode *arg = parse_expression(ctx, l); + if (!head) + { + head = arg; + } + else + { + tail->next = arg; + } + tail = arg; + args_provided++; - arg_names = xrealloc(arg_names, args_provided * sizeof(char *)); - arg_names[args_provided - 1] = arg_name; + arg_names = xrealloc(arg_names, args_provided * sizeof(char *)); + arg_names[args_provided - 1] = arg_name; - if (lexer_peek(l).type == TOK_COMMA) - { - lexer_next(l); - } - else - { - break; - } + if (lexer_peek(l).type == TOK_COMMA) + { + lexer_next(l); + } + else + { + break; } } - if (lexer_next(l).type != TOK_RPAREN) - { - zpanic("Expected )"); - } - - node = ast_create(NODE_EXPR_CALL); - node->token = t; - ASTNode *callee = ast_create(NODE_EXPR_VAR); - callee->var_ref.name = acc; - node->call.callee = callee; - node->call.args = head; - node->call.arg_names = has_named ? arg_names : NULL; - node->call.arg_count = args_provided; - // Unknown return type - let codegen infer it - node->resolved_type = xstrdup("unknown"); - // Fall through to Postfix } - else + if (lexer_next(l).type != TOK_RPAREN) { - node = ast_create(NODE_EXPR_VAR); - node->token = t; // Set source token - node->var_ref.name = acc; - node->type_info = find_symbol_type_info(ctx, acc); + zpanic("Expected )"); + } - Symbol *sym = find_symbol_entry(ctx, acc); - if (sym) - { - sym->is_used = 1; - node->definition_token = sym->decl_token; - } + node = ast_create(NODE_EXPR_CALL); + node->token = t; + ASTNode *callee = ast_create(NODE_EXPR_VAR); + callee->var_ref.name = acc; + node->call.callee = callee; + node->call.args = head; + node->call.arg_names = has_named ? arg_names : NULL; + node->call.arg_count = args_provided; + // Unknown return type - let codegen infer it + node->resolved_type = xstrdup("unknown"); + // Fall through to Postfix + } + else + { + node = ast_create(NODE_EXPR_VAR); + node->token = t; // Set source token + node->var_ref.name = acc; + node->type_info = find_symbol_type_info(ctx, acc); - char *type_str = find_symbol_type(ctx, acc); + Symbol *sym = find_symbol_entry(ctx, acc); + if (sym) + { + sym->is_used = 1; + node->definition_token = sym->decl_token; + } + + char *type_str = find_symbol_type(ctx, acc); - if (type_str) + if (type_str) + { + node->resolved_type = type_str; + node->var_ref.suggestion = NULL; + } + else + { + node->resolved_type = xstrdup("unknown"); + if (should_suppress_undef_warning(ctx, acc)) { - node->resolved_type = type_str; node->var_ref.suggestion = NULL; } else { - node->resolved_type = xstrdup("unknown"); - if (should_suppress_undef_warning(ctx, acc)) - { - node->var_ref.suggestion = NULL; - } - else - { - node->var_ref.suggestion = find_similar_symbol(ctx, acc); - } + node->var_ref.suggestion = find_similar_symbol(ctx, acc); } } + } } else if (t.type == TOK_LPAREN) @@ -2421,7 +2417,8 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec) lhs = ast_create(NODE_AWAIT); lhs->unary.operand = operand; // Type inference: await Async<T> yields T - // If operand is a call to an async function, look up its ret_type (not Async) + // If operand is a call to an async function, look up its ret_type (not + // Async) if (operand->type == NODE_EXPR_CALL && operand->call.callee->type == NODE_EXPR_VAR) { FuncSig *sig = find_func(ctx, operand->call.callee->var_ref.name); @@ -2924,8 +2921,9 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec) // Clean up string for registration (e.g. "int" from "int*") char *inner_str = type_to_string(inner); - // Strip * if it somehow managed to keep one, though parse_type_formal - // should handle it For now assume type_to_string gives base type + // Strip * if it somehow managed to keep one, though + // parse_type_formal should handle it For now assume type_to_string + // gives base type register_slice(ctx, inner_str); } } @@ -3050,7 +3048,8 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec) FuncSig *sig = find_func(ctx, mangled); if (sig) { - // It is a method! Create a Function Type Info to carry the return type + // It is a method! Create a Function Type Info to carry the return + // type Type *ft = type_new(TYPE_FUNCTION); ft->name = xstrdup(mangled); ft->inner = sig->ret_type; // Return type @@ -3164,7 +3163,7 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec) } } } - + if (strcmp(bin->binary.op, "=") == 0 || strcmp(bin->binary.op, "+=") == 0 || strcmp(bin->binary.op, "-=") == 0 || strcmp(bin->binary.op, "*=") == 0 || strcmp(bin->binary.op, "/=") == 0) @@ -3183,13 +3182,14 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec) if (!is_var_mutable(ctx, lhs->var_ref.name)) { zpanic_at(op, - "Cannot assign to immutable variable '%s' (use 'var mut' to make it " + "Cannot assign to immutable variable '%s' (use 'var mut' " + "to make it " "mutable)", lhs->var_ref.name); } } } - + int is_compound = 0; size_t op_len = strlen(bin->binary.op); @@ -3318,7 +3318,8 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec) set_callee->var_ref.name = set_name; set_call->call.callee = set_callee; - // Clone argument list (Shallow copy of arg nodes to preserve chain for get) + // Clone argument list (Shallow copy of arg nodes to preserve chain + // for get) ASTNode *lhs_args = lhs->call.args; ASTNode *new_head = NULL; ASTNode *new_tail = NULL; |
