...
This commit is contained in:
@@ -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;
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user