ox

The Ox programming language, compiler and tools (WIP)
Log | Files | Refs | README | LICENSE

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;
}