public void SumItemsFromRangeIterator_Execute_CorrectFinalResult()
        {
            DfirRoot            function        = DfirRoot.Create();
            Loop                loop            = new Loop(function.BlockDiagram);
            LoopConditionTunnel conditionTunnel = CreateLoopConditionTunnel(loop);
            IterateTunnel       iterateTunnel   = CreateIterateTunnel(loop);
            FunctionalNode      range           = new FunctionalNode(function.BlockDiagram, Signatures.RangeType);
            Wire                rangeWire       = Wire.Create(function.BlockDiagram, range.OutputTerminals[0], iterateTunnel.InputTerminals[0]);

            rangeWire.SetWireBeginsMutableVariable(true);
            Constant       lowConstant        = ConnectConstantToInputTerminal(range.InputTerminals[0], NITypes.Int32, 0, false);
            Constant       highConstant       = ConnectConstantToInputTerminal(range.InputTerminals[1], NITypes.Int32, 10, false);
            BorrowTunnel   borrow             = CreateBorrowTunnel(loop, BorrowMode.Mutable);
            Constant       accumulateConstant = ConnectConstantToInputTerminal(borrow.InputTerminals[0], NITypes.Int32, 0, true);
            FunctionalNode accumulateAdd      = new FunctionalNode(loop.Diagram, Signatures.DefineMutatingBinaryFunction("AccumulateAdd", NITypes.Int32));

            Wire.Create(loop.Diagram, borrow.OutputTerminals[0], accumulateAdd.InputTerminals[0]);
            Wire.Create(loop.Diagram, iterateTunnel.OutputTerminals[0], accumulateAdd.InputTerminals[1]);
            FunctionalNode inspect = ConnectInspectToOutputTerminal(borrow.TerminateLifetimeTunnel.OutputTerminals[0]);

            TestExecutionInstance executionInstance = CompileAndExecuteFunction(function);

            byte[] inspectValue = executionInstance.GetLastValueFromInspectNode(inspect);
            AssertByteArrayIsInt32(inspectValue, 45);
        }
        private void VisitLoopBeforeLeftBorderNodes(Compiler.Nodes.Loop loop)
        {
            LLVMBasicBlockRef startBlock           = _topLevelFunction.AppendBasicBlock($"loop{loop.UniqueId}_start"),
                              interiorBlock        = _topLevelFunction.AppendBasicBlock($"loop{loop.UniqueId}_interior"),
                              endBlock             = _topLevelFunction.AppendBasicBlock($"loop{loop.UniqueId}_end");
            LoopConditionTunnel loopCondition      = loop.BorderNodes.OfType <LoopConditionTunnel>().First();
            Terminal            loopConditionInput = loopCondition.InputTerminals[0];
            var conditionAllocationSource          = (LocalAllocationValueSource)GetTerminalValueSource(loopConditionInput);

            _loopData[loop] = new LoopData(conditionAllocationSource, startBlock, interiorBlock, endBlock);

            if (!loopConditionInput.IsConnected)
            {
                // if loop condition was unwired, initialize it to true
                conditionAllocationSource.UpdateValue(_builder, true.AsLLVMValue());
            }

            // initialize all output tunnels with None values, in case the loop interior does not execute
            foreach (Tunnel outputTunnel in loop.BorderNodes.OfType <Tunnel>().Where(tunnel => tunnel.Direction == Direction.Output))
            {
                VariableReference tunnelOutputVariable = outputTunnel.OutputTerminals[0].GetTrueVariable();
                ValueSource       tunnelOutputSource   = _variableValues[tunnelOutputVariable];
                LLVMTypeRef       tunnelOutputType     = tunnelOutputVariable.Type.AsLLVMType();
                tunnelOutputSource.UpdateValue(_builder, LLVMSharp.LLVM.ConstNull(tunnelOutputType));
            }

            _builder.CreateBr(startBlock);
            _builder.PositionBuilderAtEnd(startBlock);
        }
Beispiel #3
0
        private void AssignFalseToLoopConditionOutputTerminal(LoopConditionTunnel condition)
        {
            Diagram loopDiagram = condition.OutputTerminals[0].ParentDiagram;
            var     assign      = new FunctionalNode(loopDiagram, Signatures.AssignType);

            Wire.Create(loopDiagram, condition.OutputTerminals[0], assign.InputTerminals[0]);
            ConnectConstantToInputTerminal(assign.InputTerminals[1], NITypes.Boolean, false, false);
        }
        internal LoopConditionTunnel CreateLoopConditionTunnel(global::Rebar.Compiler.Nodes.Loop loop)
        {
            var loopConditionTunnel   = new LoopConditionTunnel(loop);
            var terminateLifetimeDfir = new TerminateLifetimeTunnel(loop);

            loopConditionTunnel.TerminateLifetimeTunnel = terminateLifetimeDfir;
            terminateLifetimeDfir.BeginLifetimeTunnel   = loopConditionTunnel;
            return(loopConditionTunnel);
        }
Beispiel #5
0
        internal LoopConditionTunnel CreateLoopConditionTunnel(Loop loop)
        {
            var loopConditionTunnel   = new LoopConditionTunnel(loop);
            var terminateLifetimeDfir = new TerminateLifetimeTunnel(loop);

            loopConditionTunnel.TerminateLifetimeTunnel = terminateLifetimeDfir;
            terminateLifetimeDfir.BeginLifetimeTunnel   = loopConditionTunnel;
            return(loopConditionTunnel);
        }
        public void LoopConditionTunnelWithUnwiredInput_SetVariableTypes_InputVariableIsBooleanType()
        {
            DfirRoot            function            = DfirRoot.Create();
            Loop                loop                = new Loop(function.BlockDiagram);
            LoopConditionTunnel loopConditionTunnel = CreateLoopConditionTunnel(loop);

            RunSemanticAnalysisUpToSetVariableTypes(function);

            VariableReference loopConditionInputVariable = loopConditionTunnel.InputTerminals[0].GetTrueVariable();

            Assert.IsTrue(loopConditionInputVariable.Type.IsBoolean());
        }
        public void LoopConditionTunnelWithNonBooleanInput_ValidateVariableUsage_TypeConflictErrorReported()
        {
            DfirRoot            function            = DfirRoot.Create();
            Loop                loop                = new Loop(function.BlockDiagram);
            LoopConditionTunnel loopConditionTunnel = CreateLoopConditionTunnel(loop);

            ConnectConstantToInputTerminal(loopConditionTunnel.InputTerminals[0], PFTypes.Int32, false);

            RunSemanticAnalysisUpToValidation(function);

            AssertTerminalHasTypeConflictMessage(loopConditionTunnel.InputTerminals[0]);
        }
        public void LoopConditionTunnelWithBooleanReferenceInput_ValidateVariableUsage_TypeConflictErrorReported()
        {
            DfirRoot            function            = DfirRoot.Create();
            Loop                loop                = new Loop(function.BlockDiagram);
            LoopConditionTunnel loopConditionTunnel = CreateLoopConditionTunnel(loop);
            ExplicitBorrowNode  borrow              = ConnectExplicitBorrowToInputTerminals(loopConditionTunnel.InputTerminals[0]);

            ConnectConstantToInputTerminal(borrow.InputTerminals[0], NITypes.Boolean, false);

            RunSemanticAnalysisUpToValidation(function);

            AssertTerminalHasTypeConflictMessage(loopConditionTunnel.InputTerminals[0]);
        }
Beispiel #9
0
        public void PanickingUnwrapOptionInsideLoopDiagram_Execute_LoopTerminatesAndDownstreamOfLoopDoesNotExecute()
        {
            DfirRoot            function  = DfirRoot.Create();
            Loop                loop      = new Loop(function.BlockDiagram);
            LoopConditionTunnel condition = CreateLoopConditionTunnel(loop);
            FunctionalNode      unwrap    = CreatePanickingUnwrapOption(loop.Diagram);

            ConnectOutputToOutputTerminal(condition.TerminateLifetimeTunnel.OutputTerminals[0]);

            TestExecutionInstance executionInstance = CompileAndExecuteFunction(function);

            AssertNoOutput(executionInstance);
        }
Beispiel #10
0
        bool IDfirNodeVisitor <bool> .VisitLoopConditionTunnel(LoopConditionTunnel loopConditionTunnel)
        {
            Terminal nodeTerminal          = loopConditionTunnel.InputTerminals[0];
            var      connectedWireTerminal = nodeTerminal.ConnectedTerminal;

            if (connectedWireTerminal != null)
            {
                // Unify node input terminal with its connected source
                AutoBorrowNodeFacade nodeFacade = AutoBorrowNodeFacade.GetNodeFacade(loopConditionTunnel);
                nodeFacade[nodeTerminal].UnifyWithConnectedWireTypeAsNodeInput(connectedWireTerminal.GetFacadeVariable(), _typeUnificationResults);
            }
            OutputLifetimeInterruptsInputVariable(nodeTerminal, loopConditionTunnel.OutputTerminals[0]);
            return(true);
        }
Beispiel #11
0
        public bool VisitLoopConditionTunnel(LoopConditionTunnel loopConditionTunnel)
        {
            Terminal inputTerminal          = loopConditionTunnel.InputTerminals[0],
                     outputTerminal         = loopConditionTunnel.OutputTerminals[0];
            VariableReference inputVariable = inputTerminal.GetTrueVariable();

            if (!inputTerminal.IsConnected)
            {
                CreateLocalAllocationForVariable(inputVariable);
            }
            var loopConditionAllocation = (TAllocation)_variableAllocations[inputVariable];

            CreateConstantLocalReferenceForVariable(outputTerminal.GetTrueVariable(), inputVariable);
            return(true);
        }
        public void LoopConditionTunnel_SetVariableTypes_OutputLifetimeIsBoundedAndDoesNotOutlastDiagram()
        {
            DfirRoot            function            = DfirRoot.Create();
            Loop                loop                = new Loop(function.BlockDiagram);
            LoopConditionTunnel loopConditionTunnel = CreateLoopConditionTunnel(loop);

            RunSemanticAnalysisUpToSetVariableTypes(function);

            VariableReference loopConditionOutputVariable = loopConditionTunnel.OutputTerminals[0].GetTrueVariable();

            Assert.IsTrue(loopConditionOutputVariable.Type.IsMutableReferenceType());
            Lifetime lifetime = loopConditionOutputVariable.Lifetime;

            Assert.IsTrue(lifetime.IsBounded);
            Assert.IsFalse(lifetime.DoesOutlastDiagram(loop.Diagrams[0]));
        }
Beispiel #13
0
        public void LoopWithOutputTunnelThatDoesNotExecute_Execute_TunnelOutputsNoneValue()
        {
            DfirRoot            function        = DfirRoot.Create();
            Loop                loop            = new Loop(function.BlockDiagram);
            LoopConditionTunnel conditionTunnel = CreateLoopConditionTunnel(loop);
            Constant            falseConstant   = ConnectConstantToInputTerminal(conditionTunnel.InputTerminals[0], NITypes.Boolean, false, false);
            Tunnel              outputTunnel    = CreateOutputTunnel(loop);

            ConnectConstantToInputTerminal(outputTunnel.InputTerminals[0], NITypes.Int32, false);
            FunctionalNode inspect = ConnectInspectToOutputTerminal(outputTunnel.OutputTerminals[0]);

            TestExecutionInstance executionInstance = CompileAndExecuteFunction(function);

            byte[] inspectValue = executionInstance.GetLastValueFromInspectNode(inspect);
            AssertByteArrayIsNoneInteger(inspectValue);
        }
        public void LoopConditionTunnel_SetVariableTypes_OutputLifetimeHasCorrectInterruptedVariables()
        {
            DfirRoot            function            = DfirRoot.Create();
            Loop                loop                = new Loop(function.BlockDiagram);
            LoopConditionTunnel loopConditionTunnel = CreateLoopConditionTunnel(loop);
            var lifetimeAssociation = new LifetimeVariableAssociation();

            RunSemanticAnalysisUpToSetVariableTypes(function, null, null, lifetimeAssociation);

            VariableReference loopConditionOutputVariable = loopConditionTunnel.OutputTerminals[0].GetTrueVariable(),
                              loopConditionInputVariable  = loopConditionTunnel.InputTerminals[0].GetTrueVariable();
            Lifetime lifetime = loopConditionOutputVariable.Lifetime;
            IEnumerable <VariableReference> interruptedVariables = lifetimeAssociation.GetVariablesInterruptedByLifetime(lifetime);

            Assert.AreEqual(1, interruptedVariables.Count());
            Assert.AreEqual(loopConditionInputVariable, interruptedVariables.First());
        }
        bool IDfirNodeVisitor <bool> .VisitLoopConditionTunnel(LoopConditionTunnel loopConditionTunnel)
        {
            // TODO: how to determine the mutability of the outer loop condition variable?
            Terminal loopConditionInput  = loopConditionTunnel.InputTerminals.ElementAt(0),
                     loopConditionOutput = loopConditionTunnel.OutputTerminals.ElementAt(0);

            TypeVariableReference boolType = _typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.Boolean);

            _nodeFacade[loopConditionInput] = new SimpleTerminalFacade(loopConditionInput, boolType);
            Lifetime innerLifetime = loopConditionOutput.GetDiagramLifetime();
            TypeVariableReference boolReferenceType = _typeVariableSet.CreateReferenceToReferenceType(
                true,
                boolType,
                _typeVariableSet.CreateReferenceToLifetimeType(innerLifetime));

            _nodeFacade[loopConditionOutput] = new SimpleTerminalFacade(loopConditionOutput, boolReferenceType);
            return(true);
        }
Beispiel #16
0
        public void PanickingUnwrapOptionIntoLoop_Execute_LoopDoesNotExecute()
        {
            DfirRoot            function  = DfirRoot.Create();
            FunctionalNode      unwrap    = CreatePanickingUnwrapOption(function.BlockDiagram);
            Loop                loop      = new Loop(function.BlockDiagram);
            LoopConditionTunnel condition = CreateLoopConditionTunnel(loop);

            // Wire explicit true to condition so that it is initialized outside the PanicAndContinue's clump
            ConnectConstantToInputTerminal(condition.InputTerminals[0], NITypes.Boolean, true, false);
            Tunnel inputTunnel = CreateInputTunnel(loop);

            Wire.Create(function.BlockDiagram, unwrap.OutputTerminals[0], inputTunnel.InputTerminals[0]);
            ConnectOutputToOutputTerminal(inputTunnel.OutputTerminals[0]);
            AssignFalseToLoopConditionOutputTerminal(condition);

            TestExecutionInstance executionInstance = CompileAndExecuteFunction(function);

            AssertNoOutput(executionInstance);
        }
Beispiel #17
0
        public void LoopWithOutputTunnelThatExecutes_Execute_TunnelOutputsSomeValue()
        {
            DfirRoot            function        = DfirRoot.Create();
            Loop                loop            = new Loop(function.BlockDiagram);
            LoopConditionTunnel conditionTunnel = CreateLoopConditionTunnel(loop);
            Constant            trueConstant    = ConnectConstantToInputTerminal(conditionTunnel.InputTerminals[0], NITypes.Boolean, true, false);
            FunctionalNode      assign          = new FunctionalNode(loop.Diagram, Signatures.AssignType);

            Wire.Create(loop.Diagram, conditionTunnel.OutputTerminals[0], assign.InputTerminals[0]);
            Constant       falseConstant = ConnectConstantToInputTerminal(assign.InputTerminals[1], NITypes.Boolean, false, false);
            Tunnel         outputTunnel  = CreateOutputTunnel(loop);
            Constant       intConstant   = ConnectConstantToInputTerminal(outputTunnel.InputTerminals[0], NITypes.Int32, 5, false);
            FunctionalNode inspect       = ConnectInspectToOutputTerminal(outputTunnel.OutputTerminals[0]);

            TestExecutionInstance executionInstance = CompileAndExecuteFunction(function);

            byte[] inspectValue = executionInstance.GetLastValueFromInspectNode(inspect);
            AssertByteArrayIsSomeInteger(inspectValue, 5);
        }
Beispiel #18
0
        private void VisitLoopBeforeLeftBorderNodes(Compiler.Nodes.Loop loop)
        {
            LabelBuilder start = _builder.CreateLabel(),
                         end   = _builder.CreateLabel();
            LoopConditionTunnel loopCondition         = loop.BorderNodes.OfType <LoopConditionTunnel>().First();
            Terminal            loopConditionInput    = loopCondition.InputTerminals.ElementAt(0);
            VariableReference   loopConditionVariable = loopConditionInput.GetTrueVariable();

            _loopData[loop] = new LoopData(start, end, loopConditionVariable);

            if (!loopConditionInput.IsConnected)
            {
                // if loop condition was unwired, initialize it to true
                LoadLocalAllocationReference(loopConditionVariable);
                _builder.EmitLoadIntegerImmediate(1);
                _builder.EmitStoreInteger();
            }

            _builder.SetLabel(start);
        }
Beispiel #19
0
        public void StringSplitIteratorIntoOutput_Execute_CorrectResult()
        {
            DfirRoot       function = DfirRoot.Create();
            FunctionalNode stringSliceToStringSplitIterator = new FunctionalNode(function.BlockDiagram, Signatures.StringSliceToStringSplitIteratorType);

            ConnectConstantToInputTerminal(stringSliceToStringSplitIterator.InputTerminals[0], DataTypes.StringSliceType.CreateImmutableReference(), "one two three", false);
            var loop = new Loop(function.BlockDiagram);
            LoopConditionTunnel loopCondition = CreateLoopConditionTunnel(loop);
            IterateTunnel       iterateTunnel = CreateIterateTunnel(loop);

            Wire.Create(function.BlockDiagram, stringSliceToStringSplitIterator.OutputTerminals[0], iterateTunnel.InputTerminals[0])
            .SetWireBeginsMutableVariable(true);
            FunctionalNode output = new FunctionalNode(loop.Diagram, Signatures.OutputType);

            Wire.Create(loop.Diagram, iterateTunnel.OutputTerminals[0], output.InputTerminals[0]);

            TestExecutionInstance executionInstance = CompileAndExecuteFunction(function);

            Assert.AreEqual("three", executionInstance.RuntimeServices.LastOutputValue);
        }
 public bool VisitLoopConditionTunnel(LoopConditionTunnel loopConditionTunnel)
 {
     ValidateOptionalInputTerminal(loopConditionTunnel.InputTerminals[0]);
     return(true);
 }
 bool IDfirNodeVisitor <bool> .VisitLoopConditionTunnel(LoopConditionTunnel loopConditionTunnel)
 {
     MarkFacadeVariableOfTerminalInterrupted(loopConditionTunnel.InputTerminals[0]);
     MarkFacadeVariableOfTerminalLive(loopConditionTunnel.OutputTerminals[0]);
     return(true);
 }
Beispiel #22
0
 public bool VisitLoopConditionTunnel(LoopConditionTunnel loopConditionTunnel)
 {
     return(true);
 }