From bea180fe4c71ea66a5f0f0b179d912289ee41343 Mon Sep 17 00:00:00 2001 From: Stefan O'Rear Date: Sun, 24 Jun 2012 15:15:58 -0700 Subject: [PATCH] Wire compiler actions to the grammar engine This wiring takes place at a lower level than just creating a p6-level actions class. This might count as premature optimization. --- lib/Actions.cs | 51 +++++++++++++++++++++++++++++++++++++++++++++++++- lib/CompMgr.cs | 8 ++++++++ lib/Cursor.cs | 8 +++++++- 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/lib/Actions.cs b/lib/Actions.cs index 8a00fdd7..99a24393 100644 --- a/lib/Actions.cs +++ b/lib/Actions.cs @@ -8,8 +8,57 @@ namespace Niecza.Compiler { class Actions { internal CompJob job; + RxOp.RxOp rnoop = new RxOp.Sequence(new RxOp.RxOp[0]); - public Actions(CompJob job) { this.job = job; } + + Dictionary> acts; + + public Actions(CompJob job) { + this.job = job; + acts = new Dictionary>(); + + Type tt = typeof(Actions); + foreach (var m in tt.GetMethods()) { + if (m.DeclaringType != tt || !m.IsPublic) + continue; + acts[m.Name] = (Action) Delegate.CreateDelegate( + typeof(Action), this, m); + } + } + + internal void CallAction(Frame th, string name, Cursor m) { + Action act; + string cooked_name = name; + int ix = name.IndexOf(':'); + if (ix >= 0) { + var sb = new StringBuilder(); + sb.Append(name.Substring(0,ix)); + int lix = name.Length; + if (lix - ix >= 6 && name.Substring(ix+1,3) == "sym") { + lix --; ix += 5; // :sym< + } + sb.Append("__"); + for (int i = ix; i < lix; i++) { + char c = name[i]; + if (c == '_' || (c >= '0' && c <= '9') || + (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { + sb.Append(c); + } else { + sb.AppendFormat("{0:x2}", (int)c); + } + } + cooked_name = sb.ToString(); + } + acts.TryGetValue(cooked_name, out act); + if (Cursor.Trace) + Console.WriteLine("Call action {0} - {1}", cooked_name, + act != null ? "found" : "not found"); + if (act != null) { + job.topframe = th; + job.curlex = Kernel.UnboxAny(job.context("$*CURLEX").Fetch()); + act(m); + } + } // Little things to make writing wads of data-extraction code nicer... string asstr(Variable v) { return v.Fetch().mo.mro_raw_Str.Get(v); } diff --git a/lib/CompMgr.cs b/lib/CompMgr.cs index c2c7b680..dc6271f7 100644 --- a/lib/CompMgr.cs +++ b/lib/CompMgr.cs @@ -73,7 +73,11 @@ public struct RxInfo { // state vars public RuntimeUnit unit; // $*unit + + // this one is used SO MUCH it gets to stay :> public SubInfo curlex; // $*CURLEX + public Frame topframe; + public RxInfo rxinfo; // %*RX public Actions actions; // $*ACTIONS public string in_decl; // $*IN_DECL @@ -88,6 +92,10 @@ public struct RxInfo { public bool monkey_typing; public bool catchy; + public Variable context(string name) { + return Kernel.ContextHelper(topframe, name, 0); + } + public Variable get_memo(int pos, string key) { throw new NotImplementedException(); } //SSTO public Dictionary proto_endsym = diff --git a/lib/Cursor.cs b/lib/Cursor.cs index a9851e2c..687d5772 100644 --- a/lib/Cursor.cs +++ b/lib/Cursor.cs @@ -12,9 +12,15 @@ public sealed class GState { public int highwater; public Variable actions; + internal Niecza.Compiler.Actions comp; internal Frame CallAction(Frame th, string name, Cursor match) { - if (actions == null || name == "" || name == null) + if (name == "" || name == null) + return th; + + if (comp != null) + comp.CallAction(th, name, match); + if (actions == null) return th; if (Cursor.Trace) Console.WriteLine("To call action {0}", name);