From 32190b3bea23c9fe195b3df78fbb40bf21f28aaf Mon Sep 17 00:00:00 2001 From: nub31 Date: Wed, 10 Sep 2025 16:32:59 +0200 Subject: [PATCH] ... --- README.md | 9 + example/makefile | 12 +- example/src/main.nub | 10 +- src/compiler/NubLang.CLI/NubLang.CLI.csproj | 7 - src/compiler/NubLang.CLI/Program.cs | 40 +-- src/compiler/NubLang.CLI/assets/runtime.o | Bin 4928 -> 0 bytes src/compiler/NubLang.CLI/assets/x64.o | Bin 2344 -> 0 bytes .../NubLang/Generation/QBE/QBEGenerator.cs | 272 ++++++++++-------- 8 files changed, 168 insertions(+), 182 deletions(-) create mode 100644 README.md delete mode 100644 src/compiler/NubLang.CLI/assets/runtime.o delete mode 100644 src/compiler/NubLang.CLI/assets/x64.o diff --git a/README.md b/README.md new file mode 100644 index 0000000..f02afbd --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +main.nm + missing: + - std::print + functions: + - main + +std.nm + functions: + - print \ No newline at end of file diff --git a/example/makefile b/example/makefile index 57fcdcc..9fc5f56 100644 --- a/example/makefile +++ b/example/makefile @@ -1,18 +1,18 @@ CC = clang NUBC = ../src/compiler/NubLang.CLI/bin/Debug/net9.0/nubc -out: build/out.a - $(CC) -o out build/out.a +.build/out: .build/out.a + $(CC) -g -o .build/out .build/out.a -build/out.a: $(NUBC) src/main.nub +.build/out.a: $(NUBC) src/main.nub $(NUBC) src/main.nub $(NUBC): dotnet build ../src/compiler/NubLang.CLI/NubLang.CLI.csproj -run: out - ./out +run: .build/out + ./.build/out clean: - @rm -r build 2>/dev/null || true + @rm -r .build 2>/dev/null || true @rm out 2>/dev/null || true diff --git a/example/src/main.nub b/example/src/main.nub index e6f514b..1195e4f 100644 --- a/example/src/main.nub +++ b/example/src/main.nub @@ -23,12 +23,12 @@ func main(args: []cstring): i64 age = "23" } - test(x&) + puts(x.age) return 0 } -func test(human: ^Human) -{ - puts(human^.name.last) -} \ No newline at end of file +// func test(human: ^Human) +// { +// puts(human^.name.last) +// } \ No newline at end of file diff --git a/src/compiler/NubLang.CLI/NubLang.CLI.csproj b/src/compiler/NubLang.CLI/NubLang.CLI.csproj index 2f25112..0550d0f 100644 --- a/src/compiler/NubLang.CLI/NubLang.CLI.csproj +++ b/src/compiler/NubLang.CLI/NubLang.CLI.csproj @@ -13,11 +13,4 @@ - - - - - - - diff --git a/src/compiler/NubLang.CLI/Program.cs b/src/compiler/NubLang.CLI/Program.cs index 86fea89..13a1fdc 100644 --- a/src/compiler/NubLang.CLI/Program.cs +++ b/src/compiler/NubLang.CLI/Program.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using NubLang.CLI; +using NubLang.CLI; using NubLang.Code; using NubLang.Diagnostics; using NubLang.Generation; @@ -91,7 +90,7 @@ var objectFiles = new List(); for (var i = 0; i < typedSyntaxTrees.Count; i++) { var syntaxTree = typedSyntaxTrees[i]; - var outFileName = Path.Combine("build", "code", Path.ChangeExtension(options.Files[i].Path, null)); + var outFileName = Path.Combine(".build", "code", Path.ChangeExtension(options.Files[i].Path, null)); var outFileDir = Path.GetDirectoryName(outFileName); if (!string.IsNullOrEmpty(outFileDir)) @@ -124,39 +123,7 @@ for (var i = 0; i < typedSyntaxTrees.Count; i++) objectFiles.Add(objFilePath); } -var resources = Assembly.GetExecutingAssembly().GetManifestResourceNames(); - -string[] runtimeObjects = ["runtime.o", "x64.o"]; - -foreach (var runtimeObject in runtimeObjects) -{ - var runtime = resources.First(r => r.EndsWith(runtimeObject)); - - await using var reader = Assembly - .GetExecutingAssembly() - .GetManifestResourceStream(runtime); - - if (reader == null) - { - Console.Error.WriteLine($"Cannot open read stream to '{runtimeObject}'"); - return 1; - } - - var runtimePath = Path.Combine("build", "runtime", runtimeObject); - var runtimeDir = Path.GetDirectoryName(runtimePath); - if (!string.IsNullOrEmpty(runtimeDir)) - { - Directory.CreateDirectory(runtimeDir); - } - - await using var writer = new FileStream(runtimePath, FileMode.Create); - - reader.CopyTo(writer); - - objectFiles.Add(runtimePath); -} - -var outPath = options.OutputPath ?? Path.Combine("build", "out.a"); +var outPath = options.OutputPath ?? Path.Combine(".build", "out.a"); var outDir = Path.GetDirectoryName(outPath); if (!string.IsNullOrEmpty(outDir)) { @@ -169,5 +136,4 @@ if (!archiveResult) return 1; } - return 0; \ No newline at end of file diff --git a/src/compiler/NubLang.CLI/assets/runtime.o b/src/compiler/NubLang.CLI/assets/runtime.o deleted file mode 100644 index 26e46783222c42d32759941cddfbcdfee24891d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4928 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 P;^Uzp>75W+oAJK@gWaBb diff --git a/src/compiler/NubLang/Generation/QBE/QBEGenerator.cs b/src/compiler/NubLang/Generation/QBE/QBEGenerator.cs index f640f4e..3f1f580 100644 --- a/src/compiler/NubLang/Generation/QBE/QBEGenerator.cs +++ b/src/compiler/NubLang/Generation/QBE/QBEGenerator.cs @@ -166,9 +166,63 @@ public class QBEGenerator return into; } + private void EmitMemset(string destination, int value, string length) + { + var count = TmpName(); + _writer.Indented($"{count} =l copy 0"); + + var loopLabel = LabelName(); + _writer.WriteLine(loopLabel); + + var continueLabel = LabelName(); + var doneLabel = LabelName(); + var condition = TmpName(); + _writer.Indented($"{condition} =w cultl {count}, {length}"); + _writer.Indented($"jnz {condition}, {continueLabel}, {doneLabel}"); + + _writer.WriteLine(continueLabel); + + var destinationAddress = TmpName(); + _writer.Indented($"{destinationAddress} =l add {destination}, {count}"); + + _writer.Indented($"storeb {value}, {destinationAddress}"); + + _writer.Indented($"{count} =l add {count}, 1"); + _writer.Indented($"jmp {loopLabel}"); + + _writer.WriteLine(doneLabel); + } + private void EmitMemcpy(string source, string destination, string length) { - _writer.Indented($"call $nub_memcpy(l {source}, l {destination}, l {length})"); + var count = TmpName(); + _writer.Indented($"{count} =l copy 0"); + + var loopLabel = LabelName(); + _writer.WriteLine(loopLabel); + + var continueLabel = LabelName(); + var doneLabel = LabelName(); + var condition = TmpName(); + _writer.Indented($"{condition} =w cultl {count}, {length}"); + _writer.Indented($"jnz {condition}, {continueLabel}, {doneLabel}"); + + _writer.WriteLine(continueLabel); + + var sourceAddress = TmpName(); + _writer.Indented($"{sourceAddress} =l add {source}, {count}"); + + var destinationAddress = TmpName(); + _writer.Indented($"{destinationAddress} =l add {destination}, {count}"); + + var value = TmpName(); + _writer.Indented($"{value} =w loadub {sourceAddress}"); + _writer.Indented($"storeb {value}, {destinationAddress}"); + + _writer.Indented($"{count} =l add {count}, 1"); + _writer.Indented($"jmp {loopLabel}"); + + _writer.WriteLine(doneLabel); } private string EmitArraySizeInBytes(ArrayTypeNode type, string array) @@ -182,10 +236,27 @@ public class QBEGenerator private string EmitCStringSizeInBytes(string cstring) { - var size = TmpName(); - _writer.Indented($"{size} =l call $nub_cstring_length(l {cstring})"); - _writer.Indented($"{size} =l add {size}, 1"); - return size; + var count = TmpName(); + _writer.Indented($"{count} =l copy 0"); + + var loopLabel = LabelName(); + _writer.WriteLine(loopLabel); + + var address = TmpName(); + _writer.Indented($"{address} =l add {cstring}, {count}"); + + var value = TmpName(); + _writer.Indented($"{value} =w loadub {address}"); + + var notZeroLabel = LabelName(); + var zeroLabel = LabelName(); + _writer.Indented($"jnz {value}, {notZeroLabel}, {zeroLabel}"); + _writer.WriteLine(notZeroLabel); + _writer.Indented($"{count} =l add {count}, 1"); + _writer.Indented($"jmp {loopLabel}"); + _writer.WriteLine(zeroLabel); + + return count; } private string EmitStringSizeInBytes(string nubstring) @@ -196,74 +267,42 @@ public class QBEGenerator return size; } - private bool EmitTryMoveInto(ExpressionNode source, string destinationLValue) + private void EmitCopyInto(ExpressionNode source, string destination) { - switch (source) - { - case ArrayInitializerNode arrayInitializer: - { - EmitStore(source.Type, EmitArrayInitializer(arrayInitializer), destinationLValue); - return true; - } - case StructInitializerNode structInitializer: - { - EmitStructInitializer(structInitializer, destinationLValue); - return true; - } - case ConvertToInterfaceNode convertToInterface: - { - EmitConvertToInterface(convertToInterface, destinationLValue); - return true; - } - case LiteralNode { Kind: LiteralKind.String } literal: - { - EmitStore(source.Type, EmitLiteral(literal), destinationLValue); - return true; - } - } - - return false; - } - - private void EmitCopyIntoOrInitialize(ExpressionNode source, string destinationLValue) - { - // If the source is a value which is not used yet such as an array/struct initializer or literal, we can skip copying - if (EmitTryMoveInto(source, destinationLValue)) + // Simple types are passed in registers and can therefore just be stored + if (source.Type.IsSimpleType(out var simpleType, out var complexType)) { + var value = EmitExpression(source); + EmitStore(simpleType, value, destination); return; } - var value = EmitExpression(source); - - if (source.Type.IsSimpleType(out var simpleType, out var complexType)) + // Structs and interfaces has known sizes at compile time + if (complexType is StructTypeNode or InterfaceTypeNode) { - EmitStore(simpleType, value, destinationLValue); + var value = EmitExpression(source); + _writer.Indented($"blit {value}, {destination}, {SizeOf(complexType)}"); } + // The rest of the complex types has unknown sizes else { - if (complexType is StructTypeNode or InterfaceTypeNode) + var value = EmitExpression(source); + var size = complexType switch { - EmitMemcpy(value, destinationLValue, SizeOf(complexType).ToString()); - } - else - { - var size = complexType switch - { - ArrayTypeNode arrayType => EmitArraySizeInBytes(arrayType, value), - CStringTypeNode => EmitCStringSizeInBytes(value), - StringTypeNode => EmitStringSizeInBytes(value), - _ => throw new ArgumentOutOfRangeException(nameof(source.Type)) - }; + ArrayTypeNode arrayType => EmitArraySizeInBytes(arrayType, value), + CStringTypeNode => EmitCStringSizeInBytes(value), + StringTypeNode => EmitStringSizeInBytes(value), + _ => throw new ArgumentOutOfRangeException(nameof(source.Type)) + }; - var buffer = TmpName(); - _writer.Indented($"{buffer} =l alloc8 {size}"); - EmitMemcpy(value, buffer, size); - EmitStore(complexType, buffer, destinationLValue); - } + var buffer = TmpName(); + _writer.Indented($"{buffer} =l alloc8 {size}"); + EmitMemcpy(value, buffer, size); + EmitStore(complexType, buffer, destination); } } - private string EmitCreateCopy(ExpressionNode source) + private string EmitCopy(ExpressionNode source) { // Allowlist for types which are safe to not copy if (source is ArrayInitializerNode or StructInitializerNode or ConvertToInterfaceNode or LiteralNode) @@ -279,19 +318,30 @@ public class QBEGenerator // For the rest, we figure out the size of the type and shallow copy them var value = EmitExpression(source); - var size = complexType switch - { - ArrayTypeNode arrayType => EmitArraySizeInBytes(arrayType, value), - CStringTypeNode => EmitCStringSizeInBytes(value), - StringTypeNode => EmitStringSizeInBytes(value), - InterfaceTypeNode interfaceType => SizeOf(interfaceType).ToString(), - StructTypeNode structType => SizeOf(structType).ToString(), - _ => throw new ArgumentOutOfRangeException(nameof(source.Type)) - }; - var destination = TmpName(); - _writer.Indented($"{destination} =l alloc8 {size}"); - EmitMemcpy(value, destination, size); + + // Structs and interfaces has known sizes at compile time + if (complexType is StructTypeNode or InterfaceTypeNode) + { + var size = SizeOf(complexType); + _writer.Indented($"{destination} =l alloc8 {size}"); + _writer.Indented($"blit {value}, {destination}, {size}"); + } + // The rest of the complex types has unknown sizes + else + { + var size = complexType switch + { + ArrayTypeNode arrayType => EmitArraySizeInBytes(arrayType, value), + CStringTypeNode => EmitCStringSizeInBytes(value), + StringTypeNode => EmitStringSizeInBytes(value), + _ => throw new ArgumentOutOfRangeException(nameof(source.Type)) + }; + + _writer.Indented($"{destination} =l alloc8 {size}"); + EmitMemcpy(value, destination, size); + } + return destination; } @@ -460,11 +510,11 @@ public class QBEGenerator private void EmitStatement(StatementNode statement) { - var tokens = statement.Tokens.ToArray(); - if (tokens.Length != 0) - { - _writer.WriteLine($"dbgloc {tokens[0].FileSpan.Span.Start.Line}"); - } + // var tokens = statement.Tokens.ToArray(); + // if (tokens.Length != 0) + // { + // _writer.WriteLine($"dbgloc {tokens[0].FileSpan.Span.Start.Line}"); + // } switch (statement) { @@ -499,7 +549,7 @@ public class QBEGenerator private void EmitAssignment(AssignmentNode assignment) { - EmitCopyIntoOrInitialize(assignment.Value, EmitAddressOfLValue(assignment.Target)); + EmitCopyInto(assignment.Value, EmitAddressOfLValue(assignment.Target)); } private void EmitBreak() @@ -554,7 +604,7 @@ public class QBEGenerator if (variableDeclaration.Assignment.HasValue) { - EmitCopyIntoOrInitialize(variableDeclaration.Assignment.Value, name); + EmitCopyInto(variableDeclaration.Assignment.Value, name); } } @@ -581,11 +631,11 @@ public class QBEGenerator private string EmitExpression(ExpressionNode expression) { - var tokens = expression.Tokens.ToArray(); - if (tokens.Length != 0) - { - _writer.WriteLine($"dbgloc {tokens[0].FileSpan.Span.Start.Line}"); - } + // var tokens = expression.Tokens.ToArray(); + // if (tokens.Length != 0) + // { + // _writer.WriteLine($"dbgloc {tokens[0].FileSpan.Span.Start.Line}"); + // } return expression switch { @@ -623,30 +673,6 @@ public class QBEGenerator return EmitLoad(arrayIndexAccess.Type, address); } - private void EmitArrayBoundsCheck(string array, string index) - { - var count = TmpName(); - _writer.Indented($"{count} =l loadl {array}"); - - var isNegative = TmpName(); - _writer.Indented($"{isNegative} =w csltl {index}, 0"); - - var isOob = TmpName(); - _writer.Indented($"{isOob} =w csgel {index}, {count}"); - - var anyOob = TmpName(); - _writer.Indented($"{anyOob} =w or {isNegative}, {isOob}"); - - var oobLabel = LabelName(); - var notOobLabel = LabelName(); - _writer.Indented($"jnz {anyOob}, {oobLabel}, {notOobLabel}"); - - _writer.Indented(oobLabel); - _writer.Indented($"call $nub_panic_array_oob()"); - - _writer.Indented(notOobLabel); - } - private string EmitArrayInitializer(ArrayInitializerNode arrayInitializer) { var capacity = EmitExpression(arrayInitializer.Capacity); @@ -663,7 +689,7 @@ public class QBEGenerator var dataPointer = TmpName(); _writer.Indented($"{dataPointer} =l add {arrayPointer}, 8"); - _writer.Indented($"call $nub_memset(l {dataPointer}, w 0, l {capacityInBytes})"); + EmitMemset(dataPointer, 0, capacityInBytes); return arrayPointer; } @@ -700,8 +726,6 @@ public class QBEGenerator var array = EmitExpression(arrayIndexAccess.Target); var index = EmitExpression(arrayIndexAccess.Index); - EmitArrayBoundsCheck(array, index); - var elementType = ((ArrayTypeNode)arrayIndexAccess.Target.Type).ElementType; var offset = TmpName(); @@ -1006,16 +1030,13 @@ public class QBEGenerator throw new NotSupportedException($"Cannot create literal of kind '{literal.Kind}' for type {literal.Type}"); } - private string EmitStructInitializer(StructInitializerNode structInitializer, string? destination = null) + private string EmitStructInitializer(StructInitializerNode structInitializer) { var structDef = _definitionTable.LookupStruct(structInitializer.StructType.Name); - if (destination == null) - { - destination = TmpName(); - var size = SizeOf(structInitializer.StructType); - _writer.Indented($"{destination} =l alloc8 {size}"); - } + var destination = TmpName(); + var size = SizeOf(structInitializer.StructType); + _writer.Indented($"{destination} =l alloc8 {size}"); foreach (var field in structDef.Fields) { @@ -1031,7 +1052,7 @@ public class QBEGenerator var offset = TmpName(); _writer.Indented($"{offset} =l add {destination}, {OffsetOf(structDef, field.Name)}"); - EmitCopyIntoOrInitialize(valueExpression, offset); + EmitCopyInto(valueExpression, offset); } return destination; @@ -1106,7 +1127,7 @@ public class QBEGenerator foreach (var parameter in structFuncCall.Parameters) { - var copy = EmitCreateCopy(parameter); + var copy = EmitCopy(parameter); parameterStrings.Add($"{FuncQBETypeName(parameter.Type)} {copy}"); } @@ -1148,7 +1169,7 @@ public class QBEGenerator foreach (var parameter in interfaceFuncCall.Parameters) { - var copy = EmitCreateCopy(parameter); + var copy = EmitCopy(parameter); parameterStrings.Add($"{FuncQBETypeName(parameter.Type)} {copy}"); } @@ -1165,7 +1186,7 @@ public class QBEGenerator } } - private string EmitConvertToInterface(ConvertToInterfaceNode convertToInterface, string? destination = null) + private string EmitConvertToInterface(ConvertToInterfaceNode convertToInterface) { var implementation = EmitExpression(convertToInterface.Implementation); @@ -1180,11 +1201,8 @@ public class QBEGenerator vtableOffset += interfaceImplementation.Functions.Count * 8; } - if (destination == null) - { - destination = TmpName(); - _writer.Indented($"{destination} =l alloc8 {SizeOf(convertToInterface.InterfaceType)}"); - } + var destination = TmpName(); + _writer.Indented($"{destination} =l alloc8 {SizeOf(convertToInterface.InterfaceType)}"); var interfaceVtablePointer = TmpName(); _writer.Indented($"{interfaceVtablePointer} =l add {StructVtableName(convertToInterface.StructType.Name)}, {vtableOffset}"); @@ -1258,7 +1276,7 @@ public class QBEGenerator foreach (var parameter in funcCall.Parameters) { - var copy = EmitCreateCopy(parameter); + var copy = EmitCopy(parameter); parameterStrings.Add($"{FuncQBETypeName(parameter.Type)} {copy}"); }