예제 #1
0
        public void InitializeVectorAndSumWithSliceIterator_Execute_CorrectSumValue()
        {
            DfirRoot       function         = DfirRoot.Create();
            FunctionalNode initializeVector = CreateInitializeVectorWithIntegerConstants(function.BlockDiagram, 4, 4);
            FunctionalNode vectorToSlice    = new FunctionalNode(function.BlockDiagram, Signatures.VectorToSliceType);

            Wire.Create(function.BlockDiagram, initializeVector.OutputTerminals[0], vectorToSlice.InputTerminals[0]);
            FunctionalNode sliceToIterator = new FunctionalNode(function.BlockDiagram, Signatures.SliceToIteratorType);

            Wire.Create(function.BlockDiagram, vectorToSlice.OutputTerminals[0], sliceToIterator.InputTerminals[0]);
            Loop loop = new Loop(function.BlockDiagram);

            CreateLoopConditionTunnel(loop);
            IterateTunnel iterateTunnel = CreateIterateTunnel(loop);
            BorrowTunnel  borrowTunnel  = CreateBorrowTunnel(loop, BorrowMode.Mutable);

            ConnectConstantToInputTerminal(borrowTunnel.InputTerminals[0], NITypes.Int32, 0, true);
            Wire.Create(function.BlockDiagram, sliceToIterator.OutputTerminals[0], iterateTunnel.InputTerminals[0])
            .SetWireBeginsMutableVariable(true);
            FunctionalNode accumulateAdd = new FunctionalNode(loop.Diagrams[0], Signatures.DefineMutatingBinaryFunction("AccumulateAdd", NITypes.Int32));

            Wire.Create(loop.Diagrams[0], borrowTunnel.OutputTerminals[0], accumulateAdd.InputTerminals[0]);
            Wire.Create(loop.Diagrams[0], iterateTunnel.OutputTerminals[0], accumulateAdd.InputTerminals[1]);
            FunctionalNode inspectNode = ConnectInspectToOutputTerminal(borrowTunnel.TerminateLifetimeTunnel.OutputTerminals[0]);

            TestExecutionInstance executionInstance = CompileAndExecuteFunction(function);

            byte[] inspectValue = executionInstance.GetLastValueFromInspectNode(inspectNode);
            AssertByteArrayIsInt32(inspectValue, 16);
        }
예제 #2
0
        public bool VisitIterateTunnel(IterateTunnel iterateTunnel)
        {
            // TODO: this should eventually call a RangeIterator::next function
            LoopData loopData = _loopData[(Compiler.Nodes.Loop)iterateTunnel.ParentStructure];

            LoadLocalAllocationReference(loopData.LoopCondition); // &cond
            _builder.EmitDuplicate();                             // &cond, &cond
            _builder.EmitDerefInteger();                          // &cond, cond

            VariableReference rangeInput = iterateTunnel.InputTerminals.ElementAt(0).GetTrueVariable();
            VariableReference output     = iterateTunnel.OutputTerminals.ElementAt(0).GetTrueVariable();

            LoadValueAsReference(rangeInput); // &range
            LoadValueAsReference(rangeInput); // &range, &range
            _builder.EmitLoadIntegerImmediate(4);
            _builder.EmitAdd();               // &range, &range.max
            _builder.EmitDerefInteger();      // &range, range.max
            _builder.EmitSwap();              // range.max, &range
            _builder.EmitDuplicate();         // range.max, &range, &range
            _builder.EmitDuplicate();         // range.max, &range, &range, &range
            _builder.EmitDerefInteger();      // range.max, &range, &range, range.current
            _builder.EmitLoadIntegerImmediate(1);
            _builder.EmitAdd();               // range.max, &range, &range, range.current+1
            _builder.EmitDuplicate();
            LoadLocalAllocationReference(output);
            _builder.EmitSwap();         // range.max, &range, &range, range.current+1, &output, range.current+1
            _builder.EmitStoreInteger(); // range.max, &range, &range, range.current+1
            _builder.EmitStoreInteger(); // range.max, &range

            _builder.EmitDerefInteger(); // range.max, range.current
            _builder.EmitGreaterThan();  // &cond, cond, (range.max > range.current)
            _builder.EmitAnd();          // &cond, (cond && range.max > range.current)
            _builder.EmitStoreInteger();
            return(true);
        }
예제 #3
0
        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);
        }
예제 #4
0
        bool IDfirNodeVisitor <bool> .VisitIterateTunnel(IterateTunnel iterateTunnel)
        {
            Terminal iteratorInput = iterateTunnel.InputTerminals.ElementAt(0),
                     itemOutput    = iterateTunnel.OutputTerminals.ElementAt(0);
            LifetimeTypeVariableGroup lifetimeTypeVariableGroup = LifetimeTypeVariableGroup.CreateFromTerminal(iteratorInput);

            TypeVariableReference loopLifetimeReference          = _typeVariableSet.CreateReferenceToLifetimeType(itemOutput.GetDiagramLifetime());
            TypeVariableReference itemTypeVariable               = _typeVariableSet.CreateReferenceToNewTypeVariable();
            TypeVariableReference implementsIteratorTypeVariable = _typeVariableSet.CreateReferenceToNewTypeVariable(
                new Constraint[] { new IteratorTraitConstraint(itemTypeVariable) });
            ReferenceInputTerminalLifetimeGroup group = CreateTerminalLifetimeGroup(InputReferenceMutability.RequireMutable, lifetimeTypeVariableGroup);

            group.AddTerminalFacade(iteratorInput, implementsIteratorTypeVariable, default(TypeVariableReference));

            _nodeFacade[itemOutput] = new SimpleTerminalFacade(itemOutput, itemTypeVariable);

            TypeVariableReference intermediateTypeVariable = _typeVariableSet.CreateReferenceToOptionType(itemTypeVariable);
            VariableReference     intermediateVariable     = iterateTunnel.GetVariableSet().CreateNewVariable(
                iterateTunnel.ParentStructure.ParentDiagram.GetLifetimeGraphIdentifier().Id,
                intermediateTypeVariable,
                false);

            intermediateVariable.Name = iterateTunnel.IntermediateValueName;
            iterateTunnel.IntermediateValueVariable = intermediateVariable;

            iterateTunnel.IteratorNextFunctionType = new FunctionType(
                Signatures.IteratorNextType,
                new TypeVariableReference[]
            {
                implementsIteratorTypeVariable,
                itemTypeVariable,
                group.LifetimeType
            });
            return(true);
        }
예제 #5
0
        public bool VisitIterateTunnel(IterateTunnel iterateTunnel)
        {
            ValueSource iteratorSource = GetTerminalValueSource(iterateTunnel.InputTerminals[0]),
                        itemSource     = GetTerminalValueSource(iterateTunnel.OutputTerminals[0]);

            // call the Iterator::next function on the iterator reference
            // TODO: create an alloca'd Option<Item> variable, so that we can pass its address to Iterator::next
            LLVMValueRef itemOption = _builder.CreateCall(
                GetImportedCommonFunction(CommonModules.RangeIteratorNextName), // TODO: determine the name of this function from the input type
                new LLVMValueRef[]
            {
                iteratorSource.GetValue(_builder)
            },
                "itemOption");
            LLVMValueRef isSome = _builder.CreateExtractValue(itemOption, 0u, "isSome"),
                         item   = _builder.CreateExtractValue(itemOption, 1u, "item");

            // &&= the loop condition with the isSome value
            var loop = (Compiler.Nodes.Loop)iterateTunnel.ParentStructure;
            LocalAllocationValueSource loopConditionAllocationSource = _loopData[loop].ConditionAllocationSource;
            LLVMValueRef condition          = loopConditionAllocationSource.GetValue(_builder);
            LLVMValueRef conditionAndIsSome = _builder.CreateAnd(condition, isSome, "conditionAndIsSome");

            loopConditionAllocationSource.UpdateValue(_builder, conditionAndIsSome);

            // bind the inner value to the output tunnel
            itemSource.UpdateValue(_builder, item);
            return(true);
        }
예제 #6
0
        private static IterateTunnel CreateIterateTunnel(Loop loop)
        {
            var iterateTunnel         = new IterateTunnel(loop);
            var terminateLifetimeDfir = new TerminateLifetimeTunnel(loop);

            iterateTunnel.TerminateLifetimeTunnel     = terminateLifetimeDfir;
            terminateLifetimeDfir.BeginLifetimeTunnel = iterateTunnel;
            return(iterateTunnel);
        }
예제 #7
0
        private IterateTunnel CreateRangeAndIterateTunnel(Loop loop, int rangeLow, int rangeHigh)
        {
            var range = new FunctionalNode(loop.ParentDiagram, Signatures.RangeType);

            ConnectConstantToInputTerminal(range.InputTerminals[0], NITypes.Int32, 1, false);
            ConnectConstantToInputTerminal(range.InputTerminals[1], NITypes.Int32, 7, false);
            IterateTunnel iterateTunnel = CreateIterateTunnel(loop);

            Wire.Create(loop.ParentDiagram, range.OutputTerminals[0], iterateTunnel.InputTerminals[0])
            .SetWireBeginsMutableVariable(true);
            return(iterateTunnel);
        }
예제 #8
0
        public void FillVectorEnoughToGrowItThenRemoveAllElements_Execute_AllElementsPreservedAndRemoved()
        {
            DfirRoot function     = DfirRoot.Create();
            var      createVector = new FunctionalNode(function.BlockDiagram, Signatures.VectorCreateType);
            Loop     firstLoop    = new Loop(function.BlockDiagram);

            CreateLoopConditionTunnel(firstLoop);
            BorrowTunnel firstLoopBorrowTunnel = CreateBorrowTunnel(firstLoop, BorrowMode.Mutable);

            Wire.Create(function.BlockDiagram, createVector.OutputTerminals[0], firstLoopBorrowTunnel.InputTerminals[0])
            .SetWireBeginsMutableVariable(true);
            IterateTunnel iterateTunnel  = CreateRangeAndIterateTunnel(firstLoop, 1, 7);
            var           appendToVector = new FunctionalNode(firstLoop.Diagram, Signatures.VectorAppendType);

            Wire.Create(firstLoop.Diagram, firstLoopBorrowTunnel.OutputTerminals[0], appendToVector.InputTerminals[0]);
            Wire.Create(firstLoop.Diagram, iterateTunnel.OutputTerminals[0], appendToVector.InputTerminals[1]);
            Loop secondLoop = new Loop(function.BlockDiagram);

            CreateLoopConditionTunnel(secondLoop);
            BorrowTunnel secondLoopBorrowTunnel = CreateBorrowTunnel(secondLoop, BorrowMode.Mutable);

            Wire.Create(function.BlockDiagram, firstLoopBorrowTunnel.TerminateLifetimeTunnel.OutputTerminals[0], secondLoopBorrowTunnel.InputTerminals[0]);
            CreateRangeAndIterateTunnel(secondLoop, 1, 7);
            var removeLastFromVector = new FunctionalNode(secondLoop.Diagram, Signatures.VectorRemoveLastType);

            Wire.Create(secondLoop.Diagram, secondLoopBorrowTunnel.OutputTerminals[0], removeLastFromVector.InputTerminals[0]);
            BorrowTunnel resultBorrowTunnel = CreateBorrowTunnel(secondLoop, BorrowMode.Mutable);

            ConnectConstantToInputTerminal(resultBorrowTunnel.InputTerminals[0], NITypes.Int32, 0, true);
            Frame unwrapFrame = Frame.Create(secondLoop.Diagram);
            UnwrapOptionTunnel unwrapTunnel = CreateUnwrapOptionTunnel(unwrapFrame);

            Wire.Create(secondLoop.Diagram, removeLastFromVector.OutputTerminals[1], unwrapTunnel.InputTerminals[0]);
            Tunnel inputTunnel = CreateInputTunnel(unwrapFrame);

            Wire.Create(secondLoop.Diagram, resultBorrowTunnel.OutputTerminals[0], inputTunnel.InputTerminals[0]);
            var accumulateAdd = new FunctionalNode(unwrapFrame.Diagram, Signatures.DefineMutatingBinaryFunction("AccumulateAdd", NITypes.Int32));

            Wire.Create(unwrapFrame.Diagram, inputTunnel.OutputTerminals[0], accumulateAdd.InputTerminals[0]);
            Wire.Create(unwrapFrame.Diagram, unwrapTunnel.OutputTerminals[0], accumulateAdd.InputTerminals[1]);
            FunctionalNode inspect = ConnectInspectToOutputTerminal(resultBorrowTunnel.TerminateLifetimeTunnel.OutputTerminals[0]);

            TestExecutionInstance executionInstance = CompileAndExecuteFunction(function);

            byte[] inspectValue = executionInstance.GetLastValueFromInspectNode(inspect);
            AssertByteArrayIsInt32(inspectValue, 21);
        }
        bool IDfirNodeVisitor <bool> .VisitIterateTunnel(IterateTunnel iterateTunnel)
        {
            Terminal iteratorInput = iterateTunnel.InputTerminals.ElementAt(0),
                     itemOutput    = iterateTunnel.OutputTerminals.ElementAt(0);
            LifetimeTypeVariableGroup lifetimeTypeVariableGroup = LifetimeTypeVariableGroup.CreateFromTerminal(iteratorInput);

            TypeVariableReference loopLifetimeReference          = _typeVariableSet.CreateReferenceToLifetimeType(itemOutput.GetDiagramLifetime());
            TypeVariableReference itemTypeVariable               = _typeVariableSet.CreateReferenceToNewTypeVariable();
            TypeVariableReference implementsIteratorTypeVariable = _typeVariableSet.CreateReferenceToNewTypeVariable(
                new Constraint[] { new IteratorTraitConstraint(itemTypeVariable) });

            _nodeFacade
            .CreateInputLifetimeGroup(InputReferenceMutability.RequireMutable, lifetimeTypeVariableGroup.LazyNewLifetime, lifetimeTypeVariableGroup.LifetimeType)
            .AddTerminalFacade(iteratorInput, implementsIteratorTypeVariable, default(TypeVariableReference));

            _nodeFacade[itemOutput] = new SimpleTerminalFacade(itemOutput, itemTypeVariable);
            return(true);
        }
예제 #10
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 VisitIterateTunnel(IterateTunnel iterateTunnel)
 {
     ValidateRequiredInputTerminal(iterateTunnel.InputTerminals[0]);
     return(true);
 }
 bool IDfirNodeVisitor <bool> .VisitIterateTunnel(IterateTunnel iterateTunnel)
 {
     MarkFacadeVariableOfTerminalInterrupted(iterateTunnel.InputTerminals[0]);
     MarkFacadeVariableOfTerminalLive(iterateTunnel.OutputTerminals[0]);
     return(true);
 }
예제 #13
0
        private NationalInstruments.Dfir.BorderNode TranslateBorderNode(BorderNode sourceModelBorderNode, NationalInstruments.Dfir.Structure dfirParentStructure)
        {
            var flatSequenceSimpleTunnel = sourceModelBorderNode as FlatSequenceSimpleTunnel;
            var loopTunnel          = sourceModelBorderNode as LoopTunnel;
            var borrowTunnel        = sourceModelBorderNode as SourceModel.BorrowTunnel;
            var loopBorrowTunnel    = sourceModelBorderNode as LoopBorrowTunnel;
            var lockTunnel          = sourceModelBorderNode as SourceModel.LockTunnel;
            var loopConditionTunnel = sourceModelBorderNode as SourceModel.LoopConditionTunnel;
            var loopIterateTunnel   = sourceModelBorderNode as SourceModel.LoopIterateTunnel;
            var flatSequenceTerminateLifetimeTunnel = sourceModelBorderNode as FlatSequenceTerminateLifetimeTunnel;
            var loopTerminateLifetimeTunnel         = sourceModelBorderNode as LoopTerminateLifetimeTunnel;
            var unwrapOptionTunnel = sourceModelBorderNode as SourceModel.UnwrapOptionTunnel;

            if (borrowTunnel != null)
            {
                var borrowDfir = new Nodes.BorrowTunnel(dfirParentStructure, borrowTunnel.BorrowMode);
                CreateTerminateLifetimeTunnel(borrowDfir, dfirParentStructure);
                return(borrowDfir);
            }
            else if (loopBorrowTunnel != null)
            {
                var borrowDfir = new Nodes.BorrowTunnel(dfirParentStructure, loopBorrowTunnel.BorrowMode);
                CreateTerminateLifetimeTunnel(borrowDfir, dfirParentStructure);
                return(borrowDfir);
            }
            else if (lockTunnel != null)
            {
                var lockDfir = new Nodes.LockTunnel(dfirParentStructure);
                CreateTerminateLifetimeTunnel(lockDfir, dfirParentStructure);
                return(lockDfir);
            }
            else if (loopConditionTunnel != null)
            {
                var loopConditionDfir = new Nodes.LoopConditionTunnel((Nodes.Loop)dfirParentStructure);
                CreateTerminateLifetimeTunnel(loopConditionDfir, dfirParentStructure);
                return(loopConditionDfir);
            }
            else if (loopIterateTunnel != null)
            {
                var loopIterateDfir = new IterateTunnel(dfirParentStructure);
                CreateTerminateLifetimeTunnel(loopIterateDfir, dfirParentStructure);
                return(loopIterateDfir);
            }
            else if (flatSequenceTerminateLifetimeTunnel != null)
            {
                var beginLifetimeDfir = (Nodes.IBeginLifetimeTunnel)_map.GetDfirForModel((Element)flatSequenceTerminateLifetimeTunnel.BeginLifetimeTunnel);
                return(beginLifetimeDfir.TerminateLifetimeTunnel);
            }
            else if (loopTerminateLifetimeTunnel != null)
            {
                var beginLifetimeDfir = (Nodes.IBeginLifetimeTunnel)_map.GetDfirForModel((Element)loopTerminateLifetimeTunnel.BeginLifetimeTunnel);
                return(beginLifetimeDfir.TerminateLifetimeTunnel);
            }
            else if (flatSequenceSimpleTunnel != null || loopTunnel != null)
            {
                return(dfirParentStructure.CreateTunnel(
                           VIDfirBuilder.TranslateDirection(sourceModelBorderNode.PrimaryOuterTerminal.Direction),
                           NationalInstruments.Dfir.TunnelMode.LastValue,
                           sourceModelBorderNode.PrimaryOuterTerminal.DataType,
                           sourceModelBorderNode.PrimaryInnerTerminals.First().DataType));
            }
            else if (unwrapOptionTunnel != null)
            {
                return(new Nodes.UnwrapOptionTunnel(dfirParentStructure));
            }
            throw new NotImplementedException("Unknown BorderNode type: " + sourceModelBorderNode.GetType().Name);
        }
예제 #14
0
 bool IDfirNodeVisitor <bool> .VisitIterateTunnel(IterateTunnel iterateTunnel)
 {
     UnifyNodeInputTerminalTypes(iterateTunnel);
     return(true);
 }
 bool IDfirNodeVisitor <bool> .VisitIterateTunnel(IterateTunnel iterateTunnel)
 {
     iterateTunnel.UnifyNodeInputTerminalTypes(_typeUnificationResults);
     return(true);
 }
예제 #16
0
 public bool VisitIterateTunnel(IterateTunnel iterateTunnel)
 {
     CreateLocalAllocationForVariable(iterateTunnel.OutputTerminals[0].GetTrueVariable());
     return(true);
 }