aboutsummaryrefslogtreecommitdiff
path: root/src/parser/ast.c
blob: 4f10915a6c9a35ffa71f03f8a3bc42dab0aa0dd9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <stdlib.h>

#include "parser/ast.h"

struct Program create_program(void)
{
	struct Program program;
	program.consts = NULL;
	program.const_count = 0;
	program.const_capacity = 0;
	program.data_decls = NULL;
	program.data_count = 0;
	program.data_capacity = 0;
	program.procs = NULL;
	program.proc_count = 0;
	program.proc_capacity = 0;
	return program;
}

void free_program(struct Program* program)
{
	free(program->consts);
	free(program->data_decls);

	for (size_t i = 0; i < program->proc_count; i += 1)
	{
		free(program->procs[i].params);
		free(program->procs[i].body);
	}
	free(program->procs);

	program->consts = NULL;
	program->const_count = 0;
	program->const_capacity = 0;
	program->data_decls = NULL;
	program->data_count = 0;
	program->data_capacity = 0;
	program->procs = NULL;
	program->proc_count = 0;
	program->proc_capacity = 0;
}

// TODO: generalize this growable-array boilerplate once a third list appears
void add_const(struct Program* program, struct ConstDecl decl)
{
	if (program->const_count == program->const_capacity)
	{
		size_t capacity = program->const_capacity < 8 ? 8 : program->const_capacity * 2;
		program->consts = realloc(program->consts, capacity * sizeof(struct ConstDecl));
		program->const_capacity = capacity;
	}

	program->consts[program->const_count] = decl;
	program->const_count += 1;
}

void add_data(struct Program* program, struct DataDecl decl)
{
	if (program->data_count == program->data_capacity)
	{
		size_t capacity = program->data_capacity < 8 ? 8 : program->data_capacity * 2;
		program->data_decls = realloc(program->data_decls, capacity * sizeof(struct DataDecl));
		program->data_capacity = capacity;
	}

	program->data_decls[program->data_count] = decl;
	program->data_count += 1;
}

struct ProcDecl create_proc(void)
{
	struct ProcDecl proc;
	proc.params = NULL;
	proc.param_count = 0;
	proc.param_capacity = 0;
	proc.body = NULL;
	proc.body_count = 0;
	proc.body_capacity = 0;
	return proc;
}

void add_param(struct ProcDecl* proc, struct Param param)
{
	if (proc->param_count == proc->param_capacity)
	{
		size_t capacity = proc->param_capacity < 4 ? 4 : proc->param_capacity * 2;
		proc->params = realloc(proc->params, capacity * sizeof(struct Param));
		proc->param_capacity = capacity;
	}

	proc->params[proc->param_count] = param;
	proc->param_count += 1;
}

void add_statement(struct ProcDecl* proc, struct Statement statement)
{
	if (proc->body_count == proc->body_capacity)
	{
		size_t capacity = proc->body_capacity < 8 ? 8 : proc->body_capacity * 2;
		proc->body = realloc(proc->body, capacity * sizeof(struct Statement));
		proc->body_capacity = capacity;
	}

	proc->body[proc->body_count] = statement;
	proc->body_count += 1;
}

void add_proc(struct Program* program, struct ProcDecl decl)
{
	if (program->proc_count == program->proc_capacity)
	{
		size_t capacity = program->proc_capacity < 8 ? 8 : program->proc_capacity * 2;
		program->procs = realloc(program->procs, capacity * sizeof(struct ProcDecl));
		program->proc_capacity = capacity;
	}

	program->procs[program->proc_count] = decl;
	program->proc_count += 1;
}