Exemple #1
0
		[STAThread] // Required by ICSharpCode.TextEditor
		public static void Main(string[] args)
		{
			BMultiMap<string,string> options = new BMultiMap<string,string>();

			var argList = args.ToList();
			UG.ProcessCommandLineArguments(argList, options, "", ShortOptions, TwoArgOptions);
			if (!options.ContainsKey("nologo"))
				Console.WriteLine("LeMP macro compiler (pre-alpha)");

			string _;
			if (options.TryGetValue("help", out _) || options.TryGetValue("?", out _)) {
				ShowHelp(KnownOptions.OrderBy(p => p.Key));
				return;
			}
			if (options.ContainsKey("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;
			}

			Severity minSeverity = Severity.Note;
			#if DEBUG
			minSeverity = Severity.Debug;
			#endif
			var filter = new SeverityMessageFilter(MessageSink.Console, minSeverity);

			Compiler c = ProcessArguments(options, filter, typeof(Macros), argList);
			Compiler.WarnAboutUnknownOptions(options, MessageSink.Console, KnownOptions);
			if (c != null) {
				c.AddMacros(typeof(global::LeMP.StandardMacros).Assembly);
				c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude"));
				c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP"));
				using (LNode.PushPrinter(Ecs.EcsNodePrinter.PrintPlainCSharp))
					c.Run();
			} else if (args.Length == 0) {
				ShowHelp(KnownOptions.OrderBy(p => p.Key));

				Console.WriteLine();
				Console.WriteLine("LeMP started without arguments. Starting editor (--editor)");

				var thread = new ThreadEx(() => {
					System.Windows.Forms.Application.EnableVisualStyles();
					System.Windows.Forms.Application.Run(new TextEditor.LempDemoForm());
				});
				thread.Thread.SetApartmentState(ApartmentState.STA);
				thread.Start();

				Console.WriteLine("Press Enter to run unit tests. Using the editor? Keep the terminal open.");
				Console.ReadLine();

				RunTests.Run(new Loyc.Syntax.Lexing.TokenTests());
				RunTests.Run(new Loyc.Syntax.Les.LesLexerTests());
				RunTests.Run(new Loyc.Syntax.Les.LesParserTests());
				RunTests.Run(new Loyc.Syntax.Les.LesPrinterTests());
				RunLeMPTests();
				Ecs.Program.RunEcsTests();
			}
		}
Exemple #2
0
        [STAThread]         // Required by ICSharpCode.TextEditor
        public static void Main(string[] args)
        {
            BMultiMap <string, string> options = new BMultiMap <string, string>();

            var argList = args.ToList();

            UG.ProcessCommandLineArguments(argList, options, "", ShortOptions, TwoArgOptions);
            if (!options.ContainsKey("nologo"))
            {
                Console.WriteLine("LeMP macro compiler (beta)");
            }

            string _;

            if (options.TryGetValue("help", out _) || options.TryGetValue("?", out _))
            {
                ShowHelp(KnownOptions.OrderBy(p => p.Key));
                return;
            }

            if (options.ContainsKey("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;
            }

            Severity minSeverity = Severity.Note;

                        #if DEBUG
            minSeverity = Severity.Debug;
                        #endif
            var filter = new SeverityMessageFilter(MessageSink.Console, minSeverity);

            Compiler c = ProcessArguments(options, filter, typeof(BuiltinMacros), argList);
            Compiler.WarnAboutUnknownOptions(options, MessageSink.Console, KnownOptions);
            if (c != null)
            {
                c.AddMacros(typeof(global::LeMP.StandardMacros).Assembly);
                c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude"));
                c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP"));
                using (LNode.PushPrinter(EcsNodePrinter.PrintPlainCSharp))
                    c.Run();
            }
            else if (args.Length == 0)
            {
                ShowHelp(KnownOptions.OrderBy(p => p.Key));
            }
        }
Exemple #3
0
        public static void Main(params string[] args)
        {
            IDictionary <string, Pair <string, string> > KnownOptions = LeMP.Compiler.KnownOptions;

            if (args.Length != 0)
            {
                BMultiMap <string, string> options = new BMultiMap <string, string>();

                var argList = args.ToList();
                UG.ProcessCommandLineArguments(argList, options, "", LeMP.Compiler.ShortOptions, LeMP.Compiler.TwoArgOptions);
                if (!options.ContainsKey("nologo"))
                {
                    Console.WriteLine("LLLPG/LeMP macro compiler");
                }

                string _;
                if (options.TryGetValue("help", out _) || options.TryGetValue("?", out _) || args.Length == 0)
                {
                    LeMP.Compiler.ShowHelp(KnownOptions.OrderBy(p => p.Key));
                    return;
                }

                Severity minSeverity = Severity.Note;
                                #if DEBUG
                minSeverity = Severity.Debug;
                                #endif
                var filter = new SeverityMessageFilter(MessageSink.Console, minSeverity);

                LeMP.Compiler c = LeMP.Compiler.ProcessArguments(options, filter, typeof(LeMP.Prelude.Les.Macros), argList);
                LeMP.Compiler.WarnAboutUnknownOptions(options, MessageSink.Console, KnownOptions);
                if (c != null)
                {
                    c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude"));
                    c.MacroProcessor.PreOpenedNamespaces.Add(Loyc.LLPG.Macros.MacroNamespace);
                    c.AddMacros(Assembly.GetExecutingAssembly());
                    c.AddMacros(typeof(LeMP.Prelude.Macros).Assembly);
                    c.Run();
                }
            }
            else
            {
                LeMP.Compiler.ShowHelp(KnownOptions.OrderBy(p => p.Key));
                Tests();
                Ecs.Program.Main(args);                 // do EC# tests
            }
        }
Exemple #4
0
        public static void Main(string[] args)
        {
            BMultiMap <string, string> options = new BMultiMap <string, string>();

            var argList = args.ToList();

            UG.ProcessCommandLineArguments(argList, options, "", ShortOptions, TwoArgOptions);
            if (!options.ContainsKey("nologo"))
            {
                Console.WriteLine("LeMP macro compiler (pre-alpha)");
            }

            string _;

            if (options.TryGetValue("help", out _) || options.TryGetValue("?", out _))
            {
                ShowHelp(KnownOptions.OrderBy(p => p.Key));
                return;
            }

            Severity minSeverity = Severity.Note;

                        #if DEBUG
            minSeverity = Severity.Debug;
                        #endif
            var filter = new SeverityMessageFilter(MessageSink.Console, minSeverity);

            Compiler c = ProcessArguments(argList, options, filter, typeof(Macros));
            Compiler.WarnAboutUnknownOptions(options, MessageSink.Console, KnownOptions);
            if (c != null)
            {
                c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude"));
                using (LNode.PushPrinter(Ecs.EcsNodePrinter.PrintPlainCSharp))
                    c.Run();
            }
            else if (args.Length == 0)
            {
                Console.WriteLine("Running unit tests...");
                RunTests.Run(new Loyc.Syntax.Les.LesLexerTests());
                RunTests.Run(new Loyc.Syntax.Les.LesParserTests());
                RunLeMPTests();
                Ecs.Program.RunEcsTests();
            }
        }
Exemple #5
0
		public static void Main(params string[] args)
		{
			IDictionary<string, Pair<string, string>> KnownOptions = LeMP.Compiler.KnownOptions;
			if (args.Length != 0) {
				BMultiMap<string,string> options = new BMultiMap<string,string>();

				var argList = args.ToList();
				UG.ProcessCommandLineArguments(argList, options, "", LeMP.Compiler.ShortOptions, LeMP.Compiler.TwoArgOptions);
				if (!options.ContainsKey("nologo"))
					Console.WriteLine("LLLPG/LeMP macro compiler");

				string _;
				if (options.TryGetValue("help", out _) || options.TryGetValue("?", out _) || args.Length == 0) {
					LeMP.Compiler.ShowHelp(KnownOptions.OrderBy(p => p.Key));
					return;
				}

				Severity minSeverity = Severity.Note;
				#if DEBUG
				minSeverity = Severity.Debug;
				#endif
				var filter = new SeverityMessageFilter(MessageSink.Console, minSeverity);

				LeMP.Compiler c = LeMP.Compiler.ProcessArguments(options, filter, typeof(LeMP.Prelude.Les.Macros), argList);
				LeMP.Compiler.WarnAboutUnknownOptions(options, MessageSink.Console, KnownOptions);
				if (c != null) {
					c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude"));
					c.MacroProcessor.PreOpenedNamespaces.Add(Loyc.LLPG.Macros.MacroNamespace);
					c.AddMacros(Assembly.GetExecutingAssembly());
					c.AddMacros(typeof(LeMP.Prelude.Macros).Assembly);
					c.Run();
				}
			} else {
				LeMP.Compiler.ShowHelp(KnownOptions.OrderBy(p => p.Key));
				Tests();
				Ecs.Program.Main(args); // do EC# tests
			}
		}
Exemple #6
0
        /// <summary>Processes all standard command-line arguments from
        /// <see cref="KnownOptions"/>, except --help.</summary>
        /// <param name="options">A set of options, presumably derived from command-
        /// line options using <see cref="UG.ProcessCommandLineArguments"/></param>
        /// <param name="warnAboutUnknownOptions">Whether to warn (to <see cref="Sink"/>)
        /// about options not listed in <see cref="KnownOptions"/>.</param>
        /// <param name="inputFiles">Files to open with <see cref="OpenSourceFiles"/></param>
        /// <returns>true, unless inputFiles != null and all input files failed to open.</returns>
        /// <remarks>
        /// This method calls AddStdMacros() unless options includes "nostdmacros".
        /// </remarks>
        public bool ProcessArguments(BMultiMap <string, string> options, bool warnAboutUnknownOptions, IList <string> inputFiles = null)
        {
            Compiler c = this;
            string   value;
            var      filter = c.Sink as SeverityMessageFilter ?? new SeverityMessageFilter(c.Sink, Severity.Note);

            if (warnAboutUnknownOptions)
            {
                WarnAboutUnknownOptions(options, Sink, KnownOptions);
            }

            if (options.TryGetValue("verbose", out value))
            {
                if (value != "false")
                {
                    try {                     // Enum.TryParse() does not exist before .NET 4 so use Enum.Parse
                        filter.MinSeverity = (Severity)Enum.Parse(typeof(Severity), value);
                    } catch (Exception) {     // Docs say OverflowException, but that just sounds wrong
                        filter.MinSeverity = Severity.Verbose;
                    }
                }
            }

            IMessageSink sink = c.Sink = filter;

            if (options.TryGetValue("max-expand", out value))
            {
                TryCatch("While parsing max-expand", sink, () => c.MaxExpansions = int.Parse(value));
            }

            foreach (var macroDll in options["macros"])
            {
                Assembly assembly;
                TryCatch("While opening " + macroDll, sink, () =>
                {
                    if (macroDll.Contains('\\') || macroDll.Contains('/'))
                    {
                        // Avoid "Absolute path information is required" exception
                        string fullPath = Path.Combine(Environment.CurrentDirectory, macroDll);
                        assembly        = Assembly.LoadFile(fullPath);
                    }
                    else
                    {
                        assembly = Assembly.LoadFrom(macroDll);
                    }
                    c.AddMacros(assembly);
                });
            }
            foreach (string macroDll in options["macros-longname"])
            {
                Assembly assembly;
                TryCatch("While opening " + macroDll, sink, () =>
                {
                    assembly = Assembly.Load(macroDll);
                    c.AddMacros(assembly);
                });
            }
            if (options.TryGetValue("noparallel", out value) && (value == null || value == "true"))
            {
                c.Parallel = false;
            }
            if (options.TryGetValue("outext", out c.OutExt) && c.OutExt != null && !c.OutExt.StartsWith("."))
            {
                c.OutExt = "." + c.OutExt;
            }
            if (options.TryGetValue("inlang", out value))
            {
                ApplyLanguageOption(sink, "--inlang", value, ref c.InLang);
            }
            if (options.TryGetValue("outlang", out value))
            {
                IParsingService lang = null;
                ApplyLanguageOption(sink, "--outlang", value, ref lang);
                c.OutLang = lang.Printer ?? c.OutLang;
            }
            if (options.TryGetValue("forcelang", out value) && (value == null || value == "true"))
            {
                c.ForceInLang = true;
            }
            if (!options.ContainsKey("outlang") && c.OutExt != null && ParsingService.GetServiceForFileName(c.OutExt) == null)
            {
                sink.Write(Severity.Error, "--outext", "No language was found for extension «{0}»", c.OutExt);
            }
            double num;

            if (options.TryGetValue("timeout", out value))
            {
                if (!double.TryParse(value, out num) || !(num >= 0))
                {
                    sink.Write(Severity.Error, "--timeout", "Invalid or missing timeout value", c.OutExt);
                }
                else
                {
                    c.AbortTimeout = TimeSpan.FromSeconds(num);
                }
            }
            foreach (string exprStr in options["set"])
            {
                SetPropertyHelper(exprStr, quote: false);
            }
            foreach (string exprStr in options["snippet"])
            {
                SetPropertyHelper(exprStr, quote: true);
            }

            if (!options.TryGetValue("nostdmacros", out value))
            {
                AddStdMacros();
            }

            if (inputFiles != null)
            {
                this.Files = new List <InputOutput>(OpenSourceFiles(Sink, inputFiles));
                if (inputFiles.Count != 0 && Files.Count == 0)
                {
                    return(false);
                }
            }

            return(true);
        }
Exemple #7
0
        /// <summary>Processes all standard command-line arguments from
        /// <see cref="KnownOptions"/>, except --help.</summary>
        /// <param name="options">A set of options, presumably derived from command-
        /// line options using <see cref="UG.ProcessCommandLineArguments"/></param>
        /// <param name="warnAboutUnknownOptions">Whether to warn (to <see cref="Sink"/>)
        /// about options not listed in <see cref="KnownOptions"/>.</param>
        /// <param name="inputFiles">Files to open with <see cref="OpenSourceFiles"/></param>
        /// <returns>true, unless inputFiles != null and all input files failed to open.</returns>
        /// <remarks>
        /// This method calls AddStdMacros() unless options includes "nostdmacros".
        /// </remarks>
        public bool ProcessArguments(BMultiMap <string, string> options, bool warnAboutUnknownOptions, IList <string> inputFiles = null)
        {
            Compiler c = this;
            string   value;
            bool?    flag;
            double?  num;
            var      filter = c.Sink as SeverityMessageFilter ?? new SeverityMessageFilter(c.Sink, Severity.NoteDetail);

            if (warnAboutUnknownOptions)
            {
                WarnAboutUnknownOptions(options, Sink, KnownOptions);
            }

            if (options.TryGetValue("verbose", out value))
            {
                if (value != "false")
                {
                    try {                     // Enum.TryParse() does not exist before .NET 4 so use Enum.Parse
                        filter.MinSeverity = (Severity)Enum.Parse(typeof(Severity), value);
                    } catch (Exception) {     // Docs say OverflowException, but that just sounds wrong
                        filter.MinSeverity = Severity.Verbose;
                    }
                }
            }

            IMessageSink sink = c.Sink = filter;

            if ((num = ParseNumericOption(options, "max-expand", sink, 0, 99999)) != null)
            {
                c.MaxExpansions = (int)num.Value;
            }

            foreach (var macroDll in options["macros"])
            {
                Assembly assembly;
                TryCatch("While opening " + macroDll, sink, () =>
                {
                    // When running standalone, Assembly.Load works properly,
                    // but not when running in Visual Studio. I'm speculating it's
                    // because Visual Studio loads the Custom Tool in the "LoadFrom"
                    // context and Assembly.Load ignores assemblies loaded in the
                    // LoadFrom context (maybe not VS's fault as it loads us via COM)
                    // See https://blogs.msdn.microsoft.com/suzcook/2003/05/29/choosing-a-binding-context/
                    // Workaround for idiotic MS design: reprogram Load to find
                    // assemblies that are already loaded.
                    AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => {
                        return(AppDomain.CurrentDomain.GetAssemblies()
                               .FirstOrDefault(a => a.FullName == e.Name));
                    };

                    string path  = Path.Combine(Environment.CurrentDirectory, macroDll);
                    byte[] bytes = File.ReadAllBytes(path);
                    assembly     = Assembly.Load(bytes);
                    c.AddMacros(assembly);
                });
            }
            foreach (string macroDll in options["macros-longname"])
            {
                Assembly assembly;
                TryCatch("While opening " + macroDll, sink, () =>
                {
                    assembly = Assembly.Load(macroDll);
                    c.AddMacros(assembly);
                });
            }
            if ((flag = ParseBoolOption(options, "noparallel", sink)) != null)
            {
                c.Parallel = flag.Value;
            }
            if (options.TryGetValue("outext", out c.OutExt))
            {
                if (c.OutExt != null && !c.OutExt.StartsWith("."))
                {
                    c.OutExt = "." + c.OutExt;
                }
            }
            if (options.TryGetValue("inlang", out value))
            {
                ApplyLanguageOption(sink, "--inlang", value, ref c.InLang);
            }
            if (options.TryGetValue("outlang", out value))
            {
                IParsingService lang = null;
                ApplyLanguageOption(sink, "--outlang", value, ref lang);
                c.OutLang = (lang as ILNodePrinter) ?? c.OutLang;
            }
            if ((flag = ParseBoolOption(options, "forcelang", sink)) != null)
            {
                c.ForceInLang = flag.Value;
            }
            if (!options.ContainsKey("outlang") && c.OutExt != null && ParsingService.GetServiceForFileName(c.OutExt) == null)
            {
                sink.Error("--outext", "No language was found for extension «{0}»", c.OutExt);
            }
            if ((num = ParseNumericOption(options, "timeout", sink)) != null)
            {
                c.AbortTimeout = TimeSpan.FromSeconds(num.Value);
            }

            foreach (string exprStr in options["set"])
            {
                SetPropertyHelper(exprStr, quote: false);
            }
            foreach (string exprStr in options["snippet"])
            {
                SetPropertyHelper(exprStr, quote: true);
            }

            if (!options.TryGetValue("nostdmacros", out value) && !options.TryGetValue("no-std-macros", out value))
            {
                AddStdMacros();
            }

            if (options.TryGetValue("preserve-comments", out value))
            {
                PreserveComments = value == null || !value.ToString().ToLowerInvariant().IsOneOf("false", "0");
            }

            // Printing options
            if ((num = ParseNumericOption(options, "o-indent-spaces", sink, 0, 20)) != null)
            {
                OutOptions.IndentString = num.Value <= 0 ? "\t" : new string(' ', (int)num.Value);
            }
            if ((flag = ParseBoolOption(options, "o-allow-change-parens", sink)) != null)
            {
                OutOptions.AllowChangeParentheses = flag.Value;
            }
            if ((flag = ParseBoolOption(options, "o-omit-comments", sink)) != null)
            {
                OutOptions.OmitComments = flag.Value;
            }
            if ((flag = ParseBoolOption(options, "o-omit-unknown-trivia", sink)) != null)
            {
                OutOptions.OmitUnknownTrivia = flag.Value;
            }
            if ((flag = ParseBoolOption(options, "o-explicit-trivia", sink)) != null)
            {
                OutOptions.PrintTriviaExplicitly = flag.Value;
            }
            if ((flag = ParseBoolOption(options, "o-compatibility-mode", sink)) != null)
            {
                OutOptions.CompatibilityMode = flag.Value;
            }
            if ((flag = ParseBoolOption(options, "o-compact-mode", sink)) != null)
            {
                OutOptions.CompactMode = flag.Value;
            }

            if (inputFiles != null)
            {
                this.Files = new List <InputOutput>(OpenSourceFiles(Sink, inputFiles));
                if (inputFiles.Count != 0 && Files.Count == 0)
                {
                    return(false);
                }
            }

            return(true);
        }
Exemple #8
0
		public static bool ProcessArguments(Compiler c, BMultiMap<string, string> options)
		{
			string value;
			var filter = c.Sink as SeverityMessageFilter ?? new SeverityMessageFilter(c.Sink, Severity.Note);
			if (options.TryGetValue("verbose", out value))
			{
				if (value != "false") {
					try { // Enum.TryParse() does not exist before .NET 4 so use Enum.Parse
						filter.MinSeverity = (Severity)Enum.Parse(typeof(Severity), value);
					} catch (Exception) { // Docs say OverflowException, but that just sounds wrong
						filter.MinSeverity = Severity.Verbose;
					}
				}
			}
			
			IMessageSink sink = c.Sink = filter;
			
			if (options.TryGetValue("max-expand", out value))
				TryCatch("While parsing max-expand", sink, () => c.MaxExpansions = int.Parse(value));

			foreach (var macroDll in options["macros"])
			{
				Assembly assembly;
				TryCatch("While opening " + macroDll, sink, () =>
				{
					if (macroDll.Contains('\\') || macroDll.Contains('/')) {
						// Avoid "Absolute path information is required" exception
						string fullPath = Path.Combine(Environment.CurrentDirectory, macroDll);
						assembly = Assembly.LoadFile(fullPath);
					} else
						assembly = Assembly.LoadFrom(macroDll);
					c.AddMacros(assembly);
				});
			}
			foreach (var macroDll in options["macros-longname"])
			{
				Assembly assembly;
				TryCatch("While opening " + macroDll, sink, () =>
				{
					assembly = Assembly.Load(macroDll);
					c.AddMacros(assembly);
				});
			}
			if (options.TryGetValue("noparallel", out value) && (value == null || value == "true"))
				c.Parallel = false;
			if (options.TryGetValue("outext", out c.OutExt) && c.OutExt != null && !c.OutExt.StartsWith("."))
				c.OutExt = "." + c.OutExt;
			if (options.TryGetValue("inlang", out value)) {
				ApplyLanguageOption(sink, "--inlang", value, ref c.InLang);
			}
			if (options.TryGetValue("outlang", out value)) {
				IParsingService lang = null;
				ApplyLanguageOption(sink, "--outlang", value, ref lang);
				c.OutLang = lang.Printer ?? c.OutLang;
			}
			if (options.TryGetValue("forcelang", out value) && (value == null || value == "true"))
				c.ForceInLang = true;
			if (!options.ContainsKey("outlang") && c.OutExt != null && FileNameToLanguage(c.OutExt) == null)
				sink.Write(Severity.Error, "--outext", "No language was found for extension «{0}»", c.OutExt);
			double num;
			if (options.TryGetValue("timeout", out value)) {
				if (!double.TryParse(value, out num) || !(num >= 0))
					sink.Write(Severity.Error, "--timeout", "Invalid or missing timeout value", c.OutExt);
				else
					c.AbortTimeout = TimeSpan.FromSeconds(num);
			}

			return true;
		}
Exemple #9
0
        protected override byte[] Generate(string inputFilePath, string inputFileContents, string defaultNamespace, IVsGeneratorProgress progressCallback)
        {
            string oldCurDir = Environment.CurrentDirectory;

            try {
                string inputFolder = Path.GetDirectoryName(inputFilePath);
                Environment.CurrentDirectory = inputFolder;                 // --macros should be relative to file being processed

                var options = new BMultiMap <string, string>();
                var argList = G.SplitCommandLineArguments(defaultNamespace);
                UG.ProcessCommandLineArguments(argList, options, "", LeMP.Compiler.ShortOptions, LeMP.Compiler.TwoArgOptions);

                string _;
                var    KnownOptions = LeMP.Compiler.KnownOptions;
                if (options.TryGetValue("help", out _) || options.TryGetValue("?", out _))
                {
                    LeMP.Compiler.ShowHelp(KnownOptions);
                }

                // Originally I wrote a conversion from IVsGeneratorProgress to
                // IMessageSink so that errors could be reported immediately and
                // directly to Visual Studio. This broke in a bizarre way when I
                // added processing on a separate thread (in order to be able to
                // abort the thread if it runs too long); I got the following
                // InvalidCastException: "Unable to cast COM object of type 'System.__ComObject'
                // to interface type 'Microsoft.VisualStudio.Shell.Interop.IVsGeneratorProgress'.
                // This operation failed because the QueryInterface call on the COM component for
                // the interface with IID '{BED89B98-6EC9-43CB-B0A8-41D6E2D6669D}' failed due to
                // the following error: No such interface supported (Exception from HRESULT:
                // 0x80004002 (E_NOINTERFACE))."
                //
                // A simple solution is to store the messages rather than reporting
                // them immediately. I'll report the errors at the very end.
                MessageHolder sink = new MessageHolder();

                var sourceFile = new InputOutput((UString)inputFileContents, inputFilePath);

                var c = new Compiler(sink, sourceFile)
                {
                    AbortTimeout = TimeSpan.FromSeconds(10),
                    Parallel     = false                 // only one file, parallel doesn't help
                };

                if (c.ProcessArguments(options))
                {
                    if (options.ContainsKey("no-out-header"))
                    {
                        options.Remove("no-out-header", 1);
                        c.NoOutHeader = true;
                    }
                    LeMP.Compiler.WarnAboutUnknownOptions(options, sink, KnownOptions);
                    if (c != null)
                    {
                        if (inputFilePath.EndsWith(".les", StringComparison.OrdinalIgnoreCase))
                        {
                            c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude.Les"));
                        }
                        Configure(c);
                        c.Run();

                        // Report errors
                        foreach (var msg in sink.List)
                        {
                            ReportErrorToVS(progressCallback, msg.Severity, msg.Context, msg.Format, msg.Args);
                        }

                        return(Encoding.UTF8.GetBytes(c.Output.ToString()));
                    }
                }
                return(null);
            } finally {
                Environment.CurrentDirectory = oldCurDir;
            }
        }
Exemple #10
0
        [STAThread]         // Required by ICSharpCode.TextEditor
        public static void Main(string[] args)
        {
            BMultiMap <string, string> options = new BMultiMap <string, string>();

            var argList = args.ToList();

            UG.ProcessCommandLineArguments(argList, options, "", ShortOptions, TwoArgOptions);
            if (!options.ContainsKey("nologo"))
            {
                Console.WriteLine("LeMP macro compiler (pre-alpha)");
            }

            string _;

            if (options.TryGetValue("help", out _) || options.TryGetValue("?", out _))
            {
                ShowHelp(KnownOptions.OrderBy(p => p.Key));
                return;
            }
            if (options.ContainsKey("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;
            }

            Severity minSeverity = Severity.Note;

                        #if DEBUG
            minSeverity = Severity.Debug;
                        #endif
            var filter = new SeverityMessageFilter(MessageSink.Console, minSeverity);

            Compiler c = ProcessArguments(options, filter, typeof(Macros), argList);
            Compiler.WarnAboutUnknownOptions(options, MessageSink.Console, KnownOptions);
            if (c != null)
            {
                c.AddMacros(typeof(global::LeMP.StandardMacros).Assembly);
                c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude"));
                c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP"));
                using (LNode.PushPrinter(Ecs.EcsNodePrinter.PrintPlainCSharp))
                    c.Run();
            }
            else if (args.Length == 0)
            {
                ShowHelp(KnownOptions.OrderBy(p => p.Key));

                Console.WriteLine();
                Console.WriteLine("LeMP started without arguments. Starting editor (--editor)");

                var thread = new ThreadEx(() => {
                    System.Windows.Forms.Application.EnableVisualStyles();
                    System.Windows.Forms.Application.Run(new TextEditor.LempDemoForm());
                });
                thread.Thread.SetApartmentState(ApartmentState.STA);
                thread.Start();

                Console.WriteLine("Press Enter to run unit tests. Using the editor? Keep the terminal open.");
                Console.ReadLine();

                RunTests.Run(new Loyc.Syntax.Lexing.TokenTests());
                RunTests.Run(new Loyc.Syntax.Les.LesLexerTests());
                RunTests.Run(new Loyc.Syntax.Les.LesParserTests());
                RunTests.Run(new Loyc.Syntax.Les.LesPrinterTests());
                RunLeMPTests();
                Ecs.Program.RunEcsTests();
            }
        }
Exemple #11
0
        public static bool ProcessArguments(Compiler c, BMultiMap <string, string> options)
        {
            IMessageSink sink = c.Sink;

            if (c.Files.Count == 0)
            {
                return(false);
            }

            string value;

            if (options.TryGetValue("max-expand", out value))
            {
                TryCatch("While parsing max-expand", sink, () => c.MaxExpansions = int.Parse(value));
            }

            foreach (var macroDll in options["macros"])
            {
                Assembly assembly;
                TryCatch("While opening " + macroDll, sink, () =>
                {
                    if (macroDll.Contains('\\') || macroDll.Contains('/'))
                    {
                        // Avoid "Absolute path information is required" exception
                        string fullPath = Path.Combine(Environment.CurrentDirectory, macroDll);
                        assembly        = Assembly.LoadFile(fullPath);
                    }
                    else
                    {
                        assembly = Assembly.LoadFrom(macroDll);
                    }
                    c.AddMacros(assembly);
                });
            }
            foreach (var macroDll in options["macros-longname"])
            {
                Assembly assembly;
                TryCatch("While opening " + macroDll, sink, () =>
                {
                    assembly = Assembly.Load(macroDll);
                    c.AddMacros(assembly);
                });
            }
            if (options.TryGetValue("noparallel", out value) && (value == null || value == "true"))
            {
                c.Parallel = false;
            }
            if (options.TryGetValue("outext", out c.OutExt) && c.OutExt != null && !c.OutExt.StartsWith("."))
            {
                c.OutExt = "." + c.OutExt;
            }
            if (options.TryGetValue("inlang", out value))
            {
                ApplyLanguageOption(sink, "--inlang", value, ref c.InLang);
            }
            if (options.TryGetValue("outlang", out value))
            {
                IParsingService lang = null;
                ApplyLanguageOption(sink, "--outlang", value, ref lang);
                c.OutLang = lang.Printer ?? c.OutLang;
            }
            if (options.TryGetValue("forcelang", out value) && (value == null || value == "true"))
            {
                c.ForceInLang = true;
            }
            if (!options.ContainsKey("outlang") && c.OutExt != null && FileNameToLanguage(c.OutExt) == null)
            {
                sink.Write(Severity.Error, "--outext", "No language was found for extension «{0}»", c.OutExt);
            }
            double num;

            if (options.TryGetValue("timeout", out value))
            {
                if (!double.TryParse(value, out num) || !(num >= 0))
                {
                    sink.Write(Severity.Error, "--timeout", "Invalid or missing timeout value", c.OutExt);
                }
                else
                {
                    c.AbortTimeout = TimeSpan.FromSeconds(num);
                }
            }

            return(true);
        }
Exemple #12
0
        /// <summary>Processes all standard command-line arguments from
        /// <see cref="KnownOptions"/>, except --help.</summary>
        /// <param name="options">A set of options, presumably derived from command-
        /// line options using <see cref="UG.ProcessCommandLineArguments"/></param>
        /// <param name="warnAboutUnknownOptions">Whether to warn (to <see cref="Sink"/>)
        /// about options not listed in <see cref="KnownOptions"/>.</param>
        /// <param name="inputFiles">Files to open with <see cref="OpenSourceFiles"/></param>
        /// <returns>true, unless inputFiles != null and all input files failed to open.</returns>
        /// <remarks>
        /// This method calls AddStdMacros() unless options includes "nostdmacros".
        /// </remarks>
        public bool ProcessArguments(BMultiMap <string, string> options, bool warnAboutUnknownOptions, IList <string> inputFiles = null)
        {
            Compiler c = this;
            string   value;
            bool?    flag;
            double?  num;
            var      filter = c.Sink as SeverityMessageFilter ?? new SeverityMessageFilter(c.Sink, Severity.NoteDetail);

            if (warnAboutUnknownOptions)
            {
                WarnAboutUnknownOptions(options, Sink, KnownOptions);
            }

            if (options.TryGetValue("verbose", out value))
            {
                if (value != "false")
                {
                    try {                     // Enum.TryParse() does not exist before .NET 4 so use Enum.Parse
                        filter.MinSeverity = (Severity)Enum.Parse(typeof(Severity), value);
                    } catch (Exception) {     // Docs say OverflowException, but that just sounds wrong
                        filter.MinSeverity = Severity.Verbose;
                    }
                }
            }

            IMessageSink sink = c.Sink = filter;

            if ((num = ParseNumericOption(options, "max-expand", sink, 0, 99999)) != null)
            {
                c.MaxExpansions = (int)num.Value;
            }

            foreach (var macroDll in options["macros"])
            {
                Assembly assembly;
                TryCatch("While opening " + macroDll, sink, () =>
                {
                    if (macroDll.Contains('\\') || macroDll.Contains('/'))
                    {
                        // Avoid "Absolute path information is required" exception
                        string fullPath = Path.Combine(Environment.CurrentDirectory, macroDll);
                        assembly        = Assembly.LoadFile(fullPath);
                    }
                    else
                    {
                        assembly = Assembly.LoadFrom(macroDll);
                    }
                    c.AddMacros(assembly);
                });
            }
            foreach (string macroDll in options["macros-longname"])
            {
                Assembly assembly;
                TryCatch("While opening " + macroDll, sink, () =>
                {
                    assembly = Assembly.Load(macroDll);
                    c.AddMacros(assembly);
                });
            }
            if ((flag = ParseBoolOption(options, "noparallel", sink)) != null)
            {
                c.Parallel = flag.Value;
            }
            if (options.TryGetValue("outext", out c.OutExt))
            {
                if (c.OutExt != null && !c.OutExt.StartsWith("."))
                {
                    c.OutExt = "." + c.OutExt;
                }
            }
            if (options.TryGetValue("inlang", out value))
            {
                ApplyLanguageOption(sink, "--inlang", value, ref c.InLang);
            }
            if (options.TryGetValue("outlang", out value))
            {
                IParsingService lang = null;
                ApplyLanguageOption(sink, "--outlang", value, ref lang);
                c.OutLang = (lang as ILNodePrinter) ?? c.OutLang;
            }
            if ((flag = ParseBoolOption(options, "forcelang", sink)) != null)
            {
                c.ForceInLang = flag.Value;
            }
            if (!options.ContainsKey("outlang") && c.OutExt != null && ParsingService.GetServiceForFileName(c.OutExt) == null)
            {
                sink.Error("--outext", "No language was found for extension «{0}»", c.OutExt);
            }
            if ((num = ParseNumericOption(options, "timeout", sink)) != null)
            {
                c.AbortTimeout = TimeSpan.FromSeconds(num.Value);
            }

            foreach (string exprStr in options["set"])
            {
                SetPropertyHelper(exprStr, quote: false);
            }
            foreach (string exprStr in options["snippet"])
            {
                SetPropertyHelper(exprStr, quote: true);
            }

            if (!options.TryGetValue("nostdmacros", out value) && !options.TryGetValue("no-std-macros", out value))
            {
                AddStdMacros();
            }

            if (options.TryGetValue("preserve-comments", out value))
            {
                PreserveComments = value == null || !value.ToString().ToLowerInvariant().IsOneOf("false", "0");
            }

            // Printing options
            if ((num = ParseNumericOption(options, "o-indent-spaces", sink, 0, 20)) != null)
            {
                OutOptions.IndentString = num.Value <= 0 ? "\t" : new string(' ', (int)num.Value);
            }
            if ((flag = ParseBoolOption(options, "o-allow-change-parens", sink)) != null)
            {
                OutOptions.AllowChangeParentheses = flag.Value;
            }
            if ((flag = ParseBoolOption(options, "o-omit-comments", sink)) != null)
            {
                OutOptions.OmitComments = flag.Value;
            }
            if ((flag = ParseBoolOption(options, "o-omit-unknown-trivia", sink)) != null)
            {
                OutOptions.OmitUnknownTrivia = flag.Value;
            }
            if ((flag = ParseBoolOption(options, "o-explicit-trivia", sink)) != null)
            {
                OutOptions.PrintTriviaExplicitly = flag.Value;
            }
            if ((flag = ParseBoolOption(options, "o-compatibility-mode", sink)) != null)
            {
                OutOptions.CompatibilityMode = flag.Value;
            }
            if ((flag = ParseBoolOption(options, "o-compact-mode", sink)) != null)
            {
                OutOptions.CompactMode = flag.Value;
            }

            if (inputFiles != null)
            {
                this.Files = new List <InputOutput>(OpenSourceFiles(Sink, inputFiles));
                if (inputFiles.Count != 0 && Files.Count == 0)
                {
                    return(false);
                }
            }

            return(true);
        }
Exemple #13
0
		protected override byte[] Generate(string inputFilePath, string inputFileContents, string defaultNamespace, IVsGeneratorProgress progressCallback)
		{
			string oldCurDir = Environment.CurrentDirectory;
			try {
				string inputFolder = Path.GetDirectoryName(inputFilePath);
 				Environment.CurrentDirectory = inputFolder; // --macros should be relative to file being processed

				var options = new BMultiMap<string, string>();
				var argList = G.SplitCommandLineArguments(defaultNamespace);
				UG.ProcessCommandLineArguments(argList, options, "", LeMP.Compiler.ShortOptions, LeMP.Compiler.TwoArgOptions);

				string _;
				var KnownOptions = LeMP.Compiler.KnownOptions;
				if (options.TryGetValue("help", out _) || options.TryGetValue("?", out _))
					LeMP.Compiler.ShowHelp(KnownOptions);
				
				// Originally I wrote a conversion from IVsGeneratorProgress to
 				// IMessageSink so that errors could be reported immediately and
				// directly to Visual Studio. This broke in a bizarre way when I
				// added processing on a separate thread (in order to be able to
				// abort the thread if it runs too long); I got the following
				// InvalidCastException: "Unable to cast COM object of type 'System.__ComObject' 
				// to interface type 'Microsoft.VisualStudio.Shell.Interop.IVsGeneratorProgress'.
				// This operation failed because the QueryInterface call on the COM component for 
				// the interface with IID '{BED89B98-6EC9-43CB-B0A8-41D6E2D6669D}' failed due to 
				// the following error: No such interface supported (Exception from HRESULT: 
				// 0x80004002 (E_NOINTERFACE))."
				// 
				// A simple solution is to store the messages rather than reporting
				// them immediately. I'll report the errors at the very end.
				MessageHolder sink = new MessageHolder();
				
				var sourceFile = new InputOutput((UString)inputFileContents, Path.GetFileName(inputFilePath));

				var c = new Compiler(sink, sourceFile) { 
					AbortTimeout = TimeSpan.FromSeconds(10),
					Parallel = false // only one file, parallel doesn't help
				};

				if (LeMP.Compiler.ProcessArguments(c, options))
				{
					if (options.ContainsKey("no-out-header"))
					{
						options.Remove("no-out-header", 1);
						c.NoOutHeader = true;
					}
					LeMP.Compiler.WarnAboutUnknownOptions(options, sink, KnownOptions);
					if (c != null)
					{
						if (inputFilePath.EndsWith(".les", StringComparison.OrdinalIgnoreCase))
							c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude.Les"));
						Configure(c);
						c.Run();

						// Report errors
						foreach (var msg in sink.List)
							ReportErrorToVS(progressCallback, msg.Severity, msg.Context, msg.Format, msg.Args);

						return Encoding.UTF8.GetBytes(c.Output.ToString());
					}
				}
				return null;
			} finally {
				Environment.CurrentDirectory = oldCurDir;
			}
		}
Exemple #14
0
		/// <summary>Processes all standard command-line arguments from 
		/// <see cref="KnownOptions"/>, except --help.</summary>
		/// <param name="options">A set of options, presumably derived from command-
		/// line options using <see cref="UG.ProcessCommandLineArguments"/></param>
		/// <param name="warnAboutUnknownOptions">Whether to warn (to <see cref="Sink"/>) 
		/// about options not listed in <see cref="KnownOptions"/>.</param>
		/// <param name="inputFiles">Files to open with <see cref="OpenSourceFiles"/></param>
		/// <returns>true, unless inputFiles != null and all input files failed to open.</returns>
		/// <remarks>
		/// This method calls AddStdMacros() unless options includes "nostdmacros".
		/// </remarks>
		public bool ProcessArguments(BMultiMap<string, string> options, bool warnAboutUnknownOptions, IList<string> inputFiles = null)
		{
			Compiler c = this;
			string value;
			bool? flag;
			double? num;
			var filter = c.Sink as SeverityMessageFilter ?? new SeverityMessageFilter(c.Sink, Severity.NoteDetail);

			if (warnAboutUnknownOptions)
				WarnAboutUnknownOptions(options, Sink, KnownOptions);

			if (options.TryGetValue("verbose", out value))
			{
				if (value != "false") {
					try { // Enum.TryParse() does not exist before .NET 4 so use Enum.Parse
						filter.MinSeverity = (Severity)Enum.Parse(typeof(Severity), value);
					} catch (Exception) { // Docs say OverflowException, but that just sounds wrong
						filter.MinSeverity = Severity.Verbose;
					}
				}
			}
			
			IMessageSink sink = c.Sink = filter;
			
			if ((num = ParseNumericOption(options, "max-expand", sink, 0, 99999)) != null)
				c.MaxExpansions = (int)num.Value;

			foreach (var macroDll in options["macros"])
			{
				Assembly assembly;
				TryCatch("While opening " + macroDll, sink, () =>
				{
					if (macroDll.Contains('\\') || macroDll.Contains('/')) {
						// Avoid "Absolute path information is required" exception
						string fullPath = Path.Combine(Environment.CurrentDirectory, macroDll);
						assembly = Assembly.LoadFile(fullPath);
					} else
						assembly = Assembly.LoadFrom(macroDll);
					c.AddMacros(assembly);
				});
			}
			foreach (string macroDll in options["macros-longname"])
			{
				Assembly assembly;
				TryCatch("While opening " + macroDll, sink, () =>
				{
					assembly = Assembly.Load(macroDll);
					c.AddMacros(assembly);
				});
			}
			if ((flag = ParseBoolOption(options, "noparallel", sink)) != null)
				c.Parallel = flag.Value;
			if (options.TryGetValue("outext", out c.OutExt)) {
				if (c.OutExt != null && !c.OutExt.StartsWith("."))
					c.OutExt = "." + c.OutExt;
			}
			if (options.TryGetValue("inlang", out value)) {
				ApplyLanguageOption(sink, "--inlang", value, ref c.InLang);
			}
			if (options.TryGetValue("outlang", out value)) {
				IParsingService lang = null;
				ApplyLanguageOption(sink, "--outlang", value, ref lang);
				c.OutLang = (lang as ILNodePrinter) ?? c.OutLang;
			}
			if ((flag = ParseBoolOption(options, "forcelang", sink)) != null)
				c.ForceInLang = flag.Value;
			if (!options.ContainsKey("outlang") && c.OutExt != null && ParsingService.GetServiceForFileName(c.OutExt) == null)
				sink.Error("--outext", "No language was found for extension «{0}»", c.OutExt);
			if ((num = ParseNumericOption(options, "timeout", sink)) != null)
				c.AbortTimeout = TimeSpan.FromSeconds(num.Value);

			foreach (string exprStr in options["set"])
				SetPropertyHelper(exprStr, quote: false);
			foreach (string exprStr in options["snippet"])
				SetPropertyHelper(exprStr, quote: true);

			if (!options.TryGetValue("nostdmacros", out value) && !options.TryGetValue("no-std-macros", out value))
				AddStdMacros();

			if (options.TryGetValue("preserve-comments", out value))
				PreserveComments = value == null || !value.ToString().ToLowerInvariant().IsOneOf("false", "0");

			// Printing options
			if ((num = ParseNumericOption(options, "o-indent-spaces", sink, 0, 20)) != null)
				OutOptions.IndentString = num.Value <= 0 ? "\t" : new string(' ', (int)num.Value);
			if ((flag = ParseBoolOption(options, "o-allow-change-parens", sink)) != null)
				OutOptions.AllowChangeParentheses = flag.Value;
			if ((flag = ParseBoolOption(options, "o-omit-comments", sink)) != null)
				OutOptions.OmitComments = flag.Value;
			if ((flag = ParseBoolOption(options, "o-omit-unknown-trivia", sink)) != null)
				OutOptions.OmitUnknownTrivia = flag.Value;
			if ((flag = ParseBoolOption(options, "o-explicit-trivia", sink)) != null)
				OutOptions.PrintTriviaExplicitly = flag.Value;
			if ((flag = ParseBoolOption(options, "o-compatibility-mode", sink)) != null)
				OutOptions.CompatibilityMode = flag.Value;
			if ((flag = ParseBoolOption(options, "o-compact-mode", sink)) != null)
				OutOptions.CompactMode = flag.Value;

			if (inputFiles != null) {
				this.Files = new List<InputOutput>(OpenSourceFiles(Sink, inputFiles));
				if (inputFiles.Count != 0 && Files.Count == 0)
					return false;
			}

			return true;
		}