public static VAL EnumOperation(VAL R0, VAL R1, object value) { Type type0 = R0.value.GetType(); Type type1 = R1.value.GetType(); Type type = null; if (type1.IsEnum) { type = type1; } else if (type0.IsEnum) { type = type0; } if (type != null) { return(VAL.Boxing1(Enum.ToObject(type, value))); } else { return(VAL.Boxing1(value)); } }
public static VAL InvokeMethod(MethodInfo methodInfo, object host, object[] arguments) { try { object obj = methodInfo.Invoke(host, arguments); return(VAL.Boxing1(obj)); } catch (Exception e) { foreach (object arg in arguments) { if (arg is Delegate) { Delegate d = (Delegate)arg; if (d.Method.Name == Constant.FUNC_CON_INSTANCE_INVOKE) { throw new HostTypeException("Call delegate {0} failed in {1} of {2}", d, methodInfo, host); } } } throw new HostTypeException("Call failed({0}) in {1} of {2}", e, methodInfo, host); } }
private static VAL HostTypeOffsetBoxing(object value, object host, object offset) { VAL v = VAL.Boxing1(value); v.temp = new HostOffset(host, offset); return(v); }
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()); } }
internal static VAL Run(object instance, string code, Memory memory) { memory.Add("$THIS", VAL.Boxing1(instance)); if (code.IndexOf("return") == -1) { return(Script.Evaluate("$THIS", code, memory, null)); } else { return(Script.Execute("$THIS", code, memory, null)); } }
public static VAL HostTypeFunction(VAL proc, VALL parameters) { VAL ret = VAL.VOID; if (proc.ty == VALTYPE.hostcon && (proc.value is MethodInfo || proc.value is MethodInfo[])) { HostOffset temp = (HostOffset)proc.temp; object host = temp.host; object offset = temp.offset; if (offset is MethodInfo) { ret = VAL.Boxing1(((MethodInfo)proc.value).Invoke(host, parameters.ObjectArray)); } else { HostFunction hFunc = new HostFunction(host, (string)offset, parameters); if (proc.value is MethodInfo[]) { ret = hFunc.RunFunction((MethodInfo[])proc.value); } else { MethodInfo method = (MethodInfo)proc.value; if (method.IsGenericMethod) { ret = hFunc.RunFunction(new MethodInfo[] { method }); } else { ret = hFunc.RunFunction(); } } } } else if (proc.value is Delegate) { Delegate d = (Delegate)proc.value; MethodInfo method = d.Method; object[] arguments = parameters.ObjectArray; return(HostFunction.InvokeMethod(method, d.Target, arguments)); } return(ret); }
public static VAL propertyof(bool isRead, Type returnType, string propertyName, object host, object val) { PropertyInfo propertyInfo = getproperty(host, returnType, propertyName); if (isRead) { if (propertyInfo.CanRead) { return(VAL.Boxing1(propertyInfo.GetValue(host, null))); } else { return(new VAL()); } } else if (propertyInfo.CanWrite) { propertyInfo.SetValue(host, val, null); } return(VAL.VOID); }
/* * * .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); }
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); }
public static VAL HostTypeOffset(VAL R0, VAL R1, OffsetType offsetType) { if (R0.ty != VALTYPE.hostcon) { return(VAL.VOID); } object host = R0.value; object offset = R1.HostValue; object obj = null; Type type = null; if (host is Type) { type = (Type)host; if (!(offset is string)) { throw new HostTypeException("{0} offset {1} must be ident type.", type.FullName, offset); } if (type.IsEnum) { FieldInfo fieldInfo = type.GetField((string)offset); if (fieldInfo != null && fieldInfo.IsStatic) { return(VAL.Boxing1(fieldInfo.GetValue(host))); } else { throw new HostTypeException("enum {0} offset {1} is not enum type.", type.FullName, offset); } } if (offsetType == OffsetType.STRUCT || offsetType == OffsetType.ANY) { return(HostTypeOffsetMemberInfo(type, host, offset)); } } type = host.GetType(); if (offsetType == OffsetType.ANY || offsetType == OffsetType.ARRAY) { //abstract Array: IList, ICollection, IEumerable //interface IList : ICollection, IEumerable //interface ICollection : IEumerable if (type.IsArray) { Array array = (Array)host; if (offset is int) { if ((int)offset >= array.Length) { throw new HostTypeException("Array {0}[{1}] index is out of range[0..{2}].", host, offset, array.Length); } return(HostTypeOffsetBoxing(array.GetValue((int)offset), host, offset)); } else if (offset is int[]) { return(HostTypeOffsetBoxing(array.GetValue((int[])offset), host, offset)); } else { throw new HostTypeException("Array {0}.[{1}] subscript must be integer.", host.GetType().FullName, offset); } } if (host is IEnumerable && offset is int) { IEnumerable collection = (IEnumerable)host; int index = (int)offset; IEnumerator enumerator = collection.GetEnumerator(); bool end = false; int count = 0; for (int i = 0; i < index + 1; i++) { if (!enumerator.MoveNext()) { end = true; count = i; break; } } if (end && index >= count) { throw new HostTypeException("IEnumerable {0}[{1}] index is out of range[{2}].", host, offset, count); } if (!end) { return(HostTypeOffsetBoxing(enumerator.Current, host, offset)); } } { Type[] types; object[] objectArray; if (R1.ty == VALTYPE.listcon) { types = new Type[R1.Size]; for (int i = 0; i < types.Length; i++) { types[i] = R1[i].Type; } objectArray = R1.ObjectArray; } else { types = new Type[] { R1.Type }; objectArray = new object[] { offset }; } MethodInfo methodInfo = type.GetMethod("get_Item", types); if (methodInfo != null) { try { obj = methodInfo.Invoke(host, objectArray); if (obj != null) { return(HostTypeOffsetBoxing(obj, host, offset)); } } catch (Exception e) { if (offsetType == OffsetType.ARRAY) { throw e; } } } } if (offsetType == OffsetType.ARRAY) { return(VAL.VOID); } } if (offset is string) { return(HostTypeOffsetMemberInfo(type, host, offset)); } else { return(HostTypeOffsetBoxing(null, host, offset)); } }
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> /// Add object variable into data segment /// </summary> /// <param name="key"></param> /// <param name="v"></param> /// <returns></returns> public VAL AddObject(string key, object v) { return(Add(key, VAL.Boxing1(v))); }