diff --git a/compiler/NubLang.CLI/Program.cs b/compiler/NubLang.CLI/Program.cs index 18c4bd7..a7b7ebe 100644 --- a/compiler/NubLang.CLI/Program.cs +++ b/compiler/NubLang.CLI/Program.cs @@ -71,10 +71,10 @@ var objectPaths = new List(); foreach (var cPath in cPaths) { var objectPath = Path.ChangeExtension(cPath, "o"); - using var compileProcess = Process.Start("gcc", [ - "-ffreestanding", "-nostartfiles", "-std=c23", - "-g", "-lm", - "-c", "-o", objectPath, + using var compileProcess = Process.Start("clang", [ + "-ffreestanding", "-std=c23", + "-g", "-c", + "-o", objectPath, cPath, ]); @@ -82,79 +82,13 @@ foreach (var cPath in cPaths) if (compileProcess.ExitCode != 0) { - Console.Error.WriteLine($"gcc failed with exit code {compileProcess.ExitCode}"); + Console.Error.WriteLine($"clang failed with exit code {compileProcess.ExitCode}"); return 1; } objectPaths.Add(objectPath); } -if (modules.TryGetValue("main", out var mainModule)) -{ - var mainFunction = mainModule - .Functions(true) - .FirstOrDefault(x => x.Prototype.ExternSymbol == "main"); - - if (mainFunction is { Prototype.ExternSymbol: not null }) - { - var runtime = $""" - .intel_syntax noprefix - - .text - .globl _start - _start: - mov rdi, [rsp] # argc - mov rsi, [rsp + 8] # argv - call {mainFunction.Prototype.ExternSymbol} - mov rdi, rax # Move return value into rdi - mov rax, 60 # syscall: exit - syscall - - """; - - var runtimePath = Path.Combine(".build", "runtime.s"); - File.WriteAllText(runtimePath, runtime); - - using var assembleProcess = Process.Start(new ProcessStartInfo("as", ["-g", "-c", runtimePath, "-o", Path.Combine(".build", "runtime.o")])); - if (assembleProcess == null) return 1; - assembleProcess.WaitForExit(); - - if (assembleProcess.ExitCode != 0) - { - Console.Error.WriteLine($"gcc failed with exit code {assembleProcess.ExitCode}"); - return 1; - } - - if (assembleProcess.ExitCode != 0) return 1; - - using var linkProcess = Process.Start(new ProcessStartInfo("gcc", [ - "-ffreestanding", "-nostartfiles", "-std=c23", - "-g", "-lm", - "-o", Path.Combine(".build", "out"), - ..objectPaths, - Path.Combine(".build", "runtime.o"), - ..objectFileArgs - ])); - - if (linkProcess == null) return 1; - linkProcess.WaitForExit(); - - if (linkProcess.ExitCode != 0) - { - Console.Error.WriteLine($"gcc failed with exit code {linkProcess.ExitCode}"); - return 1; - } - - Console.WriteLine("Build successful: .build/out"); - } - else - { - Console.WriteLine("No main function found in module main, skipping link step"); - } -} -else -{ - Console.WriteLine("No main function found in module main, skipping link step"); -} +Console.Out.WriteLine(string.Join(' ', objectPaths)); return 0; \ No newline at end of file diff --git a/compiler/NubLang/Ast/Node.cs b/compiler/NubLang/Ast/Node.cs index c904912..133afc1 100644 --- a/compiler/NubLang/Ast/Node.cs +++ b/compiler/NubLang/Ast/Node.cs @@ -100,20 +100,14 @@ public record UnaryExpressionNode(List Tokens, NubType Type, UnaryOperato public record FuncCallNode(List Tokens, NubType Type, ExpressionNode Expression, List Parameters) : RValueExpressionNode(Tokens, Type); -public record LValueIdentifierNode(List Tokens, NubType Type, string Name) : LValueExpressionNode(Tokens, Type); - -public record RValueIdentifierNode(List Tokens, NubType Type, string Name) : RValueExpressionNode(Tokens, Type); +public record VariableIdentifierNode(List Tokens, NubType Type, string Name) : LValueExpressionNode(Tokens, Type); public record FuncIdentifierNode(List Tokens, NubType Type, string Module, string Name, string? ExternSymbol) : RValueExpressionNode(Tokens, Type); public record ArrayInitializerNode(List Tokens, NubType Type, ExpressionNode Capacity, NubType ElementType) : RValueExpressionNode(Tokens, Type); -public record ConstArrayInitializerNode(List Tokens, NubType Type, long Capacity, NubType ElementType) : RValueExpressionNode(Tokens, Type); - public record ArrayIndexAccessNode(List Tokens, NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Tokens, Type); -public record ConstArrayIndexAccessNode(List Tokens, NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Tokens, Type); - public record SliceIndexAccessNode(List Tokens, NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Tokens, Type); public record AddressOfNode(List Tokens, NubType Type, LValueExpressionNode LValue) : RValueExpressionNode(Tokens, Type); @@ -128,7 +122,9 @@ public record ConvertIntNode(List Tokens, NubType Type, ExpressionNode Va public record ConvertFloatNode(List Tokens, NubType Type, ExpressionNode Value, NubFloatType ValueType, NubFloatType TargetType) : RValueExpressionNode(Tokens, Type); -// public record ConvertConstArrayToArrayNode(List Tokens, NubType Type, ExpressionNode Value) : RValueExpressionNode(Tokens, Type); +public record ConvertStringToCStringNode(List Tokens, ExpressionNode Value) : RValueExpressionNode(Tokens, new NubCStringType()); + +public record ConvertCStringToStringNode(List Tokens, ExpressionNode Value) : RValueExpressionNode(Tokens, new NubStringType()); public record SizeBuiltinNode(List Tokens, NubType Type, NubType TargetType) : RValueExpressionNode(Tokens, Type); diff --git a/compiler/NubLang/Ast/TypeChecker.cs b/compiler/NubLang/Ast/TypeChecker.cs index 90802d3..4ecb895 100644 --- a/compiler/NubLang/Ast/TypeChecker.cs +++ b/compiler/NubLang/Ast/TypeChecker.cs @@ -54,7 +54,7 @@ public sealed class TypeChecker foreach (var (name, module) in _importedModules) { - foreach (var structSyntax in module.Structs(false)) + foreach (var structSyntax in module.Structs(true)) { var fields = structSyntax.Fields .Select(f => new NubStructFieldType(f.Name, ResolveType(f.Type), f.Value != null)) @@ -63,7 +63,7 @@ public sealed class TypeChecker importedStructTypes.Add(new NubStructType(name, structSyntax.Name, fields)); } - foreach (var funcSyntax in module.Functions(false)) + foreach (var funcSyntax in module.Functions(true)) { importedFunctions.Add(CheckFuncPrototype(funcSyntax.Prototype)); } @@ -109,7 +109,7 @@ public sealed class TypeChecker { foreach (var parameter in node.Prototype.Parameters) { - CurrentScope.DeclareVariable(new Variable(parameter.Name, ResolveType(parameter.Type), VariableKind.RValue)); + CurrentScope.DeclareVariable(new Variable(parameter.Name, ResolveType(parameter.Type))); } var prototype = CheckFuncPrototype(node.Prototype); @@ -211,7 +211,7 @@ public sealed class TypeChecker throw new TypeCheckerException(Diagnostic.Error($"Cannot infer type of variable {statement.Name}").At(statement).Build()); } - CurrentScope.DeclareVariable(new Variable(statement.Name, type, VariableKind.LValue)); + CurrentScope.DeclareVariable(new Variable(statement.Name, type)); return new VariableDeclarationNode(statement.Tokens, statement.Name, assignmentNode, type); } @@ -248,7 +248,6 @@ public sealed class TypeChecker LocalIdentifierSyntax expression => CheckLocalIdentifier(expression), ModuleIdentifierSyntax expression => CheckModuleIdentifier(expression), BoolLiteralSyntax expression => CheckBoolLiteral(expression), - ConstArrayInitializerSyntax expression => CheckConstArrayInitializer(expression), StringLiteralSyntax expression => CheckStringLiteral(expression, expectedType), IntLiteralSyntax expression => CheckIntLiteral(expression, expectedType), FloatLiteralSyntax expression => CheckFloatLiteral(expression, expectedType), @@ -265,10 +264,15 @@ public sealed class TypeChecker return result; } - // if (result.Type is NubConstArrayType && expectedType is NubArrayType) - // { - // return new ConvertConstArrayToArrayNode(node.Tokens, expectedType, result); - // } + if (result.Type is NubStringType && expectedType is NubCStringType) + { + return new ConvertStringToCStringNode(node.Tokens, result); + } + + if (result.Type is NubCStringType && expectedType is NubStringType) + { + return new ConvertCStringToStringNode(node.Tokens, result); + } if (result.Type is NubIntType sourceIntType && expectedType is NubIntType targetIntType) { @@ -289,13 +293,6 @@ public sealed class TypeChecker throw new TypeCheckerException(Diagnostic.Error($"Cannot convert {result.Type} to {expectedType}").At(node).Build()); } - private ConstArrayInitializerNode CheckConstArrayInitializer(ConstArrayInitializerSyntax expression) - { - var elementType = ResolveType(expression.ElementType); - var type = new NubConstArrayType(elementType, expression.Capacity); - return new ConstArrayInitializerNode(expression.Tokens, type, expression.Capacity, elementType); - } - private FloatToIntBuiltinNode CheckFloatToInt(FloatToIntBuiltinSyntax expression) { var value = CheckExpression(expression.Value); @@ -333,13 +330,20 @@ public sealed class TypeChecker private ExpressionNode CheckArrayIndexAccess(ArrayIndexAccessSyntax expression) { - var index = CheckExpression(expression.Index, new NubIntType(false, 64)); + var index = CheckExpression(expression.Index); + if (index.Type is not NubIntType) + { + throw new TypeCheckerException(Diagnostic + .Error("Array indexer must be of type int") + .At(expression.Index) + .Build()); + } + var target = CheckExpression(expression.Target); return target.Type switch { NubArrayType arrayType => new ArrayIndexAccessNode(expression.Tokens, arrayType.ElementType, target, index), - NubConstArrayType constArrayType => new ConstArrayIndexAccessNode(expression.Tokens, constArrayType.ElementType, target, index), NubSliceType sliceType => new SliceIndexAccessNode(expression.Tokens, sliceType.ElementType, target, index), _ => throw new TypeCheckerException(Diagnostic.Error($"Cannot use array indexer on type {target.Type}").At(expression).Build()) }; @@ -581,12 +585,7 @@ public sealed class TypeChecker var scopeIdent = CurrentScope.LookupVariable(expression.Name); if (scopeIdent != null) { - return scopeIdent.Kind switch - { - VariableKind.LValue => new LValueIdentifierNode(expression.Tokens, scopeIdent.Type, expression.Name), - VariableKind.RValue => new RValueIdentifierNode(expression.Tokens, scopeIdent.Type, expression.Name), - _ => throw new ArgumentOutOfRangeException() - }; + return new VariableIdentifierNode(expression.Tokens, scopeIdent.Type, expression.Name); } var module = _importedModules[CurrentScope.Module]; @@ -635,7 +634,7 @@ public sealed class TypeChecker { NubCStringType => new CStringLiteralNode(expression.Tokens, expectedType, expression.Value), NubStringType => new StringLiteralNode(expression.Tokens, expectedType, expression.Value), - _ => new CStringLiteralNode(expression.Tokens, new NubCStringType(), expression.Value) + _ => new StringLiteralNode(expression.Tokens, new NubStringType(), expression.Value) }; } @@ -894,13 +893,7 @@ public sealed class TypeChecker } } -public enum VariableKind -{ - LValue, - RValue -} - -public record Variable(string Name, NubType Type, VariableKind Kind); +public record Variable(string Name, NubType Type); public class Scope(string module, Scope? parent = null) { diff --git a/compiler/NubLang/Generation/CType.cs b/compiler/NubLang/Generation/CType.cs index d2c45c4..666d468 100644 --- a/compiler/NubLang/Generation/CType.cs +++ b/compiler/NubLang/Generation/CType.cs @@ -14,6 +14,8 @@ public static class CType NubFloatType floatType => CreateFloatType(floatType, variableName), NubCStringType => "char*" + (variableName != null ? $" {variableName}" : ""), NubPointerType ptr => CreatePointerType(ptr, variableName), + NubSliceType nubSliceType => "slice" + (variableName != null ? $" {variableName}" : ""), + NubStringType nubStringType => "string" + (variableName != null ? $" {variableName}" : ""), NubConstArrayType arr => CreateConstArrayType(arr, variableName), NubArrayType arr => CreateArrayType(arr, variableName), NubFuncType fn => CreateFuncType(fn, variableName), diff --git a/compiler/NubLang/Generation/Generator.cs b/compiler/NubLang/Generation/Generator.cs index 7c91d07..cd76700 100644 --- a/compiler/NubLang/Generation/Generator.cs +++ b/compiler/NubLang/Generation/Generator.cs @@ -1,3 +1,4 @@ +using System.Text; using NubLang.Ast; using NubLang.Syntax; @@ -39,6 +40,21 @@ public class Generator _writer.WriteLine("#include "); _writer.WriteLine(); + _writer.WriteLine(""" + typedef struct + { + size_t length; + uint8_t *data; + } string; + + typedef struct + { + size_t length; + void *data; + } slice; + + """); + foreach (var structType in _compilationUnit.ImportedStructTypes) { _writer.WriteLine("typedef struct"); @@ -68,22 +84,6 @@ public class Generator _writer.WriteLine(); } - // note(nub31): declare extern functions - foreach (var funcNode in _compilationUnit.Functions) - { - if (funcNode.Body != null) continue; - - EmitLine(funcNode.Tokens.FirstOrDefault()); - var parameters = funcNode.Prototype.Parameters.Count != 0 - ? string.Join(", ", funcNode.Prototype.Parameters.Select(x => CType.Create(x.Type, x.Name))) - : "void"; - - var name = FuncName(funcNode.Module, funcNode.Name, funcNode.Prototype.ExternSymbol); - _writer.WriteLine($"{CType.Create(funcNode.Prototype.ReturnType, name)}({parameters});"); - } - - _writer.WriteLine(); - // note(nub31): Normal functions foreach (var funcNode in _compilationUnit.Functions) { @@ -94,11 +94,6 @@ public class Generator ? string.Join(", ", funcNode.Prototype.Parameters.Select(x => CType.Create(x.Type, x.Name))) : "void"; - if (funcNode.Prototype.ExternSymbol == null) - { - _writer.Write("static "); - } - var name = FuncName(funcNode.Module, funcNode.Name, funcNode.Prototype.ExternSymbol); _writer.WriteLine($"{CType.Create(funcNode.Prototype.ReturnType, name)}({parameters})"); EmitBlock(funcNode.Body); @@ -165,11 +160,13 @@ public class Generator private void EmitBreak(BreakNode _) { + // todo(nub31): Emit deferred statements _writer.WriteLine("break;"); } private void EmitContinue(ContinueNode _) { + // todo(nub31): Emit deferred statements _writer.WriteLine("continue;"); } @@ -265,38 +262,31 @@ public class Generator ArrayIndexAccessNode arrayIndexAccessNode => EmitArrayIndexAccess(arrayIndexAccessNode), ArrayInitializerNode arrayInitializerNode => EmitArrayInitializer(arrayInitializerNode), BinaryExpressionNode binaryExpressionNode => EmitBinaryExpression(binaryExpressionNode), - BoolLiteralNode boolLiteralNode => EmitBoolLiteral(boolLiteralNode), - ConstArrayIndexAccessNode constArrayIndexAccessNode => EmitConstArrayIndexAccess(constArrayIndexAccessNode), - ConstArrayInitializerNode constArrayInitializerNode => EmitConstArrayInitializer(constArrayInitializerNode), - // ConvertConstArrayToArrayNode convertConstArrayToArrayNode => EmitConvertConstArrayToArray(convertConstArrayToArrayNode), + BoolLiteralNode boolLiteralNode => boolLiteralNode.Value ? "true" : "false", + ConvertCStringToStringNode convertCStringToStringNode => EmitConvertCStringToString(convertCStringToStringNode), ConvertFloatNode convertFloatNode => EmitConvertFloat(convertFloatNode), ConvertIntNode convertIntNode => EmitConvertInt(convertIntNode), - CStringLiteralNode cStringLiteralNode => EmitCStringLiteral(cStringLiteralNode), + ConvertStringToCStringNode convertStringToCStringNode => EmitConvertStringToCString(convertStringToCStringNode), + CStringLiteralNode cStringLiteralNode => $"\"{cStringLiteralNode.Value}\"", DereferenceNode dereferenceNode => EmitDereference(dereferenceNode), Float32LiteralNode float32LiteralNode => EmitFloat32Literal(float32LiteralNode), Float64LiteralNode float64LiteralNode => EmitFloat64Literal(float64LiteralNode), FloatToIntBuiltinNode floatToIntBuiltinNode => EmitFloatToIntBuiltin(floatToIntBuiltinNode), FuncCallNode funcCallNode => EmitFuncCall(funcCallNode), - FuncIdentifierNode funcIdentifierNode => EmitFuncIdentifier(funcIdentifierNode), + FuncIdentifierNode funcIdentifierNode => FuncName(funcIdentifierNode.Module, funcIdentifierNode.Name, funcIdentifierNode.ExternSymbol), IntLiteralNode intLiteralNode => EmitIntLiteral(intLiteralNode), AddressOfNode addressOfNode => EmitAddressOf(addressOfNode), - LValueIdentifierNode lValueIdentifierNode => EmitLValueIdentifier(lValueIdentifierNode), - RValueIdentifierNode rValueIdentifierNode => EmitRValueIdentifier(rValueIdentifierNode), - SizeBuiltinNode sizeBuiltinNode => EmitSizeBuiltin(sizeBuiltinNode), + SizeBuiltinNode sizeBuiltinNode => $"sizeof({CType.Create(sizeBuiltinNode.TargetType)})", SliceIndexAccessNode sliceIndexAccessNode => EmitSliceArrayIndexAccess(sliceIndexAccessNode), StringLiteralNode stringLiteralNode => EmitStringLiteral(stringLiteralNode), StructFieldAccessNode structFieldAccessNode => EmitStructFieldAccess(structFieldAccessNode), StructInitializerNode structInitializerNode => EmitStructInitializer(structInitializerNode), UIntLiteralNode uIntLiteralNode => EmitUIntLiteral(uIntLiteralNode), UnaryExpressionNode unaryExpressionNode => EmitUnaryExpression(unaryExpressionNode), + VariableIdentifierNode variableIdentifierNode => variableIdentifierNode.Name, _ => throw new ArgumentOutOfRangeException(nameof(expressionNode)) }; - if (expressionNode is ConstArrayInitializerNode) - { - return expr; - } - return $"({expr})"; } @@ -309,10 +299,9 @@ public class Generator private string EmitArrayInitializer(ArrayInitializerNode arrayInitializerNode) { - var type = (NubArrayType)arrayInitializerNode.Type; var capacity = EmitExpression(arrayInitializerNode.Capacity); var tmp = NewTmp(); - _writer.WriteLine($"{CType.Create(type.ElementType)} {tmp}[{capacity}];"); + _writer.WriteLine($"{CType.Create(arrayInitializerNode.ElementType)} {tmp}[{capacity}];"); return tmp; } @@ -347,30 +336,12 @@ public class Generator return $"{left} {op} {right}"; } - private string EmitBoolLiteral(BoolLiteralNode boolLiteralNode) + private string EmitConvertCStringToString(ConvertCStringToStringNode convertCStringToStringNode) { - return boolLiteralNode.Value ? "true" : "false"; + var value = EmitExpression(convertCStringToStringNode.Value); + return $"(string){{.length = strlen({value}), .data = {value}}}"; } - private string EmitConstArrayIndexAccess(ConstArrayIndexAccessNode constArrayIndexAccessNode) - { - var array = EmitExpression(constArrayIndexAccessNode.Target); - var index = EmitExpression(constArrayIndexAccessNode.Index); - // todo(nub31): We can emit bounds checking here - return $"{array}[{index}]"; - } - - private string EmitConstArrayInitializer(ConstArrayInitializerNode constArrayInitializerNode) - { - return "{0}"; - } - - // private string EmitConvertConstArrayToArray(ConvertConstArrayToArrayNode convertConstArrayToArrayNode) - // { - // var value = EmitExpression(convertConstArrayToArrayNode.Value); - // return $"({CType.Create(convertConstArrayToArrayNode.Type)}){value}"; - // } - private string EmitConvertFloat(ConvertFloatNode convertFloatNode) { var value = EmitExpression(convertFloatNode.Value); @@ -387,24 +358,21 @@ public class Generator private string EmitConvertInt(ConvertIntNode convertIntNode) { var value = EmitExpression(convertIntNode.Value); - var targetType = (convertIntNode.TargetType.Signed, convertIntNode.TargetType.Width) switch + var targetType = convertIntNode.TargetType.Width switch { - (false, 8) => "u8", - (false, 16) => "u16", - (false, 32) => "u32", - (false, 64) => "u64", - (true, 8) => "i8", - (true, 16) => "i16", - (true, 32) => "i32", - (true, 64) => "i64", + 8 => convertIntNode.TargetType.Signed ? "int8_t" : "uint8_t", + 16 => convertIntNode.TargetType.Signed ? "int16_t" : "uint16_t", + 32 => convertIntNode.TargetType.Signed ? "int32_t" : "uint32_t", + 64 => convertIntNode.TargetType.Signed ? "int64_t" : "uint64_t", _ => throw new ArgumentOutOfRangeException() }; return $"({targetType}){value}"; } - private string EmitCStringLiteral(CStringLiteralNode cStringLiteralNode) + private string EmitConvertStringToCString(ConvertStringToCStringNode convertStringToCStringNode) { - return $"\"{cStringLiteralNode.Value}\""; + var value = EmitExpression(convertStringToCStringNode.Value); + return $"(char*){value}.data"; } private string EmitDereference(DereferenceNode dereferenceNode) @@ -438,16 +406,12 @@ public class Generator private string EmitFloatToIntBuiltin(FloatToIntBuiltinNode floatToIntBuiltinNode) { var value = EmitExpression(floatToIntBuiltinNode.Value); - var targetType = (floatToIntBuiltinNode.TargetType.Signed, floatToIntBuiltinNode.TargetType.Width) switch + var targetType = floatToIntBuiltinNode.TargetType.Width switch { - (false, 8) => "u8", - (false, 16) => "u16", - (false, 32) => "u32", - (false, 64) => "u64", - (true, 8) => "i8", - (true, 16) => "i16", - (true, 32) => "i32", - (true, 64) => "i64", + 8 => floatToIntBuiltinNode.TargetType.Signed ? "int8_t" : "uint8_t", + 16 => floatToIntBuiltinNode.TargetType.Signed ? "int16_t" : "uint16_t", + 32 => floatToIntBuiltinNode.TargetType.Signed ? "int32_t" : "uint32_t", + 64 => floatToIntBuiltinNode.TargetType.Signed ? "int64_t" : "uint64_t", _ => throw new ArgumentOutOfRangeException() }; return $"({targetType}){value}"; @@ -460,11 +424,6 @@ public class Generator return $"{name}({string.Join(", ", parameterNames)})"; } - private string EmitFuncIdentifier(FuncIdentifierNode funcIdentifierNode) - { - return FuncName(funcIdentifierNode.Module, funcIdentifierNode.Name, funcIdentifierNode.ExternSymbol); - } - private string EmitIntLiteral(IntLiteralNode intLiteralNode) { var type = (NubIntType)intLiteralNode.Type; @@ -482,32 +441,18 @@ public class Generator return $"&{value}"; } - private string EmitLValueIdentifier(LValueIdentifierNode lValueIdentifierNode) - { - return lValueIdentifierNode.Name; - } - - private string EmitRValueIdentifier(RValueIdentifierNode rValueIdentifierNode) - { - return rValueIdentifierNode.Name; - } - - private string EmitSizeBuiltin(SizeBuiltinNode sizeBuiltinNode) - { - return $"sizeof({CType.Create(sizeBuiltinNode.TargetType)})"; - } - private string EmitSliceArrayIndexAccess(SliceIndexAccessNode sliceIndexAccessNode) { var value = EmitExpression(sliceIndexAccessNode.Target); var index = EmitExpression(sliceIndexAccessNode.Index); // todo(nub31): We can emit bounds checking here - return $"{value}.data[{index}]"; + return $"(({CType.Create(sliceIndexAccessNode.Target.Type)}){value}.data)[{index}]"; } private string EmitStringLiteral(StringLiteralNode stringLiteralNode) { - throw new NotImplementedException(); + var length = Encoding.UTF8.GetByteCount(stringLiteralNode.Value); + return $"(string){{.length = {length}, .data = \"{stringLiteralNode.Value}\"}}"; } private string EmitStructFieldAccess(StructFieldAccessNode structFieldAccessNode) diff --git a/compiler/NubLang/Syntax/Parser.cs b/compiler/NubLang/Syntax/Parser.cs index 130e332..901523b 100644 --- a/compiler/NubLang/Syntax/Parser.cs +++ b/compiler/NubLang/Syntax/Parser.cs @@ -532,19 +532,10 @@ public sealed class Parser private ExpressionSyntax ParseArrayInitializer(int startIndex) { - if (TryExpectIntLiteral(out var intLiteral)) - { - ExpectSymbol(Symbol.CloseBracket); - var type = ParseType(); - return new ConstArrayInitializerSyntax(GetTokens(startIndex), Convert.ToInt64(intLiteral.Value, intLiteral.Base), type); - } - else - { - var capacity = ParseExpression(); - ExpectSymbol(Symbol.CloseBracket); - var type = ParseType(); - return new ArrayInitializerSyntax(GetTokens(startIndex), capacity, type); - } + var capacity = ParseExpression(); + ExpectSymbol(Symbol.CloseBracket); + var type = ParseType(); + return new ArrayInitializerSyntax(GetTokens(startIndex), capacity, type); } private StructInitializerSyntax ParseStructInitializer(int startIndex) diff --git a/compiler/NubLang/Syntax/Syntax.cs b/compiler/NubLang/Syntax/Syntax.cs index 31977be..1b3bc6b 100644 --- a/compiler/NubLang/Syntax/Syntax.cs +++ b/compiler/NubLang/Syntax/Syntax.cs @@ -88,8 +88,6 @@ public record ModuleIdentifierSyntax(List Tokens, string Module, string N public record ArrayInitializerSyntax(List Tokens, ExpressionSyntax Capacity, TypeSyntax ElementType) : ExpressionSyntax(Tokens); -public record ConstArrayInitializerSyntax(List Tokens, long Capacity, TypeSyntax ElementType) : ExpressionSyntax(Tokens); - public record ArrayIndexAccessSyntax(List Tokens, ExpressionSyntax Target, ExpressionSyntax Index) : ExpressionSyntax(Tokens); public record AddressOfSyntax(List Tokens, ExpressionSyntax Target) : ExpressionSyntax(Tokens); diff --git a/examples/array/main.nub b/examples/array/main.nub index 513b656..4ceef5a 100644 --- a/examples/array/main.nub +++ b/examples/array/main.nub @@ -4,7 +4,6 @@ extern "puts" func puts(text: cstring) extern "main" func main(argc: i64, argv: [?]cstring): i64 { - let x = [10]i32 - x[0] = 23 - return 0 + let x = [23]i32 + return x[0] } \ No newline at end of file diff --git a/examples/hello-world/main.nub b/examples/hello-world/main.nub index f63a21f..7a88bf1 100644 --- a/examples/hello-world/main.nub +++ b/examples/hello-world/main.nub @@ -2,9 +2,9 @@ module "main" extern "puts" func puts(text: cstring) -extern "main" func main(args: []cstring): i64 +func main(argc: i32, argv: [?]cstring): i32 { - defer puts("Goodybye World") - puts("Hello World") + defer puts("Bye cruel world!") + puts("Hello world!") return 0 } \ No newline at end of file