rubymotionlisp 0.2.2 → 1.0.0
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.
- checksums.yaml +4 -4
- data/README.md +129 -2
- data/lib/rubylisp/atom.rb +25 -6
- data/lib/rubylisp/boolean.rb +9 -6
- data/lib/rubylisp/builtins.rb +33 -0
- data/lib/rubylisp/character.rb +14 -275
- data/lib/rubylisp/class_object.rb +56 -0
- data/lib/rubylisp/cons_cell.rb +50 -20
- data/lib/rubylisp/environment.rb +27 -0
- data/lib/rubylisp/environment_frame.rb +24 -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} +97 -84
- 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 +160 -136
- data/lib/rubylisp/vector.rb +10 -31
- data/lib/rubymotion/debug.rb +40 -0
- data/lib/rubymotion/require-fix.rb +1 -0
- data/lib/rubymotionlisp.rb +4 -0
- metadata +28 -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/motion_builtins.rb +0 -31
- 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: 4a5e0c6cc93b15753596a1b9aa0c822b0b68c6a3
|
4
|
+
data.tar.gz: 00eee04b22a3f97fed1247ccfd648344e52be820
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
##
|
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/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
|
@@ -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
|
data/lib/rubylisp/character.rb
CHANGED
@@ -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}",
|
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
|