rubylisp 0.1.1 → 0.2.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 +82 -0
- data/bin/rubylisp +6 -0
- data/lib/rubylisp/alist.rb +17 -17
- data/lib/rubylisp/assignment.rb +7 -7
- data/lib/rubylisp/builtins.rb +1 -0
- data/lib/rubylisp/character.rb +21 -20
- data/lib/rubylisp/cons_cell.rb +46 -3
- data/lib/rubylisp/debug.rb +238 -0
- data/lib/rubylisp/environment_frame.rb +47 -4
- data/lib/rubylisp/exception.rb +8 -8
- data/lib/rubylisp/ext.rb +4 -0
- data/lib/rubylisp/ffi_class.rb +10 -10
- data/lib/rubylisp/ffi_send.rb +3 -3
- data/lib/rubylisp/frame.rb +51 -31
- data/lib/rubylisp/function.rb +4 -3
- data/lib/rubylisp/io.rb +6 -6
- data/lib/rubylisp/list_support.rb +93 -94
- data/lib/rubylisp/logical.rb +3 -3
- data/lib/rubylisp/macro.rb +4 -2
- data/lib/rubylisp/math.rb +58 -56
- data/lib/rubylisp/object.rb +1 -1
- data/lib/rubylisp/parser.rb +5 -5
- data/lib/rubylisp/primitive.rb +1 -1
- data/lib/rubylisp/relational.rb +4 -4
- data/lib/rubylisp/special_forms.rb +29 -27
- data/lib/rubylisp/string.rb +75 -75
- data/lib/rubylisp/system.rb +3 -2
- data/lib/rubylisp/testing.rb +3 -3
- data/lib/rubylisp/type_checks.rb +10 -8
- data/lib/rubylisp/vector.rb +1 -1
- data/lib/rubylisp.rb +1 -0
- metadata +6 -4
data/lib/rubylisp/string.rb
CHANGED
@@ -83,20 +83,20 @@ end
|
|
83
83
|
|
84
84
|
|
85
85
|
def self.stringp_impl(args, env)
|
86
|
-
|
86
|
+
return Lisp::Debug.process_error("string? requires 1 argument", env) unless args.length == 1
|
87
87
|
return Lisp::Boolean.with_value(args.car.evaluate(env).string?)
|
88
88
|
end
|
89
89
|
|
90
90
|
|
91
91
|
def self.make_string_impl(args, env)
|
92
|
-
|
93
|
-
|
92
|
+
return Lisp::Debug.process_error("make-string need requires at least 1 argument", env) unless args.length > 0
|
93
|
+
return Lisp::Debug.process_error("make-string accepts at most 2 arguments, but was passed #{args.length}", env) if args.length > 2
|
94
94
|
k_arg = args.car.evaluate(env)
|
95
|
-
|
95
|
+
return Lisp::Debug.process_error("make-string requires an integer as it's first argument.", env) unless k_arg.integer?
|
96
96
|
k = k_arg.value
|
97
97
|
c = if args.length == 2
|
98
98
|
c_arg = args.cadr.evaluate(env)
|
99
|
-
|
99
|
+
return Lisp::Debug.process_error("make-string requires a character as it's second argument, but received #{c_arg}.", env) unless c_arg.character?
|
100
100
|
c_arg.value
|
101
101
|
else
|
102
102
|
" "
|
@@ -108,7 +108,7 @@ end
|
|
108
108
|
def self.string_impl(args, env)
|
109
109
|
chars = args.to_a.map do |a|
|
110
110
|
ea = a.evaluate(env)
|
111
|
-
|
111
|
+
return Lisp::Debug.process_error("string requires character args, but was passed #{ea}.", env) unless ea.character?
|
112
112
|
ea.value
|
113
113
|
end
|
114
114
|
self.with_value(chars.join)
|
@@ -116,12 +116,12 @@ end
|
|
116
116
|
|
117
117
|
|
118
118
|
def self.list_string_impl(args, env)
|
119
|
-
|
119
|
+
return Lisp::Debug.process_error("list->string requires 1 argument, but received #{args.length}", env) unless args.length == 1
|
120
120
|
list_of_chars = args.car.evaluate(env)
|
121
|
-
|
121
|
+
return Lisp::Debug.process_error("list->string requires a list argument, but received #{str_arg}", env) unless list_of_chars.list?
|
122
122
|
chars = list_of_chars.to_a.map do |a|
|
123
123
|
ea = a.evaluate(env)
|
124
|
-
|
124
|
+
return Lisp::Debug.process_error("string requires a list of characters, but it contained #{ea}.", env) unless ea.character?
|
125
125
|
ea.value
|
126
126
|
end
|
127
127
|
self.with_value(chars.join)
|
@@ -129,45 +129,45 @@ end
|
|
129
129
|
|
130
130
|
|
131
131
|
def self.string_list_impl(args, env)
|
132
|
-
|
132
|
+
return Lisp::Debug.process_error("string->list requires 1 argument, but received #{args.length}", env) unless args.length == 1
|
133
133
|
str_arg = args.car.evaluate(env)
|
134
|
-
|
134
|
+
return Lisp::Debug.process_error("string->list requires a string argument, but received #{str_arg}", env) unless str_arg.string?
|
135
135
|
chars = str_arg.value.each_char.map {|c| Lisp::Character.find_character_for_chr(c) }
|
136
136
|
Lisp::ConsCell.array_to_list(chars)
|
137
137
|
end
|
138
138
|
|
139
139
|
|
140
140
|
def self.string_copy_impl(args, env)
|
141
|
-
|
141
|
+
return Lisp::Debug.process_error("string-copy requires 1 argument, but received #{args.length}", env) unless args.length == 1
|
142
142
|
str_arg = args.car.evaluate(env)
|
143
|
-
|
143
|
+
return Lisp::Debug.process_error("string-copy requires a string argument, but received #{str_arg}", env) unless str_arg.string?
|
144
144
|
self.with_value(str_arg.value)
|
145
145
|
end
|
146
146
|
|
147
147
|
|
148
148
|
def self.string_length_impl(args, env)
|
149
|
-
|
149
|
+
return Lisp::Debug.process_error("string-length requires 1 argument, but received #{args.length}", env) unless args.length == 1
|
150
150
|
str_arg = args.car.evaluate(env)
|
151
|
-
|
151
|
+
return Lisp::Debug.process_error("string-length requires a string argument, but received #{str_arg}", env) unless str_arg.string?
|
152
152
|
Lisp::Number.with_value(str_arg.value.length)
|
153
153
|
end
|
154
154
|
|
155
155
|
|
156
156
|
def self.string_nullp_impl(args, env)
|
157
|
-
|
157
|
+
return Lisp::Debug.process_error("string-length requires 1 argument, but received #{args.length}", env) unless args.length == 1
|
158
158
|
str_arg = args.car.evaluate(env)
|
159
|
-
|
159
|
+
return Lisp::Debug.process_error("string-length requires a string argument, but received #{str_arg}", env) unless str_arg.string?
|
160
160
|
Lisp::Boolean.with_value(str_arg.value.length == 0)
|
161
161
|
end
|
162
162
|
|
163
163
|
|
164
164
|
def self.string_ref_impl(args, env)
|
165
|
-
|
165
|
+
return Lisp::Debug.process_error("string-ref requires 2 arguments, but received #{args.length}", env) unless args.length == 2
|
166
166
|
str_arg = args.car.evaluate(env)
|
167
|
-
|
167
|
+
return Lisp::Debug.process_error("string-ref requires a string as it's first argument, but received #{arg.car}", env) unless str_arg.string?
|
168
168
|
str = str_arg.value
|
169
169
|
k_arg = args.cadr.evaluate(env)
|
170
|
-
|
170
|
+
return Lisp::Debug.process_error("string-ref requires it's second argument to be an integer, but received #{k_arg}", env) unless k_arg.integer?
|
171
171
|
k = k_arg.value
|
172
172
|
return Lisp::FALSE if k < 0 || k >= str.length
|
173
173
|
Lisp::Character.find_character_for_chr(str[k])
|
@@ -175,16 +175,16 @@ end
|
|
175
175
|
|
176
176
|
|
177
177
|
def self.string_set_impl(args, env)
|
178
|
-
|
178
|
+
return Lisp::Debug.process_error("string-set! needs 3 arguments, but received #{args.length}", env) unless args.length == 3
|
179
179
|
str_arg = args.car.evaluate(env)
|
180
|
-
|
180
|
+
return Lisp::Debug.process_error("string-set! needs a string as it's first argument, but received #{str_arg}", env) unless str_arg.string?
|
181
181
|
str = str_arg.value
|
182
182
|
k_arg = args.cadr.evaluate(env)
|
183
|
-
|
183
|
+
return Lisp::Debug.process_error("string-set! requires an integer as it's second argument, but received #{k_arg}", env) unless k_arg.integer?
|
184
184
|
k = k_arg.value
|
185
185
|
return Lisp::FALSE if k < 0 || k >= str.length
|
186
186
|
replacement_arg = args.caddr.evaluate(env)
|
187
|
-
|
187
|
+
return Lisp::Debug.process_error("string-set! requires a character as it's third argument, but received #{replacement_arg}", env) unless replacement_arg.character?
|
188
188
|
replacement = replacement_arg.value
|
189
189
|
str[k] = replacement
|
190
190
|
self.with_value(str)
|
@@ -192,20 +192,20 @@ end
|
|
192
192
|
|
193
193
|
|
194
194
|
def self.get_substring(func, str, start_index, end_index)
|
195
|
-
|
195
|
+
return Lisp::Debug.process_error("#{func} requires a string, but received #{str}", env) unless str.string?
|
196
196
|
s = str.value
|
197
|
-
|
197
|
+
return Lisp::Debug.process_error("#{func} requires an integer start index, but received #{start_index}", env) unless start_index.integer?
|
198
198
|
si = start_index.value
|
199
|
-
|
200
|
-
|
199
|
+
return Lisp::Debug.process_error("#{func} received an invalid substring start index: #{si}", env) if si < 0 || si > s.length
|
200
|
+
return Lisp::Debug.process_error("#{func} requires an integer end index, but received #{end_index}", env) unless end_index.integer?
|
201
201
|
ei = end_index.value
|
202
|
-
|
202
|
+
return Lisp::Debug.process_error("#{func} received an invalid substring end index: #{ei}", env) if ei < 0 || ei > s.length
|
203
203
|
s[si...ei]
|
204
204
|
end
|
205
205
|
|
206
206
|
|
207
207
|
def self.extract_substrings(func, args, env)
|
208
|
-
|
208
|
+
return Lisp::Debug.process_error("#{func} requires 6 arguments, but received #{args.length}", env) unless args.length == 6
|
209
209
|
substr1 = get_substring(func, args.nth(1).evaluate(env), args.nth(2).evaluate(env), args.nth(3).evaluate(env))
|
210
210
|
substr2 = get_substring(func, args.nth(4).evaluate(env), args.nth(5).evaluate(env), args.nth(6).evaluate(env))
|
211
211
|
return [substr1, substr2]
|
@@ -213,13 +213,13 @@ end
|
|
213
213
|
|
214
214
|
|
215
215
|
def self.get_string(func, str)
|
216
|
-
|
216
|
+
return Lisp::Debug.process_error("#{func} requires a string, but received #{str}", env) unless str.string?
|
217
217
|
str.value
|
218
218
|
end
|
219
219
|
|
220
220
|
|
221
221
|
def self.extract_strings(func, args, env)
|
222
|
-
|
222
|
+
return Lisp::Debug.process_error("#{func} requires 2 arguments, but received #{args.length}", env) unless args.length == 2
|
223
223
|
str1 = get_string(func, args.nth(1).evaluate(env))
|
224
224
|
str2 = get_string(func, args.nth(2).evaluate(env))
|
225
225
|
return [str1, str2]
|
@@ -347,7 +347,7 @@ end
|
|
347
347
|
|
348
348
|
|
349
349
|
def self.string_compare_impl(args, env)
|
350
|
-
|
350
|
+
return Lisp::Debug.process_error("string-compare requires 5 arguments, but received #{args.length}", env) unless args.length == 5
|
351
351
|
str1 = get_string("string-compare", args.nth(1).evaluate(env))
|
352
352
|
str2 = get_string("string-compare", args.nth(2).evaluate(env))
|
353
353
|
f_number = case str1 <=> str2
|
@@ -359,13 +359,13 @@ end
|
|
359
359
|
5
|
360
360
|
end
|
361
361
|
f = args.nth(f_number).evaluate(env)
|
362
|
-
|
362
|
+
return Lisp::Debug.process_error("string-compare requires functions for argument #{f_number}, but received #{f}", env) unless f.function?
|
363
363
|
f.apply_to(Lisp::ConsCell.cons, env)
|
364
364
|
end
|
365
365
|
|
366
366
|
|
367
367
|
def self.string_compare_ci_impl(args, env)
|
368
|
-
|
368
|
+
return Lisp::Debug.process_error("string-compare-ci requires 5 arguments, but received #{args.length}", env) unless args.length == 5
|
369
369
|
str1 = get_string("string-compare-ci", args.nth(1).evaluate(env))
|
370
370
|
str2 = get_string("string-compare-ci", args.nth(2).evaluate(env))
|
371
371
|
f_number = case str1.downcase <=> str2.downcase
|
@@ -377,7 +377,7 @@ end
|
|
377
377
|
5
|
378
378
|
end
|
379
379
|
f = args.nth(f_number).evaluate(env)
|
380
|
-
|
380
|
+
return Lisp::Debug.process_error("string-compare-ci requires functions for argument #{f_number}, but received #{f}", env) unless f.function?
|
381
381
|
f.apply_to(Lisp::ConsCell.cons, env)
|
382
382
|
end
|
383
383
|
|
@@ -391,7 +391,7 @@ end
|
|
391
391
|
def self.string_hash_mod_impl(args, env)
|
392
392
|
str = get_string("string-hash-mod", args.nth(1).evaluate(env))
|
393
393
|
k_arg = args.cadr.evaluate(env)
|
394
|
-
|
394
|
+
return Lisp::Debug.process_error("string-hash-mod requires it's second argument to be an integer, but received #{k_arg}", env) unless k_arg.integer?
|
395
395
|
k = k_arg.value
|
396
396
|
Lisp::Number.with_value(str.hash % k)
|
397
397
|
end
|
@@ -489,9 +489,9 @@ end
|
|
489
489
|
|
490
490
|
|
491
491
|
def self.string_capitalize_bang_impl(args, env)
|
492
|
-
|
492
|
+
return Lisp::Debug.process_error("string-capitalize! requires 1 argument, but received #{args.length}", env) unless args.length == 1
|
493
493
|
str = args.nth(1).evaluate(env)
|
494
|
-
|
494
|
+
return Lisp::Debug.process_error("string-capitalize! requires a string, but received #{str}", env) unless str.string?
|
495
495
|
new_chars = capitalize_string(str.value)
|
496
496
|
new_str = ""
|
497
497
|
new_chars.each {|c| new_str << c}
|
@@ -501,20 +501,20 @@ end
|
|
501
501
|
|
502
502
|
|
503
503
|
def self.substring_capitalize_bang_impl(args, env)
|
504
|
-
|
504
|
+
return Lisp::Debug.process_error("substring-capitalize! requires 3 arguments, but received #{args.length}", env) unless args.length == 3
|
505
505
|
s = args.nth(1).evaluate(env)
|
506
|
-
|
506
|
+
return Lisp::Debug.process_error("substring-capitalize! requires a string as it's first argument, but received #{s}", env) unless s.string?
|
507
507
|
str = s.value
|
508
508
|
|
509
509
|
start_index = args.nth(2).evaluate(env)
|
510
|
-
|
510
|
+
return Lisp::Debug.process_error("substring-capitalize! requires an integer start index, but received #{start_index}", env) unless start_index.integer?
|
511
511
|
si = start_index.value
|
512
|
-
|
512
|
+
return Lisp::Debug.process_error("substring-capitalize! received an invalid substring start index: #{si}", env) if si < 0 || si > str.length
|
513
513
|
|
514
514
|
end_index = args.nth(3).evaluate(env)
|
515
|
-
|
515
|
+
return Lisp::Debug.process_error("substring-capitalize! requires an integer end index, but received #{end_index}", env) unless end_index.integer?
|
516
516
|
ei = end_index.value
|
517
|
-
|
517
|
+
return Lisp::Debug.process_error("substring-capitalize! received an invalid substring end index: #{ei}", env) if ei < 0 || ei > str.length
|
518
518
|
|
519
519
|
prefix = str[0...si]
|
520
520
|
substr = str[si...ei]
|
@@ -535,29 +535,29 @@ end
|
|
535
535
|
|
536
536
|
|
537
537
|
def self.string_downcase_bang_impl(args, env)
|
538
|
-
|
538
|
+
return Lisp::Debug.process_error("string-downcase! requires 1 argument, but received #{args.length}", env) unless args.length == 1
|
539
539
|
str = args.nth(1).evaluate(env)
|
540
|
-
|
540
|
+
return Lisp::Debug.process_error("string-downcase! requires a string, but received #{str}", env) unless str.string?
|
541
541
|
str.set!(str.value.downcase)
|
542
542
|
str
|
543
543
|
end
|
544
544
|
|
545
545
|
|
546
546
|
def self.substring_downcase_bang_impl(args, env)
|
547
|
-
|
547
|
+
return Lisp::Debug.process_error("substring-downcase! requires 3 arguments, but received #{args.length}", env) unless args.length == 3
|
548
548
|
s = args.nth(1).evaluate(env)
|
549
|
-
|
549
|
+
return Lisp::Debug.process_error("substring-downcase! requires a string as it's first argument, but received #{s}", env) unless s.string?
|
550
550
|
str = s.value
|
551
551
|
|
552
552
|
start_index = args.nth(2).evaluate(env)
|
553
|
-
|
553
|
+
return Lisp::Debug.process_error("substring-downcase! requires an integer start index, but received #{start_index}", env) unless start_index.integer?
|
554
554
|
si = start_index.value
|
555
|
-
|
555
|
+
return Lisp::Debug.process_error("substring-downcase! received an invalid substring start index: #{si}", env) if si < 0 || si > str.length
|
556
556
|
|
557
557
|
end_index = args.nth(3).evaluate(env)
|
558
|
-
|
558
|
+
return Lisp::Debug.process_error("substring-downcase! requires an integer end index, but received #{end_index}", env) unless end_index.integer?
|
559
559
|
ei = end_index.value
|
560
|
-
|
560
|
+
return Lisp::Debug.process_error("substring-downcase! received an invalid substring end index: #{ei}", env) if ei < 0 || ei > str.length
|
561
561
|
|
562
562
|
prefix = str[0...si]
|
563
563
|
substr = str[si...ei]
|
@@ -578,29 +578,29 @@ end
|
|
578
578
|
|
579
579
|
|
580
580
|
def self.string_upcase_bang_impl(args, env)
|
581
|
-
|
581
|
+
return Lisp::Debug.process_error("string-upcase! requires 1 argument, but received #{args.length}", env) unless args.length == 1
|
582
582
|
str = args.nth(1).evaluate(env)
|
583
|
-
|
583
|
+
return Lisp::Debug.process_error("string-upcase! requires a string, but received #{str}", env) unless str.string?
|
584
584
|
str.set!(str.value.upcase)
|
585
585
|
str
|
586
586
|
end
|
587
587
|
|
588
588
|
|
589
589
|
def self.substring_upcase_bang_impl(args, env)
|
590
|
-
|
590
|
+
return Lisp::Debug.process_error("substring-upcase! requires 3 arguments, but received #{args.length}", env) unless args.length == 3
|
591
591
|
s = args.nth(1).evaluate(env)
|
592
|
-
|
592
|
+
return Lisp::Debug.process_error("substring-upcase! requires a string as it's first argument, but received #{s}", env) unless s.string?
|
593
593
|
str = s.value
|
594
594
|
|
595
595
|
start_index = args.nth(2).evaluate(env)
|
596
|
-
|
596
|
+
return Lisp::Debug.process_error("substring-upcase! requires an integer start index, but received #{start_index}", env) unless start_index.integer?
|
597
597
|
si = start_index.value
|
598
|
-
|
598
|
+
return Lisp::Debug.process_error("substring-upcase! received an invalid substring start index: #{si}", env) if si < 0 || si > str.length
|
599
599
|
|
600
600
|
end_index = args.nth(3).evaluate(env)
|
601
|
-
|
601
|
+
return Lisp::Debug.process_error("substring-upcase! requires an integer end index, but received #{end_index}", env) unless end_index.integer?
|
602
602
|
ei = end_index.value
|
603
|
-
|
603
|
+
return Lisp::Debug.process_error("substring-upcase! received an invalid substring end index: #{ei}", env) if ei < 0 || ei > str.length
|
604
604
|
|
605
605
|
prefix = str[0...si]
|
606
606
|
substr = str[si...ei]
|
@@ -617,7 +617,7 @@ end
|
|
617
617
|
def self.string_append_impl(args, env)
|
618
618
|
strings = args.to_a.map do |a|
|
619
619
|
s = a.evaluate(env)
|
620
|
-
|
620
|
+
return Lisp::Debug.process_error("string-append requires strings, but received #{s}", env) unless s.string?
|
621
621
|
s.value
|
622
622
|
end
|
623
623
|
|
@@ -632,49 +632,49 @@ end
|
|
632
632
|
|
633
633
|
|
634
634
|
def self.string_head_impl(args, env)
|
635
|
-
|
635
|
+
return Lisp::Debug.process_error("string-head requires 2 arguments, but received #{args.length}", env) unless args.length == 2
|
636
636
|
s = args.nth(1).evaluate(env)
|
637
|
-
|
637
|
+
return Lisp::Debug.process_error("string-head requires a string as it's first argument, but received #{s}", env) unless s.string?
|
638
638
|
str = s.value
|
639
639
|
|
640
640
|
end_index = args.nth(2).evaluate(env)
|
641
|
-
|
641
|
+
return Lisp::Debug.process_error("string-head requires an integer end index, but received #{end_index}", env) unless end_index.integer?
|
642
642
|
ei = end_index.value
|
643
|
-
|
643
|
+
return Lisp::Debug.process_error("string-head received an invalid end index: #{ei}", env) if ei < 0 || ei > str.length
|
644
644
|
|
645
645
|
self.with_value(str[0...ei])
|
646
646
|
end
|
647
647
|
|
648
648
|
|
649
649
|
def self.string_tail_impl(args, env)
|
650
|
-
|
650
|
+
return Lisp::Debug.process_error("string-tail requires 2 arguments, but received #{args.length}", env) unless args.length == 2
|
651
651
|
s = args.nth(1).evaluate(env)
|
652
|
-
|
652
|
+
return Lisp::Debug.process_error("string-tail requires a string as it's first argument, but received #{s}", env) unless s.string?
|
653
653
|
str = s.value
|
654
654
|
|
655
655
|
start_index = args.nth(2).evaluate(env)
|
656
|
-
|
656
|
+
return Lisp::Debug.process_error("string-tail requires an integer start index, but received #{start_index}", env) unless start_index.integer?
|
657
657
|
si = start_index.value
|
658
|
-
|
658
|
+
return Lisp::Debug.process_error("string-tail received an invalid end index: #{si}", env) if si < 0 || si > str.length
|
659
659
|
|
660
660
|
self.with_value(str[si..-1])
|
661
661
|
end
|
662
662
|
|
663
663
|
|
664
664
|
def self.string_pad_left_impl(args, env)
|
665
|
-
|
665
|
+
return Lisp::Debug.process_error("string-pad-left requires 2 or 3 arguments, but received #{args.length}", env) unless args.length == 2 || args.length == 3
|
666
666
|
s = args.nth(1).evaluate(env)
|
667
|
-
|
667
|
+
return Lisp::Debug.process_error("string-pad-left requires a string as it's first argument, but received #{s}", env) unless s.string?
|
668
668
|
str = s.value
|
669
669
|
|
670
670
|
size_arg = args.nth(2).evaluate(env)
|
671
|
-
|
671
|
+
return Lisp::Debug.process_error("string-pad-left requires an integer size, but received #{size_arg}", env) unless size_arg.integer?
|
672
672
|
size = size_arg.value
|
673
|
-
|
673
|
+
return Lisp::Debug.process_error("string-pad-left received an invalid size: #{size}", env) if size < 0
|
674
674
|
|
675
675
|
padding_char = if args.length == 3
|
676
676
|
ch_arg = args.nth(3).evaluate(env)
|
677
|
-
|
677
|
+
return Lisp::Debug.process_error("string-pad-left requires a character pad, but received #{ch_arg}", env) unless ch_arg.character?
|
678
678
|
ch_arg.value
|
679
679
|
else
|
680
680
|
" "
|
data/lib/rubylisp/system.rb
CHANGED
@@ -4,13 +4,14 @@ module Lisp
|
|
4
4
|
|
5
5
|
def self.register
|
6
6
|
Primitive.register("sleep") {|args, env| Lisp::System.sleep_impl(args, env) }
|
7
|
+
Primitive.register("quit") {|args, env| exit() }
|
7
8
|
end
|
8
9
|
|
9
10
|
|
10
11
|
def self.sleep_impl(args, env)
|
11
|
-
|
12
|
+
return Lisp::Debug.process_error("sleep needs 1 argument", env) if args.length != 1
|
12
13
|
arg = args.car.evaluate(env)
|
13
|
-
|
14
|
+
return Lisp::Debug.process_error("sleep needs a numeric argument", env) unless arg.number?
|
14
15
|
sleep(arg.value)
|
15
16
|
end
|
16
17
|
|
data/lib/rubylisp/testing.rb
CHANGED
@@ -11,7 +11,7 @@ module Lisp
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def self.describe_impl(args, env)
|
14
|
-
|
14
|
+
return Lisp::Debug.process_error("First arg to describe must be a string or symbol", env) if !args.car.symbol? && !args.car.string?
|
15
15
|
return if args.cdr.nil?
|
16
16
|
puts
|
17
17
|
puts " #{args.car.to_s}"
|
@@ -68,7 +68,7 @@ module Lisp
|
|
68
68
|
when 2
|
69
69
|
self.binary_check(name, args.car, args.cadr, env, inverted)
|
70
70
|
else
|
71
|
-
|
71
|
+
return Lisp::Debug.process_error("check takes 1 or 2 arguments, received #{args.length}", env)
|
72
72
|
end)
|
73
73
|
end
|
74
74
|
|
@@ -79,7 +79,7 @@ module Lisp
|
|
79
79
|
|
80
80
|
|
81
81
|
def self.check_star_impl(args, env)
|
82
|
-
|
82
|
+
return Lisp::Debug.process_error("check* needs 2 arguments, received #{args.length}", env) if args.length != 2
|
83
83
|
@@number_of_tests += 1
|
84
84
|
print " (check* #{args.car.print_string} #{args.cadr.print_string}) - "
|
85
85
|
|
data/lib/rubylisp/type_checks.rb
CHANGED
@@ -7,50 +7,52 @@ module Lisp
|
|
7
7
|
Primitive.register("pair?") {|args, env| Lisp::TypeChecks::typep_impl("pair?", :pair, args, env) }
|
8
8
|
Primitive.register("symbol?") {|args, env| Lisp::TypeChecks::typep_impl("symbol?", :symbol, args, env) }
|
9
9
|
Primitive.register("number?") {|args, env| Lisp::TypeChecks::typep_impl("number?", :number, args, env) }
|
10
|
-
Primitive.register("integer?")
|
11
|
-
Primitive.register("float?")
|
10
|
+
Primitive.register("integer?") {|args, env| Lisp::TypeChecks::integerp_impl(args, env) }
|
11
|
+
Primitive.register("float?") {|args, env| Lisp::TypeChecks::floatp_impl(args, env) }
|
12
12
|
Primitive.register("function?") {|args, env| Lisp::TypeChecks::functionp_impl(args, env) }
|
13
13
|
|
14
14
|
Primitive.register("nil?") {|args, env| Lisp::TypeChecks::nilp_impl(args, env) }
|
15
|
+
Primitive.register("null?") {|args, env| Lisp::TypeChecks::nilp_impl(args, env) }
|
15
16
|
Primitive.register("not-nil?") {|args, env| Lisp::TypeChecks::not_nilp_impl(args, env) }
|
17
|
+
Primitive.register("not-null?") {|args, env| Lisp::TypeChecks::not_nilp_impl(args, env) }
|
16
18
|
end
|
17
19
|
|
18
20
|
|
19
21
|
def self.typep_impl(name, sym, args, env)
|
20
|
-
|
22
|
+
return Lisp::Debug.process_error("#{name} needs 1 argument", env) unless args.length == 1
|
21
23
|
return Lisp::Boolean.with_value(args.car.evaluate(env).type == sym)
|
22
24
|
end
|
23
25
|
|
24
26
|
|
25
27
|
def self.integerp_impl(args, env)
|
26
|
-
|
28
|
+
return Lisp::Debug.process_error("integer? needs 1 argument", env) unless args.length == 1
|
27
29
|
val = args.car.evaluate(env)
|
28
30
|
return Lisp::Boolean.with_value(val.type == :number && val.integer?)
|
29
31
|
end
|
30
32
|
|
31
33
|
|
32
34
|
def self.floatp_impl(args, env)
|
33
|
-
|
35
|
+
return Lisp::Debug.process_error("float? needs 1 argument", env) unless args.length == 1
|
34
36
|
val = args.car.evaluate(env)
|
35
37
|
return Lisp::Boolean.with_value(val.type == :number && val.float?)
|
36
38
|
end
|
37
39
|
|
38
40
|
|
39
41
|
def self.functionp_impl(args, env)
|
40
|
-
|
42
|
+
return Lisp::Debug.process_error("function? needs 1 argument", env) unless args.length == 1
|
41
43
|
val = args.car.evaluate(env)
|
42
44
|
return Lisp::Boolean.with_value(val.type == :function || val.type == :primitive)
|
43
45
|
end
|
44
46
|
|
45
47
|
|
46
48
|
def self.nilp_impl(args, env)
|
47
|
-
|
49
|
+
return Lisp::Debug.process_error("nil? needs 1 argument", env) unless args.length == 1
|
48
50
|
return Lisp::Boolean.with_value(args.car.evaluate(env).nil?)
|
49
51
|
end
|
50
52
|
|
51
53
|
|
52
54
|
def self.not_nilp_impl(args, env)
|
53
|
-
|
55
|
+
return Lisp::Debug.process_error("not-nil? needs 1 argument", env) unless args.length == 1
|
54
56
|
return Lisp::Boolean.with_value(!args.car.evaluate(env).nil?)
|
55
57
|
end
|
56
58
|
|
data/lib/rubylisp/vector.rb
CHANGED
@@ -20,7 +20,7 @@ module Lisp
|
|
20
20
|
|
21
21
|
|
22
22
|
def self.vector_impl(args, env)
|
23
|
-
|
23
|
+
return Lisp::Debug.process_error("vector requires a single list argument.", env) unless args.length == 1
|
24
24
|
|
25
25
|
c = args.car.evaluate(env)
|
26
26
|
Lisp::Vector.new(c.to_a)
|
data/lib/rubylisp.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubylisp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dave Astels
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-11-16 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: An embeddable Lisp as an extension language for Ruby
|
14
14
|
email: dastels@icloud.com
|
@@ -17,6 +17,7 @@ executables:
|
|
17
17
|
extensions: []
|
18
18
|
extra_rdoc_files: []
|
19
19
|
files:
|
20
|
+
- README.md
|
20
21
|
- bin/rubylisp
|
21
22
|
- lib/rubylisp.rb
|
22
23
|
- lib/rubylisp/alist.rb
|
@@ -27,6 +28,7 @@ files:
|
|
27
28
|
- lib/rubylisp/builtins.rb
|
28
29
|
- lib/rubylisp/character.rb
|
29
30
|
- lib/rubylisp/cons_cell.rb
|
31
|
+
- lib/rubylisp/debug.rb
|
30
32
|
- lib/rubylisp/environment_frame.rb
|
31
33
|
- lib/rubylisp/equivalence.rb
|
32
34
|
- lib/rubylisp/exception.rb
|
@@ -65,12 +67,12 @@ require_paths:
|
|
65
67
|
- lib
|
66
68
|
required_ruby_version: !ruby/object:Gem::Requirement
|
67
69
|
requirements:
|
68
|
-
- -
|
70
|
+
- - ">="
|
69
71
|
- !ruby/object:Gem::Version
|
70
72
|
version: '0'
|
71
73
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
74
|
requirements:
|
73
|
-
- -
|
75
|
+
- - ">="
|
74
76
|
- !ruby/object:Gem::Version
|
75
77
|
version: '0'
|
76
78
|
requirements: []
|