This commit is contained in:
nub31
2025-06-29 17:06:57 +02:00
parent 30b5c1702a
commit 29a851d719
7 changed files with 138 additions and 9 deletions

View File

@@ -1,9 +1,12 @@
CFLAGS = -Wall -Werror -Wextra -g
CFLAGS = -g
example:
bin/out: src/main.nub src/c.nub
dotnet run --project ../src/compiler/CLI/CLI.csproj src/main.nub src/c.nub
mkdir -p bin
gcc $(CFLAGS) -o bin/out lib/libruntime_x64.a bin-int/out.a
gcc $(CFLAGS) -o bin/out bin-int/out/out.a
run: bin/out
bin/out
clean:
rm -r bin-int bin

View File

@@ -3,4 +3,5 @@ namespace main
export func main(args: []cstring): i64 {
c::puts("test")
return 0
}

View File

@@ -18,4 +18,9 @@
<None Remove="runtime\libruntime_x64.a" />
</ItemGroup>
<ItemGroup>
<None Remove="assets\libruntime_x64.a" />
<EmbeddedResource Include="assets\libruntime_x64.a" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,38 @@
namespace CLI;
internal static class HexString
{
private static readonly HashSet<string> _used = [];
private static readonly char[] StringChars = "0123456789abcdef".ToArray();
public static string CreateUnique(int length)
{
string hex;
while (true)
{
hex = Create(length);
if (_used.Add(hex))
{
break;
}
}
return hex;
}
public static string Create(int length)
{
var rand = new Random();
var hexString = "";
for (var i = 0; i < length; i++)
{
var randIndex = rand.Next(0, StringChars.Length);
hexString += StringChars[randIndex];
}
return hexString;
}
}

View File

@@ -0,0 +1,6 @@
namespace CLI;
public class Options
{
public string? CustomRuntime { get; set; }
}

View File

@@ -1,20 +1,49 @@
using CLI;
using System.Reflection;
using CLI;
using Generation.QBE;
using Syntax;
using Syntax.Diagnostics;
using Syntax.Parsing;
using Syntax.Tokenization;
using Syntax.Typing;
using Binder = Syntax.Typing.Binder;
const string OUT_DIR = "bin-int";
const string INT_DIR = "bin-int";
var BUILTIN_DIR = Path.Join(INT_DIR, "builtin");
var OBJECT_DIR = Path.Join(INT_DIR, "obj");
var OUT_DIR = Path.Join(INT_DIR, "out");
if (Directory.Exists(INT_DIR))
{
Directory.Delete(INT_DIR, true);
}
Directory.CreateDirectory(BUILTIN_DIR);
Directory.CreateDirectory(OBJECT_DIR);
Directory.CreateDirectory(OUT_DIR);
var options = new Options();
var files = new List<string>();
foreach (var arg in args)
for (var i = 0; i < args.Length; i++)
{
files.Add(arg);
var arg = args[i];
if (arg.StartsWith("-r") || arg.StartsWith("--runtime"))
{
i++;
if (i >= args.Length - 1)
{
Console.Error.WriteLine($"{arg} must be followed by a value");
return 1;
}
options.CustomRuntime = args[i];
}
else
{
files.Add(arg);
}
}
var diagnostics = new List<Diagnostic>();
@@ -80,7 +109,7 @@ foreach (var file in files)
return 1;
}
var fileName = Path.GetTempFileName();
var fileName = Path.Join(OBJECT_DIR, $"{HexString.CreateUnique(8)}_{Path.GetFileNameWithoutExtension(file)}.o");
var asmSuccess = await GCC.Assemble(asm, fileName);
if (!asmSuccess)
{
@@ -90,10 +119,57 @@ foreach (var file in files)
objectFiles.Add(fileName);
}
if (options.CustomRuntime == null)
{
try
{
objectFiles.Add(await CreateBuiltinRuntime());
}
catch (RuntimeCreationException e)
{
Console.Error.WriteLine(e.Message);
return 1;
}
}
else
{
if (!File.Exists(options.CustomRuntime))
{
Console.Error.WriteLine($"file '{options.CustomRuntime}' does not exist'");
return 1;
}
objectFiles.Add(options.CustomRuntime);
}
var archiveResult = await Archive.Invoke(Path.Join(OUT_DIR, "out.a"), objectFiles);
if (!archiveResult)
{
return 1;
}
return 0;
return 0;
async Task<string> CreateBuiltinRuntime()
{
const string RUNTIME_NAME = "libruntime_x64.a";
var resources = Assembly.GetExecutingAssembly().GetManifestResourceNames();
var runtime = resources.First(r => r.EndsWith(RUNTIME_NAME));
await using var reader = Assembly.GetExecutingAssembly().GetManifestResourceStream(runtime);
if (reader == null)
{
throw new RuntimeCreationException($"Cannot open stream to '{RUNTIME_NAME}'");
}
var runtimePath = Path.Combine(BUILTIN_DIR, RUNTIME_NAME);
await using var writer = new FileStream(runtimePath, FileMode.Create);
reader.CopyTo(writer);
return runtimePath;
}
class RuntimeCreationException(string message) : Exception(message);