Пример #1
0
 public SymbolNode(
     string name,
     int index, 
     int functionIndex,
     Type datatype,
     bool isArgument, 
     int runtimeIndex,
     MemoryRegion memregion = MemoryRegion.InvalidRegion, 
     int scope = -1,
     CompilerDefinitions.AccessModifier access = CompilerDefinitions.AccessModifier.Public,
     bool isStatic = false,
     int codeBlockId = Constants.kInvalidIndex)
 {
     this.name           = name;
     isTemp         = name.StartsWith("%");
     isSSATemp = name.StartsWith(Constants.kSSATempPrefix); 
     this.index          = index;
     this.functionIndex = functionIndex;
     this.absoluteFunctionIndex = functionIndex;
     this.datatype       = datatype;
     this.isArgument     = isArgument;
     this.memregion      = memregion;
     this.classScope     = scope;
     this.absoluteClassScope = scope;
     runtimeTableIndex = runtimeIndex;
     this.access = access;
     this.isStatic = isStatic;
     this.codeBlockId = codeBlockId;
 }
Пример #2
0
        protected bool DfsEmitIdentList(
            Node pNode, 
            Node parentNode, 
            int contextClassScope, 
            ref Type lefttype,
            ref int depth, 
            ref Type finalType, 
            bool isLeftidentList, 
            AssociativeGraph.GraphNode graphNode = null,
            CompilerDefinitions.SubCompilePass subPass = CompilerDefinitions.SubCompilePass.None,
            Node binaryExpNode = null)
        {
            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)
                {
                    string message = "The left hand side of an operation can only contain an indirection operator '.' (48D67B9B)";
                    buildStatus.LogSemanticError(message, core.CurrentDSFileName, bnode.line, bnode.col);
                    throw new BuildHaltException(message);
                }

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

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

            if (node is ProtoCore.AST.ImperativeAST.GroupExpressionNode)
            {
                ProtoCore.AST.ImperativeAST.ArrayNode array = node.ArrayDimensions;
                node = node.Expression;
                node.ArrayDimensions = array;
            }
            else if (node is ProtoCore.AST.AssociativeAST.GroupExpressionNode)
            {
                ProtoCore.AST.AssociativeAST.ArrayNode array = node.ArrayDimensions;
                List<ProtoCore.AST.AssociativeAST.AssociativeNode> replicationGuides = node.ReplicationGuides;

                node = node.Expression;
                node.ArrayDimensions = array;
                node.ReplicationGuides = replicationGuides;
            }

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

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

                    if (null == symbolnode)    //unbound identifier
                    {
                        if (isAllocated && !isAccessible)
                        {
                            string message = String.Format(Resources.kPropertyIsInaccessible, identnode.Value);
                            buildStatus.LogWarning(ProtoCore.BuildData.WarningID.AccessViolation, message, core.CurrentDSFileName, identnode.line, identnode.col, graphNode);
                            lefttype.UID = finalType.UID = (int)PrimitiveType.Null;
                            EmitPushNull();
                            return false;
                        }
                        else
                        {
                            string message = String.Format(Resources.kUnboundIdentifierMsg, identnode.Value);
                            var unboundSymbol = new SymbolNode
                            {
                                name = identnode.Value
                            };
                            buildStatus.LogUnboundVariableWarning(unboundSymbol, message, core.CurrentDSFileName, identnode.line, identnode.col, graphNode);
                        }

                        if (depth == 0)
                        {
                            lefttype.UID = finalType.UID = (int)PrimitiveType.Null;
                            EmitPushNull();
                            depth = 1;
                            return false;
                        }
                        else
                        {
                            DSASM.DyanmicVariableNode dynamicVariableNode = new DSASM.DyanmicVariableNode(identnode.Value, globalProcIndex, globalClassIndex);
                            core.DynamicVariableTable.variableTable.Add(dynamicVariableNode);
                            int dim = 0;
                            if (null != identnode.ArrayDimensions)
                            {
                                dim = DfsEmitArrayIndexHeap(identnode.ArrayDimensions, graphNode);
                            }


                            EmitInstrConsole(kw.pushm, identnode.Value + "[dynamic]");
                            StackValue dynamicOp = StackValue.BuildDynamic(core.DynamicVariableTable.variableTable.Count - 1);
                            EmitPushm(dynamicOp, symbolnode == null ? globalClassIndex : symbolnode.classScope, DSASM.Constants.kInvalidIndex);

                            if (dim > 0)
                            {
                                EmitPushDimensions(dim);
                                EmitLoadElement(null, Constants.kInvalidIndex);
                            }

                            lefttype.UID = finalType.UID = (int)PrimitiveType.Var;
                            depth++;
                            return true;
                        }
                    }

                    /* Dont try to figure out the type at compile time if it is
                     * an array, it is just not reliable because each element in
                     * an array can have different types
                     */
                    if (!symbolnode.datatype.IsIndexable || symbolnode.datatype.rank < 0)
                        lefttype = symbolnode.datatype;

                    int dimensions = 0;

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

                    if (lefttype.rank >= 0)
                    {
                        lefttype.rank -= dimensions;
                        if (lefttype.rank < 0)
                        {
                            lefttype.rank = 0;
                        }
                    }

                    StackValue op = StackValue.Null;
                    if (0 == depth || (symbolnode != null && symbolnode.isStatic))
                    {
                        if (ProtoCore.DSASM.Constants.kGlobalScope == symbolnode.functionIndex
                            && ProtoCore.DSASM.Constants.kInvalidIndex != symbolnode.classScope)
                        {
                            // member var
                            if (symbolnode.isStatic)
                                op = StackValue.BuildStaticMemVarIndex(symbolnode.symbolTableIndex);
                            else
                                op = StackValue.BuildMemVarIndex(symbolnode.symbolTableIndex);
                        }
                        else
                        {
                            op = StackValue.BuildVarIndex(symbolnode.symbolTableIndex);
                        }
                    }

                    if (isLeftidentList || depth == 0)
                    {
                        EmitInstrConsole(kw.pushm, identnode.Value);
                        EmitPushm(op, symbolnode == null ? globalClassIndex : symbolnode.classScope, runtimeIndex);

                        if (null != identnode.ArrayDimensions)
                        {
                            dimensions = DfsEmitArrayIndexHeap(identnode.ArrayDimensions, graphNode);
                        }

                        if (dimensions > 0)
                        {
                            EmitPushDimensions(dimensions);
                            EmitLoadElement(symbolnode, runtimeIndex);
                        }
                    }
                    else
                    {
                        // change to dynamic call to facilitate update mechanism
                        DSASM.DyanmicVariableNode dynamicVariableNode = new DSASM.DyanmicVariableNode(identnode.Name, globalProcIndex, globalClassIndex);
                        core.DynamicVariableTable.variableTable.Add(dynamicVariableNode);
                        StackValue dynamicOp = StackValue.BuildDynamic(core.DynamicVariableTable.variableTable.Count - 1);
                        EmitInstrConsole(ProtoCore.DSASM.kw.pushm, identnode.Value + "[dynamic]");
                        EmitPushm(dynamicOp, symbolnode == null ? globalClassIndex : symbolnode.classScope, runtimeIndex);

                        if (null != identnode.ArrayDimensions)
                        {
                            dimensions = DfsEmitArrayIndexHeap(identnode.ArrayDimensions, graphNode);
                        }

                        if (dimensions > 0)
                        {
                            EmitPushDimensions(dimensions);
                            EmitLoadElement(null, Constants.kInvalidIndex);
                        }
                    }
                    depth = depth + 1;
                    finalType = lefttype;
                }
                return true;
            }
            else if (node is ProtoCore.AST.ImperativeAST.FunctionCallNode || node is ProtoCore.AST.AssociativeAST.FunctionCallNode)
            {
                // A function call must always track dependents
                bool allowDependents = true;
                if (null != graphNode)
                {
                    allowDependents = graphNode.allowDependents;
                    graphNode.allowDependents = true;
                }

                if (binaryExpNode != null)
                {
                    ProtoCore.Utils.NodeUtils.SetNodeLocation(node, binaryExpNode, binaryExpNode);
                }
                ProtoCore.DSASM.ProcedureNode procnode = TraverseFunctionCall(node, pNode, lefttype.UID, depth, ref finalType, graphNode, subPass, binaryExpNode);

                // Restore the graphNode dependent state
                if (null != graphNode)
                {
                    graphNode.allowDependents = allowDependents;
                }

                // This is the first non-auto generated procedure found in the identifier list
                if (null != procnode)
                {
                    if (!procnode.IsConstructor)
                    {
                        functionCallStack.Add(procnode);
                    }
                }

                lefttype = finalType;
                depth = 1;
            }
            else
            {
                string message = "The left side of operator '.' must be an identifier. (B9AEA3A6)";
                buildStatus.LogSemanticError(message, core.CurrentDSFileName, node.line, node.col);
                throw new BuildHaltException(message);
            }
            return false;
        }