about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMel <mel@rnrd.eu>2026-05-03 01:27:40 +0200
committerMel <mel@rnrd.eu>2026-05-03 01:27:40 +0200
commitfb13c2be5538b10ae456bcb30bfef6622ab6911f (patch)
tree87a69398ec9568b0240a14ed36e27379087fe301
parent129e5669015a7ffd78d0f665f46cc434bcf126d2 (diff)
downloadcatskill-fb13c2be5538b10ae456bcb30bfef6622ab6911f.tar.zst
catskill-fb13c2be5538b10ae456bcb30bfef6622ab6911f.zip
Rename tree nodes to add consistent prefix, de-node, clean-up names
Signed-off-by: Mel <mel@rnrd.eu>
-rw-r--r--boot/parse.c500
-rw-r--r--boot/transpile.c116
-rw-r--r--boot/tree.c526
-rw-r--r--boot/visit.c652
4 files changed, 897 insertions, 897 deletions
diff --git a/boot/parse.c b/boot/parse.c
index ea6b06b..157b73d 100644
--- a/boot/parse.c
+++ b/boot/parse.c
@@ -379,8 +379,8 @@ parser_panic(struct Parser* p)
     }
 }
 
-struct Statement* parser_statement(struct Parser* p, struct Parser_Error* error);
-struct Expression* parser_expression(struct Parser* p, struct Parser_Error* error);
+struct Tree_Statement* parser_statement(struct Parser* p, struct Parser_Error* error);
+struct Tree_Expression* parser_expression(struct Parser* p, struct Parser_Error* error);
 
 void
 parser_end_statement(struct Parser* p, struct Parser_Error* error)
@@ -393,24 +393,24 @@ parser_end_statement(struct Parser* p, struct Parser_Error* error)
     parser_next(p);
 }
 
-struct Block_Node
+struct Tree_Block
 parser_block_node(struct Parser* p, struct Parser_Error* error)
 {
     struct Token start_token =
-        CHECK_RETURN(parser_need(p, TOKEN_CURLY_OPEN, error), struct Block_Node);
+        CHECK_RETURN(parser_need(p, TOKEN_CURLY_OPEN, error), struct Tree_Block);
 
     parser_unglue(p);
 
-    struct Statement* head = nil;
-    struct Statement* current = nil;
+    struct Tree_Statement* head = nil;
+    struct Tree_Statement* current = nil;
 
     while (!parser_probe(p, TOKEN_CURLY_CLOSE)) {
-        struct Statement* statement = CHECK_RETURN(parser_statement(p, error), struct Block_Node);
+        struct Tree_Statement* statement = CHECK_RETURN(parser_statement(p, error), struct Tree_Block);
 
         // statement ending token isn't required when the block ends on the same line,
         // as in e.g.: `if (true) { print("yes") }`
         if (!parser_probe(p, TOKEN_CURLY_CLOSE))
-            CHECK_RETURN(parser_end_statement(p, error), struct Block_Node);
+            CHECK_RETURN(parser_end_statement(p, error), struct Tree_Block);
 
         if (!head) {
             head = statement;
@@ -421,25 +421,25 @@ parser_block_node(struct Parser* p, struct Parser_Error* error)
     }
 
     struct Token end_token =
-        CHECK_RETURN(parser_need(p, TOKEN_CURLY_CLOSE, error), struct Block_Node);
+        CHECK_RETURN(parser_need(p, TOKEN_CURLY_CLOSE, error), struct Tree_Block);
     struct Span span = span_merge(start_token.span, end_token.span);
 
-    return (struct Block_Node){
+    return (struct Tree_Block){
         .statements = head,
         .span = span,
         .location = start_token.location,
     };
 }
 
-struct Type_Node* parser_node_type(struct Parser* p, struct Parser_Error* error);
+struct Tree_Type* parser_node_type(struct Parser* p, struct Parser_Error* error);
 
-struct Function_Header_Node
+struct Tree_Function_Header
 parser_function_header_node(struct Parser* p, struct Parser_Error* error)
 {
     struct Token open_parameters_token =
-        CHECK_RETURN(parser_need(p, TOKEN_ROUND_OPEN, error), struct Function_Header_Node);
+        CHECK_RETURN(parser_need(p, TOKEN_ROUND_OPEN, error), struct Tree_Function_Header);
 
-    struct Function_Header_Node header = { 0 };
+    struct Tree_Function_Header header = { 0 };
     while (!parser_probe(p, TOKEN_ROUND_CLOSE)) {
         // TODO: correctly output parameter spans
         bool variadic = false;
@@ -449,14 +449,14 @@ parser_function_header_node(struct Parser* p, struct Parser_Error* error)
         }
 
         struct Token name_token =
-            CHECK_RETURN(parser_need(p, TOKEN_NAME, error), struct Function_Header_Node);
+            CHECK_RETURN(parser_need(p, TOKEN_NAME, error), struct Tree_Function_Header);
         struct String name = name_token.value.name;
 
-        struct Type_Node* type;
+        struct Tree_Type* type;
         if (!parser_probe(p, TOKEN_ROUND_CLOSE) && !parser_probe(p, TOKEN_COMMA)) {
-            type = CHECK_RETURN(parser_node_type(p, error), struct Function_Header_Node);
+            type = CHECK_RETURN(parser_node_type(p, error), struct Tree_Function_Header);
         } else {
-            type = type_node_none(name_token.span, name_token.location);
+            type = tree_type_none(name_token.span, name_token.location);
         }
 
         type->value_name = name;
@@ -489,18 +489,18 @@ parser_function_header_node(struct Parser* p, struct Parser_Error* error)
         // check away.
         if (token_is(&next, TOKEN_CURLY_OPEN) && token_is(&further, TOKEN_NEWLINE)) return header;
 
-        header.return_type = CHECK_RETURN(parser_node_type(p, error), struct Function_Header_Node);
+        header.return_type = CHECK_RETURN(parser_node_type(p, error), struct Tree_Function_Header);
         header.span = span_merge(header.span, header.return_type->span);
     }
 
     return header;
 }
 
-struct Argument_Group_Node
+struct Tree_Argument_Group
 parser_argument_group_node(struct Parser* p, struct Parser_Error* error)
 {
     Array(struct String) argument_names = array_new(struct String, 32);
-    struct Expression *arguments_head = nil, *arguments_current = nil;
+    struct Tree_Expression *arguments_head = nil, *arguments_current = nil;
     for (;;) {
         // check if we have a named argument.
         struct String name = string_empty();
@@ -511,8 +511,8 @@ parser_argument_group_node(struct Parser* p, struct Parser_Error* error)
             name = name_token.value.name;
         }
 
-        struct Expression* argument =
-            CHECK_RETURN(parser_expression(p, error), struct Argument_Group_Node);
+        struct Tree_Expression* argument =
+            CHECK_RETURN(parser_expression(p, error), struct Tree_Argument_Group);
         if (!arguments_head)
             arguments_head = argument;
         else
@@ -530,12 +530,12 @@ parser_argument_group_node(struct Parser* p, struct Parser_Error* error)
         }
     }
 
-    return (struct Argument_Group_Node){
+    return (struct Tree_Argument_Group){
         .arguments = arguments_head, .argument_names = argument_names
     };
 }
 
-struct Bare_Declaration_Node
+struct Tree_Bare_Declaration
 parser_bare_declaration_node(struct Parser* p, struct Parser_Error* error)
 {
     Array(struct String) names = array_new(struct String, 16);
@@ -544,7 +544,7 @@ parser_bare_declaration_node(struct Parser* p, struct Parser_Error* error)
     struct Cursor location = parser_peek(p).location;
     for (;;) {
         struct Token name_token =
-            CHECK_RETURN(parser_need(p, TOKEN_NAME, error), struct Bare_Declaration_Node);
+            CHECK_RETURN(parser_need(p, TOKEN_NAME, error), struct Tree_Bare_Declaration);
 
         span = span_is_empty(span) ? name_token.span : span_merge(span, name_token.span);
         array_push(&names, &name_token.value.name);
@@ -555,12 +555,12 @@ parser_bare_declaration_node(struct Parser* p, struct Parser_Error* error)
     }
 
     // for now, type is always required.
-    struct Type_Node* type = CHECK_RETURN(parser_node_type(p, error), struct Bare_Declaration_Node);
-    CHECK_RETURN(parser_need(p, TOKEN_ASSIGN, error), struct Bare_Declaration_Node);
-    struct Expression* initializer =
-        CHECK_RETURN(parser_expression(p, error), struct Bare_Declaration_Node);
+    struct Tree_Type* type = CHECK_RETURN(parser_node_type(p, error), struct Tree_Bare_Declaration);
+    CHECK_RETURN(parser_need(p, TOKEN_ASSIGN, error), struct Tree_Bare_Declaration);
+    struct Tree_Expression* initializer =
+        CHECK_RETURN(parser_expression(p, error), struct Tree_Bare_Declaration);
 
-    return (struct Bare_Declaration_Node){
+    return (struct Tree_Bare_Declaration){
         .names = names,
         .initializer = initializer,
         .type = type,
@@ -570,27 +570,27 @@ parser_bare_declaration_node(struct Parser* p, struct Parser_Error* error)
     };
 }
 
-struct Type_Node*
+struct Tree_Type*
 parser_node_type_name(struct Parser* p, struct Parser_Error* error)
 {
     struct Token name_token = CHECK(parser_need(p, TOKEN_NAME, error));
-    return type_node_new(
-        TYPE_NODE_NAME, (union Type_Node_Value){ .name = { name_token.value.name } },
+    return tree_type_new(
+        TREE_TYPE_NAME, (union Tree_Type_Value){ .name = { name_token.value.name } },
         name_token.span, name_token.location);
 }
 
-struct Type_Node*
+struct Tree_Type*
 parser_node_type_structure(struct Parser* p, struct Parser_Error* error)
 {
     struct Token open_token = CHECK(parser_need(p, TOKEN_CURLY_OPEN, error));
 
     parser_unglue(p);
 
-    struct Type_Node *head = nil, *current = nil;
+    struct Tree_Type *head = nil, *current = nil;
     while (!parser_probe(p, TOKEN_CURLY_CLOSE)) {
         struct Token field_name_token = CHECK(parser_need(p, TOKEN_NAME, error));
 
-        struct Type_Node* field_type = CHECK(parser_node_type(p, error));
+        struct Tree_Type* field_type = CHECK(parser_node_type(p, error));
         field_type->value_name = field_name_token.value.name;
 
         if (!head)
@@ -607,12 +607,12 @@ parser_node_type_structure(struct Parser* p, struct Parser_Error* error)
     struct Token close_token = CHECK(parser_need(p, TOKEN_CURLY_CLOSE, error));
     struct Span span = span_merge(open_token.span, close_token.span);
 
-    return type_node_new(
-        TYPE_NODE_STRUCTURE, (union Type_Node_Value){ .structure = { head } }, span,
+    return tree_type_new(
+        TREE_TYPE_STRUCTURE, (union Tree_Type_Value){ .structure = { head } }, span,
         open_token.location);
 }
 
-struct Type_Node*
+struct Tree_Type*
 parser_node_type_variant(struct Parser* p, struct Parser_Error* error)
 {
     struct Token variant_token = CHECK(parser_need(p, TOKEN_WORD_VARIANT, error));
@@ -620,12 +620,12 @@ parser_node_type_variant(struct Parser* p, struct Parser_Error* error)
 
     parser_unglue(p);
 
-    struct Type_Node *head = nil, *current = nil;
+    struct Tree_Type *head = nil, *current = nil;
     while (!parser_probe(p, TOKEN_CURLY_CLOSE)) {
         struct Token variant_name_token = CHECK(parser_need(p, TOKEN_NAME, error));
         struct String variant_name = variant_name_token.value.name;
 
-        struct Type_Node* backing_type = nil;
+        struct Tree_Type* backing_type = nil;
 
         struct Token next = parser_peek(p);
         bool has_backing_type =
@@ -635,7 +635,7 @@ parser_node_type_variant(struct Parser* p, struct Parser_Error* error)
         if (has_backing_type) {
             backing_type = CHECK(parser_node_type(p, error));
         } else {
-            backing_type = type_node_none(variant_name_token.span, variant_name_token.location);
+            backing_type = tree_type_none(variant_name_token.span, variant_name_token.location);
         }
 
         backing_type->value_name = variant_name;
@@ -654,24 +654,24 @@ parser_node_type_variant(struct Parser* p, struct Parser_Error* error)
     struct Token close_token = CHECK(parser_need(p, TOKEN_CURLY_CLOSE, error));
     struct Span span = span_merge(variant_token.span, close_token.span);
 
-    return type_node_new(
-        TYPE_NODE_VARIANT, (union Type_Node_Value){ .variant = { head } }, span,
+    return tree_type_new(
+        TREE_TYPE_VARIANT, (union Tree_Type_Value){ .variant = { head } }, span,
         variant_token.location);
 }
 
-struct Type_Node*
+struct Tree_Type*
 parser_node_type_function(struct Parser* p, struct Parser_Error* error)
 {
     struct Token fun_token = CHECK(parser_need(p, TOKEN_WORD_FUN, error));
-    struct Function_Header_Node header = CHECK(parser_function_header_node(p, error));
+    struct Tree_Function_Header header = CHECK(parser_function_header_node(p, error));
 
     struct Span span = span_merge(fun_token.span, header.span);
-    return type_node_new(
-        TYPE_NODE_FUNCTION, (union Type_Node_Value){ .function = { header } }, span,
+    return tree_type_new(
+        TREE_TYPE_FUNCTION, (union Tree_Type_Value){ .function = { header } }, span,
         fun_token.location);
 }
 
-struct Type_Node*
+struct Tree_Type*
 parser_node_type_class(struct Parser* p, struct Parser_Error* error)
 {
     struct Token class_token = CHECK(parser_need(p, TOKEN_WORD_CLASS, error));
@@ -679,16 +679,16 @@ parser_node_type_class(struct Parser* p, struct Parser_Error* error)
 
     parser_unglue(p);
 
-    struct Type_Node *head = nil, *current = nil;
+    struct Tree_Type *head = nil, *current = nil;
     while (!parser_probe(p, TOKEN_CURLY_CLOSE)) {
         struct Token method_name_token = CHECK(parser_need(p, TOKEN_NAME, error));
         struct String method_name = method_name_token.value.name;
 
-        struct Function_Header_Node header = CHECK(parser_function_header_node(p, error));
+        struct Tree_Function_Header header = CHECK(parser_function_header_node(p, error));
         // allocate a new type node for the method type,
         // for the sake of consistency and the built-in type node linked list.
-        struct Type_Node* method_type = type_node_new(
-            TYPE_NODE_FUNCTION, (union Type_Node_Value){ .function = { header } }, header.span,
+        struct Tree_Type* method_type = tree_type_new(
+            TREE_TYPE_FUNCTION, (union Tree_Type_Value){ .function = { header } }, header.span,
             header.location);
         method_type->value_name = method_name;
 
@@ -705,18 +705,18 @@ parser_node_type_class(struct Parser* p, struct Parser_Error* error)
 
     struct Token close_token = CHECK(parser_need(p, TOKEN_CURLY_CLOSE, error));
     struct Span span = span_merge(class_token.span, close_token.span);
-    return type_node_new(
-        TYPE_NODE_CLASS, (union Type_Node_Value){ .class = { head } }, span, class_token.location);
+    return tree_type_new(
+        TREE_TYPE_CLASS, (union Tree_Type_Value){ .class = { head } }, span, class_token.location);
 }
 
-struct Type_Node*
+struct Tree_Type*
 parser_node_type_tuple(struct Parser* p, struct Parser_Error* error)
 {
     struct Token open_token = CHECK(parser_need(p, TOKEN_ROUND_OPEN, error));
 
-    struct Type_Node *head = nil, *current = nil;
+    struct Tree_Type *head = nil, *current = nil;
     while (!parser_probe(p, TOKEN_ROUND_CLOSE)) {
-        struct Type_Node* type = CHECK(parser_node_type(p, error));
+        struct Tree_Type* type = CHECK(parser_node_type(p, error));
 
         if (!head)
             head = type;
@@ -732,69 +732,69 @@ parser_node_type_tuple(struct Parser* p, struct Parser_Error* error)
 
     struct Token close_token = CHECK(parser_need(p, TOKEN_ROUND_CLOSE, error));
     struct Span span = span_merge(open_token.span, close_token.span);
-    return type_node_new(
-        TYPE_NODE_TUPLE, (union Type_Node_Value){ .tuple = { head } }, span, open_token.location);
+    return tree_type_new(
+        TREE_TYPE_TUPLE, (union Tree_Type_Value){ .tuple = { head } }, span, open_token.location);
 }
 
-struct Type_Node*
+struct Tree_Type*
 parser_node_type_array_or_map(struct Parser* p, struct Parser_Error* error)
 {
     struct Token open_token = CHECK(parser_need(p, TOKEN_SQUARE_OPEN, error));
 
-    struct Type_Node* element_or_key_type = parser_node_type(p, error);
+    struct Tree_Type* element_or_key_type = parser_node_type(p, error);
     if (!element_or_key_type) {
         parser_error_wrap(error, PARSER_ERROR_EXPECTED_TYPE);
         return nil;
     }
 
-    enum Type_Node_Type type;
-    union Type_Node_Value value;
+    enum Tree_Type_Type type;
+    union Tree_Type_Value value;
     if (parser_probe(p, TOKEN_ASSIGN)) {
         // this is a map type, e.g. `[string = int]`
         parser_next(p); // consume the assignment token
 
-        struct Type_Node* key_type = element_or_key_type;
-        struct Type_Node* value_type = parser_node_type(p, error);
+        struct Tree_Type* key_type = element_or_key_type;
+        struct Tree_Type* value_type = parser_node_type(p, error);
         if (!value_type) {
             parser_error_wrap(error, PARSER_ERROR_EXPECTED_TYPE);
             return nil;
         }
 
-        type = TYPE_NODE_MAP;
-        value.map = (struct Type_Node_Map){
+        type = TREE_TYPE_MAP;
+        value.map = (struct Tree_Type_Map){
             .key_type = key_type,
             .value_type = value_type,
         };
     } else {
         // this is an array type, e.g. `[int]`
-        type = TYPE_NODE_ARRAY;
-        value.array = (struct Type_Node_Array){ .element_type = element_or_key_type };
+        type = TREE_TYPE_ARRAY;
+        value.array = (struct Tree_Type_Array){ .element_type = element_or_key_type };
     }
 
     struct Token close_token = CHECK(parser_need(p, TOKEN_SQUARE_CLOSE, error));
 
     struct Span span = span_merge(open_token.span, close_token.span);
-    return type_node_new(type, value, span, open_token.location);
+    return tree_type_new(type, value, span, open_token.location);
 }
 
-struct Type_Node*
+struct Tree_Type*
 parser_node_type_reference(struct Parser* p, struct Parser_Error* error)
 {
     struct Token ampersand_token = CHECK(parser_need(p, TOKEN_AMPERSAND, error));
 
-    struct Type_Node* referenced_type = CHECK(parser_node_type(p, error));
+    struct Tree_Type* referenced_type = CHECK(parser_node_type(p, error));
     if (!referenced_type) {
         parser_error(error, PARSER_ERROR_EXPECTED_TYPE, ampersand_token);
         return nil;
     }
 
     struct Span span = span_merge(ampersand_token.span, referenced_type->span);
-    return type_node_new(
-        TYPE_NODE_REFERENCE, (union Type_Node_Value){ .reference = { referenced_type } }, span,
+    return tree_type_new(
+        TREE_TYPE_REFERENCE, (union Tree_Type_Value){ .reference = { referenced_type } }, span,
         ampersand_token.location);
 }
 
-struct Type_Node*
+struct Tree_Type*
 parser_node_type_inner(struct Parser* p, struct Parser_Error* error)
 {
     struct Token token = parser_peek(p);
@@ -821,34 +821,34 @@ parser_node_type_inner(struct Parser* p, struct Parser_Error* error)
     }
 }
 
-struct Type_Node*
+struct Tree_Type*
 parser_node_type(struct Parser* p, struct Parser_Error* error)
 {
-    struct Type_Node* type = CHECK(parser_node_type_inner(p, error));
+    struct Tree_Type* type = CHECK(parser_node_type_inner(p, error));
 
     // check if the type is followed by a `?`, which means it may be nil.
     if (parser_probe(p, TOKEN_QUESTION)) {
         parser_next(p); // consume the question mark
-        type = type_node_new(
-            TYPE_NODE_MAYBE, (union Type_Node_Value){ .maybe = { type } }, type->span,
+        type = tree_type_new(
+            TREE_TYPE_MAYBE, (union Tree_Type_Value){ .maybe = { type } }, type->span,
             type->location);
     }
 
     return type;
 }
 
-struct Pragma_Node*
+struct Tree_Pragma*
 parser_pragma_node(struct Parser* p, struct Parser_Error* error)
 {
     // `| c_header "stdio.h"`
     // `| clone always, printable
     CHECK(parser_need(p, TOKEN_PIPE, error));
 
-    struct Pragma_Node *head = nil, *current = nil;
+    struct Tree_Pragma *head = nil, *current = nil;
     struct Token token = parser_peek(p);
     while (!token_ends_statement(&token)) {
         struct Token pragma_token = CHECK(parser_need(p, TOKEN_NAME, error));
-        enum Pragma_Type pragma_type = pragma_type_from_string(pragma_token.value.name);
+        enum Tree_Pragma_Type pragma_type = tree_pragma_type_from_string(pragma_token.value.name);
         if (!pragma_type) {
             parser_error(error, PARSER_ERROR_EXPECTED_PRAGMA, pragma_token);
             return nil;
@@ -859,29 +859,29 @@ parser_pragma_node(struct Parser* p, struct Parser_Error* error)
         // parse the arguments until either statement end or comma
         // arguments can either be numbers, names or strings.
         uint argument_index = 0;
-        struct Pragma_Argument arguments[PRAGMA_ARGUMENT_MAX] = { 0 };
+        struct Tree_Pragma_Argument arguments[TREE_PRAGMA_ARGUMENT_MAX] = { 0 };
 
         token = parser_peek(p);
         while (!token_ends_statement(&token)) {
-            check(argument_index < PRAGMA_ARGUMENT_MAX, "too many pragma arguments");
-            struct Pragma_Argument* argument = &arguments[argument_index];
+            check(argument_index < TREE_PRAGMA_ARGUMENT_MAX, "too many pragma arguments");
+            struct Tree_Pragma_Argument* argument = &arguments[argument_index];
 
             union Token_Value* v = &token.value;
             switch (token.kind) {
             case TOKEN_LITERAL_INTEGER:
-                argument->type = PRAGMA_ARGUMENT_NUMBER;
+                argument->type = TREE_PRAGMA_ARGUMENT_NUMBER;
                 argument->value.number = v->literal_integer;
                 break;
             case TOKEN_LITERAL_FLOAT:
-                argument->type = PRAGMA_ARGUMENT_DECIMAL;
+                argument->type = TREE_PRAGMA_ARGUMENT_DECIMAL;
                 argument->value.decimal = v->literal_float;
                 break;
             case TOKEN_LITERAL_STRING:
-                argument->type = PRAGMA_ARGUMENT_NAME_OR_STRING;
+                argument->type = TREE_PRAGMA_ARGUMENT_NAME_OR_STRING;
                 argument->value.name_or_string = v->literal_string;
                 break;
             case TOKEN_NAME:
-                argument->type = PRAGMA_ARGUMENT_NAME_OR_STRING;
+                argument->type = TREE_PRAGMA_ARGUMENT_NAME_OR_STRING;
                 argument->value.name_or_string = v->name;
                 break;
             default:
@@ -901,7 +901,7 @@ parser_pragma_node(struct Parser* p, struct Parser_Error* error)
             if (token_ends_statement(&token)) { break; }
         }
 
-        struct Pragma_Node* pragma = pragma_node_new(pragma_type, span, pragma_token.location);
+        struct Tree_Pragma* pragma = tree_pragma_new(pragma_type, span, pragma_token.location);
         pragma->argument_count = argument_index;
         memcpy(pragma->arguments, arguments, sizeof(arguments));
 
@@ -916,81 +916,81 @@ parser_pragma_node(struct Parser* p, struct Parser_Error* error)
     return head;
 }
 
-struct Expression*
+struct Tree_Expression*
 parser_expression_primary_name(struct Parser* p, struct Parser_Error* error)
 {
     struct Token token = CHECK(parser_need(p, TOKEN_NAME, error));
-    union Expression_Value value = { .name = { token.value.name } };
-    return expression_new(EXPRESSION_NAME, value, token.span, token.location);
+    union Tree_Expression_Value value = { .name = { token.value.name } };
+    return tree_expression_new(TREE_EXPRESSION_NAME, value, token.span, token.location);
 }
 
-struct Expression*
+struct Tree_Expression*
 parser_expression_primary_integer(struct Parser* p, struct Parser_Error* error)
 {
     struct Token token = CHECK(parser_need(p, TOKEN_LITERAL_INTEGER, error));
-    union Expression_Value value = { .integer_literal = { token.value.literal_integer } };
-    return expression_new(EXPRESSION_INTEGER_LITERAL, value, token.span, token.location);
+    union Tree_Expression_Value value = { .integer_literal = { token.value.literal_integer } };
+    return tree_expression_new(TREE_EXPRESSION_INTEGER_LITERAL, value, token.span, token.location);
 }
 
-struct Expression*
+struct Tree_Expression*
 parser_expression_primary_float(struct Parser* p, struct Parser_Error* error)
 {
     struct Token token = CHECK(parser_need(p, TOKEN_LITERAL_FLOAT, error));
-    union Expression_Value value = { .float_literal = { token.value.literal_float } };
-    return expression_new(EXPRESSION_FLOAT_LITERAL, value, token.span, token.location);
+    union Tree_Expression_Value value = { .float_literal = { token.value.literal_float } };
+    return tree_expression_new(TREE_EXPRESSION_FLOAT_LITERAL, value, token.span, token.location);
 }
 
-struct Expression*
+struct Tree_Expression*
 parser_expression_primary_string(struct Parser* p, struct Parser_Error* error)
 {
     struct Token token = CHECK(parser_need(p, TOKEN_LITERAL_STRING, error));
-    union Expression_Value value = { .string_literal = { token.value.literal_string } };
-    return expression_new(EXPRESSION_STRING_LITERAL, value, token.span, token.location);
+    union Tree_Expression_Value value = { .string_literal = { token.value.literal_string } };
+    return tree_expression_new(TREE_EXPRESSION_STRING_LITERAL, value, token.span, token.location);
 }
 
-struct Expression*
+struct Tree_Expression*
 parser_expression_primary_boolean(struct Parser* p, struct Parser_Error* error)
 {
     struct Token token = parser_next(p);
     check(token.kind == TOKEN_WORD_TRUE || token.kind == TOKEN_WORD_FALSE,
           "expected boolean literal");
     bool literal = token.kind == TOKEN_WORD_TRUE;
-    union Expression_Value expr_value = { .bool_literal = { literal } };
-    return expression_new(EXPRESSION_BOOLEAN_LITERAL, expr_value, token.span, token.location);
+    union Tree_Expression_Value expr_value = { .bool_literal = { literal } };
+    return tree_expression_new(TREE_EXPRESSION_BOOLEAN_LITERAL, expr_value, token.span, token.location);
 }
 
-struct Expression*
+struct Tree_Expression*
 parser_expression_primary_group(struct Parser* p, struct Parser_Error* error)
 {
     struct Token start_token = CHECK(parser_need(p, TOKEN_ROUND_OPEN, error));
-    struct Expression* expression = CHECK(parser_expression(p, error));
+    struct Tree_Expression* expression = CHECK(parser_expression(p, error));
     struct Token end_token = CHECK(parser_need(p, TOKEN_ROUND_CLOSE, error));
 
     struct Span span = span_merge(start_token.span, end_token.span);
-    union Expression_Value value = { .group = { expression } };
-    return expression_new(EXPRESSION_GROUP, value, span, start_token.location);
+    union Tree_Expression_Value value = { .group = { expression } };
+    return tree_expression_new(TREE_EXPRESSION_GROUP, value, span, start_token.location);
 }
 
-struct Expression*
+struct Tree_Expression*
 parser_expression_function(struct Parser* p, struct Parser_Error* error)
 {
     struct Token fun_token = CHECK(parser_need(p, TOKEN_WORD_FUN, error));
-    struct Expression_Function fun = { 0 };
+    struct Tree_Expression_Function fun = { 0 };
 
     fun.header = CHECK(parser_function_header_node(p, error));
     fun.body = CHECK(parser_block_node(p, error));
 
-    return expression_new(
-        EXPRESSION_FUNCTION, (union Expression_Value){ .function = fun },
+    return tree_expression_new(
+        TREE_EXPRESSION_FUNCTION, (union Tree_Expression_Value){ .function = fun },
         span_merge(fun_token.span, fun.body.span), fun_token.location);
 }
 
-struct Expression*
+struct Tree_Expression*
 parser_expression_type(struct Parser* p, struct Parser_Error* error)
 {
     struct Token start_token = parser_peek(p);
 
-    struct Type_Node* type = nil;
+    struct Tree_Type* type = nil;
     switch (start_token.kind) {
     case TOKEN_WORD_TYPE:
         parser_next(p); // skip the `type` keyword.
@@ -1007,11 +1007,11 @@ parser_expression_type(struct Parser* p, struct Parser_Error* error)
     }
 
     struct Span span = span_merge(start_token.span, type->span);
-    return expression_new(
-        EXPRESSION_TYPE, (union Expression_Value){ .type = { type } }, span, start_token.location);
+    return tree_expression_new(
+        TREE_EXPRESSION_TYPE, (union Tree_Expression_Value){ .type = { type } }, span, start_token.location);
 }
 
-struct Expression*
+struct Tree_Expression*
 parser_expression_primary(struct Parser* p, struct Parser_Error* error)
 {
     struct Token token = parser_peek(p);
@@ -1043,9 +1043,9 @@ parser_expression_primary(struct Parser* p, struct Parser_Error* error)
     }
 }
 
-struct Expression*
+struct Tree_Expression*
 parser_expression_postfix_member(
-    struct Parser* p, struct Expression* subject, struct Parser_Error* error)
+    struct Parser* p, struct Tree_Expression* subject, struct Parser_Error* error)
 {
     CHECK(parser_need(p, TOKEN_DOT, error));
 
@@ -1053,18 +1053,18 @@ parser_expression_postfix_member(
     struct String name = name_token.value.name;
 
     struct Span span = span_merge(subject->span, name_token.span);
-    union Expression_Value value = { .member = { subject, name } };
-    return expression_new(EXPRESSION_MEMBER, value, span, name_token.location);
+    union Tree_Expression_Value value = { .member = { subject, name } };
+    return tree_expression_new(TREE_EXPRESSION_MEMBER, value, span, name_token.location);
 }
 
-struct Expression*
+struct Tree_Expression*
 parser_expression_postfix_call(
-    struct Parser* p, struct Expression* subject, struct Parser_Error* error)
+    struct Parser* p, struct Tree_Expression* subject, struct Parser_Error* error)
 {
     CHECK(parser_need(p, TOKEN_ROUND_OPEN, error));
     parser_unglue(p);
 
-    struct Argument_Group_Node argument_group = parser_argument_group_node(p, error);
+    struct Tree_Argument_Group argument_group = parser_argument_group_node(p, error);
     if (!parser_error_is_none(error)) {
         parser_error_wrap(error, PARSER_ERROR_EXPECTED_ARGUMENTS);
         return nil;
@@ -1074,18 +1074,18 @@ parser_expression_postfix_call(
     struct Token close_token = CHECK(parser_need(p, TOKEN_ROUND_CLOSE, error));
 
     struct Span span = span_merge(subject->span, close_token.span);
-    union Expression_Value value = { .call = { subject, argument_group } };
-    return expression_new(EXPRESSION_CALL, value, span, close_token.location);
+    union Tree_Expression_Value value = { .call = { subject, argument_group } };
+    return tree_expression_new(TREE_EXPRESSION_CALL, value, span, close_token.location);
 }
 
-struct Expression*
+struct Tree_Expression*
 parser_expression_postfix_construct(
-    struct Parser* p, struct Expression* subject, struct Parser_Error* error)
+    struct Parser* p, struct Tree_Expression* subject, struct Parser_Error* error)
 {
     CHECK(parser_need(p, TOKEN_CURLY_OPEN, error));
     parser_unglue(p);
 
-    struct Argument_Group_Node argument_group = parser_argument_group_node(p, error);
+    struct Tree_Argument_Group argument_group = parser_argument_group_node(p, error);
     if (!parser_error_is_none(error)) {
         parser_error_wrap(error, PARSER_ERROR_EXPECTED_ARGUMENTS);
         return nil;
@@ -1096,68 +1096,68 @@ parser_expression_postfix_construct(
 
     struct Span span = span_merge(subject->span, token.span);
     // TODO: convert the `subject` expression to a type node? somehow?
-    union Expression_Value value = { .construct = { subject, argument_group } };
-    return expression_new(EXPRESSION_CONSTRUCT, value, span, token.location);
+    union Tree_Expression_Value value = { .construct = { subject, argument_group } };
+    return tree_expression_new(TREE_EXPRESSION_CONSTRUCT, value, span, token.location);
 }
 
-struct Expression*
+struct Tree_Expression*
 parser_expression_postfix_subscript(
-    struct Parser* p, struct Expression* subject, struct Parser_Error* error)
+    struct Parser* p, struct Tree_Expression* subject, struct Parser_Error* error)
 {
     CHECK(parser_need(p, TOKEN_SQUARE_OPEN, error));
 
-    struct Expression* index = CHECK(parser_expression(p, error));
+    struct Tree_Expression* index = CHECK(parser_expression(p, error));
     struct Token token = CHECK(parser_need(p, TOKEN_SQUARE_CLOSE, error));
 
     struct Span span = span_merge(subject->span, span_merge(index->span, token.span));
-    union Expression_Value value = { .subscript = { subject, index } };
-    return expression_new(EXPRESSION_SUBSCRIPT, value, span, token.location);
+    union Tree_Expression_Value value = { .subscript = { subject, index } };
+    return tree_expression_new(TREE_EXPRESSION_SUBSCRIPT, value, span, token.location);
 }
 
-struct Expression*
+struct Tree_Expression*
 parser_expression_postfix_increment_decrement(
-    struct Parser* p, struct Expression* subject, struct Parser_Error* error)
+    struct Parser* p, struct Tree_Expression* subject, struct Parser_Error* error)
 {
     struct Token token = parser_peek(p);
     enum Increment_Decrement_Operation operation = increment_decrement_operation_from_token(&token);
 
-    struct Expression_Increment_Decrement inc_dec = {
+    struct Tree_Expression_Increment_Decrement inc_dec = {
         .prefix = false,
         .subject = subject,
         .operation = operation,
     };
 
     struct Span span = span_merge(subject->span, token.span);
-    union Expression_Value value = { .increment_decrement = inc_dec };
-    return expression_new(EXPRESSION_INCREMENT_DECREMENT, value, span, token.location);
+    union Tree_Expression_Value value = { .increment_decrement = inc_dec };
+    return tree_expression_new(TREE_EXPRESSION_INCREMENT_DECREMENT, value, span, token.location);
 }
 
-struct Expression*
+struct Tree_Expression*
 parser_expression_postfix_try(
-    struct Parser* p, struct Expression* subject, struct Parser_Error* error)
+    struct Parser* p, struct Tree_Expression* subject, struct Parser_Error* error)
 {
     struct Token question_token = parser_next(p);
 
     struct Span span = span_merge(subject->span, question_token.span);
-    union Expression_Value value = { .try = { subject } };
-    return expression_new(EXPRESSION_TRY, value, span, subject->location);
+    union Tree_Expression_Value value = { .try = { subject } };
+    return tree_expression_new(TREE_EXPRESSION_TRY, value, span, subject->location);
 }
 
-struct Expression*
+struct Tree_Expression*
 parser_expression_postfix_must(
-    struct Parser* p, struct Expression* subject, struct Parser_Error* error)
+    struct Parser* p, struct Tree_Expression* subject, struct Parser_Error* error)
 {
     struct Token bang_token = CHECK(parser_need(p, TOKEN_BANG, error));
 
     struct Span span = span_merge(subject->span, bang_token.span);
-    union Expression_Value value = { .try = { subject } };
-    return expression_new(EXPRESSION_MUST, value, span, subject->location);
+    union Tree_Expression_Value value = { .try = { subject } };
+    return tree_expression_new(TREE_EXPRESSION_MUST, value, span, subject->location);
 }
 
-struct Expression*
+struct Tree_Expression*
 parser_expression_postfix(struct Parser* p, struct Parser_Error* error)
 {
-    struct Expression* expression = CHECK(parser_expression_primary(p, error));
+    struct Tree_Expression* expression = CHECK(parser_expression_primary(p, error));
 
     // NOTE: we have to parse all subsequent postfix expressions non-recursively.
     for (;;) {
@@ -1190,16 +1190,16 @@ parser_expression_postfix(struct Parser* p, struct Parser_Error* error)
             increment_decrement_operation_from_token(&token);
         if (inc_dec_op) {
             parser_next(p);
-            struct Expression_Increment_Decrement inc_dec = {
+            struct Tree_Expression_Increment_Decrement inc_dec = {
                 .prefix = false,
                 .subject = expression,
                 .operation = inc_dec_op,
             };
 
             struct Span span = span_merge(expression->span, token.span);
-            union Expression_Value value = { .increment_decrement = inc_dec };
+            union Tree_Expression_Value value = { .increment_decrement = inc_dec };
             expression =
-                expression_new(EXPRESSION_INCREMENT_DECREMENT, value, span, token.location);
+                tree_expression_new(TREE_EXPRESSION_INCREMENT_DECREMENT, value, span, token.location);
             continue;
         }
 
@@ -1207,34 +1207,34 @@ parser_expression_postfix(struct Parser* p, struct Parser_Error* error)
     }
 }
 
-struct Expression*
+struct Tree_Expression*
 parser_expression_unary_operation(struct Parser* p, struct Parser_Error* error)
 {
     struct Token token = parser_peek(p);
     enum Unary_Operation operation = unary_operation_from_token(&token);
     if (operation) {
         parser_next(p);
-        struct Expression* operand = CHECK(parser_expression_unary_operation(p, error));
+        struct Tree_Expression* operand = CHECK(parser_expression_unary_operation(p, error));
 
         struct Span span = span_merge(token.span, operand->span);
-        union Expression_Value value = { .unary_operator = { operation, operand } };
-        return expression_new(EXPRESSION_UNARY_OPERATION, value, span, token.location);
+        union Tree_Expression_Value value = { .unary_operator = { operation, operand } };
+        return tree_expression_new(TREE_EXPRESSION_UNARY_OPERATION, value, span, token.location);
     }
 
     enum Increment_Decrement_Operation inc_dec_op =
         increment_decrement_operation_from_token(&token);
     if (inc_dec_op) {
         parser_next(p);
-        struct Expression* subject = CHECK(parser_expression_unary_operation(p, error));
-        struct Expression_Increment_Decrement inc_dec = {
+        struct Tree_Expression* subject = CHECK(parser_expression_unary_operation(p, error));
+        struct Tree_Expression_Increment_Decrement inc_dec = {
             .prefix = true,
             .subject = subject,
             .operation = inc_dec_op,
         };
 
         struct Span span = span_merge(token.span, inc_dec.subject->span);
-        union Expression_Value value = { .increment_decrement = inc_dec };
-        return expression_new(EXPRESSION_INCREMENT_DECREMENT, value, span, token.location);
+        union Tree_Expression_Value value = { .increment_decrement = inc_dec };
+        return tree_expression_new(TREE_EXPRESSION_INCREMENT_DECREMENT, value, span, token.location);
     }
 
     return parser_expression_postfix(p, error);
@@ -1243,16 +1243,16 @@ parser_expression_unary_operation(struct Parser* p, struct Parser_Error* error)
 // given two expressions and some kind of binary operation between them,
 // merge them into a single binary expression, with attention to operator precedence
 // and associativity.
-struct Expression_Binary_Operator
+struct Tree_Expression_Binary_Operator
 parser_merge_into_single_binary_expression(
-    struct Parser* p, struct Expression* left, enum Binary_Operation operation,
-    struct Expression* right)
+    struct Parser* p, struct Tree_Expression* left, enum Binary_Operation operation,
+    struct Tree_Expression* right)
 {
     // NOTE: due to the parser structure, the left expression is never a binary operation
     // so we can worry about fixing up the right side only.
-    check(left->kind != EXPRESSION_BINARY_OPERATION, "left expression is a binary operation");
-    if (right->kind == EXPRESSION_BINARY_OPERATION) {
-        struct Expression_Binary_Operator right_binary = right->value.binary_operator;
+    check(left->kind != TREE_EXPRESSION_BINARY_OPERATION, "left expression is a binary operation");
+    if (right->kind == TREE_EXPRESSION_BINARY_OPERATION) {
+        struct Tree_Expression_Binary_Operator right_binary = right->value.binary_operator;
 
         uint right_precedence = binary_operation_precedence(right_binary.operation);
         uint precedence = binary_operation_precedence(operation);
@@ -1268,15 +1268,15 @@ parser_merge_into_single_binary_expression(
             // since we only use static memory, we need to switch the operands around
             // without allocating more expressions, thus we have to reuse the allocation
             // slots of the previous expressions.
-            struct Expression* operands[3] = {
+            struct Tree_Expression* operands[3] = {
                 left, right_binary.left_operand, right_binary.right_operand
             };
-            struct Expression* slots[2] = { right, right_binary.right_operand };
+            struct Tree_Expression* slots[2] = { right, right_binary.right_operand };
 
-            struct Expression_Binary_Operator new_binary_operator =
+            struct Tree_Expression_Binary_Operator new_binary_operator =
                 parser_merge_into_single_binary_expression(p, operands[0], operation, operands[1]);
-            *slots[0] = (struct Expression){
-                .kind = EXPRESSION_BINARY_OPERATION,
+            *slots[0] = (struct Tree_Expression){
+                .kind = TREE_EXPRESSION_BINARY_OPERATION,
                 .value = { .binary_operator = new_binary_operator },
                 .span = span_merge(left->span, right->span),
                 .location = left->location
@@ -1290,103 +1290,103 @@ parser_merge_into_single_binary_expression(
         }
     }
 
-    return (struct Expression_Binary_Operator){
+    return (struct Tree_Expression_Binary_Operator){
         .operation = operation,
         .left_operand = left,
         .right_operand = right,
     };
 }
 
-struct Expression*
+struct Tree_Expression*
 parser_expression_binary_operation(struct Parser* p, struct Parser_Error* error)
 {
-    struct Expression* left = CHECK(parser_expression_unary_operation(p, error));
+    struct Tree_Expression* left = CHECK(parser_expression_unary_operation(p, error));
 
     struct Token token = parser_peek(p);
     enum Binary_Operation operation = binary_operation_from_token(&token);
     if (operation) {
         parser_next(p);
-        struct Expression* right = CHECK(parser_expression_binary_operation(p, error));
+        struct Tree_Expression* right = CHECK(parser_expression_binary_operation(p, error));
 
         struct Span span = span_merge(left->span, right->span);
-        struct Expression_Binary_Operator binary_value =
+        struct Tree_Expression_Binary_Operator binary_value =
             parser_merge_into_single_binary_expression(p, left, operation, right);
-        union Expression_Value value = { .binary_operator = binary_value };
-        return expression_new(EXPRESSION_BINARY_OPERATION, value, span, left->location);
+        union Tree_Expression_Value value = { .binary_operator = binary_value };
+        return tree_expression_new(TREE_EXPRESSION_BINARY_OPERATION, value, span, left->location);
     }
 
     return left;
 }
 
-struct Expression*
+struct Tree_Expression*
 parser_expression(struct Parser* p, struct Parser_Error* error)
 {
     return parser_expression_binary_operation(p, error);
 }
 
-struct Statement*
+struct Tree_Statement*
 parser_statement_declaration(struct Parser* p, struct Parser_Error* error)
 {
     struct Token declaration_token = parser_next(p);
 
-    enum Statement_Declaration_Kind declaration_kind =
-        statement_declaration_kind_from_token(&declaration_token);
+    enum Tree_Statement_Declaration_Kind declaration_kind =
+        tree_statement_declaration_kind_from_token(&declaration_token);
     check(declaration_kind, "expected valid declaration token");
 
-    struct Bare_Declaration_Node inner = CHECK(parser_bare_declaration_node(p, error));
+    struct Tree_Bare_Declaration inner = CHECK(parser_bare_declaration_node(p, error));
 
     struct Span span = span_merge(declaration_token.span, inner.span);
-    union Statement_Value value = {
+    union Tree_Statement_Value value = {
         .declaration = {
             .kind = declaration_kind,
             .inner = inner,
         },
     };
-    return statement_new(STATEMENT_DECLARATION, value, span, declaration_token.location);
+    return tree_statement_new(TREE_STATEMENT_DECLARATION, value, span, declaration_token.location);
 }
 
-struct Statement*
+struct Tree_Statement*
 parser_statement_conditional(struct Parser* p, struct Parser_Error* error)
 {
-    struct Statement_Value_Conditional conditional = { 0 };
+    struct Tree_Statement_Value_Conditional conditional = { 0 };
     struct Token if_token = parser_need(p, TOKEN_WORD_IF, error);
 
     // primary if condition + block.
     CONTEXT_START(in_statement_clause);
-    struct Expression* if_condition = CHECK(parser_expression(p, error));
+    struct Tree_Expression* if_condition = CHECK(parser_expression(p, error));
     CONTEXT_END(in_statement_clause);
 
-    struct Block_Node then_block = CHECK(parser_block_node(p, error));
-    conditional.conditions[conditional.condition_count++] = (struct Statement_Conditional_Branch){
+    struct Tree_Block then_block = CHECK(parser_block_node(p, error));
+    conditional.conditions[conditional.condition_count++] = (struct Tree_Statement_Conditional_Branch){
         .when = if_condition,
         .then = then_block,
     };
 
     struct Span span = span_merge(if_token.span, then_block.span);
     while (parser_probe(p, TOKEN_WORD_ELSE)) {
-        check(conditional.condition_count < STATEMENT_VALUE_CONDITIONAL_MAX,
+        check(conditional.condition_count < TREE_STATEMENT_VALUE_CONDITIONAL_MAX,
               "too many conditional branches");
         parser_next(p);
 
-        struct Statement_Conditional_Branch branch = { 0 };
+        struct Tree_Statement_Conditional_Branch branch = { 0 };
         if (parser_probe(p, TOKEN_WORD_IF)) {
             // else if condition + block.
             parser_next(p);
 
             CONTEXT_START(in_statement_clause);
-            struct Expression* else_condition = CHECK(parser_expression(p, error));
+            struct Tree_Expression* else_condition = CHECK(parser_expression(p, error));
             CONTEXT_END(in_statement_clause);
 
-            struct Block_Node else_block = CHECK(parser_block_node(p, error));
+            struct Tree_Block else_block = CHECK(parser_block_node(p, error));
 
-            branch = (struct Statement_Conditional_Branch){
+            branch = (struct Tree_Statement_Conditional_Branch){
                 .when = else_condition,
                 .then = else_block,
             };
         } else {
             // else block.
-            struct Block_Node else_block = CHECK(parser_block_node(p, error));
-            branch = (struct Statement_Conditional_Branch){
+            struct Tree_Block else_block = CHECK(parser_block_node(p, error));
+            branch = (struct Tree_Statement_Conditional_Branch){
                 .when = nil,
                 .then = else_block,
             };
@@ -1396,12 +1396,12 @@ parser_statement_conditional(struct Parser* p, struct Parser_Error* error)
         span = span_merge(span, branch.then.span);
     }
 
-    return statement_new(
-        STATEMENT_CONDITIONAL, (union Statement_Value){ .conditional = conditional }, span,
+    return tree_statement_new(
+        TREE_STATEMENT_CONDITIONAL, (union Tree_Statement_Value){ .conditional = conditional }, span,
         if_token.location);
 }
 
-struct Statement*
+struct Tree_Statement*
 parser_statement_for(struct Parser* p, struct Parser_Error* error)
 {
     struct Token for_token = CHECK(parser_need(p, TOKEN_WORD_FOR, error));
@@ -1412,13 +1412,13 @@ parser_statement_for(struct Parser* p, struct Parser_Error* error)
 
     // a declaration without a signifier like `var` or `let`.
     CONTEXT_START(in_statement_clause);
-    struct Bare_Declaration_Node declaration = CHECK(parser_bare_declaration_node(p, error));
+    struct Tree_Bare_Declaration declaration = CHECK(parser_bare_declaration_node(p, error));
     CONTEXT_END(in_statement_clause);
 
-    enum Statement_Loop_Style style = STATEMENT_LOOP_STYLE_FOR_EACH;
+    enum Tree_Statement_Loop_Style style = TREE_STATEMENT_LOOP_STYLE_FOR_EACH;
 
     // c-style semi-semi loop.
-    struct Expression *condition = nil, *iteration = nil;
+    struct Tree_Expression *condition = nil, *iteration = nil;
     if (parser_probe(p, TOKEN_COMMA)) {
         parser_next(p);
         condition = CHECK(parser_expression(p, error));
@@ -1428,13 +1428,13 @@ parser_statement_for(struct Parser* p, struct Parser_Error* error)
         iteration = CHECK(parser_expression(p, error));
         CONTEXT_END(in_statement_clause)
 
-        style = STATEMENT_LOOP_STYLE_C;
+        style = TREE_STATEMENT_LOOP_STYLE_C;
     }
 
-    struct Block_Node body = CHECK(parser_block_node(p, error));
+    struct Tree_Block body = CHECK(parser_block_node(p, error));
 
     struct Span span = span_merge(for_token.span, body.span);
-    union Statement_Value value = {
+    union Tree_Statement_Value value = {
         .loop = {
             .style = style,
             .declaration = declaration,
@@ -1443,113 +1443,113 @@ parser_statement_for(struct Parser* p, struct Parser_Error* error)
             .body = body,
         },
     };
-    return statement_new(STATEMENT_LOOP, value, span, for_token.location);
+    return tree_statement_new(TREE_STATEMENT_LOOP, value, span, for_token.location);
 }
 
-struct Statement*
+struct Tree_Statement*
 parser_statement_while(struct Parser* p, struct Parser_Error* error)
 {
     struct Token while_token = CHECK(parser_need(p, TOKEN_WORD_WHILE, error));
 
-    enum Statement_Loop_Style style = STATEMENT_LOOP_STYLE_ENDLESS;
-    struct Expression* condition = nil;
+    enum Tree_Statement_Loop_Style style = TREE_STATEMENT_LOOP_STYLE_ENDLESS;
+    struct Tree_Expression* condition = nil;
     if (!parser_probe(p, TOKEN_CURLY_OPEN)) {
         CONTEXT_START(in_statement_clause);
         condition = CHECK(parser_expression(p, error));
         CONTEXT_END(in_statement_clause);
 
-        style = STATEMENT_LOOP_STYLE_WHILE;
+        style = TREE_STATEMENT_LOOP_STYLE_WHILE;
     }
 
-    struct Block_Node body = CHECK(parser_block_node(p, error));
+    struct Tree_Block body = CHECK(parser_block_node(p, error));
 
     struct Span span = span_merge(while_token.span, body.span);
-    union Statement_Value value = {
+    union Tree_Statement_Value value = {
         .loop = { .style = style, .condition = condition, .body = body }
     };
-    return statement_new(STATEMENT_LOOP, value, span, while_token.location);
+    return tree_statement_new(TREE_STATEMENT_LOOP, value, span, while_token.location);
 }
 
-struct Statement*
+struct Tree_Statement*
 parser_statement_block(struct Parser* p, struct Parser_Error* error)
 {
-    struct Block_Node block = CHECK(parser_block_node(p, error));
-    return statement_new(
-        STATEMENT_BLOCK, (union Statement_Value){ .block = { block } }, block.span, block.location);
+    struct Tree_Block block = CHECK(parser_block_node(p, error));
+    return tree_statement_new(
+        TREE_STATEMENT_BLOCK, (union Tree_Statement_Value){ .block = { block } }, block.span, block.location);
 }
 
-struct Statement*
+struct Tree_Statement*
 parser_statement_return(struct Parser* p, struct Parser_Error* error)
 {
     struct Token return_token = CHECK(parser_need(p, TOKEN_WORD_RETURN, error));
 
-    struct Expression* value = nil;
+    struct Tree_Expression* value = nil;
     if (!token_ends_statement(&return_token)) { value = CHECK(parser_expression(p, error)); }
 
     struct Span span = value ? return_token.span : span_merge(return_token.span, value->span);
-    union Statement_Value statement_value = { .return_value = { value } };
-    return statement_new(STATEMENT_RETURN, statement_value, span, return_token.location);
+    union Tree_Statement_Value statement_value = { .return_value = { value } };
+    return tree_statement_new(TREE_STATEMENT_RETURN, statement_value, span, return_token.location);
 }
 
-struct Statement*
+struct Tree_Statement*
 parser_statement_break(struct Parser* p, struct Parser_Error* error)
 {
     struct Token break_token = CHECK(parser_need(p, TOKEN_WORD_BREAK, error));
     struct Span span = break_token.span;
-    return statement_new(STATEMENT_BREAK, (union Statement_Value){ 0 }, span, break_token.location);
+    return tree_statement_new(TREE_STATEMENT_BREAK, (union Tree_Statement_Value){ 0 }, span, break_token.location);
 }
 
-struct Statement*
+struct Tree_Statement*
 parser_statement_continue(struct Parser* p, struct Parser_Error* error)
 {
     struct Token continue_token = CHECK(parser_need(p, TOKEN_WORD_CONTINUE, error));
     struct Span span = continue_token.span;
-    return statement_new(
-        STATEMENT_CONTINUE, (union Statement_Value){ 0 }, span, continue_token.location);
+    return tree_statement_new(
+        TREE_STATEMENT_CONTINUE, (union Tree_Statement_Value){ 0 }, span, continue_token.location);
 }
 
-struct Statement*
+struct Tree_Statement*
 parser_statement_defer(struct Parser* p, struct Parser_Error* error)
 {
     struct Token defer_token = CHECK(parser_need(p, TOKEN_WORD_DEFER, error));
 
     struct Span span = defer_token.span;
-    struct Statement_Value_Defer defer = { 0 };
+    struct Tree_Statement_Value_Defer defer = { 0 };
     if (parser_probe(p, TOKEN_CURLY_OPEN)) {
-        struct Block_Node block = CHECK(parser_block_node(p, error));
+        struct Tree_Block block = CHECK(parser_block_node(p, error));
         span = span_merge(span, block.span);
         defer.block = block;
     } else {
-        struct Expression* expression = CHECK(parser_expression(p, error));
+        struct Tree_Expression* expression = CHECK(parser_expression(p, error));
         span = span_merge(span, expression->span);
         defer.expression = expression;
     }
 
-    union Statement_Value value = { .defer = defer };
-    return statement_new(STATEMENT_DEFER, value, span, defer_token.location);
+    union Tree_Statement_Value value = { .defer = defer };
+    return tree_statement_new(TREE_STATEMENT_DEFER, value, span, defer_token.location);
 }
 
-struct Statement*
+struct Tree_Statement*
 parser_statement_pragma(struct Parser* p, struct Parser_Error* error)
 {
     struct Token pipe_token = parser_peek(p);
 
-    struct Pragma_Node* pragma_node = parser_pragma_node(p, error);
+    struct Tree_Pragma* tree_pragma = parser_pragma_node(p, error);
     if (!parser_error_is_none(error)) {
         parser_error_wrap(error, PARSER_ERROR_EXPECTED_PRAGMA);
         return nil;
     }
 
     struct Span span = {};
-    FOR_EACH (struct Pragma_Node*, node, pragma_node) {
+    FOR_EACH (struct Tree_Pragma*, node, tree_pragma) {
         span = span_is_empty(span) ? node->span : span_merge(span, node->span);
     }
 
-    union Statement_Value value = { .pragma.inner = pragma_node };
-    return statement_new(STATEMENT_PRAGMA, value, span, pipe_token.location);
+    union Tree_Statement_Value value = { .pragma.inner = tree_pragma };
+    return tree_statement_new(TREE_STATEMENT_PRAGMA, value, span, pipe_token.location);
 }
 
-struct Statement*
+struct Tree_Statement*
 parser_statement(struct Parser* p, struct Parser_Error* error)
 {
     struct Token token = parser_peek(p);
@@ -1586,12 +1586,12 @@ parser_statement(struct Parser* p, struct Parser_Error* error)
         break;
     }
 
-    struct Expression* expression = CHECK(parser_expression(p, error));
+    struct Tree_Expression* expression = CHECK(parser_expression(p, error));
 
     // expand by one byte to include the statement terminator.
     struct Span span = span_expand(expression->span, 1);
-    union Statement_Value value = { .expression.inner = expression };
-    return statement_new(STATEMENT_EXPRESSION, value, span, expression->location);
+    union Tree_Statement_Value value = { .expression.inner = expression };
+    return tree_statement_new(TREE_STATEMENT_EXPRESSION, value, span, expression->location);
 }
 
 void
@@ -1613,10 +1613,10 @@ parser_do_your_thing(struct Parser* p, struct Tree* tree)
     struct Parser_Error error;
     parser_error_none(&error);
 
-    struct Statement* head = nil;
-    struct Statement* current = nil;
+    struct Tree_Statement* head = nil;
+    struct Tree_Statement* current = nil;
     while (!parser_reached_end(p)) {
-        struct Statement* next = parser_statement(p, &error);
+        struct Tree_Statement* next = parser_statement(p, &error);
         parser_handle_error(p, &error);
 
         if (next) {
diff --git a/boot/transpile.c b/boot/transpile.c
index 05aa5c4..798be85 100644
--- a/boot/transpile.c
+++ b/boot/transpile.c
@@ -130,17 +130,17 @@ transpiler_new(struct Transpiler* transpiler, struct Transpile_Output output)
 }
 
 void
-transpiler_visit_type_node(struct Visit* visit, struct Type_Node* node)
+transpiler_visit_type_node(struct Tree_Visit* visit, struct Tree_Type* node)
 {
     TRANSPILER_PREAMBLE
 
-    if (!node || node->type == TYPE_NODE_NONE) {
+    if (!node || node->type == TREE_TYPE_NONE) {
         TRANSPILE_WRITE("void");
         return;
     }
 
     switch (node->type) {
-    case TYPE_NODE_NAME: {
+    case TREE_TYPE_NAME: {
         struct String name = node->value.name.name;
         if (strcmp(name.data, "int") == 0) {
             TRANSPILE_WRITE("integer");
@@ -168,12 +168,12 @@ transpiler_visit_type_node(struct Visit* visit, struct Type_Node* node)
 }
 
 void
-transpiler_visit_function_header_node(struct Visit* visit, struct Function_Header_Node* header)
+transpiler_visit_function_header_node(struct Tree_Visit* visit, struct Tree_Function_Header* header)
 {
     TRANSPILER_PREAMBLE
 
     TRANSPILE_WRITE("(");
-    struct Type_Node* param = header->parameters_type_and_name;
+    struct Tree_Type* param = header->parameters_type_and_name;
     if (!param) {
         TRANSPILE_WRITE("void");
     } else {
@@ -190,21 +190,21 @@ transpiler_visit_function_header_node(struct Visit* visit, struct Function_Heade
 }
 
 void
-transpiler_visit_block_node(struct Visit* visit, struct Block_Node* node)
+transpiler_visit_block_node(struct Tree_Visit* visit, struct Tree_Block* node)
 {
     TRANSPILER_PREAMBLE
 
     TRANSPILE_WRITE("{\n");
-    FOR_EACH (struct Statement*, statement, node->statements) { VISIT(visit_statement, statement); }
+    FOR_EACH (struct Tree_Statement*, statement, node->statements) { VISIT(visit_statement, statement); }
     TRANSPILE_WRITE("}\n");
 }
 
 void
-transpiler_visit_argument_group_node(struct Visit* visit, struct Argument_Group_Node* node)
+transpiler_visit_argument_group_node(struct Tree_Visit* visit, struct Tree_Argument_Group* node)
 {
     TRANSPILER_PREAMBLE
 
-    struct Expression* arg = node->arguments;
+    struct Tree_Expression* arg = node->arguments;
     bool first = true;
     while (arg) {
         if (!first) { TRANSPILE_WRITE(", "); }
@@ -215,16 +215,16 @@ transpiler_visit_argument_group_node(struct Visit* visit, struct Argument_Group_
 }
 
 void
-transpiler_visit_statement_declaration(struct Visit* visit, struct Statement* stmt)
+transpiler_visit_statement_declaration(struct Tree_Visit* visit, struct Tree_Statement* stmt)
 {
     TRANSPILER_PREAMBLE
 
-    struct Statement_Value_Declaration* declaration = &stmt->value.declaration;
-    struct Expression* initializer = declaration->inner.initializer;
+    struct Tree_Statement_Value_Declaration* declaration = &stmt->value.declaration;
+    struct Tree_Expression* initializer = declaration->inner.initializer;
 
-    if (initializer && initializer->kind == EXPRESSION_FUNCTION) {
-        struct Expression_Function* fun = &initializer->value.function;
-        struct Function_Header_Node* header = &fun->header;
+    if (initializer && initializer->kind == TREE_EXPRESSION_FUNCTION) {
+        struct Tree_Expression_Function* fun = &initializer->value.function;
+        struct Tree_Function_Header* header = &fun->header;
 
         VISIT(visit_type_node, header->return_type);
         struct String name = *array_at(struct String, &declaration->inner.names, 0);
@@ -233,7 +233,7 @@ transpiler_visit_statement_declaration(struct Visit* visit, struct Statement* st
         TRANSPILE_WRITE(" ");
         VISIT(visit_block_node, &fun->body);
     } else {
-        if (declaration->kind == STATEMENT_DECLARATION_CONSTANT) {
+        if (declaration->kind == TREE_STATEMENT_DECLARATION_CONSTANT) {
             TRANSPILE_WRITE("const ");
         }
         VISIT(visit_type_node, declaration->inner.type);
@@ -247,7 +247,7 @@ transpiler_visit_statement_declaration(struct Visit* visit, struct Statement* st
 }
 
 void
-transpiler_visit_statement_return(struct Visit* visit, struct Statement* stmt)
+transpiler_visit_statement_return(struct Tree_Visit* visit, struct Tree_Statement* stmt)
 {
     TRANSPILER_PREAMBLE
 
@@ -259,13 +259,13 @@ transpiler_visit_statement_return(struct Visit* visit, struct Statement* stmt)
 }
 
 void
-transpiler_visit_statement_conditional(struct Visit* visit, struct Statement* stmt)
+transpiler_visit_statement_conditional(struct Tree_Visit* visit, struct Tree_Statement* stmt)
 {
     TRANSPILER_PREAMBLE
 
-    struct Statement_Value_Conditional* conditional = &stmt->value.conditional;
+    struct Tree_Statement_Value_Conditional* conditional = &stmt->value.conditional;
     for (uint i = 0; i < conditional->condition_count; ++i) {
-        struct Statement_Conditional_Branch* branch = &conditional->conditions[i];
+        struct Tree_Statement_Conditional_Branch* branch = &conditional->conditions[i];
         if (i > 0) { TRANSPILE_WRITE("else "); }
         if (branch->when) {
             TRANSPILE_WRITE("if (");
@@ -277,34 +277,34 @@ transpiler_visit_statement_conditional(struct Visit* visit, struct Statement* st
 }
 
 void
-transpiler_visit_statement(struct Visit* visit, struct Statement* statement)
+transpiler_visit_statement(struct Tree_Visit* visit, struct Tree_Statement* statement)
 {
     TRANSPILER_PREAMBLE
 
     switch (statement->kind) {
-    case STATEMENT_EXPRESSION:
+    case TREE_STATEMENT_EXPRESSION:
         VISIT(visit_expression, statement->value.expression.inner);
         if (transpiler->context.in_function) TRANSPILE_WRITE(";\n");
         break;
-    case STATEMENT_DECLARATION:
+    case TREE_STATEMENT_DECLARATION:
         VISIT(visit_statement_declaration, statement);
         if (transpiler->context.in_function) TRANSPILE_WRITE(";\n");
         break;
-    case STATEMENT_RETURN:
+    case TREE_STATEMENT_RETURN:
         VISIT(visit_statement_return, statement);
         if (transpiler->context.in_function) TRANSPILE_WRITE(";\n");
         break;
-    case STATEMENT_BLOCK:
+    case TREE_STATEMENT_BLOCK:
         VISIT(visit_block_node, &statement->value.block.inner);
         break;
     default:
-        walk_statement(visit, statement);
+        tree_walk_statement(visit, statement);
         break;
     }
 }
 
 void
-transpiler_visit_expression_integer_literal(struct Visit* visit, struct Expression* expr)
+transpiler_visit_expression_integer_literal(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TRANSPILER_PREAMBLE
 
@@ -312,7 +312,7 @@ transpiler_visit_expression_integer_literal(struct Visit* visit, struct Expressi
 }
 
 void
-transpiler_visit_expression_float_literal(struct Visit* visit, struct Expression* expr)
+transpiler_visit_expression_float_literal(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TRANSPILER_PREAMBLE
 
@@ -320,7 +320,7 @@ transpiler_visit_expression_float_literal(struct Visit* visit, struct Expression
 }
 
 void
-transpiler_visit_expression_string_literal(struct Visit* visit, struct Expression* expr)
+transpiler_visit_expression_string_literal(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TRANSPILER_PREAMBLE
 
@@ -329,7 +329,7 @@ transpiler_visit_expression_string_literal(struct Visit* visit, struct Expressio
 }
 
 void
-transpiler_visit_expression_boolean_literal(struct Visit* visit, struct Expression* expr)
+transpiler_visit_expression_boolean_literal(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TRANSPILER_PREAMBLE
 
@@ -337,7 +337,7 @@ transpiler_visit_expression_boolean_literal(struct Visit* visit, struct Expressi
 }
 
 void
-transpiler_visit_expression_name(struct Visit* visit, struct Expression* expr)
+transpiler_visit_expression_name(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TRANSPILER_PREAMBLE
 
@@ -345,7 +345,7 @@ transpiler_visit_expression_name(struct Visit* visit, struct Expression* expr)
 }
 
 void
-transpiler_visit_expression_unary_operation(struct Visit* visit, struct Expression* expr)
+transpiler_visit_expression_unary_operation(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TRANSPILER_PREAMBLE
 
@@ -355,23 +355,23 @@ transpiler_visit_expression_unary_operation(struct Visit* visit, struct Expressi
 }
 
 void
-transpiler_visit_expression_binary_operation(struct Visit* visit, struct Expression* expr)
+transpiler_visit_expression_binary_operation(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TRANSPILER_PREAMBLE
-    struct Expression_Binary_Operator* bin_op = &expr->value.binary_operator;
+    struct Tree_Expression_Binary_Operator* bin_op = &expr->value.binary_operator;
 
-    if (bin_op->operation == BINARY_ASSIGN && bin_op->right_operand->kind == EXPRESSION_FUNCTION) {
-        struct Expression* fun_expr = bin_op->right_operand;
-        struct Expression_Function* fun = &fun_expr->value.function;
-        struct Function_Header_Node* header = &fun->header;
-        struct Expression* name_expr = bin_op->left_operand;
+    if (bin_op->operation == BINARY_ASSIGN && bin_op->right_operand->kind == TREE_EXPRESSION_FUNCTION) {
+        struct Tree_Expression* fun_expr = bin_op->right_operand;
+        struct Tree_Expression_Function* fun = &fun_expr->value.function;
+        struct Tree_Function_Header* header = &fun->header;
+        struct Tree_Expression* name_expr = bin_op->left_operand;
 
         VISIT(visit_type_node, header->return_type);
         TRANSPILE_WRITE(" ");
 
         // check if this is a main function assignment
-        if (name_expr && name_expr->kind == EXPRESSION_NAME) {
-            struct Expression_Name* name = &name_expr->value.name;
+        if (name_expr && name_expr->kind == TREE_EXPRESSION_NAME) {
+            struct Tree_Expression_Name* name = &name_expr->value.name;
             if (string_equals_c_str(name->name, "main")) {
                 transpiler->context.main_function_found = true;
                 transpiler->context.main_function_takes_args =
@@ -413,7 +413,7 @@ transpiler_visit_expression_binary_operation(struct Visit* visit, struct Express
 }
 
 void
-transpiler_visit_expression_call(struct Visit* visit, struct Expression* expr)
+transpiler_visit_expression_call(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TRANSPILER_PREAMBLE
 
@@ -424,43 +424,43 @@ transpiler_visit_expression_call(struct Visit* visit, struct Expression* expr)
 }
 
 void
-transpiler_visit_expression(struct Visit* visit, struct Expression* expression)
+transpiler_visit_expression(struct Tree_Visit* visit, struct Tree_Expression* expression)
 {
     TRANSPILER_PREAMBLE
 
     switch (expression->kind) {
-    case EXPRESSION_INTEGER_LITERAL:
+    case TREE_EXPRESSION_INTEGER_LITERAL:
         VISIT(visit_expression_integer_literal, expression);
         break;
-    case EXPRESSION_FLOAT_LITERAL:
+    case TREE_EXPRESSION_FLOAT_LITERAL:
         VISIT(visit_expression_float_literal, expression);
         break;
-    case EXPRESSION_STRING_LITERAL:
+    case TREE_EXPRESSION_STRING_LITERAL:
         VISIT(visit_expression_string_literal, expression);
         break;
-    case EXPRESSION_BOOLEAN_LITERAL:
+    case TREE_EXPRESSION_BOOLEAN_LITERAL:
         VISIT(visit_expression_boolean_literal, expression);
         break;
-    case EXPRESSION_NAME:
+    case TREE_EXPRESSION_NAME:
         VISIT(visit_expression_name, expression);
         break;
-    case EXPRESSION_UNARY_OPERATION:
+    case TREE_EXPRESSION_UNARY_OPERATION:
         VISIT(visit_expression_unary_operation, expression);
         break;
-    case EXPRESSION_BINARY_OPERATION:
+    case TREE_EXPRESSION_BINARY_OPERATION:
         VISIT(visit_expression_binary_operation, expression);
         break;
-    case EXPRESSION_CALL:
+    case TREE_EXPRESSION_CALL:
         VISIT(visit_expression_call, expression);
         break;
     default:
-        walk_expression(visit, expression);
+        tree_walk_expression(visit, expression);
         break;
     }
 }
 
 void
-transpiler_visit_tree(struct Visit* visit, struct Tree* tree)
+transpiler_visit_tree(struct Tree_Visit* visit, struct Tree* tree)
 {
     TRANSPILER_PREAMBLE
 
@@ -475,7 +475,7 @@ transpiler_visit_tree(struct Visit* visit, struct Tree* tree)
     // this executable and then write them out into the temporary build directory.
     TRANSPILE_WRITE("#include \"core.c\"\n");
 
-    FOR_EACH (struct Statement*, statement, tree->top_level_statements) {
+    FOR_EACH (struct Tree_Statement*, statement, tree->top_level_statements) {
         VISIT(visit_statement, statement);
     }
 
@@ -490,7 +490,7 @@ transpiler_visit_tree(struct Visit* visit, struct Tree* tree)
     }
 }
 
-struct Visit_Table transpiler_visit_functions = {
+struct Tree_Visit_Table transpiler_visit_functions = {
     .visit_tree = transpiler_visit_tree,
     .visit_statement = transpiler_visit_statement,
     .visit_statement_declaration = transpiler_visit_statement_declaration,
@@ -514,10 +514,10 @@ struct Visit_Table transpiler_visit_functions = {
 int
 transpiler_catskill_to_c(struct Transpiler* transpiler, struct Tree* tree)
 {
-    struct Visit visit = { .table = &transpiler_visit_functions, .user_data = transpiler };
-    visit_table_fill_defaults(visit.table);
+    struct Tree_Visit visit = { .table = &transpiler_visit_functions, .user_data = transpiler };
+    tree_visit_table_fill_defaults(visit.table);
 
-    walk(&visit, tree);
+    tree_walk(&visit, tree);
 
     return 0;
 }
diff --git a/boot/tree.c b/boot/tree.c
index 751cf02..07b96a3 100644
--- a/boot/tree.c
+++ b/boot/tree.c
@@ -398,26 +398,26 @@ increment_decrement_operation_to_string(enum Increment_Decrement_Operation opera
     }
 }
 
-// nodes are parts of the syntax tree that are reused often
-// and in different places.
+// these nodes outside of the expression/statement hierarchy are parts of
+// the syntax tree that are reused often and in different places.
 
 // a block of code, enclosed in curly braces.
 // represents a sequence of statements that are executed in order.
-struct Block_Node
+struct Tree_Block
 {
-    struct Statement* statements;
+    struct Tree_Statement* statements;
     struct Span span;
     struct Cursor location;
 };
 
 // a function header, describing the parameters and return type of function.
 // used both as a type and in full function definitions.
-struct Function_Header_Node
+struct Tree_Function_Header
 {
     // linked list of parameters.
     // name, if given, is included in the type node.
-    struct Type_Node* parameters_type_and_name;
-    struct Type_Node* return_type;
+    struct Tree_Type* parameters_type_and_name;
+    struct Tree_Type* return_type;
 
     struct Span span;
     struct Cursor location;
@@ -427,10 +427,10 @@ struct Function_Header_Node
 // constructions.
 // styled as either `1, 2, 3` or, when optional names
 // are given `a = 1, b = 2, c = 3`.
-struct Argument_Group_Node
+struct Tree_Argument_Group
 {
     // linked list of argument expressions.
-    struct Expression* arguments;
+    struct Tree_Expression* arguments;
     // names of the arguments, if given.
     // an unnamed argument is represented as an empty string.
     Array(struct String) argument_names;
@@ -440,101 +440,101 @@ struct Argument_Group_Node
 // signifier, like `let` or `var`.
 // the mutability is determined by some outside context, where
 // a bare declaration in a for-loop, for example, is always mutable.
-struct Bare_Declaration_Node
+struct Tree_Bare_Declaration
 {
     Array(struct String) names;
-    struct Expression* initializer;
-    struct Type_Node* type;
+    struct Tree_Expression* initializer;
+    struct Tree_Type* type;
 
     struct Span span;
     struct Cursor location;
 };
 
-enum Type_Node_Type
+enum Tree_Type_Type
 {
-    TYPE_NODE_NONE,
+    TREE_TYPE_NONE,
 
-    TYPE_NODE_NAME,
-    TYPE_NODE_ARRAY,     // an array of a type, `[int]`.
-    TYPE_NODE_REFERENCE, // a reference to a type, `&int`.
-    TYPE_NODE_MAYBE,     // a type that may be null, `int?`.
-    TYPE_NODE_TUPLE,     // a tuple type, `(int string)`.
-    TYPE_NODE_MAP,       // a map type, `[string = int]`.
+    TREE_TYPE_NAME,
+    TREE_TYPE_ARRAY,     // an array of a type, `[int]`.
+    TREE_TYPE_REFERENCE, // a reference to a type, `&int`.
+    TREE_TYPE_MAYBE,     // a type that may be null, `int?`.
+    TREE_TYPE_TUPLE,     // a tuple type, `(int string)`.
+    TREE_TYPE_MAP,       // a map type, `[string = int]`.
 
-    TYPE_NODE_FUNCTION,  // a function type, `fun (int) int`.
-    TYPE_NODE_STRUCTURE, // a struct, invoked either with `type` or with `{}` when a type is inline.
-    TYPE_NODE_VARIANT,   // a tagged union.
-    TYPE_NODE_CLASS,     // a class of types, a.k.a. an interface.
+    TREE_TYPE_FUNCTION,  // a function type, `fun (int) int`.
+    TREE_TYPE_STRUCTURE, // a struct, invoked either with `type` or with `{}` when a type is inline.
+    TREE_TYPE_VARIANT,   // a tagged union.
+    TREE_TYPE_CLASS,     // a class of types, a.k.a. an interface.
 };
 
-struct Type_Node_Name
+struct Tree_Type_Name
 {
     struct String name;
 };
 
-struct Type_Node_Array
+struct Tree_Type_Array
 {
-    struct Type_Node* element_type;
+    struct Tree_Type* element_type;
 };
 
-struct Type_Node_Reference
+struct Tree_Type_Reference
 {
-    struct Type_Node* referenced_type;
+    struct Tree_Type* referenced_type;
 };
 
-struct Type_Node_Maybe
+struct Tree_Type_Maybe
 {
-    struct Type_Node* inner_type;
+    struct Tree_Type* inner_type;
 };
 
-struct Type_Node_Tuple
+struct Tree_Type_Tuple
 {
-    struct Type_Node* head; // the first type in the tuple, if any.
+    struct Tree_Type* head; // the first type in the tuple, if any.
 };
 
-struct Type_Node_Map
+struct Tree_Type_Map
 {
-    struct Type_Node* key_type;
-    struct Type_Node* value_type;
+    struct Tree_Type* key_type;
+    struct Tree_Type* value_type;
 };
 
-struct Type_Node_Function
+struct Tree_Type_Function
 {
-    struct Function_Header_Node header;
+    struct Tree_Function_Header header;
 };
 
-struct Type_Node_Structure
+struct Tree_Type_Structure
 {
     // the fields of the structure, linked list of types and (required) names.
-    struct Type_Node* fields;
+    struct Tree_Type* fields;
 };
 
-struct Type_Node_Variant
+struct Tree_Type_Variant
 {
     // the variants of the tagged union, linked list of (required) variant names and backing types.
-    // if a variant has no backing type, it is TYPE_NODE_NONE.
-    struct Type_Node* variants;
+    // if a variant has no backing type, it is TREE_TYPE_NONE.
+    struct Tree_Type* variants;
 };
 
-struct Type_Node_Class
+struct Tree_Type_Class
 {
     // linked list of the types of methods required to implement the class.
-    // each node is required to have a name and be of TYPE_NODE_FUNCTION.
-    struct Type_Node* methods;
+    // each node is required to have a name and be of TREE_TYPE_FUNCTION.
+    struct Tree_Type* methods;
 };
 
-union Type_Node_Value
-{
-    struct Type_Node_Name name;
-    struct Type_Node_Array array;
-    struct Type_Node_Reference reference;
-    struct Type_Node_Maybe maybe;
-    struct Type_Node_Tuple tuple;
-    struct Type_Node_Map map;
-    struct Type_Node_Function function;
-    struct Type_Node_Structure structure;
-    struct Type_Node_Variant variant;
-    struct Type_Node_Class class;
+union Tree_Type_Value
+{
+    struct Tree_Type_Name name;
+    struct Tree_Type_Array array;
+    struct Tree_Type_Reference reference;
+    struct Tree_Type_Maybe maybe;
+    struct Tree_Type_Tuple tuple;
+    struct Tree_Type_Map map;
+    struct Tree_Type_Function function;
+    struct Tree_Type_Structure structure;
+    struct Tree_Type_Variant variant;
+    struct Tree_Type_Class class;
 };
 
 // a type node represents a type in the syntax tree.
@@ -542,10 +542,10 @@ union Type_Node_Value
 // or null types.
 // also includes the name of the field, member, parameter, etc., for which
 // the type is defined.
-struct Type_Node
+struct Tree_Type
 {
-    enum Type_Node_Type type;
-    union Type_Node_Value value;
+    enum Tree_Type_Type type;
+    union Tree_Type_Value value;
     // note: we could also just include the token here i think?
     struct Span span;
     struct Cursor location;
@@ -560,19 +560,19 @@ struct Type_Node
 
     // if type is within a group of multiple types,
     // points to the next type within the group.
-    struct Type_Node* next;
+    struct Tree_Type* next;
 };
 
-REGION(struct Type_Node, type_node)
+REGION(struct Tree_Type, tree_type)
 
 // allocates a new type node in the global type node region.
-struct Type_Node*
-type_node_new(
-    enum Type_Node_Type type, union Type_Node_Value value, struct Span span, struct Cursor location)
+struct Tree_Type*
+tree_type_new(
+    enum Tree_Type_Type type, union Tree_Type_Value value, struct Span span, struct Cursor location)
 {
-    check(region_type_node_cursor < REGION_SIZE, "out of type node memory");
-    struct Type_Node* type_node = &region_type_node[region_type_node_cursor++];
-    *type_node = (struct Type_Node){
+    check(region_tree_type_cursor < REGION_SIZE, "out of type node memory");
+    struct Tree_Type* tree_type = &region_tree_type[region_tree_type_cursor++];
+    *tree_type = (struct Tree_Type){
         .type = type,
         .value = value,
         .span = span,
@@ -581,29 +581,29 @@ type_node_new(
         .value_name = string_empty(),
         .next = nil,
     };
-    return type_node;
+    return tree_type;
 }
 
 // allocates a new type node with no value, used for `none` types.
 // this is used for types that are not specified, note that it is still
 // fully allocated and can be used in the syntax tree.
-struct Type_Node*
-type_node_none(struct Span span, struct Cursor location)
+struct Tree_Type*
+tree_type_none(struct Span span, struct Cursor location)
 {
-    return type_node_new(TYPE_NODE_NONE, (union Type_Node_Value){ 0 }, span, location);
+    return tree_type_new(TREE_TYPE_NONE, (union Tree_Type_Value){ 0 }, span, location);
 }
 
 bool
-type_node_is_none(const struct Type_Node* type_node)
+tree_type_is_none(const struct Tree_Type* tree_type)
 {
-    return type_node->type == TYPE_NODE_NONE;
+    return tree_type->type == TREE_TYPE_NONE;
 }
 
-enum Pragma_Type
+enum Tree_Pragma_Type
 {
-    PRAGMA_NONE,
-    PRAGMA_UNKNOWN,
-    PRAGMA_C_HEADER,
+    TREE_PRAGMA_NONE,
+    TREE_PRAGMA_UNKNOWN,
+    TREE_PRAGMA_C_HEADER,
     // TODO: further pragma types.
 
     // NOTE: there would be plenty of use for user-defined pragmas,
@@ -612,19 +612,19 @@ enum Pragma_Type
     // but it's something to definitely consider in the future.
 };
 
-#define PRAGMA_ARGUMENT_MAX 3
+#define TREE_PRAGMA_ARGUMENT_MAX 3
 
-struct Pragma_Argument
+struct Tree_Pragma_Argument
 {
-    enum Pragma_Argument_Type
+    enum Tree_Pragma_Argument_Type
     {
-        PRAGMA_ARGUMENT_NONE,
-        PRAGMA_ARGUMENT_NAME_OR_STRING,
-        PRAGMA_ARGUMENT_NUMBER,
-        PRAGMA_ARGUMENT_DECIMAL,
+        TREE_PRAGMA_ARGUMENT_NONE,
+        TREE_PRAGMA_ARGUMENT_NAME_OR_STRING,
+        TREE_PRAGMA_ARGUMENT_NUMBER,
+        TREE_PRAGMA_ARGUMENT_DECIMAL,
     } type;
 
-    union Pragma_Argument_Value
+    union Tree_Pragma_Argument_Value
     {
         struct String name_or_string;
         int64 number;
@@ -639,26 +639,26 @@ struct Pragma_Argument
 // behaviour, to including different C compilation units and other catskill modules.
 // pragmas are parsed as lone statements in the source code at first, but are then
 // "attached" to the relevant nodes of the type the pragma is relevant to.
-struct Pragma_Node
+struct Tree_Pragma
 {
-    enum Pragma_Type type;
-    struct Pragma_Argument arguments[PRAGMA_ARGUMENT_MAX];
+    enum Tree_Pragma_Type type;
+    struct Tree_Pragma_Argument arguments[TREE_PRAGMA_ARGUMENT_MAX];
     uint argument_count;
 
     struct Span span;
     struct Cursor location;
 
-    struct Pragma_Node* next; // further pragmas on the same line.
+    struct Tree_Pragma* next; // further pragmas on the same line.
 };
 
-REGION(struct Pragma_Node, pragma_node)
+REGION(struct Tree_Pragma, tree_pragma)
 
-struct Pragma_Node*
-pragma_node_new(enum Pragma_Type type, struct Span span, struct Cursor location)
+struct Tree_Pragma*
+tree_pragma_new(enum Tree_Pragma_Type type, struct Span span, struct Cursor location)
 {
-    check(region_pragma_node_cursor < REGION_SIZE, "out of pragma node memory");
-    struct Pragma_Node* pragma = &region_pragma_node[region_pragma_node_cursor++];
-    *pragma = (struct Pragma_Node){
+    check(region_tree_pragma_cursor < REGION_SIZE, "out of pragma node memory");
+    struct Tree_Pragma* pragma = &region_tree_pragma[region_tree_pragma_cursor++];
+    *pragma = (struct Tree_Pragma){
         .type = type,
         .arguments = {},
         .argument_count = 0,
@@ -669,202 +669,202 @@ pragma_node_new(enum Pragma_Type type, struct Span span, struct Cursor location)
     return pragma;
 }
 
-enum Pragma_Type
-pragma_type_from_string(struct String name)
+enum Tree_Pragma_Type
+tree_pragma_type_from_string(struct String name)
 {
     // look up hash values with:
     // `echo -ne "string to hash" | cksum`
     uint32 hash = crc32_posix(name);
     switch (hash) {
     case 2852954401: // "c_header"
-        return PRAGMA_C_HEADER;
+        return TREE_PRAGMA_C_HEADER;
     default:
-        return PRAGMA_UNKNOWN;
+        return TREE_PRAGMA_UNKNOWN;
     }
 }
 
 const ascii*
-pragma_type_to_string(enum Pragma_Type type)
+tree_pragma_type_to_string(enum Tree_Pragma_Type type)
 {
     switch (type) {
-    case PRAGMA_C_HEADER:
+    case TREE_PRAGMA_C_HEADER:
         return "c_header";
-    case PRAGMA_UNKNOWN:
+    case TREE_PRAGMA_UNKNOWN:
         return "unknown";
     default:
-        failure("unexpected pragma type passed to `pragma_type_to_string`");
+        failure("unexpected pragma type passed to `tree_pragma_type_to_string`");
         return nil;
     }
 }
 
-enum Expression_Kind
+enum Tree_Expression_Kind
 {
-    EXPRESSION_NONE,
+    TREE_EXPRESSION_NONE,
 
-    EXPRESSION_INTEGER_LITERAL,
-    EXPRESSION_FLOAT_LITERAL,
-    EXPRESSION_STRING_LITERAL,
-    EXPRESSION_BOOLEAN_LITERAL,
-    EXPRESSION_NAME,
+    TREE_EXPRESSION_INTEGER_LITERAL,
+    TREE_EXPRESSION_FLOAT_LITERAL,
+    TREE_EXPRESSION_STRING_LITERAL,
+    TREE_EXPRESSION_BOOLEAN_LITERAL,
+    TREE_EXPRESSION_NAME,
 
-    EXPRESSION_UNARY_OPERATION,
-    EXPRESSION_BINARY_OPERATION,
+    TREE_EXPRESSION_UNARY_OPERATION,
+    TREE_EXPRESSION_BINARY_OPERATION,
 
-    EXPRESSION_GROUP,
-    EXPRESSION_CONSTRUCT,
-    EXPRESSION_CALL,
-    EXPRESSION_SUBSCRIPT,
-    EXPRESSION_MEMBER,
-    EXPRESSION_INCREMENT_DECREMENT,
-    EXPRESSION_TRY,
-    EXPRESSION_MUST,
+    TREE_EXPRESSION_GROUP,
+    TREE_EXPRESSION_CONSTRUCT,
+    TREE_EXPRESSION_CALL,
+    TREE_EXPRESSION_SUBSCRIPT,
+    TREE_EXPRESSION_MEMBER,
+    TREE_EXPRESSION_INCREMENT_DECREMENT,
+    TREE_EXPRESSION_TRY,
+    TREE_EXPRESSION_MUST,
 
-    EXPRESSION_FUNCTION,
-    EXPRESSION_TYPE,
+    TREE_EXPRESSION_FUNCTION,
+    TREE_EXPRESSION_TYPE,
 };
 
-struct Expression_Integer_Literal
+struct Tree_Expression_Integer_Literal
 {
     int64 value; // might not fit entire number given in source.
 };
 
-struct Expression_Float_Literal
+struct Tree_Expression_Float_Literal
 {
     float64 value;
 };
 
-struct Expression_String_Literal
+struct Tree_Expression_String_Literal
 {
     struct String value;
 };
 
-struct Expression_Bool_Literal
+struct Tree_Expression_Bool_Literal
 {
     bool value;
 };
 
-struct Expression_Name
+struct Tree_Expression_Name
 {
     struct String name;
 };
 
-struct Expression_Unary_Operator
+struct Tree_Expression_Unary_Operator
 {
     enum Unary_Operation operation;
-    struct Expression* operand;
+    struct Tree_Expression* operand;
 };
 
-struct Expression_Binary_Operator
+struct Tree_Expression_Binary_Operator
 {
     enum Binary_Operation operation;
-    struct Expression* left_operand;
-    struct Expression* right_operand;
+    struct Tree_Expression* left_operand;
+    struct Tree_Expression* right_operand;
 };
 
-struct Expression_Group
+struct Tree_Expression_Group
 {
-    struct Expression* inner_expression;
+    struct Tree_Expression* inner_expression;
 };
 
-struct Expression_Call
+struct Tree_Expression_Call
 {
-    struct Expression* subject;
-    struct Argument_Group_Node argument_group;
+    struct Tree_Expression* subject;
+    struct Tree_Argument_Group argument_group;
 };
 
-struct Expression_Construct
+struct Tree_Expression_Construct
 {
     // this should be the type to construct, e.g. `int` or `string` or a generic like `Maybe(X)`
     // right now, we can't guarantee it fully.
-    struct Expression* subject;
-    struct Argument_Group_Node argument_group;
+    struct Tree_Expression* subject;
+    struct Tree_Argument_Group argument_group;
 };
 
-struct Expression_Subscript
+struct Tree_Expression_Subscript
 {
-    struct Expression* subject;
-    struct Expression* index;
+    struct Tree_Expression* subject;
+    struct Tree_Expression* index;
 };
 
-struct Expression_Member
+struct Tree_Expression_Member
 {
-    struct Expression* subject;
+    struct Tree_Expression* subject;
     struct String name;
 };
 
-struct Expression_Increment_Decrement
+struct Tree_Expression_Increment_Decrement
 {
     // whether the increment/decrement is a prefix or postfix operation.
     bool prefix;
-    struct Expression* subject;
+    struct Tree_Expression* subject;
     enum Increment_Decrement_Operation operation;
 };
 
-struct Expression_Try
+struct Tree_Expression_Try
 {
-    struct Expression* expression;
+    struct Tree_Expression* expression;
 };
 
-struct Expression_Must
+struct Tree_Expression_Must
 {
-    struct Expression* expression;
+    struct Tree_Expression* expression;
 };
 
-struct Expression_Function
+struct Tree_Expression_Function
 {
-    struct Function_Header_Node header;
-    struct Block_Node body;
+    struct Tree_Function_Header header;
+    struct Tree_Block body;
 };
 
-struct Expression_Type
+struct Tree_Expression_Type
 {
-    struct Type_Node* type;
+    struct Tree_Type* type;
 };
 
-union Expression_Value
-{
-    struct Expression_Integer_Literal integer_literal;
-    struct Expression_Float_Literal float_literal;
-    struct Expression_String_Literal string_literal;
-    struct Expression_Bool_Literal bool_literal;
-    struct Expression_Name name;
-    struct Expression_Unary_Operator unary_operator;
-    struct Expression_Binary_Operator binary_operator;
-    struct Expression_Group group;
-    struct Expression_Call call;
-    struct Expression_Construct construct;
-    struct Expression_Subscript subscript;
-    struct Expression_Member member;
-    struct Expression_Increment_Decrement increment_decrement;
-    struct Expression_Try try;
-    struct Expression_Must must;
-    struct Expression_Function function;
-    struct Expression_Type type;
+union Tree_Expression_Value
+{
+    struct Tree_Expression_Integer_Literal integer_literal;
+    struct Tree_Expression_Float_Literal float_literal;
+    struct Tree_Expression_String_Literal string_literal;
+    struct Tree_Expression_Bool_Literal bool_literal;
+    struct Tree_Expression_Name name;
+    struct Tree_Expression_Unary_Operator unary_operator;
+    struct Tree_Expression_Binary_Operator binary_operator;
+    struct Tree_Expression_Group group;
+    struct Tree_Expression_Call call;
+    struct Tree_Expression_Construct construct;
+    struct Tree_Expression_Subscript subscript;
+    struct Tree_Expression_Member member;
+    struct Tree_Expression_Increment_Decrement increment_decrement;
+    struct Tree_Expression_Try try;
+    struct Tree_Expression_Must must;
+    struct Tree_Expression_Function function;
+    struct Tree_Expression_Type type;
 };
 
-struct Expression
+struct Tree_Expression
 {
-    enum Expression_Kind kind;
-    union Expression_Value value;
+    enum Tree_Expression_Kind kind;
+    union Tree_Expression_Value value;
 
     struct Span span;
     struct Cursor location;
 
     // if expression is within a group of multiple expressions,
     // points to the next expression within it.
-    struct Expression* next;
+    struct Tree_Expression* next;
 };
 
-REGION(struct Expression, expression)
+REGION(struct Tree_Expression, tree_expression)
 
-struct Expression*
-expression_new(
-    enum Expression_Kind kind, union Expression_Value value, struct Span span,
+struct Tree_Expression*
+tree_expression_new(
+    enum Tree_Expression_Kind kind, union Tree_Expression_Value value, struct Span span,
     struct Cursor location)
 {
-    check(region_expression_cursor < REGION_SIZE, "out of expression memory");
-    struct Expression* expression = &region_expression[region_expression_cursor++];
-    *expression = (struct Expression){
+    check(region_tree_expression_cursor < REGION_SIZE, "out of expression memory");
+    struct Tree_Expression* expression = &region_tree_expression[region_tree_expression_cursor++];
+    *expression = (struct Tree_Expression){
         .kind = kind,
         .value = value,
         .span = span,
@@ -874,146 +874,146 @@ expression_new(
     return expression;
 }
 
-enum Statement_Kind
+enum Tree_Statement_Kind
 {
-    STATEMENT_NONE,
-    STATEMENT_EXPRESSION,
-    STATEMENT_DECLARATION,
+    TREE_STATEMENT_NONE,
+    TREE_STATEMENT_EXPRESSION,
+    TREE_STATEMENT_DECLARATION,
     // NOTE: a block could be an expression in the future.
-    STATEMENT_BLOCK,
-    STATEMENT_CONDITIONAL,
-    STATEMENT_LOOP,
-    STATEMENT_RETURN,
-    STATEMENT_BREAK,
-    STATEMENT_CONTINUE,
-    STATEMENT_DEFER,
-
-    STATEMENT_PRAGMA,
+    TREE_STATEMENT_BLOCK,
+    TREE_STATEMENT_CONDITIONAL,
+    TREE_STATEMENT_LOOP,
+    TREE_STATEMENT_RETURN,
+    TREE_STATEMENT_BREAK,
+    TREE_STATEMENT_CONTINUE,
+    TREE_STATEMENT_DEFER,
+
+    TREE_STATEMENT_PRAGMA,
 };
 
-struct Statement_Value_Expression
+struct Tree_Statement_Value_Expression
 {
-    struct Expression* inner;
+    struct Tree_Expression* inner;
 };
 
-enum Statement_Declaration_Kind
+enum Tree_Statement_Declaration_Kind
 {
-    STATEMENT_DECLARATION_NONE,
-    STATEMENT_DECLARATION_VARIABLE,
-    STATEMENT_DECLARATION_CONSTANT,
+    TREE_STATEMENT_DECLARATION_NONE,
+    TREE_STATEMENT_DECLARATION_VARIABLE,
+    TREE_STATEMENT_DECLARATION_CONSTANT,
 };
 
-enum Statement_Declaration_Kind
-statement_declaration_kind_from_token(const struct Token* token)
+enum Tree_Statement_Declaration_Kind
+tree_statement_declaration_kind_from_token(const struct Token* token)
 {
     switch (token->kind) {
     case TOKEN_WORD_VAR:
-        return STATEMENT_DECLARATION_VARIABLE;
+        return TREE_STATEMENT_DECLARATION_VARIABLE;
     case TOKEN_WORD_LET:
-        return STATEMENT_DECLARATION_CONSTANT;
+        return TREE_STATEMENT_DECLARATION_CONSTANT;
 
     default:
-        return STATEMENT_DECLARATION_NONE;
+        return TREE_STATEMENT_DECLARATION_NONE;
     }
 }
 
-struct Statement_Value_Declaration
+struct Tree_Statement_Value_Declaration
 {
-    enum Statement_Declaration_Kind kind;
-    struct Bare_Declaration_Node inner;
+    enum Tree_Statement_Declaration_Kind kind;
+    struct Tree_Bare_Declaration inner;
 };
 
-struct Statement_Value_Block
+struct Tree_Statement_Value_Block
 {
-    struct Block_Node inner; // the block of statements.
+    struct Tree_Block inner; // the block of statements.
 };
 
-#define STATEMENT_VALUE_CONDITIONAL_MAX 8
+#define TREE_STATEMENT_VALUE_CONDITIONAL_MAX 8
 
-struct Statement_Value_Conditional
+struct Tree_Statement_Value_Conditional
 {
-    struct Statement_Conditional_Branch
+    struct Tree_Statement_Conditional_Branch
     {
         // if nil, the condition is always true.
-        struct Expression* when;
-        struct Block_Node then;
-    } conditions[STATEMENT_VALUE_CONDITIONAL_MAX];
+        struct Tree_Expression* when;
+        struct Tree_Block then;
+    } conditions[TREE_STATEMENT_VALUE_CONDITIONAL_MAX];
     uint condition_count;
 };
 
-enum Statement_Loop_Style
+enum Tree_Statement_Loop_Style
 {
-    STATEMENT_LOOP_STYLE_NONE,
-    STATEMENT_LOOP_STYLE_C,        // for i int = 0; i < 10; ++i {}
-    STATEMENT_LOOP_STYLE_FOR_EACH, // for x Obj = list {}
-    STATEMENT_LOOP_STYLE_WHILE,    // while true {}
-    STATEMENT_LOOP_STYLE_ENDLESS,  // while {}
+    TREE_STATEMENT_LOOP_STYLE_NONE,
+    TREE_STATEMENT_LOOP_STYLE_C,        // for i int = 0; i < 10; ++i {}
+    TREE_STATEMENT_LOOP_STYLE_FOR_EACH, // for x Obj = list {}
+    TREE_STATEMENT_LOOP_STYLE_WHILE,    // while true {}
+    TREE_STATEMENT_LOOP_STYLE_ENDLESS,  // while {}
 };
 
 // stands for both `for` and `while` loops.
-struct Statement_Value_Loop
+struct Tree_Statement_Value_Loop
 {
-    enum Statement_Loop_Style style;
-    struct Bare_Declaration_Node declaration;
-    struct Expression* condition;
-    struct Expression* iteration;
+    enum Tree_Statement_Loop_Style style;
+    struct Tree_Bare_Declaration declaration;
+    struct Tree_Expression* condition;
+    struct Tree_Expression* iteration;
 
-    struct Block_Node body;
+    struct Tree_Block body;
 };
 
-struct Statement_Value_Return
+struct Tree_Statement_Value_Return
 {
     // nil if there is no return value.
-    struct Expression* value;
+    struct Tree_Expression* value;
 };
 
-struct Statement_Value_Defer
+struct Tree_Statement_Value_Defer
 {
     // either a simple expression, or, if expression is nil,
     // a block of code to execute.
-    struct Expression* expression;
-    struct Block_Node block;
+    struct Tree_Expression* expression;
+    struct Tree_Block block;
 };
 
-struct Statement_Value_Pragma
+struct Tree_Statement_Value_Pragma
 {
-    struct Pragma_Node* inner;
+    struct Tree_Pragma* inner;
 };
 
-union Statement_Value
+union Tree_Statement_Value
 {
-    struct Statement_Value_Expression expression;
-    struct Statement_Value_Declaration declaration;
-    struct Statement_Value_Block block;
-    struct Statement_Value_Conditional conditional;
-    struct Statement_Value_Loop loop;
-    struct Statement_Value_Return return_value;
-    struct Statement_Value_Defer defer;
-    struct Statement_Value_Pragma pragma;
+    struct Tree_Statement_Value_Expression expression;
+    struct Tree_Statement_Value_Declaration declaration;
+    struct Tree_Statement_Value_Block block;
+    struct Tree_Statement_Value_Conditional conditional;
+    struct Tree_Statement_Value_Loop loop;
+    struct Tree_Statement_Value_Return return_value;
+    struct Tree_Statement_Value_Defer defer;
+    struct Tree_Statement_Value_Pragma pragma;
 };
 
-struct Statement
+struct Tree_Statement
 {
-    enum Statement_Kind kind;
-    union Statement_Value value;
+    enum Tree_Statement_Kind kind;
+    union Tree_Statement_Value value;
 
     struct Span span;
     struct Cursor location;
 
     // if statement is within a group of multiple statements,
     // points to the next statement within it.
-    struct Statement* next;
+    struct Tree_Statement* next;
 };
 
-REGION(struct Statement, statement)
+REGION(struct Tree_Statement, tree_statement)
 
-struct Statement*
-statement_new(
-    enum Statement_Kind kind, union Statement_Value value, struct Span span, struct Cursor location)
+struct Tree_Statement*
+tree_statement_new(
+    enum Tree_Statement_Kind kind, union Tree_Statement_Value value, struct Span span, struct Cursor location)
 {
-    check(region_statement_cursor < REGION_SIZE, "out of statement memory");
-    struct Statement* statement = &region_statement[region_statement_cursor++];
-    *statement = (struct Statement){
+    check(region_tree_statement_cursor < REGION_SIZE, "out of statement memory");
+    struct Tree_Statement* statement = &region_tree_statement[region_tree_statement_cursor++];
+    *statement = (struct Tree_Statement){
         .kind = kind,
         .value = value,
         .span = span,
@@ -1026,5 +1026,5 @@ statement_new(
 // the top-level tree of a single catskill source file.
 struct Tree
 {
-    struct Statement* top_level_statements;
+    struct Tree_Statement* top_level_statements;
 };
diff --git a/boot/visit.c b/boot/visit.c
index f9ad51c..83de09a 100644
--- a/boot/visit.c
+++ b/boot/visit.c
@@ -13,60 +13,60 @@
 
 #include "catboot.h"
 
-struct Visit
+struct Tree_Visit
 {
-    struct Visit_Table* table;
+    struct Tree_Visit_Table* table;
     void* user_data;
 };
 
-struct Visit_Table
-{
-    void (*visit_tree)(struct Visit* visitor, struct Tree* tree);
-
-    void (*visit_statement)(struct Visit* visitor, struct Statement* stmt);
-    void (*visit_statement_declaration)(struct Visit* visitor, struct Statement* stmt);
-    void (*visit_statement_conditional)(struct Visit* visitor, struct Statement* stmt);
-    void (*visit_statement_loop)(struct Visit* visitor, struct Statement* stmt);
-    void (*visit_statement_return)(struct Visit* visitor, struct Statement* stmt);
-    void (*visit_statement_break)(struct Visit* visitor, struct Statement* stmt);
-    void (*visit_statement_continue)(struct Visit* visitor, struct Statement* stmt);
-    void (*visit_statement_defer)(struct Visit* visitor, struct Statement* stmt);
-
-    void (*visit_expression)(struct Visit* visitor, struct Expression* expr);
-    void (*visit_expression_integer_literal)(struct Visit* visitor, struct Expression* expr);
-    void (*visit_expression_float_literal)(struct Visit* visitor, struct Expression* expr);
-    void (*visit_expression_string_literal)(struct Visit* visitor, struct Expression* expr);
-    void (*visit_expression_boolean_literal)(struct Visit* visitor, struct Expression* expr);
-    void (*visit_expression_name)(struct Visit* visitor, struct Expression* expr);
-    void (*visit_expression_unary_operation)(struct Visit* visitor, struct Expression* expr);
-    void (*visit_expression_binary_operation)(struct Visit* visitor, struct Expression* expr);
-    void (*visit_expression_group)(struct Visit* visitor, struct Expression* expr);
-    void (*visit_expression_call)(struct Visit* visitor, struct Expression* expr);
-    void (*visit_expression_construct)(struct Visit* visitor, struct Expression* expr);
-    void (*visit_expression_subscript)(struct Visit* visitor, struct Expression* expr);
-    void (*visit_expression_member)(struct Visit* visitor, struct Expression* expr);
-    void (*visit_expression_increment_decrement)(struct Visit* visitor, struct Expression* expr);
-    void (*visit_expression_try)(struct Visit* visitor, struct Expression* expr);
-    void (*visit_expression_must)(struct Visit* visitor, struct Expression* expr);
-    void (*visit_expression_function)(struct Visit* visitor, struct Expression* expr);
-
-    void (*visit_type_node)(struct Visit* visitor, struct Type_Node* node);
-    void (*visit_type_node_name)(struct Visit* visitor, struct Type_Node* node);
-    void (*visit_type_node_array)(struct Visit* visitor, struct Type_Node* node);
-    void (*visit_type_node_reference)(struct Visit* visitor, struct Type_Node* node);
-    void (*visit_type_node_maybe)(struct Visit* visitor, struct Type_Node* node);
-    void (*visit_type_node_tuple)(struct Visit* visitor, struct Type_Node* node);
-    void (*visit_type_node_map)(struct Visit* visitor, struct Type_Node* node);
-    void (*visit_type_node_function)(struct Visit* visitor, struct Type_Node* node);
-    void (*visit_type_node_structure)(struct Visit* visitor, struct Type_Node* node);
-    void (*visit_type_node_variant)(struct Visit* visitor, struct Type_Node* node);
-    void (*visit_type_node_class)(struct Visit* visitor, struct Type_Node* node);
-
-    void (*visit_block_node)(struct Visit* visitor, struct Block_Node* node);
-    void (*visit_bare_declaration_node)(struct Visit* visitor, struct Bare_Declaration_Node* node);
-    void (*visit_function_header_node)(struct Visit* visitor, struct Function_Header_Node* header);
-    void (*visit_argument_group_node)(struct Visit* visitor, struct Argument_Group_Node* node);
-    void (*visit_pragma_node)(struct Visit* visitor, struct Pragma_Node* node);
+struct Tree_Visit_Table
+{
+    void (*visit_tree)(struct Tree_Visit* visitor, struct Tree* tree);
+
+    void (*visit_statement)(struct Tree_Visit* visitor, struct Tree_Statement* stmt);
+    void (*visit_statement_declaration)(struct Tree_Visit* visitor, struct Tree_Statement* stmt);
+    void (*visit_statement_conditional)(struct Tree_Visit* visitor, struct Tree_Statement* stmt);
+    void (*visit_statement_loop)(struct Tree_Visit* visitor, struct Tree_Statement* stmt);
+    void (*visit_statement_return)(struct Tree_Visit* visitor, struct Tree_Statement* stmt);
+    void (*visit_statement_break)(struct Tree_Visit* visitor, struct Tree_Statement* stmt);
+    void (*visit_statement_continue)(struct Tree_Visit* visitor, struct Tree_Statement* stmt);
+    void (*visit_statement_defer)(struct Tree_Visit* visitor, struct Tree_Statement* stmt);
+
+    void (*visit_expression)(struct Tree_Visit* visitor, struct Tree_Expression* expr);
+    void (*visit_expression_integer_literal)(struct Tree_Visit* visitor, struct Tree_Expression* expr);
+    void (*visit_expression_float_literal)(struct Tree_Visit* visitor, struct Tree_Expression* expr);
+    void (*visit_expression_string_literal)(struct Tree_Visit* visitor, struct Tree_Expression* expr);
+    void (*visit_expression_boolean_literal)(struct Tree_Visit* visitor, struct Tree_Expression* expr);
+    void (*visit_expression_name)(struct Tree_Visit* visitor, struct Tree_Expression* expr);
+    void (*visit_expression_unary_operation)(struct Tree_Visit* visitor, struct Tree_Expression* expr);
+    void (*visit_expression_binary_operation)(struct Tree_Visit* visitor, struct Tree_Expression* expr);
+    void (*visit_expression_group)(struct Tree_Visit* visitor, struct Tree_Expression* expr);
+    void (*visit_expression_call)(struct Tree_Visit* visitor, struct Tree_Expression* expr);
+    void (*visit_expression_construct)(struct Tree_Visit* visitor, struct Tree_Expression* expr);
+    void (*visit_expression_subscript)(struct Tree_Visit* visitor, struct Tree_Expression* expr);
+    void (*visit_expression_member)(struct Tree_Visit* visitor, struct Tree_Expression* expr);
+    void (*visit_expression_increment_decrement)(struct Tree_Visit* visitor, struct Tree_Expression* expr);
+    void (*visit_expression_try)(struct Tree_Visit* visitor, struct Tree_Expression* expr);
+    void (*visit_expression_must)(struct Tree_Visit* visitor, struct Tree_Expression* expr);
+    void (*visit_expression_function)(struct Tree_Visit* visitor, struct Tree_Expression* expr);
+
+    void (*visit_type_node)(struct Tree_Visit* visitor, struct Tree_Type* node);
+    void (*visit_type_node_name)(struct Tree_Visit* visitor, struct Tree_Type* node);
+    void (*visit_type_node_array)(struct Tree_Visit* visitor, struct Tree_Type* node);
+    void (*visit_type_node_reference)(struct Tree_Visit* visitor, struct Tree_Type* node);
+    void (*visit_type_node_maybe)(struct Tree_Visit* visitor, struct Tree_Type* node);
+    void (*visit_type_node_tuple)(struct Tree_Visit* visitor, struct Tree_Type* node);
+    void (*visit_type_node_map)(struct Tree_Visit* visitor, struct Tree_Type* node);
+    void (*visit_type_node_function)(struct Tree_Visit* visitor, struct Tree_Type* node);
+    void (*visit_type_node_structure)(struct Tree_Visit* visitor, struct Tree_Type* node);
+    void (*visit_type_node_variant)(struct Tree_Visit* visitor, struct Tree_Type* node);
+    void (*visit_type_node_class)(struct Tree_Visit* visitor, struct Tree_Type* node);
+
+    void (*visit_block_node)(struct Tree_Visit* visitor, struct Tree_Block* node);
+    void (*visit_bare_declaration_node)(struct Tree_Visit* visitor, struct Tree_Bare_Declaration* node);
+    void (*visit_function_header_node)(struct Tree_Visit* visitor, struct Tree_Function_Header* header);
+    void (*visit_argument_group_node)(struct Tree_Visit* visitor, struct Tree_Argument_Group* node);
+    void (*visit_pragma_node)(struct Tree_Visit* visitor, struct Tree_Pragma* node);
 };
 
 #define VISIT(visit_function, node) visit->table->visit_function(visit, node);
@@ -78,76 +78,76 @@ struct Visit_Table
     type* name = (type*)visit->user_data; \
     if (!name) { failure("visit user data is NULL for " #name); }
 
-// walk functions are the default traversal mechanism
+// tree_walk functions are the default traversal mechanism
 
-// define a walk function which goes nowhere.
-#define WALK_LEAF_FUNCTION(name, type) \
-    void name(struct Visit* visit, type node) {}
+// define a tree_walk function which goes nowhere.
+#define TREE_WALK_LEAF_FUNCTION(name, type) \
+    void name(struct Tree_Visit* visit, type node) {}
 
-// top-level walk function for beginning the visit flow.
+// top-level tree_walk function for beginning the visit flow.
 void
-walk(struct Visit* visit, struct Tree* tree)
+tree_walk(struct Tree_Visit* visit, struct Tree* tree)
 {
     VISIT(visit_tree, tree);
 }
 
 void
-walk_tree(struct Visit* visit, struct Tree* tree)
+tree_walk_tree(struct Tree_Visit* visit, struct Tree* tree)
 {
-    FOR_EACH (struct Statement*, statement, tree->top_level_statements) {
+    FOR_EACH (struct Tree_Statement*, statement, tree->top_level_statements) {
         VISIT(visit_statement, statement);
     }
 }
 
 void
-walk_statement(struct Visit* visit, struct Statement* statement)
+tree_walk_statement(struct Tree_Visit* visit, struct Tree_Statement* statement)
 {
     switch (statement->kind) {
-    case STATEMENT_EXPRESSION:
+    case TREE_STATEMENT_EXPRESSION:
         VISIT(visit_expression, statement->value.expression.inner);
         break;
-    case STATEMENT_DECLARATION:
+    case TREE_STATEMENT_DECLARATION:
         VISIT(visit_statement_declaration, statement);
         break;
-    case STATEMENT_BLOCK:
+    case TREE_STATEMENT_BLOCK:
         VISIT(visit_block_node, &statement->value.block.inner);
         break;
-    case STATEMENT_CONDITIONAL:
+    case TREE_STATEMENT_CONDITIONAL:
         VISIT(visit_statement_conditional, statement);
         break;
-    case STATEMENT_LOOP:
+    case TREE_STATEMENT_LOOP:
         VISIT(visit_statement_loop, statement);
         break;
-    case STATEMENT_RETURN:
+    case TREE_STATEMENT_RETURN:
         VISIT(visit_statement_return, statement);
         break;
-    case STATEMENT_BREAK:
+    case TREE_STATEMENT_BREAK:
         VISIT(visit_statement_break, statement);
         break;
-    case STATEMENT_CONTINUE:
+    case TREE_STATEMENT_CONTINUE:
         VISIT(visit_statement_continue, statement);
         break;
-    case STATEMENT_DEFER:
+    case TREE_STATEMENT_DEFER:
         VISIT(visit_statement_defer, statement);
         break;
-    case STATEMENT_PRAGMA:
+    case TREE_STATEMENT_PRAGMA:
         VISIT(visit_pragma_node, statement->value.pragma.inner);
         break;
     default:
-        failure("unexpected statement kind in `walk_statement`");
+        failure("unexpected statement kind in `tree_walk_statement`");
     }
 }
 
 void
-walk_statement_declaration(struct Visit* visit, struct Statement* statement)
+tree_walk_statement_declaration(struct Tree_Visit* visit, struct Tree_Statement* statement)
 {
     VISIT(visit_bare_declaration_node, &statement->value.declaration.inner);
 }
 
 void
-walk_statement_conditional(struct Visit* visit, struct Statement* statement)
+tree_walk_statement_conditional(struct Tree_Visit* visit, struct Tree_Statement* statement)
 {
-    struct Statement_Value_Conditional* conditional = &statement->value.conditional;
+    struct Tree_Statement_Value_Conditional* conditional = &statement->value.conditional;
     for (uint i = 0; i < conditional->condition_count; ++i) {
         VISIT_MAYBE(visit_expression, conditional->conditions[i].when);
         VISIT(visit_block_node, &conditional->conditions[i].then);
@@ -155,16 +155,16 @@ walk_statement_conditional(struct Visit* visit, struct Statement* statement)
 }
 
 void
-walk_statement_loop(struct Visit* visit, struct Statement* statement)
+tree_walk_statement_loop(struct Tree_Visit* visit, struct Tree_Statement* statement)
 {
-    struct Statement_Value_Loop* loop = &statement->value.loop;
+    struct Tree_Statement_Value_Loop* loop = &statement->value.loop;
     VISIT_MAYBE(visit_expression, loop->condition);
     VISIT_MAYBE(visit_expression, loop->iteration);
     VISIT(visit_block_node, &loop->body);
 }
 
 void
-walk_statement_return(struct Visit* visit, struct Statement* statement)
+tree_walk_statement_return(struct Tree_Visit* visit, struct Tree_Statement* statement)
 {
     VISIT_MAYBE(visit_expression, statement->value.return_value.value);
 }
@@ -172,358 +172,358 @@ walk_statement_return(struct Visit* visit, struct Statement* statement)
 // although.. maybe with `break` we could make a loop become an expression,
 // this returning the break value as the value of the loop?
 // something to think about.
-WALK_LEAF_FUNCTION(walk_statement_break, struct Statement*);
+TREE_WALK_LEAF_FUNCTION(tree_walk_statement_break, struct Tree_Statement*);
 
-WALK_LEAF_FUNCTION(walk_statement_continue, struct Statement*);
+TREE_WALK_LEAF_FUNCTION(tree_walk_statement_continue, struct Tree_Statement*);
 
 void
-walk_statement_defer(struct Visit* visit, struct Statement* statement)
+tree_walk_statement_defer(struct Tree_Visit* visit, struct Tree_Statement* statement)
 {
     VISIT_MAYBE(visit_expression, statement->value.defer.expression);
     VISIT(visit_block_node, &statement->value.defer.block);
 }
 
 void
-walk_expression(struct Visit* visit, struct Expression* expression)
+tree_walk_expression(struct Tree_Visit* visit, struct Tree_Expression* expression)
 {
     switch (expression->kind) {
-    case EXPRESSION_INTEGER_LITERAL:
+    case TREE_EXPRESSION_INTEGER_LITERAL:
         VISIT(visit_expression_integer_literal, expression);
         break;
-    case EXPRESSION_FLOAT_LITERAL:
+    case TREE_EXPRESSION_FLOAT_LITERAL:
         VISIT(visit_expression_float_literal, expression);
         break;
-    case EXPRESSION_STRING_LITERAL:
+    case TREE_EXPRESSION_STRING_LITERAL:
         VISIT(visit_expression_string_literal, expression);
         break;
-    case EXPRESSION_BOOLEAN_LITERAL:
+    case TREE_EXPRESSION_BOOLEAN_LITERAL:
         VISIT(visit_expression_boolean_literal, expression);
         break;
-    case EXPRESSION_NAME:
+    case TREE_EXPRESSION_NAME:
         VISIT(visit_expression_name, expression);
         break;
-    case EXPRESSION_UNARY_OPERATION:
+    case TREE_EXPRESSION_UNARY_OPERATION:
         VISIT(visit_expression_unary_operation, expression);
         break;
-    case EXPRESSION_BINARY_OPERATION:
+    case TREE_EXPRESSION_BINARY_OPERATION:
         VISIT(visit_expression_binary_operation, expression);
         break;
-    case EXPRESSION_GROUP:
+    case TREE_EXPRESSION_GROUP:
         VISIT(visit_expression_group, expression);
         break;
-    case EXPRESSION_CALL:
+    case TREE_EXPRESSION_CALL:
         VISIT(visit_expression_call, expression);
         break;
-    case EXPRESSION_CONSTRUCT:
+    case TREE_EXPRESSION_CONSTRUCT:
         VISIT(visit_expression_construct, expression);
         break;
-    case EXPRESSION_SUBSCRIPT:
+    case TREE_EXPRESSION_SUBSCRIPT:
         VISIT(visit_expression_subscript, expression);
         break;
-    case EXPRESSION_MEMBER:
+    case TREE_EXPRESSION_MEMBER:
         VISIT(visit_expression_member, expression);
         break;
-    case EXPRESSION_INCREMENT_DECREMENT:
+    case TREE_EXPRESSION_INCREMENT_DECREMENT:
         VISIT(visit_expression_increment_decrement, expression);
         break;
-    case EXPRESSION_TRY:
+    case TREE_EXPRESSION_TRY:
         VISIT(visit_expression_try, expression);
         break;
-    case EXPRESSION_MUST:
+    case TREE_EXPRESSION_MUST:
         VISIT(visit_expression_must, expression);
         break;
-    case EXPRESSION_FUNCTION:
+    case TREE_EXPRESSION_FUNCTION:
         VISIT(visit_expression_function, expression);
         break;
-    case EXPRESSION_TYPE:
+    case TREE_EXPRESSION_TYPE:
         VISIT(visit_type_node, expression->value.type.type);
         break;
     default:
-        failure("unexpected expression kind in `walk_expression`");
+        failure("unexpected expression kind in `tree_walk_expression`");
     }
 }
 
-WALK_LEAF_FUNCTION(walk_expression_integer_literal, struct Expression*);
+TREE_WALK_LEAF_FUNCTION(tree_walk_expression_integer_literal, struct Tree_Expression*);
 
-WALK_LEAF_FUNCTION(walk_expression_float_literal, struct Expression*);
+TREE_WALK_LEAF_FUNCTION(tree_walk_expression_float_literal, struct Tree_Expression*);
 
-WALK_LEAF_FUNCTION(walk_expression_string_literal, struct Expression*);
+TREE_WALK_LEAF_FUNCTION(tree_walk_expression_string_literal, struct Tree_Expression*);
 
-WALK_LEAF_FUNCTION(walk_expression_boolean_literal, struct Expression*);
+TREE_WALK_LEAF_FUNCTION(tree_walk_expression_boolean_literal, struct Tree_Expression*);
 
-WALK_LEAF_FUNCTION(walk_expression_name, struct Expression*);
+TREE_WALK_LEAF_FUNCTION(tree_walk_expression_name, struct Tree_Expression*);
 
 void
-walk_expression_unary_operation(struct Visit* visit, struct Expression* expression)
+tree_walk_expression_unary_operation(struct Tree_Visit* visit, struct Tree_Expression* expression)
 {
     VISIT(visit_expression, expression->value.unary_operator.operand);
 }
 
 void
-walk_expression_binary_operation(struct Visit* visit, struct Expression* expression)
+tree_walk_expression_binary_operation(struct Tree_Visit* visit, struct Tree_Expression* expression)
 {
     VISIT(visit_expression, expression->value.binary_operator.left_operand);
     VISIT(visit_expression, expression->value.binary_operator.right_operand);
 }
 
 void
-walk_expression_group(struct Visit* visit, struct Expression* expression)
+tree_walk_expression_group(struct Tree_Visit* visit, struct Tree_Expression* expression)
 {
     VISIT(visit_expression, expression->value.group.inner_expression);
 }
 
 void
-walk_expression_call(struct Visit* visit, struct Expression* expression)
+tree_walk_expression_call(struct Tree_Visit* visit, struct Tree_Expression* expression)
 {
-    struct Expression_Call* call = &expression->value.call;
+    struct Tree_Expression_Call* call = &expression->value.call;
     VISIT(visit_expression, call->subject);
     VISIT(visit_argument_group_node, &call->argument_group);
 }
 
 void
-walk_expression_construct(struct Visit* visit, struct Expression* expression)
+tree_walk_expression_construct(struct Tree_Visit* visit, struct Tree_Expression* expression)
 {
-    struct Expression_Construct* construct = &expression->value.construct;
+    struct Tree_Expression_Construct* construct = &expression->value.construct;
     VISIT(visit_expression, construct->subject);
     VISIT(visit_argument_group_node, &construct->argument_group);
 }
 
 void
-walk_expression_subscript(struct Visit* visit, struct Expression* expression)
+tree_walk_expression_subscript(struct Tree_Visit* visit, struct Tree_Expression* expression)
 {
     VISIT(visit_expression, expression->value.subscript.subject);
     VISIT(visit_expression, expression->value.subscript.index);
 }
 
 void
-walk_expression_member(struct Visit* visit, struct Expression* expression)
+tree_walk_expression_member(struct Tree_Visit* visit, struct Tree_Expression* expression)
 {
     VISIT(visit_expression, expression->value.member.subject);
 }
 
 void
-walk_expression_increment_decrement(struct Visit* visit, struct Expression* expression)
+tree_walk_expression_increment_decrement(struct Tree_Visit* visit, struct Tree_Expression* expression)
 {
     VISIT(visit_expression, expression->value.increment_decrement.subject);
 }
 
-WALK_LEAF_FUNCTION(walk_expression_try, struct Expression*);
+TREE_WALK_LEAF_FUNCTION(tree_walk_expression_try, struct Tree_Expression*);
 
-WALK_LEAF_FUNCTION(walk_expression_must, struct Expression*);
+TREE_WALK_LEAF_FUNCTION(tree_walk_expression_must, struct Tree_Expression*);
 
 void
-walk_expression_function(struct Visit* visit, struct Expression* expression)
+tree_walk_expression_function(struct Tree_Visit* visit, struct Tree_Expression* expression)
 {
     VISIT(visit_function_header_node, &expression->value.function.header);
     VISIT(visit_block_node, &expression->value.function.body);
 }
 
 void
-walk_type_node(struct Visit* visit, struct Type_Node* node)
+tree_walk_type(struct Tree_Visit* visit, struct Tree_Type* node)
 {
     switch (node->type) {
-    case TYPE_NODE_NONE:
+    case TREE_TYPE_NONE:
         break;
-    case TYPE_NODE_NAME:
+    case TREE_TYPE_NAME:
         VISIT(visit_type_node_name, node);
         break;
-    case TYPE_NODE_ARRAY:
+    case TREE_TYPE_ARRAY:
         VISIT(visit_type_node_array, node);
         break;
-    case TYPE_NODE_REFERENCE:
+    case TREE_TYPE_REFERENCE:
         VISIT(visit_type_node_reference, node);
         break;
-    case TYPE_NODE_MAYBE:
+    case TREE_TYPE_MAYBE:
         VISIT(visit_type_node_maybe, node);
         break;
-    case TYPE_NODE_TUPLE:
+    case TREE_TYPE_TUPLE:
         VISIT(visit_type_node_tuple, node);
         break;
-    case TYPE_NODE_MAP:
+    case TREE_TYPE_MAP:
         VISIT(visit_type_node_map, node);
         break;
-    case TYPE_NODE_FUNCTION:
+    case TREE_TYPE_FUNCTION:
         VISIT(visit_type_node_function, node);
         break;
-    case TYPE_NODE_STRUCTURE:
+    case TREE_TYPE_STRUCTURE:
         VISIT(visit_type_node_structure, node);
         break;
-    case TYPE_NODE_VARIANT:
+    case TREE_TYPE_VARIANT:
         VISIT(visit_type_node_variant, node);
         break;
-    case TYPE_NODE_CLASS:
+    case TREE_TYPE_CLASS:
         VISIT(visit_type_node_class, node);
         break;
     default:
-        failure("unexpected type node kind in `walk_type_node`");
+        failure("unexpected type node kind in `tree_walk_type`");
     }
 }
 
-WALK_LEAF_FUNCTION(walk_type_node_name, struct Type_Node*);
+TREE_WALK_LEAF_FUNCTION(tree_walk_type_name, struct Tree_Type*);
 
 void
-walk_type_node_array(struct Visit* visit, struct Type_Node* node)
+tree_walk_type_array(struct Tree_Visit* visit, struct Tree_Type* node)
 {
     VISIT(visit_type_node, node->value.array.element_type);
 }
 
 void
-walk_type_node_reference(struct Visit* visit, struct Type_Node* node)
+tree_walk_type_reference(struct Tree_Visit* visit, struct Tree_Type* node)
 {
     VISIT(visit_type_node, node->value.reference.referenced_type);
 }
 
 void
-walk_type_node_maybe(struct Visit* visit, struct Type_Node* node)
+tree_walk_type_maybe(struct Tree_Visit* visit, struct Tree_Type* node)
 {
     VISIT(visit_type_node, node->value.maybe.inner_type);
 }
 
 void
-walk_type_node_tuple(struct Visit* visit, struct Type_Node* node)
+tree_walk_type_tuple(struct Tree_Visit* visit, struct Tree_Type* node)
 {
-    FOR_EACH (struct Type_Node*, current, node->value.tuple.head) {
+    FOR_EACH (struct Tree_Type*, current, node->value.tuple.head) {
         VISIT(visit_type_node, current);
     }
 }
 
 void
-walk_type_node_map(struct Visit* visit, struct Type_Node* node)
+tree_walk_type_map(struct Tree_Visit* visit, struct Tree_Type* node)
 {
     VISIT(visit_type_node, node->value.map.key_type);
     VISIT(visit_type_node, node->value.map.value_type);
 }
 
 void
-walk_type_node_function(struct Visit* visit, struct Type_Node* node)
+tree_walk_type_function(struct Tree_Visit* visit, struct Tree_Type* node)
 {
     VISIT(visit_function_header_node, &node->value.function.header);
 }
 
 void
-walk_type_node_structure(struct Visit* visit, struct Type_Node* node)
+tree_walk_type_structure(struct Tree_Visit* visit, struct Tree_Type* node)
 {
-    FOR_EACH (struct Type_Node*, field, node->value.structure.fields) {
+    FOR_EACH (struct Tree_Type*, field, node->value.structure.fields) {
         VISIT(visit_type_node, field);
     }
 }
 
 void
-walk_type_node_variant(struct Visit* visit, struct Type_Node* node)
+tree_walk_type_variant(struct Tree_Visit* visit, struct Tree_Type* node)
 {
-    FOR_EACH (struct Type_Node*, method, node->value.variant.variants) {
+    FOR_EACH (struct Tree_Type*, method, node->value.variant.variants) {
         VISIT(visit_type_node, method);
     }
 }
 
 void
-walk_type_node_class(struct Visit* visit, struct Type_Node* node)
+tree_walk_type_class(struct Tree_Visit* visit, struct Tree_Type* node)
 {
-    FOR_EACH (struct Type_Node*, method, node->value.class.methods) {
+    FOR_EACH (struct Tree_Type*, method, node->value.class.methods) {
         VISIT(visit_type_node, method);
     }
 }
 
 void
-walk_block_node(struct Visit* visit, struct Block_Node* node)
+tree_walk_block(struct Tree_Visit* visit, struct Tree_Block* node)
 {
-    FOR_EACH (struct Statement*, statement, node->statements) { VISIT(visit_statement, statement); }
+    FOR_EACH (struct Tree_Statement*, statement, node->statements) { VISIT(visit_statement, statement); }
 }
 
 void
-walk_bare_declaration_node(struct Visit* visit, struct Bare_Declaration_Node* node)
+tree_walk_bare_declaration(struct Tree_Visit* visit, struct Tree_Bare_Declaration* node)
 {
     VISIT_MAYBE(visit_type_node, node->type);
     VISIT(visit_expression, node->initializer);
 }
 
 void
-walk_function_header_node(struct Visit* visit, struct Function_Header_Node* header)
+tree_walk_function_header(struct Tree_Visit* visit, struct Tree_Function_Header* header)
 {
-    FOR_EACH (struct Type_Node*, param_type, header->parameters_type_and_name) {
+    FOR_EACH (struct Tree_Type*, param_type, header->parameters_type_and_name) {
         VISIT(visit_type_node, param_type);
     }
     VISIT_MAYBE(visit_type_node, header->return_type);
 }
 
 void
-walk_argument_group_node(struct Visit* visit, struct Argument_Group_Node* node)
+tree_walk_argument_group(struct Tree_Visit* visit, struct Tree_Argument_Group* node)
 {
-    FOR_EACH (struct Expression*, argument, node->arguments) { VISIT(visit_expression, argument); }
+    FOR_EACH (struct Tree_Expression*, argument, node->arguments) { VISIT(visit_expression, argument); }
 }
 
 void
-walk_pragma_node(struct Visit* visit, struct Pragma_Node* node)
+tree_walk_pragma(struct Tree_Visit* visit, struct Tree_Pragma* node)
 {
     // visit each pragma node in the linked list.
     VISIT_MAYBE(visit_pragma_node, node->next);
 }
 
-struct Visit_Table walk_functions = {
-    .visit_tree = walk_tree,
-
-    .visit_statement = walk_statement,
-    .visit_statement_declaration = walk_statement_declaration,
-    .visit_statement_conditional = walk_statement_conditional,
-    .visit_statement_loop = walk_statement_loop,
-    .visit_statement_return = walk_statement_return,
-    .visit_statement_break = walk_statement_break,
-    .visit_statement_continue = walk_statement_continue,
-    .visit_statement_defer = walk_statement_defer,
-
-    .visit_expression = walk_expression,
-    .visit_expression_integer_literal = walk_expression_integer_literal,
-    .visit_expression_float_literal = walk_expression_float_literal,
-    .visit_expression_string_literal = walk_expression_string_literal,
-    .visit_expression_boolean_literal = walk_expression_boolean_literal,
-    .visit_expression_name = walk_expression_name,
-    .visit_expression_unary_operation = walk_expression_unary_operation,
-    .visit_expression_binary_operation = walk_expression_binary_operation,
-    .visit_expression_group = walk_expression_group,
-    .visit_expression_call = walk_expression_call,
-    .visit_expression_construct = walk_expression_construct,
-    .visit_expression_subscript = walk_expression_subscript,
-    .visit_expression_member = walk_expression_member,
-    .visit_expression_increment_decrement = walk_expression_increment_decrement,
-    .visit_expression_function = walk_expression_function,
-
-    .visit_type_node = walk_type_node,
-    .visit_type_node_name = walk_type_node_name,
-    .visit_type_node_array = walk_type_node_array,
-    .visit_type_node_reference = walk_type_node_reference,
-    .visit_type_node_maybe = walk_type_node_maybe,
-    .visit_type_node_tuple = walk_type_node_tuple,
-    .visit_type_node_map = walk_type_node_map,
-    .visit_type_node_function = walk_type_node_function,
-    .visit_type_node_structure = walk_type_node_structure,
-    .visit_type_node_variant = walk_type_node_variant,
-    .visit_type_node_class = walk_type_node_class,
-
-    .visit_block_node = walk_block_node,
-    .visit_bare_declaration_node = walk_bare_declaration_node,
-    .visit_function_header_node = walk_function_header_node,
-    .visit_argument_group_node = walk_argument_group_node,
-    .visit_pragma_node = walk_pragma_node,
+struct Tree_Visit_Table tree_walk_functions = {
+    .visit_tree = tree_walk_tree,
+
+    .visit_statement = tree_walk_statement,
+    .visit_statement_declaration = tree_walk_statement_declaration,
+    .visit_statement_conditional = tree_walk_statement_conditional,
+    .visit_statement_loop = tree_walk_statement_loop,
+    .visit_statement_return = tree_walk_statement_return,
+    .visit_statement_break = tree_walk_statement_break,
+    .visit_statement_continue = tree_walk_statement_continue,
+    .visit_statement_defer = tree_walk_statement_defer,
+
+    .visit_expression = tree_walk_expression,
+    .visit_expression_integer_literal = tree_walk_expression_integer_literal,
+    .visit_expression_float_literal = tree_walk_expression_float_literal,
+    .visit_expression_string_literal = tree_walk_expression_string_literal,
+    .visit_expression_boolean_literal = tree_walk_expression_boolean_literal,
+    .visit_expression_name = tree_walk_expression_name,
+    .visit_expression_unary_operation = tree_walk_expression_unary_operation,
+    .visit_expression_binary_operation = tree_walk_expression_binary_operation,
+    .visit_expression_group = tree_walk_expression_group,
+    .visit_expression_call = tree_walk_expression_call,
+    .visit_expression_construct = tree_walk_expression_construct,
+    .visit_expression_subscript = tree_walk_expression_subscript,
+    .visit_expression_member = tree_walk_expression_member,
+    .visit_expression_increment_decrement = tree_walk_expression_increment_decrement,
+    .visit_expression_function = tree_walk_expression_function,
+
+    .visit_type_node = tree_walk_type,
+    .visit_type_node_name = tree_walk_type_name,
+    .visit_type_node_array = tree_walk_type_array,
+    .visit_type_node_reference = tree_walk_type_reference,
+    .visit_type_node_maybe = tree_walk_type_maybe,
+    .visit_type_node_tuple = tree_walk_type_tuple,
+    .visit_type_node_map = tree_walk_type_map,
+    .visit_type_node_function = tree_walk_type_function,
+    .visit_type_node_structure = tree_walk_type_structure,
+    .visit_type_node_variant = tree_walk_type_variant,
+    .visit_type_node_class = tree_walk_type_class,
+
+    .visit_block_node = tree_walk_block,
+    .visit_bare_declaration_node = tree_walk_bare_declaration,
+    .visit_function_header_node = tree_walk_function_header,
+    .visit_argument_group_node = tree_walk_argument_group,
+    .visit_pragma_node = tree_walk_pragma,
 };
 
-// fills in the visit table with default walk functions
+// fills in the visit table with default tree_walk functions
 void
-visit_table_fill_defaults(struct Visit_Table* table)
+tree_visit_table_fill_defaults(struct Tree_Visit_Table* table)
 {
     // not portable, nor safe, but sometimes you need to have a bit of fun! :3
 
     // assumptions:
-    // - sizeof(struct Visit_Table) is a multiple of the size of a function pointer,
+    // - sizeof(struct Tree_Visit_Table) is a multiple of the size of a function pointer,
     //   with no padding between function pointers.
     // - the size of a function pointer is the same across all platforms we care about.
-    // - casting struct Visit_Table to a function pointer array is undefined, but safe.
-    const uint function_count = sizeof(struct Visit_Table) / sizeof(void (*)());
+    // - casting struct Tree_Visit_Table to a function pointer array is undefined, but safe.
+    const uint function_count = sizeof(struct Tree_Visit_Table) / sizeof(void (*)());
     typedef void (*Function_Ptr)();
 
     for (uint fi = 0; fi < function_count; ++fi) {
         Function_Ptr* function_slot = &((Function_Ptr*)table)[fi];
-        Function_Ptr* walk = &((Function_Ptr*)&walk_functions)[fi];
-        if (!*function_slot) *function_slot = *walk;
+        Function_Ptr* tree_walk = &((Function_Ptr*)&tree_walk_functions)[fi];
+        if (!*function_slot) *function_slot = *tree_walk;
     }
 }
 
@@ -572,33 +572,33 @@ tree_printer_indent(struct Tree_Printer* printer)
 }
 
 void
-printer_visit_tree(struct Visit* visit, struct Tree* tree)
+tree_printer_visit_tree(struct Tree_Visit* visit, struct Tree* tree)
 {
     TREE_PRINTER_PREAMBLE
 
-    FOR_EACH (struct Statement*, statement, tree->top_level_statements) {
+    FOR_EACH (struct Tree_Statement*, statement, tree->top_level_statements) {
         VISIT(visit_statement, statement);
         PRINT("\n");
     }
 }
 
 void
-printer_visit_statement(struct Visit* visit, struct Statement* statement)
+tree_printer_visit_statement(struct Tree_Visit* visit, struct Tree_Statement* statement)
 {
     TREE_PRINTER_PREAMBLE
 
     tree_printer_indent(printer);
-    walk_statement(visit, statement);
+    tree_walk_statement(visit, statement);
 }
 
 void
-printer_visit_statement_declaration(struct Visit* visit, struct Statement* stmt)
+tree_printer_visit_statement_declaration(struct Tree_Visit* visit, struct Tree_Statement* stmt)
 {
     TREE_PRINTER_PREAMBLE
 
-    if (stmt->value.declaration.kind == STATEMENT_DECLARATION_VARIABLE)
+    if (stmt->value.declaration.kind == TREE_STATEMENT_DECLARATION_VARIABLE)
         PRINT("(variable ");
-    else if (stmt->value.declaration.kind == STATEMENT_DECLARATION_CONSTANT)
+    else if (stmt->value.declaration.kind == TREE_STATEMENT_DECLARATION_CONSTANT)
         PRINT("(constant ");
 
     VISIT(visit_bare_declaration_node, &stmt->value.declaration.inner);
@@ -606,13 +606,13 @@ printer_visit_statement_declaration(struct Visit* visit, struct Statement* stmt)
 }
 
 void
-printer_visit_statement_conditional(struct Visit* visit, struct Statement* stmt)
+tree_printer_visit_statement_conditional(struct Tree_Visit* visit, struct Tree_Statement* stmt)
 {
     TREE_PRINTER_PREAMBLE
 
     PRINT("(conditional");
     for (uint i = 0; i < stmt->value.conditional.condition_count; ++i) {
-        const struct Statement_Conditional_Branch* branch = &stmt->value.conditional.conditions[i];
+        const struct Tree_Statement_Conditional_Branch* branch = &stmt->value.conditional.conditions[i];
         PRINT(" ");
         if (branch->when) {
             PRINT("(when ");
@@ -621,20 +621,20 @@ printer_visit_statement_conditional(struct Visit* visit, struct Statement* stmt)
         } else {
             PRINT("(always) ");
         }
-        VISIT(visit_block_node, (struct Block_Node*)&branch->then);
+        VISIT(visit_block_node, (struct Tree_Block*)&branch->then);
     }
     PRINT(")");
 }
 
 void
-printer_visit_statement_loop(struct Visit* visit, struct Statement* stmt)
+tree_printer_visit_statement_loop(struct Tree_Visit* visit, struct Tree_Statement* stmt)
 {
     TREE_PRINTER_PREAMBLE
 
     PRINT("(loop ");
 
     switch (stmt->value.loop.style) {
-    case STATEMENT_LOOP_STYLE_C:
+    case TREE_STATEMENT_LOOP_STYLE_C:
         PRINT("c-style ");
         VISIT(visit_bare_declaration_node, &stmt->value.loop.declaration);
         PRINT(" (condition ");
@@ -643,21 +643,21 @@ printer_visit_statement_loop(struct Visit* visit, struct Statement* stmt)
         VISIT(visit_expression, stmt->value.loop.iteration);
         PRINT(") ");
         break;
-    case STATEMENT_LOOP_STYLE_FOR_EACH:
+    case TREE_STATEMENT_LOOP_STYLE_FOR_EACH:
         PRINT("for-each ");
         VISIT(visit_bare_declaration_node, &stmt->value.loop.declaration);
         PRINT(" ");
         break;
-    case STATEMENT_LOOP_STYLE_WHILE:
+    case TREE_STATEMENT_LOOP_STYLE_WHILE:
         PRINT("while (condition ");
         VISIT(visit_expression, stmt->value.loop.condition);
         PRINT(") ");
         break;
-    case STATEMENT_LOOP_STYLE_ENDLESS:
+    case TREE_STATEMENT_LOOP_STYLE_ENDLESS:
         PRINT("endless ");
         break;
     default:
-        fprintf(stderr, "unexpected loop style in `printer_visit_statement_loop`");
+        fprintf(stderr, "unexpected loop style in `tree_printer_visit_statement_loop`");
         break;
     }
 
@@ -666,7 +666,7 @@ printer_visit_statement_loop(struct Visit* visit, struct Statement* stmt)
 }
 
 void
-printer_visit_statement_return(struct Visit* visit, struct Statement* stmt)
+tree_printer_visit_statement_return(struct Tree_Visit* visit, struct Tree_Statement* stmt)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -679,7 +679,7 @@ printer_visit_statement_return(struct Visit* visit, struct Statement* stmt)
 }
 
 void
-printer_visit_statement_break(struct Visit* visit, struct Statement* stmt)
+tree_printer_visit_statement_break(struct Tree_Visit* visit, struct Tree_Statement* stmt)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -687,7 +687,7 @@ printer_visit_statement_break(struct Visit* visit, struct Statement* stmt)
 }
 
 void
-printer_visit_statement_continue(struct Visit* visit, struct Statement* stmt)
+tree_printer_visit_statement_continue(struct Tree_Visit* visit, struct Tree_Statement* stmt)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -695,7 +695,7 @@ printer_visit_statement_continue(struct Visit* visit, struct Statement* stmt)
 }
 
 void
-printer_visit_statement_defer(struct Visit* visit, struct Statement* stmt)
+tree_printer_visit_statement_defer(struct Tree_Visit* visit, struct Tree_Statement* stmt)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -709,16 +709,16 @@ printer_visit_statement_defer(struct Visit* visit, struct Statement* stmt)
 }
 
 void
-printer_visit_expression(struct Visit* visit, struct Expression* expression)
+tree_printer_visit_expression(struct Tree_Visit* visit, struct Tree_Expression* expression)
 {
     TREE_PRINTER_PREAMBLE
     PRINT("(expr ");
-    walk_expression(visit, expression);
+    tree_walk_expression(visit, expression);
     PRINT(")");
 }
 
 void
-printer_visit_expression_integer_literal(struct Visit* visit, struct Expression* expr)
+tree_printer_visit_expression_integer_literal(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -726,7 +726,7 @@ printer_visit_expression_integer_literal(struct Visit* visit, struct Expression*
 }
 
 void
-printer_visit_expression_float_literal(struct Visit* visit, struct Expression* expr)
+tree_printer_visit_expression_float_literal(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -734,7 +734,7 @@ printer_visit_expression_float_literal(struct Visit* visit, struct Expression* e
 }
 
 void
-printer_visit_expression_string_literal(struct Visit* visit, struct Expression* expr)
+tree_printer_visit_expression_string_literal(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -742,7 +742,7 @@ printer_visit_expression_string_literal(struct Visit* visit, struct Expression*
 }
 
 void
-printer_visit_expression_boolean_literal(struct Visit* visit, struct Expression* expr)
+tree_printer_visit_expression_boolean_literal(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -750,7 +750,7 @@ printer_visit_expression_boolean_literal(struct Visit* visit, struct Expression*
 }
 
 void
-printer_visit_expression_name(struct Visit* visit, struct Expression* expr)
+tree_printer_visit_expression_name(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -758,7 +758,7 @@ printer_visit_expression_name(struct Visit* visit, struct Expression* expr)
 }
 
 void
-printer_visit_expression_unary_operation(struct Visit* visit, struct Expression* expr)
+tree_printer_visit_expression_unary_operation(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -768,7 +768,7 @@ printer_visit_expression_unary_operation(struct Visit* visit, struct Expression*
 }
 
 void
-printer_visit_expression_binary_operation(struct Visit* visit, struct Expression* expr)
+tree_printer_visit_expression_binary_operation(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -780,7 +780,7 @@ printer_visit_expression_binary_operation(struct Visit* visit, struct Expression
 }
 
 void
-printer_visit_expression_group(struct Visit* visit, struct Expression* expr)
+tree_printer_visit_expression_group(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -790,11 +790,11 @@ printer_visit_expression_group(struct Visit* visit, struct Expression* expr)
 }
 
 void
-printer_visit_expression_call(struct Visit* visit, struct Expression* expr)
+tree_printer_visit_expression_call(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TREE_PRINTER_PREAMBLE
 
-    struct Expression_Call* call = &expr->value.call;
+    struct Tree_Expression_Call* call = &expr->value.call;
     PRINT("(call ");
     VISIT(visit_expression, call->subject);
     VISIT(visit_argument_group_node, &call->argument_group);
@@ -803,11 +803,11 @@ printer_visit_expression_call(struct Visit* visit, struct Expression* expr)
 }
 
 void
-printer_visit_expression_construct(struct Visit* visit, struct Expression* expr)
+tree_printer_visit_expression_construct(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TREE_PRINTER_PREAMBLE
 
-    struct Expression_Construct* construct = &expr->value.construct;
+    struct Tree_Expression_Construct* construct = &expr->value.construct;
     PRINT("(construct ");
     VISIT(visit_expression, construct->subject);
     VISIT(visit_argument_group_node, &construct->argument_group);
@@ -816,7 +816,7 @@ printer_visit_expression_construct(struct Visit* visit, struct Expression* expr)
 }
 
 void
-printer_visit_expression_subscript(struct Visit* visit, struct Expression* expr)
+tree_printer_visit_expression_subscript(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -828,7 +828,7 @@ printer_visit_expression_subscript(struct Visit* visit, struct Expression* expr)
 }
 
 void
-printer_visit_expression_member(struct Visit* visit, struct Expression* expr)
+tree_printer_visit_expression_member(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -838,11 +838,11 @@ printer_visit_expression_member(struct Visit* visit, struct Expression* expr)
 }
 
 void
-printer_visit_expression_increment_decrement(struct Visit* visit, struct Expression* expr)
+tree_printer_visit_expression_increment_decrement(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TREE_PRINTER_PREAMBLE
 
-    const struct Expression_Increment_Decrement* inc_dec = &expr->value.increment_decrement;
+    const struct Tree_Expression_Increment_Decrement* inc_dec = &expr->value.increment_decrement;
     const ascii* prefix_or_postfix = inc_dec->prefix ? "prefix" : "postfix";
     PRINT("(increment/decrement %s %s ",
           increment_decrement_operation_to_string(inc_dec->operation), prefix_or_postfix);
@@ -851,7 +851,7 @@ printer_visit_expression_increment_decrement(struct Visit* visit, struct Express
 }
 
 void
-printer_visit_expression_try(struct Visit* visit, struct Expression* expr)
+tree_printer_visit_expression_try(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -861,7 +861,7 @@ printer_visit_expression_try(struct Visit* visit, struct Expression* expr)
 }
 
 void
-printer_visit_expression_must(struct Visit* visit, struct Expression* expr)
+tree_printer_visit_expression_must(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -871,30 +871,30 @@ printer_visit_expression_must(struct Visit* visit, struct Expression* expr)
 }
 
 void
-printer_visit_expression_function(struct Visit* visit, struct Expression* expr)
+tree_printer_visit_expression_function(struct Tree_Visit* visit, struct Tree_Expression* expr)
 {
     TREE_PRINTER_PREAMBLE
 
-    struct Expression_Function* fun = &expr->value.function;
+    struct Tree_Expression_Function* fun = &expr->value.function;
     PRINT("(function ");
     VISIT(visit_function_header_node, &fun->header);
     PRINT_WHITESPACE_IF_NEEDED(" ");
-    VISIT(visit_block_node, (struct Block_Node*)&fun->body);
+    VISIT(visit_block_node, (struct Tree_Block*)&fun->body);
     PRINT(")");
 }
 
 void
-printer_visit_type_node(struct Visit* visit, struct Type_Node* node)
+tree_printer_visit_type(struct Tree_Visit* visit, struct Tree_Type* node)
 {
     TREE_PRINTER_PREAMBLE
     PRINT("(type ");
     if (node->variadic) PRINT("variadic ");
-    walk_type_node(visit, node);
+    tree_walk_type(visit, node);
     PRINT(")");
 }
 
 void
-printer_visit_type_node_name(struct Visit* visit, struct Type_Node* node)
+tree_printer_visit_type_name(struct Tree_Visit* visit, struct Tree_Type* node)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -902,7 +902,7 @@ printer_visit_type_node_name(struct Visit* visit, struct Type_Node* node)
 }
 
 void
-printer_visit_type_node_array(struct Visit* visit, struct Type_Node* node)
+tree_printer_visit_type_array(struct Tree_Visit* visit, struct Tree_Type* node)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -911,7 +911,7 @@ printer_visit_type_node_array(struct Visit* visit, struct Type_Node* node)
 }
 
 void
-printer_visit_type_node_reference(struct Visit* visit, struct Type_Node* node)
+tree_printer_visit_type_reference(struct Tree_Visit* visit, struct Tree_Type* node)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -920,7 +920,7 @@ printer_visit_type_node_reference(struct Visit* visit, struct Type_Node* node)
 }
 
 void
-printer_visit_type_node_maybe(struct Visit* visit, struct Type_Node* node)
+tree_printer_visit_type_maybe(struct Tree_Visit* visit, struct Tree_Type* node)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -929,19 +929,19 @@ printer_visit_type_node_maybe(struct Visit* visit, struct Type_Node* node)
 }
 
 void
-printer_visit_type_node_tuple(struct Visit* visit, struct Type_Node* node)
+tree_printer_visit_type_tuple(struct Tree_Visit* visit, struct Tree_Type* node)
 {
     TREE_PRINTER_PREAMBLE
 
     PRINT("tuple");
-    FOR_EACH (struct Type_Node*, current, node->value.tuple.head) {
+    FOR_EACH (struct Tree_Type*, current, node->value.tuple.head) {
         PRINT(" ");
         VISIT(visit_type_node, current);
     }
 }
 
 void
-printer_visit_type_node_map(struct Visit* visit, struct Type_Node* node)
+tree_printer_visit_type_map(struct Tree_Visit* visit, struct Tree_Type* node)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -952,7 +952,7 @@ printer_visit_type_node_map(struct Visit* visit, struct Type_Node* node)
 }
 
 void
-printer_visit_type_node_function(struct Visit* visit, struct Type_Node* node)
+tree_printer_visit_type_function(struct Tree_Visit* visit, struct Tree_Type* node)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -961,25 +961,25 @@ printer_visit_type_node_function(struct Visit* visit, struct Type_Node* node)
 }
 
 void
-printer_visit_type_node_structure(struct Visit* visit, struct Type_Node* node)
+tree_printer_visit_type_structure(struct Tree_Visit* visit, struct Tree_Type* node)
 {
     TREE_PRINTER_PREAMBLE
 
     PRINT("structure");
-    FOR_EACH (struct Type_Node*, current, node->value.structure.fields) {
+    FOR_EACH (struct Tree_Type*, current, node->value.structure.fields) {
         PRINT(" (field %s) ", current->value_name.data);
         VISIT(visit_type_node, current);
     }
 }
 
 void
-printer_visit_type_node_variant(struct Visit* visit, struct Type_Node* node)
+tree_printer_visit_type_variant(struct Tree_Visit* visit, struct Tree_Type* node)
 {
     TREE_PRINTER_PREAMBLE
 
     PRINT("variant");
-    FOR_EACH (struct Type_Node*, current, node->value.variant.variants) {
-        if (current->type == TYPE_NODE_NONE) {
+    FOR_EACH (struct Tree_Type*, current, node->value.variant.variants) {
+        if (current->type == TREE_TYPE_NONE) {
             PRINT(" (variant %s)", current->value_name.data);
         } else {
             PRINT(" (variant %s of ", current->value_name.data);
@@ -990,12 +990,12 @@ printer_visit_type_node_variant(struct Visit* visit, struct Type_Node* node)
 }
 
 void
-printer_visit_type_node_class(struct Visit* visit, struct Type_Node* node)
+tree_printer_visit_type_class(struct Tree_Visit* visit, struct Tree_Type* node)
 {
     TREE_PRINTER_PREAMBLE
 
     PRINT("class");
-    FOR_EACH (struct Type_Node*, current, node->value.class.methods) {
+    FOR_EACH (struct Tree_Type*, current, node->value.class.methods) {
         PRINT(" (method %s ", current->value_name.data);
         VISIT(visit_function_header_node, &current->value.function.header);
         PRINT(")");
@@ -1003,7 +1003,7 @@ printer_visit_type_node_class(struct Visit* visit, struct Type_Node* node)
 }
 
 void
-printer_visit_block_node(struct Visit* visit, struct Block_Node* node)
+tree_printer_visit_block(struct Tree_Visit* visit, struct Tree_Block* node)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -1011,7 +1011,7 @@ printer_visit_block_node(struct Visit* visit, struct Block_Node* node)
     if (node->statements) {
         PRINT("\n");
         printer->indentation_level++;
-        FOR_EACH (struct Statement*, statement, node->statements) {
+        FOR_EACH (struct Tree_Statement*, statement, node->statements) {
             VISIT(visit_statement, statement);
             PRINT("\n");
         }
@@ -1022,7 +1022,7 @@ printer_visit_block_node(struct Visit* visit, struct Block_Node* node)
 }
 
 void
-printer_visit_bare_declaration_node(struct Visit* visit, struct Bare_Declaration_Node* node)
+tree_printer_visit_bare_declaration(struct Tree_Visit* visit, struct Tree_Bare_Declaration* node)
 {
     TREE_PRINTER_PREAMBLE
 
@@ -1031,7 +1031,7 @@ printer_visit_bare_declaration_node(struct Visit* visit, struct Bare_Declaration
         PRINT("%s ", name.data);
     })
 
-    if (node->type && node->type->type != TYPE_NODE_NONE) {
+    if (node->type && node->type->type != TREE_TYPE_NONE) {
         VISIT(visit_type_node, node->type);
         PRINT(" ");
     }
@@ -1045,11 +1045,11 @@ printer_visit_bare_declaration_node(struct Visit* visit, struct Bare_Declaration
 }
 
 void
-printer_visit_function_header(struct Visit* visit, struct Function_Header_Node* header)
+printer_visit_function_header(struct Tree_Visit* visit, struct Tree_Function_Header* header)
 {
     TREE_PRINTER_PREAMBLE
 
-    FOR_EACH (struct Type_Node*, current, header->parameters_type_and_name) {
+    FOR_EACH (struct Tree_Type*, current, header->parameters_type_and_name) {
         // if (current != header->parameters_type_and_name) PRINT(" ");
         PRINT_WHITESPACE_IF_NEEDED(" ");
 
@@ -1071,27 +1071,27 @@ printer_visit_function_header(struct Visit* visit, struct Function_Header_Node*
 }
 
 void
-printer_visit_pragma_node(struct Visit* visit, struct Pragma_Node* node)
+tree_printer_visit_pragma(struct Tree_Visit* visit, struct Tree_Pragma* node)
 {
     TREE_PRINTER_PREAMBLE
 
-    const ascii* pragma_name = pragma_type_to_string(node->type);
+    const ascii* pragma_name = tree_pragma_type_to_string(node->type);
 
     PRINT("(pragma %s", pragma_name);
     for (uint ai = 0; ai < node->argument_count; ++ai) {
-        struct Pragma_Argument* arg = &node->arguments[ai];
+        struct Tree_Pragma_Argument* arg = &node->arguments[ai];
         switch (arg->type) {
-        case PRAGMA_ARGUMENT_NUMBER:
+        case TREE_PRAGMA_ARGUMENT_NUMBER:
             PRINT(" (number %ld)", arg->value.number);
             break;
-        case PRAGMA_ARGUMENT_DECIMAL:
+        case TREE_PRAGMA_ARGUMENT_DECIMAL:
             PRINT(" (decimal %lf)", arg->value.decimal);
             break;
-        case PRAGMA_ARGUMENT_NAME_OR_STRING:
+        case TREE_PRAGMA_ARGUMENT_NAME_OR_STRING:
             PRINT(" (name/string '%s')", arg->value.name_or_string.data);
             break;
         default:
-            failure("unexpected pragma argument type in `printer_visit_pragma_node`");
+            failure("unexpected pragma argument type in `tree_printer_visit_pragma`");
         }
     }
     PRINT(")");
@@ -1103,12 +1103,12 @@ printer_visit_pragma_node(struct Visit* visit, struct Pragma_Node* node)
 }
 
 void
-printer_visit_argument_group_node(struct Visit* visit, struct Argument_Group_Node* node)
+tree_printer_visit_argument_group(struct Tree_Visit* visit, struct Tree_Argument_Group* node)
 {
     TREE_PRINTER_PREAMBLE
 
     uint i = 0;
-    FOR_EACH (struct Expression*, argument, node->arguments) {
+    FOR_EACH (struct Tree_Expression*, argument, node->arguments) {
         struct String name = *array_at(struct String, &node->argument_names, i++);
         if (name.data && name.data[0] != '\0') {
             PRINT(" (named arg '%s' ", name.data);
@@ -1120,53 +1120,53 @@ printer_visit_argument_group_node(struct Visit* visit, struct Argument_Group_Nod
     }
 }
 
-struct Visit_Table printer_visit_functions = {
-    .visit_tree = printer_visit_tree,
-
-    .visit_statement = printer_visit_statement,
-    .visit_statement_declaration = printer_visit_statement_declaration,
-    .visit_statement_conditional = printer_visit_statement_conditional,
-    .visit_statement_loop = printer_visit_statement_loop,
-    .visit_statement_return = printer_visit_statement_return,
-    .visit_statement_break = printer_visit_statement_break,
-    .visit_statement_continue = printer_visit_statement_continue,
-    .visit_statement_defer = printer_visit_statement_defer,
-
-    .visit_expression = printer_visit_expression,
-    .visit_expression_integer_literal = printer_visit_expression_integer_literal,
-    .visit_expression_float_literal = printer_visit_expression_float_literal,
-    .visit_expression_string_literal = printer_visit_expression_string_literal,
-    .visit_expression_boolean_literal = printer_visit_expression_boolean_literal,
-    .visit_expression_name = printer_visit_expression_name,
-    .visit_expression_unary_operation = printer_visit_expression_unary_operation,
-    .visit_expression_binary_operation = printer_visit_expression_binary_operation,
-    .visit_expression_group = printer_visit_expression_group,
-    .visit_expression_call = printer_visit_expression_call,
-    .visit_expression_construct = printer_visit_expression_construct,
-    .visit_expression_subscript = printer_visit_expression_subscript,
-    .visit_expression_member = printer_visit_expression_member,
-    .visit_expression_increment_decrement = printer_visit_expression_increment_decrement,
-    .visit_expression_try = printer_visit_expression_try,
-    .visit_expression_must = printer_visit_expression_must,
-    .visit_expression_function = printer_visit_expression_function,
-
-    .visit_type_node = printer_visit_type_node,
-    .visit_type_node_name = printer_visit_type_node_name,
-    .visit_type_node_array = printer_visit_type_node_array,
-    .visit_type_node_reference = printer_visit_type_node_reference,
-    .visit_type_node_maybe = printer_visit_type_node_maybe,
-    .visit_type_node_tuple = printer_visit_type_node_tuple,
-    .visit_type_node_map = printer_visit_type_node_map,
-    .visit_type_node_function = printer_visit_type_node_function,
-    .visit_type_node_structure = printer_visit_type_node_structure,
-    .visit_type_node_variant = printer_visit_type_node_variant,
-    .visit_type_node_class = printer_visit_type_node_class,
-
-    .visit_block_node = printer_visit_block_node,
-    .visit_bare_declaration_node = printer_visit_bare_declaration_node,
+struct Tree_Visit_Table tree_printer_visit_functions = {
+    .visit_tree = tree_printer_visit_tree,
+
+    .visit_statement = tree_printer_visit_statement,
+    .visit_statement_declaration = tree_printer_visit_statement_declaration,
+    .visit_statement_conditional = tree_printer_visit_statement_conditional,
+    .visit_statement_loop = tree_printer_visit_statement_loop,
+    .visit_statement_return = tree_printer_visit_statement_return,
+    .visit_statement_break = tree_printer_visit_statement_break,
+    .visit_statement_continue = tree_printer_visit_statement_continue,
+    .visit_statement_defer = tree_printer_visit_statement_defer,
+
+    .visit_expression = tree_printer_visit_expression,
+    .visit_expression_integer_literal = tree_printer_visit_expression_integer_literal,
+    .visit_expression_float_literal = tree_printer_visit_expression_float_literal,
+    .visit_expression_string_literal = tree_printer_visit_expression_string_literal,
+    .visit_expression_boolean_literal = tree_printer_visit_expression_boolean_literal,
+    .visit_expression_name = tree_printer_visit_expression_name,
+    .visit_expression_unary_operation = tree_printer_visit_expression_unary_operation,
+    .visit_expression_binary_operation = tree_printer_visit_expression_binary_operation,
+    .visit_expression_group = tree_printer_visit_expression_group,
+    .visit_expression_call = tree_printer_visit_expression_call,
+    .visit_expression_construct = tree_printer_visit_expression_construct,
+    .visit_expression_subscript = tree_printer_visit_expression_subscript,
+    .visit_expression_member = tree_printer_visit_expression_member,
+    .visit_expression_increment_decrement = tree_printer_visit_expression_increment_decrement,
+    .visit_expression_try = tree_printer_visit_expression_try,
+    .visit_expression_must = tree_printer_visit_expression_must,
+    .visit_expression_function = tree_printer_visit_expression_function,
+
+    .visit_type_node = tree_printer_visit_type,
+    .visit_type_node_name = tree_printer_visit_type_name,
+    .visit_type_node_array = tree_printer_visit_type_array,
+    .visit_type_node_reference = tree_printer_visit_type_reference,
+    .visit_type_node_maybe = tree_printer_visit_type_maybe,
+    .visit_type_node_tuple = tree_printer_visit_type_tuple,
+    .visit_type_node_map = tree_printer_visit_type_map,
+    .visit_type_node_function = tree_printer_visit_type_function,
+    .visit_type_node_structure = tree_printer_visit_type_structure,
+    .visit_type_node_variant = tree_printer_visit_type_variant,
+    .visit_type_node_class = tree_printer_visit_type_class,
+
+    .visit_block_node = tree_printer_visit_block,
+    .visit_bare_declaration_node = tree_printer_visit_bare_declaration,
     .visit_function_header_node = printer_visit_function_header,
-    .visit_argument_group_node = printer_visit_argument_group_node,
-    .visit_pragma_node = printer_visit_pragma_node,
+    .visit_argument_group_node = tree_printer_visit_argument_group,
+    .visit_pragma_node = tree_printer_visit_pragma,
 };
 
 void
@@ -1175,9 +1175,9 @@ tree_printer(struct Tree* tree)
     struct Tree_Printer printer = {
         .indentation_level = 0, .output = stdout, .did_print_last_visit = false
     };
-    struct Visit visit = { .table = &printer_visit_functions, .user_data = &printer };
+    struct Tree_Visit visit = { .table = &tree_printer_visit_functions, .user_data = &printer };
 
-    walk(&visit, tree);
+    tree_walk(&visit, tree);
 }
 
 #undef PRINT