diff options
| author | Mel <mel@rnrd.eu> | 2025-07-01 03:04:07 +0200 |
|---|---|---|
| committer | Mel <mel@rnrd.eu> | 2025-07-01 03:04:07 +0200 |
| commit | 8e0beabeb4efa50a3072ef805682c0f42b6c16a8 (patch) | |
| tree | cd6b82d1741cdd52aadddae87c59e0617fb74ffd /boot/tree.c | |
| parent | e51799842aa367692152717a8db7c519dbc66c1f (diff) | |
| download | catskill-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/tree.c')
| -rw-r--r-- | boot/tree.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/boot/tree.c b/boot/tree.c index ea8ed69..dc22bfd 100644 --- a/boot/tree.c +++ b/boot/tree.c @@ -572,6 +572,104 @@ type_node_is_none(const struct Type_Node* type_node) return type_node->type == TYPE_NODE_NONE; } +enum Pragma_Type +{ + PRAGMA_NONE, + PRAGMA_UNKNOWN, + PRAGMA_C_HEADER, + // TODO: further pragma types. + + // NOTE: there would be plenty of use for user-defined pragmas, + // acting similar to attributes in other languages or #[derive] macros + // in Rust. for now we only support out hard-coded pragmas, + // but it's something to definitely consider in the future. +}; + +#define PRAGMA_ARGUMENT_MAX 3 + +struct Pragma_Argument +{ + enum Pragma_Argument_Type + { + PRAGMA_ARGUMENT_NONE, + PRAGMA_ARGUMENT_NAME_OR_STRING, + PRAGMA_ARGUMENT_NUMBER, + PRAGMA_ARGUMENT_DECIMAL, + } type; + + union Pragma_Argument_Value + { + struct String name_or_string; + int64 number; + float64 decimal; + } value; +}; + +// a "pragma" is what we call compiler hints used for giving almost every piece of information +// the compiler might require to compile your code. +// you can recognize a pragma by the '|' token, like in '| c_header "stdio.h"'. +// their use ranges from setting alignment/padding for structures, defining default copy or move +// 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 +{ + enum Pragma_Type type; + struct Pragma_Argument arguments[PRAGMA_ARGUMENT_MAX]; + uint argument_count; + + struct Span span; + struct Cursor location; + + struct Pragma_Node* next; // further pragmas on the same line. +}; + +REGION(struct Pragma_Node, pragma_node) + +struct Pragma_Node* +pragma_node_new(enum 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 = ®ion_pragma_node[region_pragma_node_cursor++]; + *pragma = (struct Pragma_Node){ + .type = type, + .arguments = {}, + .argument_count = 0, + .span = span, + .location = location, + .next = nil, + }; + return pragma; +} + +enum Pragma_Type +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; + default: + return PRAGMA_UNKNOWN; + } +} + +const ascii* +pragma_type_to_string(enum Pragma_Type type) +{ + switch (type) { + case PRAGMA_C_HEADER: + return "c_header"; + case PRAGMA_UNKNOWN: + return "unknown"; + default: + failure("unexpected pragma type passed to `pragma_type_to_string`"); + return nil; + } +} + enum Expression_Kind { EXPRESSION_NONE, @@ -742,6 +840,8 @@ enum Statement_Kind STATEMENT_BREAK, STATEMENT_CONTINUE, STATEMENT_DEFER, + + STATEMENT_PRAGMA, }; struct Statement_Value_Expression @@ -828,6 +928,11 @@ struct Statement_Value_Defer struct Block_Node block; }; +struct Statement_Value_Pragma +{ + struct Pragma_Node* inner; +}; + union Statement_Value { struct Statement_Value_Expression expression; @@ -837,6 +942,7 @@ union Statement_Value struct Statement_Value_Loop loop; struct Statement_Value_Return return_value; struct Statement_Value_Defer defer; + struct Statement_Value_Pragma pragma; }; struct Statement |
