rubylisp 1.0.9 → 1.0.15

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: 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