hokusai-zero 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. checksums.yaml +7 -0
  2. data/Dockerfile +26 -0
  3. data/Gemfile +15 -0
  4. data/Gemfile.lock +91 -0
  5. data/LICENSE +21 -0
  6. data/README.md +28 -0
  7. data/ast/genheader +3 -0
  8. data/ast/include/hashmap.c +1151 -0
  9. data/ast/include/hashmap.c.license +20 -0
  10. data/ast/include/hashmap.h +54 -0
  11. data/ast/src/core/ast.c +448 -0
  12. data/ast/src/core/ast.h +259 -0
  13. data/ast/src/core/common.h +24 -0
  14. data/ast/src/core/component.c +85 -0
  15. data/ast/src/core/component.h +35 -0
  16. data/ast/src/core/hml.c +665 -0
  17. data/ast/src/core/hml.h +11 -0
  18. data/ast/src/core/input.c +458 -0
  19. data/ast/src/core/input.h +118 -0
  20. data/ast/src/core/style.c +101 -0
  21. data/ast/src/core/style.h +41 -0
  22. data/ast/src/core/text.c +784 -0
  23. data/ast/src/core/text.h +93 -0
  24. data/ast/src/core/util.c +140 -0
  25. data/ast/src/core/util.h +48 -0
  26. data/ast/src/hokusai.c +6 -0
  27. data/ast/src/hokusai.h +6 -0
  28. data/ast/test/fixtures/test.ui +13 -0
  29. data/ast/test/greatest.h +1266 -0
  30. data/ast/test/hokusai.c +14 -0
  31. data/ast/test/parser.c +234 -0
  32. data/ast/test/text.c +116 -0
  33. data/ext/extconf.rb +27 -0
  34. data/grammar/Cargo.lock +80 -0
  35. data/grammar/Cargo.toml +26 -0
  36. data/grammar/binding.gyp +20 -0
  37. data/grammar/bindings/node/binding.cc +28 -0
  38. data/grammar/bindings/node/index.js +19 -0
  39. data/grammar/bindings/rust/build.rs +40 -0
  40. data/grammar/bindings/rust/lib.rs +52 -0
  41. data/grammar/corpus/1_document.txt +131 -0
  42. data/grammar/corpus/2_selectors.txt +58 -0
  43. data/grammar/corpus/3_spaces.txt +69 -0
  44. data/grammar/corpus/4_errors.txt +10 -0
  45. data/grammar/corpus/5_macros.txt +175 -0
  46. data/grammar/corpus/6_styles.txt +81 -0
  47. data/grammar/grammar.js +275 -0
  48. data/grammar/package-lock.json +34 -0
  49. data/grammar/package.json +33 -0
  50. data/grammar/src/grammar.json +1269 -0
  51. data/grammar/src/node-types.json +474 -0
  52. data/grammar/src/parser.c +5772 -0
  53. data/grammar/src/scanner.c +258 -0
  54. data/grammar/src/tree_sitter/parser.h +230 -0
  55. data/grammar/src/tree_sitter/scanner.h +12 -0
  56. data/grammar/test.nml +10 -0
  57. data/hokusai.gemspec +19 -0
  58. data/ui/examples/assets/DigitalDisplay.ttf +0 -0
  59. data/ui/examples/assets/OpenSans-Regular.ttf +0 -0
  60. data/ui/examples/assets/addy.png +0 -0
  61. data/ui/examples/assets/baby_sean.png +0 -0
  62. data/ui/examples/assets/football-troll.png +0 -0
  63. data/ui/examples/assets/gear.png +0 -0
  64. data/ui/examples/assets/icecold.ttf +0 -0
  65. data/ui/examples/assets/science-troll.png +0 -0
  66. data/ui/examples/buddy.rb +31 -0
  67. data/ui/examples/clock.rb +58 -0
  68. data/ui/examples/counter.rb +123 -0
  69. data/ui/examples/dynamic.rb +147 -0
  70. data/ui/examples/foobar.rb +236 -0
  71. data/ui/examples/stock.rb +115 -0
  72. data/ui/examples/stock_decider/option.rb +74 -0
  73. data/ui/examples/tic_tac_toe.rb +246 -0
  74. data/ui/lib/lib_hokusai.rb +425 -0
  75. data/ui/spec/hokusai/ast_spec.rb +88 -0
  76. data/ui/spec/hokusai/automation/keys_transcoder_spec.rb +50 -0
  77. data/ui/spec/hokusai/automation/selector_spec.rb +68 -0
  78. data/ui/spec/hokusai/block_spec.rb +126 -0
  79. data/ui/spec/hokusai/directives_spec.rb +327 -0
  80. data/ui/spec/hokusai/e2e/client_spec.rb +58 -0
  81. data/ui/spec/hokusai/e2e/meta_spec.rb +42 -0
  82. data/ui/spec/hokusai/publisher_spec.rb +38 -0
  83. data/ui/spec/hokusai/slots_spec.rb +150 -0
  84. data/ui/spec/hokusai/util/piece_table_spec.rb +90 -0
  85. data/ui/spec/hokusai_spec.rb +0 -0
  86. data/ui/spec/spec_helper.rb +30 -0
  87. data/ui/src/hokusai/ast.rb +446 -0
  88. data/ui/src/hokusai/automation/client.rb +167 -0
  89. data/ui/src/hokusai/automation/constants.rb +98 -0
  90. data/ui/src/hokusai/automation/converters/selector_converter.rb +61 -0
  91. data/ui/src/hokusai/automation/driver.rb +54 -0
  92. data/ui/src/hokusai/automation/driver_command_queue.rb +50 -0
  93. data/ui/src/hokusai/automation/driver_commands/base.rb +79 -0
  94. data/ui/src/hokusai/automation/driver_commands/get_attribute.rb +41 -0
  95. data/ui/src/hokusai/automation/driver_commands/invoke.rb +33 -0
  96. data/ui/src/hokusai/automation/driver_commands/locate.rb +48 -0
  97. data/ui/src/hokusai/automation/driver_commands/trigger_keyboard.rb +94 -0
  98. data/ui/src/hokusai/automation/driver_commands/trigger_mouse.rb +213 -0
  99. data/ui/src/hokusai/automation/keys_transcoder.rb +128 -0
  100. data/ui/src/hokusai/automation/selector.rb +39 -0
  101. data/ui/src/hokusai/automation/server.rb +114 -0
  102. data/ui/src/hokusai/automation.rb +3 -0
  103. data/ui/src/hokusai/backends/raylib/config.rb +47 -0
  104. data/ui/src/hokusai/backends/raylib/font.rb +113 -0
  105. data/ui/src/hokusai/backends/raylib/keys.rb +124 -0
  106. data/ui/src/hokusai/backends/raylib.rb +449 -0
  107. data/ui/src/hokusai/backends/sdl2/Monaco.ttf +0 -0
  108. data/ui/src/hokusai/backends/sdl2/color.rb +12 -0
  109. data/ui/src/hokusai/backends/sdl2/config.rb +31 -0
  110. data/ui/src/hokusai/backends/sdl2/font.rb +127 -0
  111. data/ui/src/hokusai/backends/sdl2/keys.rb +119 -0
  112. data/ui/src/hokusai/backends/sdl2.rb +529 -0
  113. data/ui/src/hokusai/block.rb +237 -0
  114. data/ui/src/hokusai/blocks/button.rb +100 -0
  115. data/ui/src/hokusai/blocks/checkbox.rb +51 -0
  116. data/ui/src/hokusai/blocks/circle.rb +28 -0
  117. data/ui/src/hokusai/blocks/clipped.rb +23 -0
  118. data/ui/src/hokusai/blocks/cursor.rb +49 -0
  119. data/ui/src/hokusai/blocks/dynamic.rb +37 -0
  120. data/ui/src/hokusai/blocks/empty.rb +10 -0
  121. data/ui/src/hokusai/blocks/hblock.rb +35 -0
  122. data/ui/src/hokusai/blocks/image.rb +18 -0
  123. data/ui/src/hokusai/blocks/input.rb +200 -0
  124. data/ui/src/hokusai/blocks/label.rb +39 -0
  125. data/ui/src/hokusai/blocks/panel.rb +126 -0
  126. data/ui/src/hokusai/blocks/rect.rb +24 -0
  127. data/ui/src/hokusai/blocks/scissor_begin.rb +18 -0
  128. data/ui/src/hokusai/blocks/scissor_end.rb +12 -0
  129. data/ui/src/hokusai/blocks/scrollbar.rb +103 -0
  130. data/ui/src/hokusai/blocks/selectable.rb +77 -0
  131. data/ui/src/hokusai/blocks/svg.rb +20 -0
  132. data/ui/src/hokusai/blocks/text.rb +214 -0
  133. data/ui/src/hokusai/blocks/titlebar/osx.rb +145 -0
  134. data/ui/src/hokusai/blocks/toggle.rb +55 -0
  135. data/ui/src/hokusai/blocks/vblock.rb +35 -0
  136. data/ui/src/hokusai/commands/base.rb +22 -0
  137. data/ui/src/hokusai/commands/circle.rb +47 -0
  138. data/ui/src/hokusai/commands/image.rb +45 -0
  139. data/ui/src/hokusai/commands/rect.rb +158 -0
  140. data/ui/src/hokusai/commands/scissor.rb +22 -0
  141. data/ui/src/hokusai/commands/text.rb +92 -0
  142. data/ui/src/hokusai/commands.rb +87 -0
  143. data/ui/src/hokusai/diff.rb +124 -0
  144. data/ui/src/hokusai/error.rb +3 -0
  145. data/ui/src/hokusai/event.rb +54 -0
  146. data/ui/src/hokusai/events/keyboard.rb +84 -0
  147. data/ui/src/hokusai/events/mouse.rb +172 -0
  148. data/ui/src/hokusai/font.rb +280 -0
  149. data/ui/src/hokusai/meta.rb +152 -0
  150. data/ui/src/hokusai/mounting/loop_entry.rb +230 -0
  151. data/ui/src/hokusai/mounting/mount_entry.rb +74 -0
  152. data/ui/src/hokusai/mounting/update_entry.rb +101 -0
  153. data/ui/src/hokusai/node.rb +98 -0
  154. data/ui/src/hokusai/node_mounter.rb +102 -0
  155. data/ui/src/hokusai/painter.rb +214 -0
  156. data/ui/src/hokusai/publisher.rb +32 -0
  157. data/ui/src/hokusai/style.rb +72 -0
  158. data/ui/src/hokusai/types.rb +266 -0
  159. data/ui/src/hokusai/util/clamping_iterator.rb +202 -0
  160. data/ui/src/hokusai/util/piece_table.rb +111 -0
  161. data/ui/src/hokusai/util/selection.rb +145 -0
  162. data/ui/src/hokusai.rb +120 -0
  163. data/ui/vendor/.gitkeep +0 -0
  164. data/vendor/.gitkeep +0 -0
  165. data/xmake.lua +192 -0
  166. metadata +222 -0
@@ -0,0 +1,665 @@
1
+ #ifndef HOKU_CORE_HML
2
+ #define HOKU_CORE_HML
3
+
4
+ #include "hml.h"
5
+
6
+ char* hoku_get_substr(char* template, int idx, int len)
7
+ {
8
+ char* init = malloc(sizeof(char) * (len + 1));
9
+ if (init == NULL) return NULL;
10
+
11
+ memcpy(init, template + idx, len);
12
+ init[len] = '\0';
13
+ return init;
14
+ }
15
+
16
+ char* hoku_get_tag(TSNode tag, char* template)
17
+ {
18
+ uint32_t start = ts_node_start_byte(tag);
19
+ uint32_t end = ts_node_end_byte(tag);
20
+ return hoku_get_substr(template, start, end - start);
21
+ }
22
+
23
+ void hoku_debug(TSNode node, char* template)
24
+ {
25
+ char* ntype = ts_node_type(node);
26
+ char* val = hoku_get_tag(node, template);
27
+
28
+ printf("[type: %s] ->\n%s\n", ntype, val);
29
+ }
30
+
31
+ void hoku_dump(hoku_ast* c, int level)
32
+ {
33
+ size_t count = hashmap_count(c->props);
34
+ printf("%*s%s", (int)((level) * 2), "", c->type);
35
+ if (c->id != NULL) printf("#%s", c->id);
36
+
37
+ hoku_ast_class_list* head = c->class_list;
38
+ while (head != NULL)
39
+ {
40
+ printf(".%s", head->name);
41
+ head = head->next;
42
+ }
43
+
44
+ printf(" [%zu]", hashmap_count(c->props) + hashmap_count(c->events));
45
+ if (c->loop != NULL)
46
+ {
47
+ printf(" (loop) ");
48
+ }
49
+
50
+ if (c->cond != NULL)
51
+ {
52
+ printf(" (condition) ");
53
+ }
54
+
55
+ printf("\n");
56
+
57
+ size_t iter = 0;
58
+ size_t eiter = 0;
59
+ void *item;
60
+
61
+ while (hashmap_iter(c->props, &iter, &item)) {
62
+ hoku_ast_prop* p = (hoku_ast_prop*) item;
63
+ hoku_ast_func_call* c = p->call;
64
+ char* cname = c->function;
65
+ int alen = c->args_len;
66
+
67
+ printf("%*s prop (%s = %s(%d))\n", (int)((level) * 2), "", p->name, cname, alen);
68
+ }
69
+
70
+ while (hashmap_iter(c->events, &eiter, &item)) {
71
+ hoku_ast_event* p = (hoku_ast_event*) item;
72
+ hoku_ast_func_call* c = p->call;
73
+ char* cname = c->function;
74
+ int alen = c->args_len;
75
+
76
+ printf("%*s event (%s = %s(%d))\n", (int)((level) * 2), "", p->name, cname, alen);
77
+ }
78
+
79
+ hoku_ast* child = c->relations->next_child;
80
+ if (child != NULL)
81
+ {
82
+ hoku_dump(child, level + 1);
83
+ }
84
+
85
+ hoku_ast* sibling = c->relations->next_sibling;
86
+ if (sibling != NULL)
87
+ {
88
+ hoku_dump(sibling, level);
89
+ }
90
+
91
+ return;
92
+ }
93
+
94
+ hoku_ast_func_call* hoku_ast_walk_func(TSNode node, char* template, int level)
95
+ {
96
+ TSNode nname = ts_node_child(node, 0);
97
+ char* name = hoku_get_tag(nname, template);
98
+ hoku_ast_func_call* init;
99
+ hoku_ast_func_call_init(&init, name);
100
+ free(name);
101
+
102
+ TSNode arguments = ts_node_next_sibling(nname);
103
+
104
+ if (!ts_node_is_null(arguments))
105
+ {
106
+ TSNode arg = ts_node_child(arguments, 0);
107
+
108
+ while (!ts_node_is_null(arg))
109
+ {
110
+ if (init->args_len >= 9)
111
+ {
112
+ printf("maxed args!\n");
113
+ break;
114
+ }
115
+ char* str = hoku_get_tag(arg, template);
116
+ init->strargs[init->args_len] = str;
117
+ init->args_len++;
118
+ arg = ts_node_next_sibling(arg);
119
+ }
120
+ }
121
+ return init;
122
+ }
123
+
124
+ hoku_ast_event* hoku_ast_walk_event(TSNode node, char* template, int level)
125
+ {
126
+ char* type = ts_node_type(node);
127
+ TSNode nname = ts_node_child(node, 0);
128
+
129
+ char* name = hoku_get_tag(nname, template);
130
+ hoku_ast_event* init;
131
+ hoku_ast_event_init(&init, name);
132
+ free(name);
133
+
134
+ // get value
135
+ TSNode nvalue = ts_node_next_sibling(nname);
136
+ hoku_ast_func_call* call = hoku_ast_walk_func(nvalue, template, level + 1);
137
+
138
+ init->call = call;
139
+ return init;
140
+ }
141
+
142
+ hoku_ast_prop* hoku_ast_walk_prop(TSNode node, char* template, int level)
143
+ {
144
+ char* type = ts_node_type(node);
145
+ bool computed = false;
146
+ TSNode nname = ts_node_child(node, 0);
147
+
148
+ if (strcmp(ts_node_type(nname), "computed") == 0)
149
+ {
150
+ computed = true;
151
+ nname = ts_node_next_sibling(nname);
152
+ }
153
+
154
+ char* name = hoku_get_tag(nname, template);
155
+
156
+ hoku_ast_prop* init;
157
+ hoku_ast_prop_init(&init, name);
158
+ free(name);
159
+ init->computed = computed;
160
+
161
+ // get value
162
+ TSNode nvalue = ts_node_next_sibling(nname);
163
+ hoku_ast_func_call* call = hoku_ast_walk_func(nvalue, template, level + 1);
164
+
165
+ init->call = call;
166
+ return init;
167
+ }
168
+
169
+ /**
170
+ Rules for the tree:
171
+ type element = element | prop | event
172
+
173
+ element 1
174
+ tag_name -> on 1
175
+ prop -> on 1
176
+ event -> on 1
177
+ element 2 -> child to 1, sibling to 3
178
+ element 3 -> child to 1, sibling to 2
179
+ */
180
+ hoku_ast* hoku_ast_walk_tree(TSNode node, char* template, int level)
181
+ {
182
+ char* ntype = ts_node_type(node);
183
+
184
+ if (strcmp(ntype, "name") == 0)
185
+ {
186
+ char* name = hoku_get_tag(node, template);
187
+ hoku_ast* init;
188
+ hoku_ast_init(&init, name);
189
+ free(name);
190
+ int i = 0;
191
+ TSNode sibling = ts_node_next_sibling(node);
192
+
193
+ // a lateral walk across siblings
194
+ // can be "attributes OR children"
195
+ while (!ts_node_is_null(sibling))
196
+ {
197
+ i++;
198
+ char* stype = ts_node_type(sibling);
199
+ if (strcmp(stype, "attributes") == 0)
200
+ {
201
+ // process attributes
202
+ TSNode attribute = ts_node_child(sibling, 0);
203
+ while (!ts_node_is_null(attribute))
204
+ {
205
+ char* atype = ts_node_type(attribute);
206
+ if (strcmp(atype, "prop") == 0)
207
+ {
208
+ hoku_ast_prop* prop = hoku_ast_walk_prop(attribute, template, level + 1);
209
+ hoku_ast_add_prop(init, prop);
210
+ }
211
+ else if (strcmp(atype, "event") == 0)
212
+ {
213
+ hoku_ast_event* event = hoku_ast_walk_event(attribute, template, level + 1);
214
+ hoku_ast_add_event(init, event);
215
+ }
216
+ else if (strcmp(atype, "style") == 0)
217
+ {
218
+
219
+ char* style_name = hoku_get_tag(attribute, template);
220
+ if (hoku_ast_style_list_prepend(init, style_name) != 0) return NULL;
221
+ }
222
+ else
223
+ {
224
+ hoku_ast_set_error(init, "Expecting `event` or `prop`", attribute, hoku_get_tag(attribute, template));
225
+ }
226
+ attribute = ts_node_next_sibling(attribute);
227
+ }
228
+ }
229
+ else if (strcmp(stype, "selectors") == 0)
230
+ {
231
+ TSNode sel = ts_node_child(sibling, 0);
232
+ while (!ts_node_is_null(sel))
233
+ {
234
+ char* seltype = ts_node_type(sel);
235
+ char* seltag = hoku_get_tag(sel, template);
236
+ if (strcmp(seltype, "id") == 0)
237
+ {
238
+ init->id = seltag;
239
+ }
240
+ else if (strcmp(seltype, "class") == 0)
241
+ {
242
+ hoku_ast_class_list_prepend(init, seltag);
243
+ free(seltag);
244
+ }
245
+
246
+ sel = ts_node_next_sibling(sel);
247
+ }
248
+ }
249
+ else if (strcmp(stype, "children") == 0)
250
+ {
251
+ TSNode child;
252
+ uint32_t child_count = ts_node_child_count(sibling);
253
+ init->child_len = (int) child_count;
254
+ hoku_ast* sinit = NULL;
255
+ for (uint32_t i=0; i<child_count; i++)
256
+ {
257
+ child = ts_node_child(sibling, i);
258
+ char* ctypee = ts_node_type(child);
259
+ hoku_ast* cchild = hoku_ast_walk_tree(child, template, level + 1);
260
+ if (sinit == NULL)
261
+ {
262
+ sinit = cchild;
263
+ }
264
+ else
265
+ {
266
+ hoku_ast_append_sibling(&sinit, cchild);
267
+ }
268
+ }
269
+
270
+ hoku_ast_append_child(&init, sinit);
271
+ }
272
+
273
+ sibling = ts_node_next_sibling(sibling);
274
+ }
275
+
276
+ return init;
277
+ }
278
+ else if (strcmp(ntype, "element") == 0)
279
+ {
280
+ TSNode child = ts_node_child(node, 0);
281
+ return hoku_ast_walk_tree(child, template, level + 1);
282
+ }
283
+ else if (strcmp(ntype, "children") == 0)
284
+ {
285
+ TSNode child = ts_node_child(node, 0);
286
+ return hoku_ast_walk_tree(child, template, level + 1);
287
+ }
288
+ else if (strcmp(ntype, "for_macro") == 0)
289
+ {
290
+ TSNode child = ts_node_named_child(node, 0);
291
+ char* name = hoku_get_tag(child, template);
292
+
293
+ TSNode sibling = ts_node_next_named_sibling(child);
294
+ char* list_name = hoku_get_tag(sibling, template);
295
+ hoku_ast_loop* loop;
296
+ if (hoku_ast_loop_init(&loop, name, list_name) == -1)
297
+ {
298
+ return NULL;
299
+ }
300
+
301
+ free(name);
302
+ free(list_name);
303
+ TSNode children = ts_node_next_named_sibling(sibling);
304
+ hoku_ast* ast = hoku_ast_walk_tree(children, template, level + 1);
305
+
306
+ ast->loop = loop;
307
+
308
+ return ast;
309
+ }
310
+ else if (strcmp(ntype, "if_macro") == 0)
311
+ {
312
+ TSNode child = ts_node_named_child(node, 0);
313
+ hoku_ast_func_call* call = hoku_ast_walk_func(child, template, level);
314
+
315
+ hoku_ast_condition* cond;
316
+ if (hoku_ast_cond_init(&cond, call) == -1)
317
+ {
318
+ return NULL;
319
+ }
320
+
321
+ TSNode ichildren = ts_node_next_named_sibling(child);
322
+ hoku_ast* iast = hoku_ast_walk_tree(ichildren, template, level + 1);
323
+ iast->cond = cond;
324
+
325
+ TSNode echild = ts_node_next_named_sibling(node);
326
+ if (!ts_node_is_null(echild))
327
+ {
328
+ char* etype = ts_node_type(echild);
329
+
330
+ if (strcmp(etype, "else_macro") == 0)
331
+ {
332
+ TSNode eechildren = ts_node_named_child(echild, 0);
333
+ hoku_ast* oast = hoku_ast_walk_tree(eechildren, template, level + 1);
334
+
335
+ iast->else_relations = malloc(sizeof(hoku_ast*));
336
+ if (iast->else_relations == NULL) return NULL;
337
+
338
+ iast->else_relations->next_child = oast;
339
+ iast->else_relations->next_sibling = NULL;
340
+ }
341
+ }
342
+
343
+ return iast;
344
+ }
345
+ else if (strcmp(ntype, "for_if_macro") == 0)
346
+ {
347
+ TSNode child = ts_node_named_child(node, 0);
348
+ char* name = hoku_get_tag(child, template);
349
+
350
+ TSNode sibling = ts_node_next_named_sibling(child);
351
+ char* list_name = hoku_get_tag(sibling, template);
352
+
353
+ TSNode if_func = ts_node_next_named_sibling(sibling);
354
+ hoku_ast_func_call* call = hoku_ast_walk_func(if_func, template, level);
355
+
356
+ hoku_ast_condition* cond;
357
+ if (hoku_ast_cond_init(&cond, call) == -1)
358
+ {
359
+ return NULL;
360
+ }
361
+
362
+ hoku_ast_loop* loop;
363
+ if (hoku_ast_loop_init(&loop, name, list_name) == -1)
364
+ {
365
+ return NULL;
366
+ }
367
+
368
+ free(name);
369
+ free(list_name);
370
+ TSNode children = ts_node_next_named_sibling(if_func);
371
+ hoku_ast* ast = hoku_ast_walk_tree(children, template, level + 1);
372
+ ast->loop = loop;
373
+ ast->cond = cond;
374
+
375
+ TSNode echild = ts_node_next_named_sibling(node);
376
+
377
+ if (!ts_node_is_null(echild))
378
+ {
379
+ char* etype = ts_node_type(echild);
380
+
381
+ if (strcmp(etype, "else_macro") == 0)
382
+ {
383
+ TSNode eechildren = ts_node_named_child(echild, 0);
384
+ hoku_ast* oast = hoku_ast_walk_tree(eechildren, template, level + 1);
385
+ ast->else_relations = malloc(sizeof(hoku_ast*));
386
+ if (ast->else_relations == NULL) return NULL;
387
+
388
+ ast->else_relations->next_child = oast;
389
+ ast->else_relations->next_sibling = NULL;
390
+ }
391
+ }
392
+
393
+ return ast;
394
+ }
395
+ else
396
+ {
397
+ return NULL;
398
+ }
399
+ }
400
+
401
+ hoku_style_attribute* hoku_walk_style_attributes(TSNode node, char* template)
402
+ {
403
+ TSNode attribute_node = ts_node_named_child(node, 0);
404
+ hoku_style_attribute* top = NULL;
405
+
406
+ while (!ts_node_is_null(attribute_node))
407
+ {
408
+ TSNode attribute_name_node = ts_node_named_child(attribute_node, 0);
409
+ char* attribute_name = hoku_get_tag(attribute_name_node, template);
410
+
411
+
412
+ TSNode value_node = ts_node_next_named_sibling(attribute_name_node);
413
+ char* value_node_type = ts_node_type(value_node);
414
+
415
+ enum HOKU_STYLE_TYPE type;
416
+ char* value = NULL;
417
+ char* function_name = NULL;
418
+
419
+ if (strcmp(value_node_type, "style_int") == 0)
420
+ {
421
+ type = HOKU_STYLE_TYPE_INT;
422
+ value = hoku_get_tag(value_node, template);
423
+
424
+ }
425
+ else if (strcmp(value_node_type, "style_float") == 0)
426
+ {
427
+ type = HOKU_STYLE_TYPE_FLOAT;
428
+ value = hoku_get_tag(value_node, template);
429
+ }
430
+ else if (strcmp(value_node_type, "style_bool") == 0)
431
+ {
432
+ type = HOKU_STYLE_TYPE_BOOL;
433
+ value = hoku_get_tag(value_node, template);
434
+
435
+ }
436
+ else if (strcmp(value_node_type, "style_string") == 0)
437
+ {
438
+ type = HOKU_STYLE_TYPE_STRING;
439
+ value = hoku_get_tag(value_node, template);
440
+
441
+ }
442
+ else if (strcmp(value_node_type, "style_func") == 0)
443
+ {
444
+ type = HOKU_STYLE_TYPE_FUNC;
445
+ TSNode func_name_node = ts_node_named_child(value_node, 0);
446
+
447
+ function_name = hoku_get_tag(func_name_node, template);
448
+
449
+ TSNode func_value_node = ts_node_next_named_sibling(func_name_node);
450
+ value = hoku_get_tag(func_value_node, template);
451
+ }
452
+
453
+ hoku_style_attribute* attribute;
454
+ hoku_style_attribute_init(&attribute, attribute_name, value, type);
455
+ if (attribute == NULL) return NULL;
456
+
457
+ if (function_name)
458
+ {
459
+ printf("setting func name!\n");
460
+ attribute->function_name = strdup(function_name);
461
+ if (attribute->function_name == NULL) return NULL;
462
+ free(function_name);
463
+ printf("fter set func name\n");
464
+ }
465
+
466
+ free(attribute_name);
467
+ free(value);
468
+
469
+ printf("after free!\n");
470
+
471
+ if (top == NULL)
472
+ {
473
+ top = attribute;
474
+ }
475
+ else
476
+ {
477
+ printf("append!\n %p, %p\n", top, attribute);
478
+ hoku_style_attribute_append(top, attribute);
479
+ printf("after append\n");
480
+ }
481
+
482
+ attribute_node = ts_node_next_named_sibling(attribute_node);
483
+ }
484
+
485
+ return top;
486
+ }
487
+
488
+ hoku_style* hoku_walk_style_template(TSNode node, char* template)
489
+ {
490
+ TSNode style_node = ts_node_named_child(node, 0);
491
+ hoku_style* top = NULL;
492
+
493
+ while (!ts_node_is_null(style_node))
494
+ {
495
+ TSNode style_name_node = ts_node_named_child(style_node, 0);
496
+ char* style_name = hoku_get_tag(style_name_node, template);
497
+ hoku_style* style;
498
+ hoku_style_init(&style, style_name);
499
+
500
+ if (style == NULL) return NULL;
501
+
502
+ TSNode style_children_node = ts_node_next_named_sibling(style_name_node);
503
+
504
+ printf("walking attributes!\n");
505
+ hoku_style_attribute* attributes = hoku_walk_style_attributes(style_children_node, template);
506
+ printf("after walk attributes!\n");
507
+ if (attributes == NULL) return NULL;
508
+ style->attributes = attributes;
509
+
510
+ if (top == NULL)
511
+ {
512
+ top = style;
513
+ }
514
+ else
515
+ {
516
+ hoku_style_append(top, style);
517
+ }
518
+
519
+ style_node = ts_node_next_named_sibling(style_node);
520
+ }
521
+
522
+ return top;
523
+ }
524
+
525
+ int hoku_style_from_template(hoku_style** out, char* template)
526
+ {
527
+ TSParser* parser = ts_parser_new();
528
+ if (parser == NULL) return -1;
529
+
530
+ ts_parser_set_language(parser, tree_sitter_hml());
531
+ TSTree* tree = ts_parser_parse_string(parser, NULL, template, strlen(template));
532
+ if (tree == NULL)
533
+ {
534
+ ts_parser_delete(parser);
535
+ return -1;
536
+ }
537
+
538
+ TSNode document = ts_tree_root_node(tree);
539
+ if (strcmp(ts_node_type(document), "document") != 0)
540
+ {
541
+ ts_tree_delete(tree);
542
+ ts_parser_delete(parser);
543
+
544
+ return -1;
545
+ }
546
+
547
+ TSNode templ = ts_node_named_child(document, 0);
548
+ if (strcmp(ts_node_type(templ), "style_template") != 0)
549
+ {
550
+ ts_tree_delete(tree);
551
+ ts_parser_delete(parser);
552
+
553
+ return -1;
554
+ }
555
+
556
+ hoku_style* style = hoku_walk_style_template(templ, template);
557
+
558
+ printf("after walk style!\n");
559
+ if (style == NULL)
560
+ {
561
+ ts_tree_delete(tree);
562
+ ts_parser_delete(parser);
563
+
564
+ return -1;
565
+ }
566
+
567
+ *out = style;
568
+ return 0;
569
+ }
570
+
571
+ int hoku_ast_from_template(hoku_ast** out, char* type, char* template)
572
+ {
573
+ hoku_ast* init;
574
+ if (hoku_ast_init(&init, type) == -1) return -1;
575
+
576
+ hoku_style* style = NULL;
577
+
578
+ TSParser* parser = ts_parser_new();
579
+ if (parser == NULL)
580
+ {
581
+ free(init);
582
+ return -1;
583
+ }
584
+
585
+ ts_parser_set_language(parser, tree_sitter_hml());
586
+ TSTree* tree = ts_parser_parse_string(parser, NULL, template, strlen(template));
587
+ if (tree == NULL)
588
+ {
589
+ ts_parser_delete(parser);
590
+ free(init);
591
+ return -1;
592
+ }
593
+
594
+ TSNode document = ts_tree_root_node(tree);
595
+ if (strcmp(ts_node_type(document), "document") != 0)
596
+ {
597
+ hoku_ast_set_error(init, "Expecting document (starts with [template])", document, hoku_get_tag(document, template));
598
+ *out = init;
599
+ return 0;
600
+ }
601
+
602
+ TSNode templ = ts_node_named_child(document, 0);
603
+ if (strcmp(ts_node_type(templ), "template") != 0 && strcmp(ts_node_type(templ), "style_template") != 0)
604
+ {
605
+ hoku_ast_set_error(init, "Expecting template", templ, hoku_get_tag(templ, template));
606
+ *out = init;
607
+ return 0;
608
+ }
609
+
610
+ if (strcmp(ts_node_type(templ), "style_template") == 0)
611
+ {
612
+ style = hoku_walk_style_template(templ, template);
613
+ templ = ts_node_next_named_sibling(templ);
614
+
615
+ if (ts_node_is_null(templ) || strcmp(ts_node_type(templ), "template") != 0)
616
+ {
617
+ hoku_ast_set_error(init, "Expecting template, got only style template", templ, "ERROR");
618
+ *out = init;
619
+ return 0;
620
+ }
621
+ }
622
+
623
+ TSNode child = ts_node_named_child(templ, 0);
624
+ hoku_ast* roots = NULL;
625
+ char* ntype = ts_node_type(child);
626
+
627
+ while (!ts_node_is_null(child))
628
+ {
629
+ hoku_ast* children;
630
+ children = hoku_ast_walk_tree(child, template, 0);
631
+
632
+ if (children == NULL)
633
+ {
634
+ char* ntype = ts_node_type(child);
635
+ }
636
+
637
+ if (roots == NULL)
638
+ {
639
+ roots = children;
640
+ }
641
+ else
642
+ {
643
+ hoku_ast_append_sibling(&roots, children);
644
+ }
645
+
646
+ child = ts_node_next_named_sibling(child);
647
+ }
648
+
649
+ hoku_ast_append_child(&init, roots);
650
+
651
+ templ = ts_node_next_named_sibling(templ);
652
+ if (!ts_node_is_null(templ) && strcmp(ts_node_type(templ), "style_template") == 0)
653
+ {
654
+ style = hoku_walk_style_template(templ, template);
655
+ }
656
+
657
+ init->styles = style;
658
+
659
+ ts_tree_delete(tree);
660
+ ts_parser_delete(parser);
661
+
662
+ *out = init;
663
+ return 0;
664
+ }
665
+ #endif
@@ -0,0 +1,11 @@
1
+ #ifndef HOKU_CORE_HML_H
2
+ #define HOKU_CORE_HML_H
3
+
4
+ #include "style.h"
5
+ #include "ast.h"
6
+
7
+ int hoku_style_from_template(hoku_style** out, char* template);
8
+ int hoku_ast_from_template(hoku_ast** out, char* type, char* template);
9
+ void hoku_dump(hoku_ast* c, int level);
10
+
11
+ #endif