This commit is contained in:
nub31
2025-06-12 23:04:47 +02:00
parent e919d81737
commit 8b4e193438
4 changed files with 69 additions and 14 deletions

View File

@@ -1,4 +1,5 @@
using Nub.Lang;
using System.Diagnostics;
using Nub.Lang;
using Nub.Lang.Frontend;
using Nub.Lang.Frontend.Generation;
using Nub.Lang.Frontend.Lexing;
@@ -22,13 +23,16 @@ if (!Directory.Exists(srcDir))
var error = false;
Dictionary<CompilationUnit, SourceText> sourceTexts = [];
List<CompilationUnit> compilationUnits = [];
foreach (var file in Directory.EnumerateFiles(srcDir, "*.nub", SearchOption.AllDirectories))
{
var content = File.ReadAllText(file);
var tokenizeResult = Lexer.Tokenize(new SourceText(file, content));
var sourceText = new SourceText(file, content);
var tokenizeResult = Lexer.Tokenize(sourceText);
tokenizeResult.PrintAllDiagnostics();
error = error || tokenizeResult.HasErrors;
@@ -39,6 +43,7 @@ foreach (var file in Directory.EnumerateFiles(srcDir, "*.nub", SearchOption.AllD
if (parseResult.Value != null)
{
compilationUnits.Add(parseResult.Value);
sourceTexts[parseResult.Value] = sourceText;
}
}
@@ -54,10 +59,61 @@ foreach (var compilationUnit in compilationUnits)
var typeCheckResult = TypeChecker.Check(compilationUnit, definitionTable);
typeCheckResult.PrintAllDiagnostics();
error = error || typeCheckResult.HasErrors;
}
var result = QBEGenerator.Generate(compilationUnit, definitionTable);
if (error)
{
return 1;
}
File.WriteAllText($"bin-int/{Guid.NewGuid():N}.ssa", result);
foreach (var compilationUnit in compilationUnits)
{
var ssaCode = QBEGenerator.Generate(compilationUnit, definitionTable);
var sourceFileName = Path.GetFileNameWithoutExtension(sourceTexts[compilationUnit].Path);
var sourceHash = Math.Abs(sourceTexts[compilationUnit].Path.GetHashCode()).ToString("x8");
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString("x");
var baseOutputName = $"{sourceFileName}_{sourceHash}_{timestamp}";
try
{
using var qbeProcess = new Process();
qbeProcess.StartInfo = new ProcessStartInfo
{
FileName = "qbe",
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
};
qbeProcess.Start();
await qbeProcess.StandardInput.WriteAsync(ssaCode);
qbeProcess.StandardInput.Close();
var assemblyCode = await qbeProcess.StandardOutput.ReadToEndAsync();
var qbeErrors = await qbeProcess.StandardError.ReadToEndAsync();
await qbeProcess.WaitForExitAsync();
if (qbeProcess.ExitCode != 0)
{
Console.Error.WriteLine($"QBE failed for {sourceTexts[compilationUnit].Path}:");
Console.Error.WriteLine(qbeErrors);
error = true;
continue;
}
var asmPath = Path.Combine("bin-int", $"{baseOutputName}.s");
await File.WriteAllTextAsync(asmPath, assemblyCode);
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error invoking QBE for {sourceTexts[compilationUnit].Path}: {ex.Message}");
error = true;
}
}
return error ? 1 : 0;

View File

@@ -72,7 +72,7 @@ public class Diagnostic
if (Span.HasValue)
{
var locationText = $" at {Span.Value.Text.Name}:{Span}";
var locationText = $" at {Span.Value.Text.Path}:{Span}";
sb.Append(ConsoleColors.Colorize(locationText, ConsoleColors.Faint));
}

View File

@@ -74,13 +74,13 @@ public struct SourceText : IEquatable<SourceText>
{
private int _lines = -1;
public SourceText(string name, string content)
public SourceText(string path, string content)
{
Name = name ?? throw new ArgumentNullException(nameof(name));
Path = path ?? throw new ArgumentNullException(nameof(path));
Content = content ?? throw new ArgumentNullException(nameof(content));
}
public string Name { get; }
public string Path { get; }
public string Content { get; }
public int LineCount()
@@ -109,7 +109,7 @@ public struct SourceText : IEquatable<SourceText>
public bool Equals(SourceText other)
{
return Name == other.Name && Content == other.Content;
return Path == other.Path && Content == other.Content;
}
public override bool Equals([NotNullWhen(true)] object? obj)
@@ -119,12 +119,12 @@ public struct SourceText : IEquatable<SourceText>
public override int GetHashCode()
{
return HashCode.Combine(Name, Content);
return HashCode.Combine(Path, Content);
}
public override string ToString()
{
return Name;
return Path;
}
public static bool operator ==(SourceText left, SourceText right) => left.Equals(right);