summaryrefslogtreecommitdiff
path: root/src/parser/parser_utils.c
diff options
context:
space:
mode:
authorZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-02-02 00:48:12 +0000
committerZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-02-02 00:48:12 +0000
commit6bbcd9536522386a53cd2f87ece7aa6cf423829f (patch)
tree55d6dc2b4e2a9d84c09a67acb36f1ab4131e290c /src/parser/parser_utils.c
parentec140e5e1823ed72e1ac8ab4af121dbe1b3f85d7 (diff)
parentdadabf8b9d11d099777acc261068a3ed8ca06f24 (diff)
Merge branch 'main' of https://github.com/z-libs/Zen-C into patch-1
Diffstat (limited to 'src/parser/parser_utils.c')
-rw-r--r--src/parser/parser_utils.c75
1 files changed, 69 insertions, 6 deletions
diff --git a/src/parser/parser_utils.c b/src/parser/parser_utils.c
index 48418b6..8ea2934 100644
--- a/src/parser/parser_utils.c
+++ b/src/parser/parser_utils.c
@@ -691,16 +691,22 @@ void register_tuple(ParserContext *ctx, const char *sig)
s_def->strct.name = xstrdup(struct_name);
char *s_sig = xstrdup(sig);
- char *tok = strtok(s_sig, "_");
+ char *current = s_sig;
+ char *next_sep = strstr(current, "__");
ASTNode *head = NULL, *tail = NULL;
int i = 0;
- while (tok)
+ while (current)
{
+ if (next_sep)
+ {
+ *next_sep = 0;
+ }
+
ASTNode *f = ast_create(NODE_FIELD);
char fname[32];
sprintf(fname, "v%d", i++);
f->field.name = xstrdup(fname);
- f->field.type = xstrdup(tok);
+ f->field.type = xstrdup(current);
if (!head)
{
@@ -712,7 +718,15 @@ void register_tuple(ParserContext *ctx, const char *sig)
}
tail = f;
- tok = strtok(NULL, "_");
+ if (next_sep)
+ {
+ current = next_sep + 2;
+ next_sep = strstr(current, "__");
+ }
+ else
+ {
+ break;
+ }
}
free(s_sig);
s_def->strct.fields = head;
@@ -3392,7 +3406,8 @@ char *consume_and_rewrite(ParserContext *ctx, Lexer *l)
}
char *parse_and_convert_args(ParserContext *ctx, Lexer *l, char ***defaults_out, int *count_out,
- Type ***types_out, char ***names_out, int *is_varargs_out)
+ Type ***types_out, char ***names_out, int *is_varargs_out,
+ char ***ctype_overrides_out)
{
Token t = lexer_next(l);
if (t.type != TOK_LPAREN)
@@ -3406,18 +3421,52 @@ char *parse_and_convert_args(ParserContext *ctx, Lexer *l, char ***defaults_out,
char **defaults = xmalloc(sizeof(char *) * 16);
Type **types = xmalloc(sizeof(Type *) * 16);
char **names = xmalloc(sizeof(char *) * 16);
+ char **ctype_overrides = xmalloc(sizeof(char *) * 16);
for (int i = 0; i < 16; i++)
{
defaults[i] = NULL;
types[i] = NULL;
names[i] = NULL;
+ ctype_overrides[i] = NULL;
}
if (lexer_peek(l).type != TOK_RPAREN)
{
while (1)
{
+ // Check for @ctype("...") before parameter
+ char *ctype_override = NULL;
+ if (lexer_peek(l).type == TOK_AT)
+ {
+ lexer_next(l); // eat @
+ Token attr = lexer_next(l);
+ if (attr.type == TOK_IDENT && attr.len == 5 && strncmp(attr.start, "ctype", 5) == 0)
+ {
+ if (lexer_next(l).type != TOK_LPAREN)
+ {
+ zpanic_at(lexer_peek(l), "Expected ( after @ctype");
+ }
+ Token ctype_tok = lexer_next(l);
+ if (ctype_tok.type != TOK_STRING)
+ {
+ zpanic_at(ctype_tok, "@ctype requires a string argument");
+ }
+ // Extract string content (strip quotes)
+ ctype_override = xmalloc(ctype_tok.len - 1);
+ strncpy(ctype_override, ctype_tok.start + 1, ctype_tok.len - 2);
+ ctype_override[ctype_tok.len - 2] = 0;
+ if (lexer_next(l).type != TOK_RPAREN)
+ {
+ zpanic_at(lexer_peek(l), "Expected ) after @ctype string");
+ }
+ }
+ else
+ {
+ zpanic_at(attr, "Unknown parameter attribute @%.*s", attr.len, attr.start);
+ }
+ }
+
Token t = lexer_next(l);
// Handle 'self'
if (t.type == TOK_IDENT && strncmp(t.start, "self", 4) == 0 && t.len == 4)
@@ -3470,6 +3519,7 @@ char *parse_and_convert_args(ParserContext *ctx, Lexer *l, char ***defaults_out,
types[count] = type_new_ptr(type_new(TYPE_VOID));
add_symbol(ctx, "self", "void*", types[count]);
}
+ ctype_overrides[count] = ctype_override;
count++;
}
else
@@ -3514,11 +3564,20 @@ char *parse_and_convert_args(ParserContext *ctx, Lexer *l, char ***defaults_out,
}
else
{
- strcat(buf, type_str);
+ // Use @ctype override if present
+ if (ctype_override)
+ {
+ strcat(buf, ctype_override);
+ }
+ else
+ {
+ strcat(buf, type_str);
+ }
strcat(buf, " ");
strcat(buf, name);
}
+ ctype_overrides[count] = ctype_override;
count++;
if (lexer_peek(l).type == TOK_OP && is_token(lexer_peek(l), "="))
@@ -3593,6 +3652,10 @@ char *parse_and_convert_args(ParserContext *ctx, Lexer *l, char ***defaults_out,
*count_out = count;
*types_out = types;
*names_out = names;
+ if (ctype_overrides_out)
+ {
+ *ctype_overrides_out = ctype_overrides;
+ }
return buf;
}