rus3 0.1.0 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a733b3f40b0fb9223d58d5293f08f68cbc404dbea10df196e92d15e47453a9b6
4
- data.tar.gz: 20749c1d7410e925577b76fdca4ecf92ffc0c1ff4aef5d894079548c324f84ed
3
+ metadata.gz: dfda189d1f2499f00d441efe70f0e8db49ecc443a8c414ec7b4f9282caf28fe2
4
+ data.tar.gz: 1a0c858ec768aec68e79b66815fd8b5cdd2c6eef2f4e688e55f90fbcd1fde558
5
5
  SHA512:
6
- metadata.gz: 5350b2341a176d7844910acb888faeae61c499659471148c9370deaad7ba2192e346a5d7e8a03cc3799540c2fe372feabc925cb8f8bdfd94e34dcaad01a36247
7
- data.tar.gz: 2aab5a0555331938bc986d418dcb18e0d116be078088846bdad73aebc520ae8bda7b1b334f5ec26dc78bfb5ffe814ff380d1fc9eb9072ad027f4b8539f4fb3ed
6
+ metadata.gz: cb42c290cdcea8dacd9ae0b024ce0c2b266ae912ddc4178c40c5134fda5a79507d420ab959fc10a9860dd8bf3d805e16347a9cd791c4e90ddffaf1e7afd29932
7
+ data.tar.gz: 16450eb77a484889dc5572a62fd48670b278fac5f4845111d6b192dbf8820bac54854a150a628004b9461b995a166f1957876d72636b732b11cf7c6db3dbc6c6
data/CHANGELOG.md CHANGED
@@ -5,9 +5,22 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/)
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/).
6
6
 
7
7
  ## [Unreleased]
8
- - Add `CHANGELOG.md`. (2021-04-04)
9
- - Modify some files to pass tests. (2021-04-04)
10
- - Add files those are generated by `bundler`. (2021-04-04)
8
+ - (nothing to record)
9
+
10
+ ## [0.1.1] - 2021-04-22
11
+ ### Added
12
+ - Add `vector`:
13
+ - add Rus3::Vector class,
14
+ - modify Rus3::Parser::Lexer to accept a vector literal,
15
+ - modify Rus3::Parser::SchemeParser to parse and translate a vector
16
+ literal,
17
+ - Add new error classes (VectorRequiredError and ExceedUpperLimitError),
18
+ - Add tests around `vector`.
19
+
20
+ ### Changed
21
+ - Modify Rus3::Parser::Lexer to convert "->" to "_to_",
22
+ - now, the Scheme identifier such "list->vector" is usable in the
23
+ REPL
11
24
 
12
25
  ## [0.1.0] - 2021-04-21
13
26
  - Initial release:
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rus3 (0.1.0)
4
+ rus3 (0.1.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -52,6 +52,8 @@ Rus3(scheme)> 1/9
52
52
  ==> (1/9)
53
53
  Rus3(scheme)> 3+4i
54
54
  ==> (3+4i)
55
+ Rus3(scheme)> #(1 2 3)
56
+ ==> #<Rus3::Vector:0x00007facf12d9fb0 @content=[1, 2, 3]>
55
57
  ```
56
58
 
57
59
  ### Procedure call
@@ -115,8 +117,8 @@ Following procedures described in the spec is available.
115
117
  - Predicates:
116
118
  - null?, list?
117
119
  - eqv?, eq?
118
- - boolean?, pair?, symbol?, number?, string?
119
- - char?, vector?, and port? are defined but it always returns `false`.
120
+ - boolean?, pair?, symbol?, number?, string?, vector?
121
+ - char? and port? are defined but it always returns `false`.
120
122
  - complex?, real?, rational?, integer?
121
123
  - zero?, positive?, negative?, odd?, even?
122
124
  - string-eq?, string-ci-eq?, string-lt?, string-gt?, string-le?,
@@ -128,6 +130,10 @@ Following procedures described in the spec is available.
128
130
  - cons, car, cdr, set-car!, set-cdr!, cxxr (caar and so on)
129
131
  - list, length, append, reverse, list-tail, list-ref
130
132
 
133
+ - Vector operations
134
+ - make-vector, vector, vector-length, vector-ref, vector-set!,
135
+ vector->list, list->vector, vector-fill!
136
+
131
137
  - Write values
132
138
  - write
133
139
  - display
data/exe/rus3 CHANGED
@@ -2,4 +2,17 @@
2
2
 
3
3
  require "rus3"
4
4
 
5
- Rus3::Repl.start(verbose: ARGV.size > 0)
5
+ opts = {}
6
+
7
+ while ARGV.size > 0
8
+ arg = ARGV.shift
9
+ case arg
10
+ when "-d", "--debug"
11
+ opts[:debug] = true
12
+ when "-v", "--version"
13
+ puts "rus3 version #{Rus3::VERSION} (#{Rus3::RELEASE})"
14
+ exit 0
15
+ end
16
+ end
17
+
18
+ Rus3::Repl.start(verbose: opts[:debug])
data/lib/rus3.rb CHANGED
@@ -39,9 +39,12 @@ module Rus3
39
39
  require_relative "rus3/pair"
40
40
  require_relative "rus3/char"
41
41
  require_relative "rus3/port"
42
+ require_relative "rus3/vector"
42
43
 
44
+ require_relative "rus3/procedure/utils"
43
45
  require_relative "rus3/procedure/predicate"
44
46
  require_relative "rus3/procedure/list"
47
+ require_relative "rus3/procedure/vector"
45
48
  require_relative "rus3/procedure/control"
46
49
  require_relative "rus3/procedure/write"
47
50
 
data/lib/rus3/error.rb CHANGED
@@ -11,12 +11,14 @@ module Rus3
11
11
  "()"
12
12
  else # a normal proper list
13
13
  list_notation = obj.to_s().gsub(/[\[\],]/, A2L_MAP)
14
- "list( %s )" % obj
14
+ "list( %s )" % list_notation
15
15
  end
16
16
  when Numeric
17
17
  "number(%d)" % obj
18
18
  when Rus3::Pair
19
19
  "pair(%s)" % obj
20
+ when Rus3::Vector
21
+ "vector(%s)" % obj
20
22
  else
21
23
  "%s(%s)" % [obj.class, obj]
22
24
  end
@@ -31,7 +33,9 @@ module Rus3
31
33
  :pair_required => "pair required: got=%s",
32
34
  :list_required => "proper list required: got=%s",
33
35
  :pair_or_list_required => "pair or proper list required: got=%s",
36
+ :vector_required => "vector required: got=%s",
34
37
  :out_of_range => "argument out of range: got=%s",
38
+ :exceed_upper_limit => "argument exceeds its upper limit (%d): got=%d",
35
39
  :unsupported_method => "specified method does not work now.",
36
40
  :wrong_type => "wrong type argument: got=%s, wants=%s",
37
41
  :integer_required => "integer required: got=%s",
@@ -63,12 +67,24 @@ module Rus3
63
67
  end
64
68
  end
65
69
 
70
+ class VectorRequiredError < Error
71
+ def initialize(obj)
72
+ super(EMSG[:vector_required] % smart_error_value(obj))
73
+ end
74
+ end
75
+
66
76
  class OutOfRangeError < Error
67
77
  def initialize(obj)
68
78
  super(EMSG[:out_of_range] % smart_error_value(obj))
69
79
  end
70
80
  end
71
81
 
82
+ class ExceedUpperLimitError < Error
83
+ def initialize(value, limit)
84
+ super(EMSG[:exceed_upper_limit] % [limit, value])
85
+ end
86
+ end
87
+
72
88
  class UnsupportedMethodError < Error
73
89
  def initialize
74
90
  super(EMSG[:unsupported_method])
@@ -14,6 +14,7 @@ module Rus3
14
14
  class Environment
15
15
  include Rus3::Procedure::Control
16
16
  include Rus3::Procedure::Write
17
+ include Rus3::Procedure::Vector
17
18
  include Rus3::Procedure::List
18
19
  include Rus3::Procedure::Predicate
19
20
  include Rus3::EmptyList
@@ -5,7 +5,7 @@ module Rus3::Parser
5
5
  class Lexer < Enumerator
6
6
 
7
7
  # Indicates the version of the lexer class
8
- LEXER_VERSION = "0.1.0"
8
+ LEXER_VERSION = "0.1.1"
9
9
 
10
10
  # :stopdoc:
11
11
 
@@ -13,6 +13,7 @@ module Rus3::Parser
13
13
  # delimiters
14
14
  :lparen,
15
15
  :rparen,
16
+ :vec_lparen,
16
17
  # value types
17
18
  :boolean,
18
19
  :ident,
@@ -31,12 +32,12 @@ module Rus3::Parser
31
32
  STRING = /\A\"[^\"]*\"\Z/
32
33
 
33
34
  # idents
34
- EXTENDED = "\\-"
35
+ EXTENDED = "\\->"
35
36
  IDENT_PAT = "[a-zA-Z_][\\w?!#{EXTENDED}]*"
36
37
  IDENTIFIER = Regexp.new("\\A#{IDENT_PAT}\\Z")
37
38
 
38
39
  EXTENDED_REGEXP = Regexp.new("[#{EXTENDED}]")
39
- EXTENDED_MAP = { "-" => "_", }
40
+ EXTENDED_MAP = { "-" => "_", ">" => "to_"}
40
41
 
41
42
  # operators
42
43
  ARITHMETIC_OPS = /\A[+\-*\/%]\Z/
@@ -90,6 +91,8 @@ module Rus3::Parser
90
91
  Token.new(:lparen, literal)
91
92
  when "]"
92
93
  Token.new(:rparen, literal)
94
+ when "#["
95
+ Token.new(:vec_lparen, literal)
93
96
  when BOOLEAN
94
97
  Token.new(:boolean, literal)
95
98
  when IDENTIFIER
@@ -6,7 +6,7 @@ module Rus3::Parser
6
6
  class SchemeParser < Parser
7
7
 
8
8
  # Indicates the version of the parser class
9
- PARSER_VERSION = "0.1.0"
9
+ PARSER_VERSION = "0.1.1"
10
10
 
11
11
  # Constructs the version string.
12
12
 
@@ -115,6 +115,10 @@ module Rus3::Parser
115
115
  # ["mul", "x", "y"]] ... i_exp
116
116
  # -> "lambda { |x, y| mul(x, y) }.call(2, 3)" ... r_exp
117
117
  #
118
+ # - vector (s_exp -> r_exp)
119
+ # - #(1 2 #(3 4) 5)
120
+ # -> "vector(1, 2, vector(3, 4), 5)"
121
+ #
118
122
  # - list (s_exp -> r_exp)
119
123
  # - (1 2 3 (4 5) (6 7 8) 9 0)
120
124
  # -> "[1, 2, 3, [4, 5], [6, 7, 8], 9, 0]"
@@ -125,18 +129,25 @@ module Rus3::Parser
125
129
 
126
130
  def parse_tokens(lexer) # :nodoc:
127
131
  r_exps = []
128
- loop {
129
- token = lexer.next
130
- if token.type == :lparen
131
- i_exp = parse_compound(lexer)
132
- r_exps << translate(i_exp)
133
- else
134
- r_exps << parse_primitive(token)
135
- end
136
- }
132
+ loop { r_exps << parse_s_exp(lexer) }
137
133
  r_exps.join("\n")
138
134
  end
139
135
 
136
+ def parse_s_exp(lexer)
137
+ r_exp = nil
138
+ token = lexer.next
139
+ case token.type
140
+ when :lparen
141
+ i_exp = parse_compound(lexer)
142
+ r_exp = translate(i_exp)
143
+ when :vec_lparen
144
+ r_exp = parse_vector(lexer)
145
+ else
146
+ r_exp = parse_primitive(token)
147
+ end
148
+ r_exp
149
+ end
150
+
140
151
  def parse_primitive(token)
141
152
  r_exp = nil
142
153
  case token.type
@@ -153,6 +164,30 @@ module Rus3::Parser
153
164
  r_exp
154
165
  end
155
166
 
167
+ def parse_vector(lexer)
168
+ r_exp = "vector("
169
+ Kernel.loop {
170
+ token = lexer.peek
171
+ case token.type
172
+ when :lparen
173
+ lexer.next
174
+ i_exp = parse_compound(lexer)
175
+ r_exp += translate(i_exp)
176
+ when :vec_lparen
177
+ lexer.next
178
+ r_exp += parse_vector(lexer)
179
+ when :rparen
180
+ lexer.next
181
+ r_exp = r_exp.sub(/,\s*\Z/, "") + ")"
182
+ break
183
+ else
184
+ r_exp += parse_s_exp(lexer)
185
+ end
186
+ r_exp += ", "
187
+ }
188
+ r_exp
189
+ end
190
+
156
191
  def parse_compound(lexer)
157
192
  i_exp = []
158
193
  Kernel.loop {
@@ -11,12 +11,13 @@ module Rus3::Procedure
11
11
 
12
12
  module List
13
13
 
14
+ include Utils
14
15
  include Predicate
15
16
  include Rus3::EmptyList
16
17
 
17
18
  # Constructs a Pair object with arguments.
18
19
  #
19
- # - R5RS procedure: (cons obj1 obj2)
20
+ # - procedure (R5RS): (cons obj1 obj2)
20
21
 
21
22
  def cons(obj1, obj2)
22
23
  case obj2
@@ -36,7 +37,7 @@ module Rus3::Procedure
36
37
  # Returns the CAR part of the argument. If the arguemnt is not
37
38
  # a pair, raises PairRequiredError.
38
39
  #
39
- # - R5RS procedure: (car pair)
40
+ # - procedure (R5RS): (car pair)
40
41
 
41
42
  def car(pair)
42
43
  case pair
@@ -53,7 +54,7 @@ module Rus3::Procedure
53
54
  # Returns the CDR part of the argument. If the arguemnt is not
54
55
  # a pair, raises PairRequiredError.
55
56
  #
56
- # - R5RS procedure: (cdr pair)
57
+ # - procedure (R5RS): (cdr pair)
57
58
 
58
59
  def cdr(pair)
59
60
  case pair
@@ -70,7 +71,7 @@ module Rus3::Procedure
70
71
  # Replaces the CAR part with the 2nd argument and returns UNDEF.
71
72
  # If the 1st arguemnt is not a pair, raises PairRequiredError.
72
73
  #
73
- # - R5RS procedure: (set-car! pair obj)
74
+ # - procedure (R5RS): (set-car! pair obj)
74
75
 
75
76
  def set_car!(pair, obj)
76
77
  case pair
@@ -87,7 +88,7 @@ module Rus3::Procedure
87
88
  # Replaces the CDR part with the 2nd argument and returns UNDEF.
88
89
  # If the 1st arguemnt is not a pair, raises PairRequiredError.
89
90
  #
90
- # - R5RS procedure: (set-cdr! pair obj)
91
+ # - procedure (R5RS): (set-cdr! pair obj)
91
92
 
92
93
  def set_cdr!(pair, obj)
93
94
  case pair
@@ -113,8 +114,8 @@ module Rus3::Procedure
113
114
 
114
115
  # Retrieves the CAR part of the CAR part of the given pair.
115
116
  #
116
- # - R5RS library procedure: (caar pair)
117
- # - R7RS procedure: (caar pair)
117
+ # - library procedure (R5RS): (caar pair)
118
+ # - procedure (R7RS): (caar pair)
118
119
 
119
120
  def caar(pair)
120
121
  car(car(pair))
@@ -122,8 +123,8 @@ module Rus3::Procedure
122
123
 
123
124
  # Retrieves the CAR part of the CDR part of the given pair.
124
125
  #
125
- # - R5RS library procedure: (cadr pair)
126
- # - R7RS procedure: (cadr pair)
126
+ # - library procedure (R5RS): (cadr pair)
127
+ # - procedure (R7RS): (cadr pair)
127
128
 
128
129
  def cadr(pair)
129
130
  car(cdr(pair))
@@ -131,8 +132,8 @@ module Rus3::Procedure
131
132
 
132
133
  # Retrieves the CDR part of the CAR part of the given pair.
133
134
  #
134
- # - R5RS library procedure: (cdar pair)
135
- # - R7RS procedure: (cdar pair)
135
+ # - library procedure (R5RS): (cdar pair)
136
+ # - procedure (R7RS): (cdar pair)
136
137
 
137
138
  def cdar(pair)
138
139
  cdr(car(pair))
@@ -140,8 +141,8 @@ module Rus3::Procedure
140
141
 
141
142
  # Retrieves the CDR part of the CDR part of the given pair.
142
143
  #
143
- # - R5RS library procedure: (cddr pair)
144
- # - R7RS procedure: (cddr pair)
144
+ # - libbrary procedure (R5RS): (cddr pair)
145
+ # - procedure (R7RS): (cddr pair)
145
146
 
146
147
  def cddr(pair)
147
148
  cdr(cdr(pair))
@@ -149,15 +150,14 @@ module Rus3::Procedure
149
150
 
150
151
  # :stopdoc:
151
152
 
152
- # - R7RS: procedure: (make-list k)
153
-
154
- # - R7RS: procedure: (make-list k fill)
153
+ # - procedure (R7RS): (make-list k)
154
+ # - procedure (R7RS): (make-list k fill)
155
155
 
156
156
  # :startdoc:
157
157
 
158
158
  # Constructs a list from arguments in its order.
159
159
  #
160
- # - R5RS library procedure: (list obj ...)
160
+ # - library procedure (R5RS): (list obj ...)
161
161
 
162
162
  def list(*objs)
163
163
  Array[*objs]
@@ -166,8 +166,8 @@ module Rus3::Procedure
166
166
  # Returns the length of the arguemnt. If the argument is not a
167
167
  # proper list, raises ListRequiredError.
168
168
  #
169
- # - R5RS library procedure: (length list)
170
- # - R7RS procedure: (length list)
169
+ # - library procedure (R5RS): (length list)
170
+ # - procedure (R7RS): (length list)
171
171
 
172
172
  def length(lst)
173
173
  check_list(lst)
@@ -177,8 +177,8 @@ module Rus3::Procedure
177
177
  # Concatenates given lists into a single list. Each argument
178
178
  # must be a proper list, otherwise raises ListRequiredError.
179
179
  #
180
- # - R5RS library procedure: (append list ...)
181
- # - R7RS procedure: (append list ...)
180
+ # - library procedure (R5RS): (append list ...)
181
+ # - procedure (R7RS): (append list ...)
182
182
 
183
183
  def append(*lists)
184
184
  lists.each { |lst|
@@ -189,8 +189,8 @@ module Rus3::Procedure
189
189
 
190
190
  # Returns a list of the same elements in reverse order.
191
191
  #
192
- # - R5RS library procedure: (reverse list)
193
- # - R7RS procedure: (reverse list)
192
+ # - library procedure (R5RS): (reverse list)
193
+ # - procedure (R7RS): (reverse list)
194
194
 
195
195
  def reverse(lst)
196
196
  check_list(lst)
@@ -199,12 +199,12 @@ module Rus3::Procedure
199
199
 
200
200
  # Returns the sublist of the arguemnt by omitting the first k
201
201
  # elements. The 2nd argument, k must be in 0..length(lst),
202
- # otherwise raises OutOfRangeError.
202
+ # otherwise raises ExceedUppeerLimitError.
203
203
  #
204
204
  # This implementation logic comes from R5RS 6.3.2.
205
205
  #
206
- # - R5RS library procedure: (list-tail list k)
207
- # - R7RS procedure: (list-tail list k)
206
+ # - library procedure (R5RS): (list-tail list k)
207
+ # - procedure (R7RS): (list-tail list k)
208
208
 
209
209
  def list_tail(lst, k)
210
210
  check_list(lst)
@@ -214,10 +214,10 @@ module Rus3::Procedure
214
214
  end
215
215
 
216
216
  # Returns kth element of the argument. k must be less than the
217
- # length of the list, otherwise, raises OutOfRangeError.
217
+ # length of the list, otherwise, raises ExceedUppeerLimitError.
218
218
  #
219
- # - R5RS library procedure: (list-ref list k)
220
- # - R7RS procedure: (list-ref list k)
219
+ # - library procedure (R5RS): (list-ref list k)
220
+ # - procedure (R7RS): (list-ref list k)
221
221
 
222
222
  def list_ref(lst, k)
223
223
  check_list(lst)
@@ -228,62 +228,45 @@ module Rus3::Procedure
228
228
 
229
229
  # :stopdoc:
230
230
 
231
- # - R7RS procedure: (list-set! list k obj)
231
+ # - procedure (R7RS): (list-set! list k obj)
232
232
 
233
233
  # :startdoc:
234
234
 
235
235
  # :stopdpc:
236
236
 
237
- # - R5RS library procedure: (memq obj list)
238
- # - R7RS procedure: (memq obj list)
237
+ # - library procedure (R5RS): (memq obj list)
238
+ # - procedure (R7RS): (memq obj list)
239
239
 
240
- # - R5RS library procedure: (memv obj list)
241
- # - R7RS procedure: (memv obj list)
240
+ # - library procedure (R5RS): (memv obj list)
241
+ # - procedure (R7RS): (memv obj list)
242
242
 
243
- # - R5RS library procedure: (member obj list)
244
- # - R7RS procedure: (member obj list)
243
+ # - library procedure (R5RS): (member obj list)
244
+ # - procedure (R7RS): (member obj list)
245
245
 
246
- # - R7RS procedure: (member obj list compare)
246
+ # - procedure (R7RS): (member obj list compare)
247
247
 
248
248
  # :startdoc:
249
249
 
250
250
  # :stopdpc:
251
251
 
252
- # - R5RS library procedure: (assq obj alist)
253
- # - R7RS procedure: (assq obj alist)
252
+ # - library procedure (R5RS): (assq obj alist)
253
+ # - procedure (R7RS): (assq obj alist)
254
254
 
255
- # - R5RS library procedure: (assv obj alist)
256
- # - R7RS procedure: (assv obj alist)
255
+ # - library procedure (R5RS): (assv obj alist)
256
+ # - procedure (R7RS): (assv obj alist)
257
257
 
258
- # - R5RS library procedure: (assoc obj alist)
259
- # - R7RS procedure: (assoc obj alist)
258
+ # - library procedure (R5RS): (assoc obj alist)
259
+ # - procedure (R7RS): (assoc obj alist)
260
260
 
261
- # - R7RS procedure: (assoc obj alist compare)
261
+ # - procedure (R7RS): (assoc obj alist compare)
262
262
 
263
263
  # :startdoc:
264
264
 
265
265
  # :stopdoc:
266
266
 
267
- # - R7RS procedure: (list-copy obj)
267
+ # - procedure (R7RS): (list-copy obj)
268
268
 
269
269
  # :startdoc:
270
270
 
271
- private
272
-
273
- def check_pair(pair) # :nodoc:
274
- if !pair.instance_of?(Rus3::Pair) and !pair.instance_of?(Array)
275
- raise Rus3::PairRequiredError, pair
276
- end
277
- end
278
-
279
- def check_list(lst) # :nodoc:
280
- raise Rus3::ListRequiredError, lst unless list?(lst)
281
- end
282
-
283
- # To make sure the number is less than its upper limit.
284
- def check_upper_limit(k, limit) # :nodoc:
285
- raise Rus3::OutOfRangeError, k if k >= limit
286
- end
287
-
288
271
  end
289
272
  end
@@ -44,12 +44,12 @@ module Rus3::Procedure
44
44
  # provides some classes for the rest of them.
45
45
  #
46
46
  # boolean? ---> FalseClass or TrueClass
47
- # pair? ------> Rus3::Pair
47
+ # pair? ------> Array (as a list) or Rus3::Pair (as a dotted pair)
48
48
  # symbol? ----> Symbol
49
49
  # number? ----> Numeric
50
50
  # char? ------> Rus3::Char
51
51
  # string? ----> String
52
- # vector? ----> Array
52
+ # vector? ----> Rus3::Vector
53
53
  # port? ------> Rus3::Port
54
54
  # procedure? -> Proc
55
55
 
@@ -64,11 +64,11 @@ module Rus3::Procedure
64
64
  end
65
65
 
66
66
  def symbol?(obj)
67
- obj.is_a?(Symbol) && obj != Rus3::UNDEF
67
+ obj.instance_of?(Symbol) && obj != Rus3::UNDEF
68
68
  end
69
69
 
70
70
  def number?(obj)
71
- obj.is_a?(Numeric)
71
+ obj.kind_of?(Numeric)
72
72
  end
73
73
 
74
74
  def char?(obj)
@@ -79,8 +79,9 @@ module Rus3::Procedure
79
79
  obj.kind_of?(String)
80
80
  end
81
81
 
82
+ # procedure (R5RS/R7RS): (vector? obj)
82
83
  def vector?(obj)
83
- false
84
+ obj.instance_of?(Rus3::Vector)
84
85
  end
85
86
 
86
87
  def port?(obj)
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rus3::Procedure
4
+ module Utils
5
+
6
+ def check_pair(pair) # :nodoc:
7
+ if !pair.instance_of?(Rus3::Pair) and !pair.instance_of?(Array)
8
+ raise Rus3::PairRequiredError, pair
9
+ end
10
+ end
11
+
12
+ def check_list(lst) # :nodoc:
13
+ raise Rus3::ListRequiredError, lst unless list?(lst)
14
+ end
15
+
16
+ def check_vector(obj) # :nodoc:
17
+ raise Rus3::VectorRequiredError, obj unless vector?(obj)
18
+ end
19
+
20
+ # To make sure the number is less than its upper limit. When k
21
+ # greater than or equal to limit, raises ExceedUpperLimitError.
22
+
23
+ def check_upper_limit(k, limit)
24
+ raise Rus3::ExceedUpperLimitError.new(k, limit) if k >= limit
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rus3::Procedure
4
+
5
+ # Provides procedures to operate a vector.
6
+
7
+ module Vector
8
+
9
+ include Utils
10
+ include List
11
+ include Predicate
12
+ include Rus3::EmptyList
13
+
14
+ UNDEF = Rus3::UNDEF
15
+
16
+ # - procedure (R5RS/R7RS): (make-vector k) or (make-vector k fill)
17
+
18
+ def make_vector(k, fill = UNDEF)
19
+ Rus3::Vector.new(k, fill)
20
+ end
21
+
22
+ # - library procedure (R5RS/R7RS): (vector obj ...)
23
+
24
+ def vector(*objs)
25
+ Rus3::Vector.vector(*objs)
26
+ end
27
+
28
+ # - procedure (R5RS/R7RS): (vector-length vector)
29
+
30
+ def vector_length(vec)
31
+ check_vector(vec)
32
+ vec.length
33
+ end
34
+
35
+ # - procedure (R5RS/R7RS): (vector-ref vector, k)
36
+
37
+ def vector_ref(vec, k)
38
+ check_vector(vec)
39
+ check_upper_limit(k, vec.length)
40
+ vec.ref(k)
41
+ end
42
+
43
+ # - procedure (R5RS/R7RS): (vector-set! vector k obj)
44
+
45
+ def vector_set!(vec, k, obj)
46
+ check_vector(vec)
47
+ Rus3::Vector.vector_set!(vec, k, obj)
48
+ end
49
+
50
+ # - library procedure (R5RS): (vector->list vector)
51
+ # - procedure (R7RS):
52
+ # (vector->list vector)
53
+ # (vector->list vector start)
54
+ # (vector->list vector start end)
55
+
56
+ def vector_to_list(vec, start_index = 0, end_index = -1)
57
+ end_index = vec.length if end_index == -1
58
+
59
+ check_vector(vec)
60
+ check_limits(start_index, end_index, vec.length)
61
+
62
+ list(*vec.ref(start_index...end_index))
63
+ end
64
+
65
+ # - library procedure (R5RS): (list->vector list)
66
+ # - procedre (R7RS): (list->vector list)
67
+
68
+ def list_to_vector(lst)
69
+ Rus3::Vector.list_to_vector(lst)
70
+ end
71
+
72
+ # - library procedure (R5RS): (vector-fill! vector fill)
73
+ # - procedure (R7RS): (vector-fill! vector fill start end)
74
+
75
+ def vector_fill!(vec, fill, start_index = 0, end_index = -1)
76
+ end_index = vec.length if end_index == -1
77
+
78
+ check_vector(vec)
79
+ check_limits(start_index, end_index, vec.length)
80
+
81
+ start_index.upto(end_index - 1) {|i| vec.set!(i, fill)}
82
+ end
83
+
84
+ # :stopdoc:
85
+
86
+ private
87
+
88
+ # Makes sure that start_index < end_index <= limit.
89
+ def check_limits(start_index, end_index, limit)
90
+ check_upper_limit(start_index, limit)
91
+ check_upper_limit(start_index, end_index)
92
+ check_upper_limit(end_index, limit + 1)
93
+ end
94
+
95
+ # :startdoc:
96
+
97
+ end
98
+ end
data/lib/rus3/repl.rb CHANGED
@@ -97,7 +97,9 @@ module Rus3
97
97
  # Shows the greeting message.
98
98
  def greeting
99
99
  puts "A simple REPL for Rus3:"
100
- puts "- Rus3 version: #{Rus3::VERSION}"
100
+ puts "- Rus3 version: #{Rus3::VERSION} (#{Rus3::RELEASE})"
101
+ return unless @verbose
102
+
101
103
  puts " - REPL version: #{VERSION}"
102
104
  COMPONENTS.keys.each { |comp_name|
103
105
  Kernel.print " - "
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+
5
+ module Rus3
6
+
7
+ # A class to represent a vector structure of Scheme.
8
+
9
+ class Vector
10
+ extend Forwardable
11
+
12
+ class << self
13
+ # Returns a new Vector instance which elements are the given objs.
14
+ def vector(*objs)
15
+ list_to_vector(objs)
16
+ end
17
+
18
+ # Converts a list into a new Vector instance.
19
+ def list_to_vector(lst)
20
+ vec = self.new(lst.size)
21
+ lst.each_with_index {|e, i| vec.set!(i, e)}
22
+ vec
23
+ end
24
+
25
+ # Converts a Vector instance into a list.
26
+ def vector_to_list(vec)
27
+ vec.to_a
28
+ end
29
+
30
+ # Replaces the k-th element of the given vector with obj.
31
+ def vector_set!(vec, k, obj)
32
+ raise ExceedUpperLimitError.new(k, vec.length) if k >= vec.length
33
+ vec.set!(k, obj)
34
+ end
35
+
36
+ end
37
+
38
+ def initialize(k, fill = UNDEF)
39
+ @content = Array.new(k, fill)
40
+ end
41
+
42
+ def_delegator :@content, :[], :ref
43
+ def_delegator :@content, :[]=, :set!
44
+ def_delegator :@content, :size, :length
45
+
46
+ # Returns an Array instance which contains the vector contents.
47
+ def to_a
48
+ @content.dup
49
+ end
50
+
51
+ # Converts a string represents as a Scheme vector.
52
+ def to_s
53
+ "#(#{@content.join(' ')})"
54
+ end
55
+
56
+ end
57
+ end
data/lib/rus3/version.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rus3
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
+ RELEASE = "2021-04-22"
5
6
  end
data/rus3.gemspec CHANGED
@@ -11,6 +11,7 @@ Gem::Specification.new do |spec|
11
11
  spec.summary = "Ruby with Syntax Sugar of Scheme"
12
12
  spec.description = "Ruby with Syntax Sugar of Scheme"
13
13
  spec.homepage = "https://github.com/mnbi/rus3"
14
+ spec.license = "MIT"
14
15
  spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
15
16
 
16
17
  spec.metadata["homepage_uri"] = spec.homepage
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rus3
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - mnbi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-04-21 00:00:00.000000000 Z
11
+ date: 2021-04-22 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Ruby with Syntax Sugar of Scheme
14
14
  email:
@@ -45,12 +45,16 @@ files:
45
45
  - lib/rus3/procedure/control.rb
46
46
  - lib/rus3/procedure/list.rb
47
47
  - lib/rus3/procedure/predicate.rb
48
+ - lib/rus3/procedure/utils.rb
49
+ - lib/rus3/procedure/vector.rb
48
50
  - lib/rus3/procedure/write.rb
49
51
  - lib/rus3/repl.rb
52
+ - lib/rus3/vector.rb
50
53
  - lib/rus3/version.rb
51
54
  - rus3.gemspec
52
55
  homepage: https://github.com/mnbi/rus3
53
- licenses: []
56
+ licenses:
57
+ - MIT
54
58
  metadata:
55
59
  homepage_uri: https://github.com/mnbi/rus3
56
60
  source_code_uri: https://github.com/mnbi/rus3