summaryrefslogtreecommitdiff
path: root/src/parser
diff options
context:
space:
mode:
authorsuresh <sureshkrishnan.ai@gmail.com>2026-01-25 11:43:23 -0500
committersuresh <sureshkrishnan.ai@gmail.com>2026-01-25 11:43:23 -0500
commit26a0b55ed5bce4ad0ba2af109cfc96da7be2e34c (patch)
tree35ba8d7742b8ac727bfc6c4c73ab8b70f6eedb53 /src/parser
parent0bb69cb67078dfa921b5b8a42275ef31dfbc9a56 (diff)
parent489336b2101bf16edeec7bfc4379408eb19b936e (diff)
Merge branch 'main' into JsonType
# Conflicts: # examples/data/json_config.zc
Diffstat (limited to 'src/parser')
-rw-r--r--src/parser/parser_core.c42
-rw-r--r--src/parser/parser_stmt.c25
-rw-r--r--src/parser/parser_type.c27
3 files changed, 61 insertions, 33 deletions
diff --git a/src/parser/parser_core.c b/src/parser/parser_core.c
index 3bc6d66..5e685d7 100644
--- a/src/parser/parser_core.c
+++ b/src/parser/parser_core.c
@@ -337,18 +337,18 @@ ASTNode *parse_program_nodes(ParserContext *ctx, Lexer *l)
{
s = parse_import(ctx, l);
}
- else if (t.len == 3 && strncmp(t.start, "var", 3) == 0)
+ else if (t.len == 3 && strncmp(t.start, "let", 3) == 0)
{
s = parse_var_decl(ctx, l);
}
- else if (t.len == 3 && strncmp(t.start, "def", 3) == 0)
+ else if (t.len == 3 && strncmp(t.start, "var", 3) == 0)
{
- s = parse_def(ctx, l);
+ zpanic_at(t, "'var' is deprecated. Use 'let' instead.");
}
else if (t.len == 5 && strncmp(t.start, "const", 5) == 0)
{
zpanic_at(t, "'const' for declarations is deprecated. Use 'def' for constants or "
- "'var x: const T' for read-only variables.");
+ "'let x: const T' for read-only variables.");
}
else if (t.len == 6 && strncmp(t.start, "extern", 6) == 0)
{
@@ -673,23 +673,23 @@ static ASTNode *generate_derive_impls(ParserContext *ctx, ASTNode *strct, char *
// Map types to appropriate get_* calls
if (strcmp(ft, "int") == 0)
{
- sprintf(assign, "var _f_%s = (*j).get_int(\"%s\").unwrap_or(0);\n", fn, fn);
+ sprintf(assign, "let _f_%s = (*j).get_int(\"%s\").unwrap_or(0);\n", fn, fn);
}
else if (strcmp(ft, "double") == 0)
{
- sprintf(assign, "var _f_%s = (*j).get_float(\"%s\").unwrap_or(0.0);\n", fn, fn);
+ sprintf(assign, "let _f_%s = (*j).get_float(\"%s\").unwrap_or(0.0);\n", fn, fn);
}
else if (strcmp(ft, "bool") == 0)
{
- sprintf(assign, "var _f_%s = (*j).get_bool(\"%s\").unwrap_or(false);\n", fn, fn);
+ sprintf(assign, "let _f_%s = (*j).get_bool(\"%s\").unwrap_or(false);\n", fn, fn);
}
else if (strcmp(ft, "char*") == 0)
{
- sprintf(assign, "var _f_%s = (*j).get_string(\"%s\").unwrap_or(\"\");\n", fn, fn);
+ sprintf(assign, "let _f_%s = (*j).get_string(\"%s\").unwrap_or(\"\");\n", fn, fn);
}
else if (strcmp(ft, "String") == 0)
{
- sprintf(assign, "var _f_%s = String::new((*j).get_string(\"%s\").unwrap_or(\"\"));\n", fn, fn);
+ sprintf(assign, "let _f_%s = String::new((*j).get_string(\"%s\").unwrap_or(\"\"));\n", fn, fn);
}
else if (ft && strstr(ft, "Vec") && strstr(ft, "String"))
{
@@ -699,16 +699,16 @@ static ASTNode *generate_derive_impls(ParserContext *ctx, ASTNode *strct, char *
vec_fields[vec_field_count++] = fn;
}
sprintf(assign,
- "var _f_%s = Vec<String>::new();\n"
- "var _arr_%s = (*j).get_array(\"%s\");\n"
+ "let _f_%s = Vec<String>::new();\n"
+ "let _arr_%s = (*j).get_array(\"%s\");\n"
"if _arr_%s.is_some() {\n"
- " var _a_%s = _arr_%s.unwrap();\n"
- " for var _i_%s: usize = 0; _i_%s < _a_%s.len(); _i_%s = _i_%s + 1 {\n"
- " var _item_%s = _a_%s.at(_i_%s);\n"
+ " let _a_%s = _arr_%s.unwrap();\n"
+ " for let _i_%s: usize = 0; _i_%s < _a_%s.len(); _i_%s = _i_%s + 1 {\n"
+ " let _item_%s = _a_%s.at(_i_%s);\n"
" if _item_%s.is_some() {\n"
- " var _str_%s = (*_item_%s.unwrap()).as_string();\n"
+ " let _str_%s = (*_item_%s.unwrap()).as_string();\n"
" if _str_%s.is_some() {\n"
- " var _s_%s = String::new(_str_%s.unwrap());\n"
+ " let _s_%s = String::new(_str_%s.unwrap());\n"
" _f_%s.push(_s_%s); _s_%s.forget();\n"
" }\n"
" }\n"
@@ -720,8 +720,8 @@ static ASTNode *generate_derive_impls(ParserContext *ctx, ASTNode *strct, char *
{
// Nested struct: call NestedType::from_json recursively
sprintf(assign,
- "var _opt_%s = (*j).get(\"%s\");\n"
- "var _f_%s: %s;\n"
+ "let _opt_%s = (*j).get(\"%s\");\n"
+ "let _f_%s: %s;\n"
"if _opt_%s.is_some() { _f_%s = %s::from_json(_opt_%s.unwrap()).unwrap(); }\n",
fn, fn, fn, ft, fn, fn, ft, fn);
}
@@ -786,7 +786,7 @@ static ASTNode *generate_derive_impls(ParserContext *ctx, ASTNode *strct, char *
}
char body[8192];
- strcpy(body, "var _obj = JsonValue::object();\n");
+ strcpy(body, "let _obj = JsonValue::object();\n");
ASTNode *f = strct->strct.fields;
while (f)
@@ -826,8 +826,8 @@ static ASTNode *generate_derive_impls(ParserContext *ctx, ASTNode *strct, char *
else if (ft && strstr(ft, "Vec") && strstr(ft, "String"))
{
sprintf(set_call,
- "var _arr_%s = JsonValue::array();\n"
- "for var _i_%s: usize = 0; _i_%s < self.%s.length(); _i_%s = _i_%s + 1 {\n"
+ "let _arr_%s = JsonValue::array();\n"
+ "for let _i_%s: usize = 0; _i_%s < self.%s.length(); _i_%s = _i_%s + 1 {\n"
" _arr_%s.push(JsonValue::string(self.%s.get(_i_%s).c_str()));\n"
"}\n"
"_obj.set(\"%s\", _arr_%s);\n",
diff --git a/src/parser/parser_stmt.c b/src/parser/parser_stmt.c
index 54e9b88..18146a5 100644
--- a/src/parser/parser_stmt.c
+++ b/src/parser/parser_stmt.c
@@ -1278,10 +1278,14 @@ ASTNode *parse_for(ParserContext *ctx, Lexer *l)
ASTNode *init = NULL;
if (lexer_peek(l).type != TOK_SEMICOLON)
{
- if (lexer_peek(l).type == TOK_IDENT && strncmp(lexer_peek(l).start, "var", 3) == 0)
+ if (lexer_peek(l).type == TOK_IDENT && strncmp(lexer_peek(l).start, "let", 3) == 0)
{
init = parse_var_decl(ctx, l);
}
+ else if (lexer_peek(l).type == TOK_IDENT && strncmp(lexer_peek(l).start, "var", 3) == 0)
+ {
+ zpanic_at(lexer_peek(l), "'var' is deprecated. Use 'let' instead.");
+ }
else
{
init = parse_expression(ctx, l);
@@ -1936,9 +1940,9 @@ ASTNode *parse_statement(ParserContext *ctx, Lexer *l)
if (tk.type == TOK_AUTOFREE)
{
lexer_next(l);
- if (lexer_peek(l).type != TOK_IDENT || strncmp(lexer_peek(l).start, "var", 3) != 0)
+ if (lexer_peek(l).type != TOK_IDENT || strncmp(lexer_peek(l).start, "let", 3) != 0)
{
- zpanic_at(lexer_peek(l), "Expected 'var' after autofree");
+ zpanic_at(lexer_peek(l), "Expected 'let' after autofree");
}
s = parse_var_decl(ctx, l);
s->var_decl.is_autofree = 1;
@@ -2077,28 +2081,33 @@ ASTNode *parse_statement(ParserContext *ctx, Lexer *l)
return parse_plugin(ctx, l);
}
- if (strncmp(tk.start, "var", 3) == 0 && tk.len == 3)
+ if (strncmp(tk.start, "let", 3) == 0 && tk.len == 3)
{
return parse_var_decl(ctx, l);
}
- // Static local variable: static var x = 0;
+ if (strncmp(tk.start, "var", 3) == 0 && tk.len == 3)
+ {
+ zpanic_at(tk, "'var' is deprecated. Use 'let' instead.");
+ }
+
+ // Static local variable: static let x = 0;
if (strncmp(tk.start, "static", 6) == 0 && tk.len == 6)
{
lexer_next(l); // eat 'static'
Token next = lexer_peek(l);
- if (strncmp(next.start, "var", 3) == 0 && next.len == 3)
+ if (strncmp(next.start, "let", 3) == 0 && next.len == 3)
{
ASTNode *v = parse_var_decl(ctx, l);
v->var_decl.is_static = 1;
return v;
}
- zpanic_at(next, "Expected 'var' after 'static'");
+ zpanic_at(next, "Expected 'let' after 'static'");
}
if (strncmp(tk.start, "const", 5) == 0 && tk.len == 5)
{
- zpanic_at(tk, "'const' for declarations is deprecated. Use 'def' for constants or 'var "
+ zpanic_at(tk, "'const' for declarations is deprecated. Use 'def' for constants or 'let "
"x: const T' for read-only variables.");
}
if (strncmp(tk.start, "return", 6) == 0 && tk.len == 6)
diff --git a/src/parser/parser_type.c b/src/parser/parser_type.c
index 5774571..0585baa 100644
--- a/src/parser/parser_type.c
+++ b/src/parser/parser_type.c
@@ -751,14 +751,31 @@ Type *parse_type_formal(ParserContext *ctx, Lexer *l)
}
}
+ Type *t = NULL;
+
// Example: fn(int, int) -> int
if (lexer_peek(l).type == TOK_IDENT && strncmp(lexer_peek(l).start, "fn", 2) == 0 &&
lexer_peek(l).len == 2)
{
lexer_next(l); // eat 'fn'
+
+ int star_count = 0;
+ while (lexer_peek(l).type == TOK_OP && strncmp(lexer_peek(l).start, "*", 1) == 0)
+ {
+ lexer_next(l);
+ star_count++;
+ }
+
Type *fn_type = type_new(TYPE_FUNCTION);
+ fn_type->is_raw = (star_count > 0);
fn_type->is_varargs = 0;
+ Type *wrapped = fn_type;
+ for (int i = 1; i < star_count; i++)
+ {
+ wrapped = type_new_ptr(wrapped);
+ }
+
expect(l, TOK_LPAREN, "Expected '(' for function type");
// Parse Arguments
@@ -794,11 +811,13 @@ Type *parse_type_formal(ParserContext *ctx, Lexer *l)
fn_type->inner = type_new(TYPE_VOID);
}
- return fn_type;
+ t = wrapped;
+ }
+ else
+ {
+ // Handles: int, Struct, Generic<T>, [Slice], (Tuple)
+ t = parse_type_base(ctx, l);
}
-
- // Handles: int, Struct, Generic<T>, [Slice], (Tuple)
- Type *t = parse_type_base(ctx, l);
// Handles: T*, T**, etc.
while (lexer_peek(l).type == TOK_OP && *lexer_peek(l).start == '*')