}
static inline b32 node_is_type(AstNode* node) {
+ if (node->kind == Ast_Kind_Alias) return node_is_type((AstNode *) ((AstAlias *) node)->alias);
+
return (node->kind > Ast_Kind_Type_Start) && (node->kind < Ast_Kind_Type_End);
}
}
@Bug // Why is '#type' needed here?
-Font_Index :: #type i32;
+Font_Index :: i32;
#private font_registry : map.Map(Font_Index, Font);
register_font :: (index: Font_Index, font: Font) {
break;
}
- /*
- This is in theory where the static if in procedures will be parsed. However,
- this breaks many things because static if statements currently only parse top
- level expressions in them, not general statements.
- */
-
if (next_tokens_are(parser, 2, '#', Token_Type_Keyword_If)) {
AstIf* static_if = parse_static_if_stmt(parser, 1);
ENTITY_SUBMIT(static_if);
retval = (AstNode *) static_if;
break;
}
+
+ if (parse_possible_directive(parser, "persist")) {
+ // :Duplicated from parse_top_level_statement
+ AstMemRes* memres = make_node(AstMemRes, Ast_Kind_Memres);
+ memres->token = expect_token(parser, Token_Type_Symbol);
+ expect_token(parser, ':');
+
+ if (parser->curr->type != '=')
+ memres->type_node = parse_type(parser);
+
+ if (consume_token_if_next(parser, '='))
+ memres->initial_value = parse_expression(parser, 1);
+
+
+ ENTITY_SUBMIT(memres);
+
+ AstBinding* binding = make_node(AstBinding, Ast_Kind_Binding);
+ binding->token = memres->token;
+ binding->node = (AstNode *) memres;
+ ENTITY_SUBMIT(binding);
+ break;
+ }
}
default:
--- /dev/null
+200
+
+1 2 3 4 5 6 7 8 9 55
+10
+11 12 13 14 15 16 17 18 19 20
+21 22 23 24 25 26 27 28 29 30
+31 32 33 34 35 36 37 38 39 40
+41 42 43 44 45 46 47 48 49 50
+51 52 53 54 55 56 57 58 59 60
+61 62 63 64 65 66 67 68 69 70
+71 72 73 74 75 76 77 78 79 23416728348467685
--- /dev/null
+// This test does not make a whole ton of sense, but it does thoroughly test the #persist local capability.
+
+#load "core/std"
+
+use package core
+
+
+main :: (args: [] cstr) {
+
+ foo(10);
+ foo(30);
+ foo(60);
+ result := foo(100);
+ println(result);
+
+ cached_fib(10) |> println();
+ cached_fib(80) |> println();
+
+}
+
+foo :: (x: i32) -> i32 {
+ #persist total := 0;
+
+ total += x;
+ return total;
+}
+
+
+cached_fib :: (n: u64) -> u64 {
+ #persist cache : map.Map(u64, u64);
+ if cache.hashes.data == null {
+ map.init(^cache, hash_count=128);
+ }
+
+ if n <= 1 do return n;
+
+ if map.has(^cache, n) do return map.get(^cache, n);
+
+ res := cached_fib(n - 1) + cached_fib(n - 2);
+ map.put(^cache, n, res);
+
+ print_cache_size();
+
+ return res;
+
+ // This can see cache because it is statically lexically scoped.
+ print_cache_size :: () {
+ #persist a := 0;
+ if a % 10 == 0 {
+ print("\n");
+ a = 0;
+ }
+ a += 1;
+
+ printf("{} ", cache.entries.count);
+ }
+}
\ No newline at end of file