This commit is contained in:
nub31
2025-05-26 20:16:23 +02:00
parent f63cee1011
commit 1105661603
6 changed files with 51 additions and 101 deletions

View File

@@ -363,12 +363,7 @@ public class Generator
private string GenerateFuncCall(FuncCall funcCall)
{
var parameterDefinitions = _definitions
.OfType<LocalFuncDefinitionNode>()
.FirstOrDefault(d => d.Name == funcCall.Name)
?.Parameters;
parameterDefinitions ??= _definitions
.OfType<ExternFuncDefinitionNode>()
.OfType<IFuncSignature>()
.FirstOrDefault(d => d.Name == funcCall.Name)
?.Parameters;

View File

@@ -1,12 +0,0 @@
using Nub.Lang.Frontend.Lexing;
namespace Nub.Lang.Frontend.Parsing;
public class ExternFuncDefinitionNode(IReadOnlyList<Token> tokens, Optional<string> documentation, string name, List<FuncParameter> parameters, Optional<NubType> returnType) : DefinitionNode(tokens, documentation)
{
public string Name { get; } = name;
public List<FuncParameter> Parameters { get; } = parameters;
public Optional<NubType> ReturnType { get; } = returnType;
public override string ToString() => $"{Name}({string.Join(", ", Parameters.Select(p => p.ToString()))}){(ReturnType.HasValue ? ": " + ReturnType.Value : "")}";
}

View File

@@ -0,0 +1,32 @@
using Nub.Lang.Frontend.Lexing;
namespace Nub.Lang.Frontend.Parsing;
public interface IFuncSignature
{
public string Name { get; }
public List<FuncParameter> Parameters { get; }
public Optional<NubType> ReturnType { get; }
public string ToString() => $"{Name}({string.Join(", ", Parameters.Select(p => p.ToString()))}){(ReturnType.HasValue ? ": " + ReturnType.Value : "")}";
}
public class LocalFuncDefinitionNode(IReadOnlyList<Token> tokens, Optional<string> documentation, string name, List<FuncParameter> parameters, BlockNode body, Optional<NubType> returnType, bool global) : DefinitionNode(tokens, documentation)
{
public string Name { get; } = name;
public List<FuncParameter> Parameters { get; } = parameters;
public BlockNode Body { get; } = body;
public Optional<NubType> ReturnType { get; } = returnType;
public bool Global { get; } = global;
public override string ToString() => $"{Name}({string.Join(", ", Parameters.Select(p => p.ToString()))}){(ReturnType.HasValue ? ": " + ReturnType.Value : "")}";
}
public class ExternFuncDefinitionNode(IReadOnlyList<Token> tokens, Optional<string> documentation, string name, List<FuncParameter> parameters, Optional<NubType> returnType) : DefinitionNode(tokens, documentation), IFuncSignature
{
public string Name { get; } = name;
public List<FuncParameter> Parameters { get; } = parameters;
public Optional<NubType> ReturnType { get; } = returnType;
public override string ToString() => $"{Name}({string.Join(", ", Parameters.Select(p => p.ToString()))}){(ReturnType.HasValue ? ": " + ReturnType.Value : "")}";
}

View File

@@ -1,14 +0,0 @@
using Nub.Lang.Frontend.Lexing;
namespace Nub.Lang.Frontend.Parsing;
public class LocalFuncDefinitionNode(IReadOnlyList<Token> tokens, Optional<string> documentation, string name, List<FuncParameter> parameters, BlockNode body, Optional<NubType> returnType, bool global) : DefinitionNode(tokens, documentation)
{
public string Name { get; } = name;
public List<FuncParameter> Parameters { get; } = parameters;
public BlockNode Body { get; } = body;
public Optional<NubType> ReturnType { get; } = returnType;
public bool Global { get; } = global;
public override string ToString() => $"{Name}({string.Join(", ", Parameters.Select(p => p.ToString()))}){(ReturnType.HasValue ? ": " + ReturnType.Value : "")}";
}

View File

@@ -176,28 +176,14 @@ public class TypeChecker
parameterTypes.Add(parameterType);
}
var localFuncDef = LookupLocalFuncDefinition(funcCall.Namespace, funcCall.Name, parameterTypes);
var externFuncDef = LookupExternFuncDefinition(funcCall.Namespace, funcCall.Name, parameterTypes);
List<FuncParameter> parameters;
Optional<NubType> returnType;
if (localFuncDef != null)
{
parameters = localFuncDef.Parameters;
returnType = localFuncDef.ReturnType;
}
else if (externFuncDef != null)
{
parameters = externFuncDef.Parameters;
returnType = externFuncDef.ReturnType;
}
else
var funcDefinition = LookupFuncSignature(funcCall.Namespace, funcCall.Name, parameterTypes);
if (funcDefinition == null)
{
ReportError($"Function '{funcCall.Name}' is not defined", node);
return null;
}
if (parameters.Take(parameters.Count - 1).Any(x => x.Variadic))
if (funcDefinition.Parameters.Take(funcDefinition.Parameters.Count - 1).Any(x => x.Variadic))
{
ReportError($"Function '{funcCall.Name}' has multiple variadic parameters", node);
return null;
@@ -208,13 +194,13 @@ public class TypeChecker
var argType = funcCall.Parameters[i].Type;
NubType paramType;
if (i < parameters.Count)
if (i < funcDefinition.Parameters.Count)
{
paramType = parameters[i].Type;
paramType = funcDefinition.Parameters[i].Type;
}
else if (parameters.LastOrDefault()?.Variadic ?? false)
else if (funcDefinition.Parameters.LastOrDefault()?.Variadic ?? false)
{
paramType = parameters[^1].Type;
paramType = funcDefinition.Parameters[^1].Type;
}
else
{
@@ -228,7 +214,7 @@ public class TypeChecker
}
}
return returnType.HasValue ? returnType.Value : NubPrimitiveType.Any;
return funcDefinition.ReturnType.HasValue ? funcDefinition.ReturnType.Value : NubPrimitiveType.Any;
}
private void TypeCheckIf(IfNode ifNode)
@@ -606,56 +592,15 @@ public class TypeChecker
}
}
private TDefinition? LookupDefinition<TDefinition>(string @namespace, Func<TDefinition, bool> predicate) where TDefinition : DefinitionNode
private IFuncSignature? LookupFuncSignature(string @namespace, string name, List<NubType> parameters)
{
return _sourceFiles
.Where(f => f.Namespace == @namespace)
.SelectMany(f => f.Definitions)
.OfType<TDefinition>()
.FirstOrDefault(predicate);
}
.OfType<IFuncSignature>()
.FirstOrDefault(SignatureMatches);
private ExternFuncDefinitionNode? LookupExternFuncDefinition(string @namespace, string name, List<NubType> parameters)
{
return LookupDefinition<ExternFuncDefinitionNode>(@namespace, SignatureMatches);
bool SignatureMatches(ExternFuncDefinitionNode node)
{
if (node.Name != name) return false;
if (node.Parameters.Count == 0 && parameters.Count == 0) return true;
if (node.Parameters.Count > parameters.Count) return false;
for (var i = 0; i < parameters.Count; i++)
{
if (i > node.Parameters.Count)
{
if (node.Parameters[^1].Variadic)
{
if (!AreTypesCompatible(parameters[i], node.Parameters[^1].Type))
{
return false;
}
}
else
{
return false;
}
}
else if (!AreTypesCompatible(parameters[i], node.Parameters[i].Type))
{
return false;
}
}
return true;
}
}
private LocalFuncDefinitionNode? LookupLocalFuncDefinition(string @namespace, string name, List<NubType> parameters)
{
return LookupDefinition<LocalFuncDefinitionNode>(@namespace, SignatureMatches);
bool SignatureMatches(LocalFuncDefinitionNode node)
bool SignatureMatches(IFuncSignature node)
{
if (node.Name != name) return false;
if (node.Parameters.Count == 0 && parameters.Count == 0) return true;
@@ -689,6 +634,10 @@ public class TypeChecker
private StructDefinitionNode? LookupStructDefinition(string @namespace, string name)
{
return LookupDefinition<StructDefinitionNode>(@namespace, d => d.Name == name);
return _sourceFiles
.Where(f => f.Namespace == @namespace)
.SelectMany(f => f.Definitions)
.OfType<StructDefinitionNode>()
.FirstOrDefault(d => d.Name == name);
}
}