Skip to content

Commit 45b754c

Browse files
committed
Adding the breakpoint feature
Adding the Possibility to add and remove breakpoint during the interpretationNew breakpoint future Signed-off-by: Florian Deljarry <[email protected]>
1 parent 9b5774b commit 45b754c

File tree

9 files changed

+150
-20
lines changed

9 files changed

+150
-20
lines changed

share/man/nit.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ Each time a method is invoked for the first time, its information is printed on
8686

8787
This option helps the user to have a simplified but humanly readable overview of the behavior of a particular program execution.
8888

89+
### `--break`
90+
Start the program to indicate the breakpoints for the interpretation.
91+
92+
Print the menu to add or remove some breakpoint
93+
8994
## DEBUGGER OPTIONS
9095

9196
### `-d`

src/interpreter/naive_interpreter.nit

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,14 @@ private import frontend::explain_assert_api
2727
redef class ToolContext
2828
# --discover-call-trace
2929
var opt_discover_call_trace = new OptionBool("Trace calls of the first invocation of methods", "--discover-call-trace")
30+
# --stop-at
31+
var opt_stop = new OptionBool("Start the program to indicate the breakpoints for the interpretation","--break")
3032

3133
redef init
3234
do
3335
super
3436
self.option_context.add_option(self.opt_discover_call_trace)
37+
self.option_context.add_option(self.opt_stop)
3538
end
3639
end
3740

src/interpreter/step_interpreter.nit

Lines changed: 124 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,20 @@ redef class NaiveInterpreter
3636
# This flag is used to launch setp by step interpreter
3737
var debug_flag = false
3838

39+
# The breakpoint tool
40+
private var breakpoint : Breakpoints
41+
42+
# The user entry is use for the step by step execution
3943
private var user_entry = ""
4044

45+
init do
46+
super
47+
breakpoint = new Breakpoints(self.modelbuilder)
48+
if modelbuilder.toolcontext.opt_stop.value then
49+
breakpoint.define_breakpoints
50+
end
51+
end
52+
4153
# Print the commands to execute step-by-step execution
4254
fun print_instruction_debug do
4355
print "────────────────────────────────────────────────────────────────────"
@@ -85,6 +97,10 @@ redef class NaiveInterpreter
8597

8698
# Main function of the step-by-step execution this method is called after each instruction
8799
fun step_execution(recv : nullable Instance) do
100+
if frame isa InterpreterFrame and breakpoint.is_breakpoint(frame.current_node.location) then
101+
self.deep_old_frame = frames.length
102+
self.debug_flag = true
103+
end
88104
if self.debug_flag then
89105
init_debug_mode
90106
if recv != null then
@@ -102,6 +118,9 @@ redef class NaiveInterpreter
102118
self.object_inspector.print_pin_list_value
103119
self.user_entry = stdin.read_line
104120
self.step_execution(recv)
121+
else if user_entry == "break" then
122+
self.user_entry = ""
123+
self.breakpoint.define_breakpoints
105124
else if user_entry == "continue" then
106125
self.user_entry = ""
107126
self.debug_flag = false
@@ -111,13 +130,17 @@ redef class NaiveInterpreter
111130
end
112131
end
113132

133+
# Step into method
134+
# He execute the step-by-step execution in the method
114135
fun step_into do
115136
print "{self.get_color_line}"
116137
deep_old_frame = frames.length
117138
user_entry = stdin.read_line
118139
old_line_number = frame.current_node.location.line_start
119140
end
120141

142+
# Step over method
143+
# He keep the step-by-step execution in the method
121144
fun step_over do
122145
# Check if the new instruction is in the same method or the new instruction is in the appellant method
123146
# Check the line to execute all instruction line
@@ -126,7 +149,7 @@ redef class NaiveInterpreter
126149
end
127150
end
128151

129-
redef fun expr(n: AExpr): nullable Instance
152+
redef fun expr(n)
130153
do
131154
var i = super
132155
if i != null then step_execution(i)
@@ -142,6 +165,105 @@ redef class NaiveInterpreter
142165
super
143166
end
144167
end
168+
169+
class Breakpoints
170+
171+
# The map representing the breakpoints with the links of the source file and array of lines
172+
private var breakpoints_list = new ArrayMap[SourceFile,Array[Int]]
173+
174+
# The modelbuilder is stored to check the module
175+
var modelbuilder: ModelBuilder
176+
177+
redef fun to_s do
178+
var return_list = ""
179+
for file, lines in breakpoints_list do
180+
return_list += "File : {file.filename} lines : {lines} \n"
181+
end
182+
return return_list
183+
end
184+
185+
# Is there location is a breakpoint?
186+
fun is_breakpoint(location : Location): Bool do
187+
if breakpoints_list.has_key(location.file) then
188+
return breakpoints_list[location.file].has(location.line_start)
189+
end
190+
return false
191+
end
192+
193+
# Method to interact with the breakpoints list
194+
fun define_breakpoints do
195+
print "────────────────────────────────────────────────────────────────────"
196+
print "Breakpoints list"
197+
print "{self.to_s}"
198+
print "For add enter" + " 'break [file name] [line number,...]'".yellow + " for remove " + "'clear [file name] [line number,...]'".yellow
199+
print "To leave the breakpoint mode enter " + "leave".yellow
200+
print "────────────────────────────────────────────────────────────────────"
201+
var user_entry = stdin.read_line.split(" ")
202+
if user_entry.length%3 == 0 then
203+
for x in [0 .. user_entry.length[.step(3) do
204+
var action = user_entry[x]
205+
var file = check_file(user_entry[x+1])
206+
var lines = check_line(user_entry[x+2])
207+
if file != null then
208+
if action == "break" then
209+
add_breakpoints(file,lines)
210+
else if action == "clear" then
211+
remove_breakpoint(file,lines)
212+
else
213+
print "Command unknown"
214+
end
215+
end
216+
end
217+
else
218+
print "Error on the number of parameters"
219+
end
220+
end
221+
222+
# Check in the list of modules the source file exists with the name of the parameter.
223+
# If it exists, return this.
224+
fun check_file(name: String) : nullable SourceFile do
225+
for mmodule in modelbuilder.identified_modules do
226+
if mmodule.location.file.filename.search(name) != null then return mmodule.location.file
227+
end
228+
print "File not found"
229+
return null
230+
end
231+
232+
# Check the user input line.
233+
fun check_line(string_line: String) : Array[Int] do
234+
var lines = string_line.split(",")
235+
var return_array = new Array[Int]
236+
for line in lines do
237+
if line.is_int then
238+
return_array.add(line.to_i)
239+
end
240+
end
241+
return return_array
242+
end
243+
244+
# Method to add an breakpoint
245+
# Take a source file and an lines array representing the breakpoints
246+
fun add_breakpoints(file : SourceFile,lines : Array[Int])do
247+
if not lines.is_empty then
248+
if breakpoints_list.has_key(file) then
249+
breakpoints_list[file].add_all(lines)
250+
else
251+
breakpoints_list[file] = lines
252+
end
253+
end
254+
end
255+
256+
# Method to remove an breakpoint
257+
# Take a source file and an lines array representing the breakpoints
258+
fun remove_breakpoint(file : SourceFile,lines : Array[Int])do
259+
if not lines.is_empty then
260+
for line in lines do
261+
breakpoints_list[file].remove_all(line)
262+
end
263+
end
264+
end
265+
end
266+
145267
# Represents the inspected object with the relationship between the instance and the name of the object (if it exists)
146268
class ObjectInspected
147269
# The instance of the inspected object.
@@ -313,7 +435,7 @@ class ObjectInspector
313435
end
314436

315437
redef class AMethPropdef
316-
redef fun intern_call(v: NaiveInterpreter, mpropdef: MMethodDef, args: Array[Instance]): nullable Instance
438+
redef fun intern_call(v,mpropdef,args)
317439
do
318440
var pname = mpropdef.mproperty.name
319441
if pname == "inspect_o" then

tests/sav/error_class_glob.res

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
../lib/core/kernel.nit:32,1--225,3: Error: `kernel$Object` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
2-
../lib/core/kernel.nit:227,1--300,3: Error: `kernel$Sys` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
3-
../lib/core/kernel.nit:313,1--371,3: Error: `kernel$Comparable` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
4-
../lib/core/kernel.nit:373,1--410,3: Error: `kernel$Discrete` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
5-
../lib/core/kernel.nit:412,1--429,3: Error: `kernel$Cloneable` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
6-
../lib/core/kernel.nit:431,1--486,3: Error: `kernel$Numeric` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
7-
../lib/core/kernel.nit:492,1--515,3: Error: `kernel$Bool` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
8-
../lib/core/kernel.nit:517,1--599,3: Error: `kernel$Float` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
9-
../lib/core/kernel.nit:601,1--700,3: Error: `kernel$Byte` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
10-
../lib/core/kernel.nit:702,1--883,3: Error: `kernel$Int` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
11-
../lib/core/kernel.nit:885,1--1064,3: Error: `kernel$Char` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
12-
../lib/core/kernel.nit:1066,1--1083,3: Error: `kernel$Pointer` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
13-
../lib/core/kernel.nit:1085,1--1094,3: Error: `kernel$Task` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
1+
../lib/core/kernel.nit:32,1--230,3: Error: `kernel$Object` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
2+
../lib/core/kernel.nit:232,1--305,3: Error: `kernel$Sys` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
3+
../lib/core/kernel.nit:318,1--376,3: Error: `kernel$Comparable` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
4+
../lib/core/kernel.nit:378,1--415,3: Error: `kernel$Discrete` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
5+
../lib/core/kernel.nit:417,1--434,3: Error: `kernel$Cloneable` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
6+
../lib/core/kernel.nit:436,1--491,3: Error: `kernel$Numeric` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
7+
../lib/core/kernel.nit:497,1--520,3: Error: `kernel$Bool` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
8+
../lib/core/kernel.nit:522,1--604,3: Error: `kernel$Float` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
9+
../lib/core/kernel.nit:606,1--705,3: Error: `kernel$Byte` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
10+
../lib/core/kernel.nit:707,1--888,3: Error: `kernel$Int` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
11+
../lib/core/kernel.nit:890,1--1069,3: Error: `kernel$Char` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
12+
../lib/core/kernel.nit:1071,1--1088,3: Error: `kernel$Pointer` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?
13+
../lib/core/kernel.nit:1090,1--1099,3: Error: `kernel$Task` does not specialize `module_0$Object`. Possible duplication of the root class `Object`?

tests/sav/nitce/fixme/base_gen_reassign_alt4.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:723)
1+
Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:728)
22
11
33
21
44
31

tests/sav/nitce/fixme/base_gen_reassign_alt5.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:723)
1+
Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:728)
22
11
33
21
44
31

tests/sav/nitce/fixme/base_gen_reassign_alt6.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:723)
1+
Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:728)
22
11
33
21
44
31

tests/sav/nituml_args3.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ digraph G {
1212
fontsize = 8
1313
]
1414
Object [
15-
label = "{interface\nObject||+ object_id(): Int\l+ is_same_type(other: Object): Bool\l+ is_same_instance(other: nullable Object): Bool\l+ ==(other: nullable Object): Bool\l+ !=(other: nullable Object): Bool\l+ output()\l+ output_class_name()\l+ hash(): Int\l+ sys(): Sys\l+ init()\l}"
15+
label = "{interface\nObject||+ object_id(): Int\l+ is_same_type(other: Object): Bool\l+ is_same_instance(other: nullable Object): Bool\l+ ==(other: nullable Object): Bool\l+ !=(other: nullable Object): Bool\l+ output()\l+ output_class_name()\l+ hash(): Int\l+ inspect_o()\l+ sys(): Sys\l+ init()\l}"
1616
]
1717

1818
Sys [

tests/sav/nituml_args4.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ digraph G {
1212
fontsize = 8
1313
]
1414
Object [
15-
label = "{interface\nObject||+ object_id(): Int\l+ is_same_type(other: Object): Bool\l+ is_same_instance(other: nullable Object): Bool\l+ ==(other: nullable Object): Bool\l+ !=(other: nullable Object): Bool\l+ output()\l+ output_class_name()\l+ hash(): Int\l+ sys(): Sys\l+ init()\l}"
15+
label = "{interface\nObject||+ object_id(): Int\l+ is_same_type(other: Object): Bool\l+ is_same_instance(other: nullable Object): Bool\l+ ==(other: nullable Object): Bool\l+ !=(other: nullable Object): Bool\l+ output()\l+ output_class_name()\l+ hash(): Int\l+ inspect_o()\l+ sys(): Sys\l+ init()\l}"
1616
]
1717

1818
Sys [

0 commit comments

Comments
 (0)