diff --git a/Losetta.Runtime/Core/Alice.Core.Utils.cs b/Losetta.Runtime/Core/Alice.Core.Utils.cs index b4b331f..55e56c7 100644 --- a/Losetta.Runtime/Core/Alice.Core.Utils.cs +++ b/Losetta.Runtime/Core/Alice.Core.Utils.cs @@ -208,6 +208,15 @@ public static Variable Ref([BindInfo] ParsingScript script) Parser.NeedReferenceNext = true; return Utils.GetItem(script); } + [AliceFunction(Attribute = FunctionAttribute.LANGUAGE_STRUCTURE, Context = ParsingScript.Contexts.IN_ARGS)] + public static Variable Out([BindInfo] ParsingScript script) + { + Parser.NeedReferenceNext = true; + var vf = Utils.GetItem(script).Reference as ValueFunction; + string name = vf.Name; + script.ParentScript.Variables[name] = vf; + return new Variable(vf); + } [AliceFunction(Attribute = FunctionAttribute.LANGUAGE_STRUCTURE, Name = "__makeref")] public static Variable MakeRef([BindInfo] ParsingScript script) => Ref(script); [AliceFunction(Attribute = FunctionAttribute.LANGUAGE_STRUCTURE, Name = "__useref")] diff --git a/Losetta.Runtime/Losetta.Runtime.csproj b/Losetta.Runtime/Losetta.Runtime.csproj index 3699d00..c18d6c9 100644 --- a/Losetta.Runtime/Losetta.Runtime.csproj +++ b/Losetta.Runtime/Losetta.Runtime.csproj @@ -5,7 +5,7 @@ disable disable alice_logo.ico - 0.10.5 + 0.11.0 WSOFT Losetta Alice.Runtime diff --git a/Losetta.Tests/Losetta/Scripting/Statement/Others.cs b/Losetta.Tests/Losetta/Scripting/Statement/Others.cs index a67e904..6fdcf41 100644 --- a/Losetta.Tests/Losetta/Scripting/Statement/Others.cs +++ b/Losetta.Tests/Losetta/Scripting/Statement/Others.cs @@ -34,4 +34,13 @@ number add(number x, number y) Assert.That(TestUtils.Script.Execute(code), Is.EqualTo(5)); } + [TestCase] + public void Dictionary() + { + string code = @" + dictionary dic = {""key1"": 1, ""key2"": 2}; + return dic; + "; + Assert.That(TestUtils.Script.Execute>(code)["key1"], Is.EqualTo(1)); + } } diff --git a/Losetta/Alice.cs b/Losetta/Alice.cs index 29d4489..f1a3645 100644 --- a/Losetta/Alice.cs +++ b/Losetta/Alice.cs @@ -20,6 +20,10 @@ public static Variable Execute(string code, string filename = "", bool mainFile { return Interpreter.Instance.Process(code, filename, mainFile); } + public static Variable Execute(string code, (string, object)[] variables, string filename = "", bool mainFile = false) + { + return Interpreter.Instance.Process(code, filename, mainFile, variables: variables); + } /// /// このインタプリタで読み込み可能なファイルを読み込みます /// diff --git a/Losetta/Functions/AssignFunction.cs b/Losetta/Functions/AssignFunction.cs index 2b1751d..87b1629 100644 --- a/Losetta/Functions/AssignFunction.cs +++ b/Losetta/Functions/AssignFunction.cs @@ -25,7 +25,8 @@ public static Variable Assign(ParsingScript script, string varName, bool localIf { string m_name = Constants.GetRealName(varName); script.CurrentAssign = m_name; - Variable varValue = Utils.GetItem(script); + script.MoveForwardIf(Constants.ASSIGNMENT.ToCharArray()); + Variable varValue = script.Prev == Constants.ASSIGNMENT[0] ? Utils.GetItem(script) : varType.Activate(new List(), script); bool registVar = varType is not null; if (varType is null) { diff --git a/Losetta/Functions/ParserFunction.cs b/Losetta/Functions/ParserFunction.cs index 588fc6f..b0844a4 100644 --- a/Losetta/Functions/ParserFunction.cs +++ b/Losetta/Functions/ParserFunction.cs @@ -121,12 +121,11 @@ private bool CheckValidFunction(ref ParserFunction func, ParsingScript script,Ha func = new ValueFunction(); return true; } - else if(script.Current == Constants.ASSIGNMENT[0]) - { - var value = AssignFunction.Assign(script, name, false, null, keywords, type); - func = new ValueFunction(value); - return true; - } + + var value = AssignFunction.Assign(script, name, false, null, keywords, type); + func = new ValueFunction(value); + return true; + } if(func is not null && (func is not FunctionBase fb || fb.Context.HasFlag(script.Context))) { diff --git a/Losetta/Interpreter.cs b/Losetta/Interpreter.cs index 32d90cb..d2be138 100644 --- a/Losetta/Interpreter.cs +++ b/Losetta/Interpreter.cs @@ -278,7 +278,7 @@ public ParsingScript GetScript(string script, string filename = "", bool mainFil } return toParse; } - public Variable Process(string script, string filename = "", bool mainFile = false, object tag = null, AlicePackage package = null) + public Variable Process(string script, string filename = "", bool mainFile = false, object tag = null, AlicePackage package = null, (string, object)[] variables = null) { string data = PreProcessor.ConvertToScript(script, out Dictionary char2Line, out var def, out var setting, filename); if (string.IsNullOrWhiteSpace(data)) @@ -295,6 +295,14 @@ public Variable Process(string script, string filename = "", bool mainFile = fal toParse.Tag = tag; toParse.Package = package; + if(variables is not null) + { + foreach (var (name, value) in variables) + { + toParse.Variables[name] = new ValueFunction(new Variable(value)); + } + } + if (mainFile) { toParse.MainFilename = toParse.Filename; diff --git a/Losetta/Losetta.csproj b/Losetta/Losetta.csproj index 06d94b8..51d3d12 100644 --- a/Losetta/Losetta.csproj +++ b/Losetta/Losetta.csproj @@ -5,7 +5,7 @@ disable disable alice_logo.ico - 0.10.5 + 0.11.0 WSOFT Losetta Alice.Runtime diff --git a/Losetta/Objects/Delegate.cs b/Losetta/Objects/Delegate.cs index cea6c89..97c6e9f 100644 --- a/Losetta/Objects/Delegate.cs +++ b/Losetta/Objects/Delegate.cs @@ -1,6 +1,7 @@ using AliceScript.Functions; using AliceScript.Parsing; using System.Collections.Generic; +using System.Linq; using System.Threading; namespace AliceScript.Objects @@ -113,6 +114,16 @@ public Variable Invoke(Variable arg = null, ParsingScript script = null, AliceSc } return Invoke(args, script, instance); } + public Variable Invoke(object[] args, ParsingScript script = null, AliceScriptClass.ClassInstance instance = null) + { + var vars = args.Select(arg => new Variable(arg)).ToList(); + return Invoke(vars, script, instance); + } + public Variable Invoke(params object[] args) + { + var vars = args.Select(arg => new Variable(arg)).ToList(); + return Invoke(args, ParsingScript.GetTopLevelScript(), null); + } public void BeginInvoke(List args = null, ParsingScript script = null, AliceScriptClass.ClassInstance instance = null) { m_BeginInvokeMessanger mb = new m_BeginInvokeMessanger(); diff --git a/Losetta/Objects/TypeObject.cs b/Losetta/Objects/TypeObject.cs index 647edae..df19a2c 100644 --- a/Losetta/Objects/TypeObject.cs +++ b/Losetta/Objects/TypeObject.cs @@ -154,7 +154,10 @@ public Variable Activate(List args, ParsingScript script) { if (ClassType is not null) { - //TODO:非ObjectBaseのクラスのアクティベート + if(ClassType is BindObject bind) + { + return new Variable(bind.Constructor.Evaluate(args, script)); + } if (ClassType is ObjectBase csClass) { return csClass.GetImplementation(args, script); @@ -166,6 +169,20 @@ public Variable Activate(List args, ParsingScript script) v.Tuple.Type = ArrayType; return v; } + if(!Nullable) + { + switch(Type) + { + case Variable.VarType.BOOLEAN: + return new Variable(args.Count > 0 ? args[0].AsBool() : false); + case Variable.VarType.NUMBER: + return new Variable(args.Count > 0 ? args[0].AsDouble() : 0); + case Variable.VarType.STRING: + return new Variable(args.Count > 0 ? args[0].AsString() : ""); + case Variable.VarType.VOID: + return Variable.EmptyInstance; + } + } return new Variable(Type); } diff --git a/Losetta/Variable.cs b/Losetta/Variable.cs index ee72b28..243a7fd 100644 --- a/Losetta/Variable.cs +++ b/Losetta/Variable.cs @@ -907,7 +907,7 @@ public T ConvertTo() /// 型の不一致により変換できない場合にスローされる例外 public object ConvertTo(Type type) { - return TryConvertTo(type, out object o) ? o : throw new ScriptException("型が一致しないか、変換できません。", Exceptions.WRONG_TYPE_VARIABLE); + return TryConvertTo(type, out object o) ? o : throw new ScriptException($"`{this.AsType()}`を`{type}`にキャストできません。", Exceptions.WRONG_TYPE_VARIABLE); } /// /// この変数を指定した型に変換できるか試みます @@ -1094,6 +1094,26 @@ public bool TryConvertTo(Type type, out object result) result = m_dictionary; return true; } + if(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>)) + { + var keyType = type.GetGenericArguments()[0]; + var valueType = type.GetGenericArguments()[1]; + var dict = (IDictionary)Activator.CreateInstance(type); + foreach (var kv in m_dictionary) + { + if (kv.Key.TryConvertTo(keyType, out var k) && kv.Value.TryConvertTo(valueType, out var v)) + { + dict.Add(k, v); + } + else + { + result = null; + return false; + } + } + result = dict; + return true; + } if (type is null || type == typeof(VariableCollection)) { result = new VariableCollection(m_dictionary.Select(item => new Variable(item)).ToList()); diff --git a/alice/alice.csproj b/alice/alice.csproj index 8f0698e..cad5757 100644 --- a/alice/alice.csproj +++ b/alice/alice.csproj @@ -8,7 +8,7 @@ true alice_logo.ico - 0.10.5 + 0.11.0 Losetta.CLI WSOFT WSOFT