private void CreateBinaryOperation(OperatorType operatorType) { var valueLeft = MemoryStack.Pop(); var valueRight = MemoryStack.Pop(); switch (operatorType) { case OperatorType.PickChild: if (valueRight is IStringConverter rightStringConverter && rightStringConverter.ConvertToString(ActiveLanguage) == "Clone") { // 复制(Clone)由于统一实现的困难暂且由运行环境处理 MemoryStack.Push(valueLeft.Clone()); } else if (valueLeft is IPickChildOperator leftPick) { try { MemoryStack.Push(leftPick.PickChild(valueRight, ActiveLanguage)); } catch (Exception ex) { throw new RuntimeException(_callStack, ex); } } else { throw new RuntimeException(_callStack, $"Unable to pick {valueRight} from {valueLeft}: parent expression has no pick child operator implementation"); } break;
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 string PopString(SerializableValue target = null) { var rawValue = target ?? MemoryStack.Pop(); switch (rawValue) { case IStringConverter stringConverter: return(stringConverter.ConvertToString(ActiveLanguage)); default: return(null); } }
private void SetMemory() { var target = MemoryStack.Pop(); var value = MemoryStack.Pop(); if (target is ReferenceValue referenceTarget) { value = value is ReferenceValue referenceValue ? referenceValue.ReferenceTarget : value; referenceTarget.ReferenceTarget = value; } else { throw new RuntimeException(_callStack, $"Unable to set memory: expected target {target} is not reference/variable value"); } MemoryStack.Push(value); }
private void CreateToNegative() { var rawValue = MemoryStack.Pop(); if (rawValue is INegativeOperator negativeOperator) { try { MemoryStack.Push(negativeOperator.ToNegative(ActiveLanguage)); } catch (Exception ex) { throw new RuntimeException(_callStack, ex); } } else { throw new RuntimeException(_callStack, $"Unable to get negative value of {rawValue}: target expression has no negative operator implementation"); } }
private async Task CreateDialogue() { var plugin = PluginManager.Find("Dialogue"); if (plugin == null) { throw new RuntimeException(_callStack, "Unable to create dialogue: no dialogue plugin registered"); } MemoryStack.Push(await plugin.Execute(PluginExecuteContext.Create(this, "Dialogue", new List <KeyValuePair <SerializableValue, SerializableValue> > { new KeyValuePair <SerializableValue, SerializableValue>(new StringValue { value = "Character" }, MemoryStack.Pop()), new KeyValuePair <SerializableValue, SerializableValue>(new StringValue { value = "Content" }, MemoryStack.Pop()) })) ?? new NullValue()); }
private void CreateToBoolean() { var rawValue = MemoryStack.Pop(); if (rawValue is BooleanValue) { MemoryStack.Push(rawValue); return; } try { var result = new BooleanValue { value = rawValue is IBooleanConverter booleanValue?booleanValue.ConvertToBoolean(ActiveLanguage) : rawValue != null }; MemoryStack.Push(result); } catch (Exception ex) { throw new RuntimeException(_callStack, ex); } }
private async Task CreatePluginCall() { var(plugin, name) = FindPlugin(); var parameterCount = ((IIntegerConverter)MemoryStack.Pop()).ConvertToInteger(ActiveLanguage); var parameters = new List <KeyValuePair <SerializableValue, SerializableValue> >(); for (var i = -1; ++i < parameterCount;) { parameters.Add(new KeyValuePair <SerializableValue, SerializableValue>( MemoryStack.Pop() ?? new NullValue(), MemoryStack.Pop() ?? new NullValue())); } parameters.Reverse(); var context = PluginExecuteContext.Create(this, name, parameters); try { MemoryStack.Push(await plugin.Execute(context) ?? new NullValue()); } catch (Exception ex) { throw new RuntimeException(_callStack, ex); } }
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); } } }
public static ICASMExecutionResult Execute(Scope _currentScope, ICASMDirectiveType type, ICASMTagType tag, ICASMDirectiveParameters parameters) { ICASMExecutionResult result = new ICASMExecutionResult() { Success = true }; ICASMValue varname, varvalue, varscope, vartype; Variable variable; Address address; string _ideoutput = ""; switch (type) { #region VariableAddDirective case ICASMDirectiveType.VariableAddDirective: if (tag == ICASMTagType.Help) { _ideoutput = "\n\tVariableAddDirective, usage - \n\t+var <name> <?scope> <?type> <?value>"; result.Data.Add("$IDE_OUTPUT$", _ideoutput); break; } varname = parameters[0].Check(ICASMValueType.Identifier); varscope = new ICASMValue(ICASMValueType.Address, "/"); vartype = null; varvalue = new ICASMValue(ICASMValueType.Normal, null); if (parameters.Count > 1) { varscope = parameters[1].Check(ICASMValueType.Address); if (parameters.Count > 2) { vartype = parameters[2].Check(ICASMValueType.Address); if (parameters.Count > 3) { varvalue = parameters[3].Check(ICASMValueType.Address, ICASMValueType.ExecutableResult, ICASMValueType.Identifier, ICASMValueType.Normal); } } } Data.Type varType = null; if (vartype != null) { varType = TypeEngine.GetType(Address.FromScope(new Scripting.Scope((string)vartype.Value))); } else { varType = ICASMValue.GetTypeFromPrimitiveType(varvalue.PrimitiveType); } string[] memberCreation = varType.MemberCreationQueue.ToArray(); variable = new Variable(varvalue.Value, varType); for (int i = 0; i < memberCreation.Length; i++) { ICASMDirective _temp_directive_function_member = ICASMInterpreter.ParseDirective(_currentScope, memberCreation[i]); if (_temp_directive_function_member.Type == ICASMDirectiveType.VariableAddDirective) { _temp_directive_function_member.SetTag(ICASMTagType.AppendTuple); string varscopestr = (string)varscope.Value; if (!varscopestr.Equals("/")) { varscopestr = varscopestr + "/"; } _temp_directive_function_member.Parameters.Insert(1, new ICASMValue(ICASMValueType.Address, varscopestr + (string)varname.Value)); ICASMExecutionResult res = Execute(_currentScope, _temp_directive_function_member); variable.TupleAddresses.Add((string)_temp_directive_function_member.Parameters[0].Value, (Address)res.Data["VariableAddDirective"]); } } address = Address.FromScope(new Scripting.Scope((string)varscope.Value + "/" + (string)varname.Value)); if (tag == ICASMTagType.Suppress) { RuntimeEngine.CreatePool(address.Parent); if (RuntimeEngine.GetPool(address.Parent).HasVariable(address.Name)) { RuntimeEngine.GetPool(address.Parent).Pull(address.Name); } } else if (tag == ICASMTagType.AppendTuple) { address = Address.FromScope(new Scripting.Scope((string)varscope.Value + "." + (string)varname.Value)); } RuntimeEngine.PutVariable(address, variable); result.Success = true; result.Data.Add(type.ToString(), address); break; #endregion #region VariableRemoveDirective case ICASMDirectiveType.VariableRemoveDirective: if (tag == ICASMTagType.Help) { _ideoutput = "\n\tVariableRemoveDirective, usage - \n\t-var <name> <?scope>"; result.Data.Add("$IDE_OUTPUT$", _ideoutput); break; } varname = parameters[0].Check(ICASMValueType.Identifier); varscope = new ICASMValue(ICASMValueType.Address, "/"); if (parameters.Count > 1) { varscope = parameters[1].Check(ICASMValueType.Address); } VariablePool pool = RuntimeEngine.GetPool(Address.FromScope(new Scope((string)varscope.Value))); variable = pool.Pull((string)varname.Value); if (variable != null) { result.Success = true; result.Data.Add(type.ToString(), new Address((string)varscope.Value, (string)varname.Value, AddressType.Variable)); } break; #endregion #region VariablePoolAddDirective case ICASMDirectiveType.VariablePoolAddDirective: if (tag == ICASMTagType.Help) { _ideoutput = "\n\tVariablePoolAddDirective, usage - \n\t+pool <name> <?scope>"; result.Data.Add("$IDE_OUTPUT$", _ideoutput); break; } varname = parameters[0].Check(ICASMValueType.Identifier); varscope = new ICASMValue(ICASMValueType.Address, "/"); if (parameters.Count > 1) { varscope = parameters[1].Check(ICASMValueType.Address); } address = Address.FromScope(new Scope((string)varscope.Value + "/" + (string)varname.Value)); RuntimeEngine.CreatePool(address); result.Success = true; result.Data.Add(type.ToString(), address); break; #endregion #region VariablePoolRemoveDirective case ICASMDirectiveType.VariablePoolRemoveDirective: if (tag == ICASMTagType.Help) { _ideoutput = "\n\tVariablePoolRemoveDirective, usage - \n\t-pool <name> <?scope>"; result.Data.Add("$IDE_OUTPUT$", _ideoutput); break; } varname = parameters[0].Check(ICASMValueType.Identifier); varscope = new ICASMValue(ICASMValueType.Address, "/"); if (parameters.Count > 1) { varscope = parameters[1].Check(ICASMValueType.Address); } address = Address.FromScope(new Scope((string)varscope.Value + "/" + (string)varname.Value)); RuntimeEngine.GetPool(address.Parent).PullPool(address.Name); result.Success = true; result.Data.Add(type.ToString(), address); break; #endregion #region CallDirective case ICASMDirectiveType.CallDirective: if (tag == ICASMTagType.Help) { _ideoutput = "\n\tCallDirective, usage - \n\tcall <type> <function name> <?parameters>"; result.Data.Add("$IDE_OUTPUT$", _ideoutput); break; } varname = parameters[0]; if (varname.Type == ICASMValueType.Identifier && varname.Value.Equals("type(stack)")) { varname.Value = MemoryStack.Peek(); } else { varname = varname.Check(ICASMValueType.Address); } varscope = parameters[1]; if ((string)varscope.Value == "/") { varscope.Type = ICASMValueType.FunctionIdentifier; } varscope = varscope.Check(ICASMValueType.FunctionIdentifier, ICASMValueType.Identifier); if (parameters.Count > 2) { Address[] _addresses = new Address[parameters.Count - 2]; for (int i = 2; i < parameters.Count; i++) { if (parameters[i].Type == ICASMValueType.Normal) { Data.Type ttt = ICASMValue.GetTypeFromPrimitiveType(parameters[i].PrimitiveType); variable = new Variable(parameters[i].Value, ttt); RuntimeEngine.PutVariable("/$SYSTEM$_temp" + (_temps), variable); _addresses[i - 2] = "/$SYSTEM$_temp" + _temps; MemoryStack.Push(_addresses[i - 2]); _temps++; } else if (parameters[i].Type == ICASMValueType.Address) { _addresses[i - 2] = (string)parameters[i].Value; } else if (parameters[i].Type == ICASMValueType.Identifier) { _addresses[i - 2] = "/" + (string)parameters[i].Value; } } address = (string)varname.Value; string temp_address = "/$SYSTEM$_temp" + (_temps); _executingFunction = true; TypeEngine.GetType(address).ExecuteFunction(temp_address, (string)varscope.Value, _addresses); MemoryStack.Push(temp_address); address = temp_address; result.Success = true; result.Data.Add(type.ToString(), (Address)temp_address); _temps++; } break; #endregion #region AssignDirective case ICASMDirectiveType.AssignDirective: if (tag == ICASMTagType.Help) { _ideoutput = "\n\tAssignDirective, usage - \n\tassign <value> <address of variable>\n\t\t<value> - can be any primitive value, address, identifier or another nested <?call> or <?ewfc>"; result.Data.Add("$IDE_OUTPUT$", _ideoutput); break; } varname = parameters[0]; varscope = parameters[1].Check(ICASMValueType.Identifier, ICASMValueType.Address); address = (string)varscope.Value; variable = new Variable(); Address addr = null; if (varname.Type == ICASMValueType.Normal) { Data.Type ttt = ICASMValue.GetTypeFromPrimitiveType(varname.PrimitiveType); variable = new Variable(varname.Value, ttt); } else if (varname.Type == ICASMValueType.Identifier) { addr = "/" + (string)varname.Value; variable = RuntimeEngine.GetVariable(addr); } else if (varname.Type == ICASMValueType.Address) { addr = (string)varname.Value; variable = RuntimeEngine.GetVariable(addr); } if (tag == ICASMTagType.Suppress) { RuntimeEngine.CreatePool(address.Parent); VariablePool variablep = RuntimeEngine.GetPool(address.Parent); if (variablep.HasVariable(address.Name)) { variablep.Pull(address.Name); } RuntimeEngine.PutVariable(address, variable); } RuntimeEngine.SetVariable(address, variable); result.Success = true; result.Data.Add(type.ToString(), address); break; #endregion #region FunctionAddDirective case ICASMDirectiveType.FunctionAddDirective: if (tag == ICASMTagType.Help) { _ideoutput = "\n\tFunctionAddDirective, usage - \n\t+function <name> <type address> <function type> <?parameter type addresses>"; result.Data.Add("$IDE_OUTPUT$", _ideoutput); break; } varname = parameters[0].Check(ICASMValueType.FunctionIdentifier, ICASMValueType.Identifier); if (varname == null && parameters[0].Value.Equals("/")) { varname = parameters[0]; } varscope = parameters[1].Check(ICASMValueType.Address); vartype = parameters[2].Check(ICASMValueType.Identifier); List <Address> parametertypes = new List <Address>(); int j = 3; while (j < parameters.Count && parameters[j].Type == ICASMValueType.Address) { parametertypes.Add((string)parameters[j].Value); j++; } FunctionType _newFunctionType = (FunctionType)Enum.Parse(typeof(FunctionType), (string)vartype.Value); ICASMFunction new_function = new ICASMFunction((string)varname.Value, (string)varname.Value, _newFunctionType, (string)varscope.Value, parametertypes.ToArray()); _mode = ICASMInterpreterMode.Function; currentFunction = new_function; break; #endregion #region FunctionRemoveDirective case ICASMDirectiveType.FunctionRemoveDirective: if (tag == ICASMTagType.Help) { _ideoutput = "\n\tFunctionRemoveDirective, usage - \n\t+function <name> <type address>"; result.Data.Add("$IDE_OUTPUT$", _ideoutput); break; } //To-do break; #endregion #region FieldsAddDirective case ICASMDirectiveType.FieldsAddDirective: if (tag == ICASMTagType.Help) { _ideoutput = "\n\tFieldsAddDirective, usage - \n\t+fields <type address>\n\t\t<... var add statements>\n\tend+"; result.Data.Add("$IDE_OUTPUT$", _ideoutput); break; } varname = parameters[0].Check(ICASMValueType.Address); currentType = TypeEngine.GetType((string)varname.Value); _mode = ICASMInterpreterMode.Fields; break; #endregion #region TypeAddDirective case ICASMDirectiveType.TypeAddDirective: if (tag == ICASMTagType.Help) { _ideoutput = "\n\tTypeAddDirective, usage - \n\t+type <name> <typespace address>"; result.Data.Add("$IDE_OUTPUT$", _ideoutput); break; } varname = parameters[0].Check(ICASMValueType.Identifier); varscope = new ICASMValue(ICASMValueType.Address, "/"); if (parameters.Count > 1) { varscope = parameters[1].Check(ICASMValueType.Address); } Data.Type t = new Data.Type((string)varname.Value, (string)varscope.Value); TypeEngine.AddType(t.Address, t); break; #endregion #region TypeRemoveDirective case ICASMDirectiveType.TypeRemoveDirective: if (tag == ICASMTagType.Help) { _ideoutput = "\n\tTypeRemoveDirective, usage - \n\t-type <name> <typespace address>"; result.Data.Add("$IDE_OUTPUT$", _ideoutput); break; } varname = parameters[0].Check(ICASMValueType.Identifier); varscope = new ICASMValue(ICASMValueType.Address, "/"); if (parameters.Count > 1) { varscope = parameters[1].Check(ICASMValueType.Address); } TypeSpace from = TypeEngine.GetTypeSpace((string)varscope.Value); if (from.HasType((string)varname.Value)) { from.Pull((string)varname.Value); } break; #endregion #region TypespaceAddDirective case ICASMDirectiveType.TypespaceAddDirective: if (tag == ICASMTagType.Help) { _ideoutput = "\n\tTypespaceAddDirective, usage - \n\t+typespace <name> <?typespace parent>"; result.Data.Add("$IDE_OUTPUT$", _ideoutput); break; } varname = parameters[0].Check(ICASMValueType.Identifier); varscope = new ICASMValue(ICASMValueType.Address, "/"); if (parameters.Count > 1) { varscope = parameters[1].Check(ICASMValueType.Address); } TypeSpace _toCreateTypespaceIn = TypeEngine.GetTypeSpace((string)varscope.Value); _toCreateTypespaceIn.CreateTypeSpace((string)varname.Value); break; #endregion #region TypespaceRemoveDirective case ICASMDirectiveType.TypespaceRemoveDirective: if (tag == ICASMTagType.Help) { _ideoutput = "\n\tTypespaceRemoveDirective, usage - \n\t-typespace <name> <?typespace parent>"; result.Data.Add("$IDE_OUTPUT$", _ideoutput); break; } varname = parameters[0].Check(ICASMValueType.Identifier); varscope = new ICASMValue(ICASMValueType.Address, "/"); if (parameters.Count > 1) { varscope = parameters[1].Check(ICASMValueType.Address); } TypeSpace _toRemoveTypespaceFrom = TypeEngine.GetTypeSpace((string)varscope.Value); _toRemoveTypespaceFrom.PullTypeSpace((string)varname.Value); break; #endregion #region ReturnDirective case ICASMDirectiveType.ReturnDirective: if (tag == ICASMTagType.Help) { _ideoutput = "\n\tReturnDirective, usage - \n\treturn <identifier/address/value>"; result.Data.Add("$IDE_OUTPUT$", _ideoutput); break; } address = null; varname = parameters[0].Check(ICASMValueType.Address, ICASMValueType.Identifier, ICASMValueType.Normal); if (varname.Type == ICASMValueType.Address) { address = (string)varname.Value; } else if (varname.Type == ICASMValueType.Identifier) { address = "/" + (string)varname.Value; } else if (varname.Type == ICASMValueType.Normal) { Data.Type ttt = ICASMValue.GetTypeFromPrimitiveType(varname.PrimitiveType); variable = new Variable(varname.Value, ttt); RuntimeEngine.PutVariable("/$SYSTEM$_temp" + (_temps), variable); address = "/$SYSTEM$_temp" + _temps; MemoryStack.Push(address); _temps++; } if (address != null) { result.Success = true; result.Data.Add(type.ToString(), address); } _functionReturned = true; _executingFunction = false; break; #endregion #region TypeAddDirective case ICASMDirectiveType.ImportDirective: if (tag == ICASMTagType.Help) { _ideoutput = "\n\tTypeAddDirective, usage - \n\timport <librarypath/filepath>\n\t\t-path - for importing a file"; result.Data.Add("$IDE_OUTPUT$", _ideoutput); break; } varname = parameters[0].Check(ICASMValueType.Normal); string _importPath = (string)varname.Value; LoadAndExecute(_importPath.Trim()); break; #endregion #region EwfcDirective case ICASMDirectiveType.EwfcDirective: if (tag == ICASMTagType.Help) { _ideoutput = "\n\tEwfcDirective, usage - \n\tewfc <.net namespace> <function name> <?parameters>"; result.Data.Add("$IDE_OUTPUT$", _ideoutput); break; } varscope = parameters[0].Check(ICASMValueType.Address); varname = parameters[1].Check(ICASMValueType.Identifier); _importPath = (string)varscope.Value; string _importMethodName = (string)varname.Value; _importPath = _importPath.Replace('/', '.').Trim('.'); object[] _parametersToCallingFunction = new object[parameters.Count - 2]; System.Type[] _parameterTypesToCallingFunction = new System.Type[parameters.Count - 2]; variable = new Variable(); for (int i = 2; i < parameters.Count; i++) { if (parameters[i].Type == ICASMValueType.Normal) { Data.Type ttt = ICASMValue.GetTypeFromPrimitiveType(parameters[i].PrimitiveType); variable = new Variable(parameters[i].Value, ttt); } else if (parameters[i].Type == ICASMValueType.Address) { variable = RuntimeEngine.GetVariable((string)parameters[i].Value); } else if (parameters[i].Type == ICASMValueType.Identifier) { variable = RuntimeEngine.GetVariable("/" + (string)parameters[i].Value); } if (variable.Value == null) { continue; } _parametersToCallingFunction[i - 2] = variable.Value; _parameterTypesToCallingFunction[i - 2] = variable.Value.GetType(); } System.Type _typeOfCallingMethod = System.Type.GetType(_importPath); MethodInfo _callingMethodInfo = _typeOfCallingMethod.GetMethod(_importMethodName, _parameterTypesToCallingFunction); object _methodCallResult = _callingMethodInfo.Invoke(null, _parametersToCallingFunction); if (_methodCallResult != null) { string _methodResultValue = _methodCallResult.ToString(); ICASMValue icasm_methodReturnedValue = null; Variable _methodCallResultVariable = null; if ((icasm_methodReturnedValue = ICASMValue.ParseValue(_methodResultValue)) != null) { Data.Type ttt = ICASMValue.GetTypeFromPrimitiveType(icasm_methodReturnedValue.PrimitiveType); _methodCallResultVariable = new Variable(icasm_methodReturnedValue.Value, ttt); } else { _methodCallResultVariable = new Variable(_methodCallResult, new Data.Type("Object", "/")); } address = "/$SYSTEM$_temp" + _temps; RuntimeEngine.PutVariable(address, _methodCallResultVariable); result.Success = true; result.Data.Add(ICASMDirectiveType.CallDirective.ToString(), address); MemoryStack.Push(address); _temps++; } break; #endregion #region ReflectDirective case ICASMDirectiveType.ReflectDirective: if (tag == ICASMTagType.Help) { _ideoutput = "\n\tReflectDirective, usage - \n\treflect <address>\n\t\t-variable - reflect variable\n\t\t-pool - reflect variable pool\n\t\t-typespace - reflect typespace\n\t\t-type - reflect type"; result.Data.Add("$IDE_OUTPUT$", _ideoutput); break; } varname = parameters[0].Check(ICASMValueType.Address); if (tag == ICASMTagType.Variable) { Variable _reflectVariable = RuntimeEngine.GetVariable((string)varname.Value); _ideoutput = "\n\tReflect options - " + tag + ", " + _reflectVariable.Address; _ideoutput += "\n\tVariable Address - " + _reflectVariable.Address; _ideoutput += "\n\tVariable Value - " + _reflectVariable.Value; if (_reflectVariable.Type != null) { _ideoutput += "\n\tVariable Type - " + _reflectVariable.Type.Address + "\n\tTuples - "; } foreach (Address _reflectVariableTuple in _reflectVariable.TupleAddresses.Values) { _ideoutput += "\n\t\t" + _reflectVariableTuple; } result.Data.Add("$IDE_OUTPUT$", _ideoutput); } else if (tag == ICASMTagType.Pool) { VariablePool _reflectPool = RuntimeEngine.GetPool((string)varname.Value); _ideoutput = "\n\tReflect options - " + tag + ", " + _reflectPool.Address; _ideoutput += "\n\tVariable Address - " + _reflectPool.Address; _ideoutput += "\n\tVariablePools - " + _reflectPool.VariablePoolCount; foreach (VariablePool _pool in _reflectPool.VariablePools.Values) { _ideoutput += "\n\t\t" + _pool.Address; } _ideoutput += "\n\tVariables - " + _reflectPool.VariableCount; foreach (Variable _var in _reflectPool.Variables.Values) { _ideoutput += "\n\t\t" + _var.Address; } result.Data.Add("$IDE_OUTPUT$", _ideoutput); } else if (tag == ICASMTagType.Type) { Data.Type _reflectType = TypeEngine.GetType((string)varname.Value); _ideoutput = "\n\tReflect options - " + tag + ", " + _reflectType.Address; _ideoutput += "\n\tFunctions - " + _reflectType.FunctionCount; foreach (FunctionOverloads f in _reflectType.Functions.Values) { _ideoutput += "\n\t\t" + f.AccessKey + " (overloads " + f.Overloads.Count + ")"; for (int i = 0; i < f.Overloads.Count; i++) { _ideoutput += "\n\t\t\t" + i + " - "; foreach (Address typse in f.Overloads[i].Parameters) { _ideoutput += "[" + typse.FullPath + "] "; } } } result.Data.Add("$IDE_OUTPUT$", _ideoutput); } else if (tag == ICASMTagType.Typespace) { } break; #endregion #region JumpDirective case ICASMDirectiveType.JumpDirective: varname = parameters[0]; int step = (int)varname.Value; result.Success = true; result.Data.Add(ICASMDirectiveType.JumpDirective.ToString(), step); break; #endregion } if (!_executingFunction) { while (MemoryStack.Count != 0) { Address addr = MemoryStack.Pop(); if (result.Data.ContainsKey("CallDirective")) { Address addr_c1 = (Address)result.Data["CallDirective"]; if (addr_c1.Equals(addr)) { continue; } } else if (result.Data.ContainsKey("ReturnDirective")) { if (result.Data["ReturnDirective"].Equals(addr.FullPath)) { continue; } } VariablePool pool = RuntimeEngine.VariablePool; RuntimeEngine.GetPool(addr.Parent).Pull(addr.Name, true); } } return(result); }
private async Task <bool> ExecuteSingleLine() { if (_callStack.Count == 0) { return(false); } _callStack.Last.Offset = Script.CurrentPosition; var code = Script.ReadOperationCode(); if (code == null) { return(false); } switch (code) { case OperationCode.LDC_I4_0: case OperationCode.LDC_I4_1: case OperationCode.LDC_I4_2: case OperationCode.LDC_I4_3: case OperationCode.LDC_I4_4: case OperationCode.LDC_I4_5: case OperationCode.LDC_I4_6: case OperationCode.LDC_I4_7: case OperationCode.LDC_I4_8: MemoryStack.Push(new IntegerValue { value = (byte)code - (byte)OperationCode.LDC_I4_0 }); break; case OperationCode.LDC_I4: MemoryStack.Push(new IntegerValue { value = Script.ReadInteger() }); break; case OperationCode.LDC_R4_0: case OperationCode.LDC_R4_025: case OperationCode.LDC_R4_05: case OperationCode.LDC_R4_075: case OperationCode.LDC_R4_1: case OperationCode.LDC_R4_125: case OperationCode.LDC_R4_15: case OperationCode.LDC_R4_175: case OperationCode.LDC_R4_2: case OperationCode.LDC_R4_225: case OperationCode.LDC_R4_25: case OperationCode.LDC_R4_275: case OperationCode.LDC_R4_3: case OperationCode.LDC_R4_325: case OperationCode.LDC_R4_35: case OperationCode.LDC_R4_375: case OperationCode.LDC_R4_4: case OperationCode.LDC_R4_425: case OperationCode.LDC_R4_45: case OperationCode.LDC_R4_475: case OperationCode.LDC_R4_5: case OperationCode.LDC_R4_525: case OperationCode.LDC_R4_55: case OperationCode.LDC_R4_575: MemoryStack.Push(new FloatValue { value = ((byte)code - (byte)OperationCode.LDC_R4_0) * 0.25F }); break; case OperationCode.LDC_R4: MemoryStack.Push(new FloatValue { value = Script.ReadFloat() }); break; case OperationCode.LDSTR: MemoryStack.Push(new StringValue { value = Script.ReadStringConstant() }); break; case OperationCode.LDENTRY: LoadEntrance(); break; case OperationCode.LDSTT: LoadTranslate(); break; case OperationCode.LDNUL: LoadNull(); break; case OperationCode.LDLOC: LoadVariable(VariableSearchMode.All); break; case OperationCode.LDCON: LoadVariable(VariableSearchMode.OnlyConstant); break; case OperationCode.LDT: MemoryStack.Push(new BooleanValue { value = true }); break; case OperationCode.LDF: MemoryStack.Push(new BooleanValue { value = false }); break; case OperationCode.CALL: await CreatePluginCall(); break; case OperationCode.POP: MemoryStack.Pop(); break; case OperationCode.DIALOGUE: await CreateDialogue(); break; case OperationCode.BVAL: CreateToBoolean(); break; case OperationCode.ADD: CreateBinaryOperation(OperatorType.Add); break; case OperationCode.SUB: CreateBinaryOperation(OperatorType.Minus); break; case OperationCode.MUL: CreateBinaryOperation(OperatorType.Multiply); break; case OperationCode.DIV: CreateBinaryOperation(OperatorType.Divide); break; case OperationCode.NEG: CreateToNegative(); break; case OperationCode.EQL: CreateBinaryOperation(OperatorType.LogicEqualsTo); break; case OperationCode.CGE: CreateBinaryOperation(OperatorType.NotLessThan); break; case OperationCode.CGT: CreateBinaryOperation(OperatorType.GreaterThan); break; case OperationCode.CLE: CreateBinaryOperation(OperatorType.NotGreaterThan); break; case OperationCode.CLT: CreateBinaryOperation(OperatorType.LesserThan); break; case OperationCode.STLOC: SetVariable(VariableSearchMode.All); break; case OperationCode.STCON: SetVariable(VariableSearchMode.OnlyConstant); break; case OperationCode.STMEM: SetMemory(); break; case OperationCode.PICK: CreateBinaryOperation(OperatorType.PickChild); break; case OperationCode.SCOPE: CreateScope(); break; case OperationCode.LEAVE: LeaveScope(); break; case OperationCode.RET: await ReturnToPreviousScript(); if (_callStack.Count == 0) { return(false); } break; case OperationCode.FUNC: await CreateFunctionCall(); break; case OperationCode.BF: if (MemoryStack.Pop() is BooleanValue condition && condition.value == false) { Move(); } break; case OperationCode.BR: Move(); break; case OperationCode.LOAD: await Load(); break; case OperationCode.EXP: Export(); break; default: throw new ArgumentOutOfRangeException(); } return(true); }