private int DfsExprValue(ImperativeNode node)
 {
     if (node is IdentifierNode)
     {
         int val = 0;
         IdentifierNode t = node as IdentifierNode;
         try
         {
             val = System.Convert.ToInt32(t.Value);
             return val;
         }
         catch (OverflowException)
         {
         }
         catch (FormatException)
         {
         }
     }
     else if (node is BinaryExpressionNode)
     {
         BinaryExpressionNode b = node as BinaryExpressionNode;
         Debug.Assert(ProtoCore.DSASM.Operator.mul == b.Optr);
         int left = DfsExprValue(b.LeftNode);
         int right = DfsExprValue(b.RightNode);
         return left * right;
     }
     return 1;
 }
Exemple #2
0
        public ForLoopNode(ForLoopNode rhs) : base(rhs)
        {
            body = new List <ImperativeNode>();
            foreach (ImperativeNode iNode in rhs.body)
            {
                ImperativeNode newNode = ProtoCore.Utils.NodeUtils.Clone(iNode);
                body.Add(newNode);
            }
            loopVar    = ProtoCore.Utils.NodeUtils.Clone(rhs.loopVar);
            expression = ProtoCore.Utils.NodeUtils.Clone(rhs.expression);

            KwForLine = rhs.KwForLine;
            KwForCol  = rhs.KwForCol;
            KwInLine  = rhs.KwInLine;
            KwInCol   = rhs.KwInCol;
        }
Exemple #3
0
        public ForLoopNode(ForLoopNode rhs) : base(rhs)
        {
            Body = new List <ImperativeNode>();
            foreach (ImperativeNode iNode in rhs.Body)
            {
                ImperativeNode newNode = NodeUtils.Clone(iNode);
                Body.Add(newNode);
            }
            LoopVariable = NodeUtils.Clone(rhs.LoopVariable);
            Expression   = NodeUtils.Clone(rhs.Expression);

            KwForLine = rhs.KwForLine;
            KwForCol  = rhs.KwForCol;
            KwInLine  = rhs.KwInLine;
            KwInCol   = rhs.KwInCol;
        }
Exemple #4
0
        public IfStmtNode(IfStmtNode rhs) : base(rhs)
        {
            //
            IfExprNode = ProtoCore.Utils.NodeUtils.Clone(rhs.IfExprNode);


            //
            IfBody = new List <ImperativeNode>();
            foreach (ImperativeNode stmt in rhs.IfBody)
            {
                ImperativeNode body = ProtoCore.Utils.NodeUtils.Clone(stmt);
                IfBody.Add(body);
            }

            //
            IfBodyPosition = ProtoCore.Utils.NodeUtils.Clone(rhs.IfBodyPosition);

            //
            ElseIfList = new List <ElseIfBlock>();
            foreach (ElseIfBlock elseBlock in rhs.ElseIfList)
            {
                ImperativeNode elseNode = ProtoCore.Utils.NodeUtils.Clone(elseBlock);
                ElseIfList.Add(elseNode as ElseIfBlock);
            }

            //
            ElseBody = new List <ImperativeNode>();
            foreach (ImperativeNode stmt in rhs.ElseBody)
            {
                ImperativeNode tmpNode = ProtoCore.Utils.NodeUtils.Clone(stmt);
                ElseBody.Add(tmpNode);
            }

            //
            ElseBodyPosition = ProtoCore.Utils.NodeUtils.Clone(rhs.ElseBodyPosition);
        }
Exemple #5
0
        private void EmitPostFixNode(ImperativeNode node, ref ProtoCore.Type inferedType)
        {
            bool parseGlobal = null == localProcedure && ProtoCore.DSASM.ImperativeCompilePass.kAll == compilePass;
            bool parseGlobalFunction = null != localProcedure && ProtoCore.DSASM.ImperativeCompilePass.kGlobalFuncBody == compilePass;

            if (parseGlobal || parseGlobalFunction)
            {
                PostFixNode pfNode = node as PostFixNode;

                //convert post fix operation to a binary operation
                BinaryExpressionNode binRight = new BinaryExpressionNode();
                BinaryExpressionNode bin = new BinaryExpressionNode();

                binRight.LeftNode = pfNode.Identifier;
                binRight.RightNode = new IntNode() { value = "1" };
                binRight.Optr = (ProtoCore.DSASM.UnaryOperator.Increment == pfNode.Operator) ? ProtoCore.DSASM.Operator.add : ProtoCore.DSASM.Operator.sub;
                bin.LeftNode = pfNode.Identifier;
                bin.RightNode = binRight;
                bin.Optr = ProtoCore.DSASM.Operator.assign;
                EmitBinaryExpressionNode(bin, ref inferedType);
            }
        }
Exemple #6
0
        private void EmitWhileStmtNode(ImperativeNode node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            if (IsParsingGlobal() || IsParsingGlobalFunctionBody())
            {
                /*

                while(E)	->	entry = pc
                                traverse E
                                emit(pop,cx)
                                L1 = pc + 1
                                L2 = null
                                bp = pc
                                emit(jmp, _cx, L1, L2)

                 * */

                int bp = (int)ProtoCore.DSASM.Constants.kInvalidIndex;
                int L1 = (int)ProtoCore.DSASM.Constants.kInvalidIndex;
                int L2 = (int)ProtoCore.DSASM.Constants.kInvalidIndex;
                int entry = (int)ProtoCore.DSASM.Constants.kInvalidIndex;

                entry = pc;

                WhileStmtNode whileNode = node as WhileStmtNode;
                DfsTraverse(whileNode.Expr, ref inferedType);

                ProtoCore.DSASM.StackValue opCX = new ProtoCore.DSASM.StackValue();
                EmitInstrConsole(ProtoCore.DSASM.kw.pop, ProtoCore.DSASM.kw.regCX);
                opCX.optype = ProtoCore.DSASM.AddressType.Register;
                opCX.opdata = (int)ProtoCore.DSASM.Registers.CX;
                EmitPop(opCX, Constants.kGlobalScope);

                L1 = pc + 1;
                L2 = ProtoCore.DSASM.Constants.kInvalidIndex;
                bp = pc;
                EmitCJmp(L1, L2, whileNode.Expr.line, whileNode.Expr.col, whileNode.Expr.endLine, whileNode.Expr.endCol);

                EmitSetExpressionUID(compileStateTracker.ExpressionUID++);

                /*
                {
                    S		->	traverse S
                                bptable.append(pc)
                                emit(jmp, entry)
                }
                            ->  backpatch(bp, pc)
                */
                if (null != whileNode.Body)
                {
                    // Create a new symboltable for this block
                    // Set the current table as the parent of the new table
                    // Set the new table as a new child of the current table
                    // Set the new table as the current table
                    // Create a new codeblock for this block
                    // Set the current codeblock as the parent of the new codeblock
                    // Set the new codeblock as a new child of the current codeblock
                    // Set the new codeblock as the current codeblock
                    ProtoCore.DSASM.CodeBlock localCodeBlock = new ProtoCore.DSASM.CodeBlock(
                        ProtoCore.DSASM.CodeBlockType.kConstruct,
                        Language.kInvalid,
                        compileStateTracker.CodeBlockIndex++,
                        new ProtoCore.DSASM.SymbolTable(GetConstructBlockName("while"), compileStateTracker.RuntimeTableIndex++),
                        null,
                        true);

                    localCodeBlock.instrStream = codeBlock.instrStream;
                    localCodeBlock.parent = codeBlock;
                    codeBlock.children.Add(localCodeBlock);
                    codeBlock = localCodeBlock;
                    compileStateTracker.CompleteCodeBlockList.Add(localCodeBlock);
                    backpatchMap.EntryTable[localCodeBlock.codeBlockId] = entry;
                    backpatchMap.BreakTable[localCodeBlock.codeBlockId] = new BackpatchTable();

                    EmitPushBlockID(localCodeBlock.codeBlockId);
                    foreach (ImperativeNode bodyNode in whileNode.Body)
                    {
                        inferedType = new ProtoCore.Type();
                        inferedType.UID = (int)PrimitiveType.kTypeVar;

                        if (bodyNode is LanguageBlockNode)
                        {
                            BinaryExpressionNode langBlockNode = new BinaryExpressionNode();
                            langBlockNode.LeftNode = nodeBuilder.BuildIdentfier(compileStateTracker.GenerateTempLangageVar());
                            langBlockNode.Optr = ProtoCore.DSASM.Operator.assign;
                            langBlockNode.RightNode = bodyNode;
                            DfsTraverse(langBlockNode, ref inferedType, isBooleanOp, graphNode);
                        }
                        else
                        {
                            DfsTraverse(bodyNode, ref inferedType, isBooleanOp, graphNode);
                        }
                    }

                    ProtoCore.AST.Node oldBlockNode = localCodeBlockNode;
                    localCodeBlockNode = node;
                    EmitInstrConsole(ProtoCore.DSASM.kw.retcn);
                    EmitRetcn(localCodeBlock.codeBlockId);
                    localCodeBlockNode = oldBlockNode;

                    // Restore - Set the local codeblock parent to be the current codeblock
                    codeBlock = localCodeBlock.parent;

                    EmitJmp(entry);
                    EmitPopBlockID();
                    Backpatch(backpatchMap.BreakTable[localCodeBlock.codeBlockId].backpatchList, pc);
                }
                Backpatch(bp, pc);
            }
        }
Exemple #7
0
        private void EmitUnaryExpressionNode(ImperativeNode node, ref ProtoCore.Type inferedType, ProtoCore.AST.ImperativeAST.BinaryExpressionNode parentNode)
        {
            if (IsParsingGlobal() || IsParsingGlobalFunctionBody())
            {
                UnaryExpressionNode u = node as UnaryExpressionNode;
                bool isPrefixOperation = ProtoCore.DSASM.UnaryOperator.Increment == u.Operator || ProtoCore.DSASM.UnaryOperator.Decrement == u.Operator;
                //(Ayush) In case of prefix, apply prefix operation first
                if (isPrefixOperation)
                {
                    if (u.Expression is IdentifierListNode || u.Expression is IdentifierNode)
                    {
                        BinaryExpressionNode binRight = new BinaryExpressionNode();
                        BinaryExpressionNode bin = new BinaryExpressionNode();
                        binRight.LeftNode = u.Expression;
                        binRight.RightNode = new IntNode { value = "1" };
                        binRight.Optr = (ProtoCore.DSASM.UnaryOperator.Increment == u.Operator) ? ProtoCore.DSASM.Operator.add : ProtoCore.DSASM.Operator.sub;
                        bin.LeftNode = u.Expression; bin.RightNode = binRight; bin.Optr = ProtoCore.DSASM.Operator.assign;
                        EmitBinaryExpressionNode(bin, ref inferedType);
                    }
                    else
                        throw new BuildHaltException("Invalid use of prefix operation (15BB9C10).");
                }

                DfsTraverse(u.Expression, ref inferedType, false, null, AssociativeSubCompilePass.kNone, parentNode);

                if (!isPrefixOperation)
                {
                    EmitInstrConsole(ProtoCore.DSASM.kw.pop, ProtoCore.DSASM.kw.regAX);
                    ProtoCore.DSASM.StackValue opAX = new ProtoCore.DSASM.StackValue();
                    opAX.optype = ProtoCore.DSASM.AddressType.Register;
                    opAX.opdata = (int)ProtoCore.DSASM.Registers.AX;
                    EmitPop(opAX, Constants.kGlobalScope);

                    string op = opKwData.unaryOpStringTable[u.Operator];
                    EmitInstrConsole(op, ProtoCore.DSASM.kw.regAX);
                    EmitUnary(opKwData.unaryOpCodeTable[u.Operator], opAX);

                    EmitInstrConsole(ProtoCore.DSASM.kw.push, ProtoCore.DSASM.kw.regAX);
                    ProtoCore.DSASM.StackValue opRes = new ProtoCore.DSASM.StackValue();
                    opRes.optype = ProtoCore.DSASM.AddressType.Register;
                    opRes.opdata = (int)ProtoCore.DSASM.Registers.AX;
                    EmitPush(opRes);
                }
            }
        }
Exemple #8
0
        private void EmitLanguageBlockNode(ImperativeNode node, ref ProtoCore.Type inferedType, ProtoCore.AssociativeGraph.GraphNode propogateUpdateGraphNode = null)
        {
            //
            // TODO Jun:
            //      Add support for language blocks, classes and functions in GRAPH post july release
            //      This Temporary guard will no longer be necessary
            bool disableLanguageBlocks = compileStateTracker.IsParsingCodeBlockNode || compileStateTracker.IsParsingPreloadedAssembly;
            if (disableLanguageBlocks)
            {
                compileStateTracker.BuildStatus.LogSemanticError("Defining language blocks are not yet supported");
            }

            if (IsParsingGlobal() || IsParsingGlobalFunctionBody())
            {
                LanguageBlockNode langblock = node as LanguageBlockNode;
                //(Fuqiang, Ayush) : Throwing an assert stops NUnit. Negative tests expect to catch a
                // CompilerException, so we throw that instead.
                //Debug.Assert(ProtoCore.Language.kInvalid != langblock.codeblock.language);

                if (ProtoCore.Language.kInvalid == langblock.codeblock.language)
                {
                    throw new ProtoCore.Exceptions.CompileErrorsOccured("Invalid language block");
                }

                ProtoCore.CompileTime.Context context = new ProtoCore.CompileTime.Context();

                int entry = 0;
                int blockId = ProtoCore.DSASM.Constants.kInvalidIndex;
                if (ProtoCore.Language.kImperative == langblock.codeblock.language)
                {
                    // TODO Jun: Move the associative and all common string into some table
                    buildStatus.LogSyntaxError("An imperative language block is declared within an imperative language block.", compileStateTracker.CurrentDSFileName, langblock.line, langblock.col);
                }

                if (globalProcIndex != ProtoCore.DSASM.Constants.kInvalidIndex && compileStateTracker.ProcNode == null)
                {
                    compileStateTracker.ProcNode = codeBlock.procedureTable.procList[globalProcIndex];
                }

                compileStateTracker.Executives[langblock.codeblock.language].Compile(compileStateTracker, out blockId, codeBlock, langblock.codeblock, context, codeBlock.EventSink, langblock.CodeBlockNode);

                if (propogateUpdateGraphNode != null)
                {
                    propogateUpdateGraphNode.languageBlockId = blockId;
                    CodeBlock childBlock = compileStateTracker.CompleteCodeBlockList[blockId];
                    foreach (var subGraphNode in childBlock.instrStream.dependencyGraph.GraphList)
                    {
                        foreach (var depentNode in subGraphNode.dependentList)
                        {
                            if (depentNode.updateNodeRefList != null
                                && depentNode.updateNodeRefList.Count > 0
                                && depentNode.updateNodeRefList[0].nodeList != null
                                && depentNode.updateNodeRefList[0].nodeList.Count > 0)
                            {
                                SymbolNode dependentSymbol = depentNode.updateNodeRefList[0].nodeList[0].symbol;
                                int symbolBlockId = dependentSymbol.codeBlockId;
                                if (symbolBlockId != Constants.kInvalidIndex)
                                {
                                    CodeBlock symbolBlock = compileStateTracker.CompleteCodeBlockList[symbolBlockId];
                                    if (!symbolBlock.IsMyAncestorBlock(codeBlock.codeBlockId))
                                    {
                                        propogateUpdateGraphNode.PushDependent(depentNode);
                                    }
                                }
                            }
                        }
                    }
                }

                setBlkId(blockId);
                inferedType = compileStateTracker.InferedType;
                //Debug.Assert(codeBlock.children[codeBlock.children.Count - 1].blockType == ProtoCore.DSASM.CodeBlockType.kLanguage);
                codeBlock.children[codeBlock.children.Count - 1].Attributes = PopulateAttributes(langblock.Attributes);

            #if ENABLE_EXCEPTION_HANDLING
                core.ExceptionHandlingManager.Register(blockId, globalProcIndex, globalClassIndex);
            #endif

                EmitInstrConsole("bounce " + blockId + ", " + entry.ToString());
                EmitBounceIntrinsic(blockId, entry);

                // The callee language block will have stored its result into the RX register.
                EmitInstrConsole(ProtoCore.DSASM.kw.push, ProtoCore.DSASM.kw.regRX);
                ProtoCore.DSASM.StackValue opRes = new ProtoCore.DSASM.StackValue();
                opRes.optype = ProtoCore.DSASM.AddressType.Register;
                opRes.opdata = (int)ProtoCore.DSASM.Registers.RX;
                EmitPush(opRes);
            }
        }
Exemple #9
0
        private void EmitIfStmtNode(ImperativeNode node, ref ProtoCore.Type inferedType, ProtoCore.AST.ImperativeAST.BinaryExpressionNode parentNode = null, bool isForInlineCondition = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            if (IsParsingGlobal() || IsParsingGlobalFunctionBody())
            {
                /*
                                def backpatch(bp, pc)
                                    instr = instrstream[bp]
                                    if instr.opcode is jmp
                                        instr.op1 = pc
                                    elseif instr.opcode is cjmp
                                        instr.op2 = pc
                                    end
                                end

                                def backpatch(table, pc)
                                    foreach node in table
                                        backpatch(node.pc, pc)
                                    end
                                end

                */
                /*
                 if(E)		->	traverse E
                                bpTable = new instance
                                L1 = pc + 1
                                L2 = null
                                bp = pc
                                emit(jmp, _cx, L1, L2)
                {
                    S		->	traverse S
                                L1 = null
                                bpTable.append(pc)
                                emit(jmp,labelEnd)
                                backpatch(bp,pc)
                }
                 * */

                int bp = (int)ProtoCore.DSASM.Constants.kInvalidIndex;
                int L1 = (int)ProtoCore.DSASM.Constants.kInvalidIndex;
                int L2 = (int)ProtoCore.DSASM.Constants.kInvalidIndex;
                ProtoCore.DSASM.StackValue opCX = new ProtoCore.DSASM.StackValue();

                // If-expr
                IfStmtNode ifnode = node as IfStmtNode;
                DfsTraverse(ifnode.IfExprNode, ref inferedType, false, graphNode, AssociativeSubCompilePass.kNone, parentNode);

                EmitInstrConsole(ProtoCore.DSASM.kw.pop, ProtoCore.DSASM.kw.regCX);
                opCX.optype = ProtoCore.DSASM.AddressType.Register;
                opCX.opdata = (int)ProtoCore.DSASM.Registers.CX;
                EmitPop(opCX, Constants.kGlobalScope);

                L1 = pc + 1;
                L2 = ProtoCore.DSASM.Constants.kInvalidIndex;
                bp = pc;
                EmitCJmp(L1, L2, ifnode.IfExprNode.line, ifnode.IfExprNode.col, ifnode.IfExprNode.endLine, ifnode.IfExprNode.endCol);

                if (!isForInlineCondition)
                {
                    EmitSetExpressionUID(compileStateTracker.ExpressionUID++);
                }

                // Create a new codeblock for this block
                // Set the current codeblock as the parent of the new codeblock
                // Set the new codeblock as a new child of the current codeblock
                // Set the new codeblock as the current codeblock
                ProtoCore.DSASM.CodeBlock localCodeBlock = new ProtoCore.DSASM.CodeBlock(
                    ProtoCore.DSASM.CodeBlockType.kConstruct,
                    Language.kInvalid,
                    compileStateTracker.CodeBlockIndex++,
                    new ProtoCore.DSASM.SymbolTable(GetConstructBlockName("if"), compileStateTracker.RuntimeTableIndex++),
                    null);

                localCodeBlock.instrStream = codeBlock.instrStream;
                localCodeBlock.parent = codeBlock;
                codeBlock.children.Add(localCodeBlock);
                codeBlock = localCodeBlock;
                compileStateTracker.CompleteCodeBlockList.Add(localCodeBlock);
                EmitPushBlockID(localCodeBlock.codeBlockId);
                // If-body
                foreach (ImperativeNode ifBody in ifnode.IfBody)
                {
                    inferedType = new ProtoCore.Type();
                    inferedType.UID = (int)PrimitiveType.kTypeVar;
                    DfsTraverse(ifBody, ref inferedType, false, graphNode, AssociativeSubCompilePass.kNone, parentNode);
                }

                if (!isForInlineCondition)
                {
                    ProtoCore.AST.Node oldBlockNode = localCodeBlockNode;
                    localCodeBlockNode = ifnode.IfBodyPosition;
                    EmitInstrConsole(ProtoCore.DSASM.kw.retcn);
                    EmitRetcn(localCodeBlock.codeBlockId);
                    localCodeBlockNode = oldBlockNode;
                }

                // Restore - Set the local codeblock parent to be the current codeblock
                codeBlock = localCodeBlock.parent;

                L1 = ProtoCore.DSASM.Constants.kInvalidIndex;

                BackpatchTable backpatchTable = new BackpatchTable();
                backpatchTable.Append(pc, L1);
                EmitJmp(L1);
                EmitPopBlockID();

                // Backpatch the L2 destination of the if block
                Backpatch(bp, pc);

                /*
                else if(E)	->	traverse E
                                L1 = pc + 1
                                L2 = null
                                bp = pc
                                emit(jmp, _cx, L1, L2)
                {
                    S		->	traverse S
                                L1 = null
                                bpTable.append(pc)
                                emit(jmp,labelEnd)
                                backpatch(bp,pc)
                }
                 * */

                // Elseif-expr
                foreach (ElseIfBlock elseifNode in ifnode.ElseIfList)
                {
                    DfsTraverse(elseifNode.Expr, ref inferedType, false, graphNode);

                    EmitInstrConsole(ProtoCore.DSASM.kw.pop, ProtoCore.DSASM.kw.regCX);
                    opCX.optype = ProtoCore.DSASM.AddressType.Register;
                    opCX.opdata = (int)ProtoCore.DSASM.Registers.CX;
                    EmitPop(opCX, Constants.kGlobalScope);

                    L1 = pc + 1;
                    L2 = ProtoCore.DSASM.Constants.kInvalidIndex;
                    bp = pc;
                    EmitCJmp(L1, L2, elseifNode.Expr.line, elseifNode.Expr.col, elseifNode.Expr.endLine, elseifNode.Expr.endCol);

                    EmitSetExpressionUID(compileStateTracker.ExpressionUID++);

                    // Elseif-body
                    if (null != elseifNode.Body)
                    {
                        // Create a new codeblock for this block
                        // Set the current codeblock as the parent of the new codeblock
                        // Set the new codeblock as a new child of the current codeblock
                        // Set the new codeblock as the current codeblock
                        localCodeBlock = new ProtoCore.DSASM.CodeBlock(
                            ProtoCore.DSASM.CodeBlockType.kConstruct,
                            Language.kInvalid,
                            compileStateTracker.CodeBlockIndex++,
                            new ProtoCore.DSASM.SymbolTable(GetConstructBlockName("elseif"), compileStateTracker.RuntimeTableIndex++),
                            null);

                        localCodeBlock.instrStream = codeBlock.instrStream;
                        localCodeBlock.parent = codeBlock;
                        codeBlock.children.Add(localCodeBlock);
                        codeBlock = localCodeBlock;
                        compileStateTracker.CompleteCodeBlockList.Add(localCodeBlock);
                        EmitPushBlockID(localCodeBlock.codeBlockId);
                        foreach (ImperativeNode elseifBody in elseifNode.Body)
                        {
                            inferedType = new ProtoCore.Type();
                            inferedType.UID = (int)PrimitiveType.kTypeVar;
                            DfsTraverse(elseifBody, ref inferedType, false, graphNode);
                        }

                        if (!isForInlineCondition)
                        {
                            ProtoCore.AST.Node oldBlockNode = localCodeBlockNode;
                            localCodeBlockNode = elseifNode.ElseIfBodyPosition;
                            EmitInstrConsole(ProtoCore.DSASM.kw.retcn);
                            EmitRetcn(localCodeBlock.codeBlockId);
                            localCodeBlockNode = oldBlockNode;
                        }

                        // Restore - Set the local codeblock parent to be the current codeblock
                        codeBlock = localCodeBlock.parent;
                    }

                    L1 = ProtoCore.DSASM.Constants.kInvalidIndex;
                    backpatchTable.Append(pc, L1);
                    EmitJmp(L1);
                    EmitPopBlockID();

                    // Backpatch the L2 destination of the elseif block
                    Backpatch(bp, pc);
                }

                /*
                else
                {
                    S		->	traverse S
                                L1 = null
                                bpTable.append(pc)
                                emit(jmp,labelEnd)
                                backpatch(bp,pc)
                }
                 * */
                // Else-body

                Debug.Assert(null != ifnode.ElseBody);
                if (0 != ifnode.ElseBody.Count)
                {
                    // Create a new symboltable for this block
                    // Set the current table as the parent of the new table
                    // Set the new table as a new child of the current table
                    // Set the new table as the current table
                    // Create a new codeblock for this block
                    // Set the current codeblock as the parent of the new codeblock
                    // Set the new codeblock as a new child of the current codeblock
                    // Set the new codeblock as the current codeblock
                    localCodeBlock = new ProtoCore.DSASM.CodeBlock(
                        ProtoCore.DSASM.CodeBlockType.kConstruct,
                        Language.kInvalid,
                        compileStateTracker.CodeBlockIndex++,
                        new ProtoCore.DSASM.SymbolTable(GetConstructBlockName("else"), compileStateTracker.RuntimeTableIndex++),
                        null);

                    localCodeBlock.instrStream = codeBlock.instrStream;
                    localCodeBlock.parent = codeBlock;
                    codeBlock.children.Add(localCodeBlock);
                    codeBlock = localCodeBlock;
                    compileStateTracker.CompleteCodeBlockList.Add(localCodeBlock);
                    EmitPushBlockID(localCodeBlock.codeBlockId);
                    foreach (ImperativeNode elseBody in ifnode.ElseBody)
                    {
                        inferedType = new ProtoCore.Type();
                        inferedType.UID = (int)PrimitiveType.kTypeVar;
                        DfsTraverse(elseBody, ref inferedType, false, graphNode, AssociativeSubCompilePass.kNone, parentNode);
                    }

                    if (!isForInlineCondition)
                    {
                        ProtoCore.AST.Node oldBlockNode = localCodeBlockNode;
                        localCodeBlockNode = ifnode.ElseBodyPosition;
                        EmitInstrConsole(ProtoCore.DSASM.kw.retcn);
                        EmitRetcn(localCodeBlock.codeBlockId);
                        localCodeBlockNode = oldBlockNode;
                    }

                    // Restore - Set the local codeblock parent to be the current codeblock
                    codeBlock = localCodeBlock.parent;

                    L1 = ProtoCore.DSASM.Constants.kInvalidIndex;
                    backpatchTable.Append(pc, L1);
                    EmitJmp(L1);
                    EmitPopBlockID();
                }

                /*
                 *
                          ->	backpatch(bpTable, pc)
                 */
                // ifstmt-exit
                // Backpatch all the previous unconditional jumps
                Backpatch(backpatchTable.backpatchList, pc);
            }
        }
Exemple #10
0
        private void EmitFunctionDefinitionNode(ImperativeNode node, ref ProtoCore.Type inferedType)
        {
            bool parseGlobalFunctionSig = null == localProcedure && ProtoCore.DSASM.ImperativeCompilePass.kGlobalFuncSig == compilePass;
            bool parseGlobalFunctionBody = null == localProcedure && ProtoCore.DSASM.ImperativeCompilePass.kGlobalFuncBody == compilePass;

            FunctionDefinitionNode funcDef = node as FunctionDefinitionNode;
            localFunctionDefNode = funcDef;

            ProtoCore.DSASM.CodeBlockType originalBlockType = codeBlock.blockType;
            codeBlock.blockType = ProtoCore.DSASM.CodeBlockType.kFunction;
            if (parseGlobalFunctionSig)
            {
                Debug.Assert(null == localProcedure);

                // TODO jun: Add semantics for checking overloads (different parameter types)
                localProcedure = new ProtoCore.DSASM.ProcedureNode();
                localProcedure.name = funcDef.Name;
                localProcedure.pc = pc;
                localProcedure.localCount = funcDef.localVars;
                localProcedure.returntype.UID = compileStateTracker.TypeSystem.GetType(funcDef.ReturnType.Name);
                if (localProcedure.returntype.UID == (int)PrimitiveType.kInvalidType)
                {
                    string message = String.Format(ProtoCore.BuildData.WarningMessage.kReturnTypeUndefined, funcDef.ReturnType.Name, funcDef.Name);
                    buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kTypeUndefined, message, null, funcDef.line, funcDef.col);
                    localProcedure.returntype.UID = (int)PrimitiveType.kTypeVar;
                }
                localProcedure.returntype.IsIndexable = funcDef.ReturnType.IsIndexable;
                localProcedure.returntype.rank = funcDef.ReturnType.rank;
                localProcedure.runtimeIndex = codeBlock.codeBlockId;
                globalProcIndex = codeBlock.procedureTable.Append(localProcedure);
                compileStateTracker.ProcNode = localProcedure;

                // Append arg symbols
                if (null != funcDef.Signature)
                {
                    foreach (VarDeclNode argNode in funcDef.Signature.Arguments)
                    {
                        IdentifierNode paramNode = null;
                        bool aIsDefault = false;
                        ProtoCore.AST.Node aDefaultExpression = null;
                        if (argNode.NameNode is IdentifierNode)
                        {
                            paramNode = argNode.NameNode as IdentifierNode;
                        }
                        else if (argNode.NameNode is BinaryExpressionNode)
                        {
                            BinaryExpressionNode bNode = argNode.NameNode as BinaryExpressionNode;
                            paramNode = bNode.LeftNode as IdentifierNode;
                            aIsDefault = true;
                            aDefaultExpression = bNode;
                            //buildStatus.LogSemanticError("Defualt parameters are not supported");
                            //throw new BuildHaltException();
                        }
                        else
                        {
                            Debug.Assert(false, "Check generated AST");
                        }

                        ProtoCore.Type argType = BuildArgumentTypeFromVarDeclNode(argNode);
                        int symbolIndex = AllocateArg(paramNode.Value, localProcedure.procId, argType);
                        if (ProtoCore.DSASM.Constants.kInvalidIndex == symbolIndex)
                        {
                            throw new BuildHaltException("26384684");
                        }

                        localProcedure.argTypeList.Add(argType);
                        ProtoCore.DSASM.ArgumentInfo argInfo = new ProtoCore.DSASM.ArgumentInfo { isDefault = aIsDefault, defaultExpression = aDefaultExpression };
                        localProcedure.argInfoList.Add(argInfo);
                    }
                }

                // TODO Jun: Remove this once agree that alltest cases assume the default assoc block is block 0
                // NOTE: Only affects mirror, not actual execution
                if (null == codeBlock.parent && pc <= 0)
                {
                    // The first node in the top level block is a function
                    compileStateTracker.DSExecutable.isSingleAssocBlock = false;
                }
            #if ENABLE_EXCEPTION_HANDLING
                core.ExceptionHandlingManager.Register(codeBlock.codeBlockId, globalProcIndex, globalClassIndex);
            #endif
            }
            else if (parseGlobalFunctionBody)
            {
                EmitCompileLogFunctionStart(GetFunctionSignatureString(funcDef.Name, funcDef.ReturnType, funcDef.Signature));

                // Build arglist for comparison
                List<ProtoCore.Type> argList = new List<ProtoCore.Type>();
                if (null != funcDef.Signature)
                {
                    foreach (VarDeclNode argNode in funcDef.Signature.Arguments)
                    {
                        ProtoCore.Type argType = BuildArgumentTypeFromVarDeclNode(argNode);
                        argList.Add(argType);
                    }
                }

                // Get the exisitng procedure that was added on the previous pass
                globalProcIndex = codeBlock.procedureTable.IndexOfExact(funcDef.Name, argList);
                localProcedure = codeBlock.procedureTable.procList[globalProcIndex];

                Debug.Assert(null != localProcedure);
                localProcedure.Attributes = PopulateAttributes(funcDef.Attributes);
                // Its only on the parse body pass where the real pc is determined. Update this procedures' pc
                //Debug.Assert(ProtoCore.DSASM.Constants.kInvalidIndex == localProcedure.pc);
                localProcedure.pc = pc;

                // Copy the active function to the core so nested language blocks can refer to it
                compileStateTracker.ProcNode = localProcedure;

                // Arguments have been allocated, update the baseOffset
                localProcedure.localCount = compileStateTracker.BaseOffset;

                ProtoCore.FunctionEndPoint fep = null;

                //Traverse default argument
                emitDebugInfo = false;
                foreach (ProtoCore.DSASM.ArgumentInfo argNode in localProcedure.argInfoList)
                {
                    if (!argNode.isDefault)
                    {
                        continue;
                    }
                    BinaryExpressionNode bNode = argNode.defaultExpression as BinaryExpressionNode;

                    // build a temporay node for statement : temp = defaultarg;
                    var iNodeTemp = nodeBuilder.BuildIdentfier(Constants.kTempDefaultArg);
                    BinaryExpressionNode bNodeTemp = nodeBuilder.BuildBinaryExpression(iNodeTemp, bNode.LeftNode) as BinaryExpressionNode;
                    EmitBinaryExpressionNode(bNodeTemp, ref inferedType);

                    //duild an inline conditional node for statement: defaultarg = (temp == DefaultArgNode) ? defaultValue : temp;
                    InlineConditionalNode icNode = new InlineConditionalNode();
                    icNode.ConditionExpression = nodeBuilder.BuildBinaryExpression(iNodeTemp, new DefaultArgNode(), Operator.eq);
                    icNode.TrueExpression = bNode.RightNode;
                    icNode.FalseExpression = iNodeTemp;
                    bNodeTemp.LeftNode = bNode.LeftNode;
                    bNodeTemp.RightNode = icNode;
                    EmitBinaryExpressionNode(bNodeTemp, ref inferedType);
                }
                emitDebugInfo = true;

                // Traverse definition
                bool hasReturnStatement = false;
                foreach (ImperativeNode bnode in funcDef.FunctionBody.Body)
                {
                    DfsTraverse(bnode, ref inferedType);
                    if (ProtoCore.Utils.NodeUtils.IsReturnExpressionNode(bnode))
                    {
                        hasReturnStatement = true;
                    }

                    if (bnode is FunctionCallNode)
                    {
                        EmitSetExpressionUID(compileStateTracker.ExpressionUID++);
                    }
                }

                // All locals have been stack allocated, update the local count of this function
                localProcedure.localCount = compileStateTracker.BaseOffset;

                // Update the param stack indices of this function
                foreach (ProtoCore.DSASM.SymbolNode symnode in codeBlock.symbolTable.symbolList.Values)
                {
                    if (symnode.functionIndex == localProcedure.procId && symnode.isArgument)
                    {
                        symnode.index -= localProcedure.localCount;
                    }
                }

                ProtoCore.Lang.JILActivationRecord record = new ProtoCore.Lang.JILActivationRecord();
                record.pc = localProcedure.pc;
                record.locals = localProcedure.localCount;
                record.classIndex = ProtoCore.DSASM.Constants.kInvalidIndex;
                record.funcIndex = localProcedure.procId;
                fep = new ProtoCore.Lang.JILFunctionEndPoint(record);

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

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

                if (!hasReturnStatement)
                {
                    if (!compileStateTracker.Options.SuppressFunctionResolutionWarning)
                    {
                        string message = String.Format(ProtoCore.BuildData.WarningMessage.kFunctionNotReturnAtAllCodePaths, localProcedure.name);
                        compileStateTracker.BuildStatus.LogWarning(ProtoCore.BuildData.WarningID.kMissingReturnStatement, message, compileStateTracker.CurrentDSFileName, funcDef.line, funcDef.col);
                    }

                    EmitReturnNull();
                }

                EmitCompileLogFunctionEnd();
                //Fuqiang: return is already done in traversing the function body
                //// function return
                //EmitInstrConsole(ProtoCore.DSASM.kw.ret);
                //EmitReturn();
            }

            compileStateTracker.ProcNode = localProcedure = null;
            globalProcIndex = ProtoCore.DSASM.Constants.kGlobalScope;
            argOffset = 0;
            compileStateTracker.BaseOffset = 0;
            codeBlock.blockType = originalBlockType;
            localFunctionDefNode = null;
        }
Exemple #11
0
 public UnaryExpressionNode(UnaryExpressionNode rhs) : base(rhs)
 {
     Operator   = rhs.Operator;
     Expression = ProtoCore.Utils.NodeUtils.Clone(rhs.Expression);
 }
Exemple #12
0
 private void EmitClassDeclNode(ImperativeNode node)
 {
     throw new NotImplementedException();
 }
        // this method is used in conjuction with array indexing
        private void DfsEmitArrayIndex(ImperativeNode node, int symbolindex, int index = 0)
        {
            // s = b + ((i * i.w) + (j * j.w) + (n * n.w))

            if (node is ArrayNode)
            {
                ArrayNode array = node as ArrayNode;

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

                DfsTraverse(array.Expr, ref type);

                // Max size of the current dimension
                int w = codeBlock.symbolTable.symbolList[symbolindex].arraySizeList[index];

                // TODO Jun: Performance improvement
                // Avoid having to generate instructions for the current index if 'w' is 0

                if (array.Type is ArrayNode)
                {
                    DfsEmitArrayIndex(array.Type, symbolindex, index + 1);
                }
            }
            else
            {
                Debug.Assert(false, "ast error – check ast construction");
            }
        }
Exemple #14
0
 public BinaryExpressionNode(BinaryExpressionNode rhs) : base(rhs)
 {
     Optr      = rhs.Optr;
     LeftNode  = rhs.LeftNode == null ? null : ProtoCore.Utils.NodeUtils.Clone(rhs.LeftNode);
     RightNode = rhs.RightNode == null ? null : ProtoCore.Utils.NodeUtils.Clone(rhs.RightNode);
 }
Exemple #15
0
 public BinaryExpressionNode(ImperativeNode left = null, ImperativeNode right = null, ProtoCore.DSASM.Operator optr = DSASM.Operator.none)
 {
     LeftNode  = left;
     Optr      = optr;
     RightNode = right;
 }
Exemple #16
0
 public ImperativeNode(ImperativeNode rhs) : base(rhs)
 {
 }
Exemple #17
0
 public IdentifierListNode(IdentifierListNode rhs) : base(rhs)
 {
     Optr      = rhs.Optr;
     LeftNode  = ProtoCore.Utils.NodeUtils.Clone(rhs.LeftNode);
     RightNode = ProtoCore.Utils.NodeUtils.Clone(rhs.RightNode);
 }
Exemple #18
0
 public ImperativeNode BuildIdentList(ImperativeNode leftNode, ImperativeNode rightNode)
 {
     var identList = new IdentifierListNode();
     identList.LeftNode = leftNode;
     identList.RightNode = rightNode;
     identList.Optr = ProtoCore.DSASM.Operator.dot;
     return identList;
 }
        private void DfsEmitArraySize(ImperativeNode node)
        {
            // s = size * ( i * j * k..n )
            if (node is ArrayNode)
            {
                ArrayNode array = node as ArrayNode;

                ProtoCore.Type type = new ProtoCore.Type();
                type.UID = (int)ProtoCore.PrimitiveType.kInvalidType;
                type.IsIndexable = false;
                DfsTraverse(array.Expr, ref type);

                if (array.Type is ArrayNode)
                {
                    DfsEmitArraySize(array.Type);
                }
            }
            else
            {
                Debug.Assert(false, "ast error – check ast construction");
            }
        }
Exemple #20
0
        private void EmitForLoopNode(ImperativeNode node, ref ProtoCore.Type inferredType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            if (IsParsingGlobal() || IsParsingGlobalFunctionBody())
            {
                /*
                x = 0;
                a = {10,20,30,40}
                for(val in a)
                {
                    x = x + val;
                }

                Compiles down to:

                x = 0;
                a = {10,20,30,40};
                val = null;
                __autogen_count = 0;
                __autogen_iterations = a.size;
                while( __autogen_count < __autogen_iterations)
                {
                    val = a[__autogen_count];
                    __autogen_count = __autogen_count + 1;
                    x = x + val;
                }
                */

                DebugProperties.BreakpointOptions oldOptions = compileStateTracker.DebugProps.breakOptions;
                DebugProperties.BreakpointOptions newOptions = oldOptions;
                newOptions |= DebugProperties.BreakpointOptions.EmitCallrForTempBreakpoint;
                compileStateTracker.DebugProps.breakOptions = newOptions;

                // TODO Jun: This compilation unit has many opportunities for optimization
                //      1. Compiling to while need not be necessary if 'expr' has exactly one element
                //      2. For-loop can have its own semantics without the need to convert to a while node

                ForLoopNode forNode = node as ForLoopNode;
                ++forloopCounter;   //new forloop beginning. increment loop counter

                // Generate the expression for ‘id’ initialized to null
                BinaryExpressionNode forIdentInit = new BinaryExpressionNode();
                forIdentInit.Optr = ProtoCore.DSASM.Operator.assign;
                IdentifierNode forIdent = nodeBuilder.BuildIdentfier(forNode.loopVar.Name) as IdentifierNode;
                forIdent.ArrayName = forNode.expression.Name;
                //IdentifierNode forLoopArrayIdent = nodeBuilder.BuildIdentfier(forNode.expression.Name) as IdentifierNode;
                ProtoCore.Utils.NodeUtils.CopyNodeLocation(forIdent, forNode.loopVar);

                forIdentInit.LeftNode = forIdent;
                forIdentInit.RightNode = new NullNode();

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

                ProtoCore.Utils.NodeUtils.CopyNodeLocation(forIdentInit, forNode);
                forIdentInit.endLine = forIdentInit.line;
                forIdentInit.endCol = forIdentInit.col + 3;
                EmitBinaryExpressionNode(forIdentInit, ref type, isBooleanOp, graphNode);

                // Generate the expression for autogen counter initialized to 0
                string forCountIdent = GetForCountIdent();
                var nodeCounter = nodeBuilder.BuildIdentfier(forCountIdent);
                BinaryExpressionNode forcounterExpr = new BinaryExpressionNode();
                forcounterExpr.Optr = ProtoCore.DSASM.Operator.assign;
                forcounterExpr.LeftNode = nodeCounter;
                forcounterExpr.RightNode = new IntNode { value = "0" };

                type.UID = (int)ProtoCore.PrimitiveType.kTypeVoid;
                EmitBinaryExpressionNode(forcounterExpr, ref type, isBooleanOp, graphNode);

                // Generate the expression for autogen iterations initialized to 0
                string forIterCountVar = GetForIterationVar();
                var nodeIterCount = nodeBuilder.BuildIdentfier(forIterCountVar);

                BinaryExpressionNode forIterations = new BinaryExpressionNode();
                forIterations.Optr = ProtoCore.DSASM.Operator.assign;
                forIterations.LeftNode = nodeIterCount;
                forIterations.RightNode = new IntNode { value = "0" };

                type.UID = (int)ProtoCore.PrimitiveType.kTypeVoid;
                EmitBinaryExpressionNode(forIterations, ref type, isBooleanOp, graphNode);

                // Generate the expression for autogen iteration count assigned to the size of ‘expr’

                // Create a temp array variable if 'expr' is an array
                string identName = GetForExprIdent();
                var exprIdent = nodeBuilder.BuildIdentfier(identName);
                NodeUtils.CopyNodeLocation(exprIdent, forNode.expression);

                BinaryExpressionNode arrayexprAssignment = new BinaryExpressionNode();
                arrayexprAssignment.Optr = ProtoCore.DSASM.Operator.assign;
                arrayexprAssignment.LeftNode = exprIdent;
                arrayexprAssignment.RightNode = forNode.expression;
                NodeUtils.UpdateBinaryExpressionLocation(arrayexprAssignment);

                bool shouldBreakOnTemporary = false;
                switch (forNode.expression.GetType().ToString())
                {
                    case "ProtoCore.AST.ImperativeAST.IdentifierNode":
                    case "ProtoCore.AST.ImperativeAST.ExprListNode":
                        shouldBreakOnTemporary = true;
                        break;
                }

                if (false == shouldBreakOnTemporary)
                {
                    type.UID = (int)ProtoCore.PrimitiveType.kTypeVoid;
                    EmitBinaryExpressionNode(arrayexprAssignment, ref type, isBooleanOp, graphNode);
                }
                else
                {
                    newOptions |= DebugProperties.BreakpointOptions.EmitPopForTempBreakpoint;
                    compileStateTracker.DebugProps.breakOptions = newOptions;

                    type.UID = (int)ProtoCore.PrimitiveType.kTypeVoid;
                    EmitBinaryExpressionNode(arrayexprAssignment, ref type, isBooleanOp, graphNode);
                }
                compileStateTracker.DebugProps.breakOptions = oldOptions; // Restore breakpoint behaviors.

                // Comment Jun: Compile such that the the forloop 'expr' is always assumed to be an array
                // If it was passed a singleton, the runtime will handle it accordingly

                ////if ((int)PrimitiveType.kTypeArray != type)
                //if (false)
                //{

                //    // 'expr' is not an array so it can be assigned directly to 'id'
                //    BinaryExpressionNode exprToIdent = new BinaryExpressionNode();
                //    exprToIdent.Optr = ProtoCore.DSASM.Operator.assign;
                //    exprToIdent.LeftNode = forIdent;
                //    exprToIdent.RightNode = forNode.expression;

                //    forNode.body.Insert(0, exprToIdent);

                //    // There is no loop since 'expr' is a single element. Traverse the for loop body directly
                //    type = (int)ProtoCore.PrimitiveType.kTypeVoid;
                //    if (null != forNode.body)
                //    {
                //        foreach (ImperativeNode bodyNode in forNode.body)
                //        {
                //            DfsTraverse(bodyNode, ref type);
                //        }
                //    }
                //}
                //else
                //{
                // 'expr' is an array

                // Get the size of expr and assign it to the autogen iteration var

                int symbolIndex = Constants.kInvalidIndex;
                SymbolNode symbol = null;
                if (ProtoCore.DSASM.Constants.kInvalidIndex != globalClassIndex && !IsInLanguageBlockDefinedInFunction())
                {
                    symbolIndex = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].symbols.IndexOf(identName);
                    if (symbolIndex != Constants.kInvalidIndex)
                    {
                        symbol = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].symbols.symbolList[symbolIndex];
                    }
                }
                else
                {
                    symbolIndex = codeBlock.symbolTable.IndexOf(identName);
                    if (symbolIndex != Constants.kInvalidIndex)
                    {
                        symbol = codeBlock.symbolTable.symbolList[symbolIndex];
                    }
                }

                EmitInstrConsole(ProtoCore.DSASM.kw.pushvarsize, identName);
                EmitPushVarSize(symbolIndex, codeBlock.symbolTable.runtimeIndex, (symbol == null) ? globalClassIndex : symbol.classScope);

                // Push the identifier local block information
                // Push the array dimensions
                int dimensions = 0;
                EmitPushVarData(codeBlock.symbolTable.runtimeIndex, dimensions);

                ProtoCore.DSASM.StackValue opDest = new ProtoCore.DSASM.StackValue();
                opDest.optype = ProtoCore.DSASM.AddressType.VarIndex;
                if (ProtoCore.DSASM.Constants.kInvalidIndex != globalClassIndex && !IsInLanguageBlockDefinedInFunction())
                {
                    symbolIndex = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].symbols.IndexOf(forIterCountVar);
                    if (symbolIndex != Constants.kInvalidIndex)
                    {
                        symbol = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].symbols.symbolList[symbolIndex];
                    }
                }
                else
                {
                    symbolIndex = codeBlock.symbolTable.IndexOf(forIterCountVar);
                    if (symbolIndex != Constants.kInvalidIndex)
                    {
                        symbol = codeBlock.symbolTable.symbolList[symbolIndex];
                    }
                }
                opDest.opdata = symbolIndex;
                EmitInstrConsole(ProtoCore.DSASM.kw.pop, forIterCountVar);
                EmitPop(opDest, (symbol == null) ? globalClassIndex : symbol.classScope);

                // Generate the comparison expression between the autogen counter and the autogen iteration count
                BinaryExpressionNode iterCondition = new BinaryExpressionNode();
                iterCondition.Optr = ProtoCore.DSASM.Operator.lt;
                iterCondition.LeftNode = nodeCounter;
                iterCondition.RightNode = nodeIterCount;

                iterCondition.line = forNode.KwInLine;
                iterCondition.col = forNode.KwInCol;
                iterCondition.endLine = forNode.KwInLine;
                iterCondition.endCol = forNode.KwInCol + 2; // 2 character for keyword "in".

                // Generate the assignment statement from where lhs is ‘id’ and rhs is ‘expr’ indexed into the autogen count
                BinaryExpressionNode IndexedExprToId = new BinaryExpressionNode();
                IndexedExprToId.Optr = ProtoCore.DSASM.Operator.assign;
                IndexedExprToId.LeftNode = forIdent;

                // Array index into the expr ident
                ArrayNode arrayIndex = new ArrayNode();
                arrayIndex.Expr = nodeCounter;
                arrayIndex.Type = null;
                (exprIdent as IdentifierNode).ArrayDimensions = arrayIndex;

                IndexedExprToId.RightNode = exprIdent;

                IndexedExprToId.line = forIdent.line;
                IndexedExprToId.col = forIdent.col;
                IndexedExprToId.endLine = forIdent.endLine;
                IndexedExprToId.endCol = forIdent.endCol;

                // Generate the expression for increment by 1 of the autogen count
                var countIncrement = nodeBuilder.BuildBinaryExpression(nodeCounter, new IntNode { value = "1" }, Operator.add);
                var countIncrementAssign = nodeBuilder.BuildBinaryExpression(nodeCounter, countIncrement);

                // Append the array indexing and increment expressions into the for-loop body
                forNode.body.Insert(0, IndexedExprToId);
                forNode.body.Insert(1, countIncrementAssign);

                // Construct and populate the equivalent while node
                WhileStmtNode whileNode = new WhileStmtNode();
                whileNode.Expr = iterCondition;
                whileNode.Body = forNode.body;
                whileNode.endLine = node.endLine;
                whileNode.endCol = node.endCol;

                type.UID = (int)ProtoCore.PrimitiveType.kTypeVoid;
                EmitWhileStmtNode(whileNode, ref type, isBooleanOp, graphNode);
                //}

                // Comment Jun: The for loop counter must be unique and does not need to reset
                //forloopCounter--;   //for loop ended. decrement counter
            }
        }
Exemple #21
0
 private void EmitConstructorDefinitionNode(ImperativeNode node)
 {
     throw new NotImplementedException();
 }
        private void EmitBinaryExpressionNode(ImperativeNode node, ref ProtoCore.Type inferedType, bool isBooleanOp = false)
        {
            if (!IsParsingGlobal() && !IsParsingGlobalFunctionBody())
                return;

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

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

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

            if (ProtoCore.DSASM.Operator.assign != b.Optr)
            {
                isBooleanOperation = ProtoCore.DSASM.Operator.lt == b.Optr
                    || ProtoCore.DSASM.Operator.gt == b.Optr
                    || ProtoCore.DSASM.Operator.le == b.Optr
                    || ProtoCore.DSASM.Operator.ge == b.Optr
                    || ProtoCore.DSASM.Operator.eq == b.Optr
                    || ProtoCore.DSASM.Operator.nq == b.Optr
                    || ProtoCore.DSASM.Operator.and == b.Optr
                    || ProtoCore.DSASM.Operator.or == b.Optr;

                DfsTraverse(b.LeftNode, ref inferedType, isBooleanOperation);

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

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

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

            BinaryExpressionNode rightNode = b.RightNode as BinaryExpressionNode;
            if ((rightNode != null) && (ProtoCore.DSASM.Operator.assign == rightNode.Optr))
                DfsTraverse(rightNode.LeftNode, ref inferedType);

            if (b.Optr != ProtoCore.DSASM.Operator.assign)
            {
                isBooleanOp = false;

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

            if (b.LeftNode is IdentifierNode)
            {
                IdentifierNode t = b.LeftNode as IdentifierNode;
                ProtoCore.DSASM.SymbolNode symbolnode = null;

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

                    bool isAccessible = false;
                    bool isAllocated = VerifyAllocation(t.Value, globalClassIndex, out symbolnode, out isAccessible);
                    int runtimeIndex = (!isAllocated) ? codeBlock.symbolTable.runtimeIndex : symbolnode.runtimeTableIndex;

                    // TODO Jun: Update mechanism work in progress - a flag to manually enable update
                    bool enableUpdate = false;
                    if (enableUpdate)
                    {
                        bool isExternal = false; // isAllocated && currentLangBlock != codeBlockId;
                        //bool isAssociative = ProtoCore.Language.kAssociative == core.exeList[currentLangBlock].language;
                        bool isAssociative = false;
                        if (isExternal && isAssociative)
                        {
                            // Check if this is a modifier variable
                            bool isVariableAModifierStack = false;
                            if (isVariableAModifierStack)
                            {
                                // Check if modifying a named modifier state
                                bool isNameModifierState = false;
                                if (isNameModifierState)
                                {
                                    //bool isStateIntermediate = false;

                                }
                                else
                                {

                                }
                                //targetLangBlock = blockId;
                            }
                        }
                    }

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

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

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

                    if (globalClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex)
                    {
                        int symbol = ProtoCore.DSASM.Constants.kInvalidIndex;

                        for (int n = 0; n < compileState.ClassTable.ClassNodes[globalClassIndex].symbols.symbolList.Count; ++n)
                        {
                            //Fuqiang: Not a member variable if it is a local variable inside a function with the same name
                            bool localVarInMemFunc = false;
                            if (localProcedure != null)
                            {
                                if (symbolnode == null)
                                {
                                    if (!isAllocated) // if isAllocated, inaccessible member variable
                                    {
                                        localVarInMemFunc = true;
                                    }
                                }
                                else if (symbolnode.functionIndex != ProtoCore.DSASM.Constants.kGlobalScope && !localProcedure.isConstructor)
                                {
                                    localVarInMemFunc = true;
                                }
                            }
                            bool isMemberVar = ProtoCore.DSASM.Constants.kGlobalScope == compileState.ClassTable.ClassNodes[globalClassIndex].symbols.symbolList[n].functionIndex
                                && compileState.ClassTable.ClassNodes[globalClassIndex].symbols.symbolList[n].name == t.Name
                                && !localVarInMemFunc;
                            if (isMemberVar)
                            {
                                symbol = n;
                                break;
                            }
                        }

                        if (symbol == ProtoCore.DSASM.Constants.kInvalidIndex)
                        {
                            if (!isAllocated)
                            {
                                symbolnode = Allocate(t.Name, globalProcIndex, inferedType);
                                IdentLocation.AddEntry(symbolnode, t.line, t.col, compileState.CurrentDSFileName);
                            }

                            symbol = symbolnode.symbolTableIndex;
                        }

                        if (b.LeftNode is TypedIdentifierNode)
                        {
                            symbolnode.SetStaticType(castType);
                        }
                    }
                    else
                    {
                        if (0 == dimensions)
                        {
                            if (!isAllocated)
                            {
                                symbolnode = Allocate(t.Value, globalProcIndex, inferedType);
                                IdentLocation.AddEntry(symbolnode, t.line, t.col, compileState.CurrentDSFileName);
                            }
                            else
                            {
                                if (compileState.TypeSystem.IsHigherRank(inferedType.UID, symbolnode.datatype.UID))
                                {
                                    symbolnode.datatype = inferedType;
                                }
                            }

                            if (b.LeftNode is TypedIdentifierNode)
                            {
                                symbolnode.SetStaticType(castType);
                            }
                        }
                    }
                }
            }
            else if (b.LeftNode is IdentifierListNode)
            {
                int depth = 0;

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

                bool isFirstIdent = false;
                bool isIdentReference = DfsEmitIdentList(b.LeftNode, b, globalClassIndex, ref lastType, ref depth, ref inferedType, true, ref isFirstIdent);
                inferedType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : inferedType.UID;
            }

            //if post fix, now traverse the post fix
            #if ENABLE_INC_DEC_FIX
                if (b.RightNode is PostFixNode)
                    EmitPostFixNode(b.RightNode, ref inferedType);
            #endif
        }
Exemple #23
0
        private void EmitFunctionCallNode(ImperativeNode node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.AST.ImperativeAST.BinaryExpressionNode bnode = null)
        {
            FunctionCallNode fnode = node as FunctionCallNode;

            ProtoCore.DSASM.ProcedureNode procNode = TraverseFunctionCall(node, null, ProtoCore.DSASM.Constants.kInvalidIndex, 0, ref inferedType, graphNode, AssociativeSubCompilePass.kNone, bnode);
            if (fnode != null && fnode.ArrayDimensions != null)
            {
                int dimensions = DfsEmitArrayIndexHeap(fnode.ArrayDimensions);
                EmitInstrConsole(ProtoCore.DSASM.kw.pushindex, dimensions.ToString() + "[dim]");
                EmitPushArrayIndex(dimensions);
                fnode.ArrayDimensions = null;
            }

            if(bnode == null)
                EmitSetExpressionUID(compileStateTracker.ExpressionUID++);
        }
Exemple #24
0
        private ProtoCore.DSASM.SymbolNode Allocate( 
            string ident,
            int funcIndex,
            ProtoCore.Type datatype,
            int size = 1,
            int datasize = ProtoCore.DSASM.Constants.kPrimitiveSize,
            ImperativeNode nodeArray = null,
            ProtoCore.DSASM.MemoryRegion region = ProtoCore.DSASM.MemoryRegion.kMemStack)
        {
            if (compileStateTracker.ClassTable.IndexOf(ident) != ProtoCore.DSASM.Constants.kInvalidIndex)
                buildStatus.LogSemanticError(ident + " is a class name, can't be used as a variable.");

            ProtoCore.DSASM.SymbolNode symbolnode = new ProtoCore.DSASM.SymbolNode(
                ident,
                ProtoCore.DSASM.Constants.kInvalidIndex,
                ProtoCore.DSASM.Constants.kInvalidIndex,
                funcIndex,
                datatype,
                compileStateTracker.TypeSystem.BuildTypeObject((int)PrimitiveType.kTypeVar, false),
                size,
                datasize,
                false,
                codeBlock.symbolTable.runtimeIndex,
                region,
                false,
                null,
                globalClassIndex,
                ProtoCore.DSASM.AccessSpecifier.kPublic,
                false,
                codeBlock.codeBlockId);

            if (this.isEmittingImportNode)
                symbolnode.ExternLib = compileStateTracker.CurrentDSFileName;

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

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

            // This is to handle that a variable is defined in a language
            // block which defined in a function, so the variable's scope
            // is that language block instead of function
            if (IsInLanguageBlockDefinedInFunction())
            {
                symbolnode.classScope = Constants.kGlobalScope;
                symbolnode.functionIndex = Constants.kGlobalScope;
            }

            int symbolindex = ProtoCore.DSASM.Constants.kInvalidIndex;
            if (ProtoCore.DSASM.Constants.kInvalidIndex != globalClassIndex && !IsInLanguageBlockDefinedInFunction())
            {

                symbolindex = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].symbols.Append(symbolnode);
            }
            else
            {
                // Do not import global symbols from external libraries
                //if (this.isEmittingImportNode && core.IsParsingPreloadedAssembly)
                //{
                //    bool importGlobalSymbolFromLib = !string.IsNullOrEmpty(symbolnode.ExternLib) &&
                //        symbolnode.functionIndex == -1 && symbolnode.classScope == -1;

                //    if (importGlobalSymbolFromLib)
                //    {
                //        return symbolnode;
                //    }
                //}

                symbolindex = codeBlock.symbolTable.Append(symbolnode);
            }

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

            if (ProtoCore.DSASM.MemoryRegion.kMemHeap == symbolnode.memregion)
            {
                EmitInstrConsole(ProtoCore.DSASM.kw.alloca, symbolindex.ToString());
                EmitAlloc(symbolindex);
            }

            symbolnode.symbolTableIndex = symbolindex;
            return symbolnode;
        }
Exemple #25
0
        private void EmitIdentifierNode(ImperativeNode node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            IdentifierNode t = node as IdentifierNode;
            if (t.Name.Equals(ProtoCore.DSDefinitions.Kw.kw_this))
            {
                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();
                        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;

            int runtimeIndex = codeBlock.symbolTable.runtimeIndex;

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

            ProtoCore.DSASM.SymbolNode symbolnode = null;
            //bool isAllocated = VerifyAllocation(t.Value, out blockId, out localAllocBlock, out symindex, ref type);
            //bool allocatedLocally = isAllocated && core.runtimeTableIndex == localAllocBlock;
            //bool allocatedExternally = isAllocated && core.runtimeTableIndex > localAllocBlock;
            //bool isVisible = isAllocated && core.runtimeTableIndex >= localAllocBlock;
            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;

                        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.Value, globalClassIndex, globalProcIndex, out symbolnode, out isAccessible);
            if (!isAllocated || !isAccessible)
            {
                if (isAllocated)
                {
                    if (!isAccessible)
                    {
                        string message = String.Format(ProtoCore.BuildData.WarningMessage.kPropertyIsInaccessible, t.Value);
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kAccessViolation, message, compileStateTracker.CurrentDSFileName, t.line, t.col);
                    }
                }
                else
                {
                    string message = String.Format(ProtoCore.BuildData.WarningMessage.kUnboundIdentifierMsg, t.Value);
                    buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kIdUnboundIdentifier, message, compileStateTracker.CurrentDSFileName, t.line, t.col);
                }

                inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeNull;

                // Jun Comment: Specification excerpt
                //      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)

                EmitPushNull();

                EmitPushVarData(runtimeIndex, dimensions);

                ProtoCore.Type varType = compileStateTracker.TypeSystem.BuildTypeObject((int)PrimitiveType.kTypeVar, false, 0);
                symbolnode = Allocate(t.Value, globalProcIndex, varType);

                EmitInstrConsole(ProtoCore.DSASM.kw.pop, t.Value);
                EmitPopForSymbol(symbolnode);
            }
            else
            {
                type = symbolnode.datatype;
                runtimeIndex = symbolnode.runtimeTableIndex;

                if (compileStateTracker.Options.AssociativeToImperativePropagation)
                {
                    // Comment Jun: If this symbol belongs to an outer block, then append it to this language blocks dependent
                    if (symbolnode.codeBlockId != codeBlock.codeBlockId)
                    {
                        // A parent codeblock owns this symbol
                        if (null != graphNode)
                        {
                            ProtoCore.AssociativeGraph.GraphNode dependentNode = new ProtoCore.AssociativeGraph.GraphNode();
                            dependentNode.PushSymbolReference(symbolnode);
                            graphNode.PushDependent(dependentNode);
                        }
                    }
                }
            }

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

            //fix type's rank
            //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);

            EmitInstrConsole(ProtoCore.DSASM.kw.push, t.Value);
            EmitPushForSymbol(symbolnode, t);

            if (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 : type.UID;
        }
Exemple #26
0
        private int AllocateArg(
            string ident,
            int funcIndex,
            ProtoCore.Type datatype,
            int size = 1,
            int datasize = ProtoCore.DSASM.Constants.kPrimitiveSize,
            ImperativeNode nodeArray = null,
            ProtoCore.DSASM.MemoryRegion region = ProtoCore.DSASM.MemoryRegion.kMemStack)
        {
            ProtoCore.DSASM.SymbolNode symbolnode = new ProtoCore.DSASM.SymbolNode(
                ident,
                ProtoCore.DSASM.Constants.kInvalidIndex,
                ProtoCore.DSASM.Constants.kInvalidIndex,
                funcIndex,
                datatype,
                datatype,
                size,
                datasize,
                true,
                codeBlock.symbolTable.runtimeIndex,
                region);
            symbolnode.codeBlockId = codeBlock.codeBlockId;
            if (this.isEmittingImportNode)
                symbolnode.ExternLib = compileStateTracker.CurrentDSFileName;

            int symbolindex = ProtoCore.DSASM.Constants.kInvalidIndex;
            if (ProtoCore.DSASM.Constants.kInvalidIndex != codeBlock.symbolTable.IndexOf(symbolnode))
            {
                buildStatus.LogSemanticError("redefinition of identifier '" + ident + "'");
            }
            else
            {
                int locOffset = localProcedure.localCount;
                locOffset = localProcedure.localCount;
                symbolnode.index = -1 - ProtoCore.DSASM.StackFrame.kStackFrameSize - (locOffset + argOffset);
                ++argOffset;

                symbolindex = codeBlock.symbolTable.Append(symbolnode);
            }
            return symbolindex;
        }
Exemple #27
0
        private void EmitInlineConditionalNode(ImperativeNode node, ref ProtoCore.Type inferedType, ProtoCore.AST.ImperativeAST.BinaryExpressionNode parentNode = null)
        {
            InlineConditionalNode inlineConNode = node as InlineConditionalNode;
            IfStmtNode ifNode = new IfStmtNode();
            ifNode.IfExprNode = inlineConNode.ConditionExpression;
            List<ImperativeNode> trueBody = new List<ImperativeNode>();
            trueBody.Add(inlineConNode.TrueExpression);
            List<ImperativeNode> falseBody = new List<ImperativeNode>();
            falseBody.Add(inlineConNode.FalseExpression);
            ifNode.IfBody = trueBody;
            ifNode.ElseBody = falseBody;

            DebugProperties.BreakpointOptions oldOptions = compileStateTracker.DebugProps.breakOptions;
            DebugProperties.BreakpointOptions newOptions = oldOptions;
            newOptions |= DebugProperties.BreakpointOptions.EmitInlineConditionalBreakpoint;
            compileStateTracker.DebugProps.breakOptions = newOptions;

            EmitIfStmtNode(ifNode, ref inferedType, parentNode, true);

            compileStateTracker.DebugProps.breakOptions = oldOptions;
        }
Exemple #28
0
        private void AllocateArray(ProtoCore.DSASM.SymbolNode symbol, ImperativeNode nodeArray)
        {
            symbol.isArray = true;

            //===================================================
            // TODO Jun:
            //  Determine which is optimal-
            //  1. Storing the array flag in the symbol, or...
            //  2. Storing the array flag as an instruction operand
            //===================================================

            // TODO Jun: allocate to the stack is the array has empty expressions
            ArrayNode array = nodeArray as ArrayNode;
            bool heapAlloc = null != array.Expr;
            symbol.memregion = heapAlloc ? ProtoCore.DSASM.MemoryRegion.kMemHeap : ProtoCore.DSASM.MemoryRegion.kMemStack;

            if (ProtoCore.DSASM.MemoryRegion.kMemStack == symbol.memregion)
            {
                symbol.arraySizeList = new List<int>();
                List<int> indexlist = new List<int>();

                // TODO Jun: Optimize this
                DfsBuildIndex(nodeArray, indexlist);
                foreach (int indexVal in indexlist)
                {
                    if (0 != indexVal)
                    {
                        symbol.size *= indexVal;
                    }
                }

                // Rebuild the array that is needed to compute the size at each index
                indexlist.RemoveAt(0);
                indexlist.Add(symbol.datasize);

                for (int n = 0; n < indexlist.Count; ++n)
                {
                    symbol.arraySizeList.Add(1);
                    for (int i = n; i < indexlist.Count; ++i)
                    {
                        symbol.arraySizeList[n] *= indexlist[i];
                    }
                }
            }
            else if (ProtoCore.DSASM.MemoryRegion.kMemHeap == symbol.memregion)
            {
                int indexCnt = DfsEmitArrayIndexHeap(nodeArray);

                EmitInstrConsole(ProtoCore.DSASM.kw.push, indexCnt.ToString());
                ProtoCore.DSASM.StackValue opSize = new ProtoCore.DSASM.StackValue();
                opSize.optype = ProtoCore.DSASM.AddressType.Int;
                opSize.opdata = indexCnt;
                EmitPush(opSize);
                SetHeapData(symbol);
            }
            else
            {
                Debug.Assert(false, "Invalid memory region");
            }
            SetStackIndex(symbol);
        }
Exemple #29
0
        private void EmitRangeExprNode(ImperativeNode node, ref ProtoCore.Type inferedType, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            RangeExprNode range = node as RangeExprNode;

            // Do some static checking...probably it is not necessary.
            // Need to move these checkings to built-in function.
            if ((range.FromNode is IntNode || range.FromNode is DoubleNode) &&
                (range.ToNode is IntNode || range.ToNode is DoubleNode) &&
                (range.StepNode == null || (range.StepNode != null && (range.StepNode is IntNode || range.StepNode is DoubleNode))))
            {
                decimal current = (range.FromNode is IntNode) ? Int64.Parse((range.FromNode as IntNode).value) : Decimal.Parse((range.FromNode as DoubleNode).value);
                decimal end = (range.ToNode is IntNode) ? Int64.Parse((range.ToNode as IntNode).value) : Decimal.Parse((range.ToNode as DoubleNode).value);
                ProtoCore.DSASM.RangeStepOperator stepoperator = range.stepoperator;

                decimal step = 1;
                if (range.StepNode != null)
                {
                    step = (range.StepNode is IntNode) ? Int64.Parse((range.StepNode as IntNode).value) : Decimal.Parse((range.StepNode as DoubleNode).value);
                }

                if (stepoperator == ProtoCore.DSASM.RangeStepOperator.stepsize)
                {
                    if (range.StepNode == null && end < current)
                    {
                        step = -1;
                    }

                    if (step == 0)
                    {
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kInvalidRangeExpression, ProtoCore.BuildData.WarningMessage.kRangeExpressionWithStepSizeZero, compileStateTracker.CurrentDSFileName, range.StepNode.line, range.StepNode.col);
                        EmitNullNode(new NullNode(), ref inferedType);
                        return;
                    }
                    if ((end > current && step < 0) || (end < current && step > 0))
                    {
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kInvalidRangeExpression, ProtoCore.BuildData.WarningMessage.kRangeExpressionWithInvalidStepSize, compileStateTracker.CurrentDSFileName, range.StepNode.line, range.StepNode.col);
                        EmitNullNode(new NullNode(), ref inferedType);
                        return;
                    }
                }
                else if (stepoperator == ProtoCore.DSASM.RangeStepOperator.num)
                {
                    if (range.StepNode != null && !(range.StepNode is IntNode))
                    {
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kInvalidRangeExpression, ProtoCore.BuildData.WarningMessage.kRangeExpressionWithNonIntegerStepNumber, compileStateTracker.CurrentDSFileName, range.StepNode.line, range.StepNode.col);
                        EmitNullNode(new NullNode(), ref inferedType);
                        return;
                    }

                    if (step <= 0)
                    {
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kInvalidRangeExpression, ProtoCore.BuildData.WarningMessage.kRangeExpressionWithNegativeStepNumber, compileStateTracker.CurrentDSFileName, range.StepNode.line, range.StepNode.col);
                        EmitNullNode(new NullNode(), ref inferedType);
                        return;
                    }
                }
                else if (stepoperator == ProtoCore.DSASM.RangeStepOperator.approxsize)
                {
                    if (step == 0)
                    {
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kInvalidRangeExpression, ProtoCore.BuildData.WarningMessage.kRangeExpressionWithStepSizeZero, compileStateTracker.CurrentDSFileName, range.StepNode.line, range.StepNode.col);
                        EmitNullNode(new NullNode(), ref inferedType);
                        return;
                    }
                }
            }

            // Replace with build-in RangeExpression() function. - Yu Ke
            var tmpFrom = nodeBuilder.BuildTempVariable();
            var assignFrom = nodeBuilder.BuildBinaryExpression(tmpFrom, range.FromNode);
            EmitBinaryExpressionNode(assignFrom, ref inferedType);

            var tmpTo = nodeBuilder.BuildTempVariable();
            var assignTo = nodeBuilder.BuildBinaryExpression(tmpTo, range.ToNode);
            EmitBinaryExpressionNode(assignTo, ref inferedType);

            var tmpStep = nodeBuilder.BuildTempVariable();
            var assignStep = nodeBuilder.BuildBinaryExpression(tmpStep, range.StepNode == null ? new NullNode() : range.StepNode);
            EmitBinaryExpressionNode(assignStep, ref inferedType);

            BooleanNode hasStep = new BooleanNode { value = range.StepNode == null ? "false" : "true" };
            var tmpStepSkip = nodeBuilder.BuildTempVariable();
            var assignStepSkip = nodeBuilder.BuildBinaryExpression(tmpStepSkip, hasStep);
            EmitBinaryExpressionNode(assignStepSkip, ref inferedType);

            IntNode op = new IntNode();
            switch (range.stepoperator)
            {
                case ProtoCore.DSASM.RangeStepOperator.stepsize:
                    op.value = "0";
                    break;
                case ProtoCore.DSASM.RangeStepOperator.num:
                    op.value = "1";
                    break;
                case ProtoCore.DSASM.RangeStepOperator.approxsize:
                    op.value = "2";
                    break;
                default:
                    op.value = "-1";
                    break;
            }

            var rangeExprFunc = nodeBuilder.BuildFunctionCall(Constants.kFunctionRangeExpression,
                new List<ImperativeNode> { tmpFrom, tmpTo, tmpStep, op, tmpStepSkip });

            NodeUtils.CopyNodeLocation(rangeExprFunc, range);
            EmitFunctionCallNode(rangeExprFunc, ref inferedType, false, graphNode);

            if (range.ArrayDimensions != null)
            {
                int dimensions = DfsEmitArrayIndexHeap(range.ArrayDimensions);
                EmitInstrConsole(ProtoCore.DSASM.kw.pushindex, dimensions.ToString() + "[dim]");
                EmitPushArrayIndex(dimensions);
            }
        }
Exemple #30
0
 // this method is used in conjuction with array var declarations
 private void DfsBuildIndex(ImperativeNode node, List<int> indexlist)
 {
     if (node is ArrayNode)
     {
         ArrayNode array = node as ArrayNode;
         int exprval = 0;
         if (null != array.Expr) {
             exprval = DfsExprValue(array.Expr);
         }
         indexlist.Add(exprval);
         DfsBuildIndex(array.Type, indexlist);
     }
 }
Exemple #31
0
        private void EmitVarDeclNode(ImperativeNode node, ref ProtoCore.Type inferedType)
        {
            VarDeclNode varNode = node as VarDeclNode;

            ProtoCore.Type type = BuildArgumentTypeFromVarDeclNode(varNode);
            type.IsIndexable = false;

            // TODO Jun: Create a class table for holding the primitive and custom data types
            const int primitivesize = 1;
            int datasize = primitivesize;

            int symindex = ProtoCore.DSASM.Constants.kInvalidIndex;
            IdentifierNode tVar = null;
            if (varNode.NameNode is IdentifierNode)
            {
                // Allocate with no initializer
                tVar = varNode.NameNode as IdentifierNode;
                ProtoCore.DSASM.SymbolNode symnode = Allocate(tVar.Value, globalProcIndex, type, datasize, datasize, tVar.ArrayDimensions, varNode.memregion);
                symindex = symnode.symbolTableIndex;
            }
            else if (varNode.NameNode is BinaryExpressionNode)
            {
                BinaryExpressionNode bNode = varNode.NameNode as BinaryExpressionNode;
                tVar = bNode.LeftNode as IdentifierNode;

                Debug.Assert(null != tVar, "Check generated AST");
                Debug.Assert(null != bNode.RightNode, "Check generated AST");

                ProtoCore.DSASM.SymbolNode symnode = null;

                // Is it an array
                if (null != tVar.ArrayDimensions)
                {
                    // Allocate an array with initializer
                    if (bNode.RightNode is ExprListNode)
                    {
                        ExprListNode exprlist = bNode.RightNode as ExprListNode;
                        int size = datasize * exprlist.list.Count;

                        symnode = Allocate(tVar.Value, globalProcIndex, type, size, datasize, tVar.ArrayDimensions, varNode.memregion);
                        symindex = symnode.symbolTableIndex;

                        for (int n = 0; n < exprlist.list.Count; ++n)
                        {
                            DfsTraverse(exprlist.list[n], ref inferedType);

                            ArrayNode array = new ArrayNode();
                            array.Expr = nodeBuilder.BuildIdentfier(n.ToString(), PrimitiveType.kTypeInt);
                            array.Type = null;

                            DfsEmitArrayIndex(array, symindex);

                            EmitInstrConsole(ProtoCore.DSASM.kw.pop, ProtoCore.DSASM.kw.regDX);
                            ProtoCore.DSASM.StackValue opRes = new ProtoCore.DSASM.StackValue();
                            opRes.optype = ProtoCore.DSASM.AddressType.Register;
                            opRes.opdata = (int)ProtoCore.DSASM.Registers.DX;
                            EmitPop(opRes, Constants.kGlobalScope);

                            EmitInstrConsole(ProtoCore.DSASM.kw.pop, tVar.Value);
                            EmitPopForSymbol(symnode);
                        }
                    }
                    else
                    {
                        buildStatus.LogSemanticError("array initializer must be an expression list", compileStateTracker.CurrentDSFileName, bNode.RightNode.line, bNode.RightNode.col);
                    }
                }
                else
                {
                    // Allocate a single variable with initializer

                    symnode = Allocate(tVar.Value, globalProcIndex, type, datasize, datasize, tVar.ArrayDimensions, varNode.memregion);
                    symindex = symnode.symbolTableIndex;
                    DfsTraverse(bNode.RightNode, ref inferedType);

                    EmitInstrConsole(ProtoCore.DSASM.kw.pop, tVar.Value);
                    EmitPopForSymbol(symnode);
                }
            }
            else
            {
                Debug.Assert(false, "Check generated AST");
            }

            if (ProtoCore.DSASM.Constants.kInvalidIndex == symindex)
            {
                throw new BuildHaltException("0CB5BD17");
            }
        }
Exemple #32
0
        // this method is used in conjuction with array indexing
        private void DfsEmitArrayIndex(ImperativeNode node, int symbolindex, int index = 0)
        {
            // s = b + ((i * i.w) + (j * j.w) + (n * n.w))

            if (node is ArrayNode)
            {
                ArrayNode array = node as ArrayNode;

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

                DfsTraverse(array.Expr, ref type);

                // Max size of the current dimension
                int w = codeBlock.symbolTable.symbolList[symbolindex].arraySizeList[index];

                // TODO Jun: Performance improvement
                // Avoid having to generate instructions for the current index if 'w' is 0

                EmitInstrConsole(ProtoCore.DSASM.kw.push, w.ToString());
                ProtoCore.DSASM.StackValue opWidth = new ProtoCore.DSASM.StackValue();
                opWidth.optype = ProtoCore.DSASM.AddressType.Int;
                opWidth.opdata = w;
                EmitPush(opWidth);

                string op = null;
                ProtoCore.DSASM.StackValue opAX = new ProtoCore.DSASM.StackValue();
                opAX.optype = ProtoCore.DSASM.AddressType.Register;
                opAX.opdata = (int)ProtoCore.DSASM.Registers.AX;

                ProtoCore.DSASM.StackValue opBX = new ProtoCore.DSASM.StackValue();
                opBX.optype = ProtoCore.DSASM.AddressType.Register;
                opBX.opdata = (int)ProtoCore.DSASM.Registers.BX;

                ProtoCore.DSASM.StackValue opRes = new ProtoCore.DSASM.StackValue();
                opRes.optype = ProtoCore.DSASM.AddressType.Register;
                opRes.opdata = (int)ProtoCore.DSASM.Registers.AX;

                // Multiplying the max array size by the number of elements
                EmitInstrConsole(ProtoCore.DSASM.kw.pop, ProtoCore.DSASM.kw.regBX);
                EmitPop(opBX, Constants.kGlobalScope);

                EmitInstrConsole(ProtoCore.DSASM.kw.pop, ProtoCore.DSASM.kw.regAX);
                EmitPop(opAX, Constants.kGlobalScope);

                op = opKwData.opStringTable[ProtoCore.DSASM.Operator.mul];
                EmitInstrConsole(op, ProtoCore.DSASM.kw.regAX, ProtoCore.DSASM.kw.regBX);
                EmitBinary(opKwData.opCodeTable[ProtoCore.DSASM.Operator.mul], opAX, opBX);

                EmitInstrConsole(ProtoCore.DSASM.kw.push, ProtoCore.DSASM.kw.regAX);
                EmitPush(opRes);

                if (array.Type is ArrayNode)
                {
                    DfsEmitArrayIndex(array.Type, symbolindex, index + 1);

                    // Adding the previous arraysize to the current one
                    EmitInstrConsole(ProtoCore.DSASM.kw.pop, ProtoCore.DSASM.kw.regBX);
                    EmitPop(opBX, Constants.kGlobalScope);

                    EmitInstrConsole(ProtoCore.DSASM.kw.pop, ProtoCore.DSASM.kw.regAX);
                    EmitPop(opAX, Constants.kGlobalScope);

                    op = opKwData.opStringTable[ProtoCore.DSASM.Operator.add];
                    EmitInstrConsole(op, ProtoCore.DSASM.kw.regAX, ProtoCore.DSASM.kw.regBX);
                    EmitBinary(opKwData.opCodeTable[ProtoCore.DSASM.Operator.add], opAX, opBX);

                    EmitInstrConsole(ProtoCore.DSASM.kw.push, ProtoCore.DSASM.kw.regAX);
                    EmitPush(opRes);
                }
            }
            else
            {
                Debug.Assert(false, "ast error – check ast construction");
            }
        }
Exemple #33
0
 private bool IsNoValueStatement(ImperativeNode node)
 {
     return (node is IfStmtNode) || (node is ForLoopNode) || (node is WhileStmtNode);
 }
Exemple #34
0
        private void DfsEmitArraySize(ImperativeNode node)
        {
            // s = size * ( i * j * k..n )
            if (node is ArrayNode)
            {
                ArrayNode array = node as ArrayNode;

                ProtoCore.Type type = new ProtoCore.Type();
                type.UID = (int)ProtoCore.PrimitiveType.kInvalidType;
                type.IsIndexable = false;
                DfsTraverse(array.Expr, ref type);

                if (array.Type is ArrayNode)
                {
                    DfsEmitArraySize(array.Type);

                    EmitInstrConsole(ProtoCore.DSASM.kw.pop, ProtoCore.DSASM.kw.regBX);
                    ProtoCore.DSASM.StackValue opBX = new ProtoCore.DSASM.StackValue();
                    opBX.optype = ProtoCore.DSASM.AddressType.Register;
                    opBX.opdata = (int)ProtoCore.DSASM.Registers.BX;
                    EmitPop(opBX, Constants.kGlobalScope);

                    EmitInstrConsole(ProtoCore.DSASM.kw.pop, ProtoCore.DSASM.kw.regAX);
                    ProtoCore.DSASM.StackValue opAX = new ProtoCore.DSASM.StackValue();
                    opAX.optype = ProtoCore.DSASM.AddressType.Register;
                    opAX.opdata = (int)ProtoCore.DSASM.Registers.AX;
                    EmitPop(opAX, Constants.kGlobalScope);

                    string op = opKwData.opStringTable[ProtoCore.DSASM.Operator.add];
                    EmitInstrConsole(op, ProtoCore.DSASM.kw.regAX, ProtoCore.DSASM.kw.regBX);
                    EmitBinary(opKwData.opCodeTable[ProtoCore.DSASM.Operator.add], opAX, opBX);

                    EmitInstrConsole(ProtoCore.DSASM.kw.push, ProtoCore.DSASM.kw.regAX);
                    EmitPush(opAX);
                }
            }
            else
            {
                Debug.Assert(false, "ast error – check ast construction");
            }
        }
Exemple #35
0
 public ImperativeNode BuildBinaryExpression(ImperativeNode leftNode, ImperativeNode rightNode, Operator op = Operator.assign)
 {
     var binaryExpr = new BinaryExpressionNode();
     binaryExpr.LeftNode = leftNode;
     binaryExpr.Optr = op;
     binaryExpr.RightNode = rightNode;
     return binaryExpr;
 }
Exemple #36
0
 private int DfsExprValue(ImperativeNode node)
 {
     if (node is IdentifierNode)
     {
         int val = 0;
         IdentifierNode t = node as IdentifierNode;
         try
         {
             val = System.Convert.ToInt32(t.Value);
             return val;
         }
         catch (OverflowException)
         {
             buildStatus.LogSemanticError("Array size overflow", compileStateTracker.CurrentDSFileName, t.line, t.col);
         }
         catch (FormatException)
         {
             buildStatus.LogSemanticError("Array declaration expected constant expression", compileStateTracker.CurrentDSFileName, t.line, t.col);
         }
     }
     else if (node is BinaryExpressionNode)
     {
         BinaryExpressionNode b = node as BinaryExpressionNode;
         Debug.Assert(ProtoCore.DSASM.Operator.mul == b.Optr);
         int left = DfsExprValue(b.LeftNode);
         int right = DfsExprValue(b.RightNode);
         return left * right;
     }
     return 1;
 }
Exemple #37
0
        protected void EmitGropuExpressionNode(ImperativeNode node, ref ProtoCore.Type inferedType)
        {
            GroupExpressionNode group = node as GroupExpressionNode;
            if (group == null)
            {
                return;
            }

            var tmpVar = nodeBuilder.BuildTempVariable();
            var binaryExpr = nodeBuilder.BuildBinaryExpression(tmpVar, group.Expression);
            EmitBinaryExpressionNode(binaryExpr, ref inferedType, false);

            if (group.ArrayDimensions != null)
            {
                (tmpVar as IdentifierNode).ArrayDimensions = group.ArrayDimensions;
            }
            EmitIdentifierNode(tmpVar, ref inferedType, false);
        }
Exemple #38
0
        private void EmitBinaryExpressionNode(ImperativeNode node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null,
            ProtoCore.AST.ImperativeAST.BinaryExpressionNode parentNode = null)
        {
            if (!IsParsingGlobal() && !IsParsingGlobalFunctionBody())
                return;

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

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

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

            if (ProtoCore.DSASM.Operator.assign != b.Optr)
            {
                isBooleanOperation = ProtoCore.DSASM.Operator.lt == b.Optr
                    || ProtoCore.DSASM.Operator.gt == b.Optr
                    || ProtoCore.DSASM.Operator.le == b.Optr
                    || ProtoCore.DSASM.Operator.ge == b.Optr
                    || ProtoCore.DSASM.Operator.eq == b.Optr
                    || ProtoCore.DSASM.Operator.nq == b.Optr
                    || ProtoCore.DSASM.Operator.and == b.Optr
                    || ProtoCore.DSASM.Operator.or == b.Optr;

                DfsTraverse(b.LeftNode, ref inferedType, isBooleanOperation, graphNode, AssociativeSubCompilePass.kNone, parentNode);

                if (inferedType.UID == (int)PrimitiveType.kTypeFunctionPointer && emitDebugInfo)
                {
                    buildStatus.LogSemanticError("Function pointer is not allowed at binary expression other than assignment!", compileStateTracker.CurrentDSFileName, b.LeftNode.line, b.LeftNode.col);
                }

                leftType.UID = inferedType.UID;
                leftType.IsIndexable = inferedType.IsIndexable;
            }
            else
            {
                if (b.LeftNode is IdentifierListNode)
                {
                    ProtoCore.AST.Node lnode = b.LeftNode;
                    bool isCollapsed;

                    if (parentNode != null)
                    {
                        NodeUtils.SetNodeLocation(lnode, parentNode, parentNode);
                    }
                    else
                    {
                        NodeUtils.SetNodeLocation(lnode, b, b);
                    }
                    EmitGetterSetterForIdentList(lnode, ref inferedType, null, ProtoCore.DSASM.AssociativeSubCompilePass.kNone, out isCollapsed, b.RightNode);

                    // Get the lhs symbol list
                    ProtoCore.Type type = new ProtoCore.Type();
                    type.UID = globalClassIndex;
                    ProtoCore.AssociativeGraph.UpdateNodeRef leftNodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef();
                    DFSGetSymbolList(lnode, ref type, leftNodeRef);

                    // Get the first identifier symbol runtime index as it is required for the pushdep
                    List<ProtoCore.DSASM.SymbolNode> symbolList = new List<ProtoCore.DSASM.SymbolNode>();
                    symbolList.Add(leftNodeRef.nodeList[0].symbol);
                    int runtimeIndex = leftNodeRef.nodeList[0].symbol.runtimeTableIndex;

                    // Append the rest of the symbols in the identifierlist
                    for (int n = 1; n < leftNodeRef.nodeList.Count; ++n)
                    {
                        if (leftNodeRef.nodeList[n].symbol != null)
                            symbolList.Add(leftNodeRef.nodeList[n].symbol);
                    }

                    EmitPushDepData(symbolList);
                    EmitPushDep(runtimeIndex, symbolList.Count, globalClassIndex);

                    return;
                }
            }

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

            if (b.RightNode == null && b.Optr == Operator.assign && b.LeftNode is IdentifierNode)
            {
                IdentifierNode t = b.LeftNode as IdentifierNode;
                ProtoCore.DSASM.SymbolNode symbolnode = null;
                bool isAccessible = false;
                bool hasAllocated = VerifyAllocation(t.Value, globalClassIndex, globalProcIndex, out symbolnode, out isAccessible);
                if (hasAllocated)
                {
                    b.RightNode = nodeBuilder.BuildIdentfier(t.Value);
                }
                else
                {
                    b.RightNode = new NullNode();
                }
            }

            if (parentNode != null)
            {
                DfsTraverse(b.RightNode, ref inferedType, isBooleanOperation, graphNode, ProtoCore.DSASM.AssociativeSubCompilePass.kNone, parentNode);
            }
            else
            {
                DfsTraverse(b.RightNode, ref inferedType, isBooleanOperation, graphNode, ProtoCore.DSASM.AssociativeSubCompilePass.kNone, b);
            }

            #if ENABLE_INC_DEC_FIX
                }
            #endif

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

            BinaryExpressionNode rightNode = b.RightNode as BinaryExpressionNode;
            if ((rightNode != null) && (ProtoCore.DSASM.Operator.assign == rightNode.Optr))
                DfsTraverse(rightNode.LeftNode, ref inferedType);

            if (b.Optr != ProtoCore.DSASM.Operator.assign)
            {
                if (inferedType.UID == (int)PrimitiveType.kTypeFunctionPointer && emitDebugInfo)
                {
                    buildStatus.LogSemanticError("Function pointer is not allowed at binary expression other than assignment!", compileStateTracker.CurrentDSFileName, b.RightNode.line, b.RightNode.col);
                }
                EmitBinaryOperation(leftType, rightType, b.Optr);
                isBooleanOp = false;

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

            if (b.LeftNode is IdentifierNode)
            {
                IdentifierNode t = b.LeftNode as IdentifierNode;
                ProtoCore.DSASM.SymbolNode symbolnode = null;

                string s = t.Value;
                bool isReturn = (s == ProtoCore.DSDefinitions.Kw.kw_return);
                if (isReturn)
                {
                    EmitReturnStatement(node, inferedType);
                }
                else
                {
                    {
                        // check whether the variable name is a function name
                        bool isAccessibleFp;
                        int realType;
                        ProtoCore.DSASM.ProcedureNode procNode = null;
                        if (globalClassIndex != ProtoCore.DSASM.Constants.kGlobalScope)
                        {
                            procNode = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].GetMemberFunction(t.Name, null, globalClassIndex, out isAccessibleFp, out realType);
                        }
                        if (procNode == null)
                        {
                            procNode = compileStateTracker.GetFirstVisibleProcedure(t.Name, null, codeBlock);
                        }
                        if (procNode != null)
                        {
                            if (ProtoCore.DSASM.Constants.kInvalidIndex != procNode.procId && emitDebugInfo)
                            {
                                buildStatus.LogSemanticError("\"" + t.Name + "\"" + "is a function and not allowed as a variable name", compileStateTracker.CurrentDSFileName, t.line, t.col);
                            }
                        }
                    }

                    bool isAccessible = false;
                    bool isAllocated = false;
                    // if it's forloop, verify allocation with its original arrayname
                    if (t.ArrayName != null && !t.ArrayName.Equals(""))
                    {
                        isAllocated = VerifyAllocation(t.Value, t.ArrayName, globalClassIndex, globalProcIndex, out symbolnode, out isAccessible);
                    }
                    else
                    {
                        isAllocated = VerifyAllocation(t.Value, globalClassIndex, globalProcIndex, out symbolnode, out isAccessible);
                    }

                    int runtimeIndex = (!isAllocated) ? codeBlock.symbolTable.runtimeIndex : symbolnode.runtimeTableIndex;

                    // Comment Jun: Add modifeid properties into the updatedProperties list of the current function
                    // This propagates upated of mproperties taht were modified in an imperative block
                    if (null != localProcedure && ProtoCore.DSASM.Constants.kGlobalScope != localProcedure.classScope)
                    {
                        if (isAllocated)
                        {
                            Validity.Assert(null != symbolnode);

                            // Get the lhs symbol list
                            ProtoCore.Type type = new ProtoCore.Type();
                            type.UID = globalClassIndex;
                            ProtoCore.AssociativeGraph.UpdateNodeRef leftNodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef();
                            DFSGetSymbolList(b.LeftNode, ref type, leftNodeRef);

                            localProcedure.updatedProperties.Push(leftNodeRef);
                        }
                    }

                    // TODO Jun: Update mechanism work in progress - a flag to manually enable update
                    bool enableUpdate = false;
                    if (enableUpdate)
                    {
                        bool isExternal = false; // isAllocated && currentLangBlock != codeBlockId;
                        //bool isAssociative = ProtoCore.Language.kAssociative == core.exeList[currentLangBlock].language;
                        bool isAssociative = false;
                        if (isExternal && isAssociative)
                        {
                            // Check if this is a modifier variable
                            bool isVariableAModifierStack = false;
                            if (isVariableAModifierStack)
                            {
                                // Check if modifying a named modifier state
                                bool isNameModifierState = false;
                                if (isNameModifierState)
                                {
                                    //bool isStateIntermediate = false;

                                }
                                else
                                {

                                }
                                //targetLangBlock = blockId;
                            }
                        }
                    }

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

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

                        if ((int)PrimitiveType.kInvalidType == castUID)
                        {
                            string message = String.Format(ProtoCore.BuildData.WarningMessage.kTypeUndefined, tident.datatype.Name);
                            buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kTypeUndefined, message, compileStateTracker.CurrentDSFileName, b.line, b.col);
                            castType = compileStateTracker.TypeSystem.BuildTypeObject((int)PrimitiveType.kInvalidType, false);
                            castType.Name = tident.datatype.Name;
                            castType.rank = tident.datatype.rank;
                            castType.IsIndexable = (castType.rank != 0);
                        }
                        else
                        {
                            castType = compileStateTracker.TypeSystem.BuildTypeObject(castUID, tident.datatype.IsIndexable, tident.datatype.rank);
                        }
                    }

                    if (globalClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex)
                    {
                        int symbol = ProtoCore.DSASM.Constants.kInvalidIndex;

                        for (int n = 0; n < compileStateTracker.ClassTable.ClassNodes[globalClassIndex].symbols.symbolList.Count; ++n)
                        {
                            //Fuqiang: Not a member variable if it is a local variable inside a function with the same name
                            bool localVarInMemFunc = false;
                            if (localProcedure != null)
                            {
                                if (symbolnode == null)
                                {
                                    if (!isAllocated) // if isAllocated, inaccessible member variable
                                    {
                                        localVarInMemFunc = true;
                                    }
                                }
                                else if (symbolnode.functionIndex != ProtoCore.DSASM.Constants.kGlobalScope && !localProcedure.isConstructor)
                                {
                                    localVarInMemFunc = true;
                                }
                            }
                            bool isMemberVar = ProtoCore.DSASM.Constants.kGlobalScope == compileStateTracker.ClassTable.ClassNodes[globalClassIndex].symbols.symbolList[n].functionIndex
                                && compileStateTracker.ClassTable.ClassNodes[globalClassIndex].symbols.symbolList[n].name == t.Name
                                && !localVarInMemFunc;
                            if (isMemberVar)
                            {
                                if (t.ArrayDimensions == null)
                                    compileStateTracker.ClassTable.ClassNodes[globalClassIndex].symbols.symbolList[n].datatype = inferedType;
                                else if (dimensions == inferedType.rank)
                                    compileStateTracker.ClassTable.ClassNodes[globalClassIndex].symbols.symbolList[n].datatype.UID = inferedType.UID;
                                symbol = symbolnode.symbolTableIndex;
                                break;
                            }
                        }

                        if (symbol == ProtoCore.DSASM.Constants.kInvalidIndex)
                        {
                            if (!isAllocated)
                            {
                                symbolnode = Allocate(t.Name, globalProcIndex, inferedType);
                            }

                            symbol = symbolnode.symbolTableIndex;

                            if (b.LeftNode is TypedIdentifierNode)
                            {
                                symbolnode.SetStaticType(castType);
                            }
                            castType = symbolnode.staticType;
                            EmitPushVarData(runtimeIndex, dimensions, castType.UID, castType.rank);

                            EmitInstrConsole(ProtoCore.DSASM.kw.pop, s);
                            ProtoCore.DSASM.StackValue operand = new ProtoCore.DSASM.StackValue();
                            operand.optype = ProtoCore.DSASM.AddressType.VarIndex;
                            operand.opdata = symbol;
                            EmitPop(operand, symbolnode.classScope, node.line, node.col, node.endLine, node.endCol);
                        }
                        else
                        {
                            if (b.LeftNode is TypedIdentifierNode)
                            {
                                symbolnode.SetStaticType(castType);
                            }
                            castType = symbolnode.staticType;
                            EmitPushVarData(runtimeIndex, dimensions, castType.UID, castType.rank);

                            EmitInstrConsole(ProtoCore.DSASM.kw.popm, t.Name);

                            ProtoCore.DSASM.StackValue operand = new ProtoCore.DSASM.StackValue();
                            operand.optype = symbolnode.isStatic ? ProtoCore.DSASM.AddressType.StaticMemVarIndex : ProtoCore.DSASM.AddressType.MemVarIndex;
                            operand.opdata = symbol;

                            EmitPopm(operand, node.line, node.col, node.endLine, node.endCol);
                        }
                    }
                    else
                    {
                        if (!isAllocated)
                        {
                            symbolnode = Allocate(t.Value, globalProcIndex, inferedType);
                            if (dimensions > 0)
                            {
                                symbolnode.datatype.rank = dimensions;
                            }
                        }
                        else if (dimensions == 0)
                        {
                            if (compileStateTracker.TypeSystem.IsHigherRank(inferedType.UID, symbolnode.datatype.UID))
                            {
                                symbolnode.datatype = inferedType;
                            }
                        }

                        if (b.LeftNode is TypedIdentifierNode)
                        {
                            symbolnode.SetStaticType(castType);
                        }
                        castType = symbolnode.staticType;
                        EmitPushVarData(runtimeIndex, dimensions, castType.UID, castType.rank);
                        EmitInstrConsole(ProtoCore.DSASM.kw.pop, t.Value);
                        if (parentNode != null)
                        {
                            EmitPopForSymbol(symbolnode, parentNode.line, parentNode.col, parentNode.endLine, parentNode.endCol);
                        }
                        else
                        {
                            EmitPopForSymbol(symbolnode, node.line, node.col, node.endLine, node.endCol);
                        }

                        // Check if the symbol was not here, only then it becomes a valid propagation symbol
                        // TODO Jun: check if the symbol was allocated from an associative block
                        if (!ProtoCore.Utils.CoreUtils.IsAutoGeneratedVar(symbolnode.name))
                        {
                            if (codeBlock.symbolTable.runtimeIndex != symbolnode.runtimeTableIndex)
                            {
                                List<ProtoCore.DSASM.SymbolNode> symbolList = new List<ProtoCore.DSASM.SymbolNode>();
                                symbolList.Add(symbolnode);

                                EmitPushDepData(symbolList);
                                EmitPushDep(runtimeIndex, symbolList.Count, globalClassIndex);
                            }
                        }
                    }
                }
            }
            else if (b.LeftNode is IdentifierListNode)
            {
                // keyu: the left hand side of an assignment statement won't be an
                // identifier list anymore after replacing all properties (not
                // including the left-most property) with getters/setter.
                //
                // If this case really happens, we need to look into that.
                Debug.Assert(false, "The left hand of an assignment statement never will be an identifier list node");

                /*
                int depth = 0;

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

                bool isFirstIdent = false;
                bool isIdentReference = DfsEmitIdentList(b.LeftNode, b, globalClassIndex, ref lastType, ref depth, ref inferedType, true, ref isFirstIdent);
                inferedType.UID = isBooleanOp ? (int)PrimitiveType.kTypeBool : inferedType.UID;

                if (!isIdentReference)
                {
                    buildStatus.LogSemanticError("The left hand side of an operation cannot be a function call", core.CurrentDSFileName, b.LeftNode.line, b.LeftNode.col);
                    throw new BuildHaltException();
                }

                EmitInstrConsole(ProtoCore.DSASM.kw.poplist, depth.ToString(), globalClassIndex.ToString());

                // TODO Jun: Get blockid
                int blockId = 0;
                EmitPopList(depth, globalClassIndex, blockId, node.line, node.col, node.endLine, node.endCol);
                */
            }
            else
            {
                string message = "Illegal assignment (38A37EA5)";
                buildStatus.LogSemanticError(message, compileStateTracker.CurrentDSFileName, b.line, b.col);
                throw new BuildHaltException(message);
            }

            if ((node as BinaryExpressionNode).Optr == Operator.assign)
                EmitSetExpressionUID(compileStateTracker.ExpressionUID++);

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