+ var new_variable = get_variable_of_type_with_value(variable.mtype.to_s, value)
+ if new_variable != null
+ then
+ var keys = frame.map.keys
+ for key in keys
+ do
+ if frame.map[key] == variable
+ then
+ frame.map[key] = new_variable
+ end
+ end
+ end
+ end
+
+ # Modifies the value of a variable contained in a MutableInstance
+ fun modify_argument_of_complex_type(papa: MutableInstance, attribute: MAttribute, value: String)
+ do
+ var final_variable = papa.attributes[attribute]
+ var type_of_variable = final_variable.mtype.to_s
+ var new_variable = get_variable_of_type_with_value(type_of_variable, value)
+ if new_variable != null
+ then
+ papa.attributes[attribute] = new_variable
+ end
+ end
+
+ #######################################################################
+ ## Variable generator functions ##
+ #######################################################################
+
+ # Returns a new variable of the type 'type_of_variable' with a value of 'value'
+ fun get_variable_of_type_with_value(type_of_variable: String, value: String): nullable Instance
+ do
+ if type_of_variable == "Int" then
+ return get_int(value)
+ else if type_of_variable == "Float" then
+ return get_float(value)
+ else if type_of_variable == "Bool" then
+ return get_bool(value)
+ else if type_of_variable == "Char" then
+ return get_char(value)
+ end
+
+ return null
+ end
+
+ # Returns a new int instance with value 'value'
+ fun get_int(value: String): nullable Instance
+ do
+ if value.is_numeric then
+ return int_instance(value.to_i)
+ else
+ return null
+ end
+ end
+
+ # Returns a new float instance with value 'value'
+ fun get_float(value:String): nullable Instance
+ do
+ if value.is_numeric then
+ return float_instance(value.to_f)
+ else
+ return null
+ end
+ end
+
+ # Returns a new char instance with value 'value'
+ fun get_char(value: String): nullable Instance
+ do
+ if value.length >= 1 then
+ return char_instance(value.chars[0])
+ else
+ return null
+ end
+ end
+
+ # Returns a new bool instance with value 'value'
+ fun get_bool(value: String): nullable Instance
+ do
+ if value.to_lower == "true" then
+ return self.true_instance
+ else if value.to_lower == "false" then
+ return self.false_instance
+ else
+ print "Invalid value, a boolean must be set at \"true\" or \"false\""
+ return null
+ end
+ end
+
+end
+
+redef class AMethPropdef
+
+ # Same as call except it will copy local variables of the parent frame to the frame defined in this call.
+ # Not supposed to be used by anyone else than the Debugger.
+ private fun rt_call(v: Debugger, mpropdef: MMethodDef, args: Array[Instance]): nullable Instance
+ do
+ var f = new Frame(self, self.mpropdef.as(not null), args)
+ var curr_instances = v.frame.map
+ for i in curr_instances.keys do
+ f.map[i] = curr_instances[i]
+ end
+ call_commons(v,mpropdef,args,f)
+ var currFra = v.frames.shift
+ for i in curr_instances.keys do
+ if currFra.map.keys.has(i) then
+ curr_instances[i] = currFra.map[i]
+ end
+ end
+ if v.returnmark == f then
+ v.returnmark = null
+ var res = v.escapevalue
+ v.escapevalue = null
+ return res
+ end
+ return null
+
+ end
+end
+
+# Traces the modifications of an object linked to a certain frame
+private class TraceObject
+
+ # Map of the local names bound to a frame
+ var trace_map: HashMap[Frame, String]
+ # Decides if breaking or printing statement when the variable is encountered
+ var break_on_encounter: Bool
+
+ init(break_on_encounter: Bool)
+ do
+ trace_map = new HashMap[Frame, String]
+ self.break_on_encounter = break_on_encounter
+ end
+
+ # Adds the local alias for a variable and the frame bound to it
+ fun add_frame_variable(frame: Frame, variable_name: String)
+ do
+ self.trace_map[frame] = variable_name
+ end
+
+ # Checks if the prompted variable is traced in the specified frame
+ fun is_variable_traced_in_frame(variable_name: String, frame: Frame): Bool
+ do
+ if self.trace_map.has_key(frame) then
+ if self.trace_map[frame] == variable_name then
+ return true
+ end
+ end
+
+ return false