public void CallbackReturn() { var thread = new Thread(); var globals = new Table(); var func = Helpers.LoadFunc("Thread/CallbackReturn.lua", globals); int numCallbacks = 0; globals[new LString("callback")] = (Callable)(l => { Assert.AreEqual(3, l.StackTop); for (int i = 1; i <= 3; i++) { l.Push(l[i].ToDouble() + i); } numCallbacks++; return(3); }); thread.Call(func, 0, 3); Assert.AreEqual(2, numCallbacks); Assert.AreEqual(42, thread[1]); Assert.AreEqual(54, thread[2]); Assert.AreEqual(66, thread[3]); }
private static void RunTestScriptWithGlobals(string script, Table globals, params Value[] expectedResults) { Libs.BaseLib.SetBaseMethods(globals); Libs.MathLib.SetMathMethods(globals); Libs.TableLib.SetTableMethods(globals); Libs.StringLib.SetStringMethods(globals); globals["print"] = (Callable)(l => 0); globals["assert"] = (Callable)(l => { if (!l[1].ToBool()) { Assert.Fail(); } return(0); }); var thread = new Thread(); var func = Helpers.LoadFunc("lua-core/" + script, globals); Function.Optimize(func); thread.Call(func, 0, Thread.CallReturnAll); Assert.AreEqual(expectedResults.Length, thread.StackTop); for (int i = 0; i < expectedResults.Length; i++) { Assert.AreEqual(expectedResults[i], thread[i + 1]); } }
public void TwoSimpleCalls() { var thread = new Thread(); var func = Helpers.LoadFunc("Thread/Call.lua", new Table()); thread.Call(func, 0, 1); Assert.AreEqual(1, thread.StackTop); Assert.AreEqual(42, thread[1]); thread.Pop(); Assert.AreEqual(0, thread.StackTop); thread.Call(func, 0, 1); Assert.AreEqual(1, thread.StackTop); Assert.AreEqual(42, thread[1]); }
public void Callback2() { var thread = new Thread(); var globals = new Table(); var func = Helpers.LoadFunc("Thread/Callback.lua", globals); var fn = new CallbackFunc(); globals[new LString("callback")] = (Callable)fn; thread.Call(func, 0, 0); Assert.AreEqual(1, fn.RunCount); }
private static void RunTestScriptWithGlobals(string script, Table globals, params Value[] expectedResults) { globals["assertEqual"] = (Callable)(l => { Assert.AreEqual(l[1], l[2]); return(0); }); var thread = new Thread(); var func = Helpers.LoadFunc("Thread/" + script, globals); Function.Optimize(func); thread.Call(func, 0, Thread.CallReturnAll); Assert.AreEqual(expectedResults.Length, thread.StackTop); for (int i = 0; i < expectedResults.Length; i++) { Assert.AreEqual(expectedResults[i], thread[i + 1]); } }
private static void RunTestScriptWithGlobals(string script, Table globals, params Value[] expectedResults) { var thread = new Thread(); Libs.BaseLib.SetBaseMethods(globals); Libs.TableLib.SetTableMethods(globals); var func = Helpers.LoadFunc("Libs/" + script, globals); Function.Optimize(func); thread.Call(func, 0, Thread.CallReturnAll); Assert.AreEqual(expectedResults.Length, thread.StackTop); for (int i = 0; i < expectedResults.Length; i++) { Assert.AreEqual(expectedResults[i], thread[i + 1]); } }
private static int BIPairs(Thread l) { var val = l[1]; var mt = GetMetatableImp(val); Value mmt; if (mt != null && mt.TryGetValue(Literals.TagMethod_IPairs, out mmt)) { l.StackTop = 1; l.Call((Callable)mmt, 1, 3); return(3); } else { return(l.SetReturnValues(INext, val, 0)); } }
private static int BPairs(Thread l) { var val = l[1]; var mt = GetMetatableImp(val); Value mmt; if (mt != null && mt.TryGetValue(Literals.TagMethod_Pairs, out mmt)) { l.StackTop = 1; l.Call((Callable)mmt, 1, 3); } else { l.SetStack((Callable) new StableNext(), val, Value.Nil); } return(3); }
public void Callback1() { var thread = new Thread(); var globals = new Table(); var func = Helpers.LoadFunc("Thread/Callback.lua", globals); int numCallbacks = 0; globals[new LString("callback")] = (Callable)(l => { Assert.AreEqual(1, l.StackTop); Assert.AreEqual(42, l[1]); numCallbacks++; return(0); }); thread.Call(func, 0, 0); Assert.AreEqual(1, numCallbacks); }
private static int SGsub(Thread l) { var str = (LString)l[1]; var pat = (LString)l[2]; var subst = l[3]; var subTy = subst.ValueType; switch (subTy) { case LValueType.Number: l.ConvertToString(ref subst); break; case LValueType.String: case LValueType.Function: case LValueType.Table: break; default: throw new ArgumentException("string/function/table expected"); } var max = l.StackTop >= 4 ? (int)l[4] : int.MaxValue; MatchState ms; InitMatchState(out ms, l); ms.Str = str.InternalData; ms.StrInit = LString.BufferDataOffset; ms.Pat = pat.InternalData; int patInit = LString.BufferDataOffset; bool anchor = patInit < ms.Pat.Length && ms.Pat[patInit] == (byte)'^'; if (anchor) { patInit++; } var strBuilder = l.GetStrBuilder(str.Length * 2); int sPos = LString.BufferDataOffset; int n = 0; while (n < max) { ms.Level = 0; Debug.Assert(ms.MatchDepth == MaxCCalls); var e = SMatch(ref ms, sPos, patInit); if (e != -1) { n++; Value substVal; switch (subTy) { case LValueType.Function: { l.Push(subst); var nCap = PushCaptures(ref ms, sPos, e, false); l.Call(nCap, 1); substVal = l.PopValue(); } break; case LValueType.Table: PushCapture(ref ms, 0, sPos, e); substVal = l.GetTable((Table)subst, l.PopValue()); break; case LValueType.Number: //it's already been made a string substVal = subst; break; case LValueType.String: //need to handle escape sequences { var sb = (byte[])subst.RefVal; for (int i = LString.BufferDataOffset; i < sb.Length; i++) { var ch = sb[i]; if (ch != (byte)'%') { strBuilder.Append(ch); continue; } if (++i == sb.Length) { throw new ArgumentException("Invalid use of % in replacement string"); } ch = sb[i]; if (ch == (byte)'%') { strBuilder.Append(ch); continue; } switch (ch) { case (byte)'0': strBuilder.Append(ms.Str, sPos, e - sPos); break; case (byte)'1': case (byte)'2': case (byte)'3': case (byte)'4': case (byte)'5': case (byte)'6': case (byte)'7': case (byte)'8': case (byte)'9': { int idx = ch - (byte)'1'; PushCapture(ref ms, idx, sPos, e); substVal = l.PopValue(); l.ConvertToString(ref substVal); strBuilder.Append((LString)substVal); } break; default: throw new ArgumentException("Invalid use o f% in replacement string"); } } } substVal = new Value(); //hush, little compiler break; default: substVal = new Value(); break; } if (subTy != LValueType.String) { //strings already appended, need to handle this case now if (!substVal.ToBool()) { strBuilder.Append(ms.Str, sPos, e - sPos); } else { l.ConvertToString(ref substVal); strBuilder.Append((LString)substVal); } } } if (e != -1 && e > sPos) { sPos = e; } else if (sPos < ms.Str.Length) { strBuilder.Append(ms.Str[sPos++]); } else { break; } if (anchor) { break; } } strBuilder.Append(ms.Str, sPos, ms.Str.Length - sPos); var ret = strBuilder.ToLString(); l.RetireStrBuilder(strBuilder); RetireMatchState(ref ms); return(l.SetReturnValues(ret, n)); }