/// <summary> /// .NETメソッドをトップレベルに登録します。 /// </summary> /// <param name="func">登録する<see cref="KecaknoahInteropDelegate"/>形式のメソッド</param> /// <param name="name">メソッド名</param> public void RegisterFunction(KecaknoahInteropDelegate func, string name) { var fo = new KecaknoahInteropMethodInfo(name, func); topMethods.Add(fo); methodReferences.Add(KecaknoahReference.CreateRightReference(null, func)); }
private KecaknoahReference GetReference(string name) { KecaknoahReference result; if (Locals.ContainsKey(name)) return Locals[name]; if ((result = RunningContext.Module.GetReference(name)) != KecaknoahNil.Reference) return result; result = new KecaknoahReference { IsLeftValue = true }; locals[name] = result; return result; }
/// <summary> /// .NETメソッドをトップレベルに登録します。 /// </summary> /// <param name="func">登録する<see cref="Func{T1, T2, TResult}"/>形式のメソッド</param> /// <param name="name">メソッド名</param> public void RegisterFunction(Func <KecaknoahObject, KecaknoahObject[], string> func, string name) { KecaknoahInteropDelegate wp = (ctx, self, args) => func(self, args).AsKecaknoahString().NoResume(); var fo = new KecaknoahInteropMethodInfo(name, wp); topMethods.Add(fo); methodReferences.Add(KecaknoahReference.CreateRightReference(null, wp)); }
/// <summary> /// .NETメソッドをトップレベルに登録します。 /// </summary> /// <param name="func">登録する<see cref="Func{T1, T2, TResult}"/>形式のメソッド</param> /// <param name="name">メソッド名</param> public void RegisterBooleanFunction(Func <KecaknoahObject, KecaknoahObject[], bool> func, string name) { KecaknoahInteropDelegate wp = (ctx, self, args) => func(self, args).AsKecaknoahBoolean().NoResume(); var fo = new KecaknoahInteropMethodInfo(name, wp); topMethods.Add(fo); methodReferences.Add(KecaknoahReference.Right(KecaknoahNil.Instance, wp)); }
/// <summary> /// .NETメソッドをトップレベルに登録します。 /// </summary> /// <param name="func">登録する<see cref="Func{T1, T2, TResult}"/>形式のメソッド</param> /// <param name="name">メソッド名</param> public void RegisterSingleFunction(Func <KecaknoahObject, KecaknoahObject[], float> func, string name) { KecaknoahInteropDelegate wp = (ctx, self, args) => ((double)func(self, args)).AsKecaknoahFloat().NoResume(); var fo = new KecaknoahInteropMethodInfo(name, wp); topMethods.Add(fo); methodReferences.Add(KecaknoahReference.Right(KecaknoahNil.Instance, wp)); }
/// <summary> /// プリコンパイルしたソースコードを登録します。 /// </summary> /// <param name="src">登録する<see cref="KecaknoahSource"/></param> public void RegisterSource(KecaknoahSource src) { foreach (var c in src.Classes) { classes.Add(c); classReferences.Add(KecaknoahReference.CreateRightReference(new KecaknoahScriptClassObject(c))); } foreach (var m in src.TopLevelMethods) { topMethods.Add(m); methodReferences.Add(KecaknoahReference.CreateRightReference(new KecaknoahScriptFunction(KecaknoahNil.Instance, m))); } }
private KecaknoahReference GetReference(string name) { KecaknoahReference result; if (Locals.ContainsKey(name)) { return(Locals[name]); } if ((result = RunningContext.Module.GetReference(name)) != KecaknoahNil.Reference) { return(result); } result = new KecaknoahReference { IsLeftValue = true }; locals[name] = result; return(result); }
/// <summary> /// 現在の状態で、現在のコードの実行を再開します。 /// </summary> /// <returns></returns> public bool Resume() { KecaknoahObject v1, v2; KecaknoahReference rfr; Stack <KecaknoahObject> args; while (ProgramCounter < Codes.Count) { var c = Codes[ProgramCounter]; switch (c.Type) { //基本-------------------------------------------------------------------- case KecaknoahILCodeType.Nop: break; case KecaknoahILCodeType.Label: break; case KecaknoahILCodeType.PushInteger: ReferenceStack.Push(KecaknoahReference.Right(c.IntegerValue)); break; case KecaknoahILCodeType.PushString: ReferenceStack.Push(KecaknoahReference.Right(c.StringValue)); break; case KecaknoahILCodeType.PushDouble: ReferenceStack.Push(KecaknoahReference.Right(c.FloatValue)); break; case KecaknoahILCodeType.PushBoolean: ReferenceStack.Push(KecaknoahReference.Right(c.BooleanValue)); break; case KecaknoahILCodeType.PushNil: ReferenceStack.Push(KecaknoahNil.Reference); break; case KecaknoahILCodeType.Pop: ReferenceStack.Pop(); break; //二項演算子-------------------------------------------------------------- case KecaknoahILCodeType.Plus: case KecaknoahILCodeType.Minus: case KecaknoahILCodeType.Multiply: case KecaknoahILCodeType.Divide: case KecaknoahILCodeType.Modular: case KecaknoahILCodeType.And: case KecaknoahILCodeType.Or: case KecaknoahILCodeType.Xor: case KecaknoahILCodeType.AndAlso: case KecaknoahILCodeType.OrElse: case KecaknoahILCodeType.LeftBitShift: case KecaknoahILCodeType.RightBitShift: case KecaknoahILCodeType.Equal: case KecaknoahILCodeType.NotEqual: case KecaknoahILCodeType.Greater: case KecaknoahILCodeType.Lesser: case KecaknoahILCodeType.GreaterEqual: case KecaknoahILCodeType.LesserEqual: v2 = ReferenceStack.Pop().RawObject; v1 = ReferenceStack.Pop().RawObject; ReferenceStack.Push(KecaknoahReference.Right(v1.ExpressionOperation(c.Type, v2))); break; case KecaknoahILCodeType.Not: case KecaknoahILCodeType.Negative: v1 = ReferenceStack.Pop().RawObject; ReferenceStack.Push(KecaknoahReference.Right(v1.ExpressionOperation(c.Type, null))); break; //代入など-------------------------------------------------------------- case KecaknoahILCodeType.Assign: v1 = ReferenceStack.Pop().RawObject; rfr = ReferenceStack.Pop(); rfr.RawObject = v1; ReferenceStack.Push(KecaknoahReference.Right(v1)); break; case KecaknoahILCodeType.PlusAssign: v1 = ReferenceStack.Pop().RawObject; rfr = ReferenceStack.Pop(); v2 = rfr.RawObject.ExpressionOperation(KecaknoahILCodeType.Plus, v1); rfr.RawObject = v2; ReferenceStack.Push(KecaknoahReference.Right(v2)); break; case KecaknoahILCodeType.MinusAssign: v1 = ReferenceStack.Pop().RawObject; rfr = ReferenceStack.Pop(); v2 = rfr.RawObject.ExpressionOperation(KecaknoahILCodeType.Minus, v1); rfr.RawObject = v2; ReferenceStack.Push(KecaknoahReference.Right(v2)); break; case KecaknoahILCodeType.MultiplyAssign: v1 = ReferenceStack.Pop().RawObject; rfr = ReferenceStack.Pop(); v2 = rfr.RawObject.ExpressionOperation(KecaknoahILCodeType.Multiply, v1); rfr.RawObject = v2; ReferenceStack.Push(KecaknoahReference.Right(v2)); break; case KecaknoahILCodeType.DivideAssign: v1 = ReferenceStack.Pop().RawObject; rfr = ReferenceStack.Pop(); v2 = rfr.RawObject.ExpressionOperation(KecaknoahILCodeType.Divide, v1); rfr.RawObject = v2; ReferenceStack.Push(KecaknoahReference.Right(v2)); break; case KecaknoahILCodeType.AndAssign: v1 = ReferenceStack.Pop().RawObject; rfr = ReferenceStack.Pop(); v2 = rfr.RawObject.ExpressionOperation(KecaknoahILCodeType.And, v1); rfr.RawObject = v2; ReferenceStack.Push(KecaknoahReference.Right(v2)); break; case KecaknoahILCodeType.OrAssign: v1 = ReferenceStack.Pop().RawObject; rfr = ReferenceStack.Pop(); v2 = rfr.RawObject.ExpressionOperation(KecaknoahILCodeType.Or, v1); rfr.RawObject = v2; ReferenceStack.Push(KecaknoahReference.Right(v2)); break; case KecaknoahILCodeType.XorAssign: v1 = ReferenceStack.Pop().RawObject; rfr = ReferenceStack.Pop(); v2 = rfr.RawObject.ExpressionOperation(KecaknoahILCodeType.Xor, v1); rfr.RawObject = v2; ReferenceStack.Push(KecaknoahReference.Right(v2)); break; case KecaknoahILCodeType.ModularAssign: v1 = ReferenceStack.Pop().RawObject; rfr = ReferenceStack.Pop(); v2 = rfr.RawObject.ExpressionOperation(KecaknoahILCodeType.Modular, v1); rfr.RawObject = v2; ReferenceStack.Push(KecaknoahReference.Right(v2)); break; case KecaknoahILCodeType.LeftBitShiftAssign: v1 = ReferenceStack.Pop().RawObject; rfr = ReferenceStack.Pop(); v2 = rfr.RawObject.ExpressionOperation(KecaknoahILCodeType.LeftBitShift, v1); rfr.RawObject = v2; ReferenceStack.Push(KecaknoahReference.Right(v2)); break; case KecaknoahILCodeType.RightBitShiftAssign: v1 = ReferenceStack.Pop().RawObject; rfr = ReferenceStack.Pop(); v2 = rfr.RawObject.ExpressionOperation(KecaknoahILCodeType.RightBitShift, v1); rfr.RawObject = v2; ReferenceStack.Push(KecaknoahReference.Right(v2)); break; case KecaknoahILCodeType.NilAssign: v1 = ReferenceStack.Pop().RawObject; rfr = ReferenceStack.Pop(); v2 = rfr.RawObject.ExpressionOperation(KecaknoahILCodeType.NilAssign, v1); rfr.RawObject = v2; ReferenceStack.Push(KecaknoahReference.Right(v2)); break; //特殊---------------------------------------------------------------------------- case KecaknoahILCodeType.StartCoroutine: args = new Stack <KecaknoahObject>(); for (int i = 0; i < c.IntegerValue; i++) { args.Push(ReferenceStack.Pop().RawObject.AsByValValue()); } var ct = ReferenceStack.Peek().RawObject as KecaknoahScriptFunction; var ict = ReferenceStack.Peek().RawObject as KecaknoahInteropFunction; ReferenceStack.Pop(); if (ct == null && ict == null) { throw new InvalidOperationException("スクリプト上のメソッド以外はコルーチン化出来ません"); } if (!ct.Equals(null)) { cors[c.StringValue] = new KecaknoahScriptCoroutineFrame(RunningContext, ct, args.ToArray()); } else { cors[c.StringValue] = new KecaknoahInteropCoroutineFrame(RunningContext, ict, args.ToArray()); } break; case KecaknoahILCodeType.ResumeCoroutine: var cobj = cors[c.StringValue]; if (cobj == null) { if (c.BooleanValue) { ReferenceStack.Pop(); } ReferenceStack.Push(KecaknoahNil.Reference); break; } var cr = cobj.Resume(); if (c.BooleanValue) { //2引数 var vas = ReferenceStack.Pop(); vas.RawObject = cr.ReturningObject; ReferenceStack.Push(KecaknoahReference.Right(cr.CanResume.AsKecaknoahBoolean())); } else { //1引数 ReferenceStack.Push(KecaknoahReference.Right(cr.ReturningObject)); } if (!cr.CanResume) { cors[c.StringValue] = null; } break; case KecaknoahILCodeType.MakeArray: var ars = new Stack <KecaknoahObject>(); for (int i = 0; i < c.IntegerValue; i++) { ars.Push(ReferenceStack.Pop().RawObject); } var arr = new KecaknoahArray(new[] { (int)c.IntegerValue }); for (int i = 0; i < c.IntegerValue; i++) { arr.array[i] = new KecaknoahReference { IsLeftValue = true, RawObject = ars.Pop() } } ; ReferenceStack.Push(KecaknoahReference.Right(arr)); break; case KecaknoahILCodeType.Jump: ProgramCounter = (int)c.IntegerValue; continue; case KecaknoahILCodeType.TrueJump: v1 = ReferenceStack.Pop().RawObject; if (v1.ToBoolean()) { ProgramCounter = (int)c.IntegerValue; continue; } break; case KecaknoahILCodeType.FalseJump: v1 = ReferenceStack.Pop().RawObject; if (!v1.ToBoolean()) { ProgramCounter = (int)c.IntegerValue; continue; } break; case KecaknoahILCodeType.Return: ReturningObject = ReferenceStack.Pop().RawObject; return(false); case KecaknoahILCodeType.Yield: ReturningObject = ReferenceStack.Pop().RawObject; ProgramCounter++; return(true); case KecaknoahILCodeType.Call: args = new Stack <KecaknoahObject>(); for (int i = 0; i < c.IntegerValue; i++) { args.Push(ReferenceStack.Pop().RawObject); } v1 = ReferenceStack.Pop().RawObject.AsByValValue(); ReferenceStack.Push(KecaknoahReference.Right(v1.Call(RunningContext, args.ToArray()).ReturningObject)); break; case KecaknoahILCodeType.IndexerCall: args = new Stack <KecaknoahObject>(); for (int i = 0; i < c.IntegerValue; i++) { args.Push(ReferenceStack.Pop().RawObject); } v1 = ReferenceStack.Pop().RawObject.AsByValValue(); ReferenceStack.Push(v1.GetIndexerReference(args.ToArray())); break; case KecaknoahILCodeType.PushArgument: ReferenceStack.Push(KecaknoahReference.Right(Arguments[(int)c.IntegerValue])); break; case KecaknoahILCodeType.LoadObject: string refname = c.StringValue; ReferenceStack.Push(GetReference(refname)); break; case KecaknoahILCodeType.LoadMember: var or = ReferenceStack.Pop(); ReferenceStack.Push(or.GetMemberReference(c.StringValue)); break; case KecaknoahILCodeType.LoadVarg: args = new Stack <KecaknoahObject>(); for (int i = 0; i < c.IntegerValue; i++) { args.Push(ReferenceStack.Pop().RawObject); } ReferenceStack.Push(KecaknoahReference.Right(VariableArguments[(int)args.Pop().ToInt64()])); break; case KecaknoahILCodeType.AsValue: ReferenceStack.Push(KecaknoahReference.Right(ReferenceStack.Pop().RawObject.AsByValValue())); break; } ProgramCounter++; } if (ReferenceStack.Count == 0) { ReferenceStack.Push(KecaknoahNil.Reference); } ReturningObject = ReferenceStack.Pop().RawObject; return(false); }
/// <summary> /// .NETメソッドをトップレベルに登録します。 /// </summary> /// <param name="method">登録する<see cref="KecaknoahInteropMethodInfo"/>形式のメソッド</param> public void RegisterMethod(KecaknoahInteropMethodInfo method) { topMethods.Add(method); methodReferences.Add(KecaknoahReference.CreateRightReference(new KecaknoahInteropFunction(null, method.Body))); }
/// <summary> /// .NET上のKecaknoah連携クラスを登録します。 /// </summary> /// <param name="klass"></param> public void RegisterClass(KecaknoahInteropClassInfo klass) { classes.Add(klass); classReferences.Add(KecaknoahReference.CreateRightReference(new KecaknoahInteropClassObject(klass))); }
/// <summary> /// .NETメソッドをトップレベルに登録します。 /// </summary> /// <param name="method">登録する<see cref="KecaknoahInteropMethodInfo"/>形式のメソッド</param> public void RegisterMethod(KecaknoahInteropMethodInfo method) { topMethods.Add(method); methodReferences.Add(KecaknoahReference.Right(KecaknoahNil.Instance, method.Body)); }