Logo

index : blog

---

  • summary
  • about
  • tree
  • log
  • branches
<< path: root/public/blog.git/html/modules/uniform/walk.jai blob: 6198b8ea89dc24b345bc86736f311f1fbe95e8b4 [raw] [clear marker]

        
0#scope_module
1
2Walk_State :: struct (T: Type) {
3 re: *Regexp_Node;
4 n := -1;
5 parent_arg: T;
6 pre_arg: T;
7 child_args: [..] T;
8}
9
10walk_state :: (re: *Regexp_Node, parent_arg: $T) -> Walk_State(T) {
11 s: Walk_State(T);
12 s.re = re;
13 s.parent_arg = parent_arg;
14 s.child_args.allocator = temp;
15 return s;
16}
17
18Walk :: struct (C: Type, T: Type) {
19 pre_visit := no_pre;
20 post_visit := no_post;
21 short_visit := no_short;
22 copy := no_copy;
23 max_visits := 1000000;
24
25 //ToDo: Use [] T as child_args
26 no_post :: (ctx: C, re: *Regexp_Node, parent_arg: T, pre_arg: T, child_args: [..] T) -> T {
27 return parent_arg;
28 }
29
30 no_pre :: (ctx: C, re: *Regexp_Node, parent_arg: T) -> T, bool {
31 return parent_arg, false;
32 }
33
34 no_short :: (ctx: C, re: *Regexp_Node, parent_arg: T) -> T {
35 return parent_arg;
36 }
37
38 no_copy :: (ctx: C, arg: T) -> T {
39 return arg;
40 }
41}
42
43walk :: (ctx: C, re: *Regexp_Node, initial_value: T, w: Walk($C, $T)) -> T, stopped_early: bool {
44 do_visit :: (ctx: C, stack: *[..] Walk_State(T), w: *Walk(C, T)) -> T, stopped_early: bool, done: bool {
45 s := *(stack.*)[stack.count - 1];
46 if s.n == -1 {
47 w.max_visits -= 1;
48 if (w.max_visits < 0) {
49 return w.short_visit(ctx, s.re, s.parent_arg), true, true;
50 }
51
52 stop: bool;
53 s.pre_arg, stop = w.pre_visit(ctx, s.re, s.parent_arg);
54 if (stop) {
55 return s.pre_arg, false, true;
56 }
57
58 array_resize(*s.child_args, s.re.subs.count, false);
59 s.n = 0;
60 }
61
62 if (s.re.subs.count > 0) {
63 if (s.n < s.re.subs.count) {
64 if (w.copy && s.n > 0 && s.re.subs[s.n - 1] == s.re.subs[s.n]) {
65 s.child_args[s.n] = w.copy(ctx, s.child_args[s.n - 1]);
66 s.n += 1;
67 } else {
68 array_add(stack, walk_state(s.re.subs[s.n], s.pre_arg));
69 }
70 t: T;
71 return t, false, false;
72 }
73 }
74
75 return w.post_visit(ctx, s.re, s.parent_arg, s.pre_arg, s.child_args), false, true;
76 }
77 assert(re != null, "Missing regexp");
78
79 stack: [..] Walk_State(T);
80 stack.allocator = temp;
81 array_add(*stack, walk_state(re, initial_value));
82 stopped_early := false;
83
84 while true {
85 t, early, done := do_visit(ctx, *stack, *w);
86 if early {
87 stopped_early = true;
88 }
89
90 if done {
91 // We've finished stack.top().
92 // Update next guy down.
93 pop(*stack);
94 if !stack.count return t, stopped_early;
95 s := *stack[stack.count - 1];
96 if s.child_args.count {
97 s.child_args[s.n] = t;
98 }
99 s.n += 1;
100 }
101 }
102
103 // This will never be reached, but Jai complains otherwise
104 // @Cleanup: remove this once Jai is fixed
105 t: T;
106 return t, true;
107}
108
109
Copyright 2026  E766CB298A6D1E64 | Git-Thing heavily inspired by cgit