rubylisp 1.0.9 → 1.0.15

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: 19a21b82aeba5d0b46584080bf3625d60fb3b49d
4
- data.tar.gz: 009daa5e7fef562898b0bbbe8c06816887c12fb6
3
+ metadata.gz: fb471b017a46d1820e5e61b82af7ffcbaed45a8e
4
+ data.tar.gz: ecdfb7e134106b6c9530fde8b03e581ddc8beca9
5
5
  SHA512:
6
- metadata.gz: cd899d823e85dd7d9a812aca7e8b75b94550c4ee4abc193e881dc17d80a4a410e22cead3a62ec286c4ff4aee28e84ea5bf6633893b52fd8a3ca30f324e4d9cc9
7
- data.tar.gz: 821ddee478d4b52f13435e29dbb40705401dfaeb7788ad62fc2fd463a29eb4ad9a2a7db8d9213a523f12175b3e530b0033da9bc622b161edae2cde1946ae928a
6
+ metadata.gz: d6800eb4f15865974d08a0d45144731fb71db8507a809c083b70fc3af2dae895f28aabe4e087f2d49659411da47da705edf69c86c87c7dcad0a18abb105fd6b6
7
+ data.tar.gz: b91cf1d11df1da585b78be7ae897afefbe94cad77c355f4535b8c3caf7c715dc5f2e13ba586f67e0e777f191719e5e1aff7b0124eef2b2be4d4e0957085cfbc4
data/bin/rubylisp CHANGED
@@ -9,7 +9,7 @@ require 'readline/history/restore'
9
9
  Lisp::Initializer.register_builtins
10
10
  Lisp::Debug.interactive = true
11
11
 
12
- program :version, '0.0.1'
12
+ program :version, '1.0.15'
13
13
  program :description, 'A large sub/super-set of MIT/GNU-Scheme implemented in pure Ruby.'
14
14
 
15
15
  # Smarter Readline to prevent empty and dups
@@ -42,7 +42,7 @@ command :repl do |c|
42
42
 
43
43
  options.default :file => ""
44
44
  puts 'RubyLisp REPL'
45
- puts 'Copyright 2014-2015 David R. Astels'
45
+ puts 'Copyright 2014-2016 David R. Astels'
46
46
  puts
47
47
  parser = Lisp::Parser.new
48
48
  parser.process_file(options.file) if options.file != ""
data/lib/rubylisp/atom.rb CHANGED
@@ -4,6 +4,10 @@ module Lisp
4
4
 
5
5
  attr_reader :value
6
6
 
7
+ def set_location(type, package, file, start, length)
8
+ end
9
+
10
+
7
11
  def lisp_object?
8
12
  true
9
13
  end
@@ -4,6 +4,10 @@ module Lisp
4
4
  include Enumerable
5
5
  attr_reader :car, :cdr
6
6
 
7
+ def set_location(type, package, file, start, length)
8
+ end
9
+
10
+
7
11
  def self.cons(a=nil, b=nil)
8
12
  b = nil if b.pair? && b.empty?
9
13
  ConsCell.new(a, b)
@@ -220,12 +224,16 @@ module Lisp
220
224
  return obj.value
221
225
  end
222
226
 
227
+
228
+ def push_current_code
229
+ env.push_code(self.print_string)
230
+ end
223
231
 
224
232
 
225
233
  def inner_eval(env)
226
234
  func = @car.evaluate(env)
227
235
  return Lisp::Debug.process_error("There is no function or macro named #{@car}", env) if func.nil?
228
- env.current_code.unshift(self.print_string()) if !Lisp::Debug.eval_in_debug_repl && Lisp::Debug.interactive
236
+ push_current_code if !Lisp::Debug.eval_in_debug_repl && Lisp::Debug.interactive
229
237
 
230
238
  Lisp::Debug.log_eval(self, env)
231
239
 
@@ -239,7 +247,7 @@ module Lisp
239
247
  end
240
248
 
241
249
  result = func.apply_to(@cdr, env)
242
- env.current_code.shift() if !Lisp::Debug.eval_in_debug_repl && Lisp::Debug.interactive
250
+ env.pop_code if !Lisp::Debug.eval_in_debug_repl && Lisp::Debug.interactive
243
251
  Lisp::Debug.log_result(result, env)
244
252
  result
245
253
  end
@@ -35,6 +35,30 @@ module Lisp
35
35
  def has_frame?
36
36
  !@frame.nil?
37
37
  end
38
+
39
+
40
+ # --------------------------------------------------------------------------------
41
+ # Exaling code management
42
+
43
+ def push_code(code)
44
+ @current_code.push(code)
45
+ end
46
+
47
+
48
+ def pop_code
49
+ @current_code.pop
50
+ end
51
+
52
+
53
+ def top_code
54
+ @current_code[-1]
55
+ end
56
+
57
+
58
+ def has_code?
59
+ !@current_code.empty?
60
+ end
61
+
38
62
 
39
63
  # Bindings following parent env frame pointer
40
64
 
@@ -29,11 +29,13 @@ module Lisp
29
29
  Lisp::Character.with_value(ch)
30
30
  end
31
31
 
32
- def parse_cons_cell(tokens)
33
- tok, lit = tokens.next_token
32
+ def parse_cons_cell(start_pos, tokens)
33
+ pos, tok, lit = tokens.next_token
34
34
  if tok == :RPAREN
35
35
  tokens.consume_token
36
- return Lisp::ConsCell.cons()
36
+ return Lisp::ConsCell.cons().tap do |obj|
37
+ obj.set_location(start_pos, pos - start_pos + 1) if @parse_for_debugging
38
+ end
37
39
  end
38
40
 
39
41
  car = nil
@@ -44,31 +46,39 @@ module Lisp
44
46
  tokens.consume_token
45
47
  cdr = self.parse_sexpr(tokens)
46
48
  return nil if tokens.next_token[0] == :EOF
47
- tok, lit = tokens.next_token
49
+ pos, tok, lit = tokens.next_token
48
50
  return Lisp::Debug.process_error("Expected ')' to follow a dotted tail on line #{tokens.line_number}", Lisp::EnvironmentFrame.global) if tok != :RPAREN
49
51
  tokens.consume_token
50
- return Lisp::ConsCell.array_to_list(cells, cdr)
52
+ return Lisp::ConsCell.array_to_list(cells, cdr).tap do |obj|
53
+ obj.set_location(start_pos, pos - start_pos + 1) if @parse_for_debugging
54
+ end
51
55
  else
52
56
  car = self.parse_sexpr(tokens)
53
57
  return Lisp::Debug.process_error("Unexpected EOF (expected ')') on line #{tokens.line_number}", Lisp::EnvironmentFrame.global) if tokens.next_token[0] == :EOF
54
58
  cells << car
55
59
  end
56
- tok, lit = tokens.next_token
60
+ pos, tok, lit = tokens.next_token
57
61
  end
58
62
 
59
63
  tokens.consume_token
60
- Lisp::ConsCell.array_to_list(cells)
64
+ Lisp::ConsCell.array_to_list(cells).tap do |obj|
65
+ obj.set_location(start_pos, pos - start_pos + 1) if @parse_for_debugging
66
+ end
61
67
  end
62
68
 
63
- def parse_frame(tokens, literal)
69
+ def parse_frame(start_pos, tokens, literal)
64
70
  m = {}
65
- tok, lit = tokens.next_token
71
+ pos, tok, lit = tokens.next_token
66
72
  if tok == :RBRACE
67
73
  tokens.consume_token
68
74
  if literal
69
- Lisp::Frame.new
75
+ Lisp::Frame.new.tap do |obj|
76
+ obj.set_location(start_pos, pos - start_pos + 1) if @parse_for_debugging
77
+ end
70
78
  else
71
- Lisp::ConsCell.cons(Lisp::Symbol.named("make-frame"), nil)
79
+ Lisp::ConsCell.cons(Lisp::Symbol.named("make-frame"), nil).tap do |obj|
80
+ obj.set_location(start_pos, pos - start_pos + 1) if @parse_for_debugging
81
+ end
72
82
  end
73
83
  else
74
84
  cells = []
@@ -76,29 +86,37 @@ module Lisp
76
86
  item = self.parse_sexpr(tokens)
77
87
  return Lisp::Debug.process_error("Unexpected EOF (expected '}') on line #{tokens.line_number}", env) if tokens.next_token[0] == :EOF
78
88
  cells << item
79
- tok, lit = tokens.next_token
89
+ pos, tok, lit = tokens.next_token
80
90
  end
81
91
 
82
92
  tokens.consume_token
83
93
  keys_and_values = Lisp::ConsCell.array_to_list(cells)
84
94
  if literal
85
- Lisp::PrimFrame.make_frame_impl(keys_and_values, Lisp::EnvironmentFrame.global)
95
+ Lisp::PrimFrame.make_frame_impl(keys_and_values, Lisp::EnvironmentFrame.global).tap do |obj|
96
+ obj.set_location(start_pos, pos - start_pos + 1) if @parse_for_debugging
97
+ end
86
98
  else
87
- Lisp::ConsCell.cons(Lisp::Symbol.named("make-frame"), keys_and_values)
99
+ Lisp::ConsCell.cons(Lisp::Symbol.named("make-frame"), keys_and_values).tap do |obj|
100
+ obj.set_location(start_pos, pos - start_pos + 1) if @parse_for_debugging
101
+ end
88
102
  end
89
103
  end
90
104
  end
91
105
 
92
106
 
93
- def parse_vector(tokens, literal)
107
+ def parse_vector(start_pos, tokens, literal)
94
108
  v = []
95
- tok, lit = tokens.next_token
109
+ pos, tok, lit = tokens.next_token
96
110
  if tok == :RPAREN
97
111
  tokens.consume_token
98
112
  if literal
99
- Lisp::Vector.new
113
+ Lisp::Vector.new.tap do |obj|
114
+ obj.set_location(start_pos, pos - start_pos + 1) if @parse_for_debugging
115
+ end
100
116
  else
101
- Lisp::ConsCell.cons(Lis::Symbol.named("vector"), nil)
117
+ Lisp::ConsCell.cons(Lis::Symbol.named("vector"), nil).tap do |obj|
118
+ obj.set_location(start_pos, pos - start_pos + 1) if @parse_for_debugging
119
+ end
102
120
  end
103
121
  else
104
122
  cells = []
@@ -106,15 +124,19 @@ module Lisp
106
124
  item = self.parse_sexpr(tokens)
107
125
  return Lisp::Debug.process_error("Unexpected EOF (expected ')') on line #{tokens.line_number}", env) if tokens.next_token[0] == :EOF
108
126
  cells << item
109
- tok, lit = tokens.next_token
127
+ pos, tok, lit = tokens.next_token
110
128
  end
111
129
 
112
130
  tokens.consume_token
113
131
 
114
132
  if literal
115
- Lisp::Vector.with_array(cells)
133
+ Lisp::Vector.with_array(cells).tap do |obj|
134
+ obj.set_location(start_pos, pos - start_pos + 1) if @parse_for_debugging
135
+ end
116
136
  else
117
- Lisp::ConsCell.cons(Lisp::Symbol.named("vector"), Lisp::ConsCell.array_to_list(cells))
137
+ Lisp::ConsCell.cons(Lisp::Symbol.named("vector"), Lisp::ConsCell.array_to_list(cells)).tap do |obj|
138
+ obj.set_location(start_pos, pos - start_pos + 1) if @parse_for_debugging
139
+ end
118
140
  end
119
141
  end
120
142
  end
@@ -122,7 +144,7 @@ module Lisp
122
144
 
123
145
  def parse_sexpr(tokens)
124
146
  while true
125
- tok, lit = tokens.next_token
147
+ pos, tok, lit = tokens.next_token
126
148
  # puts "token: <#{tok}, #{lit}>"
127
149
  return nil if tok == :EOF
128
150
  tokens.consume_token
@@ -130,55 +152,95 @@ module Lisp
130
152
  when :COMMENT
131
153
  next
132
154
  when :NUMBER
133
- return make_number(lit)
155
+ return make_number(lit).tap do |obj|
156
+ obj.set_location(pos, lit.length) if @parse_for_debugging
157
+ end
134
158
  when :FLOAT
135
- return make_float(lit)
159
+ return make_float(lit).tap do |obj|
160
+ obj.set_location(pos, lit.length) if @parse_for_debugging
161
+ end
136
162
  when :HEXNUMBER
137
- return make_hex_number(lit)
163
+ return make_hex_number(lit).tap do |obj|
164
+ obj.set_location(pos, lit.length) if @parse_for_debugging
165
+ end
138
166
  when :STRING
139
- return make_string(lit)
167
+ return make_string(lit).tap do |obj|
168
+ obj.set_location(pos, lit.length) if @parse_for_debugging
169
+ end
140
170
  when :CHARACTER
141
- return make_character(lit)
171
+ return make_character(lit).tap do |obj|
172
+ obj.set_location(pos, lit.length) if @parse_for_debugging
173
+ end
142
174
  when :LPAREN
143
- return parse_cons_cell(tokens)
175
+ return parse_cons_cell(pos, tokens)
144
176
  when :LBRACE
145
- return parse_frame(tokens, false)
177
+ return parse_frame(pos, tokens, false)
146
178
  when :QUOTE_LBRACE
147
- return parse_frame(tokens, true)
179
+ return parse_frame(pos, tokens, true)
148
180
  when :HASH_LPAREN
149
- return parse_vector(tokens, false)
181
+ return parse_vector(pos, tokens, false)
150
182
  when :QUOTE_HASH_LPAREN
151
- return parse_vector(tokens, true)
183
+ return parse_vector(pos, tokens, true)
152
184
  when :SYMBOL
153
- return make_symbol(lit)
185
+ return make_symbol(lit).tap do |obj|
186
+ obj.set_location(pos, lit.length) if @parse_for_debugging
187
+ end
154
188
  when :FFI_NEW_SYMBOL
155
- return Lisp::FfiNew.new(lit)
189
+ return Lisp::FfiNew.new(lit).tap do |obj|
190
+ obj.set_location(pos, lit.length) if @parse_for_debugging
191
+ end
156
192
  when :FFI_SEND_SYMBOL
157
- return Lisp::FfiSend.new(lit)
193
+ return Lisp::FfiSend.new(lit).tap do |obj|
194
+ obj.set_location(pos, lit.length) if @parse_for_debugging
195
+ end
158
196
  when :FFI_STATIC_SYMBOL
159
- return Lisp::FfiStatic.new(lit)
197
+ return Lisp::FfiStatic.new(lit).tap do |obj|
198
+ obj.set_location(pos, lit.length) if @parse_for_debugging
199
+ end
160
200
  when :FALSE
161
- return Lisp::FALSE
201
+ if @parse_for_debugging
202
+ return Lisp::Boolean.with_value(false).tap do |obj|
203
+ obj.set_location(pos, 2) if @parse_for_debugging
204
+ end
205
+ else
206
+ return Lisp::FALSE
207
+ end
162
208
  when :TRUE
163
- return Lisp::TRUE
209
+ if @parse_for_debugging
210
+ return Lisp::Boolean.with_value(false).tap do |obj|
211
+ obj.set_location(pos, 2) if @parse_for_debugging
212
+ end
213
+ else
214
+ return Lisp::TRUE
215
+ end
164
216
  when :QUOTE
165
217
  expr = parse_sexpr(tokens)
166
- return Lisp::ConsCell.array_to_list([Lisp::Symbol.named('quote'), expr])
218
+ return Lisp::ConsCell.array_to_list([Lisp::Symbol.named('quote'), expr]).tap do |obj|
219
+ obj.set_location(pos, expr.src_length + 1) if @parse_for_debugging
220
+ end
167
221
  when :BACKQUOTE
168
222
  expr = parse_sexpr(tokens)
169
- return Lisp::ConsCell.array_to_list([Lisp::Symbol.named('quasiquote'), expr])
223
+ return Lisp::ConsCell.array_to_list([Lisp::Symbol.named('quasiquote'), expr]).tap do |obj|
224
+ obj.set_location(pos, expr.src_length + 1) if @parse_for_debugging
225
+ end
170
226
  when :COMMA
171
227
  expr = parse_sexpr(tokens)
172
- return Lisp::ConsCell.array_to_list([Lisp::Symbol.named('unquote'), expr])
228
+ return Lisp::ConsCell.array_to_list([Lisp::Symbol.named('unquote'), expr]).tap do |obj|
229
+ obj.set_location(pos, expr.src_length + 1) if @parse_for_debugging
230
+ end
173
231
  when :COMMAAT
174
232
  expr = parse_sexpr(tokens)
175
- return Lisp::ConsCell.array_to_list([Lisp::Symbol.named('unquote-splicing'), expr])
233
+ return Lisp::ConsCell.array_to_list([Lisp::Symbol.named('unquote-splicing'), expr]).tap do |obj|
234
+ obj.set_location(pos, expr.src_length + 2) if @parse_for_debugging
235
+ end
176
236
  when :WHITESPACE
177
237
  next
178
238
  when :ILLEGAL
179
239
  return Lisp::Debug.process_error("Illegal token: #{lit} on line #{tokens.line_number}", Lisp::EnvironmentFrame.global)
180
240
  else
181
- return make_symbol(lit)
241
+ return make_symbol(lit).tap do |obj|
242
+ obj.set_location(pos, lit.length) if @parse_for_debugging
243
+ end
182
244
  end
183
245
  end
184
246
  end
@@ -22,6 +22,11 @@ module Lisp
22
22
  end
23
23
 
24
24
 
25
+ def self.output_to_stdout(to_output)
26
+ $stdout.write(to_output)
27
+ end
28
+
29
+
25
30
  def self.load_impl(args, env)
26
31
  fname = args.car
27
32
  return Lisp::Debug.process_error("'load' requires a string argument.", env) unless fname.string?
@@ -64,11 +69,11 @@ module Lisp
64
69
  p = args.cadr
65
70
  return Lisp::Debug.process_error("'write-string' requires a port as it's second argument.", env) unless p.port?
66
71
  port = p.value
72
+ port.write(s.value)
67
73
  else
68
- port = $stdout
74
+ self.output_to_stdout(s.value)
69
75
  end
70
-
71
- port.write(s.value)
76
+ Lisp::String.with_value("OK")
72
77
  end
73
78
 
74
79
 
@@ -77,11 +82,11 @@ module Lisp
77
82
  p = args.car
78
83
  return Lisp::Debug.process_error("'newline' requires a port as it's argument.", env) unless p.port?
79
84
  port = p.value
85
+ port.write("\n")
80
86
  else
81
- port = $stdout
87
+ self.output_to_stdout("\n")
82
88
  end
83
-
84
- port.write("\n")
89
+ Lisp::String.with_value("OK")
85
90
  end
86
91
 
87
92
 
@@ -90,11 +95,11 @@ module Lisp
90
95
  p = args.cadr
91
96
  return Lisp::Debug.process_error("'write' requires a port as it's second argument.", env) unless p.port?
92
97
  port = p.value
98
+ port.write(args.car.print_string)
93
99
  else
94
- port = $stdout
100
+ self.output_to_stdout(args.car.print_string)
95
101
  end
96
-
97
- port.write(args.car.print_string)
102
+ Lisp::String.with_value("OK")
98
103
  end
99
104
 
100
105
 
@@ -209,8 +214,10 @@ module Lisp
209
214
 
210
215
  if destination.port?
211
216
  destination.value.write(combined_string)
217
+ Lisp::String.with_value("OK")
212
218
  elsif destination.value
213
- $stdout.write(combined_string)
219
+ self.output_to_stdout(combined_string)
220
+ Lisp::String.with_value("OK")
214
221
  else
215
222
  return Lisp::String.with_value(combined_string)
216
223
  end
@@ -3,6 +3,7 @@ module Lisp
3
3
  class PrimSystem
4
4
 
5
5
  def self.register
6
+ Primitive.register("load-ruby", "1") {|args, env| Lisp::PrimSystem.load_ruby_impl(args, env) }
6
7
  Primitive.register("sleep", "1") {|args, env| Lisp::PrimSystem.sleep_impl(args, env) }
7
8
  Primitive.register("time", "1", "", true) {|args, env| Lisp::PrimSystem.time_impl(args, env) }
8
9
  Primitive.register("quit", "0") {|args, env| exit() }
@@ -11,6 +12,14 @@ module Lisp
11
12
  end
12
13
 
13
14
 
15
+ def self.load_ruby_impl(args, env)
16
+ arg = args.car
17
+ return Lisp::Debug.process_error("load-ruby needs a string argument", env) unless arg.string?
18
+ load(arg.value)
19
+ Lisp::TRUE
20
+ end
21
+
22
+
14
23
  def self.sleep_impl(args, env)
15
24
  arg = args.car
16
25
  return Lisp::Debug.process_error("sleep needs a numeric argument", env) unless arg.number?
@@ -38,6 +38,7 @@ module Lisp
38
38
  end
39
39
 
40
40
  def evaluate(env)
41
+ super
41
42
  return self if @naked
42
43
  env.value_of(self)
43
44
  end
@@ -15,6 +15,7 @@ module Lisp
15
15
  def initialize(src, absorb_space=true)
16
16
  @absorb_whitespace = absorb_space
17
17
  @source = src
18
+ @position = 0
18
19
  @lookahead_token = nil
19
20
  @lookahead_literal = ''
20
21
  @eof = false
@@ -51,7 +52,7 @@ module Lisp
51
52
  end
52
53
 
53
54
  def next_token
54
- return @lookahead_token, @lookahead_literal
55
+ return @position, @lookahead_token, @lookahead_literal
55
56
  end
56
57
 
57
58
  def eof?
@@ -214,6 +215,7 @@ module Lisp
214
215
  while space?(@current_ch)
215
216
  @line_number += 1 if @current_ch == "\n"
216
217
  advance
218
+ @position = @source.pos
217
219
  return :EOF, '' if eof?
218
220
  end
219
221
  end
@@ -309,6 +311,7 @@ module Lisp
309
311
  end
310
312
 
311
313
  def consume_token
314
+ @position = @source.pos
312
315
  @lookahead_token, @lookahead_literal = self.read_next_token
313
316
  consume_token if @lookahead_token == :COMMENT
314
317
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubylisp
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.9
4
+ version: 1.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dave Astels
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-14 00:00:00.000000000 Z
11
+ date: 2016-04-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: commander