Пример #1
0
        public void PushSymbolReference(SymbolNode symbol, UpdateNodeType type = UpdateNodeType.kSymbol)
        {
            Validity.Assert(null != symbol);
            UpdateNode updateNode = new UpdateNode();

            updateNode.symbol   = symbol;
            updateNode.nodeType = type;

            UpdateNodeRef nodeRef = new UpdateNodeRef();

            nodeRef.PushUpdateNode(updateNode);

            updateNodeRefList.Add(nodeRef);
        }
Пример #2
0
 public bool IsEqual(UpdateNode rhs)
 {
     if (nodeType == rhs.nodeType)
     {
         if (nodeType == UpdateNodeType.kSymbol || nodeType == UpdateNodeType.kLiteral)
         {
             return(symbol.IsEqualAtScope(rhs.symbol));
         }
         else if (nodeType == UpdateNodeType.kMethod)
         {
             return(procNode.IsEqual(rhs.procNode));
         }
     }
     return(false);
 }
Пример #3
0
        public void PushProcReference(ProtoCore.DSASM.ProcedureNode proc)
        {
            Debug.Assert(null != proc);
            Debug.Assert(null != updateNodeRefList);
            UpdateNode updateNode = new UpdateNode();

            updateNode.procNode = proc;
            updateNode.nodeType = UpdateNodeType.kMethod;

            UpdateNodeRef nodeRef = new UpdateNodeRef();

            nodeRef.PushUpdateNode(updateNode);

            updateNodeRefList.Add(nodeRef);
        }
Пример #4
0
        public void PushSymbolReference(ProtoCore.DSASM.SymbolNode symbol, ProtoCore.AssociativeGraph.UpdateNodeType type = UpdateNodeType.kSymbol)
        {
            Debug.Assert(null != symbol);
            Debug.Assert(null != updateNodeRefList);
            UpdateNode updateNode = new UpdateNode();

            updateNode.symbol   = symbol;
            updateNode.nodeType = type;

            UpdateNodeRef nodeRef = new UpdateNodeRef();

            nodeRef.PushUpdateNode(updateNode);

            updateNodeRefList.Add(nodeRef);
        }
Пример #5
0
        public void PushSymbolReference(SymbolNode symbol)
        {
            Validity.Assert(null != symbol);
            UpdateNode updateNode = new UpdateNode();

            updateNode.symbol   = symbol;
            updateNode.nodeType = UpdateNodeType.kSymbol;

            UpdateNodeRef nodeRef = new UpdateNodeRef();

            nodeRef.block = symbol.runtimeTableIndex;
            nodeRef.PushUpdateNode(updateNode);

            updateNodeRefList.Add(nodeRef);
        }
Пример #6
0
        public void PushSymbolReference(ProtoCore.DSASM.SymbolNode symbol)
        {
            Debug.Assert(null != symbol);
            Debug.Assert(null != updateNodeRefList);
            UpdateNode updateNode = new UpdateNode();

            updateNode.symbol   = symbol;
            updateNode.nodeType = UpdateNodeType.kSymbol;

            UpdateNodeRef nodeRef = new UpdateNodeRef();

            nodeRef.block = symbol.runtimeTableIndex;
            nodeRef.PushUpdateNode(updateNode);

            updateNodeRefList.Add(nodeRef);
        }
Пример #7
0
        public bool IsUpdateableBy(UpdateNodeRef modifiedRef)
        {
            // Function to check if the current graphnode can be modified by the modified reference
            bool isUpdateable = false;

            if (modifiedRef.nodeList.Count < updateNodeRefList[0].nodeList.Count)
            {
                isUpdateable = true;
                for (int n = 0; n < modifiedRef.nodeList.Count; ++n)
                {
                    UpdateNode updateNode = modifiedRef.nodeList[n];
                    if (!updateNode.Equals(updateNodeRefList[0].nodeList[n]))
                    {
                        isUpdateable = false;
                        break;
                    }
                }
            }
            return(isUpdateable);
        }
Пример #8
0
        protected void EmitDoubleNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            if (subPass == DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
            {
                return;
            }

            dynamic dNode = node;
            if (!enforceTypeCheck || core.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeDouble, inferedType.UID))
            {
                inferedType.UID = (int)PrimitiveType.kTypeDouble;
            }
            inferedType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : inferedType.UID;

            if (core.Options.TempReplicationGuideEmptyFlag)
            {
                if (emitReplicationGuide)
                {
                    int replicationGuides = 0;

                    // Push the number of guides
                    EmitInstrConsole(ProtoCore.DSASM.kw.push, replicationGuides + "[guide]");
                    ProtoCore.DSASM.StackValue opNumGuides = new ProtoCore.DSASM.StackValue();
                    opNumGuides.optype = ProtoCore.DSASM.AddressType.ReplicationGuide;
                    opNumGuides.opdata = replicationGuides;
                    EmitPush(opNumGuides);
                }
            }

            ProtoCore.DSASM.StackValue op = new ProtoCore.DSASM.StackValue();
            op.optype = ProtoCore.DSASM.AddressType.Double;
            op.opdata = (Int64)System.Convert.ToDouble(dNode.value);
            op.opdata_d = System.Convert.ToDouble(dNode.value, cultureInfo);

            if (core.Options.TempReplicationGuideEmptyFlag && emitReplicationGuide)
            {
                EmitInstrConsole(ProtoCore.DSASM.kw.pushg, dNode.value);
                EmitPushG(op, dNode.line, dNode.col);
            }
            else
            {
                EmitInstrConsole(ProtoCore.DSASM.kw.push, dNode.value);
                EmitPush(op, dNode.line, dNode.col);
            }

            if (IsAssociativeArrayIndexing)
            {
                if (null != graphNode)
                {
                    // Get the last dependent which is the current identifier being indexed into
                    SymbolNode literalSymbol = new SymbolNode();
                    literalSymbol.name = dNode.value;

                    AssociativeGraph.UpdateNode intNode = new AssociativeGraph.UpdateNode();
                    intNode.symbol = literalSymbol;
                    intNode.nodeType = AssociativeGraph.UpdateNodeType.kLiteral;

                    if (graphNode.isIndexingLHS)
                    {
                        graphNode.dimensionNodeList.Add(intNode);
                    }
                    else
                    {
                        int lastDependentIndex = graphNode.dependentList.Count - 1;
                        ProtoCore.AssociativeGraph.UpdateNode currentDependentNode = graphNode.dependentList[lastDependentIndex].updateNodeRefList[0].nodeList[0];
                        currentDependentNode.dimensionNodeList.Add(intNode);

                        if (core.Options.FullSSA)
                        {
                            if (null != firstSSAGraphNode)
                            {
                                lastDependentIndex = firstSSAGraphNode.dependentList.Count - 1;
                                ProtoCore.AssociativeGraph.UpdateNode firstSSAUpdateNode = firstSSAGraphNode.dependentList[lastDependentIndex].updateNodeRefList[0].nodeList[0];
                                firstSSAUpdateNode.dimensionNodeList.Add(intNode);
                            }
                        }
                    }
                }
            }
        }
Пример #9
0
        // Deperecate this function after further regression testing and just use DFSGetSymbolList
        public void DFSGetSymbolList_Simple(Node pNode, ref ProtoCore.Type lefttype, ref int functionindex, ProtoCore.AssociativeGraph.UpdateNodeRef nodeRef)
        {
            dynamic node = pNode;
            if (node is ProtoCore.AST.ImperativeAST.IdentifierListNode || node is ProtoCore.AST.AssociativeAST.IdentifierListNode)
            {
                dynamic bnode = node;
                DFSGetSymbolList_Simple(bnode.LeftNode, ref lefttype, ref functionindex, nodeRef);
                node = bnode.RightNode;
            }

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

                bool isAccessible = false;

                bool isAllocated = VerifyAllocation(identnode.Value, lefttype.UID, functionindex, out symbolnode, out isAccessible);
                if (isAllocated)
                {
                    if (null == symbolnode)
                    {
                        // It is inaccessible from here due to access modifier.
                        // Just attempt to retrieve the symbol
                        int symindex = core.ClassTable.ClassNodes[lefttype.UID].GetFirstVisibleSymbolNoAccessCheck(identnode.Value);
                        if (ProtoCore.DSASM.Constants.kInvalidIndex != symindex)
                        {
                            symbolnode = core.ClassTable.ClassNodes[lefttype.UID].Symbols.symbolList[symindex];
                        }
                    }

                    // Since the variable was found, all succeeding nodes in the ident list are class members
                    // Class members have a function scope of kGlobalScope as they are only local to the class, not with any member function
                    functionindex = ProtoCore.DSASM.Constants.kGlobalScope;

                    lefttype = symbolnode.datatype;

                    ProtoCore.AssociativeGraph.UpdateNode updateNode = new AssociativeGraph.UpdateNode();
                    updateNode.symbol = symbolnode;
                    updateNode.nodeType = ProtoCore.AssociativeGraph.UpdateNodeType.kSymbol;
                    nodeRef.PushUpdateNode(updateNode);
                }
                else
                {
                    // Is it a class?
                    int ci = core.ClassTable.IndexOf(identnode.Value);
                    if (ProtoCore.DSASM.Constants.kInvalidIndex != ci)
                    {
                        lefttype.UID = ci;

                        // Comment Jun:
                        // Create a symbol node that contains information about the class type that contains static properties
                        ProtoCore.DSASM.SymbolNode classSymbol = new DSASM.SymbolNode();
                        classSymbol.memregion = DSASM.MemoryRegion.kMemStatic;
                        classSymbol.name = identnode.Value;
                        classSymbol.classScope = ci;

                        ProtoCore.AssociativeGraph.UpdateNode updateNode = new AssociativeGraph.UpdateNode();
                        updateNode.symbol = classSymbol;
                        updateNode.nodeType = ProtoCore.AssociativeGraph.UpdateNodeType.kSymbol;
                        nodeRef.PushUpdateNode(updateNode);

                    }
                    else
                    {
                        // In this case, the lhs type is undefined
                        // Just attempt to create a symbol node
                        string ident = identnode.Value;
                        if (0 != ident.CompareTo(ProtoCore.DSDefinitions.Keyword.This))
                        {
                            symbolnode = new SymbolNode();
                            symbolnode.name = identnode.Value;

                            ProtoCore.AssociativeGraph.UpdateNode updateNode = new AssociativeGraph.UpdateNode();
                            updateNode.symbol = symbolnode;
                            updateNode.nodeType = AssociativeGraph.UpdateNodeType.kSymbol;
                            nodeRef.PushUpdateNode(updateNode);
                        }
                    }
                }
            }
            else if (node is ProtoCore.AST.ImperativeAST.FunctionCallNode || node is ProtoCore.AST.AssociativeAST.FunctionCallNode)
            {
                string functionName = node.Function.Value;
                if (ProtoCore.Utils.CoreUtils.IsGetterSetter(functionName))
                {
                    string property;
                    if (CoreUtils.TryGetPropertyName(functionName, out property))
                    {
                        functionName = property;
                    }
                    ProtoCore.DSASM.SymbolNode symbolnode = null;


                    bool isAccessible = false;
                    bool isAllocated = VerifyAllocation(functionName, lefttype.UID, globalProcIndex, out symbolnode, out isAccessible);
                    if (isAllocated)
                    {
                        if (null == symbolnode)
                        {
                            // It is inaccessible from here due to access modifier.
                            // Just attempt to retrieve the symbol
                            int symindex = core.ClassTable.ClassNodes[lefttype.UID].GetFirstVisibleSymbolNoAccessCheck(functionName);
                            if (ProtoCore.DSASM.Constants.kInvalidIndex != symindex)
                            {
                                symbolnode = core.ClassTable.ClassNodes[lefttype.UID].Symbols.symbolList[symindex];
                            }
                        }

                        lefttype = symbolnode.datatype;

                        ProtoCore.AssociativeGraph.UpdateNode updateNode = new AssociativeGraph.UpdateNode();
                        updateNode.symbol = symbolnode;
                        updateNode.nodeType = AssociativeGraph.UpdateNodeType.kSymbol;
                        nodeRef.PushUpdateNode(updateNode);
                    }
                }
                else
                {
                    ProtoCore.AssociativeGraph.UpdateNode updateNode = new AssociativeGraph.UpdateNode();
                    ProtoCore.DSASM.ProcedureNode procNodeDummy = new DSASM.ProcedureNode();
                    procNodeDummy.Name = functionName;
                    updateNode.procNode = procNodeDummy;
                    updateNode.nodeType = AssociativeGraph.UpdateNodeType.kMethod;
                    nodeRef.PushUpdateNode(updateNode);
                }
            }
        }
Пример #10
0
 public void PushUpdateNode(UpdateNode node)
 {
     nodeList.Add(node);
 }
Пример #11
0
        protected void EmitStringNode(
            Node node, 
            ref Type inferedType, 
            AssociativeGraph.GraphNode graphNode = null,
            ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone)
        {
            if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier)
            {
                return;
            }

            dynamic sNode = node;
            if (!enforceTypeCheck || core.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeString, inferedType.UID))
            {
                inferedType.UID = (int)PrimitiveType.kTypeString;
            }

            if (core.Options.TempReplicationGuideEmptyFlag && emitReplicationGuide)
            {
                EmitInstrConsole(ProtoCore.DSASM.kw.push, 0 + "[guide]");
                StackValue opNumGuides = StackValue.BuildReplicationGuide(0);
                EmitPush(opNumGuides);
            }

            string value = (string)sNode.Value;
            StackValue svString = core.Heap.AllocateFixedString(value);
            if (core.Options.TempReplicationGuideEmptyFlag && emitReplicationGuide)
            {
                EmitInstrConsole(kw.pushg, "\"" + value + "\"");
                EmitPushG(svString, node.line, node.col);
            }
            else
            {
                EmitInstrConsole(kw.push, "\"" + value + "\"");
                EmitPush(svString, node.line, node.col);
            }

            if (IsAssociativeArrayIndexing && graphNode != null && graphNode.isIndexingLHS)
            {
                SymbolNode literalSymbol = new SymbolNode();
                literalSymbol.name = value;

                var dimNode = new AssociativeGraph.UpdateNode();
                dimNode.symbol = literalSymbol;
                dimNode.nodeType = AssociativeGraph.UpdateNodeType.kLiteral;

                graphNode.dimensionNodeList.Add(dimNode);
            }
        }
Пример #12
0
        protected void EmitDoubleNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone)
        {
            if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier)
            {
                return;
            }

            double value;
            if (node is AST.ImperativeAST.DoubleNode)
            {
                value = (node as AST.ImperativeAST.DoubleNode).Value;
            }
            else if (node is AST.AssociativeAST.DoubleNode)
            {
                value = (node as AST.AssociativeAST.DoubleNode).Value;
            }
            else
            {
                throw new InvalidDataException("The input node is not DoubleNode");
            }

            if (!enforceTypeCheck || core.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeDouble, inferedType.UID))
            {
                inferedType.UID = (int)PrimitiveType.kTypeDouble;
            }
            inferedType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : inferedType.UID;

            if (core.Options.TempReplicationGuideEmptyFlag)
            {
                if (emitReplicationGuide)
                {
                    int replicationGuides = 0;

                    // Push the number of guides
                    EmitInstrConsole(ProtoCore.DSASM.kw.push, replicationGuides + "[guide]");
                    StackValue opNumGuides = StackValue.BuildReplicationGuide(replicationGuides);
                    EmitPush(opNumGuides);
                }
            }

            StackValue op = StackValue.BuildDouble(value);
            if (core.Options.TempReplicationGuideEmptyFlag && emitReplicationGuide)
            {
                EmitInstrConsole(ProtoCore.DSASM.kw.pushg, value.ToString());
                EmitPushG(op, node.line, node.col);
            }
            else
            {
                EmitInstrConsole(ProtoCore.DSASM.kw.push, value.ToString());
                EmitPush(op, node.line, node.col);
            }

            if (IsAssociativeArrayIndexing)
            {
                if (null != graphNode)
                {
                    // Get the last dependent which is the current identifier being indexed into
                    SymbolNode literalSymbol = new SymbolNode();
                    literalSymbol.name = value.ToString();

                    AssociativeGraph.UpdateNode intNode = new AssociativeGraph.UpdateNode();
                    intNode.symbol = literalSymbol;
                    intNode.nodeType = AssociativeGraph.UpdateNodeType.kLiteral;

                    if (graphNode.isIndexingLHS)
                    {
                        graphNode.dimensionNodeList.Add(intNode);
                    }
                    else
                    {
                        int lastDependentIndex = graphNode.dependentList.Count - 1;
                        ProtoCore.AssociativeGraph.UpdateNode currentDependentNode = graphNode.dependentList[lastDependentIndex].updateNodeRefList[0].nodeList[0];
                        currentDependentNode.dimensionNodeList.Add(intNode);

                        if (core.Options.GenerateSSA)
                        {
                            if (null != firstSSAGraphNode)
                            {
                                lastDependentIndex = firstSSAGraphNode.dependentList.Count - 1;
                                ProtoCore.AssociativeGraph.UpdateNode firstSSAUpdateNode = firstSSAGraphNode.dependentList[lastDependentIndex].updateNodeRefList[0].nodeList[0];
                                firstSSAUpdateNode.dimensionNodeList.Add(intNode);
                            }
                        }
                    }
                }
            }
        }
Пример #13
0
 public bool IsEqual(UpdateNode rhs)
 {
     if (nodeType == rhs.nodeType)
     {
         if (nodeType == UpdateNodeType.kSymbol || nodeType == UpdateNodeType.kLiteral)
         {
             return symbol.IsEqualAtScope(rhs.symbol);
         }
         else if (nodeType == UpdateNodeType.kMethod)
         {
             return procNode.IsEqual(rhs.procNode);
         }
     }
     return false;
 }
Пример #14
0
 public void PushUpdateNode(UpdateNode node)
 {
     Validity.Assert(null != nodeList);
     nodeList.Add(node);
 }
Пример #15
0
        private void EmitIdentifierNode(AssociativeNode node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone, BinaryExpressionNode parentNode = null)
        {
            IdentifierNode t = node as IdentifierNode;
            if (t.Name.Equals(ProtoCore.DSDefinitions.Keyword.This))
            {
                if (subPass != ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone)
                {
                    return;
                }

                if (localProcedure != null)
                {
                    if (localProcedure.IsStatic)
                    {
                        string message = ProtoCore.Properties.Resources.kUsingThisInStaticFunction;
                        core.BuildStatus.LogWarning(ProtoCore.BuildData.WarningID.kInvalidThis, message, core.CurrentDSFileName, t.line, t.col, graphNode);
                        EmitPushNull();
                        return;
                    }
                    else if (localProcedure.ClassID == Constants.kGlobalScope)
                    {
                        string message = ProtoCore.Properties.Resources.kInvalidThis;
                        core.BuildStatus.LogWarning(ProtoCore.BuildData.WarningID.kInvalidThis, message, core.CurrentDSFileName, t.line, t.col, graphNode);
                        EmitPushNull();
                        return;
                    }
                    else
                    {
                        EmitThisPointerNode(subPass);
                        return;
                    }
                }
                else
                {
                    string message = ProtoCore.Properties.Resources.kInvalidThis;
                    core.BuildStatus.LogWarning(ProtoCore.BuildData.WarningID.kInvalidThis, message, core.CurrentDSFileName, t.line, t.col, graphNode);
                    EmitPushNull();
                    return;
                }
            }

            int dimensions = 0;

            ProtoCore.DSASM.SymbolNode symbolnode = null;
            int runtimeIndex = codeBlock.symbolTable.RuntimeIndex;

            ProtoCore.Type type = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, 0);

            bool isAccessible = false;
            bool isAllocated = VerifyAllocation(t.Name, globalClassIndex, globalProcIndex, out symbolnode, out isAccessible);
            if (!isAllocated && null == t.ArrayDimensions)
            {
                //check if it is a function instance
                ProtoCore.DSASM.ProcedureNode procNode = null;
                procNode = CoreUtils.GetFunctionByName(t.Name, codeBlock);
                if (null != procNode)
                {
                    if (ProtoCore.DSASM.Constants.kInvalidIndex != procNode.ID)
                    {
                        // A global function
                        inferedType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeFunctionPointer, 0);
                        if (ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier != subPass)
                        {
                            int fptr = core.FunctionPointerTable.functionPointerDictionary.Count;
                            var fptrNode = new FunctionPointerNode(procNode);
                            core.FunctionPointerTable.functionPointerDictionary.TryAdd(fptr, fptrNode);
                            core.FunctionPointerTable.functionPointerDictionary.TryGetBySecond(fptrNode, out fptr);

                            EmitPushVarData(0);

                            EmitInstrConsole(ProtoCore.DSASM.kw.push, t.Name);
                            StackValue opFunctionPointer = StackValue.BuildFunctionPointer(fptr);
                            EmitPush(opFunctionPointer, runtimeIndex, t.line, t.col);
                        }
                        return;
                    }
         
                }
            }            

            if (ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier == subPass)
            {
                if (symbolnode == null)
                {
                    // The variable is unbound
                    ProtoCore.DSASM.SymbolNode unboundVariable = null;
                    if (ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter != core.Options.RunMode)
                    {
                        inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeNull;

                        // Jun Comment: Specification 
                        //      If resolution fails at this point a com.Design-Script.Imperative.Core.UnboundIdentifier 
                        //      warning is emitted during pre-execute phase, and at the ID is bound to null. (R1 - Feb)

                        // Set the first symbol that triggers the cycle to null
                        ProtoCore.AssociativeGraph.GraphNode nullAssignGraphNode = new ProtoCore.AssociativeGraph.GraphNode();
                        nullAssignGraphNode.updateBlock.startpc = pc;


                        EmitPushNull();

                        // Push the identifier local block  
                        dimensions = 0;
                        EmitPushVarData(dimensions);
                        ProtoCore.Type varType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, 0);

                        // TODO Jun: Refactor Allocate() to just return the symbol node itself
                        unboundVariable = Allocate(globalClassIndex, globalClassIndex, globalProcIndex, t.Value, varType, ProtoCore.DSASM.Constants.kPrimitiveSize,
                            false, ProtoCore.CompilerDefinitions.AccessModifier.kPublic, ProtoCore.DSASM.MemoryRegion.kMemStack, t.line, t.col, graphNode);
                        Validity.Assert(unboundVariable != null);

                        int symbolindex = unboundVariable.symbolTableIndex;
                        if (ProtoCore.DSASM.Constants.kInvalidIndex != globalClassIndex)
                        {
                            symbolnode = core.ClassTable.ClassNodes[globalClassIndex].Symbols.symbolList[symbolindex];
                        }
                        else
                        {
                            symbolnode = codeBlock.symbolTable.symbolList[symbolindex];
                        }

                        EmitInstrConsole(ProtoCore.DSASM.kw.pop, t.Value);
                        EmitPopForSymbol(unboundVariable, runtimeIndex);


                        nullAssignGraphNode.PushSymbolReference(symbolnode);
                        nullAssignGraphNode.procIndex = globalProcIndex;
                        nullAssignGraphNode.classIndex = globalClassIndex;
                        nullAssignGraphNode.updateBlock.endpc = pc - 1;

                        PushGraphNode(nullAssignGraphNode);
                        EmitDependency(ProtoCore.DSASM.Constants.kInvalidIndex, ProtoCore.DSASM.Constants.kInvalidIndex, false);
                    }

                    if (isAllocated)
                    {
                        string message = String.Format(ProtoCore.Properties.Resources.kPropertyIsInaccessible, t.Value);
                        if (localProcedure != null && localProcedure.IsStatic)
                        {
                            SymbolNode tempSymbolNode;

                            VerifyAllocation(
                                t.Name,
                                globalClassIndex,
                                Constants.kGlobalScope,
                                out tempSymbolNode,
                                out isAccessible);

                            if (tempSymbolNode != null && !tempSymbolNode.isStatic && isAccessible)
                            {
                                message = String.Format(ProtoCore.Properties.Resources.kUsingNonStaticMemberInStaticContext, t.Value);
                            }
                        }
                        buildStatus.LogWarning(
                            WarningID.kAccessViolation,
                            message,
                            core.CurrentDSFileName,
                            t.line,
                            t.col,
                            graphNode);
                    }
                    else
                    {
                        string message = String.Format(ProtoCore.Properties.Resources.kUnboundIdentifierMsg, t.Value);
                        buildStatus.LogUnboundVariableWarning(unboundVariable, message, core.CurrentDSFileName, t.line, t.col, graphNode);
                    }
                }

                if (null != t.ArrayDimensions)
                {
                    dimensions = DfsEmitArrayIndexHeap(t.ArrayDimensions, graphNode, parentNode, subPass);
                }
            }
            else
            {
                if (core.Options.RunMode == ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter &&
                    !isAllocated)
                {
                    // It happens when the debugger try to watch a variable 
                    // which has been out of scope (as watch is done through
                    // execute an expression "t = v;" where v is the variable
                    // to be watched.
                    EmitPushNull();
                    return;
                }

                Validity.Assert(isAllocated);

                if (graphNode != null 
                    && IsAssociativeArrayIndexing 
                    && !CoreUtils.IsAutoGeneratedVar(symbolnode.name))
                {
                    UpdateNode updateNode = new UpdateNode();
                    updateNode.symbol = symbolnode;
                    updateNode.nodeType = UpdateNodeType.kSymbol;

                    if (graphNode.isIndexingLHS)
                    {
                        graphNode.dimensionNodeList.Add(updateNode);
                    }
                    else
                    {
                        int curDepIndex = graphNode.dependentList.Count - 1;
                        if (curDepIndex >= 0)
                        {
                            var curDep = graphNode.dependentList[curDepIndex].updateNodeRefList[0].nodeList[0];
                            curDep.dimensionNodeList.Add(updateNode);

                            if (core.Options.GenerateSSA)
                            {
                                if (null != firstSSAGraphNode)
                                {
                                    curDepIndex = firstSSAGraphNode.dependentList.Count - 1;
                                    if (curDepIndex >= 0)
                                    {
                                        ProtoCore.AssociativeGraph.UpdateNode firstSSAUpdateNode = firstSSAGraphNode.dependentList[curDepIndex].updateNodeRefList[0].nodeList[0];
                                        firstSSAUpdateNode.dimensionNodeList.Add(updateNode);
                                    }
                                }
                            }
                        }
                    }
                }

                // If it is a property, replaced it with getter: %get_prop()
                if (symbolnode.classScope != ProtoCore.DSASM.Constants.kInvalidIndex &&
                    symbolnode.functionIndex == ProtoCore.DSASM.Constants.kGlobalScope &&
                    localProcedure != null)
                {
                    string getterName = ProtoCore.DSASM.Constants.kGetterPrefix + t.Name;
                    if (!string.Equals(localProcedure.Name, getterName))
                    {
                        var thisNode =AstFactory.BuildIdentifier(ProtoCore.DSDefinitions.Keyword.This);
                        var identListNode = AstFactory.BuildIdentList(thisNode, t);
                        EmitIdentifierListNode(identListNode, ref inferedType, false, graphNode, ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone);

                        if (null != graphNode)
                        {
                            PushSymbolAsDependent(symbolnode, graphNode);
                        }

                        return;
                    }
                }

                type = symbolnode.datatype;
                runtimeIndex = symbolnode.runtimeTableIndex;

                // The graph node always depends on this identifier
                GraphNode dependendNode = null;
                if (null != graphNode)
                {
                    dependendNode = PushSymbolAsDependent(symbolnode, graphNode);
                }


                // Flags if the variable is allocated in the current scope
                bool isAllocatedWithinCurrentBlock = symbolnode.codeBlockId == codeBlock.codeBlockId;
                bool isValidDependent = dependendNode != null && !CoreUtils.IsSSATemp(symbolnode.name);
                if (!isAllocatedWithinCurrentBlock && isValidDependent)
                {
                    /*
                    a = 1;
                    i = [Associative]
                    {
                        // In an inner language block:
                        //  Add all rhs to the parent graphnode dependency list if the rhs was not allocated at the current scope
                        //  Only those not allocated are added to the parent.
                        //  This is because external nodes should not be able to update the local block if the affected variable is local to the block
                        //  Variable 'x' is local and the outer block statement x = 2 (where x is allocated globally), should not update this inner block
                        x = 10;
                        b = x + 1;
                        return = a + b + 10; 
                    }
                    x = 2;
                    a = 2;
                    */
                    context.DependentVariablesInScope.Add(dependendNode);
                }

                bool emitReplicationGuideFlag = emitReplicationGuide;
                emitReplicationGuide = false;
                if (null != t.ArrayDimensions)
                {
                    dimensions = DfsEmitArrayIndexHeap(t.ArrayDimensions, graphNode, parentNode, subPass);
                }
                emitReplicationGuide = emitReplicationGuideFlag;

                //fix type's rank   
                if (type.rank >= 0)
                {
                    type.rank -= dimensions;
                    if (type.rank < 0)
                    {
                        //throw new Exception("Exceed maximum rank!");
                        type.rank = 0;
                    }
                }

                EmitPushVarData(dimensions);

                if (ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter == core.Options.RunMode)
                {
                    EmitInstrConsole(ProtoCore.DSASM.kw.pushw, t.Value);
                    EmitPushForSymbolW(symbolnode, runtimeIndex, t.line, t.col);
                }
                else
                {
                    EmitInstrConsole(ProtoCore.DSASM.kw.push, t.Value);
                    EmitPushForSymbol(symbolnode, runtimeIndex, t);

                    if (emitReplicationGuide)
                    {
                        EmitAtLevel(t.AtLevel);
                        EmitReplicationGuides(t.ReplicationGuides);
                    }
                }

                if (core.TypeSystem.IsHigherRank(type.UID, inferedType.UID))
                {
                    inferedType = type;
                }
                // We need to get inferedType for boolean variable so that we can perform type check
                inferedType.UID = (isBooleanOp || (type.UID == (int)PrimitiveType.kTypeBool)) ? (int)PrimitiveType.kTypeBool : inferedType.UID;
            }

        }
Пример #16
0
 public void PushUpdateNode(UpdateNode node)
 {
     nodeList.Add(node);
 }
Пример #17
0
        public bool DependsOn(UpdateNodeRef modifiedRef, ref GraphNode dependentNode)
        {
            bool match = false;

            foreach (GraphNode depNode in dependentList)
            {
                Validity.Assert(1 == depNode.updateNodeRefList.Count);
                //foreach (UpdateNodeRef depNodeRef in depNode.updateNodeRefList)
                //{
                UpdateNodeRef depNodeRef        = depNode.updateNodeRefList[0];
                bool          bothSymbolsMatch  = false;
                bool          bothSymbolsStatic = false;
                bool          inImperativeMatch = false;
                bool          inImperative      = false;
                if (depNodeRef != null)
                {
                    if (depNodeRef.nodeList != null && modifiedRef.nodeList != null && depNodeRef.nodeList.Count > 0 && modifiedRef.nodeList.Count > 0)
                    {
                        if (depNodeRef.nodeList.Count > modifiedRef.nodeList.Count)
                        {
                            for (int m = 0; m < depNodeRef.nodeList.Count; m++)
                            {
                                if (depNodeRef.nodeList[m] != null && modifiedRef.nodeList[0] != null && depNodeRef.nodeList[m].symbol != null && modifiedRef.nodeList[0].symbol != null)
                                {
                                    if (modifiedRef.nodeList[0].symbol.forArrayName != null && !modifiedRef.nodeList[0].symbol.forArrayName.Equals(""))
                                    {
                                        inImperative = true;
                                        if (modifiedRef.nodeList[0].symbol.functionIndex == Constants.kInvalidIndex)
                                        {
                                            inImperative = inImperative &&
                                                           (depNodeRef.nodeList[m].symbol.functionIndex == Constants.kInvalidIndex) &&
                                                           (modifiedRef.nodeList[0].symbol.codeBlockId == depNodeRef.nodeList[m].symbol.codeBlockId);
                                        }

                                        if (inImperative && modifiedRef.nodeList[0].symbol.functionIndex == depNodeRef.nodeList[m].symbol.functionIndex && (modifiedRef.nodeList[0].symbol.name == depNodeRef.nodeList[m].symbol.name || modifiedRef.nodeList[0].symbol.forArrayName == depNodeRef.nodeList[m].symbol.name))
                                        {
                                            inImperativeMatch = true;
                                        }
                                    }
                                }
                            }
                        }
                        else if (depNodeRef.nodeList.Count == modifiedRef.nodeList.Count)
                        {
                            for (int m = 0; m < depNodeRef.nodeList.Count && m < modifiedRef.nodeList.Count; m++)
                            {
                                if (depNodeRef.nodeList[m] != null && modifiedRef.nodeList[m] != null && depNodeRef.nodeList[m].symbol != null && modifiedRef.nodeList[m].symbol != null)
                                {
                                    if (modifiedRef.nodeList[0].symbol.forArrayName != null && !modifiedRef.nodeList[0].symbol.forArrayName.Equals(""))
                                    {
                                        inImperative = true;
                                        if (modifiedRef.nodeList[m].symbol.functionIndex == Constants.kInvalidIndex)
                                        {
                                            inImperative = inImperative &&
                                                           (depNodeRef.nodeList[m].symbol.functionIndex == Constants.kInvalidIndex) &&
                                                           (modifiedRef.nodeList[m].symbol.codeBlockId == depNodeRef.nodeList[m].symbol.codeBlockId);
                                        }
                                        if (inImperative && modifiedRef.nodeList[m].symbol.functionIndex == depNodeRef.nodeList[m].symbol.functionIndex && modifiedRef.nodeList[m].symbol.name == depNodeRef.nodeList[m].symbol.name)
                                        {
                                            inImperativeMatch = true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }


                if (!inImperativeMatch)
                {
                    // Does first symbol match


                    if (null != modifiedRef.nodeList[0].symbol && null != depNodeRef.nodeList[0].symbol)
                    {
                        bothSymbolsMatch = modifiedRef.nodeList[0].symbol.Equals(depNodeRef.nodeList[0].symbol);


                        bothSymbolsStatic =
                            modifiedRef.nodeList[0].symbol.memregion == MemoryRegion.kMemStatic &&
                            depNodeRef.nodeList[0].symbol.memregion == MemoryRegion.kMemStatic &&
                            modifiedRef.nodeList[0].symbol.name == depNodeRef.nodeList[0].symbol.name;

                        // Check further if their array index match in literal values
                        if (bothSymbolsMatch)
                        {
                            // Are the indices the same number
                            bool areIndicesMatching = modifiedRef.nodeList[0].dimensionNodeList.Count >= depNodeRef.nodeList[0].dimensionNodeList.Count;
                            if (areIndicesMatching && depNodeRef.nodeList[0].dimensionNodeList.Count > 0)
                            {
                                for (int n = 0; n < depNodeRef.nodeList[0].dimensionNodeList.Count; ++n)
                                {
                                    // Is either a non-literal
                                    UpdateNode modDimNode = modifiedRef.nodeList[0].dimensionNodeList[n];
                                    UpdateNode depDimNode = depNodeRef.nodeList[0].dimensionNodeList[n];

                                    if (modDimNode.nodeType != depDimNode.nodeType)
                                    {
                                        bothSymbolsMatch = false;
                                    }
                                    else if (modDimNode.nodeType == UpdateNodeType.kLiteral)
                                    {
                                        bothSymbolsMatch = modDimNode.symbol.name.CompareTo(depDimNode.symbol.name) == 0;
                                    }
                                    else if (modDimNode.nodeType == UpdateNodeType.kSymbol)
                                    {
                                        bothSymbolsMatch = modDimNode.symbol.Equals(depDimNode.symbol);
                                    }
                                    else
                                    {
                                        bothSymbolsMatch = false;
                                    }

                                    if (!bothSymbolsMatch)
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    if (bothSymbolsMatch || bothSymbolsStatic)
                    {
                        match = true;

                        // If it is static, then all symbols must match
                        if (bothSymbolsStatic)
                        {
                            // The number of symbols in the modifed reference...
                            //  ...must match
                            // The number of symbols in the current dependency noderef
                            if (modifiedRef.nodeList.Count == depNodeRef.nodeList.Count)
                            {
                                for (int n = 1; n < modifiedRef.nodeList.Count; ++n)
                                {
                                    //Validity.Assert(!modifiedRef.nodeList[n].isMethod);
                                    //Validity.Assert(!depNodeRef.nodeList[n].isMethod);

                                    if (UpdateNodeType.kMethod == modifiedRef.nodeList[n].nodeType || UpdateNodeType.kMethod == depNodeRef.nodeList[n].nodeType)
                                    {
                                        match = false;
                                        break;
                                    }

                                    if (modifiedRef.nodeList[n].symbol.index != depNodeRef.nodeList[n].symbol.index)
                                    {
                                        match = false;
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                match = false;
                            }
                        }
                        else
                        {
                            if (modifiedRef.nodeList.Count >= depNodeRef.nodeList.Count)
                            {
                                //
                                // The modifed reference is either the same nodelist length or more than the current dependent
                                // a.x.y is being compared to a.x
                                //
                                for (int n = 1; n < modifiedRef.nodeList.Count; ++n)
                                {
                                    if (modifiedRef.nodeList.Count != depNodeRef.nodeList.Count)
                                    {
                                        if (n >= depNodeRef.nodeList.Count)
                                        {
                                            match = false;
                                            break;
                                        }
                                    }

                                    if (UpdateNodeType.kMethod == modifiedRef.nodeList[n].nodeType || UpdateNodeType.kMethod == depNodeRef.nodeList[n].nodeType)
                                    {
                                        match = false;
                                        break;
                                    }

                                    if (modifiedRef.nodeList[n].symbol.name != depNodeRef.nodeList[n].symbol.name)
                                    {
                                        match = false;
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                //
                                // The modifed reference nodelist is less than than the current dependent nodelist
                                // a.x is being compared to a.x.y
                                //
                                for (int n = 1; n < depNodeRef.nodeList.Count; ++n)
                                {
                                    if (n >= modifiedRef.nodeList.Count)
                                    {
                                        break;
                                    }

                                    if (UpdateNodeType.kMethod == modifiedRef.nodeList[n].nodeType || UpdateNodeType.kMethod == depNodeRef.nodeList[n].nodeType)
                                    {
                                        match = false;
                                        break;
                                    }

                                    if (modifiedRef.nodeList[n].symbol.name != depNodeRef.nodeList[n].symbol.name)
                                    {
                                        match = false;
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    dependentNode = depNode;
                    if (match)
                    {
                        break;
                    }
                }
                else
                {
                    for (int m = 0; m < depNodeRef.nodeList.Count && m < modifiedRef.nodeList.Count; m++)
                    {
                        // Does first symbol match

                        if (null != modifiedRef.nodeList[m].symbol && null != depNodeRef.nodeList[m].symbol)
                        {
                            bothSymbolsMatch  = modifiedRef.nodeList[m].symbol.Equals(depNodeRef.nodeList[m].symbol);
                            bothSymbolsStatic =
                                modifiedRef.nodeList[m].symbol.memregion == MemoryRegion.kMemStatic &&
                                depNodeRef.nodeList[m].symbol.memregion == MemoryRegion.kMemStatic &&
                                modifiedRef.nodeList[m].symbol.name == depNodeRef.nodeList[m].symbol.name;

                            // Check further if their array index match in literal values
                            if (bothSymbolsMatch)
                            {
                                // Are the indices the same number
                                bool areIndicesMatching = modifiedRef.nodeList[m].dimensionNodeList.Count == depNodeRef.nodeList[m].dimensionNodeList.Count;
                                if (areIndicesMatching && modifiedRef.nodeList[m].dimensionNodeList.Count > 0)
                                {
                                    for (int n = 0; n < modifiedRef.nodeList[m].dimensionNodeList.Count; ++n)
                                    {
                                        // Is either a non-literal
                                        bool isEitherNonLiteral = modifiedRef.nodeList[m].dimensionNodeList[n].nodeType != UpdateNodeType.kLiteral ||
                                                                  depNodeRef.nodeList[m].dimensionNodeList[n].nodeType != UpdateNodeType.kLiteral;
                                        if (isEitherNonLiteral)
                                        {
                                            bothSymbolsMatch = false;
                                            break;
                                        }

                                        // They are both literal, now check for their literal values
                                        if (0 != modifiedRef.nodeList[m].dimensionNodeList[n].symbol.name.CompareTo(depNodeRef.nodeList[m].dimensionNodeList[n].symbol.name))
                                        {
                                            // They are not the same
                                            bothSymbolsMatch = false;
                                            break;
                                        }
                                    }
                                }
                            }
                        }

                        if (bothSymbolsMatch || bothSymbolsStatic || inImperativeMatch)
                        {
                            match = true;

                            // If it is static, then all symbols must match
                            if (bothSymbolsStatic)
                            {
                                // The number of symbols in the modifed reference...
                                //  ...must match
                                // The number of symbols in the current dependency noderef
                                if (modifiedRef.nodeList.Count == depNodeRef.nodeList.Count)
                                {
                                    for (int n = 1; n < modifiedRef.nodeList.Count; ++n)
                                    {
                                        //Validity.Assert(!modifiedRef.nodeList[n].isMethod);
                                        //Validity.Assert(!depNodeRef.nodeList[n].isMethod);

                                        if (UpdateNodeType.kMethod == modifiedRef.nodeList[n].nodeType || UpdateNodeType.kMethod == depNodeRef.nodeList[n].nodeType)
                                        {
                                            match = false;
                                            break;
                                        }

                                        if (modifiedRef.nodeList[n].symbol.index != depNodeRef.nodeList[n].symbol.index)
                                        {
                                            match = false;
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    match = false;
                                }
                            }
                            else
                            {
                                if (modifiedRef.nodeList.Count >= depNodeRef.nodeList.Count)
                                {
                                    //
                                    // The modifed reference is either the same nodelist length or more than the current dependent
                                    // a.x.y is being compared to a.x
                                    //
                                    for (int n = 1; n < modifiedRef.nodeList.Count; ++n)
                                    {
                                        if (modifiedRef.nodeList.Count != depNodeRef.nodeList.Count)
                                        {
                                            if (n >= depNodeRef.nodeList.Count)
                                            {
                                                match = false;
                                                break;
                                            }
                                        }

                                        if (UpdateNodeType.kMethod == modifiedRef.nodeList[n].nodeType || UpdateNodeType.kMethod == depNodeRef.nodeList[n].nodeType)
                                        {
                                            match = false;
                                            break;
                                        }

                                        if (modifiedRef.nodeList[n].symbol.name != depNodeRef.nodeList[n].symbol.name)
                                        {
                                            match = false;
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    //
                                    // The modifed reference nodelist is less than than the current dependent nodelist
                                    // a.x is being compared to a.x.y
                                    //
                                    for (int n = 1; n < depNodeRef.nodeList.Count; ++n)
                                    {
                                        if (n >= modifiedRef.nodeList.Count)
                                        {
                                            break;
                                        }

                                        if (UpdateNodeType.kMethod == modifiedRef.nodeList[n].nodeType || UpdateNodeType.kMethod == depNodeRef.nodeList[n].nodeType)
                                        {
                                            match = false;
                                            break;
                                        }

                                        if (modifiedRef.nodeList[n].symbol.name != depNodeRef.nodeList[n].symbol.name)
                                        {
                                            match = false;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    dependentNode = depNode;
                    if (match)
                    {
                        break;
                    }
                }
                //}
            }
            return(match);
        }
Пример #18
0
        public ProtoCore.DSASM.ProcedureNode TraverseDotFunctionCall(ProtoCore.AST.Node node, ProtoCore.AST.Node parentNode, int lefttype, int depth, ref ProtoCore.Type inferedType, 
            ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone,
            ProtoCore.AST.AssociativeAST.BinaryExpressionNode bnode = null)
        {
            FunctionCallNode funcCall = null;
            ProtoCore.DSASM.ProcedureNode procCallNode = null;
            ProtoCore.DSASM.ProcedureNode procDotCallNode = null;
            string procName = null;
            List<ProtoCore.Type> arglist = new List<ProtoCore.Type>();
            ProtoCore.Type dotCallType = new ProtoCore.Type();
            dotCallType.UID = (int)PrimitiveType.kTypeVar;
            dotCallType.IsIndexable = false;

            bool isConstructor = false;
            bool isStaticCall = false;
            bool isStaticCallAllowed = false;
            bool isUnresolvedDot = false;
            bool isUnresolvedMethod = false;

            int classIndex = ProtoCore.DSASM.Constants.kInvalidIndex;
            string className = string.Empty;

            ProtoCore.AST.AssociativeAST.FunctionDotCallNode dotCall = node as ProtoCore.AST.AssociativeAST.FunctionDotCallNode;
            funcCall = dotCall.DotCall;
            procName = dotCall.FunctionCall.Function.Name;

            List<AssociativeNode> replicationGuide = (dotCall.FunctionCall.Function as IdentifierNode).ReplicationGuides;

            var dotCallFirstArgument = dotCall.DotCall.FormalArguments[0];
            if (dotCallFirstArgument is FunctionDotCallNode)
            {
                isUnresolvedDot = true;
            }
            else if (dotCallFirstArgument is IdentifierNode || dotCallFirstArgument is ThisPointerNode)
            {
                // Check if the lhs identifer is a class name
                string lhsName = "";
                int ci = Constants.kInvalidIndex;

                if (dotCallFirstArgument is IdentifierNode)
                {
                    lhsName = (dotCallFirstArgument as IdentifierNode).Name;
                    ci = compileStateTracker.ClassTable.IndexOf(lhsName);
                    classIndex = ci;
                    className = lhsName;

                    // As a class name can be used as property name, we need to
                    // check if this identifier is a property or a class name.
                    //
                    if (ci != Constants.kInvalidIndex && globalClassIndex != Constants.kInvalidIndex)
                    {
                        ProtoCore.DSASM.SymbolNode symbolnode;
                        bool isAccessbile = false;
                        bool hasAllocated = VerifyAllocation(lhsName, globalClassIndex, globalProcIndex, out symbolnode, out isAccessbile);

                        // Well, found a property whose name is class name. Now
                        // we need to check if the RHS function call is
                        // constructor or not.
                        if (hasAllocated && isAccessbile && symbolnode.functionIndex == ProtoCore.DSASM.Constants.kInvalidIndex)
                        {
                            var procnode = GetProcedureFromInstance(ci, dotCall.FunctionCall);
                            if (procnode != null && !procnode.isConstructor)
                            {
                                ci = Constants.kInvalidIndex;
                                lhsName = "";
                            }
                        }
                    }
                }

                if (ci != ProtoCore.DSASM.Constants.kInvalidIndex)
                {
                    // It is a class name
                    dotCall.DotCall.FormalArguments[0] = new IntNode { value = ci.ToString() };
                    dotCallFirstArgument = dotCall.DotCall.FormalArguments[0];

                    inferedType.UID = dotCallType.UID = ci;

                    string rhsName = dotCall.FunctionCall.Function.Name;
                    procCallNode = GetProcedureFromInstance(ci, dotCall.FunctionCall, graphNode);
                    if (null != procCallNode)
                    {
                        isConstructor = procCallNode.isConstructor;

                        // It's a static call if its not a constructor
                        isStaticCall = !procCallNode.isConstructor;

                        // If this is a static call and the first method found was not static
                        // Look further
                        if (isStaticCall && !procCallNode.isStatic)
                        {
                            ProtoCore.DSASM.ProcedureNode staticProcCallNode = compileStateTracker.ClassTable.ClassNodes[ci].GetFirstStaticMemberFunction(procName);
                            if (null != staticProcCallNode)
                            {
                                procCallNode = staticProcCallNode;
                            }
                        }

                        isStaticCallAllowed = procCallNode.isStatic && isStaticCall;
                    }
                    else
                    {
                        ProtoCore.DSASM.ProcedureNode staticProcCallNode = compileStateTracker.ClassTable.ClassNodes[ci].GetFirstStaticMemberFunction(procName);
                        string functionName = dotCall.FunctionCall.Function.Name;
                        string property;

                        if (null != staticProcCallNode)
                        {
                            string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodHasInvalidArguments, functionName);
                            buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, compileStateTracker.CurrentDSFileName, dotCall.line, dotCall.col);
                        }
                        else if (CoreUtils.TryGetPropertyName(functionName, out property))
                        {
                            string message = String.Format(ProtoCore.BuildData.WarningMessage.kCallingNonStaticProperty, lhsName, property);
                            buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, compileStateTracker.CurrentDSFileName, dotCall.line, dotCall.col);
                        }
                        else
                        {
                            string message = String.Format(ProtoCore.BuildData.WarningMessage.kCallingNonStaticMethod, lhsName, functionName);
                            buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, compileStateTracker.CurrentDSFileName, dotCall.line, dotCall.col);
                        }
                    }
                }

                if (dotCall.DotCall.FormalArguments.Count == ProtoCore.DSASM.Constants.kDotCallArgCount)
                {
                    if (dotCallFirstArgument is IdentifierNode)
                    {
                        ProtoCore.DSASM.SymbolNode symbolnode = null;
                        bool isAccessible = false;
                        bool isAllocated = VerifyAllocation((dotCallFirstArgument as IdentifierNode).Name, globalClassIndex, globalProcIndex, out symbolnode, out isAccessible);
                        if (isAllocated && symbolnode.datatype.UID != (int)PrimitiveType.kTypeVar)
                        {
                            inferedType.UID = symbolnode.datatype.UID;

                            if (ProtoCore.DSASM.Constants.kInvalidIndex != inferedType.UID)
                            {
                                procCallNode = GetProcedureFromInstance(symbolnode.datatype.UID, dotCall.FunctionCall);
                            }

                            if (null != procCallNode)
                            {
                                if (procCallNode.isConstructor)
                                {
                                    if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
                                    {
                                        // A constructor cannot be called from an instance
                                        string message = String.Format(ProtoCore.BuildData.WarningMessage.KCallingConstructorOnInstance, procName);
                                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingConstructorOnInstance, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col);
                                    }

                                    isUnresolvedDot = true;
                                    isUnresolvedMethod = true;
                                }
                                else
                                {
                                   isAccessible =
                                       procCallNode.access == ProtoCore.DSASM.AccessSpecifier.kPublic
                                        || (procCallNode.access == ProtoCore.DSASM.AccessSpecifier.kPrivate && procCallNode.classScope == globalClassIndex);

                                    if (!isAccessible)
                                    {
                                        if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
                                        {
                                            string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodIsInaccessible, procName);
                                            buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kAccessViolation, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col);
                                        }
                                    }

                                    if (null != procCallNode)
                                    {
                                        int dynamicRhsIndex = int.Parse((dotCall.DotCall.FormalArguments[1] as IntNode).value);
                                        compileStateTracker.DynamicFunctionTable.functionTable[dynamicRhsIndex].classIndex = procCallNode.classScope;
                                        compileStateTracker.DynamicFunctionTable.functionTable[dynamicRhsIndex].procedureIndex = procCallNode.procId;
                                        compileStateTracker.DynamicFunctionTable.functionTable[dynamicRhsIndex].pc = procCallNode.pc;
                                    }
                                }
                            }
                        }
                        else
                        {
                            isUnresolvedDot = true;
                        }
                    }
                    else if (dotCallFirstArgument is ThisPointerNode)
                    {
                        if (globalClassIndex != Constants.kInvalidIndex)
                        {
                            procCallNode = GetProcedureFromInstance(globalClassIndex, dotCall.FunctionCall);
                            if (null != procCallNode && procCallNode.isConstructor)
                            {
                                dotCall.DotCall.FormalArguments[0] = new IntNode { value = globalClassIndex.ToString() };
                                dotCallFirstArgument = dotCall.DotCall.FormalArguments[0];
                                inferedType.UID = dotCallType.UID = ci;
                            }
                        }
                    }
                }
            }
            else if (funcCall.FormalArguments[0] is IntNode)
            {
                inferedType.UID = dotCallType.UID = int.Parse((funcCall.FormalArguments[0] as IntNode).value);
                classIndex = inferedType.UID;
                procCallNode = GetProcedureFromInstance(dotCallType.UID, dotCall.FunctionCall, graphNode);

                if (null != procCallNode)
                {
                    // It's a static call if its not a constructor
                    isConstructor = procCallNode.isConstructor;
                    isStaticCall = !procCallNode.isConstructor;

                    // If this is a static call and the first method found was not static
                    // Look further
                    if (isStaticCall && !procCallNode.isStatic)
                    {
                        ProtoCore.DSASM.ProcedureNode staticProcCallNode = compileStateTracker.ClassTable.ClassNodes[inferedType.UID].GetFirstStaticMemberFunction(procName);
                        if (null != staticProcCallNode)
                        {
                            procCallNode = staticProcCallNode;
                        }
                    }

                    isStaticCallAllowed = procCallNode.isStatic && isStaticCall;
                    className = compileStateTracker.ClassTable.ClassNodes[dotCallType.UID].name;

                    if (isStaticCall && !isStaticCallAllowed)
                    {
                        if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
                        {
                            string property;
                            className = compileStateTracker.ClassTable.ClassNodes[dotCallType.UID].name;
                            ProtoCore.DSASM.ProcedureNode staticProcCallNode = compileStateTracker.ClassTable.ClassNodes[inferedType.UID].GetFirstStaticMemberFunction(procName);

                            if (null != staticProcCallNode)
                            {
                                string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodHasInvalidArguments, procName);
                                buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, compileStateTracker.CurrentDSFileName, dotCall.line, dotCall.col);
                            }
                            else if (CoreUtils.TryGetPropertyName(procName, out property))
                            {
                                string message = String.Format(ProtoCore.BuildData.WarningMessage.kCallingNonStaticProperty, property, className);
                                buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, compileStateTracker.CurrentDSFileName, dotCall.line, dotCall.col);
                            }
                            else
                            {
                                string message = String.Format(ProtoCore.BuildData.WarningMessage.kCallingNonStaticMethod, procName, className);
                                buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, compileStateTracker.CurrentDSFileName, dotCall.line, dotCall.col);
                            }
                        }
                        isUnresolvedMethod = true;
                    }
                    else
                    {
                        inferedType = procCallNode.returntype;
                    }
                }
            }

            // Its an accceptable method at this point
            if (!isUnresolvedMethod)
            {
                int funtionArgCount = 0;

                //foreach (AssociativeNode paramNode in funcCall.FormalArguments)
                for (int n = 0; n < funcCall.FormalArguments.Count; ++n)
                {
                    AssociativeNode paramNode = funcCall.FormalArguments[n];
                    ProtoCore.Type paramType = new ProtoCore.Type();
                    paramType.UID = (int)ProtoCore.PrimitiveType.kTypeVoid;
                    paramType.IsIndexable = false;

                    emitReplicationGuide = false;

                    // If it's a binary node then continue type check, otherwise disable type check and just take the type of paramNode itself
                    // f(1+2.0) -> type check enabled - param is typed as double
                    // f(2) -> type check disabled - param is typed as int
                    enforceTypeCheck = !(paramNode is BinaryExpressionNode);

                    // TODO Jun: Cleansify me
                    // What im doing is just taking the second parameter of the dot op (The method call)
                    // ...and adding it to the graph node dependencies
                    if (ProtoCore.DSASM.Constants.kDotArgIndexDynTableIndex == n)
                    {
                        if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
                        {
                            if (!isConstructor)
                            {
                                if (null != procCallNode)
                                {
                                    if (graphNode.dependentList.Count > 0)
                                    {
                                        ProtoCore.AssociativeGraph.UpdateNodeRef nodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef();
                                        ProtoCore.AssociativeGraph.UpdateNode updateNode = new ProtoCore.AssociativeGraph.UpdateNode();
                                        ProtoCore.DSASM.ProcedureNode procNodeDummy = new ProtoCore.DSASM.ProcedureNode();
                                        if (procCallNode.isAutoGenerated)
                                        {
                                            ProtoCore.DSASM.SymbolNode sym = new ProtoCore.DSASM.SymbolNode();
                                            sym.name = procName.Remove(0, ProtoCore.DSASM.Constants.kSetterPrefix.Length);
                                            updateNode.nodeType = ProtoCore.AssociativeGraph.UpdateNodeType.kSymbol;
                                            updateNode.symbol = sym;
                                        }
                                        else
                                        {
                                            procNodeDummy.name = procName;
                                            updateNode.nodeType = ProtoCore.AssociativeGraph.UpdateNodeType.kMethod;
                                            updateNode.procNode = procNodeDummy;
                                        }
                                        graphNode.dependentList[0].updateNodeRefList[0].nodeList.Add(updateNode);
                                    }
                                }
                                else
                                {
                                    // comment Jun:
                                    // This is dotarg whos first argument is also a dotarg
                                    // dotarg(dorarg...)...)
                                    if (graphNode.dependentList.Count > 0)
                                    {
                                        if (ProtoCore.Utils.CoreUtils.IsGetterSetter(procName))
                                        {
                                            ProtoCore.AssociativeGraph.UpdateNode updateNode = new ProtoCore.AssociativeGraph.UpdateNode();
                                            ProtoCore.DSASM.SymbolNode sym = new ProtoCore.DSASM.SymbolNode();
                                            sym.name = procName.Remove(0, ProtoCore.DSASM.Constants.kSetterPrefix.Length);
                                            updateNode.nodeType = ProtoCore.AssociativeGraph.UpdateNodeType.kSymbol;
                                            updateNode.symbol = sym;

                                            graphNode.dependentList[0].updateNodeRefList[0].nodeList.Add(updateNode);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    // Traversing the first arg (the LHS pointer/Static instanct/Constructor
                    if (ProtoCore.DSASM.Constants.kDotArgIndexPtr == n)
                    {
                        // Comment Jun:
                        //      Allow guides only on 'this' pointers for non getter/setter methods
                        //      No guides for 'this' pointers in constructors calls (There is no this pointer yet)
                        //
                        /*
                            class C
                            {
                                def f(a : int)
                                {
                                    return = 10;
                                }
                            }
                            p = {C.C(), C.C()};
                            x = p<1>.f({1,2}<2>); // guides allowed on the pointer 'p'

                            class A
                            {
                                x : var[];
                                constructor A()
                                {
                                    x = {1,2};
                                }
                            }
                            a = A.A();
                            b = A.A();
                            c = a<1>.x<2>; // guides not allowed on getter

                         */
                        if (!ProtoCore.Utils.CoreUtils.IsGetterSetter(procName) && !isConstructor)
                        {
                            emitReplicationGuide = true;
                        }

                        DfsTraverse(paramNode, ref paramType, false, graphNode, subPass, bnode);
                        if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
                        {
                            if (isStaticCall && isStaticCallAllowed)
                            {
                                Validity.Assert(ProtoCore.DSASM.Constants.kInvalidIndex != classIndex);
                                Validity.Assert(string.Empty != className);
                                SymbolNode classSymbol = new SymbolNode();
                                classSymbol.name = className;
                                classSymbol.classScope = classIndex;

                                ProtoCore.AssociativeGraph.GraphNode dependentNode = new ProtoCore.AssociativeGraph.GraphNode();
                                dependentNode.PushSymbolReference(classSymbol, ProtoCore.AssociativeGraph.UpdateNodeType.kSymbol);
                                graphNode.PushDependent(dependentNode);
                            }
                        }
                    }

                    // Traversing the actual arguments passed into the function (not the dot function)
                    else if (ProtoCore.DSASM.Constants.kDotArgIndexArrayArgs == n)
                    {
                        int defaultAdded = 0;

                        // If its null this is the second call in a chained dot
                        if (null != procCallNode)
                        {
                            // Check how many args were passed in.... against what is expected
                            defaultAdded = procCallNode.argInfoList.Count - dotCall.FunctionCall.FormalArguments.Count;
                        }

                        // Enable graphnode dependencies if its a setter method
                        bool allowDependentState = null != graphNode ? graphNode.allowDependents : false;
                        if (ProtoCore.Utils.CoreUtils.IsSetter(procName))
                        {
                            // If the arguments are not temporaries
                            ProtoCore.AST.AssociativeAST.ExprListNode exprList = paramNode as ExprListNode;
                            Validity.Assert(1 == exprList.list.Count);

                            string varname = string.Empty;
                            if (exprList.list[0] is IdentifierNode)
                            {
                                varname = (exprList.list[0] as IdentifierNode).Name;

                                // Only allow the acutal function variables and SSA temp vars
                                // TODO Jun: determine what temp could be passed in that is autodegenerated and non-SSA
                                if (!ProtoCore.Utils.CoreUtils.IsAutoGeneratedVar(varname)
                                    || ProtoCore.Utils.CoreUtils.IsSSATemp(varname))
                                {
                                    graphNode.allowDependents = true;
                                }
                            }
                            else
                            {
                                graphNode.allowDependents = true;
                            }

                        }

                        emitReplicationGuide = true;

                        if (defaultAdded > 0)
                        {
                            ProtoCore.AST.AssociativeAST.ExprListNode exprList = paramNode as ExprListNode;

                            if (subPass != AssociativeSubCompilePass.kUnboundIdentifier)
                            {
                                for (int i = 0; i < defaultAdded; i++)
                                {
                                    exprList.list.Add(new DefaultArgNode());
                                }

                            }
                            DfsTraverse(paramNode, ref paramType, false, graphNode, subPass);
                            funtionArgCount = exprList.list.Count;
                        }
                        else
                        {
                            Validity.Assert(paramNode is ProtoCore.AST.AssociativeAST.ExprListNode);
                            ProtoCore.AST.AssociativeAST.ExprListNode exprList = paramNode as ProtoCore.AST.AssociativeAST.ExprListNode;

                            // Comment Jun: This is a getter/setter or a an auto-generated thisarg function...
                            // ...add the dynamic sv that will be resolved as a pointer at runtime
                            if (!isStaticCall && !isConstructor)
                            {
                                //if (null != procCallNode && ProtoCore.Utils.CoreUtils.IsGetterSetter(procCallNode.name) && AssociativeSubCompilePass.kNone == subPass)
                                // TODO Jun: pls get rid of subPass checking outside the core travesal
                                if (ProtoCore.DSASM.AssociativeSubCompilePass.kNone == subPass)
                                {
                                    exprList.list.Insert(0, new DynamicNode());
                                }
                            }

                            if (exprList.list.Count > 0)
                            {
                                foreach (ProtoCore.AST.AssociativeAST.AssociativeNode exprListNode in exprList.list)
                                {
                                    bool repGuideState = emitReplicationGuide;
                                    if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
                                    {
                                        if (exprListNode is ProtoCore.AST.AssociativeAST.ExprListNode
                                            || exprListNode is ProtoCore.AST.AssociativeAST.GroupExpressionNode)
                                        {
                                            if (compileStateTracker.Options.TempReplicationGuideEmptyFlag)
                                            {
                                                // Emit the replication guide for the exprlist
                                                List<ProtoCore.AST.AssociativeAST.AssociativeNode> repGuideList = GetReplicationGuides(exprListNode);
                                                EmitReplicationGuides(repGuideList, true);

                                                emitReplicationGuide = false;

                                                // Pop off the guide if the current element was an array
                                                if (null != repGuideList)
                                                {
                                                    EmitInstrConsole(ProtoCore.DSASM.kw.popg);
                                                    EmitPopGuide();
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        emitReplicationGuide = false;
                                    }

                                    DfsTraverse(exprListNode, ref paramType, false, graphNode, subPass, bnode);
                                    emitReplicationGuide = repGuideState;
                                }

                                if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
                                {

                                    EmitInstrConsole(ProtoCore.DSASM.kw.alloca, exprList.list.Count.ToString());
                                    EmitPopArray(exprList.list.Count);

                                    if (exprList.ArrayDimensions != null)
                                    {
                                        int dimensions = DfsEmitArrayIndexHeap(exprList.ArrayDimensions, graphNode);
                                        EmitInstrConsole(ProtoCore.DSASM.kw.pushindex, dimensions.ToString() + "[dim]");
                                        EmitPushArrayIndex(dimensions);
                                    }
                                }
                            }
                            else
                            {
                                if (exprList != null)
                                {
                                    bool emitReplicationGuideState = emitReplicationGuide;
                                    emitReplicationGuide = false;
                                    DfsTraverse(paramNode, ref paramType, false, graphNode, subPass);
                                    emitReplicationGuide = emitReplicationGuideState;
                                }
                                else
                                {
                                    DfsTraverse(paramNode, ref paramType, false, graphNode, subPass);
                                }
                            }

                            funtionArgCount = exprList.list.Count;
                        }

                        emitReplicationGuide = false;

                        // Restore the state only if it is a setter method
                        if (ProtoCore.Utils.CoreUtils.IsSetter(procName))
                        {
                            graphNode.allowDependents = allowDependentState;
                        }
                    }
                    else if (ProtoCore.DSASM.Constants.kDotArgIndexArgCount == n)
                    {
                        ProtoCore.AST.AssociativeAST.IntNode argNumNode = new ProtoCore.AST.AssociativeAST.IntNode() { value = funtionArgCount.ToString() };
                        DfsTraverse(argNumNode, ref paramType, false, graphNode, subPass);
                    }
                    else
                    {
                        DfsTraverse(paramNode, ref paramType, false, graphNode, subPass);
                    }

                    emitReplicationGuide = false;
                    enforceTypeCheck = true;

                    arglist.Add(paramType);
                }
            }

            if (subPass == ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
            {
                return null;
            }

            // Comment Jun: Append the lhs pointer as an argument to the overloaded function
            if (!isConstructor && !isStaticCall)
            {
                Validity.Assert(dotCall.DotCall.FormalArguments[ProtoCore.DSASM.Constants.kDotArgIndexArrayArgs] is ExprListNode);
                ExprListNode functionArgs = dotCall.DotCall.FormalArguments[ProtoCore.DSASM.Constants.kDotArgIndexArrayArgs] as ExprListNode;
                functionArgs.list.Insert(0, dotCall.DotCall.FormalArguments[ProtoCore.DSASM.Constants.kDotArgIndexPtr]);
            }

            if (isUnresolvedMethod)
            {
                EmitNullNode(new NullNode(), ref inferedType);
                return null;
            }

            procDotCallNode = compileStateTracker.GetFirstVisibleProcedure(ProtoCore.DSASM.Constants.kDotArgMethodName, arglist, codeBlock);

            // From here on, handle the actual procedure call
            int type = ProtoCore.DSASM.Constants.kInvalidIndex;

            int refClassIndex = ProtoCore.DSASM.Constants.kInvalidIndex;
            if (parentNode != null && parentNode is ProtoCore.AST.AssociativeAST.IdentifierListNode)
            {
                ProtoCore.AST.Node leftnode = (parentNode as ProtoCore.AST.AssociativeAST.IdentifierListNode).LeftNode;
                if (leftnode != null && leftnode is ProtoCore.AST.AssociativeAST.IdentifierNode)
                {
                    refClassIndex = compileStateTracker.ClassTable.IndexOf(leftnode.Name);
                }
            }

            if (dotCallFirstArgument is FunctionCallNode ||
                dotCallFirstArgument is FunctionDotCallNode ||
                dotCallFirstArgument is ExprListNode)
            {
                inferedType.UID = arglist[0].UID;
            }

            // If lefttype is a valid class then check if calling a constructor
            if ((int)ProtoCore.PrimitiveType.kInvalidType != inferedType.UID
                && (int)ProtoCore.PrimitiveType.kTypeVoid != inferedType.UID
                && procName != ProtoCore.DSASM.Constants.kFunctionPointerCall)
            {
                bool isStaticOrConstructor = refClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex;
                procCallNode = compileStateTracker.ClassTable.ClassNodes[inferedType.UID].GetFirstMemberFunction(procName);
            }

            // Try function pointer firstly
            if ((procCallNode == null) && (procName != ProtoCore.DSASM.Constants.kFunctionPointerCall))
            {
                bool isAccessibleFp;
                ProtoCore.DSASM.SymbolNode symbolnode = null;
                bool isAllocated = VerifyAllocation(procName, globalClassIndex, globalProcIndex, out symbolnode, out isAccessibleFp);
                if (isAllocated) // not checking the type against function pointer, as the type could be var
                {
                    procName = ProtoCore.DSASM.Constants.kFunctionPointerCall;
                    // The graph node always depends on this function pointer
                    if (null != graphNode)
                    {
                        ProtoCore.AssociativeGraph.GraphNode dependentNode = new ProtoCore.AssociativeGraph.GraphNode();
                        dependentNode.PushSymbolReference(symbolnode);
                        graphNode.PushDependent(dependentNode);
                    }
                }
            }

            // Always try global function firstly. Because we dont have syntax
            // support for calling global function (say, ::foo()), if we try
            // member function firstly, there is no way to call a global function
            // For member function, we can use this.foo() to distinguish it from
            // global function.
            if ((procCallNode == null) && (procName != ProtoCore.DSASM.Constants.kFunctionPointerCall))
            {
                procCallNode = compileStateTracker.GetFirstVisibleProcedure(procName, arglist, codeBlock);
                if (null != procCallNode)
                {
                    type = ProtoCore.DSASM.Constants.kGlobalScope;
                    if (compileStateTracker.TypeSystem.IsHigherRank(procCallNode.returntype.UID, inferedType.UID))
                    {
                        inferedType = procCallNode.returntype;
                    }
                }
            }

            // Try member functions in global class scope
            if ((procCallNode == null) && (procName != ProtoCore.DSASM.Constants.kFunctionPointerCall) && (parentNode == null))
            {
                if (globalClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex)
                {
                    int realType;
                    bool isAccessible;
                    bool isStaticOrConstructor = refClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex;
                    ProtoCore.DSASM.ProcedureNode memProcNode = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].GetMemberFunction(procName, arglist, globalClassIndex, out isAccessible, out realType, isStaticOrConstructor);

                    if (memProcNode != null)
                    {
                        Debug.Assert(realType != ProtoCore.DSASM.Constants.kInvalidIndex);
                        procCallNode = memProcNode;
                        inferedType = procCallNode.returntype;
                        type = realType;

                        if (!isAccessible)
                        {
                            string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodIsInaccessible, procName);
                            buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kAccessViolation, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col);

                            inferedType.UID = (int)PrimitiveType.kTypeNull;
                            EmitPushNull();
                            return procCallNode;
                        }
                    }
                }
            }

            if (isUnresolvedDot)
            {
                // Get the dot call procedure
                ProtoCore.DSASM.ProcedureNode procNode = procDotCallNode;
                if (!isConstructor && !isStaticCall)
                {
                    procNode = compileStateTracker.GetFirstVisibleProcedure(ProtoCore.DSASM.Constants.kDotMethodName, null, codeBlock);
                }

                if(CoreUtils.IsGetter(procName))
                {
                    EmitFunctionCall(depth, type, arglist, procNode, funcCall, true);
                }
                else
                    EmitFunctionCall(depth, type, arglist, procNode, funcCall, false, bnode);

                if (dotCallType.UID != (int)PrimitiveType.kTypeVar)
                {
                    inferedType.UID = dotCallType.UID;
                }

                return procCallNode;
            }

            if (null != procCallNode)
            {
                if (procCallNode.isConstructor &&
                        (globalClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex) &&
                        (globalProcIndex != ProtoCore.DSASM.Constants.kInvalidIndex) &&
                        (globalClassIndex == inferedType.UID))
                {
                    ProtoCore.DSASM.ProcedureNode contextProcNode = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].vtable.procList[globalProcIndex];
                    if (contextProcNode.isConstructor &&
                        string.Equals(contextProcNode.name, procCallNode.name) &&
                        contextProcNode.runtimeIndex == procCallNode.runtimeIndex)
                    {
                        string message = String.Format(ProtoCore.BuildData.WarningMessage.kCallingConstructorInConstructor, procName);
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingConstructorInConstructor, message, compileStateTracker.CurrentDSFileName, node.line, node.col);
                        inferedType.UID = (int)PrimitiveType.kTypeNull;
                        EmitPushNull();
                        return procCallNode;
                    }
                }

                inferedType = procCallNode.returntype;

                //if call is replication call
                if (procCallNode.isThisCallReplication)
                {
                    inferedType.IsIndexable = true;
                    inferedType.rank++;
                }

                // Get the dot call procedure
                ProtoCore.DSASM.ProcedureNode procNode = procDotCallNode;
                if (!isConstructor && !isStaticCall)
                {
                    procNode = compileStateTracker.GetFirstVisibleProcedure(ProtoCore.DSASM.Constants.kDotMethodName, null, codeBlock);
                }

                if (CoreUtils.IsSetter(procName))
                {
                    EmitFunctionCall(depth, type, arglist, procNode, funcCall);
                }
                // Do not emit breakpoint at getters only - pratapa
                else if (CoreUtils.IsGetter(procName))
                {
                    EmitFunctionCall(depth, type, arglist, procNode, funcCall, true);
                }
                else
                {
                    EmitFunctionCall(depth, type, arglist, procNode, funcCall, false, bnode);
                }

                if (dotCallType.UID != (int)PrimitiveType.kTypeVar)
                {
                    inferedType.UID = dotCallType.UID;
                }

                if (isConstructor)
                {
                    foreach (AssociativeNode paramNode in dotCall.FunctionCall.FormalArguments)
                    {
                        // Get the lhs symbol list
                        ProtoCore.Type ltype = new ProtoCore.Type();
                        ltype.UID = globalClassIndex;
                        ProtoCore.AssociativeGraph.UpdateNodeRef argNodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef();
                        DFSGetSymbolList(paramNode, ref ltype, argNodeRef);

                        if (null != graphNode)
                        {
                            graphNode.updatedArguments.Add(argNodeRef);
                        }
                    }

                    graphNode.firstProc = procCallNode;
                }

                return procCallNode;
            }
            else
            {
                // Function does not exist at this point but we try to reolve at runtime
                if (depth <= 0 && procName != ProtoCore.DSASM.Constants.kFunctionPointerCall)
                {
                    if (inferedType.UID != (int)PrimitiveType.kTypeVar)
                    {
                        if (!compileStateTracker.Options.SuppressFunctionResolutionWarning)
                        {
                            string property;
                            if (CoreUtils.TryGetPropertyName(procName, out property))
                            {
                                string message = String.Format(ProtoCore.BuildData.WarningMessage.kPropertyNotFound, property);
                                buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kPropertyNotFound, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col);
                            }
                            else
                            {
                                string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodNotFound, procName);
                                buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kFunctionNotFound, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col);
                            }
                        }
                        inferedType.UID = (int)PrimitiveType.kTypeNull;
                    }

                    // Get the dot call procedure
                    ProtoCore.DSASM.ProcedureNode procNode = procDotCallNode;
                    if (!isConstructor && !isStaticCall)
                    {
                        procNode = compileStateTracker.GetFirstVisibleProcedure(ProtoCore.DSASM.Constants.kDotMethodName, null, codeBlock);
                    }

                    if (CoreUtils.IsGetter(procName))
                    {
                        EmitFunctionCall(depth, type, arglist, procNode, funcCall, true);
                    }
                    else
                        EmitFunctionCall(depth, type, arglist, procNode, funcCall, false, bnode);

                    if (dotCallType.UID != (int)PrimitiveType.kTypeVar)
                    {
                        inferedType.UID = dotCallType.UID;
                    }
                }
                else
                {
                    if (procName == ProtoCore.DSASM.Constants.kFunctionPointerCall && depth == 0)
                    {
                        ProtoCore.DSASM.DynamicFunctionNode dynamicFunctionNode = new ProtoCore.DSASM.DynamicFunctionNode(procName, arglist, lefttype);
                        compileStateTracker.DynamicFunctionTable.functionTable.Add(dynamicFunctionNode);

                        var iNode = nodeBuilder.BuildIdentfier(funcCall.Function.Name);
                        EmitIdentifierNode(iNode, ref inferedType);
                    }
                    else
                    {
                        ProtoCore.DSASM.DynamicFunctionNode dynamicFunctionNode = new ProtoCore.DSASM.DynamicFunctionNode(funcCall.Function.Name, arglist, lefttype);
                        compileStateTracker.DynamicFunctionTable.functionTable.Add(dynamicFunctionNode);
                    }
                    // The function call
                    EmitInstrConsole(ProtoCore.DSASM.kw.callr, funcCall.Function.Name + "[dynamic]");
                    EmitDynamicCall(compileStateTracker.DynamicFunctionTable.functionTable.Count - 1, globalClassIndex, depth, funcCall.line, funcCall.col, funcCall.endLine, funcCall.endCol);

                    // The function return value
                    EmitInstrConsole(ProtoCore.DSASM.kw.push, ProtoCore.DSASM.kw.regRX);
                    ProtoCore.DSASM.StackValue opReturn = new ProtoCore.DSASM.StackValue();
                    opReturn.optype = ProtoCore.DSASM.AddressType.Register;
                    opReturn.opdata = (int)ProtoCore.DSASM.Registers.RX;
                    EmitPush(opReturn);

                    if (compileStateTracker.Options.TempReplicationGuideEmptyFlag && emitReplicationGuide)
                    {
                        int guides = EmitReplicationGuides(replicationGuide);
                        EmitInstrConsole(ProtoCore.DSASM.kw.pushindex, guides + "[guide]");
                        EmitPushReplicationGuide(guides);
                    }

                    //assign inferedType to var
                    inferedType.UID = (int)PrimitiveType.kTypeVar;
                }
            }
            return procDotCallNode;
        }
Пример #19
0
 public void PushUpdateNode(UpdateNode node)
 {
     Validity.Assert(null != nodeList);
     nodeList.Add(node);
 }
Пример #20
0
        protected void EmitStringNode(
            Node node, 
            ref Type inferedType, 
            AssociativeGraph.GraphNode graphNode = null,
            AssociativeSubCompilePass subPass = AssociativeSubCompilePass.kNone)
        {
            if (subPass == AssociativeSubCompilePass.kUnboundIdentifier)
            {
                return;
            }

            dynamic sNode = node;
            if (!enforceTypeCheck || core.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeString, inferedType.UID))
            {
                inferedType.UID = (int)PrimitiveType.kTypeString;
            }

            Byte[] utf8bytes = EncodingUtils.UTF8StringToUTF8Bytes((String)sNode.value);
            String value = Encoding.UTF8.GetString(utf8bytes);

            foreach (char ch in value)
            {
                String strValue = "'" + ch + "'";
                EmitInstrConsole(kw.push, strValue);

                StackValue op = StackValue.BuildChar(ch);
                EmitPush(op, node.line, node.col);
            }

            if (IsAssociativeArrayIndexing && graphNode != null && graphNode.isIndexingLHS)
            {
                SymbolNode literalSymbol = new SymbolNode();
                literalSymbol.name = value;

                var dimNode = new AssociativeGraph.UpdateNode();
                dimNode.symbol = literalSymbol;
                dimNode.nodeType = AssociativeGraph.UpdateNodeType.kLiteral;

                graphNode.dimensionNodeList.Add(dimNode);
            }

            EmitInstrConsole(kw.alloca, value.Length.ToString());
            EmitPopString(value.Length);
        }
Пример #21
0
        protected void EmitIntNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            if (subPass == DSASM.AssociativeSubCompilePass.kUnboundIdentifier) 
            {
                return;
            }

            dynamic iNode = node;
            if (!enforceTypeCheck || compileStateTracker.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeInt, inferedType.UID))
            {
                inferedType.UID = (int)PrimitiveType.kTypeInt;
            }
            
            inferedType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : inferedType.UID;


            if (compileStateTracker.Options.TempReplicationGuideEmptyFlag)
            {
                if (emitReplicationGuide)
                {
                    int replicationGuides = 0;
                    
                    // Push the number of guides
                    EmitInstrConsole(ProtoCore.DSASM.kw.push, replicationGuides + "[guide]");
                    ProtoCore.DSASM.StackValue opNumGuides = new ProtoCore.DSASM.StackValue();
                    opNumGuides.optype = ProtoCore.DSASM.AddressType.ReplicationGuide;
                    opNumGuides.opdata = replicationGuides;
                    EmitPush(opNumGuides);
                }
            }


            ProtoCore.DSASM.StackValue op = new ProtoCore.DSASM.StackValue();
            op.optype = ProtoCore.DSASM.AddressType.Int;
            try
            {
                op.opdata = System.Convert.ToInt64(iNode.value);
                op.opdata_d = System.Convert.ToDouble(iNode.value, cultureInfo);
            }
            catch (System.OverflowException)
            {
                buildStatus.LogSemanticError("The value is too big or too small to be converted to an integer", compileStateTracker.CurrentDSFileName, node.line, node.col);
            }

            if (compileStateTracker.Options.TempReplicationGuideEmptyFlag && emitReplicationGuide)
            {
                EmitInstrConsole(ProtoCore.DSASM.kw.pushg, iNode.value);
                EmitPushG(op, iNode.line, iNode.col);
            }
            else
            {
                EmitInstrConsole(ProtoCore.DSASM.kw.push, iNode.value);
                EmitPush(op, iNode.line, iNode.col);
            }

            if (IsAssociativeArrayIndexing)
            {
                if (null != graphNode)
                {
                    // Get the last dependent which is the current identifier being indexed into
                    SymbolNode literalSymbol = new SymbolNode();
                    literalSymbol.name = iNode.value;

                    AssociativeGraph.UpdateNode intNode = new AssociativeGraph.UpdateNode();
                    intNode.symbol = literalSymbol;
                    intNode.nodeType = AssociativeGraph.UpdateNodeType.kLiteral;

                    if (graphNode.isIndexingLHS)
                    {
                        graphNode.dimensionNodeList.Add(intNode);
                    }
                    else
                    {
                        int lastDependentIndex = graphNode.dependentList.Count - 1;
                        if (lastDependentIndex >= 0)
                        {
                            ProtoCore.AssociativeGraph.UpdateNode currentDependentNode = graphNode.dependentList[lastDependentIndex].updateNodeRefList[0].nodeList[0];
                            currentDependentNode.dimensionNodeList.Add(intNode);

                            if (null != firstSSAGraphNode)
                            {
                                lastDependentIndex = firstSSAGraphNode.dependentList.Count - 1;
                                if (lastDependentIndex >= 0)
                                {
                                    ProtoCore.AssociativeGraph.UpdateNode firstSSAUpdateNode = firstSSAGraphNode.dependentList[lastDependentIndex].updateNodeRefList[0].nodeList[0];
                                    firstSSAUpdateNode.dimensionNodeList.Add(intNode);
                                }
                            }
                            
                        }
                    }
                }
            }
        }
Пример #22
0
        protected void EmitStringNode(
            Node node, 
            ref Type inferedType, 
            AssociativeGraph.GraphNode graphNode = null,
            ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone)
        {
            if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier)
            {
                return;
            }

            dynamic sNode = node;
            if (!enforceTypeCheck || core.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeString, inferedType.UID))
            {
                inferedType.UID = (int)PrimitiveType.kTypeString;
            }

            string value = (string)sNode.Value;
            StackValue svString = core.Heap.AllocateFixedString(value);
            EmitOpWithEmptyReplicationGuide(emitReplicationGuide, svString, "\"" + value + "\"", node);

            if (IsAssociativeArrayIndexing && graphNode != null && graphNode.isIndexingLHS)
            {
                SymbolNode literalSymbol = new SymbolNode();
                literalSymbol.name = value;

                var dimNode = new AssociativeGraph.UpdateNode();
                dimNode.symbol = literalSymbol;
                dimNode.nodeType = AssociativeGraph.UpdateNodeType.kLiteral;

                graphNode.dimensionNodeList.Add(dimNode);
            }
        }
Пример #23
0
        protected void EmitIntNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone)
        {
            if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier) 
            {
                return;
            }

            Int64 value;
            if (node is AST.ImperativeAST.IntNode)
            {
                value = (node as AST.ImperativeAST.IntNode).Value;
            }
            else if (node is AST.AssociativeAST.IntNode)
            {
                value = (node as AST.AssociativeAST.IntNode).Value;
            }
            else
            {
                throw new InvalidDataException("The input node is not a IntNode");
            }

            if (!enforceTypeCheck || core.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeInt, inferedType.UID))
            {
                inferedType.UID = (int)PrimitiveType.kTypeInt;
            }

            inferedType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : inferedType.UID;
            EmitOpWithEmptyReplicationGuide(emitReplicationGuide, StackValue.BuildInt(value), value.ToString(), node);

            if (IsAssociativeArrayIndexing)
            {
                if (null != graphNode)
                {
                    // Get the last dependent which is the current identifier being indexed into
                    SymbolNode literalSymbol = new SymbolNode();
                    literalSymbol.name = value.ToString();

                    AssociativeGraph.UpdateNode intNode = new AssociativeGraph.UpdateNode();
                    intNode.symbol = literalSymbol;
                    intNode.nodeType = AssociativeGraph.UpdateNodeType.kLiteral;

                    if (graphNode.isIndexingLHS)
                    {
                        graphNode.dimensionNodeList.Add(intNode);
                    }
                    else
                    {
                        int lastDependentIndex = graphNode.dependentList.Count - 1;
                        if (lastDependentIndex >= 0)
                        {
                            ProtoCore.AssociativeGraph.UpdateNode currentDependentNode = graphNode.dependentList[lastDependentIndex].updateNodeRefList[0].nodeList[0];
                            currentDependentNode.dimensionNodeList.Add(intNode);

                            if (core.Options.GenerateSSA)
                            {
                                if (null != firstSSAGraphNode)
                                {
                                    lastDependentIndex = firstSSAGraphNode.dependentList.Count - 1;
                                    if (lastDependentIndex >= 0)
                                    {
                                        ProtoCore.AssociativeGraph.UpdateNode firstSSAUpdateNode = firstSSAGraphNode.dependentList[lastDependentIndex].updateNodeRefList[0].nodeList[0];
                                        firstSSAUpdateNode.dimensionNodeList.Add(intNode);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #24
0
        private void TraverseDotCallArguments(FunctionCallNode funcCall, 
                                              FunctionDotCallNode dotCall,
                                              ProcedureNode procCallNode,
                                              List<ProtoCore.Type> arglist,
                                              string procName,
                                              int classIndex,
                                              string className,
                                              bool isStaticCall,
                                              bool isConstructor,
                                              GraphNode graphNode,
                                              AssociativeSubCompilePass subPass,
                                              BinaryExpressionNode bnode)
        {
            // Update graph dependencies
            if (subPass != AssociativeSubCompilePass.kUnboundIdentifier && graphNode != null)
            {
                if (isStaticCall)
                {
                    Validity.Assert(classIndex != Constants.kInvalidIndex);
                    Validity.Assert(!string.IsNullOrEmpty(className));

                    SymbolNode classSymbol = new SymbolNode();
                    classSymbol.name = className;
                    classSymbol.classScope = classIndex;

                    GraphNode dependentNode = new GraphNode();
                    dependentNode.PushSymbolReference(classSymbol, UpdateNodeType.kSymbol);
                    graphNode.PushDependent(dependentNode);
                }

                if (!isConstructor && graphNode.dependentList.Count > 0)
                {
                    UpdateNode updateNode = new UpdateNode();

                    string propertyName;
                    if (CoreUtils.TryGetPropertyName(procName, out propertyName))
                    {
                        var dummySymbol = new SymbolNode();
                        dummySymbol.name = propertyName;

                        updateNode.nodeType = UpdateNodeType.kSymbol;
                        updateNode.symbol = dummySymbol;
                    }
                    else
                    {
                        var dummyProcNode = new ProcedureNode();
                        dummyProcNode.name = procName;

                        updateNode.nodeType = UpdateNodeType.kMethod;
                        updateNode.procNode = dummyProcNode;
                    }

                    graphNode.dependentList[0].updateNodeRefList[0].nodeList.Add(updateNode);
                }
            }

            int funtionArgCount = 0;
            for (int n = 0; n < funcCall.FormalArguments.Count; ++n)
            {
                if (isStaticCall || isConstructor)
                {
                    if (n != Constants.kDotArgIndexArrayArgs)
                    {
                        continue;
                    }
                }

                AssociativeNode paramNode = funcCall.FormalArguments[n];
                ProtoCore.Type paramType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, 0);

                emitReplicationGuide = false;

                // If it's a binary node then continue type check, otherwise 
                // disable type check and just take the type of paramNode itself
                enforceTypeCheck = !(paramNode is BinaryExpressionNode);

                if (ProtoCore.DSASM.Constants.kDotArgIndexPtr == n)
                {
                    // Traversing the first arg (the LHS pointer/Static instanct/Constructor
                    
                    // Replication guides only allowed on method, e.g.,
                    // 
                    //    x = p<1>.f({1,2}<2>); 
                    //
                    // But not on getter, e.g.,
                    // 
                    //    c = a<1>.x<2>; 
                    if (!CoreUtils.IsGetterSetter(procName) && !isConstructor)
                    {
                        emitReplicationGuide = true;
                    }

                    DfsTraverse(paramNode, ref paramType, false, graphNode, subPass, bnode);
                }
                else if (ProtoCore.DSASM.Constants.kDotArgIndexArrayArgs == n)
                {
                    // Traversing the actual arguments passed into the function 
                    // (not the dot function)
                    int defaultArgNumber = 0;

                    // If its null this is the second call in a chained dot
                    if (null != procCallNode)
                    {
                        defaultArgNumber = procCallNode.argInfoList.Count - dotCall.FunctionCall.FormalArguments.Count;
                    }

                    // Enable graphnode dependencies if its a setter method
                    bool allowDependentState = null != graphNode ? graphNode.allowDependents : false;
                    if (CoreUtils.IsSetter(procName))
                    {
                        // If the arguments are not temporaries
                        ExprListNode exprList = paramNode as ExprListNode;
                        Validity.Assert(1 == exprList.list.Count);

                        string varname = string.Empty;
                        if (exprList.list[0] is IdentifierNode)
                        {
                            varname = (exprList.list[0] as IdentifierNode).Name;

                            if (!CoreUtils.IsAutoGeneratedVar(varname))
                            {
                                graphNode.allowDependents = true;
                            }
                            else if (CoreUtils.IsSSATemp(varname) && core.Options.GenerateSSA)
                            {
                                graphNode.allowDependents = true;
                            }
                        }
                        else
                        {
                            graphNode.allowDependents = true;
                        }

                    }

                    emitReplicationGuide = true;

                    if (defaultArgNumber > 0)
                    {
                        ExprListNode exprList = paramNode as ExprListNode;

                        if (subPass != AssociativeSubCompilePass.kUnboundIdentifier)
                        {
                            for (int i = 0; i < defaultArgNumber; i++)
                            {
                                exprList.list.Add(new DefaultArgNode());
                            }

                        }

                        if (!isStaticCall && !isConstructor)
                        {
                            DfsTraverse(paramNode, ref paramType, false, graphNode, subPass);
                            funtionArgCount = exprList.list.Count;
                        }
                        else
                        {
                            foreach (AssociativeNode exprListNode in exprList.list)
                            {
                                bool repGuideState = emitReplicationGuide;
                                if (subPass != AssociativeSubCompilePass.kUnboundIdentifier)
                                {
                                    if (exprListNode is ExprListNode || exprListNode is GroupExpressionNode)
                                    {
                                        if (core.Options.TempReplicationGuideEmptyFlag)
                                        {
                                            // Emit the replication guide for the exprlist
                                            var repGuideList = GetReplicationGuides(exprListNode);
                                            if (repGuideList != null)
                                            {
                                                EmitReplicationGuides(repGuideList, true);
                                                EmitInstrConsole(ProtoCore.DSASM.kw.popg);
                                                EmitPopGuide();
                                            }

                                            emitReplicationGuide = false;
                                        }
                                    }
                                }
                                else
                                {
                                    emitReplicationGuide = false;
                                }

                                DfsTraverse(exprListNode, ref paramType, false, graphNode, subPass, bnode);
                                emitReplicationGuide = repGuideState;

                                arglist.Add(paramType);
                            }
                        }
                    }
                    else
                    {
                        ExprListNode exprList = paramNode as ExprListNode;

                        // Comment Jun: This is a getter/setter or a an auto-generated thisarg function...
                        // ...add the dynamic sv that will be resolved as a pointer at runtime
                        if (!isStaticCall && !isConstructor)
                        {
                            // TODO Jun: pls get rid of subPass checking outside the core travesal
                            if (AssociativeSubCompilePass.kNone == subPass)
                            {
                                exprList.list.Insert(0, new DynamicNode());
                            }
                        }

                        if (exprList.list.Count > 0)
                        {
                            foreach (AssociativeNode exprListNode in exprList.list)
                            {
                                bool repGuideState = emitReplicationGuide;
                                if (subPass != AssociativeSubCompilePass.kUnboundIdentifier)
                                {
                                    if (exprListNode is ExprListNode || exprListNode is GroupExpressionNode)
                                    {
                                        if (core.Options.TempReplicationGuideEmptyFlag)
                                        {
                                            // Emit the replication guide for the exprlist
                                            var repGuideList = GetReplicationGuides(exprListNode);
                                            if (repGuideList != null)
                                            {
                                                EmitReplicationGuides(repGuideList, true);
                                                EmitInstrConsole(ProtoCore.DSASM.kw.popg);
                                                EmitPopGuide();
                                            }

                                            emitReplicationGuide = false;
                                        }
                                    }
                                }
                                else
                                {
                                    emitReplicationGuide = false;
                                }

                                DfsTraverse(exprListNode, ref paramType, false, graphNode, subPass, bnode);
                                emitReplicationGuide = repGuideState;

                                arglist.Add(paramType);
                            }

                            if (subPass != AssociativeSubCompilePass.kUnboundIdentifier &&
                                !isStaticCall &&
                                !isConstructor)
                            {
                                EmitInstrConsole(ProtoCore.DSASM.kw.alloca, exprList.list.Count.ToString());
                                EmitPopArray(exprList.list.Count);

                                if (exprList.ArrayDimensions != null)
                                {
                                    int dimensions = DfsEmitArrayIndexHeap(exprList.ArrayDimensions, graphNode);
                                    EmitInstrConsole(ProtoCore.DSASM.kw.pushindex, dimensions.ToString() + "[dim]");
                                    EmitPushArrayIndex(dimensions);
                                }
                            }
                        }
                        else
                        {
                            if (!isStaticCall && !isConstructor)
                            {
                                if (exprList != null)
                                {
                                    bool emitReplicationGuideState = emitReplicationGuide;
                                    emitReplicationGuide = false;
                                    DfsTraverse(paramNode, ref paramType, false, graphNode, subPass);
                                    emitReplicationGuide = emitReplicationGuideState;
                                }
                                else
                                {
                                    DfsTraverse(paramNode, ref paramType, false, graphNode, subPass);
                                }
                            }
                        }

                        funtionArgCount = exprList.list.Count;
                    }

                    emitReplicationGuide = false;

                    // Restore the state only if it is a setter method
                    if (ProtoCore.Utils.CoreUtils.IsSetter(procName))
                    {
                        graphNode.allowDependents = allowDependentState;
                    }
                }
                else if (ProtoCore.DSASM.Constants.kDotArgIndexArgCount == n)
                {
                    IntNode argNumNode = new IntNode(funtionArgCount);
                    DfsTraverse(argNumNode, ref paramType, false, graphNode, subPass);
                }
                else
                {
                    DfsTraverse(paramNode, ref paramType, false, graphNode, subPass);
                }

                emitReplicationGuide = false;
                enforceTypeCheck = true;

                if (!isStaticCall || !isConstructor)
                {
                    arglist.Add(paramType);
                }
            } 
        }
Пример #25
0
        public void PushSymbolReference(ProtoCore.DSASM.SymbolNode symbol, ProtoCore.AssociativeGraph.UpdateNodeType type = UpdateNodeType.kSymbol)
        {
            Validity.Assert(null != symbol);
            Validity.Assert(null != updateNodeRefList);
            UpdateNode updateNode = new UpdateNode();
            updateNode.symbol = symbol;
            updateNode.nodeType = type;

            UpdateNodeRef nodeRef = new UpdateNodeRef();
            nodeRef.PushUpdateNode(updateNode);

            updateNodeRefList.Add(nodeRef);
        }
Пример #26
0
        public override ProtoCore.DSASM.ProcedureNode TraverseFunctionCall(ProtoCore.AST.Node node, ProtoCore.AST.Node parentNode, int lefttype, int depth, ref ProtoCore.Type inferedType,             
            ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone,
            ProtoCore.AST.Node bnode = null)
        {
            FunctionCallNode funcCall = null;
            string procName = null;
            List<ProtoCore.Type> arglist = new List<ProtoCore.Type>();
            ProtoCore.Type dotCallType = new ProtoCore.Type();
            dotCallType.UID = (int)PrimitiveType.kTypeVar;
            dotCallType.IsIndexable = false;

            ProtoCore.AssociativeGraph.UpdateNode updateNode = new ProtoCore.AssociativeGraph.UpdateNode();

            if (node is ProtoCore.AST.AssociativeAST.FunctionDotCallNode)
            {
                return TraverseDotFunctionCall(node, parentNode, lefttype, depth, ref inferedType, graphNode, subPass, bnode as BinaryExpressionNode);
            }
            else
            {
                funcCall = node as FunctionCallNode;
                procName = funcCall.Function.Name;

                int classIndex = compileStateTracker.ClassTable.IndexOf(procName);
                bool isAccessible;
                int dummy;

                // To support unamed constructor
                if (classIndex != Constants.kInvalidIndex)
                {
                    ProcedureNode constructor = compileStateTracker.ClassTable.ClassNodes[classIndex].GetMemberFunction(procName, arglist, globalClassIndex, out isAccessible, out dummy, true);
                    if (constructor != null && constructor.isConstructor)
                    {
                        FunctionCallNode rhsFNode = node as ProtoCore.AST.AssociativeAST.FunctionCallNode;
                        AssociativeNode classNode = nodeBuilder.BuildIdentfier(procName);
                        FunctionDotCallNode dotCallNode = ProtoCore.Utils.CoreUtils.GenerateCallDotNode(classNode, rhsFNode, compileStateTracker);
                        return TraverseDotFunctionCall(dotCallNode, parentNode, lefttype, depth, ref inferedType, graphNode, subPass, bnode as BinaryExpressionNode);
                    }
                }
            }

            foreach (AssociativeNode paramNode in funcCall.FormalArguments)
            {
                ProtoCore.Type paramType = new ProtoCore.Type();
                paramType.UID = (int)ProtoCore.PrimitiveType.kTypeVoid;
                paramType.IsIndexable = false;

                // The range expression function does not need replication guides
                emitReplicationGuide = !procName.Equals(ProtoCore.DSASM.Constants.kFunctionRangeExpression);

                // If it's a binary node then continue type check, otherwise disable type check and just take the type of paramNode itself
                // f(1+2.0) -> type check enabled - param is typed as double
                // f(2) -> type check disabled - param is typed as int
                enforceTypeCheck = !(paramNode is BinaryExpressionNode);

                DfsTraverse(paramNode, ref paramType, false, graphNode, subPass, bnode);

                emitReplicationGuide = false;
                enforceTypeCheck = true;

                arglist.Add(paramType);
            }

            if (subPass == ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
            {
                return null;
            }

            ProtoCore.DSASM.ProcedureNode procNode = null;
            int type = ProtoCore.DSASM.Constants.kInvalidIndex;

            int refClassIndex = ProtoCore.DSASM.Constants.kInvalidIndex;
            if (parentNode != null && parentNode is ProtoCore.AST.AssociativeAST.IdentifierListNode)
            {
                ProtoCore.AST.Node leftnode = (parentNode as ProtoCore.AST.AssociativeAST.IdentifierListNode).LeftNode;
                if (leftnode != null && leftnode is ProtoCore.AST.AssociativeAST.IdentifierNode)
                {
                    refClassIndex = compileStateTracker.ClassTable.IndexOf(leftnode.Name);
                }
            }

            // Check for the actual method, not the dot method
            // If lefttype is a valid class then check if calling a constructor
            if ((int)ProtoCore.PrimitiveType.kInvalidType != inferedType.UID
                && (int)ProtoCore.PrimitiveType.kTypeVoid != inferedType.UID
                && procName != ProtoCore.DSASM.Constants.kFunctionPointerCall)
            {

                bool isAccessible;
                int realType;

                bool isStaticOrConstructor = refClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex;
                procNode = compileStateTracker.ClassTable.ClassNodes[inferedType.UID].GetMemberFunction(procName, arglist, globalClassIndex, out isAccessible, out realType, isStaticOrConstructor);

                if (procNode != null)
                {
                    Debug.Assert(realType != ProtoCore.DSASM.Constants.kInvalidIndex);
                    type = lefttype = realType;

                    if (!isAccessible)
                    {
                        type = lefttype = realType;
                        procNode = null;
                        string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodIsInaccessible, procName);
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kAccessViolation, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col);
                        inferedType.UID = (int)PrimitiveType.kTypeNull;

                        EmitPushNull();
                        return procNode;
                    }

                }
            }

            // Try function pointer firstly
            if ((procNode == null) && (procName != ProtoCore.DSASM.Constants.kFunctionPointerCall))
            {
                bool isAccessibleFp;
                ProtoCore.DSASM.SymbolNode symbolnode = null;
                bool isAllocated = VerifyAllocation(procName, globalClassIndex, globalProcIndex, out symbolnode, out isAccessibleFp);
                if (isAllocated) // not checking the type against function pointer, as the type could be var
                {
                    procName = ProtoCore.DSASM.Constants.kFunctionPointerCall;
                    // The graph node always depends on this function pointer
                    if (null != graphNode)
                    {
                        ProtoCore.AssociativeGraph.GraphNode dependentNode = new ProtoCore.AssociativeGraph.GraphNode();
                        dependentNode.PushSymbolReference(symbolnode);
                        graphNode.PushDependent(dependentNode);
                    }
                }
            }

            // Always try global function firstly. Because we dont have syntax
            // support for calling global function (say, ::foo()), if we try
            // member function firstly, there is no way to call a global function
            // For member function, we can use this.foo() to distinguish it from
            // global function.
            if ((procNode == null) && (procName != ProtoCore.DSASM.Constants.kFunctionPointerCall))
            {
                procNode = compileStateTracker.GetFirstVisibleProcedure(procName, arglist, codeBlock);
                if (null != procNode)
                {
                    type = ProtoCore.DSASM.Constants.kGlobalScope;
                    if (compileStateTracker.TypeSystem.IsHigherRank(procNode.returntype.UID, inferedType.UID))
                    {
                        inferedType = procNode.returntype;
                    }
                }
            }

            // Try member functions in global class scope
            if ((procNode == null) && (procName != ProtoCore.DSASM.Constants.kFunctionPointerCall) && (parentNode == null))
            {
                if (globalClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex)
                {
                    int realType;
                    bool isAccessible;
                    bool isStaticOrConstructor = refClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex;
                    ProtoCore.DSASM.ProcedureNode memProcNode = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].GetMemberFunction(procName, arglist, globalClassIndex, out isAccessible, out realType, isStaticOrConstructor);

                    if (memProcNode != null)
                    {
                        Debug.Assert(realType != ProtoCore.DSASM.Constants.kInvalidIndex);
                        procNode = memProcNode;
                        inferedType = procNode.returntype;
                        type = realType;

                        if (!isAccessible)
                        {
                            string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodIsInaccessible, procName);
                            buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kAccessViolation, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col);

                            inferedType.UID = (int)PrimitiveType.kTypeNull;
                            EmitPushNull();
                            return procNode;
                        }
                    }
                }
            }

            if (null != procNode)
            {
                if (procNode.isConstructor &&
                        (globalClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex) &&
                        (globalProcIndex != ProtoCore.DSASM.Constants.kInvalidIndex) &&
                        (globalClassIndex == inferedType.UID))
                {
                    ProtoCore.DSASM.ProcedureNode contextProcNode = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].vtable.procList[globalProcIndex];
                    if (contextProcNode.isConstructor &&
                        string.Equals(contextProcNode.name, procNode.name) &&
                        contextProcNode.runtimeIndex == procNode.runtimeIndex)
                    {
                        string message = String.Format(ProtoCore.BuildData.WarningMessage.kCallingConstructorInConstructor, procName);
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingConstructorInConstructor, message, compileStateTracker.CurrentDSFileName, node.line, node.col );
                        inferedType.UID = (int)PrimitiveType.kTypeNull;
                        EmitPushNull();
                        return procNode;
                    }
                }

                inferedType = procNode.returntype;

                //if call is replication call
                if (procNode.isThisCallReplication)
                {
                    inferedType.IsIndexable = true;
                    inferedType.rank++;
                }

                if (ProtoCore.DSASM.Constants.kInvalidIndex != procNode.procId)
                {

                    //
                    // ==============Establishing graphnode links in modified arguments=============
                    //
                    //  proc TraverseCall(node, graphnode)
                    //      ; Get the first procedure, this will only be the first visible procedure
                    //      ; Overloads will be handled at runtime
                    //      def fnode = getProcedure(node)
                    //
                    //      ; For every argument in the function call,
                    //      ; attach the modified property list and append it to the graphnode update list
                    //      foreach arg in node.args
                    //          if fnode.updatedArgProps is not null
                    //              def noderef = arg.ident (or identlist)
                    //              noderef.append(fnode.updatedArgProps)
                    //              graphnode.pushUpdateRef(noderef)
                    //          end
                    //      end
                    //  end
                    //
                    // =============================================================================
                    //

                    foreach (AssociativeNode paramNode in funcCall.FormalArguments)
                    {
                        // Get the lhs symbol list
                        ProtoCore.Type ltype = new ProtoCore.Type();
                        ltype.UID = globalClassIndex;
                        ProtoCore.AssociativeGraph.UpdateNodeRef argNodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef();
                        DFSGetSymbolList(paramNode, ref ltype, argNodeRef);

                        if (null != graphNode)
                        {
                            graphNode.updatedArguments.Add(argNodeRef);
                        }
                    }

                    // The function is at block 0 if its a constructor, member or at the globals scope.
                    // Its at block 1 if its inside a language block.
                    // Its limited to block 1 as of R1 since we dont support nested function declarations yet
                    int blockId = procNode.runtimeIndex;

                    //push value-not-provided default argument
                    for (int i = arglist.Count; i < procNode.argInfoList.Count; i++)
                    {
                        EmitDefaultArgNode();
                    }

                    // Push the function declaration block and indexed array
                    // Jun TODO: Implementeation of indexing into a function call:
                    //  x = f()[0][1]
                    int dimensions = 0;
                    EmitPushVarData(blockId, dimensions);

                    // The function call
                    EmitInstrConsole(ProtoCore.DSASM.kw.callr, procNode.name);

                    // Do not emit breakpoints at built-in methods like _add/_sub etc. - pratapa
                    if (procNode.isAssocOperator || procNode.name.Equals(ProtoCore.DSASM.Constants.kInlineConditionalMethodName))
                    {
                        EmitCall(procNode.procId, type, depth, ProtoCore.DSASM.Constants.kInvalidIndex, ProtoCore.DSASM.Constants.kInvalidIndex,
                                    ProtoCore.DSASM.Constants.kInvalidIndex, ProtoCore.DSASM.Constants.kInvalidIndex, procNode.pc);
                    }
                    // Break at function call inside dynamic lang block created for a 'true' or 'false' expression inside an inline conditional
                    else if (compileStateTracker.DebugProps.breakOptions.HasFlag(DebugProperties.BreakpointOptions.EmitInlineConditionalBreakpoint))
                    {
                        Validity.Assert(compileStateTracker.DebugProps.highlightRange != null);

                        ProtoCore.CodeModel.CodePoint startInclusive = compileStateTracker.DebugProps.highlightRange.StartInclusive;
                        ProtoCore.CodeModel.CodePoint endExclusive = compileStateTracker.DebugProps.highlightRange.EndExclusive;

                        EmitCall(procNode.procId, type, depth, startInclusive.LineNo, startInclusive.CharNo, endExclusive.LineNo, endExclusive.CharNo, procNode.pc);
                    }
                    // Use startCol and endCol of binary expression node containing function call except if it's a setter
                    else if (bnode != null && !procNode.name.StartsWith(Constants.kSetterPrefix))
                    {
                        EmitCall(procNode.procId, type, depth, bnode.line, bnode.col, bnode.endLine, bnode.endCol, procNode.pc);
                    }
                    else
                    {
                        EmitCall(procNode.procId, type, depth, funcCall.line, funcCall.col, funcCall.endLine, funcCall.endCol, procNode.pc);
                    }

                    // The function return value
                    EmitInstrConsole(ProtoCore.DSASM.kw.push, ProtoCore.DSASM.kw.regRX);
                    ProtoCore.DSASM.StackValue opReturn = new ProtoCore.DSASM.StackValue();
                    opReturn.optype = ProtoCore.DSASM.AddressType.Register;
                    opReturn.opdata = (int)ProtoCore.DSASM.Registers.RX;
                    EmitPush(opReturn);

                    if (dotCallType.UID != (int)PrimitiveType.kTypeVar)
                    {
                        inferedType.UID = dotCallType.UID;
                    }
                }
            }
            else
            {
                if (depth <= 0 && procName != ProtoCore.DSASM.Constants.kFunctionPointerCall)
                {
                    string property;
                    if (CoreUtils.TryGetPropertyName(procName, out property))
                    {
                        string message = String.Format(ProtoCore.BuildData.WarningMessage.kPropertyNotFound, property);
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kPropertyNotFound, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col);
                    }
                    else
                    {
                        string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodNotFound, procName);
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kFunctionNotFound, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col);
                    }

                    inferedType.UID = (int)PrimitiveType.kTypeNull;
                    EmitPushNull();
                }
                else
                {
                    if (procName == ProtoCore.DSASM.Constants.kFunctionPointerCall && depth == 0)
                    {
                        ProtoCore.DSASM.DynamicFunctionNode dynamicFunctionNode = new ProtoCore.DSASM.DynamicFunctionNode(procName, arglist, lefttype);
                        compileStateTracker.DynamicFunctionTable.functionTable.Add(dynamicFunctionNode);
                        var iNode = nodeBuilder.BuildIdentfier(funcCall.Function.Name);
                        EmitIdentifierNode(iNode, ref inferedType);
                    }
                    else
                    {
                        ProtoCore.DSASM.DynamicFunctionNode dynamicFunctionNode = new ProtoCore.DSASM.DynamicFunctionNode(funcCall.Function.Name, arglist, lefttype);
                        compileStateTracker.DynamicFunctionTable.functionTable.Add(dynamicFunctionNode);
                    }
                    // The function call
                    EmitInstrConsole(ProtoCore.DSASM.kw.callr, funcCall.Function.Name + "[dynamic]");
                    EmitDynamicCall(compileStateTracker.DynamicFunctionTable.functionTable.Count - 1, globalClassIndex, depth, funcCall.line, funcCall.col, funcCall.endLine, funcCall.endCol);

                    // The function return value
                    EmitInstrConsole(ProtoCore.DSASM.kw.push, ProtoCore.DSASM.kw.regRX);
                    ProtoCore.DSASM.StackValue opReturn = new ProtoCore.DSASM.StackValue();
                    opReturn.optype = ProtoCore.DSASM.AddressType.Register;
                    opReturn.opdata = (int)ProtoCore.DSASM.Registers.RX;
                    EmitPush(opReturn);

                    //assign inferedType to var
                    inferedType.UID = (int)PrimitiveType.kTypeVar;
                }
            }
            return procNode;
        }
Пример #27
0
        public void PushSymbolReference(ProtoCore.DSASM.SymbolNode symbol)
        {
            Validity.Assert(null != symbol);
            Validity.Assert(null != updateNodeRefList);
            UpdateNode updateNode = new UpdateNode();
            updateNode.symbol = symbol;
            updateNode.nodeType = UpdateNodeType.kSymbol;

            UpdateNodeRef nodeRef = new UpdateNodeRef();
            nodeRef.block = symbol.runtimeTableIndex;
            nodeRef.PushUpdateNode(updateNode);

            updateNodeRefList.Add(nodeRef);
        }
Пример #28
0
        /*
         proc EmitIdentNode(identnode, graphnode)
            if ssa
                // Check an if this identifier is array indexed
                // The array index is a secondary property and is not the original array property of the AST. this is required because this array index is meant only to resolve graphnode dependency with arrays
                if node.arrayindex.secondary is valid
                    dimension = traverse(node.arrayindex.secondary)

                    // Create a new dependent with the array indexing
                    dependent = new GraphNode(identnode.name, dimension)
                    graphnode.pushdependent(dependent)
                end
            end
        end

         */
        private void EmitIdentifierNode(AssociativeNode node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone, BinaryExpressionNode parentNode = null)
        {
            IdentifierNode t = node as IdentifierNode;
            if (t.Name.Equals(ProtoCore.DSDefinitions.Keyword.This))
            {
                if (subPass != AssociativeSubCompilePass.kNone)
                {
                    return;
                }

                if (localProcedure != null)
                {
                    if (localProcedure.isStatic)
                    {
                        string message = ProtoCore.BuildData.WarningMessage.kUsingThisInStaticFunction;
                        compileStateTracker.BuildStatus.LogWarning(ProtoCore.BuildData.WarningID.kInvalidThis, message, compileStateTracker.CurrentDSFileName, t.line, t.col);
                        EmitPushNull();
                        return;
                    }
                    else if (localProcedure.classScope == Constants.kGlobalScope)
                    {
                        string message = ProtoCore.BuildData.WarningMessage.kInvalidThis;
                        compileStateTracker.BuildStatus.LogWarning(ProtoCore.BuildData.WarningID.kInvalidThis, message, compileStateTracker.CurrentDSFileName, t.line, t.col);
                        EmitPushNull();
                        return;
                    }
                    else
                    {
                        EmitThisPointerNode(subPass);
                        return;
                    }
                }
                else
                {
                    string message = ProtoCore.BuildData.WarningMessage.kInvalidThis;
                    compileStateTracker.BuildStatus.LogWarning(ProtoCore.BuildData.WarningID.kInvalidThis, message, compileStateTracker.CurrentDSFileName, t.line, t.col);
                    EmitPushNull();
                    return;
                }
            }

            int dimensions = 0;

            ProtoCore.DSASM.SymbolNode symbolnode = null;
            int runtimeIndex = codeBlock.symbolTable.runtimeIndex;

            ProtoCore.Type type = new ProtoCore.Type();
            type.UID = (int)ProtoCore.PrimitiveType.kTypeVoid;
            type.IsIndexable = false;

            bool isAccessible = false;

            if (null == t.ArrayDimensions)
            {
                //check if it is a function instance
                ProtoCore.DSASM.ProcedureNode procNode = null;
                procNode = compileStateTracker.GetFirstVisibleProcedure(t.Name, null, codeBlock);
                if (null != procNode)
                {
                    if (ProtoCore.DSASM.Constants.kInvalidIndex != procNode.procId)
                    {
                        // A global function
                        inferedType.IsIndexable = false;
                        inferedType.UID = (int)PrimitiveType.kTypeFunctionPointer;
                        if (ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier != subPass)
                        {
                            int fptr = compileStateTracker.FunctionPointerTable.functionPointerDictionary.Count;
                            ProtoCore.DSASM.FunctionPointerNode fptrNode = new ProtoCore.DSASM.FunctionPointerNode(procNode.procId, procNode.runtimeIndex);
                            compileStateTracker.FunctionPointerTable.functionPointerDictionary.TryAdd(fptr, fptrNode);
                            compileStateTracker.FunctionPointerTable.functionPointerDictionary.TryGetBySecond(fptrNode, out fptr);

                            EmitPushVarData(runtimeIndex, 0);

                            EmitInstrConsole(ProtoCore.DSASM.kw.push, t.Name);
                            ProtoCore.DSASM.StackValue opFunctionPointer = new ProtoCore.DSASM.StackValue();
                            opFunctionPointer.optype = ProtoCore.DSASM.AddressType.FunctionPointer;
                            opFunctionPointer.opdata = fptr;
                            opFunctionPointer.opdata_d = fptr;
                            EmitPush(opFunctionPointer, t.line, t.col);
                        }
                        return;
                    }
                }
            }

            bool isAllocated = VerifyAllocation(t.Name, globalClassIndex, globalProcIndex, out symbolnode, out isAccessible);

            // If its executing in interpreter mode - attempt to find and anubond identifer in a child block
            // Remove this, because if we are watching cases like:
            //c1 = [Imperative]
            //{
            //    a = 1;
            //    b = 2;
            //}
            //
            //c2 = [Associative]
            //{
            //    a = 3;
            //    b = 4;
            //}
            //After c2 is executed, the watch value for a, b will be 1, 2.
            //if (ProtoCore.DSASM.ExecutionMode.kExpressionInterpreter == core.ExecMode)
            //{
            //    if (!isAllocated)
            //    {
            //        isAllocated = VerifyAllocationIncludingChildBlock(t.Name, globalClassIndex, globalProcIndex, out symbolnode, out isAccessible);
            //    }
            //}

            if (AssociativeSubCompilePass.kUnboundIdentifier == subPass)
            {
                if (symbolnode == null)
                {
                    if (isAllocated)
                    {
                        string message = String.Format(WarningMessage.kPropertyIsInaccessible, t.Value);
                        if (localProcedure != null && localProcedure.isStatic)
                        {
                            SymbolNode tempSymbolNode;

                            VerifyAllocation(
                                t.Name,
                                globalClassIndex,
                                Constants.kGlobalScope,
                                out tempSymbolNode,
                                out isAccessible);

                            if (tempSymbolNode != null && !tempSymbolNode.isStatic && isAccessible)
                            {
                                message = String.Format(WarningMessage.kUsingNonStaticMemberInStaticContext, t.Value);
                            }
                        }
                        buildStatus.LogWarning(
                            ProtoCore.BuildData.WarningID.kAccessViolation,
                            message,
                            compileStateTracker.CurrentDSFileName,
                            t.line,
                            t.col);
                    }
                    else
                    {
                        string message = String.Format(WarningMessage.kUnboundIdentifierMsg, t.Value);
                        buildStatus.LogWarning(WarningID.kIdUnboundIdentifier, message, compileStateTracker.CurrentDSFileName, t.line, t.col);
                    }

                    if (ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter != compileStateTracker.ExecMode)
                    {
                        inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeNull;

                        // Jun Comment: Specification
                        //      If resolution fails at this point a com.Design-Script.Imperative.Core.UnboundIdentifier
                        //      warning is emitted during pre-execute phase, and at the ID is bound to null. (R1 - Feb)

                        int startpc = pc;
                        EmitPushNull();

                        // Push the identifier local block
                        dimensions = 0;
                        EmitPushVarData(runtimeIndex, dimensions);

                        ProtoCore.Type varType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, false, 0);

                        // TODO Jun: Refactor Allocate() to just return the symbol node itself
                        ProtoCore.DSASM.SymbolNode symnode = Allocate(globalClassIndex, globalClassIndex, globalProcIndex, t.Value, varType, ProtoCore.DSASM.Constants.kPrimitiveSize,
                            false, ProtoCore.DSASM.AccessSpecifier.kPublic, ProtoCore.DSASM.MemoryRegion.kMemStack, t.line, t.col, graphNode);
                        Debug.Assert(symnode != null);

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

                        EmitInstrConsole(ProtoCore.DSASM.kw.pop, t.Value);
                        EmitPopForSymbol(symnode);

                        // Comment it out. It doesn't work for the following
                        // case:
                        //
                        //     x = foo.X;
                        //     x = bar.X;
                        //
                        // where bar hasn't defined yet, so a null assign
                        // graph is generated for this case:
                        //
                        //    bar = null;
                        //    x = %dot(.., {bar}, ...);
                        //
                        // unfortunately the expression UID of this null graph
                        // node is 0, which is wrong. Some update routines have
                        // the assumption that the exprUID of graph node is
                        // incremental.
                        //
                        // We may generate SSA for all expressions to fix this
                        // issue. -Yu Ke
                        /*
                        ProtoCore.AssociativeGraph.GraphNode nullAssignGraphNode = new ProtoCore.AssociativeGraph.GraphNode();
                        nullAssignGraphNode.PushSymbolReference(symbolnode);
                        nullAssignGraphNode.procIndex = globalProcIndex;
                        nullAssignGraphNode.classIndex = globalClassIndex;
                        nullAssignGraphNode.updateBlock.startpc = startpc;
                        nullAssignGraphNode.updateBlock.endpc = pc - 1;

                        codeBlock.instrStream.dependencyGraph.Push(nullAssignGraphNode);
                        */
                    }
                }

                if (null != t.ArrayDimensions)
                {
                    dimensions = DfsEmitArrayIndexHeap(t.ArrayDimensions, graphNode, parentNode, subPass);
                }
            }
            else
            {
                if (compileStateTracker.ExecMode == ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter &&
                    !isAllocated)
                {
                    // It happens when the debugger try to watch a variable
                    // which has been out of scope (as watch is done through
                    // execute an expression "t = v;" where v is the variable
                    // to be watched.
                    EmitPushNull();
                    return;
                }

                Validity.Assert(isAllocated);

                if (graphNode != null
                    && IsAssociativeArrayIndexing
                    && !CoreUtils.IsAutoGeneratedVar(symbolnode.name))
                {
                    ProtoCore.AssociativeGraph.UpdateNode updateNode = new ProtoCore.AssociativeGraph.UpdateNode();
                    updateNode.symbol = symbolnode;
                    updateNode.nodeType = ProtoCore.AssociativeGraph.UpdateNodeType.kSymbol;

                    if (graphNode.isIndexingLHS)
                    {
                        graphNode.dimensionNodeList.Add(updateNode);
                    }
                    else
                    {
                        int curDepIndex = graphNode.dependentList.Count - 1;
                        if (curDepIndex >= 0)
                        {
                            var curDep = graphNode.dependentList[curDepIndex].updateNodeRefList[0].nodeList[0];
                            curDep.dimensionNodeList.Add(updateNode);

                            if (null != firstSSAGraphNode)
                            {
                                curDepIndex = firstSSAGraphNode.dependentList.Count - 1;
                                if (curDepIndex >= 0)
                                {
                                    ProtoCore.AssociativeGraph.UpdateNode firstSSAUpdateNode = firstSSAGraphNode.dependentList[curDepIndex].updateNodeRefList[0].nodeList[0];
                                    firstSSAUpdateNode.dimensionNodeList.Add(updateNode);
                                }
                            }
                        }
                    }
                }

                // If it is a property, replaced it with getter: %get_prop()
                if (symbolnode.classScope != ProtoCore.DSASM.Constants.kInvalidIndex &&
                    symbolnode.functionIndex == ProtoCore.DSASM.Constants.kGlobalScope &&
                    localProcedure != null)
                {
                    string getterName = ProtoCore.DSASM.Constants.kGetterPrefix + t.Name;
                    if (!string.Equals(localProcedure.name, getterName))
                    {
                        var thisNode = nodeBuilder.BuildIdentfier(ProtoCore.DSDefinitions.Keyword.This);
                        var identListNode = nodeBuilder.BuildIdentList(thisNode, t);
                        EmitIdentifierListNode(identListNode, ref inferedType, false, graphNode, ProtoCore.DSASM.AssociativeSubCompilePass.kNone);

                        if (null != graphNode)
                        {
                            ProtoCore.AssociativeGraph.GraphNode dependentNode = new ProtoCore.AssociativeGraph.GraphNode();
                            dependentNode.PushSymbolReference(symbolnode);
                            graphNode.PushDependent(dependentNode);
                        }

                        return;
                    }
                }

                type = symbolnode.datatype;
                runtimeIndex = symbolnode.runtimeTableIndex;

                // The graph node always depends on this identifier
                if (null != graphNode)
                {
                    ProtoCore.AssociativeGraph.GraphNode dependentNode = new ProtoCore.AssociativeGraph.GraphNode();
                    dependentNode.PushSymbolReference(symbolnode);
                    graphNode.PushDependent(dependentNode);
                }

                bool emitReplicationGuideFlag = emitReplicationGuide;
                emitReplicationGuide = false;
                if (null != t.ArrayDimensions)
                {
                    dimensions = DfsEmitArrayIndexHeap(t.ArrayDimensions, graphNode, parentNode, subPass);
                }
                emitReplicationGuide = emitReplicationGuideFlag;

                //fix type's rank
                if (type.rank >= 0)
                {
                    type.rank -= dimensions;
                    if (type.rank < 0)
                    {
                        //throw new Exception("Exceed maximum rank!");
                        type.rank = 0;
                    }
                }

                //check whether the value is an array
                if (type.rank == 0)
                {
                    type.IsIndexable = false;
                }

                EmitPushVarData(runtimeIndex, dimensions);

                if (ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter == compileStateTracker.ExecMode)
                {
                    EmitInstrConsole(ProtoCore.DSASM.kw.pushw, t.Value);
                    EmitPushForSymbolW(symbolnode, t.line, t.col);
                }
                else
                {
                    EmitInstrConsole(ProtoCore.DSASM.kw.push, t.Value);
                    EmitPushForSymbol(symbolnode, t);

                    if (compileStateTracker.Options.TempReplicationGuideEmptyFlag && emitReplicationGuide)
                    {
                        int guides = EmitReplicationGuides(t.ReplicationGuides);
                        EmitInstrConsole(ProtoCore.DSASM.kw.pushindex, guides + "[guide]");
                        EmitPushReplicationGuide(guides);
                    }
                }

                if (ignoreRankCheck || compileStateTracker.TypeSystem.IsHigherRank(type.UID, inferedType.UID))
                {
                    inferedType = type;
                }
                // We need to get inferedType for boolean variable so that we can perform type check
                inferedType.UID = (isBooleanOp || (type.UID == (int)PrimitiveType.kTypeBool)) ? (int)PrimitiveType.kTypeBool : inferedType.UID;
            }
        }
Пример #29
0
        public void PushProcReference(ProtoCore.DSASM.ProcedureNode proc)
        {
            Validity.Assert(null != proc);
            Validity.Assert(null != updateNodeRefList);
            UpdateNode updateNode = new UpdateNode();
            updateNode.procNode = proc;
            updateNode.nodeType = UpdateNodeType.kMethod;

            UpdateNodeRef nodeRef = new UpdateNodeRef();
            nodeRef.PushUpdateNode(updateNode);

            updateNodeRefList.Add(nodeRef);
        }
Пример #30
0
        //
        //  proc ResolveFinalNodeRefs()
        //      foreach graphnode in graphnodeList
        //          def firstproc = graphnode.firstproc
        //          // Auto-generate the updateNodeRefs for this graphnode given the 
        //          // list stored in the first procedure found in the assignment expression
        //          foreach noderef in firstProc.updatedProperties	
        //              def n = graphnode.firstProcRefIndex
        //              def autogenRef = updateNodeRef[n]
        //              autogenRef.append(noderef)
        //              graphnode.pushUpdateRef(autogenRef)
        //          end
        //      end
        //  end
        //
        private void ResolveFinalNodeRefs()
        {
            foreach (ProtoCore.AssociativeGraph.GraphNode graphNode in codeBlock.instrStream.dependencyGraph.GraphList)
            {
                ProtoCore.DSASM.ProcedureNode firstProc = graphNode.firstProc;
                if (null == firstProc || firstProc.IsAutoGenerated)
                {
                    continue;
                }

                // TODO: The following implementation is wrong.
                // Suppose for function call: x = foo().bar(); which converted
                // to x = %dot(foo(), bar(), ...); the following checking skips
                // it because %dot() is an internal function. -Yu Ke

                // Do this only for non auto-generated function calls 
                //if any local var is depend on global var
                if (core.Options.localDependsOnGlobalSet)
                {
                    if (!firstProc.Name.ToCharArray()[0].Equals('_') && !firstProc.Name.ToCharArray()[0].Equals('%'))
                    {
                        //for each node
                        foreach (ProtoCore.AssociativeGraph.GraphNode gNode in codeBlock.instrStream.dependencyGraph.GraphList)
                        {
                            if (gNode.updateNodeRefList != null && gNode.updateNodeRefList.Count != 0)
                            {
                                if (gNode.procIndex == firstProc.ID && !gNode.updateNodeRefList[0].nodeList[0].symbol.name.ToCharArray()[0].Equals('%'))
                                {
                                    foreach (ProtoCore.AssociativeGraph.GraphNode dNode in gNode.dependentList)
                                    {
                                        if (dNode.procIndex == ProtoCore.DSASM.Constants.kGlobalScope)
                                        {
                                            if (!dNode.updateNodeRefList[0].nodeList[0].symbol.name.ToCharArray()[0].Equals('%'))
                                            {
                                                graphNode.PushDependent(dNode);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                if (firstProc.ClassID == Constants.kGlobalScope)
                {
                    graphNode.updateNodeRefList.AddRange(firstProc.UpdatedGlobalVariables);
                }
                else
                {
                    // For each property modified
                    foreach (ProtoCore.AssociativeGraph.UpdateNodeRef updateRef in firstProc.UpdatedProperties)
                    {
                        int index = graphNode.firstProcRefIndex;

                        // Is it a global function
                        if (ProtoCore.DSASM.Constants.kInvalidIndex != index)
                        {
                            if (core.Options.GenerateSSA)
                            {
                                foreach (ProtoCore.AssociativeGraph.GraphNode dependent in graphNode.dependentList)
                                {
                                    // Do this only if first proc is a member function...
                                    ProtoCore.AssociativeGraph.UpdateNodeRef autogenRef = new ProtoCore.AssociativeGraph.UpdateNodeRef(dependent.updateNodeRefList[0]);
                                    autogenRef = autogenRef.GetUntilFirstProc();

                                    // ... and the first symbol is an instance of a user-defined type
                                    int last = autogenRef.nodeList.Count - 1;
                                    Validity.Assert(autogenRef.nodeList[last].nodeType != ProtoCore.AssociativeGraph.UpdateNodeType.kMethod && null != autogenRef.nodeList[last].symbol);
                                    if (autogenRef.nodeList[last].symbol.datatype.UID >= (int)PrimitiveType.kMaxPrimitives)
                                    {
                                        autogenRef.PushUpdateNodeRef(updateRef);
                                        graphNode.updateNodeRefList.Add(autogenRef);

                                        if (graphNode.lastGraphNode != null)
                                        {
                                            graphNode.lastGraphNode.updateNodeRefList.Add(autogenRef);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                // Do this only if first proc is a member function...
                                ProtoCore.AssociativeGraph.UpdateNodeRef autogenRef = new ProtoCore.AssociativeGraph.UpdateNodeRef(graphNode.dependentList[0].updateNodeRefList[0]);
                                autogenRef = autogenRef.GetUntilFirstProc();

                                // ... and the first symbol is an instance of a user-defined type
                                int last = autogenRef.nodeList.Count - 1;
                                Validity.Assert(autogenRef.nodeList[last].nodeType != ProtoCore.AssociativeGraph.UpdateNodeType.kMethod && null != autogenRef.nodeList[last].symbol);
                                if (autogenRef.nodeList[last].symbol.datatype.UID >= (int)PrimitiveType.kMaxPrimitives)
                                {
                                    autogenRef.PushUpdateNodeRef(updateRef);
                                    graphNode.updateNodeRefList.Add(autogenRef);
                                }
                            }
                        }
                    }
                }

                if (graphNode.updatedArguments.Count > 0)
                {
                    // For each argument modified
                    int n = 0;

                    // Create the current modified argument
                    foreach (KeyValuePair<string, List<ProtoCore.AssociativeGraph.UpdateNodeRef>> argNameModifiedStatementsPair in firstProc.UpdatedArgumentProperties)
                    {
                        // For every single arguments' modified statements
                        foreach (ProtoCore.AssociativeGraph.UpdateNodeRef nodeRef in argNameModifiedStatementsPair.Value)
                        {
                            if (core.Options.GenerateSSA)
                            {
                                //
                                // We just trigger update from whichever statement is dependent on the first pointer associatied with this SSA stmt
                                // Given:
                                //      p = C.C();
                                //      a = p.x;
                                //      i = f(p);
                                //
                                //      %t0 = C.C()
                                //      p = %t0
                                //      %t1 = p
                                //      %t2 = %t1.x
                                //      a = %t2
                                //      %t3 = p
                                //      %t4 = f(%t3)    -> Assume that function 'f' modifies the property 'x' of its argument
                                //                      -> The graph node of this stmt has 2 updatenoderefs 
                                //                      ->  there are %t4 and p ('p' because it is the first pointer of %t3
                                //      i = %t4
                                //
                                
                                // Get the modified property name 
                                string argname = graphNode.updatedArguments[n].nodeList[0].symbol.name;
                                if (ProtoCore.Utils.CoreUtils.IsSSATemp(argname) && ssaTempToFirstPointerMap.ContainsKey(argname))
                                {
                                    // The property is an SSA temp, Get the SSA first pointer associated with this temp
                                    argname = ssaTempToFirstPointerMap[argname];
                                }

                                bool isAccessible = false;
                                SymbolNode symbol = null;
                                bool isAllocated = VerifyAllocation(argname, globalClassIndex, globalProcIndex, out symbol, out isAccessible);
                                if (isAllocated)
                                {
                                    ProtoCore.AssociativeGraph.UpdateNode updateNode = new UpdateNode();
                                    updateNode.symbol = symbol;
                                    updateNode.nodeType = ProtoCore.AssociativeGraph.UpdateNodeType.kSymbol;

                                    ProtoCore.AssociativeGraph.UpdateNodeRef argNodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef();
                                    argNodeRef.PushUpdateNode(updateNode);
                                    graphNode.updateNodeRefList.Add(argNodeRef);
                                }
                                
                            }
                            else
                            {
                                ProtoCore.AssociativeGraph.UpdateNodeRef argNodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef();
                                argNodeRef.PushUpdateNodeRef(graphNode.updatedArguments[n]);
                                argNodeRef.PushUpdateNodeRef(nodeRef);
                                graphNode.updateNodeRefList.Add(argNodeRef);
                            }
                        }
                        ++n;
                    }
                }
            }
        }
Пример #31
0
        public void PushSymbolReference(SymbolNode symbol, UpdateNodeType type = UpdateNodeType.kSymbol)
        {
            Validity.Assert(null != symbol);
            UpdateNode updateNode = new UpdateNode();
            updateNode.symbol = symbol;
            updateNode.nodeType = type;

            UpdateNodeRef nodeRef = new UpdateNodeRef();
            nodeRef.PushUpdateNode(updateNode);

            updateNodeRefList.Add(nodeRef);
        }