lisp-interpreter 0.3.4 → 0.3.5
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/list.rb +14 -0
- data/lib/lisp/interpreter/parser.rb +30 -14
- data/lib/lisp/interpreter/tokenizer.rb +11 -1
- data/lib/lisp/interpreter/version.rb +1 -1
- data/spec/lisp/interpreter_spec.rb +16 -2
- data/spec/lisp/test.scm +3 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 31b5afb412627509393e82cd31613a47029d6de8
|
4
|
+
data.tar.gz: 5fb55aedca3ff30a6a41f9a808379a9483feb03c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1c1101cea234ab1711fc5208d344199fc492032c214448442c23eaba3c7940b0cb9792f374845e52b92f5e00d5525bb49e938b8091a7d4450bed56347831e64f
|
7
|
+
data.tar.gz: 15b95c4869df5dd227fbd243a0d6a53fe4ce008bc94ac6e58b09bcf99206d465f10e9821146f2438fd57e5698cf32fbe559c0d84e3ac71bb32f12e476b1dd7c6
|
@@ -102,6 +102,13 @@ module SchemeListsHelper
|
|
102
102
|
raise arg_err_build 'at least 2', 1 if other.empty?
|
103
103
|
[func, other]
|
104
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
|
105
112
|
end
|
106
113
|
|
107
114
|
# Scheme lists module
|
@@ -166,4 +173,11 @@ module SchemeLists
|
|
166
173
|
values = find_list_function_value other
|
167
174
|
build_list values.shuffle
|
168
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
|
169
183
|
end
|
@@ -24,7 +24,7 @@ class Parser
|
|
24
24
|
print 'zakichan> ' if @env_type == Environment::PROD
|
25
25
|
token = ''
|
26
26
|
until (validate_token token).nil? && token != ''
|
27
|
-
crr_input = STDIN.gets.chomp
|
27
|
+
crr_input = STDIN.gets.chomp + ' '
|
28
28
|
token << crr_input
|
29
29
|
break if crr_input == ''
|
30
30
|
end
|
@@ -47,17 +47,16 @@ class Parser
|
|
47
47
|
def read_file_helper(token)
|
48
48
|
pattern = /^ghci .*\.[.ss|.scm]+$/
|
49
49
|
result = (token =~ pattern)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
55
|
-
true
|
50
|
+
return unless result.nil?
|
51
|
+
token = token[5..-1].nil? ? token[4..-1] : token[5..-1]
|
52
|
+
msg = 'File with name "' + token + '" is not valid scheme file'
|
53
|
+
msg
|
56
54
|
end
|
57
55
|
|
58
56
|
def read_file_reader(f, expr)
|
59
|
-
|
60
|
-
|
57
|
+
last_value = ''
|
58
|
+
f.each do |line|
|
59
|
+
expr << line
|
61
60
|
if (validate_token expr).nil? && expr != ''
|
62
61
|
last_value = parse expr
|
63
62
|
expr = ''
|
@@ -74,10 +73,10 @@ class Parser
|
|
74
73
|
|
75
74
|
def read_file(token)
|
76
75
|
res = read_file_helper token
|
77
|
-
return res if res.is_a? String
|
76
|
+
return finalize_result res if res.is_a? String
|
78
77
|
filename = token[5..-1]
|
79
78
|
return read_file_executor filename if File.exist? filename
|
80
|
-
'File with name "' + filename + '" does not exist!'
|
79
|
+
finalize_result 'File with name "' + filename + '" does not exist!'
|
81
80
|
end
|
82
81
|
|
83
82
|
def parse(token)
|
@@ -89,7 +88,7 @@ class Parser
|
|
89
88
|
else
|
90
89
|
token_error
|
91
90
|
end
|
92
|
-
|
91
|
+
finalize_result result unless result.to_s.empty?
|
93
92
|
end
|
94
93
|
|
95
94
|
def validate_token(token)
|
@@ -100,10 +99,27 @@ class Parser
|
|
100
99
|
end
|
101
100
|
end
|
102
101
|
|
103
|
-
def
|
102
|
+
def finalize_result(result)
|
103
|
+
result = format_result result
|
104
|
+
display_result result if @env_type == Environment::PROD
|
105
|
+
result
|
106
|
+
end
|
107
|
+
|
108
|
+
def format_result(result)
|
104
109
|
to_remove = result.to_s.list? || result.to_s.pair? || result.to_s.quote?
|
105
110
|
result = result.delete('\'') if to_remove
|
106
|
-
puts result if @env_type == Environment::PROD
|
107
111
|
result
|
108
112
|
end
|
113
|
+
|
114
|
+
def find_result_type(res, methods)
|
115
|
+
return '#<Closure>' if res.is_a? Proc
|
116
|
+
is_func = (methods.key? res.to_s) || res.to_s.match(/c[ad]{2,}r/)
|
117
|
+
return '#<Function ' + res.to_s + '>' if is_func
|
118
|
+
res.to_s
|
119
|
+
end
|
120
|
+
|
121
|
+
def display_result(result)
|
122
|
+
to_print = find_result_type result, @tokenizer.syntax_methods
|
123
|
+
puts to_print
|
124
|
+
end
|
109
125
|
end
|
@@ -80,6 +80,10 @@ module TokenizerHelper
|
|
80
80
|
valid = valid_var var
|
81
81
|
valid ? var : (raise 'Unbound symbol "' + var + '"')
|
82
82
|
end
|
83
|
+
|
84
|
+
def syntax_methods
|
85
|
+
@functions
|
86
|
+
end
|
83
87
|
end
|
84
88
|
|
85
89
|
# Tokenizer class
|
@@ -108,7 +112,7 @@ class Tokenizer
|
|
108
112
|
|
109
113
|
def check_car_cdr(arr)
|
110
114
|
result = arr[1].match(/c[ad]{2,}r/)
|
111
|
-
raise '
|
115
|
+
raise arr[1].to_s + ' is not a function' if result.nil?
|
112
116
|
car_cdr_infinite arr
|
113
117
|
end
|
114
118
|
|
@@ -131,12 +135,17 @@ class Tokenizer
|
|
131
135
|
end
|
132
136
|
end
|
133
137
|
|
138
|
+
def validate_call_method(m_name)
|
139
|
+
raise m_name.to_s + ' is not a function' if valid_var m_name.to_s
|
140
|
+
end
|
141
|
+
|
134
142
|
def call_predefined_method(m_name, arr)
|
135
143
|
return special_check_proc m_name, arr if m_name.is_a? Proc
|
136
144
|
if @do_not_calculate.include? m_name
|
137
145
|
send m_name.to_s, arr[2..-2]
|
138
146
|
elsif !m_name.nil?
|
139
147
|
values = find_all_values arr[2..-2]
|
148
|
+
validate_call_method m_name
|
140
149
|
send m_name.to_s, values
|
141
150
|
end
|
142
151
|
end
|
@@ -170,6 +179,7 @@ class Tokenizer
|
|
170
179
|
else
|
171
180
|
return if token.empty?
|
172
181
|
token = token.join('') if token.is_a? Array
|
182
|
+
return token if token =~ /c[ad]{2,}r/
|
173
183
|
get_var token.to_s
|
174
184
|
end
|
175
185
|
end
|
@@ -720,6 +720,20 @@ RSpec.describe Lisp::Interpreter do
|
|
720
720
|
end
|
721
721
|
end
|
722
722
|
|
723
|
+
describe 'car_cdr_infinite' do
|
724
|
+
it 'throws error when <p> is the empty list' do
|
725
|
+
expect(@p.parse('(cadr null)')).to eq car_cdr_err '\'()', 'cdr'
|
726
|
+
expect(@p.parse('(cdar (list))')).to eq car_cdr_err '\'()', 'car'
|
727
|
+
expect(@p.parse('(caaadr \'())')).to eq car_cdr_err '\'()', 'cdr'
|
728
|
+
end
|
729
|
+
|
730
|
+
it 'returns the element of <p> depending of car and cdr' do
|
731
|
+
expect(@p.parse('(cadr (list 1 2 3))')).to eq '2'
|
732
|
+
expect(@p.parse('(caar (list (list 1 2) 2))')).to eq '1'
|
733
|
+
expect(@p.parse('(cdar (list (list 1 2) 4))')).to eq '(2)'
|
734
|
+
end
|
735
|
+
end
|
736
|
+
|
723
737
|
describe '(list? v)' do
|
724
738
|
it 'returns true if <v> is empty list' do
|
725
739
|
expect(@p.parse('(list? null)')).to eq '#t'
|
@@ -994,12 +1008,12 @@ RSpec.describe Lisp::Interpreter do
|
|
994
1008
|
|
995
1009
|
describe 'file read' do
|
996
1010
|
it 'reads from .ss file' do
|
997
|
-
expr1 = 'ghci
|
1011
|
+
expr1 = 'ghci spec/lisp/test.ss'
|
998
1012
|
expect(@p.parse(expr1)).to be_instance_of(Proc)
|
999
1013
|
end
|
1000
1014
|
|
1001
1015
|
it 'reads from .scm file' do
|
1002
|
-
expr1 = 'ghci
|
1016
|
+
expr1 = 'ghci spec/lisp/test.scm'
|
1003
1017
|
expect(@p.parse(expr1)).to eq 3
|
1004
1018
|
end
|
1005
1019
|
|
data/spec/lisp/test.scm
CHANGED
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.3.
|
4
|
+
version: 0.3.5
|
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-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -111,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
111
111
|
version: '0'
|
112
112
|
requirements: []
|
113
113
|
rubyforge_project:
|
114
|
-
rubygems_version: 2.
|
114
|
+
rubygems_version: 2.5.2
|
115
115
|
signing_key:
|
116
116
|
specification_version: 4
|
117
117
|
summary: Lisp interpreter gem
|