From faaca912652e4597634944e093763af956f0eb1a Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Wed, 23 Jan 2019 13:15:19 +0100 Subject: [PATCH] More fixes for function binding --- Upsilon/BaseTypes/TypeContainer.cs | 3 +- Upsilon/BaseTypes/UserData/GenericUserData.cs | 8 +++-- Upsilon/Binder/Binder.cs | 13 +++----- .../VariableSymbols/FunctionVariableSymbol.cs | 2 +- .../InternalFunctionVariableSymbol.cs | 9 ++--- .../ScriptFunctionVariableSymbol.cs | 33 ++++++++++++++----- 6 files changed, 40 insertions(+), 28 deletions(-) diff --git a/Upsilon/BaseTypes/TypeContainer.cs b/Upsilon/BaseTypes/TypeContainer.cs index f1771ec..5e50939 100644 --- a/Upsilon/BaseTypes/TypeContainer.cs +++ b/Upsilon/BaseTypes/TypeContainer.cs @@ -88,6 +88,7 @@ namespace Upsilon.BaseTypes } } + /* internal class IgnoredUserDataTypeContainer : TypeContainer { public IgnoredUserDataTypeContainer() : base(BaseTypes.Type.Unknown) @@ -98,7 +99,7 @@ namespace Upsilon.BaseTypes public IgnoredUserDataTypeContainer(string userData) : base(userData) { } - } + }*/ public class UndefinedUserDataTypeContainer : TypeContainer { diff --git a/Upsilon/BaseTypes/UserData/GenericUserData.cs b/Upsilon/BaseTypes/UserData/GenericUserData.cs index d39bfbc..aa4a880 100644 --- a/Upsilon/BaseTypes/UserData/GenericUserData.cs +++ b/Upsilon/BaseTypes/UserData/GenericUserData.cs @@ -1,3 +1,4 @@ +using Upsilon.BoundTypes; using Upsilon.Evaluator; using Upsilon.Text; @@ -8,9 +9,12 @@ namespace Upsilon.BaseTypes.UserData public GenericUserData(object obj) { Value = obj; - _typeInfo = UserDataTypeHandler.GetTypeInfo(obj.GetType()); + var type = obj.GetType(); + _typeInfo = UserDataTypeHandler.GetTypeInfo(type); + Type = new TypeContainer(_typeInfo.BoundTypeName); + } - public override TypeContainer Type { get; } = new IgnoredUserDataTypeContainer(); + public override TypeContainer Type { get; } private object Value { get; } private readonly UserDataType _typeInfo; diff --git a/Upsilon/Binder/Binder.cs b/Upsilon/Binder/Binder.cs index 99a12c7..698d7b3 100644 --- a/Upsilon/Binder/Binder.cs +++ b/Upsilon/Binder/Binder.cs @@ -304,19 +304,14 @@ namespace Upsilon.Binder { returnType = internalFunction.GetResultType(parameters.ToArray()); } - else - { - //returnType = function.ResultType; - } } - var (isValid, error, wrongParameter) = function.ValidateParameters(parameters.ToImmutable()); + var isValid = function.ValidateParameters(parameters.ToImmutable()); if (!isValid) { - var span = e.Span; - if (wrongParameter != null) - span = wrongParameter.Span; - _diagnostics.LogError(error, span); + _diagnostics.LogError( + $"No valid function with name '{function.Name}' and parameter types {string.Join(", ", parameters.Select(x => $"'{x.Type}'"))} found", + expression.Span); } } else if (resolved is UserDataVariableSymbol udSymbol) diff --git a/Upsilon/Binder/VariableSymbols/FunctionVariableSymbol.cs b/Upsilon/Binder/VariableSymbols/FunctionVariableSymbol.cs index 69dff50..3d81545 100644 --- a/Upsilon/Binder/VariableSymbols/FunctionVariableSymbol.cs +++ b/Upsilon/Binder/VariableSymbols/FunctionVariableSymbol.cs @@ -14,7 +14,7 @@ namespace Upsilon.Binder.VariableSymbols { } - public abstract (bool IsValid, string Error, BoundExpression WrongParameter) ValidateParameters( + public abstract bool ValidateParameters( ImmutableArray callingParameters); public FunctionVariableSymbolOption GetFirstValid(TypeContainer[] types) diff --git a/Upsilon/Binder/VariableSymbols/InternalFunctionVariableSymbol.cs b/Upsilon/Binder/VariableSymbols/InternalFunctionVariableSymbol.cs index e92d467..943440c 100644 --- a/Upsilon/Binder/VariableSymbols/InternalFunctionVariableSymbol.cs +++ b/Upsilon/Binder/VariableSymbols/InternalFunctionVariableSymbol.cs @@ -23,8 +23,7 @@ namespace Upsilon.Binder.VariableSymbols FunctionOption = options; } - public override (bool IsValid, string Error, - BoundExpression WrongParameter) ValidateParameters(ImmutableArray callingParameters) + public override bool ValidateParameters(ImmutableArray callingParameters) { foreach (var functionVariableSymbolOption in FunctionOption) { @@ -67,12 +66,10 @@ namespace Upsilon.Binder.VariableSymbols } if (!isValid) continue; - return (true, null, null); + return true; } - return (false, - $"No valid function with name '{Name}' and variables of type {string.Join(", ", callingParameters.Select(x => $"'{x.Type}'"))} found", - null); + return false; } public TypeContainer GetResultType(BoundExpression[] parameters) diff --git a/Upsilon/Binder/VariableSymbols/ScriptFunctionVariableSymbol.cs b/Upsilon/Binder/VariableSymbols/ScriptFunctionVariableSymbol.cs index c00a846..ea80bb9 100644 --- a/Upsilon/Binder/VariableSymbols/ScriptFunctionVariableSymbol.cs +++ b/Upsilon/Binder/VariableSymbols/ScriptFunctionVariableSymbol.cs @@ -1,6 +1,7 @@ using System.Collections.Immutable; using System.Linq; using Upsilon.BaseTypes; +using Upsilon.BoundTypes; namespace Upsilon.Binder.VariableSymbols { @@ -12,7 +13,7 @@ namespace Upsilon.Binder.VariableSymbols FunctionOption.Add(new ScriptFunctionVariableOption(resultType, parameters)); } - public override (bool IsValid, string Error, BoundExpression WrongParameter) ValidateParameters(ImmutableArray callingParameters) + public override bool ValidateParameters(ImmutableArray callingParameters) { foreach (var functionVariableSymbolOption in FunctionOption) { @@ -25,23 +26,37 @@ namespace Upsilon.Binder.VariableSymbols { var functionParameter = option.Parameters[i]; var callingParameter = callingParameters[i]; - if (functionParameter.TypeContainer != BaseTypes.Type.Unknown && - callingParameter.Type != BaseTypes.Type.Unknown && - callingParameter.Type != BaseTypes.Type.Nil) + if (functionParameter.TypeContainer == Type.Unknown || + callingParameter.Type == Type.Unknown || + callingParameter.Type == Type.Nil) + continue; + + if (!functionParameter.TypeContainer.Type.HasFlag(callingParameter.Type)) { - if (callingParameter.Type != functionParameter.TypeContainer) + isValid = false; + break; + } + + if (functionParameter.TypeContainer.Type.HasFlag(Type.UserData)) + { + var variable = Binder.ResolveVariable(callingParameter, null); + if (variable != null && variable.TypeContainer == Type.UserData) { - isValid = false; - break; + if (!string.Equals(functionParameter.TypeContainer.UserData, + callingParameter.Type.UserData)) + { + isValid = false; + break; + } } } } if (!isValid) continue; - return (true, null, null); + return true; } - return (false, null, null); + return false; } }