Beispiel #1
0
        /**
         * Parse in the “file” context defined in the language specification.
         */
        public System.Type ParseFile(ErrorCollector collector, CompilationUnit unit, string type_name)
        {
            file result;
            var  position = new ParserPosition(this, collector);

            if (file.ParseRule_Base(ref position, out result) && position.Finished)
            {
                if (result.Analyse(collector))
                {
                    return(unit.CreateRootGenerator(result, type_name, generator => result.Generate(generator, generator.Return)));
                }
            }
            else
            {
                collector.ReportParseError(FileName, Index, Row, Column, Message);
            }
            return(null);
        }
Beispiel #2
0
        public static int Main(string[] args)
        {
            var uri              = new Uri(Assembly.GetExecutingAssembly().GetName().CodeBase);
            var directory        = Path.GetDirectoryName(uri.LocalPath);
            var assembly_builder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("Test"),
                                                                                 AssemblyBuilderAccess.Run);
            var module_builder = assembly_builder.DefineDynamicModule("TestModule");
            var unit           = new CompilationUnit(module_builder, false);
            var id             = 0;
            var success        = true;
            var lib            = new DynamicallyCompiledLibraries(new DirtyCollector());

            lib.ClearPaths();
            lib.AppendPath(Path.Combine(directory, "..", "..", "..", "..", "lib"));
            success &= DoTests(Path.Combine(directory, "..", "..", "..", "..", "tests"), "*", unit, lib, ref id);
            success &= DoTests(Path.Combine(directory, "..", "..", "tests"), "I", unit, lib, ref id);
            return(success ? 0 : 1);
        }
Beispiel #3
0
        /**
         * Parse in the “repl” context defined in the language specification.
         */
        public System.Type ParseRepl(ErrorCollector collector, CompilationUnit unit, string type_name)
        {
            repl result;
            var  position = new ParserPosition(this, collector);

            if (repl.ParseRule_Base(ref position, out result) && position.Finished)
            {
                if (result.Analyse(collector))
                {
                    return(unit.CreateReplGenerator(result, type_name,
                                                    (generator, root, current, update_current, escape_value, print_value) =>
                                                    result.Generate(generator, root, current, update_current, escape_value, print_value,
                                                                    generator.Return)));
                }
            }
            else
            {
                collector.ReportParseError(FileName, Index, Row, Column, Message);
            }
            return(null);
        }
Beispiel #4
0
        public static int Main(string[] args)
        {
            var show_help       = false;
            var use_precompiled = true;
            var options         = new OptionSet {
                { "p|no-precomp", "do not use precompiled libraries", v => use_precompiled = v == null },
                { "h|help", "show this message and exit", v => show_help = v != null }
            };

            List <string> files;

            try {
                files = options.Parse(args);
            } catch (OptionException e) {
                Console.Error.Write(AppDomain.CurrentDomain.FriendlyName + ": ");
                Console.Error.WriteLine(e.Message);
                Console.Error.WriteLine("Try “" + AppDomain.CurrentDomain.FriendlyName + " --help” for more information.");
                return(1);
            }

            if (show_help)
            {
                Console.WriteLine("Usage: " + AppDomain.CurrentDomain.FriendlyName + " input.flbgst");
                Console.WriteLine("Run Flabbergast interactively.");
                Console.WriteLine();
                Console.WriteLine("Options:");
                options.WriteOptionDescriptions(Console.Out);
                return(1);
            }

            if (files.Count > 1)
            {
                Console.Error.WriteLine("No more than one Flabbergast script may be given.");
                return(1);
            }

            Frame original = null;

            var assembly_builder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("Repl"), AssemblyBuilderAccess.Run);
            var module_builder   = assembly_builder.DefineDynamicModule("ReplModule");
            var unit             = new CompilationUnit(module_builder, false);
            var collector        = new ConsoleCollector();
            var task_master      = new ConsoleTaskMaster();

            task_master.AddUriHandler(BuiltInLibraries.INSTANCE);
            if (use_precompiled)
            {
                task_master.AddUriHandler(new LoadPrecompiledLibraries());
            }
            task_master.AddUriHandler(new DynamicallyCompiledLibraries(collector));

            if (files.Count == 1)
            {
                var parser    = Parser.Open(files[0]);
                var root_type = parser.ParseFile(collector, unit, "REPLRoot");
                if (root_type != null)
                {
                    var computation = (Computation)Activator.CreateInstance(root_type, task_master);
                    computation.Notify(r => original = r as Frame);
                    task_master.Slot(computation);
                    task_master.Run();
                    task_master.ReportCircularEvaluation();
                }
            }
            if (original == null)
            {
                original = new Frame(task_master, task_master.NextId(), new SourceReference("<repl>", "<native>", 0, 0, 0, 0, null), null, null);
            }

            var           id             = 0;
            Frame         current        = original;
            bool          run            = true;
            ConsumeResult update_current = (x) => current = (x as Frame) ?? current;

            var line_editor  = new LineEditor("flabbergast");
            var completables = new Completables();

            line_editor.AutoCompleteEvent = completables.Handler;
            string s;

            while (run && (s = line_editor.Edit(id + "‽ ", "")) != null)
            {
                var parser   = new Parser("line" + id, s);
                var run_type = parser.ParseRepl(collector, unit, "REPL" + id++);
                if (run_type != null)
                {
                    object result      = null;
                    var    computation = (Computation)Activator.CreateInstance(run_type, new object[] { task_master, original, current, update_current, (ConsumeResult)(output => result = output), (ConsumeResult)Console.WriteLine });
                    computation.Notify(r => run = (r as bool?) ?? true);
                    task_master.Slot(computation);
                    task_master.Run();
                    if (result != null)
                    {
                        HandleResult(result);
                    }
                    task_master.ReportCircularEvaluation();
                }
            }
            line_editor.SaveHistory();
            return(0);
        }
Beispiel #5
0
        public static bool DoTests(string root, string type, CompilationUnit unit, ref int id)
        {
            var all_succeeded = true;

            if (!Directory.Exists(root))
            {
                Console.WriteLine("Skipping non-existent directory: " + root);
                return(all_succeeded);
            }
            foreach (var file in GetFiles(root, "malformed"))
            {
                var collector = new DirtyCollector();
                var parser    = Parser.Open(file);
                parser.ParseFile(collector, unit, "Test" + id++);
                Console.WriteLine("{0} {1} {2} {3}", collector.ParseDirty ? "----" : "FAIL", "M", type,
                                  Path.GetFileNameWithoutExtension(file));
                all_succeeded &= collector.ParseDirty;
            }
            var task_master = new TestTaskMaster();

            foreach (var file in GetFiles(root, "errors"))
            {
                bool success;
                try
                {
                    var collector = new DirtyCollector();
                    var parser    = Parser.Open(file);
                    var test_type = parser.ParseFile(collector, unit, "Test" + id++);
                    success = collector.AnalyseDirty;
                    if (!success && test_type != null)
                    {
                        var tester = new CheckResult(task_master, test_type);
                        task_master.Slot(tester);
                        task_master.Run();
                        success = !tester.Success;
                    }
                }
                catch (Exception)
                {
                    success = false;
                }
                Console.WriteLine("{0} {1} {2} {3}", success ? "----" : "FAIL", "E", type,
                                  Path.GetFileNameWithoutExtension(file));
                all_succeeded &= success;
            }
            foreach (var file in GetFiles(root, "working"))
            {
                bool success;
                try
                {
                    var collector = new DirtyCollector();
                    var parser    = Parser.Open(file);
                    var test_type = parser.ParseFile(collector, unit, "Test" + id++);
                    success = !collector.AnalyseDirty && !collector.ParseDirty;
                    if (success && test_type != null)
                    {
                        var tester = new CheckResult(task_master, test_type);
                        task_master.Slot(tester);
                        task_master.Run();
                        success = tester.Success;
                    }
                }
                catch (Exception)
                {
                    success = false;
                }
                Console.WriteLine("{0} {1} {2} {3}", success ? "----" : "FAIL", "W", type,
                                  Path.GetFileNameWithoutExtension(file));
                all_succeeded &= success;
            }
            return(all_succeeded);
        }
Beispiel #6
0
        internal Generator(CompilationUnit owner, TypeBuilder type_builder, bool has_original)
        {
            Owner       = owner;
            TypeBuilder = type_builder;
            // Create fields for all information provided by the caller.
            state_field            = TypeBuilder.DefineField("state", typeof(long), FieldAttributes.Private);
            task_master            = TypeBuilder.DefineField("task_master", typeof(TaskMaster), FieldAttributes.Private);
            InitialSourceReference = new FieldValue(TypeBuilder.DefineField("source_reference", typeof(SourceReference), FieldAttributes.Private));
            InitialContext         = new FieldValue(TypeBuilder.DefineField("context", typeof(Context), FieldAttributes.Private));
            InitialSelfFrame       = new FieldValue(TypeBuilder.DefineField("self", typeof(Frame), FieldAttributes.Private));
            InitialContainerFrame  = new FieldValue(TypeBuilder.DefineField("container", typeof(Frame), FieldAttributes.Private));
            var construct_params    = new System.Type[] { typeof(TaskMaster), typeof(SourceReference), typeof(Context), typeof(Frame), typeof(Frame) };
            var initial_information = new FieldInfo[] { task_master, InitialSourceReference.Field, InitialContext.Field, InitialSelfFrame.Field, InitialContainerFrame.Field };

            // Create a constructor the takes all the state information provided by the
            // caller and stores it in appropriate fields.
            var ctor         = type_builder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, construct_params);
            var ctor_builder = ctor.GetILGenerator();

            for (var it = 0; it < initial_information.Length; it++)
            {
                ctor_builder.Emit(OpCodes.Ldarg_0);
                ctor_builder.Emit(OpCodes.Ldarg, it + 1);
                ctor_builder.Emit(OpCodes.Stfld, initial_information[it]);
            }
            ctor_builder.Emit(OpCodes.Ldarg_0);
            ctor_builder.Emit(OpCodes.Ldc_I4_0);
            ctor_builder.Emit(OpCodes.Stfld, state_field);
            ctor_builder.Emit(OpCodes.Ret);

            System.Type[] init_params;
            if (has_original)
            {
                init_params = new System.Type[construct_params.Length + 1];
                for (var it = 0; it < construct_params.Length; it++)
                {
                    init_params[it] = construct_params[it];
                }
                init_params[init_params.Length - 1] = typeof(Computation);
            }
            else
            {
                init_params = construct_params;
            }
            // Create a static method that wraps the constructor. This is needed to create a delegate.
            Initialiser = type_builder.DefineMethod("Init", MethodAttributes.Public | MethodAttributes.Static, typeof(Computation), init_params);
            var init_builder = Initialiser.GetILGenerator();

            for (var it = 0; it < initial_information.Length; it++)
            {
                init_builder.Emit(OpCodes.Ldarg, it);
            }
            init_builder.Emit(OpCodes.Newobj, ctor);

            // If overriding, attach the overriding function to the original computation.
            if (has_original)
            {
                var init_this = init_builder.DeclareLocal(TypeBuilder);
                init_builder.Emit(OpCodes.Stloc, init_this);

                init_builder.Emit(OpCodes.Ldarg, initial_information.Length);
                init_builder.Emit(OpCodes.Ldloc, init_this);
                GenerateConsumeResult(InitialOriginal, init_builder, false);
                init_builder.Emit(OpCodes.Callvirt, typeof(Computation).GetMethod("Notify"));
                init_builder.Emit(OpCodes.Ldloc, init_this);
            }

            init_builder.Emit(OpCodes.Ret);

            // Create a run method with an initial state.
            Builder      = type_builder.DefineMethod("Run", MethodAttributes.Public | MethodAttributes.Virtual, typeof(bool), new System.Type[0]).GetILGenerator();
            switch_label = Builder.DefineLabel();
            var start_label = Builder.DefineLabel();

            entry_points.Add(start_label);
            Builder.Emit(OpCodes.Br, switch_label);
            Builder.MarkLabel(start_label);
        }