Beispiel #1
0
 public void TeardownCompilerEngine()
 {
     engine = null;
     sctx = null;
     target = null;
     root = null;
 }
Beispiel #2
0
        public IndirectCallContext(StackContext originalSctx,
            Engine parentEngine,
            Application parentApplication,
            IEnumerable<string> importedNamespaces,
            IIndirectCall callable,
            PValue[] args)
        {
            if (parentEngine == null)
                throw new ArgumentNullException("parentEngine");
            if (parentApplication == null)
                throw new ArgumentNullException("parentApplication");
            if (importedNamespaces == null)
                throw new ArgumentNullException("importedNamespaces");
            if (callable == null)
                throw new ArgumentNullException("callable");
            if (args == null)
                throw new ArgumentNullException("args");

            _engine = parentEngine;
            _application = parentApplication;
            _importedNamespaces = (importedNamespaces as SymbolCollection) ??
                new SymbolCollection(importedNamespaces);
            _callable = callable;
            _arguments = args;
            _originalStackContext = originalSctx;
        }
        public void Initialize()
        {
            Application = new Application(ApplicationName);
            Engine = new Engine();
            Loader = new Loader(Engine, Application);

            Dependencies = new List<string>();
            Root = new NullContext(Engine, Application, new string[0]);

            var slnPath = Environment.CurrentDirectory;
            while (Directory.Exists(slnPath) && !File.Exists(Path.Combine(slnPath, "Prexonite.sln")))
                slnPath = Path.Combine(slnPath, @".." + Path.DirectorySeparatorChar);

            if (Directory.Exists(slnPath))
            {
                var psrTestsPath =
                    Path.GetFullPath(Path.Combine(slnPath, @"PrexoniteTests\psr-tests"));
                Console.WriteLine("inferred psr-tests path: " + psrTestsPath, "Engine.Path");
                Engine.Paths.Add(psrTestsPath);

                var prxPath = Path.GetFullPath(Path.Combine(slnPath, @"Prx"));
                Console.WriteLine("inferred prx path: " + prxPath, "Engine.Path");
                Engine.Paths.Add(prxPath);
            }
            else
            {
                Console.WriteLine("CANNOT INFER solution PATH: " + slnPath, "Engine.Path");
            }
        }
Beispiel #4
0
 public IndirectCallContext(Engine parentEngine,
     Application parentApplication,
     IEnumerable<string> importedNamespaces,
     IIndirectCall callable,
     PValue[] args)
     : this(null, parentEngine, parentApplication, importedNamespaces, callable, args)
 {
 }
Beispiel #5
0
        internal FunctionContext
            (
            Engine parentEngine,
            PFunction implementation,
            PValue[] args,
            PVariable[] sharedVariables,
            bool suppressInitialization)
        {
            if (parentEngine == null)
                throw new ArgumentNullException("parentEngine");
            if (implementation == null)
                throw new ArgumentNullException("implementation");
            if (sharedVariables == null)
                sharedVariables = new PVariable[] {};
            if (args == null)
                args = new PValue[] {};

            if (
                !(suppressInitialization || implementation.ParentApplication._SuppressInitialization))
                implementation.ParentApplication.EnsureInitialization(parentEngine);

            _parentEngine = parentEngine;
            _implementation = implementation;
            _bindArguments(args);
            _createLocalVariables();
            ReturnMode = ReturnMode.Exit;
            if (_implementation.Meta.ContainsKey(PFunction.SharedNamesKey))
            {
                var sharedNames = _implementation.Meta[PFunction.SharedNamesKey].List;
                //Ensure enough shared variables have been passed
                if (sharedNames.Length > sharedVariables.Length)
                    throw new ArgumentException
                        (
                        "The function " + _implementation.Id + " requires " +
                            sharedNames.Length + " variables to be shared.");


                for (var i = 0; i < sharedNames.Length; i++)
                {
                    if (sharedVariables[i] == null)
                        throw new ArgumentNullException
                            (
                            "sharedVariables",
                            String.Format(
                                "The element at index {0} passed in sharedVariables is null for function {1}.",
                                i, implementation));

                    if (_localVariables.ContainsKey(sharedNames[i]))
                        continue; //Arguments are redeclarations, that is not shared 
                    _localVariables.Add(sharedNames[i], sharedVariables[i]);
                }
            }

            //Populate fast variable access array (call by index)
            _localVariableArray = new PVariable[_localVariables.Count];
            foreach (var mapping in _implementation.LocalVariableMapping)
                _localVariableArray[mapping.Value] = _localVariables[mapping.Key];
        }
Beispiel #6
0
 public FunctionContext
     (
     Engine parentEngine,
     PFunction implementation,
     PValue[] args,
     PVariable[] sharedVariables)
     : this(parentEngine, implementation, args, sharedVariables, false)
 {
 }
Beispiel #7
0
 public TestStackContext(Engine engine, Application app)
 {
     if (engine == null)
         throw new ArgumentNullException("engine");
     if (app == null)
         throw new ArgumentNullException("app");
     _engine = engine;
     _implementation = app.CreateFunction();
 }
Beispiel #8
0
 public Benchmark(Engine eng, int iterations)
 {
     if (eng == null)
         throw new ArgumentNullException("eng");
     if (iterations < 0)
         throw new ArgumentOutOfRangeException(
             "iterations", iterations, "iterations must be a positive integer.");
     _iterations = iterations;
     Machine = eng;
 }
Beispiel #9
0
 private CilFunctionContext(Engine parentEngine, Application parentApplication,
     SymbolCollection importedNamespaces)
 {
     if (parentEngine == null)
         throw new ArgumentNullException("parentEngine");
     this.parentEngine = parentEngine;
     if (parentApplication == null)
         throw new ArgumentNullException("parentApplication");
     this.parentApplication = parentApplication;
     if (importedNamespaces == null)
         throw new ArgumentNullException("importedNamespaces");
     this.importedNamespaces = importedNamespaces;
 }
Beispiel #10
0
        public NullContext(Engine parentEngine, Application parentApplication, IEnumerable<string> importedNamespaces)
        {
            if (parentEngine == null)
                throw new ArgumentNullException("parentEngine");
            if (parentApplication == null)
                throw new ArgumentNullException("parentApplication");
            if (importedNamespaces == null)
                throw new ArgumentNullException("importedNamespaces");

            this.parentEngine = parentEngine;
            this.parentApplication = parentApplication;
            this.importedNamespaces = (importedNamespaces as SymbolCollection) ??
                new SymbolCollection(importedNamespaces);
        }
Beispiel #11
0
        public static void Main(string[] args)
        {
            Console.CancelKeyPress += delegate { Environment.Exit(1); };
            var prexoniteConsole = new PrexoniteConsole(true);

            //Let the exceptions surface so they can more easily be debugged
            try
            {
                var engine = new Engine();
                engine.RegisterAssembly(Assembly.GetExecutingAssembly());

                //Load application
                var app = _loadApplication(engine, prexoniteConsole);

                //Run the applications main function.
                if (app != null) //errors have already been reported
                    _runApplication(engine, app, args);
            }
            // ReSharper disable once RedundantCatchClause
            catch (Exception ex)
            {
#if DEBUG
                _dummyUsageOf(ex);
                throw;
#else
                Console.WriteLine(ex);
#endif
            }
            finally
            {
                if (Debugger.IsAttached)
                {
                    Console.WriteLine(Prexonite.Properties.Resources.Program_DebugExit);
                    Console.ReadLine();
                }
            }
        }
Beispiel #12
0
        public void DryCrossModuleCall()
        {
            var m1 = Module.Create(new ModuleName("dragon", new Version(1, 2)));
            var m2 = Module.Create(new ModuleName("std", new Version(1, 3, 1)));

            var a1 = new Application(m1);
            var a2 = new Application(m2);

            var f1 = a1.CreateFunction(Application.DefaultEntryFunction);

            var f2 = a2.CreateFunction("sayHello");

            f1.Code.Add(new Instruction(OpCode.func, 0, f2.Id, m2.Name));
            f1.Code.Add(new Instruction(OpCode.ret_value));

            const string helloModules = "Hello Modules";
            f2.Code.Add(new Instruction(OpCode.ldc_string,helloModules));
            f2.Code.Add(new Instruction(OpCode.ret_value));

            Console.WriteLine("=========== Module {0} ==========", m1.Name);
            a1.Store(Console.Out);
            Console.WriteLine();
            Console.WriteLine("=========== Module {0} ==========", m2.Name);
            a2.Store(Console.Out);

            var eng = new Engine();

            try
            {
                a1.Run(eng);
                Assert.Fail("Should not succeed as applications are not linked.");
            }
            catch (PrexoniteRuntimeException e)
            {
                Console.WriteLine("EXPECTED EXCEPTION");
                Console.WriteLine(e.Message);
                Console.WriteLine("END OF EXPECTED EXCEPTION");
            }

            Application.Link(a1, a2);
            var r = a1.Run(eng);
            Expect(r.Value,Is.InstanceOf<string>());
            Expect(r.Value,Is.EqualTo(helloModules));
        }
Beispiel #13
0
 /// <summary>
 ///     Writes the application to the supplied <paramref name = "writer" /> using the default settings.
 /// </summary>
 /// <param name = "writer">The <see cref = "TextWriter" /> to write the application to.</param>
 /// <remarks>
 ///     <para>
 ///         <c>Store</c> is always superior to <see cref = "StoreInString" />.
 ///     </para>
 ///     <example>
 ///         <para>
 ///             If you want to write the application to stdout, use <see cref = "Store" /> and not <see
 ///      cref = "StoreInString" /> like in the following example:
 ///         </para>
 ///         <code>
 ///             public void WriteApplicationToStdOut(Application app)
 ///             {
 ///             app.Store(Console.Out);
 ///             //instead of
 ///             //  Console.Write(app.StoreInString());
 ///             }
 ///         </code>
 ///         <para>
 ///             By using the <see cref = "Store" />, everything Prexonite assembles is immedeately sent to stdout.
 ///         </para>
 ///     </example>
 /// </remarks>
 public void Store(TextWriter writer)
 {
     //Create a crippled engine for this process
     var eng = new Engine {ExecutionProhibited = true};
     var ldr = new Loader(eng, this);
     ldr.Store(writer);
 }
Beispiel #14
0
 public void StoreInFile(string path)
 {
     //Create a crippled engine for this process
     var eng = new Engine {ExecutionProhibited = true};
     var ldr = new Loader(eng, this);
     ldr.StoreInFile(path);
 }
Beispiel #15
0
 /// <summary>
 ///     Executes the application's <see cref = "EntryFunction">entry function</see> in the given <paramref
 ///      name = "parentEngine">Engine</paramref> and returns it's result.<br />
 ///     This overload does not supply any arguments.
 /// </summary>
 /// <param name = "parentEngine">The engine in which execute the entry function.</param>
 /// <returns>The value returned by the entry function.</returns>
 public PValue Run(Engine parentEngine)
 {
     return Run(parentEngine, new PValue[] {});
 }
Beispiel #16
0
        /// <summary>
        ///     Executes the application's <see cref = "EntryFunction">entry function</see> in the given <paramref
        ///      name = "parentEngine">Engine</paramref> and returns it's result.
        /// </summary>
        /// <param name = "parentEngine">The engine in which execute the entry function.</param>
        /// <param name = "args">The actual arguments for the entry function.</param>
        /// <returns>The value returned by the entry function.</returns>
        public PValue Run(Engine parentEngine, PValue[] args)
        {
            string entryName = Meta[EntryKey];
            PFunction func;
            if (!Functions.TryGetValue(entryName, out func))
                throw new PrexoniteException(
                    "Cannot find an entry function named \"" + entryName + "\"");

            //Make sure the functions environment is initialized.
            EnsureInitialization(parentEngine);

            return func.Run(parentEngine, args);
        }
Beispiel #17
0
        /// <summary>
        ///     <para>Makes the application ensure that it is initialized.</para>
        /// </summary>
        /// <param name = "targetEngine">The engine in which to perform initialization.</param>
        /// <remarks>
        ///     <para>
        ///         <ul>
        ///             <list type = "table">
        ///                 <listheader>
        ///                     <term><see cref = "InitializationState" /></term>
        ///                     <description>Behaviour</description>
        ///                 </listheader>
        ///                 <item>
        ///                     <term><see cref = "ApplicationInitializationState.None" /></term>
        ///                     <description>Initialization always required.</description>
        ///                 </item>
        ///                 <item>
        ///                     <term><see cref = "ApplicationInitializationState.Complete" /></term>
        ///                     <description>No initialization required.</description>
        ///                 </item>
        ///             </list>
        ///         </ul>
        ///     </para>
        /// </remarks>
        public void EnsureInitialization(Engine targetEngine)
        {
            if (_SuppressInitialization)
                return;
            switch (_initializationState)
            {
#pragma warning disable 612,618
                case ApplicationInitializationState.Partial:
#pragma warning restore 612,618
                case ApplicationInitializationState.None:
                    try
                    {
                        _SuppressInitialization = true;
                        FunctionContext fctx =
                            _initializationFunction.CreateFunctionContext
                                (
                                    targetEngine,
                                    new PValue[0], // \init has no arguments
                                    new PVariable[0], // \init is not a closure
                                    true // don't initialize. That's what WE are trying to do here.
                                );

                        //Find offset at which to continue initialization. 
                        fctx.Pointer = _initializationOffset;
#if Verbose
                        Console.WriteLine("#Initialization (offset = {0}).", _initializationOffset);
#endif

                        //Execute the part of the initialize function that is missing
                        targetEngine.Stack.AddLast(fctx);
                        try
                        {
                            targetEngine.Process();
                        }
                        finally
                        {
                            //Save the current initialization state (offset)
                            _initializationOffset = _initializationFunction.Code.Count;
                            _initializationState = ApplicationInitializationState.Complete;
                        }
                    }
                    finally
                    {
                        _SuppressInitialization = false;
                    }
                    break;
                case ApplicationInitializationState.Complete:
                    break;
                default:
                    throw new PrexoniteException(
                        "Invalid InitializationState " + _initializationState);
            }
        }
Beispiel #18
0
 public void EnsureInitialization(Engine targetEngine, IHasMetaTable context)
 {
     EnsureInitialization(targetEngine);
 }
Beispiel #19
0
        private static Application _loadApplication(Engine engine, PrexoniteConsole prexoniteConsole)
        {
            var plan = Plan.CreateSelfAssembling();

            #region Stopwatch commands

            //prx.exe provides these three additional commands for high speed access to a stopwatch from your script code
            var timer = new Stopwatch();
            engine.Commands.AddHostCommand
                (
                    @"timer\start",
                    new DelegatePCommand
                        (
                        delegate
                        {
                            timer.Start();
                            return null;
                        }));

            engine.Commands.AddHostCommand
                (
                    @"timer\stop",
                    new DelegatePCommand
                        (
                        delegate
                        {
                            timer.Stop();
                            return (double)timer.ElapsedMilliseconds;
                        }));

            engine.Commands.AddHostCommand
                (
                    @"timer\reset",
                    new DelegatePCommand
                        (
                        delegate
                        {
                            timer.Reset();
                            return null;
                        }));

            engine.Commands.AddHostCommand
                (
                    @"timer\elapsed",
                    new DelegatePCommand
                        (
                        delegate { return (double)timer.ElapsedMilliseconds; }));

            #endregion

            #region Stack Manipulation commands

            engine.Commands.AddHostCommand
                (
                    @"__replace_call",
                    delegate(StackContext sctx, PValue[] cargs)
                    {
                        if (cargs == null)
                            cargs = new PValue[]
                            {
                            };
                        if (sctx == null)
                            throw new ArgumentNullException("sctx");

                        var e = sctx.ParentEngine;

                        if (cargs.Length < 1)
                            throw new PrexoniteException
                                (
                                "__replace_call requires the context or function to be replaced.");

                        var carg = cargs[0];
                        var rargs = new PValue[cargs.Length - 1];
                        Array.Copy(cargs, 1, rargs, 0, rargs.Length);

                        FunctionContext rctx = null;
                        PFunction f;
                        switch (carg.Type.ToBuiltIn())
                        {
                            case PType.BuiltIn.String:
                                if (
                                    !sctx.ParentApplication.Functions.TryGetValue
                                        (
                                            (string)carg.Value, out f))
                                    throw new PrexoniteException
                                        (
                                        "Cannot replace call to " + carg +
                                        " because no such function exists.");

                                rctx = f.CreateFunctionContext(e, rargs);
                                break;
                            case PType.BuiltIn.Object:
                                var clrType = ((ObjectPType)carg.Type).ClrType;
                                if (clrType == typeof(PFunction))
                                {
                                    f = (PFunction)carg.Value;
                                    rctx = f.CreateFunctionContext(e, rargs);
                                }
                                else if (clrType == typeof(Closure) &&
                                         clrType != typeof(Continuation))
                                {
                                    var c = (Closure)carg.Value;
                                    rctx = c.CreateFunctionContext(sctx, rargs);
                                }
                                else if (clrType == typeof(FunctionContext))
                                {
                                    rctx = (FunctionContext)carg.Value;
                                }
                                break;
                        }
                        if (rctx == null)
                            throw new PrexoniteException("Cannot replace a context based on " +
                                                         carg);

                        var node = e.Stack.Last;
                        do
                        {
                            var ectx = node.Value as FunctionContext;

                            if (ectx != null)
                            {
                                if (ReferenceEquals(ectx.Implementation, rctx.Implementation))
                                {
                                    node.Value = rctx;
                                    break;
                                }
                            }
                        } while ((node = node.Previous) != null);

                        return PType.Null.CreatePValue();
                    });

            #endregion

            #region Prexonite Console constant

            engine.Commands.AddHostCommand("__console", prexoniteConsole);

            #endregion

            #region Create benchmark command

            engine.Commands.AddHostCommand
                ("createBenchmark",
                    delegate(StackContext sctx, PValue[] cargs)
                    {
                        if (sctx == null)
                            throw new ArgumentNullException("sctx");
                        if (cargs == null)
                            cargs = new PValue[]
                            {
                            };

                        Engine teng;
                        int tit;

                        if (cargs.Length >= 2)
                        {
                            teng = cargs[0].ConvertTo<Engine>(sctx);
                            tit = cargs[1].ConvertTo<int>(sctx);
                        }
                        else if (cargs.Length >= 1)
                        {
                            teng = sctx.ParentEngine;
                            tit = cargs[0].ConvertTo<int>(sctx);
                        }
                        else
                        {
                            return sctx.CreateNativePValue(new Benchmark(sctx.ParentEngine));
                        }

                        return sctx.CreateNativePValue(new Benchmark(teng, tit));
                    });

            #endregion

            #region Self-assembling build plan reference

            engine.Commands.AddHostCommand(@"host\self_assembling_build_plan", (sctx, args) => sctx.CreateNativePValue(plan));

            #endregion

            var deleteSrc = false;
            var entryPath = GetPrxPath() + Path.DirectorySeparatorChar + PrxScriptFileName;
            if (!File.Exists(entryPath))
            {
                //Load default CLI app
                entryPath = GetPrxPath() + Path.DirectorySeparatorChar + @"src" +
                            Path.DirectorySeparatorChar + "prx_main.pxs";

                if (!File.Exists(entryPath))
                {
                    if (!Directory.Exists("src"))
                    {
                        var di =
                            Directory.CreateDirectory(GetPrxPath() + Path.DirectorySeparatorChar +
                                                      @"src");
                        di.Attributes = di.Attributes | FileAttributes.Hidden;
                        deleteSrc = true;
                    }

                    //Unpack source
                    writeFile(Resources.prx_main, "prx_main.pxs");
                    writeFile(Resources.prx_lib, "prx_lib.pxs");
                    writeFile(Resources.prx_interactive, "prx_interactive.pxs");
                }
            }

            Tuple<Application, ITarget> result;

            try
            {
                var entryDesc =
                    plan.AssembleAsync(Source.FromFile(entryPath, Encoding.UTF8), CancellationToken.None).Result;
                result = plan.Load(entryDesc.Name);
            }
            catch (BuildFailureException e)
            {
                _reportErrors(e.Messages);
                Console.WriteLine(e);
#if DEBUG
                throw;
#else
                result = null;
#endif
            }
            catch (BuildException e)
            {
                if(e.RelatedTarget != null)
                    _reportErrors(e.RelatedTarget.BuildMessages);

                Console.WriteLine(e);
#if DEBUG
                throw;
#else
                result = null;
#endif
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
#if DEBUG
                throw;
#else
                result = null;
#endif
            }


            if (deleteSrc)
                Directory.Delete(GetPrxPath() + Path.DirectorySeparatorChar + @"src", true);

            if (result == null)
            {
                return null;
            }
            else
            {
                return !_reportErrors(result.Item2.Messages) ? result.Item1 : null;
            }
        }
Beispiel #20
0
 public void SetupCompilerEngine()
 {
     engine = new Engine();
     target = new Application("testApplication");
     sctx = new TestStackContext(engine, target);
 }
Beispiel #21
0
 public void CreateModuleNameCommand()
 {
     var cmd = CreateModuleName.Instance;
     var eng = new Engine();
     var app = new Application("cmnc");
     var sctx = new NullContext(eng, app, Enumerable.Empty<string>());
     var rawMn = cmd.Run(sctx, new[] {sctx.CreateNativePValue(new MetaEntry(new MetaEntry[]{"sys","1.0"}))});
     Assert.That(rawMn.Value,Is.InstanceOf<ModuleName>());
     var mn = (ModuleName) rawMn.Value;
     Assert.That(mn.Id,Is.EqualTo("sys"));
     Assert.That(mn.Version,Is.EqualTo(new Version(1,0)));
 }
Beispiel #22
0
 internal PTypeMapIterator(Engine outer)
 {
     _outer = outer;
 }
Beispiel #23
0
 public FunctionContext(Engine parentEngine, PFunction implementation, PValue[] args)
     : this(parentEngine, implementation, args, null)
 {
 }
Beispiel #24
0
 public void TeardownTypeSystemEngine()
 {
     engine = null;
     sctx = null;
 }
Beispiel #25
0
 public void SetupTypeSystemEngine()
 {
     engine = new Engine();
     sctx = new TestStackContext(engine, new Application());
 }
Beispiel #26
0
 private static void _runApplication(Engine engine, Application app, IEnumerable<string> args)
 {
     app.Run(engine, args.Select(engine.CreateNativePValue).ToArray());
 }
Beispiel #27
0
 public FunctionContext(Engine parentEngine, PFunction implementation)
     : this(parentEngine, implementation, null)
 {
 }
Beispiel #28
0
 internal PTypeRegistryIterator(Engine outer)
 {
     _outer = outer;
 }
Beispiel #29
0
 public Benchmark(Engine eng)
     : this(eng, DefaultIterations)
 {
 }