This commit is contained in:
nub31
2025-09-29 16:57:25 +02:00
parent c0948e856a
commit d560b632c9
6 changed files with 127 additions and 120 deletions

View File

@@ -1,9 +1,7 @@
using System.Diagnostics;
using System.Globalization;
using NubLang.Diagnostics;
using NubLang.Modules;
using NubLang.Parsing.Syntax;
using NubLang.Tokenization;
using NubLang.TypeChecking.Node;
namespace NubLang.TypeChecking;
@@ -339,7 +337,10 @@ public sealed class TypeChecker
FuncCallSyntax expression => CheckFuncCall(expression),
LocalIdentifierSyntax expression => CheckLocalIdentifier(expression),
ModuleIdentifierSyntax expression => CheckModuleIdentifier(expression),
LiteralSyntax expression => CheckLiteral(expression, expectedType),
BoolLiteralSyntax expression => CheckBoolLiteral(expression),
StringLiteralSyntax expression => CheckStringLiteral(expression, expectedType),
IntLiteralSyntax expression => CheckIntLiteral(expression, expectedType),
FloatLiteralSyntax expression => CheckFloatLiteral(expression, expectedType),
MemberAccessSyntax expression => CheckMemberAccess(expression),
StructInitializerSyntax expression => CheckStructInitializer(expression, expectedType),
InterpretBuiltinSyntax expression => CheckExpression(expression.Target) with { Type = ResolveType(expression.Type) },
@@ -766,81 +767,50 @@ public sealed class TypeChecker
.Build());
}
private ExpressionNode CheckLiteral(LiteralSyntax expression, NubType? expectedType)
private ExpressionNode CheckStringLiteral(StringLiteralSyntax expression, NubType? expectedType)
{
switch (expression.Kind)
return expectedType switch
{
case LiteralKind.Integer:
{
if (expectedType is NubIntType intType)
{
return intType.Signed
? new IntLiteralNode(intType, long.Parse(expression.Value))
: new UIntLiteralNode(intType, ulong.Parse(expression.Value));
}
NubCStringType => new CStringLiteralNode(expectedType, expression.Value),
NubStringType => new StringLiteralNode(expectedType, expression.Value),
_ => new CStringLiteralNode(new NubCStringType(), expression.Value)
};
}
if (expectedType is NubFloatType floatType)
{
return floatType.Width switch
{
32 => new Float32LiteralNode(floatType, float.Parse(expression.Value, CultureInfo.InvariantCulture)),
64 => new Float64LiteralNode(floatType, double.Parse(expression.Value, CultureInfo.InvariantCulture)),
_ => throw new ArgumentOutOfRangeException()
};
}
var type = new NubIntType(true, 64);
return new IntLiteralNode(type, long.Parse(expression.Value));
}
case LiteralKind.Float:
{
var type = expectedType as NubFloatType ?? new NubFloatType(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.Hex:
{
if (expectedType is NubIntType intType)
{
return intType.Signed
? new IntLiteralNode(intType, Convert.ToInt64(expression.Value, 16))
: new UIntLiteralNode(intType, Convert.ToUInt64(expression.Value, 16));
}
var type = new NubIntType(true, 64);
return new IntLiteralNode(type, Convert.ToInt64(expression.Value, 16));
}
case LiteralKind.Binary:
{
if (expectedType is NubIntType intType)
{
return intType.Signed
? new IntLiteralNode(intType, Convert.ToInt64(expression.Value[2..], 2))
: new UIntLiteralNode(intType, Convert.ToUInt64(expression.Value[2..], 2));
}
var type = new NubIntType(true, 64);
return new IntLiteralNode(type, Convert.ToInt64(expression.Value.Substring(2), 2));
}
case LiteralKind.String:
{
return expectedType switch
{
NubCStringType => new CStringLiteralNode(expectedType, expression.Value),
NubStringType => new StringLiteralNode(expectedType, expression.Value),
_ => new CStringLiteralNode(new NubCStringType(), expression.Value)
};
}
case LiteralKind.Bool:
{
return new BoolLiteralNode(new NubBoolType(), bool.Parse(expression.Value));
}
default:
{
throw new ArgumentOutOfRangeException(nameof(expression.Kind), $"Unknown literal kind: {expression.Kind}");
}
private ExpressionNode CheckIntLiteral(IntLiteralSyntax expression, NubType? expectedType)
{
if (expectedType is NubIntType intType)
{
return intType.Signed
? new IntLiteralNode(intType, Convert.ToInt64(expression.Value, expression.Base))
: new UIntLiteralNode(intType, Convert.ToUInt64(expression.Value, expression.Base));
}
if (expectedType is NubFloatType floatType)
{
return floatType.Width switch
{
32 => new Float32LiteralNode(floatType, Convert.ToSingle(Convert.ToInt64(expression.Value, expression.Base))),
64 => new Float64LiteralNode(floatType, Convert.ToDouble(Convert.ToInt64(expression.Value, expression.Base))),
_ => throw new ArgumentOutOfRangeException()
};
}
var type = new NubIntType(true, 64);
return new IntLiteralNode(type, Convert.ToInt64(expression.Value, expression.Base));
}
private ExpressionNode CheckFloatLiteral(FloatLiteralSyntax expression, NubType? expectedType)
{
var type = expectedType as NubFloatType ?? new NubFloatType(64);
return type.Width == 32
? new Float32LiteralNode(type, Convert.ToSingle(expression.Value))
: new Float64LiteralNode(type, Convert.ToDouble(expression.Value));
}
private BoolLiteralNode CheckBoolLiteral(BoolLiteralSyntax expression)
{
return new BoolLiteralNode(new NubBoolType(), expression.Value);
}
private ExpressionNode CheckMemberAccess(MemberAccessSyntax expression)