rus3 0.2.0 → 0.2.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.
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Rus3
4
- module AST
5
- class Error < StandardError
6
- end
7
- end
8
- end
@@ -1,55 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Rus3
4
- module AST
5
-
6
- class LeafNode < Node
7
- def leaf?
8
- true
9
- end
10
- end
11
-
12
- class BooleanNode < LeafNode
13
- def type
14
- :boolean
15
- end
16
- end
17
-
18
- class IdentifierNode < LeafNode
19
- def type
20
- :identifier
21
- end
22
- end
23
-
24
- class PeculiarIdentifierNode < IdentifierNode
25
- def type
26
- :peculiar_identifier
27
- end
28
- end
29
-
30
- class CharacterNode < LeafNode
31
- def type
32
- :character
33
- end
34
- end
35
-
36
- class StringNode < LeafNode
37
- def type
38
- :string
39
- end
40
- end
41
-
42
- class NumberNode < LeafNode
43
- def type
44
- :number
45
- end
46
- end
47
-
48
- class DotNode < LeafNode
49
- def type
50
- :dot
51
- end
52
- end
53
-
54
- end
55
- end
data/lib/rus3/lexer.rb DELETED
@@ -1,104 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Rus3
4
-
5
- class Lexer < Enumerator
6
-
7
- # Indicates the version of the lexer class
8
- LEXER_VERSION = "0.2.0"
9
-
10
- class << self
11
-
12
- def version # :nodoc:
13
- "(scheme-lexer :version #{LEXER_VERSION})"
14
- end
15
-
16
- end
17
-
18
- # :stopdoc:
19
-
20
- BOOLEAN = /\A#(f(alse)?|t(rue)?)\Z/
21
- STRING = /\A\"[^\"]*\"\Z/
22
-
23
- # idents
24
- EXTENDED_CHARS = "!\\$%&\\*\\+\\-\\./:<=>\\?@\\^_~"
25
- IDENT_PAT = "[a-zA-Z_][a-zA-Z0-9#{EXTENDED_CHARS}]*"
26
- IDENTIFIER = Regexp.new("\\A#{IDENT_PAT}\\Z")
27
-
28
- # operators
29
- ARITHMETIC_OPS = /\A[+\-*\/%]\Z/
30
- COMPARISON_OPS = /\A([<>]=?|=)\Z/
31
-
32
- # numbers
33
- REAL_PAT = "(([1-9][0-9]*)|0)(\.[0-9]+)?"
34
- RAT_PAT = "#{REAL_PAT}\\/#{REAL_PAT}"
35
- C_REAL_PAT = "(#{REAL_PAT}|#{RAT_PAT})"
36
- C_IMAG_PAT = "#{C_REAL_PAT}"
37
- COMP_PAT = "#{C_REAL_PAT}(\\+|\\-)#{C_IMAG_PAT}i"
38
-
39
- REAL_NUM = Regexp.new("\\A[+-]?#{REAL_PAT}\\Z")
40
- RATIONAL = Regexp.new("\\A[+-]?#{RAT_PAT}\\Z")
41
- COMPLEX = Regexp.new("\\A[+-]?#{COMP_PAT}\\Z")
42
- PURE_IMAG = Regexp.new("\\A[+-](#{C_IMAG_PAT})?i\\Z")
43
-
44
- # char
45
- SINGLE_CHAR_PAT = "."
46
- SPACE_PAT = "space"
47
- NEWLINE_PAT = "newline"
48
-
49
- CHAR_PREFIX = "\#\\\\"
50
- CHAR_PAT = "(#{SINGLE_CHAR_PAT}|#{SPACE_PAT}|#{NEWLINE_PAT})"
51
- CHAR = Regexp.new("\\A#{CHAR_PREFIX}#{CHAR_PAT}\\Z")
52
-
53
- # :startdoc:
54
-
55
- class << self
56
-
57
- def new(exp, _ = nil)
58
- tokens = tokenize(exp)
59
- super(tokens.size) { |y|
60
- tokens.each { |tk|
61
- y.yield(tk)
62
- }
63
- }
64
- end
65
-
66
- S2R_MAP = { "(" => "[ ", ")" => " ] ", "'" => " ' " } # :nodoc:
67
-
68
- def tokenize(exp)
69
- source = exp.gsub(/[()']/, S2R_MAP)
70
-
71
- source.split(" ").map { |literal|
72
- case literal
73
- when "["
74
- Token.new(:lparen, literal)
75
- when "]"
76
- Token.new(:rparen, literal)
77
- when "."
78
- Token.new(:dot, literal)
79
- when "'"
80
- Token.new(:quotation, literal)
81
- when "#["
82
- Token.new(:vec_lparen, literal)
83
- when BOOLEAN
84
- Token.new(:boolean, literal)
85
- when IDENTIFIER
86
- Token.new(:identifier, literal)
87
- when CHAR
88
- Token.new(:character, literal)
89
- when STRING
90
- Token.new(:string, literal)
91
- when ARITHMETIC_OPS, COMPARISON_OPS
92
- Token.new(:op_proc, literal)
93
- when REAL_NUM, RATIONAL, COMPLEX, PURE_IMAG
94
- Token.new(:number, literal)
95
- else
96
- Token.new(:illegal, literal)
97
- end
98
- }
99
- end
100
-
101
- end
102
-
103
- end
104
- end
data/lib/rus3/parser.rb DELETED
@@ -1,87 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "readline"
4
-
5
- module Rus3
6
-
7
- module Parser
8
-
9
- # Indicates the version of the parser module.
10
- VERSION = "0.2.0"
11
-
12
- # A base class to derived a parser.
13
- class Parser
14
-
15
- # Holds a prompt string. It is intended to be set in the REPL
16
- # loop.
17
- attr_reader :prompt
18
-
19
- # Constructs the version string.
20
-
21
- def version
22
- "parser-module :version #{VERSION}"
23
- end
24
-
25
- def initialize
26
- @prompt = ""
27
- end
28
-
29
- def prompt=(str)
30
- index = str.index(">")
31
- class_name = self.class.name.split("::")[-1]
32
- parser_name = class_name.delete_suffix("Parser").downcase
33
- @prompt = str[0...index] + "(#{parser_name})" + str[index..-1]
34
- end
35
-
36
- # Reads program source from the passed IO instance, then returns
37
- # the AST (abstract syntax tree). Returns nil when reaches to
38
- # EOF.
39
-
40
- def read(io = STDIN)
41
- program_source = nil
42
- if io == STDIN
43
- program_source = Readline::readline(@prompt, true)
44
- else
45
- program_source = io.readlines(chomp: true).join(" ")
46
- end
47
- program_source.nil? ? nil : parse(program_source)
48
- end
49
-
50
- protected
51
-
52
- # Parses the passed program source, then returns the AST to be
53
- # evaluated by an evaluator. How to process depends on each
54
- # derived parser class.
55
-
56
- def parse(program_source)
57
- nil
58
- end
59
-
60
- end
61
-
62
- require_relative "parser/scheme_parser"
63
-
64
- # :stopdoc:
65
-
66
- class PassthroughParser < Parser
67
- PARSER_VERSION = "0.2.0"
68
-
69
- def version
70
- vmsg = "(pass-through-parser version: #{PARSER_VERSION})"
71
- vmsg += " #{Lexer.version}"
72
- super + " (#{vmsg})"
73
- end
74
-
75
- def parse(program_source)
76
- [Lexer.new(program_source).map {|tk| tk.to_s}]
77
- end
78
-
79
- end
80
-
81
- # :startdoc:
82
-
83
- DEFAULT_PARSER = SchemeParser # :nodoc:
84
-
85
- end
86
-
87
- end
@@ -1,657 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Rus3
4
-
5
- module Parser
6
-
7
- # A simple parser to read a s-expression for Scheme.
8
- class SchemeParser < Parser
9
-
10
- # Indicates the version of the parser class
11
- PARSER_VERSION = "0.2.0"
12
-
13
- # Constructs the version string.
14
-
15
- def version
16
- vmsg = "(scheme-parser :version #{PARSER_VERSION})"
17
- vmsg += " #{Lexer.version}"
18
- super + " (#{vmsg})"
19
- end
20
-
21
- def initialize
22
- super
23
- @lexer = nil
24
- @curr_token = @peek_token = nil
25
- end
26
-
27
- # Parses a portion of or the whole program source then returns a
28
- # AST structure.
29
-
30
- def parse(program_source)
31
- @lexer = Lexer.new(program_source)
32
- parse_program
33
- end
34
-
35
- # :stopdoc:
36
-
37
- private
38
-
39
- def next_token
40
- if @peek_token
41
- @curr_token = @peek_token
42
- @peek_token = nil
43
- else
44
- @curr_token = @lexer.next
45
- end
46
- @curr_token
47
- end
48
-
49
- def peek_token
50
- if @peek_token.nil?
51
- @peek_token = @lexer.next
52
- end
53
- @peek_token
54
- end
55
-
56
- def current_token
57
- @curr_token
58
- end
59
-
60
- def push_back_token(token)
61
- @peek_token = token
62
- end
63
-
64
- # <program> -> <expression>*
65
- def parse_program
66
- program = Rus3::AST.instantiate(:program)
67
- Kernel.loop {
68
- node = parse_expression
69
- program << node
70
- }
71
- program
72
- end
73
-
74
- TOKEN_START_DELIMITERS = [ # :nodoc:
75
- :lparen, # list: ( ... )
76
- :vec_lparen, # vector: #( ... )
77
- :bytevec_lparen, # bytevector: #u8( ... )
78
- :quotation, # quotation: '<something>
79
- :backquote, # quasiquote: `<something>
80
- :comma, # used in quasiquote
81
- :comma_at, # used in quasiquote
82
- :comment_lparen, # comment start
83
- ]
84
-
85
- def start_delimiter?(token)
86
- TOKEN_START_DELIMITERS.include?(token.type)
87
- end
88
-
89
- # <expression> -> <simple expression> | <compound expression>
90
- # <compound expression> -> <start delimiter> <expression>* <end delimiter>
91
- # <start delimiter> -> <lparen> | <vec lparen> | <bytevec lparen> |
92
- # <quotation> |
93
- # <backquote> | <comma> | <comma at> |
94
- # <comment lparen>
95
- # <end delimier> -> <rparen> | <comment_rparen>
96
- def parse_expression
97
- if start_delimiter?(peek_token)
98
- parse_compound_expression
99
- else
100
- parse_simple_expression
101
- end
102
- end
103
-
104
- # <simple expression> -> <identifier> | <self evaluating>
105
- # <self evaluating> -> <boolean> | <number> | <character> | <string>
106
- def parse_simple_expression
107
- type, literal = *next_token
108
- type = :peculiar_identifier if type == :op_proc
109
- Rus3::AST.instantiate(type, literal)
110
- end
111
-
112
- def parse_identifier
113
- Rus3::AST.instantiate(:identifier, next_token.literal)
114
- end
115
-
116
- # <compound expression> -> <quotation> |
117
- # <vector> |
118
- # <list expression>
119
- def parse_compound_expression
120
- node = nil
121
- token = peek_token
122
- case token.type
123
- when :vec_lparen
124
- node = parse_vector
125
- when :lparen
126
- node = parse_list_expression
127
- when :quotation
128
- node = parse_quotation
129
- else
130
- raise Rus3::SchemeSynaxError, token.to_a
131
- end
132
- node
133
- end
134
-
135
- # <list expression> ->
136
- # <procedure call> |
137
- # <lambda expression> |
138
- # <conditional> |
139
- # <assignment> |
140
- # <macro use> |
141
- # <macro block> |
142
- # <definition> |
143
- # <derived expression> |
144
- # <includer>
145
- def parse_list_expression
146
- node = nil
147
- next_token # read :lparen
148
- case peek_token.type
149
- when :rparen
150
- # an empty list
151
- node = Rus3::AST.instantiate(:list)
152
- next_token # skip :rparen
153
- when :identifier
154
- case peek_token.literal
155
- when "lambda" # lambda expression
156
- node = parse_lambda_expression
157
- when "if" # conditional
158
- node = parse_conditional
159
- when "set!" # assignment
160
- node = parse_assignment
161
- when "let-syntax", "letrec-syntax" # macro block
162
- node = parse_macro_block
163
- when "define", "define-syntax", "define-values", "define-record-type", "begin"
164
- node = parse_definition
165
- else
166
- node = parse_derived_expression
167
- node = parse_macro_use if node.nil?
168
- end
169
- end
170
- node || parse_procedure_call
171
- end
172
-
173
- def parse_macro_use
174
- nil
175
- end
176
-
177
- # <procedure call> -> ( <operator> <operand>* )
178
- def parse_procedure_call
179
- proc_call_node = Rus3::AST.instantiate(:procedure_call,
180
- current_token.literal)
181
- proc_call_node.operator = parse_operator
182
-
183
- Kernel.loop {
184
- if peek_token.type == :rparen
185
- next_token # skip :rparen
186
- break
187
- end
188
- proc_call_node.add_operand(parse_operand)
189
- }
190
- proc_call_node
191
- end
192
-
193
- # <operator> -> <expression>
194
- def parse_operator
195
- parse_expression
196
- end
197
-
198
- # <operand> -> <expression>
199
- def parse_operand
200
- parse_expression
201
- end
202
-
203
- # <lambda expression> -> ( lambda <formals> <body> )
204
- # <sequence> -> <command>* <expression>
205
- # <command> -> <expression>
206
- # <definition> ... see parse_definition
207
- def parse_lambda_expression
208
- lambda_node = Rus3::AST.instantiate(:lambda_expression,
209
- next_token.literal)
210
- lambda_node.formals = parse_formals
211
- lambda_node.body = read_body
212
- next_token # skip :rparen
213
- lambda_node
214
- end
215
-
216
- # <formals> -> ( <identifier>* ) | <identifier> |
217
- # ( <identifier>+ . <identifier> )
218
- def parse_formals
219
- token = next_token
220
- formals = nil
221
- if token.type == :lparen
222
- formals = Rus3::AST.instantiate(:list)
223
- Kernel.loop {
224
- if peek_token.type == :rparen
225
- next_token
226
- break
227
- end
228
- formals << Rus3::AST.instantiate(:identifier, next_token.literal)
229
- }
230
- else
231
- formals = Rus3::AST.instantiate(:identifier, token.literal)
232
- end
233
- formals
234
- end
235
-
236
- # <body> -> <definition>* <sequence>
237
- def read_body
238
- body = []
239
- Kernel.loop {
240
- break if peek_token.type == :rparen # end of <lambda expression>
241
- body << parse_expression
242
- }
243
- body
244
- end
245
-
246
- # <conditional> -> ( if <test> <consequent> <alternamte> )
247
- def parse_conditional
248
- if_node = Rus3::AST.instantiate(:conditional, next_token.literal)
249
- if_node.test = parse_test
250
- if_node.consequent = parse_consequent
251
- if peek_token.type != :rparen
252
- if_node.alternate = parse_alternate
253
- end
254
- next_token # skip :rparen
255
- if_node
256
- end
257
-
258
- # <test> -> <expression>
259
- def parse_test
260
- parse_expression
261
- end
262
-
263
- # <consequent> -> <expression>
264
- def parse_consequent
265
- parse_expression
266
- end
267
-
268
- # <alternate> -> <expression> | <empty>
269
- # <empty> -> ""
270
- def parse_alternate
271
- parse_expression
272
- end
273
-
274
- # <assignment> -> ( set! <identifier> <expression> )
275
- def parse_assignment
276
- assignment_node = Rus3::AST.instantiate(:assignment, next_token.literal)
277
- assignment_node.identifier = parse_identifier
278
- assignment_node.expression = parse_expression
279
- next_token # skip :rparen
280
- assignment_node
281
- end
282
-
283
- def parse_macro_block
284
- nil
285
- end
286
-
287
- # <definition> -> ( define <identifier> <expression> ) |
288
- # ( define ( <identifier> <def formals> ) <body> ) |
289
- # <syntax definition> |
290
- # ( define-values <formals> <body> ) |
291
- # ( define-record-type <identifier>
292
- # <constructor> <identifier> <field spec>* ) |
293
- # ( begin <definition>* )
294
- #
295
- # <def formals> -> <identifier>* |
296
- # <identifier>* . <identifier>
297
- # <constructor> -> ( <identifier> <field name>* )
298
- # <field spec> -> ( <field name> <accessor> ) |
299
- # ( <field name> <accessor> <mutator> )
300
- # <field name> -> <identifier>
301
- # <accessor> -> <identifier>
302
- # <mutator> -> <identifier>
303
- # <syntax definition> -> ( define-syntax <keyword> <transformer spec> )
304
- # <transformer spec> -> ...
305
- # :
306
- def parse_definition
307
- case peek_token.literal
308
- when "define"
309
- parse_identifier_definition
310
- when "define-syntax"
311
- nil # not implemented yet
312
- when "define-values"
313
- nil # not implemented yet
314
- when "define-record-type"
315
- nil # not implemented yet
316
- when "begin"
317
- nil # not implemented yet
318
- else
319
- raise Rus3::SchemeSynaxError, token.to_a
320
- end
321
- end
322
-
323
- # ( define <identifier> <expression> )
324
- # ( define ( <identifier> <def formals> ) <body> )
325
- #
326
- # ( define foo 3 )
327
- # ( define bar ( lambda ( x y ) ( + x y )))
328
- # ( deifne ( hoge n m ) ( * n m ))
329
-
330
- def parse_identifier_definition
331
- token = next_token # define
332
- define_node = Rus3::AST.instantiate(:identifier_definition, token.literal)
333
- case peek_token.type
334
- when :lparen
335
- next_token # skip :lparen
336
- # procedure name
337
- define_node.identifier = parse_identifier
338
-
339
- def_formals = Rus3::AST.instantiate(:list)
340
- Kernel.loop {
341
- if peek_token.type == :rparen
342
- next_token
343
- break
344
- end
345
- def_formals << parse_identifier
346
- }
347
-
348
- lambda_node = Rus3::AST.instantiate(:lambda_expression, nil)
349
- lambda_node.formals = def_formals
350
- lambda_node.body = read_body
351
- next_token # skip :rparen
352
-
353
- define_node.expression = lambda_node
354
- when :identifier
355
- define_node.identifier = parse_identifier
356
- define_node.expression = parse_expression
357
- next_token
358
- else
359
- raise Rus3::SchemeSynaxError, current_token.to_a
360
- end
361
- define_node
362
- end
363
-
364
- # <quotation> -> '<datum> | ( quote <datum> )
365
- def parse_quotation
366
- token = next_token
367
- quote_node = Rus3::AST.instantiate(:quotation, token.literal)
368
- quote_node << parse_datum
369
- quote_node
370
- end
371
-
372
- # <vetor> -> #( <datum>* )
373
- def parse_vector
374
- parse_data_to_rparen
375
- end
376
-
377
- def parse_data_to_rparen
378
- token = next_token
379
- ast_type = nil
380
- case token.type
381
- when :lparen
382
- ast_type = :list
383
- when :vec_lparen
384
- ast_type = :vector
385
- else
386
- ast_type = :list
387
- end
388
- node = Rus3::AST.instantiate(ast_type, nil)
389
- raise Rus3::SchemeSyntaxError, token.to_a unless node.branch?
390
- Kernel.loop {
391
- token = peek_token
392
- break if token.type == :rparen
393
- node << parse_datum
394
- }
395
- next_token # skip :rparen
396
- node
397
- end
398
-
399
- # <datum> -> <simple datum> | <compound datum>
400
- def parse_datum
401
- if start_delimiter?(peek_token)
402
- parse_compound_datum
403
- else
404
- parse_simple_datum
405
- end
406
- end
407
-
408
- # <simple datum> -> <boolean> | <number> | <character> |
409
- # <string> | <symbol>
410
- # <symbol> -> <identifier>
411
- #
412
- # See `parse_simple_expression`.
413
- def parse_simple_datum
414
- parse_simple_expression
415
- end
416
-
417
- # <compound datum> -> <list> | <vector> | <bytevector> | <abbreviation>
418
- # <abbreviation> -> <abbrev prefix> <datum>
419
- def parse_compound_datum
420
- case peek_token.type
421
- when :lparen
422
- parse_list
423
- when :vec_lparen
424
- parse_vector
425
- else
426
- raise Rus3::SchemeSyntaxError, peek_token.to_a
427
- end
428
- end
429
-
430
- # <list> -> ( <datum>* ) | ( <datum>+ . <datum> )
431
- def parse_list
432
- parse_data_to_rparen
433
- end
434
-
435
- DERIVED_IDENTIFIERS = [
436
- "cond", "case", "and", "or", "when", "unless",
437
- "let", "let*", "letrec", "letrec*",
438
- "let-values", "let*-values",
439
- "begin", "do",
440
- "delay", "delay-force",
441
- "parameterize",
442
- "guard",
443
- "case-lambda",
444
- ]
445
-
446
- # <derived expression> ->
447
- # ( cond <cond clause>+ ) |
448
- # ( cond <cond cluase>* ( else <sequence> ) ) |
449
- # ( case <expression> <case caluse>+ ) |
450
- # ( case <expression> <case caluse>* ( else <sequence> ) ) |
451
- # ( case <expression> <case caluse>* ( else => <recipient> ) ) |
452
- # ( and <test>* ) |
453
- # ( or <test>* ) |
454
- # ( when <test> <sequence> ) |
455
- # ( unless <test> <sequence> ) |
456
- # ( let ( <binding spec>* ) <body> ) |
457
- # ( let <identifier> ( <binding spec>* ) <body> ) |
458
- # ( let* ( <binding spec>* ) <body> ) |
459
- # ( letrec ( <binding spec>* ) <body> ) |
460
- # ( letrec* ( <binding spec>* ) <body> ) |
461
- # ( let-values ( <my binding spec>* ) <body> ) |
462
- # ( let*-values ( <my binding spec>* ) <body> ) |
463
- # ( begin <sequence> ) |
464
- # ( do ( <iteration spec>* ) ( <test> <do result> ) <command>* ) |
465
- # ( delay <expression> ) |
466
- # ( delay-force <expression> ) |
467
- # ( parameterize ( ( <expression> <expression> )* ) <body> ) |
468
- # ( guard ( <identifier> <cond clause>* ) <body> ) |
469
- # ( case-lambda <case-lambda clause>* ) |
470
- # <quasiquotation>
471
- def parse_derived_expression
472
- node = nil
473
- token = next_token
474
- if token.type == :identifier
475
- if DERIVED_IDENTIFIERS.include?(token.literal)
476
- method_name = compose_method_name("parse_", token.literal).intern
477
- method = self.method(method_name)
478
- node = method.call
479
- else
480
- node = parse_quasiquotation
481
- end
482
- end
483
- push_back_token(token) if node.nil?
484
- node
485
- end
486
-
487
- SCM_CHAR_TO_RB_MAP = {
488
- "*" => "_star",
489
- "-" => "_",
490
- }
491
-
492
- def compose_method_name(prefix, type_name)
493
- converted_name = type_name.gsub(/[*\-]/, SCM_CHAR_TO_RB_MAP)
494
- prefix + converted_name
495
- end
496
-
497
- def not_implemented_yet(feature)
498
- raise Rus3::NotImplementedYetError, feature
499
- end
500
-
501
- # ( cond <cond clause>+ )
502
- # ( cond <cond cluase>* ( else <sequence> ) )
503
- def parse_cond
504
- cond_node = Rus3::AST.instantiate(:cond, current_token.literal)
505
-
506
- Kernel.loop {
507
- if peek_token.type == :rparen
508
- next_token # skip :rparen
509
- break
510
- end
511
- cond_node.add_clause(parse_cond_clause)
512
- }
513
- cond_node
514
- end
515
-
516
- # <cond cluase> -> ( <test> <sequence> ) |
517
- # ( <test> ) |
518
- # ( <test> => <recipient> )
519
- # <test> -> <expression>
520
- # <recipient> -> <expression>
521
- # <sequence> -> <command>* <expression>
522
- # <command> -> <expression>
523
- def parse_cond_clause
524
- clause_node = Rus3::AST.instantiate(:cond_clause)
525
- next_token # skip :lparen
526
-
527
- clause_node.test = parse_test
528
-
529
- Kernel.loop {
530
- if peek_token.type == :rparen
531
- next_token
532
- break
533
- end
534
- clause_node.add_expression(parse_expression)
535
- }
536
- clause_node
537
- end
538
-
539
- def prase_test
540
- parse_expression
541
- end
542
-
543
- def parse_case
544
- not_implemented_yet("case")
545
- end
546
-
547
- def parse_and
548
- not_implemented_yet("and")
549
- end
550
-
551
- def parse_or
552
- not_implemented_yet("or")
553
- end
554
-
555
- def parse_when
556
- not_implemented_yet("when")
557
- end
558
-
559
- def parse_unless
560
- not_implemented_yet("unless")
561
- end
562
-
563
- # ( let ( <binding spec>* ) <body> ) |
564
- # <bind spec> -> ( <identifier> <expression> )
565
- #
566
- # `Named let` has not supported yet.
567
- # ( let <identifier> ( <binding spec>* ) <body> )
568
- def parse_let
569
- let_node = Rus3::AST.instantiate(:let, current_token.literal)
570
-
571
- let_node.bind_specs = parse_bind_specs
572
- let_node.body = read_body
573
- next_token # skip :rparen
574
-
575
- let_node
576
- end
577
-
578
- def parse_bind_specs
579
- specs_node = Rus3::AST.instantiate(:list)
580
- next_token # skip :lparen
581
-
582
- Kernel.loop {
583
- if peek_token.type == :rparen
584
- next_token # skip :rparen
585
- break
586
- end
587
- specs_node << parse_bind_spec
588
- }
589
- specs_node
590
- end
591
-
592
- def parse_bind_spec
593
- spec_node = Rus3::AST::instantiate(:bind_spec)
594
- next_token # skip :lpraren
595
- spec_node.identifier = parse_identifier
596
- spec_node.expression = parse_expression
597
- next_token # skip :rparen
598
- spec_node
599
- end
600
-
601
- def parse_let_star
602
- not_implemented_yet("let*")
603
- end
604
-
605
- def parse_letrec
606
- not_implemented_yet("letrec")
607
- end
608
-
609
- def parse_letrec_star
610
- not_implemented_yet("letrec*")
611
- end
612
-
613
- def parse_let_values
614
- not_implemented_yet("let-values")
615
- end
616
-
617
- def parse_let_star_values
618
- not_implemented_yet("let*-values")
619
- end
620
-
621
- def parse_begin
622
- not_implemented_yet("begin")
623
- end
624
-
625
- def parse_do
626
- not_implemented_yet("do")
627
- end
628
-
629
- def parse_delay
630
- not_implemented_yet("delay")
631
- end
632
-
633
- def parse_delay_force
634
- not_implemented_yet("delay-force")
635
- end
636
-
637
- def parse_parameterize
638
- not_implemented_yet("parameterize")
639
- end
640
-
641
- def parse_guard
642
- not_implemented_yet("guard")
643
- end
644
-
645
- def parse_case_lambda
646
- not_implemented_yet("case-lambda")
647
- end
648
-
649
- def parse_quasiquotation
650
- nil
651
- end
652
-
653
- # :startdoc:
654
-
655
- end
656
- end
657
- end