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