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 +6 -0
- data/Rakefile +1 -1
- data/bin/dslisprb +27 -7
- data/lib/dslisprb.rb +16 -6
- data/lib/dslisprb.rb~ +21 -4
- data/spec/functions.rb +25 -0
- data/spec/functions.rb~ +1 -1
- data/spec/stack.rb +38 -0
- data/spec/stack.rb~ +39 -1
- metadata +2 -2
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
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
|
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
|
-
|
38
|
-
if cmd == "quit"
|
39
|
-
exit
|
40
|
-
end
|
43
|
+
accumulated = ""
|
41
44
|
|
45
|
+
while cmd = Readline.readline(accumulated == "" ? '> ' : '?> ', true)
|
42
46
|
begin
|
43
|
-
|
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
|
-
|
70
|
-
|
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.
|
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
|
233
|
-
|
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
|
-
|
70
|
-
|
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.
|
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
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.
|
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.
|
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-
|
12
|
+
date: 2012-06-02 00:00:00.000000000Z
|
13
13
|
dependencies: []
|
14
14
|
description:
|
15
15
|
email: robertodarioseminara@gmail.com
|