Пример #1
0
        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);
        }
Пример #2
0
        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);
                }
            }
        }