private void Test(string input, string output, int maxExpand = 0xFFFF, bool suppressWarnings = false) { _sink.MinSeverity = suppressWarnings ? Severity.DebugDetail : Severity.ErrorDetail; using (LNode.SetPrinter(EcsLanguageService.Value)) using (ParsingService.SetDefault(Les2LanguageService.Value)) TestCompiler.Test(input, output, _sink, maxExpand, "LeMP.Prelude.Les"); }
protected override void Stmt(string text, LNode expected, Action <EcsPrinterOptions> configure = null, Mode mode = Mode.Both) { bool exprMode = (mode & Mode.Expression) != 0; if ((mode & (Mode.ParserTest | Mode.ExpectAndDropParserError)) == 0) { return; } var sink = (mode & Mode.ExpectAndDropParserError) != 0 ? new MessageHolder() : (IMessageSink)ConsoleMessageSink.Value; using (Token.SetToStringStrategy(TokenExt.ToString)) // debugging aid { // This is the easy way: // LNode result = EcsLanguageService.Value.ParseSingle(text, sink, exprMode ? ParsingMode.Expressions : ParsingMode.Statements, preserveComments: true); // But to make debugging easier, I'll do it the long way: ILexer <Token> lexer = EcsLanguageService.Value.Tokenize(new UString(text), "", sink); var preprocessed = new EcsPreprocessor(lexer, true); var treeified = new TokensToTree(preprocessed, false); var parser = new EcsParser(treeified.Buffered(), lexer.SourceFile, sink, null); LNodeList results = exprMode ? LNode.List(parser.ExprStart(false)) : LNode.List(parser.ParseStmtsGreedy()); // Inject comments var injector = new EcsTriviaInjector(preprocessed.TriviaList, preprocessed.SourceFile, (int)TokenType.Newline, "/*", "*/", "//", (mode & Mode.Expression) == 0); results = LNode.List(injector.Run(results.GetEnumerator()).ToList()); LNode result = results.AsLNode(S.Splice); AreEqual(TokenType.EOF, parser.LT0.Type(), string.Format("Parser stopped before EOF at [{0}] in {1}", parser.LT0.StartIndex, text)); if ((mode & Mode.IgnoreTrivia) != 0) { result = result.ReplaceRecursive(n => n.IsTrivia ? Maybe <LNode> .NoValue : n, LNode.ReplaceOpt.ProcessAttrs).Value; } if (sink is MessageHolder) { ((MessageHolder)sink).WriteListTo(TraceMessageSink.Value); GreaterOrEqual(((MessageHolder)sink).List.Count(m => m.Severity >= Severity.Error), 1, "Expected an error but got none for " + text); if (expected == null) { return; } } if (!expected.Equals(result, LNode.CompareMode.TypeMarkers)) { if ((mode & Mode.CompareAsLes) != 0) { using (LNode.SetPrinter(Syntax.Les.Les3LanguageService.Value)) AreEqual(expected.ToString(), result.ToString()); } else { AreEqual(expected, result); } Fail("{0} has a different type marker than {1}", expected, result); } } }
protected void Test(string input, string expected, IMessageSink sink = null, IParsingService parser = null) { using (ParsingService.PushCurrent(parser ?? Les2LanguageService.Value)) using (LNode.SetPrinter(EcsLanguageService.WithPlainCSharpPrinter)) { var c = new TestCompiler(sink ?? _sink, new UString(input)); c.Run(); Assert.AreEqual(StripExtraWhitespace(expected), StripExtraWhitespace(c.Output.ToString())); } }
//int _alternator; public void Test(string input, string output, int maxExpand = 0xFFFF, ILNodePrinter printer = null) { using (LNode.SetPrinter(printer ?? EcsLanguageService.Value)) using (ParsingService.SetDefault(Les3LanguageService.Value)) TestCompiler.Test(input, output, _sink, maxExpand, "LeMP.les3.to.ecs"); // LeMP.Prelude.Les3 is set up as an alias; both namespaces should work, // but we're not using this logic as of 2021/01 because we don't have a // way to turn off annoying deprecation warnings //(++_alternator & 1) != 0 ? "LeMP.les3.to.ecs" : "LeMP.Prelude.Les3"); }
public static void Test(string input, string output, IMessageSink sink, int maxExpand = 0xFFFF, bool plainCS = true) { ILNodePrinter printer = plainCS ? EcsLanguageService.WithPlainCSharpPrinter : EcsLanguageService.Value; using (LNode.SetPrinter(printer)) { var c = new TestCompiler(sink, new UString(input), ""); c.MaxExpansions = maxExpand; c.MacroProcessor.AbortTimeout = TimeSpan.Zero; // never timeout (avoids spawning a new thread) c.Run(); Assert.AreEqual(StripExtraWhitespace(output), StripExtraWhitespace(c.Output.ToString())); } }
[STAThread] // Required by ICSharpCode.TextEditor public static void Main(string[] args) { if (!args.Contains("--nologo")) { Console.WriteLine("LeMP macro compiler ({0})", typeof(Compiler).Assembly.GetName().Version.ToString()); } Severity minSeverity = Severity.NoteDetail; #if DEBUG minSeverity = Severity.DebugDetail; #endif var filter = new SeverityMessageFilter(ConsoleMessageSink.Value, minSeverity); Compiler c = new Compiler(filter, typeof(BuiltinMacros)); var argList = args.ToList(); var options = c.ProcessArguments(argList, false, true); if (options == null) { return; // error occurred, message should have printed already } if (!MaybeShowHelp(options, KnownOptions)) { WarnAboutUnknownOptions(options, filter, KnownOptions); if (c.Files.Count == 0) { Console.WriteLine(); filter.Error(null, "No input files provided, stopping. Add --help for usage info.".Localized()); if (!options.ContainsKey("nologo")) { // Give users a simple way to find out which copy they're using: // Windows doesn't have `which` and the dotnet tools version of // LeMP.exe is not the real one anyway (it's not a .NET module) Console.WriteLine("You're using {0}".Localized(typeof(MacroProcessor).Assembly.Location)); Console.WriteLine(" ({0})".Localized(typeof(MacroProcessor).Assembly.FullName)); } return; } else { using (LNode.SetPrinter(EcsLanguageService.WithPlainCSharpPrinter)) c.Run(); } } }
[STAThread] // Required by ICSharpCode.TextEditor public static void Main(string[] args) { if (!args.Contains("--nologo")) { Console.WriteLine("LeMP macro compiler ({0})", typeof(Compiler).Assembly.GetName().Version.ToString()); } if (args.Contains("--editor")) { Console.WriteLine("Starting editor..."); System.Windows.Forms.Application.EnableVisualStyles(); System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); System.Windows.Forms.Application.Run(new TextEditor.LempDemoForm()); return; } KnownOptions["editor"] = Pair.Create("", "Show built-in text editor"); Severity minSeverity = Severity.NoteDetail; #if DEBUG minSeverity = Severity.DebugDetail; #endif var filter = new SeverityMessageFilter(ConsoleMessageSink.Value, minSeverity); Compiler c = new Compiler(filter, typeof(BuiltinMacros)); var argList = args.ToList(); var options = c.ProcessArguments(argList, false, true); if (options == null) { return; // error occurred, message should have printed already } if (argList.Count == 0) { filter.Error(null, "No input files provided, stopping."); return; } if (!MaybeShowHelp(options, KnownOptions)) { WarnAboutUnknownOptions(options, filter, KnownOptions.With("nologo", Pair.Create("", ""))); using (LNode.SetPrinter(EcsLanguageService.WithPlainCSharpPrinter)) c.Run(); } }
public static string QuickRun(IParsingService inputLang, int maxExpand, string input, params Assembly[] macroAssemblies) { var c = new LeMP.TestCompiler(TraceMessageSink.Value, new UString(input)); c.Parallel = false; c.MaxExpansions = maxExpand; c.AddMacros(Assembly.GetExecutingAssembly()); c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude")); c.MacroProcessor.PreOpenedNamespaces.Add(Loyc.LLPG.Macros.MacroNamespace); foreach (var assembly in macroAssemblies) { c.AddMacros(assembly); } using (ParsingService.SetDefault(inputLang ?? ParsingService.Default)) using (LNode.SetPrinter(Ecs.EcsLanguageService.Value)) c.Run(); return(c.Output.ToString()); }
protected void Test(LNodeList input, MacroProcessor lemp, string expected, IParsingService outLang) { // The current printer affects the assert macro and contract macros, // so we'll want to set it up before running LeMP using (LNode.SetPrinter((ILNodePrinter)outLang)) { var inputCode = input; var results = lemp.ProcessSynchronously(inputCode); var expectCode = outLang.Parse(expected, MessageSink.Default); if (!results.SequenceEqual(expectCode)) { // TEST FAILED, print error string resultStr = results.Select(n => ((ILNodePrinter)outLang).Print(n)).Join("\n"); Assert.AreEqual(TestCompiler.StripExtraWhitespace(expected), TestCompiler.StripExtraWhitespace(resultStr)); // In some tests, the text is equal even though the trees are different, // typically because of differences in #trivia attributes between the two. Console.WriteLine("(minor dif)"); // it's OK, but print a hint that this occurred. } } }
protected void Test(string input, IParsingService inLang, string expected, IParsingService outLang, int maxExpand = 0xFFFF) { var lemp = NewLemp(maxExpand, inLang); // The current printer affects the assert macro and contract macros using (LNode.SetPrinter((ILNodePrinter)outLang)) { var inputCode = new VList <LNode>(inLang.Parse(input, MessageSink.Default)); var results = lemp.ProcessSynchronously(inputCode); var expectCode = outLang.Parse(expected, MessageSink.Default); if (!results.SequenceEqual(expectCode)) { // TEST FAILED, print error string resultStr = results.Select(n => ((ILNodePrinter)outLang).Print(n)).Join("\n"); Assert.AreEqual(TestCompiler.StripExtraWhitespace(expected), TestCompiler.StripExtraWhitespace(resultStr)); // In some tests, the text is equal even though the trees are different, // typically because of differences in #trivia attributes between the two. Console.WriteLine(); // it's OK, but print a hint that this occurred. } } }
protected override void WriteOutput(InputOutput io) { VList <LNode> results = io.Output; string NewlineString = io.OutOptions.NewlineString, IndentString = io.OutOptions.IndentString; if (!NoOutHeader) { Output.AppendFormat( "// Generated from {1} by LeMP custom tool. LeMP version: {2}{0}" + "// Note: you can give command-line arguments to the tool via 'Custom Tool Namespace':{0}" + "// --no-out-header Suppress this message{0}" + "// --verbose Allow verbose messages (shown by VS as 'warnings'){0}" + "// --timeout=X Abort processing thread after X seconds (default: 10){0}" + "// --macros=FileName.dll Load macros from FileName.dll, path relative to this file {0}" + "// Use #importMacros to use macros in a given namespace, e.g. #importMacros(Loyc.LLPG);{0}", NewlineString, Path.GetFileName(io.FileName), typeof(MacroProcessor).Assembly.GetName().Version.ToString()); } var options = new LNodePrinterOptions { IndentString = IndentString, NewlineString = NewlineString }; using (LNode.SetPrinter(io.OutPrinter ?? LNode.Printer)) LNode.Printer.Print(results, Output, Sink, ParsingMode.File, options); }
protected override byte[] Generate(string inputFilePath, string inputFileContents, string defaultNamespace, IVsGeneratorProgress progressCallback) { using (LNode.SetPrinter(EcsLanguageService.WithPlainCSharpPrinter)) return(base.Generate(inputFilePath, inputFileContents, defaultNamespace, progressCallback)); }
private void Test(string input, string output, int maxExpand = 0xFFFF, IParsingService parser = null, ILNodePrinter printer = null, IMessageSink sink = null) { using (ParsingService.SetDefault(parser ?? Les2LanguageService.Value)) using (LNode.SetPrinter(printer ?? EcsLanguageService.WithPlainCSharpPrinter)) TestCompiler.Test(input, output, sink ?? _sink, maxExpand, "LeMP.les2.to.ecs"); }