public static string Encode(object host, bool persistent) { Type type; if (host is MethodInfo) { MethodInfo methodInfo = (MethodInfo)host; if (methodInfo.IsStatic) { return(methodInfo.ReflectedType.FullName + "." + methodInfo.Name); } else { return(methodInfo.Name); } } else if (host is Type) { type = (Type)host; return(string.Format("typeof({0})", type.FullName)); } else { type = host.GetType(); } if (type.IsEnum) //处理enum常量 { return(HostOperation.EnumBitFlags(host)); } if (host is DateTime) { return(string.Format("new {0}({1})", typeof(DateTime).FullName, ((DateTime)host).Ticks)); } VAL val = HostValization.Host2Valor(host); if (persistent) { return(val.Valor); } else { //default contructor if (HostCoding.HasContructor(type, new Type[] {})) { return(string.Format("new {0}()", type.FullName)); //有缺省的constructor } if (type.FullName == host.ToString()) { return(string.Format("new {0}(...)", type.FullName)); } else { return(string.Format("new {0}({1})", type.FullName, host)); } } }
public static VAL Assign(VAL R0, VAL R1) { bool r = false; if (R0.ty != VALTYPE.funccon) { r = HostOperation.HostTypeAssign(R0, R1); } if (!r) { R0.ty = R1.ty; R0.Class = R1.Class; R0.hty = R1.hty; R0.value = R1.value; //R0.name = R1.name; if (R1.ty == VALTYPE.funccon || (R1.ty == VALTYPE.hostcon && (R1.value is MethodInfo || R1.value is MethodInfo[])) ) { R0.temp = R1.temp; //instance of CPU } } return(R0); }
private void setter(VAL arr, VAL value) { switch (arr.ty) { case VALTYPE.intcon: int pos = arr.Intcon; if (pos < list.Count && pos >= 0) { list[pos] = value; } else if (pos >= 0) { //subscript number > size of array, increase size of array automatically while (pos > list.Count) { list.Add(new VAL()); } list.Add(value); } else //pos < 0 { pos = Pos(pos); list[pos] = value; } return; case VALTYPE.stringcon: string key = arr.Str; foreach (VAL v in list) { if (v.ty != VALTYPE.listcon) { continue; } string prop = v[0].Str; if (v.Size == 2 && v[0].ty == VALTYPE.stringcon && key == prop) { v.List.Remove(v[1]); v.List.Add(value); return; } else if (prop == Expression.BASE_INSTANCE) { VAL BS = v[1][key]; if (BS.Defined) { HostOperation.Assign(BS, value); return; } } } Add(key, value); return; } }
private static void SetValue(object host, Type type, string offset, VAL val) { object temp = ValizerScript.ToHost(val, type); if (temp == null) { temp = val.HostValue; } HostOperation.HostTypeAssign(host, offset, temp, true); }
private bool SysFuncCall(object func, VAL proc, VAL instance, bool arg0) { if (proc.ty == VALTYPE.funccon) { UserFuncCall(proc, instance, arg0); return(true); } VALL L = SysFuncBeginParameter(); if (arg0 && proc.temp is HostOffset) { object host = ((HostOffset)proc.temp).host; if (host != instance.value) { L.Insert(instance); //extend method arg0 = false; } } VAL ret = HostOperation.HostTypeFunction(proc, L); if (ret.Defined) { return(SysFuncEnd(ret)); } if (arg0) { L.Insert(instance); } try { ret = context.InvokeFunction((string)func, new VAL(L), position); } catch (FunctionNotFoundException e1) { throw e1; } catch (Exception e2) { if (e2 is RuntimeException) { throw e2; } else { throw new RuntimeException(position, "Error: function {0}({1}) implementation, {2}", func, L.ToString2(), e2.Message); } } return(SysFuncEnd(ret)); }
private VAL ForEach(VAL collection, VAL element, VAL index) { int i = index.Intcon; if (collection.ty == VALTYPE.listcon) { if (i >= collection.Size) { return(new VAL(false)); } HostOperation.Assign(element, collection[i]); index.value = ++i; return(new VAL(true)); } else if (collection.ty == VALTYPE.hostcon) { if (!(collection.value is IEnumerable)) { throw new RuntimeException(position, "foreach statement requires {0} to be IEnumerable", collection.value.GetType().FullName); } IEnumerable enumerable = (IEnumerable)collection.value; IEnumerator enumerator; if (index.temp is IEnumerator) { enumerator = (IEnumerator)index.temp; } else { enumerator = enumerable.GetEnumerator(); index.temp = enumerator; } if (enumerator.MoveNext()) { HostOperation.Assign(element, VAL.Boxing1(enumerator.Current)); index.value = ++i; return(new VAL(true)); } else { index.temp = null; return(new VAL(false)); } } else { throw new RuntimeException(position, "foreach statement requires [{0}]={1} to be IEnumerable", collection.name, collection.ToString()); } }
private VAL GetVAL(string ident, bool readOnly) { if (ES.SP > -1) { VAL val = null; VAL instance = ES.Top(); if (instance.ty == VALTYPE.hostcon && CS[IP + 2].cmd == INSTYPE.ESO) { val = HostOperation.HostTypeOffset(instance, new VAL(ident), OffsetType.STRUCT); } else { val = instance[ident]; } if (val.Defined) { return(val); } } return(context.GetVAL(ident, readOnly)); }
private static VAL Host2Valor(object host, VAL val) { if (host == null || host is System.DBNull) { val = new VAL(); } else if (host is string || host is char || host is byte || host is int || host is short || host is long || host is bool || host is double || host is float || host is decimal || host is DateTime) { val = VAL.Boxing1(host); } else if (host is IValizable) { val = ((IValizable)host).GetValData(); } else if (host is Type) { val = VAL.Script(string.Format("typeof({0})", ((Type)host).FullName)); } else if (host.GetType().IsEnum) { val = VAL.Script(HostOperation.EnumBitFlags(host)); } else if (host is ICollection) { val = VAL.Array(); foreach (object a in (ICollection)host) { val.Add(Host2Valor(a, new VAL())); } } else { VAL temp = ValizerScript.ToValor(host); if ((object)temp != null) { return(temp); } FieldInfo[] fields = host.GetType().GetFields(); foreach (FieldInfo fieldInfo in fields) { Attribute[] A = (Attribute[])fieldInfo.GetCustomAttributes(typeof(NonValizedAttribute), true); if (A.Length != 0) { continue; } object fieldValue = fieldInfo.GetValue(host); VAL persistent = ValizerScript.ToValor(fieldInfo, fieldValue); if ((object)persistent == null) { persistent = VAL.Boxing(fieldValue); if (!fieldInfo.FieldType.IsValueType && persistent.IsHostType) { persistent = Host2Valor(fieldValue, new VAL()); } } val[fieldInfo.Name] = persistent; } PropertyInfo[] properties = host.GetType().GetProperties(); foreach (PropertyInfo propertyInfo in properties) { ValizableAttribute[] attributes = (ValizableAttribute[])propertyInfo.GetCustomAttributes(typeof(ValizableAttribute), true); if (attributes.Length == 0 || !propertyInfo.CanRead) { continue; } object propertyValue = propertyInfo.GetValue(host, null); if (propertyValue == null) { continue; } VAL persistent = ValizerScript.ToValor(propertyInfo, propertyValue); if ((object)persistent == null) { if (propertyValue is ICollection) { ICollection collection = (ICollection)propertyValue; persistent = VAL.Array(); foreach (object obj in collection) { persistent.Add(VAL.Boxing(obj)); } } else { persistent = VAL.Boxing(propertyValue); if (!propertyInfo.PropertyType.IsValueType && persistent.IsHostType) { persistent = Host2Valor(propertyValue, new VAL()); } } } val[propertyInfo.Name] = persistent; } } val.Class = host.GetType().FullName; return(val); }
private Tuple <MethodInfo, object[]> CheckParameters(MethodInfo method) { ParameterInfo[] parameters = method.GetParameters(); int len = parameters.Length; object[] args2 = new object[len]; Type[] argTypes2 = new Type[len]; if (len > 0 && len < args1.Length) { bool isParams = Attribute.IsDefined(parameters[len - 1], typeof(ParamArrayAttribute)); if (isParams) { for (int i = 0; i < len - 1; i++) { args2[i] = args1[i]; argTypes2[i] = argTypes1[i]; } Type ty = parameters[len - 1].ParameterType; Array array = (Array)Activator.CreateInstance(ty, new object[] { args1.Length - len + 1 }); for (int i = 0; i < args1.Length - len + 1; i++) { array.SetValue(args1[len + i - 1], i); } args2[len - 1] = array; argTypes2[len - 1] = ty; goto L1; } } if (len != args1.Length) { return(null); } for (int i = 0; i < len; i++) { args2[i] = args1[i]; argTypes2[i] = argTypes1[i]; } L1: GenericArguments gas = new GenericArguments(); for (int i = 0; i < len; i++) { if (!HostOperation.IsCompatibleType(parameters[i].ParameterType, args2[i], argTypes2[i])) { if (args2[i] == null && argTypes2[i] == null) { return(null); } object temp = gas.CheckCompatibleType(parameters[i], args2[i], argTypes2[i]); if (temp == null) { return(null); } args2[i] = temp; } } if (method.IsGenericMethod && method.IsGenericMethodDefinition) { Type[] gaty2 = gas.ConstructGenericArguments(method.GetGenericArguments()); method = method.MakeGenericMethod(gaty2); } return(Tuple.Create(method, args2)); }
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; }