public override Func <T> CreateGetFunction <T>(CompilerData cdata) { if (CompilerUtility.IsFunc(_targetObject)) { Func <object> targetFunc = _targetObject as Func <object>; return((Func <T>)(() => { ResolveArguments(_argNodeBuffer, ref _argBuffer, cdata); object targ = targetFunc(); if (targ.GetType() == typeof(System.Type)) { throw new Exception("Methods in the type System.Type cannot be accessed"); } return (T)_cdata._delegateCache.CallMethod(targetFunc(), _identifer, _argBuffer); })); } else { return((Func <T>)(() => { ResolveArguments(_argNodeBuffer, ref _argBuffer, cdata); return (T)_cdata._delegateCache.CallMethod(_targetObject, _identifer, _argBuffer); })); } }
protected virtual object CompileArrayAccess(object output) { // This is to handle the last identifier SetContextualIdentifierHandler(CompileLastKeyWord, output); object right = CompileArrowFunctionIndexer(output); ClearContextualIdentifierHandler(); Require(Token.Type.ClosingArrayIndex, "] Expected"); Func <object> rightFunc = CompilerUtility.ForceGetFunction(right, _cdata); if (rightFunc != null) { right = rightFunc; } Type type = CompilerUtility.GetReturnType(right); if (typeof(IList).IsAssignableFrom(type)) { output = CreateListAccessorReference(output, right); } else { output = CreateIntAccessorReference(output, right); } return(output); }
protected virtual object CompileCast() { if (MatchToken(Token.Type.Cast)) { Token op = previous; object right = CompileCast(); Type rightType = CompilerUtility.GetReturnType(right); bool isArray = op.text.Contains("[]"); if (isArray) { TypeDef typeDef = _assembly.GetTypeDef(op.text.Substring(0, op.text.Length - 2)); if (typeDef == null) { throw new Exception("Compilation Error: The specified type " + op.text + " was not found in the Assembly"); } return(typeDef.CastArray(right, _cdata)); } else { TypeDef typeDef = _assembly.GetTypeDef(op.text); if (typeDef == null) { throw new Exception("Compilation Error: The specified type " + op.text + " was not found in the Assembly"); } return(typeDef.Cast(right, _cdata)); } } return(CompilePostUnary()); }
protected virtual object CompileLastKeyWord(object left) { if (LookAhead(Token.Type.Dot, Token.Type.Identifier)) { if (_tokens[_index + 1].text == "last") { Step(); Step(); } Func <object> arrayFunc = CompilerUtility.ForceGetFunction(left, _cdata); if (arrayFunc == null) { return((Func <int>)(() => { return ((IList)left).Count - 1; })); } else { return((Func <int>)(() => { return ((IList)arrayFunc()).Count - 1; })); } } return(null); }
public override Func <T> CreateModifyFunction <T>(object value, CompilerData cdata, Token.Type operation) { Type rtype = CompilerUtility.GetReturnType(value); Operation.BinaryOperationDelegate del = cdata._assembly.GetBinaryOperation(operation, type, rtype); // This section was made for runtime type inference // May cause some weird issues, definitely check this out if there are problems if (del == null && type != typeof(Object) && rtype == typeof(Object)) { del = cdata._assembly.GetBinaryOperation(operation, type, type); } if (del == null && type == typeof(Object) && rtype != typeof(Object)) { del = cdata._assembly.GetBinaryOperation(operation, rtype, rtype); } if (del == null) { throw new CompilationException("Cannot perform the operation " + operation.ToString() + " on " + type.Name + " and " + rtype.Name); } object func = del(this, value, cdata); Type returnType = CompilerUtility.GetReturnType(func); TypeDef returnTypeDef = cdata._assembly.GetTypeDef(returnType); return(() => { object ob = returnTypeDef.CallFunction(func); cdata._environment[_environmentIndex].data = ob; return (T)ob; }); }
public override Func <T> CreateGetFunction <T>(CompilerData cdata) { Func <object> accessorFunc = CompilerUtility.ForceGetFunction <object>(_accessor, cdata); if (accessorFunc == null) { IList list = _accessor as IList; int accessorCount = list.Count; return(() => { IList arr = System.Array.CreateInstance(_elemType, accessorCount); for (int i = 0; i < accessorCount; i += 1) { arr[i] = ((IList)cdata._environment[_environmentIndex].data)[(int)list[i]]; } return (T)arr; }); } else { return(() => { IList list = accessorFunc() as IList; int accessorCount = list.Count; IList arr = System.Array.CreateInstance(_elemType, accessorCount); for (int i = 0; i < accessorCount; i += 1) { arr[i] = ((IList)cdata._environment[_environmentIndex].data)[(int)list[i]]; } return (T)arr; }); } }
public override Func <T> CreateGetFunction <T>(CompilerData cdata) { Func <object> accessorFunc = CompilerUtility.ForceGetFunction(_accessor, cdata); Func <object> targetFunc = (CompilerUtility.IsFunc(_targetObject)) ? (Func <object>)_targetObject : null; if (targetFunc == null && accessorFunc == null) { return(() => { return (T)((IList)_targetObject)[(int)_accessor]; }); } else if (targetFunc == null && accessorFunc != null) { return(() => { return (T)((IList)_targetObject)[(int)accessorFunc()]; }); } else if (targetFunc != null && accessorFunc == null) { return(() => { return (T)((IList)targetFunc())[(int)_accessor]; }); } else { return(() => { return (T)((IList)targetFunc())[(int)accessorFunc()]; }); } }
/// <summary> /// Main compilation entry /// </summary> /// <returns></returns> /// protected virtual CompiledScript _InternalCompile() { _cdata = new CompilerData(_assembly); List <Func <object> > functions = new List <Func <object> >(); while (!isAtEnd) { Func <object> function = null; object compiled = CompileDeclaration(); if (compiled == null) { continue; } Type returnType = CompilerUtility.GetReturnType(compiled); TypeDef typeDef = _assembly.GetTypeDef(returnType); if (CompilerUtility.IsFunc(compiled)) { if (compiled.GetType() != typeof(Func <object>)) { function = typeDef.ToGenericFunction(compiled, _cdata); } else { function = (Func <object>)compiled; } } else if (CompilerUtility.IsReference(compiled)) { function = ((Reference)compiled).CreateGetFunction(_cdata); } else { function = () => { return(compiled); }; } functions.Add(function); } Func <object>[] funcArray = functions.ToArray(); CompiledScript compiledScript = new CompiledScript(() => { object output = null; for (int mn = 0; mn < funcArray.Length; mn += 1) { output = funcArray[mn](); if ((_cdata._runtimeFlags & (int)CompilerData.ControlInstruction.Exit) != 0) { break; } } _cdata._runtimeFlags = 0; return(_cdata._returnValue); }, _cdata); return(compiledScript); }
private MethodInfo FindMethod(Type targetType, string identifier, object[] argumentNodes) { List <Type> typeList = new List <Type>(); for (int i = 0; i < argumentNodes.Length; i += 1) { typeList.Add(CompilerUtility.GetReturnType(argumentNodes[i])); } return(ReflectionUtility.FindMethod(targetType, identifier, typeList.ToArray())); }
protected virtual object CompileWhileStatement() { Require(Token.Type.OpenParenthesis, "Parenthesis Required"); object condition = CompileExpression(); Require(Token.Type.ClosingParethesis, ") Expected"); object statement = CompileDeclaration(); Func <object> whileFunc = null; Func <object> blockFunc = (Func <object>)statement; Func <bool> conditionFunc = CompilerUtility.ForceGetFunction <bool>(condition, _cdata); if (conditionFunc != null) { whileFunc = () => { while (conditionFunc()) { blockFunc(); if ((_cdata._runtimeFlags & (int)CompilerData.ControlInstruction.Break) != 0) { _cdata._runtimeFlags = 0; break; } if ((_cdata._runtimeFlags & (int)CompilerData.ControlInstruction.Exit) != 0) { return(null); } } return(null); }; } else { whileFunc = () => { while ((bool)condition) { blockFunc(); if ((_cdata._runtimeFlags & (int)CompilerData.ControlInstruction.Break) != 0) { _cdata._runtimeFlags = 0; break; } if ((_cdata._runtimeFlags & (int)CompilerData.ControlInstruction.Exit) != 0) { return(null); } } return(null); }; } return(whileFunc); }
protected virtual object CompileArrayLiteral() { if (MatchToken(Token.Type.ClosingArrayIndex)) { return(new object[0]); } List <object> list = new List <object>(); Type arrType = null; do { object elem = CompileAddition(); Type elemType = CompilerUtility.GetReturnType(elem); TypeDef elemTypeDef = _cdata._assembly.GetTypeDef(elemType, false); if (arrType == null) { arrType = elemType; } if (elemType == typeof(float) && arrType == typeof(int)) { arrType = typeof(float); } if (arrType != elemType) { if (!(arrType == typeof(float) && elemType == typeof(int)) && !(arrType == typeof(object) || elemType == typeof(object))) { throw new Exception("All elements must be the same type: " + elemType.Name + " is not " + arrType.Name); } } var elemFunc = CompilerUtility.ForceGetFunction(elem, _cdata); if (elemFunc != null) { elem = elemFunc; } list.Add(elem); } while (!isAtEnd && MatchToken(Token.Type.Comma)); TypeDef typeDef = _assembly.GetTypeDef(arrType, false); for (int i = 0; i < list.Count; i += 1) { list[i] = typeDef.Cast(list[i], _cdata); } Require(Token.Type.ClosingArrayIndex, "] Expected"); return(typeDef.CreateArrayLiteral(list.ToArray(), _cdata)); }
public MethodCall(Type t, string identifier, object target, object[] argumentNodes, CompilerData cdata, Type targetType) : base(t, identifier, target, targetType) { _returnType = (t != null) ? CompilerUtility.GetReturnType(t) : typeof(object); _cdata = cdata; _argNodeBuffer = (argumentNodes != null) ? argumentNodes : new object[0]; //_method = targetType.GetMethod(identifier); _argBuffer = new object[_argNodeBuffer.Length]; if (!ValidateArguments()) { throw new Exception("Arguments suppied do not match the spefied signaure: " + _identifer + _type.ToString()); } }
public MethodCall(MethodInfo methodInfo, object target, object[] argumentNodes, CompilerData cdata) : base(DelegateUtility.GetMethodType(methodInfo), methodInfo.Name, target, methodInfo.DeclaringType) { _method = methodInfo; _returnType = CompilerUtility.GetReturnType(DelegateUtility.GetMethodType(methodInfo)); _cdata = cdata; _argNodeBuffer = (argumentNodes != null) ? argumentNodes : new object[0]; _argBuffer = new object[_argNodeBuffer.Length]; if (!ValidateArguments()) { throw new Exception("Arguments suppied do not match the spefied signaure: " + _identifer + _type.ToString()); } }
public static Func <T> ForceGetFunction <T>(object refOrFunc, CompilerData cdata) { if (refOrFunc == null) { return(null); } else if (IsFunc(refOrFunc)) { if ((refOrFunc as Func <T>) != null) { return((Func <T>)refOrFunc); } else if ((refOrFunc as Func <object>) != null) { if (typeof(T) == typeof(object)) { return(() => { return (T)((Func <object>)refOrFunc)(); }); } else { return((Func <T>)refOrFunc); } } else { TypeDef typedef = cdata._assembly.GetTypeDef(CompilerUtility.GetReturnType(refOrFunc)); if (typedef != null) { Func <object> genFunc = typedef.ToGenericFunction(refOrFunc, cdata); if (typeof(T) == typeof(object)) { return(() => { return (T)genFunc(); }); } else { return((Func <T>)(object) genFunc); } } } throw new Exception("Cannot cast from " + refOrFunc.GetType().ToString() + " to " + typeof(Func <T>).ToString()); } else if (IsReference(refOrFunc)) { return(((Reference)refOrFunc).CreateGetFunction <T>(cdata)); } else { return(null); } }
public FunctionCall(Type t, string identifier, int envIndex, object[] argumentNodes, CompilerData cdata) : base(t, identifier, envIndex) { UnityEngine.Debug.Log("Creating Function"); _returnType = (t != null) ? CompilerUtility.GetReturnType(t) : typeof(object); _cdata = cdata; _argNodeBuffer = (argumentNodes != null) ? argumentNodes : new object[0]; _typeDef = _cdata._assembly.GetTypeDef(CompilerUtility.GetReturnType(t)); _argBuffer = new object[0]; //always zero, on a function call the variables are injected right into the envrionment array if (!ValidateArguments()) { throw new Exception("Arguments suppied do not match the spefied signaure: " + _identifer + _type.ToString()); } }
protected virtual object BuildFunctionCall(object callingFunction) { // For now, every function call is a runtime reference so we do not have to worry about the rest List <object> argList = new List <object>(); if (Peek().type != Token.Type.ClosingParethesis) { do { object expr = CompileExpression(); Func <object> func = null; //Type returnType = CompilerUtility.GetReturnType(expr); //TypeDef typeDef = _assembly.GetTypeDef(returnType); func = CompilerUtility.ForceGetFunction(expr, _cdata); if (func == null) { func = () => { return(expr); }; } argList.Add(func); } while (MatchToken(Token.Type.Comma)); } if (Step().type != Token.Type.ClosingParethesis) { throw new Exception(") expected after function call arguments"); } RunTimeReference callingReference = callingFunction as RunTimeReference; if (callingReference != null) { Func <object> targetFunc = CompilerUtility.ForceGetFunction(callingReference.targetObject, _cdata); if (targetFunc == null) { return(new MethodCall(callingReference.type, callingReference.identifer, callingReference.targetObject, argList.ToArray(), _cdata, callingReference.targetType)); } else { return(new MethodCall(callingReference.type, callingReference.identifer, targetFunc, argList.ToArray(), _cdata, callingReference.targetType)); } } CompileTimeReference compileTimeReference = callingFunction as CompileTimeReference; if (compileTimeReference != null) { return(new FunctionCall(compileTimeReference.type, compileTimeReference.identifer, compileTimeReference.environmentIndex, argList.ToArray(), _cdata)); } return(callingFunction); }
public virtual Func <object> ToGenericFunction(object arg, CompilerData _internal) { if (CompilerUtility.IsFunc(arg)) { if (type.IsSubclassOf(typeof(object))) { return((Func <object>)arg); } throw new InvalidCastException("Cannot cast " + type.Name + " to Func<object>"); } else { return(() => { return arg; }); } }
private object CompileDefaultBinaryOperator(Func <object> nextFunc, params Token.Type[] tokenTypes) { object left = nextFunc(); object output = null; while (MatchToken(tokenTypes)) { Token op = previous; int line = UpdateLineNumber(); object right = nextFunc(); if (output == null) { output = left; } Type ltype = CompilerUtility.GetReturnType(output); Type rtype = CompilerUtility.GetReturnType(right); Operation.BinaryOperationDelegate del = _assembly.GetBinaryOperation(op.type, ltype, rtype); // This section was made for runtime type inference // May cause some weird issues, definitely check this out if there are problems if (del == null && ltype != typeof(Object) && rtype == typeof(Object)) { del = _assembly.GetBinaryOperation(op.type, ltype, ltype); } if (del == null && ltype == typeof(Object) && rtype != typeof(Object)) { del = _assembly.GetBinaryOperation(op.type, rtype, rtype); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * if (del == null) { del = _assembly.GetBinaryOperation(op.type, typeof(Object), typeof(Object)); } if (del == null) { throw new CompilationException("[line " + line + "] Cannot perform the operation " + op.text + " on " + ltype.Name + " and " + rtype.Name); } output = del(output, right, _cdata); } return((output != null) ? (object)output : left); }
public override Func <T> CreateModifyFunction <T>(object value, CompilerData cdata, Token.Type operation) { Type rtype = CompilerUtility.GetReturnType(value); Operation.BinaryOperationDelegate del = cdata._assembly.GetBinaryOperation(operation, type, rtype); // This section was made for runtime type inference // May cause some weird issues, definitely check this out if there are problems if (del == null && type != typeof(Object) && rtype == typeof(Object)) { del = cdata._assembly.GetBinaryOperation(operation, type, type); } if (del == null && type == typeof(Object) && rtype != typeof(Object)) { del = cdata._assembly.GetBinaryOperation(operation, rtype, rtype); } if (del == null) { throw new CompilationException("Cannot perform the operation " + operation.ToString() + " on " + type.Name + " and " + rtype.Name); } Func <object> targetFunc = CompilerUtility.ForceGetFunction <object>(_targetObject, cdata); object func = del(this, value, cdata); Type returnType = CompilerUtility.GetReturnType(func); TypeDef returnTypeDef = cdata._assembly.GetTypeDef(returnType); if (targetFunc == null) { return(() => { object ob = returnTypeDef.CallFunction(func); return (T)RunTimeUtility.SetMemberValue(_targetObject, _identifer, cdata, ob); }); } else { return(() => { object ob = returnTypeDef.CallFunction(func); return (T)RunTimeUtility.SetMemberValue(targetFunc(), _identifer, cdata, ob); }); } }
protected virtual object CompileFunctionCall() { object left = CompileIdentifier(); object output = null; while (MatchToken(Token.Type.OpenParenthesis, Token.Type.Dot, Token.Type.IfDot, Token.Type.ArrayIndexBegin)) { Token.Type op = previous.type; int line = UpdateLineNumber(); if (output == null) { output = left; } Type leftType = CompilerUtility.GetReturnType(output); if (leftType == null) { throw RuntimeException.Create("Cannot call " + previous.text + " on NULL", line); } if (op == Token.Type.OpenParenthesis) { output = BuildFunctionCall(output); } else if (op == Token.Type.Dot) { Token identifier = Require(Token.Type.Identifier, "Identifier Expected"); Func <object> parentGetter = CompilerUtility.ForceGetFunction(output, _cdata); if (leftType != typeof(object)) { Type t = ReflectionUtility.GetMemberDataType(leftType, identifier.text); output = new RunTimeReference(t, identifier.text, parentGetter, leftType); } else { output = new RunTimeReference(typeof(object), identifier.text, parentGetter, typeof(object)); } } else if (op == Token.Type.ArrayIndexBegin) { output = CompileArrayAccess(output); } } return((output != null) ? (object)output : left); }
protected virtual object CompileUnary() { if (MatchToken(Token.Type.Not, Token.Type.Subtraction)) { Token op = previous; object right = CompileUnary(); Type rightType = CompilerUtility.GetReturnType(right); Operation.UnaryOperationDelegate del = _assembly.GetUnaryOperation(op.type, rightType); if (del == null) { throw new Exception("Cannot perform the operation " + op.text + " on " + rightType.Name); } return(del.Invoke(right, _cdata)); } return(CompileCast()); }
public override Func <T> CreateSetFunction <T>(object value, CompilerData cdata) { Func <object> accessorFunc = CompilerUtility.ForceGetFunction(_accessor, cdata); Func <T> valueFunc = CompilerUtility.ForceGetFunction <T>(value, cdata); if (valueFunc == null && accessorFunc == null) { T val = (T)value; return(() => { ((IList)(cdata._environment[_environmentIndex].data))[(int)_accessor] = val; return (T)val; }); } else if (valueFunc == null && accessorFunc != null) { T val = (T)value; return(() => { ((IList)(cdata._environment[_environmentIndex].data))[(int)accessorFunc()] = val; return (T)val; }); } if (valueFunc != null && accessorFunc == null) { return(() => { T val = (T)valueFunc(); ((IList)(cdata._environment[_environmentIndex].data))[(int)_accessor] = val; return (T)val; }); } else { return(() => { T val = (T)valueFunc(); ((IList)(cdata._environment[_environmentIndex].data))[(int)accessorFunc()] = val; return (T)val; }); } }
public override Func <T> CreateGetFunction <T>(CompilerData cdata) { Func <object> accessorFunc = CompilerUtility.ForceGetFunction <object>(_accessor, cdata); if (accessorFunc != null) { Type accessorFuncType = CompilerUtility.GetReturnType(accessorFunc); return(() => { return (T)((IList)cdata._environment[_environmentIndex].data)[(int)accessorFunc()]; }); } else { return(() => { return (T)((IList)cdata._environment[_environmentIndex].data)[(int)_accessor]; }); } }
protected virtual object CompilePostUnary() { object left = CompileFunctionCall(); object output = null; if (MatchToken(Token.Type.Increment, Token.Type.Decrement)) { Token op = previous; Type leftType = CompilerUtility.GetReturnType(left); Operation.UnaryOperationDelegate del = _assembly.GetUnaryOperation(op.type, leftType); if (del == null) { throw new Exception("Cannot perform the operation " + op.text + " on " + leftType.Name); } return(del.Invoke(left, _cdata)); } return((output != null) ? (object)output : left); }
public override Func <T> CreateSetFunction <T>(object value, CompilerData cdata) { if (CompilerUtility.IsFunc(value)) { Func <T> valueFunc = (Func <T>)value; return(() => { T ob = valueFunc(); //Type checking Type refType = cdata._environment[_environmentIndex].type; if (refType != typeof(Object) && refType != ob.GetType()) { throw new RuntimeException("data type does not match: " + refType.Name + " is not " + ob.GetType().Name); } //Assign data cdata._environment[_environmentIndex].data = ob; return (T)(cdata._environment[_environmentIndex].data); }); } else { T val = (T)value; return(() => { //Type checking Type refType = cdata._environment[_environmentIndex].type; if (refType != typeof(Object) && refType != val.GetType()) { throw new RuntimeException("data type does not match"); } //Assign data cdata._environment[_environmentIndex].data = val; return val; }); } }
public override Func <T> CreateSetFunction <T>(object value, CompilerData cdata) { Func <object> targetFunc = CompilerUtility.ForceGetFunction <object>(_targetObject, cdata); Func <T> valueFunc = CompilerUtility.ForceGetFunction <T>(value, cdata); if (targetFunc == null && valueFunc == null) { T val = (T)value; return(() => { return (T)RunTimeUtility.SetMemberValue(_targetObject, _identifer, cdata, val); }); } else if (targetFunc == null && valueFunc != null) { return(() => { return (T)RunTimeUtility.SetMemberValue(_targetObject, _identifer, cdata, valueFunc()); }); } else if (targetFunc != null && valueFunc == null) { T val = (T)value; return(() => { return (T)RunTimeUtility.SetMemberValue(targetFunc(), _identifer, cdata, val); }); } else { return(() => { return (T)RunTimeUtility.SetMemberValue(targetFunc(), _identifer, cdata, valueFunc()); }); } }
protected virtual object CompileBlockStatement() { List <Func <object> > functions = new List <Func <object> >(); _cdata._scopeResolver.Push(); while (!isAtEnd && Peek().type != Token.Type.CloseBlock) { object compiled = CompileDeclaration(); Func <object> function = CompilerUtility.ForceGetFunction(compiled, _cdata); if (function == null) { function = () => { return(compiled); }; } functions.Add(function); } Func <object>[] funcArray = functions.ToArray(); Func <object> block = () => { object output = null; for (int mn = 0; mn < funcArray.Length; mn += 1) { output = funcArray[mn](); if ((_cdata._runtimeFlags & (int)CompilerData.ControlInstruction.Break) != 0) { break; } } return(output); }; Require(Token.Type.CloseBlock, "Closing } Expected"); _cdata._scopeResolver.Pop(); return(block); }
protected virtual object CompileHelpStatement() { if (isAtEnd || Peek().type == Token.Type.EOS) { return((Func <object>)(() => { string meta = ReflectionUtility.PrintMembers(_cdata._contextInterface.context); _cdata._exit(meta); return meta; })); } Func <object> func = null; object statement = CompileExpressionStatement(); if (statement == null) { return((Func <object>)(() => { return null; })); } Type returnType = CompilerUtility.GetReturnType(statement); TypeDef typedef = _assembly.GetTypeDef(returnType); if (CompilerUtility.IsFunc(statement)) { if (returnType != typeof(object)) { func = typedef.ToGenericFunction(statement, _cdata); } else { func = (Func <object>)statement; } return((Func <object>)(() => { object val = ReflectionUtility.PrintMembers(func()); _cdata._exit(val); return val; })); } else if (CompilerUtility.IsReference(statement)) { func = ((Reference)statement).CreateGetFunction(_cdata); return((Func <object>)(() => { object val = ReflectionUtility.PrintMembers(func()); _cdata._exit(val); return val; })); } else { return((Func <object>)(() => { _cdata._exit(ReflectionUtility.PrintMembers(statement)); return statement; })); } }
protected virtual object CompileDimensionalIndexer() { object left = CompileExpression(); object output = left; if (MatchToken(Token.Type.Colon)) { Type leftType = CompilerUtility.GetReturnType(left); if (leftType != typeof(Int32) && leftType != typeof(object)) { throw new Exception("Function is not supported for type: " + leftType.Name); } List <object> integerList = new List <object>(); object right = CompileExpression(); Type rightType = CompilerUtility.GetReturnType(right); if (rightType != typeof(Int32) && rightType != typeof(object)) { throw new Exception("Function is not supported for type: " + rightType.Name); } Func <int> leftFunc = CompilerUtility.ForceGetFunction <int>(left, _cdata); if (leftFunc != null) { left = leftFunc; } integerList.Add(left); Func <int> rightFunc = CompilerUtility.ForceGetFunction <int>(right, _cdata); if (rightFunc != null) { right = rightFunc; } integerList.Add(right); while (MatchToken(Token.Type.Comma)) { left = CompileExpression(); leftFunc = CompilerUtility.ForceGetFunction <int>(left, _cdata); if (leftFunc != null) { left = leftFunc; } integerList.Add(left); if (MatchToken(Token.Type.Colon)) { right = CompileExpression(); rightFunc = CompilerUtility.ForceGetFunction <int>(right, _cdata); if (rightFunc != null) { right = rightFunc; } integerList.Add(right); } } return((Func <int>)(() => { int total = 0; int dimensionSize = 1; int count = integerList.Count; for (int i = 0; i < count; i += 2) { Func <int> lFunc = integerList[i] as Func <int>; if (lFunc != null) { total += lFunc() * dimensionSize; } else { Debug.Log(integerList[i]); total += (int)integerList[i] * dimensionSize; } if (i + 1 < count) { Func <int> rFunc = integerList[i + 1] as Func <int>; if (rFunc != null) { dimensionSize *= rFunc(); } else { dimensionSize *= (int)integerList[i + 1]; } } } return total; })); } return(output); }
protected virtual object CompileForStatement() { _cdata._scopeResolver.Push(); Require(Token.Type.OpenParenthesis, "( Expected"); object initializer = CompileDeclaration(); object condition = CompileAssignment(); Require(Token.Type.EOS, "; Expected"); object incrementor = CompileExpression(); Require(Token.Type.ClosingParethesis, ") Expected"); Require(Token.Type.OpenBlock, "{ Expected"); Func <object> initFunction = CompilerUtility.ForceGetFunction(initializer, _cdata); Func <bool> conditionFunction = CompilerUtility.ForceGetFunction <bool>(condition, _cdata); Func <object> incrementorFunction = CompilerUtility.ForceGetFunction(incrementor, _cdata); if (initFunction == null && initializer != null) { initFunction = () => { return(initializer); }; } if (conditionFunction == null) { if (condition != null) { conditionFunction = () => { return((bool)condition); }; } else { conditionFunction = () => { return(true); }; } } if (incrementorFunction == null && incrementor != null) { incrementorFunction = () => { return(incrementor); }; } if (CompilerUtility.GetReturnType(conditionFunction) != typeof(bool)) { throw new Exception("for loop condition must be a bool"); } List <Func <object> > functions = new List <Func <object> >(); while (!isAtEnd && Peek().type != Token.Type.CloseBlock) { object compiled = CompileDeclaration(); Func <object> function = CompilerUtility.ForceGetFunction(compiled, _cdata); if (function == null && compiled != null) { function = () => { return(compiled); }; } functions.Add(function); } Func <object>[] funcArray = functions.ToArray(); Func <object> block = () => { object output = null; for (int mn = 0; mn < funcArray.Length; mn += 1) { output = funcArray[mn](); if ((_cdata._runtimeFlags & (int)CompilerData.ControlInstruction.Break) != 0) { break; } if ((_cdata._runtimeFlags & (int)CompilerData.ControlInstruction.Continue) != 0) { _cdata._runtimeFlags = 0; break; } if ((_cdata._runtimeFlags & (int)CompilerData.ControlInstruction.Exit) != 0) { return(null); } } return(output); }; Func <object> forFunc = () => { for (initFunction(); conditionFunction(); incrementorFunction()) { block(); if ((_cdata._runtimeFlags & (int)CompilerData.ControlInstruction.Break) != 0) { _cdata._runtimeFlags = 0; break; } if ((_cdata._runtimeFlags & (int)CompilerData.ControlInstruction.Exit) != 0) { return(null); } } return(null); }; Require(Token.Type.CloseBlock, "} Expected"); _cdata._scopeResolver.Pop(); return(forFunc); }