Add float to int builtin

This commit is contained in:
nub31
2025-09-28 22:48:32 +02:00
parent a2bdf47f5d
commit c489f23c41
6 changed files with 111 additions and 15 deletions

View File

@@ -78,4 +78,6 @@ public record ConvertIntNode(NubType Type, ExpressionNode Value, NubIntType Valu
public record ConvertFloatNode(NubType Type, ExpressionNode Value, NubFloatType ValueType, NubFloatType TargetType) : RValueExpressionNode(Type);
public record SizeCompilerMacroNode(NubType Type, NubType TargetType) : RValueExpressionNode(Type);
public record SizeBuiltinNode(NubType Type, NubType TargetType) : RValueExpressionNode(Type);
public record FloatToIntBuiltinNode(NubType Type, ExpressionNode Value, NubFloatType ValueType, NubIntType TargetType) : RValueExpressionNode(Type);

View File

@@ -305,8 +305,9 @@ public sealed class TypeChecker
LiteralSyntax expression => CheckLiteral(expression, expectedType),
StructFieldAccessSyntax expression => CheckStructFieldAccess(expression),
StructInitializerSyntax expression => CheckStructInitializer(expression, expectedType),
InterpretCompilerMacroSyntax expression => CheckExpression(expression.Target) with { Type = ResolveType(expression.Type) },
SizeCompilerMacroSyntax expression => new SizeCompilerMacroNode(new NubIntType(false, 64), ResolveType(expression.Type)),
InterpretBuiltinSyntax expression => CheckExpression(expression.Target) with { Type = ResolveType(expression.Type) },
SizeBuiltinSyntax expression => new SizeBuiltinNode(new NubIntType(false, 64), ResolveType(expression.Type)),
FloatToIntBuiltinSyntax expression => CheckFloatToInt(expression),
_ => throw new ArgumentOutOfRangeException(nameof(node))
};
@@ -334,6 +335,29 @@ public sealed class TypeChecker
throw new TypeCheckerException(Diagnostic.Error($"Cannot convert {result.Type} to {expectedType}").At(node).Build());
}
private FloatToIntBuiltinNode CheckFloatToInt(FloatToIntBuiltinSyntax expression)
{
var value = CheckExpression(expression.Value);
if (value.Type is not NubFloatType sourceFloatType)
{
throw new TypeCheckerException(Diagnostic
.Error("Source type of float to int conversion must be an float")
.At(expression.Value)
.Build());
}
var targetType = ResolveType(expression.Type);
if (targetType is not NubIntType targetIntType)
{
throw new TypeCheckerException(Diagnostic
.Error("Target type of float to int conversion must be an integer")
.At(expression.Type)
.Build());
}
return new FloatToIntBuiltinNode(targetIntType, value, sourceFloatType, targetIntType);
}
private AddressOfNode CheckAddressOf(AddressOfSyntax expression)
{
var target = CheckExpression(expression.Target);
@@ -652,10 +676,25 @@ public sealed class TypeChecker
{
case LiteralKind.Integer:
{
var type = expectedType as NubIntType ?? new NubIntType(true, 64);
return type.Signed
? new IntLiteralNode(type, long.Parse(expression.Value))
: new UIntLiteralNode(type, ulong.Parse(expression.Value));
if (expectedType is NubIntType intType)
{
return intType.Signed
? new IntLiteralNode(intType, long.Parse(expression.Value))
: new UIntLiteralNode(intType, ulong.Parse(expression.Value));
}
if (expectedType is NubFloatType floatType)
{
return floatType.Width switch
{
32 => new Float32LiteralNode(floatType, float.Parse(expression.Value)),
64 => new Float64LiteralNode(floatType, double.Parse(expression.Value)),
_ => throw new ArgumentOutOfRangeException()
};
}
var type = new NubIntType(true, 64);
return new IntLiteralNode(type, long.Parse(expression.Value));
}
case LiteralKind.Float:
{