예제 #1
0
 private void LoadEntrance()
 {
     MemoryStack.Push(new ScopeValue {
         scriptId    = Script.Header.Id,
         entrance    = Script.ReadLabelOffset(),
         parentScope = ActiveScope?.Clone() as ScopeValue
     });
 }
예제 #2
0
 public void Log(string format, params object[] args)
 {
     if (scopes.Count > 0)
     {
         ActiveScope.Log(format, args);
     }
     else
     {
         Console.WriteLine(String.Format(format, args));
     }
 }
예제 #3
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);
        }
예제 #4
0
        public IDisposable Begin(string title = "", params object[] args)
        {
            Log(title, args);
            Scope scope;

            if (scopes.Count == 0)
            {
                scope = new Scope(this, 1);
            }
            else
            {
                scope = ActiveScope.Begin();
            }
            scopes.Push(scope);
            return(scope);
        }
예제 #5
0
        private void SetVariable(VariableSearchMode mode)
        {
            var name  = PopString();
            var value = MemoryStack.Pop();

            value = value is ReferenceValue referenceValue ? referenceValue.ReferenceTarget : value;
            if (string.IsNullOrEmpty(name))
            {
                throw new RuntimeException(_callStack, $"Unable to set variable: expected name {name} is not string value");
            }
            var variable = ActiveScope?.FindVariableAndScope(name, true, mode);

            if (name.Equals("true", StringComparison.InvariantCultureIgnoreCase) || name.Equals("false", StringComparison.InvariantCultureIgnoreCase))
            {
                throw new RuntimeException(_callStack, "Unable to set variable: system value true/false is readonly");
            }
            if (variable.HasValue)
            {
                try {
                    if (value == null || value is NullValue)
                    {
                        variable.Value.Scope.LocalVariables.Remove(name);
                    }
                    else
                    {
                        variable.Value.Target.ReferenceTarget = value;
                    }
                } catch (Exception ex) {
                    throw new RuntimeException(_callStack, ex);
                }
            }
            else if (value != null && !(value is NullValue))
            {
                ActiveScope?.LocalVariables.Add(name, new ReferenceValue {
                    ReferenceTarget = value, IsConstant = mode == VariableSearchMode.OnlyConstant
                });
            }
            MemoryStack.Push(value);
        }
예제 #6
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);
                }
            }
        }