rubasteme 0.1.1 → 0.1.6

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.
@@ -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,255 @@
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
+ elsif list[0].instance_of?(Array)
65
+ to_procedure_call(list)
66
+ else
67
+ raise SchemeSyntaxErrorError,
68
+ "invalid application; got=%s" % list.to_a.to_s
69
+ end
70
+ end
71
+
72
+ def to_quotation(list)
73
+ quote = AST.instantiate(:ast_quotation)
74
+ quote << list
75
+ quote
76
+ end
77
+
78
+ def to_procedure_call(list)
79
+ proc_call = AST.instantiate(:ast_procedure_call)
80
+ proc_call.operator = list[0]
81
+ list[1..-1].each { |node|
82
+ proc_call.add_operand(parse(node))
83
+ }
84
+ proc_call
85
+ end
86
+
87
+ def to_lambda_expression(list)
88
+ # ( lambda <formals> <body> )
89
+ lambda_exp = AST.instantiate(:ast_lambda_expression)
90
+ lambda_exp.formals = to_formals(list[1])
91
+ lambda_exp.body = to_body(list[2..-1])
92
+ lambda_exp
93
+ end
94
+
95
+ def to_formals(list)
96
+ # type 1: <identifier>
97
+ # type 2: ( <identifier 1> <identifier 2> ... )
98
+ # type 3: ( <identifier 1> <identifier 2> <dot> <identifier n> )
99
+ # => not supported yet
100
+ if ast_type?(list, :ast_identifier)
101
+ # type 1
102
+ list
103
+ else
104
+ # type 2
105
+ formals = AST.instantiate(:ast_formals)
106
+ list.each{|e| formals.add_identifier(e)}
107
+ formals
108
+ end
109
+ end
110
+
111
+ def to_body(list)
112
+ # <body> -> <definition>* <sequence>
113
+ body = AST.instantiate(:ast_body)
114
+ definitions = AST.instantiate(:ast_internal_definitions)
115
+
116
+ i = 0
117
+ list.each { |e|
118
+ break unless is_definition?(e)
119
+ definitions.add_definition(to_definition(e))
120
+ i += 1
121
+ }
122
+ body.definitions = definitions
123
+
124
+ body.sequence = to_sequence(list[i..-1])
125
+ body
126
+ end
127
+
128
+ def to_sequence(list)
129
+ # <sequence> -> <command>* <expression>
130
+ # <command> -> <expression>
131
+ seq = AST.instantiate(:ast_sequence)
132
+ list.each { |node|
133
+ if is_definition?(node)
134
+ raise SchemeSyntaxErrorError,
135
+ "wrong position of internal definition"
136
+ end
137
+ seq.add_expression(parse(node))
138
+ }
139
+ seq
140
+ end
141
+
142
+ DEFINITION_IDENTIFIERS = [
143
+ "define",
144
+ "define-syntax",
145
+ "define-values",
146
+ "define-record-type",
147
+ ]
148
+
149
+ def is_definition?(list)
150
+ list.instance_of?(Array) &&
151
+ ast_type?(list[0], :ast_identifier) &&
152
+ DEFINITION_IDENTIFIERS.include?(list[0].identifier)
153
+ end
154
+
155
+ def to_definition(list)
156
+ case list[0].identifier
157
+ when "define"
158
+ to_identifier_definition(list)
159
+ when "define-syntax"
160
+ to_define_syntax(list)
161
+ when "define-values"
162
+ to_define_values(list)
163
+ when "define-record-type"
164
+ to_define_record_type(list)
165
+ else
166
+ raise SchemeSyntaxErrorError, "not definition got=%s" % list[0].identifier
167
+ end
168
+ end
169
+
170
+ def to_identifier_definition(list)
171
+ # type 1: (define foo 3)
172
+ # type 2: (define bar (lambda (x y) (+ x y)))
173
+ # type 3: (define (hoge n m) (display n) (display m) (* n m))
174
+ define = AST.instantiate(:ast_identifier_definition)
175
+
176
+ if ast_type?(list[1], :ast_identifier)
177
+ # type 1 and type 2
178
+ define.identifier = list[1]
179
+ define.expression = parse(list[2])
180
+ elsif list[1].instance_of?(Array)
181
+ # type 3:
182
+ # make a lambda expression, then handle as type 2
183
+ lambda_exp = AST.instantiate(:ast_lambda_expression)
184
+ lambda_exp.formals = to_formals(list[1][1..-1])
185
+ lambda_exp.body = to_body(list[2..-1])
186
+
187
+ define.identifier = list[1][0]
188
+ define.expression = lambda_exp
189
+ else
190
+ raise SchemeSyntaxErrorError, "got=%s" % list[1].to_s
191
+ end
192
+
193
+ define
194
+ end
195
+
196
+ def to_define_syntax(ast_node)
197
+ not_implemented_yet("DEFINE-SYNTAX")
198
+ end
199
+
200
+ def to_define_values(ast_node)
201
+ not_implemented_yet("DEFINE-VALUES")
202
+ end
203
+
204
+ def to_define_record_type(ast_node)
205
+ not_implemented_yet("DEFINE-RECORD-TYPE")
206
+ end
207
+
208
+ def to_includer(ast_node)
209
+ not_implemented_yet("INCLUDE or INCLUDE-CI")
210
+ end
211
+
212
+ def to_conditional(list)
213
+ # ( if <test> <consequent> )
214
+ # ( if <test> <consequent> <alternate> )
215
+ if_node = AST.instantiate(:ast_conditional)
216
+ if_node.test = parse(list[1])
217
+ if_node.consequent = parse(list[2])
218
+
219
+ if list.size > 3
220
+ if_node.alternate = parse(list[3])
221
+ end
222
+
223
+ if_node
224
+ end
225
+
226
+ def to_assignment(list)
227
+ # ( set! <identifier> <expression>)
228
+ assignment = AST.instantiate(:ast_assignment)
229
+ assignment.identifier = list[1]
230
+ assignment.expression = parse(list[2])
231
+ assignment
232
+ end
233
+
234
+ def to_macro_block(list)
235
+ not_implemented_yet("MACRO BLOCK")
236
+ end
237
+
238
+ def to_include(list)
239
+ not_implemented_yet("INCLUDE")
240
+ end
241
+
242
+ SCM_CHAR_TO_RB_MAP = {
243
+ "*" => "_star",
244
+ "-" => "_",
245
+ }
246
+
247
+ def compose_method_name(prefix, type_name)
248
+ converted_name = type_name.gsub(/[*\-]/, SCM_CHAR_TO_RB_MAP)
249
+ prefix + converted_name
250
+ end
251
+
252
+ # :startdoc:
253
+ end # end of Phase2Parser
254
+ end # end of Parser
255
+ end