From dcf62e3e05b3314a8314b11a3877b928c602f4f5 Mon Sep 17 00:00:00 2001 From: nub31 Date: Mon, 26 May 2025 20:16:23 +0200 Subject: [PATCH] ... --- src/compiler/Nub.Lang/Backend/Generator.cs | 7 +- .../Frontend/Parsing/DefinitionNode.cs | 2 +- .../Parsing/ExternFuncDefinitionNode.cs | 12 --- .../Frontend/Parsing/FuncDefinitionNode.cs | 32 +++++++ .../Parsing/LocalFuncDefinitionNode.cs | 14 --- .../Nub.Lang/Frontend/Typing/TypeChecker.cs | 85 ++++--------------- 6 files changed, 51 insertions(+), 101 deletions(-) delete mode 100644 src/compiler/Nub.Lang/Frontend/Parsing/ExternFuncDefinitionNode.cs create mode 100644 src/compiler/Nub.Lang/Frontend/Parsing/FuncDefinitionNode.cs delete mode 100644 src/compiler/Nub.Lang/Frontend/Parsing/LocalFuncDefinitionNode.cs diff --git a/src/compiler/Nub.Lang/Backend/Generator.cs b/src/compiler/Nub.Lang/Backend/Generator.cs index b4314eb..05b6430 100644 --- a/src/compiler/Nub.Lang/Backend/Generator.cs +++ b/src/compiler/Nub.Lang/Backend/Generator.cs @@ -363,12 +363,7 @@ public class Generator private string GenerateFuncCall(FuncCall funcCall) { var parameterDefinitions = _definitions - .OfType() - .FirstOrDefault(d => d.Name == funcCall.Name) - ?.Parameters; - - parameterDefinitions ??= _definitions - .OfType() + .OfType() .FirstOrDefault(d => d.Name == funcCall.Name) ?.Parameters; diff --git a/src/compiler/Nub.Lang/Frontend/Parsing/DefinitionNode.cs b/src/compiler/Nub.Lang/Frontend/Parsing/DefinitionNode.cs index f60c5e2..899352e 100644 --- a/src/compiler/Nub.Lang/Frontend/Parsing/DefinitionNode.cs +++ b/src/compiler/Nub.Lang/Frontend/Parsing/DefinitionNode.cs @@ -5,4 +5,4 @@ namespace Nub.Lang.Frontend.Parsing; public abstract class DefinitionNode(IReadOnlyList tokens, Optional documentation) : Node(tokens) { public Optional Documentation { get; set; } = documentation; -} \ No newline at end of file +} diff --git a/src/compiler/Nub.Lang/Frontend/Parsing/ExternFuncDefinitionNode.cs b/src/compiler/Nub.Lang/Frontend/Parsing/ExternFuncDefinitionNode.cs deleted file mode 100644 index e5df5b6..0000000 --- a/src/compiler/Nub.Lang/Frontend/Parsing/ExternFuncDefinitionNode.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Nub.Lang.Frontend.Lexing; - -namespace Nub.Lang.Frontend.Parsing; - -public class ExternFuncDefinitionNode(IReadOnlyList tokens, Optional documentation, string name, List parameters, Optional returnType) : DefinitionNode(tokens, documentation) -{ - public string Name { get; } = name; - public List Parameters { get; } = parameters; - public Optional ReturnType { get; } = returnType; - - public override string ToString() => $"{Name}({string.Join(", ", Parameters.Select(p => p.ToString()))}){(ReturnType.HasValue ? ": " + ReturnType.Value : "")}"; -} \ No newline at end of file diff --git a/src/compiler/Nub.Lang/Frontend/Parsing/FuncDefinitionNode.cs b/src/compiler/Nub.Lang/Frontend/Parsing/FuncDefinitionNode.cs new file mode 100644 index 0000000..bcfbc56 --- /dev/null +++ b/src/compiler/Nub.Lang/Frontend/Parsing/FuncDefinitionNode.cs @@ -0,0 +1,32 @@ +using Nub.Lang.Frontend.Lexing; + +namespace Nub.Lang.Frontend.Parsing; + +public interface IFuncSignature +{ + public string Name { get; } + public List Parameters { get; } + public Optional ReturnType { get; } + + public string ToString() => $"{Name}({string.Join(", ", Parameters.Select(p => p.ToString()))}){(ReturnType.HasValue ? ": " + ReturnType.Value : "")}"; +} + +public class LocalFuncDefinitionNode(IReadOnlyList tokens, Optional documentation, string name, List parameters, BlockNode body, Optional returnType, bool global) : DefinitionNode(tokens, documentation) +{ + public string Name { get; } = name; + public List Parameters { get; } = parameters; + public BlockNode Body { get; } = body; + public Optional 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 tokens, Optional documentation, string name, List parameters, Optional returnType) : DefinitionNode(tokens, documentation), IFuncSignature +{ + public string Name { get; } = name; + public List Parameters { get; } = parameters; + public Optional ReturnType { get; } = returnType; + + public override string ToString() => $"{Name}({string.Join(", ", Parameters.Select(p => p.ToString()))}){(ReturnType.HasValue ? ": " + ReturnType.Value : "")}"; +} \ No newline at end of file diff --git a/src/compiler/Nub.Lang/Frontend/Parsing/LocalFuncDefinitionNode.cs b/src/compiler/Nub.Lang/Frontend/Parsing/LocalFuncDefinitionNode.cs deleted file mode 100644 index da0059a..0000000 --- a/src/compiler/Nub.Lang/Frontend/Parsing/LocalFuncDefinitionNode.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Nub.Lang.Frontend.Lexing; - -namespace Nub.Lang.Frontend.Parsing; - -public class LocalFuncDefinitionNode(IReadOnlyList tokens, Optional documentation, string name, List parameters, BlockNode body, Optional returnType, bool global) : DefinitionNode(tokens, documentation) -{ - public string Name { get; } = name; - public List Parameters { get; } = parameters; - public BlockNode Body { get; } = body; - public Optional ReturnType { get; } = returnType; - public bool Global { get; } = global; - - public override string ToString() => $"{Name}({string.Join(", ", Parameters.Select(p => p.ToString()))}){(ReturnType.HasValue ? ": " + ReturnType.Value : "")}"; -} \ No newline at end of file diff --git a/src/compiler/Nub.Lang/Frontend/Typing/TypeChecker.cs b/src/compiler/Nub.Lang/Frontend/Typing/TypeChecker.cs index 96dcf27..4fb75af 100644 --- a/src/compiler/Nub.Lang/Frontend/Typing/TypeChecker.cs +++ b/src/compiler/Nub.Lang/Frontend/Typing/TypeChecker.cs @@ -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 parameters; - Optional 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(string @namespace, Func predicate) where TDefinition : DefinitionNode + private IFuncSignature? LookupFuncSignature(string @namespace, string name, List parameters) { return _sourceFiles .Where(f => f.Namespace == @namespace) .SelectMany(f => f.Definitions) - .OfType() - .FirstOrDefault(predicate); - } + .OfType() + .FirstOrDefault(SignatureMatches); - private ExternFuncDefinitionNode? LookupExternFuncDefinition(string @namespace, string name, List parameters) - { - return LookupDefinition(@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 parameters) - { - return LookupDefinition(@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(@namespace, d => d.Name == name); + return _sourceFiles + .Where(f => f.Namespace == @namespace) + .SelectMany(f => f.Definitions) + .OfType() + .FirstOrDefault(d => d.Name == name); } } \ No newline at end of file