rubymotionlisp 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 490db605233e6a3d1bae6cf46d8e1409b40a574f
4
- data.tar.gz: e824c1b27bc82ef51da8e3eeb5361afba60b22e8
3
+ metadata.gz: 9cd26bad53833fe2ee3f15b08e989595f835762a
4
+ data.tar.gz: 8bc181d5653cb58ce352f6ca4e1ff79a0d66e6fc
5
5
  SHA512:
6
- metadata.gz: fb3ccd4f6c3303ced67a6b5d952560019938644e0234db70ccfaf5d959f4ba2a4e75eb6608a1e8b2e647d5c34968232b69fff7c1f50b8159b75b2611b3d65ee7
7
- data.tar.gz: cb6574334fac4294650d0d9ceaed4e878e7e42d103570005018e8727719f2fbe51d9bf00aa7c3fd4b73e1899685bbe315c6556213058f69ed40dcbc3df331e40
6
+ metadata.gz: 85e9ff41520cad81442bb0299bd9087e296dc3cc250df0f9b316d1201201d27ab585f9770cb96b1590833c3d50e49e364537b9321b1a79b06a5e9dba93d1428a
7
+ data.tar.gz: 5e27bb3023a10c31605901fcfb9c8493a441371129e0a59c50389d00b73ee928170299096be4a2a689fb0808eeb228e3efa8c4b13e23f28c7ca072c7b7972b4a
@@ -14,12 +14,12 @@ module Lisp
14
14
  end
15
15
 
16
16
  def self.acons_impl(args, env)
17
- raise "acons require at least 2 or 3 arguments" unless args.length == 2 || args.length == 3
17
+ return Lisp::Debug.process_error("acons require at least 2 or 3 arguments", env) unless args.length == 2 || args.length == 3
18
18
  key = args.car.evaluate(env)
19
19
  value = args.cadr.evaluate(env)
20
20
  alist = args.length == 2 ? nil : args.caddr.evaluate(env)
21
21
  alist = Lisp::AList.from_list(alist) if !alist.nil? && alist.list? && !alist.alist?
22
- raise "the last argument to acons has to be an association list" unless alist.nil? || alist.alist?
22
+ return Lisp::Debug.process_error("the last argument to acons has to be an association list", env) unless alist.nil? || alist.alist?
23
23
 
24
24
  if alist.nil?
25
25
  Lisp::AList.new({key => value})
@@ -29,44 +29,44 @@ module Lisp
29
29
  end
30
30
 
31
31
  def self.assoc_impl(args, env)
32
- raise "assoc require 2 arguments" unless args.length == 2
32
+ return Lisp::Debug.process_error("assoc require 2 arguments", env) unless args.length == 2
33
33
  key = args.car.evaluate(env)
34
34
  alist = args.cadr.evaluate(env)
35
35
  alist = Lisp::AList.from_list(alist) if alist.list? && !alist.alist?
36
- raise "the last argument to assoc has to be an association list" unless alist.alist?
36
+ return Lisp::Debug.process_error("the last argument to assoc has to be an association list", env) unless alist.alist?
37
37
  alist.assoc(key)
38
38
  end
39
39
 
40
40
  def self.rassoc_impl(args, env)
41
- raise "assoc require 2 arguments" unless args.length == 2
41
+ return Lisp::Debug.process_error("assoc require 2 arguments", env) unless args.length == 2
42
42
  value = args.car.evaluate(env)
43
43
  alist = args.cadr.evaluate(env)
44
44
  alist = Lisp::AList.from_list(alist) if alist.list? && !alist.alist?
45
- raise "the last argument to rassoc has to be an association list" unless alist.alist?
45
+ return Lisp::Debug.process_error("the last argument to rassoc has to be an association list", env) unless alist.alist?
46
46
  alist.rassoc(value)
47
47
  end
48
48
 
49
49
  def self.dissoc_impl(args, env)
50
- raise "assoc require 2 arguments" unless args.length == 2
50
+ return Lisp::Debug.process_error("assoc require 2 arguments", env) unless args.length == 2
51
51
  key = args.car.evaluate(env)
52
52
  alist = args.cadr.evaluate(env)
53
53
  alist = Lisp::AList.from_list(alist) if alist.list? && !alist.alist?
54
- raise "the last argument to dissoc has to be an association list" unless alist.alist?
54
+ return Lisp::Debug.process_error("the last argument to dissoc has to be an association list", env) unless alist.alist?
55
55
  alist.dissoc(key)
56
56
  end
57
57
 
58
58
  def self.zip_impl(args, env)
59
- raise "assoc require 2 or 3arguments" unless args.length == 2 || args.length == 3
59
+ return Lisp::Debug.process_error("assoc require 2 or 3arguments", env) unless args.length == 2 || args.length == 3
60
60
  key_list = args.car.evaluate(env)
61
- raise "the keys supplied to zip has to be a list" unless key_list.list?
61
+ return Lisp::Debug.process_error("the keys supplied to zip has to be a list", env) unless key_list.list?
62
62
  value_list = args.cadr.evaluate(env)
63
- raise "the values supplied to zip has to be a list" unless value_list.list?
64
- raise "zip requires the same number of keys and values" unless key_list.length == value_list.length
63
+ return Lisp::Debug.process_error("the values supplied to zip has to be a list", env) unless value_list.list?
64
+ return Lisp::Debug.process_error("zip requires the same number of keys and values", env) unless key_list.length == value_list.length
65
65
 
66
66
  if args.length == 3
67
67
  alist = args.caddr.evaluate(env)
68
68
  alist = Lisp::AList.from_list(alist) if alist.list? && !alist.alist?
69
- raise "the third argument to zip has to be an association list" unless alist.alist?
69
+ return Lisp::Debug.process_error("the third argument to zip has to be an association list", env) unless alist.alist?
70
70
  alist.zip(key_list.to_a, value_list.to_a)
71
71
  else
72
72
  Lisp::AList.zip(key_list.to_a, value_list.to_a)
@@ -74,18 +74,18 @@ module Lisp
74
74
  end
75
75
 
76
76
  def self.alist_to_list_impl(args, env)
77
- raise "alist-to-list requires 1 arguments" unless args.length == 1
77
+ return Lisp::Debug.process_error("alist-to-list requires 1 arguments", env) unless args.length == 1
78
78
  alist = args.car.evaluate(env)
79
79
  return alist if alist.list? && !alist.alist?
80
- raise "the argument to alist-to-list has to be an association list" unless alist.alist?
80
+ return Lisp::Debug.process_error("the argument to alist-to-list has to be an association list", env) unless alist.alist?
81
81
 
82
82
  alist.to_list
83
83
  end
84
84
 
85
85
  def self.list_to_alist_impl(args, env)
86
- raise "list-to-alist requires 1 arguments" unless args.length == 1
86
+ return Lisp::Debug.process_error("list-to-alist requires 1 arguments", env) unless args.length == 1
87
87
  list = args.car.evaluate(env)
88
- raise "the argument to list-to-alist has to be a list" unless list.list?
88
+ return Lisp::Debug.process_error("the argument to list-to-alist has to be a list", env) unless list.list?
89
89
 
90
90
  Lisp::AList.from_list(list)
91
91
  end
@@ -25,7 +25,7 @@ The `new-value` sexpr is evaluated to arrive at the new value to be bound to. Us
25
25
 
26
26
  def self.setbang_impl(args, env)
27
27
  sym = args.car
28
- raise "set! requires a raw (unevaluated) symbol as it's first argument." unless sym.symbol?
28
+ return Lisp::Debug.process_error("set! requires a raw (unevaluated) symbol as it's first argument.", env) unless sym.symbol?
29
29
  value = args.cadr.evaluate(env)
30
30
  env.set(sym, value)
31
31
  end
@@ -33,7 +33,7 @@ The `new-value` sexpr is evaluated to arrive at the new value to be bound to. Us
33
33
 
34
34
  def self.setcarbang_impl(args, env)
35
35
  pair = args.car.evaluate(env)
36
- raise "set-car! requires a pair as it's first argument." unless pair.pair?
36
+ return Lisp::Debug.process_error("set-car! requires a pair as it's first argument.", env) unless pair.pair?
37
37
  value = args.cadr.evaluate(env)
38
38
  pair.set_car!(value)
39
39
  end
@@ -41,20 +41,20 @@ The `new-value` sexpr is evaluated to arrive at the new value to be bound to. Us
41
41
 
42
42
  def self.setcdrbang_impl(args, env)
43
43
  pair = args.car.evaluate(env)
44
- raise "set-cdr! requires a pair as it's first argument." unless pair.pair?
44
+ return Lisp::Debug.process_error("set-cdr! requires a pair as it's first argument.", env) unless pair.pair?
45
45
  value = args.cadr.evaluate(env)
46
46
  pair.set_cdr!(value)
47
47
  end
48
48
 
49
49
 
50
50
  def self.setnthbang_impl(args, env)
51
- raise "set-nth! requires 3 arguments." unless args.length == 3
51
+ return Lisp::Debug.process_error("set-nth! requires 3 arguments.", env) unless args.length == 3
52
52
  n = args.car.evaluate(env)
53
- raise "The first argument of set-nth! has to be an number." unless n.number?
54
- raise "The first argument of set-nth! has to be positive." unless n.value > 0
53
+ return Lisp::Debug.process_error("The first argument of set-nth! has to be an number.", env) unless n.number?
54
+ return Lisp::Debug.process_error("The first argument of set-nth! has to be positive.", env) unless n.value > 0
55
55
 
56
56
  l = args.cadr.evaluate(env)
57
- raise "set-nth! requires a list or vector as it's first argument." unless l.list? || l.vector?
57
+ return Lisp::Debug.process_error("set-nth! requires a list or vector as it's first argument.", env) unless l.list? || l.vector?
58
58
  value = args.caddr.evaluate(env)
59
59
  l.set_nth!(n.value, value)
60
60
  l
@@ -25,6 +25,7 @@ module Lisp
25
25
  Lisp::ClassObject.register
26
26
  Lisp::System.register
27
27
  Lisp::Vector.register
28
+ Lisp::Debug.register
28
29
  end
29
30
  end
30
31
 
@@ -99,39 +99,40 @@ module Lisp
99
99
 
100
100
 
101
101
  def self.char_name_impl(args, env)
102
- raise "char->name requires a single argument, found #{args.length}" unless args.length == 1
102
+ return Lisp::Debug.process_error("char->name requires a single argument, found #{args.length}", env) unless args.length == 1
103
103
  char = args.car.evaluate(env)
104
- raise "char->name requires a character argument" unless char.character?
104
+ return Lisp::Debug.process_error("char->name requires a character argument", env) unless char.character?
105
105
  kv = @@character_constants.rassoc(char)
106
106
  return Lisp::String.with_value(kv[0]) unless kv.nil?
107
- raise "char->name was passed an invalid character"
107
+ return Lisp::Debug.process_error("char->name was passed an invalid character", env)
108
108
  end
109
109
 
110
110
 
111
111
  def self.name_char_impl(args, env)
112
- raise "name->char requires a single argument, found #{args.length}" unless args.length == 1
112
+ return Lisp::Debug.process_error("name->char requires a single argument, found #{args.length}", env) unless args.length == 1
113
113
  name = args.car.evaluate(env)
114
- raise "name->char requires a string argument" unless name.string?
114
+ return Lisp::Debug.process_error("name->char requires a string argument", env) unless name.string?
115
115
  ch = find_character_for_name(name.value)
116
116
  return ch unless ch.nil?
117
- raise "There is no character with the name #{name}"
117
+ return Lisp::Debug.process_error("There is no character with the name #{name}", env)
118
118
  end
119
119
 
120
120
 
121
121
  def self.get_one_character_arg(func, args, env)
122
- raise "#{func} requires a character argument, found no args" unless args.length >= 1
122
+ return Lisp::Debug.process_error("#{func} requires a character argument, found no args", env) unless args.length >= 1
123
123
  char1 = args.car.evaluate(env)
124
- raise "#{func} requires a character argument, found #{char1}" unless char1.character?
124
+ return Lisp::Debug.process_error("#{func} requires a character argument, found #{char1}", env) unless char1.character?
125
125
  return char1
126
126
  end
127
127
 
128
128
 
129
129
  def self.get_two_character_args(func, args, env)
130
- raise "#{func} requires two arguments, found #{args.length}" unless args.length == 2
130
+ return Lisp::Debug.process_error("#{func} requires two arguments, found
131
+ ##{args.length}", env) unless args.length == 2
131
132
  char1 = args.car.evaluate(env)
132
- raise "#{func} requires character arguments, found #{char1}" unless char1.character?
133
+ return Lisp::Debug.process_error("#{func} requires character arguments, found #{char1}", env) unless char1.character?
133
134
  char2 = args.cadr.evaluate(env)
134
- raise "#{func} requires character arguments, found #{char2}" unless char2.character?
135
+ return Lisp::Debug.process_error("#{func} requires character arguments, found #{char2}", env) unless char2.character?
135
136
  return [char1, char2]
136
137
  end
137
138
 
@@ -197,7 +198,7 @@ module Lisp
197
198
 
198
199
 
199
200
  def self.charp_impl(args, env)
200
- raise "char->name requires a single argument, found #{args.length}" unless args.length == 1
201
+ return Lisp::Debug.process_error("char->name requires a single argument, found #{args.length}", env) unless args.length == 1
201
202
  char = args.car.evaluate(env)
202
203
  Lisp::Boolean.with_value(char.character?)
203
204
  end
@@ -221,8 +222,8 @@ module Lisp
221
222
  10
222
223
  else
223
224
  b = args.cadr.evaluate(env)
224
- raise "Base for char->digit has to be an integer" unless b.integer?
225
- raise "Base for char->digit has to be between 2 and 36" unless b.value >=2 && b.value <= 36
225
+ return Lisp::Debug.process_error("Base for char->digit has to be an integer", env) unless b.integer?
226
+ return Lisp::Debug.process_error("Base for char->digit has to be between 2 and 36", env) unless b.value >=2 && b.value <= 36
226
227
  b.value
227
228
  end
228
229
  ch = char.value.upcase
@@ -246,13 +247,13 @@ module Lisp
246
247
 
247
248
  def self.digit_char_impl(args, env)
248
249
  d = args.car.evaluate(env)
249
- raise "Digit value for digit->char has to be an integer" unless d.integer?
250
+ return Lisp::Debug.process_error("Digit value for digit->char has to be an integer", env) unless d.integer?
250
251
  base = if args.length == 1
251
252
  10
252
253
  else
253
254
  b = args.cadr.evaluate(env)
254
- raise "Base for char->digit has to be an integer" unless b.integer?
255
- raise "Base for char->digit has to be between 2 and 36" unless b.value >=2 && b.value <= 36
255
+ return Lisp::Debug.process_error("Base for char->digit has to be an integer", env) unless b.integer?
256
+ return Lisp::Debug.process_error("Base for char->digit has to be between 2 and 36", env) unless b.value >=2 && b.value <= 36
256
257
  b.value
257
258
  end
258
259
  val = d.value
@@ -269,7 +270,7 @@ module Lisp
269
270
 
270
271
  def self.int_char_impl(args, env)
271
272
  i = args.car.evaluate(env)
272
- raise "Integer value for int->char has to be an integer" unless i.integer?
273
+ return Lisp::Debug.process_error("Integer value for int->char has to be an integer", env) unless i.integer?
273
274
  find_character_for_chr(i.value.chr)
274
275
  end
275
276
 
@@ -374,10 +375,10 @@ module Lisp
374
375
  elsif n[0..1] == "U+"
375
376
  find_character_for_chr(n[2..-1].to_i(16).chr)
376
377
  else
377
- raise "Invalid character name: #{n}"
378
+ return Lisp::Debug.process_error("Invalid character name: #{n}", env)
378
379
  end
379
380
  end
380
381
 
381
- end
382
+ end
382
383
 
383
384
  end
@@ -123,6 +123,8 @@ module Lisp
123
123
  def to_s
124
124
  return "()" if self.empty?
125
125
  return "'#{@cdr.car.to_s}" if @car.symbol? && @car.name == "quote"
126
+ return "{#{@cdr.to_s_helper}}" if @car.symbol? && @car.name == "make-frame"
127
+ return "[#{@cdr.to_s_helper}]" if @car.symbol? && @car.name == "make-vector"
126
128
  return "(#{@car.to_s} . #{@cdr.to_s})" if !@cdr.nil? && !@cdr.pair?
127
129
  return "(#{self.to_s_helper})"
128
130
  end
@@ -134,6 +136,8 @@ module Lisp
134
136
  def print_string
135
137
  return "()" if self.empty?
136
138
  return "'#{@cdr.car.print_string}" if @car.symbol? && @car.name == "quote"
139
+ return "{#{@cdr.print_string_helper}}" if @car.symbol? && @car.name == "make-frame"
140
+ return "[#{@cdr.print_string_helper}]" if @car.symbol? && @car.name == "make-vector"
137
141
  return "(#{@car.print_string} . #{@cdr.print_string})" if !@cdr.nil? && !@cdr.pair?
138
142
  return "(#{self.print_string_helper})"
139
143
  end
@@ -203,13 +207,52 @@ module Lisp
203
207
  return nil unless obj.object?
204
208
  return obj.value
205
209
  end
210
+
211
+
212
+
213
+ def inner_eval(env)
214
+ func = @car.evaluate(env)
215
+ return Lisp::Debug.process_error("There is no function or macro named #{@car}", env) if func.nil?
216
+ env.current_code.unshift(self.print_string()) if !Lisp::Debug.eval_in_debug_repl && Lisp::Debug.interactive
217
+
218
+ Lisp::Debug.log_eval(self, env)
206
219
 
220
+ unless Lisp::Debug.eval_in_debug_repl
221
+ if !Lisp::Debug.target_env.nil? && env == Lisp::Debug.target_env.previous
222
+ Lisp::Debug.target_env = nil
223
+ Lisp::Debug.debug_repl(env)
224
+ elsif Lisp::Debug.single_step || (func.function? && Lisp::Debug.on_entry.include?(func.name))
225
+ Lisp::Debug.debug_repl(env)
226
+ end
227
+ end
228
+ result = func.apply_to(@cdr, env)
229
+ env.current_code.shift() if !Lisp::Debug.eval_in_debug_repl && Lisp::Debug.interactive
230
+ Lisp::Debug.log_result(result, env)
231
+ result
232
+ end
233
+
207
234
 
208
235
  def evaluate(env)
209
236
  return self if empty?
210
- func = @car.evaluate(env)
211
- raise "There is no function or macro named #{@car}" if func.nil?
212
- func.apply_to(@cdr, env)
237
+ sexpr = if @car.symbol?
238
+ key = @car
239
+ frame = nth(2)
240
+ value = nth(3)
241
+
242
+ s = key.name
243
+ if s.end_with?(":")
244
+ ConsCell.array_to_list([Symbol.named("get-slot"), frame, key])
245
+ elsif s.end_with?(":!")
246
+ ConsCell.array_to_list([Symbol.named("set-slot!"), frame, Symbol.named(s[0..-2]), value])
247
+ elsif s.end_with?(":?")
248
+ ConsCell.array_to_list([Symbol.named("has-slot?"), frame, Symbol.named(s[0..-2])])
249
+ else
250
+ self
251
+ end
252
+ else
253
+ self
254
+ end
255
+ sexpr.inner_eval(env)
213
256
  end
214
257
 
215
258
  def evaluate_each(env)
@@ -0,0 +1,238 @@
1
+ # Copyright 2014 David R. Astels. All rights reserved.
2
+ # Use of this source code is governed by a BSD-style
3
+ # license that can be found in the LICENSE file.
4
+
5
+
6
+ module Lisp
7
+
8
+ class Debug
9
+
10
+ class <<self
11
+ attr_accessor :trace, :on_error, :on_entry, :single_step, :interactive, :target_env, :eval_in_debug_repl
12
+ end
13
+
14
+
15
+ def self.register
16
+ self.trace = false
17
+ self.on_error = false
18
+ self.on_entry = Set.new
19
+ self.single_step = false
20
+ self.interactive = false
21
+
22
+ Primitive.register("debug-trace") {|args, env| Lisp::Debug::debug_trace_impl(args, env) }
23
+ Primitive.register("debug-on-error") {|args, env| Lisp::Debug::debug_on_error_impl(args, env) }
24
+ Primitive.register("debug-on-entry") {|args, env| Lisp::Debug::debug_on_entry_impl(args, env) }
25
+ Primitive.register("add-debug-on-entry") {|args, env| Lisp::Debug::add_debug_on_entry_impl(args, env) }
26
+ Primitive.register("remove-debug-on-entry") {|args, env| Lisp::Debug::remove_debug_on_entry_impl(args, env) }
27
+ Primitive.register("debug") {|args, env| Lisp::Debug::debug_impl(args, env) }
28
+ Primitive.register("dump") {|args, env| Lisp::Debug::dump_imp2l(args, env) }
29
+ end
30
+
31
+
32
+ def self.debug_trace_impl(args, env)
33
+ return Lisp::Debug.process_error("debug-trace requires 1 argument", env) unless args.length == 1
34
+ flag = args.car.evaluate(env)
35
+ return Lisp::Debug.process_error("the argument to debug-trace has to be a boolean", env) unless flag.boolean?
36
+ self.trace = flag.value
37
+ flag
38
+ end
39
+
40
+ def self.debug_on_error_impl(args, env)
41
+ return Lisp::Debug.process_error("debug-on-error requires 1 argument", env) unless args.length == 1
42
+ flag = args.car.evaluate(env)
43
+ return Lisp::Debug.process_error("the argument to debug-on-error has to be a boolean", env) unless flag.boolean?
44
+ self.on_error = flag.value
45
+ flag
46
+ end
47
+
48
+ def self.debug_on_entry_impl(args, env)
49
+ Lisp::ConsCell.array_to_list(self.on_entry.to_a.sort.map {|s| Lisp::String.with_value(s) })
50
+ end
51
+
52
+ def self.add_debug_on_entry_impl(args, env)
53
+ return Lisp::Debug.process_error("add-debug-on-error requires 1 argument", env) unless args.length == 1
54
+ f = args.car.evaluate(env)
55
+ return Lisp::Debug.process_error("the argument to add-debug-on-error has to be a function", env) unless f.function? || f.primitive?
56
+
57
+ self.on_entry.add(f.name)
58
+ f
59
+ end
60
+
61
+ def self.remove_debug_on_entry_impl(args, env)
62
+ return Lisp::Debug.process_error("remove-debug-on-error requires 1 argument", env) unless args.length == 1
63
+ f = args.car.evaluate(env)
64
+ return Lisp::Debug.process_error("the argument to remove-debug-on-error has to be a function", env) unless f.function?
65
+
66
+ self.on_entry.remove(f.name)
67
+ f
68
+ end
69
+
70
+ def self.debug_impl(args, env)
71
+ end
72
+
73
+ def self.dump_impl(args, env)
74
+ env.dump()
75
+ end
76
+
77
+
78
+ def self.process_state(tokens)
79
+ if tokens.size != 2
80
+ puts "Missing on/off"
81
+ [false, false]
82
+ else
83
+ case tokens[1]
84
+ when 'on'
85
+ [true, true]
86
+ when 'off'
87
+ [true, false]
88
+ else
89
+ puts "on/off expected."
90
+ [false, false]
91
+ end
92
+ end
93
+ end
94
+
95
+
96
+ def func_or_nil(fname, env)
97
+ f = env.value_of(Lisp::Symbol.named(fname))
98
+ if f.nil? || !f.function?
99
+ puts "No such function."
100
+ nil
101
+ else
102
+ f
103
+ end
104
+ end
105
+
106
+
107
+ def self.debug_repl(env)
108
+ parser = Lisp::Parser.new
109
+ puts("Debugging: #{env.current_code[0]}")
110
+ while line = Readline.readline('D> ', true)
111
+ if !line.empty?
112
+ if line[0] == ':'
113
+ tokens = line[1..-1].split
114
+ case tokens[0]
115
+ when '(+'
116
+ f = func_or_nil(tokens[1], env)
117
+ self.on_entry.add(f.name) unless f.nil?
118
+ when '(-'
119
+ f = func_or_nil(tokens[1], env)
120
+ self.on_entry.delete(f.name) unless f.nil?
121
+ when '('
122
+ self.on_entry.to_a.sort.each {|f| puts f}
123
+ when '?'
124
+ puts "RubyLisp Debugger"
125
+ puts "-----------------"
126
+ puts ":(+ func - debug on entry to func"
127
+ puts ":(- func - don't debug on entry to func"
128
+ puts ":( - show functions marked as debug on entry"
129
+ puts ":? - show this command summary"
130
+ puts ":b - show the environment stack"
131
+ puts ":c - continue, exiting the debugger"
132
+ puts ":d - do a full of the environment stack"
133
+ puts ":e on/off - Enable/disable debug on error"
134
+ puts ":f frame# - do a full dump of a single environment frame"
135
+ puts ":q - quit GoLisp"
136
+ puts ":r sexpr - return from the current evaluation with the specified value"
137
+ puts ":s - single step (run to the next evaluation)"
138
+ puts ":t on/off - Enable/disable tracing"
139
+ puts ":u - continue until the enclosing environment frame is returned to"
140
+ puts
141
+ when 'b'
142
+ env.dump_headers()
143
+ puts
144
+ when 'c'
145
+ self.target_env = nil
146
+ self.single_step = false
147
+ self.eval_in_debug_repl = false
148
+ return
149
+ when 'd'
150
+ env.dump
151
+ when 'e'
152
+ ok, state = process_state(tokens)
153
+ self.on_error = state if ok
154
+ when 'f'
155
+ if tokens.size != 2
156
+ puts "Missing frame number."
157
+ else
158
+ fnum = tokens[1].to_i
159
+ env.dump_single_frame(fnum)
160
+ end
161
+ when 'q'
162
+ exit()
163
+ when 'r'
164
+ self.eval_in_debug_repl = true
165
+ code = parser.parse(tokens[1..-1].join(' '))
166
+ return_value = code.evaluate(env)
167
+ self.eval_in_debug_repl = false
168
+ self.target_env = nil
169
+ self.single_step = false
170
+ self.eval_in_debug_repl = false
171
+ return return_value
172
+ when 's'
173
+ self.single_step = true
174
+ return
175
+ when 't'
176
+ ok, state = process_state(tokens)
177
+ self.trace = state if ok
178
+ when 'u'
179
+ if env.previous.nil?
180
+ puts "Already at top frame."
181
+ else
182
+ self.target_env = env
183
+ return
184
+ end
185
+ end
186
+ else
187
+ begin
188
+ self.eval_in_debug_repl = true
189
+ code = parser.parse(line)
190
+ value = code.evaluate(env)
191
+ self.eval_in_debug_repl = false
192
+ puts value.to_s
193
+ rescue Exception => ex
194
+ puts "ERROR: #{ex}"
195
+ puts ex.backtrace
196
+ end
197
+ end
198
+ end
199
+ end
200
+ end
201
+
202
+ def self.process_error(error_message, env)
203
+ if self.on_error && self.interactive
204
+ puts "ERROR: #{error_message}"
205
+ self.debug_repl(env)
206
+ else
207
+ raise error_message
208
+ end
209
+ end
210
+
211
+
212
+ def self.print_dashes(level)
213
+ print("-" * level)
214
+ end
215
+
216
+
217
+ def self.log_eval(sexpr, env)
218
+ if !self.eval_in_debug_repl && self.trace
219
+ depth = env.depth
220
+ print("% #d: " % depth)
221
+ print_dashes(depth)
222
+ puts("> #{sexpr.to_s}")
223
+ end
224
+ end
225
+
226
+
227
+ def self.log_result(result, env)
228
+ if !self.eval_in_debug_repl && self.trace
229
+ depth = env.depth
230
+ print("% #d: <" % depth)
231
+ print_dashes(depth)
232
+ puts(" #{result.to_s}")
233
+ end
234
+ end
235
+
236
+
237
+ end
238
+ end