Parrot Allison Randal The Perl Foundation & O'Reilly Media, Inc.
There's an odd misconception in the computing world that writing compilers is hard. This view is fueled by the fact that we don't write compilers very often. People used to think writing CGI code was hard. Well, it is hard, if you do it in C without any tools.
Python Ruby Perl 5 Perl 6 PHP Parrot VM
Objective-C Lua Javascript Python Ruby Scheme Tcl Dylan Perl 5 Perl 6 PHP TeX macro Invent your language here. Forth Parrot VM
Dynamic Languages ● Runtime vs. compile-time ● Extend code (eval, load) ● Define classes ● Alter type system ● Higher-order functions ● Closures, Continuations, Coroutines
Why? ● Revolution ● Powerful tools ● Portability ● Interoperability ● Drive innovation
Register-based ● Stack operations
Register-based ● Stack operations 14
Register-based ● Stack operations 9 14
Register-based ● Stack operations 9 add 14
Register-based ● Stack operations 23
Register-based ● Stack operations ● Register operations 9 14
Register-based ● Stack operations ● Register operations 9 14 add
Register-based ● Stack operations ● Register operations 23 9 14
Register-based ● Stack operations ● Register operations ● Fewer instructions ● Hardware registers ● Register spilling ● Flexible register sets
Continuation Passing Style ● Stack-based control flow
Continuation Passing Style ● Stack-based control flow foo
Continuation Passing Style ● Stack-based control flow foo return addr
Continuation Passing Style ● Stack-based control flow 12 9 foo return addr
Continuation Passing Style ● Stack-based control flow return addr
Continuation Passing Style ● Stack-based control flow
Continuation Passing Style ● Stack-based control flow ● Continuation-based control flow Context: main
Continuation Passing Style ● Stack-based control flow ● Continuation-based control flow Context: main Context: foo
Continuation Passing Style ● Stack-based control flow ● Continuation-based control flow Continuation Context: main Context: foo
Continuation Passing Style ● Stack-based control flow ● Continuation-based control flow Continuation Context: main Context: foo Context: bar
Continuation Passing Style ● Stack-based control flow ● Continuation-based Continuation control flow Continuation Context: main Context: foo Context: bar
Continuation Passing Style ● Stack-based control flow ● Continuation-based Continuation control flow Continuation Context: ● Deeply nested contexts main ● Tail recursion Context: foo Context: bar
Parser Grammar Engine (PGE) Parrot Compiler Toolkit (PCT) NQP HLLCompiler PAST PIR (intermediate representation) PASM (assembly language) Parrot VM I/O GC Events Exceptions OO IMCC Unicode Threads STM JIT
PASM ● Assembly language ● Simple syntax ● add I0, I1, I2 ● Human-readable bytecode
PIR ● Syntactic sugar ● $I0 = $I1 + $I2 ● ● Named variables ● .local int myvar ● $I0 = myvar + 5 ● ● Sub and method calls ● result = object.'method'($I0)
NQP ● Not Quite P(erl|ython|HP|uby) ● Lightweight language ● $a := 1; ● print($a, "\n"); ● ● Compiler tools ● $past := PAST::Op.new( :name('printnl') );
Parser Grammar Engine ● Regular expressions ● Recursive descent ● Operator precedence parser
HLLCompiler ● Base library ● Quick start ● Common features
Pynie ● Download ● http://www.parrotcode.org ● Build ● $ perl Configure.PL ● $ make test ● Language ● $ cd languages/pynie ● $ make test
Pynie ● hello.py ● print "Hello, World!" ● Run ● $ parrot pynie.pir hello.py
pynie.pir ● 67 lines ● Half documentation ● c = hllcompiler.new() ● c.language('Pynie') ● c.parsegrammar('Pynie::Grammar') c.parseactions('Pynie::Grammar::Actions')
Grammar.pg ● Parser ● token stmt_list { ● <simple_stmt> [ ';' <simple_stmt> ]* ';'? ● {*} ● } ● Familiar? ● stmt_list ::= ● simple_stmt (";" simple_stmt)* [";"]
Actions.pct ● Transform to AST ● method identifier($/) { ● make PAST::Var.new( :name( ~$/ ), ● :scope('package'), ● :node($/) ● ); ● }
Value Transformation 42
Value Transformation Parser grammar rule “integer” 42 \d+ token integer { \d+ }
Value Transformation Parser grammar Parse tree rule “integer” <integer> 42 \d+ value: 42
Value Transformation Parser grammar Parse tree Transform rule rule “integer” <integer> 42 \d+ integer value: 42 method integer($/) {...}
Value Transformation Parser grammar Parse tree Transform rule rule “integer” <integer> 42 \d+ integer value: 42 AST node <PAST::Val> value: 42 returns: Integer
Value Transformation Parser grammar Parse tree AST tree rule “integer” grammar rule <integer> 42 \d+ integer value: 42 AST node Transform rule <PAST::Val> value: 42 PAST::Val returns: Integer ost = self.as_post(ast)
Value Transformation Parser grammar Parse tree Transform rule rule “integer” <integer> 42 \d+ integer value: 42 AST node Transform rule OST node <PAST::Val> <POST::Op> value: 42 PAST::Val result: 1 returns: Integer
Value Transformation Parser grammar Parse tree Transform rule rule “integer” <integer> 42 \d+ integer value: 42 AST node Transform rule OST node Transform rule <PAST::Val> <POST::Op> value: 42 PAST::Val POST::Val result: 1 returns: Integer self.pir(ost)
Value Transformation Parser grammar Parse tree Transform rule rule “integer” <integer> 42 \d+ integer value: 42 AST node Transform rule OST node Transform rule <PAST::Val> <POST::Op> value: 42 PAST::Val POST::Val result: 1 returns: Integer 42
Operator Transformation 6 * 9
Operator Transformation Parser grammar OPP rule 6 * 9 infix:* proto infix:* is looser(prefix:+) {...}
Operator Transformation Parser grammar Parse tree OPP rule <expr> 6 * 9 infix:* type: 'infix:*' <integer> <integer> value: 6 value: 9
Operator Transformation Parse tree <expr> type: 'infix:*' <integer> <integer> value: 6 value: 9
Operator Transformation Parse tree Transform rule <expr> expr type: 'infix:*' <integer> <integer> value: 6 value: 9
Operator Transformation Parse tree Transform rule AST tree <expr> <PAST::Op> expr type: 'infix:*' name: infix:* <PAST::Val> <PAST::Val> <integer> <integer> value: 9 value: 6 value: 6 value: 9 returns: Integer returns: Integer
Operator Transformation AST tree <PAST::Op> name: infix:* <PAST::Val> <PAST::Val> value: 9 value: 6 returns: Integer returns: Integer
Operator Transformation Transform rule AST tree <PAST::Op> PAST::Op name: infix:* <PAST::Val> <PAST::Val> value: 9 value: 6 returns: Integer returns: Integer
Operator Transformation Transform rule AST tree OST tree <PAST::Op> <POST::Ops> PAST::Op name: infix:* <PAST::Val> <PAST::Val> <POST::Op> variable value: 9 value: 6 name: n_mul setup returns: Integer returns: Integer <POST::Ops> <POST::Ops> <POST::Ops> result: $P1 result: 6 result: 9
Operator Transformation ● .sub _main :main ● new $P1, 'Integer' ● new $P2, 'Integer' ● set $P2, 6 ● new $P3, 'Integer' ● set $P3, 9 ● mul $P1, $P2, $P3 ● .end
Examples ● In the Parrot distribution: ● examples/tutorial/*.pir
Questions? ● Further Reading – “Continuations and advanced flow control” by Jonathan Bartlett <http://www.ibm.com/developerworks/linux/library/l- advflow.html> – “The case for virtual register machines” by Brian Davis, et al. <http://portal.acm.org/citation.cfm?id=858575>
Recommend
More recommend