From 0cf982a577e43e660de6fbff155d50315a66119e Mon Sep 17 00:00:00 2001 From: Mustafa Quraish Date: Fri, 28 Jan 2022 10:01:30 -0500 Subject: Add AST/type definitions Just the basic building blocks for now, probably need to re-think how these are stored. --- cup/ast.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ cup/ast.h | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+) create mode 100644 cup/ast.c create mode 100644 cup/ast.h diff --git a/cup/ast.c b/cup/ast.c new file mode 100644 index 0000000..2f3d94d --- /dev/null +++ b/cup/ast.c @@ -0,0 +1,71 @@ +#include "ast.h" +#include +#include + +char *data_type_to_str(DataType type) +{ + switch (type) + { + case TYPE_NONE: return "void"; + case TYPE_INT: return "int"; + default: assert(false && "Unreachable"); + } +} + +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"); + } +} + +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) { + printf("fn %s()", node->func.name); + if (node->func.return_type.type != TYPE_NONE) { + // FIXME: Print return type properly + Type t = node->func.return_type; + printf(" -> %s", data_type_to_str(t.type)); + for (int i = 0; i < t.indirection; i++) { + printf("*"); + } + + } + printf("\n"); + do_print_ast(node->func.body, depth + 1); + } else if (node->type == AST_LITERAL) { + printf("(literal %d)\n", node->literal.as_int); + } else if (node->type == AST_RETURN) { + printf("return\n"); + do_print_ast(node->unary_expr, depth + 1); + } else { + printf("(unknown)\n"); + } +} + + +void print_ast(Node *node) +{ + do_print_ast(node, 0); +} \ No newline at end of file diff --git a/cup/ast.h b/cup/ast.h new file mode 100644 index 0000000..6170489 --- /dev/null +++ b/cup/ast.h @@ -0,0 +1,71 @@ +#pragma once + +#include + +#define ENUM_AST_TYPES(F) \ + F(OP_PLUS, "+") \ + F(OP_MINUS, "-") \ + F(OP_MUL, "*") \ + F(OP_DIV, "/") \ + F(AST_LITERAL, "literal") \ + F(AST_RETURN, "return") \ + F(AST_FUNC, "func") \ + F(AST_PROGRAM, "program") \ + F(AST_BLOCK, "block statements") \ + + +typedef enum { +#define DEFINE_ENUM(name, str) name, + ENUM_AST_TYPES(DEFINE_ENUM) +#undef DEFINE_ENUM +} NodeType; + +char *node_type_to_str(NodeType type); + +typedef enum { + TYPE_NONE, + TYPE_INT, +} DataType; + +char *data_type_to_str(DataType type); + +typedef struct { + DataType type; + // 0 = value, 1 = pointer, 2 = double pointer, ... + int indirection; +} Type; + +typedef struct ast_node Node; +typedef struct ast_node { + NodeType type; + + union { + // Binary expr + struct { + Node *left; + Node *right; + } binary; + // Unary expr + Node *unary_expr; + // Function definition + struct { + char *name; + Type return_type; + Node *body; + // TODO: Arguments / etc? + } func; + // Block of statements + struct { + Node **children; + int num_children; + } block; + struct { + Type type; + union { + int as_int; + }; + } literal; + }; +} Node; + +void print_ast(Node *node); \ No newline at end of file -- cgit v1.2.3