This commit is contained in:
nub31
2026-02-27 22:20:32 +01:00
parent e512650440
commit 73ecbf8e9b
10 changed files with 163 additions and 90 deletions

View File

@@ -34,14 +34,21 @@ public class TypeChecker
var invalidParameter = false;
TypedNodeStatement? body = null;
try
if (function.ReturnType == null)
{
functionReturnType = ResolveType(function.ReturnType);
functionReturnType = NubTypeVoid.Instance;
}
catch (CompileException e)
else
{
diagnostics.Add(e.Diagnostic);
return null;
try
{
functionReturnType = ResolveType(function.ReturnType);
}
catch (CompileException e)
{
diagnostics.Add(e.Diagnostic);
return null;
}
}
using (scope.EnterScope())
@@ -395,15 +402,34 @@ public class TypeChecker
private TypedNodeExpressionIntLiteral CheckExpressionIntLiteral(NodeExpressionIntLiteral expression, NubType? expectedType)
{
return new TypedNodeExpressionIntLiteral(expression.Tokens, NubTypeSInt.Get(32), expression.Value);
NubType? type = null;
if (expectedType is NubTypeSInt or NubTypeUInt)
type = expectedType;
type ??= NubTypeSInt.Get(32);
return new TypedNodeExpressionIntLiteral(expression.Tokens, type, expression.Value);
}
private TypedNodeExpressionMemberAccess CheckExpressionMemberAccess(NodeExpressionMemberAccess expression, NubType? expectedType)
private TypedNodeExpression CheckExpressionMemberAccess(NodeExpressionMemberAccess expression, NubType? expectedType)
{
var target = CheckExpression(expression.Target, null);
switch (target.Type)
{
case NubTypeString stringType:
{
switch (expression.Name.Ident)
{
case "length":
return new TypedNodeExpressionStringLength(expression.Tokens, NubTypeUInt.Get(64), target);
case "ptr":
return new TypedNodeExpressionStringPointer(expression.Tokens, NubTypePointer.Get(NubTypeUInt.Get(8)), target);
default:
throw BasicError($"'{expression.Name.Ident}' is not a member of type string", expression.Name);
}
}
case NubTypeStruct structType:
{
if (!moduleGraph.TryResolveModule(structType.Module, out var module))
@@ -419,7 +445,7 @@ public class TypeChecker
if (field == null)
throw BasicError($"Struct '{target.Type}' does not have a field matching the name '{expression.Name.Ident}'", target);
return new TypedNodeExpressionMemberAccess(expression.Tokens, field.Type, target, expression.Name);
return new TypedNodeExpressionStructMemberAccess(expression.Tokens, field.Type, target, expression.Name);
}
case NubTypeAnonymousStruct anonymousStructType:
{
@@ -427,24 +453,7 @@ public class TypeChecker
if (field == null)
throw BasicError($"Struct '{target.Type}' does not have a field matching the name '{expression.Name.Ident}'", target);
return new TypedNodeExpressionMemberAccess(expression.Tokens, field.Type, target, expression.Name);
}
case NubTypeEnumVariant enumVariantType:
{
if (!moduleGraph.TryResolveModule(enumVariantType.EnumType.Module, out var module))
throw BasicError($"Module '{enumVariantType.EnumType.Module}' not found", expression.Target);
if (!module.TryResolveType(enumVariantType.EnumType.Name, currentModule == enumVariantType.EnumType.Module, out var typeDef))
throw BasicError($"Type '{enumVariantType.EnumType.Name}' not found in module '{enumVariantType.EnumType.Module}'", expression.Target);
if (typeDef is not Module.TypeInfoEnum enumDef)
throw BasicError($"Type '{enumVariantType.EnumType.Module}::{enumVariantType.EnumType.Name}' is not an enum", expression.Target);
var variant = enumDef.Variants.FirstOrDefault(x => x.Name == enumVariantType.Variant);
if (variant == null)
throw BasicError($"Type '{target.Type}' does not have a variant named '{enumVariantType.Variant}'", expression.Target);
return new TypedNodeExpressionMemberAccess(expression.Tokens, variant.Type, target, expression.Name);
return new TypedNodeExpressionStructMemberAccess(expression.Tokens, field.Type, target, expression.Name);
}
default:
throw BasicError($"{target.Type} has no member '{expression.Name.Ident}'", target);
@@ -867,12 +876,22 @@ public class TypedNodeExpressionEnumLiteral(List<Token> tokens, NubType type, Ty
public TypedNodeExpression Value { get; } = value;
}
public class TypedNodeExpressionMemberAccess(List<Token> tokens, NubType type, TypedNodeExpression target, TokenIdent name) : TypedNodeExpression(tokens, type)
public class TypedNodeExpressionStructMemberAccess(List<Token> tokens, NubType type, TypedNodeExpression target, TokenIdent name) : TypedNodeExpression(tokens, type)
{
public TypedNodeExpression Target { get; } = target;
public TokenIdent Name { get; } = name;
}
public class TypedNodeExpressionStringLength(List<Token> tokens, NubType type, TypedNodeExpression target) : TypedNodeExpression(tokens, type)
{
public TypedNodeExpression Target { get; } = target;
}
public class TypedNodeExpressionStringPointer(List<Token> tokens, NubType type, TypedNodeExpression target) : TypedNodeExpression(tokens, type)
{
public TypedNodeExpression Target { get; } = target;
}
public class TypedNodeExpressionFuncCall(List<Token> tokens, NubType type, TypedNodeExpression target, List<TypedNodeExpression> parameters) : TypedNodeExpression(tokens, type)
{
public TypedNodeExpression Target { get; } = target;