Newer
Older
#include "mcc/ast.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
// Constantcs
const int MCC_PROGRAM_FUNCTION_DEF_SIZE = 4;
const int MCC_PARAMETER_DECLARATION_SIZE = 4;
const int MCC_ARGUMENT_EXPRESSION_SIZE = 4;
// ---------------------------------------------------------------- Expressions
struct mcc_ast_expression *
mcc_ast_new_expression_literal(struct mcc_ast_literal *literal)
{
assert(literal);
struct mcc_ast_expression *expr = malloc(sizeof(*expr));
if (!expr) {
return NULL;
}
expr->type = MCC_AST_EXPRESSION_TYPE_LITERAL;
expr->literal = literal;
return expr;
}
struct mcc_ast_expression *
mcc_ast_new_expression_unary_op(enum mcc_ast_unary_op op,
struct mcc_ast_expression *expression)
{
assert(expression);
struct mcc_ast_expression *expr = malloc(sizeof(*expr));
if (!expr) {
return NULL;
}
expr->type = MCC_AST_EXPRESSION_TYPE_UNARY_OP;
expr->unary_op = op;
expr->unary_expression = expression;
}
struct mcc_ast_expression *
mcc_ast_new_expression_binary_op(enum mcc_ast_binary_op op,
struct mcc_ast_expression *lhs,
struct mcc_ast_expression *rhs)
{
assert(lhs);
assert(rhs);
struct mcc_ast_expression *expr = malloc(sizeof(*expr));
if (!expr) {
return NULL;
}
expr->type = MCC_AST_EXPRESSION_TYPE_BINARY_OP;
expr->op = op;
expr->lhs = lhs;
expr->rhs = rhs;
return expr;
}
struct mcc_ast_expression *
mcc_ast_new_expression_parenth(struct mcc_ast_expression *expression)
{
assert(expression);
struct mcc_ast_expression *expr = malloc(sizeof(*expr));
if (!expr) {
return NULL;
}
expr->type = MCC_AST_EXPRESSION_TYPE_PARENTH;
expr->expression = expression;
return expr;
}
struct mcc_ast_expression *
mcc_ast_new_expression_bracket(struct mcc_ast_identifier *identifier,
struct mcc_ast_expression *expression)
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
120
121
122
{
assert(identifier);
assert(expression);
struct mcc_ast_expression *expr = malloc(sizeof(*expr));
if (!expr) {
return NULL;
}
expr->type = MCC_AST_EXPRESSION_TYPE_BRACKET;
expr->bracket_identifier = identifier;
expr->bracket_expression = expression;
return expr;
}
struct mcc_ast_expression *mcc_ast_new_expression_identifier(struct mcc_ast_identifier *identifier)
{
assert(identifier);
struct mcc_ast_expression *expr = malloc(sizeof(*expr));
if (!expr) {
return NULL;
}
expr->type = MCC_AST_EXPRESSION_TYPE_IDENTIFIER;
expr->identifier = identifier;
return expr;
}
void mcc_ast_delete_expression(struct mcc_ast_expression *expression)
{
assert(expression);
switch (expression->type) {
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
case MCC_AST_EXPRESSION_TYPE_LITERAL:
mcc_ast_delete_literal(expression->literal);
break;
case MCC_AST_EXPRESSION_TYPE_IDENTIFIER:
mcc_ast_delete_identifier(expression->identifier);
break;
case MCC_AST_EXPRESSION_TYPE_UNARY_OP:
mcc_ast_delete_expression(expression->unary_expression);
break;
case MCC_AST_EXPRESSION_TYPE_BINARY_OP:
mcc_ast_delete_expression(expression->lhs);
mcc_ast_delete_expression(expression->rhs);
break;
case MCC_AST_EXPRESSION_TYPE_PARENTH:
mcc_ast_delete_expression(expression->expression);
break;
case MCC_AST_EXPRESSION_TYPE_BRACKET:
mcc_ast_delete_identifier(expression->bracket_identifier);
mcc_ast_delete_expression(expression->bracket_expression);
break;
case MCC_AST_EXPRESSION_TYPE_CALL_EXPRESSION:
mcc_ast_delete_identifier(expression->bracket_identifier);
if(expression->argument != NULL){
mcc_ast_delete_argument(expression->argument);
}
break;
}
free(expression);
}
struct mcc_ast_expression *
mcc_ast_new_expression_call_expression(struct mcc_ast_identifier *function_name,
struct mcc_ast_argument *argument)
struct mcc_ast_expression *expression = malloc(sizeof(*expression));
expression -> type = MCC_AST_EXPRESSION_TYPE_CALL_EXPRESSION;
expression -> argument = argument;
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
}
// ------------------------------------------------------------------- Literals
struct mcc_ast_literal *mcc_ast_new_literal_bool(bool value)
{
struct mcc_ast_literal *lit = malloc(sizeof(*lit));
assert(lit);
lit->type = MCC_AST_DATA_TYPE_BOOL;
lit->b_value = value;
return lit;
}
struct mcc_ast_literal *mcc_ast_new_literal_int(long value)
{
struct mcc_ast_literal *lit = malloc(sizeof(*lit));
assert(lit);
lit->type = MCC_AST_DATA_TYPE_INT;
lit->i_value = value;
return lit;
}
struct mcc_ast_literal *mcc_ast_new_literal_float(double value)
{
struct mcc_ast_literal *lit = malloc(sizeof(*lit));
assert(lit);
lit->type = MCC_AST_DATA_TYPE_FLOAT;
lit->f_value = value;
return lit;
}
struct mcc_ast_literal *mcc_ast_new_literal_string(char *value)
{
struct mcc_ast_literal *lit = malloc(sizeof(*lit));
assert(lit);
char *copyValue = malloc(sizeof(char) * (strlen(value) + 4));
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
lit->type = MCC_AST_DATA_TYPE_STRING;
lit->s_value = copyValue;
return lit;
}
void mcc_ast_delete_literal(struct mcc_ast_literal *literal)
{
assert(literal);
if (literal->type == MCC_AST_DATA_TYPE_STRING) {
free(literal->s_value);
}
free(literal);
}
// ------------------------------------------------------------------- Identifier
struct mcc_ast_identifier *mcc_ast_new_identifier(char *value)
{
struct mcc_ast_identifier *id = malloc(sizeof(*id));
if (!id) {
return NULL;
}
char *str = malloc((strlen(value) + 1) * sizeof(char));
strcpy(str, value);
id->i_value = str;
return id;
}
void mcc_ast_delete_identifier(struct mcc_ast_identifier *identifier)
{
assert(identifier);
free(identifier->i_value);
free(identifier);
}
// ------------------------------------------------------------------- Declaration
struct mcc_ast_declaration *mcc_ast_new_declaration(enum mcc_ast_data_type type, struct mcc_ast_literal *arr_size, struct mcc_ast_identifier *ident)
{
struct mcc_ast_declaration *decl = malloc(sizeof(*decl));
if (!decl) {
return NULL;
}
decl -> type = type;
decl -> ident = ident;
decl -> arr_literal = arr_size ? arr_size : NULL;
return decl;
}
void mcc_ast_delete_declaration(struct mcc_ast_declaration *declaration)
{
assert(declaration);
mcc_ast_delete_identifier(declaration->ident);
if (declaration->arr_literal) {
mcc_ast_delete_literal(declaration->arr_literal);
}
free(declaration);
}
// ------------------------------------------------------------------- Assignment
struct mcc_ast_assignment *
mcc_ast_new_assignment(struct mcc_ast_identifier *identifier,
{
assert(identifier);
assert(rhs);
struct mcc_ast_assignment *ass = malloc(sizeof(*ass));
assert(ass);
ass->type = MCC_AST_ASSIGNMENT_TYPE_NORMAL;
ass->identifier = identifier;
ass->normal_ass.rhs = rhs;
return ass;
}
struct mcc_ast_assignment *
mcc_ast_new_array_assignment(struct mcc_ast_identifier *identifier,
struct mcc_ast_expression *index,
struct mcc_ast_expression *rhs)
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
{
assert(identifier);
assert(index);
assert(rhs);
struct mcc_ast_assignment *ass = malloc(sizeof(*ass));
assert(ass);
ass->type = MCC_AST_ASSIGNMENT_TYPE_ARRAY;
ass->identifier = identifier;
ass->array_ass.index = index;
ass->array_ass.rhs = rhs;
return ass;
}
void mcc_ast_delete_assignment(struct mcc_ast_assignment *assignment)
{
assert(assignment);
mcc_ast_delete_identifier(assignment->identifier);
if (assignment->type == MCC_AST_ASSIGNMENT_TYPE_NORMAL) {
mcc_ast_delete_expression(assignment->normal_ass.rhs);
} else {
mcc_ast_delete_expression(assignment->array_ass.index);
mcc_ast_delete_expression(assignment->array_ass.rhs);
}
free(assignment);
}
// ------------------------------------------------------------------- Statements
struct mcc_ast_statement *mcc_ast_new_statement_expression(struct mcc_ast_expression *expression)
{
assert(expression);
struct mcc_ast_statement *stmt = malloc(sizeof(*stmt));
stmt -> type = MCC_AST_STATEMENT_TYPE_EXPRESSION;
stmt -> expression = expression;
return stmt;
}
struct mcc_ast_statement *mcc_ast_new_statement_if(struct mcc_ast_expression *condition,
struct mcc_ast_statement *if_stmt,
struct mcc_ast_statement *else_stmt)
assert(condition);
assert(if_stmt);
struct mcc_ast_statement *stmt = malloc(sizeof(*stmt));
stmt -> type = MCC_AST_STATEMENT_TYPE_IF;
stmt->if_condition = condition;
stmt -> if_stmt = if_stmt;
stmt->else_stmt = else_stmt;
return stmt;
}
struct mcc_ast_statement *mcc_ast_new_statement_declaration(struct mcc_ast_declaration *declaration)
{
struct mcc_ast_statement *stmt = malloc(sizeof(*stmt));
if (!stmt) {
stmt-> declaration = declaration;
stmt -> type = MCC_AST_STATEMENT_TYPE_DECL;
return stmt;
}
struct mcc_ast_statement *mcc_ast_new_statement_while(struct mcc_ast_expression *condition,
struct mcc_ast_statement *while_stmt)
assert(condition);
assert(while_stmt);
struct mcc_ast_statement *stmt = malloc(sizeof(*stmt));
stmt -> type = MCC_AST_STATEMENT_TYPE_WHILE;
stmt -> while_condition = condition;
stmt -> while_stmt = while_stmt;
}
struct mcc_ast_statement *mcc_ast_new_statement(struct mcc_ast_statement *statement){
struct mcc_ast_statement *stmt = malloc(sizeof(*stmt));
return statement;
}
struct mcc_ast_statement_list *
mcc_ast_new_statement_list(struct mcc_ast_statement *statement)
{
assert(statement);
struct mcc_ast_statement_list *list = malloc(sizeof(*list));
assert(list);
list->statement = statement;
return list;
}
void mcc_ast_delete_statement_list(
struct mcc_ast_statement_list *statement_list)
{
assert(statement_list);
if (statement_list->next != NULL) {
mcc_ast_delete_statement_list(statement_list->next);
}
mcc_ast_delete_statement(statement_list->statement);
}
struct mcc_ast_statement *
mcc_ast_new_statement_compound(struct mcc_ast_statement_list *statement)
{
struct mcc_ast_statement *stmt = malloc(sizeof(*stmt));
assert(stmt);
stmt -> type = MCC_AST_STATEMENT_TYPE_COMPOUND;
stmt -> statement_list = statement;
}
struct mcc_ast_statement *mcc_ast_new_statement_assignment(struct mcc_ast_assignment *assignment)
{
struct mcc_ast_statement *stmt = malloc(sizeof(*stmt));
assert(stmt);
stmt->type = assignment->type == MCC_AST_ASSIGNMENT_TYPE_NORMAL
? MCC_AST_STATEMENT_TYPE_ASSGN
: MCC_AST_STATEMENT_TYPE_ASSGN_ARR;
}
struct mcc_ast_statement *mcc_ast_new_statement_return(struct mcc_ast_expression *expression)
{
struct mcc_ast_statement *stmt = malloc(sizeof(*stmt));
if (!stmt) {
return NULL;
}
stmt->type = MCC_AST_STATEMENT_TYPE_RETURN;
stmt->expression = expression;
return stmt;
}
void mcc_ast_delete_statement(struct mcc_ast_statement *statement)
{
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
assert(statement);
switch(statement->type){
case MCC_AST_STATEMENT_TYPE_EXPRESSION:
mcc_ast_delete_expression(statement->expression);
break;
case MCC_AST_STATEMENT_TYPE_IF:
mcc_ast_delete_expression(statement->if_condition);
mcc_ast_delete_statement(statement->if_stmt);
if(statement->else_stmt != NULL){
mcc_ast_delete_statement(statement->else_stmt);
}
break;
case MCC_AST_STATEMENT_TYPE_WHILE:
mcc_ast_delete_expression(statement->while_condition);
mcc_ast_delete_statement(statement->while_stmt);
break;
case MCC_AST_STATEMENT_TYPE_DECL:
mcc_ast_delete_declaration(statement->declaration);
break;
case MCC_AST_STATEMENT_TYPE_ASSGN:
case MCC_AST_STATEMENT_TYPE_ASSGN_ARR:
mcc_ast_delete_assignment(statement->assignment);
break;
case MCC_AST_STATEMENT_TYPE_COMPOUND:
if(statement -> statement_list != NULL){
mcc_ast_delete_statement_list(statement->statement_list);
}
break;
case MCC_AST_STATEMENT_TYPE_RETURN:
mcc_ast_delete_expression(statement->expression);
break;
}
void mcc_ast_empty_node() {
}
// ------------------------------------------------------------------- Parameters
struct mcc_ast_parameter *mcc_ast_new_parameter(struct mcc_ast_declaration *declaration) {
struct mcc_ast_parameter *p = malloc(sizeof(*p));
if (p == NULL) return NULL;
p -> parameters = mcc_create_dynamic_array(MCC_PARAMETER_DECLARATION_SIZE);
mcc_add_to_array(p -> parameters, declaration);
return p;
}
struct mcc_ast_parameter *mcc_ast_add_new_parameter(struct mcc_ast_parameter *params, struct mcc_ast_declaration *declaration) {
assert(declaration);
if(mcc_add_to_array(params->parameters, declaration) == 1) {
return NULL;
static void delete_param_declaration(void *decl) {
struct mcc_ast_declaration *d = (struct mcc_ast_declaration *) decl;
mcc_ast_delete_declaration(d);
}
void mcc_ast_delete_parameter(struct mcc_ast_parameter *parameter) {
mcc_delete_array(parameter -> parameters, delete_param_declaration);
}
// ------------------------------------------------------------------- Arguments
struct mcc_ast_argument *mcc_ast_new_argument(struct mcc_ast_expression *expression) {
struct mcc_ast_argument *argument = malloc(sizeof(*argument));
argument -> expressions = mcc_create_dynamic_array(MCC_ARGUMENT_EXPRESSION_SIZE);
mcc_add_to_array(argument -> expressions, expression);
return argument;
}
struct mcc_ast_argument *mcc_ast_add_new_argument(struct mcc_ast_expression *expression, struct mcc_ast_argument *argument) {
assert(argument);
assert(expression);
if (mcc_add_to_array(argument -> expressions, expression) == 1) {
perror("Error adding expression argument");
// cast void pointer to expression pointer
void delete_argument_expression(void *expression) {
struct mcc_ast_expression *e = (struct mcc_ast_expression *) expression;
mcc_ast_delete_expression(e);
}
void mcc_ast_delete_argument(struct mcc_ast_argument *argument) {
mcc_delete_array(argument -> expressions, delete_argument_expression);
free(argument);
}
// ------------------------------------------------------------------- Function
struct mcc_ast_function *mcc_ast_new_function(
enum mcc_ast_data_type return_type,
struct mcc_ast_identifier *identifier,
struct mcc_ast_parameter *parameter,
struct mcc_ast_statement *statement
struct mcc_ast_function *func = malloc(sizeof(*func));
func -> return_type = return_type;
func -> identifier = identifier;
if (parameter != NULL) {
func -> parameter = parameter;
}
}
void mcc_ast_delete_function(struct mcc_ast_function *function) {
assert(function);
mcc_ast_delete_identifier(function -> identifier);
if (function -> parameter != NULL) {
mcc_ast_delete_parameter(function -> parameter);
}
if (function -> statement != NULL) {
mcc_ast_delete_statement(function -> statement);
}
}
// ------------------------------------------------------------------- Program
struct mcc_ast_program *mcc_ast_new_program(struct mcc_ast_function *function_def) {
struct mcc_ast_program *p = malloc(sizeof(*p));
p -> function_def = mcc_create_dynamic_array(MCC_PROGRAM_FUNCTION_DEF_SIZE);
mcc_add_to_array(p -> function_def, function_def);
}
struct mcc_ast_program *mcc_ast_add_function(struct mcc_ast_function *function_def, struct mcc_ast_program *program)
{
assert(program);
assert(function_def);
if (mcc_add_to_array(program -> function_def, function_def) == 1) {
perror("Function def add error");
};
static void delete_func(void *function_def) {
struct mcc_ast_function *f = (struct mcc_ast_function*) function_def;
mcc_ast_delete_function(f);
}
void mcc_ast_delete_program(struct mcc_ast_program *program)
{
mcc_delete_array(program -> function_def, delete_func);