More type support, allow inheriting types to be assigned to a function

This commit is contained in:
Deukhoofd 2019-01-23 18:15:57 +01:00
parent c7bb42711a
commit d641ab936f
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
4 changed files with 54 additions and 17 deletions

View File

@ -113,18 +113,29 @@ namespace Upsilon.BaseTypes
public static TypeContainer GetScriptType(this System.Type t) public static TypeContainer GetScriptType(this System.Type t)
{ {
if (t == typeof(bool)) var typeCode = System.Type.GetTypeCode(t);
switch (typeCode)
{
case TypeCode.Boolean:
return Type.Boolean; return Type.Boolean;
if (t == typeof(string)) case TypeCode.Char:
case TypeCode.String:
return Type.String; return Type.String;
if (t == typeof(int)) case TypeCode.Byte:
return Type.Number; case TypeCode.Decimal:
if (t == typeof(long)) case TypeCode.Double:
return Type.Number; case TypeCode.Int16:
if (t == typeof(float)) case TypeCode.Int32:
return Type.Number; case TypeCode.Int64:
if (t == typeof(double)) case TypeCode.SByte:
case TypeCode.Single:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
return Type.Number; return Type.Number;
case TypeCode.Empty:
return Type.Nil;
}
if (t == typeof(void)) if (t == typeof(void))
return Type.Nil; return Type.Nil;

View File

@ -17,6 +17,6 @@ namespace Upsilon.BoundTypes
} }
public TypeContainer ScriptType { get; } public TypeContainer ScriptType { get; }
public System.Type[] ValidInternalTypes { get; } public System.Type[] ValidInternalTypes { get; protected set; }
} }
} }

View File

@ -12,7 +12,7 @@ namespace Upsilon.BoundTypes
{ {
dic.TryAdd("string", new BoundTypeDefinition(Type.String, typeof(string))); dic.TryAdd("string", new BoundTypeDefinition(Type.String, typeof(string)));
dic.TryAdd("number", new BoundTypeDefinition(Type.Number, dic.TryAdd("number", new BoundTypeDefinition(Type.Number,
new[] {typeof(int), typeof(long), typeof(float), typeof(double)})); new[] {typeof(int), typeof(long), typeof(float), typeof(double), typeof(byte)}));
dic.TryAdd("bool", new BoundTypeDefinition(Type.Boolean, typeof(bool))); dic.TryAdd("bool", new BoundTypeDefinition(Type.Boolean, typeof(bool)));
dic.TryAdd("table", new BoundTypeDefinition(Type.Table, typeof(IEnumerator))); dic.TryAdd("table", new BoundTypeDefinition(Type.Table, typeof(IEnumerator)));
dic.TryAdd("function", new BoundTypeDefinition(Type.Function, new System.Type[0])); dic.TryAdd("function", new BoundTypeDefinition(Type.Function, new System.Type[0]));

View File

@ -20,6 +20,30 @@ namespace Upsilon.BoundTypes
: base(new TypeContainer(name), backingType) : base(new TypeContainer(name), backingType)
{ {
Name = backingType.Name; Name = backingType.Name;
ValidInternalTypes = ValidInternalTypes.Concat(GetParentTypes(backingType)).ToArray();
}
private static IEnumerable<System.Type> GetParentTypes(System.Type type)
{
// is there any base type?
if (type == null)
{
yield break;
}
// return all implemented or inherited interfaces
foreach (var i in type.GetInterfaces())
{
yield return i;
}
// return all inherited types
var currentBaseType = type.BaseType;
while (currentBaseType != null)
{
yield return currentBaseType;
currentBaseType = currentBaseType.BaseType;
}
} }
public UserDataBoundTypeDefinition(string name, Dictionary<string, UserDataBoundProperty> backingType) public UserDataBoundTypeDefinition(string name, Dictionary<string, UserDataBoundProperty> backingType)
@ -196,14 +220,16 @@ namespace Upsilon.BoundTypes
{ {
ResultType = resultType; ResultType = resultType;
Parameters = parameters; Parameters = parameters;
NonOptionalParameterCount = Parameters.Count(x => !x.IsOptional);
} }
public TypeContainer ResultType { get; set; } public TypeContainer ResultType { get; }
public UserDataBoundFunctionParameter[] Parameters { get; set; } public UserDataBoundFunctionParameter[] Parameters { get; }
private int NonOptionalParameterCount { get; }
public bool ValidateParameters(ImmutableArray<BoundExpression> callingParameters) public bool ValidateParameters(ImmutableArray<BoundExpression> callingParameters)
{ {
if (callingParameters.Length < Parameters.Count(x => !x.IsOptional) if (callingParameters.Length < NonOptionalParameterCount
|| callingParameters.Length > Parameters.Length) || callingParameters.Length > Parameters.Length)
{ {
return false; return false;