#include "ast.h" #include "lexer.h" #include #include #include void name_init(struct Name* name) { name->length = 0; name->text[0] = '\0'; } bool name_push(struct Name* name, char character) { if (name->length == NAME_LENGTH_MAX) return false; name->text[name->length++] = character; name->text[name->length] = '\0'; return true; } static struct Node* node_new(enum NodeKind kind) { struct Node* node = calloc(1, sizeof *node); if (node == NULL) { (void)fprintf(stderr, "out of memory\n"); exit(1); } node->kind = kind; node->line = yylineno; return node; } struct Node* node_leaf(enum NodeKind kind) { return node_new(kind); } struct Node* node_char(char character) { struct Node* node = node_new(NODE_CHAR); node->character = character; return node; } struct Node* node_unary(enum NodeKind kind, struct Node* first) { struct Node* node = node_new(kind); node->first = first; return node; } struct Node* node_binary(enum NodeKind kind, struct Node* first, struct Node* second) { struct Node* node = node_new(kind); node->first = first; node->second = second; return node; } struct Node* node_ternary(enum NodeKind kind, struct Node* first, struct Node* second, struct Node* third) { struct Node* node = node_new(kind); node->first = first; node->second = second; node->third = third; return node; } struct Node* node_named(enum NodeKind kind, const struct Name* name, struct Node* first) { struct Node* node = node_new(kind); (void)snprintf(node->name, sizeof node->name, "%s", name->text); node->first = first; return node; } struct Node* node_block(enum NodeKind kind, struct Node* first, struct Node* body) { struct Node* node = node_new(kind); node->first = first; node->body = body; return node; } struct Node* node_append(struct Node* list, struct Node* node) { struct Node* last = list; if (list == NULL) return node; while (last->next != NULL) last = last->next; last->next = node; return list; } void node_free(struct Node* node) { if (node == NULL) return; node_free(node->first); node_free(node->second); node_free(node->third); node_free(node->body); node_free(node->next); free(node); }