From fd8f7bf9f867d549215a5d2420049d893fee76f8 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Sat, 19 Jan 2019 17:13:53 +0100 Subject: [PATCH] Support for casting to other types --- Upsilon/Binder/Binder.cs | 17 +++++++++----- .../VariableSymbols/UserDataVariableSymbol.cs | 6 ++--- Upsilon/StandardLibraries/BasicFunctions.cs | 22 +++++++++++++++++++ Upsilon/StandardLibraries/StaticScope.cs | 4 ++-- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/Upsilon/Binder/Binder.cs b/Upsilon/Binder/Binder.cs index 61c1eaa..e064d61 100644 --- a/Upsilon/Binder/Binder.cs +++ b/Upsilon/Binder/Binder.cs @@ -352,7 +352,7 @@ namespace Upsilon.Binder var boundDef = BoundTypeHandler.GetTypeDefinition(bDefProperty.ActualType); if (boundDef != null) { - return new UserDataVariableSymbol(fullStopIndexExpression.Index, boundDef, parent); + return new UserDataVariableSymbol(fullStopIndexExpression.Index, boundDef, true, parent); } } } @@ -365,7 +365,7 @@ namespace Upsilon.Binder { var property = bProp.Properties[fullStopIndexExpression.Index.ToLowerInvariant()]; var boundDef = BoundTypeHandler.GetTypeDefinition(property.ActualType); - return new UserDataVariableSymbol(fullStopIndexExpression.Index, boundDef, bProp); + return new UserDataVariableSymbol(fullStopIndexExpression.Index, boundDef, true, bProp); } } @@ -463,6 +463,11 @@ namespace Upsilon.Binder variable = new TableVariableSymbol(name, isLocal, assignment.Type); } } + else if (assignment.Type == Type.UserData) + { + variable = new UserDataVariableSymbol(name, + BoundTypeHandler.GetTypeDefinition(assignment.Type.UserData), isLocal); + } else { variable = new VariableSymbol(name, assignment.Type, isLocal); @@ -604,16 +609,16 @@ namespace Upsilon.Binder if (type == null) { _diagnostics.LogError($"Unknown type name '{variable.TypeName.Name}'", variable.Span); - variableSymbol = new UserDataVariableSymbol(variable.IdentifierName.Name, Type.Unknown); + variableSymbol = new UserDataVariableSymbol(variable.IdentifierName.Name, Type.Unknown, true); } else { - variableSymbol = new UserDataVariableSymbol(variable.IdentifierName.Name, type); + variableSymbol = new UserDataVariableSymbol(variable.IdentifierName.Name, type, true); } } else { - variableSymbol = new UserDataVariableSymbol(variable.IdentifierName.Name, Type.Unknown); + variableSymbol = new UserDataVariableSymbol(variable.IdentifierName.Name, Type.Unknown, true); } parameters.Add(new BoundVariableSymbol(variableSymbol, true, identifierToken.Span)); innerScope.DefineLocalVariable(variableSymbol); @@ -958,7 +963,7 @@ namespace Upsilon.Binder if (type == Type.UserData) { valueVariable = new UserDataVariableSymbol(valueVar.Name, - BoundTypeHandler.GetTypeDefinition(type.UserData)); + BoundTypeHandler.GetTypeDefinition(type.UserData), true); } else { diff --git a/Upsilon/Binder/VariableSymbols/UserDataVariableSymbol.cs b/Upsilon/Binder/VariableSymbols/UserDataVariableSymbol.cs index 7103443..f457ae4 100644 --- a/Upsilon/Binder/VariableSymbols/UserDataVariableSymbol.cs +++ b/Upsilon/Binder/VariableSymbols/UserDataVariableSymbol.cs @@ -8,13 +8,13 @@ namespace Upsilon.Binder.VariableSymbols public BoundTypeDefinition BoundTypeDefinition { get; } public UserDataBoundTypeDefinition Parent { get; } - public UserDataVariableSymbol(string name, Type typeContainer) : base(name, typeContainer, true) + public UserDataVariableSymbol(string name, Type typeContainer, bool isLocal) : base(name, typeContainer, isLocal) { _typeContainer = typeContainer; } - public UserDataVariableSymbol(string name, BoundTypeDefinition type, UserDataBoundTypeDefinition parent = null) - : base(name, type.ScriptType, true) + public UserDataVariableSymbol(string name, BoundTypeDefinition type, bool isLocal, UserDataBoundTypeDefinition parent = null) + : base(name, type.ScriptType, isLocal) { BoundTypeDefinition = type; Parent = parent; diff --git a/Upsilon/StandardLibraries/BasicFunctions.cs b/Upsilon/StandardLibraries/BasicFunctions.cs index a5c662f..d9d2d24 100644 --- a/Upsilon/StandardLibraries/BasicFunctions.cs +++ b/Upsilon/StandardLibraries/BasicFunctions.cs @@ -4,6 +4,7 @@ using Upsilon.BaseTypes.Number; using Upsilon.BaseTypes.ScriptTypeInterfaces; using Upsilon.Binder; using Upsilon.Binder.VariableSymbols; +using Upsilon.BoundTypes; using Upsilon.Evaluator; // ReSharper disable UnusedMember.Global @@ -109,5 +110,26 @@ namespace Upsilon.StandardLibraries return new ScriptString(obj.Type.ToString()); } + [ScriptFunction("cast", "Casts an object to a given type.", directScriptManipulation: true, + overrideReturnType: typeof(BasicFunctions), overrideReturnMethod: nameof(CastBindHelper))] + public ScriptType Cast(ScriptType obj, ScriptString typeName) + { + return obj; + } + + private static TypeContainer CastBindHelper(BoundExpression[] expressions) + { + if (expressions.Length != 2) + return BaseTypes.Type.Unknown; + var typeNameExpression = expressions[1]; + if (!(typeNameExpression is BoundLiteralExpression literal) || literal.Type != BaseTypes.Type.String) + return BaseTypes.Type.Unknown; + + var boundType = BoundTypeHandler.GetTypeDefinition(((ScriptString) literal.Value)); + if (boundType == null) + return BaseTypes.Type.Unknown; + + return boundType.ScriptType; + } } } \ No newline at end of file diff --git a/Upsilon/StandardLibraries/StaticScope.cs b/Upsilon/StandardLibraries/StaticScope.cs index 763596f..4784c2c 100644 --- a/Upsilon/StandardLibraries/StaticScope.cs +++ b/Upsilon/StandardLibraries/StaticScope.cs @@ -75,7 +75,7 @@ namespace Upsilon.StandardLibraries UserDataTypeHandler.LoadType(); funcs.Add("math", new MathLibrary().ToScriptType()); boundFuncs.Add("math", - new UserDataVariableSymbol("math", BoundTypeHandler.GetTypeDefinition(typeof(MathLibrary)))); + new UserDataVariableSymbol("math", BoundTypeHandler.GetTypeDefinition(typeof(MathLibrary)), true)); var scope = new EvaluationScope(funcs); var boundScope = new BoundScope(boundFuncs, null); @@ -89,7 +89,7 @@ namespace Upsilon.StandardLibraries VariableSymbol varSymbol = null; if (ubDef != null) { - varSymbol = new UserDataVariableSymbol(name, ubDef); + varSymbol = new UserDataVariableSymbol(name, ubDef, true); } else {