Пример #1
0
        ProgramNode ParseModule(ModulePath?path, SourceText source, SyntaxContext context)
        {
            var msg = path != null ? $" with path '{path}'" : string.Empty;

            if (!_loading.Add(source.FullPath))
            {
                throw new ModuleLoadException($"Module{msg} could not be loaded due to circular 'use' declarations.");
            }

            try
            {
                if (context.Parses.ContainsKey(source.FullPath))
                {
                    throw new ModuleLoadException($"Module{msg} was already loaded previously.");
                }

                var lex   = LanguageLexer.Lex(source);
                var parse = LanguageParser.Parse(lex, SyntaxMode.Normal);

                context.AddParse(source.FullPath, parse);

                foreach (var diag in lex.Diagnostics)
                {
                    context.AddDiagnostic(diag);
                }

                foreach (var diag in parse.Diagnostics)
                {
                    context.AddDiagnostic(diag);
                }

                var analysis = LanguageAnalyzer.Analyze(parse, this, context);

                foreach (var diag in analysis.Diagnostics)
                {
                    context.AddDiagnostic(diag);
                }

                return(analysis.IsSuccess ? (ProgramNode)parse.Tree : throw new ModuleLoadException(
                           $"Module{msg} failed to load due to syntax and/or semantic errors."));
            }
            finally
            {
                _ = _loading.Remove(source.FullPath);
            }
        }
Пример #2
0
        int Run(Options options)
        {
            ReadLine.AutoCompletionHandler = null;

            var loader = new StandardModuleLoader(ModuleLoaderMode.Interactive);
            var i      = 0;

            while (true)
            {
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.Write($"flare({i})> ");
                Console.ResetColor();

                var text      = new StringBuilder();
                var quit      = false;
                var continued = false;

                while (true)
                {
                    var input = ReadLine.Read();

                    if (input != string.Empty)
                    {
                        ReadLine.AddHistory(input);
                    }

                    var broken = false;

                    if (input == "'repl:quit")
                    {
                        quit = true;
                        break;
                    }
                    if (continued && input == "'repl:break")
                    {
                        broken = true;
                    }
                    else
                    {
                        _ = text.AppendLine(input);
                    }

                    var lex = LanguageLexer.Lex(StringSourceText.From("<repl>", text.ToString()));

                    foreach (var diag in lex.Diagnostics)
                    {
                        LogDiagnostic(diag);
                    }

                    if (!lex.IsSuccess)
                    {
                        break;
                    }

                    var parse = LanguageParser.Parse(lex, SyntaxMode.Interactive);

                    if (!broken && IsIncomplete(parse))
                    {
                        Console.ForegroundColor = ConsoleColor.Cyan;
                        Console.Write($".....({i})> ");
                        Console.ResetColor();

                        continued = true;

                        continue;
                    }

                    foreach (var diag in parse.Diagnostics)
                    {
                        LogDiagnostic(diag);
                    }

                    var analysis = LanguageAnalyzer.Analyze(parse, loader, new SyntaxContext());

                    foreach (var diag in analysis.Diagnostics)
                    {
                        LogDiagnostic(diag);
                    }

                    break;
                }

                if (quit)
                {
                    break;
                }

                i++;
            }

            return(0);
        }