示例#1
0
        private void EmitInlineConditionalNode(AssociativeNode node, ref ProtoCore.Type inferedType, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone, ProtoCore.AST.AssociativeAST.BinaryExpressionNode parentNode = null)
        {
            if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier)
            {
                return;
            }

            bool isInlineConditionalFlag = false;
            int startPC = pc;
            bool isReturn = false;
            if (graphNode != null)
            {
                isInlineConditionalFlag = graphNode.isInlineConditional;
                graphNode.isInlineConditional = true;
                startPC = graphNode.updateBlock.startpc;
                isReturn = graphNode.isReturn;
            }

            InlineConditionalNode inlineConditionalNode = node as InlineConditionalNode;
            // TODO: Jun, this 'if' condition needs to be removed as it was the old implementation - pratapa
            if (inlineConditionalNode.IsAutoGenerated)
            {
                // Normal inline conditional

                IfStatementNode ifNode = new IfStatementNode();
                ifNode.ifExprNode = inlineConditionalNode.ConditionExpression;
                List<AssociativeNode> ifBody = new List<AssociativeNode>();
                List<AssociativeNode> elseBody = new List<AssociativeNode>();
                ifBody.Add(inlineConditionalNode.TrueExpression);
                elseBody.Add(inlineConditionalNode.FalseExpression);
                ifNode.IfBody = ifBody;
                ifNode.ElseBody = elseBody;

                EmitIfStatementNode(ifNode, ref inferedType, graphNode);
            }
            else
            {
                // CPS inline conditional
                
                FunctionCallNode inlineCall = new FunctionCallNode();
                IdentifierNode identNode = new IdentifierNode();
                identNode.Name = ProtoCore.DSASM.Constants.kInlineConditionalMethodName;
                inlineCall.Function = identNode;

                DebugProperties.BreakpointOptions oldOptions = core.DebuggerProperties.breakOptions;
                DebugProperties.BreakpointOptions newOptions = oldOptions;
                newOptions |= DebugProperties.BreakpointOptions.EmitInlineConditionalBreakpoint;
                core.DebuggerProperties.breakOptions = newOptions;

                core.DebuggerProperties.highlightRange = new ProtoCore.CodeModel.CodeRange
                {
                    StartInclusive = new ProtoCore.CodeModel.CodePoint
                    {
                        LineNo = parentNode.line,
                        CharNo = parentNode.col
                    },

                    EndExclusive = new ProtoCore.CodeModel.CodePoint
                    {
                        LineNo = parentNode.endLine,
                        CharNo = parentNode.endCol
                    }
                };

                // As SSA conversion is enabled, we have got the values of
                // true and false branch, so it isn't necessary to create 
                // language blocks.
                if (core.Options.GenerateSSA)
                {
                    inlineCall.FormalArguments.Add(inlineConditionalNode.ConditionExpression);
                    inlineCall.FormalArguments.Add(inlineConditionalNode.TrueExpression);
                    inlineCall.FormalArguments.Add(inlineConditionalNode.FalseExpression);
                }
                else
                {
                    // True condition language block
                    BinaryExpressionNode bExprTrue = AstFactory.BuildReturnStatement(inlineConditionalNode.TrueExpression);

                    LanguageBlockNode langblockT = new LanguageBlockNode();
                    int trueBlockId = Constants.kInvalidIndex;
                    langblockT.codeblock.Language = ProtoCore.Language.Associative;
                    core.AssocNode = bExprTrue;
                    core.InlineConditionalBodyGraphNodes.Push(new List<GraphNode>());
                    EmitDynamicLanguageBlockNode(langblockT, bExprTrue, ref inferedType, ref trueBlockId, graphNode, ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone);
                    List<GraphNode> trueBodyNodes = core.InlineConditionalBodyGraphNodes.Pop();

                    // Append dependent nodes of the inline conditional 
                    foreach (GraphNode gnode in trueBodyNodes)
                        foreach (GraphNode dNode in gnode.dependentList)
                            graphNode.PushDependent(dNode);

                    core.AssocNode = null;
                    DynamicBlockNode dynBlockT = new DynamicBlockNode(trueBlockId);

                    // False condition language block
                    BinaryExpressionNode bExprFalse = AstFactory.BuildReturnStatement(inlineConditionalNode.FalseExpression);

                    LanguageBlockNode langblockF = new LanguageBlockNode();
                    int falseBlockId = Constants.kInvalidIndex;
                    langblockF.codeblock.Language = ProtoCore.Language.Associative;
                    core.AssocNode = bExprFalse;
                    core.InlineConditionalBodyGraphNodes.Push(new List<GraphNode>());
                    EmitDynamicLanguageBlockNode(langblockF, bExprFalse, ref inferedType, ref falseBlockId, graphNode, ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone);
                    List<GraphNode> falseBodyNodes = core.InlineConditionalBodyGraphNodes.Pop();

                    // Append dependent nodes of the inline conditional 
                    foreach (GraphNode gnode in falseBodyNodes)
                        foreach (GraphNode dNode in gnode.dependentList)
                            graphNode.PushDependent(dNode);

                    core.AssocNode = null;
                    DynamicBlockNode dynBlockF = new DynamicBlockNode(falseBlockId);

                    inlineCall.FormalArguments.Add(inlineConditionalNode.ConditionExpression);
                    inlineCall.FormalArguments.Add(dynBlockT);
                    inlineCall.FormalArguments.Add(dynBlockF);
                }

                core.DebuggerProperties.breakOptions = oldOptions;
                core.DebuggerProperties.highlightRange = new ProtoCore.CodeModel.CodeRange
                {
                    StartInclusive = new ProtoCore.CodeModel.CodePoint
                    {
                        LineNo = Constants.kInvalidIndex,
                        CharNo = Constants.kInvalidIndex
                    },

                    EndExclusive = new ProtoCore.CodeModel.CodePoint
                    {
                        LineNo = Constants.kInvalidIndex,
                        CharNo = Constants.kInvalidIndex
                    }
                };

                // Save the pc and store it after the call
                EmitFunctionCallNode(inlineCall, ref inferedType, false, graphNode, ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier);
                EmitFunctionCallNode(inlineCall, ref inferedType, false, graphNode, ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone, parentNode);

                // Need to restore those settings.
                if (graphNode != null)
                {
                    graphNode.isInlineConditional = isInlineConditionalFlag;
                    graphNode.updateBlock.startpc = startPC;
                    graphNode.isReturn = isReturn;
                }
            }
        }
示例#2
0
        private void EmitInlineConditionalNode(AssociativeNode node, ref ProtoCore.Type inferedType, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone, ProtoCore.AST.AssociativeAST.BinaryExpressionNode parentNode = null)
        {
            if (subPass == AssociativeSubCompilePass.kUnboundIdentifier)
            {
                return;
            }

            bool isInlineConditionalFlag = false;
            int startPC = pc;
            bool isReturn = false;
            if (graphNode != null)
            {
                isInlineConditionalFlag = graphNode.isInlineConditional;
                graphNode.isInlineConditional = true;
                startPC = graphNode.updateBlock.startpc;
                isReturn = graphNode.isReturn;
            }

            InlineConditionalNode inlineConditionalNode = node as InlineConditionalNode;
            // TODO: Jun, this 'if' condition needs to be removed as it was the old implementation - pratapa
            if (inlineConditionalNode.IsAutoGenerated)
            {
                // Normal inline conditional

                IfStatementNode ifNode = new IfStatementNode();
                ifNode.ifExprNode = inlineConditionalNode.ConditionExpression;
                List<AssociativeNode> ifBody = new List<AssociativeNode>();
                List<AssociativeNode> elseBody = new List<AssociativeNode>();
                ifBody.Add(inlineConditionalNode.TrueExpression);
                elseBody.Add(inlineConditionalNode.FalseExpression);
                ifNode.IfBody = ifBody;
                ifNode.ElseBody = elseBody;

                EmitIfStatementNode(ifNode, ref inferedType, graphNode);
            }
            else
            {
                // CPS inline conditional

                FunctionCallNode inlineCall = new FunctionCallNode();
                IdentifierNode identNode = new IdentifierNode();
                identNode.Name = ProtoCore.DSASM.Constants.kInlineConditionalMethodName;
                inlineCall.Function = identNode;

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

                compileStateTracker.DebugProps.highlightRange = new ProtoCore.CodeModel.CodeRange
                {
                    StartInclusive = new ProtoCore.CodeModel.CodePoint
                    {
                        LineNo = parentNode.line,
                        CharNo = parentNode.col
                    },

                    EndExclusive = new ProtoCore.CodeModel.CodePoint
                    {
                        LineNo = parentNode.endLine,
                        CharNo = parentNode.endCol
                    }
                };

                // True condition language block
                BinaryExpressionNode bExprTrue = new BinaryExpressionNode();
                bExprTrue.LeftNode = nodeBuilder.BuildReturn();
                bExprTrue.Optr = Operator.assign;
                bExprTrue.RightNode = inlineConditionalNode.TrueExpression;

                LanguageBlockNode langblockT = new LanguageBlockNode();
                int trueBlockId = ProtoCore.DSASM.Constants.kInvalidIndex;
                langblockT.codeblock.language = ProtoCore.Language.kAssociative;
                langblockT.codeblock.fingerprint = "";
                langblockT.codeblock.version = "";
                compileStateTracker.AssocNode = bExprTrue;
                EmitDynamicLanguageBlockNode(langblockT, bExprTrue, ref inferedType, ref trueBlockId, graphNode, AssociativeSubCompilePass.kNone);
                compileStateTracker.AssocNode = null;
                ProtoCore.AST.AssociativeAST.DynamicBlockNode dynBlockT = new ProtoCore.AST.AssociativeAST.DynamicBlockNode(trueBlockId);

                // False condition language block
                BinaryExpressionNode bExprFalse = new BinaryExpressionNode();
                bExprFalse.LeftNode = nodeBuilder.BuildReturn();
                bExprFalse.Optr = Operator.assign;
                bExprFalse.RightNode = inlineConditionalNode.FalseExpression;

                LanguageBlockNode langblockF = new LanguageBlockNode();
                int falseBlockId = ProtoCore.DSASM.Constants.kInvalidIndex;
                langblockF.codeblock.language = ProtoCore.Language.kAssociative;
                langblockF.codeblock.fingerprint = "";
                langblockF.codeblock.version = "";
                compileStateTracker.AssocNode = bExprFalse;
                EmitDynamicLanguageBlockNode(langblockF, bExprFalse, ref inferedType, ref falseBlockId, graphNode, AssociativeSubCompilePass.kNone);
                compileStateTracker.AssocNode = null;
                ProtoCore.AST.AssociativeAST.DynamicBlockNode dynBlockF = new ProtoCore.AST.AssociativeAST.DynamicBlockNode(falseBlockId);

                compileStateTracker.DebugProps.breakOptions = oldOptions;
                compileStateTracker.DebugProps.highlightRange = new ProtoCore.CodeModel.CodeRange
                {
                    StartInclusive = new ProtoCore.CodeModel.CodePoint
                    {
                        LineNo = Constants.kInvalidIndex,
                        CharNo = Constants.kInvalidIndex
                    },

                    EndExclusive = new ProtoCore.CodeModel.CodePoint
                    {
                        LineNo = Constants.kInvalidIndex,
                        CharNo = Constants.kInvalidIndex
                    }
                };

                inlineCall.FormalArguments.Add(inlineConditionalNode.ConditionExpression);
                inlineCall.FormalArguments.Add(dynBlockT);
                inlineCall.FormalArguments.Add(dynBlockF);

                // Save the pc and store it after the call
                EmitFunctionCallNode(inlineCall, ref inferedType, false, graphNode, AssociativeSubCompilePass.kUnboundIdentifier);
                EmitFunctionCallNode(inlineCall, ref inferedType, false, graphNode, AssociativeSubCompilePass.kNone, parentNode);

                // Need to restore those settings.
                if (graphNode != null)
                {
                    graphNode.isInlineConditional = isInlineConditionalFlag;
                    graphNode.updateBlock.startpc = startPC;
                    graphNode.isReturn = isReturn;
                }
            }
        }