rubasteme 0.1.1 → 0.1.6

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