Example #1
0
        public override void Define(Maker into)
        {
            into.Define("==", (Cobject value1, Cobject value2) => Bool.From(Equals(value1, value2)));
            into.Define("!=", (Cobject value1, Cobject value2) => Bool.From(!Equals(value1, value2)));

            into.Define("compare", (Cobject value1, Cobject value2) => (Integer)((dynamic)value1).CompareTo((dynamic)value2));

            into.Define("<", (Cobject value1, Cobject value2) => Bool.From(((dynamic)value1).CompareTo((dynamic)value2) < 0));
            into.Define("<=", (Cobject value1, Cobject value2) => Bool.From(((dynamic)value1).CompareTo((dynamic)value2) <= 0));
            into.Define(">", (Cobject value1, Cobject value2) => Bool.From(((dynamic)value1).CompareTo((dynamic)value2) > 0));
            into.Define(">=", (Cobject value1, Cobject value2) => Bool.From(((dynamic)value1).CompareTo((dynamic)value2) >= 0));

            into.Define("+", (Cobject value1, Cobject value2) => (dynamic)value1 + (dynamic)value2);
            into.Define("-", (Cobject value1, Cobject value2) => (dynamic)value1 - (dynamic)value2);
            into.Define("*", (Cobject value1, Cobject value2) => (dynamic)value1 * (dynamic)value2);
            into.Define("/", (Cobject value1, Cobject value2) => (dynamic)value1 / (dynamic)value2);
            into.Define("%", (Cobject value1, Cobject value2) => (dynamic)value1 % (dynamic)value2);

            into.Define("not", (Cobject value) => !(dynamic)value);
            into.Define("and", (Cobject value1, Cobject value2) => (dynamic)value1 & (dynamic)value2);
            into.Define("or", (Cobject value1, Cobject value2) => (dynamic)value1 | (dynamic)value2);
            into.Define("xor", (Cobject value1, Cobject value2) => (dynamic)value1 ^ (dynamic)value2);

            into.Define("neutral", () => Neutrum.Neutral);

            into.Define("bool?", (Cobject value) => Bool.From(value is Bool));
            into.Define("true", () => Bool.True);
            into.Define("false", () => Bool.False);

            into.Define("integer", (Cobject value) => (Integer)(dynamic)value);
            into.Define("integer?", (Cobject value) => Bool.From(value is Integer));

            into.Define("sequence?", (Cobject value) => Bool.From(value is IEnumerable <Cobject>));
        }
Example #2
0
        public override void Define(Maker into)
        {
            into.Define("any?", value => Bool.From(!(value is IEnumerable <Cobject> enumerable) || enumerable.Any()));
            into.Define("empty?", value => Bool.From(value is IEnumerable <Cobject> enumerable && !enumerable.Any()));
            into.Define("atomic?", value => Bool.From(!(value is IEnumerable <Cobject>)));

            into.Define(
                "single?",
                value =>
            {
                if (value is IEnumerable <Cobject> enumerable)
                {
                    using (var enumerator = enumerable.GetEnumerator())
                    {
                        return(Bool.From(enumerator.MoveNext() && !enumerator.MoveNext()));
                    }
                }
                return(Bool.True);
            });

            into.Define(
                "first-rest",
                (scope, stack, value) =>
            {
                if (value is IEnumerable <Cobject> enumerable)
                {
                    // ReSharper disable once PossibleMultipleEnumeration
                    var first = enumerable.FirstOrDefault() ?? Sequence.Empty;
                    // ReSharper disable once PossibleMultipleEnumeration
                    var rest = Sequence.From(enumerable.Skip(1));
                    stack.Push(first);
                    stack.Push(rest);
                }
                else
                {
                    stack.Push(value);
                    stack.Push(Sequence.Empty);
                }
            });

            into.Define(",", (scope, stack, value1, value2) => Sequence.From(value1.Enumerate().Concat(value2.Enumerate())));
            into.Define(",,", (scope, stack, value1, value2, value3) => Sequence.From(value1.Enumerate().Concat(value2.Enumerate()).Concat(value3.Enumerate())));

            into.Define(
                "take",
                (Cobject values, Cobject count) =>
            {
                return(Sequence.From(Loop(values, (Integer)(dynamic)count)));

                IEnumerable <Cobject> Loop(Cobject _values, Integer _count)
                {
                    foreach (var value in _values.Enumerate())
                    {
                        if (Integer.Zero.CompareTo(_count) < 0)
                        {
                            yield return(value);

                            --_count;
                        }

                        if (Integer.Zero.CompareTo(_count) >= 0)
                        {
                            yield break;
                        }
                    }
                }
            });

            into.Define(
                "skip",
                (Cobject values, Cobject count) =>
            {
                return(Sequence.From(Loop(values, (Integer)(dynamic)count)));

                IEnumerable <Cobject> Loop(Cobject _values, Integer _count)
                {
                    foreach (var value in _values.Enumerate())
                    {
                        if (Integer.Zero.CompareTo(_count) < 0)
                        {
                            --_count;
                        }
                        else
                        {
                            yield return(value);
                        }
                    }
                }
            });

            into.Define(
                "range",
                (Cobject start, Cobject count) =>
            {
                return(Sequence.From(Loop(start, (Integer)(dynamic)count)));

                IEnumerable <Cobject> Loop(dynamic current, Integer _count)
                {
                    while (Integer.Zero.CompareTo(_count) < 0)
                    {
                        yield return(current);

                        current = ++current;
                        --_count;
                    }
                }
            });

            into.Define(
                "forever",
                value =>
            {
                return(Sequence.From(Loop(value)));

                IEnumerable <Cobject> Loop(Cobject _value)
                {
                    while (true)
                    {
                        yield return(_value);
                    }

                    // ReSharper disable once IteratorNeverReturns
                }
            });

            into.Define(
                "repeat",
                (Cobject value, Cobject count) =>
            {
                return(Sequence.From(Loop(value, (Integer)(dynamic)count)));

                IEnumerable <Cobject> Loop(Cobject _value, Integer _count)
                {
                    while (Integer.Zero.CompareTo(_count) < 0)
                    {
                        yield return(_value);

                        --_count;
                    }
                }
            });

            into.Define(
                "collapse",
                (scope, stack, values, action) =>
            {
                var first = true;
                foreach (var value in values.Enumerate())
                {
                    stack.Push(value);
                    if (!first)
                    {
                        action.Eval(scope, stack);
                    }
                    else
                    {
                        first = false;
                    }
                }

                if (first)
                {
                    stack.Push(Sequence.Empty);
                }
            });

            into.Define(
                "reduce",
                (scope, stack, values, seed, action) =>
            {
                stack.Push(seed);
                foreach (var value in values.Enumerate())
                {
                    stack.Push(value);
                    action.Eval(scope, stack);
                }
            });

            into.Define(
                "select",
                (scope, stack, values, action) =>
            {
                var result =
                    values is IEnumerable <Cobject> sequence
                               ? Sequence.From(sequence.Select(value => Eval(value, action)))
                               : Eval(values, action);

                stack.Push(result);

                Cobject Eval(Cobject _value, Cobject _action)
                {
                    stack.Push(_value);
                    _action.Eval(scope, stack);
                    return(stack.Pop());
                }
            });


            into.Define(
                "where",
                (scope, stack, values, predicate) =>
            {
                var sequence = values is IEnumerable <Cobject> enumerable
                                          ? enumerable
                                          : Enumerable.Repeat(values, 1);

                var result = Sequence.From(sequence.Where(value => Eval(value, predicate)));

                stack.Push(result);

                bool Eval(Cobject _value, Cobject _predicate)
                {
                    stack.Push(_value);
                    _predicate.Eval(scope, stack);
                    return(stack.Pop() is Bool b && b.Value);
                }
            });

            into.Define(
                "foreach",
                (scope, stack, sequence, action) =>
            {
                foreach (var value in sequence.Enumerate())
                {
                    stack.Push(value);
                    action.Eval(scope, stack);
                }
            });

            into.Define(
                "count",
                (scope, stack, values) =>
            {
                var count = Integer.Zero;

                foreach (var _ in values.Enumerate())
                {
                    ++count;
                }

                stack.Push(count);
            });
        }