Esempio n. 1
0
        protected void EmitDoubleNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            if (subPass == ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
            {
                return;
            }

            dynamic dNode = node;
            if (!enforceTypeCheck || compileState.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeDouble, inferedType.UID))
            {
                inferedType.UID = (int)PrimitiveType.kTypeDouble;
            }
            inferedType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : inferedType.UID;
        }
Esempio n. 2
0
        protected void EmitIdentifierListNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, 
            ProtoCore.AssociativeGraph.GraphNode graphNode = null, 
            ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone, 
            ProtoCore.AST.Node bnode = null)
        {
            if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier)
            {
                //to process all unbounded parameters if any
                dynamic iNode = node;
                while (iNode is ProtoCore.AST.AssociativeAST.IdentifierListNode || iNode is ProtoCore.AST.ImperativeAST.IdentifierListNode)
                {
                    dynamic rightNode = iNode.RightNode;
                    if (rightNode is ProtoCore.AST.AssociativeAST.FunctionCallNode || rightNode is ProtoCore.AST.ImperativeAST.FunctionCallNode)
                    {
                        foreach (dynamic paramNode in rightNode.FormalArguments)
                        {
                            ProtoCore.Type paramType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, 0);
                            DfsTraverse(paramNode, ref paramType, false, graphNode, ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier);
                        }
                    }
                    iNode = iNode.LeftNode;
                }
                return;
            }

            int depth = 0;

            ProtoCore.Type leftType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kInvalidType, 0);
            bool isFirstIdent = true;

            BuildSSADependency(node, graphNode);
            if (core.Options.GenerateSSA)
            {
                BuildRealDependencyForIdentList(graphNode);

                if (node is ProtoCore.AST.AssociativeAST.IdentifierListNode)
                {
                    if ((node as ProtoCore.AST.AssociativeAST.IdentifierListNode).IsLastSSAIdentListFactor)
                    {
                        Validity.Assert(null != ssaPointerStack);
                        ssaPointerStack.Pop();
                    }
                }
            }

            bool isCollapsed;
            EmitGetterSetterForIdentList(node, ref inferedType, graphNode, subPass, out isCollapsed);
            if (!isCollapsed)
            {
                bool isMethodCallPresent = false;
                ProtoCore.DSASM.SymbolNode firstSymbol = null;
                bool isIdentReference = DfsEmitIdentList(node, null, globalClassIndex, ref leftType, ref depth, ref inferedType, false, ref isFirstIdent, ref isMethodCallPresent, ref firstSymbol, graphNode, subPass, bnode);
                inferedType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : inferedType.UID;


                if (isIdentReference && depth > 1)
                {
                    EmitInstrConsole(ProtoCore.DSASM.kw.pushlist, depth.ToString(), globalClassIndex.ToString());

                    // TODO Jun: Get blockid
                    int blockId = 0;
                    EmitPushList(depth, globalClassIndex, blockId);
                }
            }
        }
Esempio n. 3
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);
                }
            }
        }
Esempio n. 4
0
        protected void EmitNullNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone)
        {
            if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier)
            {
                return;
            }

            dynamic nullNode = node;
            inferedType.UID = (int)PrimitiveType.kTypeNull;

            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.Null;

            if (core.Options.TempReplicationGuideEmptyFlag && emitReplicationGuide)
            {
                EmitInstrConsole(ProtoCore.DSASM.kw.pushg, ProtoCore.DSASM.Literal.Null);
                EmitPushG(op, nullNode.line, nullNode.col);
            }
            else
            {
                EmitInstrConsole(ProtoCore.DSASM.kw.push, ProtoCore.DSASM.Literal.Null);
                EmitPush(op, nullNode.line, nullNode.col);
            }
        }
Esempio n. 5
0
        protected void EmitReturnStatement(Node node, Type inferedType)
        {
            // Check the returned type against the declared return type
            if (null != localProcedure && 
                localProcedure.IsConstructor &&
                core.IsFunctionCodeBlock(codeBlock))
            {
                buildStatus.LogSemanticError(Resources.ReturnStatementIsNotAllowedInConstructor, 
                                             core.CurrentDSFileName, 
                                             node.line, 
                                             node.col);
            }

            EmitReturnToRegister(node.line, node.col, node.endLine, node.endCol);
        }
Esempio n. 6
0
        protected void EmitCharNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone)
        {
            if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier)
            {
                return;
            }

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

            String value = (String)cNode.Value;
            if (value.Length > 1)
            {
                buildStatus.LogSyntaxError(Resources.TooManyCharacters, null, node.line, node.col);
            }
  
            String strValue = "'" + value + "'";
            StackValue op = ProtoCore.DSASM.StackValue.BuildChar(value[0]);

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

                EmitInstrConsole(ProtoCore.DSASM.kw.pushg, strValue);
                EmitPushG(op, node.line, node.col);
            }
            else
            {
                EmitInstrConsole(ProtoCore.DSASM.kw.push, strValue);
                EmitPush(op, cNode.line, cNode.col);
            }
        }
Esempio n. 7
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);
                            }
                        }
                    }
                }
            }
        }
Esempio n. 8
0
        protected void EmitIdentifierListNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            if (subPass == ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
            {
                //to process all unbounded parameters if any
                dynamic iNode = node;
                while (iNode is ProtoCore.AST.AssociativeAST.IdentifierListNode || iNode is ProtoCore.AST.ImperativeAST.IdentifierListNode)
                {
                    dynamic rightNode = iNode.RightNode;
                    if (rightNode is ProtoCore.AST.AssociativeAST.FunctionCallNode || rightNode is ProtoCore.AST.ImperativeAST.FunctionCallNode)
                    {
                        foreach (dynamic paramNode in rightNode.FormalArguments)
                        {
                            ProtoCore.Type paramType = new ProtoCore.Type();
                            paramType.UID = (int)ProtoCore.PrimitiveType.kTypeVoid;
                            paramType.IsIndexable = false;
                            DfsTraverse(paramNode, ref paramType, false, graphNode, ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier);
                        }
                    }
                    iNode = iNode.LeftNode;
                }
                return;
            }

            int depth = 0;

            ProtoCore.Type leftType = new ProtoCore.Type();
            leftType.UID = (int)PrimitiveType.kInvalidType;
            leftType.IsIndexable = false;
            bool isFirstIdent = true;

            bool isIdentReference = DfsEmitIdentList(node, null, globalClassIndex, ref leftType, ref depth, ref inferedType, false, ref isFirstIdent, graphNode, subPass);
            inferedType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : inferedType.UID;
        }
Esempio n. 9
0
 protected abstract void DfsTraverse(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone);
Esempio n. 10
0
        protected void EmitExprListNode(Node node, ref ProtoCore.Type inferedType, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            int firstType = (int)PrimitiveType.kTypeVoid;
            dynamic exprlist = node;

            int rank = 0;
            if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
            {
                //get the rank
                dynamic ltNode = exprlist;
                while ((ltNode is ProtoCore.AST.ImperativeAST.ExprListNode || ltNode is ProtoCore.AST.AssociativeAST.ExprListNode) && ltNode.list.Count > 0)
                {
                    rank++;
                    ltNode = ltNode.list[0];
                }
            }

            foreach (Node listNode in exprlist.list)
            {
                // The infered type is the type of the first element
                DfsTraverse(listNode, ref inferedType, false, graphNode, subPass);

                if ((listNode is ProtoCore.AST.AssociativeAST.ExprListNode) == false)
                {
                    // If 'listNode' was another sub-array, then don't bother adding 
                    // it here, as it has added itself in the call to 'DfsTraverse'.
                    if (null != this.arrayElementType)
                        this.arrayElementType.AppendChildType(inferedType);
                }

                if ((int)PrimitiveType.kTypeVoid == firstType)
                {
                    firstType = inferedType.UID;
                }
            }

            inferedType.UID = firstType;
            inferedType.IsIndexable = true;
            inferedType.rank = rank;
        }
Esempio n. 11
0
        protected void EmitReturnStatement(Node node, ProtoCore.Type inferedType)
        {
            // Check the returned type against the declared return type
            if (null != localProcedure && compileState.IsFunctionCodeBlock(codeBlock))
            {
                if (localProcedure.isConstructor)
                {
                    Debug.Assert(ProtoCore.DSASM.Constants.kInvalidIndex != inferedType.UID);

                    ProtoCore.DSASM.ClassNode typeNode = compileState.ClassTable.ClassNodes[inferedType.UID];
                    Debug.Assert(null != typeNode);
                }
            }
        }
Esempio n. 12
0
        protected void EmitNullNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            if (subPass == ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
            {
                return;
            }

            dynamic nullNode = node;
            inferedType.UID = (int)PrimitiveType.kTypeNull;

            inferedType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : inferedType.UID;
        }
Esempio n. 13
0
        protected void EmitStringNode(Node node, ref ProtoCore.Type inferedType, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            if (subPass == ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
            {
                return;
            }

            dynamic sNode = node;
            if (!enforceTypeCheck || compileState.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeString, inferedType.UID))
            {
                inferedType.UID = (int)PrimitiveType.kTypeString;
            }
            throw new NotImplementedException();
        }
Esempio n. 14
0
        protected void EmitBooleanNode(Node node, ref ProtoCore.Type inferedType, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            if (subPass == ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
            {
                return;
            }

            dynamic bNode = node;
            // We need to get inferedType for boolean variable so that we can perform type check
            if (enforceTypeCheck || compileState.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeBool, inferedType.UID))
            {
                inferedType.UID = (int)PrimitiveType.kTypeBool;
            }
        }
Esempio n. 15
0
        protected int DfsEmitArrayIndexHeap(Node node, AssociativeGraph.GraphNode graphNode = null, ProtoCore.AST.Node parentNode = null, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone)
        {
            int indexCnt = 0;
            Validity.Assert(node is ProtoCore.AST.AssociativeAST.ArrayNode || node is ProtoCore.AST.ImperativeAST.ArrayNode);

            IsAssociativeArrayIndexing = true;

            dynamic arrayNode = node;
            while (arrayNode is ProtoCore.AST.AssociativeAST.ArrayNode || arrayNode is ProtoCore.AST.ImperativeAST.ArrayNode)
            {
                ++indexCnt;
                dynamic array = arrayNode;
                ProtoCore.Type lastType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, 0);
                DfsTraverse(array.Expr, ref lastType, false, graphNode, subPass, parentNode);
                arrayNode = array.Type;
            }

            IsAssociativeArrayIndexing = false;

            return indexCnt;
        }
Esempio n. 16
0
        protected void EmitReturnStatement(Node node, Type inferedType)
        {
            // Check the returned type against the declared return type
            if (null != localProcedure && core.IsFunctionCodeBlock(codeBlock))
            {
                if (localProcedure.isConstructor)
                {
                    buildStatus.LogSemanticError("return statements are not allowed in constructors", core.CurrentDSFileName, node.line, node.col);
                }
                else
                {
#if STATIC_TYPE_CHECKING
                    if (inferedType.UID == (int)PrimitiveType.kInvalidType)
                    {
                        EmitPushNull();
                        EmitReturnToRegister(node.line, node.col, node.endLine, node.endCol);
                        return;
                    }

                    ProtoCore.DSASM.ClassNode typeNode = core.classTable.list[inferedType.UID];
                    Validity.Assert(null != typeNode);

                    bool diableRankCheck = localProcedure.returntype.UID == (int)PrimitiveType.kTypeVar || localProcedure.returntype.rank == -1 || inferedType.UID == (int)PrimitiveType.kTypeVar || inferedType.rank == -1;
                    bool notMatchedRank = diableRankCheck ? false : localProcedure.returntype.rank != inferedType.rank;
                    bool isReturnTypeMatch = (localProcedure.returntype.UID == inferedType.UID) && !notMatchedRank;
                    if (!isReturnTypeMatch)
                    {
                        if (inferedType.UID != (int)PrimitiveType.kTypeVar && (!typeNode.ConvertibleTo(localProcedure.returntype.UID) || notMatchedRank))
                        {
                            // Log a warning and force conversion to null by popping the result to the LX register and pushing a null

                            ProtoCore.DSASM.ClassNode returnTypeNode = core.classTable.list[localProcedure.returntype.UID];
                            if (notMatchedRank)
                            {
                                buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kMismatchReturnType, "Function '" + localProcedure.name + "' " + "expects return value to be of type " + returnTypeNode.name + " and of rank " + localProcedure.returntype.rank, core.CurrentDSFileName, node.line, node.col);
                            }
                            else
                            {
                                buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kMismatchReturnType, "Function '" + localProcedure.name + "' " + "expects return value to be of type " + returnTypeNode.name, core.CurrentDSFileName, node.line, node.col);
                            }
                            EmitPushNull();
                        }
                        else if (localProcedure.returntype.UID < (int)PrimitiveType.kMaxPrimitives && inferedType.UID > (int)PrimitiveType.kTypeNull)
                        {
                            // EmitInstrConsole(ProtoCore.DSASM.kw.cast, localProcedure.returntype.UID.ToString());
                            // EmitConvert(localProcedure.returntype.UID, localProcedure.returntype.rank);
                        }
                    }
                }
#endif
                }
            }
Esempio n. 17
0
 public abstract ProtoCore.DSASM.ProcedureNode TraverseFunctionCall(Node node, Node parentNode, int lefttype, int depth, ref ProtoCore.Type inferedType, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone, ProtoCore.AST.Node bnode = null);
Esempio n. 18
0
        protected void EmitCharNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            if (subPass == DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
            {
                return;
            }

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

            Byte[] utf8bytes = ProtoCore.Utils.EncodingUtils.UTF8StringToUTF8Bytes((String)cNode.value);
            String value = Encoding.UTF8.GetString(utf8bytes);
            if (value.Length > 1)
            {
                buildStatus.LogSyntaxError("Too many characters in character literal", null, node.line, node.col);
            }
  
            String strValue = "'" + value + "'";
            EmitInstrConsole(ProtoCore.DSASM.kw.push, strValue);

            StackValue op = ProtoCore.DSASM.StackValue.BuildChar(value[0]);
            EmitPush(op, cNode.line, cNode.col);
        }
Esempio n. 19
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);
            }
        }
Esempio n. 20
0
        protected void EmitStringNode(Node node, ref ProtoCore.Type inferedType, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            if (subPass == DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
            {
                return;
            }

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

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

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

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

            EmitInstrConsole(ProtoCore.DSASM.kw.alloca, value.Length.ToString());
            EmitPopString(value.Length);
        }
Esempio n. 21
0
        protected void EmitBooleanNode(Node node, ref ProtoCore.Type inferedType, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone)
        {
            if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier)
            {
                return;
            }

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

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

            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.BuildBoolean(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);
            }
        }
Esempio n. 22
0
 protected void EmitReturnNode(Node node)
 {
     throw new NotImplementedException();
 }
Esempio n. 23
0
        protected void EmitExprListNode(Node node, ref ProtoCore.Type inferedType, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone, ProtoCore.AST.Node parentNode = null)
        {
            dynamic exprlist = node;
            int rank = 0;

            if (subPass != ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier)
            {
                //get the rank
                dynamic ltNode = exprlist;

                bool isExprListNode = (ltNode is ProtoCore.AST.ImperativeAST.ExprListNode || ltNode is ProtoCore.AST.AssociativeAST.ExprListNode);
                bool isStringNode = (ltNode is ProtoCore.AST.ImperativeAST.StringNode || ltNode is ProtoCore.AST.AssociativeAST.StringNode);
                while ((isExprListNode && ltNode.Exprs.Count > 0) || isStringNode)
                {
                    rank++;
                    if (isStringNode)
                        break;

                    ltNode = ltNode.Exprs[0];
                    isExprListNode = (ltNode is ProtoCore.AST.ImperativeAST.ExprListNode || ltNode is ProtoCore.AST.AssociativeAST.ExprListNode);
                    isStringNode = (ltNode is ProtoCore.AST.ImperativeAST.StringNode || ltNode is ProtoCore.AST.AssociativeAST.StringNode);
                }
            }

            int commonType = (int)PrimitiveType.kTypeVoid;
            foreach (Node listNode in exprlist.Exprs)
            {
                bool emitReplicationGuideFlag = emitReplicationGuide;
                emitReplicationGuide = false;

                DfsTraverse(listNode, ref inferedType, false, graphNode, subPass, parentNode);
                if ((int)PrimitiveType.kTypeVoid== commonType)
                {
                    commonType = inferedType.UID;
                }
                else 
                {
                    if (inferedType.UID != commonType)
                    {
                        commonType = (int)PrimitiveType.kTypeVar;
                    }
                }

                emitReplicationGuide = emitReplicationGuideFlag;
            }

            inferedType.UID = commonType;
            inferedType.rank = rank;

            if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier)
            {
                return;
            }

            EmitInstrConsole(ProtoCore.DSASM.kw.alloca, exprlist.Exprs.Count.ToString());
            EmitPopArray(exprlist.Exprs.Count);

            if (exprlist.ArrayDimensions != null)
            {
                int dimensions = DfsEmitArrayIndexHeap(exprlist.ArrayDimensions, graphNode);
                EmitInstrConsole(ProtoCore.DSASM.kw.pushindex, dimensions.ToString() + "[dim]");
                EmitPushArrayIndex(dimensions);
            }

            if (core.Options.TempReplicationGuideEmptyFlag && emitReplicationGuide)
            {
                if (node is ProtoCore.AST.AssociativeAST.ExprListNode)
                {
                    var exprNode = node as ProtoCore.AST.AssociativeAST.ExprListNode;
                    int guides = EmitReplicationGuides(exprNode.ReplicationGuides);
                    EmitInstrConsole(ProtoCore.DSASM.kw.pushindex, guides + "[guide]");
                    EmitPushReplicationGuide(guides);
                }
            }
        }
Esempio n. 24
0
	void Imperative(out Node codeBlockNode) {
		ProtoCore.AST.ImperativeAST.ImperativeNode node = null; 
		ProtoCore.AST.ImperativeAST.CodeBlockNode codeblock = new ProtoCore.AST.ImperativeAST.CodeBlockNode();
		NodeUtils.SetNodeStartLocation(codeblock, t);
		
		while (StartOf(15)) {
			if (IsNotAttributeFunction()) {
				Imperative_stmt(out node);
			} else {
				List<ProtoCore.AST.ImperativeAST.ImperativeNode> attrs = new List<ProtoCore.AST.ImperativeAST.ImperativeNode>(); 
				if (la.kind == 10) {
					Imperative_AttributeDeclaration(out attrs);
				}
				Imperative_functiondecl(out node, attrs);
			}
			if (null != node)   
			   codeblock.Body.Add(node); 
			
		}
		codeBlockNode = codeblock;
		
		// We look ahead (la) here instead of looking at the current token (t)
		// because when we get here at the end of a language block, "t" would 
		// have been pointing to the ending token of the last statement in the 
		// language block. What we really need here is the closing bracket '}'
		// character, and that's conveniently residing in the look ahead token.
		// 
		NodeUtils.SetNodeEndLocation(codeblock, la);
		
	}
Esempio n. 25
0
        private void BuildSSADependency(Node node, AssociativeGraph.GraphNode graphNode)
        {
            // Jun Comment: set the graphNode dependent as this identifier list
            ProtoCore.Type type = new ProtoCore.Type();
            type.UID = globalClassIndex;
            ProtoCore.AssociativeGraph.UpdateNodeRef nodeRef = new AssociativeGraph.UpdateNodeRef();
            DFSGetSymbolList(node, ref type, nodeRef);

            if (null != graphNode && nodeRef.nodeList.Count > 0)
            {
                ProtoCore.AssociativeGraph.GraphNode dependentNode = new ProtoCore.AssociativeGraph.GraphNode();
                dependentNode.updateNodeRefList.Add(nodeRef);
                graphNode.PushDependent(dependentNode);
            }
        }
Esempio n. 26
0
	void Hydrogen(out Node codeBlockNode) {
		ProtoCore.AST.AssociativeAST.CodeBlockNode codeblock = new ProtoCore.AST.AssociativeAST.CodeBlockNode();  
		NodeUtils.SetNodeStartLocation(codeblock, t); 
		ProtoCore.AST.AssociativeAST.AssociativeNode node = null; 
		ProtoFFI.ImportModuleHandler imh = null;
		if (core.IsParsingPreloadedAssembly)
		{
		imh = core.ImportHandler;
		}
		else
		{
		imh = this.ImportModuleHandler;
		}
		bool rootImport = (null == imh) ? true : false;  
		while (la.kind == 34) {
			ProtoCore.AST.AssociativeAST.AssociativeNode importNode = null; 
			Import_Statement(out importNode);
			if (null != importNode)
			   (codeblock as ProtoCore.AST.AssociativeAST.CodeBlockNode).Body.Add(importNode);
			
		}
		imh = null;
		  if (core.IsParsingPreloadedAssembly)
		  {
		      imh = core.ImportHandler;
		  }
		  else
		      imh = ImportModuleHandler;
		
		if(null != core.ContextDataManager)
		{
		   if (imh == null)
		       imh = new ProtoFFI.ImportModuleHandler(core);
		   ProtoCore.AST.AssociativeAST.AssociativeNode importNode = null;
		   importNode = core.ContextDataManager.Compile(imh);
		   if (null != importNode)
		       (codeblock as ProtoCore.AST.AssociativeAST.CodeBlockNode).Body.Add(importNode);
		}
		
		if (rootImport && null != imh && imh.RootImportNode.CodeNode.Body.Count != 0)
		   (codeblock as ProtoCore.AST.AssociativeAST.CodeBlockNode).Body.Add(imh.RootImportNode);
		
		if (rootImport && core.IsParsingPreloadedAssembly && !builtinMethodsLoaded)
		{
		CoreUtils.InsertPredefinedAndBuiltinMethods(core, codeblock);
		core.ImportNodes = codeblock;
		}
		
		while (StartOf(1)) {
			if (IsNotAttributeFunctionClass()) {
				Associative_Statement(out node);
			} else {
				List<ProtoCore.AST.AssociativeAST.AssociativeNode> attrs = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>(); 
				if (la.kind == 10) {
					Associative_AttributeDeclaration(out attrs);
				}
				if (la.kind == 27) {
					Associative_functiondecl(out node, attrs);
				} else if (la.kind == 25) {
					Associative_classdecl(out node, attrs);
				} else SynErr(67);
			}
			if (null != node)
			{
			   (codeblock as ProtoCore.AST.AssociativeAST.CodeBlockNode).Body.Add(node); 
			   
			   stmtsParsed++;
			}
			
		}
		if (la.val == "if")
		  SynErr(String.Format(Resources.UseInlineConditional, la.val)); 
		if ((la.val == "for")||(la.val == "while"))
		  SynErr(String.Format(Resources.ValidForImperativeBlockOnly, la.val)); 
		codeBlockNode = codeblock;
		
		// We look ahead (la) here instead of looking at the current token (t)
		// because when we get here at the end of a language block, "t" would 
		// have been pointing to the ending token of the last statement in the 
		// language block. What we really need here is the closing bracket '}'
		// character, and that's conveniently residing in the look ahead token.
		// 
		NodeUtils.SetNodeEndLocation(codeblock, la); 
		
	}
Esempio n. 27
0
 protected abstract void DfsTraverse(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null, 
     ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone, ProtoCore.AST.Node parentNode = null);
Esempio n. 28
0
        protected void EmitIdentifierListNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, 
            ProtoCore.AssociativeGraph.GraphNode graphNode = null, 
            ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone, 
            ProtoCore.AST.Node bnode = null)
        {
            if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier)
            {
                //to process all unbounded parameters if any
                dynamic iNode = node;
                while (iNode is ProtoCore.AST.AssociativeAST.IdentifierListNode || iNode is ProtoCore.AST.ImperativeAST.IdentifierListNode)
                {
                    dynamic rightNode = iNode.RightNode;
                    if (rightNode is ProtoCore.AST.AssociativeAST.FunctionCallNode || rightNode is ProtoCore.AST.ImperativeAST.FunctionCallNode)
                    {
                        foreach (dynamic paramNode in rightNode.FormalArguments)
                        {
                            ProtoCore.Type paramType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, 0);
                            DfsTraverse(paramNode, ref paramType, false, graphNode, ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier);
                        }
                    }
                    iNode = iNode.LeftNode;
                }
                return;
            }

            int depth = 0;

            ProtoCore.Type leftType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kInvalidType, 0);
            bool isFirstIdent = true;

            BuildSSADependency(node, graphNode);
            if (core.Options.GenerateSSA)
            {
                BuildRealDependencyForIdentList(graphNode);

                if (node is ProtoCore.AST.AssociativeAST.IdentifierListNode)
                {
                    if ((node as ProtoCore.AST.AssociativeAST.IdentifierListNode).IsLastSSAIdentListFactor)
                    {
                        Validity.Assert(null != ssaPointerStack);
                        ssaPointerStack.Pop();
                    }
                }
            }

            bool isCollapsed;
            EmitGetterSetterForIdentList(node, ref inferedType, graphNode, subPass, out isCollapsed);
            if (!isCollapsed)
            {
                bool isMethodCallPresent = false;
                ProtoCore.DSASM.SymbolNode firstSymbol = null;
                bool isIdentReference = DfsEmitIdentList(node, null, globalClassIndex, ref leftType, ref depth, ref inferedType, false, ref isFirstIdent, ref isMethodCallPresent, ref firstSymbol, graphNode, subPass, bnode);
                inferedType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : inferedType.UID;


                if (isIdentReference && depth > 1)
                {
                    EmitInstrConsole(ProtoCore.DSASM.kw.pushlist, depth.ToString(), globalClassIndex.ToString());

                    // TODO Jun: Get blockid
                    int blockId = 0;
                    EmitPushList(depth, globalClassIndex, blockId);
                }

                
#if PROPAGATE_PROPERTY_MODIFY_VIA_METHOD_UPDATE
                if (isMethodCallPresent)
                {
                    // Comment Jun: If the first symbol is null, it is a constructor. If you see it isnt, pls tell me
                    if (null != firstSymbol)
                    {
                        StackValue op = StackValue.Null;

                        if (firstSymbol.classScope != ProtoCore.DSASM.Constants.kInvalidIndex &&
                            firstSymbol.functionIndex == ProtoCore.DSASM.Constants.kGlobalScope)
                        {
                            // Member var
                            op = firstSymbol.isStatic 
                                 ? StackValue.BuildStaticMemVarIndex(firstSymbol.symbolTableIndex)
                                 : StackValue.BuildMemVarIndex(firstSymbol.symbolTableIndex);
                        }
                        else
                        {
                            op = StackValue.BuildVarIndex(firstSymbol.symbolTableIndex);
                        }

                        EmitPushDependencyData(currentBinaryExprUID, false);
                        EmitInstrConsole(ProtoCore.DSASM.kw.dep, firstSymbol.name);
                        EmitDependency(firstSymbol.runtimeTableIndex, op, 0);
                    }
                }
#endif
            }
        }
Esempio n. 29
0
        protected bool DfsEmitIdentList(
            Node pNode, 
            Node parentNode, 
            int contextClassScope, 
            ref ProtoCore.Type lefttype,
            ref int depth, 
            ref ProtoCore.Type finalType, 
            bool isLeftidentList, 
            ref bool isFirstIdent, 
            ref bool isMethodCallPresent,
            ref ProtoCore.DSASM.SymbolNode firstSymbol,
            ProtoCore.AssociativeGraph.GraphNode graphNode = null,
            ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone,
            ProtoCore.AST.Node binaryExpNode = null)
        {
            dynamic node = pNode;
            if (node is ProtoCore.AST.ImperativeAST.IdentifierListNode || node is ProtoCore.AST.AssociativeAST.IdentifierListNode)
            {
                dynamic bnode = node;
                if (ProtoCore.DSASM.Operator.dot != bnode.Optr)
                {
                    string message = "The left hand side of an operation can only contain an indirection operator '.' (48D67B9B)";
                    buildStatus.LogSemanticError(message, core.CurrentDSFileName, bnode.line, bnode.col);
                    throw new BuildHaltException(message);
                }

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

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

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

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

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

                int ci = core.ClassTable.IndexOf(identnode.Value);
                if (ProtoCore.DSASM.Constants.kInvalidIndex != ci)
                {
                    finalType.UID = lefttype.UID = ci;
                }
                else if (identnode.Value == ProtoCore.DSDefinitions.Keyword.This)
                {
                    finalType.UID = lefttype.UID = contextClassScope;
                    EmitInstrConsole(ProtoCore.DSASM.kw.push, 0 + "[dim]");
                    StackValue opdim = StackValue.BuildArrayDimension(0);
                    EmitPush(opdim);
                    EmitThisPointerNode();
                    depth++;
                    return true;
                }
                else
                {
                    ProtoCore.DSASM.SymbolNode symbolnode = null;
                    bool isAllocated = false;
                    bool isAccessible = false;
                    if (lefttype.UID != -1)
                    {
                        isAllocated = VerifyAllocation(identnode.Value, lefttype.UID, globalProcIndex, out symbolnode, out isAccessible);
                    }
                    else
                    {
                        isAllocated = VerifyAllocation(identnode.Value, contextClassScope, globalProcIndex, out symbolnode, out isAccessible);
                        Validity.Assert(null == firstSymbol);
                        firstSymbol = symbolnode;
                    }

                    bool callOnClass = false;
                    string leftClassName = "";
                    int leftci = Constants.kInvalidIndex;

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

                                EmitInstrConsole(ProtoCore.DSASM.kw.push, 0 + "[dim]");
                                StackValue dynamicOpdim = StackValue.BuildArrayDimension(0);
                                EmitPush(dynamicOpdim);

                                EmitInstrConsole(ProtoCore.DSASM.kw.pushm, leftClassName);
                                StackValue classOp = StackValue.BuildClassIndex(leftci);
                                EmitPushm(classOp, globalClassIndex, codeBlock.codeBlockId);

                                depth = depth + 1;
                            }
                        }
                    }

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

                        if (depth == 0)
                        {
                            lefttype.UID = finalType.UID = (int)PrimitiveType.kTypeNull;
                            EmitPushNull();
                            depth = 1;
                            return false;
                        }
                        else
                        {
                            DSASM.DyanmicVariableNode dynamicVariableNode = new DSASM.DyanmicVariableNode(identnode.Value, globalProcIndex, globalClassIndex);
                            core.DynamicVariableTable.variableTable.Add(dynamicVariableNode);
                            int dim = 0;
                            if (null != identnode.ArrayDimensions)
                            {
                                dim = DfsEmitArrayIndexHeap(identnode.ArrayDimensions, graphNode);
                            }
                            EmitInstrConsole(ProtoCore.DSASM.kw.push, dim + "[dim]");
                            StackValue dynamicOpdim = StackValue.BuildArrayDimension(dim);
                            EmitPush(dynamicOpdim);

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

                            lefttype.UID = finalType.UID = (int)PrimitiveType.kTypeVar;
                            depth++;
                            return true;
                        }
                    }
                    else
                    {
                        if (callOnClass && !symbolnode.isStatic)
                        {
                            string procName = identnode.Name;
                            string property;
                            ProtoCore.DSASM.ProcedureNode staticProcCallNode = core.ClassTable.ClassNodes[leftci].GetFirstStaticFunctionBy(procName);

                            if (null != staticProcCallNode)
                            {
                                string message = String.Format(Resources.kMethodHasInvalidArguments, procName);
                                buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, core.CurrentDSFileName, identnode.line, identnode.col, graphNode);
                            }
                            else if (CoreUtils.TryGetPropertyName(procName, out property))
                            {
                                string message = String.Format(Resources.kPropertyIsInaccessible, property);
                                buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, core.CurrentDSFileName, identnode.line, identnode.col, graphNode);
                            }
                            else
                            {
                                string message = String.Format(Resources.kMethodIsInaccessible, procName);
                                buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, core.CurrentDSFileName, identnode.line, identnode.col, graphNode);
                            }

                            lefttype.UID = finalType.UID = (int)PrimitiveType.kTypeNull;
                            EmitPushNull();
                            return false;
                        }
                    }

                    //
                    // The graph node depends on the first identifier in this identifier list
                    // Where:
                    //      p = f(1);			        
                    //      px = p.x; // px dependent on p
                    //      p = f(2);
                    //
                    if (isFirstIdent && null != graphNode)
                    {
                        isFirstIdent = false;
                        //ProtoCore.AssociativeGraph.GraphNode dependentNode = new ProtoCore.AssociativeGraph.GraphNode();
                        //dependentNode.symbol = symbolnode;
                        //dependentNode.symbolList.Add(symbolnode);
                        //graphNode.PushDependent(dependentNode);
                    }
                    
                    /* Dont try to figure out the type at compile time if it is
                     * an array, it is just not reliable because each element in
                     * an array can have different types
                     */
                    if (!symbolnode.datatype.IsIndexable || symbolnode.datatype.rank < 0)
                        lefttype = symbolnode.datatype;

                    int dimensions = 0;

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

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

                    if (null != identnode.ArrayDimensions)
                    {
                        dimensions = DfsEmitArrayIndexHeap(identnode.ArrayDimensions, graphNode);
                        operandType = ProtoCore.DSASM.AddressType.ArrayPointer;
                    }

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

                    if (0 == depth || (symbolnode != null && symbolnode.isStatic))
                    {
                        if (ProtoCore.DSASM.Constants.kGlobalScope == symbolnode.functionIndex
                            && ProtoCore.DSASM.Constants.kInvalidIndex != symbolnode.classScope)
                        {
                            // member var
                            operandType = symbolnode.isStatic ? ProtoCore.DSASM.AddressType.StaticMemVarIndex : ProtoCore.DSASM.AddressType.MemVarIndex;
                        }
                        else
                        {
                            operandType = ProtoCore.DSASM.AddressType.VarIndex;
                        }
                    }

                    StackValue op = new StackValue();
                    op.optype = operandType;
                    op.opdata = symbolnode.symbolTableIndex;

                    // TODO Jun: Performance. 
                    // Is it faster to have a 'push' specific to arrays to prevent pushing dimension for push instruction?
                    EmitInstrConsole(ProtoCore.DSASM.kw.push, dimensions + "[dim]");
                    StackValue opdim = StackValue.BuildArrayDimension(dimensions);
                    EmitPush(opdim);

                    
                    if (isLeftidentList || depth == 0)
                    {
                        EmitInstrConsole(ProtoCore.DSASM.kw.pushm, identnode.Value);
                        EmitPushm(op, symbolnode == null ? globalClassIndex : symbolnode.classScope, runtimeIndex);
                    }
                    else
                    {
                        // change to dynamic call to facilitate update mechanism
                        DSASM.DyanmicVariableNode dynamicVariableNode = new DSASM.DyanmicVariableNode(identnode.Name, globalProcIndex, globalClassIndex);
                        core.DynamicVariableTable.variableTable.Add(dynamicVariableNode);
                        StackValue dynamicOp = StackValue.BuildDynamic(core.DynamicVariableTable.variableTable.Count - 1);
                        EmitInstrConsole(ProtoCore.DSASM.kw.pushm, identnode.Value + "[dynamic]");
                        EmitPushm(dynamicOp, symbolnode == null ? globalClassIndex : symbolnode.classScope, runtimeIndex);
                    }
                    depth = depth + 1;
                    finalType = lefttype;
                }
                return true;
            }
            else if (node is ProtoCore.AST.ImperativeAST.FunctionCallNode || node is ProtoCore.AST.AssociativeAST.FunctionCallNode)
            {
                // A function call must always track dependents
                bool allowDependents = true;
                if (null != graphNode)
                {
                    allowDependents = graphNode.allowDependents;
                    graphNode.allowDependents = true;
                }

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

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

                // This is the first non-auto generated procedure found in the identifier list
                if (null != procnode)
                {
                    if (!procnode.IsConstructor && !procnode.Name.Equals(ProtoCore.DSASM.Constants.kStaticPropertiesInitializer))
                    {
                        functionCallStack.Add(procnode);
                        if (null != graphNode)
                        {
                            graphNode.firstProcRefIndex = graphNode.dependentList.Count - 1;
                        }
                    }
                    isMethodCallPresent = !isMethodCallPresent && !procnode.IsAutoGenerated && !procnode.IsConstructor;
                }

                //finalType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : finalType.UID;
                lefttype = finalType;
                depth = 1;
            }
            else
            {
                string message = "The left side of operator '.' must be an identifier. (B9AEA3A6)";
                buildStatus.LogSemanticError(message, core.CurrentDSFileName, node.line, node.col);
                throw new BuildHaltException(message);
            }
            return false;
        }
Esempio n. 30
0
        protected void EmitCharNode(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            if (subPass == ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier)
            {
                return;
            }

            dynamic cNode = node;
            if (!enforceTypeCheck || compileState.TypeSystem.IsHigherRank((int)PrimitiveType.kTypeChar, inferedType.UID))
            {
                inferedType.UID = (int)PrimitiveType.kTypeChar;
            }
            inferedType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : inferedType.UID;
            throw new NotImplementedException();
        }