...
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user