dslisprb 0.0.3 → 0.0.4

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.
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ 0.0.4 Implemented apply and funcall
2
+
3
+ Fix of variable assignments on lambda calla
4
+
5
+ Load of source files from console and multiline functions allowing line breaks
6
+
1
7
  0.0.3 fixed interpretation of special nil and T symbols
2
8
 
3
9
  implemented autocompletion of lisp variable names on dslisp console
data/Rakefile CHANGED
@@ -7,7 +7,7 @@ require "rspec/core/rake_task"
7
7
 
8
8
  spec = Gem::Specification.new do |s|
9
9
  s.name = 'dslisprb'
10
- s.version = '0.0.3'
10
+ s.version = '0.0.4'
11
11
  s.author = 'Dario Seminara'
12
12
  s.email = 'robertodarioseminara@gmail.com'
13
13
  s.platform = Gem::Platform::RUBY
data/bin/dslisprb CHANGED
@@ -24,23 +24,43 @@ if ARGV[0]
24
24
  else
25
25
  # repl
26
26
  require 'readline'
27
- print "enter lisp commands or quit to exit\n"
27
+ print "enter lisp commands and see the output
28
+ enter quit to exit
29
+ enter load to execute a source file. Example: load test.lisp
30
+
31
+ Tip: use tab key to autocomplete variable/function names
32
+ "
33
+
28
34
 
29
35
  stty_save = `stty -g`.chomp
30
36
  trap('INT') { system('stty', stty_save); exit }
31
37
 
32
38
  Readline.completion_append_character = " "
33
39
  Readline.completion_proc = proc do |s|
34
- dslisp.variables.grep( /^#{Regexp.escape(s)}/ )
40
+ (dslisp.variables + ["quit", "load"]).grep( /^#{Regexp.escape(s)}/ )
35
41
  end
36
42
 
37
- while cmd = Readline.readline('> ', true)
38
- if cmd == "quit"
39
- exit
40
- end
43
+ accumulated = ""
41
44
 
45
+ while cmd = Readline.readline(accumulated == "" ? '> ' : '?> ', true)
42
46
  begin
43
- print dslisp.evaluate(cmd).lisp_inspect,"\n"
47
+ if cmd.split.first == "quit"
48
+ exit
49
+ elsif cmd.split.first == "load"
50
+ filename = cmd.split[1]
51
+ print dslisp.evaluate(File.open(filename).read.gsub("\n"," ")).lisp_inspect,"\n"
52
+ else
53
+ accumulated = accumulated + " " + cmd
54
+ if accumulated.count('(') - accumulated.count(')') == 0
55
+ begin
56
+ print dslisp.evaluate(accumulated.gsub("\n"," ")).lisp_inspect,"\n"
57
+ ensure
58
+ accumulated = ""
59
+ end
60
+ end
61
+ end
62
+ rescue SystemExit => e
63
+ raise e
44
64
  rescue Exception => e
45
65
  p e
46
66
  print e.backtrace.join("\n"),"\n"
data/lib/dslisprb.rb CHANGED
@@ -66,13 +66,17 @@ class DsLisp
66
66
 
67
67
  def lambda(code)
68
68
  arguments = code[1].map(&ToRuby.method(:name_convert)).map(&:to_s)
69
- "(#{arguments.join(",")} = #{code[1].map{"nil"}.join(",")} ;lambda{|*x|
70
- oldargs = [ #{arguments.join(",")} ] # save current bindings
69
+
70
+ @count = (@count || 0) + 1
71
+ oldargsvar = "oldargs_#{@count}"
72
+
73
+ "(lambda{|*x|
74
+ #{oldargsvar} = [ #{arguments.map{|z| "begin; #{z}; rescue; nil; end"}.join(",")} ] # save current bindings
71
75
  #{(0..arguments.size-1).map{|i| "#{arguments[i]} = x[#{i}]" }.join(";")}
72
76
  begin
73
77
  aux = #{ToRuby.to_ruby(code[2])}
74
78
  ensure
75
- #{arguments.join(",")} = oldargs # restore bindings
79
+ #{(0..arguments.size-1).map{|i| "#{arguments[i]} = #{oldargsvar}[#{i}]" }.join(";")}
76
80
  end
77
81
  aux
78
82
  }.lisp_inner_code(#{code.lisp_inspect.inspect}))"
@@ -121,6 +125,10 @@ class DsLisp
121
125
  end
122
126
 
123
127
  def parse(str)
128
+ if str =~ /^\s*$/
129
+ return :nil
130
+ end
131
+
124
132
  if str.count("(") != str.count(")")
125
133
  raise "Parentheshis count does not match, try adding parenthesis at the end of string :P"
126
134
  end
@@ -199,7 +207,7 @@ private
199
207
  _nth = lambda{|index,list| list[index-1]}
200
208
 
201
209
  # list constructors
202
- _cons = lambda{|element, list| [element]+list}
210
+ _cons = lambda{|element, list| [element]+list.to_a}
203
211
  _append = plus
204
212
  _list = lambda{|*args| args}
205
213
 
@@ -229,8 +237,8 @@ private
229
237
  as_function = lambda{|object|
230
238
  if Symbol === object
231
239
  eval(ToRuby.name_convert(object),@binding)
232
- elsif not object.respond_to?(:call)
233
- lambda{|*x| object}
240
+ elsif Array === object
241
+ evaluate(object)
234
242
  else
235
243
  object
236
244
  end
@@ -243,6 +251,8 @@ private
243
251
  }
244
252
 
245
253
  _mapcar = lambda{|function, list| list.map(&as_function.call(function))}
254
+ _apply = lambda{|function, arguments| as_function.call(function).call(*arguments) }
255
+ _funcall = lambda{|function, *arguments| as_function.call(function).call(*arguments) }
246
256
  end
247
257
  @binding
248
258
  end
data/lib/dslisprb.rb~ CHANGED
@@ -66,13 +66,17 @@ class DsLisp
66
66
 
67
67
  def lambda(code)
68
68
  arguments = code[1].map(&ToRuby.method(:name_convert)).map(&:to_s)
69
- "(#{arguments.join(",")} = #{code[1].map{"nil"}.join(",")} ;lambda{|*x|
70
- oldargs = [ #{arguments.join(",")} ] # save current bindings
69
+
70
+ @count = (@count || 0) + 1
71
+ oldargsvar = "oldargs_#{@count}"
72
+
73
+ "(lambda{|*x|
74
+ #{oldargsvar} = [ #{arguments.map{|z| "begin; #{z}; rescue; nil; end"}.join(",")} ] # save current bindings
71
75
  #{(0..arguments.size-1).map{|i| "#{arguments[i]} = x[#{i}]" }.join(";")}
72
76
  begin
73
77
  aux = #{ToRuby.to_ruby(code[2])}
74
78
  ensure
75
- #{arguments.join(",")} = oldargs # restore bindings
79
+ #{(0..arguments.size-1).map{|i| "#{arguments[i]} = #{oldargsvar}[#{i}]" }.join(";")}
76
80
  end
77
81
  aux
78
82
  }.lisp_inner_code(#{code.lisp_inspect.inspect}))"
@@ -121,6 +125,10 @@ class DsLisp
121
125
  end
122
126
 
123
127
  def parse(str)
128
+ if str =~ /^\s*$/
129
+ return :nil
130
+ end
131
+
124
132
  if str.count("(") != str.count(")")
125
133
  raise "Parentheshis count does not match, try adding parenthesis at the end of string :P"
126
134
  end
@@ -199,7 +207,7 @@ private
199
207
  _nth = lambda{|index,list| list[index-1]}
200
208
 
201
209
  # list constructors
202
- _cons = lambda{|element, list| [element]+list}
210
+ _cons = lambda{|element, list| [element]+list.to_a}
203
211
  _append = plus
204
212
  _list = lambda{|*args| args}
205
213
 
@@ -230,6 +238,7 @@ private
230
238
  if Symbol === object
231
239
  eval(ToRuby.name_convert(object),@binding)
232
240
  elsif not object.respond_to?(:call)
241
+ _funcall = lambda{|function, *arguments| as_function.call(function).call(*arguments) }
233
242
  lambda{|*x| object}
234
243
  else
235
244
  object
@@ -243,6 +252,8 @@ private
243
252
  }
244
253
 
245
254
  _mapcar = lambda{|function, list| list.map(&as_function.call(function))}
255
+ _apply = lambda{|function, arguments| as_function.call(function).call(*arguments) }
256
+ _funcall = lambda{|function, *arguments| as_function.call(function).call(*arguments) }
246
257
  end
247
258
  @binding
248
259
  end
@@ -260,6 +271,12 @@ class Symbol
260
271
  end
261
272
  end
262
273
 
274
+ class TrueClass
275
+ def lisp_inspect
276
+ "T"
277
+ end
278
+ end
279
+
263
280
  class Array
264
281
  def lisp_inspect
265
282
  "(" + map(&:lisp_inspect).join(" ") + ")"
data/spec/functions.rb CHANGED
@@ -144,6 +144,31 @@ describe DsLisp, "ds lisp functions" do
144
144
  it "should interpret T symbol as true" do
145
145
  DsLisp.new.evaluate(:T).should be == true
146
146
  end
147
+
148
+ it "should execute apply with symbol function" do
149
+ DsLisp.new.evaluate("(apply 'car '((1 2 3)))").should be == 1
150
+ end
151
+
152
+ it "should execute apply with lambda" do
153
+ DsLisp.new.evaluate("(apply (lambda (x) (car x)) '((1 2 3)))").should be == 1
154
+ end
155
+
156
+ it "should execute apply with quoted lambda" do
157
+ DsLisp.new.evaluate("(apply '(lambda (x) (car x)) '((1 2 3)))").should be == 1
158
+ end
159
+
160
+ it "should execute funcall with symbol function" do
161
+ DsLisp.new.evaluate("(funcall 'car '(1 2 3))").should be == 1
162
+ end
163
+
164
+ it "should execute apply with lambda" do
165
+ DsLisp.new.evaluate("(funcall (lambda (x) (car x)) '(1 2 3))").should be == 1
166
+ end
167
+
168
+ it "should execute apply with quoted lambda" do
169
+ DsLisp.new.evaluate("(funcall '(lambda (x) (car x)) '(1 2 3))").should be == 1
170
+ end
171
+
147
172
  end
148
173
 
149
174
 
data/spec/functions.rb~ CHANGED
@@ -142,7 +142,7 @@ describe DsLisp, "ds lisp functions" do
142
142
  end
143
143
 
144
144
  it "should interpret T symbol as true" do
145
- DsLisp.new.evaluate(:T).should be == nil
145
+ DsLisp.new.evaluate(:T).should be == true
146
146
  end
147
147
  end
148
148
 
data/spec/stack.rb CHANGED
@@ -10,5 +10,43 @@ describe DsLisp, "ds lisp stack" do
10
10
  dslisp.evaluate("(set foo2 (lambda (x) (foo1 4)))")
11
11
  dslisp.evaluate("(foo2 3)").should be == 7
12
12
  end
13
+
14
+ it "should restore variable f when assigned to list" do
15
+
16
+ dslisp = DsLisp.new
17
+
18
+ dslisp.evaluate("(defun b (f x)
19
+ (mapcar
20
+ (lambda (a)
21
+ (a x)
22
+ )
23
+
24
+ f
25
+ )
26
+ ) ".gsub("\n"," "))
27
+
28
+ dslisp.evaluate("(set f 100)")
29
+ dslisp.evaluate("(b (list car cdr) '(1 2 3))")
30
+ dslisp.evaluate("f").should be == 100
31
+ end
32
+
33
+ it "should restore variable f when assigned to list when assignment occurs before defun" do
34
+
35
+ dslisp = DsLisp.new
36
+
37
+ dslisp.evaluate("(set f 100)")
38
+ dslisp.evaluate("(defun b (f x)
39
+ (mapcar
40
+ (lambda (a)
41
+ 1
42
+ )
43
+
44
+ f
45
+ )
46
+ ) ".gsub("\n"," "))
47
+
48
+ dslisp.evaluate("(b '(list car) '(1 2 3))")
49
+ dslisp.evaluate("f").should be == 100
50
+ end
13
51
  end
14
52
 
data/spec/stack.rb~ CHANGED
@@ -8,7 +8,45 @@ describe DsLisp, "ds lisp stack" do
8
8
  dslisp.evaluate("(set x 100)")
9
9
  dslisp.evaluate("(set foo1 (lambda (z) (+ x z)))")
10
10
  dslisp.evaluate("(set foo2 (lambda (x) (foo1 4)))")
11
- dslisp.evluaate("(foo2 3)").should be == 7
11
+ dslisp.evaluate("(foo2 3)").should be == 7
12
+ end
13
+
14
+ it "should restore variable f when assigned to list" do
15
+
16
+ dslisp = DsLisp.new
17
+
18
+ dslisp.evaluate("(defun b (f x)
19
+ (mapcar
20
+ (lambda (a)
21
+ (a x)
22
+ )
23
+
24
+ f
25
+ )
26
+ ) ".gsub("\n"," "))
27
+
28
+ dslisp.evaluate("(set f 100)")
29
+ dslisp.evaluate("(b (list car cdr) '(1 2 3))")
30
+ dslisp.evaluate("f").should be == 100
31
+ end
32
+
33
+ it "should restore variable f when assigned to list when assignment occurs before defun" do
34
+
35
+ dslisp = DsLisp.new
36
+
37
+ dslisp.evaluate("(set f 100)")
38
+ dslisp.evaluate("(defun b (f x)
39
+ (mapcar
40
+ (lambda (a)
41
+ 1
42
+ )
43
+
44
+ f
45
+ )
46
+ ) ".gsub("\n"," "))
47
+
48
+ dslisp.evaluate("(b '() '(1 2 3))")
49
+ dslisp.evaluate("f").should be == 100
12
50
  end
13
51
  end
14
52
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dslisprb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-30 00:00:00.000000000Z
12
+ date: 2012-06-02 00:00:00.000000000Z
13
13
  dependencies: []
14
14
  description:
15
15
  email: robertodarioseminara@gmail.com