예제 #1
0
        protected virtual object CompileIdentifier()
        {
            object res = CompileContextualIdentifier();

            if (res != null)
            {
                return(res);
            }
            else if (MatchToken(Token.Type.Identifier))
            {
                int     id      = _cdata._scopeResolver.Resolve(previous.text);
                TypeDef typeDef = null;
                Type    type    = typeof(object);
                if (id < 0)
                {
                    if (_contextType != null)
                    {
                        type    = ReflectionUtility.GetMemberDataType(_contextType, previous.text);
                        typeDef = _assembly.GetTypeDef(type);
                    }

                    return(new RunTimeReference(type, previous.text, (Func <object>)(() => { return _cdata._contextInterface.context; }), _contextType));
                }
                type = _cdata._environment[id].type;
                return(new CompileTimeReference(type, previous.text, id));
            }
            else
            {
                return(CompilePrimitive());
            }
        }
        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);
        }