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); } }
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); }