diff options
| author | Mustafa Quraish <[email protected]> | 2022-01-30 01:19:54 -0500 |
|---|---|---|
| committer | Mustafa Quraish <[email protected]> | 2022-01-30 01:19:54 -0500 |
| commit | 5b87ec6ef2b84f1d319e5376bcf9eedea9829d79 (patch) | |
| tree | f1afa80f034a1cd73192510046978435252e1160 /src/ast.c | |
| parent | Remove return-0 example (diff) | |
| download | cup-5b87ec6ef2b84f1d319e5376bcf9eedea9829d79.tar.xz cup-5b87ec6ef2b84f1d319e5376bcf9eedea9829d79.zip | |
Rename `cup` directory to `src`
Diffstat (limited to 'src/ast.c')
| -rw-r--r-- | src/ast.c | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/src/ast.c b/src/ast.c new file mode 100644 index 0000000..6e33de1 --- /dev/null +++ b/src/ast.c @@ -0,0 +1,161 @@ +#include "ast.h" +#include <assert.h> +#include <stdio.h> + +char *data_type_to_str(DataType type) +{ + switch (type) + { + case TYPE_NONE: return "void"; + case TYPE_INT: return "int"; + default: assert(false && "Unreachable"); + } +} + +void print_type_to_file(FILE *out, Type type) +{ + fprintf(out, "%s", data_type_to_str(type.type)); + for (int i = 0; i < type.indirection; i++) { + fprintf(out, "*"); + } +} + +char *node_type_to_str(NodeType type) +{ + switch (type) + { + #define ENUM_TOKEN(t, name) case t: return name; + ENUM_AST_TYPES(ENUM_TOKEN) + #undef ENUM_TOKEN + default: assert(false && "Unreachable"); + } +} + +bool is_binary_op(NodeType type) +{ + switch (type) + { + case OP_PLUS: + case OP_MINUS: + case OP_MUL: + case OP_DIV: + case OP_MOD: + case OP_LSHIFT: + case OP_RSHIFT: + case OP_AND: + case OP_OR: + case OP_XOR: + case OP_EQ: + case OP_NEQ: + case OP_LT: + case OP_LEQ: + case OP_GT: + case OP_GEQ: + return true; + default: return false; + } +} + +bool is_unary_op(NodeType type) +{ + switch (type) + { + case OP_NEG: + case OP_NOT: + case OP_BWINV: + return true; + default: return false; + } +} + +bool is_expression(NodeType type) +{ + if (is_unary_op(type) || is_binary_op(type)) + return true; + return type == AST_LITERAL; +} + +void dump_func(Node *, int); + +static void do_print_ast(Node *node, int depth) +{ + for (int i = 0; i < depth; i++) { + printf(" "); + } + if (node->type == AST_PROGRAM) { + for (int i = 0; i < node->block.num_children; i++) { + do_print_ast(node->block.children[i], depth); + } + } else if (node->type == AST_BLOCK) { + printf("{\n"); + for (int i = 0; i < node->block.num_children; i++) { + do_print_ast(node->block.children[i], depth + 1); + } + for (int i = 0; i < depth; i++) { + printf(" "); + } + printf("}\n"); + } else if (node->type == AST_FUNC) { + dump_func(node, depth); + } else if (node->type == AST_LITERAL) { + printf("%d\n", node->literal.as_int); + } else if (node->type == AST_RETURN) { + printf("return\n"); + do_print_ast(node->unary_expr, depth + 1); + } else if (is_unary_op(node->type)) { + printf("%s\n", node_type_to_str(node->type)); + do_print_ast(node->unary_expr, depth + 1); + } else if (is_binary_op(node->type)) { + printf("%s\n", node_type_to_str(node->type)); + do_print_ast(node->binary.left, depth + 1); + do_print_ast(node->binary.right, depth + 1); + } else if (node->type == AST_VAR) { + assert(node->variable && node->variable->name); + printf("%s\n", node->variable->name); + } else if (node->type == AST_VARDECL) { + printf("var %s (", node->var_decl.var.name); + print_type_to_file(stdout, node->var_decl.var.type); + printf(")"); + if (node->var_decl.value != NULL) { + printf(" = \n"); + do_print_ast(node->var_decl.value, depth + 1); + } else { + printf("\n"); + } + } else if (node->type == AST_FUNCCALL) { + printf("CALL %s(\n", node->call.func->func.name); + for (int i = 0; i < node->call.num_args; i++) { + do_print_ast(node->call.args[i], depth + 1); + } + for (int i = 0; i < depth; i++) { + printf(" "); + } + printf(")\n"); + } else { + printf("{{ %s }}\n", node_type_to_str(node->type)); + } +} + +void dump_func(Node *node, int depth) +{ + printf("fn %s(", node->func.name); + for (int i = 0; i < node->func.num_args; i++) { + if (i > 0) printf(", "); + printf("%s: ", node->func.args[i].name); + print_type_to_file(stdout, node->func.args[i].type); + printf("[[%lld]]", node->func.args[i].offset); + } + printf(")"); + if (node->func.return_type.type != TYPE_NONE) { + // FIXME: Print return type properly + printf(" -> "); + print_type_to_file(stdout, node->func.return_type); + } + + do_print_ast(node->func.body, depth + 1); +} + +void print_ast(Node *node) +{ + do_print_ast(node, 0); +}
\ No newline at end of file |