KCC - Kayte C Compiler 1.10.0
A C compiler implementation with preprocessor, lexer, parser, and code generator
Loading...
Searching...
No Matches
ast.c
1#include "kcc.h"
2
3// Create a generic AST node
4ASTNode *ast_create_node(ASTNodeType type) {
5 ASTNode *node = safe_malloc(sizeof(ASTNode));
6 memset(node, 0, sizeof(ASTNode)); // Initialize everything to 0/NULL
7 node->type = type;
8 node->data_type = TYPE_UNKNOWN;
9 return node;
10}
11
12// Create program node (root of AST)
13ASTNode *ast_create_program(void) {
14 ASTNode *node = ast_create_node(AST_PROGRAM); // Fixed: Use proper type
15 if (node) {
16 node->data.program.declarations = NULL;
17 node->data.program.declaration_count = 0;
18 }
19 return node;
20}
21
22// Create function declaration
23ASTNode *ast_create_function_decl(DataType return_type, const char *name, ASTNode **params, ASTNode *body) {
24 ASTNode *node = ast_create_node(AST_FUNCTION_DECLARATION);
25 if (node && name) {
26 node->data.function_decl.return_type = return_type;
27 node->data.function_decl.name = safe_strdup(name);
28 node->data.function_decl.parameters = params;
29 node->data.function_decl.parameter_count = 0; // Set appropriately if params provided
30 node->data.function_decl.body = body;
31 }
32 return node;
33}
34
35// Create variable declaration
36ASTNode *ast_create_var_decl(DataType type, const char *name, ASTNode *initializer) {
37 ASTNode *node = ast_create_node(AST_VARIABLE_DECLARATION);
38 if (node && name) {
39 node->data.var_decl.var_type = type;
40 node->data.var_decl.name = safe_strdup(name);
41 node->data.var_decl.initializer = initializer;
42 }
43 return node;
44}
45
46// Create parameter node
47ASTNode *ast_create_parameter(DataType type, const char *name) {
48 ASTNode *node = ast_create_node(AST_PARAMETER); // Fixed: Use proper type
49 if (node && name) {
50 node->data.parameter.param_type = type;
51 node->data.parameter.name = safe_strdup(name);
52 }
53 return node;
54}
55
56// Create compound statement
57ASTNode *ast_create_compound_stmt(void) {
58 ASTNode *node = ast_create_node(AST_COMPOUND_STATEMENT);
59 if (node) {
60 node->data.compound_stmt.statements = NULL;
61 node->data.compound_stmt.statement_count = 0;
62 }
63 return node;
64}
65
66// Create expression statement
67ASTNode *ast_create_expression_stmt(ASTNode *expr) {
68 ASTNode *node = ast_create_node(AST_EXPRESSION_STATEMENT);
69 if (node) {
70 node->data.expression_stmt.expression = expr;
71 }
72 return node;
73}
74
75// Create return statement
76ASTNode *ast_create_return_stmt(ASTNode *expr) {
77 ASTNode *node = ast_create_node(AST_RETURN_STATEMENT);
78 if (node) {
79 node->data.return_stmt.expression = expr;
80 }
81 return node;
82}
83
84// Create if statement
85ASTNode *ast_create_if_stmt(ASTNode *condition, ASTNode *then_stmt, ASTNode *else_stmt) {
86 ASTNode *node = ast_create_node(AST_IF_STATEMENT);
87 if (node) {
88 node->data.if_stmt.condition = condition;
89 node->data.if_stmt.then_stmt = then_stmt;
90 node->data.if_stmt.else_stmt = else_stmt;
91 }
92 return node;
93}
94
95// Create while statement
96ASTNode *ast_create_while_stmt(ASTNode *condition, ASTNode *body) {
97 ASTNode *node = ast_create_node(AST_WHILE_STATEMENT);
98 if (node) {
99 node->data.while_stmt.condition = condition;
100 node->data.while_stmt.body = body;
101 }
102 return node;
103}
104
105// Create for statement
106ASTNode *ast_create_for_stmt(ASTNode *init, ASTNode *condition, ASTNode *update, ASTNode *body) {
107 ASTNode *node = ast_create_node(AST_FOR_STATEMENT);
108 if (node) {
109 node->data.for_stmt.init = init;
110 node->data.for_stmt.condition = condition;
111 node->data.for_stmt.update = update;
112 node->data.for_stmt.body = body;
113 }
114 return node;
115}
116
117// Create break statement
118ASTNode *ast_create_break_stmt(void) {
119 return ast_create_node(AST_BREAK_STATEMENT);
120}
121
122// Create continue statement
123ASTNode *ast_create_continue_stmt(void) {
124 return ast_create_node(AST_CONTINUE_STATEMENT);
125}
126
127// Create binary expression
128ASTNode *ast_create_binary_expr(TokenType op, ASTNode *left, ASTNode *right) {
129 ASTNode *node = ast_create_node(AST_BINARY_OP);
130 if (node) {
131 node->data.binary_expr.operator = op;
132 node->data.binary_expr.left = left;
133 node->data.binary_expr.right = right;
134 }
135 return node;
136}
137
138// Create unary expression
139ASTNode *ast_create_unary_expr(TokenType op, ASTNode *operand) {
140 ASTNode *node = ast_create_node(AST_UNARY_OP);
141 if (node) {
142 node->data.unary_expr.operator = op;
143 node->data.unary_expr.operand = operand;
144 }
145 return node;
146}
147
148// Create function call expression
149ASTNode *ast_create_call_expr(const char *function_name) {
150 ASTNode *node = ast_create_node(AST_FUNCTION_CALL);
151 if (node && function_name) {
152 node->data.call_expr.function_name = safe_strdup(function_name);
153 node->data.call_expr.arguments = NULL;
154 node->data.call_expr.argument_count = 0;
155 }
156 return node;
157}
158
159// Create identifier
160ASTNode *ast_create_identifier(const char *name) {
161 ASTNode *node = ast_create_node(AST_IDENTIFIER); // Fixed: Use proper type
162 if (node && name) {
163 node->data.identifier.name = safe_strdup(name);
164 }
165 return node;
166}
167
168// Create number literal
169ASTNode *ast_create_number(int value) {
170 ASTNode *node = ast_create_node(AST_NUMBER_LITERAL);
171 if (node) {
172 node->data.number.value = value;
173 }
174 return node;
175}
176
177// Create string literal
178ASTNode *ast_create_string(const char *value) {
179 ASTNode *node = ast_create_node(AST_STRING_LITERAL);
180 if (node && value) {
181 node->data.string.value = safe_strdup(value);
182 }
183 return node;
184}
185
186// Create assignment expression
187ASTNode *ast_create_assignment(const char *var_name, ASTNode *value) {
188 ASTNode *node = ast_create_node(AST_ASSIGNMENT); // Fixed: Use proper type
189 if (node && var_name) {
190 node->data.assignment.variable = safe_strdup(var_name);
191 node->data.assignment.value = value;
192 }
193 return node;
194}
195
196// Add declaration to program
197void ast_add_declaration(ASTNode *program, ASTNode *declaration) {
198 if (!program || !declaration) return;
199
200 int new_count = program->data.program.declaration_count + 1;
201 ASTNode **new_declarations = realloc(program->data.program.declarations,
202 new_count * sizeof(ASTNode*));
203 if (new_declarations) {
204 program->data.program.declarations = new_declarations;
205 program->data.program.declarations[program->data.program.declaration_count] = declaration;
206 program->data.program.declaration_count = new_count;
207 }
208}
209
210// Add statement to compound statement
211void ast_add_statement(ASTNode *compound, ASTNode *statement) {
212 if (!compound || compound->type != AST_COMPOUND_STATEMENT || !statement) return;
213
214 int new_count = compound->data.compound_stmt.statement_count + 1;
215 ASTNode **new_statements = realloc(compound->data.compound_stmt.statements,
216 new_count * sizeof(ASTNode*));
217 if (new_statements) {
218 compound->data.compound_stmt.statements = new_statements;
219 compound->data.compound_stmt.statements[compound->data.compound_stmt.statement_count] = statement;
220 compound->data.compound_stmt.statement_count = new_count;
221 }
222}
223
224// Add argument to function call
225void ast_add_argument(ASTNode *call, ASTNode *arg) {
226 if (!call || call->type != AST_FUNCTION_CALL || !arg) return;
227
228 int new_count = call->data.call_expr.argument_count + 1;
229 ASTNode **new_arguments = realloc(call->data.call_expr.arguments,
230 new_count * sizeof(ASTNode*));
231 if (new_arguments) {
232 call->data.call_expr.arguments = new_arguments;
233 call->data.call_expr.arguments[call->data.call_expr.argument_count] = arg;
234 call->data.call_expr.argument_count = new_count;
235 }
236}
237
238// Destroy AST node and all its children
239void ast_destroy(ASTNode *node) {
240 if (!node) {
241 return; // Safe to call with NULL
242 }
243
244 // Debug output to help identify problematic nodes
245 #ifdef DEBUG_AST_DESTROY
246 printf("DEBUG: Destroying node with type %d\n", node->type);
247 #endif
248
249 // Clean up based on node type
250 switch (node->type) {
251 case AST_PROGRAM:
252 if (node->data.program.declarations) {
253 for (int i = 0; i < node->data.program.declaration_count; i++) {
254 ast_destroy(node->data.program.declarations[i]);
255 }
256 free(node->data.program.declarations);
257 node->data.program.declarations = NULL;
258 }
259 break;
260
261 case AST_FUNCTION_DECLARATION:
262 // Free function name
263 if (node->data.function_decl.name) {
264 free(node->data.function_decl.name);
265 node->data.function_decl.name = NULL;
266 }
267 // Free parameters
268 if (node->data.function_decl.parameters) {
269 for (int i = 0; i < node->data.function_decl.parameter_count; i++) {
270 ast_destroy(node->data.function_decl.parameters[i]);
271 }
272 free(node->data.function_decl.parameters);
273 node->data.function_decl.parameters = NULL;
274 }
275 // Free body
276 if (node->data.function_decl.body) {
277 ast_destroy(node->data.function_decl.body);
278 node->data.function_decl.body = NULL;
279 }
280 break;
281
282 case AST_VARIABLE_DECLARATION:
283 if (node->data.var_decl.name) {
284 free(node->data.var_decl.name);
285 node->data.var_decl.name = NULL;
286 }
287 if (node->data.var_decl.initializer) {
288 ast_destroy(node->data.var_decl.initializer);
289 node->data.var_decl.initializer = NULL;
290 }
291 break;
292
293 case AST_PARAMETER:
294 if (node->data.parameter.name) {
295 free(node->data.parameter.name);
296 node->data.parameter.name = NULL;
297 }
298 break;
299
300 case AST_COMPOUND_STATEMENT:
301 if (node->data.compound_stmt.statements) {
302 for (int i = 0; i < node->data.compound_stmt.statement_count; i++) {
303 ast_destroy(node->data.compound_stmt.statements[i]);
304 }
305 free(node->data.compound_stmt.statements);
306 node->data.compound_stmt.statements = NULL;
307 }
308 break;
309
310 case AST_EXPRESSION_STATEMENT:
311 if (node->data.expression_stmt.expression) {
312 ast_destroy(node->data.expression_stmt.expression);
313 node->data.expression_stmt.expression = NULL;
314 }
315 break;
316
317 case AST_IF_STATEMENT:
318 if (node->data.if_stmt.condition) {
319 ast_destroy(node->data.if_stmt.condition);
320 node->data.if_stmt.condition = NULL;
321 }
322 if (node->data.if_stmt.then_stmt) {
323 ast_destroy(node->data.if_stmt.then_stmt);
324 node->data.if_stmt.then_stmt = NULL;
325 }
326 if (node->data.if_stmt.else_stmt) {
327 ast_destroy(node->data.if_stmt.else_stmt);
328 node->data.if_stmt.else_stmt = NULL;
329 }
330 break;
331
332 case AST_WHILE_STATEMENT:
333 if (node->data.while_stmt.condition) {
334 ast_destroy(node->data.while_stmt.condition);
335 node->data.while_stmt.condition = NULL;
336 }
337 if (node->data.while_stmt.body) {
338 ast_destroy(node->data.while_stmt.body);
339 node->data.while_stmt.body = NULL;
340 }
341 break;
342
343 case AST_FOR_STATEMENT:
344 if (node->data.for_stmt.init) {
345 ast_destroy(node->data.for_stmt.init);
346 node->data.for_stmt.init = NULL;
347 }
348 if (node->data.for_stmt.condition) {
349 ast_destroy(node->data.for_stmt.condition);
350 node->data.for_stmt.condition = NULL;
351 }
352 if (node->data.for_stmt.update) {
353 ast_destroy(node->data.for_stmt.update);
354 node->data.for_stmt.update = NULL;
355 }
356 if (node->data.for_stmt.body) {
357 ast_destroy(node->data.for_stmt.body);
358 node->data.for_stmt.body = NULL;
359 }
360 break;
361
362 case AST_RETURN_STATEMENT:
363 if (node->data.return_stmt.expression) {
364 ast_destroy(node->data.return_stmt.expression);
365 node->data.return_stmt.expression = NULL;
366 }
367 break;
368
369 case AST_BINARY_OP:
370 if (node->data.binary_expr.left) {
371 ast_destroy(node->data.binary_expr.left);
372 node->data.binary_expr.left = NULL;
373 }
374 if (node->data.binary_expr.right) {
375 ast_destroy(node->data.binary_expr.right);
376 node->data.binary_expr.right = NULL;
377 }
378 break;
379
380 case AST_UNARY_OP:
381 if (node->data.unary_expr.operand) {
382 ast_destroy(node->data.unary_expr.operand);
383 node->data.unary_expr.operand = NULL;
384 }
385 break;
386
387 case AST_ASSIGNMENT:
388 if (node->data.assignment.variable) {
389 free(node->data.assignment.variable);
390 node->data.assignment.variable = NULL;
391 }
392 if (node->data.assignment.value) {
393 ast_destroy(node->data.assignment.value);
394 node->data.assignment.value = NULL;
395 }
396 break;
397
398 case AST_FUNCTION_CALL:
399 if (node->data.call_expr.function_name) {
400 free(node->data.call_expr.function_name);
401 node->data.call_expr.function_name = NULL;
402 }
403 if (node->data.call_expr.arguments) {
404 for (int i = 0; i < node->data.call_expr.argument_count; i++) {
405 ast_destroy(node->data.call_expr.arguments[i]);
406 }
407 free(node->data.call_expr.arguments);
408 node->data.call_expr.arguments = NULL;
409 }
410 break;
411
412 case AST_IDENTIFIER:
413 if (node->data.identifier.name) {
414 free(node->data.identifier.name);
415 node->data.identifier.name = NULL;
416 }
417 break;
418
419 case AST_STRING_LITERAL:
420 if (node->data.string.value) {
421 free(node->data.string.value);
422 node->data.string.value = NULL;
423 }
424 break;
425
426 case AST_NUMBER_LITERAL:
427 case AST_CHAR_LITERAL:
428 case AST_BREAK_STATEMENT:
429 case AST_CONTINUE_STATEMENT:
430 // These don't have dynamically allocated fields
431 break;
432
433 default:
434 // Unknown node type - this might be the problem!
435 #ifdef DEBUG_AST_DESTROY
436 printf("WARNING: Unknown node type %d in ast_destroy\n", node->type);
437 #endif
438 break;
439 }
440
441 // Finally, free the node itself
442 free(node);
443}
AST Node structure.
Definition types.h:333
ASTNodeType
AST Node types.
Definition types.h:215
TokenType
Token types for lexical analysis.
Definition types.h:24
DataType
Data types supported by the compiler.
Definition types.h:193