Beispiel #1
0
        public static PValue RunStatically(StackContext sctx, PValue[] args)
        {
            if (args == null)
                throw new ArgumentNullException("args");
            if (sctx == null)
                throw new ArgumentNullException("sctx");

            var xss = new List<IEnumerable<PValue>>();
            foreach (var arg in args)
            {
                var xs = Map._ToEnumerable(sctx, arg);
                if (xs != null)
                    xss.Add(xs);
            }

            var n = xss.Count;
            if (n < 2)
                throw new PrexoniteException("Except requires at least two sources.");

            var t = new Dictionary<PValue, bool>();
            //All elements of the last source are considered candidates
            foreach (var x in xss[n - 1])
                if (!t.ContainsKey(x))
                    t.Add(x, true);

            for (var i = 0; i < n - 1; i++)
                foreach (var x in xss[i])
                    if (t.ContainsKey(x))
                        t.Remove(x);

            return sctx.CreateNativePValue(t.Keys);
        }
Beispiel #2
0
 /// <summary>
 ///     Sorts an IEnumerable.
 ///     <code>function sort(ref f1(a,b), ref f2(a,b), ... , xs)
 ///         { ... }</code>
 /// </summary>
 /// <param name = "sctx">The stack context in which the sort is performed.</param>
 /// <param name = "args">A list of sort expressions followed by the list to sort.</param>
 /// <returns>The a sorted copy of the list.</returns>
 public override PValue Run(StackContext sctx, PValue[] args)
 {
     if (sctx == null)
         throw new ArgumentNullException("sctx");
     if (args == null)
         args = new PValue[] {};
     var lst = new List<PValue>();
     if (args.Length == 0)
         return PType.Null.CreatePValue();
     else if (args.Length == 1)
     {
         var set = Map._ToEnumerable(sctx, args[0]);
         foreach (var x in set)
             lst.Add(x);
         return (PValue) lst;
     }
     else
     {
         var clauses = new List<PValue>();
         for (var i = 0; i + 1 < args.Length; i++)
             clauses.Add(args[i]);
         foreach (var x in Map._ToEnumerable(sctx, args[args.Length - 1]))
             lst.Add(x);
         lst.Sort(
             delegate(PValue a, PValue b)
                 {
                     foreach (var f in clauses)
                     {
                         var pdec = f.IndirectCall(sctx, new[] {a, b});
                         if (!(pdec.Type is IntPType))
                             pdec = pdec.ConvertTo(sctx, PType.Int);
                         var dec = (int) pdec.Value;
                         if (dec != 0)
                             return dec;
                     }
                     return 0;
                 });
         return (PValue) lst;
     }
 }
Beispiel #3
0
        protected override IEnumerable<PValue> CoroutineRun(ContextCarrier sctxCarrier,
            PValue[] args)
        {
            if (args == null)
                throw new ArgumentNullException("args");
            if (sctxCarrier == null)
                throw new ArgumentNullException("sctxCarrier");

            var sctx = sctxCarrier.StackContext;

            var xss = new List<IEnumerable<PValue>>();
            foreach (var arg in args)
            {
                var xs = Map._ToEnumerable(sctx, arg);
                if (xs != null)
                    xss.Add(xs);
            }

            var n = xss.Count;
            if (n < 2)
                throw new PrexoniteException("Intersect requires at least two sources.");

            var t = new Dictionary<PValue, int>();
            //All elements of the first source are considered candidates
            foreach (var x in xss[0])
                if (!t.ContainsKey(x))
                    t.Add(x, 1);

            var d = new Dictionary<PValue, object>();
            for (var i = 1; i < n - 1; i++)
            {
                foreach (var x in xss[i])
                    if ((!d.ContainsKey(x)) && t.ContainsKey(x))
                    {
                        d.Add(x, null); //only current source
                        t[x]++;
                    }
                d.Clear();
            }

            foreach (var x in xss[n - 1])
                if ((!d.ContainsKey(x)) && t.ContainsKey(x))
                {
                    d.Add(x, null); //only current source
                    var k = t[x] + 1;
                    if (k == n)
                        yield return x;
                }
        }
Beispiel #4
0
        protected override IEnumerable<PValue> CoroutineRun(ContextCarrier sctxCarrier,
            PValue[] args)
        {
            if (args == null)
                throw new ArgumentNullException("args");
            if (sctxCarrier == null)
                throw new ArgumentNullException("sctxCarrier");

            if (args.Length < 1)
                throw new PrexoniteException("GroupBy requires at least one argument.");

            var f = args[0];

            var sctx = sctxCarrier.StackContext;

            var groups =
                new Dictionary<PValue, List<PValue>>();

            for (var i = 1; i < args.Length; i++)
            {
                var arg = args[i];
                var xs = Map._ToEnumerable(sctx, arg);
                if (xs == null)
                    continue;
                foreach (var x in xs)
                {
                    var fx = f.IndirectCall(sctx, new[] {x});
                    if (!groups.ContainsKey(fx))
                    {
                        var lst = new List<PValue>();
                        lst.Add(x);
                        groups.Add(fx, lst);
                    }
                    else
                    {
                        groups[fx].Add(x);
                    }
                }
            }
            // DO NO CONVERT TO LINQ, dereferencing of sctx MUST be delayed!
            // ReSharper disable LoopCanBeConvertedToQuery 
            foreach (var pair in groups)
            {
                yield return new PValueKeyValuePair(pair.Key, (PValue) pair.Value);
            }
            // ReSharper restore LoopCanBeConvertedToQuery
        }
Beispiel #5
0
        /// <summary>
        ///     Creates a new Prexonite virtual machine.
        /// </summary>
        public Engine()
        {
            //Thread local storage for stack
            _stackSlot = Thread.AllocateDataSlot();

            //Metatable
            _meta = MetaTable.Create();

            //PTypes
            _pTypeMap = new Dictionary<Type, PType>();
            _ptypemapiterator = new PTypeMapIterator(this);
            //int
            PTypeMap[typeof (int)] = PType.Int;
            PTypeMap[typeof (long)] = PType.Int;
            PTypeMap[typeof (short)] = PType.Int;
            PTypeMap[typeof (byte)] = PType.Int;

#if UseNonCTSIntegers
            PTypeMap[typeof(uint)]      = IntPType.Instance;
            PTypeMap[typeof(ulong)]     = IntPType.Instance;
            PTypeMap[typeof(ushort)]    = IntPType.Instance;
            PTypeMap[typeof(sbyte)]     = IntPType.Instance;
#endif

            //char
            PTypeMap[typeof (char)] = PType.Char;

            //bool
            PTypeMap[typeof (bool)] = PType.Bool;

            //real
            PTypeMap[typeof (float)] = PType.Real;
            PTypeMap[typeof (double)] = PType.Real;

            //string
            PTypeMap[typeof (string)] = PType.String;

            PTypeMap[typeof (List<PValue>)] = PType.List;
            PTypeMap[typeof (PValue[])] = PType.List;
            PTypeMap[typeof (PValueHashtable)] = PType.Hash;

            //Registry
            _pTypeRegistry = new SymbolTable<Type>();
            _pTypeRegistryIterator = new PTypeRegistryIterator(this);
            PTypeRegistry[IntPType.Literal] = typeof (IntPType);
            PTypeRegistry[BoolPType.Literal] = typeof (BoolPType);
            PTypeRegistry[RealPType.Literal] = typeof (RealPType);
            PTypeRegistry[CharPType.Literal] = typeof (CharPType);
            PTypeRegistry[StringPType.Literal] = typeof (StringPType);
            PTypeRegistry[NullPType.Literal] = typeof (NullPType);
            PTypeRegistry[ObjectPType.Literal] = typeof (ObjectPType);
            PTypeRegistry[ListPType.Literal] = typeof (ListPType);
            PTypeRegistry[StructurePType.Literal] = typeof (StructurePType);
            PTypeRegistry[HashPType.Literal] = typeof (HashPType);
            PTypeRegistry[StructurePType.Literal] = typeof (StructurePType);

            //Assembly registry
            _registeredAssemblies = new List<Assembly>();
            foreach (
                var assName in Assembly.GetExecutingAssembly().GetReferencedAssemblies())
                _registeredAssemblies.Add(Assembly.Load(assName.FullName));

            //Commands
            _commandTable = new CommandTable();
            PCommand cmd;

            Commands.AddEngineCommand(PrintAlias, ConsolePrint.Instance);

            Commands.AddEngineCommand(PrintLineAlias, ConsolePrintLine.Instance);

            Commands.AddEngineCommand(MetaAlias, Prexonite.Commands.Core.Meta.Instance);

            Commands.AddEngineCommand(BoxedAlias, Boxed.Instance);

            // The concatenate command has been renamed to `string_concat` for Prexonite 2
            Commands.AddEngineCommand(ConcatenateAlias, Concat.Instance);
            Commands.AddEngineCommand(OldConcatenateAlias, Concat.Instance);

            Commands.AddEngineCommand(MapAlias, cmd = Map.Instance);
            Commands.AddEngineCommand(SelectAlias, cmd);

            Commands.AddEngineCommand(FoldLAlias, FoldL.Instance);

            Commands.AddEngineCommand(FoldRAlias, FoldR.Instance);

            Commands.AddEngineCommand(DisposeAlias, Dispose.Instance);

            // There is a macro that uses the same alias (CallAlias)
            //  it has the same purpose. For backwards compatibility,
            //  the command table will retain the old binding.
            Commands.AddEngineCommand(CallAlias, Call.Instance);
            Commands.AddEngineCommand(Call.Alias, Call.Instance);

            Commands.AddEngineCommand(ThunkAlias, ThunkCommand.Instance);
            Commands.AddEngineCommand(AsThunkAlias, AsThunkCommand.Instance);
            Commands.AddEngineCommand(ForceAlias, ForceCommand.Instance);
            Commands.AddEngineCommand(ToSeqAlias, ToSeqCommand.Instance);

            // There is a macro that uses the same alias (Call_MemberAlias)
            //  it has the same purpose. For backwards compatibility,
            //  the command table will retain the old binding.
            Commands.AddEngineCommand(Call_MemberAlias, Call_Member.Instance);
            Commands.AddEngineCommand(Call_Member.Alias, Call_Member.Instance);

            Commands.AddEngineCommand(CallerAlias, Caller.Instance);

            Commands.AddEngineCommand(PairAlias, Pair.Instance);

            Commands.AddEngineCommand(UnbindAlias, Unbind.Instance);

            Commands.AddEngineCommand(SortAlias, Sort.Instance);
            Commands.AddEngineCommand(SortAlternativeAlias, Sort.Instance);

            Commands.AddEngineCommand(LoadAssemblyAlias, LoadAssembly.Instance);

            Commands.AddEngineCommand(DebugAlias, new Debug());

            Commands.AddEngineCommand(SetCenterAlias, SetCenterCommand.Instance);

            Commands.AddEngineCommand(SetLeftAlias, SetLeftCommand.Instance);

            Commands.AddEngineCommand(SetRightAlias, SetRightCommand.Instance);

            Commands.AddEngineCommand(AllAlias, All.Instance);

            Commands.AddEngineCommand(WhereAlias, Where.Instance);

            Commands.AddEngineCommand(SkipAlias, Skip.Instance);

            Commands.AddEngineCommand(LimitAlias, cmd = Limit.Instance);
            Commands.AddEngineCommand(TakeAlias, cmd);

            Commands.AddEngineCommand(AbsAlias, Abs.Instance);

            Commands.AddEngineCommand(CeilingAlias, Ceiling.Instance);

            Commands.AddEngineCommand(ExpAlias, Exp.Instance);

            Commands.AddEngineCommand(FloorAlias, Floor.Instance);

            Commands.AddEngineCommand(LogAlias, Log.Instance);

            Commands.AddEngineCommand(MaxAlias, Max.Instance);

            Commands.AddEngineCommand(MinAlias, Min.Instance);

            Commands.AddEngineCommand(PiAlias, Pi.Instance);

            Commands.AddEngineCommand(RoundAlias, Round.Instance);

            Commands.AddEngineCommand(SinAlias, Sin.Instance);
            Commands.AddEngineCommand(CosAlias, Cos.Instance);

            Commands.AddEngineCommand(SqrtAlias, Sqrt.Instance);

            Commands.AddEngineCommand(TanAlias, Tan.Instance);

            Commands.AddEngineCommand(CharAlias, Char.Instance);

            Commands.AddEngineCommand(CountAlias, Count.Instance);

            Commands.AddEngineCommand(DistinctAlias, cmd = new Distinct());
            Commands.AddEngineCommand(UnionAlias, cmd);
            Commands.AddEngineCommand(UniqueAlias, cmd);

            Commands.AddEngineCommand(FrequencyAlias, new Frequency());

            Commands.AddEngineCommand(GroupByAlias, new GroupBy());

            Commands.AddEngineCommand(IntersectAlias, new Intersect());

            // There is a macro that uses the same alias (Call_TailAlias)
            //  it has the same purpose. For backwards compatibility,
            //  the command table will retain the old binding.
            Commands.AddEngineCommand(Call_TailAlias, Call_Tail.Instance);
            Commands.AddEngineCommand(Call_Tail.Alias, Call_Tail.Instance);

            Commands.AddEngineCommand(ListAlias, List.Instance);

            Commands.AddEngineCommand(EachAlias, Each.Instance);

            Commands.AddEngineCommand(ExistsAlias, new Exists());

            Commands.AddEngineCommand(ForAllAlias, new ForAll());

            Commands.AddEngineCommand(CompileToCilAlias, CompileToCil.Instance);

            Commands.AddEngineCommand(TakeWhileAlias, TakeWhile.Instance);

            Commands.AddEngineCommand(ExceptAlias, Except.Instance);

            Commands.AddEngineCommand(RangeAlias, Range.Instance);

            Commands.AddEngineCommand(ReverseAlias, Reverse.Instance);

            Commands.AddEngineCommand(HeadTailAlias, HeadTail.Instance);

            Commands.AddEngineCommand(AppendAlias, Append.Instance);

            Commands.AddEngineCommand(SumAlias, Sum.Instance);

            Commands.AddEngineCommand(Contains.Alias, Contains.Instance);

            Commands.AddEngineCommand(ChanAlias, Chan.Instance);

            Commands.AddEngineCommand(SelectAlias, Select.Instance);

            Commands.AddEngineCommand(Call_AsyncAlias, CallAsync.Instance);
            Commands.AddEngineCommand(CallAsync.Alias, CallAsync.Instance);

            Commands.AddEngineCommand(AsyncSeqAlias, AsyncSeq.Instance);

            Commands.AddEngineCommand(CallSubPerformAlias, CallSubPerform.Instance);

            Commands.AddEngineCommand(PartialCallAlias, new PartialCallCommand());

            Commands.AddEngineCommand(PartialMemberCallAlias, PartialMemberCallCommand.Instance);

            Commands.AddEngineCommand(PartialConstructionAlias, PartialConstructionCommand.Instance);

            Commands.AddEngineCommand(PartialTypeCheckAlias, PartialTypeCheckCommand.Instance);
            Commands.AddEngineCommand(PartialTypeCastAlias, PartialTypecastCommand.Instance);
            Commands.AddEngineCommand(PartialStaticCallAlias, PartialStaticCallCommand.Instance);
            Commands.AddEngineCommand(FunctionalPartialCallCommand.Alias,
                FunctionalPartialCallCommand.Instance);
            Commands.AddEngineCommand(FlippedFunctionalPartialCallCommand.Alias,
                FlippedFunctionalPartialCallCommand.Instance);
            Commands.AddEngineCommand(PartialCallStarImplCommand.Alias,
                PartialCallStarImplCommand.Instance);

            Commands.AddEngineCommand(ThenAlias, ThenCommand.Instance);

            Commands.AddEngineCommand(Id.Alias, Id.Instance);
            Commands.AddEngineCommand(Const.Alias, Const.Instance);

            OperatorCommands.AddToEngine(this);

            Commands.AddEngineCommand(CreateEnumerator.Alias, CreateEnumerator.Instance);

            Commands.AddEngineCommand(CreateModuleName.Alias, CreateModuleName.Instance);

            Commands.AddEngineCommand(GetUnscopedAstFactory.Alias, GetUnscopedAstFactory.Instance);

            Commands.AddEngineCommand(CreateSourcePosition.Alias, CreateSourcePosition.Instance);

            Commands.AddEngineCommand(SeqConcat.Alias, SeqConcat.Instance);
        }
Beispiel #6
0
 /// <summary>
 ///     Takes an argument list and injects elements of top-level lists into that argument list.
 /// </summary>
 /// <param name = "sctx">The stack context in which to convert enumerables.</param>
 /// <param name = "args">The raw list of arguments to process.</param>
 /// <param name = "offset">The offset at which to start processing.</param>
 /// <returns>A copy of the argument list with top-level lists expanded.</returns>
 public static List<PValue> FlattenArguments(StackContext sctx, PValue[] args, int offset)
 {
     if (args == null)
         args = new PValue[] {};
     var iargs = new List<PValue>();
     for (var i = offset; i < args.Length; i++)
     {
         var arg = args[i];
         var folded = Map._ToEnumerable(sctx, arg);
         if (folded == null)
             iargs.Add(arg);
         else
             iargs.AddRange(folded);
     }
     return iargs;
 }
Beispiel #7
0
        public static PValue RunStatically(StackContext sctx, PValue[] args)
        {
            if (sctx == null)
                throw new ArgumentNullException("sctx");
            if (args == null)
                throw new ArgumentNullException("args");

            //Get f
            IIndirectCall f;
            if (args.Length < 1)
                throw new PrexoniteException("The foldl command requires a function argument.");
            else
                f = args[0];

            //Get left
            PValue left;
            if (args.Length < 2)
                left = null;
            else
                left = args[1];

            //Get the source
            IEnumerable<PValue> source;
            if (args.Length == 3)
            {
                var psource = args[2];
                source = Map._ToEnumerable(sctx, psource) ?? new[] {psource};
            }
            else
            {
                var lstsource = new List<PValue>();
                for (var i = 1; i < args.Length; i++)
                {
                    var multiple = Map._ToEnumerable(sctx, args[i]);
                    if (multiple != null)
                        lstsource.AddRange(multiple);
                    else
                        lstsource.Add(args[i]);
                }
                source = lstsource;
            }

            return Run(sctx, f, left, source);
        }
Beispiel #8
0
        protected static IEnumerable<PValue> CoroutineRunStatically(ContextCarrier sctxCarrier,
            PValue[] args)
        {
            if (sctxCarrier == null)
                throw new ArgumentNullException("sctxCarrier");
            if (args == null)
                throw new ArgumentNullException("args");

            var sctx = sctxCarrier.StackContext;

            //Get f
            IIndirectCall f;
            if (args.Length < 1)
                f = null;
            else
                f = args[0];

            //Get the source
            IEnumerable<PValue> source;
            if (args.Length == 2)
            {
                var psource = args[1];
                source = _ToEnumerable(sctx, psource) ?? new[] {psource};
            }
            else
            {
                var lstsource = new List<PValue>();
                for (var i = 1; i < args.Length; i++)
                {
                    var multiple = _ToEnumerable(sctx, args[i]);
                    if (multiple != null)
                        lstsource.AddRange(multiple);
                    else
                        lstsource.Add(args[i]);
                }
                source = lstsource;
            }

            //Note: need to forward element because this method must remain lazy.
            foreach (var value in CoroutineRun(sctxCarrier, f, source))
            {
                yield return value;
            }
        }
Beispiel #9
0
        /// <summary>
        ///     Implementation of (obj, id, arg1, arg2, arg3, ..., argn) => obj.id(arg1, arg2, arg3, ..., argn);
        /// </summary>
        /// <param name = "sctx">The stack context in which to call the member of <paramref name = "obj" />.</param>
        /// <param name = "obj">The obj to call.</param>
        /// <param name = "isSet">Indicates whether to perform a Set-call.</param>
        /// <param name = "id">The id of the member to call.</param>
        /// <param name = "args">The array of arguments to pass to the member call.<br />
        ///     Lists and coroutines are expanded.</param>
        /// <returns>The result returned by the member call.</returns>
        /// <exception cref = "ArgumentNullException"><paramref name = "sctx" /> is null.</exception>
        public PValue Run(StackContext sctx, PValue obj, bool isSet, string id, params PValue[] args)
        {
            if (obj == null)
                return PType.Null.CreatePValue();
            if (sctx == null)
                throw new ArgumentNullException("sctx");
            if (args == null)
                args = new PValue[] {};

            var iargs = new List<PValue>();
            for (var i = 0; i < args.Length; i++)
            {
                var arg = args[i];
                var folded = Map._ToEnumerable(sctx, arg);
                if (folded == null)
                    iargs.Add(arg);
                else
                    iargs.AddRange(folded);
            }

            return obj.DynamicCall(sctx, iargs.ToArray(), isSet ? PCall.Set : PCall.Get, id);
        }