Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor RxUnitTest to be more data-driven
- Loading branch information
Showing
1 changed file
with
85 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,39 +1,98 @@ | ||
using Niecza; | ||
using System; | ||
using System.Collections.Generic; | ||
|
||
class CodeBuf { | ||
public delegate Frame D(Frame th); | ||
|
||
public List<D> ops = new List<D>(); | ||
public List<int> labels = new List<int>(); | ||
|
||
public int NewLabel() { labels.Add(0); return labels.Count - 1; } | ||
} | ||
|
||
abstract class RxOp { | ||
public abstract void Compile(CodeBuf cb); | ||
} | ||
|
||
class RxExact: RxOp { | ||
string s; | ||
public RxExact(string s) { this.s = s; } | ||
public override void Compile(CodeBuf cb) { | ||
cb.ops.Add(delegate(Frame th) { | ||
return th.rx.Exact(th, s); | ||
}); | ||
} | ||
} | ||
|
||
class RxStar: RxOp { | ||
RxOp inner; | ||
public RxStar(RxOp inner) { this.inner = inner; } | ||
public override void Compile(CodeBuf cb) { | ||
int l1 = cb.NewLabel(); | ||
int l2 = cb.NewLabel(); | ||
cb.ops.Add(delegate(Frame th) { | ||
th.rx.OpenQuant(); | ||
return th; | ||
}); | ||
cb.labels[l1] = cb.ops.Count; | ||
cb.ops.Add(delegate(Frame th) { | ||
th.rx.PushBacktrack("*", cb.labels[l2]); | ||
return th; | ||
}); | ||
inner.Compile(cb); | ||
cb.ops.Add(delegate(Frame th) { | ||
th.ip = cb.labels[l1]; | ||
return th; | ||
}); | ||
cb.labels[l2] = cb.ops.Count; | ||
cb.ops.Add(delegate(Frame th) { | ||
th.rx.CloseQuant(); | ||
return th; | ||
}); | ||
} | ||
} | ||
|
||
class RxSeq: RxOp { | ||
RxOp[] z; | ||
public RxSeq(RxOp[] z) { this.z = z; } | ||
public override void Compile(CodeBuf cb) { | ||
foreach (RxOp ze in z) | ||
ze.Compile(cb); | ||
} | ||
} | ||
|
||
public class RxUnitTest { | ||
private static SubInfo TestSI = new SubInfo(TestC); | ||
private static bool ok; | ||
private static Frame TestC(Frame th) { | ||
if (Kernel.TraceCont) Console.WriteLine("At {0}", th.ip); | ||
switch (th.ip) { | ||
case 0: | ||
th.rx = new RxFrame(Kernel.MockBox(new Cursor("aaaaab"))); | ||
th.rx.OpenQuant(); | ||
goto case 1; | ||
case 1: | ||
th.rx.PushBacktrack("*", 3); | ||
th.ip = 2; | ||
return th.rx.ExactOne(th, 'a'); | ||
case 2: | ||
th.rx.IncQuant(); | ||
goto case 1; | ||
case 3: | ||
th.rx.CloseQuant(); | ||
th.ip = 4; | ||
return th.rx.Exact(th, "ab"); | ||
case 4: | ||
System.Console.WriteLine("Match!"); | ||
return null; | ||
default: | ||
System.Console.WriteLine("Bad IP"); | ||
return null; | ||
CodeBuf cb = (CodeBuf) th.lex0; | ||
if (th.ip == cb.ops.Count) { | ||
ok = true; | ||
return null; | ||
} | ||
CodeBuf.D d = cb.ops[th.ip++]; | ||
return d(th); | ||
} | ||
|
||
public static void Main() { | ||
Frame fr = new Frame(null, null, TestSI); | ||
private static void RunTest(int ix, bool y, string s, RxOp ot) { | ||
CodeBuf cb = new CodeBuf(); | ||
ot.Compile(cb); | ||
|
||
Frame th = new Frame(null, null, TestSI); | ||
th.rx = new RxFrame(Kernel.MockBox(new Cursor(s))); | ||
th.lex0 = cb; | ||
|
||
while (fr != null) | ||
fr = fr.Continue(); | ||
ok = false; | ||
while (th != null) | ||
th = th.Continue(); | ||
|
||
Console.WriteLine((ok == y) ? "ok {0}" : "not ok {0}", ix); | ||
} | ||
|
||
|
||
public static void Main() { | ||
RunTest(0, true, "aaaaab", new RxSeq(new RxOp[] { new RxStar( new RxExact("a") ), new RxExact("ab") })); | ||
} | ||
} |