summaryrefslogtreecommitdiff
path: root/appl/lib/sh9parser.b
diff options
context:
space:
mode:
authorKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-13 14:45:13 +0300
committerKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-13 14:45:13 +0300
commita104f80e61f7e6a110a209cf7cc5ffd09d6b5b4f (patch)
treeb5282c35b4e50a1cd0e08f54c8de35d64ae9bd1c /appl/lib/sh9parser.b
parent70c48bade8529b4b5f762754db96982c8c95c31a (diff)
Add variable substitution
Diffstat (limited to 'appl/lib/sh9parser.b')
-rw-r--r--appl/lib/sh9parser.b94
1 files changed, 87 insertions, 7 deletions
diff --git a/appl/lib/sh9parser.b b/appl/lib/sh9parser.b
index 8df4cfc..54c26b5 100644
--- a/appl/lib/sh9parser.b
+++ b/appl/lib/sh9parser.b
@@ -26,13 +26,87 @@ GrammarNode.print_expr(gn: self ref GrammarNode)
}
}
+ShModule.find_var(m: self ref ShModule, name: string): ref ModVar
+{
+ l:= len m.vars;
+ vars := m.vars;
+ for (i:=0; i<l; i++) {
+ v := hd vars;
+ if (v.name == name) {
+ return v;
+ }
+ vars = tl vars;
+ }
+ return nil;
+}
+
+ShModule.print_vars(m: self ref ShModule)
+{
+ l:= len m.vars;
+ vars := m.vars;
+ for (i:=0; i<l; i++) {
+ v := hd vars;
+ sys->print("%s: %s\n", v.name, v.val);
+ vars = tl vars;
+ }
+}
+
+ShModule.set_var(m: self ref ShModule, v: ref ModVar)
+{
+ m.vars = v :: m.vars;
+}
+
ParserCtx.add_module(ctx: self ref ParserCtx, name: string)
{
m:= ref ShModule;
m.name = name;
+ if (ctx.current_module == nil) {
+ sys->print("Set current module %s\n", name);
+ ctx.current_module = name;
+ }
ctx.modules = m :: ctx.modules;
}
+ParserCtx.find_module(ctx: self ref ParserCtx, name: string): ref ShModule
+{
+ l:= len ctx.modules;
+ mods := ctx.modules;
+ for (i:=0; i<l; i++) {
+ m := hd mods;
+ if (m.name == name) {
+ return m;
+ }
+ mods = tl mods;
+ }
+ return nil;
+}
+
+ParserCtx.find_var_in_current_module(ctx: self ref ParserCtx, name: string): ref ModVar
+{
+ m := ctx.find_module(ctx.current_module);
+ if (m == nil) {
+ return nil;
+ }
+ return m.find_var(name);
+}
+
+ParserCtx.print_all_vars(ctx: self ref ParserCtx)
+{
+ l:= len ctx.modules;
+ mods := ctx.modules;
+ for (i:=0; i<l; i++) {
+ m := hd mods;
+ m.print_vars();
+ mods = tl mods;
+ }
+}
+
+ParserCtx.get_current_module(ctx: self ref ParserCtx): ref ShModule
+{
+ m := ctx.find_module(ctx.current_module);
+ return m;
+}
+
init()
{
sys = load Sys Sys->PATH;
@@ -127,24 +201,30 @@ parse_toks(toks: array of ref TokNode, g: array of ref GrammarNode): array of re
do
{
lt := len toks;
- #sys->print("Loop %d: ", ctr);
- #print_toks_short(toks);
+ sys->print("Loop %d: ", ctr);
+ print_toks_short(toks);
ctr ++;
changed = 0;
- fast: for (i := 0; i <= lt; i ++) {
+ fast: for (i := 0; i < lt; i ++) {
for (j := 0; j < lgns; j++) {
gj:= g[j];
- if (check_grammar_node_match(toks[lt - i:], gj) == 1) {
+ if (check_grammar_node_match(toks[i:], gj) == 1) {
#sys->print("Something matched !\n");
#gj.print_expr();
#sys->print("Before replace: ");
#print_toks_short(toks);
- gj.callback(gj.ctx, toks[lt-i: lt-i+len gj.expr]);
+ if ((i+len gj.expr) > lt) {
+ continue;
+ }
+ #sys->print("len toks: %d, i: %d, len gj.expr: %d\n", len toks, i, len gj.expr);
+ result := gj.callback(gj.ctx, toks[i:i+len gj.expr]);
if (gj.transform == S_NONE) {
- toks = replace_toks(toks, lt-i, len gj.expr, array[0] of ref TokNode);
+ toks = replace_toks(toks, i, len gj.expr, array[0] of ref TokNode);
+ } else if (gj.transform == nil) {
+ toks = replace_toks(toks, i, len gj.expr, result);
} else {
- toks = replace_toks(toks, lt-i, len gj.expr, array[] of {mk_tok(toks[lt - i].start, toks[lt - i].line, "", gj.transform)});
+ toks = replace_toks(toks, i, len gj.expr, array[] of {mk_tok(toks[i].start, toks[i].line, "", gj.transform)});
}
#sys->print("After replace: ");
changed = 1;