private static VAL HostTypeOffsetMemberInfo(Type type, object host, object offset) { object obj = null; if (offset.Equals("FullName")) { return(new VAL(type.FullName)); } FieldInfo fieldInfo = type.GetField((string)offset); if (fieldInfo != null) { obj = fieldInfo.GetValue(host); return(HostTypeOffsetBoxing(obj, host, offset)); } PropertyInfo propertyInfo = type.GetProperty((string)offset); if (propertyInfo != null) { if (propertyInfo.CanRead) { obj = propertyInfo.GetValue(host, null); } return(HostTypeOffsetBoxing(obj, host, offset)); } MethodInfo[] methods = HostFunction.OverloadingMethods(type, (string)offset); if (methods.Length > 0) { if (methods.Length == 1) { return(HostTypeOffsetBoxing(methods[0], host, offset)); } return(HostTypeOffsetBoxing(methods, host, offset)); } EventInfo eventInfo = type.GetEvent((string)offset); if (eventInfo != null) { return(HostTypeOffsetBoxing(eventInfo, host, offset)); } return(VAL.VOID); }
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 OperatorOverloading(Operator opr, VAL v1, VAL v2, bool silent) { VALL L = new VALL(); L.Add(v1); if ((object)v2 != null) { L.Add(v2); } HostFunction hFunc = new HostFunction(v1.value, opr.ToString(), L); if (silent) { return(hFunc.RunFunctionSilently(null)); } else { return(hFunc.RunFunction(null)); } }
public static int HostCompareTo(Operator opr, VAL v1, VAL v2) { if (v1.ty != VALTYPE.hostcon || v2.ty != VALTYPE.hostcon) { throw new HostTypeException("cannot compare different type value {0} and {1}.", v1, v2); } object x1 = v1.value; object x2 = v2.value; if (x1 == null && x2 == null) { return(0); } if (x1 != null && x2 == null) { if (x1.GetType().IsValueType) { throw new HostTypeException("cannot compare value type {0} to null.", x1); } else { return(1); } } else if (x1 == null && x2 != null) { if (x2.GetType().IsValueType) { throw new HostTypeException("cannot compare value type {0} to null.", x2); } else { return(-1); } } if (x1 is Type && x2 is Type) { if ((Type)x1 == (Type)x2) { return(0); } else { return(-1); } } else if (!(x1 is Type) && (x2 is Type) || (x1 is Type) && !(x2 is Type)) { throw new HostTypeException("cannot compare type to non-type: {0} and {1}.", x1, x2); } Type type1 = x1.GetType(); Type type2 = x2.GetType(); if (type1.IsValueType && type2.IsValueType) { if (System.ValueType.Equals(x1, x2)) { return(0); } } Type[] I = type1.GetInterfaces(); if (I.Length != 0) { foreach (Type i in I) { if (i == typeof(IComparable)) { return((x1 as IComparable).CompareTo(x2)); } } } I = type2.GetInterfaces(); if (I.Length != 0) { foreach (Type i in I) { if (i == typeof(IComparable)) { return((x2 as IComparable).CompareTo(x1)); } } } //operator overloading >, >=, <, <=, !=, == VAL comp = HostFunction.OperatorOverloading(opr, v1, v2, true); if ((object)comp != null) { switch (opr) { case Operator.op_LessThan: return(comp.Boolcon? -1: 10); case Operator.op_Equality: return(comp.Boolcon ? 0 : 10); case Operator.op_GreaterThan: return(comp.Boolcon ? 1 : -10); } } Type type = HostCoding.CommonBaseClass(new object[] { x1, x2 }); if (type != null) { if (x1 == x2) { return(0); } } throw new HostTypeException("cannot compare value {0} and {1} without implement IComparable.", x1, x2); }
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); }