ref counted strings

This commit is contained in:
nub31
2026-02-28 01:07:02 +01:00
parent 84627dde45
commit d58e006be4
3 changed files with 34 additions and 12 deletions

View File

@@ -5,21 +5,21 @@ namespace Compiler;
public class Generator public class Generator
{ {
public static string Emit(List<TypedNodeDefinitionFunc> functions, ModuleGraph moduleGraph, bool compileLib) public static string Emit(List<TypedNodeDefinitionFunc> functions, ModuleGraph moduleGraph, string? entryPoint)
{ {
return new Generator(functions, moduleGraph, compileLib).Emit(); return new Generator(functions, moduleGraph, entryPoint).Emit();
} }
private Generator(List<TypedNodeDefinitionFunc> functions, ModuleGraph moduleGraph, bool compileLib) private Generator(List<TypedNodeDefinitionFunc> functions, ModuleGraph moduleGraph, string? entryPoint)
{ {
this.functions = functions; this.functions = functions;
this.moduleGraph = moduleGraph; this.moduleGraph = moduleGraph;
this.compileLib = compileLib; this.entryPoint = entryPoint;
} }
private readonly List<TypedNodeDefinitionFunc> functions; private readonly List<TypedNodeDefinitionFunc> functions;
private readonly ModuleGraph moduleGraph; private readonly ModuleGraph moduleGraph;
private readonly bool compileLib; private readonly string? entryPoint;
private IndentedTextWriter writer = new(); private IndentedTextWriter writer = new();
private HashSet<NubType> referencedTypes = new(); private HashSet<NubType> referencedTypes = new();
private readonly HashSet<NubType> emittedTypes = new(); private readonly HashSet<NubType> emittedTypes = new();
@@ -28,15 +28,12 @@ public class Generator
private string Emit() private string Emit()
{ {
if (!compileLib) if (entryPoint != null)
{ {
if (!moduleGraph.TryResolveIdentifier("main", "main", true, out var info))
throw new UnreachableException("func main::main() is not defined. This should have been caught earlier");
writer.WriteLine($$""" writer.WriteLine($$"""
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
return {{info.MangledName}}(); return {{entryPoint}}();
} }
"""); """);
@@ -604,7 +601,6 @@ public class Generator
writer.WriteLine("{"); writer.WriteLine("{");
using (writer.Indent()) using (writer.Indent())
{ {
writer.WriteLine("puts(\"free\");");
writer.WriteLine($"free({value});"); writer.WriteLine($"free({value});");
} }
writer.WriteLine("}"); writer.WriteLine("}");

View File

@@ -128,7 +128,32 @@ else
Directory.CreateDirectory(".build"); Directory.CreateDirectory(".build");
} }
var output = Generator.Emit(functions, moduleGraph, compileLib); string? entryPoint = null;
if (!compileLib)
{
if (!moduleGraph.TryResolveIdentifier("main", "main", true, out var info) || info.Type is not NubTypeFunc entryPointType)
{
DiagnosticFormatter.Print(Diagnostic.Error("func main::main(): i32 is not defined. If you wanted to compile as a library, specify --type=lib").Build(), Console.Error);
return 1;
}
if (!entryPointType.ReturnType.IsAssignableTo(NubTypeSInt.Get(32)))
{
DiagnosticFormatter.Print(Diagnostic.Error($"Entrypoint must return an i32 (currently '{entryPointType.ReturnType}')").Build(), Console.Error);
return 1;
}
if (entryPointType.Parameters.Any())
{
DiagnosticFormatter.Print(Diagnostic.Error($"Entrypoint must not take any parameters").Build(), Console.Error);
return 1;
}
entryPoint = info.MangledName;
}
var output = Generator.Emit(functions, moduleGraph, entryPoint);
File.WriteAllText(".build/out.c", output); File.WriteAllText(".build/out.c", output);
if (compileLib) if (compileLib)

View File

@@ -1,5 +1,6 @@
module main module main
func main(): i32 { func main(): i32 {
core::print("Your mom")
return 0 return 0
} }