Beispiel #1
0
        public Item Invoke(SymbolSpace space, List <Item> items)
        {
            if (!this.EvaluateDemands(items))
            {
                throw new Exception("Failed demands.");
            }

            var result = this.Function(space, items);

            if (result == null)
            {
                if (this.ReturnType != ItemType.None && this.ReturnType != ItemType.Any)
                {
                    throw new Exception("Non-void function returned void.");
                }
            }
            else
            {
                if (this.ReturnType != ItemType.Something &&
                    this.ReturnType != ItemType.Any &&
                    this.ReturnType != result.ItemType)
                {
                    throw new Exception("Function returned improper type.");
                }
            }

            return(result);
        }
Beispiel #2
0
        /// <summary>
        ///     Updates the weight of <paramref name="symbol" /> based on the provided <paramref name="weightModifier" />.
        ///     The modification can be either positive or negative.
        ///     This function runs in O(weightModifier * height).  Expected is E(height).
        /// </summary>
        private void UpdateSymbolInternal(SymbolSpace symbol, int weightModifier)
        {
            // Find out if the symbol is in the tree
            uint index;

            if (!_map.TryGetValue(symbol, out index))
            {
                index = AddNewSymbol(symbol);
                ToDot(DotOp.AddSymbol, index, 0, 0, symbol.Symbol);
            }

            if (weightModifier < 0 &&
                _entries[index].Weight < -weightModifier)
            {
                throw new ArgumentOutOfRangeException("weightModifier");
            }

            if (weightModifier < 0)
            {
                DecreaseIndex(index, Math.Abs(weightModifier));
            }
            else
            {
                IncreaseIndex(index, weightModifier);
            }
        }
Beispiel #3
0
            public static void Setup()
            {
                var invo = new InvokeableItem();
                var fn   = new Invokeable
                {
                    ReturnType = ItemType.Space,

                    Demands = InvokeableUtils.MakeDemands(
                        InvokeableUtils.DemandType(0, ItemType.List),
                        args => (args[0] as ListItem).Expression.HasEvenLength(),
                        args => (args[0] as ListItem).Expression
                        .GroupingSelect(2)
                        .All(pair => pair[0].ItemType == ItemType.Symbol)),

                    Function = (space, args) =>
                    {
                        var newSpace         = new SymbolSpace(space);
                        var symbolValuePairs = (args[0] as ListItem).Expression.GroupingSelect(2);

                        foreach (var pair in symbolValuePairs)
                        {
                            var symbol = pair[0] as SymbolItem;
                            newSpace.Bind(symbol.Name, pair[1]);
                        }

                        return(new SymbolSpaceItem(newSpace));
                    }
                };

                invo.AddInvokeable(fn);
                globalSpace.Bind("make-space", invo);
            }
Beispiel #4
0
        /// <summary>
        ///     Adds the new symbol to the list with a weight of zero as the last entry.
        ///     This function runs in O(map).
        /// </summary>
        /// <returns>
        ///     The index to the new symbol.
        /// </returns>
        private uint AddNewSymbol(SymbolSpace symbol)
        {
            var oldMinWeightEntry = MinWeightEntry;
            var movedSymbol       = _entries[oldMinWeightEntry].Symbol;

            {
                var newEntries = new Entry[_entries.Length + 2];
                Array.Copy(_entries, newEntries, _entries.Length);
                _entries = newEntries;
            }

            // Copy the previous entry
            _entries[oldMinWeightEntry + 1] = _entries[oldMinWeightEntry];

            // Make the old entry an internal node
            _entries[oldMinWeightEntry].FirstChildIndex = oldMinWeightEntry + 1;
            _entries[oldMinWeightEntry].Symbol.Clear();

            // Update the new entry
            _entries[oldMinWeightEntry + 2].Symbol = symbol;
            _entries[oldMinWeightEntry + 2].Height = 1;

            // Set parents
            _entries[oldMinWeightEntry + 1].ParentIndex = oldMinWeightEntry;
            _entries[oldMinWeightEntry + 2].ParentIndex = oldMinWeightEntry;

            RecomputeHeightsFrom(oldMinWeightEntry);

            _map[movedSymbol] = oldMinWeightEntry + 1;
            _map[symbol]      = oldMinWeightEntry + 2;

            return(oldMinWeightEntry + 2);
        }
Beispiel #5
0
        private List <Item> Flatten(SymbolSpace space)
        {
            var         current = new List <Item>(this.Expression);
            List <Item> output;

            Func <List <Item>, bool> anyNonquoted = l => l
                                                    .Select(item => item as EvaluateableItem)
                                                    .Where(item => item != null)
                                                    .Count(item => !item.IsQuoted) > 0;

            // Evaluate all non-quoted while there are still non-quoted.
            while (anyNonquoted(current))
            {
                output = new List <Item>();

                foreach (var item in current)
                {
                    Item evaluated;

                    if (item is EvaluateableItem)
                    {
                        var evaluateable = item as EvaluateableItem;
                        evaluated = evaluateable.IsQuoted
                                                        ? evaluateable
                                                        : evaluateable.Evaluate(space);
                    }
                    else
                    {
                        evaluated = item;
                    }

                    output.Add(evaluated);
                }

                current = output;
            }

            // Evaluate all quoted items *ONCE*.
            output = new List <Item>();
            foreach (var item in current)
            {
                Item evaluated;

                if (item is EvaluateableItem)
                {
                    var evaluateable = item as EvaluateableItem;
                    evaluated = evaluateable.IsQuoted
                                                ? evaluateable.Evaluate(space)
                                                : evaluateable;
                }
                else
                {
                    evaluated = item;
                }

                output.Add(evaluated);
            }

            return(output);
        }
Beispiel #6
0
        private static Item Deref(SymbolSpace space, SymbolItem symbol)
        {
            var reference = space.Lookup(symbol.Name);

            return(reference is EvaluateableItem
                                ? (reference as EvaluateableItem).Quote()
                                : reference);
        }
Beispiel #7
0
        public override Item Evaluate(SymbolSpace space)
        {
            if (this.IsQuoted)
            {
                this.IsQuoted = false;
                return(this);
            }

            return(this.Flatten(this.BoundSpace ?? space));
        }
Beispiel #8
0
        /// <summary>
        ///     Returns the weight of <paramref name="symbol" /> in the tree.
        ///     This function runs in O(map).
        /// </summary>
        /// <returns>The weight of the symbol or zero if not found.</returns>
        private uint GetWeightInternal(SymbolSpace symbol)
        {
            uint index;

            if (_map.TryGetValue(symbol, out index))
            {
                return(_entries[index].Weight);
            }
            return(0);
        }
Beispiel #9
0
        /// <summary>
        ///     Returns the level in the tree <paramref name="symbol" /> occurs at.
        ///     This function runs in O(map + level).
        /// </summary>
        private uint GetLevelInternal(SymbolSpace symbol)
        {
            uint level = 0;

            for (var index = _map[symbol]; index != Root; index = _entries[index].ParentIndex)
            {
                ++level;
            }
            return(level);
        }
Beispiel #10
0
        public Item Invoke(SymbolSpace space, List <Item> items)
        {
            foreach (var invokeable in this.invokeables)
            {
                if (invokeable.EvaluateDemands(items))
                {
                    return(invokeable.Invoke(space, items));
                }
            }

            throw new Exception("No matching signature in invokeable collection.");
        }
Beispiel #11
0
        /// <summary>
        /// Retrieves a symbol.  If the bit sequence from <paramref name="bitReader"/>
        /// identifies a symbol literal, <paramref name="symbolReader"/> is called.
        /// </summary>
        public TSymbolType GetSymbol(ReadBitDelegate bitReader, ReadSymbolDelegate <TSymbolType> symbolReader)
        {
            SymbolSpace result = GetSymbolInternal(bitReader);

            if (result.IsValid)
            {
                UpdateSymbolInternal(result, 1);
                UpdateSymbolInternal(SymbolSpace.NotYetTransmitted, GetTweak(result.Symbol, false));
                return(result.Symbol);
            }

            result = symbolReader();
            UpdateSymbolInternal(SymbolSpace.NotYetTransmitted, GetTweak(result.Symbol, true));
            UpdateSymbolInternal(result, 1);
            return(result.Symbol);
        }
Beispiel #12
0
        public Item Flatten(SymbolSpace space)
        {
            var current = space.Lookup(this.Name);

            while (current.ItemType == ItemType.Symbol)
            {
                var symbol = (SymbolItem)current;

                if (symbol.IsQuoted)
                {
                    break;
                }

                current = symbol.Evaluate(space);
            }

            return(current);
        }
Beispiel #13
0
 public static void SetupBuiltins(SymbolSpace space)
 {
     globalSpace = space;
     Unless.Setup();
     When.Setup();
     If.Setup();
     Let.Setup();
     Equal.Setup();
     Bind.Setup();
     DerefSymbol.Setup();
     Evaluate.Setup();
     In.Setup();
     Print.Setup();
     Negate.Setup();
     Quote.Setup();
     Unquote.Setup();
     MakeSpace.Setup();
     Def.Setup();
     Get.Setup();
     Add.Setup();
     Defn.Setup();
 }
Beispiel #14
0
        public override Item Evaluate(SymbolSpace space)
        {
            if (this.IsQuoted)
            {
                this.IsQuoted = false;
                return(this);
            }

            var exp = this.Flatten(space);

            var head = exp.First() as InvokeableItem;
            var tail = exp.Skip(1).ToList();

            if (head == null)
            {
                throw new Exception();
            }

            var result = head.Invoke(space, tail);

            return(result);
        }
Beispiel #15
0
            public static void Setup()
            {
                const int typeIndex   = 0;
                const int paramsIndex = 1;
                const int bodyIndex   = 2;

                Func <Item, List <Tuple <Item, Item> > > groupArguments = l =>
                                                                          (l as ListItem).Expression
                                                                          .GroupingSelect(2, xs => new Tuple <Item, Item>(xs[0], xs[1]));

                Func <List <Item>, ListItem> getParams = args => (args[paramsIndex] as ListItem);

                // now to the meat of things

                var invo = new InvokeableItem();

                var fn = new Invokeable
                {
                    ReturnType = ItemType.Invokeable,

                    Demands = InvokeableUtils.MakeDemands(
                        InvokeableUtils.DemandTypes(ItemType.Type, ItemType.List, ItemType.List),
                        args => args.Count == 3,
                        args => getParams(args).Expression.HasEvenLength(),
                        args => groupArguments(getParams(args)).All(pair =>
                                                                    pair.Item1.ItemType == ItemType.Symbol &&
                                                                    pair.Item2.ItemType == ItemType.Type)
                        ),

                    Function = (space, args) =>
                    {
                        var returnType   = args[typeIndex] as TypeItem;
                        var argumentList = groupArguments(args[paramsIndex]);
                        var body         = args[bodyIndex] as ListItem;

                        var argumentTypes =
                            argumentList
                            .Select(argument => (argument.Item2 as TypeItem).Type)
                            .ToArray();

                        var resultingInvokeable = new InvokeableItem();

                        resultingInvokeable.AddInvokeable(new Invokeable()
                        {
                            ReturnType = returnType.Type,

                            Demands = InvokeableUtils.MakeDemands(InvokeableUtils.DemandTypes(argumentTypes)),

                            // create symbol space,
                            // bind fnargs,
                            // evaluate body with new symbol space
                            Function = (fnspace, fnargs) => {
                                var newSpace = new SymbolSpace(space);

                                for (var index = 0; index < fnargs.Count; index++)
                                {
                                    newSpace.Bind(
                                        (argumentList[index].Item1 as SymbolItem).Name,
                                        fnargs[index]);
                                }

                                body = body.Unquote() as ListItem;
                                return(body.Evaluate(newSpace));
                            }
                        });

                        return(resultingInvokeable);
                    }
                };

                invo.AddInvokeable(fn);

                globalSpace.Bind("=>", invo);
            }
Beispiel #16
0
 public SymbolSpaceItem(SymbolSpace space) : base(ItemType.Space)
 {
     this.Space = space;
 }
Beispiel #17
0
 public SymbolItem(string name, SymbolSpace space) : base(ItemType.Symbol)
 {
     this.Name       = name;
     this.BoundSpace = space;
 }
Beispiel #18
0
 /// <summary>
 ///     Converts writing <paramref name="symbol" /> to writing based on its corresponding index in the tree.
 /// </summary>
 private void WriteCodeInternal(SymbolSpace symbol, WriteBitDelegate bitWriter)
 {
     WriteCode(_map[symbol], bitWriter);
 }
Beispiel #19
0
 public abstract Item Evaluate(SymbolSpace space);