lisp-interpreter 0.3.5 → 0.4.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/lib/lisp/interpreter/checker.rb +7 -8
- data/lib/lisp/interpreter/{boolean.rb → core/boolean.rb} +2 -1
- data/lib/lisp/interpreter/{errors.rb → core/errors.rb} +12 -0
- data/lib/lisp/interpreter/{functional.rb → core/functional.rb} +7 -1
- data/lib/lisp/interpreter/{list.rb → core/list.rb} +1 -1
- data/lib/lisp/interpreter/{numbers.rb → core/numbers.rb} +5 -5
- data/lib/lisp/interpreter/core/object.rb +66 -0
- data/lib/lisp/interpreter/core/strings.rb +140 -0
- data/lib/lisp/interpreter/object.rb +15 -0
- data/lib/lisp/interpreter/parser.rb +1 -1
- data/lib/lisp/interpreter/strings.rb +1 -1
- data/lib/lisp/interpreter/tokenizer.rb +18 -14
- data/lib/lisp/interpreter/validator.rb +9 -4
- data/lib/lisp/interpreter/version.rb +1 -1
- data/lisp-interpreter-0.3.5.gem +0 -0
- data/spec/lisp/interpreter_spec.rb +4 -10
- metadata +10 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f2eed4083aad91446e2fd71b4b7ad1181e7c4d4
|
4
|
+
data.tar.gz: 553180b55363be657880ebeeefc78a46f410e95b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 67963dab535ddc3f856fb7dbe0b286eae6f0ac1d4a2d728d144374fe805639f489ecf57b50928d51ee47710e50d105e7b4cc3cb411406c72a4232efe587d82b5
|
7
|
+
data.tar.gz: 78bcaad6f467ad69d83af2afedc9d9f4c9631b9383f2a769dc56efc787e917a2cd98591eb5bd7ce6b74562f82ad4c4fd4839d61e47bc742d453dcb91506fa042
|
@@ -1,39 +1,38 @@
|
|
1
1
|
# Check if variable is specific type
|
2
2
|
module SchemeChecker
|
3
3
|
def check_for_bool(token)
|
4
|
-
return true if
|
4
|
+
return true if token.boolean?
|
5
5
|
is_instance_var = check_instance_var token
|
6
|
-
return
|
6
|
+
return (check_for_bool get_var token) if is_instance_var
|
7
7
|
false
|
8
8
|
end
|
9
9
|
|
10
10
|
def check_for_string(token)
|
11
11
|
return true if token.string?
|
12
12
|
is_instance_var = check_instance_var token
|
13
|
-
return
|
13
|
+
return (check_for_string get_var token) if is_instance_var
|
14
14
|
false
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
17
|
+
def check_for_num(token)
|
18
18
|
return true if token.to_s.number?
|
19
19
|
is_instance_var = check_instance_var token
|
20
|
-
return
|
20
|
+
return (check_for_num get_var token) if is_instance_var
|
21
21
|
false
|
22
22
|
end
|
23
23
|
|
24
24
|
def check_for_quote(token)
|
25
25
|
return true if token[0].quote?
|
26
26
|
is_instance_var = check_instance_var token
|
27
|
-
return
|
27
|
+
return (check_for_num get_var token) if is_instance_var
|
28
28
|
false
|
29
29
|
end
|
30
30
|
|
31
31
|
def check_for_symbol(var)
|
32
32
|
var = var.join('') if var.is_a? Array
|
33
|
-
return true if var == '#\space'
|
34
33
|
return true if var.character?
|
35
34
|
is_instance_var = check_instance_var var
|
36
|
-
return
|
35
|
+
return (check_for_character get_var var) if is_instance_var
|
37
36
|
false
|
38
37
|
end
|
39
38
|
|
@@ -29,7 +29,8 @@ module SchemeBooleans
|
|
29
29
|
|
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 data_type_err '<boolean>', other[0].type unless valid
|
33
34
|
other[0] == '#t' ? '#f' : '#t'
|
34
35
|
end
|
35
36
|
|
@@ -11,6 +11,18 @@ module ErrorMessages
|
|
11
11
|
def arg_err_build(exp, got)
|
12
12
|
'Incorrect number of arguments, expected ' + exp.to_s + ' got ' + got.to_s
|
13
13
|
end
|
14
|
+
|
15
|
+
def no_procedure_build(name)
|
16
|
+
'No procedure found ' + name.to_s
|
17
|
+
end
|
18
|
+
|
19
|
+
def unbound_symbol_err(symbol)
|
20
|
+
'Unbound symbol ' + symbol.to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
def data_type_err(exp, got)
|
24
|
+
'Invalid data type, expected ' + exp.to_s + ' got ' + got.to_s
|
25
|
+
end
|
14
26
|
end
|
15
27
|
|
16
28
|
class SchemeException < RuntimeError
|
@@ -91,6 +91,12 @@ module Optimize
|
|
91
91
|
expr = build_compose_expr funcs
|
92
92
|
proc_lambda expr
|
93
93
|
end
|
94
|
+
|
95
|
+
def define_var_stl(var, values)
|
96
|
+
valid_stl = methods.include? values.to_s[2..-3].to_sym
|
97
|
+
return set_var var, values.to_s[2..-3].to_sym if valid_stl
|
98
|
+
set_var var, values[0]
|
99
|
+
end
|
94
100
|
end
|
95
101
|
|
96
102
|
# FunctionalScheme helper
|
@@ -163,7 +169,7 @@ module FunctionalSchemeHelper
|
|
163
169
|
def define_var(var, values)
|
164
170
|
raise arg_err_build 1, values.size if values.size != 1
|
165
171
|
raise 'Invalid variable name' unless valid_var_name var
|
166
|
-
|
172
|
+
define_var_stl var, values
|
167
173
|
end
|
168
174
|
|
169
175
|
def set_values_define(other, params, args)
|
@@ -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 data_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 data_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 data_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 data_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 data_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 data_type_err '<number>', result.type unless check_for_num result
|
136
136
|
result.to_num
|
137
137
|
end
|
138
138
|
|
@@ -0,0 +1,66 @@
|
|
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
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# Helper functions for SchemeStrings
|
2
|
+
module SchemeStringsHelper
|
3
|
+
def substring_builder(str, from, to)
|
4
|
+
result = (str[1..-2])[from..(to.nil? ? -1 : to - 1)]
|
5
|
+
return '""' if result.nil?
|
6
|
+
'"' + result + '"'
|
7
|
+
end
|
8
|
+
|
9
|
+
def find_delimeter(other)
|
10
|
+
return ' ' if other.nil?
|
11
|
+
other[1..-2]
|
12
|
+
end
|
13
|
+
|
14
|
+
def build_as_string_helper(other, idx)
|
15
|
+
value = other[0..idx].join(' ').gsub('( ', '(').gsub(' )', ')')
|
16
|
+
[value, other[idx + 1..-1]]
|
17
|
+
end
|
18
|
+
|
19
|
+
def build_next_value_as_string(other)
|
20
|
+
idx = find_idx_for_list other
|
21
|
+
if other[0] == '('
|
22
|
+
build_as_string_helper other, idx
|
23
|
+
elsif other[0..1].join == '\'('
|
24
|
+
[(get_raw_value other[0..idx]), other[idx + 1..-1]]
|
25
|
+
else
|
26
|
+
[other[0], other[1..-1]]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def build_character(char)
|
31
|
+
'#\\' + (char == ' ' ? 'space' : char)
|
32
|
+
end
|
33
|
+
|
34
|
+
def remove_carriage(str)
|
35
|
+
str = str[1..-2]
|
36
|
+
str.gsub('\n', '').gsub('\r', '').gsub('\t', '').strip.squeeze(' ')
|
37
|
+
end
|
38
|
+
|
39
|
+
def arg_function_validator(other, vars = 1)
|
40
|
+
raise arg_err_build other.size, vars if other.size != vars
|
41
|
+
res = other[0..vars - 1].reject { |v| check_for_string v }
|
42
|
+
raise data_type_err '<string>', res[0].type unless res.empty?
|
43
|
+
res
|
44
|
+
end
|
45
|
+
|
46
|
+
def string_join_helper(other, dilimeter)
|
47
|
+
values = split_list_as_string other.to_s
|
48
|
+
delim_result = find_delimeter dilimeter
|
49
|
+
'"' + (values.join delim_result) + '"'
|
50
|
+
end
|
51
|
+
|
52
|
+
def strjoin_validate(other)
|
53
|
+
raise arg_err_build '[1, 2]', other.size unless other.size.between? 1, 2
|
54
|
+
raise data_type_err '<list>', other[0].type unless other[0].to_s.list?
|
55
|
+
end
|
56
|
+
|
57
|
+
def substring_validator(from, to)
|
58
|
+
valid = (check_for_num from) && (to.nil? || (check_for_num to))
|
59
|
+
type = [from, to].first { |t| t.type if t.type != 'number' }
|
60
|
+
raise data_type_err '<number>', type unless valid
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Scheme numbers module
|
65
|
+
module SchemeStrings
|
66
|
+
include SchemeStringsHelper
|
67
|
+
def substring(other)
|
68
|
+
raise arg_err_build '[2, 3]', other.size unless other.size.between? 2, 3
|
69
|
+
str, from, to = other
|
70
|
+
arg_function_validator [str]
|
71
|
+
substring_validator from, to
|
72
|
+
substring_builder str, from.to_num, to.to_num
|
73
|
+
end
|
74
|
+
|
75
|
+
def string?(other)
|
76
|
+
raise arg_err_build 1, other.size if other.size != 1
|
77
|
+
result = check_for_string other[0].to_s
|
78
|
+
result ? '#t' : '#f'
|
79
|
+
end
|
80
|
+
|
81
|
+
def strlen(other)
|
82
|
+
arg_function_validator other
|
83
|
+
other[0][1..-2].length
|
84
|
+
end
|
85
|
+
|
86
|
+
def strupcase(other)
|
87
|
+
arg_function_validator other
|
88
|
+
other[0].upcase
|
89
|
+
end
|
90
|
+
|
91
|
+
def strdowncase(other)
|
92
|
+
arg_function_validator other
|
93
|
+
other[0].downcase
|
94
|
+
end
|
95
|
+
|
96
|
+
def strcontains(other)
|
97
|
+
arg_function_validator other, 2
|
98
|
+
result = other[0][1..-2].include? other[1][1..-2]
|
99
|
+
result ? '#t' : '#f'
|
100
|
+
end
|
101
|
+
|
102
|
+
def strsplit(other)
|
103
|
+
arg_function_validator other
|
104
|
+
str = remove_carriage other[0]
|
105
|
+
result = str.split(' ').map { |s| '"' + s + '"' }
|
106
|
+
build_list result
|
107
|
+
end
|
108
|
+
|
109
|
+
def strlist(other)
|
110
|
+
arg_function_validator other
|
111
|
+
result = other[0][1..-2].chars.map { |c| build_character c }
|
112
|
+
build_list result
|
113
|
+
end
|
114
|
+
|
115
|
+
def strreplace(other)
|
116
|
+
arg_function_validator other, 3
|
117
|
+
str, to_replace, replace_with = other.map { |t| t[1..-2] }
|
118
|
+
'"' + (str.gsub to_replace, replace_with) + '"'
|
119
|
+
end
|
120
|
+
|
121
|
+
def strprefix(other)
|
122
|
+
arg_function_validator other, 2
|
123
|
+
str, to_check = other.map { |t| t[1..-2] }
|
124
|
+
result = str.start_with? to_check
|
125
|
+
result ? '#t' : '#f'
|
126
|
+
end
|
127
|
+
|
128
|
+
def strsufix(other)
|
129
|
+
arg_function_validator other, 2
|
130
|
+
str, to_check = other.map { |t| t[1..-2] }
|
131
|
+
result = str.end_with? to_check
|
132
|
+
result ? '#t' : '#f'
|
133
|
+
end
|
134
|
+
|
135
|
+
def strjoin(other)
|
136
|
+
strjoin_validate other
|
137
|
+
arg_function_validator [other[1]] if other.size == 2
|
138
|
+
string_join_helper other[0], other[1]
|
139
|
+
end
|
140
|
+
end
|
@@ -10,6 +10,7 @@ class Object
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def character?
|
13
|
+
return true if self == '#\space'
|
13
14
|
(start_with? '#\\') && (('a'..'z').to_a.include? self[2]) && size == 3
|
14
15
|
end
|
15
16
|
|
@@ -35,6 +36,20 @@ class Object
|
|
35
36
|
false
|
36
37
|
end
|
37
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
|
+
|
38
53
|
private
|
39
54
|
|
40
55
|
def object_split
|
@@ -62,7 +62,7 @@ module SchemeStrings
|
|
62
62
|
raise arg_err_build '[2, 3]', other.size unless other.size.between? 2, 3
|
63
63
|
str, from, to = other
|
64
64
|
arg_function_validator [str]
|
65
|
-
valid = (
|
65
|
+
valid = (check_for_num from) && (to.nil? || (check_for_num to))
|
66
66
|
raise 'Incorrect parameter type' unless valid
|
67
67
|
substring_builder str, from.to_num, to.to_num
|
68
68
|
end
|
@@ -1,13 +1,13 @@
|
|
1
|
-
require_relative 'object'
|
2
|
-
require_relative 'errors'
|
1
|
+
require_relative 'core/object'
|
2
|
+
require_relative 'core/errors'
|
3
|
+
require_relative 'core/numbers'
|
4
|
+
require_relative 'core/strings'
|
5
|
+
require_relative 'core/boolean'
|
6
|
+
require_relative 'core/list'
|
7
|
+
require_relative 'core/functional'
|
3
8
|
require_relative 'value_finder'
|
4
9
|
require_relative 'checker'
|
5
10
|
require_relative 'validator'
|
6
|
-
require_relative 'numbers'
|
7
|
-
require_relative 'strings'
|
8
|
-
require_relative 'boolean'
|
9
|
-
require_relative 'list'
|
10
|
-
require_relative 'functional'
|
11
11
|
|
12
12
|
# Tokenizer helper
|
13
13
|
module TokenizerHelper
|
@@ -66,9 +66,8 @@ module TokenizerHelper
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def set_var(var, value)
|
69
|
-
raise 'Cannot predefine reserved keyword' if @reserved.key? var.to_s
|
70
69
|
valid = (valid_var value.to_s) || (value.is_a? Proc)
|
71
|
-
raise 'Invalid parameter' unless valid
|
70
|
+
raise 'Invalid parameter' unless valid || (value.is_a? Symbol)
|
72
71
|
@procs[var] = value
|
73
72
|
end
|
74
73
|
|
@@ -78,7 +77,7 @@ module TokenizerHelper
|
|
78
77
|
val = (predefined_method_caller [var])
|
79
78
|
return val unless val.nil?
|
80
79
|
valid = valid_var var
|
81
|
-
valid ? var : (raise
|
80
|
+
valid ? var : (raise unbound_symbol_err var)
|
82
81
|
end
|
83
82
|
|
84
83
|
def syntax_methods
|
@@ -124,12 +123,17 @@ class Tokenizer
|
|
124
123
|
call_predefined_method m_name, arr
|
125
124
|
end
|
126
125
|
|
126
|
+
def check_for_stl_function(arr)
|
127
|
+
idx = find_bracket_idx arr, 1
|
128
|
+
func, = valid_function arr[1..idx]
|
129
|
+
values = find_all_values arr[idx + 1..-2]
|
130
|
+
return func.call(*values) if func.is_a? Proc
|
131
|
+
calc_input_val ['(', func, *values, ')']
|
132
|
+
end
|
133
|
+
|
127
134
|
def special_check_proc(m_name, arr)
|
128
135
|
if arr[0..1].join == '(('
|
129
|
-
|
130
|
-
func, = valid_function arr[1..idx]
|
131
|
-
values = find_all_values arr[idx + 1..-2]
|
132
|
-
func.call(*values)
|
136
|
+
check_for_stl_function arr
|
133
137
|
else
|
134
138
|
m_name.call(*arr[2..-2])
|
135
139
|
end
|
@@ -27,20 +27,20 @@ module Validator
|
|
27
27
|
|
28
28
|
def valid_function(fn)
|
29
29
|
idx = fn[0] == '(' ? (find_bracket_idx fn, 0) : 0
|
30
|
-
|
30
|
+
f =
|
31
31
|
if idx.zero?
|
32
32
|
predefined_method_caller [fn[idx]]
|
33
33
|
else
|
34
34
|
calc_input_val fn[0..idx]
|
35
35
|
end
|
36
|
-
|
37
|
-
[
|
36
|
+
valid_function? f, fn, idx
|
37
|
+
[f, fn[idx + 1..-1]]
|
38
38
|
end
|
39
39
|
|
40
40
|
private
|
41
41
|
|
42
42
|
def valid_literals(var)
|
43
|
-
number =
|
43
|
+
number = check_for_num var
|
44
44
|
string = check_for_string var
|
45
45
|
boolean = check_for_bool var
|
46
46
|
symbol = check_for_symbol var
|
@@ -51,4 +51,9 @@ module Validator
|
|
51
51
|
def valid_objects(var)
|
52
52
|
var.list? || var.pair?
|
53
53
|
end
|
54
|
+
|
55
|
+
def valid_function?(f, fn, idx)
|
56
|
+
idx = find_bracket_idx fn, 1 if fn[idx] == '\''
|
57
|
+
raise no_procedure_build fn[0..idx].join if f.nil? && (!f.is_a? Proc)
|
58
|
+
end
|
54
59
|
end
|
Binary file
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require_relative '../../lib/lisp/interpreter/core/errors'
|
2
3
|
|
3
4
|
RSpec.describe Lisp::Interpreter do
|
5
|
+
include ErrorMessages
|
4
6
|
before do
|
5
7
|
@p = Parser.new
|
6
8
|
@p.parse('(define x 5)')
|
@@ -19,14 +21,6 @@ RSpec.describe Lisp::Interpreter do
|
|
19
21
|
'(' + arr.join(' ') + ')'
|
20
22
|
end
|
21
23
|
|
22
|
-
def arg_err_build(e, g)
|
23
|
-
'Incorrect number of arguments, expected ' + e.to_s + ' got ' + g.to_s
|
24
|
-
end
|
25
|
-
|
26
|
-
def unbound_symbol(sym)
|
27
|
-
'Unbound symbol "' + sym.to_s + '"'
|
28
|
-
end
|
29
|
-
|
30
24
|
@p.parse('(define xl (lambda (x) (* 2 x)))')
|
31
25
|
@p.parse('(define yl (lambda () 5))')
|
32
26
|
@p.parse('(define zl (lambda ()))')
|
@@ -68,7 +62,7 @@ RSpec.describe Lisp::Interpreter do
|
|
68
62
|
|
69
63
|
describe 'literals' do
|
70
64
|
it 'throws invalid variable error when the data is invalid' do
|
71
|
-
expect(@p.parse('#\invalid')).to eq
|
65
|
+
expect(@p.parse('#\invalid')).to eq unbound_symbol_err '#\invalid'
|
72
66
|
end
|
73
67
|
|
74
68
|
it 'can parse integers' do
|
@@ -1002,7 +996,7 @@ RSpec.describe Lisp::Interpreter do
|
|
1002
996
|
expr1 = '(define prodfive (lambda (x)(define yy 5)(* x yy)))'
|
1003
997
|
expect(@p.parse(expr1)).to be_instance_of(Proc)
|
1004
998
|
expect(@p.parse('(prodfive 6)')).to eq 30
|
1005
|
-
expect(@p.parse('yy')).to eq
|
999
|
+
expect(@p.parse('yy')).to eq unbound_symbol_err 'yy'
|
1006
1000
|
end
|
1007
1001
|
end
|
1008
1002
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lisp-interpreter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zaki Petrov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-08-
|
11
|
+
date: 2017-08-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -71,12 +71,14 @@ files:
|
|
71
71
|
- bin/start.rb
|
72
72
|
- bin/zakichan.bat
|
73
73
|
- lib/lisp/interpreter.rb
|
74
|
-
- lib/lisp/interpreter/boolean.rb
|
75
74
|
- lib/lisp/interpreter/checker.rb
|
76
|
-
- lib/lisp/interpreter/
|
77
|
-
- lib/lisp/interpreter/
|
78
|
-
- lib/lisp/interpreter/
|
79
|
-
- lib/lisp/interpreter/
|
75
|
+
- lib/lisp/interpreter/core/boolean.rb
|
76
|
+
- lib/lisp/interpreter/core/errors.rb
|
77
|
+
- lib/lisp/interpreter/core/functional.rb
|
78
|
+
- lib/lisp/interpreter/core/list.rb
|
79
|
+
- lib/lisp/interpreter/core/numbers.rb
|
80
|
+
- lib/lisp/interpreter/core/object.rb
|
81
|
+
- lib/lisp/interpreter/core/strings.rb
|
80
82
|
- lib/lisp/interpreter/object.rb
|
81
83
|
- lib/lisp/interpreter/parser.rb
|
82
84
|
- lib/lisp/interpreter/run.rb
|
@@ -85,6 +87,7 @@ files:
|
|
85
87
|
- lib/lisp/interpreter/validator.rb
|
86
88
|
- lib/lisp/interpreter/value_finder.rb
|
87
89
|
- lib/lisp/interpreter/version.rb
|
90
|
+
- lisp-interpreter-0.3.5.gem
|
88
91
|
- lisp-interpreter.gemspec
|
89
92
|
- spec/lisp/interpreter_spec.rb
|
90
93
|
- spec/lisp/test.scm
|