summaryrefslogtreecommitdiff
path: root/src/parser
diff options
context:
space:
mode:
authorZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-11 22:51:29 +0000
committerZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-11 22:51:29 +0000
commit45feb20bf55c16ee415ef31a356ada67e1df18d6 (patch)
treeadfd5b4c5641dc5bdfac96f330553140ee90319b /src/parser
parent36938b584ea2d096d97a124b70da51f685850ff7 (diff)
Some more, and some fixes
Diffstat (limited to 'src/parser')
-rw-r--r--src/parser/parser_expr.c42
-rw-r--r--src/parser/parser_stmt.c23
-rw-r--r--src/parser/parser_utils.c5
3 files changed, 55 insertions, 15 deletions
diff --git a/src/parser/parser_expr.c b/src/parser/parser_expr.c
index 469d623..b451a26 100644
--- a/src/parser/parser_expr.c
+++ b/src/parser/parser_expr.c
@@ -245,6 +245,16 @@ Precedence get_token_precedence(Token t)
return PREC_OR;
}
+ if (t.type == TOK_OR)
+ {
+ return PREC_OR;
+ }
+
+ if (t.type == TOK_AND)
+ {
+ return PREC_AND;
+ }
+
if (t.type == TOK_QQ_EQ)
{
return PREC_ASSIGNMENT;
@@ -1247,6 +1257,7 @@ ASTNode *parse_primary(ParserContext *ctx, Lexer *l)
free(acc);
acc = tmp;
}
+
else
{
char *tmp = xmalloc(strlen(mod->base_name) + suffix.len + 2);
@@ -3096,6 +3107,14 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec)
{
bin->binary.op = xstrdup(">");
}
+ else if (op.type == TOK_AND)
+ {
+ bin->binary.op = xstrdup("&&");
+ }
+ else if (op.type == TOK_OR)
+ {
+ bin->binary.op = xstrdup("||");
+ }
else
{
bin->binary.op = token_strdup(op);
@@ -3465,6 +3484,27 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec)
char *t2 = type_to_string(rhs->type_info);
// Skip type check if either operand is void* (escape hatch type)
int skip_check = (strcmp(t1, "void*") == 0 || strcmp(t2, "void*") == 0);
+
+ // Allow comparing pointers/strings with integer literal 0 (NULL)
+ if (!skip_check)
+ {
+ int lhs_is_ptr =
+ (lhs->type_info->kind == TYPE_POINTER ||
+ lhs->type_info->kind == TYPE_STRING || (t1 && strstr(t1, "*")));
+ int rhs_is_ptr =
+ (rhs->type_info->kind == TYPE_POINTER ||
+ rhs->type_info->kind == TYPE_STRING || (t2 && strstr(t2, "*")));
+
+ if (lhs_is_ptr && rhs->type == NODE_EXPR_LITERAL && rhs->literal.int_val == 0)
+ {
+ skip_check = 1;
+ }
+ if (rhs_is_ptr && lhs->type == NODE_EXPR_LITERAL && lhs->literal.int_val == 0)
+ {
+ skip_check = 1;
+ }
+ }
+
if (!skip_check && !type_eq(lhs->type_info, rhs->type_info))
{
char msg[256];
@@ -3493,8 +3533,10 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec)
if (strcmp(bin->binary.op, "+") == 0 || strcmp(bin->binary.op, "-") == 0)
{
int lhs_is_ptr = (lhs->type_info->kind == TYPE_POINTER ||
+ lhs->type_info->kind == TYPE_STRING ||
(t1 && strstr(t1, "*") != NULL));
int rhs_is_ptr = (rhs->type_info->kind == TYPE_POINTER ||
+ rhs->type_info->kind == TYPE_STRING ||
(t2 && strstr(t2, "*") != NULL));
int lhs_is_int =
(lhs->type_info->kind == TYPE_INT || lhs->type_info->kind == TYPE_I32 ||
diff --git a/src/parser/parser_stmt.c b/src/parser/parser_stmt.c
index 30c9e90..1b8637e 100644
--- a/src/parser/parser_stmt.c
+++ b/src/parser/parser_stmt.c
@@ -1168,10 +1168,6 @@ ASTNode *parse_var_decl(ParserContext *ctx, Lexer *l)
type_obj = type_new(TYPE_STRUCT);
type_obj->name = xstrdup(type);
}
-
- // fprintf(stderr, "DEBUG PVarDecl: Var '%s' inferred type '%s'
- // (init->type_info present: %d)\n", name, type, init && init->type_info ?
- // 1 : 0);
}
}
@@ -1553,21 +1549,18 @@ ASTNode *parse_for(ParserContext *ctx, Lexer *l)
if (in_tok.type == TOK_IDENT && strncmp(in_tok.start, "in", 2) == 0)
{
- Token start_tok = lexer_next(l);
- if (lexer_next(l).type == TOK_DOTDOT)
+ ASTNode *start_expr = parse_expression(ctx, l);
+ if (lexer_peek(l).type == TOK_DOTDOT)
{
- Token end_tok = lexer_next(l);
+ lexer_next(l); // consume ..
+ ASTNode *end_expr = parse_expression(ctx, l);
ASTNode *n = ast_create(NODE_FOR_RANGE);
n->for_range.var_name = xmalloc(var.len + 1);
strncpy(n->for_range.var_name, var.start, var.len);
n->for_range.var_name[var.len] = 0;
- n->for_range.start = xmalloc(start_tok.len + 1);
- strncpy(n->for_range.start, start_tok.start, start_tok.len);
- n->for_range.start[start_tok.len] = 0;
- n->for_range.end = xmalloc(end_tok.len + 1);
- strncpy(n->for_range.end, end_tok.start, end_tok.len);
- n->for_range.end[end_tok.len] = 0;
+ n->for_range.start = start_expr;
+ n->for_range.end = end_expr;
if (lexer_peek(l).type == TOK_IDENT && strncmp(lexer_peek(l).start, "step", 4) == 0)
{
@@ -2118,6 +2111,10 @@ ASTNode *parse_statement(ParserContext *ctx, Lexer *l)
else if (next_type == TOK_DOTDOT)
{
lexer_next(l); // consume ..
+ if (lexer_peek(l).type == TOK_SEMICOLON)
+ {
+ lexer_next(l); // consume optional ;
+ }
}
ASTNode *n = ast_create(NODE_RAW_STMT);
diff --git a/src/parser/parser_utils.c b/src/parser/parser_utils.c
index fcaab7f..ef66104 100644
--- a/src/parser/parser_utils.c
+++ b/src/parser/parser_utils.c
@@ -2148,9 +2148,10 @@ char *rewrite_expr_methods(ParserContext *ctx, char *raw)
dest -= strlen(acc);
- if (*src == '(')
+ Module *mod = find_module(ctx, acc);
+ if (mod && mod->is_c_header)
{
- dest += sprintf(dest, "%s_%s", acc, field);
+ dest += sprintf(dest, "%s", field);
}
else
{