/// <summary> /// Remove a <see cref="Variable"/> and its references /// </summary> /// <param name="expr"> <see cref="Expression"/> resulting in a <see cref="Variable"/></param> /// <returns> <see cref="NullVar"/> (equivalent of null/void)</returns> private static NullVar deleteVarFunction(Expression expr) { // evaluate every expression Variable variable = expr.evaluate(); string var_name = variable.getName(); // delete var Debugging.assert(Global.variableExistsInCurrentScope(var_name), new AquilaExceptions.NameError($"Variable name \"{var_name}\" does not exist in the current Context")); // remove the Tracer if is traced if (variable.isTraced()) { // remove from the usable variables Global.usable_variables.Remove(var_name); // Deletion Alteration var alter = new Alteration("delete_var", variable, null, new dynamic[] {}); // Update the tracer with the death event variable.tracer.update(new Event(alter)); // Remove the tracer Global.var_tracers.Remove(variable.tracer); } // remove from the dict Global.getCurrentDict().Remove(var_name); return(new NullVar()); }
private static DataTree variableDataTree(Variable v) { string var_type = v.getTypeString(); string value = v.ToString(); string is_const = v.isConst().ToString(); string is_traced = v.isTraced().ToString(); return(new DataTree(v.getName(), null, new List <string> { "Name: " + v.getName(), "Type: " + var_type, "Value: " + value, "Const: " + is_const, "Traced: " + is_traced })); }
/// <summary> /// Changes the tracing mode of a variable. If it is not traced, trace it beforehand /// </summary> /// <param name="var_expr"> Traced variable</param> /// <param name="mode_expr"> Mode (expresion content as string)</param> /// <returns> <see cref="NullVar"/> (equivalent of null/void)</returns> private static NullVar traceModeFunction(Expression var_expr, Expression mode_expr) { Tracer.printTrace($"Tracing \"{var_expr.expr}\" with mode \"{mode_expr.expr}\""); // get the variable Variable var = var_expr.evaluate(); // change the tracing mode (using in Alteration.mode) var.trace_mode = mode_expr.expr; // trace it if not already traced if (!var.isTraced()) { var.startTracing(); } return(new NullVar()); }
public override void execute() { setContext(); int context_integrity_check = Context.getStatusStackCount(); // the tracing instruction execution doesn't take any Tracer.updateTracers() calls foreach (Expression traced_expr in _traced_vars) { Variable traced_var = traced_expr.evaluate(); if (traced_var.isTraced()) { Debugging.print("trying to trace a variable that is already traced: " + traced_expr.expr); continue; } traced_var.startTracing(); } // Smooth Context Context.resetUntilCountReached(context_integrity_check); Context.reset(); }
/// <summary> /// Process the <see cref="Event"/> /// </summary> /// <param name="event_"> <see cref="Event"/> that should be processed</param> public override void update(Event event_) { // blocked context ? if (Context.isFrozen() && !Global.getSetting("allow tracing in frozen context")) { printTrace("Context is blocked in function tracer update call. Normal behaviour ?"); return; } // checks Debugging.assert(event_ != null); // extract events.Push(event_); printTrace("event stack size: " + events.Count); Alteration alter = event_.alter; Variable affected = alter.affected; Debugging.assert(affected != null); Debugging.assert(affected.isTraced()); affected.tracer.update(new Event(new Alteration(traced_func, affected, event_.alter.main_value, event_.alter.minor_values))); //! just push event_ ! printTrace("updated all in function tracer update"); }
private static DataTree variableDataTree(string variable) { if (!Global.variableExistsInCurrentScope(variable)) { return(new DataTree(variable, null, new List <string> { $"The variable \"{variable}\" does not exist in the current scope" })); } Variable v = Global.variableFromName(variable); string var_type = v.getTypeString(); string value = v.ToString(); string is_const = v.isConst().ToString(); string is_traced = v.isTraced().ToString(); return(new DataTree(variable, null, new List <string> { "Name: " + variable, "Type: " + var_type, "Value: " + value, "Const: " + is_const, "Traced: " + is_traced })); }
/// <summary> /// Process the input from the interpreter. /// If the input is one of the interactive-mode-only commands, the command should not /// be executed by the interpreter but will be executed by this function manually. /// </summary> /// <param name="input"> command line from the interactive-mode</param> /// <returns> should the command be executed ?</returns> internal static bool processInterpreterInput(string input) { switch (input) { case "help": { Global.stdoutWriteLine("All existing interactive-mode-only commands:"); // ReSharper disable once RedundantExplicitArrayCreation foreach (string command in new string[] { "help", "exit", "reset_env", "clear", // base interactive-mode "exec", "exec_info", // exec "debug", "trace_debug", "parse_debug", // debugging (enable/disable) "eval %expr", // expr "var %var_name", "vars", "$%var_name", // variables // ReSharper disable once StringLiteralTypo "funcs", "df_funcs", // functions "type", // ? "trace_info", "trace_uniq_stacks", "rewind %n %var_name", "peek_trace $%traced_value", // trace "get_context", "set_status", "set_info_null", "reset_context", // context "scope_info", // scope "show-settings", // settings }) { Global.stdoutWriteLine(" -> " + command); } return(false); } case "clear": if (!Global.getSetting("redirect debug stout & stderr")) { Console.Clear(); } return(false); case "vars": { Global.stdoutWriteLine("Global Variables:"); foreach (var pair in Global.getGlobalVariables()) { Global.stdoutWriteLine("\t" + pair.Key + " : " + pair.Value); } int i = 0; Global.stdoutWriteLine("Local Scope Variables:"); foreach (var dict in Global.getCurrentDictList()) { i++; foreach (var pair in dict) { Global.stdoutWrite(new string('\t', i)); Global.stdoutWrite(pair.Key + " : "); Global.stdoutWriteLine(pair.Value.ToString()); } } return(false); } // ReSharper disable once StringLiteralTypo case "funcs": { Global.stdoutWriteLine("User defined functions:"); foreach (var pair in Functions.user_functions) { Global.stdoutWriteLine(" * " + pair.Key + (pair.Value.isRec() ? " : [rec] " : " : ") + "(" + pair.Value.func_args.Count + ") -> " + pair.Value.getType()); } return(false); } case "df_funcs": Global.stdoutWriteLine("Default (predefined) functions:"); foreach (var pair in Functions.functions_dict) { MethodInfo method = pair.Value.GetMethodInfo(); Global.stdoutWriteLine(" * " + pair.Key + " [?] : (" + method.GetParameters().Length + ") -> " + method.ReturnType); } return(false); case "debug": Global.setSetting("debug", !Global.getSetting("debug")); return(false); case "trace_debug": Global.setSetting("trace debug", !Global.getSetting("trace debug")); return(false); case "parse_debug": Global.setSetting("parse debug", !Global.getSetting("parse debug")); return(false); case "trace_info": { Global.stdoutWriteLine("var tracers:"); foreach (VarTracer tracer in Global.var_tracers) { Global.stdoutWriteLine(" - var : " + (tracer.getTracedObject() as Variable).getName()); Global.stdoutWriteLine(" - stack : " + tracer.getStackCount()); Global.stdoutWriteLine(" - updated : " + tracer.last_stack_count); } Global.stdoutWriteLine("func tracers:"); foreach (FuncTracer tracer in Global.func_tracers) { Global.stdoutWriteLine(" - func : " + tracer.getTracedObject()); Global.stdoutWriteLine(" - stack : " + tracer.getStackCount()); } return(false); } case "trace_uniq_stacks": Global.var_tracers[0].printEventStack(); return(false); case "reset_env": Global.resetEnv(); Global.stdoutWriteLine(" [!] Global Environment reset"); return(false); case "get_context": { int status = Context.getStatus(); Context.StatusEnum status_quote = (Context.StatusEnum)status; object info = Context.getInfo(); bool blocked = Context.isFrozen(); bool enabled = Global.getSetting("fail on context assertions"); Global.stdoutWriteLine("status : " + status); Global.stdoutWriteLine("quote : " + status_quote); Global.stdoutWriteLine("info : " + info); Global.stdoutWriteLine("blocked : " + blocked); Global.stdoutWriteLine("asserts : " + enabled); return(false); } case "set_info_null": Context.setInfo(null); return(false); case "reset_context": Context.reset(); return(false); case "type": Global.stdoutWriteLine("type of NullVar: " + typeof(NullVar)); Global.stdoutWriteLine("type of Variable: " + typeof(Variable)); Global.stdoutWriteLine("type of Integer: " + typeof(Integer)); return(false); case "scope_info": Global.stdoutWriteLine("local scope depth: " + Global.getLocalScopeDepth()); Global.stdoutWriteLine("main scope depth: " + Global.getMainScopeDepth()); return(false); case "show-settings": foreach (var pair in Global.getSettings()) { Global.stdoutWriteLine($" - {pair.Key} : {pair.Value}"); } return(false); } if (input[0] == '$' && Global.variableExistsInCurrentScope(input.Substring(1))) { Global.stdoutWriteLine(Global.variableFromName(input.Substring(1)).ToString()); return(false); } if (input.StartsWith("set_status ")) { int status = int.Parse(input.Substring(11)); Context.setStatus((Context.StatusEnum)status); return(false); } if (input.StartsWith("eval ")) { Variable var_ = Expression.parse(input.Substring(5)); Global.stdoutWriteLine(var_.ToString()); return(false); } if (input.StartsWith("var ")) { string var_name = input.Substring(4); var_name = StringUtils.normalizeWhiteSpaces(var_name); if (var_name == "") { return(false); } Variable var_ = Global.variableFromName(var_name); Global.stdoutWriteLine("name : " + var_.getName()); Global.stdoutWriteLine("type : " + var_.getTypeString()); Global.stdoutWriteLine("const : " + var_.isConst()); Global.stdoutWriteLine("assigned : " + var_.assigned); Global.stdoutWriteLine("value : " + var_); Global.stdoutWriteLine("traced : " + var_.isTraced()); Global.stdoutWriteLine("^ mode : " + var_.trace_mode); if (var_ is NumericalValue value) { Global.stdoutWriteLine("*source : " + StringUtils.dynamic2Str(value.source_vars)); } return(false); } if (input.StartsWith("rewind")) { string[] splitted = input.Split(' '); if (splitted.Length == 3) { if (!int.TryParse(splitted[1], out int n)) { Global.stdoutWriteLine("cannot read n"); return(false); } string var_name = splitted[2]; Variable var_ = Expression.parse(var_name); if (!var_.isTraced()) { Global.stdoutWriteLine("Variable is not traced! Use the \"trace\" instruction to start tracing variables"); return(false); } var_.tracer.rewind(n); return(false); } Global.stdoutWriteLine("split count does not match 3"); return(false); } if (input.StartsWith("peek_trace")) { if (input.Length < 11) { return(false); } Variable var_ = Expression.parse(input.Substring(11)); if (!var_.isTraced()) { Global.stdoutWriteLine("Variable is not traced! Use the \"trace\" instruction to start tracing variables"); return(false); } Alteration alter = var_.tracer.peekEvent().alter; Global.stdoutWriteLine("name : " + alter.name); Global.stdoutWriteLine("variable : " + alter.affected.getName()); Global.stdoutWriteLine("main value : " + StringUtils.dynamic2Str(alter.main_value)); Global.stdoutWriteLine("num minor : " + alter.minor_values.Length); Global.stdoutWriteLine("minor values : " + StringUtils.dynamic2Str(alter.main_value)); Global.stdoutWriteLine("stack count : " + var_.tracer.getStackCount()); Global.stdoutWriteLine("updated : " + var_.tracer.last_stack_count); return(false); } if (input.StartsWith("#")) { Global.stdoutWriteLine("Handling macro parameter"); if (!input.Contains(' ')) { Parser.handleMacro(input.Substring(1), null); return(false); } int index = input.IndexOf(' '); // extract the key & value pair string value = input.Substring(index); input = input.Substring(1, index); // purge pair value = StringUtils.normalizeWhiteSpaces(value); input = StringUtils.normalizeWhiteSpaces(input); Parser.handleMacro(input, value); return(false); } return(true); }
/// <summary> /// Get the value at the index in a list /// </summary> /// <param name="list_expr"> The list</param> /// <param name="index_list_expr"> The index</param> /// <returns></returns> private static Variable listAtFunction(Expression list_expr, Expression index_list_expr) { // extract list Variable list_var = list_expr.evaluate(); Debugging.assert(list_var is DynamicList); // TypeError DynamicList list = list_var as DynamicList; // extract index Variable index_list_var = index_list_expr.evaluate(); Debugging.assert(index_list_var is DynamicList); // TypeError DynamicList index_list = index_list_var as DynamicList; /*// test run ? * if (Global.getSetting("test mode")) * { * // function to add to index dict * void addToIndexList(string var_name) * { * if (var_name == "") return; * var index_var_name_list = (List<string>) Global.test_values["index values"]; * // variable name already in index dict ? * if (index_var_name_list.Contains(var_name)) return; * // add to index dict * index_var_name_list.Add(var_name); * } * }*/ // access at index Variable result = list.atIndexList(index_list); // trace list if (!list_var.isTraced()) { return(result); } Tracer.printTrace("list_at last event: " + list_var.tracer.peekEvent()); handleValueFunctionTracing("list_at", list, new dynamic[] { index_list.getValue() }); // trace index //Tracer.printTrace("tmp list at ", index_list.toString()); /*var index_list_var_value = index_list_var.getValue(); * for (int i = 0; i < index_list_var_value.Count; i++) * { * Variable index_var = index_list_var_value[i]; * var numeric_index = (NumericalValue) index_var; * NumericalValue source = numeric_index.getTracedSource(); * if (source == null) * { * Tracer.printTrace("tmp index without source var"); * numeric_index.setName($"comp /{i}/"); * list.tracer.update(new Event(new Alteration("tmp_list_at", numeric_index, * numeric_index.getValue(), new[] {list.getName(), index_list.getValue()}, * mode:"index"))); * continue; * } * * Tracer.printTrace("Traced source var: " + source.getName()); * numeric_index.setName($"comp /{i}/"); * list.tracer.update(new Event(new Alteration("tmp_list_at", numeric_index, * numeric_index.getValue(), new[] {list.getName(), index_list.getValue()}, * mode:"index"))); * }*/ return(result); }