rubymotionlisp 0.2.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +129 -2
  3. data/lib/rubylisp/atom.rb +25 -6
  4. data/lib/rubylisp/boolean.rb +9 -6
  5. data/lib/rubylisp/builtins.rb +33 -0
  6. data/lib/rubylisp/character.rb +14 -275
  7. data/lib/rubylisp/class_object.rb +56 -0
  8. data/lib/rubylisp/cons_cell.rb +50 -20
  9. data/lib/rubylisp/environment.rb +27 -0
  10. data/lib/rubylisp/environment_frame.rb +24 -6
  11. data/lib/rubylisp/eof_object.rb +26 -0
  12. data/lib/rubylisp/exception.rb +61 -61
  13. data/lib/rubylisp/ext.rb +32 -6
  14. data/lib/rubylisp/ffi_new.rb +2 -1
  15. data/lib/rubylisp/ffi_send.rb +15 -5
  16. data/lib/rubylisp/frame.rb +5 -164
  17. data/lib/rubylisp/function.rb +4 -3
  18. data/lib/rubylisp/macro.rb +13 -8
  19. data/lib/rubylisp/{object.rb → native_object.rb} +0 -15
  20. data/lib/rubylisp/number.rb +5 -0
  21. data/lib/rubylisp/parser.rb +81 -52
  22. data/lib/rubylisp/port.rb +27 -0
  23. data/lib/rubylisp/prim_alist.rb +115 -0
  24. data/lib/rubylisp/prim_assignment.rb +61 -0
  25. data/lib/rubylisp/prim_character.rb +273 -0
  26. data/lib/rubylisp/{ffi_class.rb → prim_class_object.rb} +16 -69
  27. data/lib/rubylisp/prim_environment.rb +203 -0
  28. data/lib/rubylisp/prim_equivalence.rb +93 -0
  29. data/lib/rubylisp/prim_frame.rb +166 -0
  30. data/lib/rubylisp/prim_io.rb +266 -0
  31. data/lib/rubylisp/prim_list_support.rb +496 -0
  32. data/lib/rubylisp/{logical.rb → prim_logical.rb} +9 -14
  33. data/lib/rubylisp/prim_math.rb +397 -0
  34. data/lib/rubylisp/prim_native_object.rb +21 -0
  35. data/lib/rubylisp/prim_relational.rb +42 -0
  36. data/lib/rubylisp/{special_forms.rb → prim_special_forms.rb} +97 -84
  37. data/lib/rubylisp/prim_string.rb +792 -0
  38. data/lib/rubylisp/prim_system.rb +55 -0
  39. data/lib/rubylisp/prim_type_checks.rb +58 -0
  40. data/lib/rubylisp/prim_vector.rb +497 -0
  41. data/lib/rubylisp/primitive.rb +51 -6
  42. data/lib/rubylisp/string.rb +4 -803
  43. data/lib/rubylisp/symbol.rb +0 -1
  44. data/lib/rubylisp/tokenizer.rb +160 -136
  45. data/lib/rubylisp/vector.rb +10 -31
  46. data/lib/rubymotion/debug.rb +40 -0
  47. data/lib/rubymotion/require-fix.rb +1 -0
  48. data/lib/rubymotionlisp.rb +4 -0
  49. metadata +28 -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/motion_builtins.rb +0 -31
  57. data/lib/rubylisp/relational.rb +0 -46
  58. data/lib/rubylisp/system.rb +0 -20
  59. data/lib/rubylisp/testing.rb +0 -136
  60. data/lib/rubylisp/type_checks.rb +0 -60
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d85596233d6ab54b78b99d7f4342ffd4715b0232
4
- data.tar.gz: 2d932f67ed7198a177d3e861f7e28e8bf44ed17b
3
+ metadata.gz: 4a5e0c6cc93b15753596a1b9aa0c822b0b68c6a3
4
+ data.tar.gz: 00eee04b22a3f97fed1247ccfd648344e52be820
5
5
  SHA512:
6
- metadata.gz: b7a037bf9a0259db400540ffed44e03435c9f5b99000b1109b2cd80904c35a2a15c5b1e56db1986246daf758cba332cf6aefe149f48bbdd32485c5cb9c9e9381
7
- data.tar.gz: 3b44862aef4a032f91ef8049eda3b3c8d513643cc3c6c500ffbbd1ab90b6d93a825da01245d7428fd70e595b179b38832ddbd2c636762cc84d933db572d27982
6
+ metadata.gz: 9c4ff7a0acfd6600aaf14a59d7a4ed1f3d44bf159f5058e0314637e475acfff5cef39dd2749d3f1f4ea33109d6bab6232762f5b8e7b29a81883b4afef893892e
7
+ data.tar.gz: 4bcdc3a7c9b7af440ffe8c563c8e422b5e63724189b873eb0e39d12b4647332550349c67494e0892ace064bb67fd1856280713fb6612eceb0e0570af53d62850
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/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
@@ -0,0 +1,33 @@
1
+ module Lisp
2
+
3
+ class Initializer
4
+
5
+ def self.initialize_global_environment
6
+ Lisp::EnvironmentFrame.global.bind(Symbol.named("nil"), nil)
7
+ end
8
+
9
+ def self.register_builtins
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
27
+ Lisp::Debug.register
28
+ Lisp::PrimEnvironment.register
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -3,278 +3,6 @@ module Lisp
3
3
 
4
4
  class Character < Atom
5
5
 
6
- def self.register
7
- Primitive.register("char->name", "(char->name char)\n\nReturns a string corresponding to the printed representation of char. This is the character or character-name component of the external representation.") do |args, env|
8
- Lisp::Character::char_name_impl(args, env)
9
- end
10
-
11
- Primitive.register("name->char", "(name->char string)\n\nConverts a string that names a character into the character specified. If string does not name any character, name->char signals an error.") do |args, env|
12
- Lisp::Character::name_char_impl(args, env)
13
- end
14
-
15
- Primitive.register("char=?", "(char=? char1 char2)\n\nReturn whether char1 and char2 are the same") do |args, env|
16
- Lisp::Character::char_eq_impl(args, env)
17
- end
18
-
19
- Primitive.register("char<?", "(char<? char1 char2)\n\nReturn whether char1 is less than char2") do |args, env|
20
- Lisp::Character::char_lt_impl(args, env)
21
- end
22
-
23
- Primitive.register("char>?", "(char>? char1 char2)\n\nReturn whether char1 is greater than char2") do |args, env|
24
- Lisp::Character::char_gt_impl(args, env)
25
- end
26
-
27
- Primitive.register("char<=?", "(char<=? char1 char2)\n\nReturn whether char1 is less than or equal to char2") do |args, env|
28
- Lisp::Character::char_lteq_impl(args, env)
29
- end
30
-
31
- Primitive.register("char>=?", "(char>=? char1 char2)\n\nReturn whether char1 is greater than or equal to char2") do |args, env|
32
- Lisp::Character::char_gteq_impl(args, env)
33
- end
34
-
35
- Primitive.register("char-ci=?", "(char=? char1 char2)\n\nReturn whether char1 is equal to char2, ignoring case") do |args, env|
36
- Lisp::Character::char_ci_eq_impl(args, env)
37
- end
38
-
39
- Primitive.register("char-ci<?", "(char=? char1 char2)\n\nReturn whether char1 is less than char2, ignoring case") do |args, env|
40
- Lisp::Character::char_ci_lt_impl(args, env)
41
- end
42
-
43
- Primitive.register("char-ci>?", "(char=? char1 char2)\n\nReturn whether char1 is greater than char2, ignoring case") do |args, env|
44
- Lisp::Character::char_ci_gt_impl(args, env)
45
- end
46
-
47
- Primitive.register("char-ci<=?", "(char=? char1 char2)\n\nReturn whether char1 is less than or equal to char2, ignoring case") do |args, env|
48
- Lisp::Character::char_ci_lteq_impl(args, env)
49
- end
50
-
51
- Primitive.register("char-ci>=?", "(char=? char1 char2)\n\nReturn whether char1 is greater than orequal to char2, ignoring case") do |args, env|
52
- Lisp::Character::char_ci_gteq_impl(args, env)
53
- end
54
-
55
- Primitive.register("char?", "(char? sexpr)\n\nReturns #t if object is a character; otherwise returns #f.") do |args, env|
56
- Lisp::Character::charp_impl(args, env)
57
- end
58
-
59
- Primitive.register("char-upcase", "(char-upcase char)\n\nReturns the uppercase equivalent of char if char is a letter; otherwise returns char. These procedures return a character char2 such that (char-ci=? char char2).") do |args, env|
60
- Lisp::Character::char_upcase_impl(args, env)
61
- end
62
-
63
- Primitive.register("char-downcase", "(char-downcase char)\n\nReturns the lowercase equivalent of char if char is a letter; otherwise returns char. These procedures return a character char2 such that (char-ci=? char char2).") do |args, env|
64
- Lisp::Character::char_downcase_impl(args, env)
65
- end
66
-
67
- Primitive.register("char->digit", "(char->digit char [radix])\n\nIf char is a character representing a digit in the given radix, returns the corresponding integer value. If you specify radix (which must be an integer between 2 and 36 inclusive), the conversion is done in that base, otherwise it is done in base 10. If char doesn’t represent a digit in base radix, char->digit returns #f.\n\nNote that this procedure is insensitive to the alphabetic case of char.") do |args, env|
68
- Lisp::Character::char_digit_impl(args, env)
69
- end
70
-
71
- Primitive.register("digit->char", "(digit->char digit [radix])\n\nReturns a character that represents digit in the radix given by radix. Radix must be an exact integer between 2 and 36 (inclusive), and defaults to 10. Digit, which must be a non-negative integer, should be less than radix; if digit is greater than or equal to radix, digit->char returns #f.") do |args, env|
72
- Lisp::Character::digit_char_impl(args, env)
73
- end
74
-
75
- Primitive.register("char->integer", "(char->integer char)\n\nchar->integer returns the character code representation for char.") do |args, env|
76
- Lisp::Character::char_int_impl(args, env)
77
- end
78
-
79
- Primitive.register("integer->char", "(integer->char k)\n\ninteger->char returns the character whose character code representation is k.") do |args, env|
80
- Lisp::Character::int_char_impl(args, env)
81
- end
82
- end
83
-
84
-
85
- def self.find_character_for_chr(ch)
86
- @@character_constants.each_value {|v| return v if v.value == ch}
87
- return @@character_constants[ch] = Lisp::Character.new(ch)
88
- end
89
-
90
-
91
- def self.find_character_for_name(n)
92
- return @@character_constants[n] if @@character_constants.has_key?(n)
93
- if n.length == 1
94
- ch = self.new(n[0])
95
- return @@character_constants[n] = ch
96
- end
97
- nil
98
- end
99
-
100
-
101
- def self.char_name_impl(args, env)
102
- return Lisp::Debug.process_error("char->name requires a single argument, found #{args.length}", env) unless args.length == 1
103
- char = args.car.evaluate(env)
104
- return Lisp::Debug.process_error("char->name requires a character argument", env) unless char.character?
105
- kv = @@character_constants.rassoc(char)
106
- return Lisp::String.with_value(kv[0]) unless kv.nil?
107
- return Lisp::Debug.process_error("char->name was passed an invalid character", env)
108
- end
109
-
110
-
111
- def self.name_char_impl(args, env)
112
- return Lisp::Debug.process_error("name->char requires a single argument, found #{args.length}", env) unless args.length == 1
113
- name = args.car.evaluate(env)
114
- return Lisp::Debug.process_error("name->char requires a string argument", env) unless name.string?
115
- ch = find_character_for_name(name.value)
116
- return ch unless ch.nil?
117
- return Lisp::Debug.process_error("There is no character with the name #{name}", env)
118
- end
119
-
120
-
121
- def self.get_one_character_arg(func, args, env)
122
- return Lisp::Debug.process_error("#{func} requires a character argument, found no args", env) unless args.length >= 1
123
- char1 = args.car.evaluate(env)
124
- return Lisp::Debug.process_error("#{func} requires a character argument, found #{char1}", env) unless char1.character?
125
- return char1
126
- end
127
-
128
-
129
- def self.get_two_character_args(func, args, env)
130
- return Lisp::Debug.process_error("#{func} requires two arguments, found
131
- ##{args.length}", env) unless args.length == 2
132
- char1 = args.car.evaluate(env)
133
- return Lisp::Debug.process_error("#{func} requires character arguments, found #{char1}", env) unless char1.character?
134
- char2 = args.cadr.evaluate(env)
135
- return Lisp::Debug.process_error("#{func} requires character arguments, found #{char2}", env) unless char2.character?
136
- return [char1, char2]
137
- end
138
-
139
-
140
- def self.char_eq_impl(args, env)
141
- char1, char2 = get_two_character_args("char=?", args, env)
142
- Lisp::Boolean.with_value(char1.value == char2.value)
143
- end
144
-
145
-
146
- def self.char_lt_impl(args, env)
147
- char1, char2 = get_two_character_args("char<?", args, env)
148
- Lisp::Boolean.with_value(char1.value < char2.value)
149
- end
150
-
151
-
152
- def self.char_gt_impl(args, env)
153
- char1, char2 = get_two_character_args("char>?", args, env)
154
- Lisp::Boolean.with_value(char1.value > char2.value)
155
- end
156
-
157
-
158
- def self.char_lteq_impl(args, env)
159
- char1, char2 = get_two_character_args("char<=?", args, env)
160
- Lisp::Boolean.with_value(char1.value <= char2.value)
161
- end
162
-
163
-
164
- def self.char_gteq_impl(args, env)
165
- char1, char2 = get_two_character_args("char>=?", args, env)
166
- Lisp::Boolean.with_value(char1.value >= char2.value)
167
- end
168
-
169
-
170
- def self.char_ci_eq_impl(args, env)
171
- char1, char2 = get_two_character_args("char-ci=?", args, env)
172
- Lisp::Boolean.with_value(char1.value.downcase == char2.value.downcase)
173
- end
174
-
175
-
176
- def self.char_ci_lt_impl(args, env)
177
- char1, char2 = get_two_character_args("char-ci<?", args, env)
178
- Lisp::Boolean.with_value(char1.value.downcase < char2.value.downcase)
179
- end
180
-
181
-
182
- def self.char_ci_gt_impl(args, env)
183
- char1, char2 = get_two_character_args("char-ci>?", args, env)
184
- Lisp::Boolean.with_value(char1.value.downcase > char2.value.downcase)
185
- end
186
-
187
-
188
- def self.char_ci_lteq_impl(args, env)
189
- char1, char2 = get_two_character_args("char-ci<=?", args, env)
190
- Lisp::Boolean.with_value(char1.value.downcase <= char2.value.downcase)
191
- end
192
-
193
-
194
- def self.char_ci_gteq_impl(args, env)
195
- char1, char2 = get_two_character_args("char-ci>=?", args, env)
196
- Lisp::Boolean.with_value(char1.value.downcase >= char2.value.downcase)
197
- end
198
-
199
-
200
- def self.charp_impl(args, env)
201
- return Lisp::Debug.process_error("char->name requires a single argument, found #{args.length}", env) unless args.length == 1
202
- char = args.car.evaluate(env)
203
- Lisp::Boolean.with_value(char.character?)
204
- end
205
-
206
-
207
- def self.char_upcase_impl(args, env)
208
- char = get_one_character_arg("char->digit", args, env)
209
- find_character_for_chr(char.value.upcase)
210
- end
211
-
212
-
213
- def self.char_downcase_impl(args, env)
214
- char = get_one_character_arg("char->digit", args, env)
215
- find_character_for_chr(char.value.downcase)
216
- end
217
-
218
-
219
- def self.char_digit_impl(args, env)
220
- char = get_one_character_arg("char->digit", args, env)
221
- base = if args.length == 1
222
- 10
223
- else
224
- b = args.cadr.evaluate(env)
225
- return Lisp::Debug.process_error("Base for char->digit has to be an integer", env) unless b.integer?
226
- return Lisp::Debug.process_error("Base for char->digit has to be between 2 and 36", env) unless b.value >=2 && b.value <= 36
227
- b.value
228
- end
229
- ch = char.value.upcase
230
- value = case ch
231
- when /[0-9]/
232
- ch[0].ord - 48
233
- when /[A-Z]/
234
- 10 + ch[0].ord - 65
235
- else
236
- -1
237
- end
238
- if value == -1
239
- Lisp::FALSE
240
- elsif value >= base
241
- Lisp::FALSE
242
- else
243
- Lisp::Number.with_value(value)
244
- end
245
- end
246
-
247
-
248
- def self.digit_char_impl(args, env)
249
- d = args.car.evaluate(env)
250
- return Lisp::Debug.process_error("Digit value for digit->char has to be an integer", env) unless d.integer?
251
- base = if args.length == 1
252
- 10
253
- else
254
- b = args.cadr.evaluate(env)
255
- return Lisp::Debug.process_error("Base for char->digit has to be an integer", env) unless b.integer?
256
- return Lisp::Debug.process_error("Base for char->digit has to be between 2 and 36", env) unless b.value >=2 && b.value <= 36
257
- b.value
258
- end
259
- val = d.value
260
- return Lisp::FALSE if val < 0 || val >= base
261
- find_character_for_chr((((val < 10) ? 48 : 55) + val).chr)
262
- end
263
-
264
-
265
- def self.char_int_impl(args, env)
266
- char = get_one_character_arg("char->int", args, env)
267
- Lisp::Number.with_value(char.value.ord)
268
- end
269
-
270
-
271
- def self.int_char_impl(args, env)
272
- i = args.car.evaluate(env)
273
- return Lisp::Debug.process_error("Integer value for int->char has to be an integer", env) unless i.integer?
274
- find_character_for_chr(i.value.chr)
275
- end
276
-
277
-
278
6
  def initialize(n)
279
7
  @value = n
280
8
  end
@@ -289,6 +17,12 @@ module Lisp
289
17
  true
290
18
  end
291
19
 
20
+
21
+ def eqv?(other)
22
+ return false unless other.character?
23
+ @value == other.value
24
+ end
25
+
292
26
 
293
27
  def type
294
28
  :character
@@ -363,9 +97,14 @@ module Lisp
363
97
  @@character_constants["DEL"] = Lisp::Character.new("\x7F")
364
98
 
365
99
 
100
+ def self.character_constants()
101
+ @@character_constants
102
+ end
103
+
104
+
366
105
  def self.with_value(n)
367
106
  if n.length == 1
368
- ch = find_character_for_chr(n[0])
107
+ ch = Lisp::PrimCharacter.find_character_for_chr(n[0])
369
108
  return ch unless ch.nil?
370
109
  ch = self.new(n[0])
371
110
  @@character_constants[n] = ch
@@ -373,9 +112,9 @@ module Lisp
373
112
  elsif @@character_constants.has_key?(n)
374
113
  @@character_constants[n]
375
114
  elsif n[0..1] == "U+"
376
- find_character_for_chr(n[2..-1].to_i(16).chr)
115
+ Lisp::PrimCharacter.find_character_for_chr(n[2..-1].to_i(16).chr)
377
116
  else
378
- return Lisp::Debug.process_error("Invalid character name: #{n}", env)
117
+ return Lisp::Debug.process_error("Invalid character name: #{n}", Lisp::EnvironmentFrame.global)
379
118
  end
380
119
  end
381
120
 
@@ -0,0 +1,56 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Lisp
3
+
4
+ class ClassObject < Atom
5
+
6
+ def self.new_instance
7
+ self.new(@value.alloc.init)
8
+ end
9
+
10
+
11
+ def self.with_class(c)
12
+ self.new(c)
13
+ end
14
+
15
+
16
+ def initialize(c)
17
+ @value = c
18
+ end
19
+
20
+
21
+ def with_value(&block)
22
+ block.call(@value)
23
+ end
24
+
25
+
26
+ def class?
27
+ true
28
+ end
29
+
30
+
31
+ def type
32
+ :class
33
+ end
34
+
35
+
36
+ def native_type
37
+ @value.class
38
+ end
39
+
40
+
41
+ def to_s
42
+ "<a class: #{@value.name}>"
43
+ end
44
+
45
+
46
+ def true?
47
+ @value != nil
48
+ end
49
+
50
+
51
+ def false?
52
+ @value == nil
53
+ end
54
+
55
+ end
56
+ end