This commit is contained in:
nub31
2025-09-11 23:34:13 +02:00
parent 0fd1af7e60
commit adcc9f3580
7 changed files with 95 additions and 31 deletions

View File

@@ -379,7 +379,7 @@ public class QBEGenerator
_labelIndex = 0;
_tmpIndex = 0;
_writer.Write("export function ");
_writer.Write(funcDef.ExternSymbol != null ? "export function " : "function ");
if (funcDef.Signature.ReturnType is not VoidTypeNode)
{

View File

@@ -6,7 +6,7 @@ public record FuncParameterNode(string Name, TypeNode Type) : Node;
public record FuncSignatureNode(IReadOnlyList<FuncParameterNode> Parameters, TypeNode ReturnType) : Node;
public record FuncNode(string Module, string Name, FuncSignatureNode Signature, BlockNode? Body) : DefinitionNode(Module, Name);
public record FuncNode(string Module, string Name, string? ExternSymbol, FuncSignatureNode Signature, BlockNode? Body) : DefinitionNode(Module, Name);
public record StructFieldNode(int Index, string Name, TypeNode Type, Optional<ExpressionNode> Value) : Node;

View File

@@ -1,3 +1,4 @@
using System.Diagnostics;
using NubLang.Diagnostics;
using NubLang.Parsing.Syntax;
using NubLang.Tokenization;
@@ -59,7 +60,11 @@ public sealed class TypeChecker
private InterfaceNode CheckInterfaceDefinition(InterfaceSyntax node)
{
throw new NotImplementedException();
var functions = node.Functions
.Select(function => new InterfaceFuncNode(function.Name, CheckFuncSignature(function.Signature)))
.ToList();
return new InterfaceNode(_syntaxTree.Metadata.ModuleName, node.Name, functions);
}
private StructNode CheckStructDefinition(StructSyntax node)
@@ -124,7 +129,7 @@ public sealed class TypeChecker
_funcReturnTypes.Pop();
}
return new FuncNode(_syntaxTree.Metadata.ModuleName, node.Name, CheckFuncSignature(node.Signature), body);
return new FuncNode(_syntaxTree.Metadata.ModuleName, node.Name, node.ExternSymbol, CheckFuncSignature(node.Signature), body);
}
private StatementNode CheckStatement(StatementSyntax node)
@@ -308,7 +313,7 @@ public sealed class TypeChecker
var parameterExpression = CheckExpression(parameter, expectedType);
if (parameterExpression.Type != expectedType)
{
throw new Exception($"Parameter {i + 1} does not match the type {expectedType} for function {funcType}");
throw new TypeCheckerException(Diagnostic.Error($"Parameter {i + 1} does not match the type {expectedType} for function {funcType}").At(parameter).Build());
}
parameters.Add(parameterExpression);
@@ -402,12 +407,77 @@ public sealed class TypeChecker
private StructFieldAccessNode CheckStructFieldAccess(StructFieldAccessSyntax expression)
{
throw new NotImplementedException();
var target = CheckExpression(expression.Target);
if (target.Type is not StructTypeNode structType)
{
throw new TypeCheckerException(Diagnostic
.Error($"Cannot access struct member on non-struct type {target.Type}")
.At(expression)
.Build());
}
var field = structType.Fields.FirstOrDefault(x => x.Name == expression.Member);
if (field == null)
{
throw new TypeCheckerException(Diagnostic
.Error($"Struct {target.Type} does not have a field with the name {expression.Member}")
.At(expression)
.Build());
}
return new StructFieldAccessNode(field.Type, structType, target, expression.Member);
}
private StructInitializerNode CheckStructInitializer(StructInitializerSyntax expression, TypeNode? expectedType)
{
throw new NotImplementedException();
StructTypeNode? structType = null;
if (expression.StructType.TryGetValue(out var customType))
{
var checkedType = ResolveType(customType);
if (checkedType is not StructTypeNode checkedStructType)
{
throw new UnreachableException("Parser fucked up");
}
structType = checkedStructType;
}
else if (expectedType is StructTypeNode expectedStructType)
{
structType = expectedStructType;
}
if (structType == null)
{
throw new TypeCheckerException(Diagnostic
.Error("Cannot get implicit type of struct")
.WithHelp("Specify struct type with struct {type_name} syntax")
.At(expression)
.Build());
}
var initializers = new Dictionary<string, ExpressionNode>();
foreach (var initializer in expression.Initializers)
{
initializers.Add(initializer.Key, CheckExpression(initializer.Value));
}
var missingFields = structType.Fields
.Where(x => !x.HasDefaultValue && !initializers.ContainsKey(x.Name))
.Select(x => x.Name)
.ToArray();
if (missingFields.Length != 0)
{
throw new TypeCheckerException(Diagnostic
.Error($"Fields {string.Join(", ", missingFields)} are not initialized")
.At(expression)
.Build());
}
return new StructInitializerNode(structType, initializers);
}
private UnaryExpressionNode CheckUnaryExpression(UnaryExpressionSyntax expression)
@@ -453,7 +523,7 @@ public sealed class TypeChecker
{
if (!_importedModules.TryGetValue(customType.Module, out var module))
{
throw new Exception("Module not found: " + customType.Module);
throw new TypeCheckerException(Diagnostic.Error($"Module {customType.Module} not found").WithHelp($"import \"{customType.Module}\"").At(customType).Build());
}
if (customType.Module == _syntaxTree.Metadata.ModuleName)