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) private string GenerateFuncCall(FuncCall funcCall)
{ {
var parameterDefinitions = _definitions var parameterDefinitions = _definitions
.OfType<LocalFuncDefinitionNode>() .OfType<IFuncSignature>()
.FirstOrDefault(d => d.Name == funcCall.Name)
?.Parameters;
parameterDefinitions ??= _definitions
.OfType<ExternFuncDefinitionNode>()
.FirstOrDefault(d => d.Name == funcCall.Name) .FirstOrDefault(d => d.Name == funcCall.Name)
?.Parameters; ?.Parameters;

View File

@@ -5,4 +5,4 @@ namespace Nub.Lang.Frontend.Parsing;
public abstract class DefinitionNode(IReadOnlyList<Token> tokens, Optional<string> documentation) : Node(tokens) public abstract class DefinitionNode(IReadOnlyList<Token> tokens, Optional<string> documentation) : Node(tokens)
{ {
public Optional<string> Documentation { get; set; } = documentation; public Optional<string> Documentation { get; set; } = documentation;
} }

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); parameterTypes.Add(parameterType);
} }
var localFuncDef = LookupLocalFuncDefinition(funcCall.Namespace, funcCall.Name, parameterTypes); var funcDefinition = LookupFuncSignature(funcCall.Namespace, funcCall.Name, parameterTypes);
var externFuncDef = LookupExternFuncDefinition(funcCall.Namespace, funcCall.Name, parameterTypes); if (funcDefinition == null)
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
{ {
ReportError($"Function '{funcCall.Name}' is not defined", node); ReportError($"Function '{funcCall.Name}' is not defined", node);
return null; 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); ReportError($"Function '{funcCall.Name}' has multiple variadic parameters", node);
return null; return null;
@@ -208,13 +194,13 @@ public class TypeChecker
var argType = funcCall.Parameters[i].Type; var argType = funcCall.Parameters[i].Type;
NubType paramType; 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 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) 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 return _sourceFiles
.Where(f => f.Namespace == @namespace) .Where(f => f.Namespace == @namespace)
.SelectMany(f => f.Definitions) .SelectMany(f => f.Definitions)
.OfType<TDefinition>() .OfType<IFuncSignature>()
.FirstOrDefault(predicate); .FirstOrDefault(SignatureMatches);
}
private ExternFuncDefinitionNode? LookupExternFuncDefinition(string @namespace, string name, List<NubType> parameters) bool SignatureMatches(IFuncSignature node)
{
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)
{ {
if (node.Name != name) return false; if (node.Name != name) return false;
if (node.Parameters.Count == 0 && parameters.Count == 0) return true; if (node.Parameters.Count == 0 && parameters.Count == 0) return true;
@@ -689,6 +634,10 @@ public class TypeChecker
private StructDefinitionNode? LookupStructDefinition(string @namespace, string name) 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);
} }
} }