...
This commit is contained in:
@@ -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
|
dotnet run --project ../src/compiler/CLI/CLI.csproj src/main.nub src/c.nub
|
||||||
mkdir -p bin
|
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:
|
clean:
|
||||||
rm -r bin-int bin
|
rm -r bin-int bin
|
||||||
|
|||||||
@@ -3,4 +3,5 @@ namespace main
|
|||||||
export func main(args: []cstring): i64 {
|
export func main(args: []cstring): i64 {
|
||||||
c::puts("test")
|
c::puts("test")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,4 +18,9 @@
|
|||||||
<None Remove="runtime\libruntime_x64.a" />
|
<None Remove="runtime\libruntime_x64.a" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="assets\libruntime_x64.a" />
|
||||||
|
<EmbeddedResource Include="assets\libruntime_x64.a" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
38
src/compiler/CLI/HexString.cs
Normal file
38
src/compiler/CLI/HexString.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/compiler/CLI/Options.cs
Normal file
6
src/compiler/CLI/Options.cs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
namespace CLI;
|
||||||
|
|
||||||
|
public class Options
|
||||||
|
{
|
||||||
|
public string? CustomRuntime { get; set; }
|
||||||
|
}
|
||||||
@@ -1,20 +1,49 @@
|
|||||||
using CLI;
|
using System.Reflection;
|
||||||
|
using CLI;
|
||||||
using Generation.QBE;
|
using Generation.QBE;
|
||||||
using Syntax;
|
using Syntax;
|
||||||
using Syntax.Diagnostics;
|
using Syntax.Diagnostics;
|
||||||
using Syntax.Parsing;
|
using Syntax.Parsing;
|
||||||
using Syntax.Tokenization;
|
using Syntax.Tokenization;
|
||||||
using Syntax.Typing;
|
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);
|
Directory.CreateDirectory(OUT_DIR);
|
||||||
|
|
||||||
|
var options = new Options();
|
||||||
|
|
||||||
var files = new List<string>();
|
var files = new List<string>();
|
||||||
|
|
||||||
foreach (var arg in args)
|
for (var i = 0; i < args.Length; i++)
|
||||||
{
|
{
|
||||||
|
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);
|
files.Add(arg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var diagnostics = new List<Diagnostic>();
|
var diagnostics = new List<Diagnostic>();
|
||||||
@@ -80,7 +109,7 @@ foreach (var file in files)
|
|||||||
return 1;
|
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);
|
var asmSuccess = await GCC.Assemble(asm, fileName);
|
||||||
if (!asmSuccess)
|
if (!asmSuccess)
|
||||||
{
|
{
|
||||||
@@ -90,6 +119,29 @@ foreach (var file in files)
|
|||||||
objectFiles.Add(fileName);
|
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);
|
var archiveResult = await Archive.Invoke(Path.Join(OUT_DIR, "out.a"), objectFiles);
|
||||||
if (!archiveResult)
|
if (!archiveResult)
|
||||||
{
|
{
|
||||||
@@ -97,3 +149,27 @@ if (!archiveResult)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
Reference in New Issue
Block a user