From e3f819411c4c809ce1b34ca1f92ff4b55dbecbac Mon Sep 17 00:00:00 2001 From: nub31 Date: Tue, 21 Oct 2025 20:47:00 +0200 Subject: [PATCH] ... --- compiler/NubLang/Ast/Node.cs | 10 +- compiler/NubLang/Ast/TypeChecker.cs | 36 +------ compiler/NubLang/Generation/Generator.cs | 131 +++++++++++------------ compiler/NubLang/Syntax/Parser.cs | 19 +--- compiler/NubLang/Syntax/Syntax.cs | 2 - examples/hello-world/makefile | 1 + 6 files changed, 74 insertions(+), 125 deletions(-) diff --git a/compiler/NubLang/Ast/Node.cs b/compiler/NubLang/Ast/Node.cs index f6fc2f9..d5d665d 100644 --- a/compiler/NubLang/Ast/Node.cs +++ b/compiler/NubLang/Ast/Node.cs @@ -100,23 +100,19 @@ 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 ArrayInitializerNode(List Tokens, NubType Type, ExpressionNode Capacity, NubType ElementType) : LValueExpressionNode(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); -public record StructFieldAccessNode(List Tokens, NubType Type, LValueExpressionNode Target, string Field) : LValueExpressionNode(Tokens, Type); +public record StructFieldAccessNode(List Tokens, NubType Type, ExpressionNode Target, string Field) : LValueExpressionNode(Tokens, Type); public record StructInitializerNode(List Tokens, NubStructType StructType, Dictionary Initializers) : LValueExpressionNode(Tokens, StructType); diff --git a/compiler/NubLang/Ast/TypeChecker.cs b/compiler/NubLang/Ast/TypeChecker.cs index f11903d..3c88d50 100644 --- a/compiler/NubLang/Ast/TypeChecker.cs +++ b/compiler/NubLang/Ast/TypeChecker.cs @@ -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), @@ -284,13 +283,6 @@ public sealed class TypeChecker throw new TypeCheckerException(Diagnostic.Error($"Cannot convert {result.Type} to {expectedType}").At(node).Build()); } - private ArrayInitializerNode CheckConstArrayInitializer(ConstArrayInitializerSyntax expression) - { - var elementType = ResolveType(expression.ElementType); - var type = new NubArrayType(elementType); - return new ArrayInitializerNode(expression.Tokens, type, new IntLiteralNode([], new NubIntType(false, 64), expression.Capacity), elementType); - } - private FloatToIntBuiltinNode CheckFloatToInt(FloatToIntBuiltinSyntax expression) { var value = CheckExpression(expression.Value); @@ -334,8 +326,6 @@ public sealed class TypeChecker 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()) }; } @@ -576,12 +566,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]; @@ -686,12 +671,7 @@ public sealed class TypeChecker .Build()); } - if (target is not LValueExpressionNode lValueTarget) - { - throw new TypeCheckerException(Diagnostic.Error("Struct field access is not an lvalue (this should never happen)").At(expression.Target).Build()); - } - - return new StructFieldAccessNode(expression.Tokens, field.Type, lValueTarget, expression.Member); + return new StructFieldAccessNode(expression.Tokens, field.Type, target, expression.Member); } default: { @@ -894,13 +874,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/Generator.cs b/compiler/NubLang/Generation/Generator.cs index 65fcaaf..55c1705 100644 --- a/compiler/NubLang/Generation/Generator.cs +++ b/compiler/NubLang/Generation/Generator.cs @@ -191,7 +191,7 @@ public class Generator { var target = EmitLValue(assignmentNode.Target); var value = EmitExpression(assignmentNode.Value); - _builder.BuildStore(value, target); + _builder.BuildStore(Unbox(value), target); } private void EmitBreak(BreakNode breakNode) @@ -223,7 +223,7 @@ public class Generator else { var returnValue = EmitExpression(returnNode.Value); - _builder.BuildRet(returnValue); + _builder.BuildRet(Unbox(returnValue)); } } @@ -247,7 +247,7 @@ public class Generator if (variableDeclarationNode.Assignment != null) { var initValue = EmitExpression(variableDeclarationNode.Assignment); - _builder.BuildStore(initValue, alloca); + _builder.BuildStore(Unbox(initValue), alloca); } _namedValues[variableDeclarationNode.Name] = alloca; @@ -258,18 +258,17 @@ public class Generator throw new NotImplementedException(); } - private LLVMValueRef EmitExpression(ExpressionNode expressionNode) + private Box EmitExpression(ExpressionNode expressionNode) { switch (expressionNode) { case LValueExpressionNode lvalue: { - var value = EmitLValue(lvalue); - return _builder.BuildLoad2(MapType(lvalue.Type), value); + return new Box(EmitLValue(lvalue), true); } case RValueExpressionNode rvalue: { - return EmitRValue(rvalue); + return new Box(EmitRValue(rvalue), false); } default: { @@ -283,12 +282,12 @@ public class Generator return lValueNode switch { ArrayIndexAccessNode arrayIndexAccessNode => EmitArrayIndexAccess(arrayIndexAccessNode), - ConstArrayIndexAccessNode constArrayIndexAccessNode => EmitConstArrayIndexAccess(constArrayIndexAccessNode), + ArrayInitializerNode arrayInitializerNode => EmitArrayInitializer(arrayInitializerNode), DereferenceNode dereferenceNode => EmitDereference(dereferenceNode), - LValueIdentifierNode lValueIdentifierNode => EmitLValueIdentifier(lValueIdentifierNode), SliceIndexAccessNode sliceIndexAccessNode => EmitSliceIndexAccess(sliceIndexAccessNode), StructFieldAccessNode structFieldAccessNode => EmitStructFieldAccess(structFieldAccessNode), StructInitializerNode structInitializerNode => EmitStructInitializer(structInitializerNode), + VariableIdentifierNode variableIdentifierNode => _namedValues[variableIdentifierNode.Name], _ => throw new ArgumentOutOfRangeException(nameof(lValueNode)) }; } @@ -298,7 +297,6 @@ public class Generator return rValueNode switch { AddressOfNode addressOfNode => EmitAddressOf(addressOfNode), - ArrayInitializerNode arrayInitializerNode => EmitArrayInitializer(arrayInitializerNode), BinaryExpressionNode binaryExpressionNode => EmitBinaryExpression(binaryExpressionNode), BoolLiteralNode boolLiteralNode => EmitBoolLiteral(boolLiteralNode), ConvertFloatNode convertFloatNode => EmitConvertFloat(convertFloatNode), @@ -310,7 +308,6 @@ public class Generator FuncCallNode funcCallNode => EmitFuncCall(funcCallNode), FuncIdentifierNode funcIdentifierNode => EmitFuncIdentifier(funcIdentifierNode), IntLiteralNode intLiteralNode => EmitIntLiteral(intLiteralNode), - RValueIdentifierNode rValueIdentifierNode => EmitRValueIdentifier(rValueIdentifierNode), SizeBuiltinNode sizeBuiltinNode => EmitSizeBuiltin(sizeBuiltinNode), StringLiteralNode stringLiteralNode => EmitStringLiteral(stringLiteralNode), UIntLiteralNode uIntLiteralNode => EmitUIntLiteral(uIntLiteralNode), @@ -327,13 +324,13 @@ public class Generator var target = EmitExpression(arrayIndexAccessNode.Target); var index = EmitExpression(arrayIndexAccessNode.Index); - return _builder.BuildGEP2(elementType, target, [index]); + return _builder.BuildGEP2(elementType, Unbox(target), [Unbox(index)]); } private LLVMValueRef EmitArrayInitializer(ArrayInitializerNode arrayInitializerNode) { var capacity = EmitExpression(arrayInitializerNode.Capacity); - return _builder.BuildArrayAlloca(MapType(arrayInitializerNode.ElementType), capacity); + return _builder.BuildArrayAlloca(MapType(arrayInitializerNode.ElementType), Unbox(capacity)); } private LLVMValueRef EmitBinaryExpression(BinaryExpressionNode binaryExpressionNode) @@ -347,24 +344,24 @@ public class Generator { return binaryExpressionNode.Operator switch { - BinaryOperator.Plus => _builder.BuildAdd(left, right), - BinaryOperator.Minus => _builder.BuildSub(left, right), - BinaryOperator.Multiply => _builder.BuildMul(left, right), - BinaryOperator.Divide => _builder.BuildSDiv(left, right), - BinaryOperator.Modulo => _builder.BuildSRem(left, right), + BinaryOperator.Plus => _builder.BuildAdd(Unbox(left), Unbox(right)), + BinaryOperator.Minus => _builder.BuildSub(Unbox(left), Unbox(right)), + BinaryOperator.Multiply => _builder.BuildMul(Unbox(left), Unbox(right)), + BinaryOperator.Divide => _builder.BuildSDiv(Unbox(left), Unbox(right)), + BinaryOperator.Modulo => _builder.BuildSRem(Unbox(left), Unbox(right)), - BinaryOperator.Equal => _builder.BuildICmp(LLVMIntPredicate.LLVMIntEQ, left, right), - BinaryOperator.NotEqual => _builder.BuildICmp(LLVMIntPredicate.LLVMIntNE, left, right), - BinaryOperator.LessThan => _builder.BuildICmp(LLVMIntPredicate.LLVMIntSLT, left, right), - BinaryOperator.LessThanOrEqual => _builder.BuildICmp(LLVMIntPredicate.LLVMIntSLE, left, right), - BinaryOperator.GreaterThan => _builder.BuildICmp(LLVMIntPredicate.LLVMIntSGT, left, right), - BinaryOperator.GreaterThanOrEqual => _builder.BuildICmp(LLVMIntPredicate.LLVMIntSGE, left, right), + BinaryOperator.Equal => _builder.BuildICmp(LLVMIntPredicate.LLVMIntEQ, Unbox(left), Unbox(right)), + BinaryOperator.NotEqual => _builder.BuildICmp(LLVMIntPredicate.LLVMIntNE, Unbox(left), Unbox(right)), + BinaryOperator.LessThan => _builder.BuildICmp(LLVMIntPredicate.LLVMIntSLT, Unbox(left), Unbox(right)), + BinaryOperator.LessThanOrEqual => _builder.BuildICmp(LLVMIntPredicate.LLVMIntSLE, Unbox(left), Unbox(right)), + BinaryOperator.GreaterThan => _builder.BuildICmp(LLVMIntPredicate.LLVMIntSGT, Unbox(left), Unbox(right)), + BinaryOperator.GreaterThanOrEqual => _builder.BuildICmp(LLVMIntPredicate.LLVMIntSGE, Unbox(left), Unbox(right)), - BinaryOperator.BitwiseAnd => _builder.BuildAnd(left, right), - BinaryOperator.BitwiseOr => _builder.BuildOr(left, right), - BinaryOperator.BitwiseXor => _builder.BuildXor(left, right), - BinaryOperator.LeftShift => _builder.BuildShl(left, right), - BinaryOperator.RightShift => _builder.BuildAShr(left, right), + BinaryOperator.BitwiseAnd => _builder.BuildAnd(Unbox(left), Unbox(right)), + BinaryOperator.BitwiseOr => _builder.BuildOr(Unbox(left), Unbox(right)), + BinaryOperator.BitwiseXor => _builder.BuildXor(Unbox(left), Unbox(right)), + BinaryOperator.LeftShift => _builder.BuildShl(Unbox(left), Unbox(right)), + BinaryOperator.RightShift => _builder.BuildAShr(Unbox(left), Unbox(right)), _ => throw new NotSupportedException($"Binary operator {binaryExpressionNode.Operator} not supported for int") }; @@ -374,18 +371,18 @@ public class Generator { return binaryExpressionNode.Operator switch { - BinaryOperator.Plus => _builder.BuildFAdd(left, right), - BinaryOperator.Minus => _builder.BuildFSub(left, right), - BinaryOperator.Multiply => _builder.BuildFMul(left, right), - BinaryOperator.Divide => _builder.BuildFDiv(left, right), - BinaryOperator.Modulo => _builder.BuildFRem(left, right), + BinaryOperator.Plus => _builder.BuildFAdd(Unbox(left), Unbox(right)), + BinaryOperator.Minus => _builder.BuildFSub(Unbox(left), Unbox(right)), + BinaryOperator.Multiply => _builder.BuildFMul(Unbox(left), Unbox(right)), + BinaryOperator.Divide => _builder.BuildFDiv(Unbox(left), Unbox(right)), + BinaryOperator.Modulo => _builder.BuildFRem(Unbox(left), Unbox(right)), - BinaryOperator.Equal => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealOEQ, left, right), - BinaryOperator.NotEqual => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealONE, left, right), - BinaryOperator.LessThan => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealOLT, left, right), - BinaryOperator.LessThanOrEqual => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealOLE, left, right), - BinaryOperator.GreaterThan => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealOGT, left, right), - BinaryOperator.GreaterThanOrEqual => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealOGE, left, right), + BinaryOperator.Equal => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealOEQ, Unbox(left), Unbox(right)), + BinaryOperator.NotEqual => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealONE, Unbox(left), Unbox(right)), + BinaryOperator.LessThan => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealOLT, Unbox(left), Unbox(right)), + BinaryOperator.LessThanOrEqual => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealOLE, Unbox(left), Unbox(right)), + BinaryOperator.GreaterThan => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealOGT, Unbox(left), Unbox(right)), + BinaryOperator.GreaterThanOrEqual => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealOGE, Unbox(left), Unbox(right)), _ => throw new NotSupportedException($"Binary operator {binaryExpressionNode.Operator} not supported for float") }; @@ -395,10 +392,10 @@ public class Generator { return binaryExpressionNode.Operator switch { - BinaryOperator.LogicalAnd => _builder.BuildAnd(left, right), - BinaryOperator.LogicalOr => _builder.BuildOr(left, right), - BinaryOperator.Equal => _builder.BuildICmp(LLVMIntPredicate.LLVMIntEQ, left, right), - BinaryOperator.NotEqual => _builder.BuildICmp(LLVMIntPredicate.LLVMIntNE, left, right), + BinaryOperator.LogicalAnd => _builder.BuildAnd(Unbox(left), Unbox(right)), + BinaryOperator.LogicalOr => _builder.BuildOr(Unbox(left), Unbox(right)), + BinaryOperator.Equal => _builder.BuildICmp(LLVMIntPredicate.LLVMIntEQ, Unbox(left), Unbox(right)), + BinaryOperator.NotEqual => _builder.BuildICmp(LLVMIntPredicate.LLVMIntNE, Unbox(left), Unbox(right)), _ => throw new NotSupportedException($"Binary operator {binaryExpressionNode.Operator} not supported for bool") }; } @@ -411,16 +408,6 @@ public class Generator return LLVMValueRef.CreateConstInt(LLVMTypeRef.Int1, boolLiteralNode.Value ? 1ul : 0ul); } - private LLVMValueRef EmitConstArrayIndexAccess(ConstArrayIndexAccessNode constArrayIndexAccessNode) - { - var arrayType = (NubConstArrayType)constArrayIndexAccessNode.Target.Type; - - var target = EmitExpression(constArrayIndexAccessNode.Target); - var index = EmitExpression(constArrayIndexAccessNode.Index); - - return _builder.BuildGEP2(MapType(arrayType), target, [LLVMValueRef.CreateConstInt(LLVMTypeRef.Int64, 0), index]); - } - private LLVMValueRef EmitConvertFloat(ConvertFloatNode convertFloatNode) { throw new NotImplementedException(); @@ -459,8 +446,8 @@ public class Generator private LLVMValueRef EmitFuncCall(FuncCallNode funcCallNode) { var function = EmitExpression(funcCallNode.Expression); - var args = funcCallNode.Parameters.Select(EmitExpression).ToArray(); - return _builder.BuildCall2(MapType(funcCallNode.Expression.Type), function, args); + var args = funcCallNode.Parameters.Select(x => Unbox(EmitExpression(x))).ToArray(); + return _builder.BuildCall2(MapType(funcCallNode.Expression.Type), Unbox(function), args); } private LLVMValueRef EmitFuncIdentifier(FuncIdentifierNode funcIdentifierNode) @@ -478,16 +465,6 @@ public class Generator throw new NotImplementedException(); } - private LLVMValueRef EmitLValueIdentifier(LValueIdentifierNode lValueIdentifierNode) - { - return _namedValues[lValueIdentifierNode.Name]; - } - - private LLVMValueRef EmitRValueIdentifier(RValueIdentifierNode rValueIdentifierNode) - { - return _builder.BuildLoad2(MapType(rValueIdentifierNode.Type), _namedValues[rValueIdentifierNode.Name], rValueIdentifierNode.Name); - } - private LLVMValueRef EmitSizeBuiltin(SizeBuiltinNode sizeBuiltinNode) { throw new NotImplementedException(); @@ -506,7 +483,7 @@ public class Generator private LLVMValueRef EmitStructFieldAccess(StructFieldAccessNode structFieldAccessNode) { var type = (NubStructType)structFieldAccessNode.Target.Type; - var target = EmitLValue(structFieldAccessNode.Target); + var target = EmitLValue((LValueExpressionNode)structFieldAccessNode.Target); var fieldIndex = type.Fields.FindIndex(x => x.Name == structFieldAccessNode.Field); return _builder.BuildStructGEP2(MapType(structFieldAccessNode.Target.Type), target, (uint)fieldIndex); } @@ -522,7 +499,7 @@ public class Generator var fieldIndex = structInitializerNode.StructType.Fields.FindIndex(x => x.Name == initializer.Key); var fieldPtr = _builder.BuildStructGEP2(type, ptr, (uint)fieldIndex); - _builder.BuildStore(value, fieldPtr); + _builder.BuildStore(Unbox(value), fieldPtr); } return ptr; @@ -538,10 +515,22 @@ public class Generator var operand = EmitExpression(unaryExpressionNode.Operand); return unaryExpressionNode.Operator switch { - UnaryOperator.Negate when unaryExpressionNode.Operand.Type is NubIntType => _builder.BuildNeg(operand), - UnaryOperator.Negate when unaryExpressionNode.Operand.Type is NubFloatType => _builder.BuildFNeg(operand), - UnaryOperator.Invert => _builder.BuildNot(operand), + UnaryOperator.Negate when unaryExpressionNode.Operand.Type is NubIntType => _builder.BuildNeg(Unbox(operand)), + UnaryOperator.Negate when unaryExpressionNode.Operand.Type is NubFloatType => _builder.BuildFNeg(Unbox(operand)), + UnaryOperator.Invert => _builder.BuildNot(Unbox(operand)), _ => throw new NotImplementedException($"Unary operator {unaryExpressionNode.Operator} not implemented") }; } + + private LLVMValueRef Unbox(Box box) + { + if (box.LValue) + { + return _builder.BuildLoad2(box.Value.TypeOf, box.Value); + } + + return box.Value; + } + + private record Box(LLVMValueRef Value, bool LValue); } \ No newline at end of file diff --git a/compiler/NubLang/Syntax/Parser.cs b/compiler/NubLang/Syntax/Parser.cs index 130e332..785e55e 100644 --- a/compiler/NubLang/Syntax/Parser.cs +++ b/compiler/NubLang/Syntax/Parser.cs @@ -530,21 +530,12 @@ public sealed class Parser return expr; } - private ExpressionSyntax ParseArrayInitializer(int startIndex) + private ArrayInitializerSyntax 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/hello-world/makefile b/examples/hello-world/makefile index 490cbcc..b96eb29 100644 --- a/examples/hello-world/makefile +++ b/examples/hello-world/makefile @@ -1,5 +1,6 @@ .build/out: main.nub nubc main.nub + clang -o .build/out .build/main.ll clean: @rm -r .build 2>/dev/null || true