ox

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

decl.c (2105B)


      1 #include "../parser.h"
      2 #include "../utils.h"
      3 
      4 #include <stdio.h>
      5 #include <string.h>
      6 #include <stdbool.h>
      7 #include <assert.h>
      8 
      9 Node*
     10 parse_type_or_void(Parser* par)
     11 {
     12 	Token tok = peek(par);
     13 	if (tok.type == TOKEN_COMP_TIME || tok.type == TOKEN_VARIADIC || tok.type == TOKEN_IDENT) {
     14 		return parse_type(par);
     15 	} else {
     16 		return NULL;
     17 	}
     18 }
     19 
     20 Node*
     21 parse_type(Parser* par)
     22 {
     23 	bool comp_time = (peek(par).type == TOKEN_COMP_TIME);
     24 	bool variadic = (peek(par).type == TOKEN_VARIADIC);
     25 	if (comp_time || variadic) { consume(par); }
     26 
     27 	Token tok = expect(par, TOKEN_IDENT);
     28 
     29 	// @later we will resolve types later, incl. custom vs. system, allow for now
     30 	//
     31 	// const char firstChar = par->src[t.start];
     32 	// if (firstChar >= 'A' && firstChar <= 'Z') {
     33 	//     // assume this is a user type
     34 	// }
     35 
     36 	Node* node = calloc(1, sizeof(Node));
     37 	if (node == NULL) panic("parse_type: alloc failed");
     38 	node->type = NODE_TYPE;
     39 	node->scope = NULL;
     40 	node->data.ident_type.name = (Span) { .start = tok.start, .end = tok.end };
     41 	node->data.ident_type.is_comp_time = comp_time;
     42 	node->data.ident_type.is_variadic = variadic;
     43 	return node;
     44 }
     45 
     46 // <TYPE> name:<IDENT>
     47 Node*
     48 make_param_decl(Parser* par)
     49 {
     50 	Node* type = parse_type(par);
     51 	Token param_name = expect(par, TOKEN_IDENT);
     52 	Span ident_name = { .start = param_name.start, .end = param_name.end };
     53 	Node* param = (Node*)calloc(1, sizeof(Node));
     54 	if (param == NULL) panic("make_param_decl alloc failed");
     55 	param->type = NODE_PARAM;
     56 	param->scope = NULL;
     57 	param->data.param.name = ident_name;
     58 	param->data.param.type = type;
     59 	return param;
     60 }
     61 
     62 NodeVec
     63 parse_param_list(Parser* par)
     64 {
     65 	NodeVec v = { 0 };
     66 	if (peek(par).type == TOKEN_RPAREN) return v; // found `)` no parameters
     67 
     68 	v.cap = 4;
     69 	v.items = (Node**)calloc(v.cap, sizeof(Node*));
     70 
     71 	if (v.items == NULL) panic("parse_param_list: could not alloc");
     72 
     73 	for (;;) {
     74 		Node* param = make_param_decl(par);
     75 
     76 		if (v.len == v.cap) {
     77 			v.cap *= 2;
     78 			v.items = (Node**)realloc(v.items, v.cap * sizeof(Node*));
     79 		}
     80 
     81 		v.items[v.len++] = param;
     82 
     83 		if (!match(par, TOKEN_COMMA)) break; // found `)` instead of `,`
     84 	}
     85 	return v;
     86 }