using CLI; using Generation.QBE; using Syntax; using Syntax.Diagnostics; using Syntax.Parsing; using Syntax.Tokenization; using Syntax.Typing; using Binder = Syntax.Typing.Binder; const string OUT_DIR = "bin-int"; if (Directory.Exists(OUT_DIR)) { Directory.Delete(OUT_DIR, true); } var files = new List(); foreach (var arg in args) { files.Add(arg); } var diagnostics = new List(); var syntaxTrees = new Dictionary(); foreach (var file in files) { if (!File.Exists(file)) { Console.Error.WriteLine($"File '{file}' does not exist"); return 1; } } foreach (var file in files) { var content = File.ReadAllText(file); var sourceText = new SourceText(file, content); var tokenizeResult = Tokenizer.Tokenize(sourceText, out var tokenizerDiagnostics); diagnostics.AddRange(tokenizerDiagnostics); var syntaxTree = Parser.ParseFile(tokenizeResult, out var parseDiagnostics); diagnostics.AddRange(parseDiagnostics); if (syntaxTree != null) { syntaxTrees[file] = syntaxTree; } } var definitionTable = new DefinitionTable(syntaxTrees.Values); var boundSyntaxTrees = new Dictionary(); foreach (var (file, syntaxTree) in syntaxTrees) { var boundSyntaxTree = Binder.Bind(syntaxTree, definitionTable, out var binderDiagnostics); diagnostics.AddRange(binderDiagnostics); boundSyntaxTrees[file] = boundSyntaxTree; } var boundDefinitionTable = new BoundDefinitionTable(boundSyntaxTrees.Values); foreach (var diagnostic in diagnostics) { Console.Error.WriteLine(diagnostic.FormatANSI()); } if (diagnostics.Any(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)) { return 1; } var objectFiles = new List(); foreach (var file in files) { var ssa = QBEGenerator.Emit(boundSyntaxTrees[file], boundDefinitionTable); var asm = await QBE.Invoke(ssa); if (asm == null) { return 1; } var fileName = $"{StringRandomizer.GenerateUniqueHexString(8)}_{Path.GetFileNameWithoutExtension(file)}.o"; var objPath = Path.Combine(OUT_DIR, fileName); var asmSuccess = await GCC.Assemble(asm, objPath); if (!asmSuccess) { return 1; } objectFiles.Add(objPath); } Console.Out.WriteLine(string.Join('\t', objectFiles)); return 0; internal static class StringRandomizer { private static readonly char[] StringChars = "0123456789abcdef".ToArray(); public static string GenerateUniqueHexString(int length) { var rand = new Random(); var hexString = ""; for (var i = 0; i < length; i++) { var randIndex = rand.Next(0, StringChars.Length); hexString += StringChars[randIndex]; } return hexString; } }