literal fix

This commit is contained in:
nub31
2025-06-07 19:19:27 +02:00
parent 44320aa784
commit 23f955f8b2
8 changed files with 58 additions and 61 deletions

View File

@@ -69,17 +69,17 @@ public static class ConsoleColors
case IdentifierToken: case IdentifierToken:
return White; return White;
case LiteralToken literal: case LiteralToken literal:
if (literal.Type.Equals(NubPrimitiveType.String)) if (literal.Kind.Equals(NubPrimitiveType.String))
{ {
return Green; 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; return BrightBlue;
} }
if (literal.Type.Equals(NubPrimitiveType.Bool)) if (literal.Kind.Equals(NubPrimitiveType.Bool))
{ {
return Blue; return Blue;
} }

View File

@@ -1,6 +1,7 @@
using System.Diagnostics; using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.Text; using System.Text;
using Nub.Lang.Frontend.Lexing;
using Nub.Lang.Frontend.Parsing; using Nub.Lang.Frontend.Parsing;
using Nub.Lang.Frontend.Parsing.Definitions; using Nub.Lang.Frontend.Parsing.Definitions;
using Nub.Lang.Frontend.Parsing.Expressions; using Nub.Lang.Frontend.Parsing.Expressions;
@@ -15,7 +16,7 @@ public class Generator
private List<SourceFile> _sourceFiles = []; private List<SourceFile> _sourceFiles = [];
private StringBuilder _builder = new(); private StringBuilder _builder = new();
private Dictionary<string, Variable> _variables = []; private Dictionary<string, string> _variables = [];
private List<string> _strings = []; private List<string> _strings = [];
private Stack<string> _breakLabels = []; private Stack<string> _breakLabels = [];
private Stack<string> _continueLabels = []; private Stack<string> _continueLabels = [];
@@ -28,7 +29,7 @@ public class Generator
{ {
_sourceFiles = sourceFiles; _sourceFiles = sourceFiles;
_builder = new StringBuilder(); _builder = new StringBuilder();
_variables = new Dictionary<string, Variable>(); _variables = new Dictionary<string, string>();
_strings = []; _strings = [];
_funcNames = []; _funcNames = [];
_breakLabels = []; _breakLabels = [];
@@ -355,11 +356,7 @@ public class Generator
_builder.AppendLine($" {pointerName} {QBEAssign(parameter.Type)} alloc8 {SizeOf(parameter.Type)}"); _builder.AppendLine($" {pointerName} {QBEAssign(parameter.Type)} alloc8 {SizeOf(parameter.Type)}");
_builder.AppendLine($" storel %{parameterName}, {pointerName}"); _builder.AppendLine($" storel %{parameterName}, {pointerName}");
_variables[parameter.Name] = new Variable _variables[parameter.Name] = pointerName;
{
Pointer = pointerName,
Type = parameter.Type
};
} }
_builder.AppendLine(); _builder.AppendLine();
@@ -627,7 +624,7 @@ public class Generator
private void GenerateVariableAssignment(VariableAssignmentNode variableAssignment) private void GenerateVariableAssignment(VariableAssignmentNode variableAssignment)
{ {
var result = GenerateExpression(variableAssignment.Value); 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) private void GenerateVariableDeclaration(VariableDeclarationNode variableDeclaration)
@@ -664,11 +661,7 @@ public class Generator
} }
} }
_variables[variableDeclaration.Name] = new Variable _variables[variableDeclaration.Name] = pointerName;
{
Pointer = pointerName,
Type = type
};
} }
private void GenerateWhile(WhileNode whileStatement) private void GenerateWhile(WhileNode whileStatement)
@@ -1522,42 +1515,34 @@ public class Generator
var variable = _variables[identifier.Identifier]; var variable = _variables[identifier.Identifier];
if (IsLargeType(identifier.Type)) if (IsLargeType(identifier.Type))
{ {
return variable.Pointer; return variable;
} }
else else
{ {
var outputName = GenVarName(); 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; return outputName;
} }
} }
private string GenerateLiteral(LiteralNode literal) private string GenerateLiteral(LiteralNode literal)
{ {
if (literal.LiteralType.Equals(NubPrimitiveType.String)) switch (literal.Kind)
{
_strings.Add(literal.Literal);
return $"$str{_strings.Count}";
}
if (literal.LiteralType.Equals(NubPrimitiveType.I64))
{ {
case LiteralKind.Integer:
return literal.Literal; return literal.Literal;
} case LiteralKind.Float:
if (literal.LiteralType.Equals(NubPrimitiveType.F64))
{
var value = double.Parse(literal.Literal, CultureInfo.InvariantCulture); var value = double.Parse(literal.Literal, CultureInfo.InvariantCulture);
var bits = BitConverter.DoubleToInt64Bits(value); var bits = BitConverter.DoubleToInt64Bits(value);
return bits.ToString(); return bits.ToString();
} case LiteralKind.String:
_strings.Add(literal.Literal);
if (literal.LiteralType.Equals(NubPrimitiveType.Bool)) return $"$str{_strings.Count}";
{ case LiteralKind.Bool:
return bool.Parse(literal.Literal) ? "1" : "0"; return bool.Parse(literal.Literal) ? "1" : "0";
default:
throw new ArgumentOutOfRangeException();
} }
throw new NotSupportedException($"Literal {literal.LiteralType} is not supported");
} }
private string GenerateStructInitializer(StructInitializerNode structInitializer) 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)); 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; }
}
} }

View File

@@ -1,5 +1,4 @@
using Nub.Lang.Diagnostics; using Nub.Lang.Diagnostics;
using Nub.Lang.Frontend.Typing;
namespace Nub.Lang.Frontend.Lexing; namespace Nub.Lang.Frontend.Lexing;
@@ -143,7 +142,7 @@ public class Lexer
if (buffer is "true" or "false") 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); 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 // TODO: Revisit this
@@ -237,7 +236,7 @@ public class Lexer
Next(); Next();
} }
return new LiteralToken(CreateSpan(startIndex), NubPrimitiveType.String, buffer); return new LiteralToken(CreateSpan(startIndex), LiteralKind.String, buffer);
} }
throw new Exception($"Unknown character {current}"); throw new Exception($"Unknown character {current}");

View File

@@ -1,9 +1,15 @@
using Nub.Lang.Frontend.Typing; namespace Nub.Lang.Frontend.Lexing;
namespace Nub.Lang.Frontend.Lexing; public class LiteralToken(SourceSpan span, LiteralKind kind, string value) : Token(span)
public class LiteralToken(SourceSpan span, NubType type, string value) : Token(span)
{ {
public NubType Type { get; } = type; public LiteralKind Kind { get; } = kind;
public string Value { get; } = value; public string Value { get; } = value;
} }
public enum LiteralKind
{
Integer,
Float,
String,
Bool
}

View File

@@ -3,8 +3,8 @@ using Nub.Lang.Frontend.Typing;
namespace Nub.Lang.Frontend.Parsing.Expressions; namespace Nub.Lang.Frontend.Parsing.Expressions;
public class LiteralNode(IReadOnlyList<Token> tokens, string literal, NubType literalType) : ExpressionNode(tokens) public class LiteralNode(IReadOnlyList<Token> tokens, string literal, LiteralKind kind) : ExpressionNode(tokens)
{ {
public string Literal { get; } = literal; public string Literal { get; } = literal;
public NubType LiteralType { get; } = literalType; public LiteralKind Kind { get; } = kind;
} }

View File

@@ -429,7 +429,7 @@ public class Parser
{ {
case LiteralToken literal: case LiteralToken literal:
{ {
expr = new LiteralNode(GetTokensForNode(startIndex), literal.Value, literal.Type); expr = new LiteralNode(GetTokensForNode(startIndex), literal.Value, literal.Kind);
break; break;
} }
case IdentifierToken identifier: case IdentifierToken identifier:
@@ -529,7 +529,7 @@ public class Parser
} }
case Symbol.OpenBracket: 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); var capacity = int.Parse(literalToken.Value);
Next(); Next();
@@ -689,7 +689,7 @@ public class Parser
if (TryExpectSymbol(Symbol.OpenBracket)) 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(); Next();
ExpectSymbol(Symbol.CloseBracket); ExpectSymbol(Symbol.CloseBracket);

View File

@@ -1,5 +1,6 @@
using System.Diagnostics; using System.Diagnostics;
using Nub.Lang.Diagnostics; using Nub.Lang.Diagnostics;
using Nub.Lang.Frontend.Lexing;
using Nub.Lang.Frontend.Parsing; using Nub.Lang.Frontend.Parsing;
using Nub.Lang.Frontend.Parsing.Definitions; using Nub.Lang.Frontend.Parsing.Definitions;
using Nub.Lang.Frontend.Parsing.Expressions; using Nub.Lang.Frontend.Parsing.Expressions;
@@ -376,7 +377,7 @@ public class TypeChecker
AddressOfNode addressOf => TypeCheckAddressOf(addressOf), AddressOfNode addressOf => TypeCheckAddressOf(addressOf),
ArrayIndexAccessNode arrayIndex => TypeCheckArrayIndex(arrayIndex), ArrayIndexAccessNode arrayIndex => TypeCheckArrayIndex(arrayIndex),
ArrayInitializerNode arrayInitializer => TypeCheckArrayInitializer(arrayInitializer), ArrayInitializerNode arrayInitializer => TypeCheckArrayInitializer(arrayInitializer),
LiteralNode literal => literal.LiteralType, LiteralNode literal => TypeCheckLiteral(literal),
IdentifierNode identifier => TypeCheckIdentifier(identifier), IdentifierNode identifier => TypeCheckIdentifier(identifier),
BinaryExpressionNode binaryExpr => TypeCheckBinaryExpression(binaryExpr), BinaryExpressionNode binaryExpr => TypeCheckBinaryExpression(binaryExpr),
CastNode cast => TypeCheckCast(cast), CastNode cast => TypeCheckCast(cast),
@@ -397,6 +398,18 @@ public class TypeChecker
return resultType; 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) private NubType? TypeCheckArrayIndex(ArrayIndexAccessNode arrayIndexAccess)
{ {
var expressionType = TypeCheckExpression(arrayIndexAccess.Array); var expressionType = TypeCheckExpression(arrayIndexAccess.Array);