Better literal handling
This commit is contained in:
@@ -1,6 +1,4 @@
|
||||
using NubLang.Tokenization;
|
||||
|
||||
namespace NubLang.TypeChecking.Node;
|
||||
namespace NubLang.TypeChecking.Node;
|
||||
|
||||
public enum UnaryOperator
|
||||
{
|
||||
@@ -36,6 +34,20 @@ public abstract record LValueExpressionNode(TypeNode Type) : ExpressionNode(Type
|
||||
|
||||
public abstract record RValueExpressionNode(TypeNode Type) : ExpressionNode(Type);
|
||||
|
||||
public record StringLiteralNode(TypeNode Type, string Value) : RValueExpressionNode(Type);
|
||||
|
||||
public record CStringLiteralNode(TypeNode Type, string Value) : RValueExpressionNode(Type);
|
||||
|
||||
public record IntLiteralNode(TypeNode Type, long Value) : RValueExpressionNode(Type);
|
||||
|
||||
public record UIntLiteralNode(TypeNode Type, ulong Value) : RValueExpressionNode(Type);
|
||||
|
||||
public record Float32LiteralNode(TypeNode Type, float Value) : RValueExpressionNode(Type);
|
||||
|
||||
public record Float64LiteralNode(TypeNode Type, double Value) : RValueExpressionNode(Type);
|
||||
|
||||
public record BoolLiteralNode(TypeNode Type, bool Value) : RValueExpressionNode(Type);
|
||||
|
||||
public record BinaryExpressionNode(TypeNode Type, ExpressionNode Left, BinaryOperator Operator, ExpressionNode Right) : RValueExpressionNode(Type);
|
||||
|
||||
public record UnaryExpressionNode(TypeNode Type, UnaryOperator Operator, ExpressionNode Operand) : RValueExpressionNode(Type);
|
||||
@@ -56,8 +68,6 @@ public record ArrayIndexAccessNode(TypeNode Type, ExpressionNode Target, Express
|
||||
|
||||
public record AddressOfNode(TypeNode Type, LValueExpressionNode LValue) : RValueExpressionNode(Type);
|
||||
|
||||
public record LiteralNode(TypeNode Type, string Value, LiteralKind Kind) : RValueExpressionNode(Type);
|
||||
|
||||
public record StructFieldAccessNode(TypeNode Type, StructTypeNode StructType, ExpressionNode Target, string Field) : LValueExpressionNode(Type);
|
||||
|
||||
public record StructInitializerNode(StructTypeNode StructType, Dictionary<string, ExpressionNode> Initializers) : RValueExpressionNode(StructType);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using NubLang.Diagnostics;
|
||||
using NubLang.Modules;
|
||||
using NubLang.Parsing.Syntax;
|
||||
@@ -618,19 +619,42 @@ public sealed class TypeChecker
|
||||
throw new TypeCheckerException(Diagnostic.Error($"No exported symbol {expression.Name} not found in module {expression.Module}").At(expression).Build());
|
||||
}
|
||||
|
||||
private LiteralNode CheckLiteral(LiteralSyntax expression, TypeNode? expectedType)
|
||||
private ExpressionNode CheckLiteral(LiteralSyntax expression, TypeNode? expectedType)
|
||||
{
|
||||
// todo(nub31): Check if the types can actually be represented as another one. For example, an int should be passed when a string is expected
|
||||
var type = expectedType ?? expression.Kind switch
|
||||
switch (expression.Kind)
|
||||
{
|
||||
LiteralKind.Integer => new IntTypeNode(true, 64),
|
||||
LiteralKind.Float => new FloatTypeNode(64),
|
||||
LiteralKind.String => new StringTypeNode(),
|
||||
LiteralKind.Bool => new BoolTypeNode(),
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
|
||||
return new LiteralNode(type, expression.Value, expression.Kind);
|
||||
case LiteralKind.Integer:
|
||||
{
|
||||
var type = expectedType as IntTypeNode ?? new IntTypeNode(true, 64);
|
||||
return type.Signed
|
||||
? new IntLiteralNode(type, long.Parse(expression.Value))
|
||||
: new UIntLiteralNode(type, ulong.Parse(expression.Value));
|
||||
}
|
||||
case LiteralKind.Float:
|
||||
{
|
||||
var type = expectedType as FloatTypeNode ?? new FloatTypeNode(64);
|
||||
return type.Width == 32
|
||||
? new Float32LiteralNode(type, float.Parse(expression.Value, CultureInfo.InvariantCulture))
|
||||
: new Float64LiteralNode(type, double.Parse(expression.Value, CultureInfo.InvariantCulture));
|
||||
}
|
||||
case LiteralKind.String:
|
||||
{
|
||||
return expectedType switch
|
||||
{
|
||||
CStringTypeNode => new CStringLiteralNode(expectedType, expression.Value),
|
||||
StringTypeNode => new StringLiteralNode(expectedType, expression.Value),
|
||||
_ => new CStringLiteralNode(new CStringTypeNode(), expression.Value)
|
||||
};
|
||||
}
|
||||
case LiteralKind.Bool:
|
||||
{
|
||||
return new BoolLiteralNode(new BoolTypeNode(), bool.Parse(expression.Value));
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(expression.Kind), $"Unknown literal kind: {expression.Kind}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private StructFieldAccessNode CheckStructFieldAccess(StructFieldAccessSyntax expression)
|
||||
|
||||
Reference in New Issue
Block a user