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