This commit is contained in:
nub31
2025-10-20 18:31:43 +02:00
parent 0bd52298fb
commit 34d36eb8b2
12 changed files with 313 additions and 724 deletions

View File

@@ -2,14 +2,13 @@
using NubLang.Ast;
using NubLang.Diagnostics;
using NubLang.Generation;
using NubLang.Modules;
using NubLang.Syntax;
var diagnostics = new List<Diagnostic>();
var syntaxTrees = new List<SyntaxTree>();
var nubFiles = args.Where(x => Path.GetExtension(x) == ".nub");
var objectFiles = args.Where(x => Path.GetExtension(x) is ".o" or ".a");
var nubFiles = args.Where(x => Path.GetExtension(x) == ".nub").ToArray();
var objectFileArgs = args.Where(x => Path.GetExtension(x) is ".o" or ".a").ToArray();
foreach (var file in nubFiles)
{
@@ -24,16 +23,15 @@ foreach (var file in nubFiles)
syntaxTrees.Add(syntaxTree);
}
var moduleRepository = new ModuleRepository(syntaxTrees);
var modules = Module.Collect(syntaxTrees);
var compilationUnits = new List<CompilationUnit>();
var definitions = new List<DefinitionNode>();
foreach (var syntaxTree in syntaxTrees)
for (var i = 0; i < nubFiles.Length; i++)
{
var typeChecker = new TypeChecker(syntaxTree, moduleRepository);
typeChecker.Check();
var typeChecker = new TypeChecker(syntaxTrees[i], modules);
var compilationUnit = typeChecker.Check();
definitions.AddRange(typeChecker.Definitions);
compilationUnits.Add(compilationUnit);
diagnostics.AddRange(typeChecker.Diagnostics);
}
@@ -47,36 +45,57 @@ if (diagnostics.Any(diagnostic => diagnostic.Severity == DiagnosticSeverity.Erro
return 1;
}
var cPaths = new List<string>();
Directory.CreateDirectory(".build");
var generator = new Generator(definitions);
var c = generator.Emit();
var cFilePath = Path.Combine(".build", "out.c");
File.WriteAllText(cFilePath, c);
using var compileProcess = Process.Start("gcc", [
"-ffreestanding", "-nostartfiles", "-std=c23",
"-g", "-lm",
"-c", "-o", Path.Combine(".build", "out.o"),
cFilePath,
]);
compileProcess.WaitForExit();
if (compileProcess.ExitCode != 0)
for (var i = 0; i < nubFiles.Length; i++)
{
Console.Error.WriteLine($"gcc failed with exit code {compileProcess.ExitCode}");
return 1;
var file = nubFiles[i];
var compilationUnit = compilationUnits[i];
var generator = new Generator(compilationUnit);
var directory = Path.GetDirectoryName(file);
if (!string.IsNullOrWhiteSpace(directory))
{
Directory.CreateDirectory(Path.Combine(".build", directory));
}
var path = Path.Combine(".build", Path.ChangeExtension(file, "c"));
File.WriteAllText(path, generator.Emit());
cPaths.Add(path);
}
if (moduleRepository.Modules().TryGetValue("main", out var mainModule))
var objectPaths = new List<string>();
foreach (var cPath in cPaths)
{
var objectPath = Path.ChangeExtension(cPath, "o");
using var compileProcess = Process.Start("gcc", [
"-ffreestanding", "-nostartfiles", "-std=c23",
"-g", "-lm",
"-c", "-o", objectPath,
cPath,
]);
compileProcess.WaitForExit();
if (compileProcess.ExitCode != 0)
{
Console.Error.WriteLine($"gcc failed with exit code {compileProcess.ExitCode}");
return 1;
}
objectPaths.Add(objectPath);
}
if (modules.TryGetValue("main", out var mainModule))
{
var mainFunction = mainModule
.Functions(true)
.FirstOrDefault(x => x.ExternSymbol == "main");
.FirstOrDefault(x => x.Prototype.ExternSymbol == "main");
if (mainFunction is { ExternSymbol: not null })
if (mainFunction is { Prototype.ExternSymbol: not null })
{
var runtime = $"""
.intel_syntax noprefix
@@ -85,7 +104,7 @@ if (moduleRepository.Modules().TryGetValue("main", out var mainModule))
.globl _start
_start:
mov rdi, rsp # Pass stack pointer to main (length + cstring pointers)
call {mainFunction.ExternSymbol}
call {mainFunction.Prototype.ExternSymbol}
mov rdi, rax # Move return value into rdi
mov rax, 60 # syscall: exit
syscall
@@ -111,9 +130,9 @@ if (moduleRepository.Modules().TryGetValue("main", out var mainModule))
"-ffreestanding", "-nostartfiles", "-std=c23",
"-g", "-lm",
"-o", Path.Combine(".build", "out"),
Path.Combine(".build", "out.o"),
..objectPaths,
Path.Combine(".build", "runtime.o"),
..objectFiles
..objectFileArgs
]));
if (linkProcess == null) return 1;