Beispiel #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();
			}
		}
Beispiel #2
0
        private double?ParseNumericOption(BMultiMap <string, string> options, string key, IMessageSink sink, double?min = null, double?max = null)
        {
            string value;

            if (!options.TryGetValue(key, out value))
            {
                return(null);
            }
            double num;

            if (double.TryParse(value ?? "", out num))
            {
                if ((min == null || num >= min.Value) &&
                    (max == null || num <= max.Value))
                {
                    return(num);
                }
            }
            if (sink != null)
            {
                if (min != null && max != null)
                {
                    sink.Error("--" + key, "Expected numeric value between {0} and {1}", min.Value, max.Value);
                }
                else
                {
                    sink.Error("--" + key, "Expected numeric value");
                }
            }
            return(null);
        }
Beispiel #3
0
        private bool?ParseBoolOption(BMultiMap <string, string> options, string key, IMessageSink sink)
        {
            string value;

            if (!options.TryGetValue(key, out value))
            {
                return(null);
            }
            if (value == null)
            {
                return(true);
            }
            if (value.Equals("true", StringComparison.InvariantCultureIgnoreCase) || value == "1")
            {
                return(true);
            }
            if (value.Equals("false", StringComparison.InvariantCultureIgnoreCase) || value == "0")
            {
                return(false);
            }
            if (sink != null)
            {
                sink.Error("--" + key, "Expected boolean `true` or `false`");
            }
            return(null);
        }
Beispiel #4
0
        public IReadOnlyList <Pair <ILNode, IndexRange> > FindRelatedNodesCore(IndexRange targetRange, int maxSearchResults, bool trim)
        {
            var candidates = new Dictionary <Pair <ILNode, IndexRange>, float>();

            // This is a heuristic search, not an algorithm; it is not guaranteed to find the
            // best answer, rather we scan enough entries to find what we're looking for with
            // high probability. In total, scan about 10x as many entries as maxSearchResults.
            Scan(_startLocations, targetRange.StartIndex, targetRange, 1, maxSearchResults * 5, candidates);
            Scan(_startLocations, targetRange.StartIndex, targetRange, -1, maxSearchResults * 2, candidates);
            Scan(_endLocations, targetRange.EndIndex, targetRange, 1, maxSearchResults * 1, candidates);
            Scan(_endLocations, targetRange.EndIndex, targetRange, -1, maxSearchResults * 2, candidates);

            var sorted = new BMultiMap <float, Pair <ILNode, IndexRange> >(null, (p, q) => 0);

            foreach (var candidate in candidates)
            {
                if (!trim || sorted[candidate.Value].StartIndex < maxSearchResults)
                {
                    sorted[candidate.Value].Add(candidate.Key);
                }
            }
            if (trim && sorted.Count > maxSearchResults)
            {
                sorted.RemoveRange(maxSearchResults, sorted.Count - maxSearchResults);
            }
            return(sorted.Select(pair => pair.Value).ToList());
        }
Beispiel #5
0
 public void NodeAdded(AListNode <K, T> child, AListInnerBase <K, T> parent)
 {
     if (_nodes == null)
     {
         _nodes = new BMultiMap <AListNode <K, T>, AListInnerBase <K, T> >(CompareNodeHashCodes, CompareInnerHashCodes);
     }
     _nodes.Add(new KeyValuePair <AListNode <K, T>, AListInnerBase <K, T> >(child, parent));
 }
Beispiel #6
0
 public static void WarnAboutUnknownOptions(BMultiMap <string, string> options, IMessageSink sink, IDictionary <string, Pair <string, string> > knownOptions)
 {
     foreach (var opt in options.Keys)
     {
         if (!knownOptions.ContainsKey(opt))
         {
             sink.Write(Severity.Warning, "Command line", "Unrecognized option '--{0}'", opt);
         }
     }
 }
Beispiel #7
0
        public virtual int Generate(string inputFilePath, string inputFileContents, string defaultNamespace, IntPtr[] outputFileContents, out uint outputSize, IVsGeneratorProgress progressCallback)
        {
            string inputFolder = Path.GetDirectoryName(inputFilePath);
            string oldCurDir   = Environment.CurrentDirectory;

            try {
                Environment.CurrentDirectory = inputFolder;                 // --macros should be relative to file being processed

                var sourceFile = new StringCharSourceFile(inputFileContents, inputFilePath);
                var sink       = ToMessageSink(progressCallback);

                var c = new Compiler(sink, sourceFile);

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

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

                Symbol minSeverity = MessageSink.Note;
                var    filter      = new SeverityMessageFilter(MessageSink.Console, minSeverity);

                if (LEL.Compiler.ProcessArguments(c, options))
                {
                    LEL.Compiler.WarnAboutUnknownOptions(options, MessageSink.Console, KnownOptions);
                    if (c != null)
                    {
                        c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LEL.Prelude"));
                        c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("Loyc.LLParserGenerator"));
                        c.AddMacros(typeof(Loyc.LLParserGenerator.Macros).Assembly);
                        c.Run();
                    }

                    var outputBytes = Encoding.UTF8.GetBytes(c.Output.ToString());
                    c.Output              = null;        // no longer needed
                    outputSize            = (uint)outputBytes.Length;
                    outputFileContents[0] = Marshal.AllocCoTaskMem(outputBytes.Length);
                    Marshal.Copy(outputBytes, 0, outputFileContents[0], outputBytes.Length);
                }
                else
                {
                    outputFileContents[0] = IntPtr.Zero;
                    outputSize            = 0;
                }
                return(VSConstants.S_OK);
            } finally {
                Environment.CurrentDirectory = oldCurDir;
            }
        }
Beispiel #8
0
        public static Compiler ProcessArguments(BMultiMap <string, string> options, SeverityMessageFilter sink, Type prelude, List <string> inputFiles)
        {
            if (inputFiles.Count == 0)
            {
                sink.Write(Severity.Error, null, "No input provided, stopping.");
                return(null);
            }
            Compiler c = new Compiler(sink, prelude);

            c.Files = new List <InputOutput>(OpenSourceFiles(sink, inputFiles));
            return(ProcessArguments(c, options) ? c : null);
        }
Beispiel #9
0
        private void RunLeMP(IList <string> args, string inputCode, string inputPath)
        {
            var options = new BMultiMap <string, string>();

            UG.ProcessCommandLineArguments(args, options, "", LeMP.Compiler.ShortOptions, LeMP.Compiler.TwoArgOptions);

            string _;
            var    KnownOptions = LeMP.Compiler.KnownOptions;

            if (options.TryGetValue("help", out _) || options.TryGetValue("?", out _))
            {
                var ms = new MemoryStream();
                LeMP.Compiler.ShowHelp(LeMP.Compiler.KnownOptions, new StreamWriter(ms));
                string output = Encoding.UTF8.GetString(ms.GetBuffer(), 0, (int)ms.Length);
                _outFileName = null;
                ShowOutput(output);
            }
            else
            {
                var sink       = MessageSink.FromDelegate(WriteMessage);
                var sourceFile = new InputOutput((UString)inputCode, Path.GetFileName(inputPath));

                var c = new Compiler(sink, sourceFile);
                c.Files = new List <InputOutput> {
                    sourceFile
                };
                c.Parallel = false;                 // only one file, parallel doesn't help

                if (LeMP.Compiler.ProcessArguments(c, options))
                {
                    LeMP.Compiler.WarnAboutUnknownOptions(options, sink, KnownOptions);

                    c.AddMacros(typeof(global::LeMP.StandardMacros).Assembly);
                    c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP"));
                    c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude"));
                    if (inputPath.EndsWith(".les", StringComparison.OrdinalIgnoreCase))
                    {
                        c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude.Les"));
                    }

                    LempStarted = true;
                    new Thread(() => {
                        try {
                            c.Run();
                            // Must get OutFileName after calling Run()
                            _outFileName = sourceFile.OutFileName;
                            ShowOutput(c.Output.ToString());
                        } finally { LempStarted = false; }
                    }).Start();
                }
            }
        }
Beispiel #10
0
 public void RootChanged(AListNode <K, T> newRoot, bool clear)
 {
     if (newRoot == null)
     {
         if (!clear && _items.Count != 0)
         {
             BadState();
         }
         _items.Clear();
         _nodes = null;
     }
     _root = newRoot;
 }
Beispiel #11
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));
            }
        }
Beispiel #12
0
        /// <summary>Processes command-line arguments to build a BMultiMap and
        /// sends those options to the other overload of this method.</summary>
        /// <param name="args">Arg list from which to extract options. **NOTE**:
        /// discovered options are removed from the list. This parameter
        /// cannot be an array.</param>
        /// <param name="warnAboutUnknownOptions">Whether this method should
        /// call <see cref="WarnAboutUnknownOptions"/> for you.</param>
        /// <param name="autoOpenInputFiles">Whether to open input files
        /// for you by calling <see cref="OpenSourceFiles(IMessageSink, IEnumerable{string})"/>.
        /// </param>
        /// <param name="inputFiles">A list of input files to open if
        /// autoOpenInputFiles is true. If this is null, The input files are
        /// assumed to be those command-line arguments left over after the options
        /// are removed.</param>
        /// <returns>The map of options (key-value pairs and, for options that
        /// don't have a value, key-null pairs).</returns>
        /// <remarks>
        /// Note: If you get your command-line arguments as a single
        /// string, use <see cref="G.SplitCommandLineArguments(string)"/> first
        /// to split it into an array.
        /// <para/>
        /// This method doesn't check for --help. To implement --help, call
        /// <see cref="MaybeShowHelp"/> on the return value.
        /// </remarks>
        public BMultiMap <string, string> ProcessArguments(IList <string> args, bool warnAboutUnknownOptions, bool autoOpenInputFiles, IList <string> inputFiles = null)
        {
            BMultiMap <string, string> options = new BMultiMap <string, string>();

            UG.ProcessCommandLineArguments(args, options, "", ShortOptions, TwoArgOptions);
            if (inputFiles == null && autoOpenInputFiles)
            {
                inputFiles = args;
            }
            if (!ProcessArguments(options, warnAboutUnknownOptions, inputFiles))
            {
                return(null);
            }
            return(options);
        }
Beispiel #13
0
 private static void Scan(BMultiMap <int, Pair <ILNode, int> > locations, int charIndex, IndexRange targetRange, int scanDirection, int iterations, Dictionary <Pair <ILNode, IndexRange>, float> results)
 {
     for (int i = locations.FindLowerBound(charIndex); iterations > 0; iterations--, i += scanDirection)
     {
         var pair = locations.TryGet(i, out bool fail);
         if (!fail)
         {
             var   nodeWithRange = Pair.Create(pair.Value.Item1, RangeOf(pair));
             float score         = GetMismatchScore(pair, targetRange);
             if (score < results.TryGetValue(nodeWithRange, float.MaxValue))
             {
                 results[nodeWithRange] = score;
             }
         }
     }
 }
Beispiel #14
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
            }
        }
Beispiel #15
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();
            }
        }
Beispiel #16
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
			}
		}
Beispiel #17
0
        public static Compiler ProcessArguments(List <string> inputFiles, BMultiMap <string, string> options, SeverityMessageFilter sink, Type prelude)
        {
            if (inputFiles.Count == 0)
            {
                sink.Write(Severity.Error, null, "No input provided, stopping.");
                return(null);
            }

            string value;

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

            var c = new Compiler(sink, prelude, inputFiles);

            return(ProcessArguments(c, options) ? c : null);
        }
Beispiel #18
0
		public static void WarnAboutUnknownOptions(BMultiMap<string, string> options, IMessageSink sink, IDictionary<string, Pair<string, string>> knownOptions)
		{
			foreach (var opt in options.Keys) {
				if (!knownOptions.ContainsKey(opt))
					sink.Write(Severity.Warning, "Command line", "Unrecognized option '--{0}'", opt);
			}
		}
Beispiel #19
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;
		}
Beispiel #20
0
		public static Compiler ProcessArguments(BMultiMap<string, string> options, SeverityMessageFilter sink, Type prelude, List<string> inputFiles)
		{
			if (inputFiles.Count == 0)
			{
				sink.Write(Severity.Error, null, "No input provided, stopping.");
				return null;
			}
			Compiler c = new Compiler(sink, prelude);
			c.Files = new List<InputOutput>(OpenSourceFiles(sink, inputFiles));
			return ProcessArguments(c, options) ? c : null;
		}
Beispiel #21
0
		void WhereClausesOpt(ref LNode name)
		{
			TokenType la0;
			#line 1163 "EcsParserGrammar.les"
			var list = new BMultiMap<Symbol,LNode>();
			#line default
			// Line 1164: (WhereClause)*
			for (;;) {
				la0 = LA0;
				if (la0 == TT.ContextualKeyword)
					list.Add(WhereClause());
				else
					break;
			}
			#line 1165 "EcsParserGrammar.les"
			if ((list.Count != 0)) {
				if ((!name.CallsMin(S.Of, 2))) {
					Error("'{0}' is not generic and cannot use 'where' clauses.", name.ToString());
				} else {
					var tparams = name.Args.ToRWList();
					for (int i = 1; i < tparams.Count; i++) {
						var wheres = list[TParamSymbol(tparams[i])];
						tparams[i] = tparams[i].PlusAttrs(wheres);
						wheres.Clear();
					}
					name = name.WithArgs(tparams.ToRVList());
					if ((list.Count > 0)) {
						Error(list[0].Value, "There is no type parameter named '{0}'", list[0].Key);
					}
				}
			}
			#line default
		}
Beispiel #22
0
		private double? ParseNumericOption(BMultiMap<string, string> options, string key, IMessageSink sink, double? min = null, double? max = null)
		{
			string value;
			if (!options.TryGetValue(key, out value))
				return null;
			double num;
			if (double.TryParse(value ?? "", out num)) {
				if ((min == null || num >= min.Value) && 
					(max == null || num <= max.Value))
					return num;
			}
			if (sink != null) {
				if (min != null && max != null)
					sink.Error("--" + key, "Expected numeric value between {0} and {1}", min.Value, max.Value);
				else
					sink.Error("--" + key, "Expected numeric value");
			}
			return null;
		}
Beispiel #23
0
        private void UpdateGraph(PlotModel model, MSet <EzDataPoint> points)
        {
            model.Series.Clear();
            var allSeries = new BMultiMap <string, EzDataPoint>((a, b) => string.CompareOrdinal(a, b));

            foreach (var dp in points)
            {
                allSeries.Add(dp.Series, dp);
            }

            // Add text labels to axis if the data uses text Parameters
            CategoryAxis cAxis = null;

            if (points.Any(dp => dp.Parameter is string))
            {
                var headings = new SortedSet <string>(points.Select(dp => dp.Parameter as string).WhereNotNull());
                cAxis = model.Axes.OfType <CategoryAxis>().SingleOrDefault();
                if (cAxis == null)
                {
                    model.Axes.Add(cAxis = new CategoryAxis {
                        MajorGridlineStyle = LineStyle.Dot,
                        Position           = AxisPosition.Bottom
                    });
                }
                cAxis.Labels.Clear();
                foreach (var text in headings)
                {
                    cAxis.Labels.Add(text);
                }
                cAxis.Key = "CategoryAxis";
            }

            int iSeries = 0;

            foreach (var series in allSeries.Values)
            {
                if (series.Any(p => p.Parameter is string))
                {
                    var plotSeries = new ColumnSeries {
                        Title = series.First().Series
                    };
                    plotSeries.XAxisKey = cAxis.Key;
                    foreach (var dp in series)
                    {
                        plotSeries.Items.Add(new ColumnItem(dp.Value, cAxis.Labels.IndexOf(dp.Parameter.ToString())));
                    }
                    model.Series.Add(plotSeries);
                }
                else
                {
                    var plotSeries = new LineSeries {
                        Title = series.First().Series
                    };
                    if (cAxis != null)
                    {
                        plotSeries.XAxisKey = cAxis.Key;
                    }
                    // There are 7 marker types starting at 1, excluding None (0)
                    plotSeries.MarkerType = (MarkerType)((iSeries % 7) + 1);
                    plotSeries.MarkerSize = 4;
                    plotSeries.MarkerFill = plotSeries.Color;
                    foreach (var dp in series)
                    {
                        plotSeries.Points.Add(new OxyPlot.DataPoint(Convert.ToDouble(dp.Parameter), dp.Value));
                    }
                    model.Series.Add(plotSeries);
                }
                iSeries++;
            }
        }
Beispiel #24
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);
        }
Beispiel #25
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;
			}
		}
Beispiel #26
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);
        }
Beispiel #27
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);
        }
Beispiel #28
0
		private bool? ParseBoolOption(BMultiMap<string, string> options, string key, IMessageSink sink)
		{
			string value;
			if (!options.TryGetValue(key, out value))
				return null;
			if (value == null)
				return true;
			if (value.Equals("true", StringComparison.InvariantCultureIgnoreCase) || value == "1")
				return true;
			if (value.Equals("false", StringComparison.InvariantCultureIgnoreCase) || value == "0")
				return false;
			if (sink != null)
				sink.Error("--" + key, "Expected boolean `true` or `false`");
			return null;
		}
Beispiel #29
0
 public AListIndexer()
 {
     _items = new BMultiMap <T, AListLeaf <K, T> >(CompareTHashCodes, CompareLeafHashCodes);
 }
Beispiel #30
0
		public virtual int Generate(string inputFilePath, string inputFileContents, string defaultNamespace, IntPtr[] outputFileContents, out uint outputSize, IVsGeneratorProgress progressCallback)
		{
			string inputFolder = Path.GetDirectoryName(inputFilePath);
			string oldCurDir = Environment.CurrentDirectory;
			try {
 				Environment.CurrentDirectory = inputFolder; // --macros should be relative to file being processed

				var sourceFile = new StringCharSourceFile(inputFileContents, inputFilePath);
				var sink = ToMessageSink(progressCallback);
			
				var c = new Compiler(sink, sourceFile);

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

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

				Symbol minSeverity = MessageSink.Note;
				var filter = new SeverityMessageFilter(MessageSink.Console, minSeverity);

				if (LEL.Compiler.ProcessArguments(c, options)) {
					LEL.Compiler.WarnAboutUnknownOptions(options, MessageSink.Console, KnownOptions);
					if (c != null)
					{
						c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LEL.Prelude"));
						c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("Loyc.LLParserGenerator"));
						c.AddMacros(typeof(Loyc.LLParserGenerator.Macros).Assembly);
						c.Run();
					}

					var outputBytes = Encoding.UTF8.GetBytes(c.Output.ToString());
					c.Output = null; // no longer needed
					outputSize = (uint)outputBytes.Length;
					outputFileContents[0] = Marshal.AllocCoTaskMem(outputBytes.Length);
					Marshal.Copy(outputBytes, 0, outputFileContents[0], outputBytes.Length);
				}
				else
				{
					outputFileContents[0] = IntPtr.Zero;
					outputSize = 0;
				}
				return VSConstants.S_OK;
			} finally {
				Environment.CurrentDirectory = oldCurDir;
			}
		}
Beispiel #31
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;
            }
        }
Beispiel #32
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();
            }
        }
Beispiel #33
0
		/// <summary>Processes command-line arguments to build a BMultiMap and 
		/// sends those options to the other overload of this method.</summary>
		/// <param name="args">Arg list from which to extract options. **NOTE**:
		/// discovered options are removed from the list. This parameter 
		/// cannot be an array.</param>
		/// <param name="warnAboutUnknownOptions">Whether this method should
		/// call <see cref="WarnAboutUnknownOptions"/> for you.</param>
		/// <param name="autoOpenInputFiles">Whether to open input files 
		/// for you by calling <see cref="OpenSourceFiles(IMessageSink, IEnumerable{string})"/>.
		/// </param>
		/// <param name="inputFiles">A list of input files to open if 
		/// autoOpenInputFiles is true. If this is null, The input files are 
		/// assumed to be those command-line arguments left over after the options 
		/// are removed.</param>
		/// <returns>The map of options (key-value pairs and, for options that 
		/// don't have a value, key-null pairs).</returns>
		/// <remarks>
		/// Note: If you get your command-line arguments as a single 
		/// string, use <see cref="G.SplitCommandLineArguments(string)"/> first 
		/// to split it into an array.
		/// <para/>
		/// This method doesn't check for --help. To implement --help, call 
		/// <see cref="MaybeShowHelp"/> on the return value.
		/// </remarks>
		public BMultiMap<string, string> ProcessArguments(IList<string> args, bool warnAboutUnknownOptions, bool autoOpenInputFiles, IList<string> inputFiles = null)
		{
			BMultiMap<string,string> options = new BMultiMap<string,string>();

			UG.ProcessCommandLineArguments(args, options, "", ShortOptions, TwoArgOptions);
			if (inputFiles == null && autoOpenInputFiles)
				inputFiles = args;
			if (!ProcessArguments(options, warnAboutUnknownOptions, inputFiles))
				return null;
			return options;
		}
Beispiel #34
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);
        }
Beispiel #35
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;
		}