private SpokeObject evaluate(SpokeMethod fm, SpokeObject parent, SpokeObject[] paras) { #if Stacktrace dfss.AppendLine(fm.MethodName); #endif SpokeObject[] variables = new SpokeObject[fm.NumOfVars]; for (int i = 0; i < fm.Parameters.Length; i++) { variables[i] = paras[i]; } var sm = new SpokeMethodRun(); sm.RunningClass = parent; return evaluateLines(fm.Lines, sm, variables); }
private SpokeObject evaluateLines(SpokeLine[] lines, SpokeMethodRun currentObject, SpokeObject[] variables) { #if Stacktrace File.WriteAllText("C:\\mna.txt", dfss.ToString()); #endif foreach (var spokeLine in lines) { #if Stacktrace dfss.AppendLine(spokeLine.ToString()); #endif switch (spokeLine.LType) { case ISpokeLine.If: var b = evalute(((SpokeIf)spokeLine).Condition, currentObject, variables); if (b.BoolVal) { var df = evaluateLines(((SpokeIf)spokeLine).IfLines, currentObject, variables); if (df != null) { return df; } } else { if (((SpokeIf)spokeLine).ElseLines != null) { var df = evaluateLines(((SpokeIf)spokeLine).ElseLines, currentObject, variables); if (df != null) { return df; } } } break; case ISpokeLine.Return: if (((SpokeReturn)spokeLine).Return == null) { return NULL; } return evalute(((SpokeReturn)spokeLine).Return, currentObject, variables); break; //case ISpokeLine.Yield: // currentObject.ForYield.Add(evalute(((SpokeYield)spokeLine).Yield, currentObject, variables)); // break; //case ISpokeLine.YieldReturn: // SpokeObject d; // currentObject.ForYield.Add(d = evalute(((SpokeYieldReturn)spokeLine).YieldReturn, currentObject, variables)); // return d; // break; case ISpokeLine.MethodCall: evalute((SpokeItem)spokeLine, currentObject, variables, true); break; case ISpokeLine.AnonMethod: var arm = evalute((SpokeItem)spokeLine, currentObject, variables, true); if (arm != null && !((SpokeAnonMethod)spokeLine).SpecAnon) { return arm; } break; case ISpokeLine.Construct: return evalute((SpokeItem)spokeLine, currentObject, variables); break; case ISpokeLine.Set: var grf = ((SpokeEqual)spokeLine); var right = evalute(grf.RightSide, currentObject, variables); SpokeObject left; switch (right.Type) { case ObjectType.Null: break; case ObjectType.Int: left = evalute(grf.LeftSide, currentObject, variables); left.Type = ObjectType.Int; left.IntVal = right.IntVal; break; case ObjectType.String: left = evalute(grf.LeftSide, currentObject, variables); left.Type = ObjectType.String; left.StringVal = right.StringVal; break; case ObjectType.Float: left = evalute(grf.LeftSide, currentObject, variables); left.Type = ObjectType.Float; left.FloatVal = right.FloatVal; break; case ObjectType.Bool: left = evalute(grf.LeftSide, currentObject, variables); left.Type = ObjectType.Bool; left.BoolVal = right.BoolVal; break; case ObjectType.Array: left = evalute(grf.LeftSide, currentObject, variables); left.Type = ObjectType.Array; left.ArrayItems = new List<SpokeObject>(right.ArrayItems); break; case ObjectType.Object: left = evalute(grf.LeftSide, currentObject, variables); left.Type = ObjectType.Object; left.Variables = (SpokeObject[])right.Variables.Clone(); break; case ObjectType.Method: left = evalute(grf.LeftSide, currentObject, variables); left.Type = ObjectType.Method; left.AnonMethod = right.AnonMethod; left.Variables = right.Variables; break; default: throw new ArgumentOutOfRangeException(); } break; default: throw new ArgumentOutOfRangeException(); } } return null; }
private SpokeObject evalute(SpokeItem condition, SpokeMethodRun currentObject, SpokeObject[] variables, bool parentIsNull = false) { #if Stacktrace dfss.AppendLine(condition.ToString()); #endif SpokeObject r; SpokeObject l; switch (condition.IType) { case ISpokeItem.Array: var ar = new SpokeObject() { Type = ObjectType.Array}; ar.ArrayItems = new List<SpokeObject>(20); foreach (var spokeItem in ((SpokeArray)condition).Parameters) { var grb = evalute(spokeItem, currentObject, variables); if (grb.Type == ObjectType.Array) ar.ArrayItems.AddRange(grb.ArrayItems); else ar.ArrayItems.Add(grb); } return ar; break; case ISpokeItem.Float: return new SpokeObject() { FloatVal = ((SpokeFloat)condition).Value, Type = ObjectType.Float }; break; case ISpokeItem.Int: return intCache(((SpokeInt)condition).Value); break; case ISpokeItem.String: return new SpokeObject() { StringVal = ((SpokeString)condition).Value, Type = ObjectType.String }; break; case ISpokeItem.Bool: return ((SpokeBool)condition).Value ? TRUE : FALSE; break; case ISpokeItem.Variable: SpokeObject g; SpokeVariable mv = ((SpokeVariable)condition); if (mv.Parent != null) { var ca = evalute(mv.Parent, currentObject, variables); return ca.GetVariable(mv.VariableIndex, mv.ForSet); } if (mv.This) { g = currentObject.RunningClass.Variables[mv.VariableIndex]; if (g == null) { return currentObject.RunningClass.Variables[mv.VariableIndex] = new SpokeObject(); } if (mv.ForSet) { return currentObject.RunningClass.Variables[mv.VariableIndex] = new SpokeObject(); } return g; } if ((g = variables[mv.VariableIndex]) != null) { if (mv.ForSet) { return variables[mv.VariableIndex] = new SpokeObject(); } return g; } return variables[((SpokeVariable)condition).VariableIndex] = new SpokeObject(); break; case ISpokeItem.ArrayIndex: var pa = evalute(((SpokeArrayIndex)condition).Parent, currentObject, variables); var ind = evalute(((SpokeArrayIndex)condition).Index, currentObject, variables); if (ind.Type == ObjectType.String) { throw new AbandonedMutexException("hmmmm"); if (((SpokeArrayIndex)condition).ForSet) { var drb = new SpokeObject(); // pa.Variables[ind.StringVal] = drb; return drb; } // return pa.Variables[ind.StringVal]; } if (ind.Type == ObjectType.Array) { specialIndeces = new List<int>(ind.ArrayItems.Count); foreach (var spokeObject in ind.ArrayItems) { specialIndeces.Add(spokeObject.IntVal); } return pa; } if (((SpokeArrayIndex)condition).ForSet) { var drb = new SpokeObject(); pa.ArrayItems[ind.IntVal] = drb; return drb; } return pa.ArrayItems[ind.IntVal]; break; case ISpokeItem.Current: return currentObject.RunningClass; break; case ISpokeItem.Null: return NULL; break; case ISpokeItem.AnonMethod: if (((SpokeAnonMethod)condition).HasYield || ((SpokeAnonMethod)condition).HasYieldReturn) { if (((SpokeAnonMethod)condition).ReturnYield != null) { var d = evalute(((SpokeAnonMethod)condition).ReturnYield, currentObject, variables); d.ArrayItems = new List<SpokeObject>(); d.Type = ObjectType.Array; } } if (((SpokeAnonMethod)condition).Parent != null) { #if Stacktrace dfss.AppendLine(((SpokeAnonMethod)condition).Parent.ToString()); #endif var rl = evalute(((SpokeAnonMethod)condition).Parent, currentObject, variables); SpokeMethodRun df; if (((SpokeAnonMethod)condition).RunOnVar != null) { df = new SpokeMethodRun() { RunningClass = evalute(((SpokeAnonMethod)condition).RunOnVar, currentObject, variables) }; if (df.RunningClass.AnonMethod != null) { var d = evalute(df.RunningClass.AnonMethod.ReturnYield, currentObject, variables); d.ArrayItems = new List<SpokeObject>(); d.Type = ObjectType.Array; } } else { df = new SpokeMethodRun() { RunningClass = currentObject.RunningClass }; } if (rl.Type == ObjectType.Array) { if (rl.ArrayItems.Count == 0) { if (((SpokeAnonMethod)condition).HasReturn) { return NULL; } else { } } if (specialIndeces != null) { foreach (var item in specialIndeces) { var spokeObject = rl.ArrayItems[item]; if (((SpokeAnonMethod)condition).RunOnVar != null) { for (int i = 0; i < df.RunningClass.AnonMethod.Parameters.Count(); i++) { variables[i] = spokeObject; if (df.RunningClass.AnonMethod.Parameters[i].ByRef) { spokeObject.ByRef = true; } } var rme = evaluateLines(df.RunningClass.AnonMethod.Lines, df, variables); if (rme != null) if (df.RunningClass.AnonMethod.HasReturn) { //for (int i = 0; i < df.RunningClass.AnonMethod.Parameters.Count(); i++) //{ // variables.Remove(df.RunningClass.AnonMethod.Parameters[i].Name); //} return rme; } //for (int i = 0; i < df.RunningClass.AnonMethod.Parameters.Count(); i++) //{ // var c = df.RunningClass.AnonMethod.Parameters[i].Name; // variables[c].ByRef = false; // variables.Remove(c); //} } else { if (((SpokeAnonMethod)condition).Parameters != null) { variables[((SpokeAnonMethod)condition).Parameters[0].Index] = spokeObject; if (((SpokeAnonMethod)condition).Parameters.Length == 2) variables[((SpokeAnonMethod)condition).Parameters[1].Index] = intCache(item); } var rme = evaluateLines(((SpokeAnonMethod)condition).Lines, df, variables); //yield return if (rme != null) if (((SpokeAnonMethod)condition).HasReturn) { return rme; } } } specialIndeces = null; } else { var vmr = rl.ArrayItems.ToArray(); for (int index = 0; index < vmr.Length; index++) { var spokeObject = vmr[index]; if (((SpokeAnonMethod)condition).RunOnVar != null) { for (int i = 0; i < df.RunningClass.AnonMethod.Parameters.Count(); i++) { variables[df.RunningClass.AnonMethod.Parameters[i].Index] = spokeObject; if (df.RunningClass.AnonMethod.Parameters[i].ByRef) { spokeObject.ByRef = true; } } var rme = evaluateLines(df.RunningClass.AnonMethod.Lines, df, variables); if (rme != null) if (df.RunningClass.AnonMethod.HasReturn) { //for (int i = 0; i < df.RunningClass.AnonMethod.Parameters.Count(); i++) //{ // variables.Remove(df.RunningClass.AnonMethod.Parameters[i].Name); //} return rme; } //for (int i = 0; i < df.RunningClass.AnonMethod.Parameters.Count(); i++) //{ // var c = df.RunningClass.AnonMethod.Parameters[i].Name; // variables[c].ByRef = false; // variables.Remove(c); //} } else { if (((SpokeAnonMethod)condition).Parameters != null) { variables[((SpokeAnonMethod)condition).Parameters[0].Index] = spokeObject; if (((SpokeAnonMethod)condition).Parameters.Length == 2) variables[((SpokeAnonMethod)condition).Parameters[1].Index] = intCache(index); } var rme = evaluateLines(((SpokeAnonMethod)condition).Lines, df, variables); //yield return if (rme != null && rme.Type != ObjectType.Null) if (((SpokeAnonMethod)condition).HasReturn) { return rme; } } } } } else if (rl.Type == ObjectType.Bool) { g: if (rl.BoolVal) { var def = evaluateLines(((SpokeAnonMethod)condition).Lines, df, variables); if (def != null) { if (((SpokeAnonMethod)condition).HasReturn) { return def; } } rl = evalute(((SpokeAnonMethod)condition).Parent, currentObject, variables); goto g; } } if (((SpokeAnonMethod)condition).ReturnYield != null) { return evalute(((SpokeAnonMethod)condition).ReturnYield, currentObject, variables); } if (df.RunningClass.AnonMethod != null) { var d = evalute(df.RunningClass.AnonMethod.ReturnYield, currentObject, variables); return d; } if (((SpokeAnonMethod)condition).HasReturn) { return null; return new SpokeObject() { Type = ObjectType.Null };//should have returned earlier } } else { return new SpokeObject() { Type = ObjectType.Method, AnonMethod = new SpokeObjectMethod() { ReturnYield = ((SpokeAnonMethod)condition).ReturnYield, Lines = ((SpokeAnonMethod)condition).Lines, Parameters = ((SpokeAnonMethod)condition).Parameters, HasReturn = ((SpokeAnonMethod)condition).HasReturn, } }; } break; case ISpokeItem.MethodCall: var gf = ((SpokeMethodCall)condition); if (gf.Parent is SpokeAnonMethod) { for (int index = 1; index < gf.Parameters.Length; index++) { var spokeItem = gf.Parameters[index]; SpokeObject eh; variables[((SpokeAnonMethod)gf.Parent).Parameters[index - 1].Index] = eh = evalute(spokeItem, currentObject, variables); eh.ByRef = ((SpokeAnonMethod)gf.Parent).Parameters[index - 1].ByRef; } var fd = evaluateLines(((SpokeAnonMethod)gf.Parent).Lines, currentObject, variables); if (!parentIsNull) { return fd; } else { //Console.Write("Hmm"); } } else { var d = ((SpokeVariable)gf.Parent); if (d.Parent == null) { SpokeMethod meth; SpokeObject[] parms; switch (d.VType) { case SpokeVType.V: if ((g = variables[d.VariableIndex]) != null && g.Type == ObjectType.Method) { for (int i = 0; i < g.AnonMethod.Parameters.Count(); i++) { SpokeObject cg; variables[g.AnonMethod.Parameters[i].Index] = cg = evalute(gf.Parameters[i + 1], currentObject, variables); cg.ByRef = g.AnonMethod.Parameters[i].ByRef; } if (g.AnonMethod.ReturnYield != null) { var dr = evalute(g.AnonMethod.ReturnYield, currentObject, variables); dr.ArrayItems = new List<SpokeObject>(); dr.Type = ObjectType.Array; } var rme = evaluateLines(g.AnonMethod.Lines, currentObject, variables); if (g.AnonMethod.ReturnYield != null) { return evalute(g.AnonMethod.ReturnYield, currentObject, variables); } return rme; } break; case SpokeVType.MethodName: meth = Methods[d.VariableIndex]; parms = new SpokeObject[gf.Parameters.Length]; for (int i = 0; i < parms.Length; i++) { parms[i] = evalute(gf.Parameters[i], currentObject, variables); } return evaluate(meth, currentObject.RunningClass, parms); break; case SpokeVType.InternalMethodName: parms = new SpokeObject[gf.Parameters.Length]; for (int i = 0; i < parms.Length; i++) { parms[i] = evalute(gf.Parameters[i], currentObject, variables); } return InternalMethods[d.VariableIndex](parms); break; case SpokeVType.ThisV: if ((g = currentObject.RunningClass.Variables[d.VariableIndex]) != null && g.Type == ObjectType.Method) { for (int i = 0; i < g.AnonMethod.Parameters.Count(); i++) { SpokeObject cg; variables[g.AnonMethod.Parameters[i].Index] = cg = evalute(gf.Parameters[i + 1], currentObject, variables); cg.ByRef = g.AnonMethod.Parameters[i].ByRef; } var rme = evaluateLines(g.AnonMethod.Lines, currentObject, variables); return rme; } break; default: throw new ArgumentOutOfRangeException(); } } else { var pp = evalute(d.Parent, currentObject, variables); var meth =Methods[d.VariableIndex]; if (meth != null) { if (meth.MethodFunc != null) { var gm = new SpokeObject[gf.Parameters.Length]; gm[0] = pp; for (int index = 1; index < gf.Parameters.Length; index++) { gm[index] = evalute(gf.Parameters[index], currentObject, variables); } return meth.MethodFunc(gm); } else { var parms = new SpokeObject[gf.Parameters.Length]; parms[0] = pp; for (int i = 1; i < parms.Length; i++) { parms[i] = evalute(gf.Parameters[i], currentObject, variables); } return evaluate(meth, pp, parms); } } if (pp.TryGetVariable(d.VariableIndex, out g) && g.Type == ObjectType.Method) { for (int i = 0; i < g.AnonMethod.Parameters.Count(); i++) { SpokeObject cg; variables[g.AnonMethod.Parameters[i].Index] = cg = evalute(gf.Parameters[i + 1], currentObject, variables); cg.ByRef = g.AnonMethod.Parameters[i].ByRef; } var rme = evaluateLines(g.AnonMethod.Lines, new SpokeMethodRun() { RunningClass = pp }, variables); return rme; } else throw new AbandonedMutexException("no method: " + d.VariableName); } } break; case ISpokeItem.Construct: var cons = new SpokeObject(); cons.Type = ObjectType.Object; var rf = (SpokeConstruct)condition; if (rf.MethodIndex >=0) { var fd =Methods[rf.MethodIndex]; cons.Variables = new SpokeObject[rf.NumOfVars]; var parms = new SpokeObject[fd.NumOfVars]; parms[0] = cons; for (int i = 1; i < rf.Parameters.Length + 1; i++) { parms[i] = evalute(rf.Parameters[i - 1], currentObject, variables); } evaluate(fd, cons, parms); } else { cons.Variables = new SpokeObject[rf.SetVars.Length]; } for (int index = 0; index < rf.SetVars.Length; index++) { SVarItems spokeItem = rf.SetVars[index]; cons.Variables[spokeItem.Index] = evalute(spokeItem.Item, currentObject, variables); } return cons; break; case ISpokeItem.Addition: l = evalute(((SpokeAddition)condition).LeftSide, currentObject, variables); r = evalute(((SpokeAddition)condition).RightSide, currentObject, variables); switch (l.Type) { case ObjectType.Int: switch (r.Type) { case ObjectType.Int: return intCache(l.IntVal + r.IntVal); break; case ObjectType.Float: return new SpokeObject() { FloatVal = l.IntVal + r.FloatVal, Type = r.Type }; break; case ObjectType.String: return new SpokeObject() { StringVal = l.IntVal + r.StringVal, Type = r.Type }; break; default: throw new ArgumentOutOfRangeException(); } break; case ObjectType.Float: switch (r.Type) { case ObjectType.Int: return new SpokeObject() { FloatVal = l.FloatVal + r.IntVal, Type = l.Type }; break; case ObjectType.Float: return new SpokeObject() { FloatVal = l.FloatVal + r.FloatVal, Type = l.Type }; break; case ObjectType.String: return new SpokeObject() { StringVal = l.FloatVal + r.StringVal, Type = r.Type }; break; default: throw new ArgumentOutOfRangeException(); } break; case ObjectType.String: switch (r.Type) { case ObjectType.Int: return new SpokeObject() { StringVal = l.StringVal + r.IntVal, Type = l.Type }; break; case ObjectType.Float: return new SpokeObject() { StringVal = l.StringVal + r.FloatVal, Type = l.Type }; break; case ObjectType.String: return new SpokeObject() { StringVal = l.StringVal + r.StringVal, Type = l.Type }; break; default: throw new ArgumentOutOfRangeException(); } break; default: throw new ArgumentOutOfRangeException(); } break; case ISpokeItem.Subtraction: l = evalute(((SpokeSubtraction)condition).LeftSide, currentObject, variables); r = evalute(((SpokeSubtraction)condition).RightSide, currentObject, variables); switch (l.Type) { case ObjectType.Int: switch (r.Type) { case ObjectType.Int: return intCache(l.IntVal- r.IntVal); break; case ObjectType.Float: return new SpokeObject() { FloatVal = l.IntVal - r.FloatVal, Type = r.Type }; break; default: throw new ArgumentOutOfRangeException(); } break; case ObjectType.Float: switch (r.Type) { case ObjectType.Int: return new SpokeObject() { FloatVal = l.FloatVal - r.IntVal, Type = l.Type }; break; case ObjectType.Float: return new SpokeObject() { FloatVal = l.FloatVal - r.FloatVal, Type = l.Type }; break; default: throw new ArgumentOutOfRangeException(); } break; default: throw new ArgumentOutOfRangeException(); } break; case ISpokeItem.Multiplication: l = evalute(((SpokeMultiplication)condition).LeftSide, currentObject, variables); r = evalute(((SpokeMultiplication)condition).RightSide, currentObject, variables); switch (l.Type) { case ObjectType.Int: switch (r.Type) { case ObjectType.Int: return intCache(l.IntVal * r.IntVal); break; case ObjectType.Float: return new SpokeObject() { FloatVal = l.IntVal * r.FloatVal, Type = r.Type }; break; default: throw new ArgumentOutOfRangeException(); } break; case ObjectType.Float: switch (r.Type) { case ObjectType.Int: return new SpokeObject() { FloatVal = l.FloatVal * r.IntVal, Type = l.Type }; break; case ObjectType.Float: return new SpokeObject() { FloatVal = l.FloatVal * r.FloatVal, Type = l.Type }; break; default: throw new ArgumentOutOfRangeException(); } break; default: throw new ArgumentOutOfRangeException(); } break; case ISpokeItem.Division: l = evalute(((SpokeDivision)condition).LeftSide, currentObject, variables); r = evalute(((SpokeDivision)condition).RightSide, currentObject, variables); switch (l.Type) { case ObjectType.Int: switch (r.Type) { case ObjectType.Int: return intCache(l.IntVal /r.IntVal); break; case ObjectType.Float: return new SpokeObject(l.IntVal / r.FloatVal) ; break; default: throw new ArgumentOutOfRangeException(); } break; case ObjectType.Float: switch (r.Type) { case ObjectType.Int: return new SpokeObject(l.FloatVal / r.IntVal) ; break; case ObjectType.Float: return new SpokeObject(l.FloatVal / r.FloatVal) ; break; default: throw new ArgumentOutOfRangeException(); } break; default: throw new ArgumentOutOfRangeException(); } break; case ISpokeItem.Greater: l = evalute(((SpokeGreaterThan)condition).LeftSide, currentObject, variables); r = evalute(((SpokeGreaterThan)condition).RightSide, currentObject, variables); switch (l.Type) { case ObjectType.Int: switch (r.Type) { case ObjectType.Int: return l.IntVal > r.IntVal?TRUE:FALSE; break; case ObjectType.Float: return l.IntVal > r.FloatVal ? TRUE : FALSE; break; default: throw new ArgumentOutOfRangeException(); } break; case ObjectType.Float: switch (r.Type) { case ObjectType.Int: return l.FloatVal > r.IntVal?TRUE:FALSE; break; case ObjectType.Float: return l.FloatVal > r.FloatVal?TRUE:FALSE; break; default: throw new ArgumentOutOfRangeException(); } break; default: throw new ArgumentOutOfRangeException(); } break; case ISpokeItem.Less: l = evalute(((SpokeLessThan)condition).LeftSide, currentObject, variables); r = evalute(((SpokeLessThan)condition).RightSide, currentObject, variables); switch (l.Type) { case ObjectType.Int: switch (r.Type) { case ObjectType.Int: return l.IntVal < r.IntVal ? TRUE : FALSE; break; case ObjectType.Float: return l.IntVal < r.FloatVal?TRUE:FALSE; break; default: throw new ArgumentOutOfRangeException(); } break; case ObjectType.Float: switch (r.Type) { case ObjectType.Int: return l.FloatVal < r.IntVal?TRUE:FALSE; break; case ObjectType.Float: return l.FloatVal < r.FloatVal?TRUE:FALSE; break; default: throw new ArgumentOutOfRangeException(); } break; default: throw new ArgumentOutOfRangeException(); } break; case ISpokeItem.And: l = evalute(((SpokeAnd)condition).LeftSide, currentObject, variables); if (l.BoolVal) { r = evalute(((SpokeAnd)condition).RightSide, currentObject, variables); return r.BoolVal?TRUE:FALSE; } return FALSE; break; case ISpokeItem.Or: l = evalute(((SpokeOr)condition).LeftSide, currentObject, variables); if (l.BoolVal) { return TRUE; } r = evalute(((SpokeOr)condition).RightSide, currentObject, variables); return r.BoolVal?TRUE:FALSE; break; case ISpokeItem.GreaterEqual: l = evalute(((SpokeGreaterThanOrEqual)condition).LeftSide, currentObject, variables); r = evalute(((SpokeGreaterThanOrEqual)condition).RightSide, currentObject, variables); switch (l.Type) { case ObjectType.Int: switch (r.Type) { case ObjectType.Int: return l.IntVal >= r.IntVal?TRUE:FALSE; break; case ObjectType.Float: return l.IntVal >= r.FloatVal?TRUE:FALSE; break; default: throw new ArgumentOutOfRangeException(); } break; case ObjectType.Float: switch (r.Type) { case ObjectType.Int: return l.FloatVal >= r.IntVal?TRUE:FALSE; break; case ObjectType.Float: return l.FloatVal >= r.FloatVal?TRUE:FALSE; break; default: throw new ArgumentOutOfRangeException(); } break; default: throw new ArgumentOutOfRangeException(); } break; case ISpokeItem.LessEqual: l = evalute(((SpokeLessThanOrEqual)condition).LeftSide, currentObject, variables); r = evalute(((SpokeLessThanOrEqual)condition).RightSide, currentObject, variables); switch (l.Type) { case ObjectType.Int: switch (r.Type) { case ObjectType.Int: return l.IntVal <= r.IntVal?TRUE:FALSE; break; case ObjectType.Float: return l.IntVal <= r.FloatVal?TRUE:FALSE; break; default: throw new ArgumentOutOfRangeException(); } break; case ObjectType.Float: switch (r.Type) { case ObjectType.Int: return l.FloatVal <= r.IntVal?TRUE:FALSE; break; case ObjectType.Float: return l.FloatVal <= r.FloatVal?TRUE:FALSE; break; default: throw new ArgumentOutOfRangeException(); } break; default: throw new ArgumentOutOfRangeException(); } break; case ISpokeItem.Equality: l = evalute(((SpokeEquality)condition).LeftSide, currentObject, variables); r = evalute(((SpokeEquality)condition).RightSide, currentObject, variables); return SpokeObject.Compare(l, r)?TRUE:FALSE; break; case ISpokeItem.NotEqual: l = evalute(((SpokeNotEqual)condition).LeftSide, currentObject, variables); r = evalute(((SpokeNotEqual)condition).RightSide, currentObject, variables); return SpokeObject.Compare(l, r)?FALSE:TRUE; default: throw new ArgumentOutOfRangeException(); } return null; }