private async Task CreateFunctionCall() { var functionName = MemoryStack.Pop(); while (functionName is ReferenceValue referenceFunction) { functionName = referenceFunction.ReferenceTarget; } ScopeValue functionBody; if (functionName is ScopeValue directBody) { functionBody = directBody; } else { if (!(functionName is IStringConverter stringConverter)) { throw new RuntimeException(_callStack, $"Unable to call scene: name {functionName} is not string value"); } var function = ActiveScope?.FindVariable(stringConverter.ConvertToString(ActiveLanguage), true, VariableSearchMode.All); if (function == null || !(function.ReferenceTarget is ScopeValue scopeValue)) { throw new RuntimeException(_callStack, $"Unable to call function: expected function {stringConverter.ConvertToString(ActiveLanguage)} not existed in current scope"); } functionBody = scopeValue; } // 生成形参 var paramCount = ((IntegerValue)MemoryStack.Pop()).value; for (var i = -1; ++i < paramCount;) { var paramName = PopString(); if (string.IsNullOrEmpty(paramName)) { throw new RuntimeException(_callStack, $"Unable to call {functionName}: expected parameter name {paramName} is not string value"); } functionBody.LocalVariables.Add(paramName, new ReferenceValue { ReferenceTarget = MemoryStack.Pop() }); } // 切换作用域 _historyScope.Push(ActiveScope); ActiveScope = functionBody; // 重定向执行位置 Script = await ScriptFile.Load(ActiveScope.scriptId); Script.MoveTo(ActiveScope.entrance); await Script.UseTranslation(ActiveLanguage); _callStack.Push(Script); }
private void LoadVariable(VariableSearchMode mode) { string name; if (MemoryStack.Peek() is ReferenceValue referenceValue) { name = PopString(referenceValue.ReferenceTarget); MemoryStack.Pop(); } else { name = PopString(); } if (name.Equals("true", StringComparison.InvariantCultureIgnoreCase)) { MemoryStack.Push(new BooleanValue { value = true }); } else if (name.Equals("false", StringComparison.InvariantCultureIgnoreCase)) { MemoryStack.Push(new BooleanValue { value = false }); } else { var target = ActiveScope?.FindVariable(name, true, mode); if (target == null) { LoadNull(); } else { MemoryStack.Push(target.ReferenceTarget); } } }