示例#1
0
        public bool TryAddTree(Model model, Trees trees, int treeIndex, MortalityCause reason)
        {
            if (this.treeFilter.IsEmpty == false)
            {
                // skip trees if filter is present
                TreeWrapper treeWrapper = new(model)
                {
                    Trees     = trees,
                    TreeIndex = treeIndex
                };
                this.treeFilter.Wrapper = treeWrapper;
                if (this.treeFilter.Execute() == 0.0)
                {
                    return(false);
                }
            }

            if (this.removedTreesByResourceUnit.TryGetValue(trees.RU, out MutableTuple <Trees, List <MortalityCause> >?removedTreesOfSpecies) == false)
            {
                removedTreesOfSpecies = new MutableTuple <Trees, List <MortalityCause> >(new Trees(model.Landscape, trees.RU, trees.Species),
                                                                                         new List <MortalityCause>());
                this.removedTreesByResourceUnit.Add(trees.RU, removedTreesOfSpecies);
            }

            removedTreesOfSpecies.Item1.Add(trees, treeIndex);
            removedTreesOfSpecies.Item2.Add(reason);
            return(true);
        }
示例#2
0
        /// <summary>
        /// Converts a term AST to a term, and expands symbolic constants as much as possible.
        /// Returns null if there are errors.
        /// Should only be called after the set has been successfully compiled.
        /// </summary>
        private Term Expand(AST <Node> ast, List <Flag> flags)
        {
            bool gotLock = false;

            try
            {
                termIndexLock.Enter(ref gotLock);

                UserSymbol other;
                var        symTable        = index.SymbolTable;
                var        valParamToValue = new Map <UserCnstSymb, Term>(Symbol.Compare);
                foreach (var kv in valueInputs)
                {
                    valParamToValue.Add(
                        (UserCnstSymb)symTable.Resolve(string.Format("%{0}", kv.Key), out other, symTable.ModuleSpace),
                        kv.Value);
                }

                var nextDcVarId = new MutableTuple <int>(0);
                var success     = new SuccessToken();
                var symbStack   = new Stack <Tuple <Namespace, Symbol> >();
                symbStack.Push(new Tuple <Namespace, Symbol>(index.SymbolTable.Root, null));
                var result = ast.Compute <Tuple <Term, Term> >(
                    x => Expand_Unfold(x, symbStack, nextDcVarId, success, flags),
                    (x, y) => Expand_Fold(x, y, symbStack, valParamToValue, success, flags));
                return(result == null ? null : result.Item1);
            }
            finally
            {
                if (gotLock)
                {
                    termIndexLock.Exit();
                }
            }
        }
示例#3
0
        /// <summary>
        /// Python ctor - maps to function.__new__
        ///
        /// y = func(x.__code__, globals(), 'foo', None, (a, ))
        /// </summary>
        public PythonFunction(CodeContext context, FunctionCode code, PythonDictionary globals, string name, PythonTuple defaults, PythonTuple closure)
        {
            if (closure != null && closure.__len__() != 0)
            {
                throw new NotImplementedException("non empty closure argument is not supported");
            }

            if (globals == context.GlobalDict)
            {
                _module  = context.Module.GetName();
                _context = context;
            }
            else
            {
                _module  = null;
                _context = new CodeContext(new PythonDictionary(), new ModuleContext(globals, DefaultContext.DefaultPythonContext));
            }

            _defaults = defaults == null ? ArrayUtils.EmptyObjects : defaults.ToArray();
            _code     = code;
            _name     = name;
            _doc      = code._initialDoc;
            Closure   = null;

            var scopeStatement = _code.PythonCode;

            if (scopeStatement.IsClosure)
            {
                throw new NotImplementedException("code containing closures is not supported");
            }
            scopeStatement.RewriteBody(FunctionDefinition.ArbitraryGlobalsVisitorInstance);

            _compat = CalculatedCachedCompat();
        }
示例#4
0
文件: TestTuple.cs 项目: zspitz/dlr
        public void TestNestedTupleSize()
        {
            int size = 8;

            Type[] args = new Type[size];
            for (int i = 0; i < size; i++)
            {
                if (i == 5)
                {
                    var nestedTupleType = MutableTuple.MakeTupleType(typeof(int), typeof(int));
                    args[i] = nestedTupleType;
                }
                else
                {
                    args[i] = typeof(int);
                }
            }

            var tupleType = MutableTuple.MakeTupleType(args);

            // these both fail - https://github.com/IronLanguages/dlr/issues/231
            //Assert.AreEqual(MutableTuple.GetSize(tupleType), size);
            //Assert.Throws<ArgumentException>(() => MutableTuple.GetAccessPath(tupleType, size).ToArray());
            Assert.AreEqual(MutableTuple.GetSize(tupleType), size + 1);
            Assert.Throws <InvalidOperationException>(() => MutableTuple.GetAccessPath(tupleType, size).ToArray());
        }
示例#5
0
 internal static void CopyTupleFields(MutableTuple /*!*/ src, MutableTuple /*!*/ dst)
 {
     Debug.Assert(src.Capacity == dst.Capacity);
     for (int i = 0; i < src.Capacity; i++)
     {
         dst.SetValue(i, src.GetValue(i));
     }
 }
示例#6
0
        public void MutableTuple_ChangeValue_ExpectedChange()
        {
            MutableTuple <string, string> test = new MutableTuple <string, string>("V1", "V2");

            test.First = "Test";
            Assert.That(test.First, Is.EqualTo("Test"));
            Assert.That(test.Second, Is.EqualTo("V2"));
        }
    /// <summary>
    /// Takes a single tile on the map and calculates all paths to every other tile, starting from that initial tile.
    /// returns those pathways as a Dictionary
    /// it's keys are ints representing the distance required to travel
    /// its values are dictionaries with keys representing the destination and values representing the Queue path to follow
    /// </summary>
    /// <param name="start"> (x, y) coordinate to start from</param>
    public Dictionary <int, Dictionary <Vector2Int, Queue <Vector2Int> > > ScanFromStart(Vector2Int start)
    {
        // create two data structures: tiles that need to be visited and tiles already visited
        // visited is just a set of Vector2Int
        // toVisit is a queue, storing the tile to visit, the path taken to get there, and the total movement spent to reach the tile
        HashSet <Vector2Int> visited = new HashSet <Vector2Int>();
        Queue <MutableTuple <Vector2Int, MutableTuple <Queue <Vector2Int>, int> > > toVisit = new Queue <MutableTuple <Vector2Int, MutableTuple <Queue <Vector2Int>, int> > >();

        Dictionary <int, Dictionary <Vector2Int, Queue <Vector2Int> > > result = new Dictionary <int, Dictionary <Vector2Int, Queue <Vector2Int> > >();

        toVisit.Enqueue(new MutableTuple <Vector2Int, MutableTuple <Queue <Vector2Int>, int> >(start, new MutableTuple <Queue <Vector2Int>, int>(new Queue <Vector2Int>(), 0)));

        while (toVisit.Count != 0)
        {
            // get the next tile in line to visit
            MutableTuple <Vector2Int, MutableTuple <Queue <Vector2Int>, int> > current = toVisit.Dequeue();

            // make sure that this tile is valid to be visited. an Invalid tile:
            //      has already been visited            does not exist within weightedMap         or has a weight of OBSTRUCTED AND is not the starting tile
            if (visited.Contains(current.Item1) || (!weightedMap.ContainsKey(current.Item1)) || (weightedMap[current.Item1] == (int)TileWeight.OBSTRUCTED && current.Item1 != start))
            {
                continue;
            }

            // this is the first time that we've reached a tile this much movement away. set it up.
            if (!result.ContainsKey(current.Item2.Item2))
            {
                result.Add(current.Item2.Item2, new Dictionary <Vector2Int, Queue <Vector2Int> >());
            }

            // This is the first time that we've reached this tile with this amount of movement. it is the shortest path. store it
            if (!result[current.Item2.Item2].ContainsKey(current.Item1))
            {
                result[current.Item2.Item2].Add(current.Item1, current.Item2.Item1);
            }

            // check each neighbor of this tile
            Dictionary <Vector2Int, Direction> neighbors = MapMath.GetNeighbors(current.Item1);
            foreach (Vector2Int neighbor in neighbors.Keys)
            {
                int movement = current.Item2.Item2;
                if (weightedMap.ContainsKey(neighbor))
                {
                    movement += weightedMap[neighbor];
                }

                Queue <Vector2Int> newPath = new Queue <Vector2Int>(current.Item2.Item1.ToArray());
                newPath.Enqueue(neighbor);
                // Debug.Log("Need to visit Tile " + neighbor);
                toVisit.Enqueue(new MutableTuple <Vector2Int, MutableTuple <Queue <Vector2Int>, int> >(neighbor, new MutableTuple <Queue <Vector2Int>, int>(newPath, movement)));
            }

            // this tile has been officially 'visited'
            visited.Add(current.Item1);
        }

        return(result);
    }
示例#8
0
 internal Type GetClosureTupleType() {
     if (TupleCells > 0) {
         Type[] args = new Type[TupleCells];
         for (int i = 0; i < TupleCells; i++) {
             args[i] = typeof(ClosureCell);
         }
         return MutableTuple.MakeTupleType(args);
     }
     return null;
 }
示例#9
0
        public override Expression Reduce()
        {
            Expression res = _tupleExpr.Value;

            foreach (PropertyInfo pi in MutableTuple.GetAccessPath(_tupleType.Value, Index))
            {
                res = Expression.Property(res, pi);
            }
            return(res);
        }
示例#10
0
        private MutableTuple <int, object> GetDataTuple()
        {
            MutableTuple <int, object> res = _data as MutableTuple <int, object>;

            if (res == null)
            {
                res = GetBigData(_data);
            }
            return(res);
        }
    // This function will evaluate the tiles in which this ability can reach, and update the affectableTiles Dictionary to its correct state
    public void EvaluateAffectableTiles()
    {
        ResetAffectableTiles();
        ResetAffectableUnits();

        // Attacks have affectable areas. Therefore, only those types of UnitAbilities need to be evaluated
        // if not an Attack, this function will only add the tile that the unit is occupying
        if (!(ability.GetType().IsSubclassOf(typeof(Attack))))
        {
            // add to affectableTiles, creating a new set at the key if it hasn't been made yet
            if (!affectableTiles.ContainsKey(sourceUnit.GetMapPosition()))
            {
                affectableTiles[sourceUnit.GetMapPosition()] = new HashSet <Tuple <Vector2Int, Direction> >();
            }
            affectableTiles[sourceUnit.GetMapPosition()].Add(new Tuple <Vector2Int, Direction>(sourceUnit.GetMapPosition(), Direction.S));

            affectableUnits[sourceUnit.GetMapPosition()] = new MutableTuple <Unit, float>(sourceUnit, 0.0f);
            return;
        }

        // otherwise, if this ability is a type of Attack, iterate through
        else
        {
            // iterate three times: first for all possible moveable tiles, second for all cardinal directions, third for each tile in the area of effect at that location
            List <Direction> directionsToCheck = new List <Direction> {
                Direction.N, Direction.S, Direction.E, Direction.W
            };
            foreach (Vector2Int tile in sourceUnit.MoveableTiles.Keys)
            {
                foreach (Direction direction in directionsToCheck)
                {
                    List <Vector2Int> areaOfEffect = (ability as Attack).GetAreaOfEffect(tile, direction);

                    foreach (Vector2Int affectedTile in areaOfEffect)
                    {
                        // if this tile Key is new to the Dictionary:
                        if (!affectableTiles.ContainsKey(affectedTile))
                        {
                            // create the HashSet for this Key
                            affectableTiles[affectedTile] = new HashSet <Tuple <Vector2Int, Direction> >();

                            // check if there's a Unit here. if there is one and it's new, add it to the affectableUnits
                            Unit searchResult = sourceUnit.globalPositionalData.SearchLocation(affectedTile);
                            if (searchResult != null && !affectableUnits.ContainsKey(affectedTile))
                            {
                                affectableUnits[affectedTile] = new MutableTuple <Unit, float>(searchResult, 0.0f);
                            }
                        }
                        // add the movement information to the HashSet at this Key. (If it already exists, it will automatically do nothing since its a Set)
                        affectableTiles[affectedTile].Add(new Tuple <Vector2Int, Direction>(tile, direction));
                    }
                }
            }
        }
    }
        public void CanUseTuple()
        {
            // ARRANGE & ACT
            var tuple1 = new MutableTuple <string, int>("key", 7);
            var tuple2 = new MutableTuple <string, int>("key", 7);

            // ASSERT
            Assert.AreEqual("key", tuple1.Item1);
            Assert.AreEqual(7, tuple1.Item2);
            Assert.AreEqual(tuple1, tuple2);
        }
示例#13
0
 internal Type GetVariableType(Compiler compiler, out IEnumerable <PropertyInfo> tupleAccessPath, out bool localInTuple)
 {
     localInTuple    = (this._tupleIndex >= 0) && (compiler.Optimize || (this._tupleIndex < 9));
     tupleAccessPath = null;
     if (localInTuple)
     {
         tupleAccessPath = MutableTuple.GetAccessPath(compiler.LocalVariablesTupleType, this._tupleIndex);
         return(tupleAccessPath.Last <PropertyInfo>().PropertyType);
     }
     return(typeof(object));
 }
示例#14
0
        public static MSA.Expression /*!*/ GetVariableAccessor(MSA.Expression /*!*/ tupleVariable, int tupleFieldIndex)
        {
            MSA.Expression accessor = tupleVariable;

            foreach (var property in MutableTuple.GetAccessPath(tupleVariable.Type, tupleFieldIndex))
            {
                accessor = Ast.Property(accessor, property);
            }

            return(accessor);
        }
示例#15
0
 private Type /*!*/ MakeLocalsTupleType()
 {
     // Note: The actual tuple type might be a subclass of the type used here. Accesses to the additional fields would need to down-cast.
     // This will only happen if a hidden lifted variable is defined, which is needed only for flip-flop operator so far.
     Type[] types = new Type[LiftedVisibleVariableCount];
     for (int i = 0; i < types.Length; i++)
     {
         types[i] = typeof(object);
     }
     return(MutableTuple.MakeTupleType(types));
 }
示例#16
0
        private static MutableTuple <int, object> GetBigData(MutableTuple data)
        {
            MutableTuple <int, object> smallGen;

            do
            {
                data = (MutableTuple)data.GetValue(0);
            } while ((smallGen = (data as MutableTuple <int, object>)) == null);

            return(smallGen);
        }
示例#17
0
 internal MSAst.MethodCallExpression CreateLocalContext(MSAst.Expression parentContext) {
     var closureVariables = _closureVariables;
     if (_closureVariables == null) {
         closureVariables = new ClosureInfo[0];
     }
     return Ast.Call(
         AstMethods.CreateLocalContext,
         parentContext,
         MutableTuple.Create(ArrayUtils.ConvertAll(closureVariables, x => GetClosureCell(x))),
         Ast.Constant(ArrayUtils.ConvertAll(closureVariables, x => x.AccessedInScope ? x.Variable.Name : null))
     );
 }
示例#18
0
 private void DecrementRunningFuncCounter(string methodId = "")
 {
     Interlocked.Decrement(
         ref _methodIdCounters.GetOrAdd(
             methodId,
             x => MutableTuple.Create(0)
             ).Item1
         );
     if (Interlocked.Decrement(ref _runningFuncCounter) <= 0)
     {
         _zeroFuncTrigger.OnNext(null);
     }
 }
示例#19
0
        private Tuple <Type, Dictionary <string, int> > FinishAnalysis(bool scriptCmdlet = false)
        {
            List <Block> list             = Block.GenerateReverseDepthFirstOrder(this._entryBlock);
            BitArray     assignedBitArray = new BitArray(this._variables.Count);

            list[0]._visitData = assignedBitArray;
            this.AnalyzeBlock(assignedBitArray, list[0]);
            for (int i = 1; i < list.Count; i++)
            {
                Block block = list[i];
                assignedBitArray = new BitArray(this._variables.Count);
                assignedBitArray.SetAll(true);
                block._visitData = assignedBitArray;
                int num2 = 0;
                foreach (Block block2 in block._predecessors)
                {
                    if (block2._visitData != null)
                    {
                        num2++;
                        assignedBitArray.And((BitArray)block2._visitData);
                    }
                }
                this.AnalyzeBlock(assignedBitArray, block);
            }
            var v = this._variables.Values.Where(x => x.LocalTupleIndex == -2).SelectMany(x => x.AssociatedAsts);

            foreach (Ast ast in v)
            {
                FixTupleIndex(ast, -2);
            }
            VariableAnalysisDetails[] detailsArray = (from details in this._variables.Values
                                                      where details.LocalTupleIndex >= 0
                                                      orderby details.LocalTupleIndex
                                                      select details).ToArray <VariableAnalysisDetails>();
            Dictionary <string, int> dictionary = new Dictionary <string, int>(0, StringComparer.OrdinalIgnoreCase);

            for (int j = 0; j < detailsArray.Length; j++)
            {
                VariableAnalysisDetails details = detailsArray[j];
                string name = details.Name;
                dictionary.Add(name, j);
                if (details.LocalTupleIndex != j)
                {
                    foreach (Ast ast2 in details.AssociatedAsts)
                    {
                        FixTupleIndex(ast2, j);
                    }
                }
            }
            return(Tuple.Create <Type, Dictionary <string, int> >(MutableTuple.MakeTupleType((from l in detailsArray select l.Type).ToArray <Type>()), dictionary));
        }
示例#20
0
        private Unit MkSubRuleLocators_Fold(
            Term t,
            Term output,
            LinkedList <Tuple <Term, int> > placeStack,
            MutableTuple <int> matchCount)
        {
            placeStack.RemoveLast();
            while (matchCount.Item1 > 0 && t == output.Args[matchCount.Item1 - 1])
            {
                --matchCount.Item1;
            }

            return(default(Unit));
        }
示例#21
0
        internal PythonGenerator(PythonFunction function, Func <MutableTuple, object> /*!*/ next, MutableTuple data)
        {
            _function  = function;
            _next      = next;
            _data      = data;
            _dataTuple = GetDataTuple();
            State      = GeneratorRewriter.NotStarted;

            if (_LastFinalizer == null || (_finalizer = Interlocked.Exchange(ref _LastFinalizer, null)) == null)
            {
                _finalizer = new GeneratorFinalizer(this);
            }
            else
            {
                _finalizer.Generator = this;
            }
        }
示例#22
0
        internal PythonFunction(CodeContext /*!*/ context, FunctionCode funcInfo, object modName, object[] defaults, MutableTuple closure)
        {
            Assert.NotNull(context, funcInfo);

            _context  = context;
            _defaults = defaults ?? ArrayUtils.EmptyObjects;
            _code     = funcInfo;
            _doc      = funcInfo._initialDoc;
            _name     = funcInfo.co_name;

            Debug.Assert(_defaults.Length <= _code.co_argcount);
            if (modName != Uninitialized.Instance)
            {
                _module = modName;
            }

            Closure = closure;
            _compat = CalculatedCachedCompat();
        }
示例#23
0
        /// <summary>
        /// If a subrule returns output Sub(t1,...,tn) from input with inputLocations, then finds all locations
        /// of the terms t1, ..., tn.
        /// </summary>
        private LinkedList <Locator> MkSubRuleLocators(
            Node subRuleHead,
            Term input,
            Term output,
            LinkedList <Locator> inputLocations)
        {
            var outputLocs = new LinkedList <Locator>();
            var placeStack = new LinkedList <Tuple <Term, int> >();

            placeStack.AddLast(new Tuple <Term, int>(input, -1));
            var matchCount = new MutableTuple <int>();

            matchCount.Item1 = 0;
            input.Compute <Unit>(
                (x, s) => MkSubRuleLocators_Unfold(x, output, placeStack, inputLocations, outputLocs, subRuleHead, matchCount),
                (x, ch, s) => MkSubRuleLocators_Fold(x, output, placeStack, matchCount));
            Contract.Assert(placeStack.Count == 0 && matchCount.Item1 == 0 && outputLocs.Count > 0);
            return(outputLocs);
        }
示例#24
0
        private void GetCapacityRelative <AI>(VehicleInfo info, AI ai, ref Dictionary <string, MutableTuple <float, int> > relativeParts, out int totalCapacity, bool noLoop = false) where AI : VehicleAI
        {
            if (info == null)
            {
                totalCapacity = 0;
                return;
            }

            totalCapacity = UpdateDefaultCapacity(ai);
            if (relativeParts.ContainsKey(info.name))
            {
                relativeParts[info.name].Second++;
            }
            else
            {
                relativeParts[info.name] = MutableTuple.New((float)totalCapacity, 1);
            }
            if (!noLoop)
            {
                try
                {
                    foreach (VehicleInfo.VehicleTrailer trailer in info.m_trailers)
                    {
                        if (trailer.m_info != null)
                        {
                            GetCapacityRelative(trailer.m_info, trailer.m_info.m_vehicleAI, ref relativeParts, out int capacity, true);
                            totalCapacity += capacity;
                        }
                    }

                    for (int i = 0; i < relativeParts.Keys.Count; i++)
                    {
                        relativeParts[relativeParts.Keys.ElementAt(i)].First /= totalCapacity;
                    }
                }
                catch (Exception e)
                {
                    LogUtils.DoLog($"ERRO AO OBTER CAPACIDADE REL: [{info}] {e} {e.Message}\n{e.StackTrace}");
                }
            }
        }
示例#25
0
        public override bool Equals(object obj)
        {
            MutableTuple <T1, T2> p = obj as MutableTuple <T1, T2>;

            if (obj == null)
            {
                return(false);
            }

            if (Item1 == null)
            {
                if (p.Item1 != null)
                {
                    return(false);
                }
            }
            else
            {
                if (p.Item1 == null || !Item1.Equals(p.Item1))
                {
                    return(false);
                }
            }

            if (Item2 == null)
            {
                if (p.Item2 != null)
                {
                    return(false);
                }
            }
            else
            {
                if (p.Item2 == null || !Item2.Equals(p.Item2))
                {
                    return(false);
                }
            }

            return(true);
        }
        public override void SaveChanges()
        {
            AssignIds();
            SaveReferencesIds();
            var tuple
                = new MutableTuple <Customer[], Order[], Car[]>
                {
                Item1 = GetCustomers().OrderBy(c => c.CustomerId).ToArray(),
                Item2 = GetOrders().OrderBy(o => o.OrderId).ToArray(),
                Item3 = GetCars().OrderBy(c => c.CarId).ToArray()
                };

            try
            {
                XmlHelper <MutableTuple <Customer[], Order[], Car[]> > .Save(FilePath, tuple);
            }
            catch (Exception e)
            {
                Logger.Log(e);
                Logger.SetError(this);
            }
        }
示例#27
0
        internal PythonFunction(CodeContext /*!*/ context, FunctionCode funcInfo, object modName, object[] defaults, PythonDictionary kwdefaults, PythonDictionary annotations, MutableTuple closure)
        {
            Assert.NotNull(context, funcInfo);

            _context       = context;
            _defaults      = defaults ?? ArrayUtils.EmptyObjects;
            __kwdefaults__ = kwdefaults;
            _code          = funcInfo;
            _doc           = funcInfo._initialDoc;
            _name          = funcInfo.co_name;
            _annotations   = annotations ?? new PythonDictionary();

            Debug.Assert(_defaults.Length <= _code.co_argcount);
            Debug.Assert((__kwdefaults__?.Count ?? 0) <= _code.co_kwonlyargcount);
            if (modName != Uninitialized.Instance)
            {
                _module = modName;
            }

            Closure = closure;
            FunctionCompatibility = CalculatedCachedCompat();
        }
示例#28
0
 private void IncrementRunningFuncCounter(string methodId = "")
 {
     Interlocked.Increment(ref _runningFuncCounter);
     Interlocked.Increment(
         ref _methodIdCounters.GetOrAdd(
             methodId,
             x => MutableTuple.Create(0)
             ).Item1
         );
     if (_state != EDisposableObjectState.Initialized)
     {
         Interlocked.Decrement(ref _runningFuncCounter);
         Interlocked.Decrement(
             ref _methodIdCounters.GetOrAdd(
                 methodId,
                 x => MutableTuple.Create(0)
                 ).Item1
             );
         throw new WrongDisposableObjectStateException()
               {
                   ActualState = _state
               };
     }
 }
示例#29
0
        private IEnumerable <Term> MkSubRuleLocators_Unfold(
            Term t,
            Term output,
            LinkedList <Tuple <Term, int> > placeStack,
            LinkedList <Locator> inputLocations,
            LinkedList <Locator> outputLocations,
            Node subRuleHead,
            MutableTuple <int> matchCount)
        {
            ////  t may extend the match (possibly one or more times)
            if (t == output.Args[matchCount.Item1])
            {
                while (matchCount.Item1 < output.Symbol.Arity && t == output.Args[matchCount.Item1])
                {
                    ++matchCount.Item1;
                }
            }

            //// The match is complete.
            if (matchCount.Item1 >= output.Symbol.Arity)
            {
                int i       = 0;
                var argLocs = new LinkedList <Locator> [output.Symbol.Arity];
                var prev    = inputLocations;
                LinkedList <Locator> next;
                foreach (var place in placeStack)
                {
                    if (place.Item2 < 0)
                    {
                        next = prev;
                    }
                    else
                    {
                        next = new LinkedList <Locator>();
                        foreach (var l in prev)
                        {
                            next.AddLast(l[place.Item2]);
                        }
                    }

                    while (i < output.Symbol.Arity && output.Args[i] == place.Item1)
                    {
                        argLocs[i] = next;
                        ++i;
                    }

                    if (i >= output.Symbol.Arity)
                    {
                        break;
                    }

                    prev = next;
                }

                foreach (var alocs in Locator.MkPermutations(argLocs, maxLocationsPerProof))
                {
                    outputLocations.AddLast(new CompositeLocator(subRuleHead.Span, alocs));
                }

                yield break;
            }

            for (int i = 0; i < t.Symbol.Arity; ++i)
            {
                placeStack.AddLast(new Tuple <Term, int>(t.Args[i], i));
                yield return(t.Args[i]);
            }
        }
示例#30
0
        internal Expression Reduce(bool shouldInterpret, bool emitDebugSymbols, int compilationThreshold,
                                   IList <ParameterExpression> parameters, Func <Expression <Func <MutableTuple, object> >,
                                                                                 Expression <Func <MutableTuple, object> > > bodyConverter)
        {
            _state   = LiftVariable(Expression.Parameter(typeof(int), "state"));
            _current = LiftVariable(Expression.Parameter(typeof(object), "current"));

            // lift the parameters into the tuple
            foreach (ParameterExpression pe in parameters)
            {
                LiftVariable(pe);
            }
            DelayedTupleExpression liftedGen = LiftVariable(_generatorParam);
            // Visit body
            Expression body = Visit(_body);

            Debug.Assert(_returnLabels.Count == 1);

            // Add the switch statement to the body
            int count = _yields.Count;
            var cases = new SwitchCase[count + 1];

            for (int i = 0; i < count; i++)
            {
                cases[i] = Expression.SwitchCase(Expression.Goto(_yields[i].Label), AstUtils.Constant(_yields[i].State));
            }
            cases[count] = Expression.SwitchCase(Expression.Goto(_returnLabels.Peek()), AstUtils.Constant(Finished));

            // Create the lambda for the PythonGeneratorNext, hoisting variables
            // into a tuple outside the lambda
            Expression[] tupleExprs = new Expression[_vars.Count];
            foreach (var variable in _orderedVars)
            {
                // first 2 are our state & out var
                if (variable.Value.Index >= 2 && variable.Value.Index < (parameters.Count + 2))
                {
                    tupleExprs[variable.Value.Index] = parameters[variable.Value.Index - 2];
                }
                else
                {
                    tupleExprs[variable.Value.Index] = Expression.Default(variable.Key.Type);
                }
            }

            Expression          newTuple  = MutableTuple.Create(tupleExprs);
            Type                tupleType = _tupleType.Value = newTuple.Type;
            ParameterExpression tupleExpr = _tupleExpr.Value = Expression.Parameter(tupleType, "tuple");
            ParameterExpression tupleArg  = Expression.Parameter(typeof(MutableTuple), "tupleArg");

            _temps.Add(_gotoRouter);
            _temps.Add(tupleExpr);

            // temps for the outer lambda
            ParameterExpression tupleTmp = Expression.Parameter(tupleType, "tuple");
            ParameterExpression ret      = Expression.Parameter(typeof(PythonGenerator), "ret");

            var innerLambda = Expression.Lambda <Func <MutableTuple, object> >(
                Expression.Block(
                    _temps.ToArray(),
                    Expression.Assign(
                        tupleExpr,
                        Expression.Convert(
                            tupleArg,
                            tupleType
                            )
                        ),
                    Expression.Switch(Expression.Assign(_gotoRouter, _state), cases),
                    body,
                    MakeAssign(_state, AstUtils.Constant(Finished)),
                    Expression.Label(_returnLabels.Peek()),
                    _current
                    ),
                _name,
                new ParameterExpression[] { tupleArg }
                );

            // Generate a call to PythonOps.MakeGeneratorClosure(Tuple data, object generatorCode)
            return(Expression.Block(
                       new[] { tupleTmp, ret },
                       Expression.Assign(
                           ret,
                           Expression.Call(
                               typeof(PythonOps).GetMethod("MakeGenerator"),
                               parameters[0],
                               Expression.Assign(tupleTmp, newTuple),
                               emitDebugSymbols ?
                               (Expression)bodyConverter(innerLambda) :
                               (Expression)Expression.Constant(
                                   new LazyCode <Func <MutableTuple, object> >(
                                       bodyConverter(innerLambda),
                                       shouldInterpret,
                                       compilationThreshold
                                       ),
                                   typeof(object)
                                   )
                               )
                           ),
                       new DelayedTupleAssign(
                           new DelayedTupleExpression(liftedGen.Index, new StrongBox <ParameterExpression>(tupleTmp), _tupleType, typeof(PythonGenerator)),
                           ret
                           ),
                       ret
                       ));
        }