Handling for type checking parameters of internal functions

This commit is contained in:
Deukhoofd 2018-11-30 16:19:25 +01:00
parent f08d1c2541
commit 00178cfa82
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
4 changed files with 30 additions and 19 deletions

View File

@ -24,9 +24,9 @@ namespace Upsilon.BaseTypes.ScriptFunction
private readonly bool _passScriptReference;
public System.Type ReturnType { get; }
public IEnumerable<System.Type> GetParameterTypes()
public IEnumerable<UserDataMethod.UserDataMethodParameter> GetParameterInfo()
{
return _method.GetMethods().First().Parameters.Select(x => x.Type);
return _method.GetMethods().First().Parameters;
}
public override ScriptType Run(Diagnostics diagnostics, ScriptType[] variables, Script script)

View File

@ -5,8 +5,8 @@ namespace Upsilon.BaseTypes
[Flags]
public enum Type : byte
{
Unknown = 0,
Nil = 1,
Nil = 0,
Unknown = 1,
Boolean = 2,
Number = 4,
String = 8,

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Immutable;
using System.Linq;
using Type = Upsilon.BaseTypes.Type;
namespace Upsilon.Binder.VariableSymbols
@ -8,44 +9,50 @@ namespace Upsilon.Binder.VariableSymbols
{
public class InternalFunctionParameter
{
public InternalFunctionParameter(Type t)
public InternalFunctionParameter(Type type, bool isOptional)
{
ValidTypes = t;
ValidTypes = type;
IsOptional = isOptional;
}
public Type ValidTypes { get; set; }
public Type ValidTypes { get; }
public bool IsOptional { get; }
}
public InternalFunctionParameter[] FunctionParameters { get; }
private InternalFunctionParameter[] FunctionParameters { get; }
private int MinimalParametersRequired { get; }
public InternalFunctionVariableSymbol(string name, bool local, Type resultType, InternalFunctionParameter[] functionParameters)
: base(name, local, resultType)
{
FunctionParameters = functionParameters;
MinimalParametersRequired = functionParameters.Count(x => !x.IsOptional);
}
public override (bool IsValid, string Error,
BoundExpression WrongParameter) ValidateParameters(ImmutableArray<BoundExpression> callingParameters)
{
if (FunctionParameters.Length != callingParameters.Length)
if (FunctionParameters.Length < MinimalParametersRequired
|| callingParameters.Length > FunctionParameters.Length)
{
return (false,
$"Invalid number of parameters for function '{Name}'. Expected {FunctionParameters.Length}, got {callingParameters.Length}",
null);
}
for (var i = 0; i < FunctionParameters.Length; i++)
for (var i = 0; i < callingParameters.Length; i++)
{
var functionParameter = FunctionParameters[i];
var callingParameter = callingParameters[i];
if (callingParameter.Type != Type.Unknown && callingParameter.Type != Type.Nil)
if (callingParameter.Type == Type.Unknown || callingParameter.Type == Type.Nil)
continue;
if (!functionParameter.ValidTypes.HasFlag(callingParameter.Type))
{
if ((functionParameter.ValidTypes ^ callingParameter.Type) != 0)
{
return (false,
$"Unexpected variable passed to internal function '{functionParameter}'.",
callingParameter);
}
return (false,
$"Unexpected variable passed to internal function '{functionParameter}'." +
$"Expected one of the following: {functionParameter.ValidTypes.ToString()}, got: '{callingParameter.Type}'",
callingParameter);
}
}

View File

@ -54,8 +54,12 @@ namespace Upsilon.StandardLibraries
funcs.Add(func.Key, func.Value.MethodInfoFunction);
var functionSymbol = new InternalFunctionVariableSymbol(func.Key, true,
func.Value.MethodInfoFunction.ReturnType.GetScriptType(),
func.Value.MethodInfoFunction.GetParameterTypes().Select(x =>
new InternalFunctionVariableSymbol.InternalFunctionParameter(DeriveValidTypes(x))).ToArray())
func.Value.MethodInfoFunction.GetParameterInfo().Select(typeInfo =>
{
var derivedType = DeriveValidTypes(typeInfo.Type);
return new InternalFunctionVariableSymbol.InternalFunctionParameter(derivedType,
typeInfo.IsOptional);
}).ToArray())
{
CommentValue = func.Value.CommentValue?.Split('\n')
};