rus3 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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