...
This commit is contained in:
@@ -53,7 +53,7 @@ public class DefinitionTable
|
||||
var implementations = _syntaxTrees
|
||||
.SelectMany(c => c.Definitions)
|
||||
.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));
|
||||
|
||||
@@ -164,7 +164,7 @@ public class BoundDefinitionTable
|
||||
var implementations = _syntaxTrees
|
||||
.SelectMany(c => c.Definitions)
|
||||
.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));
|
||||
|
||||
|
||||
@@ -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;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
Reference in New Issue
Block a user