Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 343 lines (281 sloc) 7.959 kB
272b0b9 @tewk languages/cardinal Initial checkin
tewk authored
1 =head1 NAME
2
3 cardinal -- A compiler for Ruby 1.8.4
4
5 =head1 SYNOPSIS
6
7 $ ./parrot languages/cardinal/cardinal.pir script.rb
8
9 =head1 DESCRIPTION
10
11 Ruby is a compiler for Ruby version 1.8, running on Parrot. Its parser is
12 a PGE grammar (a subclass of PGE::Grammar). The compilation is a series of
13 tree transformations using TGE: from match tree to abstract syntax tree
14 (AST), from AST to opcode syntax tree (OST), and finally from OST to
15 bytecode (actually to PIR, at first). For more on the ideas behind the
16 compiler, see:
17
18 =cut
1aa8d01 @tewk [Cardinal]
tewk authored
19 .HLL 'Ruby', 'ruby_group'
06b8a84 @tewk [Cardinal] refactor to follow Perl6 AST/OST example
tewk authored
20 .include 'errors.pasm'
21 .include 'library/dumper.pir'
272b0b9 @tewk languages/cardinal Initial checkin
tewk authored
22
23 .sub _main :main
24 .param pmc args
25
26 errorson .PARROT_ERRORS_PARAM_COUNT_FLAG
27
06b8a84 @tewk [Cardinal] refactor to follow Perl6 AST/OST example
tewk authored
28 load_bytecode 'PGE.pbc'
272b0b9 @tewk languages/cardinal Initial checkin
tewk authored
29 load_bytecode 'dumper.pbc'
30 load_bytecode 'PGE/Dumper.pbc'
31 load_bytecode 'PGE/Text.pbc'
32 load_bytecode 'Getopt/Obj.pbc'
33
06b8a84 @tewk [Cardinal] refactor to follow Perl6 AST/OST example
tewk authored
34 load_bytecode 'languages/cardinal/src/PAST.pir'
35 load_bytecode 'languages/cardinal/src/POST.pir'
36 #load_bytecode 'languages/cardinal/src/CardinalGrammar.pir'
37 load_bytecode 'languages/cardinal/src/CardinalGrammar.pbc'
38 load_bytecode 'languages/cardinal/src/PGE2AST.pir'
39 load_bytecode 'languages/cardinal/src/AST2OST.pir'
40 load_bytecode 'languages/cardinal/src/builtins_gen.pir'
1aa8d01 @tewk [Cardinal]
tewk authored
41
06b8a84 @tewk [Cardinal] refactor to follow Perl6 AST/OST example
tewk authored
42 .local pmc _dumper
43 .local pmc getopts
44 .local pmc opts
272b0b9 @tewk languages/cardinal Initial checkin
tewk authored
45 .local string arg0
06b8a84 @tewk [Cardinal] refactor to follow Perl6 AST/OST example
tewk authored
46 _dumper = get_root_global [ 'parrot' ], '_dumper'
272b0b9 @tewk languages/cardinal Initial checkin
tewk authored
47 arg0 = shift args
48 getopts = new 'Getopt::Obj'
49 getopts.'notOptStop'(1)
50 push getopts, 'target=s'
51 push getopts, 'dump-optable'
06b8a84 @tewk [Cardinal] refactor to follow Perl6 AST/OST example
tewk authored
52 push getopts, 'dump-source|s'
272b0b9 @tewk languages/cardinal Initial checkin
tewk authored
53 push getopts, 'dump-pge-parse|p'
54 push getopts, 'dump-tge-AST|a'
55 push getopts, 'dump-tge-OST|o'
56 push getopts, 'dump-tge-PIR|i'
06b8a84 @tewk [Cardinal] refactor to follow Perl6 AST/OST example
tewk authored
57 push getopts, 'execute|e'
272b0b9 @tewk languages/cardinal Initial checkin
tewk authored
58 push getopts, 'dump-all|x'
59 push getopts, 'dump|d'
60 push getopts, 'help|h'
61 push getopts, 'trace|t'
62 opts = getopts.'get_options'(args)
63
64 $S0 = opts['dump-optable']
65 if $S0 goto dump_optable
66 $S0 = opts['help']
67 if $S0 goto usage
68
69 .local int stopafter
70 .local string dump
71 .local string target
72 .local int istrace
06b8a84 @tewk [Cardinal] refactor to follow Perl6 AST/OST example
tewk authored
73
74 stopafter = 0
75 dump = opts['dump']
76 target = opts['target']
272b0b9 @tewk languages/cardinal Initial checkin
tewk authored
77 $S0 = opts['trace']
78 istrace = isne $S0, ''
79
80 .local int dump_pge
81 $S0 = opts['dump-pge-parse']
82 dump_pge = isne $S0, ''
83 unless $S0 goto a1
84 stopafter = 1
85 a1:
86
87 .local int dump_ast
88 $S0 = opts['dump-tge-AST']
89 dump_ast = isne $S0, ''
90 unless $S0 goto a2
91 stopafter = 2
92 a2:
93
94 .local int dump_ost
95 $S0 = opts['dump-tge-OST']
96 dump_ost = isne $S0, ''
97 unless $S0 goto a3
98 stopafter = 3
99 a3:
100
101 .local int dump_pir
102 $S0 = opts['dump-tge-PIR']
103 dump_pir = isne $S0, ''
104 unless $S0 goto a4
105 stopafter = 4
106 a4:
107
06b8a84 @tewk [Cardinal] refactor to follow Perl6 AST/OST example
tewk authored
108 .local int dump_src
109 $S0 = opts['dump-source']
110 dump_src = isne $S0, ''
111
112 $S0 = opts['execute']
113 eq $S0, '', a5
114 stopafter = 0
115 a5:
116
272b0b9 @tewk languages/cardinal Initial checkin
tewk authored
117 .local int istrace
118 $S0 = opts['dump-all']
119 if $S0 goto dump_all
120 $S0 = dump
121 unless $S0 goto after_dump_all
122 dump_all:
123 dump_pge = 1
124 dump_ast = 1
125 dump_ost = 1
126 dump_pir = 1
06b8a84 @tewk [Cardinal] refactor to follow Perl6 AST/OST example
tewk authored
127 dump_src = 1
272b0b9 @tewk languages/cardinal Initial checkin
tewk authored
128 stopafter = 0
129 after_dump_all:
130
131 .local pmc cardinal
132 .local string filename
133 cardinal = compreg 'Cardinal'
134
135 .local string source
136
137 $I0 = elements args
138 if $I0 > 0 goto file_arg
139 filename = "STDIN"
140
141 .local pmc stdin
142 stdin = getstdin
143 push stdin, 'utf8'
144 # enable interactive readline if possible
145 $I0 = stdin.'set_readline_interactive'(1)
146
147 stmt_loop:
148 .local string stmt
149 stmt = stdin.'readline'('cardinal> ')
150 unless stmt goto end
151 bsr cardinal_irb_eval
152 goto stmt_loop
153
154 file_arg:
155 filename = args[1]
156 source = _get_source(filename)
157 goto compile_it
158
159 cardinal_irb_eval:
160 $I0 = find_charset 'iso-8859-1' # XXX: Note 2006-04-14
161 trans_charset stmt, $I0
162 #$P0 = perl6(stmt, 'target' => target, 'dump' => dump)
163 null $P0
164 if target == 'PIR' goto dump_pir_output
165 if target goto dump_object
166 trace istrace
167 $P0()
168 trace 0
169 ret
170 dump_pir_output:
171 print $P0
172 ret
173 dump_object:
1aa8d01 @tewk [Cardinal]
tewk authored
174 _dumper($P0, target)
272b0b9 @tewk languages/cardinal Initial checkin
tewk authored
175 ret
176
177 dump_optable:
06b8a84 @tewk [Cardinal] refactor to follow Perl6 AST/OST example
tewk authored
178 #$P0 = get_hll_global [ 'Cardinal'; 'Grammar'], '$optable'
1aa8d01 @tewk [Cardinal]
tewk authored
179 $P0 = get_root_global [ 'parrot'; 'Cardinal::Grammar'], '$optable'
180 _dumper($P0, "Cardinal::Grammar::optable")
272b0b9 @tewk languages/cardinal Initial checkin
tewk authored
181 goto end
182
183 usage:
184 print "usage: cardinal.pbc [--dump-optable] [--target=OUT] [file]\n"
185 end
186
187 compile_it:
188 # Match against the source
189 .local pmc match
190 .local pmc start_rule
06b8a84 @tewk [Cardinal] refactor to follow Perl6 AST/OST example
tewk authored
191
192 $P99 = get_root_namespace [ 'parrot'; 'Cardinal::Grammar']
1aa8d01 @tewk [Cardinal]
tewk authored
193 start_rule = get_root_global [ 'parrot'; 'Cardinal::Grammar'], 'program'
272b0b9 @tewk languages/cardinal Initial checkin
tewk authored
194 match = start_rule(source, 'grammar'=> 'Cardinal::Grammar')
195
196 # Verify the match
197 $I0 = match.__get_bool()
198 unless $I0 goto err_match_fail # if match fails stop
199
200 unless dump_pge goto after_pge_dump
201 print "parse succeeded\n"
202 print "Match tree dump:\n"
1aa8d01 @tewk [Cardinal]
tewk authored
203 _dumper(match, "PGE Dump")
272b0b9 @tewk languages/cardinal Initial checkin
tewk authored
204 after_pge_dump:
205 eq stopafter, 1, end
206
207 # "Traverse" the parse tree
208 .local pmc grammar
06b8a84 @tewk [Cardinal] refactor to follow Perl6 AST/OST example
tewk authored
209 grammar = new 'Cardinal::ASTGrammar'
272b0b9 @tewk languages/cardinal Initial checkin
tewk authored
210
211 # Construct the "AST"
212 .local pmc astbuilder
213 astbuilder = grammar.apply(match)
214 .local pmc ast
215 ast = astbuilder.get('result')
216 $I0 = defined ast
217 unless $I0 goto err_no_ast # if AST fails stop
218
219 unless dump_ast goto after_ast_dump
220 print "\n\nAST tree dump:\n"
06b8a84 @tewk [Cardinal] refactor to follow Perl6 AST/OST example
tewk authored
221 '_dumper'(ast)
222 #ast.'dump'()
272b0b9 @tewk languages/cardinal Initial checkin
tewk authored
223 after_ast_dump:
224 eq stopafter, 2, end
225
226 # Compile the abstract syntax tree down to an opcode syntax tree
227 .local pmc ostgrammar
228 .local pmc ostbuilder
229 .local pmc ost
06b8a84 @tewk [Cardinal] refactor to follow Perl6 AST/OST example
tewk authored
230 ostgrammar = new 'Cardinal::OSTGrammar'
231 ostbuilder = ostgrammar.apply(ast)
232 ost = ostbuilder.get('root')
272b0b9 @tewk languages/cardinal Initial checkin
tewk authored
233 $I0 = defined ost
234 unless $I0 goto err_no_ost # if OST fails stop
235
236 unless dump_ost goto after_ost_dump
237 print "\n\nOST tree dump:\n"
06b8a84 @tewk [Cardinal] refactor to follow Perl6 AST/OST example
tewk authored
238 '_dumper'(ost)
239 #ost.'dump'()
272b0b9 @tewk languages/cardinal Initial checkin
tewk authored
240 after_ost_dump:
241 eq stopafter, 3, end
242
243 # Compile the OST down to PIR
244 .local pmc pirgrammar
245 .local pmc pirbuilder
246 .local pmc pir
06b8a84 @tewk [Cardinal] refactor to follow Perl6 AST/OST example
tewk authored
247 #pirgrammar = new 'PIRGrammar'
248 #pirbuilder = pirgrammar.apply(ost)
249 #pir = pirbuilder.get('result')
250 #unless pir goto err_no_pir # if PIR not generated, stop
251
252 #unless dump_ast goto after_pir_dump
253 #print "\n\nPIR dump:\n"
254 #print pir
255 #after_pir_dump:
256 #eq stopafter, 4, end
257
258 # Compile the OST down to PIR
259 .local pmc pir
260 pir = ost.'root_pir'()
261
262 unless dump_src goto after_src_dump
263 print "\n\nSource dump:\n"
264 print source
265 after_src_dump:
272b0b9 @tewk languages/cardinal Initial checkin
tewk authored
266
06b8a84 @tewk [Cardinal] refactor to follow Perl6 AST/OST example
tewk authored
267 unless dump_pir goto after_pir_dump
272b0b9 @tewk languages/cardinal Initial checkin
tewk authored
268 print "\n\nPIR dump:\n"
269 print pir
06b8a84 @tewk [Cardinal] refactor to follow Perl6 AST/OST example
tewk authored
270 after_pir_dump:
272b0b9 @tewk languages/cardinal Initial checkin
tewk authored
271 eq stopafter, 4, end
272
273 # Execute
274 .local pmc pir_compiler
275 .local pmc pir_compiled
276 pir_compiler = compreg "PIR"
277 pir_compiled = pir_compiler( pir )
278 pir_compiled()
279 end
280
281 err_match_fail:
282 print "Parse failed on "
283 print filename
284 print "\n"
285 exit -1
286
287 err_no_ast:
288 print "Unable to construct AST.\n"
289 exit -2
290
291 err_no_ost:
292 print "Unable to construct OST.\n"
293 exit -3
294
295 err_no_pir:
296 print "Unable to construct PIR.\n"
297 exit -4
298
299 end:
300 exit 0
301 .end
302
303 # Read in the source from a file
304 .sub _get_source
305 .param string filename
306
307 $S1 = _slurp_file(filename)
308 .return ($S1)
309
310 err_no_file:
311 print "You must supply a Ruby file to parse.\n"
312 end
313 .end
314
315 .sub _slurp_file
316 .param string filename
317 .local pmc filehandle
318 filehandle = open filename, "<"
319 unless filehandle goto err_no_file
320 $S1 = read filehandle, 65535
321 close filehandle
322 .return ($S1)
323
324 err_no_file:
325 print "Unable to open file "
326 print filename
327 print "\n"
328 end
329 .end
330
331 =head1 LICENSE
332
333 Copyright (c) 2005 The Perl Foundation
334
335 This is free software; you may redistribute it and/or modify
336 it under the same terms as Parrot.
337
338 =head1 AUTHOR
339
340 Kevin Tew <kevintew@tewk.com>
341
342 =cut
Something went wrong with that request. Please try again.