public static Array ToArray(Mixed m) { if (m is Boolean) { Array a = new Array(); a.Append(m); return a; } else if (m is Integer) { Array a = new Array(); a.Append(m); return a; } else if (m is Double) { Array a = new Array(); a.Append(m); return a; } else if (m is String) { Array a = new Array(); a.Append(m); return a; } else if (m is Array) return (Array)m; else if (m is Object) { Array result = new Array(); foreach (FieldInfo f in m.GetType().GetFields()) { // don't use the internal fields __id and __maxId if (f.Name != "__id" && f.Name != "__maxId") { String name; if (f.Name.StartsWith("$")) name = new String(f.Name.Substring(1, f.Name.Length - 1)); else name = new String(f.Name); Mixed value = (Mixed)f.GetValue(m); result.Append(name, value); } } return result; } else if (m is Null) return new Array(); else return new Array(); }
public static Mixed LoadFromClassMember(Mixed classObject, Mixed classMemberName) { string classMemberNameString = Convert.ToString(classMemberName).value; // check if an Object was passed if (!(classObject is Object)) { Report.Warn(403); return new Null(); } // load FieldInfo fi = classObject.GetType().GetField(classMemberNameString); if (fi == null) { Report.Warn(207, classMemberNameString); return new Null(); } else { Mixed result = (Mixed)fi.GetValue(classObject); return Refresh(result); } }
public static Mixed InvokeFunction(Mixed classObject, ArrayList parametersSupplied, Mixed functionName) { string functionNameString = Convert.ToString(functionName).value; // check if an Object was passed if (!(classObject is Object)) { Report.Warn(405); return new Null(); } // invoke MethodInfo mi = classObject.GetType().GetMethod(functionNameString); if (mi == null) { Report.Warn(214, functionNameString); return new Null(); } else { // pass parameters (only as many as needed) int parametersNeeded = mi.GetParameters().Length; object[] parametersPassed = new object[parametersNeeded]; int i = 0; for (; i < Math.Min(parametersNeeded, parametersSupplied.Count); i++) parametersPassed[i] = parametersSupplied[i]; // if less parameters actually passed then necessary, pass Null objects instead for (; i < parametersNeeded; i++) parametersPassed[i] = new Null(); // add function call to trace AddFunctionCallToTrace(classObject.GetType().Name + "->" + functionNameString); // invoke Mixed result = (Mixed)mi.Invoke(classObject, parametersPassed); // remove function call to trace RemoveFunctionCallFromTrace(); // push return value return result; } }
public static Boolean IsIdentical(Mixed m1, Mixed m2) { // if both operands are arrays, check identity on array pairs if (m1 is Array && m2 is Array) { Array a1 = (Array)m1; Array a2 = (Array)m2; if (a1.keys.Count != a2.keys.Count) return new Boolean(false); for (int i = 0; i < a1.keys.Count; i++) { if (!IsIdentical((Mixed)a1.keys[i], (Mixed)a2.keys[i]).value) return new Boolean(false); if ((int)a1.values[i] != (int)a2.values[i]) return new Boolean(false); } return new Boolean(true); } // if both operands are objects, check identity on instances else if (m1 is Object && m2 is Object) { int id1 = ((Object)m1).__id; int id2 = ((Object)m2).__id; return new Boolean(id1 == id2); } // otherwise perform regular identity check else { if (m1.GetType() == m2.GetType()) return IsEqual(m1, m2); else return new Boolean(false); } }
public static Mixed Clone(Mixed m) { if (m is Boolean) return new Boolean(((Boolean)m).value); else if (m is Integer) return new Integer(((Integer)m).value); else if (m is Double) return new Double(((Double)m).value); else if (m is String) return new String(((String)m).value); else if (m is Array) { Array a = (Array)m; Mixed clonedKey; int clonedValue; ArrayList clonedKeys = new ArrayList(); ArrayList clonedValues = new ArrayList(); for (int i = 0; i < a.keys.Count; i++) { clonedKey = Clone((Mixed)a.keys[i]); clonedValue = (int)a.values[i]; clonedKeys.Add(clonedKey); clonedValues.Add(clonedValue); } return new Array(clonedKeys, clonedValues); } else if (m is Object) { // find constructor of object to be cloned ConstructorInfo ctor = null; foreach(ConstructorInfo ci in m.GetType().GetConstructors()) { if (!ci.IsStatic) ctor = ci; } int parameterCount = ctor.GetParameters().Length; object[] parameters = new object[parameterCount]; for (int i = 0; i < parameters.Length; i++) parameters[i] = new Null(); // set the standard out to nowhere to avoid output when calling the constructor right now Console.SetOut(nowhere); // create new instance Object result = (Object)Activator.CreateInstance(m.GetType(), parameters); // set field values foreach (FieldInfo f in m.GetType().GetFields()) { // don't use the internal fields __id and __placeOnHeap if (f.Name != "__id" && f.Name != "__placeOnHeap") f.SetValue(result, f.GetValue(m)); } // if a __clone function is available, invoke MethodInfo clone = m.GetType().GetMethod("__clone", Type.EmptyTypes); if (clone != null) { clone.Invoke(result, null); } // reset the standard output Console.SetOut(stdOut); return result; } else if (m is Null) return new Null(); else return new Null(); }
public static void StoreToClassMember(Mixed classObject, Mixed value, Mixed classMemberName) { string classMemberNameString = Convert.ToString(classMemberName).value; // check if an Object was passed if (!(classObject is Object)) { Report.Warn(403); return; } // store FieldInfo fi = classObject.GetType().GetField(classMemberNameString); if (fi == null) { Report.Warn(207, classMemberNameString); return; } else { // determine place on heap if (value.__placeOnHeap == 0) { Mixed oldObject = (Mixed)fi.GetValue(classObject); if (oldObject.__placeOnHeap == 0) value.__placeOnHeap = ++maxPlaceOnHeap; else value.__placeOnHeap = (int)oldObject.__placeOnHeap; } // add variable to variable pool fi.SetValue(classObject, value); // store value to heap heap[value.__placeOnHeap] = value; } }