Пример #1
0
        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());
        }
Пример #2
0
        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));
        }
Пример #3
0
        /// <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);
        }