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; } } }
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; } } }