From 96b0959bd656d6f674d5b1a4689c05acd9087ad6 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Sat, 19 Jan 2019 16:38:33 +0100 Subject: [PATCH] Reworked type handling to handle userdata more easily --- Upsilon/BaseTypes/TypeContainer.cs | 15 +++++++++- Upsilon/BaseTypes/TypeConversion.cs | 5 ++-- Upsilon/Binder/Binder.cs | 11 +++++++- .../BoundExpressions/BoundIndexExpression.cs | 2 +- .../BoundExpressions/BoundTableExpression.cs | 2 +- Upsilon/BoundTypes/BoundTypeDefinition.cs | 6 ++-- Upsilon/BoundTypes/BoundTypeHandler.cs | 5 ++++ .../BoundTypes/UserDataBoundTypeDefinition.cs | 28 +++++++++---------- 8 files changed, 51 insertions(+), 23 deletions(-) diff --git a/Upsilon/BaseTypes/TypeContainer.cs b/Upsilon/BaseTypes/TypeContainer.cs index d537bc7..88c4288 100644 --- a/Upsilon/BaseTypes/TypeContainer.cs +++ b/Upsilon/BaseTypes/TypeContainer.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Immutable; namespace Upsilon.BaseTypes @@ -5,12 +6,24 @@ namespace Upsilon.BaseTypes public class TypeContainer { public Type Type { get; } + public string UserData { get; } protected TypeContainer(Type t) { + if (t == Type.UserData) + { + throw new Exception( + "Instantiating a userdata type without specifying type. Use constructor with string instead."); + } Type = t; } + public TypeContainer(string userData) + { + Type = Type.UserData; + UserData = userData; + } + public static implicit operator TypeContainer (Type type) { return new TypeContainer(type); @@ -61,7 +74,7 @@ namespace Upsilon.BaseTypes public class CompositeTypeContainer : TypeContainer { - public ImmutableArray Types { get; set; } + public ImmutableArray Types { get; set; } public CompositeTypeContainer() : base(Type.Table) { diff --git a/Upsilon/BaseTypes/TypeConversion.cs b/Upsilon/BaseTypes/TypeConversion.cs index 5900d21..c809646 100644 --- a/Upsilon/BaseTypes/TypeConversion.cs +++ b/Upsilon/BaseTypes/TypeConversion.cs @@ -6,6 +6,7 @@ using Upsilon.BaseTypes.Number; using Upsilon.BaseTypes.ScriptFunction; using Upsilon.BaseTypes.ScriptTypeInterfaces; using Upsilon.BaseTypes.UserData; +using Upsilon.BoundTypes; using Upsilon.Text; namespace Upsilon.BaseTypes @@ -108,7 +109,7 @@ namespace Upsilon.BaseTypes } } - public static Type GetScriptType(this System.Type t) + public static TypeContainer GetScriptType(this System.Type t) { if (t == typeof(bool)) return Type.Boolean; @@ -144,7 +145,7 @@ namespace Upsilon.BaseTypes if (t == typeof(ScriptType)) return Type.Unknown; - return Type.UserData; + return new TypeContainer(BoundTypeHandler.GetTypeName(t)); } } diff --git a/Upsilon/Binder/Binder.cs b/Upsilon/Binder/Binder.cs index a09ad8d..61c1eaa 100644 --- a/Upsilon/Binder/Binder.cs +++ b/Upsilon/Binder/Binder.cs @@ -954,7 +954,16 @@ namespace Upsilon.Binder VariableSymbol valueVariable; if (boundEnumerableExpression.Type is CompositeTypeContainer composite && composite.Types.Length == 2) { - valueVariable = new VariableSymbol(valueVar.Name, composite.Types[1], true); + var type = composite.Types[1]; + if (type == Type.UserData) + { + valueVariable = new UserDataVariableSymbol(valueVar.Name, + BoundTypeHandler.GetTypeDefinition(type.UserData)); + } + else + { + valueVariable = new VariableSymbol(valueVar.Name, composite.Types[1], true); + } } else { diff --git a/Upsilon/Binder/BoundExpressions/BoundIndexExpression.cs b/Upsilon/Binder/BoundExpressions/BoundIndexExpression.cs index 7828ba4..56b2ece 100644 --- a/Upsilon/Binder/BoundExpressions/BoundIndexExpression.cs +++ b/Upsilon/Binder/BoundExpressions/BoundIndexExpression.cs @@ -33,7 +33,7 @@ namespace Upsilon.Binder public BoundExpression Expression { get; } public string Index { get; } - public BoundFullStopIndexExpression(BoundExpression expression, string index, Type type, TextSpan span) : base(span) + public BoundFullStopIndexExpression(BoundExpression expression, string index, TypeContainer type, TextSpan span) : base(span) { Expression = expression; Index = index; diff --git a/Upsilon/Binder/BoundExpressions/BoundTableExpression.cs b/Upsilon/Binder/BoundExpressions/BoundTableExpression.cs index a5561dc..584a2f7 100644 --- a/Upsilon/Binder/BoundExpressions/BoundTableExpression.cs +++ b/Upsilon/Binder/BoundExpressions/BoundTableExpression.cs @@ -50,7 +50,7 @@ namespace Upsilon.Binder if (valueType.HasValue) valueRealType = valueType.Value; - var arr = new[] {BaseTypes.Type.String, valueRealType}; + var arr = new TypeContainer[] {BaseTypes.Type.String, valueRealType}; return new CompositeTypeContainer() { Types = arr.ToImmutableArray() diff --git a/Upsilon/BoundTypes/BoundTypeDefinition.cs b/Upsilon/BoundTypes/BoundTypeDefinition.cs index 22883be..30ffdfc 100644 --- a/Upsilon/BoundTypes/BoundTypeDefinition.cs +++ b/Upsilon/BoundTypes/BoundTypeDefinition.cs @@ -4,19 +4,19 @@ namespace Upsilon.BoundTypes { public class BoundTypeDefinition { - public BoundTypeDefinition(Type scriptType, System.Type[] validInternalTypes) + public BoundTypeDefinition(TypeContainer scriptType, System.Type[] validInternalTypes) { ScriptType = scriptType; ValidInternalTypes = validInternalTypes; } - public BoundTypeDefinition(Type scriptType, System.Type backingType) + public BoundTypeDefinition(TypeContainer scriptType, System.Type backingType) { ScriptType = scriptType; ValidInternalTypes = new []{backingType}; } - public Type ScriptType { get; } + public TypeContainer ScriptType { get; } public System.Type[] ValidInternalTypes { get; } } } \ No newline at end of file diff --git a/Upsilon/BoundTypes/BoundTypeHandler.cs b/Upsilon/BoundTypes/BoundTypeHandler.cs index 2103008..f8b4759 100644 --- a/Upsilon/BoundTypes/BoundTypeHandler.cs +++ b/Upsilon/BoundTypes/BoundTypeHandler.cs @@ -41,6 +41,11 @@ namespace Upsilon.BoundTypes return TypeDefinitions.Values.FirstOrDefault(x => x.ValidInternalTypes.Contains(type)); } + public static string GetTypeName(System.Type type) + { + return TypeDefinitions.FirstOrDefault(x => x.Value.ValidInternalTypes.Contains(type)).Key; + } + public static void LoadUserDataTypeDefinition(UserDataBoundTypeDefinition def) { var key = def.Name.ToLowerInvariant(); diff --git a/Upsilon/BoundTypes/UserDataBoundTypeDefinition.cs b/Upsilon/BoundTypes/UserDataBoundTypeDefinition.cs index 9fd8458..102a66b 100644 --- a/Upsilon/BoundTypes/UserDataBoundTypeDefinition.cs +++ b/Upsilon/BoundTypes/UserDataBoundTypeDefinition.cs @@ -16,14 +16,14 @@ namespace Upsilon.BoundTypes public string Name { get; protected set; } public Dictionary Properties { get; protected set; } - internal UserDataBoundTypeDefinition(System.Type backingType) - : base(Type.UserData, backingType) + internal UserDataBoundTypeDefinition(System.Type backingType, string name) + : base(new TypeContainer(name), backingType) { Name = backingType.Name; } public UserDataBoundTypeDefinition(string name, Dictionary backingType) - : base(Type.UserData, typeof(void)) + : base(new TypeContainer(name), typeof(void)) { Name = name; Properties = backingType; @@ -33,7 +33,7 @@ namespace Upsilon.BoundTypes public static UserDataBoundTypeDefinition Create(System.Type backingType, string name) { - var obj = new UserDataBoundTypeDefinition(backingType) + var obj = new UserDataBoundTypeDefinition(backingType, name) { Properties = new Dictionary(), Name = name @@ -101,7 +101,7 @@ namespace Upsilon.BoundTypes public class UserDataBoundEnumDefinition : UserDataBoundTypeDefinition { - public UserDataBoundEnumDefinition(System.Type enumType, string name) : base(enumType) + public UserDataBoundEnumDefinition(System.Type enumType, string name) : base(enumType, name) { if (!enumType.IsEnum) throw new Exception("Trying to bind an enum with a type that's not an enum"); @@ -120,7 +120,7 @@ namespace Upsilon.BoundTypes { Name = valueName, ActualType = enumType.ToString(), - Type = Type.UserData + Type = new TypeContainer(name) }); } } @@ -136,7 +136,7 @@ namespace Upsilon.BoundTypes Properties.Add(valueName, new UserDataBoundProperty() { Name = valueName, - Type = Type.UserData, + Type = new TypeContainer(name), ActualType = name }); } @@ -146,7 +146,7 @@ namespace Upsilon.BoundTypes public class UserDataBoundProperty { public string Name { get; set; } - public Type Type { get; set; } + public TypeContainer Type { get; set; } public virtual string ActualType { get; set; } public string Comment { get; set; } } @@ -159,7 +159,7 @@ namespace Upsilon.BoundTypes public class UserDataBoundMethod: UserDataBoundProperty { public override string ActualType => "Function"; - public Type ResultType { get; set; } + public TypeContainer ResultType { get; set; } public UserDataBoundFunctionParameter[] Parameters { get; set; } public (bool IsValid, string Error, @@ -177,21 +177,21 @@ namespace Upsilon.BoundTypes { var functionParameter = Parameters[i]; var callingParameter = callingParameters[i]; - if (callingParameter.Type == Type.Unknown || callingParameter.Type == Type.Nil) + if (callingParameter.Type == BaseTypes.Type.Unknown || callingParameter.Type == BaseTypes.Type.Nil) continue; - if (!functionParameter.Type.HasFlag(callingParameter.Type)) + if (!functionParameter.Type.Type.HasFlag(callingParameter.Type)) { return (false, $"Unexpected variable passed to internal function at variable {i + 1}. " + - $"Expected one of the following: {functionParameter.Type.ToString()}, got: '{callingParameter.Type}'", + $"Expected one of the following: {functionParameter.Type}, got: '{callingParameter.Type}'", callingParameter); } - if (functionParameter.Type.HasFlag(Type.UserData)) + if (functionParameter.Type.Type.HasFlag(BaseTypes.Type.UserData)) { var variable = Binder.Binder.ResolveVariable(callingParameter, null); - if (variable != null && variable.TypeContainer == Type.UserData) + if (variable != null && variable.TypeContainer == BaseTypes.Type.UserData) { var parent = (UserDataBoundTypeDefinition) ((UserDataVariableSymbol) variable).BoundTypeDefinition;