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 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)); }
/// <summary> /// Compile function declaration /// </summary> /// <param name="type"></param> /// <param name="identifier"></param> /// <returns></returns> protected virtual object CompileFunctionDeclaration(TypeDef type, string identifier, bool isArray = false) { string tempIdentifier = identifier; Require(Token.Type.OpenParenthesis, "( Expected"); // Prebind the function to support recursion //_cdata._environment.Add(type.Cast((Func<object>)(() => { return null; }), _cdata)); //int refIndex = _cdata._environment.Count - 1; //_cdata._scopeResolver.Add(identifier, refIndex); // Push local function scope _cdata._scopeResolver.AddScopeStack(tempIdentifier); _cdata._scopeResolver.SetScopeByID(tempIdentifier); // Process arguments if (Peek().type != Token.Type.ClosingParethesis) { int arrCount = 0; do { CompileFunctionArgumentDeclaration(); arrCount += 1; }while (MatchToken(Token.Type.Comma)); _cdata._scopeResolver.localArgumentCount = arrCount; } else { _cdata._scopeResolver.localArgumentCount = 0; } // continue function Require(Token.Type.ClosingParethesis, ") Expected"); List <Func <object> > functions = new List <Func <object> >(); Require(Token.Type.OpenBlock, "{ Expected"); while (!isAtEnd && Peek().type != Token.Type.CloseBlock) { object compiled = CompileDeclaration(false); Func <object> function = CompilerUtility.ForceGetFunction(compiled, _cdata); if (function == null && compiled != null) { function = () => { return(compiled); }; } if (function != null) { functions.Add(function); } } _cdata._scopeResolver.SetScopeByID(ScopeResolver.GLOBAL_ID); Require(Token.Type.CloseBlock, "} Expected"); 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 ^= (int)CompilerData.ControlInstruction.Continue; break; } if ((_cdata._runtimeFlags & (int)CompilerData.ControlInstruction.Exit) != 0) { _cdata._runtimeFlags ^= (int)CompilerData.ControlInstruction.Exit; return(_cdata._returnValue); } } return(output); }; object func; if (isArray) { func = type.CastArray(block, _cdata); } else { func = type.Cast(block, _cdata); } int refIndex = _cdata.AddMemoryObject(func); _cdata._scopeResolver.Add(identifier, refIndex); return(null); }