rubasteme 0.1.2 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -32,6 +32,10 @@ module Rubasteme
32
32
  def initialize(literal)
33
33
  super
34
34
  end
35
+
36
+ def identifier
37
+ literal
38
+ end
35
39
  end
36
40
 
37
41
  class CharacterNode < LeafNode
@@ -5,7 +5,7 @@ module Rubasteme
5
5
 
6
6
  # :stopdoc:
7
7
  EMSG = {
8
- scheme_sytanx_error: "syntax error: got=%s",
8
+ scheme_syntax_error: "syntax error: %s",
9
9
  unexpected_token_type: "unexpected token type: got=%s, expected=%s",
10
10
  missing_right_parenthesis: "missing right parenthesis",
11
11
  unsupported_feature: "unsupported feature: %s",
@@ -15,8 +15,8 @@ module Rubasteme
15
15
 
16
16
  # Indicates a syntax error as Scheme program.
17
17
  class SchemeSyntaxErrorError < Error
18
- def initialize(literal)
19
- super(EMSG[:scheme_syntax_error] % literal)
18
+ def initialize(msg)
19
+ super(EMSG[:scheme_syntax_error] % msg)
20
20
  end
21
21
  end
22
22
 
@@ -3,611 +3,54 @@
3
3
  module Rubasteme
4
4
 
5
5
  def self.parser
6
- Parser.new
6
+ Parser::Parser.new
7
7
  end
8
8
 
9
- class Parser
9
+ module Parser
10
10
 
11
11
  def self.version
12
- "rubasteme.parser :version #{VERSION} :relase #{RELEASE}"
12
+ Rubasteme.send(:make_version, self.name)
13
13
  end
14
14
 
15
- def initialize
16
- @lexer = nil
17
- end
18
-
19
- def parse(lexer)
20
- return [] if lexer.nil?
21
- @lexer = lexer
22
- parse_program
23
- end
24
-
25
- def parse_program
26
- ast_program = AST.instantiate(:ast_program, nil)
27
- Kernel.loop {
28
- ast_program << parse_expression
29
- }
30
- ast_program
31
- end
32
-
33
- def parse_expression
34
- if start_delimiter?(@lexer.peek_token)
35
- parse_compound_expression
36
- else
37
- parse_simple_expression
38
- end
39
- end
40
-
41
- def parse_simple_expression
42
- type, literal = *@lexer.next_token
43
- AST.instantiate(ast_simple_type(type), literal)
44
- end
45
-
46
- def parse_identifier
47
- parse_simple_expression
48
- end
49
-
50
- TOKEN_START_DELIMITERS = [ # :nodoc:
51
- :lparen, # list: ( ... )
52
- :vec_lparen, # vector: #( ... )
53
- :bytevec_lparen, # bytevector: #u8( ... )
54
- :quotation, # quotation: '<something>
55
- :backquote, # quasiquote: `<something>
56
- :comma, # used in quasiquote
57
- :comma_at, # used in quasiquote
58
- :comment_lparen, # comment start
59
- ]
60
-
61
- def start_delimiter?(token)
62
- TOKEN_START_DELIMITERS.include?(token.type)
63
- end
64
-
65
- def parse_compound_expression
66
- case @lexer.peek_token.type
67
- when :vec_lparen
68
- parse_vector
69
- when :quotation
70
- parse_quotation
71
- when :lparen
72
- parse_list_expression
73
- else
74
- raise SchemeSyntaxError, @lexer.peek_token.literal
75
- end
76
- end
77
-
78
- def parse_vector
79
- parse_data_to_matched_rparen
80
- end
81
-
82
- def parse_data_to_matched_rparen
83
- token = @lexer.next_token
84
- node = AST.instantiate(ast_compound_type(token.type), nil)
85
- Kernel.loop {
86
- break if @lexer.peek_token.type == :rparen
87
- node << parse_datum
88
- }
89
- skip_rparen
90
-
91
- node
92
- end
93
-
94
- def parse_datum
95
- if start_delimiter?(@lexer.peek_token)
96
- parse_compound_datum
97
- else
98
- parse_simple_datum
99
- end
100
- end
101
-
102
- def parse_simple_datum
103
- parse_simple_expression
104
- end
105
-
106
- def parse_compound_datum
107
- case @lexer.peek_token.type
108
- when :lparen
109
- parse_data_list
110
- when :vec_lparen
111
- parse_vector
112
- else
113
- parse_simple_expression
114
- end
115
- end
116
-
117
- def parse_data_list
118
- parse_data_to_matched_rparen
119
- end
120
-
121
- def parse_quotation
122
- literal = @lexer.next_token.literal
123
- quote_node = AST.instantiate(:ast_quotation, literal)
124
- quote_node << parse_datum
125
- quote_node
126
- end
127
-
128
- DERIVED_IDENTIFIERS = [
129
- "cond", "case", "and", "or", "when", "unless",
130
- "let", "let*", "letrec", "letrec*",
131
- "let-values", "let*-values",
132
- "begin", "do",
133
- "delay", "delay-force",
134
- "parameterize",
135
- "guard",
136
- "case-lambda",
137
- ]
138
-
139
- def parse_list_expression
140
- node = nil
141
- skip_lparen
142
- type, literal = *@lexer.peek_token
143
- case type
144
- when :rparen
145
- # an empty list
146
- node = AST.instantiate(:ast_empty_list, nil)
147
- skip_rparen
148
- when :identifier
149
- case literal
150
- when "lambda"
151
- node = parse_lambda_expression
152
- when "if"
153
- node = parse_conditional
154
- when "set!"
155
- node = parse_assignment
156
- when "let-syntax", "letrec-syntax"
157
- node = parse_macro_block
158
- when "define", "define-syntax", "define-values", "define-record-type"
159
- node = parse_definition
160
- when "include", "include-ci"
161
- node = parse_includer
162
- when *DERIVED_IDENTIFIERS
163
- node = parse_derived_expression
164
- end
165
- end
166
- node || parse_procedure_call
167
- end
168
-
169
- def parse_procedure_call
170
- proc_call_node = AST.instantiate(:ast_procedure_call, nil)
171
- proc_call_node.operator = parse_operator
172
- Kernel.loop {
173
- break if @lexer.peek_token.type == :rparen
174
- proc_call_node.add_operand(parse_operand)
175
- }
176
- skip_rparen
177
- proc_call_node
178
- end
179
-
180
- def parse_operator
181
- parse_expression
182
- end
183
-
184
- def parse_operand
185
- parse_expression
186
- end
187
-
188
- def parse_lambda_expression
189
- @lexer.skip_token # skip :lambda
190
- lambda_node = make_lambda_expression_node(parse_formals, read_body)
191
- skip_rparen
192
- lambda_node
193
- end
194
-
195
- def make_lambda_expression_node(formals, body)
196
- lambda_node = AST.instantiate(:ast_lambda_expression, nil)
197
- lambda_node.formals = formals
198
- lambda_node.body = body
199
- lambda_node
200
- end
201
-
202
- def parse_formals
203
- formals_node = nil
204
- # type 1: <identifier>
205
- # type 2: ( <identifier 1> <identifier 2> ... )
206
- # type 3: ( <identifier 1> <identifier 2> <dot> <identifier n> )
207
- # => not supported yet
208
- if @lexer.peek_token.type == :lparen
209
- formals_node = AST.instantiate(:ast_formals, nil)
210
- skip_lparen
211
- Kernel.loop {
212
- break if @lexer.peek_token.type == :rparen
213
- formals_node.add_identifier(parse_identifier)
214
- }
215
- else # type 1
216
- formals_node = parse_identifier
217
- end
218
- skip_rparen
219
- formals_node
220
- end
221
-
222
- def read_body
223
- body = []
224
- Kernel.loop {
225
- break if @lexer.peek_token.type == :rparen # the end of lambda exp.
226
- body << parse_expression
227
- }
228
- body
229
- end
230
-
231
- def parse_conditional
232
- if_node = AST.instantiate(:ast_conditional, @lexer.next_token.literal)
233
- if_node.test = parse_test
234
- if_node.consequent = parse_consequent
235
- if @lexer.peek_token.type != :rparen
236
- if_node.alternate = parse_alternate
237
- end
238
- skip_rparen
239
- if_node
240
- end
241
-
242
- def parse_test
243
- parse_expression
244
- end
245
-
246
- def parse_consequent
247
- parse_expression
248
- end
249
-
250
- def parse_alternate
251
- parse_expression
252
- end
253
-
254
- def parse_assignment
255
- assignment_node = AST.instantiate(:ast_assignment, @lexer.next_token.literal)
256
- assignment_node.identifier = parse_identifier
257
- assignment_node.expression = parse_expression
258
- skip_rparen
259
- assignment_node
260
- end
261
-
262
- def parse_macro_block
263
- not_implemented_yet("MACRO block")
264
- end
265
-
266
- def parse_definition
267
- case @lexer.peek_token.literal
268
- when "define"
269
- parse_identifier_definition
270
- when "define-syntax"
271
- parse_define_syntax
272
- when "define-values"
273
- parse_define_values
274
- when "define-record-type"
275
- parse_define_record_type
276
- else
277
- raise SchemeSyntaxErrorError, @lexer.peek_token.literal
278
- end
279
- end
280
-
281
- def parse_identifier_definition
282
- # type 1: (define foo 3)
283
- # type 2: (define bar (lambda (x y) (+ x y)))
284
- # type 3: (define (hoge n m) (display n) (display m) (* n m))
285
- define_node = AST.instantiate(:ast_identifier_definition, @lexer.next_token.literal)
286
-
287
- case @lexer.peek_token.type
288
- when :identifier
289
- # type 1 and type 2
290
- define_node.identifier = parse_identifier
291
- define_node.expression = parse_expression
292
- skip_rparen
293
- when :lparen
294
- # type 3:
295
- # make a lambda expression, then handle as type 2
296
- skip_lparen
297
- define_node.identifier = parse_identifier
298
- def_formals_node = AST.instantiate(:ast_formals, nil)
299
- Kernel.loop {
300
- break if @lexer.peek_token.type == :rparen
301
- def_formals_node.add_identifier(parse_identifier)
302
- }
303
- skip_rparen
304
-
305
- lambda_node = make_lambda_expression_node(def_formals_node, read_body)
306
- skip_rparen
307
-
308
- define_node.expression = lambda_node
309
- else
310
- raise SchemeSyntaxErrorError, @lexer.peek_token.literal
311
- end
312
-
313
- define_node
314
- end
315
-
316
- def parse_define_syntax
317
- not_implemented_yet("DEFINE-SYNTAX")
318
- end
319
-
320
- def parse_define_values
321
- not_implemented_yet("DEFINE-VALUES")
322
- end
323
-
324
- def parse_define_record_type
325
- not_implemented_yet("DEFINE-RECORD-TYPE")
326
- end
327
-
328
- def parse_includer
329
- not_implemented_yet("INCLUDE or INCLUDE-CI")
330
- end
331
-
332
- def parse_derived_expression
333
- literal = @lexer.next_token.literal
334
- name = compose_method_name("parse_", literal).intern
335
- if self.respond_to?(name)
336
- m = self.method(name)
337
- m.call
338
- else
339
- not_implemented_yet(literal)
15
+ module Utils
16
+ def ast?(obj)
17
+ obj.kind_of?(AST::Node)
340
18
  end
341
- end
342
-
343
- def parse_cond
344
- cond_node = AST.instantiate(:ast_cond, nil)
345
- Kernel.loop {
346
- break if @lexer.peek_token.type == :rparen
347
- cond_node.add_clause(parse_cond_clause)
348
- }
349
- skip_rparen
350
- cond_node
351
- end
352
-
353
- def parse_cond_clause
354
- skip_lparen
355
- clause_node = AST.instantiate(:ast_cond_clause, nil)
356
- # type 1: ( <test> )
357
- # type 2: ( <test> => <expression> )
358
- # type 3: ( <test> <sequence> )
359
- # type 4: ( else <sequence> )
360
- clause_node.test = parse_test
361
- Kernel.loop {
362
- break if @lexer.peek_token.type == :rparen
363
- clause_node.add_expression(parse_expression)
364
- }
365
- skip_rparen
366
- clause_node
367
- end
368
-
369
- def parse_case
370
- not_implemented_yet("CASE")
371
- end
372
-
373
- def parse_and
374
- parse_logical_test("and")
375
- end
376
-
377
- def parse_or
378
- parse_logical_test("or")
379
- end
380
19
 
381
- def parse_logical_test(type)
382
- ast_type = "ast_#{type}".intern
383
- node = AST.instantiate(ast_type, nil)
384
- Kernel.loop {
385
- break if @lexer.peek_token.type == :rparen
386
- node << parse_test
387
- }
388
- skip_rparen
389
- node
390
- end
391
-
392
- def parse_when
393
- parse_test_and_sequence("when")
394
- end
395
-
396
- def parse_unless
397
- parse_test_and_sequence("unless")
398
- end
399
-
400
- def parse_test_and_sequence(type)
401
- ast_type = "ast_#{type}".intern
402
- node = AST.instantiate(ast_type, nil)
403
- node.test = parse_test
404
- Kernel.loop {
405
- break if @lexer.peek_token.type == :rparen
406
- node << parse_expression
407
- }
408
- skip_rparen
409
- node
410
- end
411
-
412
- def parse_let
413
- let_node = AST.instantiate(:ast_let, nil)
414
- if @lexer.peek_token.type == :identifier
415
- let_node.identifier = parse_identifier
20
+ def ast_type?(obj, type)
21
+ ast?(obj) && obj.type == type
416
22
  end
417
- let_node.bindings = parse_bindings
418
- let_node.body = read_body
419
- skip_rparen
420
- let_node
421
- end
422
-
423
- def parse_bindings
424
- bindings_node = AST.instantiate(:ast_bindings, nil)
425
- skip_lparen
426
- Kernel.loop {
427
- break if @lexer.peek_token.type == :rparen
428
- bindings_node.add_bind_spec(parse_bind_spec)
429
- }
430
- skip_rparen
431
- bindings_node
432
- end
433
-
434
- def parse_bind_spec
435
- spec_node = AST.instantiate(:ast_bind_spec, nil)
436
- skip_lparen
437
- spec_node.identifier = parse_identifier
438
- spec_node.expression = parse_expression
439
- skip_rparen
440
- spec_node
441
- end
442
-
443
- def parse_let_star
444
- parse_let_base("let_star")
445
- end
446
-
447
- def parse_letrec
448
- parse_let_base("letrec")
449
- end
450
-
451
- def parse_letrec_star
452
- parse_let_base("letrec_star")
453
- end
454
23
 
455
- def parse_let_base(type)
456
- ast_type = "ast_#{type}".intern
457
- node = AST.instantiate(ast_type, nil)
458
- node.bindings = parse_bindings
459
- node.body = read_body
460
- skip_rparen
461
- node
462
- end
463
-
464
- def parse_let_values
465
- not_implemented_yet("LET-VALUES")
466
- end
467
-
468
- def parse_let_star_values
469
- not_implemented_yet("LET*-VALUES")
470
- end
471
-
472
- def parse_begin
473
- begin_node = AST.instantiate(:ast_begin, nil)
474
- Kernel.loop {
475
- break if @lexer.peek_token.type == :rparen
476
- begin_node << parse_expression
477
- }
478
- skip_rparen
479
- begin_node
480
- end
481
-
482
- def parse_do
483
- do_node = AST.instantiate(:ast_do, nil)
484
- do_node.iteration_bindings = parse_iteration_bindings
485
- do_node.test_and_do_result = parse_test_and_do_result
486
- Kernel.loop {
487
- break if @lexer.peek_token.type == :rparen
488
- do_node.add_command(parse_expression)
489
- }
490
- skip_rparen
491
- do_node
492
- end
493
-
494
- def parse_iteration_bindings
495
- node = AST.instantiate(:ast_iteration_bindings, nil)
496
- skip_lparen
497
- Kernel.loop {
498
- break if @lexer.peek_token.type == :rparen
499
- node.add_iteration_spec(parse_iteration_spec)
500
- }
501
- skip_rparen
502
- node
503
- end
504
-
505
- def parse_iteration_spec
506
- spec_node = AST.instantiate(:ast_iteration_spec, nil)
507
- skip_lparen
508
- spec_node.identifier = parse_identifier
509
- spec_node.init = parse_init
510
- if @lexer.peek_token.type != :rparen
511
- spec_node.step = parse_step
24
+ def not_implemented_yet(feature)
25
+ raise NotImplementedYetError, feature
512
26
  end
513
- skip_rparen
514
- spec_node
515
- end
516
-
517
- def parse_init
518
- parse_expression
519
- end
520
-
521
- def parse_step
522
- parse_expression
523
- end
524
-
525
- def parse_test_and_do_result
526
- node = AST.instantiate(:ast_test_and_do_result, nil)
527
- skip_lparen
528
- node << parse_test
529
- Kernel.loop {
530
- break if @lexer.peek_token.type == :rparen
531
- node.add_expression(parse_expression)
532
- }
533
- skip_rparen
534
- node
535
- end
536
-
537
- def parse_delay
538
- not_implemented_yet("DELAY")
539
- end
540
-
541
- def parse_delay_force
542
- not_implemented_yet("DELAY-FORCE")
543
- end
544
-
545
- def parse_parameterize
546
- not_implemented_yet("PARAMETERIZE")
547
27
  end
548
28
 
549
- def parse_guard
550
- not_implemented_yet("GUARD")
551
- end
552
-
553
- def parse_case_lambda
554
- not_implemented_yet("CASE-LAMBDA")
555
- end
29
+ require_relative "parser/phase1_parser"
30
+ require_relative "parser/phase2_parser"
556
31
 
557
- private
32
+ class Parser
33
+ include Utils
558
34
 
559
- def skip_lparen
560
- if @lexer.peek_token.type == :lparen
561
- @lexer.skip_token
562
- else
563
- raise UnexpectedTokenTypeError.new(@lexer.peek_token.type, :lparen)
35
+ def self.version
36
+ Rubasteme::Parser.send(:version)
564
37
  end
565
- end
566
38
 
567
- def skip_rparen
568
- if @lexer.peek_token.type == :rparen
569
- @lexer.skip_token
570
- else
571
- raise MissingRightParenthesisError
39
+ def version
40
+ self.class.version
572
41
  end
573
- end
574
42
 
575
- def ast_simple_type(token_type)
576
- case token_type
577
- when :identifier
578
- :ast_identifier
579
- when :boolean, :character, :number, :string
580
- "ast_#{token_type}".intern
581
- when :dot
582
- :ast_dot
583
- else
584
- :ast_identifier
43
+ def initialize
44
+ @p1 = Phase1Parser.new
45
+ @p2 = Phase2Parser.new
585
46
  end
586
- end
587
47
 
588
- def ast_compound_type(token_type)
589
- case token_type
590
- when :vec_lparen
591
- :ast_vector
592
- else
593
- :ast_list
48
+ def parse(lexer)
49
+ return [] if lexer.nil?
50
+ ast_program = AST.instantiate(:ast_program)
51
+ Kernel.loop{ast_program << @p2.parse(@p1.parse(lexer))}
52
+ ast_program
594
53
  end
595
- end
596
-
597
- SCM_CHAR_TO_RB_MAP = {
598
- "*" => "_star",
599
- "-" => "_",
600
- }
601
-
602
- def compose_method_name(prefix, type_name)
603
- converted_name = type_name.gsub(/[*\-]/, SCM_CHAR_TO_RB_MAP)
604
- prefix + converted_name
605
- end
606
-
607
- def not_implemented_yet(feature)
608
- raise NotImplementedYetError, feature
609
- end
610
-
611
- end # end of Parser class
612
-
54
+ end # end of Parser class
55
+ end # end of Parser module
613
56
  end