/** * 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); }
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); }
/** * 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); }
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); }
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); }
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); }