/// <summary> /// Register a generic class /// </summary> /// <param name="typeName">type name in script</param> /// <param name="type">generic type</param> /// <returns></returns> public static bool Register(string typeName, Type type) { Computer.DS1.Add("$1", VAL.NewHostType(type)); Script.Execute(typeName + "=$1;", Computer.DS1); Computer.DS1.Remove("$1"); return(true); }
private void Callback(object sender, EventArgs e) { VALL L = new VALL(); L.Add(VAL.NewHostType(sender)); L.Add(VAL.NewHostType(e)); VAL arguments = new VAL(L); ret = CPU.ExternalUserFuncCall(func, instance, arguments, context); }
public VAL RemoveDelegateEventHandler() { Delegate dEmitted = LoadEventHandler(); VAL dVAL = VAL.NewHostType(dEmitted); dVAL.temp = this; dVAL.hty = HandlerActionType.Remove; //using SEGREG.NS as flag of REMOVE HANDLER return(dVAL); }
public VAL AddDelegateEventHandler() { MethodInfo methodInfo = this.GetType().GetMethod("Callback", BindingFlags.NonPublic | BindingFlags.Instance); Delegate dEmitted = Delegate.CreateDelegate(eventInfo.EventHandlerType, this, methodInfo); SaveEventHandler(dEmitted); VAL dVAL = VAL.NewHostType(dEmitted); dVAL.temp = this; dVAL.hty = HandlerActionType.Add; //using SEGREG.DS as flag of ADD HANDLER return(dVAL); }
bool NewInstance(VAL V) //new user defined class, .net object or a listcon { VALL L = SysFuncBeginParameter(); if (V.ty == VALTYPE.funccon) { string func = V.Str; VAL userClass = GetVAL(func, true); if (userClass.ty == VALTYPE.classcon) { //VAL instance = NewVAL.UserType(func); VAL instance = new VAL(); VAL ret = InternalUserFuncCall(userClass, instance, new VAL(L)); return(SysFuncEnd(ret)); } else { VAL args = new VAL(L); VAL scope = new VAL(); if (!ES.IsEmpty()) { scope = ES.Top(); } VAL Clss = HostCoding.Decode(func, args, scope, context); return(SysFuncEnd(Clss)); } } else if (V.value is Type) //generic class { VAL args = new VAL(L); object instance = Activator.CreateInstance((Type)V.value, HostCoding.ConstructorArguments(args)); return(SysFuncEnd(VAL.NewHostType(instance))); } throw new RuntimeException(position, "new instance {0} failed", V); }
/* * * .net object format/protocol: * * (1) new className(args,...) * 如 new System.Windows.Form.TextBox() * new Tie.VAL(20) * * * (2) new SerializedObject(string className, string value.ToString(), string SerializedValue); * 请看Encode()生成的格式 * * 例如: * 前提: * System.Windows.Form.Label的值是Type, 已经用Register函数登记在数据字典Computer.DS中. * * 求: * new System.Windows.Form.Label(); 转化为 new Label(System.Window.Form); * * */ public static VAL Decode(string className, VAL args, VAL scope, Context context) { VAL clss = new VAL(); /* * 如果是注册过的class, 那么它的namespace是定义在Computer.DS中 * 譬如 * A= new NS.CLSS(); * scope[className] --> clss; * * 如果没有定义namespace,那么直接到Computer.DS中去取值 * 譬如 * A= CLSS(); * Computer.DS[className] --> clss * * */ clss = scope[className]; if (clss.Undefined) { clss = context.GetVAL(className, true); //如果没有找到val.Class, context.GetVAL(...)返回new VAL() } //返回注册过的class名字 if (clss.Defined && clss.value is Type) { Type type = (Type)clss.value; object instance = Activator.CreateInstance(type, ConstructorArguments(args)); return(VAL.Boxing1(instance)); //返回实例 } //throw new RuntimeException(string.Format("class [{0}]has not registered yet.", scope.name + "." + val.Class)); //如果没有注册过 if (scope.name != null) { object instance = HostType.NewInstance(scope.name + "." + className, ConstructorArguments(args)); if (instance != null) { //把HostType类型注册到CPU.DS2中去 VAL hostType = VAL.NewHostType(instance.GetType()); scope[className] = hostType; return(VAL.Boxing1(instance)); //返回实例 } } if (clss.IsNull) { throw new HostTypeException("class {0} is not defined.", className); } if (clss.value != null) { Type type; if (clss.value is Type) { type = (Type)clss.value; } else { type = clss.value.GetType(); } object instance = Activator.CreateInstance(type, ConstructorArguments(args)); return(VAL.NewHostType(instance)); } return(args); }
/// <summary> /// Register multiple .NET types with brief/short name /// </summary> /// <param name="types"></param> /// <param name="briefName"></param> /// <returns></returns> public static bool Register(Type[] types, bool briefName) { string code = ""; for (int i = 0; i < types.Length; i++) { Type type = types[i]; Computer.DS1.Add("$" + i, VAL.NewHostType(type)); code += string.Format("{0}=${1};", type.FullName, i); if (briefName) { code += string.Format("{0}=${1};", type.Name, i); } if (type.IsClass && type.IsAbstract && type.IsSealed) { MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static); foreach (MethodInfo methodInfo in methods) { VAL method; string name = methodInfo.Name; if (Computer.DS1.ContainsKey(name)) { List <MethodInfo> L = new List <MethodInfo>(); object m = Computer.DS1[name].value; if (m is MethodInfo) { L.Add((MethodInfo)m); } else if (m is MethodInfo[]) { L.AddRange((MethodInfo[])m); } else { RuntimeException.Warning("{0}.{1}(...) conflict with variable/function {2} during extend method registering", type.FullName, name, Computer.DS1[name]); continue; } if (L.IndexOf(methodInfo) == -1) { L.Add(methodInfo); Computer.DS1.Remove(name); method = VAL.NewHostType(L.ToArray()); } else { continue; } } else { method = VAL.NewHostType(methodInfo); } Computer.DS1.Add(name, method); method.temp = new HostOffset(typeof(object), name); } } } Script.Execute(code, Computer.DS1); for (int i = 0; i < types.Length; i++) { Computer.DS1.Remove("$" + i); } return(true); }
public VAL Run(int breakPoint) { L1: Instruction I = CS[IP]; Operand operand = I.operand; position.line = I.line; position.col = I.col; position.cur = I.cur; position.block = I.block; if (I.line == breakPoint) { return(null); } switch (I.cmd) { //---------------------------------------------------------------------------- #region MOV, STO,STO1, RMT. RCP case INSTYPE.MOV: if (operand.ty == OPRTYPE.identcon) // MOV [v] { if (CS[IP + 1].cmd == INSTYPE.OFS) // if this is offset of a struct, keep variable name { REG.Push(new VAL(operand)); } else { REG.Push(GetVAL(operand.Str, false)); } } else if (operand.ty == OPRTYPE.addrcon) // MOV [BP-3] { //VAL opr = Register.BPAddr(BP, operand); VAL opr = new VAL(); opr.ty = VALTYPE.addrcon; opr.value = BP + operand.Addr; opr.name = operand.name; REG.Push(opr); } else { VAL x = new VAL(operand); if (operand.ty == OPRTYPE.funccon) { if (ES.SP > -1) { x.temp = new ContextInstance(this.context, ES.Top()); } else { x.temp = new ContextInstance(this.context, new VAL()); } } REG.Push(VAL.Clone(x)); // MOV 3 } break; //---------------------------------------------------------------------------- case INSTYPE.STO1: case INSTYPE.STO: R0 = REG.Pop(); R1 = REG.pop(); if (R1.ty == VALTYPE.addrcon) { SS[R1.Address] = R0; } else { HostOperation.Assign(R1, R0); } if (I.cmd == INSTYPE.STO) { REG.Push(R1); } break; case INSTYPE.RMT: if (CS[IP + 1].cmd != INSTYPE.HALT) //used for expression decoding,keep last value { REG.Pop(); } break; case INSTYPE.RCP: REG.Push(VAL.Clone(REG.Top())); break; #endregion //---------------------------------------------------------------------------- #region PUSH/POP/SP/ESI/ESO case INSTYPE.ESI: R0 = REG.Pop(); ES.Push(R0); break; case INSTYPE.ESO: ES.Pop(); break; case INSTYPE.PUSH: if (operand != null && operand.ty == OPRTYPE.regcon) { switch (operand.SEG) { case SEGREG.BP: SS.Push(new VAL(BP)); break; case SEGREG.SP: SS.Push(new VAL(SS.SP)); break; case SEGREG.SI: SS.Push(new VAL(SI)); break; case SEGREG.IP: SS.Push(new VAL(IP + 2)); break; case SEGREG.EX: EX.Push((int)operand.value); break; } } else { R0 = REG.Pop(); SS.Push(R0); } break; case INSTYPE.POP: if (operand.ty == OPRTYPE.regcon) { switch (operand.SEG) { case SEGREG.BP: BP = (SS.Pop()).Address; break; case SEGREG.SI: SI = (SS.Pop()).Address; break; case SEGREG.SP: SS.SP = (SS.Pop()).Address; break; case SEGREG.EX: EX.Pop(); break; } } else { R0 = SS.Pop(); REG.Push(R0); } break; case INSTYPE.SP: SS.SP += operand.Addr; break; #endregion //---------------------------------------------------------------------------- #region OFS, ARR //---------------------------------------------------------------------------- // Associative List // Mike={{"street", "3620 Street"},{"zip", 20201},{"phone","111-222-333},{"apt",1111}} // Mike.street = "3620 Street"; // Mike.zip = 40802; case INSTYPE.OFS: R0 = REG.Pop(); R1 = REG.pop(); { VAL v = new VAL(); switch (R1.ty) { case VALTYPE.hostcon: v = R1.getter(R0, true, OffsetType.STRUCT); goto LOFS; case VALTYPE.addrcon: v = SS[R1.Address]; if (v.Undefined || v.IsNull) { v.ty = VALTYPE.listcon; v.value = new VALL(); } break; case VALTYPE.listcon: v = R1; break; default: // if assoicative arrary is empty or not list R1.ty = VALTYPE.listcon; R1.value = new VALL(); v = R1; break; } switch (v.ty) { case VALTYPE.listcon: VALL L = v.List; v = L[R0.Str]; // if property is not found in the associative array if (!v.Defined) { L[R0.Str] = v; } break; case VALTYPE.hostcon: //VAL.Assign(v, VAL.HostTypeOffset(v.value, R0.value)); v = HostOperation.HostTypeOffset(v, R0, OffsetType.STRUCT); break; } LOFS: if ((object)v == null) { v = new VAL(); } v.name = R1.name + "." + R0.name; REG.Push(v); } break; case INSTYPE.ARR: R0 = REG.Pop(); R1 = REG.pop(); { VAL v = new VAL(); switch (R1.ty) { case VALTYPE.addrcon: v = SS[R1.Address]; //indirect addressing if (v.Undefined || v.IsNull) { v.ty = VALTYPE.listcon; v.value = new VALL(); v = v.getter(R0, true, OffsetType.ARRAY); } else { v = v.getter(R0, true, OffsetType.ARRAY); } break; case VALTYPE.listcon: //push reference v = R1.getter(R0, true, OffsetType.ARRAY); break; case VALTYPE.hostcon: v = R1.getter(R0, true, OffsetType.ARRAY); if (!v.Defined) { throw new RuntimeException(position, "{0} does not have property {1}.", R1, R0); } break; default: //refer: public VAL this[VAL arr], when R1 == null, dynamically allocate a list R1.ty = VALTYPE.listcon; R1.value = new VALL(); v = R1.getter(R0, true, OffsetType.ARRAY); //JError.OnRuntime(0); break; } v.name = R1.name + "[" + R0.ToString() + "]"; REG.Push(v); } break; #endregion //---------------------------------------------------------------------------- #region CALL, NEW, ENDP, RET, GNRC case INSTYPE.GNRC: R0 = REG.Pop(); // R0 = new Type[] { string, int } R1 = REG.Pop(); // R1 = System.Collection.Generic { Operand opr = I.operand; VAL R2 = R1[opr.Str]; // I.val.Str == Dictionary`2 if (R2.Undefined) // Type is not registered { object t = HostType.GetType(R1.name + "." + opr.Str); if (t != null) { R2 = VAL.NewHostType(t); } else { throw new RuntimeException(position, "Type {0}.{1} is not registered.", R1.name, opr.Str); } } object A = R0.HostValue; if (A is object[] && ((object[])A).Length == 0) //case: typeof(Dictionary<,>) { if (R2.value is Type) { REG.Push(VAL.NewHostType(R2.value)); } else { throw new RuntimeException(position, "{0} is not System.Type.", R1); } } else { if (!(A is Type[])) { throw new RuntimeException(position, "<{0}> is not System.Type[].", R0.ToString2()); } if (R2.value is Type) { Type t = (Type)R2.value; REG.Push(VAL.NewHostType(t.MakeGenericType((Type[])A))); } else if (R2.value is MethodInfo) { MethodInfo t = (MethodInfo)R2.value; VAL m = VAL.NewHostType(t.MakeGenericMethod((Type[])A)); m.temp = R2.temp; REG.Push(m); } else if (R2.value is MethodInfo[]) { MethodInfo[] T = (MethodInfo[])R2.value; for (int i = 0; i < T.Length; i++) { T[i] = T[i].MakeGenericMethod((Type[])A); } VAL m = VAL.NewHostType(T); m.temp = R2.temp; REG.Push(m); } else { throw new RuntimeException(position, "{0} is not System.Type.", R1); } } } break; case INSTYPE.CALL: if (operand.ty == OPRTYPE.intcon) { IP = operand.Addr; } else if (operand.ty == OPRTYPE.addrcon) // high-level programming { SysFuncCallByAddr(SS[operand.Addr + BP]); } else if (operand.ty == OPRTYPE.regcon) { SysFuncCallByAddr(SS[operand.Addr + SS.SP]); } else if (operand.ty == OPRTYPE.none) //used for Generic method { if (ES.IsEmpty()) { R0 = REG.Pop(); } else { R0 = ES.Top(); } SysFuncCallByName(R0); } else { SysFuncCallByName(new VAL(operand)); } goto L1; case INSTYPE.NEW: if (operand.ty == OPRTYPE.funccon) { NewInstance(new VAL(operand)); //system predifined class & user-defined class } else if (operand.ty == OPRTYPE.none) //used for Generic class { if (ES.IsEmpty()) { R0 = REG.Pop(); } else { R0 = ES.Top(); } NewInstance(R0); } else if (operand.ty == OPRTYPE.intcon) { int opr = (int)operand.value; if (opr > 1) { R0 = REG.Pop(); R1 = REG.Pop(); } else { R1 = REG.Pop(); } if (R1.value is Type) { Type ty = (Type)R1.value; if (opr == 1) { if (ty.IsArray) { R0 = VAL.Array(); } else { R0 = new VAL(); } } if (R0.ty == VALTYPE.listcon) { if (ty.IsArray) { R0.List.ty = ty; } else { throw new RuntimeException(position, "new object failed. {0} is not Array Type", R1); } } R0.Class = ty.FullName; REG.Push(R0); } else { throw new RuntimeException(position, "new object failed. {0} is not System.Type", R1); } IP++; } goto L1; case INSTYPE.ENDP: if ((OPRTYPE)operand.Intcon == OPRTYPE.classcon) { REG.Push(ES.Top()); //return this; } else { REG.Push(VAL.VOID); //return void; } SS.SP = BP; //PUSH BP; POP SP; BP = (SS.Pop()).Address; //POP BP; R0 = SS.Top(); //EXEC RET IP = R0.Address; goto L1; case INSTYPE.RET: if (!SS.IsEmpty()) { R0 = SS.Top(); IP = R0.Address; //goto V.i } else { if (REG.IsEmpty()) { return(VAL.VOID); } else { return(REG.Top()); } } goto L1; #endregion //---------------------------------------------------------------------------- #region +,-,*,/,%,>,<,!=,==,<=,>=, ++, -- //---------------------------------------------------------------------------- case INSTYPE.NEG: R0 = REG.Pop(); if (operand.Intcon == -1) { R0 = -R0; //call VAL.operator -(VAL) } else { R0 = +R0; //call VAL.operator +(VAL) } REG.Push(R0); break; case INSTYPE.ADD: R0 = REG.Pop(); R1 = REG.Pop(); R1 += R0; REG.Push(R1); break; case INSTYPE.SUB: R0 = REG.Pop(); R1 = REG.Pop(); R1 -= R0; REG.Push(R1); break; case INSTYPE.MUL: R0 = REG.Pop(); R1 = REG.Pop(); R1 *= R0; REG.Push(R1); break; case INSTYPE.DIV: R0 = REG.Pop(); R1 = REG.Pop(); R1 /= R0; REG.Push(R1); break; case INSTYPE.MOD: R0 = REG.Pop(); R1 = REG.Pop(); R1 %= R0; REG.Push(R1); break; case INSTYPE.GTR: R0 = REG.Pop(); R1 = REG.Pop(); REG.Push(new VAL(R1 > R0)); break; case INSTYPE.LSS: R0 = REG.Pop(); R1 = REG.Pop(); REG.Push(new VAL(R1 < R0)); break; case INSTYPE.GEQ: R0 = REG.Pop(); R1 = REG.Pop(); REG.Push(new VAL(R1 >= R0)); break; case INSTYPE.LEQ: R0 = REG.Pop(); R1 = REG.Pop(); REG.Push(new VAL(R1 <= R0)); break; case INSTYPE.EQL: R0 = REG.Pop(); R1 = REG.Pop(); REG.Push(new VAL(R1 == R0)); break; case INSTYPE.NEQ: R0 = REG.Pop(); R1 = REG.Pop(); REG.Push(new VAL(R1 != R0)); break; case INSTYPE.INC: R0 = REG.pop(); R1 = VAL.Clone(R0); if (R0.ty == VALTYPE.addrcon) { SS[R0.Address] += new VAL(1); } else //global varible { HostOperation.Assign(R0, R0 + new VAL(1)); } REG.Push(R1); break; case INSTYPE.DEC: R0 = REG.pop(); R1 = VAL.Clone(R0); if (R0.ty == VALTYPE.addrcon) { SS[R0.Address] -= new VAL(1); } else //global varible { HostOperation.Assign(R0, R0 - new VAL(1)); } REG.Push(R1); break; #endregion //---------------------------------------------------------------------------- #region MARK, END, EACH, CAS, DIRC case INSTYPE.MARK: REG.Push(Mark); break; case INSTYPE.END: { VAL L = new VAL(new VALL()); while (REG.Top() != Mark) { L.List.Insert(REG.Pop()); } REG.Pop(); // pop mark REG.Push(L); } break; case INSTYPE.EACH: R0 = REG.Pop(); //Collection R1 = REG.pop(); //address of element [BP+addr] REG.Push(ForEach(R0, SS[R1.Intcon], SS[R1.Intcon + 1])); break; case INSTYPE.CAS: R0 = REG.Pop(); R1 = REG.Top(); if (R1 == R0) { REG.Pop(); IP = operand.Addr; goto L1; } //goto V.i break; case INSTYPE.DIRC: //directive command switch (operand.mod) { case Constant.SCOPE: this.scope = (string)operand.value; break; } break; #endregion //---------------------------------------------------------------------------- #region &&, ||, ~, &, |, >>, << //---------------------------------------------------------------------------- case INSTYPE.NOTNOT: R0 = REG.Pop(); if (R0.ty == VALTYPE.stringcon) { REG.Push(Computer.Run(scope, R0.Str, CodeType.statements, context)); } else { REG.Push(new VAL(!R0)); //call VAL.operator !(VAL) } break; case INSTYPE.ANDAND: R0 = REG.pop(); R1 = REG.Pop(); REG.Push(new VAL(R0.ty == VALTYPE.boolcon && R1.ty == VALTYPE.boolcon? R0.Boolcon && R1.Boolcon: false)); break; case INSTYPE.OROR: R0 = REG.pop(); R1 = REG.Pop(); REG.Push(new VAL(R0.ty == VALTYPE.boolcon && R1.ty == VALTYPE.boolcon ? R0.Boolcon || R1.Boolcon : false)); break; //---------------------------------------------------------------------------- case INSTYPE.NOT: R0 = REG.Pop(); REG.Push(~R0); //call VAL.operator ~(VAL) break; case INSTYPE.AND: R0 = REG.pop(); R1 = REG.Pop(); REG.Push(R1 & R0); break; case INSTYPE.OR: R0 = REG.pop(); R1 = REG.Pop(); REG.Push(R1 | R0); break; case INSTYPE.XOR: R0 = REG.pop(); R1 = REG.Pop(); REG.Push(R1 ^ R0); break; //---------------------------------------------------------------------------- case INSTYPE.SHL: R0 = REG.pop(); R1 = REG.Pop(); if (!(R0.value is int)) { throw new RuntimeException(position, "the 2nd operand {0} in << operation must be integer", R0); } REG.Push(R1 << (int)R0.value); break; case INSTYPE.SHR: R0 = REG.pop(); R1 = REG.Pop(); if (!(R0.value is int)) { throw new RuntimeException(position, "the 2nd operand {0} in >> operation must be integer", R0); } REG.Push(R1 >> (int)R0.value); break; #endregion //---------------------------------------------------------------------------- #region JUMP, ADR, VLU case INSTYPE.JMP: IP = operand.Addr; goto L1; case INSTYPE.LJMP: IP += operand.Addr; goto L1; case INSTYPE.JNZ: if (REG.Pop() == new VAL(true)) { IP = operand.Addr; goto L1; } else { break; } case INSTYPE.JZ: if (REG.Pop() != new VAL(true)) { IP = operand.Addr; goto L1; } else { break; } case INSTYPE.LJZ: if (REG.Pop() != new VAL(true)) { IP += operand.Addr; goto L1; } else { break; } case INSTYPE.ADR: R0 = REG.Pop(); REG.Push(new VAL(R0.name)); break; case INSTYPE.VLU: R0 = REG.Pop(); if (R0.ty == VALTYPE.stringcon) { REG.Push(Computer.Run(scope, R0.Str, CodeType.expression, context)); } else { throw new RuntimeException(position, "Invalid address type:" + R0.ToString()); } break; #endregion //---------------------------------------------------------------------------- #region THIS,BASE case INSTYPE.THIS: //this.x if (ES.SP > -1) { if (this.scope != "") { VAL NS = GetScopeVAL(this.scope); if (NS != ES.Top()) { REG.Push(NS); } } else { REG.Push(ES.Top()); } } else if (this.scope != "") { if (operand.ty == OPRTYPE.intcon) //this.x=100; { REG.Push(GetScopeVAL(this.scope)); } else { REG.Push(new VAL(this.scope)); //p=&this.x; } } else { if (CS[IP + 2].cmd == INSTYPE.OFS) { CS[IP + 2].cmd = INSTYPE.NOP; } else { throw new RuntimeException(position, "Operator[this] is invalid since namespace is empty."); } } break; case INSTYPE.BASE: //base.x //if (ES.SP > -1) //{ // VAL BS = ES.Top()[JExpression.BASE_INSTANCE]; // if((object)BS!=null) // REG.Push(BS); // else // throw new RuntimeException(string.Format("Operator[base] is invalid since class {0} does not have base class.",ES.Top())); //} if (this.scope != "") { string bv = ""; int n = 1; if (operand.ty == OPRTYPE.intcon) //base.base.x=10; { n = operand.Intcon; bv = GetBaseScope(this.scope, n); if (bv != "") { REG.Push(GetScopeVAL(bv)); } else { if (CS[IP + 2].cmd == INSTYPE.OFS) { CS[IP + 2].cmd = INSTYPE.NOP; } } } else { n = operand.Addr; // p = &base.base.x; bv = GetBaseScope(this.scope, n); REG.Push(new VAL(bv)); } } else { throw new RuntimeException(position, "Operator[base] is invalid since scope is root."); } break; #endregion //---------------------------------------------------------------------------- #region THRW, DDT, HALT case INSTYPE.THRW: R0 = REG.Top(); if (!(R0.HostValue is Exception)) { throw new RuntimeException(position, "{0} is not type of System.Exception.", R0.HostValue); } if (EX.IsEmpty()) { throw (Exception)R0.HostValue; } IP = EX.Pop(); if (IP == -1) { throw (Exception)R0.HostValue; } break; case INSTYPE.DDT: Logger.WriteLine(DebugInfo()); break; case INSTYPE.HALT: if (REG.IsEmpty()) { return(VAL.VOID); } else { return(REG.Top()); } #endregion } IP++; goto L1; }
private void register(string ty, Type type) { ds1.Add(ty, VAL.NewHostType(type)); }
public static VAL Function(string func, VAL parameters, Memory DS, Position position) { VALL L = (VALL)parameters.value; VAL R0; int size = L.Size; VAL L0 = size > 0 ? L[0] : null; VAL L1 = size > 1 ? L[1] : null; switch (func) { /* * register(Type type) * register(Assembly assemby) * */ case "register": if (size == 1) { if (L0.ty == VALTYPE.hostcon) { object host = L0.HostValue; if (host is Type) { return(new VAL(HostType.Register((Type)host))); } if (host is Type[]) { return(new VAL(HostType.Register((Type[])host))); } else if (host is Assembly) { return(new VAL(HostType.Register((Assembly)host))); } } } break; case "addreference": if (size == 2 && L0.ty == VALTYPE.stringcon && L1.ty == VALTYPE.hostcon) { object host = L1.HostValue; if (host is Assembly) { HostType.AddReference(L0.Str, (Assembly)host); return(VAL.NewHostType(host)); } } break; //return VAL type case "type": if (size == 1) { return(new VAL((int)L0.ty)); } break; case "GetType": if (size == 1) { if (L0.value == null) { return(new VAL()); } else { return(VAL.NewHostType(L0.value.GetType())); } } break; case "typeof": if (size == 2) { if (L0.ty == VALTYPE.listcon && L1.ty == VALTYPE.stringcon) //1. { L0.Class = L1.Str; return(L0); } } else if (size == 1) { if (L0.value == null) { Type ty = HostType.GetType(L0.name); if (ty != null) { return(VAL.NewHostType(ty)); } else { return(new VAL()); } } else if (L0.ty == VALTYPE.listcon) { if (L0.Class == null) { return(VAL.VOID); } return(new VAL(L0.Class)); } else if (L0.ty == VALTYPE.hostcon) { if (L0.value is Type) { return(L0); } else { return(VAL.NewHostType(L0.value.GetType())); } } else if (L0.ty == VALTYPE.stringcon) { return(VAL.NewHostType(HostType.GetType(L0.Str))); //6. } } break; case "classof": if (size == 1) { if (L0.ty == VALTYPE.hostcon) { return(HostValization.Host2Val(L0.value)); } } else if (size == 2) { if (L0.ty == VALTYPE.hostcon && L1.ty == VALTYPE.listcon) //1. { HostValization.Val2Host(L1, L0.value); return(L0); } } break; case "valize": if (size == 1) { return(VAL.Script(L0.Valor)); } break; case "isnull": if (size == 2) { if (L0.ty == VALTYPE.nullcon) { return(L1); } else { return(L0); } } break; case "VAL": if (size == 1) { R0 = VAL.Clone(L0); R0.Class = "VAL"; //force to CAST VAL, don't do HostValue unboxing return(R0); } break; case "HOST": //cast to hostcon if (size == 1) { R0 = VAL.Clone(L0); R0.ty = VALTYPE.hostcon; return(R0); } break; case "ctype": if (size == 2) { if (L1.value is Type) { return(VAL.cast(VAL.Clone(L0), (Type)L1.value)); } else if (L[1].value is string) { Type ty = HostType.GetType(L1.Str); if (ty != null) { return(VAL.cast(VAL.Clone(L0), ty)); } } } break; case "DateTime": if (size == 6) { return(VAL.NewHostType(new DateTime(L0.Intcon, L1.Intcon, L[2].Intcon, L[3].Intcon, L[4].Intcon, L[5].Intcon))); } else if (size == 3) { return(VAL.NewHostType(new DateTime(L0.Intcon, L1.Intcon, L[2].Intcon))); } break; //STRING case "format": if (size >= 1 && L0.ty == VALTYPE.stringcon) { return(format(L)); } break; #region LIST function case "size": if (size == 1) { return(new VAL(L0.Size)); } break; case "array": //array(2,3,4) int[] A = new int[size]; for (int i = 0; i < size; i++) { if (L[1].ty != VALTYPE.intcon) { return(null); } A[i] = L[i].Intcon; } return(VAL.Array(A)); case "slice": return(Slice(L)); case "append": case "push": if (size == 2 && L0.ty == VALTYPE.listcon) { R0 = L1; L0.List.Add(VAL.Clone(R0)); return(L0); } break; case "pop": if (size == 1 && L0.ty == VALTYPE.listcon) { int index = L0.List.Size - 1; R0 = L0.List[index]; L0.List.Remove(index); return(R0); } else if (size == 2 && L0.ty == VALTYPE.listcon && L1.ty == VALTYPE.intcon) { int index = L1.Intcon; R0 = L0.List[index]; L0.List.Remove(index); return(R0); } break; case "insert": if (size == 3 && L0.ty == VALTYPE.listcon && L1.ty == VALTYPE.intcon) { L0.List.Insert(L1.Intcon, VAL.Clone(L[2])); return(L0); } break; case "remove": if (size == 2 && L0.ty == VALTYPE.listcon && L1.ty == VALTYPE.intcon) { L0.List.Remove(L1.Intcon); return(L0); } break; #endregion //DEBUG case "echo": return(new VAL(L)); case "write": return(WriteLine(L)); case "loginfo": return(LogInfo(L)); #region internal functions used by parser case Constant.FUNC_CAST_TYPE_VALUE: if (size == 2) { return(cast(L1, L0)); } break; case Constant.FUNC_CAST_VALUE_TYPE: if (size == 2) { return(cast(L0, L1)); } break; case Constant.FUNC_IS_TYPE: if (size == 2) { Type type = SystemFunction.GetValDefinitionType(L1); if (type != null) { if (L0.value == null) { return(new VAL(false)); } else { return(new VAL(type.IsAssignableFrom(L0.value.GetType()))); } } else { throw new RuntimeException(position, "{0} is not type or not registered.", L1.value); } } break; case Constant.FUNC_MAKE_ARRAY_TYPE: if (size == 1 || size == 2) { Type ty = SystemFunction.GetValDefinitionType(L0); if (ty != null) { if (size == 1) { return(VAL.Boxing1(ty.MakeArrayType())); } else if (L1.value is int) { return(VAL.Boxing1(ty.MakeArrayType(L1.Intcon))); } } else { throw new RuntimeException(position, "declare array failed, {0} is not type.", L0.value); } } break; case Constant.FUNC_FUNCTION: if (L[1].ty == VALTYPE.intcon) { return(new VAL(Operand.Func(L[1].Intcon, L[0].Str))); } else { return(new VAL(Operand.Func(L[1].Str, L[0].Str))); } case Constant.FUNC_CLASS: return(new VAL(Operand.Clss(L[1].Intcon, L[0].Str))); #endregion #region propertyof, methodof, fieldof case "propertyof": if (size >= 2 && size <= 4) { object host = L0.value; if (host == null) { break; } if (L0.ty == VALTYPE.hostcon && L1.ty == VALTYPE.stringcon) { if (size == 2 || size == 3) { return(HostFunction.propertyof(size == 2, null, (string)L1.value, host, size == 2 ? null: L[2].HostValue)); } } else if (L0.ty == VALTYPE.hostcon && L1.ty == VALTYPE.hostcon && L1.value is Type && L[2].ty == VALTYPE.stringcon) { if (size == 3 || size == 4) { return(HostFunction.propertyof(size == 3, (Type)L1.value, (string)L[2].value, host, size == 3 ? null : L[3].HostValue)); } } } break; case "fieldof": if (size == 2 || size == 3) { object host = L0.value; if (host == null) { break; } if (L0.ty == VALTYPE.hostcon && L1.ty == VALTYPE.stringcon) { Type ty = HostType.GetHostType(host); FieldInfo fieldInfo = ty.GetField((string)L1.value, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance); if (fieldInfo == null) { throw new RuntimeException(position, string.Format("Invalid field name: {0}.{1}", ty.FullName, L1.value)); } if (size == 2) { return(VAL.Boxing1(fieldInfo.GetValue(host))); } else { fieldInfo.SetValue(host, L[2].HostValue); return(VAL.VOID); } } } break; case "methodof": if (size == 4) { object host = L0.value; if (host == null) { break; } VAL L2 = L[2]; object args = L[3].HostValue; if (L0.ty == VALTYPE.hostcon && L1.ty == VALTYPE.hostcon && L1.value is Type && L2.ty == VALTYPE.stringcon && args is Type[]) { MethodInfo methodInfo = HostFunction.methodof(host, (Type)L1.value, (string)L2.value, (Type[])args); if (methodInfo != null) { VAL method = VAL.Boxing1(methodInfo); method.temp = new HostOffset(host, methodInfo); return(method); } else { throw new RuntimeException(position, "method {0} is not existed", L2.value); } } } break; #endregion } return(null); }
/// <summary> /// Synchronize class's internal Fields/Properties/Methods between HOST and Data Segment /// </summary> /// <param name="DS">Data segment(DS)</param> /// <param name="instance">Host instance</param> /// <param name="toHost">true: synchronize from DS to Host, false: synchrnize from Host to DS</param> public static void SyncInstance(Memory DS, object instance, bool toHost) { Type type = instance.GetType(); FieldInfo[] fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); foreach (FieldInfo fieldInfo in fields) { if (toHost) { VAL v = DS[fieldInfo.Name]; if (v.Defined) { fieldInfo.SetValue(instance, v.HostValue); } } else { object obj = fieldInfo.GetValue(instance); DS.AddObject(fieldInfo.Name, obj); } } PropertyInfo[] properties = type.GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); foreach (PropertyInfo propertyInfo in properties) { if (toHost) { VAL v = DS[propertyInfo.Name]; if (v.Defined && propertyInfo.CanWrite) { propertyInfo.SetValue(instance, v.HostValue, null); } } else { if (propertyInfo.CanRead) { object obj = propertyInfo.GetValue(instance, null); DS.AddObject(propertyInfo.Name, obj); } } } MethodInfo[] methods = type.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); foreach (MethodInfo methodInfo in methods) { if (!toHost) { VAL method = VAL.NewHostType(methodInfo); if (methodInfo.IsPublic) { method.temp = new HostOffset(instance, methodInfo.Name); } else { method.temp = new HostOffset(instance, methodInfo); } DS.Add(methodInfo.Name, method); } } EventInfo[] events = type.GetEvents(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); foreach (EventInfo eventInfo in events) { if (!toHost) { VAL _event = VAL.NewHostType(eventInfo); DS.Add(eventInfo.Name, _event); } } }
/// <summary> /// Add host object variable /// </summary> /// <param name="key"></param> /// <param name="v"></param> /// <returns></returns> public VAL AddHostObject(string key, object v) { return(Add(key, VAL.NewHostType(v))); }