Esempio n. 1
0
        /// <summary>
        /// VM Debugging API for general Debugging purposes
        /// temporarily used by Cmmand Line REPL
        /// </summary>
        /// <returns></returns>
        public string GetCoreDump()
        {
            // Prints out the final Value of every symbol in the program
            // Traverse order:
            //  Exelist, Globals symbols

            StringBuilder globaltrace = null;

            ProtoCore.DSASM.Executive exec = runnerCore.CurrentExecutive.CurrentDSASMExec;
            ProtoCore.DSASM.Mirror.ExecutionMirror execMirror = new ProtoCore.DSASM.Mirror.ExecutionMirror(exec, runnerCore);
            ProtoCore.DSASM.Executable             exe        = exec.rmem.Executable;

            // Only display symbols defined in the default top-most langauge block;
            // Otherwise garbage information may be displayed.
            string formattedString = string.Empty;

            if (exe.runtimeSymbols.Length > 0)
            {
                int blockId = 0;

                ProtoCore.DSASM.SymbolTable symbolTable = exe.runtimeSymbols[blockId];

                for (int i = 0; i < symbolTable.symbolList.Count; ++i)
                {
                    //int n = symbolTable.symbolList.Count - 1;
                    //formatParams.ResetOutputDepth();
                    ProtoCore.DSASM.SymbolNode symbolNode = symbolTable.symbolList[i];

                    bool isLocal  = ProtoCore.DSASM.Constants.kGlobalScope != symbolNode.functionIndex;
                    bool isStatic = (symbolNode.classScope != ProtoCore.DSASM.Constants.kInvalidIndex && symbolNode.isStatic);
                    if (symbolNode.isArgument || isLocal || isStatic || symbolNode.isTemp)
                    {
                        // These have gone out of scope, their values no longer exist
                        //return ((null == globaltrace) ? string.Empty : globaltrace.ToString());
                        continue;
                    }

                    ProtoCore.Runtime.RuntimeMemory rmem = exec.rmem;
                    ProtoCore.DSASM.StackValue      sv   = rmem.GetStackData(blockId, i, ProtoCore.DSASM.Constants.kGlobalScope);
                    formattedString = formattedString + string.Format("{0} = {1}\n", symbolNode.name, execMirror.GetStringValue(sv, rmem.Heap, blockId));

                    //if (null != globaltrace)
                    //{
                    //    int maxLength = 1020;
                    //    while (formattedString.Length > maxLength)
                    //    {
                    //        globaltrace.AppendLine(formattedString.Substring(0, maxLength));
                    //        formattedString = formattedString.Remove(0, maxLength);
                    //    }

                    //    globaltrace.AppendLine(formattedString);
                    //}
                }

                //formatParams.ResetOutputDepth();
            }

            //return ((null == globaltrace) ? string.Empty : globaltrace.ToString());
            return(formattedString);
        }
Esempio n. 2
0
 protected void AllocateVar(ProtoCore.DSASM.SymbolNode symbol)
 {
     symbol.isArray = false;
     if (ProtoCore.DSASM.MemoryRegion.kMemHeap == symbol.memregion)
     {
         SetHeapData(symbol);
     }
     SetStackIndex(symbol);
 }
Esempio n. 3
0
        /// <summary>
        /// This method traverses an identifier list, like a.b.c.d and returns the type of "d"
        /// it also has an out parameter isStatic, this indicates if the type is Static,
        /// for example: if you are searching for A, A is a class name, then the isStatic will be true
        /// otherwize it will be false
        /// </summary>
        /// <param name="idents">ident list, if you are searching the type of a.b.c, you should pass it { a, b, c }</param>
        /// <param name="si">the scope of the ident list</param>
        /// <param name="cp">the location of the ident list</param>
        /// <param name="isStatic"></param>
        /// <returns></returns>
        private static int TraverseIdentList(string[] idents, int depth, ScopeInfo si, ProtoCore.CodeModel.CodePoint cp, out bool isStatic)
        {
            isStatic = false;
            if (idents.Length == 0 || depth > idents.Length)
            {
                return(ProtoCore.DSASM.Constants.kInvalidIndex);
            }

            string firstIdentifier = idents[0];
            int    finalType       = GetArrayElementType(si, firstIdentifier);

            if (finalType == ProtoCore.DSASM.Constants.kInvalidIndex)
            {
                if (firstIdentifier.IndexOfAny(new char[] { '[', ']' }) != -1)
                {
                    string[] tokens = TokenizeArrayIndexers(firstIdentifier);
                    firstIdentifier = tokens[0];
                }

                // this will get the type of the first identifier in the identifier list (a in  a.b.c.d)
                // it is special because it is plain variables,     ( a is plain variable)
                // and all the followings are class member variabls ( b, c, and d are all class member variables)
                finalType = GetIdentType(si, firstIdentifier, cp);
            }

            if (finalType == ProtoCore.DSASM.Constants.kInvalidIndex)
            {
                // cannot find a variable named "a"
                // check if there is a class named "a:,
                // if there is return its class index as final type
                // and set isStatic to true
                // we are only interested in its static members and constructors now
                finalType = compileState.ClassTable.IndexOf(idents[0]);
                isStatic  = true;
            }
            if (finalType == ProtoCore.DSASM.Constants.kInvalidIndex)
            {
                return(ProtoCore.DSASM.Constants.kInvalidIndex);
            }

            // iterate through all the remaining identifiers, (b c and d)
            for (int ix = 1; ix < depth; ++ix)
            {
                ProtoCore.DSASM.SymbolNode sn = GetMemberVariable(finalType, idents[ix], si, isStatic);
                if (sn == null || sn.datatype.UID == ProtoCore.DSASM.Constants.kInvalidIndex)
                {
                    return(ProtoCore.DSASM.Constants.kInvalidIndex);
                }
                finalType = GetSymbolType(sn);
                isStatic  = false;
            }

            return(finalType);
        }
Esempio n. 4
0
 private static int GetSymbolType(ProtoCore.DSASM.SymbolNode symbolnode)
 {
     ProtoCore.Type staticType = symbolnode.staticType;
     if (staticType.UID == (int)ProtoCore.PrimitiveType.kTypeVar)
     {
         return(symbolnode.datatype.UID);
     }
     else
     {
         return(staticType.UID);
     }
 }
Esempio n. 5
0
        protected bool VerifyAllocation(string name, int classscope, out ProtoCore.DSASM.SymbolNode node, out bool isAccessible)
        {
            // Identifier scope resolution
            //  1. Current block
            //  2. Outer language blocks
            //  3. Class scope (TODO Jun: Implement checking the class scope)
            //  4. Global scope (Comment Jun: Is there really a global scope? Conceptually, the outer most block is considered global)

            isAccessible = false;


            node = core.GetFirstVisibleSymbol(name, globalClassIndex, globalProcIndex, codeBlock);
            if (null != node)
            {
                isAccessible = true;
                return(true);
            }

            node = null;
            // TODO Jun: Is this the correct check? checking for null type first?
            if (((int)ProtoCore.PrimitiveType.kTypeVoid == classscope) ||
                (ProtoCore.DSASM.Constants.kInvalidIndex == classscope) ||
                (core.ClassTable.ClassNodes[classscope].symbols == null))
            {
                return(false);
            }


            bool hasThisSymbol;

            ProtoCore.DSASM.AddressType addressType;
            int symbol;

            symbol = core.ClassTable.ClassNodes[classscope].GetSymbolIndex(name, globalClassIndex, globalProcIndex, codeBlock.codeBlockId, core, out hasThisSymbol, out addressType);

            if (ProtoCore.DSASM.Constants.kInvalidIndex != symbol)
            {
                // It is static member, then get node from code block
                if (addressType == ProtoCore.DSASM.AddressType.StaticMemVarIndex)
                {
                    node = core.CodeBlockList[0].symbolTable.symbolList[symbol];
                }
                else
                {
                    node = core.ClassTable.ClassNodes[classscope].symbols.symbolList[symbol];
                }
                isAccessible = true;
                return(true);
            }

            return(hasThisSymbol);
        }
Esempio n. 6
0
        public void AddEntry(ProtoCore.DSASM.SymbolNode sn, int line, int col, string file)
        {
            ProtoCore.CodeModel.CodePoint cp = new ProtoCore.CodeModel.CodePoint()
            {
                LineNo         = line,
                CharNo         = col,
                SourceLocation = new ProtoCore.CodeModel.CodeFile()
                {
                    FilePath = file
                }
            };

            Table[sn] = cp;
        }
Esempio n. 7
0
 protected bool VerifyAllocation(string name, int classScope, out ProtoCore.DSASM.SymbolNode node)
 {
     // Identifier scope resolution
     //  1. Current block
     //  2. Outer language blocks
     //  3. Class scope (TODO Jun: Implement checking the class scope)
     //  4. Global scope (Comment Jun: Is there really a global scope? Conceptually, the outer most block is considered global)
     //node = core.GetFirstVisibleSymbol(name, classScope, functionindex, codeBlock);
     node = core.GetFirstVisibleSymbol(name, classScope, procIndex, codeBlock);
     if (null != node)
     {
         return(true);
     }
     return(false);
 }
        public static List <ProtoCore.VHDL.AST.SignalDeclarationNode> GenerateSignalsDeclarationList(ProtoCore.DSASM.SymbolTable symbolTable)
        {
            List <ProtoCore.VHDL.AST.SignalDeclarationNode> signalDeclList = new List <ProtoCore.VHDL.AST.SignalDeclarationNode>();

            foreach (KeyValuePair <int, ProtoCore.DSASM.SymbolNode> kvp in symbolTable.symbolList)
            {
                ProtoCore.DSASM.SymbolNode symbol = kvp.Value;
                ProtoCore.VHDL.AST.ArrayTypeDefinitionNode arrayType = null;
                if (symbol.size > 1)
                {
                    arrayType = new AST.ArrayTypeDefinitionNode(new List <int>(symbol.size));
                }
                ProtoCore.VHDL.AST.SignalDeclarationNode signalDecl = new ProtoCore.VHDL.AST.SignalDeclarationNode(symbol, arrayType);

                signalDeclList.Add(signalDecl);
            }
            return(signalDeclList);
        }
Esempio n. 9
0
        public SignalDeclarationNode(ProtoCore.DSASM.SymbolNode symbol, ArrayTypeDefinitionNode arrayType = null, string arrayTypeName = null, int bits = ProtoCore.VHDL.Constants.Numeric.SignalBitCount)
        {
            DSSymbol      = symbol;
            SignalName    = DSSymbol.name;
            BitCount      = ProtoCore.VHDL.Constants.Numeric.SignalBitCount;
            ArrayTypeName = arrayTypeName;

            int elements = DSSymbol.size;

            ArrayType = arrayType;

            if (DSSymbol.staticType.UID == (int)ProtoCore.PrimitiveType.kTypeBool)
            {
                BitCount = 1;
            }
            else
            {
                // Handle other data type size here
                BitCount = ProtoCore.VHDL.Constants.Numeric.SignalBitCount;
            }
        }
Esempio n. 10
0
 protected void SetStackIndex(ProtoCore.DSASM.SymbolNode symbol)
 {
     if ((int)ProtoCore.DSASM.Constants.kGlobalScope != globalClassIndex)
     {
         if (null != localProcedure)
         {
             // Local variable in a member function
             symbol.index     = -1 - ProtoCore.DSASM.StackFrame.kStackFrameSize - core.BaseOffset;
             core.BaseOffset += symbol.size;
         }
         else
         {
             // Member variable: static variable allocated on global
             // stack
             if (symbol.isStatic)
             {
                 symbol.index     = core.GlobOffset;
                 core.GlobOffset += symbol.size;
             }
             else
             {
                 symbol.index = classOffset;
                 classOffset += symbol.size;
             }
         }
     }
     else if (null != localProcedure)
     {
         // Local variable in a global function
         symbol.index     = -1 - ProtoCore.DSASM.StackFrame.kStackFrameSize - core.BaseOffset;
         core.BaseOffset += symbol.size;
     }
     else
     {
         // Global variable
         symbol.index     = core.GlobOffset;
         core.GlobOffset += symbol.size;
     }
 }
Esempio n. 11
0
        private static ProtoCore.DSASM.SymbolNode GetMemberVariable(int classIndex, string field, ScopeInfo si, bool isStatic)
        {
            if (field.IndexOfAny(new char[] { '[', ']' }) != -1)
            {
                string[] tokens = TokenizeArrayIndexers(field);
                field = tokens[0];
            }

            // one search is enough, because the code gen will copy all the accessible base
            // class member variabs to the current class table, life easier
            ProtoCore.DSASM.ClassNode cn = compileState.ClassTable.ClassNodes[classIndex];
            if (cn.symbols == null)
            {
                return(null);
            }
            for (int ix = cn.symbols.symbolList.Values.Count - 1; ix >= 0; --ix)
            {
                // we should search in reverse order because in code gen
                // the base class member variable is added first
                // hence we shoud search the its own variable first
                ProtoCore.DSASM.SymbolNode sn = cn.symbols.symbolList[ix];
                if (sn.functionIndex != ProtoCore.DSASM.Constants.kInvalidIndex ||
                    sn.name != field ||
                    isStatic != sn.isStatic)
                {
                    continue;
                }

                // here we have found a variable with the same name
                if (GetAccessLevel(si.ClassScope, sn.classScope) >= sn.access)
                {
                    return(sn);
                }
            }

            return(null);
        }
Esempio n. 12
0
        private int AllocateArg(
            string ident,
            int funcIndex,
            ProtoCore.Type datatype,
            int size = 1,
            int datasize = (int)ProtoCore.DSASM.Constants.kPrimitiveSize,
            ImperativeNode nodeArray = null,
            ProtoCore.DSASM.MemoryRegion region = ProtoCore.DSASM.MemoryRegion.kMemStack)
        {
            ProtoCore.DSASM.SymbolNode symbolnode = new ProtoCore.DSASM.SymbolNode(
                ident,
                ProtoCore.DSASM.Constants.kInvalidIndex,
                ProtoCore.DSASM.Constants.kInvalidIndex,
                funcIndex,
                datatype,
                compileState.TypeSystem.BuildTypeObject((int)PrimitiveType.kTypeVar, false, -2),
                size,
                datasize,
                true,
                codeBlock.symbolTable.runtimeIndex,
                region);

            int symbolindex = ProtoCore.DSASM.Constants.kInvalidIndex;
            if (ProtoCore.DSASM.Constants.kInvalidIndex != codeBlock.symbolTable.IndexOf(symbolnode))
            {

            }
            else
            {
                int locOffset = localProcedure.localCount;
                locOffset = localProcedure.localCount;
                symbolnode.index = -1 - ProtoCore.DSASM.StackFrame.kStackFrameSize - (locOffset + argOffset);
                ++argOffset;

                symbolindex = codeBlock.symbolTable.Append(symbolnode);
            }
            return symbolindex;
        }
Esempio n. 13
0
        private ProtoCore.DSASM.SymbolNode Allocate(
            string ident,
            int funcIndex,
            ProtoCore.Type datatype,
            int size = 1,
            int datasize = (int)ProtoCore.DSASM.Constants.kPrimitiveSize,
            ImperativeNode nodeArray = null,
            ProtoCore.DSASM.MemoryRegion region = ProtoCore.DSASM.MemoryRegion.kMemStack)
        {
            ProtoCore.DSASM.SymbolNode symbolnode = new ProtoCore.DSASM.SymbolNode(
                ident,
                ProtoCore.DSASM.Constants.kInvalidIndex,
                ProtoCore.DSASM.Constants.kInvalidIndex,
                funcIndex,
                datatype,
                compileState.TypeSystem.BuildTypeObject((int)PrimitiveType.kTypeVar, false, - 2),
                size,
                datasize,
                false,
                codeBlock.symbolTable.runtimeIndex,
                region,
                false,
                null,
                globalClassIndex);

            Debug.Assert(ProtoCore.DSASM.Constants.kInvalidIndex == symbolnode.symbolTableIndex);

            if (null == nodeArray)
            {
                AllocateVar(symbolnode);
            }
            else
            {
                AllocateArray(symbolnode, nodeArray);
            }

            int symbolindex = ProtoCore.DSASM.Constants.kInvalidIndex;
            if ((int)ProtoCore.DSASM.Constants.kInvalidIndex != globalClassIndex)
            {
                symbolindex = compileState.ClassTable.ClassNodes[globalClassIndex].symbols.Append(symbolnode);
            }
            else
            {
                symbolindex = codeBlock.symbolTable.Append(symbolnode);
            }

            // TODO Jun: Set the symbol table index of the first local variable of 'funcIndex'
            // This will no longer required once the functiontable is refactored to include a symbol table
            // if the current codeblock is a while block, the procedureTable will be null
            if (null != localProcedure && null == localProcedure.firstLocal)
            {
                localProcedure.firstLocal = symbolnode.index;
            }

            symbolnode.symbolTableIndex = symbolindex;
            return symbolnode;
        }
Esempio n. 14
0
        private void EmitBinaryExpressionNode(AssociativeNode node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            if (!IsParsingGlobal() && !IsParsingGlobalFunctionBody() && !IsParsingMemberFunctionBody())
                return;

            bool isBooleanOperation = false;
            BinaryExpressionNode bnode = node as BinaryExpressionNode;

            ProtoCore.Type leftType = new ProtoCore.Type();
            leftType.UID = (int)ProtoCore.PrimitiveType.kTypeVar;
            leftType.IsIndexable = false;

            ProtoCore.Type rightType = new ProtoCore.Type();
            rightType.UID = (int)ProtoCore.PrimitiveType.kTypeVar;
            rightType.IsIndexable = false;

            // If this is an assignment statement, setup the top level graph node
            if (ProtoCore.DSASM.Operator.assign != bnode.Optr)
            {
                // Traversing the left node if this binary expression is not an assignment
                //
                isBooleanOperation = ProtoCore.DSASM.Operator.lt == bnode.Optr
                     || ProtoCore.DSASM.Operator.gt == bnode.Optr
                     || ProtoCore.DSASM.Operator.le == bnode.Optr
                     || ProtoCore.DSASM.Operator.ge == bnode.Optr
                     || ProtoCore.DSASM.Operator.eq == bnode.Optr
                     || ProtoCore.DSASM.Operator.nq == bnode.Optr
                     || ProtoCore.DSASM.Operator.and == bnode.Optr
                     || ProtoCore.DSASM.Operator.or == bnode.Optr;

                DfsTraverse(bnode.LeftNode, ref inferedType, isBooleanOperation, graphNode, subPass);

                leftType.UID = inferedType.UID;
                leftType.IsIndexable = inferedType.IsIndexable;
            }

            int startpc = ProtoCore.DSASM.Constants.kInvalidIndex;
            // (Ayush) in case of PostFixNode, only traverse the identifier now. Post fix operation will be applied later.
            #if ENABLE_INC_DEC_FIX
                if (bnode.RightNode is PostFixNode)
                {
                    DfsTraverse((bnode.RightNode as PostFixNode).Identifier, ref inferedType, isBooleanOperation, graphNode);
                }
                else
                {
            #endif
            if ((ProtoCore.DSASM.Operator.assign == bnode.Optr) && (bnode.RightNode is LanguageBlockNode))
            {
                inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeVar;
                inferedType.IsIndexable = false;
            }

            if (null != localProcedure && localProcedure.isConstructor && setConstructorStartPC)
            {
                startpc -= 1;
                setConstructorStartPC = false;
            }

            DfsTraverse(bnode.RightNode, ref inferedType, isBooleanOperation, graphNode, subPass);
            #if ENABLE_INC_DEC_FIX
                }
            #endif

            rightType.UID = inferedType.UID;
            rightType.IsIndexable = inferedType.IsIndexable;

            BinaryExpressionNode rightNode = bnode.RightNode as BinaryExpressionNode;
            if ((rightNode != null) && (ProtoCore.DSASM.Operator.assign == rightNode.Optr))
            {
                DfsTraverse(rightNode.LeftNode, ref inferedType, false, graphNode);
            }

            if (bnode.Optr != ProtoCore.DSASM.Operator.assign)
            {
                if (subPass == ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
                {
                    return;
                }
                isBooleanOp = false;

                //if post fix, now traverse the post fix
            #if ENABLE_INC_DEC_FIX
                if (bnode.RightNode is PostFixNode)
                    EmitPostFixNode(bnode.RightNode, ref inferedType);
            #endif
                return;
            }

            DfsTraverse(bnode.RightNode, ref inferedType, isBooleanOperation, graphNode, ProtoCore.DSASM.AssociativeSubCompilePass.kNone);
            subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier;

            if (bnode.LeftNode is IdentifierNode)
            {
                // TODO Jun: Cleansify this block where the lhs is being handled.
                // For one, make the return as a return node
                IdentifierNode t = bnode.LeftNode as IdentifierNode;
                ProtoCore.DSASM.SymbolNode symbolnode = null;

                string s = t.Value;
                if (s == ProtoCore.DSDefinitions.Kw.kw_return)
                {
                    Debug.Assert(null == symbolnode);
                    symbolnode = new ProtoCore.DSASM.SymbolNode();
                    symbolnode.name = s;
                    symbolnode.functionIndex = globalProcIndex;
                    symbolnode.classScope = globalClassIndex;

                    EmitReturnStatement(node, inferedType);
                }
                else
                {
                    {
                        // check whether the variable name is a function name
                        bool isAccessibleFp;
                        int realType;
                        ProtoCore.DSASM.ProcedureNode procNode = null;
                        if (globalClassIndex != ProtoCore.DSASM.Constants.kGlobalScope)
                        {
                            procNode = core.ClassTable.ClassNodes[globalClassIndex].GetMemberFunction(t.Name, null, globalClassIndex, out isAccessibleFp, out realType);
                        }
                        if (procNode == null)
                        {
                            procNode = core.GetFirstVisibleProcedure(t.Name, null, codeBlock);
                        }
                    }

                    //int type = (int)ProtoCore.PrimitiveType.kTypeVoid;
                    bool isAccessible = false;
                    bool isAllocated = VerifyAllocation(t.Name, globalClassIndex, out symbolnode, out isAccessible);
                    int runtimeIndex = (!isAllocated || !isAccessible) ? codeBlock.symbolTable.runtimeIndex : symbolnode.runtimeTableIndex;

                    int dimensions = 0;
                    if (null != t.ArrayDimensions)
                    {
                        dimensions = DfsEmitArrayIndexHeap(t.ArrayDimensions);
                    }

                    ProtoCore.Type castType = core.TypeSystem.BuildTypeObject((int)PrimitiveType.kTypeVar, false);
                    var tident = bnode.LeftNode as TypedIdentifierNode;
                    if (tident != null)
                    {
                        int castUID = tident.datatype.UID;
                        if ((int)PrimitiveType.kInvalidType == castUID)
                        {
                            castUID = core.ClassTable.IndexOf(tident.datatype.Name);
                        }

                        if ((int)PrimitiveType.kInvalidType == castUID)
                        {
                            castType = core.TypeSystem.BuildTypeObject((int)PrimitiveType.kInvalidType, false);
                            castType.Name = tident.datatype.Name;
                            castType.rank = tident.datatype.rank;
                            castType.IsIndexable = (castType.rank != 0);
                        }
                        else
                        {
                            castType = core.TypeSystem.BuildTypeObject(castUID, tident.datatype.IsIndexable, tident.datatype.rank);
                        }
                    }

                    if (ProtoCore.DSASM.Constants.kInvalidIndex != globalClassIndex)
                    {
                        // In a class

                        // TODO Jun: refactor this by having symbol table functions for retrieval of node index
                        int symbol = ProtoCore.DSASM.Constants.kInvalidIndex;
                        bool isMemVar = false;
                        if (symbolnode != null)
                        {
                            if (symbolnode.classScope != ProtoCore.DSASM.Constants.kInvalidIndex &&
                                symbolnode.functionIndex == ProtoCore.DSASM.Constants.kGlobalScope)
                            {
                                isMemVar = true;
                            }
                            symbol = symbolnode.symbolTableIndex;
                        }

                        if (!isMemVar)
                        {
                            // This is local variable
                            // TODO Jun: If this local var exists globally, should it allocate a local copy?
                            if (!isAllocated || !isAccessible)
                            {
                                symbolnode = Allocate(globalClassIndex, globalClassIndex, globalProcIndex, t.Name, inferedType);
                                Debug.Assert(symbolnode != null);
                                IdentLocation.AddEntry(symbolnode, t.line, t.col, core.CurrentDSFileName);
                            }

                            symbol = symbolnode.symbolTableIndex;

                            if (bnode.LeftNode is TypedIdentifierNode)
                            {
                                symbolnode.SetStaticType(castType);
                            }
                        }
                        else
                        {
                            if (bnode.LeftNode is TypedIdentifierNode)
                            {
                                symbolnode.SetStaticType(castType);
                            }
                        }
                    }
                    else
                    {
                        if (0 == dimensions)
                        {
                            // Not indexing an array, allocate memory for this
                            if (!isAllocated)
                            {
                                symbolnode = Allocate(globalClassIndex, globalClassIndex, globalProcIndex, t.Name, inferedType);
                                Debug.Assert(symbolnode != null);
                                IdentLocation.AddEntry(symbolnode, t.line, t.col, core.CurrentDSFileName);
                            }
                        }

                        if (bnode.LeftNode is TypedIdentifierNode)
                        {
                            symbolnode.SetStaticType(castType);
                        }
                    }
                }

            }
            else if (bnode.LeftNode is IdentifierListNode)
            {
                int depth = 0;

                ProtoCore.Type lastType = new ProtoCore.Type();
                lastType.UID = (int)PrimitiveType.kInvalidType;
                lastType.IsIndexable = false;

                bool isFirstIdent = false;
                bool isIdentReference = DfsEmitIdentList(bnode.LeftNode, bnode, globalClassIndex, ref lastType, ref depth, ref inferedType, true, ref isFirstIdent, graphNode, subPass);

                // Jun: Ge the left most identifier node and use that as the parent graph
                // This may have to go through re-design if we want full dependency on a.b.c...
                IdentifierListNode listNode = bnode.LeftNode as IdentifierListNode;
                int leftClassIndex = ProtoCore.DSASM.Constants.kInvalidIndex;
                if (listNode.LeftNode is IdentifierNode)
                {
                    leftClassIndex = core.ClassTable.IndexOf(listNode.LeftNode.Name);
                }
                AssociativeNode iNode = (listNode.LeftNode.Name == ProtoCore.DSDefinitions.Kw.kw_this ||
                                         leftClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex) ? listNode.RightNode : listNode.LeftNode;
                while (iNode is IdentifierListNode)
                {
                    if ((iNode as IdentifierListNode).LeftNode.Name != ProtoCore.DSDefinitions.Kw.kw_this)
                    {
                        iNode = (iNode as IdentifierListNode).LeftNode;
                    }
                    else
                    {
                        iNode = (iNode as IdentifierListNode).RightNode;
                    }
                }

                Debug.Assert(iNode is IdentifierNode);
                iNode = iNode as IdentifierNode;
                if (null != iNode)
                {
                    ProtoCore.DSASM.SymbolNode symnode = null;
                    bool isAccessible = false;

                    int oldClassIndex = globalClassIndex;
                    if (leftClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex)
                        globalClassIndex = leftClassIndex;

                    bool isAllocated = VerifyAllocation(iNode.Name, globalClassIndex, out symnode, out isAccessible);
                    globalClassIndex = oldClassIndex;
                }
            }

            //if post fix, now traverse the post fix
            #if ENABLE_INC_DEC_FIX
                if (bnode.RightNode is PostFixNode)
                    EmitPostFixNode(bnode.RightNode, ref inferedType);
            #endif
        }
Esempio n. 15
0
        private int AllocateArg(
            string ident,
            int funcIndex,
            ProtoCore.Type datatype,
            int size = 1,
            int datasize = (int)ProtoCore.DSASM.Constants.kPrimitiveSize,
            AssociativeNode nodeArray = null,
            ProtoCore.DSASM.MemoryRegion region = ProtoCore.DSASM.MemoryRegion.kMemStack)
        {
            ProtoCore.DSASM.SymbolNode node = new ProtoCore.DSASM.SymbolNode(
                ident,
                ProtoCore.DSASM.Constants.kInvalidIndex,
                ProtoCore.DSASM.Constants.kInvalidIndex,
                funcIndex,
                datatype,
                core.TypeSystem.BuildTypeObject((int)PrimitiveType.kTypeVar, false, -2),
                size,
                datasize,
                true,
                codeBlock.symbolTable.runtimeIndex,
                region,
                false,
                null,
                globalClassIndex);

            node.name = ident;
            node.size = datasize;
            node.functionIndex = funcIndex;
            node.datatype = datatype;
            node.isArgument = true;
            node.memregion = ProtoCore.DSASM.MemoryRegion.kMemStack;
            node.classScope = globalClassIndex;

            // Comment Jun: The local count will be adjusted and all dependent symbol offsets after the function body has been traversed
            int locOffset = 0;

            // This will be offseted by the local count after locals have been allocated
            node.index = -1 - ProtoCore.DSASM.StackFrame.kStackFrameSize - (locOffset + argOffset);
            ++argOffset;

            int symbolindex = ProtoCore.DSASM.Constants.kInvalidIndex;
            if ((int)ProtoCore.DSASM.Constants.kInvalidIndex != globalClassIndex)
            {
                symbolindex = core.ClassTable.ClassNodes[globalClassIndex].symbols.Append(node);
            }
            else
            {
                symbolindex = codeBlock.symbolTable.Append(node);
            }
            return symbolindex;
        }
Esempio n. 16
0
        private ProtoCore.DSASM.SymbolNode Allocate(
            int classIndex,  // In which class table this variable will be allocated to ?
            int classScope,  // Variable's class scope. For example, it is a variable in base class
            int funcIndex,   // In which function this variable is defined?
            string ident,
            ProtoCore.Type datatype,
            int datasize = (int)ProtoCore.DSASM.Constants.kPrimitiveSize,
            bool isStatic = false,
            ProtoCore.DSASM.AccessSpecifier access = ProtoCore.DSASM.AccessSpecifier.kPublic,
            ProtoCore.DSASM.MemoryRegion region = ProtoCore.DSASM.MemoryRegion.kMemStack
            )
        {
            bool allocateForBaseVar = classScope < classIndex;

            ProtoCore.DSASM.SymbolNode symbolnode = new ProtoCore.DSASM.SymbolNode();
            symbolnode.name = ident;
            symbolnode.size = datasize;
            symbolnode.functionIndex = funcIndex;
            symbolnode.datatype = datatype;
            symbolnode.staticType = core.TypeSystem.BuildTypeObject((int)PrimitiveType.kTypeVar, false, -2);
            symbolnode.isArgument = false;
            symbolnode.memregion = region;
            symbolnode.classScope = classScope;
            symbolnode.runtimeTableIndex = codeBlock.symbolTable.runtimeIndex;
            symbolnode.isStatic = isStatic;
            symbolnode.access = access;

            int symbolindex = ProtoCore.DSASM.Constants.kInvalidIndex;
            if ((int)ProtoCore.DSASM.Constants.kInvalidIndex != classIndex)
            {
                // NOTE: the following comment and code is OBSOLETE - member
                // variable is not supported now
                //
                // Yu Ke: it is possible that class table contains same-named
                // symbols if a class inherits some member variables from base
                // class, so we need to check name + class index + function
                // index.
                //
                //if (core.classTable.list[classIndex].symbols.IndexOf(ident, classIndex, funcIndex) != (int)ProtoCore.DSASM.Constants.kInvalidIndex)
                //    return null;

                symbolindex = core.ClassTable.ClassNodes[classIndex].symbols.IndexOf(ident);
                if (symbolindex != (int)ProtoCore.DSASM.Constants.kInvalidIndex)
                {
                    ProtoCore.DSASM.SymbolNode node = core.ClassTable.ClassNodes[classIndex].symbols.symbolList[symbolindex];
                    if (node.functionIndex == ProtoCore.DSASM.Constants.kGlobalScope &&
                        funcIndex == ProtoCore.DSASM.Constants.kGlobalScope)
                        return null;
                }

                symbolindex = core.ClassTable.ClassNodes[classIndex].symbols.Append(symbolnode);
                if (symbolindex == ProtoCore.DSASM.Constants.kInvalidIndex)
                {
                    return null;
                }

                if (isStatic)
                {
                    Debug.Assert(funcIndex == ProtoCore.DSASM.Constants.kGlobalScope);
                    ProtoCore.DSASM.SymbolNode staticSymbolnode = new ProtoCore.DSASM.SymbolNode();
                    staticSymbolnode.name = ident;
                    staticSymbolnode.size = datasize;
                    staticSymbolnode.functionIndex = funcIndex;
                    staticSymbolnode.datatype = datatype;
                    staticSymbolnode.staticType = core.TypeSystem.BuildTypeObject((int)PrimitiveType.kTypeVar, false, -2);
                    staticSymbolnode.isArgument = false;
                    staticSymbolnode.memregion = region;
                    staticSymbolnode.classScope = classScope;
                    staticSymbolnode.runtimeTableIndex = codeBlock.symbolTable.runtimeIndex;
                    staticSymbolnode.isStatic = isStatic;
                    staticSymbolnode.access = access;

                    // If inherits a static property from base class, that propery
                    // symbol should have been added to code block's symbol table,
                    // so we just update symbolTableIndex
                    int staticSymbolindex = codeBlock.symbolTable.IndexOf(ident, classScope);
                    if (staticSymbolindex == ProtoCore.DSASM.Constants.kInvalidIndex)
                    {
                        AllocateVar(staticSymbolnode);
                        staticSymbolindex = codeBlock.symbolTable.Append(staticSymbolnode);
                        if (staticSymbolindex == ProtoCore.DSASM.Constants.kInvalidIndex)
                        {
                            return null;
                        }
                        staticSymbolnode.symbolTableIndex = staticSymbolindex;
                    }
                    symbolnode.symbolTableIndex = staticSymbolindex;
                }
                else
                {
                    AllocateVar(symbolnode);
                }
            }
            else
            {
                AllocateVar(symbolnode);
                symbolindex = codeBlock.symbolTable.Append(symbolnode);
                if (symbolindex == ProtoCore.DSASM.Constants.kInvalidIndex)
                {
                    return null;
                }
                symbolnode.symbolTableIndex = symbolindex;
            }

            // TODO Jun: Set the symbol table index of the first local variable of 'funcIndex'
            if (null != localProcedure && null == localProcedure.firstLocal)
            {
                localProcedure.firstLocal = symbolnode.index;
            }

            if (ProtoCore.DSASM.Constants.kInvalidIndex == symbolindex)
            {
                return null;
            }
            return symbolnode;
        }
Esempio n. 17
0
        private void EmitConstructorDefinitionNode(AssociativeNode node, ref ProtoCore.Type inferedType, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            ConstructorDefinitionNode funcDef = node as ConstructorDefinitionNode;
            ProtoCore.DSASM.CodeBlockType originalBlockType = codeBlock.blockType;
            codeBlock.blockType = ProtoCore.DSASM.CodeBlockType.kFunction;

            if (IsParsingMemberFunctionSig())
            {
                Debug.Assert(null == localProcedure);
                localProcedure = new ProtoCore.DSASM.ProcedureNode();

                localProcedure.name = funcDef.Name;
                localProcedure.pc = ProtoCore.DSASM.Constants.kInvalidIndex;
                localProcedure.localCount = 0;// Defer till all locals are allocated
                localProcedure.returntype.UID = core.TypeSystem.GetType(funcDef.ReturnType.Name);
                if (localProcedure.returntype.UID == ProtoCore.DSASM.Constants.kInvalidIndex)
                    localProcedure.returntype.UID = (int)PrimitiveType.kTypeVar;
                localProcedure.returntype.Name = core.TypeSystem.GetType(localProcedure.returntype.UID);
                localProcedure.returntype.IsIndexable = false;
                localProcedure.isConstructor = true;
                localProcedure.runtimeIndex = 0;

                Debug.Assert(ProtoCore.DSASM.Constants.kInvalidIndex != globalClassIndex, "A constructor node must be associated with class");
                localProcedure.localCount = 0;

                int peekFunctionindex = core.ClassTable.ClassNodes[globalClassIndex].vtable.procList.Count;

                if (!funcDef.IsExternLib)
                    CodeRangeTable.AddClassBlockFunctionEntry(globalClassIndex,
                        peekFunctionindex,
                        funcDef.FunctionBody.line,
                        funcDef.FunctionBody.col,
                        funcDef.FunctionBody.endLine,
                        funcDef.FunctionBody.endCol,
                        core.CurrentDSFileName);

                // Append arg symbols
                List<KeyValuePair<string, ProtoCore.Type>> argsToBeAllocated = new List<KeyValuePair<string, ProtoCore.Type>>();
                if (null != funcDef.Signature)
                {
                    int argNumber = 0;
                    foreach (VarDeclNode argNode in funcDef.Signature.Arguments)
                    {
                        ++argNumber;

                        IdentifierNode paramNode = null;
                        bool aIsDefault = false;
                        ProtoCore.AST.Node aDefaultExpression = null;
                        if (argNode.NameNode is IdentifierNode)
                        {
                            paramNode = argNode.NameNode as IdentifierNode;
                        }
                        else if (argNode.NameNode is BinaryExpressionNode)
                        {
                            BinaryExpressionNode bNode = argNode.NameNode as BinaryExpressionNode;
                            paramNode = bNode.LeftNode as IdentifierNode;
                            aIsDefault = true;
                            aDefaultExpression = bNode;
                            //buildStatus.LogSemanticError("Default parameters are not supported");
                            //throw new BuildHaltException();
                        }
                        else
                        {
                            Debug.Assert(false, "Check generated AST");
                        }

                        ProtoCore.Type argType = new ProtoCore.Type();
                        argType.UID = core.TypeSystem.GetType(argNode.ArgumentType.Name);
                        if (argType.UID == ProtoCore.DSASM.Constants.kInvalidIndex)
                            argType.UID = (int)PrimitiveType.kTypeVar;
                        argType.Name = core.TypeSystem.GetType(argType.UID);
                        argType.IsIndexable = argNode.ArgumentType.IsIndexable;
                        argType.rank = argNode.ArgumentType.rank;

                        argsToBeAllocated.Add(new KeyValuePair<string, ProtoCore.Type>(paramNode.Value, argType));
                        localProcedure.argTypeList.Add(argType);
                        ProtoCore.DSASM.ArgumentInfo argInfo = new ProtoCore.DSASM.ArgumentInfo { isDefault = aIsDefault, defaultExpression = aDefaultExpression, Name = paramNode.Name };
                        localProcedure.argInfoList.Add(argInfo);
                    }
                }

                int findex = core.ClassTable.ClassNodes[globalClassIndex].vtable.Append(localProcedure);

                // Comment Jun: Catch this assert given the condition as this type of mismatch should never occur
                if (ProtoCore.DSASM.Constants.kInvalidIndex != findex)
                {
                    Debug.Assert(peekFunctionindex == localProcedure.procId);
                    argsToBeAllocated.ForEach(arg =>
                    {
                        int symbolIndex = AllocateArg(arg.Key, findex, arg.Value);
                        if (ProtoCore.DSASM.Constants.kInvalidIndex == symbolIndex)
                        {
                            throw new BuildHaltException();
                        }
                    });
                }
            }
            else if (IsParsingMemberFunctionBody())
            {
                // Build arglist for comparison
                List<ProtoCore.Type> argList = new List<ProtoCore.Type>();
                if (null != funcDef.Signature)
                {
                    foreach (VarDeclNode argNode in funcDef.Signature.Arguments)
                    {
                        int argType = core.TypeSystem.GetType(argNode.ArgumentType.Name);
                        bool isArray = argNode.ArgumentType.IsIndexable;
                        int rank = argNode.ArgumentType.rank;
                        argList.Add(core.TypeSystem.BuildTypeObject(argType, isArray, rank));
                    }
                }

                globalProcIndex = core.ClassTable.ClassNodes[globalClassIndex].vtable.IndexOfExact(funcDef.Name, argList);

                Debug.Assert(null == localProcedure);
                localProcedure = core.ClassTable.ClassNodes[globalClassIndex].vtable.procList[globalProcIndex];

                Debug.Assert(null != localProcedure);
                if (null == localProcedure)
                    return;

                if (-1 == localProcedure.classScope && (localProcedure.classScope != globalClassIndex))
                    localProcedure.classScope = globalClassIndex; // Assign class index if it's not done.

                ProtoCore.FunctionEndPoint fep = null;
                if (!funcDef.IsExternLib)
                {
                    // Traverse default assignment for the class
                    foreach (BinaryExpressionNode bNode in core.ClassTable.ClassNodes[globalClassIndex].defaultArgExprList)
                    {
                        EmitBinaryExpressionNode(bNode, ref inferedType, false, null, subPass);
                        UpdateType(bNode.LeftNode.Name, ProtoCore.DSASM.Constants.kInvalidIndex, inferedType);
                    }

                    //Traverse default argument for the constructor
                    foreach (ProtoCore.DSASM.ArgumentInfo argNode in localProcedure.argInfoList)
                    {
                        if (!argNode.isDefault)
                        {
                            continue;
                        }
                        BinaryExpressionNode bNode = argNode.defaultExpression as BinaryExpressionNode;
                        // build a temporay node for statement : temp = defaultarg;
                        IdentifierNode iNodeTemp = new IdentifierNode()
                        {
                            Value = ProtoCore.DSASM.Constants.kTempDefaultArg,
                            Name = ProtoCore.DSASM.Constants.kTempDefaultArg,
                            datatype = core.TypeSystem.BuildTypeObject(PrimitiveType.kTypeVar, false)
                        };
                        BinaryExpressionNode bNodeTemp = new BinaryExpressionNode();
                        bNodeTemp.LeftNode = iNodeTemp;
                        bNodeTemp.Optr = ProtoCore.DSASM.Operator.assign;
                        bNodeTemp.RightNode = bNode.LeftNode;
                        EmitBinaryExpressionNode(bNodeTemp, ref inferedType);
                        //duild an inline conditional node for statement: defaultarg = (temp == DefaultArgNode) ? defaultValue : temp;
                        InlineConditionalNode icNode = new InlineConditionalNode();
                        BinaryExpressionNode cExprNode = new BinaryExpressionNode();
                        cExprNode.Optr = ProtoCore.DSASM.Operator.eq;
                        cExprNode.LeftNode = iNodeTemp;
                        cExprNode.RightNode = new DefaultArgNode();
                        icNode.ConditionExpression = cExprNode;
                        icNode.TrueExpression = bNode.RightNode;
                        icNode.FalseExpression = iNodeTemp;
                        bNodeTemp.LeftNode = bNode.LeftNode;
                        bNodeTemp.RightNode = icNode;
                        EmitBinaryExpressionNode(bNodeTemp, ref inferedType);
                    }

                    // Traverse definition
                    foreach (AssociativeNode bnode in funcDef.FunctionBody.Body)
                    {
                        inferedType.UID = (int)PrimitiveType.kTypeVoid;
                        inferedType.rank = 0;
                        DfsTraverse(bnode, ref inferedType, false, null, subPass);
                    }

                    // All locals have been stack allocated, update the local count of this function
                    localProcedure.localCount = core.BaseOffset;
                    core.ClassTable.ClassNodes[globalClassIndex].vtable.procList[globalProcIndex].localCount = core.BaseOffset;

                    // Update the param stack indices of this function
                    foreach (ProtoCore.DSASM.SymbolNode symnode in core.ClassTable.ClassNodes[globalClassIndex].symbols.symbolList.Values)
                    {
                        if (symnode.functionIndex == globalProcIndex && symnode.isArgument)
                        {
                            symnode.index -= localProcedure.localCount;
                        }
                    }

                    // JIL FEP
                    ProtoCore.Lang.JILActivationRecord record = new ProtoCore.Lang.JILActivationRecord();
                    record.pc = localProcedure.pc;
                    record.locals = localProcedure.localCount;
                    record.classIndex = globalClassIndex;
                    record.funcIndex = globalProcIndex;

                    // Construct the fep arguments
                    fep = new ProtoCore.Lang.JILFunctionEndPoint(record);
                }
                else
                {
                    ProtoCore.Lang.JILActivationRecord jRecord = new ProtoCore.Lang.JILActivationRecord();
                    jRecord.pc = localProcedure.pc;
                    jRecord.locals = localProcedure.localCount;
                    jRecord.classIndex = globalClassIndex;
                    jRecord.funcIndex = localProcedure.procId;

                    ProtoCore.Lang.FFIActivationRecord record = new ProtoCore.Lang.FFIActivationRecord();
                    record.JILRecord = jRecord;
                    record.FunctionName = funcDef.Name;
                    record.ModuleName = funcDef.ExternLibName;
                    record.ModuleType = "dll";
                    record.IsDNI = false;
                    record.ReturnType = funcDef.ReturnType;
                    record.ParameterTypes = localProcedure.argTypeList;
                    fep = new ProtoCore.Lang.FFIFunctionEndPoint(record);
                }

                // Construct the fep arguments
                fep.FormalParams = new ProtoCore.Type[localProcedure.argTypeList.Count];
                localProcedure.argTypeList.CopyTo(fep.FormalParams, 0);

                // TODO Jun: 'classIndexAtCallsite' is the class index as it is stored at the callsite function tables
                // Determine whether this still needs to be aligned to the actual 'classIndex' variable
                // The factors that will affect this is whether the 2 function tables (compiler and callsite) need to be merged
                int classIndexAtCallsite = globalClassIndex + 1;
                core.FunctionTable.AddFunctionEndPointer(classIndexAtCallsite, funcDef.Name, fep);

                // Build and append a graphnode for this return statememt
                ProtoCore.DSASM.SymbolNode returnNode = new ProtoCore.DSASM.SymbolNode();
                returnNode.name = "return";
            }

            // Constructors have no return statemetns, reset variables here
            core.ProcNode = localProcedure = null;
            globalProcIndex = ProtoCore.DSASM.Constants.kGlobalScope;
            core.BaseOffset = 0;
            argOffset = 0;
            classOffset = 0;
            codeBlock.blockType = originalBlockType;
        }
Esempio n. 18
0
        /// <summary>
        /// get the type of an identifier based on its location and name
        /// </summary>
        /// <param name="si">where is the ident</param>
        /// <param name="ident">name of the ident</param>
        /// <param name="cp">
        /// where is the ident, not the same usage as parameter "si",
        /// this is used to see if the ident location is before its definition or after its definition
        /// </param>
        /// <returns></returns>
        private static int GetIdentType(ScopeInfo si, string ident, ProtoCore.CodeModel.CodePoint cp)
        {
            if (si.ClassScope == ProtoCore.DSASM.Constants.kInvalidIndex)
            {
                // Not inside any class
                ProtoCore.DSASM.CodeBlock        cb         = null;
                List <ProtoCore.DSASM.CodeBlock> codeBlocks = compileState.CodeBlockList;
                if (null != codeBlocks && (si.BlockId >= 0) && (si.BlockId < codeBlocks.Count))
                {
                    cb = codeBlocks[si.BlockId];
                }

                // loop used to search its parent block
                while (cb != null)
                {
                    // search by matching ident name and function index
                    IEnumerable <ProtoCore.DSASM.SymbolNode> sns = cb.symbolTable.symbolList.Values.Where(x =>
                                                                                                          x.name == ident &&
                                                                                                          x.functionIndex == si.FunctionIndex &&
                                                                                                          x.classScope == ProtoCore.DSASM.Constants.kInvalidIndex);

                    if (sns.Count() > 0) // found something
                    {
                        ProtoCore.DSASM.SymbolNode symbolNode = sns.ElementAt(0);

                        // if it is argument, it is visible every where inside the fucntion
                        if (symbolNode.isArgument == true)
                        {
                            return(GetSymbolType(symbolNode));
                        }

                        // check if the variable definition location is before our searching site
                        if (cp.Before(identLocationTable.Table[symbolNode]))
                        {
                            return(GetSymbolType(symbolNode));
                        }

                        // if not argument, check if it is defined some where in the imported files, if yes, it is visible
                        CodeFile file = identLocationTable.Table[symbolNode].SourceLocation;
                        if (importTable.IsImported(cp.SourceLocation.FilePath, file.FilePath))
                        {
                            return(GetSymbolType(symbolNode));
                        }
                    }

                    if (si.FunctionIndex != ProtoCore.DSASM.Constants.kInvalidIndex)
                    {
                        // no name look up inside a fucntion
                        // TODO: This may need to change, since we are now allowing to access global variables inside a fucntion
                        break;
                    }

                    // update cb to its parent block
                    cb = cb.parent;
                }
            }
            else
            {
                // we are inside a function
                // check if it is this keyword
                if (ident == "this")
                {
                    // the type is the class itself
                    return(si.ClassScope);
                }

                // inside a class scope
                ProtoCore.DSASM.CodeBlock  cb = compileState.CodeBlockList[si.BlockId];
                ProtoCore.DSASM.SymbolNode sn = null;
                while (cb.parent != null)
                {
                    // if it is inside a language block which is inside a function
                    IEnumerable <ProtoCore.DSASM.SymbolNode> sns = cb.symbolTable.symbolList.Values.Where(x => x.name == ident);
                    if (sns.Count() > 0 &&
                        (sns.ElementAt(0).isArgument == true ||
                         importTable.IsImported(cp.SourceLocation.FilePath, identLocationTable.Table[sns.ElementAt(0)].SourceLocation.FilePath) ||
                         cp.Before(identLocationTable.Table[sns.ElementAt(0)])))
                    {
                        sn = sns.ElementAt(0);
                        break;
                    }

                    cb = cb.parent;
                }

                if (sn == null)
                {
                    // search local variables in the funtion
                    IEnumerable <ProtoCore.DSASM.SymbolNode> sns = compileState.ClassTable.ClassNodes[si.ClassScope].symbols.symbolList.Values.Where(x => x.name == ident && x.functionIndex == si.FunctionIndex);
                    if (sns.Count() > 0)
                    {
                        sn = sns.ElementAt(0);
                    }
                    else
                    {
                        // the final search, search the class member variables
                        sn = GetMemberVariable(si.ClassScope, ident, si, false);
                        //sn = GetClassMemberVariable(si.ClassScope, ident);
                    }
                }

                if (sn != null)
                {
                    return(sn.datatype.UID);
                }
            }

            return(ProtoCore.DSASM.Constants.kInvalidIndex);
        }
Esempio n. 19
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);
        }
Esempio n. 20
0
 protected void SetHeapData(ProtoCore.DSASM.SymbolNode symbol)
 {
     symbol.size      = ProtoCore.DSASM.Constants.kPointerSize;
     symbol.heapIndex = core.GlobHeapOffset++;
 }