lisp-interpreter 0.4.3 → 0.4.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bac8ea2951af78891e06278ec6ae00b35858f875
4
- data.tar.gz: e8a83f418220ff4fba37e74bb52223fd9e34e80f
3
+ metadata.gz: a65e89fbe8025750a006c6c098017b1f65242fd6
4
+ data.tar.gz: 555c606c9d3ed1367a41c6c82c569e4afc4a25c8
5
5
  SHA512:
6
- metadata.gz: 690b6efb7cf32a7e8534d54ef4521e0eaf28f7ec8aa66e70973901236e39754d2b46fb45d3c5b263571e6af115641cd6631d530fdbdf47853d918689de51a9a0
7
- data.tar.gz: 411a2c4f8239fb7e0bd86d0589e7c5a10a7d5917b47d3dfd9500f69fb039288ade0b1c8d0b6c1416e5b25ce275f3aa405f176c97b74db27b654757e518586d08
6
+ metadata.gz: c1e32ed761f22a0dab7fd5d4072e4457650fc4ff4efeb98628e172b63fcd7363cc4395decfd99bcaab9fef6f028b76e8b2de06ab380002fb23542aa30e2233bf
7
+ data.tar.gz: 60ea067619421cb4d173b9ef99ef725a16c03c43a5643fcf6e25771878cdd012ccf65d1c6c2f6081a1d959558fac5ad401ca67c1b773c516660c7dc264b8eb53
@@ -169,7 +169,7 @@ module FunctionalSchemeHelper
169
169
 
170
170
  def define_var(var, values)
171
171
  raise arg_err_build 1, values.size if values.size != 1
172
- raise 'Invalid variable name' unless valid_var_name var
172
+ raise var.to_s + ' is not valid variable name' unless valid_var_name var
173
173
  define_var_stl var, values
174
174
  end
175
175
 
@@ -186,7 +186,7 @@ module FunctionalSchemeHelper
186
186
 
187
187
  def define_func_helper(other, params, args)
188
188
  temp = set_values_define other, params, args
189
- calc_input_val temp
189
+ (find_all_values temp)[-1]
190
190
  end
191
191
 
192
192
  def arg_finder_helper(name, args)
@@ -0,0 +1,44 @@
1
+ require_relative 'object'
2
+ require_relative 'stl_functions'
3
+ require_relative 'errors'
4
+ require_relative 'numbers'
5
+ require_relative 'strings'
6
+ require_relative 'boolean'
7
+ require_relative 'list'
8
+ require_relative 'functional'
9
+
10
+ # Module for loading stl functions and keywords
11
+ module StlLoader
12
+ include SchemeStl
13
+ def initialize
14
+ @other = []
15
+ @procs = {}
16
+ @do_not_calculate = init_do_not_calculate_fn
17
+ @reserved = init_reserved_fn
18
+ set_reserved_keywords
19
+ @functions = init_functions.dup
20
+ init_predefined.each { |f| @functions[f] = f }
21
+ end
22
+
23
+ def init_do_not_calculate_fn
24
+ DO_NOT_CALCULATE_FUNCTIONS
25
+ end
26
+
27
+ def init_functions
28
+ SPECIAL_CHARACTER_FUNCTIONS
29
+ end
30
+
31
+ def init_predefined
32
+ PREDEFINED_FUNCTIONS
33
+ end
34
+
35
+ def init_reserved_fn
36
+ RESERVED_KEYWORDS
37
+ end
38
+
39
+ def set_reserved_keywords
40
+ @reserved.each do |key, value|
41
+ @procs[key.to_s] = value
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,31 @@
1
+ # STL functions
2
+ module SchemeStl
3
+ DO_NOT_CALCULATE_FUNCTIONS =
4
+ %w[
5
+ foldl foldr map filter
6
+ if apply numerator denominator
7
+ lambda compose define
8
+ ].freeze
9
+
10
+ SPECIAL_CHARACTER_FUNCTIONS =
11
+ {
12
+ 'string-downcase' => 'strdowncase', 'string-upcase' => 'strupcase',
13
+ 'string-contains?' => 'strcontains', 'string-length' => 'strlen',
14
+ 'string->list' => 'strlist', 'string-split' => 'strsplit',
15
+ 'string-sufix?' => 'strsufix', 'string-prefix?' => 'strprefix',
16
+ 'string-replace' => 'strreplace', 'string-join' => 'strjoin'
17
+ }.freeze
18
+
19
+ PREDEFINED_FUNCTIONS =
20
+ %w[
21
+ define not equal? if quotient remainder modulo numerator denominator
22
+ min max sub1 add1 abs string? substring null? cons null list car
23
+ cdr list? pair? length reverse remove shuffle map foldl foldr filter
24
+ member lambda apply compose
25
+ ].freeze
26
+
27
+ RESERVED_KEYWORDS =
28
+ {
29
+ 'null' => '\'()'
30
+ }.freeze
31
+ end
@@ -57,4 +57,31 @@ module ValueFinder
57
57
  return [other[0], other[1..-1]] if other[0].is_a? Proc
58
58
  find_value_helper other
59
59
  end
60
+
61
+ def set_var(var, value)
62
+ valid = (valid_var value.to_s) || (value.is_a? Proc)
63
+ raise 'Invalid parameter' unless valid || (value.is_a? Symbol)
64
+ return if var == value.to_s
65
+ @procs[var] = value
66
+ end
67
+
68
+ def get_var(var)
69
+ check = check_instance_var var
70
+ return @procs[var.to_s] if check
71
+ val = (predefined_method_caller [var])
72
+ return val unless val.nil?
73
+ valid = valid_var var
74
+ valid ? var : (raise unbound_symbol_err var)
75
+ end
76
+
77
+ def get_raw_value(token)
78
+ if token.pair? || token.list?
79
+ build_list no_eval_list token[2..-2]
80
+ else
81
+ return if token.empty?
82
+ token = token.join('') if token.is_a? Array
83
+ return token if token =~ /c[ad]{2,}r/
84
+ get_var token.to_s
85
+ end
86
+ end
60
87
  end
@@ -1,5 +1,3 @@
1
- require_relative 'core/errors'
2
- require_relative 'validator'
3
1
  require_relative 'tokenizer'
4
2
 
5
3
  # Environment type
@@ -1,95 +1,12 @@
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'
8
- require_relative 'value_finder'
9
- require_relative 'checker'
10
- require_relative 'validator'
11
-
12
- # Tokenizer helper
13
- module TokenizerHelper
14
- def initialize
15
- @other = []
16
- @procs = {}
17
- @do_not_calculate = init_do_not_calculate_fn
18
- @reserved = init_reserved_fn
19
- set_reserved_keywords
20
- @functions = init_functions
21
- init_predefined.each { |f| @functions[f] = f }
22
- end
23
-
24
- def reset
25
- @other = []
26
- end
27
-
28
- def init_do_not_calculate_fn
29
- %w[
30
- foldl foldr map filter
31
- if apply numerator denominator
32
- lambda compose define
33
- ]
34
- end
35
-
36
- def init_functions
37
- {
38
- 'string-downcase' => 'strdowncase', 'string-upcase' => 'strupcase',
39
- 'string-contains?' => 'strcontains', 'string-length' => 'strlen',
40
- 'string->list' => 'strlist', 'string-split' => 'strsplit',
41
- 'string-sufix?' => 'strsufix', 'string-prefix?' => 'strprefix',
42
- 'string-replace' => 'strreplace', 'string-join' => 'strjoin'
43
- }
44
- end
45
-
46
- def init_predefined
47
- %w[
48
- define not equal? if quotient remainder modulo numerator denominator
49
- min max sub1 add1 abs string? substring null? cons null list car
50
- cdr list? pair? length reverse remove shuffle map foldl foldr filter
51
- member lambda apply compose
52
- ]
53
- end
54
-
55
- def init_reserved_fn
56
- {
57
- 'null' => '\'()',
58
- 'ghci' => ''
59
- }
60
- end
61
-
62
- def set_reserved_keywords
63
- @reserved.each do |key, value|
64
- @procs[key.to_s] = value
65
- end
66
- end
67
-
68
- def set_var(var, value)
69
- valid = (valid_var value.to_s) || (value.is_a? Proc)
70
- raise 'Invalid parameter' unless valid || (value.is_a? Symbol)
71
- return if var == value.to_s
72
- @procs[var] = value
73
- end
74
-
75
- def get_var(var)
76
- check = check_instance_var var
77
- return @procs[var.to_s] if check
78
- val = (predefined_method_caller [var])
79
- return val unless val.nil?
80
- valid = valid_var var
81
- valid ? var : (raise unbound_symbol_err var)
82
- end
83
-
84
- def syntax_methods
85
- @functions
86
- end
87
- end
1
+ require_relative 'core/loader'
2
+ require_relative 'helpers/value_finder'
3
+ require_relative 'helpers/checker'
4
+ require_relative 'helpers/validator'
88
5
 
89
6
  # Tokenizer class
90
7
  class Tokenizer
8
+ include StlLoader
91
9
  include ErrorMessages
92
- include TokenizerHelper
93
10
  include ValueFinder
94
11
  include SchemeChecker
95
12
  include Validator
@@ -99,8 +16,11 @@ class Tokenizer
99
16
  include SchemeLists
100
17
  include FunctionalScheme
101
18
 
19
+ def syntax_methods
20
+ @functions
21
+ end
22
+
102
23
  def tokenize(token)
103
- reset
104
24
  token.delete('')
105
25
  @other = token
106
26
  begin
@@ -177,15 +97,4 @@ class Tokenizer
177
97
  end
178
98
  predefined_method_caller_helper m_name, operations
179
99
  end
180
-
181
- def get_raw_value(token)
182
- if token.pair? || token.list?
183
- build_list no_eval_list token[2..-2]
184
- else
185
- return if token.empty?
186
- token = token.join('') if token.is_a? Array
187
- return token if token =~ /c[ad]{2,}r/
188
- get_var token.to_s
189
- end
190
- end
191
100
  end
@@ -1,5 +1,5 @@
1
1
  module Lisp
2
2
  module Interpreter
3
- VERSION = '0.4.3'.freeze
3
+ VERSION = '0.4.4'.freeze
4
4
  end
5
5
  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.3
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zaki Petrov
@@ -71,20 +71,21 @@ files:
71
71
  - bin/start.rb
72
72
  - bin/zakichan.bat
73
73
  - lib/lisp/interpreter.rb
74
- - lib/lisp/interpreter/checker.rb
75
74
  - lib/lisp/interpreter/core/boolean.rb
76
75
  - lib/lisp/interpreter/core/errors.rb
77
76
  - lib/lisp/interpreter/core/functional.rb
78
77
  - lib/lisp/interpreter/core/list.rb
78
+ - lib/lisp/interpreter/core/loader.rb
79
79
  - lib/lisp/interpreter/core/numbers.rb
80
80
  - lib/lisp/interpreter/core/object.rb
81
+ - lib/lisp/interpreter/core/stl_functions.rb
81
82
  - lib/lisp/interpreter/core/strings.rb
82
- - lib/lisp/interpreter/functional.rb
83
+ - lib/lisp/interpreter/helpers/checker.rb
84
+ - lib/lisp/interpreter/helpers/validator.rb
85
+ - lib/lisp/interpreter/helpers/value_finder.rb
83
86
  - lib/lisp/interpreter/parser.rb
84
87
  - lib/lisp/interpreter/run.rb
85
88
  - lib/lisp/interpreter/tokenizer.rb
86
- - lib/lisp/interpreter/validator.rb
87
- - lib/lisp/interpreter/value_finder.rb
88
89
  - lib/lisp/interpreter/version.rb
89
90
  - lisp-interpreter.gemspec
90
91
  - spec/lisp/interpreter_spec.rb
@@ -1,290 +0,0 @@
1
- # Optimization module
2
- module Optimize
3
- def fold_values_helper(other)
4
- other = other.map { |t| find_list_function_value [t] }
5
- (equalize_lists other).transpose
6
- end
7
-
8
- def get_fold_values(other)
9
- values = find_all_values other
10
- raise arg_err_build 'at least 2', 0 if values.empty?
11
- x = values[0]
12
- y = fold_values_helper values[1..-1]
13
- [x, y]
14
- end
15
-
16
- def rm_from_in_scope(scope, idx, def_vars)
17
- i = find_bracket_idx scope, idx
18
- def_vars[scope[idx + 2].to_s] = scope[idx + 3..i - 1]
19
- scope.slice!(idx..i)
20
- [i + 1, scope, def_vars]
21
- end
22
-
23
- def inner_scope_replace(scope, vars)
24
- scope.each_with_index do |t, i|
25
- scope[i] = vars[t.to_s] if vars.key? t.to_s
26
- end
27
- scope.flatten
28
- end
29
-
30
- def fetch_inner_scope(scope, idx = 0, def_vars = {})
31
- until idx >= scope.size
32
- if scope[idx] == 'define'
33
- idx, scope, def_vars = rm_from_in_scope scope, idx - 1, def_vars
34
- else
35
- idx += 1
36
- end
37
- end
38
- inner_scope_replace scope, def_vars
39
- end
40
-
41
- def filter_helper(func, values)
42
- result =
43
- if func.is_a? Proc
44
- values.select { |t| func.call(*t) == '#t' }
45
- else
46
- values.select { |t| (send func, [t]) == '#t' }
47
- end
48
- build_list result
49
- end
50
-
51
- def apply_helper(func, values)
52
- *vs, lst = values
53
- raise 'Incorrect data type' unless lst.list?
54
- (find_list_function_value [lst]).each { |t| vs << t }
55
- return func.call(*vs) if func.is_a? Proc
56
- send func, vs
57
- end
58
-
59
- def call_compose_helper(other)
60
- tmp = ['(', *other[1..-1]]
61
- idx = find_bracket_idx tmp, 0
62
- funcs = find_all_values tmp[1..idx - 1]
63
- return '' if tmp[idx + 1..-1].nil? && funcs.empty?
64
- [funcs, idx, tmp]
65
- end
66
-
67
- def call_compose(other)
68
- funcs, idx, tmp = call_compose_helper other
69
- value = find_all_values tmp[idx + 1..-1]
70
- funcs.reverse.each do |t|
71
- value = value.to_s unless value.is_a? Array
72
- value = calc_input_val ['(', t, *value, ')']
73
- end
74
- value
75
- end
76
-
77
- def build_compose_expr(funcs)
78
- expr = ['(', 'x', ')']
79
- funcs.each do |f|
80
- expr << '('
81
- expr << f
82
- end
83
- expr << 'x'
84
- funcs.size.times { expr << ')' }
85
- expr
86
- end
87
-
88
- def do_not_call_compose(other)
89
- funcs = find_all_values other
90
- raise 'Incorrect data type' if funcs.any? { |t| t.to_s.number? }
91
- expr = build_compose_expr funcs
92
- proc_lambda expr
93
- end
94
-
95
- def define_var_stl(var, values)
96
- puts methods.to_s
97
- valid_stl = methods.include? values.to_s[2..-3].to_sym
98
- return set_var var, values.to_s[2..-3].to_sym if valid_stl
99
- set_var var, values[0]
100
- end
101
- end
102
-
103
- # FunctionalScheme helper
104
- module FunctionalSchemeHelper
105
- include Optimize
106
- def foldl_helper(func, accum, lst)
107
- return accum if lst.empty?
108
- value = func.call(*lst[0], accum.to_s) if func.is_a? Proc
109
- value = send func, [*lst[0], accum] if value.nil?
110
- foldl_helper func, value.to_s, lst[1..-1]
111
- end
112
-
113
- def foldr_helper(func, accum, lst)
114
- return accum if lst.empty?
115
- value = foldr_helper func, accum, lst[1..-1]
116
- return func.call(*lst[0], value.to_s) if func.is_a? Proc
117
- send func, [*lst[0], value.to_s]
118
- end
119
-
120
- def equalize_lists(other)
121
- min = other.map(&:size).min
122
- other.map { |t| t[0..min - 1] }
123
- end
124
-
125
- def member_helper(to_check, values)
126
- return '#f' unless values.include? to_check
127
- idx = values.index(to_check)
128
- build_list values[idx..-1]
129
- end
130
-
131
- def find_params_lambda(other)
132
- raise 'Invalid syntax' if other[0] != '('
133
- idx = find_bracket_idx other, 0
134
- [other[1..idx - 1], other[idx + 1..-1]]
135
- end
136
-
137
- def eval_lambda(other)
138
- idx = find_bracket_idx other.unshift('('), 0
139
- to_eval = other[1..idx - 1]
140
- (proc_lambda to_eval, true).call(*other[idx + 1..-1])
141
- end
142
-
143
- def proc_lambda_helper(other, params, args)
144
- args = arg_finder args
145
- raise arg_err_build params.size, args.size unless params.size == args.size
146
- define_func_helper other.dup, params.dup, args
147
- end
148
-
149
- def proc_lambda(other, is_call = false)
150
- params, other = find_params_lambda other
151
- other = fetch_inner_scope other
152
- valid = params.all? { |t| valid_var_name t } || is_call
153
- raise 'Invalid syntax' unless valid
154
- to_return = other[0..1].join == '(compose' && params.empty?
155
- return calc_input_val other if to_return
156
- proc = proc do |*args|
157
- proc_lambda_helper other, params, args
158
- end
159
- proc
160
- end
161
-
162
- def fetch_define(other)
163
- if other[0] == '('
164
- define_function other
165
- else
166
- define_var other[0].to_s, (find_all_values other[1..-1])
167
- end
168
- end
169
-
170
- def define_var(var, values)
171
- raise arg_err_build 1, values.size if values.size != 1
172
- raise 'Invalid variable name' unless valid_var_name var
173
- define_var_stl var, values
174
- end
175
-
176
- def set_values_define(other, params, args)
177
- args = [args] unless args.is_a? Array
178
- other.each_with_index do |t, idx|
179
- if params.include? t
180
- i = params.index t
181
- other[idx] = args[i]
182
- end
183
- end
184
- other
185
- end
186
-
187
- def define_func_helper(other, params, args)
188
- temp = set_values_define other, params, args
189
- calc_input_val temp
190
- end
191
-
192
- def arg_finder_helper(name, args)
193
- if !name.nil?
194
- args = args[1..-1]
195
- [name, args]
196
- else
197
- find_next_value args
198
- end
199
- end
200
-
201
- def arg_finder(args)
202
- result = []
203
- until args.empty?
204
- name = predefined_method_caller [args[0]]
205
- temp, args = arg_finder_helper name, args
206
- result << temp
207
- end
208
- result
209
- end
210
-
211
- def define_function(other)
212
- idx = find_bracket_idx other, 0
213
- name, *params = other[1..idx - 1]
214
- build_fn = ['(', 'lambda', '(', *params, ')', *other[idx + 1..-1], ')']
215
- define_var name, (find_all_values build_fn)
216
- end
217
- end
218
-
219
- # Functional programming main functions
220
- module FunctionalScheme
221
- include FunctionalSchemeHelper
222
- def foldl(other)
223
- raise arg_err_build 'at least 2', other.size if other.size < 2
224
- func, other = valid_function other
225
- val_one, val_two = get_fold_values other
226
- foldl_helper func, val_one, val_two
227
- end
228
-
229
- def foldr(other)
230
- raise arg_err_build 'at least 2', other.size if other.size < 2
231
- func, other = valid_function other
232
- val_one, val_two = get_fold_values other
233
- foldr_helper func, val_one, val_two
234
- end
235
-
236
- def filter(other)
237
- raise arg_err_build 2, other.size if other.size < 2
238
- func, other = valid_function other
239
- raise arg_err_build 2, 1 if other.empty?
240
- values = find_all_values other
241
- values = find_list_function_value [values[0]]
242
- filter_helper func, values
243
- end
244
-
245
- def member(other)
246
- raise arg_err_build 2, other.size unless other.size == 2
247
- to_check = other[0]
248
- split_val = split_list_string other[1]
249
- raise 'Invalid argument' unless split_val.pair? || split_val.list?
250
- values = find_all_values split_val[2..-2]
251
- member_helper to_check, values
252
- end
253
-
254
- def remove(other)
255
- raise arg_err_build 2, other.size unless other.size == 2
256
- to_remove = other[0]
257
- values = find_list_function_value [other[1]]
258
- values.delete_at(values.index(to_remove) || values.length)
259
- build_list values
260
- end
261
-
262
- def apply(other)
263
- raise arg_err_build 'at least 2', 0 if other.nil? || other.empty?
264
- func, other = valid_function other
265
- raise arg_err_build 'at least 2', 1 if other.empty?
266
- values = find_all_values other
267
- apply_helper func, values
268
- end
269
-
270
- def compose(other)
271
- if other[0] != 'compose'
272
- do_not_call_compose other
273
- else
274
- call_compose other
275
- end
276
- end
277
-
278
- def lambda(other)
279
- if other[0] == 'lambda'
280
- eval_lambda other[1..-1]
281
- else
282
- proc_lambda other
283
- end
284
- end
285
-
286
- def define(other)
287
- raise arg_err_build 2, other.size if other.size < 2
288
- fetch_define other
289
- end
290
- end