about summary refs log tree commit diff
path: root/boot/visit.c
diff options
context:
space:
mode:
authorMel <mel@rnrd.eu>2025-07-01 03:04:07 +0200
committerMel <mel@rnrd.eu>2025-07-01 03:04:07 +0200
commit8e0beabeb4efa50a3072ef805682c0f42b6c16a8 (patch)
treecd6b82d1741cdd52aadddae87c59e0617fb74ffd /boot/visit.c
parente51799842aa367692152717a8db7c519dbc66c1f (diff)
downloadcatskill-8e0beabeb4efa50a3072ef805682c0f42b6c16a8.tar.zst
catskill-8e0beabeb4efa50a3072ef805682c0f42b6c16a8.zip
Parse pragmas as free-standing statements, without attachment
Signed-off-by: Mel <mel@rnrd.eu>
Diffstat (limited to 'boot/visit.c')
-rw-r--r--boot/visit.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/boot/visit.c b/boot/visit.c
index c297fb4..500fb5a 100644
--- a/boot/visit.c
+++ b/boot/visit.c
@@ -62,6 +62,7 @@ struct Visit_Table
     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_pragma_node)(struct Visit* visitor, struct Pragma_Node* node);
 };
 
 #define VISIT(visit_function, node) visit->table->visit_function(visit, node);
@@ -125,6 +126,9 @@ walk_statement(struct Visit* visit, struct Statement* statement)
     case STATEMENT_DEFER:
         VISIT(visit_statement_defer, statement);
         break;
+    case STATEMENT_PRAGMA:
+        VISIT(visit_pragma_node, statement->value.pragma.inner);
+        break;
     default:
         failure("unexpected statement kind in `walk_statement`");
     }
@@ -417,6 +421,13 @@ walk_function_header_node(struct Visit* visit, struct Function_Header_Node* head
     VISIT_MAYBE(visit_type_node, header->return_type);
 }
 
+void
+walk_pragma_node(struct Visit* visit, struct Pragma_Node* 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,
 
@@ -459,6 +470,7 @@ struct Visit_Table walk_functions = {
     .visit_block_node = walk_block_node,
     .visit_bare_declaration_node = walk_bare_declaration_node,
     .visit_function_header_node = walk_function_header_node,
+    .visit_pragma_node = walk_pragma_node,
 };
 
 // fills in the visit table with default walk functions
@@ -964,6 +976,38 @@ printer_visit_function_header(struct Visit* visit, struct Function_Header_Node*
     }
 }
 
+void
+printer_visit_pragma_node(struct Visit* visit, struct Pragma_Node* node)
+{
+    DATA_FOR_VISIT(struct Tree_Printer, printer);
+
+    const ascii* pragma_name = pragma_type_to_string(node->type);
+
+    fprintf(printer->output, "(pragma %s", pragma_name);
+    for (uint ai = 0; ai < node->argument_count; ++ai) {
+        struct Pragma_Argument* arg = &node->arguments[ai];
+        switch (arg->type) {
+        case PRAGMA_ARGUMENT_NUMBER:
+            fprintf(printer->output, " (number %ld)", arg->value.number);
+            break;
+        case PRAGMA_ARGUMENT_DECIMAL:
+            fprintf(printer->output, " (decimal %lf)", arg->value.decimal);
+            break;
+        case PRAGMA_ARGUMENT_NAME_OR_STRING:
+            fprintf(printer->output, " (name/string '%s')", arg->value.name_or_string.data);
+            break;
+        default:
+            failure("unexpected pragma argument type in `printer_visit_pragma_node`");
+        }
+    }
+    fprintf(printer->output, ")");
+
+    if (node->next) {
+        fprintf(printer->output, " ");
+        VISIT(visit_pragma_node, node->next);
+    }
+}
+
 struct Visit_Table printer_visit_functions = {
     .visit_tree = printer_visit_tree,
 
@@ -1006,6 +1050,7 @@ struct Visit_Table printer_visit_functions = {
     .visit_block_node = printer_visit_block_node,
     .visit_bare_declaration_node = printer_visit_bare_declaration_node,
     .visit_function_header_node = printer_visit_function_header,
+    .visit_pragma_node = printer_visit_pragma_node,
 };
 
 void