예제 #1
0
        protected void TraceScope(string msg)
        {
            string     lead   = new String(' ', (_callCount - 1) * 2);
            StackScope scope  = _callStack[_callCount - 1];
            string     output = lead + "Scope[" + (_callCount - 1) + "] VSS=" + scope.varStackStart + (scope.terminal ? " TERMINAL" : "") + " - Name='" + scope.name + "'";

            if (null != scope.funcType)
            {
                output += " functype(" + scope.funcType.ToString() + ")";
            }
            else if (null != scope.classInstance)
            {
                output += " @(" + scope.classInstance.classDef.name + ")";
            }
            Console.WriteLine(output + " by='" + msg + "'");
            //Console.WriteLine(lead + "C" + _callCount + " - " + msg);
        }
예제 #2
0
        // BIG IMPORTANT FUNCTION.
        // Searches the current call stack for a variable with the given name and returns a VarStackRef,
        // which can be used by GetVarAtIndex to find the variable, usually later at execution time.
        // This saves us from having to do string searches for variables at execution time, but also
        // adds a lot of complexity to the system. Since the idea is to create these Refs during
        // TypeCheck, any discrepancy between the order scopes are pushed/popped and variables created
        // between TypeCheck and Evaluate WILL result in a grave error.
        public VarStackRef GetVarIndexByName(ExecContext context, string name, bool stopAtTerminals = false)
        {
            bool onlyUnique = false;
            int  callIx     = _callCount;
            int  varIx      = _varCount - 1;

            while (--callIx >= 0)
            {
                StackScope scope = _callStack[callIx];

                if (!onlyUnique && null != scope.classInstance)
                {
                    // If this scope is a class function call, search that class for
                    // a member with that name.
                    ITypeDef  typeDef = null;
                    MemberRef memRef  = _callStack[callIx].classInstance.classDef.GetMemberRef(context, name, scope.isStatic ? ClassDef.SEARCH.STATIC : ClassDef.SEARCH.EITHER, ref typeDef);
                    if (!memRef.isInvalid)
                    {
                        return(new VarStackRef(typeDef, callIx - _callCount, memRef));
                    }
                }

                if (!onlyUnique && null != scope.classDef)
                {
                    ITypeDef  typeDef = null;
                    MemberRef memRef  = _callStack[callIx].classDef.GetMemberRef(context, name, scope.isStatic ? ClassDef.SEARCH.STATIC : ClassDef.SEARCH.EITHER, ref typeDef);
                    if (!memRef.isInvalid)
                    {
                        return(new VarStackRef(typeDef, callIx - _callCount, memRef));
                    }
                }

                // Otherwise, search the variable stack for it.
                while (varIx >= scope.varStackStart)
                {
                    if (null != _varStack[varIx] && _varStack[varIx].name == name)
                    {
                        Variable var = _varStack[varIx];
                        if (var.unique)
                        {
                            return(new VarStackRef(var, false));
                        }
                        else if (!onlyUnique)
                        {
                            return(new VarStackRef(_varStack[varIx].type, callIx - _callCount, varIx - scope.varStackStart));
                        }
                        else
                        {
                            return(new VarStackRef(VarStackRef.ErrorType.NonUnique));
                        }
                    }
                    --varIx;
                }

                if (scope.hardTerminal)
                {
                    break;
                }

                if (scope.terminal)
                {
                    if (stopAtTerminals)
                    {
                        break;
                    }
                    else
                    {
                        onlyUnique = true;
                    }
                }
            }

            // Search globals last. Globals are always in scope.
            int globIx = _globals.GetIndex(name);

            if (globIx >= 0)
            {
                Variable var = _globals.Get(globIx);
                return(new VarStackRef(var, true));
            }

            return(new VarStackRef(VarStackRef.ErrorType.NotFound));
        }
예제 #3
0
        public override string ToString()
        {
            string res = "";

            int count = _globals.Count;

            res += "GLOBALS:\n";
            for (int ii = 0; ii < count; ++ii)
            {
                Variable var = _globals.Get(ii);
                if (var.type is TypeDef_Function)
                {
                    res += "  " + ((TypeDef_Function)var.type).GetDebugString(var.name);
                }
                else
                {
                    res += GetVariableString(var);
                }
            }

            res += "STACK: varCount = " + _varCount + ", callCount = " + _callCount + "\n";
            if (_callCount > 0)
            {
                for (int iVar = 0; iVar <= _callStack[0].varStackStart - 1; ++iVar)
                {
                    Variable var = _varStack[iVar];
                    res += GetVariableString(var);
                }

                for (int iCall = 0; iCall < _callCount; ++iCall)
                {
                    StackScope scope = _callStack[iCall];
                    if (scope.terminal)
                    {
                        res += "  *** " + scope.name + " ***\n";
                    }
                    else
                    {
                        res += "  --- " + scope.name + " ---\n";
                    }

                    int startIndex = scope.varStackStart;
                    int endIndex;
                    if (iCall < _callCount - 1)
                    {
                        endIndex = _callStack[iCall + 1].varStackStart - 1;
                    }
                    else
                    {
                        endIndex = _varCount - 1;
                    }

                    for (int iVar = startIndex; iVar <= endIndex; ++iVar)
                    {
                        Variable var = _varStack[iVar];
                        res += "  " + GetVariableString(var);
                    }
                }
            }
            else
            {
                for (int iVar = 0; iVar < _varCount; ++iVar)
                {
                    Variable var = _varStack[iVar];
                    res += "  " + GetVariableString(var);
                }
            }

            return(res);
        }