diff --git a/example/core/syscall.nub b/example/core/sys.nub similarity index 100% rename from example/core/syscall.nub rename to example/core/sys.nub diff --git a/src/lang/Nub.Lang/Diagnostics/ConsoleColors.cs b/src/lang/Nub.Lang/Diagnostics/ConsoleColors.cs index 6c211a0..6541d6f 100644 --- a/src/lang/Nub.Lang/Diagnostics/ConsoleColors.cs +++ b/src/lang/Nub.Lang/Diagnostics/ConsoleColors.cs @@ -69,17 +69,17 @@ public static class ConsoleColors case IdentifierToken: return White; case LiteralToken literal: - if (literal.Type.Equals(NubPrimitiveType.String)) + if (literal.Kind.Equals(NubPrimitiveType.String)) { return Green; } - if (literal.Type.Equals(NubPrimitiveType.I64) || literal.Type.Equals(NubPrimitiveType.F64)) + if (literal.Kind.Equals(NubPrimitiveType.I64) || literal.Kind.Equals(NubPrimitiveType.F64)) { return BrightBlue; } - if (literal.Type.Equals(NubPrimitiveType.Bool)) + if (literal.Kind.Equals(NubPrimitiveType.Bool)) { return Blue; } diff --git a/src/lang/Nub.Lang/Frontend/Generation/Generator.cs b/src/lang/Nub.Lang/Frontend/Generation/Generator.cs index 668644b..8f3a573 100644 --- a/src/lang/Nub.Lang/Frontend/Generation/Generator.cs +++ b/src/lang/Nub.Lang/Frontend/Generation/Generator.cs @@ -1,6 +1,7 @@ using System.Diagnostics; using System.Globalization; using System.Text; +using Nub.Lang.Frontend.Lexing; using Nub.Lang.Frontend.Parsing; using Nub.Lang.Frontend.Parsing.Definitions; using Nub.Lang.Frontend.Parsing.Expressions; @@ -15,7 +16,7 @@ public class Generator private List _sourceFiles = []; private StringBuilder _builder = new(); - private Dictionary _variables = []; + private Dictionary _variables = []; private List _strings = []; private Stack _breakLabels = []; private Stack _continueLabels = []; @@ -28,7 +29,7 @@ public class Generator { _sourceFiles = sourceFiles; _builder = new StringBuilder(); - _variables = new Dictionary(); + _variables = new Dictionary(); _strings = []; _funcNames = []; _breakLabels = []; @@ -355,11 +356,7 @@ public class Generator _builder.AppendLine($" {pointerName} {QBEAssign(parameter.Type)} alloc8 {SizeOf(parameter.Type)}"); _builder.AppendLine($" storel %{parameterName}, {pointerName}"); - _variables[parameter.Name] = new Variable - { - Pointer = pointerName, - Type = parameter.Type - }; + _variables[parameter.Name] = pointerName; } _builder.AppendLine(); @@ -627,7 +624,7 @@ public class Generator private void GenerateVariableAssignment(VariableAssignmentNode variableAssignment) { var result = GenerateExpression(variableAssignment.Value); - _builder.AppendLine($" storel {result}, {_variables[variableAssignment.Identifier.Identifier].Pointer}"); + _builder.AppendLine($" storel {result}, {_variables[variableAssignment.Identifier.Identifier]}"); } private void GenerateVariableDeclaration(VariableDeclarationNode variableDeclaration) @@ -664,11 +661,7 @@ public class Generator } } - _variables[variableDeclaration.Name] = new Variable - { - Pointer = pointerName, - Type = type - }; + _variables[variableDeclaration.Name] = pointerName; } private void GenerateWhile(WhileNode whileStatement) @@ -1522,42 +1515,34 @@ public class Generator var variable = _variables[identifier.Identifier]; if (IsLargeType(identifier.Type)) { - return variable.Pointer; + return variable; } else { var outputName = GenVarName(); - _builder.AppendLine($" {outputName} {QBEAssign(identifier.Type)} {QBELoad(identifier.Type)} {variable.Pointer}"); + _builder.AppendLine($" {outputName} {QBEAssign(identifier.Type)} {QBELoad(identifier.Type)} {variable}"); return outputName; } } private string GenerateLiteral(LiteralNode literal) { - if (literal.LiteralType.Equals(NubPrimitiveType.String)) + switch (literal.Kind) { - _strings.Add(literal.Literal); - return $"$str{_strings.Count}"; + case LiteralKind.Integer: + return literal.Literal; + case LiteralKind.Float: + var value = double.Parse(literal.Literal, CultureInfo.InvariantCulture); + var bits = BitConverter.DoubleToInt64Bits(value); + return bits.ToString(); + case LiteralKind.String: + _strings.Add(literal.Literal); + return $"$str{_strings.Count}"; + case LiteralKind.Bool: + return bool.Parse(literal.Literal) ? "1" : "0"; + default: + throw new ArgumentOutOfRangeException(); } - - if (literal.LiteralType.Equals(NubPrimitiveType.I64)) - { - return literal.Literal; - } - - if (literal.LiteralType.Equals(NubPrimitiveType.F64)) - { - var value = double.Parse(literal.Literal, CultureInfo.InvariantCulture); - var bits = BitConverter.DoubleToInt64Bits(value); - return bits.ToString(); - } - - if (literal.LiteralType.Equals(NubPrimitiveType.Bool)) - { - return bool.Parse(literal.Literal) ? "1" : "0"; - } - - throw new NotSupportedException($"Literal {literal.LiteralType} is not supported"); } private string GenerateStructInitializer(StructInitializerNode structInitializer) @@ -1787,10 +1772,4 @@ public class Generator { return structDefinition.Fields.TakeWhile(f => f.Name != member).Sum(f => SizeOf(f.Type)); } - - private class Variable - { - public required string Pointer { get; init; } - public required NubType Type { get; init; } - } } \ No newline at end of file diff --git a/src/lang/Nub.Lang/Frontend/Lexing/Lexer.cs b/src/lang/Nub.Lang/Frontend/Lexing/Lexer.cs index 989e5ba..dc1c768 100644 --- a/src/lang/Nub.Lang/Frontend/Lexing/Lexer.cs +++ b/src/lang/Nub.Lang/Frontend/Lexing/Lexer.cs @@ -1,5 +1,4 @@ using Nub.Lang.Diagnostics; -using Nub.Lang.Frontend.Typing; namespace Nub.Lang.Frontend.Lexing; @@ -143,7 +142,7 @@ public class Lexer if (buffer is "true" or "false") { - return new LiteralToken(CreateSpan(startIndex), NubPrimitiveType.Bool, buffer); + return new LiteralToken(CreateSpan(startIndex), LiteralKind.Bool, buffer); } return new IdentifierToken(CreateSpan(startIndex), buffer); @@ -184,7 +183,7 @@ public class Lexer } } - return new LiteralToken(CreateSpan(startIndex), isFloat ? NubPrimitiveType.F64 : NubPrimitiveType.I64, buffer); + return new LiteralToken(CreateSpan(startIndex), isFloat ? LiteralKind.Float : LiteralKind.Integer, buffer); } // TODO: Revisit this @@ -237,7 +236,7 @@ public class Lexer Next(); } - return new LiteralToken(CreateSpan(startIndex), NubPrimitiveType.String, buffer); + return new LiteralToken(CreateSpan(startIndex), LiteralKind.String, buffer); } throw new Exception($"Unknown character {current}"); diff --git a/src/lang/Nub.Lang/Frontend/Lexing/LiteralToken.cs b/src/lang/Nub.Lang/Frontend/Lexing/LiteralToken.cs index 948a079..2164ca4 100644 --- a/src/lang/Nub.Lang/Frontend/Lexing/LiteralToken.cs +++ b/src/lang/Nub.Lang/Frontend/Lexing/LiteralToken.cs @@ -1,9 +1,15 @@ -using Nub.Lang.Frontend.Typing; +namespace Nub.Lang.Frontend.Lexing; -namespace Nub.Lang.Frontend.Lexing; - -public class LiteralToken(SourceSpan span, NubType type, string value) : Token(span) +public class LiteralToken(SourceSpan span, LiteralKind kind, string value) : Token(span) { - public NubType Type { get; } = type; + public LiteralKind Kind { get; } = kind; public string Value { get; } = value; +} + +public enum LiteralKind +{ + Integer, + Float, + String, + Bool } \ No newline at end of file diff --git a/src/lang/Nub.Lang/Frontend/Parsing/Expressions/LiteralNode.cs b/src/lang/Nub.Lang/Frontend/Parsing/Expressions/LiteralNode.cs index 834f0fb..a91f02a 100644 --- a/src/lang/Nub.Lang/Frontend/Parsing/Expressions/LiteralNode.cs +++ b/src/lang/Nub.Lang/Frontend/Parsing/Expressions/LiteralNode.cs @@ -3,8 +3,8 @@ using Nub.Lang.Frontend.Typing; namespace Nub.Lang.Frontend.Parsing.Expressions; -public class LiteralNode(IReadOnlyList tokens, string literal, NubType literalType) : ExpressionNode(tokens) +public class LiteralNode(IReadOnlyList tokens, string literal, LiteralKind kind) : ExpressionNode(tokens) { public string Literal { get; } = literal; - public NubType LiteralType { get; } = literalType; + public LiteralKind Kind { get; } = kind; } \ No newline at end of file diff --git a/src/lang/Nub.Lang/Frontend/Parsing/Parser.cs b/src/lang/Nub.Lang/Frontend/Parsing/Parser.cs index 1bdbba4..091ee59 100644 --- a/src/lang/Nub.Lang/Frontend/Parsing/Parser.cs +++ b/src/lang/Nub.Lang/Frontend/Parsing/Parser.cs @@ -429,7 +429,7 @@ public class Parser { case LiteralToken literal: { - expr = new LiteralNode(GetTokensForNode(startIndex), literal.Value, literal.Type); + expr = new LiteralNode(GetTokensForNode(startIndex), literal.Value, literal.Kind); break; } case IdentifierToken identifier: @@ -529,7 +529,7 @@ public class Parser } case Symbol.OpenBracket: { - if (Peek().TryGetValue(out var capacityToken) && capacityToken is LiteralToken { Type: NubPrimitiveType { Kind: PrimitiveTypeKind.I64 } } literalToken) + if (Peek().TryGetValue(out var capacityToken) && capacityToken is LiteralToken { Kind: LiteralKind.Integer } literalToken) { var capacity = int.Parse(literalToken.Value); Next(); @@ -689,7 +689,7 @@ public class Parser if (TryExpectSymbol(Symbol.OpenBracket)) { - if (Peek().TryGetValue(out var token) && token is LiteralToken { Type: NubPrimitiveType { Kind: PrimitiveTypeKind.I64 }, Value: var sizeValue }) + if (Peek().TryGetValue(out var token) && token is LiteralToken { Kind: LiteralKind.Integer, Value: var sizeValue }) { Next(); ExpectSymbol(Symbol.CloseBracket); diff --git a/src/lang/Nub.Lang/Frontend/Typing/TypeChecker.cs b/src/lang/Nub.Lang/Frontend/Typing/TypeChecker.cs index 7d88590..3cb97f6 100644 --- a/src/lang/Nub.Lang/Frontend/Typing/TypeChecker.cs +++ b/src/lang/Nub.Lang/Frontend/Typing/TypeChecker.cs @@ -1,5 +1,6 @@ using System.Diagnostics; using Nub.Lang.Diagnostics; +using Nub.Lang.Frontend.Lexing; using Nub.Lang.Frontend.Parsing; using Nub.Lang.Frontend.Parsing.Definitions; using Nub.Lang.Frontend.Parsing.Expressions; @@ -376,7 +377,7 @@ public class TypeChecker AddressOfNode addressOf => TypeCheckAddressOf(addressOf), ArrayIndexAccessNode arrayIndex => TypeCheckArrayIndex(arrayIndex), ArrayInitializerNode arrayInitializer => TypeCheckArrayInitializer(arrayInitializer), - LiteralNode literal => literal.LiteralType, + LiteralNode literal => TypeCheckLiteral(literal), IdentifierNode identifier => TypeCheckIdentifier(identifier), BinaryExpressionNode binaryExpr => TypeCheckBinaryExpression(binaryExpr), CastNode cast => TypeCheckCast(cast), @@ -397,6 +398,18 @@ public class TypeChecker return resultType; } + private NubType TypeCheckLiteral(LiteralNode literal) + { + return literal.Kind switch + { + LiteralKind.Integer => NubPrimitiveType.I64, + LiteralKind.Float => NubPrimitiveType.F64, + LiteralKind.String => NubPrimitiveType.String, + LiteralKind.Bool => NubPrimitiveType.Bool, + _ => throw new UnreachableException() + }; + } + private NubType? TypeCheckArrayIndex(ArrayIndexAccessNode arrayIndexAccess) { var expressionType = TypeCheckExpression(arrayIndexAccess.Array);