rubasteme 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,315 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubasteme
4
+ module Parser
5
+
6
+ module DerivedConverter
7
+ include Utils
8
+
9
+ DERIVED_IDENTIFIERS = [
10
+ "cond", "case", "and", "or", "when", "unless",
11
+ "let", "let*", "letrec", "letrec*",
12
+ "let-values", "let*-values",
13
+ "begin", "do",
14
+ "delay", "delay-force",
15
+ "parameterize",
16
+ "guard",
17
+ "case-lambda",
18
+ ]
19
+
20
+ def to_derived_expression(list)
21
+ name = compose_method_name("to_", list[0].identifier).intern
22
+ if self.respond_to?(name, true)
23
+ self.send(name, list)
24
+ else
25
+ not_implemented_yet(list[0])
26
+ end
27
+ end
28
+
29
+ def to_cond(list)
30
+ # ( cond <cond clause> ... <else clause> )
31
+ cond = AST.instantiate(:ast_cond)
32
+ list[1..-2].each { |e|
33
+ cond.add_clause(to_cond_clause(e))
34
+ }
35
+ last = list[-1]
36
+ method = is_else_clause?(last) ? :to_else_clause : :to_cond_clause
37
+ cond.add_clause(self.send(method, last))
38
+ cond
39
+ end
40
+
41
+ def is_else_clause?(list)
42
+ ast_type?(list[0], :ast_identifier) && list[0].identifier == "else"
43
+ end
44
+
45
+ def to_cond_clause(list)
46
+ # type 1: ( <test> )
47
+ # type 2: ( <test> <sequence> )
48
+ # type 3: ( <test> => <recipient> )
49
+ clause = nil
50
+ if is_recipient_clause?(list)
51
+ # type 3
52
+ clause = AST.instantiate(:ast_cond_recipient_clause)
53
+ clause.recipient = to_recipient(list[2..-1])
54
+ else
55
+ # type 1 and 2
56
+ clause = AST.instantiate(:ast_cond_clause)
57
+ clause.sequence = to_sequence(list[1..-1])
58
+ end
59
+ clause.test = to_test(list[0])
60
+ clause
61
+ end
62
+
63
+ def is_recipient_clause?(list)
64
+ ast_type?(list[1], :ast_identifier) && list[1].identifier == "=>"
65
+ end
66
+
67
+ def to_else_clause(list)
68
+ # ( else <sequence> )
69
+ else_clause = AST.instantiate(:ast_else_clause)
70
+ else_clause.sequence = to_sequence(list[1..-1])
71
+ else_clause
72
+ end
73
+
74
+ def to_test(list)
75
+ # <test> -> <expression>
76
+ parse(list)
77
+ end
78
+
79
+ def to_recipient(list)
80
+ # <recipient> -> <expression>
81
+ parse(list)
82
+ end
83
+
84
+ def to_case(list)
85
+ # ( case <expression> <case clause>+ )
86
+ # ( case <expression> <case clause>* ( else <sequence> ) )
87
+ # ( case <expression> <case clause>* ( else => <recipient> ) )
88
+ case_node = AST.instantiate(:ast_case)
89
+ case_node.expression = parse(list[1])
90
+ list[2..-2].each { |e|
91
+ case_node.add_clause(to_case_clause(e))
92
+ }
93
+ last = list[-1]
94
+ method = is_else_clause?(last) ? :to_case_else_clause : :to_case_clause
95
+ case_node.add_clause(self.send(method, last))
96
+ case_node
97
+ end
98
+
99
+ def to_case_clause(list)
100
+ # ( ( <datum>* ) <sequence> )
101
+ # ( ( <datum>* ) => <recipient> )
102
+ if is_recipient_clause?(list)
103
+ to_case_recipient_clause(list)
104
+ else
105
+ clause = AST.instantiate(:ast_case_clause)
106
+ clause.data = to_data(list[0])
107
+ clause.sequence = to_sequence(list[1..-1])
108
+ clause
109
+ end
110
+ end
111
+
112
+ def to_case_recipient_clause(list)
113
+ # ( ( <datum>* ) => <recipient> )
114
+ clause = AST.instantiate(:ast_case_recipient_clause)
115
+ clause.data = to_data(list[0])
116
+ caluse.recipient = to_recipient(list[2])
117
+ end
118
+
119
+ def to_case_else_clause(list)
120
+ # ( else <sequence> )
121
+ # ( else => <recipient> )
122
+ if is_recipient_clause?(list)
123
+ to_case_else_recipient_clause(list)
124
+ else
125
+ to_else_clause(list)
126
+ end
127
+ end
128
+
129
+ def to_case_else_recipient_clause(list)
130
+ # ( else => <recipient> )
131
+ clause = AST.instantiate(:ast_else_recipient_clause)
132
+ clause.recipient = to_recipient(list[2])
133
+ clause
134
+ end
135
+
136
+ def to_data(list)
137
+ # ( <datum>* )
138
+ data = AST.instantiate(:ast_data)
139
+ list.each{|e| data << parse(e)}
140
+ data
141
+ end
142
+
143
+ def to_and(list)
144
+ to_logical_test("and", list)
145
+ end
146
+
147
+ def to_or(list)
148
+ to_logical_test("or", list)
149
+ end
150
+
151
+ def to_logical_test(type, list)
152
+ # ( and <test>* )
153
+ # ( or <test>* )
154
+ ast_type = "ast_#{type}".intern
155
+ node = AST.instantiate(ast_type)
156
+ list[1..-1].each{|e| node << to_test(e)}
157
+ node
158
+ end
159
+
160
+ def to_when(list)
161
+ to_test_and_sequence("when", list)
162
+ end
163
+
164
+ def to_unless(list)
165
+ to_test_and_sequence("unless", list)
166
+ end
167
+
168
+ def to_test_and_sequence(type, list)
169
+ # ( when <test> <sequence> )
170
+ # ( unless <test> <sequence> )
171
+ ast_type = "ast_#{type}".intern
172
+ node = AST.instantiate(ast_type)
173
+ node.test = to_test(list[1])
174
+ node.sequence = to_sequence(list[2..-1])
175
+ node
176
+ end
177
+
178
+ def to_let(list)
179
+ # ( let ( <binding spec>* ) <body> )
180
+ # ( let <identifier> ( <binding spec>* ) <body> )
181
+ let = AST.instantiate(:ast_let)
182
+ bindings_pos = 1
183
+ if ast_type?(list[1], :ast_identifier)
184
+ # named let
185
+ let.identifier = list[1]
186
+ bindings_pos += 1
187
+ end
188
+ let.bindings = to_bindings(list[bindings_pos])
189
+ let.body = to_body(list[(bindings_pos + 1)..-1])
190
+ let
191
+ end
192
+
193
+ def to_bindings(list)
194
+ # ( <binding spec>* )
195
+ bindings = AST.instantiate(:ast_bindings)
196
+ list.each { |e|
197
+ bindings.add_bind_spec(to_bind_spec(e))
198
+ }
199
+ bindings
200
+ end
201
+
202
+ def to_bind_spec(list)
203
+ # ( <identifier> <expression> )
204
+ spec = AST.instantiate(:ast_bind_spec)
205
+ spec.identifier = list[0]
206
+ spec.expression = parse(list[1])
207
+ spec
208
+ end
209
+
210
+
211
+ def to_let_star(list)
212
+ to_let_base("let_star", list)
213
+ end
214
+
215
+ def to_letrec(list)
216
+ to_let_base("letrec", list)
217
+ end
218
+
219
+ def to_letrec_star(list)
220
+ to_let_base("letrec_star", list)
221
+ end
222
+
223
+ def to_let_base(type, list)
224
+ # ( let* ( <binding spec>* ) <body> )
225
+ # ( letrec ( <binding spec>* ) <body> )
226
+ # ( letrec* ( <binding spec>* ) <body> )
227
+ ast_type = "ast_#{type}".intern
228
+ node = AST.instantiate(ast_type)
229
+ node.bindings = to_bindings(list[1])
230
+ node.body = to_body(list[2..-1])
231
+ node
232
+ end
233
+
234
+ def to_let_values(list)
235
+ not_implemented_yet("LET-VALUES")
236
+ end
237
+
238
+ def to_let_star_values(list)
239
+ not_implemented_yet("LET*-VALUES")
240
+ end
241
+
242
+ def to_begin(list)
243
+ # ( begin <sequence> )
244
+ begin_node = AST.instantiate(:ast_begin)
245
+ begin_node.sequence = to_sequence(list[1..-1])
246
+ begin_node
247
+ end
248
+
249
+ def to_do(list)
250
+ # ( do ( <iteration spec>* ) ( <test> <do result> ) <command>* )
251
+ do_node = AST.instantiate(:ast_do)
252
+ do_node.iteration_bindings = to_iteration_bindings(list[1])
253
+ do_node.test_and_do_result = to_test_and_do_result(list[2])
254
+ list[3..-1].each { |e|
255
+ do_node.add_command(parse(e))
256
+ }
257
+ do_node
258
+ end
259
+
260
+ def to_iteration_bindings(list)
261
+ # ( <iteration spec>* )
262
+ node = AST.instantiate(:ast_iteration_bindings)
263
+ list.each { |e|
264
+ node.add_iteration_spec(to_iteration_spec(e))
265
+ }
266
+ node
267
+ end
268
+
269
+ def to_iteration_spec(list)
270
+ # ( <identifier> <init> )
271
+ # ( <identifier> <init> <step> )
272
+ # <init> -> <expression>
273
+ # <step> -> <expression>
274
+ spec = AST.instantiate(:ast_iteration_spec)
275
+ spec.identifier = list[0]
276
+ spec.init = parse(list[1])
277
+ if list.size > 2
278
+ spec.step = parse(list[2])
279
+ end
280
+ spec
281
+ end
282
+
283
+ def to_test_and_do_result(list)
284
+ # ( <test> <do result> )
285
+ # <do result> -> <sequence> | <empty>
286
+ node = AST.instantiate(:ast_test_and_do_result)
287
+ node.test = to_test(list[0])
288
+ node.sequence = to_sequence(list[1..-1])
289
+ node
290
+ end
291
+
292
+ def to_delay(list)
293
+ not_implemented_yet("DELAY")
294
+ end
295
+
296
+ def to_delay_force(list)
297
+ not_implemented_yet("DELAY-FORCE")
298
+ end
299
+
300
+ def to_parameterize(list)
301
+ not_implemented_yet("PARAMETERIZE")
302
+ end
303
+
304
+ def to_guard(list)
305
+ not_implemented_yet("GUARD")
306
+ end
307
+
308
+ def to_case_lambda(list)
309
+ not_implemented_yet("CASE-LAMBDA")
310
+ end
311
+
312
+ end
313
+
314
+ end # end of Parser (module)
315
+ end
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubasteme
4
+
5
+ def self.phase1_parse(source)
6
+ Parser::Phase1Parser.new.parse(Rbscmlex.lexer(source))
7
+ end
8
+
9
+ module Parser
10
+
11
+ class Phase1Parser
12
+ include Utils
13
+
14
+ def self.version
15
+ Rubasteme.send(:make_version, self.name)
16
+ end
17
+
18
+ def version
19
+ self.class.version
20
+ end
21
+
22
+ def parse(lexer)
23
+ return [] if lexer.nil?
24
+ parse_expression(lexer)
25
+ end
26
+
27
+ # :stopdoc:
28
+ private
29
+
30
+ def parse_expression(lexer)
31
+ if start_delimiter?(lexer.peek_token)
32
+ parse_compound_expression(lexer)
33
+ else
34
+ parse_simple_expression(lexer)
35
+ end
36
+ end
37
+
38
+ TOKEN_START_DELIMITERS = [ # :nodoc:
39
+ :lparen, # list: ( ... )
40
+ :vec_lparen, # vector: #( ... )
41
+ :bytevec_lparen, # bytevector: #u8( ... )
42
+ :quotation, # quotation: '<something>
43
+ :backquote, # quasiquote: `<something>
44
+ :comma, # used in quasiquote
45
+ :comma_at, # used in quasiquote
46
+ :comment_lparen, # comment start
47
+ ]
48
+
49
+ def start_delimiter?(token)
50
+ TOKEN_START_DELIMITERS.include?(token.type)
51
+ end
52
+
53
+ def parse_simple_expression(lexer)
54
+ type, literal = *lexer.next_token
55
+ AST.instantiate(ast_simple_type(type), literal)
56
+ end
57
+
58
+ def ast_simple_type(token_type)
59
+ case token_type
60
+ when :identifier
61
+ :ast_identifier
62
+ when :boolean, :character, :number, :string
63
+ "ast_#{token_type}".intern
64
+ when :dot
65
+ :ast_dot
66
+ else
67
+ :ast_illegal
68
+ end
69
+ end
70
+
71
+ def parse_compound_expression(lexer)
72
+ case lexer.peek_token.type
73
+ when :vec_lparen
74
+ parse_vector(lexer)
75
+ when :quotation
76
+ parse_quotation(lexer)
77
+ when :lparen
78
+ parse_list(lexer)
79
+ else
80
+ raise SchemeSyntaxErrorError, "%s" % lexer.peek_token.literal
81
+ end
82
+ end
83
+
84
+ def parse_list(lexer)
85
+ if lexer.peek_token(1).type == :rparen
86
+ # an empty list
87
+ lexer.skip_rparen(1)
88
+ AST.instantiate(:ast_empty_list)
89
+ else
90
+ nodes = []
91
+ parse_container(nodes, lexer)
92
+ end
93
+ end
94
+
95
+ def parse_vector(lexer)
96
+ vector = AST.instantiate(:ast_vector)
97
+ parse_container(vector, lexer)
98
+ end
99
+
100
+ def parse_container(container, lexer)
101
+ lexer.skip_token
102
+ Kernel.loop {
103
+ break if lexer.peek_token.type == :rparen
104
+ container << parse_expression(lexer)
105
+ }
106
+ lexer.skip_rparen
107
+ container
108
+ end
109
+
110
+ def parse_quotation(lexer)
111
+ lexer.skip_token
112
+ quote = AST.instantiate(:ast_identifier, "quote")
113
+ [quote, parse_expression(lexer)]
114
+ end
115
+
116
+ # :startdoc:
117
+ end # end of Phase1Parser
118
+ end
119
+ end
@@ -0,0 +1,253 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubasteme
4
+
5
+ def self.phase2_parse(source)
6
+ nodes = Parser::Phase1Parser.new.parse(Rbscmlex.lexer(source))
7
+ Parser::Phase2Parser.new.parse(nodes)
8
+ end
9
+
10
+ module Parser
11
+
12
+ require_relative "derived_converter"
13
+
14
+ class Phase2Parser
15
+ include Utils
16
+ include DerivedConverter
17
+
18
+ def self.version
19
+ Rubasteme.send(:make_version, self.name)
20
+ end
21
+
22
+ def version
23
+ self.class.version
24
+ end
25
+
26
+ def parse(list)
27
+ if ast?(list)
28
+ list
29
+ elsif list.instance_of?(Array)
30
+ to_ast(list)
31
+ else
32
+ raise SchemeSyntaxErrorError,
33
+ "unknown syntax element; got=%s" % node.to_s
34
+ end
35
+ end
36
+
37
+ # :stopdoc:
38
+ private
39
+
40
+ def to_ast(list)
41
+ if list.empty?
42
+ AST.instantiate(:ast_empty_list)
43
+ elsif ast_type?(list[0], :ast_identifier)
44
+ node = nil
45
+ case list[0].identifier
46
+ when "quote"
47
+ node = to_quotation(list)
48
+ when "lambda"
49
+ node = to_lambda_expression(list)
50
+ when "if"
51
+ node = to_conditional(list)
52
+ when "set!"
53
+ node = to_assignment(list)
54
+ when "let-syntax", "letrec-syntax"
55
+ node = to_macro_block(list)
56
+ when "define", "define-syntax", "define-values", "define-record-type"
57
+ node = to_definition(list)
58
+ when "include", "include-ci"
59
+ node = to_include(list)
60
+ when *DERIVED_IDENTIFIERS
61
+ node = to_derived_expression(list)
62
+ end
63
+ node || to_procedure_call(list)
64
+ else
65
+ # TODO: it it correct?
66
+ list
67
+ end
68
+ end
69
+
70
+ def to_quotation(list)
71
+ quote = AST.instantiate(:ast_quotation)
72
+ quote << list
73
+ quote
74
+ end
75
+
76
+ def to_procedure_call(list)
77
+ proc_call = AST.instantiate(:ast_procedure_call)
78
+ proc_call.operator = list[0]
79
+ list[1..-1].each { |node|
80
+ proc_call.add_operand(parse(node))
81
+ }
82
+ proc_call
83
+ end
84
+
85
+ def to_lambda_expression(list)
86
+ # ( lambda <formals> <body> )
87
+ lambda_exp = AST.instantiate(:ast_lambda_expression)
88
+ lambda_exp.formals = to_formals(list[1])
89
+ lambda_exp.body = to_body(list[2..-1])
90
+ lambda_exp
91
+ end
92
+
93
+ def to_formals(list)
94
+ # type 1: <identifier>
95
+ # type 2: ( <identifier 1> <identifier 2> ... )
96
+ # type 3: ( <identifier 1> <identifier 2> <dot> <identifier n> )
97
+ # => not supported yet
98
+ if ast_type?(list, :ast_identifier)
99
+ # type 1
100
+ list
101
+ else
102
+ # type 2
103
+ formals = AST.instantiate(:ast_formals)
104
+ list.each{|e| formals.add_identifier(e)}
105
+ formals
106
+ end
107
+ end
108
+
109
+ def to_body(list)
110
+ # <body> -> <definition>* <sequence>
111
+ body = AST.instantiate(:ast_body)
112
+ definitions = AST.instantiate(:ast_internal_definitions)
113
+
114
+ i = 0
115
+ list.each { |e|
116
+ break unless is_definition?(e)
117
+ definitions.add_definition(to_definition(e))
118
+ i += 1
119
+ }
120
+ body.definitions = definitions
121
+
122
+ body.sequence = to_sequence(list[i..-1])
123
+ body
124
+ end
125
+
126
+ def to_sequence(list)
127
+ # <sequence> -> <command>* <expression>
128
+ # <command> -> <expression>
129
+ seq = AST.instantiate(:ast_sequence)
130
+ list.each { |node|
131
+ if is_definition?(node)
132
+ raise SchemeSyntaxErrorError,
133
+ "wrong position of internal definition"
134
+ end
135
+ seq.add_expression(parse(node))
136
+ }
137
+ seq
138
+ end
139
+
140
+ DEFINITION_IDENTIFIERS = [
141
+ "define",
142
+ "define-syntax",
143
+ "define-values",
144
+ "define-record-type",
145
+ ]
146
+
147
+ def is_definition?(list)
148
+ list.instance_of?(Array) &&
149
+ ast_type?(list[0], :ast_identifier) &&
150
+ DEFINITION_IDENTIFIERS.include?(list[0].identifier)
151
+ end
152
+
153
+ def to_definition(list)
154
+ case list[0].identifier
155
+ when "define"
156
+ to_identifier_definition(list)
157
+ when "define-syntax"
158
+ to_define_syntax(list)
159
+ when "define-values"
160
+ to_define_values(list)
161
+ when "define-record-type"
162
+ to_define_record_type(list)
163
+ else
164
+ raise SchemeSyntaxErrorError, "not definition got=%s" % list[0].identifier
165
+ end
166
+ end
167
+
168
+ def to_identifier_definition(list)
169
+ # type 1: (define foo 3)
170
+ # type 2: (define bar (lambda (x y) (+ x y)))
171
+ # type 3: (define (hoge n m) (display n) (display m) (* n m))
172
+ define = AST.instantiate(:ast_identifier_definition)
173
+
174
+ if ast_type?(list[1], :ast_identifier)
175
+ # type 1 and type 2
176
+ define.identifier = list[1]
177
+ define.expression = parse(list[2])
178
+ elsif list[1].instance_of?(Array)
179
+ # type 3:
180
+ # make a lambda expression, then handle as type 2
181
+ lambda_exp = AST.instantiate(:ast_lambda_expression)
182
+ lambda_exp.formals = to_formals(list[1][1..-1])
183
+ lambda_exp.body = to_body(list[2..-1])
184
+
185
+ define.identifier = list[1][0]
186
+ define.expression = lambda_exp
187
+ else
188
+ raise SchemeSyntaxErrorError, "got=%s" % list[1].to_s
189
+ end
190
+
191
+ define
192
+ end
193
+
194
+ def to_define_syntax(ast_node)
195
+ not_implemented_yet("DEFINE-SYNTAX")
196
+ end
197
+
198
+ def to_define_values(ast_node)
199
+ not_implemented_yet("DEFINE-VALUES")
200
+ end
201
+
202
+ def to_define_record_type(ast_node)
203
+ not_implemented_yet("DEFINE-RECORD-TYPE")
204
+ end
205
+
206
+ def to_includer(ast_node)
207
+ not_implemented_yet("INCLUDE or INCLUDE-CI")
208
+ end
209
+
210
+ def to_conditional(list)
211
+ # ( if <test> <consequent> )
212
+ # ( if <test> <consequent> <alternate> )
213
+ if_node = AST.instantiate(:ast_conditional)
214
+ if_node.test = parse(list[1])
215
+ if_node.consequent = parse(list[2])
216
+
217
+ if list.size > 3
218
+ if_node.alternate = parse(list[3])
219
+ end
220
+
221
+ if_node
222
+ end
223
+
224
+ def to_assignment(list)
225
+ # ( set! <identifier> <expression>)
226
+ assignment = AST.instantiate(:ast_assignment)
227
+ assignment.identifier = list[1]
228
+ assignment.expression = parse(list[2])
229
+ assignment
230
+ end
231
+
232
+ def to_macro_block(list)
233
+ not_implemented_yet("MACRO BLOCK")
234
+ end
235
+
236
+ def to_include(list)
237
+ not_implemented_yet("INCLUDE")
238
+ end
239
+
240
+ SCM_CHAR_TO_RB_MAP = {
241
+ "*" => "_star",
242
+ "-" => "_",
243
+ }
244
+
245
+ def compose_method_name(prefix, type_name)
246
+ converted_name = type_name.gsub(/[*\-]/, SCM_CHAR_TO_RB_MAP)
247
+ prefix + converted_name
248
+ end
249
+
250
+ # :startdoc:
251
+ end # end of Phase2Parser
252
+ end # end of Parser
253
+ end