libmya 0.1.0
Library to parse Mya language.
Loading...
Searching...
No Matches
ast.c
Go to the documentation of this file.
1#include <stdlib.h>
2#include <string.h>
3
4#include "ast.h"
5#include "types/token.h"
6
7static void
8_ast_to_json_aux(ast_node_t* root, FILE* file, int level);
9
10static void
11_print_at_level(FILE* file, int level, char* text);
12
13static void
14_ast_ensure_children_size(ast_node_t* node);
15
16void
18{
19 node->parent = parent;
20 node->type = type;
21 node->token = token;
22
23 node->children = malloc(sizeof(ast_node_t) * AST_INITIAL_CHILDREN_LENGTH);
24 node->children_count = 0;
26}
27
28void
30{
31 for (int i = 0; i < root->children_count; i++) {
32 ast_close(&root->children[i]);
33 }
34
35 free(root->children);
36 root->children = NULL;
37}
38
41{
42 _ast_ensure_children_size(parent);
43
44 ast_node_t* child = &parent->children[parent->children_count++];
45 ast_node_init(child, parent, type, token);
46
47 return child;
48}
49
52{
53 _ast_ensure_children_size(parent);
54
55 ast_node_t* new_child = &parent->children[parent->children_count++];
56
57 ast_copy(new_child, child);
58 new_child->parent = parent;
59
60 return new_child;
61}
62
63void
64ast_copy(ast_node_t* destiny, ast_node_t* source)
65{
66 memcpy(destiny, source, sizeof(ast_node_t));
67}
68
69void
70ast_to_json(ast_node_t* root, FILE* file)
71{
72 _ast_to_json_aux(root, file, 0);
73 fputc('\n', file);
74}
75
76#define _JSON_PRINT_FIELD(level, name, fmt, ...) \
77 _print_at_level(file, level, "\"" name "\": "); \
78 fprintf(file, fmt, __VA_ARGS__);
79
80static void
81_ast_to_json_aux(ast_node_t* root, FILE* file, int level)
82{
83 _print_at_level(file, level, "{\n");
84
85 _JSON_PRINT_FIELD(level + 1, "type", "\"%s\",\n", mya_node_types[root->type]);
86
87 if (root->token != NULL) {
88 _JSON_PRINT_FIELD(level + 1, "token", "%s", "{\n");
89 _JSON_PRINT_FIELD(level + 2, "lexeme", "\"%s\",\n", root->token->lexeme.data);
90 _JSON_PRINT_FIELD(level + 2, "type", "\"%s\",\n", mya_token_types[root->token->type]);
91 _JSON_PRINT_FIELD(level + 2, "line", "%d,\n", root->token->line);
92 _JSON_PRINT_FIELD(level + 2, "column", "%d,\n", root->token->column);
93 _JSON_PRINT_FIELD(level + 2, "value", "%lld\n", root->token->value);
94 _print_at_level(file, level + 1, "},\n");
95 }
96
97 if (root->children_count == 0) {
98 _JSON_PRINT_FIELD(level + 1, "children", "%s", "[]\n");
99 } else {
100 _JSON_PRINT_FIELD(level + 1, "children", "%s", "[\n");
101 for (int i = 0; i < root->children_count; i++) {
102 _ast_to_json_aux(&root->children[i], file, level + 2);
103
104 fputs((i < root->children_count - 1 ? ",\n" : "\n"), file);
105 }
106 _print_at_level(file, level + 1, "]\n");
107 }
108
109 _print_at_level(file, level, "}");
110}
111
112static void
113_print_at_level(FILE* file, int level, char* text)
114{
115 if (level <= 0) {
116 fputs(text, file);
117 return;
118 }
119
120 fprintf(file, "%*c%s", level * 2, ' ', text);
121}
122
123static void
124_ast_ensure_children_size(ast_node_t* node)
125{
126 if (node->children_count < node->_children_length) {
127 return;
128 }
129
131 node->children = realloc(node->children, sizeof(ast_node_t) * node->_children_length);
132}
void ast_node_init(ast_node_t *node, ast_node_t *parent, node_type_t type, token_t *token)
Initializes an AST node.
Definition ast.c:17
void ast_copy(ast_node_t *destiny, ast_node_t *source)
Copies the content of source to destinty AST nodes.
Definition ast.c:64
void ast_close(ast_node_t *root)
Closes the given AST root node and all children.
Definition ast.c:29
ast_node_t * ast_insert_children(ast_node_t *parent, ast_node_t *child)
Insert a exitent AST node as children of the given parent node.
Definition ast.c:51
void ast_to_json(ast_node_t *root, FILE *file)
Reads the AST and converts it to JSON, writting on the given file stream.
Definition ast.c:70
#define _JSON_PRINT_FIELD(level, name, fmt,...)
Definition ast.c:76
ast_node_t * ast_add_children(ast_node_t *parent, node_type_t type, token_t *token)
Add a new children for the given AST node.
Definition ast.c:40
const char * mya_node_types[]
Definition globals.c:65
const char * mya_token_types[]
Definition globals.c:44
unsigned int children_count
Definition ast.h:32
token_t * token
Definition ast.h:30
struct ast_node * children
Definition ast.h:31
unsigned int _children_length
Definition ast.h:33
struct ast_node * parent
Definition ast.h:28
node_type_t type
Definition ast.h:29
char * data
Pointer for the raw string content (a normal C string).
Definition dstring.h:12
Struct for a Mya token.
Definition token.h:34
long long int value
Integer value of the token.
Definition token.h:38
token_type_t type
Token type.
Definition token.h:35
dstring_t lexeme
Lexeme of the token.
Definition token.h:41
unsigned int line
Token line inside the module.
Definition token.h:36
unsigned int column
Column of the token position on the line.
Definition token.h:37
enum node_type node_type_t
#define AST_CHILDREN_LENGTH_INCREMENT
Definition ast.h:6
struct ast_node ast_node_t
#define AST_INITIAL_CHILDREN_LENGTH
Definition ast.h:5
struct token token_t
Struct for a Mya token.