/// <summary> /// 特定の<see cref="KecaknoahScriptClassInfo"/>を元にして、インスタンスを生成します。 /// コンストラクタがあった場合、呼び出します。 /// </summary> /// <param name="klass">クラス</param> /// <param name="ctx">コンテキスト</param> /// <param name="ctorArgs">コンストラクタ引数</param> public KecaknoahInstance(KecaknoahScriptClassInfo klass, KecaknoahContext ctx, KecaknoahObject[] ctorArgs) { Class = klass; ExtraType = klass.Name; LocalFieldReferences = localReferences; InstanceMethodReferences = methodReferences; foreach (var i in klass.LocalInfos) { localReferences[i.Name] = new KecaknoahReference() { IsLeftValue = true }; if (i.InitializeIL != null) { localReferences[i.Name].RawObject = ctx.ExecuteExpressionIL(i.InitializeIL); } } foreach (var i in klass.methods) methodReferences[i.Name] = new KecaknoahReference() { IsLeftValue = true, RawObject = new KecaknoahScriptFunction(this, i) }; var ctor = klass.classMethods.FirstOrDefault(p => p.Name == "new"); if (ctor != null) { new KecaknoahScriptFunction(this, ctor).Call(ctx, ctorArgs); } }
private KecaknoahFunctionResult InstanceCreareInstance(KecaknoahContext ctx, KecaknoahObject self, KecaknoahObject[] args) { List<object> ia = new List<object>(); foreach (var i in args) { switch (i.Type) { case TypeCode.Boolean: ia.Add(i.ToBoolean()); break; case TypeCode.Double: ia.Add(i.ToDouble()); break; case TypeCode.Int64: ia.Add(i.ToInt32()); break; case TypeCode.String: ia.Add(i.ToString()); break; case TypeCode.Empty: ia.Add(null); break; default: var t = i as KecaknoahDynamicLibraryObject; ia.Add(t != null ? t.rawobj : null); break; } } var obj = Activator.CreateInstance(type, ia.ToArray()); return new KecaknoahDynamicLibraryObject(obj).NoResume(); }
protected internal override KecaknoahObject ExpressionOperation(KecaknoahILCodeType op, KecaknoahObject target) { if (target.ExtraType == "TimeSpan") { var t = ((KecaknoahTimeSpan)target).timespan; switch (op) { case KecaknoahILCodeType.Plus: return new KecaknoahTimeSpan(timespan + t); case KecaknoahILCodeType.Minus: return new KecaknoahTimeSpan(timespan - t); default: return KecaknoahNil.Instance; } } else { switch (op) { case KecaknoahILCodeType.Equal: return KecaknoahBoolean.False; case KecaknoahILCodeType.NotEqual: return KecaknoahBoolean.True; default: return KecaknoahNil.Instance; } } }
/// <summary> /// インデクサーの参照を得ます。 /// <see cref="GetMemberReference(string)"/>と<see cref="KecaknoahObject.Call(KecaknoahContext, KecaknoahObject[])"/>の /// 中間のような存在です。 /// </summary> /// <param name="indices">インデックス</param> /// <returns>返す参照</returns> protected internal override KecaknoahReference GetIndexerReference(KecaknoahObject[] indices) { if (!dict.ContainsKey(indices[0])) { dict[indices[0]] = new KecaknoahReference { IsLeftValue = true }; } return dict[indices[0]]; }
private static KecaknoahFunctionResult CreateArray(KecaknoahContext context, KecaknoahObject self, KecaknoahObject[] args) { if (args.Length == 0) throw new ArgumentException("次元数が不正です"); if (args.Length >= 5) throw new ArgumentException("次元数が多すぎます"); var dq = args.Select(p => (int)p.ToInt64()).ToArray(); var result = new KecaknoahArray(dq); return result.NoResume(); }
/// <summary> /// 呼び出します。 /// </summary> /// <param name="context"></param> /// <param name="args">引数</param> /// <returns>返り値</returns> protected internal override KecaknoahFunctionResult Call(KecaknoahContext context, KecaknoahObject[] args) { var sf = new KecaknoahStackFrame(context, BaseMethod.Codes); sf.Locals["self"] = KecaknoahReference.CreateRightReference(Instance); sf.Arguments = args; var r = sf.Resume(); return new KecaknoahFunctionResult(sf.ReturningObject, r); }
/// <summary> /// インデクサーの参照を得ます。 /// <see cref="GetMemberReference(string)"/>と<see cref="KecaknoahObject.Call(KecaknoahContext, KecaknoahObject[])"/>の /// 中間のような存在です。 /// </summary> /// <param name="indices">インデックス</param> /// <returns>返す参照</returns> protected internal override KecaknoahReference GetIndexerReference(KecaknoahObject[] indices) { if (!dict.ContainsKey(indices[0])) { dict[indices[0]] = KecaknoahReference.Left(KecaknoahNil.Instance); } return dict[indices[0]]; }
private static KecaknoahFunctionResult ClassLoadFile(KecaknoahContext ctx, KecaknoahObject self, KecaknoahObject[] args) { var name = Path.GetFullPath(args[0].ToString()); var catalog = new DirectoryCatalog(Path.GetDirectoryName(name), Path.GetFileName(name)); var result = new KecaknoahExtensionLibrary(); var container = new CompositionContainer(catalog); container.ComposeParts(result); return result.NoResume(); }
/// <summary> /// 呼び出します。 /// </summary> /// <param name="context"></param> /// <param name="args">引数</param> /// <returns>返り値</returns> protected internal override KecaknoahFunctionResult Call(KecaknoahContext context, KecaknoahObject[] args) { if (args != null) { CurrentFrame = new KecaknoahStackFrame(context, BaseMethod.Codes); CurrentFrame.Locals["self"] = KecaknoahReference.Right(Instance); CurrentFrame.Arguments = args; } var r = CurrentFrame.Resume(); return new KecaknoahFunctionResult(CurrentFrame.ReturningObject, r); }
/// <summary> /// このオブジェクトに対して二項式としての演算をしようとしても大体nilです。 /// </summary> /// <param name="op">演算子</param> /// <param name="target">2項目の<see cref="KecaknoahObject"/></param> /// <returns></returns> protected internal override KecaknoahObject ExpressionOperation(KecaknoahILCodeType op, KecaknoahObject target) { switch (op) { case KecaknoahILCodeType.Equal: return (dynamic)this == (dynamic)target; case KecaknoahILCodeType.NotEqual: return (dynamic)this != (dynamic)target; default: return KecaknoahNil.Instance; } }
/// <summary> /// このオブジェクトに対して二項式としての演算をします。 /// </summary> /// <param name="op">演算子</param> /// <param name="target">2項目の<see cref="KecaknoahObject"/></param> /// <returns></returns> protected internal virtual KecaknoahObject ExpressionOperation(KecaknoahILCodeType op, KecaknoahObject target) { switch(op) { case KecaknoahILCodeType.Equal: return Equals(target).AsKecaknoahBoolean(); case KecaknoahILCodeType.NotEqual: return (!Equals(target)).AsKecaknoahBoolean(); default: throw new InvalidOperationException($"この{nameof(KecaknoahObject)}に対して式操作は出来ません。"); } }
/// <summary> /// このオブジェクトに対して二項式としての演算をしようとしても大体nilです。 /// </summary> /// <param name="op">演算子</param> /// <param name="target">2項目の<see cref="KecaknoahObject"/></param> /// <returns></returns> protected internal override KecaknoahObject ExpressionOperation(KecaknoahILCodeType op, KecaknoahObject target) { switch (op) { case KecaknoahILCodeType.Equal: return (ExtraType == target.ExtraType).AsKecaknoahBoolean(); case KecaknoahILCodeType.NotEqual: return (ExtraType != target.ExtraType).AsKecaknoahBoolean(); default: return Instance; } }
private static KecaknoahFunctionResult WriteLine(KecaknoahContext context, KecaknoahObject self, KecaknoahObject[] args) { if (args.Length == 0) { Console.WriteLine(); } else { Console.WriteLine(args[0].ToString()); } return KecaknoahNil.Instance.NoResume(); }
private KecaknoahFunctionResult InstanceGetInteger(KecaknoahContext ctx, KecaknoahObject self, KecaknoahObject[] args) { switch (args.Length) { case 0: return random.Next().AsKecaknoahInteger().NoResume(); case 1: var a = args.ExpectInt32(1, false); return random.Next(a[0]).AsKecaknoahInteger().NoResume(); default: var a2 = args.ExpectInt32(2, false); return random.Next(a2[0], a2[1]).AsKecaknoahInteger().NoResume(); } }
private static KecaknoahFunctionResult ToInteger(KecaknoahContext ctx, KecaknoahObject self, KecaknoahObject[] args) { switch (args[0].Type) { case TypeCode.Boolean: return Convert.ToInt64(args[0].ToBoolean()).AsKecaknoahInteger().NoResume(); case TypeCode.Int64: return args[0].NoResume(); case TypeCode.Double: return Convert.ToInt64(args[0].ToDouble()).AsKecaknoahInteger().NoResume(); case TypeCode.String: return Convert.ToInt64(args[0].ToString()).AsKecaknoahInteger().NoResume(); default: return 0.AsKecaknoahInteger().NoResume(); } }
/// <summary> /// 特定の<see cref="KecaknoahScriptClassInfo"/>を元にして、インスタンスを生成します。 /// コンストラクタがあった場合、呼び出します。 /// </summary> /// <param name="klass">クラス</param> /// <param name="ctx">コンテキスト</param> /// <param name="ctorArgs">コンストラクタ引数</param> public KecaknoahInstance(KecaknoahScriptClassInfo klass, KecaknoahContext ctx, KecaknoahObject[] ctorArgs) { Class = klass; LocalFieldReferences = localReferences; InstanceMethodReferences = methodReferences; foreach (var i in klass.Locals) localReferences[i] = new KecaknoahReference() { IsLeftValue = true }; foreach (var i in klass.methods) methodReferences[i.Name] = new KecaknoahReference() { IsLeftValue = true, RawObject = new KecaknoahScriptFunction(this, i) }; if (klass.classMethods.Any(p => p.Name == "new")) { var ctor = klass.classMethods.First(p => p.Name == "new"); new KecaknoahScriptFunction(this, ctor).Call(ctx, ctorArgs); } }
/// <summary> /// 特定の<see cref="KecaknoahInteropClassInfo"/>を元にして、インスタンスを生成します。 /// コンストラクタがあった場合、呼び出します。 /// </summary> /// <param name="klass">クラス</param> /// <param name="ctx">コンテキスト</param> /// <param name="ctorArgs">コンストラクタ引数</param> public KecaknoahInstance(KecaknoahInteropClassInfo klass, KecaknoahContext ctx, KecaknoahObject[] ctorArgs) { Class = klass; ExtraType = klass.Name; LocalFieldReferences = localReferences; InstanceMethodReferences = methodReferences; foreach (var i in klass.LocalInfos) { localReferences[i.Name] = KecaknoahReference.Left(i.Value.AsByValValue()); } foreach (var i in klass.methods) methodReferences[i.Name] = new KecaknoahReference() { IsLeftValue = true, RawObject = new KecaknoahInteropFunction(this, i.Body) }; var ctor = klass.classMethods.FirstOrDefault(p => p.Name == "new"); if (ctor != null) ctor.Body(ctx, this, ctorArgs); }
private KecaknoahFunctionResult InstanceMatch(KecaknoahContext ctx, KecaknoahObject self, KecaknoahObject[] args) { Match result; switch (args.Length) { case 1: result = regex.Match(args[0].ToString()); break; case 2: result = regex.Match(args[0].ToString(), args[1].ToInt32()); break; case 3: result = regex.Match(args[0].ToString(), args[1].ToInt32(), args[2].ToInt32()); break; default: result = null; break; } return new KecaknoahMatch(result).NoResume(); }
/// <summary> /// /// </summary> /// <param name="op"></param> /// <param name="target"></param> /// <returns></returns> protected internal override KecaknoahObject ExpressionOperation(KecaknoahILCodeType op, KecaknoahObject target) { if (target.Type == TypeCode.Boolean) { var t = (KecaknoahBoolean)target; switch (op) { case KecaknoahILCodeType.Not: return (!Value).AsKecaknoahBoolean(); case KecaknoahILCodeType.AndAlso: return (Value && t.Value).AsKecaknoahBoolean(); case KecaknoahILCodeType.OrElse: return (Value || t.Value).AsKecaknoahBoolean(); case KecaknoahILCodeType.And: return (Value & t.Value).AsKecaknoahBoolean(); case KecaknoahILCodeType.Or: return (Value | t.Value).AsKecaknoahBoolean(); case KecaknoahILCodeType.Xor: return (Value ^ t.Value).AsKecaknoahBoolean(); case KecaknoahILCodeType.Equal: return (Value == t.Value).AsKecaknoahBoolean(); case KecaknoahILCodeType.NotEqual: return (Value != t.Value).AsKecaknoahBoolean(); default: return KecaknoahNil.Instance; } } else { switch (op) { case KecaknoahILCodeType.Equal: return False; case KecaknoahILCodeType.NotEqual: return True; default: return KecaknoahNil.Instance; } } }
/// <summary> /// /// </summary> /// <param name="op"></param> /// <param name="target"></param> /// <returns></returns> protected internal override KecaknoahObject ExpressionOperation(KecaknoahILCodeType op, KecaknoahObject target) { if (target.Type == TypeCode.String) { var t = (KecaknoahString)target; switch (op) { case KecaknoahILCodeType.Plus: return (Value + t.Value).AsKecaknoahString(); case KecaknoahILCodeType.Equal: return (Value == t.Value).AsKecaknoahBoolean(); case KecaknoahILCodeType.NotEqual: return (Value != t.Value).AsKecaknoahBoolean(); case KecaknoahILCodeType.Greater: return (Value.CompareTo(t.Value) > 0).AsKecaknoahBoolean(); case KecaknoahILCodeType.Lesser: return (Value.CompareTo(t.Value) < 0).AsKecaknoahBoolean(); case KecaknoahILCodeType.GreaterEqual: return (Value.CompareTo(t.Value) >= 0).AsKecaknoahBoolean(); case KecaknoahILCodeType.LesserEqual: return (Value.CompareTo(t.Value) <= 0).AsKecaknoahBoolean(); default: return KecaknoahNil.Instance; } } else { switch (op) { case KecaknoahILCodeType.Equal: return KecaknoahBoolean.False; case KecaknoahILCodeType.NotEqual: return KecaknoahBoolean.True; default: return KecaknoahNil.Instance; } } }
/// <summary> /// /// </summary> /// <param name="op"></param> /// <param name="target"></param> /// <returns></returns> protected internal override KecaknoahObject ExpressionOperation(KecaknoahILCodeType op, KecaknoahObject target) { if (target.Type == TypeCode.Int64) { return ExpressionOperation(op, (KecaknoahInteger)target); } else if (target.Type == TypeCode.Double) { return ExpressionOperation(op, (KecaknoahFloat)target); } else { switch (op) { case KecaknoahILCodeType.Equal: return KecaknoahBoolean.False; case KecaknoahILCodeType.NotEqual: return KecaknoahBoolean.True; default: return KecaknoahNil.Instance; } } }
private KecaknoahFunctionResult InstanceReplace(KecaknoahContext context, KecaknoahObject self, KecaknoahObject[] args) => raw.Replace(args[0].ToString(), args[1].ToString()).AsKecaknoahString().NoResume();
private KecaknoahFunctionResult InstanceSplit(KecaknoahContext context, KecaknoahObject self, KecaknoahObject[] args) { var l = args[0]; var op = StringSplitOptions.None; if (args.Length >= 2) { var flag = args[1].ToBoolean(); if (flag) op = StringSplitOptions.RemoveEmptyEntries; } if (l.ExtraType == "Array") { var list = l.ToStringArray(); var result = raw.Split(list.ToArray(), op); return new KecaknoahArray(result.Select(p => p.AsKecaknoahString())).NoResume(); } else { var str = l.ToString(); var result = raw.Split(new[] { str }, op); return new KecaknoahArray(result.Select(p => p.AsKecaknoahString())).NoResume(); } }
private static KecaknoahFunctionResult ClassCosh(KecaknoahContext ctx, KecaknoahObject self, KecaknoahObject[] args) { var result = Math.Cosh(args[0].ToDouble()); return result.AsKecaknoahFloat().NoResume(); }
private KecaknoahFunctionResult InstanceSubstring(KecaknoahContext context, KecaknoahObject self, KecaknoahObject[] args) { var t = self.ToString(); switch (args.Length) { case 0: return "".AsKecaknoahString().NoResume(); case 1: return t.Substring((int)args[0].ToInt64()).AsKecaknoahString().NoResume(); default: return t.Substring((int)args[0].ToInt64(), (int)args[1].ToInt64()).AsKecaknoahString().NoResume(); } }
private KecaknoahFunctionResult InstanceFind(KecaknoahContext ctx, KecaknoahObject self, KecaknoahObject[] args) { var result = array.FindIndex(p => p.RawObject.ExpressionOperation(KecaknoahILCodeType.Equal, args[0]).ToBoolean()); return(result.AsKecaknoahInteger().NoResume()); }
/// <summary> /// このオブジェクトに対して二項式としての演算をします。 /// </summary> /// <param name="op">演算子</param> /// <param name="target">2項目の<see cref="KecaknoahObject"/></param> /// <returns></returns> protected internal virtual KecaknoahObject ExpressionOperation(KecaknoahILCodeType op, KecaknoahObject target) { throw new InvalidOperationException($"この{nameof(KecaknoahObject)}に対して式操作は出来ません。"); }
private KecaknoahFunctionResult InstanceReplace(KecaknoahContext context, KecaknoahObject self, KecaknoahObject[] args) => self.ToString().Replace(args[0].ToString(), args[1].ToString()).AsKecaknoahString().NoResume();
private KecaknoahFunctionResult InstanceToLower(KecaknoahContext context, KecaknoahObject self, KecaknoahObject[] args) => raw.ToLower().AsKecaknoahString().NoResume();
protected internal override KecaknoahObject ExpressionOperation(KecaknoahILCodeType op, KecaknoahObject target) { if (target.ExtraType == "DynamicObject") { var t = target as KecaknoahDynamicObject; switch (op) { case KecaknoahILCodeType.Equal: return((t == target).AsKecaknoahBoolean()); case KecaknoahILCodeType.NotEqual: return((t != target).AsKecaknoahBoolean()); default: return(base.ExpressionOperation(op, target)); } } else { switch (op) { case KecaknoahILCodeType.Equal: return(KecaknoahBoolean.False); case KecaknoahILCodeType.NotEqual: return(KecaknoahBoolean.True); default: return(base.ExpressionOperation(op, target)); } } }
/// <summary> /// /// </summary> /// <param name="op"></param> /// <param name="target"></param> /// <returns></returns> protected internal override KecaknoahObject ExpressionOperation(KecaknoahILCodeType op, KecaknoahObject target) { if (target.Type == TypeCode.String) { var t = (KecaknoahString)target; switch (op) { case KecaknoahILCodeType.Plus: return((Value + t.Value).AsKecaknoahString()); case KecaknoahILCodeType.Equal: return((Value == t.Value).AsKecaknoahBoolean()); case KecaknoahILCodeType.NotEqual: return((Value != t.Value).AsKecaknoahBoolean()); case KecaknoahILCodeType.Greater: return((Value.CompareTo(t.Value) > 0).AsKecaknoahBoolean()); case KecaknoahILCodeType.Lesser: return((Value.CompareTo(t.Value) < 0).AsKecaknoahBoolean()); case KecaknoahILCodeType.GreaterEqual: return((Value.CompareTo(t.Value) >= 0).AsKecaknoahBoolean()); case KecaknoahILCodeType.LesserEqual: return((Value.CompareTo(t.Value) <= 0).AsKecaknoahBoolean()); default: return(KecaknoahNil.Instance); } } else { switch (op) { case KecaknoahILCodeType.Equal: return(KecaknoahBoolean.False); case KecaknoahILCodeType.NotEqual: return(KecaknoahBoolean.True); default: return(KecaknoahNil.Instance); } } }
private static KecaknoahReference InstanceToString(KecaknoahObject self) => KecaknoahReference.CreateRightReference(self, (ctx, s, args) => s.ToString().AsKecaknoahString().NoResume());
private static KecaknoahReference InstanceHash(KecaknoahObject self) => KecaknoahReference.CreateRightReference(self, (ctx, s, args) => s.GetHashCode().AsKecaknoahInteger().NoResume());
/// <summary> /// 新しいインスタンスを初期化します。 /// </summary> /// <param name="obj">返却する<see cref="KecaknoahObject"/></param> /// <param name="res">再開可能な場合はtrue</param> public KecaknoahFunctionResult(KecaknoahObject obj, bool res) { CanResume = res; ReturningObject = obj; }
private KecaknoahFunctionResult InstanceEndsWith(KecaknoahContext context, KecaknoahObject self, KecaknoahObject[] args) => raw.EndsWith(args[0].ToString()).AsKecaknoahBoolean().NoResume();
private KecaknoahFunctionResult CreateInstance(KecaknoahContext context, KecaknoahObject self, KecaknoahObject[] args) => new KecaknoahInstance(Class, context, args).NoResume();
private KecaknoahFunctionResult InstancePadRight(KecaknoahContext context, KecaknoahObject self, KecaknoahObject[] args) => raw.PadRight(args[0].ToInt32()).AsKecaknoahString().NoResume();
private KecaknoahFunctionResult InstanceReduce(KecaknoahContext ctx, KecaknoahObject self, KecaknoahObject[] args) { var result = array.Aggregate((p, q) => KecaknoahReference.CreateRightReference(args[0].Call(ctx, new[] { p.RawObject, q.RawObject }).ReturningObject)); return(result.RawObject.NoResume()); }
private static KecaknoahFunctionResult ClassJoin(KecaknoahContext context, KecaknoahObject self, KecaknoahObject[] args) { var ls = args[1].ToStringArray(); var s = args[0].ToString(); var result = string.Join(s, ls); return result.AsKecaknoahString().NoResume(); }
private KecaknoahFunctionResult InstanceMap(KecaknoahContext ctx, KecaknoahObject self, KecaknoahObject[] args) { var result = array.Select(p => args[0].Call(ctx, new[] { p.RawObject }).ReturningObject); return(new KecaknoahArray(result.ToList()).NoResume()); }
/// <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> /// /// </summary> /// <param name="op"></param> /// <param name="target"></param> /// <returns></returns> protected internal override KecaknoahObject ExpressionOperation(KecaknoahILCodeType op, KecaknoahObject target) { if (op == KecaknoahILCodeType.Negative) { return((-Value).AsKecaknoahInteger()); } if (target.Type == TypeCode.Int64) { return(ExpressionOperation(op, (KecaknoahInteger)target)); } else if (target.Type == TypeCode.Double) { return(ExpressionOperation(op, (KecaknoahFloat)target)); } else { switch (op) { case KecaknoahILCodeType.Equal: return(KecaknoahBoolean.False); case KecaknoahILCodeType.NotEqual: return(KecaknoahBoolean.True); default: return(KecaknoahNil.Instance); } } }