This repository has been archived on 2025-10-24. You can view files and clone it, but cannot push or open issues or pull requests.
Files
nub-lang-archive-2/compiler/NubLang.CLI/Program.cs
2025-10-16 13:44:19 +02:00

153 lines
3.7 KiB
C#

using System.Diagnostics;
using NubLang.Ast;
using NubLang.CLI;
using NubLang.Diagnostics;
using NubLang.Generation;
using NubLang.Modules;
using NubLang.Syntax;
var sw = Stopwatch.StartNew();
var options = new Options();
for (var i = 0; i < args.Length; i++)
{
var arg = args[i];
switch (arg)
{
case "-o":
{
++i;
if (i >= args.Length)
{
return 1;
}
options.OutputPath = args[i];
break;
}
default:
{
options.Files.Add(arg);
break;
}
}
}
Console.WriteLine($"Parse cli args: {sw.ElapsedMilliseconds}ms");
sw.Restart();
foreach (var file in options.Files)
{
if (!File.Exists(file))
{
Console.Error.WriteLine($"File '{file}' does not exist");
return 1;
}
}
Console.WriteLine($"Check file exists: {sw.ElapsedMilliseconds}ms");
sw.Restart();
var diagnostics = new List<Diagnostic>();
var syntaxTrees = new List<SyntaxTree>();
foreach (var file in options.Files)
{
var tokenizer = new Tokenizer(file, File.ReadAllText(file));
tokenizer.Tokenize();
diagnostics.AddRange(tokenizer.Diagnostics);
Console.WriteLine($" Tokenize: {Path.GetFileName(file)}: {sw.ElapsedMilliseconds}ms");
sw.Restart();
var parser = new Parser();
var syntaxTree = parser.Parse(tokenizer.Tokens);
diagnostics.AddRange(parser.Diagnostics);
Console.WriteLine($" Parse: {Path.GetFileName(file)}: {sw.ElapsedMilliseconds}ms");
sw.Restart();
syntaxTrees.Add(syntaxTree);
}
sw.Restart();
var moduleRepository = new ModuleRepository(syntaxTrees);
Console.WriteLine($"Create module repository: {sw.ElapsedMilliseconds}ms");
sw.Restart();
var definitions = new List<DefinitionNode>();
var referencedStructTypes = new HashSet<NubStructType>();
foreach (var syntaxTree in syntaxTrees)
{
var typeChecker = new TypeChecker(syntaxTree, moduleRepository);
typeChecker.Check();
Console.WriteLine($" Type check {syntaxTree.Metadata.ModuleName}: {sw.ElapsedMilliseconds}ms");
sw.Restart();
definitions.AddRange(typeChecker.Definitions);
diagnostics.AddRange(typeChecker.Diagnostics);
foreach (var structType in typeChecker.ReferencedStructTypes)
{
referencedStructTypes.Add(structType);
}
}
sw.Restart();
foreach (var diagnostic in diagnostics)
{
Console.Error.WriteLine(diagnostic.FormatANSI());
}
Console.WriteLine($"Print diagnostics: {sw.ElapsedMilliseconds}ms");
sw.Restart();
if (diagnostics.Any(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error))
{
return 1;
}
Directory.CreateDirectory(".build");
var generator = new CGenerator(definitions, referencedStructTypes);
var c = generator.Emit();
var cFilePath = Path.Combine(".build", "out.c");
File.WriteAllText(cFilePath, c);
var objFilePath = Path.Combine(".build", "out.o");
var asmSuccess = await GCC.Compile(cFilePath, objFilePath);
if (!asmSuccess) return 1;
// sw.Restart();
//
// var generator = new QBEGenerator(definitions, referencedStructTypes);
// var ssa = generator.Emit();
// var ssaFilePath = Path.Combine(".build", "out.ssa");
// File.WriteAllText(ssaFilePath, ssa);
//
// Console.WriteLine($"Emit ssa: {sw.ElapsedMilliseconds}ms");
// sw.Restart();
//
// var asmFilePath = Path.Combine(".build", "out.asm");
// var qbeSuccess = await QBE.Invoke(ssaFilePath, asmFilePath);
// if (!qbeSuccess) return 1;
//
// Console.WriteLine($"Emit asm: {sw.ElapsedMilliseconds}ms");
// sw.Restart();
//
// var objFilePath = Path.Combine(".build", "out.o");
// var asmSuccess = await GCC.Assemble(asmFilePath, objFilePath);
// if (!asmSuccess) return 1;
//
// Console.WriteLine($"Assemble: {sw.ElapsedMilliseconds}ms");
sw.Restart();
return 0;