Upsilon/Upsilon/Binder/VariableSymbols/ScriptFunctionVariableSymbo...

81 lines
3.1 KiB
C#

using System.Collections.Immutable;
using System.Linq;
using Upsilon.BaseTypes;
using Upsilon.BoundTypes;
namespace Upsilon.Binder.VariableSymbols
{
public class ScriptFunctionVariableSymbol : FunctionVariableSymbol
{
public ScriptFunctionVariableSymbol(string name, bool local, ImmutableArray<VariableSymbol> parameters, Type resultType)
: base(name, local, resultType)
{
FunctionOption.Add(new ScriptFunctionVariableOption(resultType, parameters));
}
public override bool ValidateParameters(ImmutableArray<BoundExpression> callingParameters)
{
foreach (var functionVariableSymbolOption in FunctionOption)
{
if (!(functionVariableSymbolOption is ScriptFunctionVariableOption option))
continue;
if (option.Parameters.Length != callingParameters.Length)
continue;
bool isValid = true;
for (var i = 0; i < option.Parameters.Length; i++)
{
var functionParameter = option.Parameters[i];
var callingParameter = callingParameters[i];
if (functionParameter.TypeContainer == Type.Unknown ||
callingParameter.ValueType == Type.Unknown ||
callingParameter.ValueType == Type.Nil)
continue;
if (!functionParameter.TypeContainer.Type.HasFlag(callingParameter.ValueType))
{
isValid = false;
break;
}
if (functionParameter.TypeContainer.Type.HasFlag(Type.UserData))
{
var variable = Binder.ResolveVariable(callingParameter, null);
if (variable != null && variable.TypeContainer == Type.UserData)
{
var userData = functionParameter.TypeContainer.UserData;
if (string.IsNullOrEmpty(userData))
continue;
if (!string.Equals(userData,
callingParameter.ValueType.UserData))
{
isValid = false;
break;
}
}
}
}
if (!isValid)
continue;
return true;
}
return false;
}
}
public class ScriptFunctionVariableOption : FunctionVariableSymbolOption
{
public ImmutableArray<VariableSymbol> Parameters { get; }
public bool IsBound { get; set; }
public ScriptFunctionVariableOption(Type resultType, ImmutableArray<VariableSymbol> parameters) : base(resultType)
{
Parameters = parameters;
}
public override TypeContainer[] GetParameterTypes()
{
return Parameters.Select(x => x.TypeContainer).ToArray();
}
}
}