Ejemplo n.º 1
0
        public static int GetSymbolIndex(ClassNode classNode, string name, int classScope, int functionScope, int blockId, List <CodeBlock> codeblocks, out bool hasThisSymbol, out ProtoCore.DSASM.AddressType addressType)
        {
            var dict = new SortedDictionary <int, CodeBlock>();

            codeblocks.ForEach(x => dict.Add(x.codeBlockId, x));

            return(GetSymbolIndex(classNode, name, classScope, functionScope, blockId, dict, out hasThisSymbol, out addressType));
        }
Ejemplo n.º 2
0
        // classScope is a global context, it tells we are in which class's scope
        // functionScope is telling us which function we are in.
        //
        // 1. Try to find if the target is a member function's local variable
        //        classScope != kInvalidIndex && functionScope != kInvalidIndex;
        //
        // 2. Try to find if the target is a member variable
        //     2.1 In a member functions classScope != kInvalidIndex && functionScope != kInvalidIndex.
        //         Returns member in derived class, or non-private member in base classes
        //
        //     2.2 In a global functions classScope == kInvalidIndex && functionScope != kInvalidIndex.
        //         Returns public member in derived class, or public member in base classes
        //
        //     2.3 Otherwise, classScope == kInvalidIndex && functionScope == kInvalidIndex
        //         Return public member in derived class, or public member in base classes
        internal static int GetSymbolIndex(ClassNode classNode, string name, int classScope, int functionScope, int blockId, SortedDictionary <int, CodeBlock> codeblocks, out bool hasThisSymbol, out ProtoCore.DSASM.AddressType addressType)
        {
            hasThisSymbol = false;
            addressType   = ProtoCore.DSASM.AddressType.Invalid;

            if (classNode.Symbols == null)
            {
                return(ProtoCore.DSASM.Constants.kInvalidIndex);
            }

            IEnumerable <SymbolNode> allSymbols = classNode.Symbols.GetNodeForName(name);

            if (allSymbols == null)
            {
                return(ProtoCore.DSASM.Constants.kInvalidIndex);
            }

            int  myself = classNode.TypeSystem.classTable.IndexOf(classNode.Name);
            bool isInMemberFunctionContext = (classScope == myself) && (functionScope != ProtoCore.DSASM.Constants.kInvalidIndex);
            bool isInStaticFunction        = isInMemberFunctionContext &&
                                             classNode.ProcTable.Procedures.Count > functionScope &&
                                             classNode.ProcTable.Procedures[functionScope].IsStatic;

            // Try for member function variables
            var blocks = GetAncestorBlockIdsOfBlock(blockId, codeblocks);

            blocks.Insert(0, blockId);

            Dictionary <int, SymbolNode> symbolOfBlockScope = new Dictionary <int, SymbolNode>();

            foreach (var memvar in allSymbols)
            {
                if ((isInMemberFunctionContext) && (memvar.functionIndex == functionScope))
                {
                    symbolOfBlockScope[memvar.codeBlockId] = memvar;
                }
            }
            if (symbolOfBlockScope.Count > 0)
            {
                foreach (var blockid in blocks)
                {
                    if (symbolOfBlockScope.ContainsKey(blockid))
                    {
                        hasThisSymbol = true;
                        addressType   = AddressType.VarIndex;
                        return(symbolOfBlockScope[blockid].symbolTableIndex);
                    }
                }
            }

            // Try for member variables.
            var candidates = new List <SymbolNode>();

            foreach (var memvar in allSymbols)
            {
                if (memvar.functionIndex == ProtoCore.DSASM.Constants.kGlobalScope)
                {
                    candidates.Add(memvar);
                }
            }
            // Sort candidates descending based on their class scopes so that
            // we can search member variable in reverse order of hierarchy tree.
            candidates.Sort((lhs, rhs) => rhs.classScope.CompareTo(lhs.classScope));
            hasThisSymbol = candidates.Count > 0;

            foreach (var symbol in candidates)
            {
                bool isAccessible = false;
                if (isInMemberFunctionContext)
                {
                    isAccessible = (symbol.classScope == myself) || (symbol.access != ProtoCore.CompilerDefinitions.AccessModifier.Private);
                    if (isInStaticFunction)
                    {
                        isAccessible = isAccessible && symbol.isStatic;
                    }
                }
                else
                {
                    isAccessible = symbol.access == ProtoCore.CompilerDefinitions.AccessModifier.Public;
                }

                if (isAccessible)
                {
                    addressType = symbol.isStatic ? AddressType.StaticMemVarIndex : AddressType.MemVarIndex;
                    return(symbol.symbolTableIndex);
                }
            }

            return(Constants.kInvalidIndex);
        }