This commit is contained in:
nub31
2025-06-13 00:26:37 +02:00
parent 2a2c70b499
commit ec3bfaf5f2

View File

@@ -38,9 +38,9 @@ foreach (var file in Directory.GetFiles(BIN_DIR))
} }
var error = false; var error = false;
List<CompilationUnit> compilationUnits = []; var compilationUnits = new List<CompilationUnit>();
Dictionary<CompilationUnit, SourceText> sourceTexts = []; var sourceTexts = new Dictionary<CompilationUnit, SourceText>();
List<string> objectFiles = []; var objectFiles = new List<string>();
foreach (var file in Directory.EnumerateFiles(srcDir, "*.nub", SearchOption.AllDirectories)) foreach (var file in Directory.EnumerateFiles(srcDir, "*.nub", SearchOption.AllDirectories))
{ {
@@ -89,22 +89,19 @@ foreach (var compilationUnit in compilationUnits)
var sourceHash = Math.Abs(sourceTexts[compilationUnit].Path.GetHashCode()).ToString("x8"); var sourceHash = Math.Abs(sourceTexts[compilationUnit].Path.GetHashCode()).ToString("x8");
var baseOutputName = $"{sourceFileName}_{sourceHash}"; var baseOutputName = $"{sourceFileName}_{sourceHash}";
try var assemblyCode = await InvokeQBE(ssaCode);
{
var assemblyCode = await InvokeQBE(ssaCode);
var asmPath = Path.Combine(BIN_INT_DIR, $"{baseOutputName}.s");
await File.WriteAllTextAsync(asmPath, assemblyCode);
var objPath = Path.Combine(BIN_INT_DIR, $"{baseOutputName}.o"); var asmPath = Path.Combine(BIN_INT_DIR, $"{baseOutputName}.s");
await InvokeAssembler(asmPath, objPath); await File.WriteAllTextAsync(asmPath, assemblyCode);
objectFiles.Add(objPath);
} var objPath = Path.Combine(BIN_INT_DIR, $"{baseOutputName}.o");
catch (Exception ex) var asmSuccess = await InvokeAssembler(asmPath, objPath);
if (!asmSuccess)
{ {
Console.Error.WriteLine($"Error processing {sourceTexts[compilationUnit].Path}: {ex.Message}");
return 1; return 1;
} }
objectFiles.Add(objPath);
} }
var assembly = Assembly.GetExecutingAssembly(); var assembly = Assembly.GetExecutingAssembly();
@@ -114,48 +111,36 @@ var runtimeResources = assembly
foreach (var resourceName in runtimeResources) foreach (var resourceName in runtimeResources)
{ {
try await using var stream = assembly.GetManifestResourceStream(resourceName);
if (stream == null)
{ {
await using var stream = assembly.GetManifestResourceStream(resourceName); Console.Error.WriteLine($"Warning: Could not load embedded resource {resourceName}");
if (stream == null) continue;
{
Console.Error.WriteLine($"Warning: Could not load embedded resource {resourceName}");
continue;
}
using var reader = new StreamReader(stream);
var assemblyCode = await reader.ReadToEndAsync();
var fileName = resourceName.Split('.').Reverse().Skip(1).First();
var asmPath = Path.Combine(BIN_INT_DIR, $"runtime_{fileName}.s");
var objPath = Path.Combine(BIN_INT_DIR, $"runtime_{fileName}.o");
await File.WriteAllTextAsync(asmPath, assemblyCode);
await InvokeAssembler(asmPath, objPath);
objectFiles.Add(objPath);
File.Delete(asmPath);
} }
catch (Exception ex)
using var reader = new StreamReader(stream);
var assemblyCode = await reader.ReadToEndAsync();
var fileName = resourceName.Split('.').Reverse().Skip(1).First();
var asmPath = Path.Combine(BIN_INT_DIR, $"runtime_{fileName}.s");
var objPath = Path.Combine(BIN_INT_DIR, $"runtime_{fileName}.o");
await File.WriteAllTextAsync(asmPath, assemblyCode);
var asmSuccess = await InvokeAssembler(asmPath, objPath);
if (!asmSuccess)
{ {
Console.Error.WriteLine($"Error processing runtime resource {resourceName}: {ex.Message}");
return 1; return 1;
} }
objectFiles.Add(objPath);
File.Delete(asmPath);
} }
try var outputPath = Path.Combine(BIN_DIR, "out");
{ var linkSuccess = await InvokeLinker(objectFiles, outputPath);
var outputPath = Path.Combine(BIN_DIR, "out"); return linkSuccess ? 0 : 1;
await InvokeLinker(objectFiles, outputPath);
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error linking: {ex.Message}");
return 1;
}
return 0;
static async Task<string> InvokeQBE(string ssa) static async Task<string> InvokeQBE(string ssa)
{ {
@@ -188,7 +173,7 @@ static async Task<string> InvokeQBE(string ssa)
return assemblyCode; return assemblyCode;
} }
static async Task InvokeAssembler(string asmPath, string objPath) static async Task<bool> InvokeAssembler(string asmPath, string objPath)
{ {
using var gccProcess = new Process(); using var gccProcess = new Process();
gccProcess.StartInfo = new ProcessStartInfo("gcc", ["-c", asmPath, "-o", objPath]) gccProcess.StartInfo = new ProcessStartInfo("gcc", ["-c", asmPath, "-o", objPath])
@@ -200,19 +185,18 @@ static async Task InvokeAssembler(string asmPath, string objPath)
}; };
gccProcess.Start(); gccProcess.Start();
var gccOutput = await gccProcess.StandardOutput.ReadToEndAsync();
var gccErrors = await gccProcess.StandardError.ReadToEndAsync();
await gccProcess.WaitForExitAsync(); await gccProcess.WaitForExitAsync();
if (gccProcess.ExitCode != 0) var gccErrors = await gccProcess.StandardError.ReadToEndAsync();
if (!string.IsNullOrWhiteSpace(gccErrors))
{ {
throw new Exception($"Assembler errors:\n{gccErrors}"); Console.Error.WriteLine("gcc error:\n" + gccErrors);
} }
return gccProcess.ExitCode == 0;
} }
static async Task InvokeLinker(List<string> objectFiles, string outputPath) static async Task<bool> InvokeLinker(List<string> objectFiles, string outputPath)
{ {
using var gccProcess = new Process(); using var gccProcess = new Process();
gccProcess.StartInfo = new ProcessStartInfo("gcc", ["-nostartfiles", "-o", outputPath, ..objectFiles]) gccProcess.StartInfo = new ProcessStartInfo("gcc", ["-nostartfiles", "-o", outputPath, ..objectFiles])
@@ -224,14 +208,13 @@ static async Task InvokeLinker(List<string> objectFiles, string outputPath)
}; };
gccProcess.Start(); gccProcess.Start();
var gccOutput = await gccProcess.StandardOutput.ReadToEndAsync();
var gccErrors = await gccProcess.StandardError.ReadToEndAsync();
await gccProcess.WaitForExitAsync(); await gccProcess.WaitForExitAsync();
if (gccProcess.ExitCode != 0) var gccErrors = await gccProcess.StandardError.ReadToEndAsync();
if (!string.IsNullOrWhiteSpace(gccErrors))
{ {
throw new Exception($"Linker errors:\n{gccErrors}"); Console.Error.WriteLine("gcc error:\n" + gccErrors);
} }
return gccProcess.ExitCode == 0;
} }