rubylisp 0.2.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +129 -2
- data/bin/rubylisp +87 -12
- data/lib/rubylisp/atom.rb +25 -6
- data/lib/rubylisp/boolean.rb +9 -6
- data/lib/rubylisp/builtins.rb +19 -18
- data/lib/rubylisp/character.rb +14 -275
- data/lib/rubylisp/class_object.rb +56 -0
- data/lib/rubylisp/cons_cell.rb +56 -25
- data/lib/rubylisp/debug.rb +15 -19
- data/lib/rubylisp/environment.rb +27 -0
- data/lib/rubylisp/environment_frame.rb +31 -6
- data/lib/rubylisp/eof_object.rb +26 -0
- data/lib/rubylisp/exception.rb +61 -61
- data/lib/rubylisp/ext.rb +32 -6
- data/lib/rubylisp/ffi_new.rb +2 -1
- data/lib/rubylisp/ffi_send.rb +15 -5
- data/lib/rubylisp/frame.rb +5 -164
- data/lib/rubylisp/function.rb +4 -3
- data/lib/rubylisp/macro.rb +13 -8
- data/lib/rubylisp/{object.rb → native_object.rb} +0 -15
- data/lib/rubylisp/number.rb +5 -0
- data/lib/rubylisp/parser.rb +81 -52
- data/lib/rubylisp/port.rb +27 -0
- data/lib/rubylisp/prim_alist.rb +115 -0
- data/lib/rubylisp/prim_assignment.rb +61 -0
- data/lib/rubylisp/prim_character.rb +273 -0
- data/lib/rubylisp/{ffi_class.rb → prim_class_object.rb} +16 -69
- data/lib/rubylisp/prim_environment.rb +203 -0
- data/lib/rubylisp/prim_equivalence.rb +93 -0
- data/lib/rubylisp/prim_frame.rb +166 -0
- data/lib/rubylisp/prim_io.rb +266 -0
- data/lib/rubylisp/prim_list_support.rb +496 -0
- data/lib/rubylisp/{logical.rb → prim_logical.rb} +9 -14
- data/lib/rubylisp/prim_math.rb +397 -0
- data/lib/rubylisp/prim_native_object.rb +21 -0
- data/lib/rubylisp/prim_relational.rb +42 -0
- data/lib/rubylisp/{special_forms.rb → prim_special_forms.rb} +98 -85
- data/lib/rubylisp/prim_string.rb +792 -0
- data/lib/rubylisp/prim_system.rb +55 -0
- data/lib/rubylisp/prim_type_checks.rb +58 -0
- data/lib/rubylisp/prim_vector.rb +497 -0
- data/lib/rubylisp/primitive.rb +51 -6
- data/lib/rubylisp/string.rb +4 -803
- data/lib/rubylisp/symbol.rb +0 -1
- data/lib/rubylisp/tokenizer.rb +161 -137
- data/lib/rubylisp/vector.rb +10 -31
- data/lib/rubylisp.rb +1 -0
- metadata +46 -17
- data/lib/rubylisp/alist.rb +0 -230
- data/lib/rubylisp/assignment.rb +0 -65
- data/lib/rubylisp/equivalence.rb +0 -118
- data/lib/rubylisp/io.rb +0 -74
- data/lib/rubylisp/list_support.rb +0 -526
- data/lib/rubylisp/math.rb +0 -405
- data/lib/rubylisp/relational.rb +0 -46
- data/lib/rubylisp/system.rb +0 -20
- data/lib/rubylisp/testing.rb +0 -136
- data/lib/rubylisp/type_checks.rb +0 -60
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb5f9ceceb5366ea22a1684c23f1f891baff4ee9
|
4
|
+
data.tar.gz: 4dcf3352fe2c53178012846dd428a55e25e6ff5e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8b6a30a4b7811e1c08bd49710de04c17ac2cce55a0bd9cd375e5f71c58c386c7c0a70c1335c79cb40d55fc558e06812568b48990b178f39fb0b0264451f5db30
|
7
|
+
data.tar.gz: 8cd9f89766f14601094794fa31404629e5780ce5072ad95abfd346b4733152c7962fa68c17234e475247458e7d65a93985ab7a6fe4bd61ff769c1df60c9293c2
|
data/README.md
CHANGED
@@ -43,13 +43,75 @@ Or install it yourself as:
|
|
43
43
|
4. Push to the branch (git push origin my-new-feature)
|
44
44
|
5. Create new Pull Request
|
45
45
|
|
46
|
-
##
|
46
|
+
## The rubylisp command ##
|
47
|
+
|
48
|
+
Installing the rubylisp gem installs the `rubylisp` command
|
49
|
+
|
50
|
+
>:rubylisp help
|
51
|
+
NAME:
|
52
|
+
|
53
|
+
rubylisp
|
54
|
+
|
55
|
+
DESCRIPTION:
|
56
|
+
|
57
|
+
A large sub/super-set of MIT/GNU-Scheme implemented in pure Ruby.
|
58
|
+
|
59
|
+
COMMANDS:
|
60
|
+
|
61
|
+
help Display global or [command] help documentation
|
62
|
+
repl Rubylisp REPL
|
63
|
+
test Runs tests
|
64
|
+
|
65
|
+
GLOBAL OPTIONS:
|
66
|
+
|
67
|
+
-h, --help
|
68
|
+
Display help documentation
|
69
|
+
|
70
|
+
-v, --version
|
71
|
+
Display version information
|
72
|
+
|
73
|
+
-t, --trace
|
74
|
+
Display backtrace when an error occurs
|
75
|
+
|
76
|
+
>:
|
77
|
+
|
78
|
+
|
79
|
+
### REPL ###
|
47
80
|
|
48
81
|
RubyLisp includes a very basic REPL that, as expected, lets you type
|
49
82
|
in snippets (it does not support multiline snippets) of Lisp code,
|
50
83
|
evaluates them, and prints the result.
|
51
84
|
|
52
|
-
>:
|
85
|
+
>:rubylisp help repl
|
86
|
+
|
87
|
+
NAME:
|
88
|
+
|
89
|
+
repl
|
90
|
+
|
91
|
+
SYNOPSIS:
|
92
|
+
|
93
|
+
rubylisp repl [options]
|
94
|
+
|
95
|
+
DESCRIPTION:
|
96
|
+
|
97
|
+
Rubylisp REPL
|
98
|
+
|
99
|
+
EXAMPLES:
|
100
|
+
|
101
|
+
# Simply run the REPL
|
102
|
+
rubylisp repl
|
103
|
+
|
104
|
+
# Run the REPL, loading a file first
|
105
|
+
rubylisp repl --file code.lsp
|
106
|
+
|
107
|
+
OPTIONS:
|
108
|
+
|
109
|
+
-f, --file LISPFILE
|
110
|
+
The name of the lisp file to load
|
111
|
+
|
112
|
+
|
113
|
+
|
114
|
+
>: rubylisp repl
|
53
115
|
|
54
116
|
RubyLisp REPL
|
55
117
|
> 4
|
@@ -61,6 +123,71 @@ evaluates them, and prints the result.
|
|
61
123
|
> (fib 4)
|
62
124
|
24
|
63
125
|
|
126
|
+
The repl uses readline for editing and history. History is saved in ~/.rubylisp_history. Evaling `(quit)` will exit the repl.
|
127
|
+
|
128
|
+
### Test runner ###
|
129
|
+
|
130
|
+
The `rubylisp` command also contains a test runner.
|
131
|
+
|
132
|
+
>:ruby -Ilib bin/rubylisp help test
|
133
|
+
|
134
|
+
NAME:
|
135
|
+
|
136
|
+
test
|
137
|
+
|
138
|
+
SYNOPSIS:
|
139
|
+
|
140
|
+
rubylisp test [options]
|
141
|
+
|
142
|
+
DESCRIPTION:
|
143
|
+
|
144
|
+
Runs tests
|
145
|
+
|
146
|
+
EXAMPLES:
|
147
|
+
|
148
|
+
# Run the tests in tests/list_tests.lsp with verbose output
|
149
|
+
rubylisp test -v -f tests/list_tests.lsp
|
150
|
+
|
151
|
+
# Quietly run all tests in the directory tests
|
152
|
+
rubylisp test -q -d tests
|
153
|
+
|
154
|
+
OPTIONS:
|
155
|
+
|
156
|
+
-f, --file TESTFILE
|
157
|
+
The name of the test file to run
|
158
|
+
|
159
|
+
-d, --dir TESTDIR
|
160
|
+
The name of a directory of test files, all of which will be run
|
161
|
+
|
162
|
+
--verbose
|
163
|
+
Verbose test output: all context & it labels, and each assertion and it's result.
|
164
|
+
|
165
|
+
--terse
|
166
|
+
terse test output (the default): + for passes, - for failures, and ! for errors
|
167
|
+
|
168
|
+
--quiet
|
169
|
+
Only output a summary
|
170
|
+
|
171
|
+
>:rubylisp test -d lisptest --terse
|
172
|
+
|
173
|
+
|
174
|
+
Running lisp tests
|
175
|
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
176
|
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
177
|
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
178
|
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
179
|
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
180
|
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
181
|
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
182
|
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
183
|
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
184
|
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
185
|
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
186
|
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
187
|
+
++++++++++++++++++++++++++++
|
188
|
+
Ran 928 lisp tests in 7.0789 seconds
|
189
|
+
928 passes, 0 failures, 0 errors
|
190
|
+
|
64
191
|
## Integrating
|
65
192
|
|
66
193
|
|
data/bin/rubylisp
CHANGED
@@ -1,24 +1,99 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'rubylisp'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'commander/import'
|
4
6
|
require 'readline'
|
7
|
+
require 'readline/history/restore'
|
5
8
|
|
6
9
|
Lisp::Initializer.register_builtins
|
7
10
|
Lisp::Debug.interactive = true
|
8
11
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
program :version, '0.0.1'
|
13
|
+
program :description, 'A large sub/super-set of MIT/GNU-Scheme implemented in pure Ruby.'
|
14
|
+
|
15
|
+
# Smarter Readline to prevent empty and dups
|
16
|
+
# 1. Read a line and append to history
|
17
|
+
# 2. Quick Break on nil
|
18
|
+
# 3. Remove from history if empty or dup
|
19
|
+
|
20
|
+
def readline_with_hist_management
|
21
|
+
line = Readline.readline('> ', true)
|
22
|
+
return nil if line.nil?
|
23
|
+
if line =~ /^\s*$/ or Readline::HISTORY.to_a[-2] == line
|
24
|
+
Readline::HISTORY.pop
|
25
|
+
end
|
26
|
+
line
|
27
|
+
end
|
28
|
+
|
29
|
+
command :repl do |c|
|
30
|
+
c.syntax = 'rubylisp repl [options]'
|
31
|
+
c.summary = 'Rubylisp REPL'
|
32
|
+
c.description = c.summary
|
33
|
+
c.example 'Simply run the REPL', 'rubylisp repl'
|
34
|
+
c.example 'Run the REPL, loading a file first', 'rubylisp repl --file code.lsp'
|
35
|
+
c.option '-f', '--file LISPFILE', String, 'The name of the lisp file to load'
|
36
|
+
c.action do |args, options|
|
37
|
+
history_path = File.join(Dir.home, '.rubylisp_history')
|
38
|
+
unless File.exist?(history_path)
|
39
|
+
File.open(history_path, "w") {|f| }
|
40
|
+
end
|
41
|
+
Readline::History::Restore.new(history_path)
|
42
|
+
|
43
|
+
options.default :file => ""
|
44
|
+
puts 'RubyLisp REPL'
|
45
|
+
puts 'Copyright 2014-2015 David R. Astels'
|
46
|
+
puts
|
47
|
+
parser = Lisp::Parser.new
|
48
|
+
parser.process_file(options.file) if options.file != ""
|
49
|
+
while line = readline_with_hist_management
|
50
|
+
begin
|
51
|
+
puts parser.parse_and_eval(line).print_string
|
52
|
+
rescue Exception => ex
|
53
|
+
exit if ex.to_s == "exit"
|
54
|
+
puts "ERROR: #{ex}"
|
55
|
+
# puts ex.backtrace
|
56
|
+
end
|
57
|
+
end
|
21
58
|
end
|
22
59
|
end
|
23
60
|
|
61
|
+
command :test do |c|
|
62
|
+
c.syntax = 'rubylisp test [options]'
|
63
|
+
c.summary = 'Runs tests'
|
64
|
+
c.description = c.summary
|
65
|
+
c.example 'Run the tests in tests/list_tests.lsp with verbose output', 'rubylisp test -v -f tests/list_tests.lsp'
|
66
|
+
c.example 'Quietly run all tests in the directory tests', 'rubylisp test -q -d tests'
|
67
|
+
c.option '-f', '--file TESTFILE', String, 'The name of the test file to run'
|
68
|
+
c.option '-d', '--dir TESTDIR', String, 'The name of a directory of test files, all of which will be run'
|
69
|
+
c.option '--verbose', "Verbose test output: all context & it labels, and each assertion and it's result."
|
70
|
+
c.option '--terse', 'terse test output (the default): + for passes, - for failures, and ! for errors'
|
71
|
+
c.option '--quiet', 'Only output a summary'
|
72
|
+
c.action do |args, options|
|
73
|
+
options.default :file => "",
|
74
|
+
:dir => "",
|
75
|
+
:verbose => false,
|
76
|
+
:quiet => false
|
77
|
+
rubylisp_home = ENV['RUBYLISP_HOME'] || "."
|
78
|
+
cmd, arg = if options.file != ""
|
79
|
+
["run-test", File.join(rubylisp_home, options.file)]
|
80
|
+
elsif options.dir != ""
|
81
|
+
["run-all-tests", File.join(rubylisp_home, options.dir)]
|
82
|
+
else
|
83
|
+
puts "Either a file or directory must be specified"
|
84
|
+
exit
|
85
|
+
end
|
86
|
+
verbosity = if options.verbose
|
87
|
+
"'verbose"
|
88
|
+
elsif options.quiet
|
89
|
+
"'quiet"
|
90
|
+
else
|
91
|
+
""
|
92
|
+
end
|
93
|
+
test_command = "(#{cmd} \"#{arg}\" #{verbosity})"
|
94
|
+
parser = Lisp::Parser.new
|
95
|
+
parser.process_file("#{rubylisp_home}/lisp/testing.lsp")
|
96
|
+
parser.parse_and_eval(test_command).value
|
97
|
+
end
|
98
|
+
end
|
24
99
|
|
data/lib/rubylisp/atom.rb
CHANGED
@@ -68,15 +68,23 @@ module Lisp
|
|
68
68
|
false
|
69
69
|
end
|
70
70
|
|
71
|
-
def
|
71
|
+
def frame?
|
72
72
|
false
|
73
73
|
end
|
74
74
|
|
75
|
-
def
|
75
|
+
def vector?
|
76
76
|
false
|
77
77
|
end
|
78
78
|
|
79
|
-
def
|
79
|
+
def port?
|
80
|
+
false
|
81
|
+
end
|
82
|
+
|
83
|
+
def eof_object?
|
84
|
+
false
|
85
|
+
end
|
86
|
+
|
87
|
+
def environment?
|
80
88
|
false
|
81
89
|
end
|
82
90
|
|
@@ -88,10 +96,16 @@ module Lisp
|
|
88
96
|
self.class.new(self.value)
|
89
97
|
end
|
90
98
|
|
99
|
+
def eqv?(sexpr)
|
100
|
+
self == sexpr
|
101
|
+
end
|
102
|
+
|
91
103
|
def eq?(sexpr)
|
92
|
-
|
93
|
-
|
94
|
-
|
104
|
+
eqv?(sexpr)
|
105
|
+
end
|
106
|
+
|
107
|
+
def equal?(sexpr)
|
108
|
+
eq?(sexpr)
|
95
109
|
end
|
96
110
|
|
97
111
|
def type
|
@@ -133,6 +147,11 @@ module Lisp
|
|
133
147
|
def set!(v)
|
134
148
|
end
|
135
149
|
|
150
|
+
def to_s
|
151
|
+
@value.to_s
|
152
|
+
end
|
153
|
+
|
154
|
+
|
136
155
|
def print_string
|
137
156
|
self.to_s
|
138
157
|
end
|
data/lib/rubylisp/boolean.rb
CHANGED
@@ -2,11 +2,11 @@ module Lisp
|
|
2
2
|
|
3
3
|
class Boolean < Atom
|
4
4
|
def self.TRUE
|
5
|
-
@true_constant ||= Boolean.new(true)
|
5
|
+
@true_constant ||= Lisp::Boolean.new(true)
|
6
6
|
end
|
7
7
|
|
8
8
|
def self.FALSE
|
9
|
-
@false_constant ||= Boolean.new(false)
|
9
|
+
@false_constant ||= Lisp::Boolean.new(false)
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.with_value(b)
|
@@ -26,8 +26,11 @@ module Lisp
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def to_s
|
29
|
-
|
30
|
-
|
29
|
+
if @value
|
30
|
+
"#t"
|
31
|
+
else
|
32
|
+
"#f"
|
33
|
+
end
|
31
34
|
end
|
32
35
|
|
33
36
|
def true?
|
@@ -44,6 +47,6 @@ module Lisp
|
|
44
47
|
|
45
48
|
end
|
46
49
|
|
47
|
-
TRUE = Boolean.TRUE
|
48
|
-
FALSE = Boolean.FALSE
|
50
|
+
TRUE = Lisp::Boolean.TRUE
|
51
|
+
FALSE = Lisp::Boolean.FALSE
|
49
52
|
end
|
data/lib/rubylisp/builtins.rb
CHANGED
@@ -7,26 +7,27 @@ module Lisp
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def self.register_builtins
|
10
|
-
Lisp::
|
11
|
-
Lisp::
|
12
|
-
Lisp::
|
13
|
-
Lisp::
|
14
|
-
Lisp::
|
15
|
-
Lisp::
|
16
|
-
Lisp::
|
17
|
-
Lisp::
|
18
|
-
Lisp::
|
19
|
-
Lisp::
|
20
|
-
Lisp::
|
21
|
-
Lisp::
|
22
|
-
Lisp::
|
23
|
-
Lisp::
|
24
|
-
Lisp::
|
25
|
-
Lisp::
|
26
|
-
Lisp::
|
27
|
-
Lisp::Vector.register
|
10
|
+
Lisp::PrimEquivalence.register
|
11
|
+
Lisp::PrimMath.register
|
12
|
+
Lisp::PrimLogical.register
|
13
|
+
Lisp::PrimSpecialForms.register
|
14
|
+
Lisp::PrimListSupport.register
|
15
|
+
Lisp::PrimRelational.register
|
16
|
+
Lisp::PrimTypeChecks.register
|
17
|
+
Lisp::PrimAssignment.register
|
18
|
+
Lisp::PrimIo.register
|
19
|
+
Lisp::PrimAlist.register
|
20
|
+
Lisp::PrimFrame.register
|
21
|
+
Lisp::PrimCharacter.register
|
22
|
+
Lisp::PrimString.register
|
23
|
+
Lisp::PrimNativeObject.register
|
24
|
+
Lisp::PrimClassObject.register
|
25
|
+
Lisp::PrimSystem.register
|
26
|
+
Lisp::PrimVector.register
|
28
27
|
Lisp::Debug.register
|
28
|
+
Lisp::PrimEnvironment.register
|
29
29
|
end
|
30
|
+
|
30
31
|
end
|
31
32
|
|
32
33
|
end
|