rubymotionlisp 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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