rubasteme 0.1.0 → 0.1.5

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: 7318849fdcbcfd2daa359998f303bba5c27429bce2a36f06e9beddf05d26ba8a
4
- data.tar.gz: 0037b93486d56d45c125ec47aa5417de6f61dbb6519679154974ac039206a738
3
+ metadata.gz: 55b3523ac9cea424c63244acb962f5a8c282515339cbf957ff34bd691ff3d5ef
4
+ data.tar.gz: 25f8653c598ac0cb61d3fd3c8277548f4b0ea033bc4d2fdb37fbab81efd8642f
5
5
  SHA512:
6
- metadata.gz: 10e44958db29f64d4b17e0db107756e8952393941b7305f9b32adf79b5f71ca18faa234d99cf24ceb5d6da6023e4855260998d16c50d105d002645d80231aa15
7
- data.tar.gz: 7abdcb827afb2cbbe428e1ac59167d98f21c07ab83046e212cd48af734cc4245f32de39f7b36741f46a740f8787e1b08c981f91dce62154070704140ff0f463c
6
+ metadata.gz: 0b35c5f9339f74b843a2d19977fb1a5e08e0e018b59b699bd4d58f88ee7d541f24be08054bd5d5e96e48c9bfcf5995e441df330cbbe33e7990ee61e7824c6e70
7
+ data.tar.gz: 531caab37c793ebcef980fe0f146158871c374a47e6eca90778d7bba05de3d6834d51f4d169f8f13b6b9c96ab7a9129b7ee60658116005080afb2fccd074176e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  ## [Unreleased]
2
2
  - (nothing to record here)
3
3
 
4
+ ## [0.1.5] - 2021-06-09
5
+ ### Added
6
+ - Add a new node to represent `case` expression and its parsing.
7
+
8
+ ### Changed
9
+ - Refactor parser to parse in 2 phases.
10
+
11
+ ### Fixed
12
+ - Fix #5: incorrect parsing with internal definition at wrong
13
+ position.
14
+
15
+ ## [0.1.4] - 2021-05-31
16
+ ### Added
17
+ - Add a new node to represent sequence. (#3)
18
+ - Incorporate missing methods to ListNode from rbsiev project.
19
+
20
+ ### Fixed
21
+ - Fix #2: typo in the version string.
22
+
23
+ ## [0.1.3] - 2021-05-20
24
+ ### Fixed
25
+ - Change a method name of AST::CondNode.
26
+ - `#cond_clause` -> `#cond_clauses`
27
+ - Modify the timing to pass lexer to parser in `exe/rubasteme`.
28
+ - Fix #1: `:ast_vector` is missing in AST::AST_NODE_TYPE.
29
+
30
+ ## [0.1.2] - 2021-05-20
31
+ ### Added
32
+ - Add a singleton method, `version` to Parser class.
33
+
34
+ ## [0.1.1] - 2021-05-20
35
+ ### Changed
36
+ - Change the timing to pass a lexer instance to a Parser object:
37
+ - 0.1.0: initialize Parser object,
38
+ - `Parser.new(lexer)`
39
+ - 0.1.1: call parser method.
40
+ - `parser = Parser.new; parser.parse(lexer)`
41
+
4
42
  ## [0.1.0] - 2021-05-20
5
43
  - Initial release
data/examples/mini_rus3 CHANGED
@@ -47,9 +47,25 @@ class Evaluator
47
47
  @env.receiver.instance_eval("def #{proc_name}(op1, op2); op1 #{op} op2; end")
48
48
  }
49
49
  @env.receiver.instance_eval {
50
+ def list(*objs)
51
+ objs
52
+ end
53
+
54
+ def append(*lists)
55
+ if lists.empty?
56
+ []
57
+ else
58
+ lists[0] + append(*lists[1..-1])
59
+ end
60
+ end
61
+
50
62
  def display(obj)
51
63
  pp obj
52
64
  end
65
+
66
+ def zero?(obj)
67
+ obj == 0
68
+ end
53
69
  }
54
70
  end
55
71
 
@@ -74,7 +90,7 @@ class Evaluator
74
90
  def translate(ast_node)
75
91
  case ast_node.type
76
92
  when :ast_empty_list
77
- ast_node.literal
93
+ "[]"
78
94
  when :ast_boolean
79
95
  (ast_node.literal[1] == "f") ? "false" : "true"
80
96
  when :ast_identifier
@@ -82,7 +98,13 @@ class Evaluator
82
98
  when :ast_string
83
99
  ast_node.literal
84
100
  when :ast_number
85
- ast_node.literal
101
+ case ast_node.literal
102
+ when /([^\/]+)\/([^\/]+)/
103
+ md = Regexp.last_match
104
+ "Rational(#{md[1]}, #{md[2]})"
105
+ else
106
+ ast_node.literal
107
+ end
86
108
  when :ast_procedure_call
87
109
  translate_procedure_call(ast_node)
88
110
  when :ast_lambda_expression
@@ -133,7 +155,7 @@ class Evaluator
133
155
 
134
156
  def translate_lambda_expression(ast_node)
135
157
  formals = ast_node.formals.map{|e| translate(e)}.join(",")
136
- body = ast_node.body.map{|e| translate(e)}.join("; ")
158
+ body = ast_node.body.sequence.map{|e| translate(e)}.join("; ")
137
159
  "lambda{|#{formals}|#{body}}"
138
160
  end
139
161
 
@@ -150,10 +172,15 @@ class Evaluator
150
172
  def translate_identifier_definition(ast_node)
151
173
  name = translate(ast_node.identifier)
152
174
  if ast_node.expression.type == :ast_lambda_expression
175
+ src = ""
153
176
  node = ast_node.expression
154
177
  formals = node.formals.map{|e| translate(e)}.join(", ")
155
- body = node.body.map{|e| translate(e)}.join("; ")
156
- "def #{name}(#{formals}); #{body}; end"
178
+ unless node.body.definitions.empty?
179
+ src += node.body.definitions.map{|e| translate(e)}.join("; ")
180
+ src += "; "
181
+ end
182
+ body = node.body.sequence.map{|e| translate(e)}.join("; ")
183
+ src + "def #{name}(#{formals}); #{body}; end"
157
184
  else
158
185
  value = translate(ast_node.expression)
159
186
  "#{name} = #{value}"
@@ -162,6 +189,7 @@ class Evaluator
162
189
 
163
190
  end
164
191
 
192
+ parser = Rubasteme.parser
165
193
  evaluator = Evaluator.new
166
194
 
167
195
  require "readline"
@@ -183,8 +211,7 @@ msg = loop {
183
211
  end
184
212
 
185
213
  lexer = Rbscmlex::Lexer.new(source, form: :token)
186
- parser = Rubasteme.parser(lexer)
187
- ast_program = parser.parse
214
+ ast_program = parser.parse(lexer)
188
215
 
189
216
  result = evaluator.eval(ast_program)
190
217
 
@@ -25,6 +25,7 @@ module SicpScheme
25
25
 
26
26
  def self.repl(prompt)
27
27
  env = TOPLEVEL_ENV
28
+ parser = Rubasteme.parser
28
29
  evaluator = Evaluator.new
29
30
  printer = Printer.new
30
31
 
@@ -44,8 +45,7 @@ module SicpScheme
44
45
  end
45
46
 
46
47
  lexer = Rbscmlex::Lexer.new(source, form: :token)
47
- parser = Rubasteme.parser(lexer)
48
- exp = parser.parse.to_a
48
+ exp = parser.parse(lexer).to_a
49
49
 
50
50
  result = evaluator.eval(exp, env)
51
51
 
@@ -43,6 +43,9 @@ module SicpScheme
43
43
  when *EV_IF
44
44
  eval_if(exp, env)
45
45
  when *EV_LAMBDA
46
+ internal_definitions(exp).each { |d|
47
+ eval_definition(d, env)
48
+ }
46
49
  make_procedure(lambda_parameters(exp),
47
50
  lambda_body(exp),
48
51
  env)
@@ -199,8 +202,9 @@ module SicpScheme
199
202
  end
200
203
 
201
204
  def begin_actions(exp)
202
- # exp = [:ast_begin, [:ast_*_1], [:ast_*_2], ... ]
203
- exp[1..-1]
205
+ # exp = [:ast_begin, [:ast_sequence]]
206
+ # sequence = [:ast_sequence, [:ast_*_1], [:ast_*_2], ...]
207
+ exp[1][1..-1]
204
208
  end
205
209
 
206
210
  def eval_sequence(exps, env)
@@ -241,15 +245,24 @@ module SicpScheme
241
245
  exp[2]
242
246
  end
243
247
 
248
+ def internal_definitions(exp)
249
+ # exp = [:ast_lambda_expression, [:ast_formals], [:ast_body]]
250
+ # body = [:ast_body, [:ast_internal_definitions], [:ast_sequence]]
251
+ # internal_definitions = [:ast_intern_definitions, [:ast_definition], ...]
252
+ exp[2][1][1..-1]
253
+ end
254
+
244
255
  def lambda_parameters(exp)
245
- # exp = [:ast_lambda_expression, [:ast_formals], [:ast_*_1] ...]
256
+ # exp = [:ast_lambda_expression, [:ast_formals], [:ast_body]]
246
257
  formals = exp[1][1..-1]
247
258
  formals.map{|node| identifier(node)}
248
259
  end
249
260
 
250
261
  def lambda_body(exp)
251
- # exp = [:ast_lambda_expression, [:ast_formals], [:ast_*_1] ...]
252
- exp[2..-1]
262
+ # exp = [:ast_lambda_expression, [:ast_formals], [:ast_body]]
263
+ # body = [:ast_body, [:ast_internal_definitions], [:ast_sequence]]
264
+ # sequence = [:ast_sequence, [:ast_*_1], [:ast_*_2], ...]
265
+ exp[2][2][1..-1]
253
266
  end
254
267
 
255
268
  def make_procedure(parameters, body, env)
data/exe/rubasteme CHANGED
@@ -73,8 +73,8 @@ end
73
73
 
74
74
  tokens = lines.map{|e| Kernel.eval(e)}
75
75
  lexer = Rubasteme.lexer(tokens)
76
- parser = Rubasteme.parser(lexer)
77
- ast = parser.parse
76
+ parser = Rubasteme.parser
77
+ ast = parser.parse(lexer)
78
78
 
79
79
  output = ""
80
80
  PP.pp(ast.to_a, output)
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rbscmlex
4
+
5
+ # :stopdoc:
6
+ EMSG = {
7
+ unexpected_token_type: "unexpected token type: got=%s, expected=%s",
8
+ missing_right_parenthesis: "missing right parenthesis",
9
+ }
10
+ # :startdoc:
11
+
12
+ # Indicates a token is not expected one.
13
+ class UnexpectedTokenTypeError < Error
14
+ def initialize(got, expected = nil)
15
+ super(EMSG[:unexpected_token_type] % [got, expected])
16
+ end
17
+ end
18
+
19
+ # Indicates a mismatch of parenthesizes.
20
+ class MissingRightParenthesisError < Error
21
+ def initialize
22
+ super(EMSG[:missing_right_parenthesis])
23
+ end
24
+ end
25
+
26
+ class Lexer
27
+
28
+ def skip_lparen(offset = 0)
29
+ if peek_token(offset).type == :lparen
30
+ skip_token(offset)
31
+ else
32
+ raise UnexpectedTokenTypeError.new(peek_token(offset).type, :lparen)
33
+ end
34
+ end
35
+
36
+ def skip_rparen(offset = 0)
37
+ if peek_token(offset).type == :rparen
38
+ skip_token(offset)
39
+ else
40
+ raise MissingRightParenthesisError
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+ end
data/lib/rubasteme.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "rbscmlex"
4
+ require_relative "rbscmlex/missing"
4
5
 
5
6
  module Rubasteme
6
7
 
@@ -8,6 +9,10 @@ module Rubasteme
8
9
  Rbscmlex::Lexer.new(obj)
9
10
  end
10
11
 
12
+ def self.parse(source)
13
+ parser.parse(lexer(source))
14
+ end
15
+
11
16
  require_relative "rubasteme/error"
12
17
  require_relative "rubasteme/utils"
13
18
  require_relative "rubasteme/ast"
data/lib/rubasteme/ast.rb CHANGED
@@ -19,17 +19,27 @@ module Rubasteme
19
19
  :ast_dot,
20
20
  # branch
21
21
  :ast_program,
22
+ :ast_vector,
22
23
  :ast_list,
23
24
  :ast_quotation,
24
25
  :ast_procedure_call,
25
26
  :ast_lambda_expression,
26
27
  :ast_formals,
28
+ :ast_body,
29
+ :ast_internal_definitions,
30
+ :ast_sequence,
27
31
  :ast_conditional,
28
32
  :ast_assignment,
29
33
  :ast_identifier_definition,
30
34
  :ast_cond,
31
35
  :ast_cond_clause,
36
+ :ast_cond_recipient_clause,
37
+ :ast_else_clause,
32
38
  :ast_case,
39
+ :ast_case_clause,
40
+ :ast_data,
41
+ :ast_case_recipient_clause,
42
+ :ast_else_recipient_clause,
33
43
  :ast_and,
34
44
  :ast_or,
35
45
  :ast_when,
@@ -49,7 +59,7 @@ module Rubasteme
49
59
  :ast_illegal,
50
60
  ]
51
61
 
52
- def self.instantiate(ast_node_type, literal)
62
+ def self.instantiate(ast_node_type, literal = nil)
53
63
  type_name = Utils.camel_case(ast_node_type.to_s.delete_prefix("ast_"))
54
64
  klass = AST.const_get("#{type_name}Node")
55
65
 
@@ -55,21 +55,37 @@ module Rubasteme
55
55
  end
56
56
 
57
57
  class ListNode < BranchNode
58
- def initialize(_ = nil)
59
- super(nil)
58
+ def initialize(initial_size = 0, _ = nil)
59
+ super(initial_size)
60
+ end
61
+
62
+ def empty?
63
+ @nodes.empty?
64
+ end
65
+
66
+ def first
67
+ @nodes[0]
68
+ end
69
+
70
+ def rest
71
+ @nodes[1..-1]
72
+ end
73
+
74
+ def elements
75
+ @nodes
60
76
  end
61
77
  end
62
78
 
63
79
  class QuotationNode < ListNode
64
80
  def initialize(_ = nil)
65
- super(nil)
81
+ super(0, nil)
66
82
  end
67
83
  end
68
84
 
69
85
  class ProcedureCallNode < ListNode
70
86
  def initialize(_ = nil)
71
87
  # @nodes = [<operator>, <operand>*]
72
- super(1)
88
+ super(1, _)
73
89
  end
74
90
 
75
91
  def operator
@@ -91,8 +107,8 @@ module Rubasteme
91
107
 
92
108
  class LambdaExpressionNode < ListNode
93
109
  def initialize(_ = nil)
94
- # @nodes = [<formals>, <body>, ...]
95
- super(1)
110
+ # @nodes = [<formals>, <body>]
111
+ super(2, _)
96
112
  end
97
113
 
98
114
  def formals
@@ -104,20 +120,18 @@ module Rubasteme
104
120
  end
105
121
 
106
122
  def body
107
- @nodes[1..-1]
123
+ @nodes[1]
108
124
  end
109
125
 
110
- def body=(nodes)
111
- nodes.each_with_index { |node, i|
112
- @nodes[i + 1] = node
113
- }
126
+ def body=(node)
127
+ @nodes[1] = node
114
128
  end
115
129
  end
116
130
 
117
131
  class FormalsNode < ListNode
118
132
  def initialize(_ = nil)
119
133
  # @nodes = [<identifier 1>, <identifier 2>, ... ]
120
- super(nil)
134
+ super(0, nil)
121
135
  end
122
136
 
123
137
  def add_identifier(node)
@@ -125,11 +139,64 @@ module Rubasteme
125
139
  end
126
140
  end
127
141
 
142
+ class HoldingSequenceBaseNode < ListNode
143
+ def initialize(initial_size = 0, sequence_pos = 0, _ = nil)
144
+ # @nodes = [..., <sequence>, ...]
145
+ super(initial_size, _)
146
+ @sequence_pos = sequence_pos
147
+ end
148
+
149
+ def sequence
150
+ @nodes[@sequence_pos]
151
+ end
152
+
153
+ def sequence=(node)
154
+ @nodes[@sequence_pos] = node
155
+ end
156
+ end
157
+
158
+ class BodyNode < HoldingSequenceBaseNode
159
+ def initialize(_ = nil)
160
+ # @nodes = [<definitions>, <sequence>]
161
+ super(2, 1, _)
162
+ end
163
+
164
+ def definitions
165
+ @nodes[0]
166
+ end
167
+
168
+ def definitions=(node)
169
+ @nodes[0] = node
170
+ end
171
+ end
172
+
173
+ class InternalDefinitionsNode < ListNode
174
+ def initialize(_ = nil)
175
+ # @nodes = [<definition 1>, <definition 2>, ... ]
176
+ super(0, nil)
177
+ end
178
+
179
+ def add_definition(node)
180
+ @nodes << node
181
+ end
182
+ end
183
+
184
+ class SequenceNode < ListNode
185
+ def initialize(_ = nil)
186
+ # @nodes = [<expression 1>, <expression 2>, ... ]
187
+ super(0, _)
188
+ end
189
+
190
+ def add_expression(node)
191
+ @nodes << node
192
+ end
193
+ end
194
+
128
195
  class ConditionalNode < ListNode
129
196
  def initialize(_ = nil)
130
197
  # @nodes = [<test>, <consequent>] or
131
198
  # [<test>, <consequent>, <alternate>]
132
- super(1)
199
+ super(2, _)
133
200
  end
134
201
 
135
202
  def test
@@ -164,7 +231,7 @@ module Rubasteme
164
231
  class AssignmentNode < ListNode
165
232
  def initialize(_ = nil)
166
233
  # @nodes = [<identifier>, <expression>]
167
- super(2)
234
+ super(2, _)
168
235
  end
169
236
 
170
237
  def identifier
@@ -188,7 +255,7 @@ module Rubasteme
188
255
  def initialize(_ = nil)
189
256
  # @nodes = [<identifier>, <expression>]
190
257
  # <expression> might be a lambda expression.
191
- super(2)
258
+ super(2, _)
192
259
  end
193
260
 
194
261
  def identifier
@@ -224,10 +291,10 @@ module Rubasteme
224
291
 
225
292
  class CondNode < ListNode
226
293
  def initialize(_ = nil)
227
- super(nil)
294
+ super(0, _)
228
295
  end
229
296
 
230
- def cond_clause
297
+ def cond_clauses
231
298
  @nodes[0..-1]
232
299
  end
233
300
 
@@ -236,10 +303,12 @@ module Rubasteme
236
303
  end
237
304
  end
238
305
 
239
- class CondClauseNode < ListNode
240
- # @nodes = [<test>, <sequence>]
306
+ class CondClauseNode < HoldingSequenceBaseNode
241
307
  def initialize(_ = nil)
242
- super(nil)
308
+ # type 1: @nodes = [<test>, <sequence>]
309
+ # type 2: @nodes = [<test>]
310
+ # - <sequence> is empty
311
+ super(2, 1, _)
243
312
  end
244
313
 
245
314
  def test
@@ -249,33 +318,135 @@ module Rubasteme
249
318
  def test=(node)
250
319
  @nodes[0] = node
251
320
  end
321
+ end
252
322
 
253
- def sequence
323
+ class RecipientClauseBaseNode < ListNode
324
+ def initialize(initial_size = 0, recipient_pos = 0, _ = nil)
325
+ # @nodes = [<recipient>]
326
+ # <recipient> -> <expression>
327
+ super(initial_size, _)
328
+ @recipient_pos = recipient_pos
329
+ end
330
+
331
+ def recipient
332
+ @nodes[@recipient_pos]
333
+ end
334
+
335
+ def recipient=(node)
336
+ @nodes[@recipient_pos] = node
337
+ end
338
+ end
339
+
340
+ class CondRecipientClauseNode < RecipientClauseBaseNode
341
+ def initialize(_ = nil)
342
+ # <cond clause> -> ( <test> => <recipient> )
343
+ # @nodes = [<test>, <recipient>]
344
+ super(2, 1, _)
345
+ end
346
+
347
+ def test
348
+ @nodes[0]
349
+ end
350
+
351
+ def test=(node)
352
+ @nodes[0] = node
353
+ end
354
+ end
355
+
356
+ class ElseClauseNode < HoldingSequenceBaseNode
357
+ def initialize(_ = nil)
358
+ # @nodes = [<sequence>]
359
+ super(1, 0, _)
360
+ end
361
+ end
362
+
363
+ class CaseNode < ListNode
364
+ def initialize(_ = nil)
365
+ # @nodes = [<expression>, <case caluse>, ... <else clause>]
366
+ super(1, _)
367
+ end
368
+
369
+ def expression
370
+ @nodes[0]
371
+ end
372
+
373
+ def expression=(node)
374
+ @nodes[0] = node
375
+ end
376
+
377
+ def case_clauses
254
378
  @nodes[1..-1]
255
379
  end
256
380
 
257
- def add_expression(node)
381
+ def add_clause(node)
258
382
  @nodes << node
259
383
  end
260
384
  end
261
385
 
386
+ class CaseClauseNode < HoldingSequenceBaseNode
387
+ def initialize(_ = nil)
388
+ # @nodes = [<data>, <sequence>]
389
+ super(2, 1, _)
390
+ end
391
+
392
+ def data
393
+ @nodes[0]
394
+ end
395
+
396
+ def data=(node)
397
+ @nodes[0] = node
398
+ end
399
+ end
400
+
401
+ class DataNode < ListNode
402
+ def initialize(_ = nil)
403
+ # @nodes = [<datum>, ...]
404
+ super(0, _)
405
+ end
406
+ end
407
+
408
+ class CaseRecipientClauseNode < RecipientClauseBaseNode
409
+ def initialize(_ = nil)
410
+ # ( ( <datum>* ) => <recipient> )
411
+ # @nodes = [<data>, <recipient>]
412
+ super(2, 1, _)
413
+ end
414
+
415
+ def data
416
+ @nodes[0]
417
+ end
418
+
419
+ def data=(node)
420
+ @nodes[0] = node
421
+ end
422
+ end
423
+
424
+ class ElseRecipientClauseNode < RecipientClauseBaseNode
425
+ def initialize(_ = nil)
426
+ # ( else => <recipient> )
427
+ # @nodes = [<recipient>]
428
+ super(1, 0, _)
429
+ end
430
+ end
431
+
262
432
  class AndNode < ListNode
263
433
  def initialize(_ = nil)
264
434
  # @nodes = [<test>, ...]
265
- super(nil)
435
+ super(0, _)
266
436
  end
267
437
  end
268
438
 
269
439
  class OrNode < ListNode
270
440
  def initialize(_ = nil)
271
441
  # @nodes = [<test>, ...]
272
- super(nil)
442
+ super(0, _)
273
443
  end
274
444
  end
275
445
 
276
- class TestAndSequenceNode < ListNode
446
+ class TestAndSequenceBaseNode < HoldingSequenceBaseNode
277
447
  def initialize(_ = nil)
278
- super(1)
448
+ # @nodes = [<test>, <sequence>]
449
+ super(2, 1, _)
279
450
  end
280
451
 
281
452
  def test
@@ -285,27 +456,19 @@ module Rubasteme
285
456
  def test=(node)
286
457
  @nodes[0] = node
287
458
  end
288
-
289
- def sequence
290
- @nodes[1..-1]
291
- end
292
-
293
- def add_sequence(node)
294
- @nodes << node
295
- end
296
459
  end
297
460
 
298
- class WhenNode < TestAndSequenceNode
461
+ class WhenNode < TestAndSequenceBaseNode
299
462
  end
300
463
 
301
- class UnlessNode < TestAndSequenceNode
464
+ class UnlessNode < TestAndSequenceBaseNode
302
465
  end
303
466
 
304
467
  class LetNode < ListNode
305
468
  def initialize(_ = nil)
306
- # @nodes = [<bindings>, <body>, ...] or
307
- # [<identifier>, <bindings>, <body>, ...]
308
- super(1)
469
+ # @nodes = [<bindings>, <body>] or
470
+ # [<identifier>, <bindings>, <body>]
471
+ super(1, _)
309
472
  end
310
473
 
311
474
  def identifier
@@ -329,14 +492,12 @@ module Rubasteme
329
492
  end
330
493
 
331
494
  def body
332
- named_let? ? @nodes[2..-1] : @nodes[1..-1]
495
+ named_let? ? @nodes[2] : @nodes[1]
333
496
  end
334
497
 
335
- def body=(nodes)
498
+ def body=(node)
336
499
  start_pos = named_let? ? 2 : 1
337
- nodes.each_with_index { |node, i|
338
- @nodes[start_pos + i] = node
339
- }
500
+ @nodes[start_pos] = node
340
501
  end
341
502
 
342
503
  private
@@ -348,8 +509,8 @@ module Rubasteme
348
509
 
349
510
  class LetBaseNode < ListNode
350
511
  def initialize(_ = nil)
351
- # @nodes = [<bindings>, <body>, ...]
352
- super(1)
512
+ # @nodes = [<bindings>, <body>]
513
+ super(2, _)
353
514
  end
354
515
 
355
516
  def bindings
@@ -361,13 +522,11 @@ module Rubasteme
361
522
  end
362
523
 
363
524
  def body
364
- @nodes[1..-1]
525
+ @nodes[1]
365
526
  end
366
527
 
367
- def body=(nodes)
368
- nodes.each_with_index { |node, i|
369
- @nodes[1 + i] = node
370
- }
528
+ def body=(node)
529
+ @nodes[1] = node
371
530
  end
372
531
  end
373
532
 
@@ -383,7 +542,7 @@ module Rubasteme
383
542
  class BindingsNode < ListNode
384
543
  def initialize(_ = nil)
385
544
  # @nodes = [<bind spec 1>, <bind spec 2> , ...]
386
- super(nil)
545
+ super(0, _)
387
546
  end
388
547
 
389
548
  def add_bind_spec(node)
@@ -393,7 +552,7 @@ module Rubasteme
393
552
 
394
553
  class BindSpecNode < ListNode
395
554
  def initialize(_ = nil)
396
- super(2)
555
+ super(2, _)
397
556
  end
398
557
 
399
558
  def identifier
@@ -413,16 +572,17 @@ module Rubasteme
413
572
  end
414
573
  end
415
574
 
416
- class BeginNode < ListNode
575
+ class BeginNode < HoldingSequenceBaseNode
417
576
  def initialize(_ = nil)
418
- super(nil)
577
+ # @nodes = [<sequnece>]
578
+ super(1, 0, _)
419
579
  end
420
580
  end
421
581
 
422
582
  class DoNode < ListNode
423
583
  def initialize(_ = nil)
424
584
  # @nodes = [<iteration bindings>, <test and do result>, <command>, ...]
425
- super(2)
585
+ super(2, _)
426
586
  end
427
587
 
428
588
  def iteration_bindings
@@ -452,7 +612,7 @@ module Rubasteme
452
612
 
453
613
  class IterationBindingsNode < ListNode
454
614
  def initialize(_ = nil)
455
- super(nil)
615
+ super(0, _)
456
616
  end
457
617
 
458
618
  def add_iteration_spec(node)
@@ -460,28 +620,14 @@ module Rubasteme
460
620
  end
461
621
  end
462
622
 
463
- class TestAndDoResultNode < ListNode
464
- def initialize(_ = nil)
465
- super(1)
466
- end
467
-
468
- def test
469
- @nodes[0]
470
- end
471
-
472
- def test=(node)
473
- @nodes[0] = node
474
- end
475
-
476
- def add_expression(node)
477
- @nodes << node
478
- end
623
+ class TestAndDoResultNode < TestAndSequenceBaseNode
479
624
  end
480
625
 
481
626
  class IterationSpecNode < ListNode
482
627
  def initialize(_ = nil)
483
- # @nodes = [<identifier>, <init>, <step>]
484
- super(3)
628
+ # 1. @nodes = [<identifier>, <init>, <step>]
629
+ # 2. @nodes = [<identifier>, <init>]
630
+ super(2, _)
485
631
  end
486
632
 
487
633
  def identifier