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);
        }
        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 CreateListAccessorReference(object output, object accessor)
        {
            if (output as RunTimeReference != null)
            {
                RunTimeReference reference = output as RunTimeReference;
                object           target    = reference.CreateGetFunction(_cdata);

                if (reference.type == null || reference.type == typeof(object))
                {
                    output = new RunTimeArrayAccessReferenceListAccess(typeof(object), reference.identifer, target, accessor, typeof(object));
                }
                else
                {
                    output = new RunTimeArrayAccessReferenceListAccess(reference.type, reference.identifer, target, accessor, reference.targetType);
                }
            }
            else if (output as FunctionCall != null || output as MethodCall != null || output as CompileTimeArrayAccessReference != null)
            {
                Reference reference = output as Reference;
                object    target    = reference.CreateGetFunction(_cdata);
                if (reference.type == null || reference.type == typeof(object))
                {
                    output = new RunTimeArrayAccessReferenceListAccess(typeof(object), reference.identifer, target, accessor, typeof(object));
                }
                else
                {
                    output = new RunTimeArrayAccessReferenceListAccess(reference.type, reference.identifer, target, accessor, reference.type);
                }
            }
            else if (output as CompileTimeReference != null)
            {
                CompileTimeReference reference = output as CompileTimeReference;

                if (reference.type == null || reference.type == typeof(object))
                {
                    output = new CompileTimeArrayAccessReferenceListAccess(typeof(object), reference.identifer, reference.environmentIndex, accessor);
                }
                else
                {
                    output = new CompileTimeArrayAccessReferenceListAccess(reference.type, reference.identifer, reference.environmentIndex, accessor);
                }
            }
            return(output);
        }