authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-27 21:10:38-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-27 21:10:38-07:00
logb6354ddd5a4840d856899eca63267785355cbd3e
tree34314c10b8e1f7986395c36011c99c89a2efc20e
parentc281533638dd08bb84f4f538fd8c5ae85791d034

move AST rendering code to separate file


11 files changed, 789 insertions(+), 592 deletions(-)

CMakeLists.txt+1
...@@ -25,6 +25,7 @@ include_directories(...@@ -25,6 +25,7 @@ include_directories(
25)25)
2626
27set(ZIG_SOURCES27set(ZIG_SOURCES
28 "${CMAKE_SOURCE_DIR}/src/ast_render.cpp"
28 "${CMAKE_SOURCE_DIR}/src/bignum.cpp"29 "${CMAKE_SOURCE_DIR}/src/bignum.cpp"
29 "${CMAKE_SOURCE_DIR}/src/tokenizer.cpp"30 "${CMAKE_SOURCE_DIR}/src/tokenizer.cpp"
30 "${CMAKE_SOURCE_DIR}/src/parser.cpp"31 "${CMAKE_SOURCE_DIR}/src/parser.cpp"
doc/targets.md+3
...@@ -11,3 +11,6 @@ for the target when an exported or external function has a byvalue struct....@@ -11,3 +11,6 @@ for the target when an exported or external function has a byvalue struct.
11Write the target-specific code in std.zig.11Write the target-specific code in std.zig.
1212
13Update the C integer types to be the correct size for the target.13Update the C integer types to be the correct size for the target.
14
15Add the conditional compilation code for the page size global. It is hardcoded
16for each target.
src/all_types.hpp+1
...@@ -894,6 +894,7 @@ struct ImportTableEntry {...@@ -894,6 +894,7 @@ struct ImportTableEntry {
894 ZigList<int> *line_offsets;894 ZigList<int> *line_offsets;
895 BlockContext *block_context;895 BlockContext *block_context;
896 ZigList<ImporterInfo> importers;896 ZigList<ImporterInfo> importers;
897 bool is_c_import;
897898
898 // reminder: hash tables must be initialized before use899 // reminder: hash tables must be initialized before use
899 HashMap<Buf *, FnTableEntry *, buf_hash, buf_eql_buf> fn_table;900 HashMap<Buf *, FnTableEntry *, buf_hash, buf_eql_buf> fn_table;
src/analyze.cpp+14-10
...@@ -1039,15 +1039,15 @@ static void resolve_error_value_decl(CodeGen *g, ImportTableEntry *import, AstNo...@@ -1039,15 +1039,15 @@ static void resolve_error_value_decl(CodeGen *g, ImportTableEntry *import, AstNo
1039 }1039 }
1040}1040}
10411041
1042static void resolve_c_import_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {1042static void resolve_c_import_decl(CodeGen *g, ImportTableEntry *parent_import, AstNode *node) {
1043 assert(node->type == NodeTypeCImport);1043 assert(node->type == NodeTypeCImport);
10441044
1045 AstNode *block_node = node->data.c_import.block;1045 AstNode *block_node = node->data.c_import.block;
10461046
1047 BlockContext *child_context = new_block_context(node, import->block_context);1047 BlockContext *child_context = new_block_context(node, parent_import->block_context);
1048 child_context->c_import_buf = buf_alloc();1048 child_context->c_import_buf = buf_alloc();
10491049
1050 TypeTableEntry *resolved_type = analyze_block_expr(g, import, child_context,1050 TypeTableEntry *resolved_type = analyze_block_expr(g, parent_import, child_context,
1051 g->builtin_types.entry_void, block_node);1051 g->builtin_types.entry_void, block_node);
10521052
1053 if (resolved_type->id == TypeTableEntryIdInvalid) {1053 if (resolved_type->id == TypeTableEntryIdInvalid) {
...@@ -1055,23 +1055,27 @@ static void resolve_c_import_decl(CodeGen *g, ImportTableEntry *import, AstNode...@@ -1055,23 +1055,27 @@ static void resolve_c_import_decl(CodeGen *g, ImportTableEntry *import, AstNode
1055 }1055 }
10561056
1057 find_libc_path(g);1057 find_libc_path(g);
1058
1059 ImportTableEntry child_import = {0};
1060 ZigList<ErrorMsg *> errors = {0};
1061
1058 int err;1062 int err;
1059 ParseH parse_h = {{0}};1063 if ((err = parse_h_buf(&child_import, &errors, child_context->c_import_buf, g->clang_argv, g->clang_argv_len,
1060 if ((err = parse_h_buf(&parse_h, child_context->c_import_buf, g->clang_argv, g->clang_argv_len,
1061 buf_ptr(g->libc_include_path))))1064 buf_ptr(g->libc_include_path))))
1062 {1065 {
1063 zig_panic("unable to parse h file: %s\n", err_str(err));1066 zig_panic("unable to parse h file: %s\n", err_str(err));
1064 }1067 }
10651068
1066 if (parse_h.errors.length > 0) {1069 if (errors.length > 0) {
1067 ErrorMsg *parent_err_msg = add_node_error(g, node, buf_sprintf("C import failed"));1070 ErrorMsg *parent_err_msg = add_node_error(g, node, buf_sprintf("C import failed"));
1068 for (int i = 0; i < parse_h.errors.length; i += 1) {1071 for (int i = 0; i < errors.length; i += 1) {
1069 ErrorMsg *err_msg = parse_h.errors.at(i);1072 ErrorMsg *err_msg = errors.at(i);
1070 err_msg_add_note(parent_err_msg, err_msg);1073 err_msg_add_note(parent_err_msg, err_msg);
1071 }1074 }
1072 } else {1075 return;
1073 zig_panic("TODO integrate the parsed AST");
1074 }1076 }
1077
1078 zig_panic("TODO integrate the AST");
1075}1079}
10761080
1077static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {1081static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {
src/ast_render.cpp created+682
...@@ -0,0 +1,682 @@
1#include "ast_render.hpp"
2
3#include <stdio.h>
4
5static const char *bin_op_str(BinOpType bin_op) {
6 switch (bin_op) {
7 case BinOpTypeInvalid: return "(invalid)";
8 case BinOpTypeBoolOr: return "||";
9 case BinOpTypeBoolAnd: return "&&";
10 case BinOpTypeCmpEq: return "==";
11 case BinOpTypeCmpNotEq: return "!=";
12 case BinOpTypeCmpLessThan: return "<";
13 case BinOpTypeCmpGreaterThan: return ">";
14 case BinOpTypeCmpLessOrEq: return "<=";
15 case BinOpTypeCmpGreaterOrEq: return ">=";
16 case BinOpTypeBinOr: return "|";
17 case BinOpTypeBinXor: return "^";
18 case BinOpTypeBinAnd: return "&";
19 case BinOpTypeBitShiftLeft: return "<<";
20 case BinOpTypeBitShiftRight: return ">>";
21 case BinOpTypeAdd: return "+";
22 case BinOpTypeSub: return "-";
23 case BinOpTypeMult: return "*";
24 case BinOpTypeDiv: return "/";
25 case BinOpTypeMod: return "%";
26 case BinOpTypeAssign: return "=";
27 case BinOpTypeAssignTimes: return "*=";
28 case BinOpTypeAssignDiv: return "/=";
29 case BinOpTypeAssignMod: return "%=";
30 case BinOpTypeAssignPlus: return "+=";
31 case BinOpTypeAssignMinus: return "-=";
32 case BinOpTypeAssignBitShiftLeft: return "<<=";
33 case BinOpTypeAssignBitShiftRight: return ">>=";
34 case BinOpTypeAssignBitAnd: return "&=";
35 case BinOpTypeAssignBitXor: return "^=";
36 case BinOpTypeAssignBitOr: return "|=";
37 case BinOpTypeAssignBoolAnd: return "&&=";
38 case BinOpTypeAssignBoolOr: return "||=";
39 case BinOpTypeUnwrapMaybe: return "??";
40 case BinOpTypeStrCat: return "++";
41 }
42}
43
44static const char *prefix_op_str(PrefixOp prefix_op) {
45 switch (prefix_op) {
46 case PrefixOpInvalid: return "(invalid)";
47 case PrefixOpNegation: return "-";
48 case PrefixOpBoolNot: return "!";
49 case PrefixOpBinNot: return "~";
50 case PrefixOpAddressOf: return "&";
51 case PrefixOpConstAddressOf: return "&const ";
52 case PrefixOpDereference: return "*";
53 case PrefixOpMaybe: return "?";
54 case PrefixOpError: return "%";
55 case PrefixOpUnwrapError: return "%%";
56 }
57}
58
59static const char *return_prefix_str(ReturnKind kind) {
60 switch (kind) {
61 case ReturnKindError: return "%";
62 case ReturnKindMaybe: return "?";
63 case ReturnKindUnconditional: return "";
64 }
65}
66
67static const char *visib_mod_string(VisibMod mod) {
68 switch (mod) {
69 case VisibModPub: return "pub ";
70 case VisibModPrivate: return "";
71 case VisibModExport: return "export ";
72 }
73}
74
75static const char *extern_string(bool is_extern) {
76 return is_extern ? "export " : "";
77}
78
79static const char *const_or_var_string(bool is_const) {
80 return is_const ? "const" : "var";
81}
82
83static const char *node_type_str(NodeType node_type) {
84 switch (node_type) {
85 case NodeTypeRoot:
86 return "Root";
87 case NodeTypeRootExportDecl:
88 return "RootExportDecl";
89 case NodeTypeFnDef:
90 return "FnDef";
91 case NodeTypeFnDecl:
92 return "FnDecl";
93 case NodeTypeFnProto:
94 return "FnProto";
95 case NodeTypeParamDecl:
96 return "ParamDecl";
97 case NodeTypeBlock:
98 return "Block";
99 case NodeTypeBinOpExpr:
100 return "BinOpExpr";
101 case NodeTypeUnwrapErrorExpr:
102 return "UnwrapErrorExpr";
103 case NodeTypeFnCallExpr:
104 return "FnCallExpr";
105 case NodeTypeArrayAccessExpr:
106 return "ArrayAccessExpr";
107 case NodeTypeSliceExpr:
108 return "SliceExpr";
109 case NodeTypeDirective:
110 return "Directive";
111 case NodeTypeReturnExpr:
112 return "ReturnExpr";
113 case NodeTypeVariableDeclaration:
114 return "VariableDeclaration";
115 case NodeTypeErrorValueDecl:
116 return "ErrorValueDecl";
117 case NodeTypeNumberLiteral:
118 return "NumberLiteral";
119 case NodeTypeStringLiteral:
120 return "StringLiteral";
121 case NodeTypeCharLiteral:
122 return "CharLiteral";
123 case NodeTypeSymbol:
124 return "Symbol";
125 case NodeTypePrefixOpExpr:
126 return "PrefixOpExpr";
127 case NodeTypeImport:
128 return "Import";
129 case NodeTypeCImport:
130 return "CImport";
131 case NodeTypeBoolLiteral:
132 return "BoolLiteral";
133 case NodeTypeNullLiteral:
134 return "NullLiteral";
135 case NodeTypeUndefinedLiteral:
136 return "UndefinedLiteral";
137 case NodeTypeIfBoolExpr:
138 return "IfBoolExpr";
139 case NodeTypeIfVarExpr:
140 return "IfVarExpr";
141 case NodeTypeWhileExpr:
142 return "WhileExpr";
143 case NodeTypeForExpr:
144 return "ForExpr";
145 case NodeTypeSwitchExpr:
146 return "SwitchExpr";
147 case NodeTypeSwitchProng:
148 return "SwitchProng";
149 case NodeTypeSwitchRange:
150 return "SwitchRange";
151 case NodeTypeLabel:
152 return "Label";
153 case NodeTypeGoto:
154 return "Goto";
155 case NodeTypeBreak:
156 return "Break";
157 case NodeTypeContinue:
158 return "Continue";
159 case NodeTypeAsmExpr:
160 return "AsmExpr";
161 case NodeTypeFieldAccessExpr:
162 return "FieldAccessExpr";
163 case NodeTypeStructDecl:
164 return "StructDecl";
165 case NodeTypeStructField:
166 return "StructField";
167 case NodeTypeStructValueField:
168 return "StructValueField";
169 case NodeTypeContainerInitExpr:
170 return "ContainerInitExpr";
171 case NodeTypeArrayType:
172 return "ArrayType";
173 case NodeTypeErrorType:
174 return "ErrorType";
175 }
176}
177
178
179void ast_print(FILE *f, AstNode *node, int indent) {
180 for (int i = 0; i < indent; i += 1) {
181 fprintf(f, " ");
182 }
183 assert(node->type == NodeTypeRoot || *node->parent_field == node);
184
185 switch (node->type) {
186 case NodeTypeRoot:
187 fprintf(f, "%s\n", node_type_str(node->type));
188 for (int i = 0; i < node->data.root.top_level_decls.length; i += 1) {
189 AstNode *child = node->data.root.top_level_decls.at(i);
190 ast_print(f, child, indent + 2);
191 }
192 break;
193 case NodeTypeRootExportDecl:
194 fprintf(f, "%s %s '%s'\n", node_type_str(node->type),
195 buf_ptr(&node->data.root_export_decl.type),
196 buf_ptr(&node->data.root_export_decl.name));
197 break;
198 case NodeTypeFnDef:
199 {
200 fprintf(f, "%s\n", node_type_str(node->type));
201 AstNode *child = node->data.fn_def.fn_proto;
202 ast_print(f, child, indent + 2);
203 ast_print(f, node->data.fn_def.body, indent + 2);
204 break;
205 }
206 case NodeTypeFnProto:
207 {
208 Buf *name_buf = &node->data.fn_proto.name;
209 fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf));
210
211 for (int i = 0; i < node->data.fn_proto.params.length; i += 1) {
212 AstNode *child = node->data.fn_proto.params.at(i);
213 ast_print(f, child, indent + 2);
214 }
215
216 ast_print(f, node->data.fn_proto.return_type, indent + 2);
217
218 break;
219 }
220 case NodeTypeBlock:
221 {
222 fprintf(f, "%s\n", node_type_str(node->type));
223 for (int i = 0; i < node->data.block.statements.length; i += 1) {
224 AstNode *child = node->data.block.statements.at(i);
225 ast_print(f, child, indent + 2);
226 }
227 break;
228 }
229 case NodeTypeParamDecl:
230 {
231 Buf *name_buf = &node->data.param_decl.name;
232 fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf));
233
234 ast_print(f, node->data.param_decl.type, indent + 2);
235
236 break;
237 }
238 case NodeTypeReturnExpr:
239 {
240 const char *prefix_str = return_prefix_str(node->data.return_expr.kind);
241 fprintf(f, "%s%s\n", prefix_str, node_type_str(node->type));
242 if (node->data.return_expr.expr)
243 ast_print(f, node->data.return_expr.expr, indent + 2);
244 break;
245 }
246 case NodeTypeVariableDeclaration:
247 {
248 Buf *name_buf = &node->data.variable_declaration.symbol;
249 fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf));
250 if (node->data.variable_declaration.type)
251 ast_print(f, node->data.variable_declaration.type, indent + 2);
252 if (node->data.variable_declaration.expr)
253 ast_print(f, node->data.variable_declaration.expr, indent + 2);
254 break;
255 }
256 case NodeTypeErrorValueDecl:
257 {
258 Buf *name_buf = &node->data.error_value_decl.name;
259 fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf));
260 break;
261 }
262 case NodeTypeFnDecl:
263 fprintf(f, "%s\n", node_type_str(node->type));
264 ast_print(f, node->data.fn_decl.fn_proto, indent + 2);
265 break;
266 case NodeTypeBinOpExpr:
267 fprintf(f, "%s %s\n", node_type_str(node->type),
268 bin_op_str(node->data.bin_op_expr.bin_op));
269 ast_print(f, node->data.bin_op_expr.op1, indent + 2);
270 ast_print(f, node->data.bin_op_expr.op2, indent + 2);
271 break;
272 case NodeTypeUnwrapErrorExpr:
273 fprintf(f, "%s\n", node_type_str(node->type));
274 ast_print(f, node->data.unwrap_err_expr.op1, indent + 2);
275 if (node->data.unwrap_err_expr.symbol) {
276 ast_print(f, node->data.unwrap_err_expr.symbol, indent + 2);
277 }
278 ast_print(f, node->data.unwrap_err_expr.op2, indent + 2);
279 break;
280 case NodeTypeFnCallExpr:
281 fprintf(f, "%s\n", node_type_str(node->type));
282 ast_print(f, node->data.fn_call_expr.fn_ref_expr, indent + 2);
283 for (int i = 0; i < node->data.fn_call_expr.params.length; i += 1) {
284 AstNode *child = node->data.fn_call_expr.params.at(i);
285 ast_print(f, child, indent + 2);
286 }
287 break;
288 case NodeTypeArrayAccessExpr:
289 fprintf(f, "%s\n", node_type_str(node->type));
290 ast_print(f, node->data.array_access_expr.array_ref_expr, indent + 2);
291 ast_print(f, node->data.array_access_expr.subscript, indent + 2);
292 break;
293 case NodeTypeSliceExpr:
294 fprintf(f, "%s\n", node_type_str(node->type));
295 ast_print(f, node->data.slice_expr.array_ref_expr, indent + 2);
296 ast_print(f, node->data.slice_expr.start, indent + 2);
297 if (node->data.slice_expr.end) {
298 ast_print(f, node->data.slice_expr.end, indent + 2);
299 }
300 break;
301 case NodeTypeDirective:
302 fprintf(f, "%s\n", node_type_str(node->type));
303 break;
304 case NodeTypePrefixOpExpr:
305 fprintf(f, "%s %s\n", node_type_str(node->type),
306 prefix_op_str(node->data.prefix_op_expr.prefix_op));
307 ast_print(f, node->data.prefix_op_expr.primary_expr, indent + 2);
308 break;
309 case NodeTypeNumberLiteral:
310 {
311 NumLit kind = node->data.number_literal.kind;
312 const char *name = node_type_str(node->type);
313 if (kind == NumLitUInt) {
314 fprintf(f, "%s uint %" PRIu64 "\n", name, node->data.number_literal.data.x_uint);
315 } else {
316 fprintf(f, "%s float %f\n", name, node->data.number_literal.data.x_float);
317 }
318 break;
319 }
320 case NodeTypeStringLiteral:
321 {
322 const char *c = node->data.string_literal.c ? "c" : "";
323 fprintf(f, "StringLiteral %s'%s'\n", c,
324 buf_ptr(&node->data.string_literal.buf));
325 break;
326 }
327 case NodeTypeCharLiteral:
328 {
329 fprintf(f, "%s '%c'\n", node_type_str(node->type), node->data.char_literal.value);
330 break;
331 }
332 case NodeTypeSymbol:
333 fprintf(f, "Symbol %s\n", buf_ptr(&node->data.symbol_expr.symbol));
334 break;
335 case NodeTypeImport:
336 fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.import.path));
337 break;
338 case NodeTypeCImport:
339 fprintf(f, "%s\n", node_type_str(node->type));
340 ast_print(f, node->data.c_import.block, indent + 2);
341 break;
342 case NodeTypeBoolLiteral:
343 fprintf(f, "%s '%s'\n", node_type_str(node->type),
344 node->data.bool_literal.value ? "true" : "false");
345 break;
346 case NodeTypeNullLiteral:
347 fprintf(f, "%s\n", node_type_str(node->type));
348 break;
349 case NodeTypeIfBoolExpr:
350 fprintf(f, "%s\n", node_type_str(node->type));
351 if (node->data.if_bool_expr.condition)
352 ast_print(f, node->data.if_bool_expr.condition, indent + 2);
353 ast_print(f, node->data.if_bool_expr.then_block, indent + 2);
354 if (node->data.if_bool_expr.else_node)
355 ast_print(f, node->data.if_bool_expr.else_node, indent + 2);
356 break;
357 case NodeTypeIfVarExpr:
358 {
359 Buf *name_buf = &node->data.if_var_expr.var_decl.symbol;
360 fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf));
361 if (node->data.if_var_expr.var_decl.type)
362 ast_print(f, node->data.if_var_expr.var_decl.type, indent + 2);
363 if (node->data.if_var_expr.var_decl.expr)
364 ast_print(f, node->data.if_var_expr.var_decl.expr, indent + 2);
365 ast_print(f, node->data.if_var_expr.then_block, indent + 2);
366 if (node->data.if_var_expr.else_node)
367 ast_print(f, node->data.if_var_expr.else_node, indent + 2);
368 break;
369 }
370 case NodeTypeWhileExpr:
371 fprintf(f, "%s\n", node_type_str(node->type));
372 ast_print(f, node->data.while_expr.condition, indent + 2);
373 ast_print(f, node->data.while_expr.body, indent + 2);
374 break;
375 case NodeTypeForExpr:
376 fprintf(f, "%s\n", node_type_str(node->type));
377 ast_print(f, node->data.for_expr.elem_node, indent + 2);
378 ast_print(f, node->data.for_expr.array_expr, indent + 2);
379 if (node->data.for_expr.index_node) {
380 ast_print(f, node->data.for_expr.index_node, indent + 2);
381 }
382 ast_print(f, node->data.for_expr.body, indent + 2);
383 break;
384 case NodeTypeSwitchExpr:
385 fprintf(f, "%s\n", node_type_str(node->type));
386 ast_print(f, node->data.switch_expr.expr, indent + 2);
387 for (int i = 0; i < node->data.switch_expr.prongs.length; i += 1) {
388 AstNode *child_node = node->data.switch_expr.prongs.at(i);
389 ast_print(f, child_node, indent + 2);
390 }
391 break;
392 case NodeTypeSwitchProng:
393 fprintf(f, "%s\n", node_type_str(node->type));
394 for (int i = 0; i < node->data.switch_prong.items.length; i += 1) {
395 AstNode *child_node = node->data.switch_prong.items.at(i);
396 ast_print(f, child_node, indent + 2);
397 }
398 if (node->data.switch_prong.var_symbol) {
399 ast_print(f, node->data.switch_prong.var_symbol, indent + 2);
400 }
401 ast_print(f, node->data.switch_prong.expr, indent + 2);
402 break;
403 case NodeTypeSwitchRange:
404 fprintf(f, "%s\n", node_type_str(node->type));
405 ast_print(f, node->data.switch_range.start, indent + 2);
406 ast_print(f, node->data.switch_range.end, indent + 2);
407 break;
408 case NodeTypeLabel:
409 fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.label.name));
410 break;
411 case NodeTypeGoto:
412 fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.goto_expr.name));
413 break;
414 case NodeTypeBreak:
415 fprintf(f, "%s\n", node_type_str(node->type));
416 break;
417 case NodeTypeContinue:
418 fprintf(f, "%s\n", node_type_str(node->type));
419 break;
420 case NodeTypeUndefinedLiteral:
421 fprintf(f, "%s\n", node_type_str(node->type));
422 break;
423 case NodeTypeAsmExpr:
424 fprintf(f, "%s\n", node_type_str(node->type));
425 break;
426 case NodeTypeFieldAccessExpr:
427 fprintf(f, "%s '%s'\n", node_type_str(node->type),
428 buf_ptr(&node->data.field_access_expr.field_name));
429 ast_print(f, node->data.field_access_expr.struct_expr, indent + 2);
430 break;
431 case NodeTypeStructDecl:
432 fprintf(f, "%s '%s'\n",
433 node_type_str(node->type), buf_ptr(&node->data.struct_decl.name));
434 for (int i = 0; i < node->data.struct_decl.fields.length; i += 1) {
435 AstNode *child = node->data.struct_decl.fields.at(i);
436 ast_print(f, child, indent + 2);
437 }
438 for (int i = 0; i < node->data.struct_decl.fns.length; i += 1) {
439 AstNode *child = node->data.struct_decl.fns.at(i);
440 ast_print(f, child, indent + 2);
441 }
442 break;
443 case NodeTypeStructField:
444 fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.struct_field.name));
445 if (node->data.struct_field.type) {
446 ast_print(f, node->data.struct_field.type, indent + 2);
447 }
448 break;
449 case NodeTypeStructValueField:
450 fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.struct_val_field.name));
451 ast_print(f, node->data.struct_val_field.expr, indent + 2);
452 break;
453 case NodeTypeContainerInitExpr:
454 fprintf(f, "%s\n", node_type_str(node->type));
455 ast_print(f, node->data.container_init_expr.type, indent + 2);
456 for (int i = 0; i < node->data.container_init_expr.entries.length; i += 1) {
457 AstNode *child = node->data.container_init_expr.entries.at(i);
458 ast_print(f, child, indent + 2);
459 }
460 break;
461 case NodeTypeArrayType:
462 {
463 const char *const_str = node->data.array_type.is_const ? "const" : "var";
464 fprintf(f, "%s %s\n", node_type_str(node->type), const_str);
465 if (node->data.array_type.size) {
466 ast_print(f, node->data.array_type.size, indent + 2);
467 }
468 ast_print(f, node->data.array_type.child_type, indent + 2);
469 break;
470 }
471 case NodeTypeErrorType:
472 fprintf(f, "%s\n", node_type_str(node->type));
473 break;
474 }
475}
476
477struct AstRender {
478 int indent;
479 int indent_size;
480 FILE *f;
481};
482
483static void print_indent(AstRender *ar) {
484 for (int i = 0; i < ar->indent; i += 1) {
485 fprintf(ar->f, " ");
486 }
487}
488
489static void render_node(AstRender *ar, AstNode *node) {
490 assert(node->type == NodeTypeRoot || *node->parent_field == node);
491
492 switch (node->type) {
493 case NodeTypeRoot:
494 for (int i = 0; i < node->data.root.top_level_decls.length; i += 1) {
495 AstNode *child = node->data.root.top_level_decls.at(i);
496 print_indent(ar);
497 render_node(ar, child);
498
499 if (child->type == NodeTypeImport ||
500 child->type == NodeTypeVariableDeclaration ||
501 child->type == NodeTypeErrorValueDecl)
502 {
503 fprintf(ar->f, ";");
504 }
505 fprintf(ar->f, "\n");
506 }
507 break;
508 case NodeTypeRootExportDecl:
509 zig_panic("TODO");
510 case NodeTypeFnProto:
511 {
512 const char *fn_name = buf_ptr(&node->data.fn_proto.name);
513 const char *pub_str = visib_mod_string(node->data.fn_proto.visib_mod);
514 const char *extern_str = extern_string(node->data.fn_proto.is_extern);
515 fprintf(ar->f, "%s%sfn %s(", pub_str, extern_str, fn_name);
516 int arg_count = node->data.fn_proto.params.length;
517 bool is_var_args = node->data.fn_proto.is_var_args;
518 for (int arg_i = 0; arg_i < arg_count; arg_i += 1) {
519 AstNode *param_decl = node->data.fn_proto.params.at(arg_i);
520 assert(param_decl->type == NodeTypeParamDecl);
521 const char *arg_name = buf_ptr(&param_decl->data.param_decl.name);
522 const char *noalias_str = param_decl->data.param_decl.is_noalias ? "noalias " : "";
523 fprintf(ar->f, "%s%s: ", noalias_str, arg_name);
524 render_node(ar, param_decl->data.param_decl.type);
525
526 if (arg_i + 1 < arg_count || is_var_args) {
527 fprintf(ar->f, ", ");
528 }
529 }
530 if (is_var_args) {
531 fprintf(ar->f, "...");
532 }
533 fprintf(ar->f, ")");
534
535 AstNode *return_type_node = node->data.fn_proto.return_type;
536 bool is_void = return_type_node->type != NodeTypeSymbol &&
537 buf_eql_str(&return_type_node->data.symbol_expr.symbol, "void");
538 if (!is_void) {
539 fprintf(ar->f, " -> ");
540 render_node(ar, return_type_node);
541 }
542 fprintf(ar->f, ";");
543 break;
544 }
545 case NodeTypeFnDef:
546 zig_panic("TODO");
547 case NodeTypeFnDecl:
548 zig_panic("TODO");
549 case NodeTypeParamDecl:
550 zig_panic("TODO");
551 case NodeTypeBlock:
552 zig_panic("TODO");
553 case NodeTypeDirective:
554 zig_panic("TODO");
555 case NodeTypeReturnExpr:
556 zig_panic("TODO");
557 case NodeTypeVariableDeclaration:
558 {
559 const char *pub_str = visib_mod_string(node->data.variable_declaration.visib_mod);
560 const char *extern_str = extern_string(node->data.variable_declaration.is_extern);
561 const char *var_name = buf_ptr(&node->data.variable_declaration.symbol);
562 const char *const_or_var = const_or_var_string(node->data.variable_declaration.is_const);
563 fprintf(ar->f, "%s%s%s %s", pub_str, extern_str, const_or_var, var_name);
564 if (node->data.variable_declaration.type) {
565 fprintf(ar->f, ": ");
566 render_node(ar, node->data.variable_declaration.type);
567 }
568 if (node->data.variable_declaration.expr) {
569 fprintf(ar->f, " = ");
570 render_node(ar, node->data.variable_declaration.expr);
571 }
572 break;
573 }
574 case NodeTypeErrorValueDecl:
575 zig_panic("TODO");
576 case NodeTypeBinOpExpr:
577 zig_panic("TODO");
578 case NodeTypeUnwrapErrorExpr:
579 zig_panic("TODO");
580 case NodeTypeNumberLiteral:
581 zig_panic("TODO");
582 case NodeTypeStringLiteral:
583 zig_panic("TODO");
584 case NodeTypeCharLiteral:
585 zig_panic("TODO");
586 case NodeTypeSymbol:
587 fprintf(ar->f, "%s", buf_ptr(&node->data.symbol_expr.symbol));
588 break;
589 case NodeTypePrefixOpExpr:
590 {
591 PrefixOp op = node->data.prefix_op_expr.prefix_op;
592 fprintf(ar->f, "%s", prefix_op_str(op));
593
594 render_node(ar, node->data.prefix_op_expr.primary_expr);
595 break;
596 }
597 case NodeTypeFnCallExpr:
598 zig_panic("TODO");
599 case NodeTypeArrayAccessExpr:
600 zig_panic("TODO");
601 case NodeTypeSliceExpr:
602 zig_panic("TODO");
603 case NodeTypeFieldAccessExpr:
604 zig_panic("TODO");
605 case NodeTypeImport:
606 zig_panic("TODO");
607 case NodeTypeCImport:
608 zig_panic("TODO");
609 case NodeTypeBoolLiteral:
610 zig_panic("TODO");
611 case NodeTypeNullLiteral:
612 zig_panic("TODO");
613 case NodeTypeUndefinedLiteral:
614 zig_panic("TODO");
615 case NodeTypeIfBoolExpr:
616 zig_panic("TODO");
617 case NodeTypeIfVarExpr:
618 zig_panic("TODO");
619 case NodeTypeWhileExpr:
620 zig_panic("TODO");
621 case NodeTypeForExpr:
622 zig_panic("TODO");
623 case NodeTypeSwitchExpr:
624 zig_panic("TODO");
625 case NodeTypeSwitchProng:
626 zig_panic("TODO");
627 case NodeTypeSwitchRange:
628 zig_panic("TODO");
629 case NodeTypeLabel:
630 zig_panic("TODO");
631 case NodeTypeGoto:
632 zig_panic("TODO");
633 case NodeTypeBreak:
634 zig_panic("TODO");
635 case NodeTypeContinue:
636 zig_panic("TODO");
637 case NodeTypeAsmExpr:
638 zig_panic("TODO");
639 case NodeTypeStructDecl:
640 {
641 const char *struct_name = buf_ptr(&node->data.struct_decl.name);
642 const char *pub_str = visib_mod_string(node->data.struct_decl.visib_mod);
643 fprintf(ar->f, "%sstruct %s {\n", pub_str, struct_name);
644 ar->indent += ar->indent_size;
645 for (int field_i = 0; field_i < node->data.struct_decl.fields.length; field_i += 1) {
646 AstNode *field_node = node->data.struct_decl.fields.at(field_i);
647 assert(field_node->type == NodeTypeStructField);
648 const char *field_name = buf_ptr(&field_node->data.struct_field.name);
649 print_indent(ar);
650 fprintf(ar->f, "%s: ", field_name);
651 render_node(ar, field_node->data.struct_field.type);
652 fprintf(ar->f, ",\n");
653 }
654
655 ar->indent -= ar->indent_size;
656 fprintf(ar->f, "}\n");
657 break;
658 }
659 case NodeTypeStructField:
660 zig_panic("TODO");
661 case NodeTypeContainerInitExpr:
662 zig_panic("TODO");
663 case NodeTypeStructValueField:
664 zig_panic("TODO");
665 case NodeTypeArrayType:
666 zig_panic("TODO");
667 case NodeTypeErrorType:
668 zig_panic("TODO");
669 }
670}
671
672
673void ast_render(FILE *f, AstNode *node, int indent_size) {
674 AstRender ar = {0};
675 ar.f = f;
676 ar.indent_size = indent_size;
677 ar.indent = 0;
678
679 assert(node->type == NodeTypeRoot);
680
681 render_node(&ar, node);
682}
src/ast_render.hpp created+20
...@@ -0,0 +1,20 @@
1/*
2 * Copyright (c) 2015 Andrew Kelley
3 *
4 * This file is part of zig, which is MIT licensed.
5 * See http://opensource.org/licenses/MIT
6 */
7
8#ifndef ZIG_AST_RENDER_HPP
9#define ZIG_AST_RENDER_HPP
10
11#include "all_types.hpp"
12
13#include <stdio.h>
14
15void ast_print(FILE *f, AstNode *node, int indent);
16
17void ast_render(FILE *f, AstNode *node, int indent_size);
18
19#endif
20
src/codegen.cpp+2-1
...@@ -13,6 +13,7 @@...@@ -13,6 +13,7 @@
13#include "error.hpp"13#include "error.hpp"
14#include "analyze.hpp"14#include "analyze.hpp"
15#include "errmsg.hpp"15#include "errmsg.hpp"
16#include "ast_render.hpp"
1617
17#include <stdio.h>18#include <stdio.h>
18#include <errno.h>19#include <errno.h>
...@@ -3117,7 +3118,7 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,...@@ -3117,7 +3118,7 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,
3117 &g->next_node_index);3118 &g->next_node_index);
3118 assert(import_entry->root);3119 assert(import_entry->root);
3119 if (g->verbose) {3120 if (g->verbose) {
3120 ast_print(import_entry->root, 0);3121 ast_print(stderr, import_entry->root, 0);
3121 }3122 }
31223123
3123 import_entry->di_file = LLVMZigCreateFile(g->dbuilder, buf_ptr(src_basename), buf_ptr(src_dirname));3124 import_entry->di_file = LLVMZigCreateFile(g->dbuilder, buf_ptr(src_basename), buf_ptr(src_dirname));
src/main.cpp+29-112
...@@ -11,6 +11,7 @@...@@ -11,6 +11,7 @@
11#include "os.hpp"11#include "os.hpp"
12#include "error.hpp"12#include "error.hpp"
13#include "parseh.hpp"13#include "parseh.hpp"
14#include "ast_render.hpp"
1415
15#include <stdio.h>16#include <stdio.h>
1617
...@@ -162,41 +163,10 @@ static int build(const char *arg0, int argc, char **argv) {...@@ -162,41 +163,10 @@ static int build(const char *arg0, int argc, char **argv) {
162 return 0;163 return 0;
163}164}
164165
165struct ParseHPrint {
166 ParseH parse_h;
167 FILE *f;
168 int cur_indent;
169};
170
171static const int indent_size = 4;
172
173static void print_indent(ParseHPrint *p) {
174 for (int i = 0; i < p->cur_indent; i += 1) {
175 fprintf(p->f, " ");
176 }
177}
178
179static Buf *node_to_buf(AstNode *node) {
180 if (node->type == NodeTypeSymbol) {
181 return &node->data.symbol_expr.symbol;
182 } else if (node->type == NodeTypePrefixOpExpr) {
183 PrefixOp op = node->data.prefix_op_expr.prefix_op;
184 const char *child_type_str = buf_ptr(node_to_buf(node->data.prefix_op_expr.primary_expr));
185 if (op == PrefixOpAddressOf) {
186 return buf_sprintf("&%s", child_type_str);
187 } else if (op == PrefixOpConstAddressOf) {
188 return buf_sprintf("&const %s", child_type_str);
189 } else {
190 zig_unreachable();
191 }
192 } else {
193 zig_unreachable();
194 }
195}
196
197static int parseh(const char *arg0, int argc, char **argv) {166static int parseh(const char *arg0, int argc, char **argv) {
198 char *in_file = nullptr;167 char *in_file = nullptr;
199 ZigList<const char *> clang_argv = {0};168 ZigList<const char *> clang_argv = {0};
169 ErrColor color = ErrColorAuto;
200 for (int i = 0; i < argc; i += 1) {170 for (int i = 0; i < argc; i += 1) {
201 char *arg = argv[i];171 char *arg = argv[i];
202 if (arg[0] == '-') {172 if (arg[0] == '-') {
...@@ -206,10 +176,24 @@ static int parseh(const char *arg0, int argc, char **argv) {...@@ -206,10 +176,24 @@ static int parseh(const char *arg0, int argc, char **argv) {
206 if (i + 1 >= argc) {176 if (i + 1 >= argc) {
207 return usage(arg0);177 return usage(arg0);
208 }178 }
179 i += 1;
209 clang_argv.append("-isystem");180 clang_argv.append("-isystem");
210 clang_argv.append(argv[i + 1]);181 clang_argv.append(argv[i]);
182 } else if (strcmp(arg, "--color") == 0) {
183 if (i + 1 >= argc) {
184 return usage(arg0);
185 }
211 i += 1;186 i += 1;
212 } else {187 if (strcmp(argv[i], "auto") == 0) {
188 color = ErrColorAuto;
189 } else if (strcmp(argv[i], "on") == 0) {
190 color = ErrColorOn;
191 } else if (strcmp(argv[i], "off") == 0) {
192 color = ErrColorOff;
193 } else {
194 return usage(arg0);
195 }
196 } else {
213 fprintf(stderr, "unrecognized argument: %s", arg);197 fprintf(stderr, "unrecognized argument: %s", arg);
214 return usage(arg0);198 return usage(arg0);
215 }199 }
...@@ -231,91 +215,24 @@ static int parseh(const char *arg0, int argc, char **argv) {...@@ -231,91 +215,24 @@ static int parseh(const char *arg0, int argc, char **argv) {
231 clang_argv.append("-isystem");215 clang_argv.append("-isystem");
232 clang_argv.append(buf_ptr(libc_include_path));216 clang_argv.append(buf_ptr(libc_include_path));
233217
234 ParseHPrint parse_h_print = {{{0}}};218 ImportTableEntry import = {0};
235 ParseHPrint *p = &parse_h_print;219 ZigList<ErrorMsg *> errors = {0};
236 p->f = stdout;220 int err = parse_h_file(&import, &errors, &clang_argv);
237 p->cur_indent = 0;
238
239 parse_h_file(&p->parse_h, &clang_argv);
240221
241 if (p->parse_h.errors.length > 0) {222 if (err) {
242 for (int i = 0; i < p->parse_h.errors.length; i += 1) {223 fprintf(stderr, "unable to parse .h file: %s\n", err_str(err));
243 ErrorMsg *err_msg = p->parse_h.errors.at(i);
244 // TODO respect --color arg
245 print_err_msg(err_msg, ErrColorAuto);
246 }
247 return EXIT_FAILURE;224 return EXIT_FAILURE;
248 }225 }
249226
250 for (int var_i = 0; var_i < p->parse_h.var_list.length; var_i += 1) {227 if (errors.length > 0) {
251 AstNode *var_decl = p->parse_h.var_list.at(var_i);228 for (int i = 0; i < errors.length; i += 1) {
252 assert(var_decl->type == NodeTypeVariableDeclaration);229 ErrorMsg *err_msg = errors.at(i);
253 const char *pub_str = (var_decl->data.variable_declaration.visib_mod == VisibModPub) ? "pub " : "";230 print_err_msg(err_msg, color);
254 const char *extern_str = var_decl->data.variable_declaration.is_extern ? "extern " : "";
255 const char *var_name = buf_ptr(&var_decl->data.variable_declaration.symbol);
256 const char *const_or_var = var_decl->data.variable_declaration.is_const ? "const" : "var";
257 print_indent(p);
258 fprintf(p->f, "%s%s%s %s", pub_str, extern_str, const_or_var, var_name);
259 if (var_decl->data.variable_declaration.type) {
260 fprintf(p->f, ": %s", buf_ptr(node_to_buf(var_decl->data.variable_declaration.type)));
261 }
262 if (var_decl->data.variable_declaration.expr) {
263 fprintf(p->f, " = %s", buf_ptr(node_to_buf(var_decl->data.variable_declaration.expr)));
264 }231 }
265 fprintf(p->f, ";\n");232 return EXIT_FAILURE;
266 }
267
268 for (int struct_i = 0; struct_i < p->parse_h.struct_list.length; struct_i += 1) {
269 AstNode *struct_decl = p->parse_h.struct_list.at(struct_i);
270 assert(struct_decl->type == NodeTypeStructDecl);
271 const char *struct_name = buf_ptr(&struct_decl->data.struct_decl.name);
272 print_indent(p);
273 fprintf(p->f, "struct %s {\n", struct_name);
274 p->cur_indent += indent_size;
275 for (int field_i = 0; field_i < struct_decl->data.struct_decl.fields.length; field_i += 1) {
276 AstNode *field_node = struct_decl->data.struct_decl.fields.at(field_i);
277 assert(field_node->type == NodeTypeStructField);
278 const char *field_name = buf_ptr(&field_node->data.struct_field.name);
279 Buf *type_name = node_to_buf(field_node->data.struct_field.type);
280 print_indent(p);
281 fprintf(p->f, "%s: %s,\n", field_name, buf_ptr(type_name));
282 }
283
284 p->cur_indent -= indent_size;
285 fprintf(p->f, "}\n\n");
286 }233 }
287234
288 for (int fn_i = 0; fn_i < p->parse_h.fn_list.length; fn_i += 1) {235 ast_render(stdout, import.root, 4);
289 AstNode *fn_proto = p->parse_h.fn_list.at(fn_i);
290 assert(fn_proto->type == NodeTypeFnProto);
291 print_indent(p);
292 const char *fn_name = buf_ptr(&fn_proto->data.fn_proto.name);
293 const char *pub_str = (fn_proto->data.fn_proto.visib_mod == VisibModPub) ? "pub " : "";
294 const char *extern_str = fn_proto->data.fn_proto.is_extern ? "extern " : "";
295 fprintf(p->f, "%s%sfn %s(", pub_str, extern_str, fn_name);
296 int arg_count = fn_proto->data.fn_proto.params.length;
297 bool is_var_args = fn_proto->data.fn_proto.is_var_args;
298 for (int arg_i = 0; arg_i < arg_count; arg_i += 1) {
299 AstNode *param_decl = fn_proto->data.fn_proto.params.at(arg_i);
300 assert(param_decl->type == NodeTypeParamDecl);
301 const char *arg_name = buf_ptr(&param_decl->data.param_decl.name);
302 Buf *arg_type = node_to_buf(param_decl->data.param_decl.type);
303 const char *noalias_str = param_decl->data.param_decl.is_noalias ? "noalias " : "";
304 fprintf(p->f, "%s%s: %s", noalias_str, arg_name, buf_ptr(arg_type));
305 if (arg_i + 1 < arg_count || is_var_args) {
306 fprintf(p->f, ", ");
307 }
308 }
309 if (is_var_args) {
310 fprintf(p->f, "...");
311 }
312 fprintf(p->f, ")");
313 Buf *return_type_name = node_to_buf(fn_proto->data.fn_proto.return_type);
314 if (!buf_eql_str(return_type_name, "void")) {
315 fprintf(p->f, " -> %s", buf_ptr(return_type_name));
316 }
317 fprintf(p->f, ";\n");
318 }
319236
320 return 0;237 return 0;
321}238}
src/parseh.cpp+33-8
...@@ -9,6 +9,8 @@...@@ -9,6 +9,8 @@
9#include "config.h"9#include "config.h"
10#include "os.hpp"10#include "os.hpp"
11#include "error.hpp"11#include "error.hpp"
12#include "parser.hpp"
13#include "all_types.hpp"
1214
13#include <clang/Frontend/ASTUnit.h>15#include <clang/Frontend/ASTUnit.h>
14#include <clang/Frontend/CompilerInstance.h>16#include <clang/Frontend/CompilerInstance.h>
...@@ -18,10 +20,12 @@...@@ -18,10 +20,12 @@
18using namespace clang;20using namespace clang;
1921
20struct Context {22struct Context {
21 ParseH *parse_h;23 ImportTableEntry *import;
24 ZigList<ErrorMsg *> *errors;
22 bool warnings_on;25 bool warnings_on;
23 VisibMod visib_mod;26 VisibMod visib_mod;
24 AstNode *c_void_decl_node;27 AstNode *c_void_decl_node;
28 AstNode *root;
25 HashMap<Buf *, bool, buf_hash, buf_eql_buf> type_table;29 HashMap<Buf *, bool, buf_hash, buf_eql_buf> type_table;
26};30};
2731
...@@ -30,6 +34,7 @@ static AstNode *make_qual_type_node(Context *c, QualType qt);...@@ -30,6 +34,7 @@ static AstNode *make_qual_type_node(Context *c, QualType qt);
30static AstNode *create_node(Context *c, NodeType type) {34static AstNode *create_node(Context *c, NodeType type) {
31 AstNode *node = allocate<AstNode>(1);35 AstNode *node = allocate<AstNode>(1);
32 node->type = type;36 node->type = type;
37 node->owner = c->import;
33 return node;38 return node;
34}39}
3540
...@@ -44,6 +49,10 @@ static const char *decl_name(const Decl *decl) {...@@ -44,6 +49,10 @@ static const char *decl_name(const Decl *decl) {
44 return (const char *)named_decl->getName().bytes_begin();49 return (const char *)named_decl->getName().bytes_begin();
45}50}
4651
52static ZigList<AstNode *> *create_empty_directives(Context *c) {
53 return allocate<ZigList<AstNode*>>(1);
54}
55
47static AstNode *create_typedef_node(Context *c, Buf *new_name, AstNode *target_node) {56static AstNode *create_typedef_node(Context *c, Buf *new_name, AstNode *target_node) {
48 if (!target_node) {57 if (!target_node) {
49 return nullptr;58 return nullptr;
...@@ -53,7 +62,10 @@ static AstNode *create_typedef_node(Context *c, Buf *new_name, AstNode *target_n...@@ -53,7 +62,10 @@ static AstNode *create_typedef_node(Context *c, Buf *new_name, AstNode *target_n
53 node->data.variable_declaration.is_const = true;62 node->data.variable_declaration.is_const = true;
54 node->data.variable_declaration.visib_mod = c->visib_mod;63 node->data.variable_declaration.visib_mod = c->visib_mod;
55 node->data.variable_declaration.expr = target_node;64 node->data.variable_declaration.expr = target_node;
56 c->parse_h->var_list.append(node);65 node->data.variable_declaration.directives = create_empty_directives(c);
66 normalize_parent_ptrs(node);
67
68 c->root->data.root.top_level_decls.append(node);
57 return node;69 return node;
58}70}
5971
...@@ -79,6 +91,7 @@ static AstNode *pointer_to_type(Context *c, AstNode *type_node, bool is_const) {...@@ -79,6 +91,7 @@ static AstNode *pointer_to_type(Context *c, AstNode *type_node, bool is_const) {
79 AstNode *node = create_node(c, NodeTypePrefixOpExpr);91 AstNode *node = create_node(c, NodeTypePrefixOpExpr);
80 node->data.prefix_op_expr.prefix_op = is_const ? PrefixOpConstAddressOf : PrefixOpAddressOf;92 node->data.prefix_op_expr.prefix_op = is_const ? PrefixOpConstAddressOf : PrefixOpAddressOf;
81 node->data.prefix_op_expr.primary_expr = convert_to_c_void(c, type_node);93 node->data.prefix_op_expr.primary_expr = convert_to_c_void(c, type_node);
94 normalize_parent_ptrs(node);
82 return node;95 return node;
83}96}
8497
...@@ -255,6 +268,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {...@@ -255,6 +268,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
255 AstNode *node = create_node(c, NodeTypeFnProto);268 AstNode *node = create_node(c, NodeTypeFnProto);
256 node->data.fn_proto.is_extern = true;269 node->data.fn_proto.is_extern = true;
257 node->data.fn_proto.visib_mod = c->visib_mod;270 node->data.fn_proto.visib_mod = c->visib_mod;
271 node->data.fn_proto.directives = create_empty_directives(c);
258 node->data.fn_proto.is_var_args = fn_decl->isVariadic();272 node->data.fn_proto.is_var_args = fn_decl->isVariadic();
259 buf_init_from_str(&node->data.fn_proto.name, decl_name(fn_decl));273 buf_init_from_str(&node->data.fn_proto.name, decl_name(fn_decl));
260274
...@@ -276,6 +290,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {...@@ -276,6 +290,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
276 break;290 break;
277 }291 }
278292
293 normalize_parent_ptrs(param_decl_node);
279 node->data.fn_proto.params.append(param_decl_node);294 node->data.fn_proto.params.append(param_decl_node);
280 }295 }
281296
...@@ -296,8 +311,9 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {...@@ -296,8 +311,9 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
296 return;311 return;
297 }312 }
298313
299 c->parse_h->fn_list.append(node);314 normalize_parent_ptrs(node);
300315
316 c->root->data.root.top_level_decls.append(node);
301}317}
302318
303static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) {319static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) {
...@@ -322,6 +338,7 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl)...@@ -322,6 +338,7 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl)
322 AstNode *node = create_typedef_node(c, type_name, make_qual_type_node(c, child_qt));338 AstNode *node = create_typedef_node(c, type_name, make_qual_type_node(c, child_qt));
323339
324 if (node) {340 if (node) {
341 normalize_parent_ptrs(node);
325 c->type_table.put(type_name, true);342 c->type_table.put(type_name, true);
326 }343 }
327}344}
...@@ -345,7 +362,9 @@ static bool decl_visitor(void *context, const Decl *decl) {...@@ -345,7 +362,9 @@ static bool decl_visitor(void *context, const Decl *decl) {
345 return true;362 return true;
346}363}
347364
348int parse_h_buf(ParseH *parse_h, Buf *source, const char **args, int args_len, const char *libc_include_path) {365int parse_h_buf(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, Buf *source,
366 const char **args, int args_len, const char *libc_include_path)
367{
349 int err;368 int err;
350 Buf tmp_file_path = BUF_INIT;369 Buf tmp_file_path = BUF_INIT;
351 if ((err = os_buf_to_tmp_file(source, buf_create_from_str(".h"), &tmp_file_path))) {370 if ((err = os_buf_to_tmp_file(source, buf_create_from_str(".h"), &tmp_file_path))) {
...@@ -361,17 +380,18 @@ int parse_h_buf(ParseH *parse_h, Buf *source, const char **args, int args_len, c...@@ -361,17 +380,18 @@ int parse_h_buf(ParseH *parse_h, Buf *source, const char **args, int args_len, c
361 clang_argv.append(args[i]);380 clang_argv.append(args[i]);
362 }381 }
363382
364 err = parse_h_file(parse_h, &clang_argv);383 err = parse_h_file(import, errors, &clang_argv);
365384
366 os_delete_file(&tmp_file_path);385 os_delete_file(&tmp_file_path);
367386
368 return err;387 return err;
369}388}
370389
371int parse_h_file(ParseH *parse_h, ZigList<const char *> *clang_argv) {390int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, ZigList<const char *> *clang_argv) {
372 Context context = {0};391 Context context = {0};
373 Context *c = &context;392 Context *c = &context;
374 c->parse_h = parse_h;393 c->import = import;
394 c->errors = errors;
375 c->type_table.init(64);395 c->type_table.init(64);
376396
377 char *ZIG_PARSEH_CFLAGS = getenv("ZIG_PARSEH_CFLAGS");397 char *ZIG_PARSEH_CFLAGS = getenv("ZIG_PARSEH_CFLAGS");
...@@ -455,13 +475,18 @@ int parse_h_file(ParseH *parse_h, ZigList<const char *> *clang_argv) {...@@ -455,13 +475,18 @@ int parse_h_file(ParseH *parse_h, ZigList<const char *> *clang_argv) {
455475
456 ErrorMsg *err_msg = err_msg_create_with_offset(path, line, column, offset, source, msg);476 ErrorMsg *err_msg = err_msg_create_with_offset(path, line, column, offset, source, msg);
457477
458 parse_h->errors.append(err_msg);478 c->errors->append(err_msg);
459 }479 }
460480
461 return 0;481 return 0;
462 }482 }
463483
484 c->root = create_node(c, NodeTypeRoot);
464 ast_unit->visitLocalTopLevelDecls(c, decl_visitor);485 ast_unit->visitLocalTopLevelDecls(c, decl_visitor);
486 normalize_parent_ptrs(c->root);
487
488 import->root = c->root;
489 import->is_c_import = true;
465490
466 return 0;491 return 0;
467}492}
src/parseh.hpp+4-2
...@@ -11,7 +11,9 @@...@@ -11,7 +11,9 @@
1111
12#include "all_types.hpp"12#include "all_types.hpp"
1313
14int parse_h_file(ParseH *parse_h, ZigList<const char *> *clang_argv);14int parse_h_file(ImportTableEntry *out_import, ZigList<ErrorMsg *> *out_errs,
15int parse_h_buf(ParseH *parse_h, Buf *source, const char **args, int args_len, const char *libc_include_path);15 ZigList<const char *> *clang_argv);
16int parse_h_buf(ImportTableEntry *out_import, ZigList<ErrorMsg *> *out_errs,
17 Buf *source, const char **args, int args_len, const char *libc_include_path);
1618
17#endif19#endif
src/parser.cpp-459
...@@ -14,465 +14,6 @@...@@ -14,465 +14,6 @@
14#include <limits.h>14#include <limits.h>
15#include <errno.h>15#include <errno.h>
1616
17static const char *bin_op_str(BinOpType bin_op) {
18 switch (bin_op) {
19 case BinOpTypeInvalid: return "(invalid)";
20 case BinOpTypeBoolOr: return "||";
21 case BinOpTypeBoolAnd: return "&&";
22 case BinOpTypeCmpEq: return "==";
23 case BinOpTypeCmpNotEq: return "!=";
24 case BinOpTypeCmpLessThan: return "<";
25 case BinOpTypeCmpGreaterThan: return ">";
26 case BinOpTypeCmpLessOrEq: return "<=";
27 case BinOpTypeCmpGreaterOrEq: return ">=";
28 case BinOpTypeBinOr: return "|";
29 case BinOpTypeBinXor: return "^";
30 case BinOpTypeBinAnd: return "&";
31 case BinOpTypeBitShiftLeft: return "<<";
32 case BinOpTypeBitShiftRight: return ">>";
33 case BinOpTypeAdd: return "+";
34 case BinOpTypeSub: return "-";
35 case BinOpTypeMult: return "*";
36 case BinOpTypeDiv: return "/";
37 case BinOpTypeMod: return "%";
38 case BinOpTypeAssign: return "=";
39 case BinOpTypeAssignTimes: return "*=";
40 case BinOpTypeAssignDiv: return "/=";
41 case BinOpTypeAssignMod: return "%=";
42 case BinOpTypeAssignPlus: return "+=";
43 case BinOpTypeAssignMinus: return "-=";
44 case BinOpTypeAssignBitShiftLeft: return "<<=";
45 case BinOpTypeAssignBitShiftRight: return ">>=";
46 case BinOpTypeAssignBitAnd: return "&=";
47 case BinOpTypeAssignBitXor: return "^=";
48 case BinOpTypeAssignBitOr: return "|=";
49 case BinOpTypeAssignBoolAnd: return "&&=";
50 case BinOpTypeAssignBoolOr: return "||=";
51 case BinOpTypeUnwrapMaybe: return "??";
52 case BinOpTypeStrCat: return "++";
53 }
54 zig_unreachable();
55}
56
57static const char *prefix_op_str(PrefixOp prefix_op) {
58 switch (prefix_op) {
59 case PrefixOpInvalid: return "(invalid)";
60 case PrefixOpNegation: return "-";
61 case PrefixOpBoolNot: return "!";
62 case PrefixOpBinNot: return "~";
63 case PrefixOpAddressOf: return "&";
64 case PrefixOpConstAddressOf: return "&const";
65 case PrefixOpDereference: return "*";
66 case PrefixOpMaybe: return "?";
67 case PrefixOpError: return "%";
68 case PrefixOpUnwrapError: return "%%";
69 }
70 zig_unreachable();
71}
72
73static const char *return_prefix_str(ReturnKind kind) {
74 switch (kind) {
75 case ReturnKindError: return "%";
76 case ReturnKindMaybe: return "?";
77 case ReturnKindUnconditional: return "";
78 }
79 zig_unreachable();
80}
81
82const char *node_type_str(NodeType node_type) {
83 switch (node_type) {
84 case NodeTypeRoot:
85 return "Root";
86 case NodeTypeRootExportDecl:
87 return "RootExportDecl";
88 case NodeTypeFnDef:
89 return "FnDef";
90 case NodeTypeFnDecl:
91 return "FnDecl";
92 case NodeTypeFnProto:
93 return "FnProto";
94 case NodeTypeParamDecl:
95 return "ParamDecl";
96 case NodeTypeBlock:
97 return "Block";
98 case NodeTypeBinOpExpr:
99 return "BinOpExpr";
100 case NodeTypeUnwrapErrorExpr:
101 return "UnwrapErrorExpr";
102 case NodeTypeFnCallExpr:
103 return "FnCallExpr";
104 case NodeTypeArrayAccessExpr:
105 return "ArrayAccessExpr";
106 case NodeTypeSliceExpr:
107 return "SliceExpr";
108 case NodeTypeDirective:
109 return "Directive";
110 case NodeTypeReturnExpr:
111 return "ReturnExpr";
112 case NodeTypeVariableDeclaration:
113 return "VariableDeclaration";
114 case NodeTypeErrorValueDecl:
115 return "ErrorValueDecl";
116 case NodeTypeNumberLiteral:
117 return "NumberLiteral";
118 case NodeTypeStringLiteral:
119 return "StringLiteral";
120 case NodeTypeCharLiteral:
121 return "CharLiteral";
122 case NodeTypeSymbol:
123 return "Symbol";
124 case NodeTypePrefixOpExpr:
125 return "PrefixOpExpr";
126 case NodeTypeImport:
127 return "Import";
128 case NodeTypeCImport:
129 return "CImport";
130 case NodeTypeBoolLiteral:
131 return "BoolLiteral";
132 case NodeTypeNullLiteral:
133 return "NullLiteral";
134 case NodeTypeUndefinedLiteral:
135 return "UndefinedLiteral";
136 case NodeTypeIfBoolExpr:
137 return "IfBoolExpr";
138 case NodeTypeIfVarExpr:
139 return "IfVarExpr";
140 case NodeTypeWhileExpr:
141 return "WhileExpr";
142 case NodeTypeForExpr:
143 return "ForExpr";
144 case NodeTypeSwitchExpr:
145 return "SwitchExpr";
146 case NodeTypeSwitchProng:
147 return "SwitchProng";
148 case NodeTypeSwitchRange:
149 return "SwitchRange";
150 case NodeTypeLabel:
151 return "Label";
152 case NodeTypeGoto:
153 return "Goto";
154 case NodeTypeBreak:
155 return "Break";
156 case NodeTypeContinue:
157 return "Continue";
158 case NodeTypeAsmExpr:
159 return "AsmExpr";
160 case NodeTypeFieldAccessExpr:
161 return "FieldAccessExpr";
162 case NodeTypeStructDecl:
163 return "StructDecl";
164 case NodeTypeStructField:
165 return "StructField";
166 case NodeTypeStructValueField:
167 return "StructValueField";
168 case NodeTypeContainerInitExpr:
169 return "ContainerInitExpr";
170 case NodeTypeArrayType:
171 return "ArrayType";
172 case NodeTypeErrorType:
173 return "ErrorType";
174 }
175 zig_unreachable();
176}
177
178void ast_print(AstNode *node, int indent) {
179 for (int i = 0; i < indent; i += 1) {
180 fprintf(stderr, " ");
181 }
182 assert(node->type == NodeTypeRoot || *node->parent_field == node);
183
184 switch (node->type) {
185 case NodeTypeRoot:
186 fprintf(stderr, "%s\n", node_type_str(node->type));
187 for (int i = 0; i < node->data.root.top_level_decls.length; i += 1) {
188 AstNode *child = node->data.root.top_level_decls.at(i);
189 ast_print(child, indent + 2);
190 }
191 break;
192 case NodeTypeRootExportDecl:
193 fprintf(stderr, "%s %s '%s'\n", node_type_str(node->type),
194 buf_ptr(&node->data.root_export_decl.type),
195 buf_ptr(&node->data.root_export_decl.name));
196 break;
197 case NodeTypeFnDef:
198 {
199 fprintf(stderr, "%s\n", node_type_str(node->type));
200 AstNode *child = node->data.fn_def.fn_proto;
201 ast_print(child, indent + 2);
202 ast_print(node->data.fn_def.body, indent + 2);
203 break;
204 }
205 case NodeTypeFnProto:
206 {
207 Buf *name_buf = &node->data.fn_proto.name;
208 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf));
209
210 for (int i = 0; i < node->data.fn_proto.params.length; i += 1) {
211 AstNode *child = node->data.fn_proto.params.at(i);
212 ast_print(child, indent + 2);
213 }
214
215 ast_print(node->data.fn_proto.return_type, indent + 2);
216
217 break;
218 }
219 case NodeTypeBlock:
220 {
221 fprintf(stderr, "%s\n", node_type_str(node->type));
222 for (int i = 0; i < node->data.block.statements.length; i += 1) {
223 AstNode *child = node->data.block.statements.at(i);
224 ast_print(child, indent + 2);
225 }
226 break;
227 }
228 case NodeTypeParamDecl:
229 {
230 Buf *name_buf = &node->data.param_decl.name;
231 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf));
232
233 ast_print(node->data.param_decl.type, indent + 2);
234
235 break;
236 }
237 case NodeTypeReturnExpr:
238 {
239 const char *prefix_str = return_prefix_str(node->data.return_expr.kind);
240 fprintf(stderr, "%s%s\n", prefix_str, node_type_str(node->type));
241 if (node->data.return_expr.expr)
242 ast_print(node->data.return_expr.expr, indent + 2);
243 break;
244 }
245 case NodeTypeVariableDeclaration:
246 {
247 Buf *name_buf = &node->data.variable_declaration.symbol;
248 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf));
249 if (node->data.variable_declaration.type)
250 ast_print(node->data.variable_declaration.type, indent + 2);
251 if (node->data.variable_declaration.expr)
252 ast_print(node->data.variable_declaration.expr, indent + 2);
253 break;
254 }
255 case NodeTypeErrorValueDecl:
256 {
257 Buf *name_buf = &node->data.error_value_decl.name;
258 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf));
259 break;
260 }
261 case NodeTypeFnDecl:
262 fprintf(stderr, "%s\n", node_type_str(node->type));
263 ast_print(node->data.fn_decl.fn_proto, indent + 2);
264 break;
265 case NodeTypeBinOpExpr:
266 fprintf(stderr, "%s %s\n", node_type_str(node->type),
267 bin_op_str(node->data.bin_op_expr.bin_op));
268 ast_print(node->data.bin_op_expr.op1, indent + 2);
269 ast_print(node->data.bin_op_expr.op2, indent + 2);
270 break;
271 case NodeTypeUnwrapErrorExpr:
272 fprintf(stderr, "%s\n", node_type_str(node->type));
273 ast_print(node->data.unwrap_err_expr.op1, indent + 2);
274 if (node->data.unwrap_err_expr.symbol) {
275 ast_print(node->data.unwrap_err_expr.symbol, indent + 2);
276 }
277 ast_print(node->data.unwrap_err_expr.op2, indent + 2);
278 break;
279 case NodeTypeFnCallExpr:
280 fprintf(stderr, "%s\n", node_type_str(node->type));
281 ast_print(node->data.fn_call_expr.fn_ref_expr, indent + 2);
282 for (int i = 0; i < node->data.fn_call_expr.params.length; i += 1) {
283 AstNode *child = node->data.fn_call_expr.params.at(i);
284 ast_print(child, indent + 2);
285 }
286 break;
287 case NodeTypeArrayAccessExpr:
288 fprintf(stderr, "%s\n", node_type_str(node->type));
289 ast_print(node->data.array_access_expr.array_ref_expr, indent + 2);
290 ast_print(node->data.array_access_expr.subscript, indent + 2);
291 break;
292 case NodeTypeSliceExpr:
293 fprintf(stderr, "%s\n", node_type_str(node->type));
294 ast_print(node->data.slice_expr.array_ref_expr, indent + 2);
295 ast_print(node->data.slice_expr.start, indent + 2);
296 if (node->data.slice_expr.end) {
297 ast_print(node->data.slice_expr.end, indent + 2);
298 }
299 break;
300 case NodeTypeDirective:
301 fprintf(stderr, "%s\n", node_type_str(node->type));
302 break;
303 case NodeTypePrefixOpExpr:
304 fprintf(stderr, "%s %s\n", node_type_str(node->type),
305 prefix_op_str(node->data.prefix_op_expr.prefix_op));
306 ast_print(node->data.prefix_op_expr.primary_expr, indent + 2);
307 break;
308 case NodeTypeNumberLiteral:
309 {
310 NumLit kind = node->data.number_literal.kind;
311 const char *name = node_type_str(node->type);
312 if (kind == NumLitUInt) {
313 fprintf(stderr, "%s uint %" PRIu64 "\n", name, node->data.number_literal.data.x_uint);
314 } else {
315 fprintf(stderr, "%s float %f\n", name, node->data.number_literal.data.x_float);
316 }
317 break;
318 }
319 case NodeTypeStringLiteral:
320 {
321 const char *c = node->data.string_literal.c ? "c" : "";
322 fprintf(stderr, "StringLiteral %s'%s'\n", c,
323 buf_ptr(&node->data.string_literal.buf));
324 break;
325 }
326 case NodeTypeCharLiteral:
327 {
328 fprintf(stderr, "%s '%c'\n", node_type_str(node->type), node->data.char_literal.value);
329 break;
330 }
331 case NodeTypeSymbol:
332 fprintf(stderr, "Symbol %s\n", buf_ptr(&node->data.symbol_expr.symbol));
333 break;
334 case NodeTypeImport:
335 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.import.path));
336 break;
337 case NodeTypeCImport:
338 fprintf(stderr, "%s\n", node_type_str(node->type));
339 ast_print(node->data.c_import.block, indent + 2);
340 break;
341 case NodeTypeBoolLiteral:
342 fprintf(stderr, "%s '%s'\n", node_type_str(node->type),
343 node->data.bool_literal.value ? "true" : "false");
344 break;
345 case NodeTypeNullLiteral:
346 fprintf(stderr, "%s\n", node_type_str(node->type));
347 break;
348 case NodeTypeIfBoolExpr:
349 fprintf(stderr, "%s\n", node_type_str(node->type));
350 if (node->data.if_bool_expr.condition)
351 ast_print(node->data.if_bool_expr.condition, indent + 2);
352 ast_print(node->data.if_bool_expr.then_block, indent + 2);
353 if (node->data.if_bool_expr.else_node)
354 ast_print(node->data.if_bool_expr.else_node, indent + 2);
355 break;
356 case NodeTypeIfVarExpr:
357 {
358 Buf *name_buf = &node->data.if_var_expr.var_decl.symbol;
359 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf));
360 if (node->data.if_var_expr.var_decl.type)
361 ast_print(node->data.if_var_expr.var_decl.type, indent + 2);
362 if (node->data.if_var_expr.var_decl.expr)
363 ast_print(node->data.if_var_expr.var_decl.expr, indent + 2);
364 ast_print(node->data.if_var_expr.then_block, indent + 2);
365 if (node->data.if_var_expr.else_node)
366 ast_print(node->data.if_var_expr.else_node, indent + 2);
367 break;
368 }
369 case NodeTypeWhileExpr:
370 fprintf(stderr, "%s\n", node_type_str(node->type));
371 ast_print(node->data.while_expr.condition, indent + 2);
372 ast_print(node->data.while_expr.body, indent + 2);
373 break;
374 case NodeTypeForExpr:
375 fprintf(stderr, "%s\n", node_type_str(node->type));
376 ast_print(node->data.for_expr.elem_node, indent + 2);
377 ast_print(node->data.for_expr.array_expr, indent + 2);
378 if (node->data.for_expr.index_node) {
379 ast_print(node->data.for_expr.index_node, indent + 2);
380 }
381 ast_print(node->data.for_expr.body, indent + 2);
382 break;
383 case NodeTypeSwitchExpr:
384 fprintf(stderr, "%s\n", node_type_str(node->type));
385 ast_print(node->data.switch_expr.expr, indent + 2);
386 for (int i = 0; i < node->data.switch_expr.prongs.length; i += 1) {
387 AstNode *child_node = node->data.switch_expr.prongs.at(i);
388 ast_print(child_node, indent + 2);
389 }
390 break;
391 case NodeTypeSwitchProng:
392 fprintf(stderr, "%s\n", node_type_str(node->type));
393 for (int i = 0; i < node->data.switch_prong.items.length; i += 1) {
394 AstNode *child_node = node->data.switch_prong.items.at(i);
395 ast_print(child_node, indent + 2);
396 }
397 if (node->data.switch_prong.var_symbol) {
398 ast_print(node->data.switch_prong.var_symbol, indent + 2);
399 }
400 ast_print(node->data.switch_prong.expr, indent + 2);
401 break;
402 case NodeTypeSwitchRange:
403 fprintf(stderr, "%s\n", node_type_str(node->type));
404 ast_print(node->data.switch_range.start, indent + 2);
405 ast_print(node->data.switch_range.end, indent + 2);
406 break;
407 case NodeTypeLabel:
408 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.label.name));
409 break;
410 case NodeTypeGoto:
411 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.goto_expr.name));
412 break;
413 case NodeTypeBreak:
414 fprintf(stderr, "%s\n", node_type_str(node->type));
415 break;
416 case NodeTypeContinue:
417 fprintf(stderr, "%s\n", node_type_str(node->type));
418 break;
419 case NodeTypeUndefinedLiteral:
420 fprintf(stderr, "%s\n", node_type_str(node->type));
421 break;
422 case NodeTypeAsmExpr:
423 fprintf(stderr, "%s\n", node_type_str(node->type));
424 break;
425 case NodeTypeFieldAccessExpr:
426 fprintf(stderr, "%s '%s'\n", node_type_str(node->type),
427 buf_ptr(&node->data.field_access_expr.field_name));
428 ast_print(node->data.field_access_expr.struct_expr, indent + 2);
429 break;
430 case NodeTypeStructDecl:
431 fprintf(stderr, "%s '%s'\n",
432 node_type_str(node->type), buf_ptr(&node->data.struct_decl.name));
433 for (int i = 0; i < node->data.struct_decl.fields.length; i += 1) {
434 AstNode *child = node->data.struct_decl.fields.at(i);
435 ast_print(child, indent + 2);
436 }
437 for (int i = 0; i < node->data.struct_decl.fns.length; i += 1) {
438 AstNode *child = node->data.struct_decl.fns.at(i);
439 ast_print(child, indent + 2);
440 }
441 break;
442 case NodeTypeStructField:
443 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.struct_field.name));
444 if (node->data.struct_field.type) {
445 ast_print(node->data.struct_field.type, indent + 2);
446 }
447 break;
448 case NodeTypeStructValueField:
449 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.struct_val_field.name));
450 ast_print(node->data.struct_val_field.expr, indent + 2);
451 break;
452 case NodeTypeContainerInitExpr:
453 fprintf(stderr, "%s\n", node_type_str(node->type));
454 ast_print(node->data.container_init_expr.type, indent + 2);
455 for (int i = 0; i < node->data.container_init_expr.entries.length; i += 1) {
456 AstNode *child = node->data.container_init_expr.entries.at(i);
457 ast_print(child, indent + 2);
458 }
459 break;
460 case NodeTypeArrayType:
461 {
462 const char *const_str = node->data.array_type.is_const ? "const" : "var";
463 fprintf(stderr, "%s %s\n", node_type_str(node->type), const_str);
464 if (node->data.array_type.size) {
465 ast_print(node->data.array_type.size, indent + 2);
466 }
467 ast_print(node->data.array_type.child_type, indent + 2);
468 break;
469 }
470 case NodeTypeErrorType:
471 fprintf(stderr, "%s\n", node_type_str(node->type));
472 break;
473 }
474}
475
476struct ParseContext {17struct ParseContext {
477 Buf *buf;18 Buf *buf;
478 AstNode *root;19 AstNode *root;