Exemplo n.º 1
0
 protected ProtoCore.DSASM.AddressType GetOpType(ProtoCore.PrimitiveType type)
 {
     ProtoCore.DSASM.AddressType optype = ProtoCore.DSASM.AddressType.Int;
     // Data coercion for the prototype
     // The JIL executive handles int primitives
     if (ProtoCore.PrimitiveType.kTypeInt == type ||
         ProtoCore.PrimitiveType.kTypeBool == type ||
         ProtoCore.PrimitiveType.kTypeChar == type ||
         ProtoCore.PrimitiveType.kTypeString == type)
     {
         optype = ProtoCore.DSASM.AddressType.Int;
     }
     else if (ProtoCore.PrimitiveType.kTypeDouble == type)
     {
         optype = ProtoCore.DSASM.AddressType.Double;
     }
     else if (ProtoCore.PrimitiveType.kTypeVar == type)
     {
         optype = ProtoCore.DSASM.AddressType.VarIndex;
     }
     else if (ProtoCore.PrimitiveType.kTypeReturn == type)
     {
         optype = ProtoCore.DSASM.AddressType.Register;
     }
     else
     {
         Debug.Assert(false);
     }
     return(optype);
 }
Exemplo 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
        public int GetSymbolIndex(string name, int classScope, int functionScope, int blockId, Core core, out bool hasThisSymbol, out ProtoCore.DSASM.AddressType addressType)
        {
            hasThisSymbol = false;
            addressType   = ProtoCore.DSASM.AddressType.Invalid;

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

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

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

            int  myself = typeSystem.classTable.IndexOf(this.name);
            bool isInMemberFunctionContext = (classScope == myself) && (functionScope != ProtoCore.DSASM.Constants.kInvalidIndex);
            bool isInStaticFunction        = isInMemberFunctionContext && (vtable.procList[functionScope].isStatic);

            // Try for member function variables
            var blocks = core.GetAncestorBlockIdsOfBlock(blockId);

            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.AccessSpecifier.kPrivate);
                    if (isInStaticFunction)
                    {
                        isAccessible = isAccessible && symbol.isStatic;
                    }
                }
                else
                {
                    isAccessible = symbol.access == ProtoCore.CompilerDefinitions.AccessSpecifier.kPublic;
                }

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

            return(Constants.kInvalidIndex);
        }
Exemplo n.º 3
0
        protected bool DfsEmitIdentList(Node pNode, Node parentNode, int contextClassScope, ref ProtoCore.Type lefttype, ref int depth, ref ProtoCore.Type finalType, bool isLeftidentList, ref bool isFirstIdent, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            bool isRefFromIdentifier = false;

            dynamic node = pNode;

            if (node is ProtoCore.AST.ImperativeAST.IdentifierListNode || node is ProtoCore.AST.AssociativeAST.IdentifierListNode)
            {
                dynamic bnode = node;
                if (ProtoCore.DSASM.Operator.dot != bnode.Optr)
                {
                    throw new BuildHaltException();
                }

                isRefFromIdentifier = DfsEmitIdentList(bnode.LeftNode, bnode, contextClassScope, ref lefttype, ref depth, ref finalType, isLeftidentList, ref isFirstIdent, graphNode, subPass);

                if (lefttype.rank > 0)
                {
                    lefttype.UID = finalType.UID = (int)PrimitiveType.kTypeNull;
                    return(false);
                }
                node = bnode.RightNode;
            }

            if (node is ProtoCore.AST.ImperativeAST.IdentifierNode || node is ProtoCore.AST.AssociativeAST.IdentifierNode)
            {
                dynamic identnode = node;

                int ci = core.ClassTable.IndexOf(identnode.Value);
                if (ProtoCore.DSASM.Constants.kInvalidIndex != ci)
                {
                    finalType.UID = lefttype.UID = ci;
                }
                else if (identnode.Value == ProtoCore.DSDefinitions.Kw.kw_this)
                {
                    finalType.UID = lefttype.UID = contextClassScope;
                    depth++;
                    return(true);
                }
                else
                {
                    ProtoCore.DSASM.SymbolNode symbolnode = null;
                    bool isAllocated  = false;
                    bool isAccessible = false;
                    if (lefttype.UID != -1)
                    {
                        isAllocated = VerifyAllocation(identnode.Value, lefttype.UID, out symbolnode, out isAccessible);
                    }
                    else
                    {
                        isAllocated = VerifyAllocation(identnode.Value, contextClassScope, out symbolnode, out isAccessible);
                    }

                    bool callOnClass = false;
                    if (pNode is ProtoCore.AST.ImperativeAST.IdentifierListNode ||
                        pNode is ProtoCore.AST.AssociativeAST.IdentifierListNode)
                    {
                        dynamic leftnode = ((dynamic)pNode).LeftNode;
                        if (leftnode != null &&
                            (leftnode is ProtoCore.AST.ImperativeAST.IdentifierNode ||
                             leftnode is ProtoCore.AST.AssociativeAST.IdentifierNode))
                        {
                            string leftClassName = leftnode.Name;
                            int    leftci        = core.ClassTable.IndexOf(leftClassName);
                            if (leftci != ProtoCore.DSASM.Constants.kInvalidIndex)
                            {
                                callOnClass = true;

                                depth = depth + 1;
                            }
                        }
                    }

                    if (null == symbolnode)    //unbound identifier
                    {
                        if (isAllocated && !isAccessible)
                        {
                            lefttype.UID = finalType.UID = (int)PrimitiveType.kTypeNull;
                            return(false);
                        }

                        if (depth == 0)
                        {
                            lefttype.UID = finalType.UID = (int)PrimitiveType.kTypeNull;
                            return(false);
                        }
                        else
                        {
                            ProtoCore.DSASM.DyanmicVariableNode dynamicVariableNode = new ProtoCore.DSASM.DyanmicVariableNode(identnode.Value, globalProcIndex, globalClassIndex);
                            core.DynamicVariableTable.variableTable.Add(dynamicVariableNode);
                            int dim = 0;
                            if (null != identnode.ArrayDimensions)
                            {
                                dim = DfsEmitArrayIndexHeap(identnode.ArrayDimensions);
                            }
                            lefttype.UID = finalType.UID = (int)PrimitiveType.kTypeVar;
                            depth++;
                            return(true);
                        }
                    }
                    else
                    {
                        if (callOnClass && !symbolnode.isStatic)
                        {
                            lefttype.UID = finalType.UID = (int)PrimitiveType.kTypeNull;
                            return(false);
                        }
                    }
                    lefttype = symbolnode.datatype;

                    int dimensions = 0;

                    // Get the symbols' table index
                    int runtimeIndex = symbolnode.runtimeTableIndex;

                    ProtoCore.DSASM.AddressType operandType = ProtoCore.DSASM.AddressType.Pointer;

                    if (null != identnode.ArrayDimensions)
                    {
                        /* Remove static type checking
                         * if (lefttype.UID != (int)PrimitiveType.kTypeArray && !lefttype.IsIndexable)
                         *  buildStatus.LogWarning(BuildData.WarningID.kWarnMax, string.Format("'{0}' is not indexable at compile time", identnode.Name));
                         */
                        dimensions  = DfsEmitArrayIndexHeap(identnode.ArrayDimensions);
                        operandType = ProtoCore.DSASM.AddressType.ArrayPointer;
                    }

                    //update the rank
                    if (lefttype.rank >= 0)
                    {
                        lefttype.rank -= dimensions;
                        if (lefttype.rank < 0)
                        {
                            //throw new Exception("Exceed maximum rank!");
                            lefttype.rank = 0;
                        }
                    }

                    if (0 == depth || (symbolnode != null && symbolnode.isStatic))
                    {
                        if (ProtoCore.DSASM.Constants.kGlobalScope == symbolnode.functionIndex &&
                            ProtoCore.DSASM.Constants.kInvalidIndex != symbolnode.classScope)
                        {
                            // member var
                            operandType = symbolnode.isStatic ? ProtoCore.DSASM.AddressType.StaticMemVarIndex : ProtoCore.DSASM.AddressType.MemVarIndex;
                        }
                        else
                        {
                            operandType = ProtoCore.DSASM.AddressType.VarIndex;
                        }
                    }
                    depth     = depth + 1;
                    finalType = lefttype;
                }
                return(true);
            }
            else if (node is ProtoCore.AST.ImperativeAST.FunctionCallNode || node is ProtoCore.AST.AssociativeAST.FunctionCallNode)
            {
                TraverseFunctionCall(node, pNode, lefttype.UID, depth, ref finalType, graphNode, subPass);
                //finalType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : finalType.UID;
                lefttype = finalType;
                depth    = 1;
            }
            //else
            //{
            //    throw new BuildHaltException();
            //}
            return(false);
        }