decl.c (2105B)
#include "../parser.h"
#include "../utils.h"
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <assert.h>
Node*
parse_type_or_void(Parser* par)
{
Token tok = peek(par);
if (tok.type == TOKEN_COMP_TIME || tok.type == TOKEN_VARIADIC || tok.type == TOKEN_IDENT) {
return parse_type(par);
} else {
return NULL;
}
}
Node*
parse_type(Parser* par)
{
bool comp_time = (peek(par).type == TOKEN_COMP_TIME);
bool variadic = (peek(par).type == TOKEN_VARIADIC);
if (comp_time || variadic) { consume(par); }
Token tok = expect(par, TOKEN_IDENT);
// @later we will resolve types later, incl. custom vs. system, allow for now
//
// const char firstChar = par->src[t.start];
// if (firstChar >= 'A' && firstChar <= 'Z') {
// // assume this is a user type
// }
Node* node = calloc(1, sizeof(Node));
if (node == NULL) panic("parse_type: alloc failed");
node->type = NODE_TYPE;
node->scope = NULL;
node->data.ident_type.name = (Span) { .start = tok.start, .end = tok.end };
node->data.ident_type.is_comp_time = comp_time;
node->data.ident_type.is_variadic = variadic;
return node;
}
// <TYPE> name:<IDENT>
Node*
make_param_decl(Parser* par)
{
Node* type = parse_type(par);
Token param_name = expect(par, TOKEN_IDENT);
Span ident_name = { .start = param_name.start, .end = param_name.end };
Node* param = (Node*)calloc(1, sizeof(Node));
if (param == NULL) panic("make_param_decl alloc failed");
param->type = NODE_PARAM;
param->scope = NULL;
param->data.param.name = ident_name;
param->data.param.type = type;
return param;
}
NodeVec
parse_param_list(Parser* par)
{
NodeVec v = { 0 };
if (peek(par).type == TOKEN_RPAREN) return v; // found `)` no parameters
v.cap = 4;
v.items = (Node**)calloc(v.cap, sizeof(Node*));
if (v.items == NULL) panic("parse_param_list: could not alloc");
for (;;) {
Node* param = make_param_decl(par);
if (v.len == v.cap) {
v.cap *= 2;
v.items = (Node**)realloc(v.items, v.cap * sizeof(Node*));
}
v.items[v.len++] = param;
if (!match(par, TOKEN_COMMA)) break; // found `)` instead of `,`
}
return v;
}