protected override void ExecuteCmd(List <string> args)
        {
            if (_languagedLoaded)
            {
                BetterConsole.WriteOnNextLine("Language already loaded, unloading languages is not currently supported.");
                return;
            }

            if (!File.Exists(args[0]))
            {
                BetterConsole.WriteOnNextLine($"No file named {args[0]}");
                return;
            }

            try {
                var assem        = Assembly.LoadFile(args[0]);
                var handlers     = assem.GetTypes().Where(x => x.GetInterfaces().Contains(typeof(ISymbolHandler))).Select(x => (ISymbolHandler)Activator.CreateInstance(x)).ToArray();
                var languageInfo = (ILanguageInfo)Activator.CreateInstance(assem.GetTypes().First(x => x.GetInterfaces().Contains(typeof(ILanguageInfo))));
                Program.LanguageName = languageInfo.Name;

                var results = LoadLanguageInterpreter.MakeTemporaryParser(languageInfo.Grammar);
                if (results.Item2.Count > 0)
                {
                    BetterConsole.WriteOnNextLine($"Failure to load language: {string.Join("\n\n", results.Item2.Select(y => TreePrinter.ToString(y, z => z.SubErrors)))}", ConsoleColor.Red);
                    return;
                }

                Program._languageInterp = code => results.Item1(code, handlers);
                _languagedLoaded        = true;
                BetterConsole.WriteOnNextLine($"{languageInfo.Name} loaded.");
            } catch (Exception ex) {
                BetterConsole.WriteOnNextLine($"{args[0]} is not a path to a valid language assembly.");
            }
        }
        public void NotEmptyString()
        {
            var grammar   = $"<{"EntryPoint"}> = -'''1'";
            var codeToRun = "1";
            var results   = LoadLanguageInterpreter.MakeTemporaryParser(grammar);

            Expect(results.Item2, Is.Empty);

            var result = results.Item1(codeToRun, new ISymbolHandler[] { new CombineToStringSymbolHandler("EntryPoint") });

            Expect(result.Item1, Is.Empty, "Negating the empty string should always fail");
        }
        public void DoubleNegative()
        {
            var grammar   = $"<EntryPoint> = -(-'1')'1'";
            var codeToRun = "11";
            var results   = LoadLanguageInterpreter.MakeTemporaryParser(grammar);

            Expect(results.Item2, Is.Empty);

            var result = results.Item1(codeToRun, new ISymbolHandler[] { new CombineToStringSymbolHandler("EntryPoint") });

            Expect(result.Item1[0], Is.EqualTo("1"), "result was incorrect");
        }
        public void GroupingTest()
        {
            var grammar   = $"<{"EntryPoint"}> = '0'('1'|'2''3')";
            var codeToRun = "0231";
            var results   = LoadLanguageInterpreter.MakeTemporaryParser(grammar);

            Expect(results.Item2, Is.Empty);

            var result = results.Item1(codeToRun, new ISymbolHandler[] { new CombineToStringSymbolHandler("EntryPoint") });

            Expect(result.Item1[0], Is.EqualTo("023"), "result was incorrect");
        }
        public void LiteralWithQuotes()
        {
            var grammar   = $"<{"EntryPoint"}> = '\"123\"'";
            var codeToRun = "\"123\"";
            var results   = LoadLanguageInterpreter.MakeTemporaryParser(grammar);

            Expect(results.Item2, Is.Empty);

            var result = results.Item1(codeToRun, new ISymbolHandler[] { new CombineToStringSymbolHandler("EntryPoint") });

            Expect(result.Item1[0], Is.EqualTo("\"123\""), "result was incorrect");
        }
        public void SimpleDigitRangeTest()
        {
            var grammar    = $"<{"EntryPoint"}> = [0:9]";
            var codeToRun  = "1";
            var addHandler = Handler.Create("EntryPoint", args => int.Parse(args.ToDelimitedString("")));
            var results    = LoadLanguageInterpreter.MakeTemporaryParser(grammar);

            Expect(results.Item2, Is.Empty);

            var result = results.Item1(codeToRun, new ISymbolHandler[] { addHandler });

            Expect(result.Item1[0], Is.EqualTo(1), "result was incorrect");
        }
        public void Recursion()
        {
            var grammar      = $"<{"EntryPoint"}> = '1'|'1'<{"EntryPoint"}>";
            var codeToRun    = "111";
            var entryHandler = Handler.Create("EntryPoint", args => int.Parse(args.ToDelimitedString("")));
            var results      = LoadLanguageInterpreter.MakeTemporaryParser(grammar);

            Expect(results.Item2, Is.Empty);

            var result = results.Item1(codeToRun, new ISymbolHandler[] { entryHandler });

            Expect(result.Item1[0], Is.EqualTo(111), "result was incorrect");
        }
        public void KeywordTest()
        {
            var grammar   = $@"<char> = 'a'|'b'|'c'
                             <allchars> = <char>|<char><allchars>
                             <keywords> = 'cba'|'abc'
                             <keyword> = <keywords> -<char>
                             <name> = -<keyword><allchars>
                             <{"EntryPoint"}> = <name>|<keyword>";
            var codeToRun = "abca";
            var results   = LoadLanguageInterpreter.MakeTemporaryParser(grammar);

            Expect(results.Item2, Is.Empty);

            var result = results.Item1(codeToRun, new ISymbolHandler[] { new CombineToStringSymbolHandler("keyword") });

            Expect(result.Item1[0], Is.Not.EqualTo("abc"), "result was incorrect");
        }
        public void SomeHandlersNotDefined()
        {
            var grammar = $@"<{"EntryPoint"}> = <a>
                             <a> = <digit_or_char>|<digit_or_char><a>
                             <digit_or_char> = <digit>|<char>
                             <digit> = '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'
                             <char> = 'a'|'b'|'c'";

            var codeToRun    = "123abc";
            var entryHandler = Handler.Create("EntryPoint", args => args);
            var results      = LoadLanguageInterpreter.MakeTemporaryParser(grammar);

            Expect(results.Item2, Is.Empty);

            var result = results.Item1(codeToRun, new ISymbolHandler[] { entryHandler });

            Expect(result.Item1.ToDelimitedString(""), Is.EqualTo(codeToRun));
        }
        public void AddTest()
        {
            var grammar = $@"<{"EntryPoint"}> = <add>
                             <add> = <digit>|<digit>'+'<add>
                             <digit> = '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'";

            var codeToRun    = "1+2+3+4+5";
            var entryHandler = Handler.Create("EntryPoint", args => args.First());
            var digitHandler = Handler.Create("digit", args => int.Parse(args.First().ToString()));
            var addHandler   = Handler.Create("add", args => args.Select(x => x.ToString() == "+" ? 0 : (int)x).Sum());
            var results      = LoadLanguageInterpreter.MakeTemporaryParser(grammar);

            Expect(results.Item2, Is.Empty);

            var result = results.Item1(codeToRun, new ISymbolHandler[] { entryHandler, digitHandler, addHandler });

            Expect(result.Item1[0], Is.EqualTo(15), "Incorrect result");
        }