This commit is contained in:
nub31
2025-10-22 11:22:06 +02:00
parent c3d774fd78
commit 576369db19
9 changed files with 91 additions and 233 deletions

View File

@@ -100,20 +100,14 @@ public record UnaryExpressionNode(List<Token> Tokens, NubType Type, UnaryOperato
public record FuncCallNode(List<Token> Tokens, NubType Type, ExpressionNode Expression, List<ExpressionNode> Parameters) : RValueExpressionNode(Tokens, Type);
public record LValueIdentifierNode(List<Token> Tokens, NubType Type, string Name) : LValueExpressionNode(Tokens, Type);
public record RValueIdentifierNode(List<Token> Tokens, NubType Type, string Name) : RValueExpressionNode(Tokens, Type);
public record VariableIdentifierNode(List<Token> Tokens, NubType Type, string Name) : LValueExpressionNode(Tokens, Type);
public record FuncIdentifierNode(List<Token> Tokens, NubType Type, string Module, string Name, string? ExternSymbol) : RValueExpressionNode(Tokens, Type);
public record ArrayInitializerNode(List<Token> Tokens, NubType Type, ExpressionNode Capacity, NubType ElementType) : RValueExpressionNode(Tokens, Type);
public record ConstArrayInitializerNode(List<Token> Tokens, NubType Type, long Capacity, NubType ElementType) : RValueExpressionNode(Tokens, Type);
public record ArrayIndexAccessNode(List<Token> Tokens, NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Tokens, Type);
public record ConstArrayIndexAccessNode(List<Token> Tokens, NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Tokens, Type);
public record SliceIndexAccessNode(List<Token> Tokens, NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Tokens, Type);
public record AddressOfNode(List<Token> Tokens, NubType Type, LValueExpressionNode LValue) : RValueExpressionNode(Tokens, Type);
@@ -128,7 +122,9 @@ public record ConvertIntNode(List<Token> Tokens, NubType Type, ExpressionNode Va
public record ConvertFloatNode(List<Token> Tokens, NubType Type, ExpressionNode Value, NubFloatType ValueType, NubFloatType TargetType) : RValueExpressionNode(Tokens, Type);
// public record ConvertConstArrayToArrayNode(List<Token> Tokens, NubType Type, ExpressionNode Value) : RValueExpressionNode(Tokens, Type);
public record ConvertStringToCStringNode(List<Token> Tokens, ExpressionNode Value) : RValueExpressionNode(Tokens, new NubCStringType());
public record ConvertCStringToStringNode(List<Token> Tokens, ExpressionNode Value) : RValueExpressionNode(Tokens, new NubStringType());
public record SizeBuiltinNode(List<Token> Tokens, NubType Type, NubType TargetType) : RValueExpressionNode(Tokens, Type);

View File

@@ -54,7 +54,7 @@ public sealed class TypeChecker
foreach (var (name, module) in _importedModules)
{
foreach (var structSyntax in module.Structs(false))
foreach (var structSyntax in module.Structs(true))
{
var fields = structSyntax.Fields
.Select(f => new NubStructFieldType(f.Name, ResolveType(f.Type), f.Value != null))
@@ -63,7 +63,7 @@ public sealed class TypeChecker
importedStructTypes.Add(new NubStructType(name, structSyntax.Name, fields));
}
foreach (var funcSyntax in module.Functions(false))
foreach (var funcSyntax in module.Functions(true))
{
importedFunctions.Add(CheckFuncPrototype(funcSyntax.Prototype));
}
@@ -109,7 +109,7 @@ public sealed class TypeChecker
{
foreach (var parameter in node.Prototype.Parameters)
{
CurrentScope.DeclareVariable(new Variable(parameter.Name, ResolveType(parameter.Type), VariableKind.RValue));
CurrentScope.DeclareVariable(new Variable(parameter.Name, ResolveType(parameter.Type)));
}
var prototype = CheckFuncPrototype(node.Prototype);
@@ -211,7 +211,7 @@ public sealed class TypeChecker
throw new TypeCheckerException(Diagnostic.Error($"Cannot infer type of variable {statement.Name}").At(statement).Build());
}
CurrentScope.DeclareVariable(new Variable(statement.Name, type, VariableKind.LValue));
CurrentScope.DeclareVariable(new Variable(statement.Name, type));
return new VariableDeclarationNode(statement.Tokens, statement.Name, assignmentNode, type);
}
@@ -248,7 +248,6 @@ public sealed class TypeChecker
LocalIdentifierSyntax expression => CheckLocalIdentifier(expression),
ModuleIdentifierSyntax expression => CheckModuleIdentifier(expression),
BoolLiteralSyntax expression => CheckBoolLiteral(expression),
ConstArrayInitializerSyntax expression => CheckConstArrayInitializer(expression),
StringLiteralSyntax expression => CheckStringLiteral(expression, expectedType),
IntLiteralSyntax expression => CheckIntLiteral(expression, expectedType),
FloatLiteralSyntax expression => CheckFloatLiteral(expression, expectedType),
@@ -265,10 +264,15 @@ public sealed class TypeChecker
return result;
}
// if (result.Type is NubConstArrayType && expectedType is NubArrayType)
// {
// return new ConvertConstArrayToArrayNode(node.Tokens, expectedType, result);
// }
if (result.Type is NubStringType && expectedType is NubCStringType)
{
return new ConvertStringToCStringNode(node.Tokens, result);
}
if (result.Type is NubCStringType && expectedType is NubStringType)
{
return new ConvertCStringToStringNode(node.Tokens, result);
}
if (result.Type is NubIntType sourceIntType && expectedType is NubIntType targetIntType)
{
@@ -289,13 +293,6 @@ public sealed class TypeChecker
throw new TypeCheckerException(Diagnostic.Error($"Cannot convert {result.Type} to {expectedType}").At(node).Build());
}
private ConstArrayInitializerNode CheckConstArrayInitializer(ConstArrayInitializerSyntax expression)
{
var elementType = ResolveType(expression.ElementType);
var type = new NubConstArrayType(elementType, expression.Capacity);
return new ConstArrayInitializerNode(expression.Tokens, type, expression.Capacity, elementType);
}
private FloatToIntBuiltinNode CheckFloatToInt(FloatToIntBuiltinSyntax expression)
{
var value = CheckExpression(expression.Value);
@@ -333,13 +330,20 @@ public sealed class TypeChecker
private ExpressionNode CheckArrayIndexAccess(ArrayIndexAccessSyntax expression)
{
var index = CheckExpression(expression.Index, new NubIntType(false, 64));
var index = CheckExpression(expression.Index);
if (index.Type is not NubIntType)
{
throw new TypeCheckerException(Diagnostic
.Error("Array indexer must be of type int")
.At(expression.Index)
.Build());
}
var target = CheckExpression(expression.Target);
return target.Type switch
{
NubArrayType arrayType => new ArrayIndexAccessNode(expression.Tokens, arrayType.ElementType, target, index),
NubConstArrayType constArrayType => new ConstArrayIndexAccessNode(expression.Tokens, constArrayType.ElementType, target, index),
NubSliceType sliceType => new SliceIndexAccessNode(expression.Tokens, sliceType.ElementType, target, index),
_ => throw new TypeCheckerException(Diagnostic.Error($"Cannot use array indexer on type {target.Type}").At(expression).Build())
};
@@ -581,12 +585,7 @@ public sealed class TypeChecker
var scopeIdent = CurrentScope.LookupVariable(expression.Name);
if (scopeIdent != null)
{
return scopeIdent.Kind switch
{
VariableKind.LValue => new LValueIdentifierNode(expression.Tokens, scopeIdent.Type, expression.Name),
VariableKind.RValue => new RValueIdentifierNode(expression.Tokens, scopeIdent.Type, expression.Name),
_ => throw new ArgumentOutOfRangeException()
};
return new VariableIdentifierNode(expression.Tokens, scopeIdent.Type, expression.Name);
}
var module = _importedModules[CurrentScope.Module];
@@ -635,7 +634,7 @@ public sealed class TypeChecker
{
NubCStringType => new CStringLiteralNode(expression.Tokens, expectedType, expression.Value),
NubStringType => new StringLiteralNode(expression.Tokens, expectedType, expression.Value),
_ => new CStringLiteralNode(expression.Tokens, new NubCStringType(), expression.Value)
_ => new StringLiteralNode(expression.Tokens, new NubStringType(), expression.Value)
};
}
@@ -894,13 +893,7 @@ public sealed class TypeChecker
}
}
public enum VariableKind
{
LValue,
RValue
}
public record Variable(string Name, NubType Type, VariableKind Kind);
public record Variable(string Name, NubType Type);
public class Scope(string module, Scope? parent = null)
{