aboutsummaryrefslogtreecommitdiff
path: root/src/ast_render.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-04-06 11:38:12 -0700
committerAndrew Kelley <superjoe30@gmail.com>2016-04-06 12:58:54 -0700
commit67152f729431d58a9cd140498d50c1e9d795c34b (patch)
tree7997511873fe650e71f5efb527103688f62271b3 /src/ast_render.cpp
parente144ddab249af3737f04267c7f1f0f0e093ed314 (diff)
downloadzig-67152f729431d58a9cd140498d50c1e9d795c34b.tar.gz
zig-67152f729431d58a9cd140498d50c1e9d795c34b.zip
support simple generic functions
Diffstat (limited to 'src/ast_render.cpp')
-rw-r--r--src/ast_render.cpp333
1 files changed, 22 insertions, 311 deletions
diff --git a/src/ast_render.cpp b/src/ast_render.cpp
index 4a1d829546..59a287b886 100644
--- a/src/ast_render.cpp
+++ b/src/ast_render.cpp
@@ -59,15 +59,6 @@ static const char *prefix_op_str(PrefixOp prefix_op) {
zig_unreachable();
}
-static const char *return_prefix_str(ReturnKind kind) {
- switch (kind) {
- case ReturnKindError: return "%";
- case ReturnKindMaybe: return "?";
- case ReturnKindUnconditional: return "";
- }
- zig_unreachable();
-}
-
static const char *visib_mod_string(VisibMod mod) {
switch (mod) {
case VisibModPub: return "pub ";
@@ -195,316 +186,36 @@ static const char *node_type_str(NodeType node_type) {
zig_unreachable();
}
+struct AstPrint {
+ int indent;
+ FILE *f;
+};
-void ast_print(FILE *f, AstNode *node, int indent) {
- for (int i = 0; i < indent; i += 1) {
- fprintf(f, " ");
- }
- assert(node->type == NodeTypeRoot || *node->parent_field == node);
-
- switch (node->type) {
- case NodeTypeRoot:
- fprintf(f, "%s\n", node_type_str(node->type));
- for (int i = 0; i < node->data.root.top_level_decls.length; i += 1) {
- AstNode *child = node->data.root.top_level_decls.at(i);
- ast_print(f, child, indent + 2);
- }
- break;
- case NodeTypeFnDef:
- {
- fprintf(f, "%s\n", node_type_str(node->type));
- AstNode *child = node->data.fn_def.fn_proto;
- ast_print(f, child, indent + 2);
- ast_print(f, node->data.fn_def.body, indent + 2);
- break;
- }
- case NodeTypeFnProto:
- {
- Buf *name_buf = &node->data.fn_proto.name;
- fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf));
+static void ast_print_visit(AstNode **node_ptr, void *context) {
+ AstNode *node = *node_ptr;
+ AstPrint *ap = (AstPrint *)context;
- for (int i = 0; i < node->data.fn_proto.params.length; i += 1) {
- AstNode *child = node->data.fn_proto.params.at(i);
- ast_print(f, child, indent + 2);
- }
+ for (int i = 0; i < ap->indent; i += 1) {
+ fprintf(ap->f, " ");
+ }
- ast_print(f, node->data.fn_proto.return_type, indent + 2);
+ fprintf(ap->f, "%s\n", node_type_str(node->type));
- break;
- }
- case NodeTypeBlock:
- {
- fprintf(f, "%s\n", node_type_str(node->type));
- for (int i = 0; i < node->data.block.statements.length; i += 1) {
- AstNode *child = node->data.block.statements.at(i);
- ast_print(f, child, indent + 2);
- }
- break;
- }
- case NodeTypeParamDecl:
- {
- Buf *name_buf = &node->data.param_decl.name;
- fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf));
+ AstPrint new_ap;
+ new_ap.indent = ap->indent + 2;
+ new_ap.f = ap->f;
- ast_print(f, node->data.param_decl.type, indent + 2);
+ ast_visit_node_children(node, ast_print_visit, &new_ap);
+}
- break;
- }
- case NodeTypeReturnExpr:
- {
- const char *prefix_str = return_prefix_str(node->data.return_expr.kind);
- fprintf(f, "%s%s\n", prefix_str, node_type_str(node->type));
- if (node->data.return_expr.expr)
- ast_print(f, node->data.return_expr.expr, indent + 2);
- break;
- }
- case NodeTypeDefer:
- {
- const char *prefix_str = return_prefix_str(node->data.defer.kind);
- fprintf(f, "%s%s\n", prefix_str, node_type_str(node->type));
- if (node->data.defer.expr)
- ast_print(f, node->data.defer.expr, indent + 2);
- break;
- }
- case NodeTypeVariableDeclaration:
- {
- Buf *name_buf = &node->data.variable_declaration.symbol;
- fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf));
- if (node->data.variable_declaration.type)
- ast_print(f, node->data.variable_declaration.type, indent + 2);
- if (node->data.variable_declaration.expr)
- ast_print(f, node->data.variable_declaration.expr, indent + 2);
- break;
- }
- case NodeTypeTypeDecl:
- {
- Buf *name_buf = &node->data.type_decl.symbol;
- fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf));
- ast_print(f, node->data.type_decl.child_type, indent + 2);
- break;
- }
- case NodeTypeErrorValueDecl:
- {
- Buf *name_buf = &node->data.error_value_decl.name;
- fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf));
- break;
- }
- case NodeTypeFnDecl:
- fprintf(f, "%s\n", node_type_str(node->type));
- ast_print(f, node->data.fn_decl.fn_proto, indent + 2);
- break;
- case NodeTypeBinOpExpr:
- fprintf(f, "%s %s\n", node_type_str(node->type),
- bin_op_str(node->data.bin_op_expr.bin_op));
- ast_print(f, node->data.bin_op_expr.op1, indent + 2);
- ast_print(f, node->data.bin_op_expr.op2, indent + 2);
- break;
- case NodeTypeUnwrapErrorExpr:
- fprintf(f, "%s\n", node_type_str(node->type));
- ast_print(f, node->data.unwrap_err_expr.op1, indent + 2);
- if (node->data.unwrap_err_expr.symbol) {
- ast_print(f, node->data.unwrap_err_expr.symbol, indent + 2);
- }
- ast_print(f, node->data.unwrap_err_expr.op2, indent + 2);
- break;
- case NodeTypeFnCallExpr:
- fprintf(f, "%s\n", node_type_str(node->type));
- ast_print(f, node->data.fn_call_expr.fn_ref_expr, indent + 2);
- for (int i = 0; i < node->data.fn_call_expr.params.length; i += 1) {
- AstNode *child = node->data.fn_call_expr.params.at(i);
- ast_print(f, child, indent + 2);
- }
- break;
- case NodeTypeArrayAccessExpr:
- fprintf(f, "%s\n", node_type_str(node->type));
- ast_print(f, node->data.array_access_expr.array_ref_expr, indent + 2);
- ast_print(f, node->data.array_access_expr.subscript, indent + 2);
- break;
- case NodeTypeSliceExpr:
- fprintf(f, "%s\n", node_type_str(node->type));
- ast_print(f, node->data.slice_expr.array_ref_expr, indent + 2);
- ast_print(f, node->data.slice_expr.start, indent + 2);
- if (node->data.slice_expr.end) {
- ast_print(f, node->data.slice_expr.end, indent + 2);
- }
- break;
- case NodeTypeDirective:
- fprintf(f, "%s\n", node_type_str(node->type));
- ast_print(f, node->data.directive.expr, indent + 2);
- break;
- case NodeTypePrefixOpExpr:
- fprintf(f, "%s %s\n", node_type_str(node->type),
- prefix_op_str(node->data.prefix_op_expr.prefix_op));
- ast_print(f, node->data.prefix_op_expr.primary_expr, indent + 2);
- break;
- case NodeTypeNumberLiteral:
- {
- NumLit kind = node->data.number_literal.kind;
- const char *name = node_type_str(node->type);
- if (kind == NumLitUInt) {
- fprintf(f, "%s uint %" PRIu64 "\n", name, node->data.number_literal.data.x_uint);
- } else {
- fprintf(f, "%s float %f\n", name, node->data.number_literal.data.x_float);
- }
- break;
- }
- case NodeTypeStringLiteral:
- {
- const char *c = node->data.string_literal.c ? "c" : "";
- fprintf(f, "StringLiteral %s'%s'\n", c,
- buf_ptr(&node->data.string_literal.buf));
- break;
- }
- case NodeTypeCharLiteral:
- {
- fprintf(f, "%s '%c'\n", node_type_str(node->type), node->data.char_literal.value);
- break;
- }
- case NodeTypeSymbol:
- fprintf(f, "Symbol %s\n", buf_ptr(&node->data.symbol_expr.symbol));
- break;
- case NodeTypeUse:
- fprintf(f, "%s\n", node_type_str(node->type));
- ast_print(f, node->data.use.expr, indent + 2);
- break;
- case NodeTypeBoolLiteral:
- fprintf(f, "%s '%s'\n", node_type_str(node->type),
- node->data.bool_literal.value ? "true" : "false");
- break;
- case NodeTypeNullLiteral:
- fprintf(f, "%s\n", node_type_str(node->type));
- break;
- case NodeTypeIfBoolExpr:
- fprintf(f, "%s\n", node_type_str(node->type));
- if (node->data.if_bool_expr.condition)
- ast_print(f, node->data.if_bool_expr.condition, indent + 2);
- ast_print(f, node->data.if_bool_expr.then_block, indent + 2);
- if (node->data.if_bool_expr.else_node)
- ast_print(f, node->data.if_bool_expr.else_node, indent + 2);
- break;
- case NodeTypeIfVarExpr:
- {
- Buf *name_buf = &node->data.if_var_expr.var_decl.symbol;
- fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf));
- if (node->data.if_var_expr.var_decl.type)
- ast_print(f, node->data.if_var_expr.var_decl.type, indent + 2);
- if (node->data.if_var_expr.var_decl.expr)
- ast_print(f, node->data.if_var_expr.var_decl.expr, indent + 2);
- ast_print(f, node->data.if_var_expr.then_block, indent + 2);
- if (node->data.if_var_expr.else_node)
- ast_print(f, node->data.if_var_expr.else_node, indent + 2);
- break;
- }
- case NodeTypeWhileExpr:
- fprintf(f, "%s\n", node_type_str(node->type));
- ast_print(f, node->data.while_expr.condition, indent + 2);
- ast_print(f, node->data.while_expr.body, indent + 2);
- break;
- case NodeTypeForExpr:
- fprintf(f, "%s\n", node_type_str(node->type));
- ast_print(f, node->data.for_expr.elem_node, indent + 2);
- ast_print(f, node->data.for_expr.array_expr, indent + 2);
- if (node->data.for_expr.index_node) {
- ast_print(f, node->data.for_expr.index_node, indent + 2);
- }
- ast_print(f, node->data.for_expr.body, indent + 2);
- break;
- case NodeTypeSwitchExpr:
- fprintf(f, "%s\n", node_type_str(node->type));
- ast_print(f, node->data.switch_expr.expr, indent + 2);
- for (int i = 0; i < node->data.switch_expr.prongs.length; i += 1) {
- AstNode *child_node = node->data.switch_expr.prongs.at(i);
- ast_print(f, child_node, indent + 2);
- }
- break;
- case NodeTypeSwitchProng:
- fprintf(f, "%s\n", node_type_str(node->type));
- for (int i = 0; i < node->data.switch_prong.items.length; i += 1) {
- AstNode *child_node = node->data.switch_prong.items.at(i);
- ast_print(f, child_node, indent + 2);
- }
- if (node->data.switch_prong.var_symbol) {
- ast_print(f, node->data.switch_prong.var_symbol, indent + 2);
- }
- ast_print(f, node->data.switch_prong.expr, indent + 2);
- break;
- case NodeTypeSwitchRange:
- fprintf(f, "%s\n", node_type_str(node->type));
- ast_print(f, node->data.switch_range.start, indent + 2);
- ast_print(f, node->data.switch_range.end, indent + 2);
- break;
- case NodeTypeLabel:
- fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.label.name));
- break;
- case NodeTypeGoto:
- fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.goto_expr.name));
- break;
- case NodeTypeBreak:
- fprintf(f, "%s\n", node_type_str(node->type));
- break;
- case NodeTypeContinue:
- fprintf(f, "%s\n", node_type_str(node->type));
- break;
- case NodeTypeUndefinedLiteral:
- fprintf(f, "%s\n", node_type_str(node->type));
- break;
- case NodeTypeAsmExpr:
- fprintf(f, "%s\n", node_type_str(node->type));
- break;
- case NodeTypeFieldAccessExpr:
- fprintf(f, "%s '%s'\n", node_type_str(node->type),
- buf_ptr(&node->data.field_access_expr.field_name));
- ast_print(f, node->data.field_access_expr.struct_expr, indent + 2);
- break;
- case NodeTypeStructDecl:
- fprintf(f, "%s '%s'\n",
- node_type_str(node->type), buf_ptr(&node->data.struct_decl.name));
- for (int i = 0; i < node->data.struct_decl.fields.length; i += 1) {
- AstNode *child = node->data.struct_decl.fields.at(i);
- ast_print(f, child, indent + 2);
- }
- for (int i = 0; i < node->data.struct_decl.fns.length; i += 1) {
- AstNode *child = node->data.struct_decl.fns.at(i);
- ast_print(f, child, indent + 2);
- }
- break;
- case NodeTypeStructField:
- fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.struct_field.name));
- if (node->data.struct_field.type) {
- ast_print(f, node->data.struct_field.type, indent + 2);
- }
- break;
- case NodeTypeStructValueField:
- fprintf(f, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.struct_val_field.name));
- ast_print(f, node->data.struct_val_field.expr, indent + 2);
- break;
- case NodeTypeContainerInitExpr:
- fprintf(f, "%s\n", node_type_str(node->type));
- ast_print(f, node->data.container_init_expr.type, indent + 2);
- for (int i = 0; i < node->data.container_init_expr.entries.length; i += 1) {
- AstNode *child = node->data.container_init_expr.entries.at(i);
- ast_print(f, child, indent + 2);
- }
- break;
- case NodeTypeArrayType:
- {
- const char *const_str = node->data.array_type.is_const ? "const" : "var";
- fprintf(f, "%s %s\n", node_type_str(node->type), const_str);
- if (node->data.array_type.size) {
- ast_print(f, node->data.array_type.size, indent + 2);
- }
- ast_print(f, node->data.array_type.child_type, indent + 2);
- break;
- }
- case NodeTypeErrorType:
- fprintf(f, "%s\n", node_type_str(node->type));
- break;
- case NodeTypeTypeLiteral:
- fprintf(f, "%s\n", node_type_str(node->type));
- break;
- }
+void ast_print(FILE *f, AstNode *node, int indent) {
+ AstPrint ap;
+ ap.indent = indent;
+ ap.f = f;
+ ast_visit_node_children(node, ast_print_visit, &ap);
}
+
struct AstRender {
int indent;
int indent_size;