From 08cb6b9f41f9f36970547623413d7eb11acc70a1 Mon Sep 17 00:00:00 2001 From: nub31 Date: Mon, 18 Aug 2025 14:13:52 +0200 Subject: [PATCH] Remove alloc keyword for struct --- example/src/main.nub | 2 +- .../NubLang/Diagnostics/Diagnostic.cs | 1 - src/compiler/NubLang/Parsing/Parser.cs | 57 ++++++++++--------- .../Parsing/Syntax/ExpressionSyntax.cs | 2 +- src/compiler/NubLang/Tokenization/Token.cs | 1 - .../NubLang/Tokenization/Tokenizer.cs | 1 - .../NubLang/TypeChecking/TypeChecker.cs | 21 +++++-- 7 files changed, 48 insertions(+), 37 deletions(-) diff --git a/example/src/main.nub b/example/src/main.nub index eb05ccd..a9f48e0 100644 --- a/example/src/main.nub +++ b/example/src/main.nub @@ -23,7 +23,7 @@ struct Human : Test func main(args: []cstring): i64 { - let human: Test = alloc Human { + let human: Human = struct { name = "oliver" } diff --git a/src/compiler/NubLang/Diagnostics/Diagnostic.cs b/src/compiler/NubLang/Diagnostics/Diagnostic.cs index b12ab54..b1fdd5f 100644 --- a/src/compiler/NubLang/Diagnostics/Diagnostic.cs +++ b/src/compiler/NubLang/Diagnostics/Diagnostic.cs @@ -270,7 +270,6 @@ public class Diagnostic case Symbol.Continue: case Symbol.Struct: case Symbol.Let: - case Symbol.Alloc: case Symbol.Calls: case Symbol.Interface: case Symbol.For: diff --git a/src/compiler/NubLang/Parsing/Parser.cs b/src/compiler/NubLang/Parsing/Parser.cs index 08b0b41..28763e9 100644 --- a/src/compiler/NubLang/Parsing/Parser.cs +++ b/src/compiler/NubLang/Parsing/Parser.cs @@ -416,10 +416,10 @@ public sealed class Parser Symbol.Minus => new UnaryExpressionSyntax(GetTokens(startIndex), UnaryOperatorSyntax.Negate, ParsePrimaryExpression()), Symbol.Bang => new UnaryExpressionSyntax(GetTokens(startIndex), UnaryOperatorSyntax.Invert, ParsePrimaryExpression()), Symbol.OpenBracket => ParseArrayInitializer(startIndex), - Symbol.Alloc => ParseStructInitializer(startIndex), + Symbol.Struct => ParseStructInitializer(startIndex), _ => throw new ParseException(Diagnostic .Error($"Unexpected symbol '{symbolToken.Symbol}' in expression") - .WithHelp("Expected literal, identifier, or '(' to start expression") + .WithHelp("Expected '(', '-', '!', '[' or '{'") .At(symbolToken) .Build()) }, @@ -440,30 +440,6 @@ public sealed class Parser return expression; } - private ExpressionSyntax ParseArrayInitializer(int startIndex) - { - var capacity = ParseExpression(); - ExpectSymbol(Symbol.CloseBracket); - var type = ParseType(); - return new ArrayInitializerSyntax(GetTokens(startIndex), capacity, type); - } - - private ExpressionSyntax ParseStructInitializer(int startIndex) - { - var type = ParseType(); - Dictionary initializers = []; - ExpectSymbol(Symbol.OpenBrace); - while (!TryExpectSymbol(Symbol.CloseBrace)) - { - var name = ExpectIdentifier().Value; - ExpectSymbol(Symbol.Assign); - var value = ParseExpression(); - initializers.Add(name, value); - } - - return new StructInitializerSyntax(GetTokens(startIndex), type, initializers); - } - private ExpressionSyntax ParsePostfixOperators(ExpressionSyntax expr) { var startIndex = _tokenIndex; @@ -538,6 +514,35 @@ public sealed class Parser return expr; } + private ArrayInitializerSyntax ParseArrayInitializer(int startIndex) + { + var capacity = ParseExpression(); + ExpectSymbol(Symbol.CloseBracket); + var type = ParseType(); + return new ArrayInitializerSyntax(GetTokens(startIndex), capacity, type); + } + + private StructInitializerSyntax ParseStructInitializer(int startIndex) + { + var type = Optional.Empty(); + if (!TryExpectSymbol(Symbol.OpenBrace)) + { + type = ParseType(); + ExpectSymbol(Symbol.OpenBrace); + } + + Dictionary initializers = []; + while (!TryExpectSymbol(Symbol.CloseBrace)) + { + var name = ExpectIdentifier().Value; + ExpectSymbol(Symbol.Assign); + var value = ParseExpression(); + initializers.Add(name, value); + } + + return new StructInitializerSyntax(GetTokens(startIndex), type, initializers); + } + private BlockSyntax ParseBlock() { var startIndex = _tokenIndex; diff --git a/src/compiler/NubLang/Parsing/Syntax/ExpressionSyntax.cs b/src/compiler/NubLang/Parsing/Syntax/ExpressionSyntax.cs index 476197a..57fb43b 100644 --- a/src/compiler/NubLang/Parsing/Syntax/ExpressionSyntax.cs +++ b/src/compiler/NubLang/Parsing/Syntax/ExpressionSyntax.cs @@ -44,6 +44,6 @@ public record LiteralSyntax(IEnumerable Tokens, string Value, LiteralKind public record StructFieldAccessSyntax(IEnumerable Tokens, ExpressionSyntax Target, string Member) : ExpressionSyntax(Tokens); -public record StructInitializerSyntax(IEnumerable Tokens, TypeSyntax StructType, Dictionary Initializers) : ExpressionSyntax(Tokens); +public record StructInitializerSyntax(IEnumerable Tokens, Optional StructType, Dictionary Initializers) : ExpressionSyntax(Tokens); public record DereferenceSyntax(IEnumerable Tokens, ExpressionSyntax Expression) : ExpressionSyntax(Tokens); \ No newline at end of file diff --git a/src/compiler/NubLang/Tokenization/Token.cs b/src/compiler/NubLang/Tokenization/Token.cs index 12276c9..13e9648 100644 --- a/src/compiler/NubLang/Tokenization/Token.cs +++ b/src/compiler/NubLang/Tokenization/Token.cs @@ -65,7 +65,6 @@ public enum Symbol Caret, Ampersand, Let, - Alloc, Calls, Interface, For, diff --git a/src/compiler/NubLang/Tokenization/Tokenizer.cs b/src/compiler/NubLang/Tokenization/Tokenizer.cs index b8d37c0..021b4bd 100644 --- a/src/compiler/NubLang/Tokenization/Tokenizer.cs +++ b/src/compiler/NubLang/Tokenization/Tokenizer.cs @@ -14,7 +14,6 @@ public sealed class Tokenizer ["break"] = Symbol.Break, ["continue"] = Symbol.Continue, ["return"] = Symbol.Return, - ["alloc"] = Symbol.Alloc, ["struct"] = Symbol.Struct, ["let"] = Symbol.Let, ["calls"] = Symbol.Calls, diff --git a/src/compiler/NubLang/TypeChecking/TypeChecker.cs b/src/compiler/NubLang/TypeChecking/TypeChecker.cs index af224ca..af4baee 100644 --- a/src/compiler/NubLang/TypeChecking/TypeChecker.cs +++ b/src/compiler/NubLang/TypeChecking/TypeChecker.cs @@ -276,7 +276,7 @@ public sealed class TypeChecker IdentifierSyntax expression => CheckIdentifier(expression), LiteralSyntax expression => CheckLiteral(expression, expectedType), StructFieldAccessSyntax expression => CheckStructFieldAccess(expression), - StructInitializerSyntax expression => CheckStructInitializer(expression), + StructInitializerSyntax expression => CheckStructInitializer(expression, expectedType), UnaryExpressionSyntax expression => CheckUnaryExpression(expression), _ => throw new ArgumentOutOfRangeException(nameof(node)) }; @@ -475,7 +475,7 @@ public sealed class TypeChecker throw new TypeCheckerException(Diagnostic.Error($"No identifier with the name {expression.Name} exists").Build()); } - private LiteralNode CheckLiteral(LiteralSyntax expression, TypeNode? expectedType = null) + private LiteralNode CheckLiteral(LiteralSyntax expression, TypeNode? expectedType) { var type = expectedType ?? expression.Kind switch { @@ -523,11 +523,20 @@ public sealed class TypeChecker throw new TypeCheckerException(Diagnostic.Error($"{boundExpression.Type} does not have a member with the name {expression.Member}").Build()); } - private StructInitializerNode CheckStructInitializer(StructInitializerSyntax expression) + private StructInitializerNode CheckStructInitializer(StructInitializerSyntax expression, TypeNode? expectedType) { - var boundType = CheckType(expression.StructType); + var type = expectedType; + if (expression.StructType.HasValue) + { + type = CheckType(expression.StructType.Value); + } - if (boundType is not StructTypeNode structType) + if (type == null) + { + throw new TypeCheckerException(Diagnostic.Error("Cannot determine type of struct").Build()); + } + + if (type is not StructTypeNode structType) { throw new TypeCheckerException(Diagnostic.Error($"Cannot initialize non-struct type {expression.StructType}").Build()); } @@ -598,7 +607,7 @@ public sealed class TypeChecker if (type == null) { - throw new NotImplementedException("Diagnostics not implemented"); + throw new TypeCheckerException(Diagnostic.Error($"Cannot perform unary operation {expression.Operand} on type {boundOperand.Type}").Build()); } return new UnaryExpressionNode(type, CheckUnaryOperator(expression.OperatorSyntax), boundOperand);