lisp-interpreter 0.4.0 → 0.4.1
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/lib/lisp/interpreter/core/boolean.rb +1 -1
- data/lib/lisp/interpreter/core/errors.rb +1 -1
- data/lib/lisp/interpreter/core/list.rb +1 -1
- data/lib/lisp/interpreter/core/numbers.rb +5 -5
- data/lib/lisp/interpreter/core/strings.rb +3 -3
- data/lib/lisp/interpreter/list.rb +183 -0
- data/lib/lisp/interpreter/numbers.rb +162 -0
- data/lib/lisp/interpreter/version.rb +1 -1
- data/spec/lisp/interpreter_spec.rb +5 -6
- metadata +3 -3
- data/lib/lisp/interpreter/object.rb +0 -66
- data/lisp-interpreter-0.3.5.gem +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d0691fe861df7ee5e54aac3b2f291df8e517a48d
|
4
|
+
data.tar.gz: d370f3810b7e2e9caa9af9372f3ac2cc2ea1601f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 16869c9165eaebbd985f3c866f25fdd0c55f18f21bd13c841b6aac63f6217134ef0464ee4962770088b13442bceaada40c1e69e371911cf5d316c462b3a60bb1
|
7
|
+
data.tar.gz: 31711dfa5b59c031d06aa2e67c4b68a5f3edd0cf41e02a88b83505d2e2ba5c9490ddce51a022b55a888de9617bb054ae1d638583c31047d3ef5fbf2712c7c470
|
@@ -30,7 +30,7 @@ module SchemeBooleans
|
|
30
30
|
def not(other)
|
31
31
|
raise arg_err_build 1, other.size if other.size != 1
|
32
32
|
valid = check_for_bool other[0]
|
33
|
-
raise
|
33
|
+
raise type_err '<boolean>', other[0].type unless valid
|
34
34
|
other[0] == '#t' ? '#f' : '#t'
|
35
35
|
end
|
36
36
|
|
@@ -76,7 +76,7 @@ module SchemeListsHelper
|
|
76
76
|
|
77
77
|
def find_list_function_value(other)
|
78
78
|
raise arg_err_build 1, other.size if other.size != 1
|
79
|
-
raise
|
79
|
+
raise type_err '<list>', other[0].type unless other[0].list?
|
80
80
|
split_list_as_string other[0].to_s
|
81
81
|
end
|
82
82
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
module SchemeNumbersHelper
|
3
3
|
def get_one_arg_function(other)
|
4
4
|
raise arg_err_build 1, other.size if other.size != 1
|
5
|
-
raise
|
5
|
+
raise type_err '<number>', other[0].type unless check_for_num other[0]
|
6
6
|
other[0].to_num
|
7
7
|
end
|
8
8
|
|
@@ -24,7 +24,7 @@ module SchemeNumbersHelper
|
|
24
24
|
|
25
25
|
def get_num_denom(other)
|
26
26
|
num, other = find_next_value other
|
27
|
-
raise
|
27
|
+
raise type_err '<number>', num.type unless check_for_num num
|
28
28
|
return [num, 1] if other.empty?
|
29
29
|
denom, other = find_next_value other
|
30
30
|
raise arg_err_build 1, other.size unless other.empty?
|
@@ -40,7 +40,7 @@ module SchemeNumbersHelper
|
|
40
40
|
|
41
41
|
def convert_to_num(other)
|
42
42
|
other.each do |t|
|
43
|
-
raise
|
43
|
+
raise type_err '<number>', t.type unless check_for_num t
|
44
44
|
end
|
45
45
|
other.map(&:to_num)
|
46
46
|
end
|
@@ -124,7 +124,7 @@ module SchemeNumbers
|
|
124
124
|
raise arg_err_build 1, 0 if other.empty?
|
125
125
|
other = num_denom_helper other
|
126
126
|
result = (get_num_denom other)[0]
|
127
|
-
raise
|
127
|
+
raise type_err '<number>', result.type unless check_for_num result
|
128
128
|
result.to_num
|
129
129
|
end
|
130
130
|
|
@@ -132,7 +132,7 @@ module SchemeNumbers
|
|
132
132
|
raise arg_err_build 1, 0 if other.empty?
|
133
133
|
other = num_denom_helper other
|
134
134
|
result = (get_num_denom other)[1]
|
135
|
-
raise
|
135
|
+
raise type_err '<number>', result.type unless check_for_num result
|
136
136
|
result.to_num
|
137
137
|
end
|
138
138
|
|
@@ -39,7 +39,7 @@ module SchemeStringsHelper
|
|
39
39
|
def arg_function_validator(other, vars = 1)
|
40
40
|
raise arg_err_build other.size, vars if other.size != vars
|
41
41
|
res = other[0..vars - 1].reject { |v| check_for_string v }
|
42
|
-
raise
|
42
|
+
raise type_err '<string>', res[0].type unless res.empty?
|
43
43
|
res
|
44
44
|
end
|
45
45
|
|
@@ -51,13 +51,13 @@ module SchemeStringsHelper
|
|
51
51
|
|
52
52
|
def strjoin_validate(other)
|
53
53
|
raise arg_err_build '[1, 2]', other.size unless other.size.between? 1, 2
|
54
|
-
raise
|
54
|
+
raise type_err '<list>', other[0].type unless other[0].to_s.list?
|
55
55
|
end
|
56
56
|
|
57
57
|
def substring_validator(from, to)
|
58
58
|
valid = (check_for_num from) && (to.nil? || (check_for_num to))
|
59
59
|
type = [from, to].first { |t| t.type if t.type != 'number' }
|
60
|
-
raise
|
60
|
+
raise type_err '<number>', type unless valid
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
@@ -0,0 +1,183 @@
|
|
1
|
+
# Helper functions for SchemeLists
|
2
|
+
module SchemeListsHelper
|
3
|
+
def evaluate_list(tokens, no_quotes)
|
4
|
+
find_all_values_list_evaluate tokens, no_quotes
|
5
|
+
end
|
6
|
+
|
7
|
+
def no_eval_list(tokens, no_quotes = false)
|
8
|
+
result = []
|
9
|
+
until tokens.empty?
|
10
|
+
value, tokens = build_next_value_as_string tokens
|
11
|
+
value = value[1..-2] if no_quotes && (check_for_string value.to_s)
|
12
|
+
result << value
|
13
|
+
end
|
14
|
+
result
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_to_evaluate_or_not(tokens, no_quotes = false)
|
18
|
+
if tokens[0..1].join == '(list'
|
19
|
+
evaluate_list tokens[2..-2], no_quotes
|
20
|
+
elsif tokens[0..1].join == '(cons'
|
21
|
+
result = cons tokens[2..-2]
|
22
|
+
result[2..-2].split(' ')
|
23
|
+
else
|
24
|
+
no_eval_list tokens[2..-2], no_quotes
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def find_idx_for_list(tokens)
|
29
|
+
if tokens[0] == '('
|
30
|
+
find_bracket_idx tokens, 0
|
31
|
+
elsif tokens[1] == '('
|
32
|
+
find_bracket_idx tokens, 1
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def find_all_values_list_evaluate(tokens, no_quotes = false)
|
37
|
+
result = []
|
38
|
+
until tokens.empty?
|
39
|
+
x, tokens = find_next_value tokens
|
40
|
+
x = x[1..-2] if no_quotes && (check_for_string x.to_s)
|
41
|
+
result << x
|
42
|
+
end
|
43
|
+
result
|
44
|
+
end
|
45
|
+
|
46
|
+
def build_list(values)
|
47
|
+
'\'(' + values.join(' ') + ')'
|
48
|
+
end
|
49
|
+
|
50
|
+
def build_cons_from_list(values)
|
51
|
+
spacer = values[1].size == 3 ? '' : ' '
|
52
|
+
values[0].to_s + spacer + values[1][2..-2].to_s
|
53
|
+
end
|
54
|
+
|
55
|
+
def cons_helper(values)
|
56
|
+
result =
|
57
|
+
if values[1].to_s[0..1] == '\'('
|
58
|
+
build_cons_from_list values
|
59
|
+
else
|
60
|
+
values[0].to_s + ' . ' + values[1].to_s
|
61
|
+
end
|
62
|
+
'\'(' + result + ')'
|
63
|
+
end
|
64
|
+
|
65
|
+
def get_cons_values(tokens)
|
66
|
+
result = get_k_arguments tokens, false, 2
|
67
|
+
raise arg_err_build 2, result.size if result.size != 2
|
68
|
+
result
|
69
|
+
end
|
70
|
+
|
71
|
+
def split_list_string(list)
|
72
|
+
result = list.split(/(\(|\)|\.)|\ /)
|
73
|
+
result.delete('')
|
74
|
+
result
|
75
|
+
end
|
76
|
+
|
77
|
+
def find_list_function_value(other)
|
78
|
+
raise arg_err_build 1, other.size if other.size != 1
|
79
|
+
raise data_type_err 'list', other[0].type unless other[0].list?
|
80
|
+
split_list_as_string other[0].to_s
|
81
|
+
end
|
82
|
+
|
83
|
+
def split_list_as_string(list_as_string)
|
84
|
+
split_value = split_list_string list_as_string.to_s
|
85
|
+
no_eval_list split_value[2..-2]
|
86
|
+
end
|
87
|
+
|
88
|
+
def car_cdr_values(other)
|
89
|
+
raise arg_err_build 1, other.size if other.size != 1
|
90
|
+
return find_list_function_value other if other[0].list?
|
91
|
+
(split_list_string other[0].to_s)[2..-2] if other[0].pair?
|
92
|
+
end
|
93
|
+
|
94
|
+
def map_helper(lst, func)
|
95
|
+
return lst.map { |t| func.call(*t) } if func.is_a? Proc
|
96
|
+
lst.map { |t| send func, t }
|
97
|
+
end
|
98
|
+
|
99
|
+
def map_validate_helper(other)
|
100
|
+
raise arg_err_build 'at least 2', 0 if other.empty?
|
101
|
+
func, other = valid_function other
|
102
|
+
raise arg_err_build 'at least 2', 1 if other.empty?
|
103
|
+
[func, other]
|
104
|
+
end
|
105
|
+
|
106
|
+
def car_cdr_infinite_helper(value, fn)
|
107
|
+
fn.reverse[1..-2].each_char do |t|
|
108
|
+
value = t == 'a' ? (car [value]) : (cdr [value])
|
109
|
+
end
|
110
|
+
value
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Scheme lists module
|
115
|
+
module SchemeLists
|
116
|
+
include SchemeListsHelper
|
117
|
+
def cons(other)
|
118
|
+
raise arg_err_build 2, other.size if other.size != 2
|
119
|
+
cons_helper other
|
120
|
+
end
|
121
|
+
|
122
|
+
def list(other)
|
123
|
+
build_list other
|
124
|
+
end
|
125
|
+
|
126
|
+
def car(other)
|
127
|
+
value = car_cdr_values other
|
128
|
+
raise 'Cannot apply car on ' + other[0].to_s if value.nil? || value.empty?
|
129
|
+
value.shift
|
130
|
+
end
|
131
|
+
|
132
|
+
def cdr(other)
|
133
|
+
value = car_cdr_values other
|
134
|
+
raise 'Cannot apply cdr on ' + other[0].to_s if value.nil? || value.empty?
|
135
|
+
idx = value[1] == '.' ? 2 : 1
|
136
|
+
build_list value[idx..-1]
|
137
|
+
end
|
138
|
+
|
139
|
+
def list?(other)
|
140
|
+
raise arg_err_build 1, other.size if other.size != 1
|
141
|
+
other[0].to_s.list? ? '#t' : '#f'
|
142
|
+
end
|
143
|
+
|
144
|
+
def pair?(other)
|
145
|
+
raise arg_err_build 1, other.size if other.size != 1
|
146
|
+
other[0].to_s.pair? ? '#t' : '#f'
|
147
|
+
end
|
148
|
+
|
149
|
+
def null?(other)
|
150
|
+
raise arg_err_build 1, other.size if other.size != 1
|
151
|
+
return '#f' unless other[0].to_s.list?
|
152
|
+
other[0].to_s.size == 3 ? '#t' : '#f'
|
153
|
+
end
|
154
|
+
|
155
|
+
def length(other)
|
156
|
+
(find_list_function_value other).size
|
157
|
+
end
|
158
|
+
|
159
|
+
def reverse(other)
|
160
|
+
value = find_list_function_value other
|
161
|
+
build_list value.reverse
|
162
|
+
end
|
163
|
+
|
164
|
+
def map(other)
|
165
|
+
func, other = map_validate_helper other
|
166
|
+
lst = find_all_values other
|
167
|
+
lst = lst.map { |t| find_list_function_value [t] }
|
168
|
+
lst = (equalize_lists lst).transpose
|
169
|
+
build_list map_helper lst, func
|
170
|
+
end
|
171
|
+
|
172
|
+
def shuffle(other)
|
173
|
+
values = find_list_function_value other
|
174
|
+
build_list values.shuffle
|
175
|
+
end
|
176
|
+
|
177
|
+
def car_cdr_infinite(other)
|
178
|
+
fn = other[1]
|
179
|
+
values = find_all_values other[2..-2]
|
180
|
+
raise 'Incorrect number of arguments' unless values.size == 1
|
181
|
+
car_cdr_infinite_helper values[0], fn
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
# Helper functions for SchemeNumbers
|
2
|
+
module SchemeNumbersHelper
|
3
|
+
def get_one_arg_function(other)
|
4
|
+
raise arg_err_build 1, other.size if other.size != 1
|
5
|
+
raise type_err 'number', other[0].type unless check_for_num other[0]
|
6
|
+
other[0].to_num
|
7
|
+
end
|
8
|
+
|
9
|
+
def find_idx_numerators(other)
|
10
|
+
other[0] == '(' ? (find_bracket_idx other, 0) + 1 : 1
|
11
|
+
end
|
12
|
+
|
13
|
+
def num_denom_helper(other)
|
14
|
+
if other.size == 1
|
15
|
+
other = other[0].split('/')
|
16
|
+
else
|
17
|
+
_, temp = find_next_value other
|
18
|
+
raise arg_err_build 1, 0 unless temp[0] == '/' || temp.empty?
|
19
|
+
i = find_idx_numerators other
|
20
|
+
other.delete_at(i)
|
21
|
+
end
|
22
|
+
other
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_num_denom(other)
|
26
|
+
num, other = find_next_value other
|
27
|
+
raise 'Invalid data type' unless check_for_num num
|
28
|
+
return [num, 1] if other.empty?
|
29
|
+
denom, other = find_next_value other
|
30
|
+
raise arg_err_build 1, other.size unless other.empty?
|
31
|
+
[num, denom]
|
32
|
+
end
|
33
|
+
|
34
|
+
def compare_value_arithmetic(other, oper)
|
35
|
+
raise arg_err_build 'at least 2', other.size if other.size < 2
|
36
|
+
other = convert_to_num other
|
37
|
+
result = other.each_cons(2).all? { |x, y| x.public_send oper, y }
|
38
|
+
result ? '#t' : '#f'
|
39
|
+
end
|
40
|
+
|
41
|
+
def convert_to_num(other)
|
42
|
+
other.each do |t|
|
43
|
+
raise 'Invalid data type' unless check_for_num t
|
44
|
+
end
|
45
|
+
other.map(&:to_num)
|
46
|
+
end
|
47
|
+
|
48
|
+
def divide_special_convert(other)
|
49
|
+
other = convert_to_num other
|
50
|
+
return [0] if other.size == 1 && other[0] == 0.0
|
51
|
+
other
|
52
|
+
end
|
53
|
+
|
54
|
+
def divide_number(a, b)
|
55
|
+
return a / b if (a / b).to_i.to_f == a / b.to_f
|
56
|
+
a / b.to_f
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Scheme numbers module
|
61
|
+
module SchemeNumbers
|
62
|
+
include SchemeNumbersHelper
|
63
|
+
|
64
|
+
def <(other)
|
65
|
+
compare_value_arithmetic other, '<'
|
66
|
+
end
|
67
|
+
|
68
|
+
def >(other)
|
69
|
+
compare_value_arithmetic other, '>'
|
70
|
+
end
|
71
|
+
|
72
|
+
def <=(other)
|
73
|
+
compare_value_arithmetic other, '<='
|
74
|
+
end
|
75
|
+
|
76
|
+
def >=(other)
|
77
|
+
compare_value_arithmetic other, '>='
|
78
|
+
end
|
79
|
+
|
80
|
+
def +(other)
|
81
|
+
other = convert_to_num other
|
82
|
+
other.reduce(0, :+)
|
83
|
+
end
|
84
|
+
|
85
|
+
def -(other)
|
86
|
+
return 0 if other.empty?
|
87
|
+
other = convert_to_num other
|
88
|
+
return -other[0] if other.size == 1
|
89
|
+
other[0] + other[1..-1].reduce(0, :-)
|
90
|
+
end
|
91
|
+
|
92
|
+
def *(other)
|
93
|
+
other = convert_to_num other
|
94
|
+
other.reduce(1, :*)
|
95
|
+
end
|
96
|
+
|
97
|
+
def /(other)
|
98
|
+
raise arg_err_build 'at least 1', 0 if other.empty?
|
99
|
+
other = divide_special_convert other
|
100
|
+
return (divide_number 1, other[0].to_num) if other.size == 1
|
101
|
+
other[1..-1].inject(other[0]) { |res, t| divide_number res, t }
|
102
|
+
end
|
103
|
+
|
104
|
+
def quotient(other)
|
105
|
+
raise arg_err_build 2, other.size if other.size != 2
|
106
|
+
x, y = convert_to_num other
|
107
|
+
result = divide_number x, y
|
108
|
+
result < 0 ? result.ceil : result.floor
|
109
|
+
end
|
110
|
+
|
111
|
+
def remainder(other)
|
112
|
+
raise arg_err_build 2, other.size if other.size != 2
|
113
|
+
x, y = convert_to_num other
|
114
|
+
(x.abs % y.abs) * (x / x.abs)
|
115
|
+
end
|
116
|
+
|
117
|
+
def modulo(other)
|
118
|
+
raise arg_err_build 2, other.size if other.size != 2
|
119
|
+
x, y = convert_to_num other
|
120
|
+
x.modulo y
|
121
|
+
end
|
122
|
+
|
123
|
+
def numerator(other)
|
124
|
+
raise arg_err_build 1, 0 if other.empty?
|
125
|
+
other = num_denom_helper other
|
126
|
+
result = (get_num_denom other)[0]
|
127
|
+
raise 'Invalid data type' unless check_for_num result
|
128
|
+
result.to_num
|
129
|
+
end
|
130
|
+
|
131
|
+
def denominator(other)
|
132
|
+
raise arg_err_build 1, 0 if other.empty?
|
133
|
+
other = num_denom_helper other
|
134
|
+
result = (get_num_denom other)[1]
|
135
|
+
raise 'Invalid data type' unless check_for_num result
|
136
|
+
result.to_num
|
137
|
+
end
|
138
|
+
|
139
|
+
def abs(other)
|
140
|
+
(get_one_arg_function other).abs
|
141
|
+
end
|
142
|
+
|
143
|
+
def add1(other)
|
144
|
+
(get_one_arg_function other) + 1
|
145
|
+
end
|
146
|
+
|
147
|
+
def sub1(other)
|
148
|
+
(get_one_arg_function other) - 1
|
149
|
+
end
|
150
|
+
|
151
|
+
def min(other)
|
152
|
+
raise arg_err_build 'at least 1', 0 if other.empty?
|
153
|
+
other = convert_to_num other
|
154
|
+
other.min
|
155
|
+
end
|
156
|
+
|
157
|
+
def max(other)
|
158
|
+
raise arg_err_build 'at least 1', 0 if other.empty?
|
159
|
+
other = convert_to_num other
|
160
|
+
other.max
|
161
|
+
end
|
162
|
+
end
|
@@ -9,8 +9,7 @@ RSpec.describe Lisp::Interpreter do
|
|
9
9
|
@p.parse('(define y 0.999)')
|
10
10
|
@msg =
|
11
11
|
{
|
12
|
-
'zero_div' => 'divided by 0'
|
13
|
-
'inv_type' => 'Invalid data type'
|
12
|
+
'zero_div' => 'divided by 0'
|
14
13
|
}
|
15
14
|
|
16
15
|
def car_cdr_err(got, fn)
|
@@ -43,19 +42,19 @@ RSpec.describe Lisp::Interpreter do
|
|
43
42
|
|
44
43
|
context 'incorrect argument type' do
|
45
44
|
it 'throws error when <number> is expected' do
|
46
|
-
expect(@p.parse('(+ #t)')).to eq
|
45
|
+
expect(@p.parse('(+ #t)')).to eq type_err '<number>', '<boolean>'
|
47
46
|
end
|
48
47
|
|
49
48
|
it 'throws error when <string> is expected' do
|
50
|
-
expect(@p.parse('(
|
49
|
+
expect(@p.parse('(substring 1)')).to eq arg_err_build '[2, 3]', '1'
|
51
50
|
end
|
52
51
|
|
53
52
|
it 'throws error when <boolean> is expected' do
|
54
|
-
expect(@p.parse('(not \'apple)')).to eq
|
53
|
+
expect(@p.parse('(not \'apple)')).to eq type_err '<boolean>', '<quote>'
|
55
54
|
end
|
56
55
|
|
57
56
|
it 'throws error when <list> is expected' do
|
58
|
-
expect(@p.parse('(length "
|
57
|
+
expect(@p.parse('(length "str")')).to eq type_err '<list>', '<string>'
|
59
58
|
end
|
60
59
|
end
|
61
60
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lisp-interpreter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zaki Petrov
|
@@ -79,7 +79,8 @@ files:
|
|
79
79
|
- lib/lisp/interpreter/core/numbers.rb
|
80
80
|
- lib/lisp/interpreter/core/object.rb
|
81
81
|
- lib/lisp/interpreter/core/strings.rb
|
82
|
-
- lib/lisp/interpreter/
|
82
|
+
- lib/lisp/interpreter/list.rb
|
83
|
+
- lib/lisp/interpreter/numbers.rb
|
83
84
|
- lib/lisp/interpreter/parser.rb
|
84
85
|
- lib/lisp/interpreter/run.rb
|
85
86
|
- lib/lisp/interpreter/strings.rb
|
@@ -87,7 +88,6 @@ files:
|
|
87
88
|
- lib/lisp/interpreter/validator.rb
|
88
89
|
- lib/lisp/interpreter/value_finder.rb
|
89
90
|
- lib/lisp/interpreter/version.rb
|
90
|
-
- lisp-interpreter-0.3.5.gem
|
91
91
|
- lisp-interpreter.gemspec
|
92
92
|
- spec/lisp/interpreter_spec.rb
|
93
93
|
- spec/lisp/test.scm
|
@@ -1,66 +0,0 @@
|
|
1
|
-
# redefine method in Object class
|
2
|
-
class Object
|
3
|
-
def number?
|
4
|
-
to_f.to_s == to_s || to_i.to_s == to_s
|
5
|
-
end
|
6
|
-
|
7
|
-
def to_num
|
8
|
-
return to_f if to_f.to_s == to_s
|
9
|
-
return to_i if to_i.to_s == to_s
|
10
|
-
end
|
11
|
-
|
12
|
-
def character?
|
13
|
-
return true if self == '#\space'
|
14
|
-
(start_with? '#\\') && (('a'..'z').to_a.include? self[2]) && size == 3
|
15
|
-
end
|
16
|
-
|
17
|
-
def string?
|
18
|
-
return false unless self.class == String
|
19
|
-
(start_with? '"') && (end_with? '"') && (size != 1)
|
20
|
-
end
|
21
|
-
|
22
|
-
def list?
|
23
|
-
return false if size < 3
|
24
|
-
check_for_list
|
25
|
-
end
|
26
|
-
|
27
|
-
def pair?
|
28
|
-
res = object_split if is_a? String
|
29
|
-
res = to_a if is_a? Array
|
30
|
-
return true if res[-3] == '.'
|
31
|
-
list? && !res[2..-2].empty?
|
32
|
-
end
|
33
|
-
|
34
|
-
def quote?
|
35
|
-
return true if start_with? '\''
|
36
|
-
false
|
37
|
-
end
|
38
|
-
|
39
|
-
def boolean?
|
40
|
-
['#t', '#f'].include? self
|
41
|
-
end
|
42
|
-
|
43
|
-
def type
|
44
|
-
return 'list' if list?
|
45
|
-
return 'pair' if pair?
|
46
|
-
return 'string' if string?
|
47
|
-
return 'number' if number?
|
48
|
-
return 'character' if character?
|
49
|
-
return 'boolean' if boolean?
|
50
|
-
'quote'
|
51
|
-
end
|
52
|
-
|
53
|
-
private
|
54
|
-
|
55
|
-
def object_split
|
56
|
-
result = to_s.split(/(\(|\)|\.)|\ /)
|
57
|
-
result.delete('')
|
58
|
-
result
|
59
|
-
end
|
60
|
-
|
61
|
-
def check_for_list
|
62
|
-
res = to_a if is_a? Array
|
63
|
-
res = object_split if is_a? String
|
64
|
-
res[0..1].join == '\'(' && res[-1] == ')' && res[-3] != '.'
|
65
|
-
end
|
66
|
-
end
|
data/lisp-interpreter-0.3.5.gem
DELETED
Binary file
|