diff options
| author | Zuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian> | 2026-01-24 00:09:29 +0000 |
|---|---|---|
| committer | Zuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian> | 2026-01-24 00:09:29 +0000 |
| commit | 27d041865d17a4055e7e6b3e297656d6f35a0f3b (patch) | |
| tree | 8fe0cbd2fecf24a6da3150dc4a2666a1c6dec0c3 /src | |
| parent | 1991cb62d26b954e54cf13c2d765fb3a0bbaa3ca (diff) | |
Welcome to 'def' + changed 'const'
Diffstat (limited to 'src')
| -rw-r--r-- | src/codegen/codegen.c | 2 | ||||
| -rw-r--r-- | src/lexer/token.c | 4 | ||||
| -rw-r--r-- | src/parser/parser.h | 9 | ||||
| -rw-r--r-- | src/parser/parser_core.c | 10 | ||||
| -rw-r--r-- | src/parser/parser_decl.c | 21 | ||||
| -rw-r--r-- | src/parser/parser_expr.c | 60 | ||||
| -rw-r--r-- | src/parser/parser_stmt.c | 7 | ||||
| -rw-r--r-- | src/zprep.h | 1 |
8 files changed, 80 insertions, 34 deletions
diff --git a/src/codegen/codegen.c b/src/codegen/codegen.c index 95e0ccd..ebbfdb6 100644 --- a/src/codegen/codegen.c +++ b/src/codegen/codegen.c @@ -42,8 +42,6 @@ static void codegen_literal_expr(ASTNode *node, FILE *out) // Emit variable reference expression static void codegen_var_expr(ParserContext *ctx, ASTNode *node, FILE *out) { - (void)ctx; // May be used for context lookup in future - if (g_current_lambda) { for (int i = 0; i < g_current_lambda->lambda.num_captures; i++) diff --git a/src/lexer/token.c b/src/lexer/token.c index ea636b1..decabbe 100644 --- a/src/lexer/token.c +++ b/src/lexer/token.c @@ -145,6 +145,10 @@ Token lexer_next(Lexer *l) { return (Token){TOK_DEFER, s, 5, start_line, start_col}; } + if (len == 3 && strncmp(s, "def", 3) == 0) + { + return (Token){TOK_DEF, s, 3, start_line, start_col}; + } if (len == 8 && strncmp(s, "autofree", 8) == 0) { return (Token){TOK_AUTOFREE, s, 8, start_line, start_col}; diff --git a/src/parser/parser.h b/src/parser/parser.h index 6ac55bf..8857641 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -41,6 +41,7 @@ typedef struct Symbol int is_autofree; Token decl_token; int is_const_value; + int is_def; int const_int_val; int is_moved; struct Symbol *next; @@ -56,14 +57,14 @@ typedef struct Scope typedef struct FuncSig { char *name; - Token decl_token; // For LSP + Token decl_token; int total_args; char **defaults; Type **arg_types; Type *ret_type; int is_varargs; - int is_async; // Async function flag - int must_use; // Attribute: warn if return value discarded + int is_async; + int must_use; struct FuncSig *next; } FuncSig; @@ -438,7 +439,7 @@ ASTNode *parse_defer(ParserContext *ctx, Lexer *l); ASTNode *parse_asm(ParserContext *ctx, Lexer *l); ASTNode *parse_plugin(ParserContext *ctx, Lexer *l); ASTNode *parse_var_decl(ParserContext *ctx, Lexer *l); -ASTNode *parse_const(ParserContext *ctx, Lexer *l); +ASTNode *parse_def(ParserContext *ctx, Lexer *l); ASTNode *parse_type_alias(ParserContext *ctx, Lexer *l); ASTNode *parse_function(ParserContext *ctx, Lexer *l, int is_async); diff --git a/src/parser/parser_core.c b/src/parser/parser_core.c index 464c905..8410203 100644 --- a/src/parser/parser_core.c +++ b/src/parser/parser_core.c @@ -267,6 +267,10 @@ ASTNode *parse_program_nodes(ParserContext *ctx, Lexer *l) s = ast_create(NODE_RAW_STMT); s->raw_stmt.content = content; } + else if (t.type == TOK_DEF) + { + s = parse_def(ctx, l); + } else if (t.type == TOK_IDENT) { // Inline function: inline fn name(...) { } @@ -337,9 +341,13 @@ ASTNode *parse_program_nodes(ParserContext *ctx, Lexer *l) { s = parse_var_decl(ctx, l); } + else if (t.len == 3 && strncmp(t.start, "def", 3) == 0) + { + s = parse_def(ctx, l); + } else if (t.len == 5 && strncmp(t.start, "const", 5) == 0) { - s = parse_const(ctx, l); + zpanic_at(t, "'const' for declarations is deprecated. Use 'def' for constants or 'var x: const T' for read-only variables."); } else if (t.len == 6 && strncmp(t.start, "extern", 6) == 0) { diff --git a/src/parser/parser_decl.c b/src/parser/parser_decl.c index 5cac0b4..87b15ad 100644 --- a/src/parser/parser_decl.c +++ b/src/parser/parser_decl.c @@ -701,9 +701,9 @@ ASTNode *parse_var_decl(ParserContext *ctx, Lexer *l) return n; } -ASTNode *parse_const(ParserContext *ctx, Lexer *l) +ASTNode *parse_def(ParserContext *ctx, Lexer *l) { - lexer_next(l); // eat const + lexer_next(l); // eat def Token n = lexer_next(l); char *type_str = NULL; @@ -723,7 +723,14 @@ ASTNode *parse_const(ParserContext *ctx, Lexer *l) type_obj = type_new(TYPE_UNKNOWN); // Ensure we have an object } type_obj->is_const = 1; + + // Use is_def flag for manifest constants add_symbol(ctx, ns, type_str ? type_str : "unknown", type_obj); + Symbol *sym_entry = find_symbol_entry(ctx, ns); + if (sym_entry) { + sym_entry->is_def = 1; + // is_const_value set only if literal + } ASTNode *i = 0; if (lexer_peek(l).type == TOK_OP && is_token(lexer_peek(l), "=")) @@ -741,6 +748,7 @@ ASTNode *parse_const(ParserContext *ctx, Lexer *l) { s->is_const_value = 1; s->const_int_val = val; + s->is_def = 1; // Double ensure if (!s->type_name || strcmp(s->type_name, "unknown") == 0) { @@ -754,6 +762,7 @@ ASTNode *parse_const(ParserContext *ctx, Lexer *l) free(s->type_info); } s->type_info = type_new(TYPE_INT); + s->type_info->is_const = 1; } } } @@ -771,7 +780,7 @@ ASTNode *parse_const(ParserContext *ctx, Lexer *l) } else { - lexer_next(l); + zpanic_at(n, "'def' constants must be initialized"); } if (lexer_peek(l).type == TOK_SEMICOLON) @@ -783,6 +792,7 @@ ASTNode *parse_const(ParserContext *ctx, Lexer *l) o->var_decl.name = ns; o->var_decl.type_str = type_str; o->var_decl.init_expr = i; + // Store extra metadata if needed, but NODE_CONST usually suffices if (!ctx->current_scope || !ctx->current_scope->parent) { @@ -805,10 +815,7 @@ ASTNode *parse_type_alias(ParserContext *ctx, Lexer *l) char *o = parse_type(ctx, l); - lexer_next(l); // consume ';' (parse_type doesn't consume it? parse_type calls parse_type_formal - // which doesn't consume ;?) - // Note: parse_type_stmt usually expects ; but parse_type just parses type expression. - // Check previous implementation: it had lexer_next(l) at end. This assumes ;. + lexer_next(l); ASTNode *node = ast_create(NODE_TYPE_ALIAS); node->type_alias.alias = xmalloc(n.len + 1); diff --git a/src/parser/parser_expr.c b/src/parser/parser_expr.c index 9251f98..9d21e77 100644 --- a/src/parser/parser_expr.c +++ b/src/parser/parser_expr.c @@ -2327,35 +2327,48 @@ ASTNode *parse_primary(ParserContext *ctx, Lexer *l) } 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); - 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 (sym && sym->is_def && sym->is_const_value) { - node->resolved_type = type_str; - node->var_ref.suggestion = NULL; + // Constant Folding for 'def', emits literal + node = ast_create(NODE_EXPR_LITERAL); + node->token = t; + node->literal.type_kind = 0; // INT (assumed for now from const_int_val) + node->literal.int_val = sym->const_int_val; + node->type_info = type_new(TYPE_INT); + // No need for resolution } else { - node->resolved_type = xstrdup("unknown"); - if (should_suppress_undef_warning(ctx, acc)) + 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); + + if (sym) + { + sym->is_used = 1; + node->definition_token = sym->decl_token; + } + + char *type_str = find_symbol_type(ctx, acc); + + if (type_str) { + node->resolved_type = type_str; node->var_ref.suggestion = NULL; } else { - node->var_ref.suggestion = find_similar_symbol(ctx, acc); + 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); + } } } } @@ -3405,6 +3418,15 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec) lexer_next(l); // consume op ASTNode *operand = parse_expr_prec(ctx, l, PREC_UNARY); + if (is_token(t, "&") && operand->type == NODE_EXPR_VAR) + { + Symbol *s = find_symbol_entry(ctx, operand->var_ref.name); + if (s && s->is_def) + { + zpanic_at(t, "Cannot take address of manifest constant '%s' (use 'var' if you need an address)", operand->var_ref.name); + } + } + char *method = NULL; if (is_token(t, "-")) { diff --git a/src/parser/parser_stmt.c b/src/parser/parser_stmt.c index dfc99db..bc1849d 100644 --- a/src/parser/parser_stmt.c +++ b/src/parser/parser_stmt.c @@ -1869,6 +1869,10 @@ ASTNode *parse_statement(ParserContext *ctx, Lexer *l) { return parse_asm(ctx, l); } + if (tk.type == TOK_DEF) + { + return parse_def(ctx, l); + } // Identifiers (Keywords or Expressions) if (tk.type == TOK_IDENT) @@ -1956,9 +1960,10 @@ ASTNode *parse_statement(ParserContext *ctx, Lexer *l) } zpanic_at(next, "Expected 'var' after 'static'"); } + if (strncmp(tk.start, "const", 5) == 0 && tk.len == 5) { - return parse_const(ctx, l); + zpanic_at(tk, "'const' for declarations is deprecated. Use 'def' for constants or 'var x: const T' for read-only variables."); } if (strncmp(tk.start, "return", 6) == 0 && tk.len == 6) { diff --git a/src/zprep.h b/src/zprep.h index 18c4c51..03c17fc 100644 --- a/src/zprep.h +++ b/src/zprep.h @@ -59,6 +59,7 @@ typedef enum TOK_TEST, TOK_ASSERT, TOK_SIZEOF, + TOK_DEF, TOK_DEFER, TOK_AUTOFREE, TOK_QUESTION, |
