rubylisp 0.2.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +129 -2
  3. data/bin/rubylisp +87 -12
  4. data/lib/rubylisp/atom.rb +25 -6
  5. data/lib/rubylisp/boolean.rb +9 -6
  6. data/lib/rubylisp/builtins.rb +19 -18
  7. data/lib/rubylisp/character.rb +14 -275
  8. data/lib/rubylisp/class_object.rb +56 -0
  9. data/lib/rubylisp/cons_cell.rb +56 -25
  10. data/lib/rubylisp/debug.rb +15 -19
  11. data/lib/rubylisp/environment.rb +27 -0
  12. data/lib/rubylisp/environment_frame.rb +31 -6
  13. data/lib/rubylisp/eof_object.rb +26 -0
  14. data/lib/rubylisp/exception.rb +61 -61
  15. data/lib/rubylisp/ext.rb +32 -6
  16. data/lib/rubylisp/ffi_new.rb +2 -1
  17. data/lib/rubylisp/ffi_send.rb +15 -5
  18. data/lib/rubylisp/frame.rb +5 -164
  19. data/lib/rubylisp/function.rb +4 -3
  20. data/lib/rubylisp/macro.rb +13 -8
  21. data/lib/rubylisp/{object.rb → native_object.rb} +0 -15
  22. data/lib/rubylisp/number.rb +5 -0
  23. data/lib/rubylisp/parser.rb +81 -52
  24. data/lib/rubylisp/port.rb +27 -0
  25. data/lib/rubylisp/prim_alist.rb +115 -0
  26. data/lib/rubylisp/prim_assignment.rb +61 -0
  27. data/lib/rubylisp/prim_character.rb +273 -0
  28. data/lib/rubylisp/{ffi_class.rb → prim_class_object.rb} +16 -69
  29. data/lib/rubylisp/prim_environment.rb +203 -0
  30. data/lib/rubylisp/prim_equivalence.rb +93 -0
  31. data/lib/rubylisp/prim_frame.rb +166 -0
  32. data/lib/rubylisp/prim_io.rb +266 -0
  33. data/lib/rubylisp/prim_list_support.rb +496 -0
  34. data/lib/rubylisp/{logical.rb → prim_logical.rb} +9 -14
  35. data/lib/rubylisp/prim_math.rb +397 -0
  36. data/lib/rubylisp/prim_native_object.rb +21 -0
  37. data/lib/rubylisp/prim_relational.rb +42 -0
  38. data/lib/rubylisp/{special_forms.rb → prim_special_forms.rb} +98 -85
  39. data/lib/rubylisp/prim_string.rb +792 -0
  40. data/lib/rubylisp/prim_system.rb +55 -0
  41. data/lib/rubylisp/prim_type_checks.rb +58 -0
  42. data/lib/rubylisp/prim_vector.rb +497 -0
  43. data/lib/rubylisp/primitive.rb +51 -6
  44. data/lib/rubylisp/string.rb +4 -803
  45. data/lib/rubylisp/symbol.rb +0 -1
  46. data/lib/rubylisp/tokenizer.rb +161 -137
  47. data/lib/rubylisp/vector.rb +10 -31
  48. data/lib/rubylisp.rb +1 -0
  49. metadata +46 -17
  50. data/lib/rubylisp/alist.rb +0 -230
  51. data/lib/rubylisp/assignment.rb +0 -65
  52. data/lib/rubylisp/equivalence.rb +0 -118
  53. data/lib/rubylisp/io.rb +0 -74
  54. data/lib/rubylisp/list_support.rb +0 -526
  55. data/lib/rubylisp/math.rb +0 -405
  56. data/lib/rubylisp/relational.rb +0 -46
  57. data/lib/rubylisp/system.rb +0 -20
  58. data/lib/rubylisp/testing.rb +0 -136
  59. data/lib/rubylisp/type_checks.rb +0 -60
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e0b0a096ef5fa46d08615d4c222367a34836a0b7
4
- data.tar.gz: 70c1c21b7dbdc44f90a363c1449e0884277a1629
3
+ metadata.gz: bb5f9ceceb5366ea22a1684c23f1f891baff4ee9
4
+ data.tar.gz: 4dcf3352fe2c53178012846dd428a55e25e6ff5e
5
5
  SHA512:
6
- metadata.gz: d3dc36bfb715c2107428acc3c04e79d13880969c82b4b5a8681f4b7be5a3025a811a0eee146c431536cd4d0527f975476d9508d5a24ce367bcf0f6048f11cbc9
7
- data.tar.gz: 0305826d42b7b62acc6828a776a6145c28a805cf0d80a325d79088b12d5caca69f8a7da8ebea341e83094b0e304e737223ebb0646b64dc01fd4058dde2e68343
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
- ## REPL
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
- >: rubylisp
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
- puts 'RubyLisp REPL'
10
- puts 'Copyright 2014 David R. Astels'
11
- puts
12
- parser = Lisp::Parser.new
13
-
14
- while line = Readline.readline('> ', true)
15
- begin
16
- puts parser.parse_and_eval(line)
17
- rescue Exception => ex
18
- exit if ex.to_s == "exit"
19
- puts "ERROR: #{ex}"
20
- puts ex.backtrace
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 alist?
71
+ def frame?
72
72
  false
73
73
  end
74
74
 
75
- def frame?
75
+ def vector?
76
76
  false
77
77
  end
78
78
 
79
- def vector?
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
- return false if sexpr.nil?
93
- return false if self.type != sexpr.type
94
- self.value == sexpr.value
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
@@ -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
- return "#t" if @value
30
- "#f"
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
@@ -7,26 +7,27 @@ module Lisp
7
7
  end
8
8
 
9
9
  def self.register_builtins
10
- Lisp::Equivalence.register
11
- Lisp::Math.register
12
- Lisp::Logical.register
13
- Lisp::SpecialForms.register
14
- Lisp::ListSupport.register
15
- Lisp::Relational.register
16
- Lisp::TypeChecks.register
17
- Lisp::Assignment.register
18
- Lisp::Testing.register
19
- Lisp::IO.register
20
- Lisp::AList.register
21
- Lisp::Frame.register
22
- Lisp::Character.register
23
- Lisp::String.register
24
- Lisp::NativeObject.register
25
- Lisp::ClassObject.register
26
- Lisp::System.register
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