This commit is contained in:
nub31
2025-07-05 15:17:31 +02:00
parent 9f932e63bd
commit efceb3b68b
2 changed files with 2 additions and 635 deletions

View File

@@ -53,7 +53,7 @@ public class DefinitionTable
var implementations = _syntaxTrees var implementations = _syntaxTrees
.SelectMany(c => c.Definitions) .SelectMany(c => c.Definitions)
.OfType<TraitImplementationDefinitionNode>() .OfType<TraitImplementationDefinitionNode>()
.Where(c => c.ForType.Equals(type)); .Where(c => c.ForType == type);
var implementation = implementations.SingleOrDefault(c => c.Functions.Any(x => x.Name == funcName)); var implementation = implementations.SingleOrDefault(c => c.Functions.Any(x => x.Name == funcName));
@@ -164,7 +164,7 @@ public class BoundDefinitionTable
var implementations = _syntaxTrees var implementations = _syntaxTrees
.SelectMany(c => c.Definitions) .SelectMany(c => c.Definitions)
.OfType<BoundTraitImplementationDefinitionNode>() .OfType<BoundTraitImplementationDefinitionNode>()
.Where(c => c.ForType.Equals(type)); .Where(c => c.ForType == type);
var implementation = implementations.SingleOrDefault(c => c.Functions.Any(x => x.Name == funcName)); var implementation = implementations.SingleOrDefault(c => c.Functions.Any(x => x.Name == funcName));

View File

@@ -1,633 +0,0 @@
// using System.Diagnostics;
// using Syntax.Diagnostics;
// using Syntax.Parsing;
// using Syntax.Parsing.Node;
// using Syntax.Tokenization;
//
// namespace Syntax.Typing;
//
// public static class TypeChecker
// {
// private static SyntaxTree _syntaxTree = null!;
// private static DefinitionTable _definitionTable = null!;
//
// private static Dictionary<string, NubType> _variables = new();
// private static List<Diagnostic> _diagnostics = [];
// private static NubType? _currentFunctionReturnType;
// private static Queue<AnonymousFuncNode> _anonymousFunctions = [];
//
// public static void Check(SyntaxTree syntaxTree, DefinitionTable definitionTable, out IEnumerable<Diagnostic> diagnostics)
// {
// _syntaxTree = syntaxTree;
// _definitionTable = definitionTable;
//
// _variables = new Dictionary<string, NubType>();
// _diagnostics = [];
// _currentFunctionReturnType = null;
// _anonymousFunctions = [];
//
// foreach (var structDef in syntaxTree.Definitions.OfType<StructDefinitionNode>())
// {
// CheckStructDef(structDef);
// }
//
// foreach (var funcDef in syntaxTree.Definitions.OfType<LocalFuncDefinitionNode>())
// {
// CheckFuncDef(funcDef.Parameters, funcDef.Body, funcDef.ReturnType);
// }
//
// while (_anonymousFunctions.TryDequeue(out var func))
// {
// CheckFuncDef(func.Parameters, func.Body, func.ReturnType);
//
// }
//
// diagnostics = _diagnostics;
// }
//
// private static void CheckStructDef(StructDefinitionNode structDef)
// {
// var fields = new Dictionary<string, NubType>();
// foreach (var field in structDef.Fields)
// {
// if (fields.ContainsKey(field.Name))
// {
// ReportError($"Duplicate field '{field.Name}' in struct '{structDef.Name}'", structDef);
// continue;
// }
//
// if (field.Value.HasValue)
// {
// var fieldType = CheckExpression(field.Value.Value, field.Type);
// if (fieldType != null && !fieldType.Equals(field.Type))
// {
// ReportError("Default field initializer does not match the defined type", field.Value.Value);
// }
// }
//
// fields[field.Name] = field.Type;
// }
// }
//
// private static void CheckFuncDef(List<FuncParameter> parameters, BlockNode body, NubType returnType)
// {
// _variables.Clear();
// _currentFunctionReturnType = returnType;
//
// foreach (var param in parameters)
// {
// _variables[param.Name] = param.Type;
// }
//
// CheckBlock(body);
// }
//
// private static void CheckBlock(BlockNode block)
// {
// foreach (var statement in block.Statements)
// {
// CheckStatement(statement);
// }
// }
//
// private static void CheckStatement(StatementNode statement)
// {
// switch (statement)
// {
// case ArrayIndexAssignmentNode arrayIndexAssignment:
// CheckArrayIndexAssignment(arrayIndexAssignment);
// break;
// case VariableAssignmentNode variableAssignment:
// CheckVariableAssignment(variableAssignment);
// break;
// case VariableDeclarationNode variableDeclaration:
// CheckVariableVariableDeclaration(variableDeclaration);
// break;
// case IfNode ifNode:
// CheckIf(ifNode);
// break;
// case MemberAssignmentNode memberAssignment:
// CheckMemberAssignment(memberAssignment);
// break;
// case WhileNode whileNode:
// CheckWhile(whileNode);
// break;
// case ReturnNode returnNode:
// CheckReturn(returnNode);
// break;
// case StatementExpressionNode statementExpression:
// CheckExpression(statementExpression.Expression);
// break;
// case BreakNode:
// case ContinueNode:
// break;
// case DereferenceAssignmentNode dereferenceAssignment:
// CheckDereferenceAssignment(dereferenceAssignment);
// break;
// default:
// ReportError($"Unsupported statement type: {statement.GetType().Name}", statement);
// break;
// }
// }
//
// private static void CheckMemberAssignment(MemberAssignmentNode memberAssignment)
// {
// var memberType = CheckExpression(memberAssignment.MemberAccess);
// if (memberType == null) return;
// var valueType = CheckExpression(memberAssignment.Value, memberType);
// if (valueType == null) return;
//
// if (!NubType.IsCompatibleWith(memberType, valueType))
// {
// ReportError($"'{valueType}' is not assignable to member of type '{memberType}'", memberAssignment);
// }
// }
//
// private static void CheckArrayIndexAssignment(ArrayIndexAssignmentNode arrayIndexAssignment)
// {
// var itemType = CheckExpression(arrayIndexAssignment.ArrayIndexAccess);
// if (itemType == null) return;
// var valueType = CheckExpression(arrayIndexAssignment.Value, itemType);
// if (valueType == null) return;
//
// if (!NubType.IsCompatibleWith(itemType, valueType))
// {
// ReportError($"'{valueType}' is not assignable to array of type '{itemType}'", arrayIndexAssignment);
// }
// }
//
// private static void CheckVariableAssignment(VariableAssignmentNode variableAssignment)
// {
// if (!_variables.TryGetValue(variableAssignment.Identifier.Name, out var variable))
// {
// ReportError($"Variable '{variableAssignment.Identifier}' is not declared", variableAssignment);
// return;
// }
//
// var valueType = CheckExpression(variableAssignment.Value, variable);
// if (valueType == null) return;
//
// if (!NubType.IsCompatibleWith(variableAssignment.Value.Type, variable))
// {
// ReportError($"Cannot assign expression of type '{variableAssignment.Value.Type}' to variable '{variableAssignment.Identifier}' with type '{variable}'", variableAssignment);
// }
// }
//
// private static void CheckVariableVariableDeclaration(VariableDeclarationNode variableDeclaration)
// {
// if (_variables.TryGetValue(variableDeclaration.Name, out var variable))
// {
// ReportError($"Cannot redeclare variable '{variable}'", variableDeclaration);
// }
//
// _variables[variableDeclaration.Name] = variableDeclaration.Type;
// }
//
// private static NubType? CheckDereference(DereferenceNode dereference)
// {
// var exprType = CheckExpression(dereference.Expression);
// if (exprType == null) return null;
//
// if (exprType is not NubPointerType nubPointerType)
// {
// ReportError($"Cannot dereference a non-pointer type {exprType}", dereference);
// return null;
// }
//
// return nubPointerType.BaseType;
// }
//
// private static NubType CheckFixedInitializerArray(FixedArrayInitializerNode fixedArrayInitializer)
// {
// return new NubFixedArrayType(fixedArrayInitializer.ElementType, fixedArrayInitializer.Capacity);
// }
//
// private static NubType? CheckFuncCall(FuncCallNode funcCall)
// {
// var identType = CheckExpression(funcCall.Expression);
// if (identType is not NubFuncType funcType)
// {
// ReportError("Cannot call function on non-function type", funcCall);
// return null;
// }
//
// if (funcCall.Parameters.Count != funcType.Parameters.Count)
// {
// ReportError($"{funcType} expects {funcType.Parameters.Count} arguments, but was called with {funcType.Parameters.Count} arguments", funcCall);
// return null;
// }
//
// for (var i = 0; i < funcCall.Parameters.Count; i++)
// {
// var parameter = funcCall.Parameters[i];
// var parameterType = CheckExpression(parameter);
// if (parameterType == null) return null;
//
// if (!NubType.IsCompatibleWith(parameterType, funcType.Parameters[i]))
// {
// ReportError($"'{parameterType}' does not match expected type {funcType.Parameters[i]}", funcCall);
// return null;
// }
// }
//
// return funcType.ReturnType;
// }
//
// private static void CheckIf(IfNode ifNode)
// {
// var conditionType = CheckExpression(ifNode.Condition, NubPrimitiveType.Bool);
// if (conditionType != null && !conditionType.Equals(NubPrimitiveType.Bool))
// {
// ReportError($"If condition must be a boolean expression, got '{conditionType}'", ifNode.Condition);
// }
//
// CheckBlock(ifNode.Body);
//
// if (ifNode.Else.HasValue)
// {
// var elseValue = ifNode.Else.Value;
// elseValue.Match(CheckIf, CheckBlock);
// }
// }
//
// private static void CheckWhile(WhileNode whileNode)
// {
// var conditionType = CheckExpression(whileNode.Condition, NubPrimitiveType.Bool);
// if (conditionType != null && !conditionType.Equals(NubPrimitiveType.Bool))
// {
// ReportError($"While condition must be a boolean expression, got '{conditionType}'", whileNode.Condition);
// }
//
// CheckBlock(whileNode.Body);
// }
//
// private static void CheckReturn(ReturnNode returnNode)
// {
// if (returnNode.Value.HasValue)
// {
// var returnType = CheckExpression(returnNode.Value.Value, _currentFunctionReturnType);
// if (returnType == null) return;
//
// if (_currentFunctionReturnType == null)
// {
// ReportError("Cannot return a value from a function with no return type", returnNode.Value.Value);
// return;
// }
//
// if (!NubType.IsCompatibleWith(returnType, _currentFunctionReturnType))
// {
// ReportError($"Return value of type '{returnType}' is not compatible with function return type '{_currentFunctionReturnType}'", returnNode.Value.Value);
// }
// }
// else if (_currentFunctionReturnType != null)
// {
// ReportError($"Function must return a value of type '{_currentFunctionReturnType}'", returnNode);
// }
// }
//
// private static void CheckDereferenceAssignment(DereferenceAssignmentNode dereferenceAssignment)
// {
// var dereferenceType = CheckExpression(dereferenceAssignment.Dereference);
// if (dereferenceType == null) return;
// var valueType = CheckExpression(dereferenceAssignment.Value, dereferenceType);
// if (valueType == null) return;
//
// if (!NubType.IsCompatibleWith(dereferenceType, valueType))
// {
// ReportError($"'{valueType}' is not assignable to type '{dereferenceType}'", dereferenceAssignment);
// }
// }
//
// private static NubType? CheckExpression(ExpressionNode expression, NubType? expectedType = null)
// {
// var resultType = expression switch
// {
// AddressOfNode addressOf => CheckAddressOf(addressOf),
// AnonymousFuncNode anonymousFunc => CheckAnonymousFunc(anonymousFunc),
// ArrayIndexAccessNode arrayIndex => CheckArrayIndex(arrayIndex),
// ArrayInitializerNode arrayInitializer => CheckArrayInitializer(arrayInitializer),
// LiteralNode literal => CheckLiteral(literal, expectedType),
// IdentifierNode identifier => CheckIdentifier(identifier),
// BinaryExpressionNode binaryExpr => CheckBinaryExpression(binaryExpr),
// DereferenceNode dereference => CheckDereference(dereference),
// FixedArrayInitializerNode fixedArray => CheckFixedInitializerArray(fixedArray),
// FuncCallNode funcCallExpr => CheckFuncCall(funcCallExpr),
// StructInitializerNode structInit => CheckStructInitializer(structInit),
// UnaryExpressionNode unaryExpression => CheckUnaryExpression(unaryExpression),
// MemberAccessNode memberAccess => CheckMemberAccess(memberAccess),
// _ => throw new UnreachableException()
// };
//
// if (resultType != null)
// {
// expression.Type = resultType;
// }
//
// return resultType;
// }
//
// private static NubType CheckAnonymousFunc(AnonymousFuncNode anonymousFunc)
// {
// _anonymousFunctions.Enqueue(anonymousFunc);
// return new NubFuncType(anonymousFunc.ReturnType, anonymousFunc.Parameters.Select(p => p.Type).ToList());
// }
//
// private static NubType? CheckLiteral(LiteralNode literal, NubType? expectedType = null)
// {
// if (expectedType != null)
// {
// if (expectedType.IsNumber && literal.Kind is not LiteralKind.Integer and not LiteralKind.Float)
// {
// ReportError("Expression expects a numeric literal", literal);
// return null;
// }
//
// if (expectedType.IsInteger && literal.Kind == LiteralKind.Float)
// {
// if (literal.Kind == LiteralKind.Float)
// {
// ReportWarning("Float used in integer context. Everything after the '.' will be ignored", literal);
// }
// }
//
// return expectedType;
// }
//
// return literal.Kind switch
// {
// LiteralKind.Integer => NubPrimitiveType.I64,
// LiteralKind.Float => NubPrimitiveType.F64,
// LiteralKind.String => new NubCStringType(),
// LiteralKind.Bool => NubPrimitiveType.Bool,
// _ => throw new ArgumentOutOfRangeException()
// };
// }
//
// private static NubType? CheckArrayIndex(ArrayIndexAccessNode arrayIndexAccess)
// {
// var expressionType = CheckExpression(arrayIndexAccess.Array);
// if (expressionType == null) return null;
// var indexType = CheckExpression(arrayIndexAccess.Index, NubPrimitiveType.U64);
// if (indexType is { IsInteger: false })
// {
// ReportError("Array index type must be a number", arrayIndexAccess.Index);
// }
//
// if (expressionType is NubArrayType arrayType)
// {
// return arrayType.ElementType;
// }
//
// if (expressionType is NubFixedArrayType fixedArrayType)
// {
// return fixedArrayType.ElementType;
// }
//
// ReportError($"Cannot access index of non-array type {expressionType}", arrayIndexAccess.Array);
// return null;
// }
//
// private static NubType CheckArrayInitializer(ArrayInitializerNode arrayInitializer)
// {
// var capacityType = CheckExpression(arrayInitializer.Capacity, NubPrimitiveType.U64);
// if (capacityType is { IsInteger: false })
// {
// ReportError("Array capacity type must be an integer", arrayInitializer.Capacity);
// }
//
// return new NubArrayType(arrayInitializer.ElementType);
// }
//
// private static NubType? CheckIdentifier(IdentifierNode identifier)
// {
// var definition = _definitionTable.LookupFunc(identifier.Namespace.Or(_syntaxTree.Namespace), identifier.Name);
// if (definition.HasValue)
// {
// return new NubFuncType(definition.Value.ReturnType, definition.Value.Parameters.Select(p => p.Type).ToList());
// }
//
// if (!identifier.Namespace.HasValue)
// {
// return _variables[identifier.Name];
// }
//
// ReportError($"Identifier '{identifier}' not found", identifier);
// return null;
// }
//
// private static NubType? CheckAddressOf(AddressOfNode addressOf)
// {
// var exprType = CheckExpression(addressOf.Expression);
// if (exprType == null) return null;
//
// return new NubPointerType(exprType);
// }
//
// private static NubType? CheckBinaryExpression(BinaryExpressionNode binaryExpr)
// {
// var leftType = CheckExpression(binaryExpr.Left);
// var rightType = CheckExpression(binaryExpr.Right);
//
// if (leftType == null || rightType == null) return null;
//
// if (!leftType.Equals(rightType))
// {
// ReportError($"Left '{leftType}' and right '{rightType}' side of the binary expression must be the same type", binaryExpr);
// return null;
// }
//
// switch (binaryExpr.Operator)
// {
// case BinaryExpressionOperator.Equal:
// case BinaryExpressionOperator.NotEqual:
// return NubPrimitiveType.Bool;
// case BinaryExpressionOperator.GreaterThan:
// case BinaryExpressionOperator.GreaterThanOrEqual:
// case BinaryExpressionOperator.LessThan:
// case BinaryExpressionOperator.LessThanOrEqual:
// if (!IsNumeric(leftType))
// {
// ReportError($"Comparison operators require numeric operands, got '{leftType}' and '{rightType}'", binaryExpr);
// return null;
// }
//
// return NubPrimitiveType.Bool;
// case BinaryExpressionOperator.Plus:
// case BinaryExpressionOperator.Minus:
// case BinaryExpressionOperator.Multiply:
// case BinaryExpressionOperator.Divide:
// if (!IsNumeric(leftType))
// {
// ReportError($"Arithmetic operators require numeric operands, got '{leftType}' and '{rightType}'", binaryExpr);
// return null;
// }
//
// return leftType;
// default:
// ReportError($"Unsupported binary operator: {binaryExpr.Operator}", binaryExpr);
// return null;
// }
// }
//
// private static NubType? CheckStructInitializer(StructInitializerNode structInit)
// {
// var initialized = new HashSet<string>();
//
// var defOpt = _definitionTable.LookupStruct(structInit.StructType.Namespace, structInit.StructType.Name);
// if (!defOpt.TryGetValue(out var definition))
// {
// ReportError($"Struct type '{structInit.StructType.Name}' is not defined", structInit);
// return null;
// }
//
// foreach (var initializer in structInit.Initializers)
// {
// var definitionField = definition.Fields.FirstOrDefault(f => f.Name == initializer.Key);
// if (definitionField == null)
// {
// ReportError($"Field '{initializer.Key}' does not exist in struct '{structInit.StructType.Name}'", initializer.Value);
// continue;
// }
//
// var initializerType = CheckExpression(initializer.Value, definitionField.Type);
// if (initializerType != null && !NubType.IsCompatibleWith(initializerType, definitionField.Type))
// {
// ReportError($"Cannot initialize field '{initializer.Key}' of type '{definitionField.Type}' with expression of type '{initializerType}'", initializer.Value);
// }
//
// initialized.Add(initializer.Key);
// }
//
// foreach (var field in definition.Fields.Where(f => f.Value.HasValue))
// {
// initialized.Add(field.Name);
// }
//
// foreach (var field in definition.Fields)
// {
// if (!initialized.Contains(field.Name))
// {
// ReportError($"Struct field '{field.Name}' is not initialized on type '{structInit.StructType.Name}'", structInit);
// }
// }
//
// return structInit.StructType;
// }
//
// private static NubType? CheckUnaryExpression(UnaryExpressionNode unaryExpression)
// {
// var operandType = CheckExpression(unaryExpression.Operand);
// if (operandType == null) return null;
//
// switch (unaryExpression.Operator)
// {
// case UnaryExpressionOperator.Negate:
// {
// if (operandType.Equals(NubPrimitiveType.I8) ||
// operandType.Equals(NubPrimitiveType.I16) ||
// operandType.Equals(NubPrimitiveType.I32) ||
// operandType.Equals(NubPrimitiveType.I64) ||
// operandType.Equals(NubPrimitiveType.F32) ||
// operandType.Equals(NubPrimitiveType.F64))
// {
// return operandType;
// }
//
// ReportError($"Cannot negate non-numeric type {operandType}", unaryExpression.Operand);
// return null;
// }
// case UnaryExpressionOperator.Invert:
// {
// if (!operandType.Equals(NubPrimitiveType.Bool))
// {
// ReportError($"Cannot invert non-boolean type {operandType}", unaryExpression.Operand);
// return null;
// }
//
// return operandType;
// }
// default:
// {
// ReportError($"Unsupported unary operator: {unaryExpression.Operator}", unaryExpression);
// return null;
// }
// }
// }
//
// private static NubType? CheckMemberAccess(MemberAccessNode memberAccess)
// {
// var expressionType = CheckExpression(memberAccess.Expression);
// if (expressionType == null) return null;
//
// switch (expressionType)
// {
// case NubArrayType:
// {
// if (memberAccess.Member == "count")
// {
// return NubPrimitiveType.I64;
// }
//
// break;
// }
// case NubStructType structType:
// {
// var defOpt = _definitionTable.LookupStruct(structType.Namespace, structType.Name);
// if (!defOpt.TryGetValue(out var definition))
// {
// ReportError($"Struct type '{structType.Name}' is not defined", memberAccess);
// return null;
// }
//
// var field = definition.Fields.FirstOrDefault(f => f.Name == memberAccess.Member);
// if (field == null)
// {
// ReportError($"Field '{memberAccess.Member}' does not exist in struct '{structType.Name}'", memberAccess);
// return null;
// }
//
// return field.Type;
// }
// }
//
// ReportError($"Cannot access member '{memberAccess.Member}' on type '{expressionType}'", memberAccess);
// return null;
// }
//
// private static void ReportError(string message, Node node)
// {
// var diagnostic = Diagnostic.Error(message).At(node).Build();
// _diagnostics.Add(diagnostic);
// }
//
// private static void ReportWarning(string message, Node node)
// {
// var diagnostic = Diagnostic.Warning(message).At(node).Build();
// _diagnostics.Add(diagnostic);
// }
//
// private static bool IsNumeric(NubType type)
// {
// if (type is not NubPrimitiveType primitiveType)
// {
// return false;
// }
//
// switch (primitiveType.Kind)
// {
// case PrimitiveTypeKind.I8:
// case PrimitiveTypeKind.I16:
// case PrimitiveTypeKind.I32:
// case PrimitiveTypeKind.I64:
// case PrimitiveTypeKind.U8:
// case PrimitiveTypeKind.U16:
// case PrimitiveTypeKind.U32:
// case PrimitiveTypeKind.U64:
// case PrimitiveTypeKind.F32:
// case PrimitiveTypeKind.F64:
// return true;
// default:
// return false;
// }
// }
// }