Allison's Journal Allison's use Perl Journal en-us use Perl; is Copyright 1998-2006, Chris Nandor. Stories, comments, journals, and other submissions posted on use Perl; are Copyright their respective owners. 2012-01-25T02:01:30+00:00 pudge Technology hourly 1 1970-01-01T00:00+00:00 Allison's Journal Installing Pod::Simple on Solaris 9/10 <p> After answering this in several individual emails over a year or so, I figure I'll stick it somewhere googleable. If you're attempting to install Pod::Simple and get something like the following error:</p><blockquote><div><p> <tt>Can't locate Pod/ in @INC (@INC contains: [...]) at<nobr> <wbr></nobr>/usr/local/lib/perl5/5.8.8/Pod/ line 35.<br>BEGIN failed--compilation aborted at<nobr> <wbr></nobr>/usr/local/lib/perl5/5.8.8/Pod/ line 35.<br>Compilation failed in require at<nobr> <wbr></nobr>/usr/local/lib/perl5/5.8.8/ExtUtils/Command/ line 92.<br>*** Error code 2<br>make: Fatal error: Command failed for target `manifypods'</tt></p></div> </blockquote><p> You've ended up with a version of Pod::Man installed that has a dependency on Pod::Simple, without first installing Pod::Simple. (That shouldn't be possible, since Pod::Man has a check for Pod::Simple in the install process, but that doesn't guarantee it can never happen, especially with a vendor install of Perl.) </p><p> So, the thing to do is run the install for Pod::Simple twice. (The first time through you won't get the manpage entries for the modules, but otherwise it'll install fine. The second time through you'll get the manpage entries too.) The first time you'll need to edit the Makefile manually. Find the line that looks like:</p><blockquote><div><p> <tt># --- MakeMaker top_targets section:<br>all<nobr> <wbr></nobr>:: pure_all manifypods</tt></p></div> </blockquote><p> and change it to:</p><blockquote><div><p> <tt>all<nobr> <wbr></nobr>:: pure_all</tt></p></div> </blockquote><p> Then run 'make', 'make test', and 'make install'. Once you've done that go back and run:</p><blockquote><div><p> <tt>make clean<br>perl Makefile.PL<br>make<br>make test<br>make install</tt></p></div> </blockquote><p> Once you have Pod::Simple installed, you won't get that error from Pod::Man anymore, so manifypods should work for everything else you're installing too.</p> Allison 2008-09-11T09:30:17+00:00 journal Perl and LaTeX <p> I'm working on the final typesetting for the <a href="">mod_perl 2 User's Guide</a>. My brain is filled with style conventions, and index items, and installation options, Oh My! In the process, I've nearly tripled the size of chromatic's <a href="">Pod::PseudoPod::LaTeX</a> (a subclass of my <a href="">Pod::PseudoPod</a>), carrying it from the styles needed for a novel (text and headings), to the styles needed for a full-powered technical book. </p><p> I have to say, I'm really loving LaTeX. It has a package for <b>everything</b>. A bit like Perl, really. Also like Perl in its lovably quirky nature.</p> Allison 2007-08-15T19:22:41+00:00 journal Parrot 0.4.13 "Clifton" Released <p>On behalf of the Parrot team, I'm proud to announce Parrot 0.4.13 "Clifton." <a href="">Parrot</a> is a virtual machine aimed at running all dynamic languages.</p><p>Parrot 0.4.13 can be obtained via <a href="">CPAN</a> (soon), or <a href="">follow the download instructions</a>.</p><p>Parrot 0.4.13 News:</p><blockquote><div><p> <tt>- Languages:<br> + Updated Lisp, Lua, PHP ("Plumhead"), Python ("Pynie"), ABC,<br>&nbsp; &nbsp;WMLScript, and Tcl ("ParTcl").<br> + Perl 6 passes all of the sanity tests.<br> + PGE supports latest Perl 6 grammar syntax. Perl 6, Python<br>&nbsp; &nbsp;("Pynie"), and ABC parsers updated to match.<br> + Updated PHP ("Plumhead") to Antlr 3.0.<br> + Lua added the beginnings of a PGE/TGE based compiler (not yet<br>&nbsp; &nbsp;replacing the Perl/Yapp compiler).<br> + Lisp updated for current features, added a test suite.<br>- Core Implementation:<br> + Filled in features and backward compatibility for PDD 15 objects.<br>&nbsp; &nbsp;New object metamodel passes 85% of old test suite.<br> + GCC API symbols are visible externally only when explicitly exported.<br> + Added generated GCC compiler attributes to increase warnings, and<br>&nbsp; &nbsp;cleaned up resulting warnings.<br> + Code cleanup efforts and fixed memory leaks by the cage cleaners,<br>&nbsp; &nbsp;resulting in notable speed increases.<br>- Misc:<br> + Updated Parrot distribution to Artistic License 2.0, from dual<br>&nbsp; &nbsp;Artistic 1/GPL license.<br> + SDL examples brought up-to-date with current features.</tt></p></div> </blockquote><p>For those who would like to develop on Parrot, or help develop Parrot itself, we recommend using <a href="">Subversion</a> or <a href="">SVK</a> on <a href="">our source code repository</a> to get the latest and best Parrot code. The next scheduled release is July 17, 2007.</p><p>Thanks to all our contributors for making this possible, and our sponsors for supporting this project.</p><p>Enjoy!</p> Allison 2007-06-20T00:03:44+00:00 parrot Perl saves the day <a href="">Tarzan loves Perl</a> Allison 2007-01-12T08:27:02+00:00 journal Punie tests all pass again <p> I converted Punie over to using PAST-pm's way of representing conditionals. I tried out altering Punie's parsing of conditionals to match Perl 6's, but it turns out parsing else/elsif blocks recursively results in simpler parse-&gt;past transformation rules than the iterative way Perl6 is parsing them. So, I kept Punie's existing parse rules. </p><p> I had to set the 'pasttype' attribute in the PAST::Op node for '=' to 'assign' rather than setting the 'pirop' attribute to 'assign'. This stops the PIR generator from trying to assign 3 values to a string. It's an oddish work-around, possibly a bug in the past-&gt;post transformation, I'll come back and look at it later. </p><p> I had to set Punie variables to vivify as undef, by setting the 'viviself' attribute on PAST::Var nodes to '.Undef'. </p><p> I changed all the builtin operator names to have 'infix:' on the front. This is the Perl 6 way of naming operators, and I haven't decided if I want to keep it. I'll come back to it later. </p><p> And finally, I had to set '&amp;&amp;' operators to a 'pasttype' of 'if', and '||' operators to a 'pasttype' of 'unless'. </p><p> With those changes, all Punie test pass, so I'm checking it in. The next step is some refactoring and cleanup.</p> Allison 2007-01-02T06:51:26+00:00 journal Punie printing again <p> I'm in the process of porting Punie to the new Partridge (PAST-pm) toolchain. Tonight I got single and double quoted strings to work, thanks to Patrick's solution of <a href="">leaving off the 'ctype' attribute from the PAST::Val node</a>, and by retrieving the full matched string including surrounding quotes instead of the bare string contents (so it can pass through exactly as parsed). </p><p> I also switched comma ops over from the custom parse I was using before to a standard operator-precedence parse, and fixed up the AST transforms to handle the restructured parse tree. With these two changes, all of Punie's t/io_print.t is now passing. </p><p> The remaining failing test files are t/base_cond.t, t/base_if.t, and t/comp_cmdopt.t. All of these depend on conditionals, so there's a good chance that updating Punie to use the new toolchain's way of producing conditionals will be the final step of the port.</p> Allison 2006-12-24T07:46:28+00:00 journal The 6 Days of Christmas Now we really have to call Parrot's compiler tool chain Partridge. Thanks to <a href="">Jonathan Worthington</a>.<blockquote><div><p><i>On the first day of Christmas my true love sent to me,<br> A Partridge with a parse tree, </i></p><p><i> On the second day of Chritmas my true love sent to me,<br> Two ASTs,<br> And a Partridge with a parse tree, </i></p><p><i> On the third day of Chritmas my true love sent to me, <br> Three POST nodes,<br> Two ASTs,<br> And a Partridge with a parse tree, </i></p><p><i> On the forth day of Chritmas my true love sent to me,<br> Four bytes of bytecode,<br> Three POST nodes,<br> Two ASTs,<br> And a Partridge with a parse tree, </i></p><p><i> On the fifth day of Chritmas my true love sent to me,<br> FIVE LANGUAGES COMPILING!<br> Four bytes of bytecode,<br> Three POST nodes,<br> Two ASTs,<br> And a Partridge with a parse tree, </i></p><p><i> On the sixth day of Chritmas my true love sent to me,<br> Six versions of Perl,<br> FIVE LANGUAGES COMPILING!<br> Four bytes of bytecode,<br> Three POST nodes,<br> Two ASTs,<br> And a Partridge with a parse tree. </i></p></div> </blockquote> Allison 2006-11-27T22:38:28+00:00 journal Partridge Ketchup <p> Okay, I'm not even going to try to catch up with all the Parrot stuff I've done since I last posted. The mailing list archives pretty much cover it. </p><p> On Friday I visited Jerry Gay and his wife Bethany. Jerry and I spent some time hacking on Parrot, and I made a good bit of progress on converting Punie over to Patrick's new PAST, POST, and HLLCompiler module. Over the weekend I've pushed the port to the point where it's generating valid PIR for many of Punie's basic low-level constructs. Some of the larger pieces are going to need a serious conceptual refactor: the top-level structure of the AST, conditionals, comma lists, etc. The new PAST has ways of handling them, they're just very different than Punie's current implementation. </p><p> On a related note, here's why the new compiler toolchain should be called "Partridge":</p><blockquote><div><p> <tt>partridge<br><br><br>par[s]..e<br>pa.tri[ck]</tt></p></div> </blockquote><p> Obvious, isn't it?</p> Allison 2006-11-27T07:36:36+00:00 journal My other journal <p> This is <a href="">Allison's other journal</a>. Not a replacement, just an addition. </p><p> Oh yeah, I've got quite a bit of Parrot stuff to catch up on here.</p> Allison 2006-09-12T07:11:05+00:00 journal Pick up, dust off, keep walking... <p> My past month hasn't been entirely absorbed by troubleshooting failing hardware and setting up new hardware. Despite working on a different box pretty much every week, I've made significant <a href="">progress on TGE</a>. I still have more refactors planned, but I'll be spending the next couple of weeks working on Punie, to see how far I can push it before <a href="">my YAPC::NA talk</a>. </p><p> Yesterday I added scalar variables and the assignment operator to Punie. Today I added the comparison operators <code>==</code>, <code>!=</code>, <code>&lt;</code>, <code>&gt;</code>, <code>&lt;=</code>, <code>&gt;=</code>, <code>eq</code>, <code>ne</code>, <code>lt</code>, <code>gt</code>, <code>le</code>, and <code>ge</code>. I'm impressed by how much easier and faster it is to develop Punie after all the TGE improvements. </p><p> Today is a milestone for Punie: it passed its first complete test file from the Perl 1 test suite.</p> Allison 2006-06-16T05:39:59+00:00 journal Dapperiffic I just installed <a href="">Ubuntu 6.06</a> ("Dapper Drake") on my shiny new linux desktop. I'm quite happy with it. It seems almost too easy. X works, the sound works. I didn't spend hours tweaking the configuration. It just works. It comes with Perl 5.8.7, and a quick <code>aptitude</code> command got me SVK 1.06 (okay, they're a version behind on both, but it's a liveable lag, instead of the usual painful gap). I've been using Debian for years now, and I didn't expect the bit of spit-n-polish on the surface would make much difference. But it does. I can't quite explain it, but it's something like: "Strong reliable server, but also a comfortable desktop." Allison 2006-06-03T07:00:28+00:00 journal A few words <ul> <li>Thunderbird rocks!</li> <li>PGE rules!</li> <li>A laptop that dies (the horrible, unrecoverable hard drive grind of death) less than a week after you switch your life over to it is not cool.</li> <li>Having the old laptop to fall back on is good, unless the reason you were switching to a new one is that the old one was dying.</li> <li>Having an even older laptop (multicolor iBook, circa the late '90s) around the house as a spare is a good idea.</li> <li> won't help you if exim and subversion are trying to use two different incompatible instances of in two different directories and you're using exim and subversion in the same perl process. But then, there really isn't a good reason for exim and subversion to be using different versions of Cruft accumulates on older systems, but it's easy to clean up.</li> </ul> Allison 2006-05-10T18:31:14+00:00 journal What's licensing got to do with it? <p> I've spent a good part of the past week answering <a href="">Pugs legal questions</a>. Still haven't cleared up all the confusion there, but we're close. </p><p> So why is this licensing stuff important? Well, part of Larry's original intent with the Artistic License was to allow proprietary and free versions of Perl to peacefully coexist. It would be great if everyone would peacefully coexist without encouragement, but since this world isn't always nice, we need other tools. The Artistic License helps by limiting the ways people can release a proprietary version, and also by saying what it takes to be considered a "free" version. </p><p> To do this it relies on copyright law, the same as the GPL and most other software licenses. The word "copyright" can be loosely translated into plain English as "an artist's right to copy or change their work, or to give it to someone else". In the commercial world, copyright law, is sometimes used to take away freedoms (which is unfortunate). But in the open source/free software world we use copyright law to promote greater freedom. (<i>Hence the term "copyleft" which is a pun on the fact that the word "right" is sometimes used to refer to conservative political views, and "left" to more liberal ones.</i>) </p><p> So, if you're wondering why someone would object to having their code released as public domain, or why it's worth spending a week or so to get the terms right, it's this: we want to protect and promote the freedoms of our users.</p> Allison 2006-04-25T07:44:00+00:00 journal On the philosophy of conditionals Today I implemented <code>elsif</code> and <code>else</code> blocks in Punie. Fairly straightforward. One interesting tidbit: the logic for translating conditionals down to PIR is actually simpler if you reverse it. So this bit of Perl 1 code:<blockquote><div><p> <tt>if (1) {<br>&nbsp; print "is true\n";<br>} elsif (2) {<br>&nbsp; print "else is true\n";<br>} else {<br>&nbsp; print "is false\n";<br>}</tt></p></div> </blockquote><p>translates to something like this bit of PIR code:</p><blockquote><div><p> <tt>unless 1 goto is_false<br># if<br>&nbsp; &nbsp; print "is true\n"<br>&nbsp; &nbsp; goto end_if<br>is_false:<br> <br>unless 2 goto else_is_false<br># elsif<br>&nbsp; &nbsp; print "else is true\n"<br>&nbsp; &nbsp; goto end_elsif<br>else_is_false:<br> <br># else<br>&nbsp; &nbsp; print "is false\n"<br>end_elsif:<br>end_if:</tt></p></div> </blockquote><p>This is far easier to generate from a tree than the alternative:</p><blockquote><div><p> <tt>if 1 goto is_true<br>if 2 goto else_is_true<br># else<br>&nbsp; &nbsp; print "is false\n"<br>&nbsp; &nbsp; goto end_if<br>else_is_true:<br># elsif<br>&nbsp; &nbsp; print "else is true\n"<br>&nbsp; &nbsp; goto end_if<br>is_true:<br>&nbsp; &nbsp; print "is true\n"<br>end_if:</tt></p></div> </blockquote><p>I've noticed this in general when writing PIR code --that <code>unless</code> gives me a control flow more similar to the <code>if</code> of a high-level language. It's because the actual meaning is reversed: HLL <code>if</code> means "if X is true do the following chunk of code" while the assembly <code>if</code> means "if X is true skip over the following chunk of code to label Y".</p> Allison 2006-04-18T06:37:34+00:00 journal pre-compiled rules for TGE <p> Today I added a tool for TGE (<code>compilers/tge/tgc.pir</code>) that outputs the compiled grammars as PIR files so they can be pre-compiled to bytecode. I also updated Punie to use it. It's a small optimization, but it doubles the speed of the Punie test suite. </p><p> Before: <i> Files=19, Tests=55, 48 wallclock secs (28.47 cusr + 5.01 csys = 33.48 CPU) </i> </p><p> After: <i> Files=19, Tests=55, <b>26</b> wallclock secs (<b>11.48</b> cusr + 4.53 csys = <b>16.01</b> CPU) </i> </p><p> I've been putting off this addition on the general principle of avoiding premature optimizations, but now that TGE has other users (APL, Scheme, and another one soon) I feel more responsible to develop features as they request them.</p> Allison 2006-04-05T07:13:52+00:00 journal Announcing my candidacy for the presidency <p>Hey, why not? All the <a href="">cool</a> <a href="">kids</a> are doing it!<nobr> <wbr></nobr>:) </p><p>I would like to announce my candidacy for the presidency of The Perl Foundation. My platform is as follows: </p><ol> <li> I will work long hours without pay or thanks.</li> <li> I will spend my personal income and vacation time to attend Perl conferences around the world.</li> <li> I will always be enthusiastic about new volunteers, no matter how many times I hear:<blockquote><div><p> <i> "Hi, I'd like to volunteer."<br> "Great! What would you like to do?"<br> "I don't know."<br> "How about X?"<br> "I don't want to do *that*." </i></p></div> </blockquote><p>Or:</p><blockquote><div><p> <i> "Hi, I'd like to volunteer to do Y."<br> "Great!"</i> 1 month later: <i>"Hey, how's Y going?"<br> &lt;silence&gt; </i></p></div> </blockquote></li> <li> I will consistently have faith that I can determine the answer to the problems at hand, because that's my job. When one solution fails, I will try another, and another, and another. When a solution succeeds, I will not be disappointed that no one notices.</li> <li> I will always be aware that the title is just a title and holds no real value.</li> <li> I will face criticism kindly, and not take it personally. I will honestly assess my actions and the actions of other volunteers to look for ways we can improve. I will also accept that some improvements take time, and appreciate short-term progress towards larger improvements.</li> <li> I will always look for good ideas, but also remember that not all ideas are good ideas.</li> <li> I will hold on to my sense of humor and understand when a joke contains a serious truth and when a serious statement is a joke.</li> </ol><p>Thanks for listening, and I look forward to your support in the 2002 elections!<nobr> <wbr></nobr>;)</p> Allison 2006-03-30T06:41:27+00:00 journal I/O I'm part way through <code>else</code> and <code>elsif</code> blocks in Punie, but have shifted focus for the past couple of weeks to the I/O design document for Parrot. This covers both traditional "filehandle" I/O and network socket operations (in Parrot they're all implemented with ParrotIO objects). I checked in a second draft on Friday, after a round of comments on the Parrot mailing list. Allison 2006-03-21T19:44:07+00:00 journal Punier operators <p>I added a few more operators today: multiplication, division, modulus, repetition, concatenation, bitwise left shift, bitwise right shift, and bitwise AND, OR, and XOR. Because of the way the operator precedence parser is integrated, all I had to add for each operator was one entry in the Punie grammar module, one entry in a lookup table, and then test it. Schweet! </p><p> I also did some documentation updates and code cleanup, since we have a Parrot release coming up soon.</p> Allison 2006-02-21T06:44:44+00:00 journal Punie operators Yesterday and today I finished plugging in the operator precedence parser. (Three cheers to Patrick for his work that made it possible!) Punie can now handle statements like:<blockquote><div><p> <tt>print 1 + 2 + 3;</tt></p></div> </blockquote><p>and</p><blockquote><div><p> <tt>print 1 - 2, "\n", 7 - 1, "\n";</tt></p></div> </blockquote><p>and</p><blockquote><div><p> <tt>if (42 + 11) {<br>&nbsp; print "ok 1\n";<br>}</tt></p></div> </blockquote><p>I first implemented it with most of the work happening in the POST-&gt;PIR transformation, but that turned out to be pretty hacky. So, I redid the bottom half with most of the work in the PAST-&gt;POST transformation. This is much cleaner, and produces POST structures that are quite close to the final PIR syntax. While I was at it, I refactored the code for printing lists, so it also splits out the opcodes during the PAST-&gt;POST transformation. Both the operator implementation and the print statement refactor rely heavily on the new <code>POST::Ops</code> node, so it is turning out to be quite useful.</p> Allison 2006-02-16T06:50:25+00:00 journal Punie do, if, unless <p> Whoops, no journal entries in a while. Mostly I've been working on <a href="">bug fixes</a>. Not exactly progress on the Punie compiler, but I consider it progress, since one of the main goals of Punie is to give Parrot/PGE/TGE a workout. </p><p> Today I added simple <code>do</code> block support. One "ah-ha" moment in there resulted in me adding a new POST node type: <code>Ops</code>. This node is just a sequence of opcode statements, and the conversion to PIR flattens it out. The way TGE works at the moment, the code for dealing with a transformation that can return either a single opcode or multiple opcodes is a bit clunky. This happens when a single HLL statement breaks down into multiple assembly operations (like a block with multiple statements, or a single <code>print</code> of a list that turns into multiple independent <code>print</code> statements in POST). Adding <code>POST::Ops</code> means this fragmentation isn't an issue. The transformation always returns a single node, even if it's generating multiple opcodes. (I haven't decided if this is ultimately the right solution yet. It'll partly depend on how useful it proves to be across the rest of the language.) </p><p> I also added simple conditional support today, such as:</p><blockquote><div><p> <tt>if (1) {<br>&nbsp; &nbsp; print "hello world";<br>}<br> <br>unless (0) {<br>&nbsp; &nbsp; print "hello world";<br>}</tt></p></div> </blockquote><p>It only supports simple values as conditional expressions so far (that's just about all Punie supports as expressions so far anyway). It also doesn't support <code>else</code> or <code>elsif</code> blocks yet. That's probably next. Although, it's also time to work on the operator precedence parser again, as Patrick pushed it two steps further while I was bug chasing. Decisions, decisions.</p> Allison 2006-02-14T05:00:47+00:00 journal calling Pod::Webserver users Looking for pre-release <a href="">comments on Pod::Webserver 3.04</a>. Allison 2006-02-02T05:33:39+00:00 journal Punie value types I modified Punie's grammars yesterday to make it a little smarter about how it handles different kinds of literal values. It now annotates the PAST and POST nodes with info about what kind of value was extracted in the parse. This solves Bernhard's problem with double quotes appearing around integers. While I was at it, I went ahead and added support (and tests) for floating point numbers and single quoted strings. Allison 2006-01-21T23:00:50+00:00 journal Punie commas Last journal post I mentioned I was in the process of deciding which way to transform the tree structure for comma lists. Between options A, B, and C, I chose option D: modify the parser grammar. I actually implemented option B, but the result was somewhat tortured (a "code smell"), and it looked like A and C would be equally tortured. Interestingly, the way you write the parser grammar can make it easier or harder to transform the resulting parse tree. In this case, following the old yacc pattern (cexpr rule within a cexpr rule) made for a nasty transformation, while changing it to a simple repetition allowed the transformation to fall out in fairly few lines of code. I'm happy.<nobr> <wbr></nobr>:) Allison 2006-01-12T21:33:10+00:00 journal strings, commas, and operator precedence <p> On my Parrot days this week I started to add operator support (just + and - to start), but ran into a snag with PGE's operator precedence parser. I expect it's just an undocumented necessary step, so I dropped a note to Patrick and set that aside. </p><p> Instead, I made the changes to take advantage of fact that <code>PGE::Text::bracketed</code> now extracts the bracketed value for you. (Thanks Patrick!) And then I started on comma lists. I've got it parsing and transforming to PAST. I'm currently trying to decide what the best way is to handle the transformation to POST. Specifically, I want to transform a Punie statement such as:</p><blockquote><div><p> <tt>print 1, 2;</tt></p></div> </blockquote><p>into the PIR:</p><blockquote><div><p> <tt>print 1<br>print 2</tt></p></div> </blockquote><p>So internally, I'm splitting a <code>PAST::Op</code> (<code>print</code>) node with a <code>PAST::Op</code> (<code>comma</code>) child into two equal level <code>POST::Op</code> (<code>print</code>) nodes. There are several ways to do it. It's mainly a question of where I want the complexity to bubble up (waterbed theory). </p><p>~~~~~~~~~~~~~~~~~~~~ </p><p> One interesting little tidbit: because PGE is a recursive descent parser, I can't just directly translate certain rules from the original perl.y. The biggest problem is left recursion:</p><blockquote><div><p> <tt>&nbsp; rule expr&nbsp; &nbsp;{<br>&nbsp; &nbsp; &nbsp; &lt;PunieGrammar::expr&gt; = &lt;PunieGrammar::expr&gt;<br>&nbsp; &nbsp; &nbsp; | &lt;PunieGrammar::expr&gt; \+ &lt;PunieGrammar::expr&gt;<br>&nbsp; &nbsp; &nbsp; |<nobr> <wbr></nobr>...<br>&nbsp; &nbsp; &nbsp; | &lt;PunieGrammar::term&gt;<br>&nbsp; }</tt></p></div> </blockquote><p>In a recursive descent parser the left recursion is infinite. One solution is to eliminate the left recursion and translate that to something like:</p><blockquote><div><p> <tt>rule expr {<br>&nbsp; &nbsp; &lt;PunieGrammar::term&gt; &lt;PunieGrammar::rexpr&gt;<br>}<br> <br>rule rexpr {<br>&nbsp; &nbsp; = &lt;PunieGrammar::rexpr&gt;<br>&nbsp; &nbsp; | \+ &lt;PunieGrammar::rexpr&gt;<br>&nbsp; &nbsp; |<nobr> <wbr></nobr>...<br>&nbsp; &nbsp; | &lt;null&gt;<br>}</tt></p></div> </blockquote><p>Unfortunately, this produces a match tree that's less-than-ideal for working out operator precedence. That's why PGE has a built-in operator precedence (shift/reduce) parser.</p> Allison 2006-01-08T04:19:46+00:00 journal Blink, blink, sunlight? <p> I've been off work for most of the past two weeks. I wish I could say I got lots of lovely development time in there, but unfortunately I spent most of it doped up and lying on a couch with a heating pad to my face trying to get my jaw to unlock (complications after getting all 4 wisdom teeth pulled). It's finally unlocked now and last night I got to eat steak for the first time. That may very well be the most delicious steak I've ever tasted.<nobr> <wbr></nobr>:) </p><p> I'm still not quite 100%, but I plan to get back to my normal development schedule next week. </p><p> One bit of development news I forgot to post before I went AFK: I finished the switch to using a pre-compiled PGE grammar for parsing Punie. This is a tiny speed boost, but more importantly it makes the Punie grammar easier to expand (and maintain), because the grammar source is abstracted out into a separate file, instead of being mixed up with PIR code.</p> Allison 2005-12-30T22:08:49+00:00 journal Everyday magic <p> Do you have a shortcut or two you use all the time when you're writing Perl code? I don't mean how you condense your code from 12 lines to 3 characters, but things like the Vim or Emacs incantations you can't live without, or Firefox shortcuts so you can just type "cpan Module::Name" in the URL bar to jump to results. Or, perhaps something written in Perl that's a little off-the-wall but makes your life easier or more fun, like your favorite Perl GUI widget, or a Perl-controlled alarm clock? </p><p> If you have an idea like this, or if you just want to debate the rules of the CPAN drinking game, drop us a note at <a href=""></a> (this will send your message to the list and subscribe you). The best ideas will get added to a book called Perl Hacks.</p> Allison 2005-12-13T16:50:48+00:00 journal Punie, print "ok 1" <p> Today I worked on expanding Punie. Until now it has only been able to print a single digit, and only allowed one print statement in a file. It can now handle more than one statement in a file, and can print multi-digit integers and double-quoted strings.</p><blockquote><div><p> <tt>&nbsp; print 1;<br>&nbsp; print 23;<br>&nbsp; print "ok 1\n";</tt></p></div> </blockquote><p> The double-quoted strings use the Text::Bracketed feature Patrick developed for PGE. </p><p> I've also started working on switching the Punie grammar over to the new, more maintainable way PGE offers for defining grammars. So, instead of:</p><blockquote><div><p> <tt>p6rule('\d+ | &lt;PGE::Text::bracketed: "&gt;', 'PunieGrammar', 'term')<br>...</tt></p></div> </blockquote><p>I can now say:</p><blockquote><div><p> <tt>&nbsp; grammar PunieGrammar;<br>&nbsp; rule term&nbsp; &nbsp; { \d+ | &lt;PGE::Text::bracketed: "&gt; }<br>&nbsp;<nobr> <wbr></nobr>...</tt></p></div> </blockquote> Allison 2005-12-08T07:13:14+00:00 journal Punie: AST to OST to PIR <p>This week I worked on the tree grammar to transform Punie's abstract syntax tree (PAST) to an opcode syntax tree (POST). That went along pretty quickly, even with a little time wasted down an <a href="">odd rabbit hole</a> or two. The current set of POST nodes are minimal because I'm still only trying to compile "<code>print 1;</code>". They'll grow and change as I expand the compiler. </p><p>Since I had a little time left over, I went ahead and started working on the next step: converting POST into something executable. For now, PIR output is good enough. I just need to close the final gap so I can run tests on Perl 1 code. So, I threw together a little mock-up to fill the gap. It's a TGE tree grammar, but instead of transforming one tree to another tree, it transforms a tree to a string of source code. It's kind of like a PGE grammar in reverse. </p><p>That also went pretty fast and I still had a little time left over, so I went ahead with the last step, which is compiling and excuting the PIR code. That part only takes a few lines of code. </p><p>So, I swapped <code>punie2.pir</code> in as the main <code>punie.pir</code>, ran the language tests and they passed. Yay! </p><p>Next week I'll expand Punie so it does more than just print a single digit.</p> Allison 2005-12-02T05:34:20+00:00 journal Punie to AST <p> I've checked in the code to transform Punie match objects into AST trees. The core pieces are: </p><ul> <li>A tree grammar for the transformation in <code>languages/punie/lib/pge2past.g</code></li> <li>A series of AST nodes in <code>languages/punie/lib/PAST/</code></li> <li>A script that parses a Punie source file, transforms the match result into an AST tree, and dumps the tree in a text format for verification. This is named <code>punie2.pir</code>, because it's still not far enough along to replace <code>punie.pir</code>.</li> </ul><p> So, if you run:</p><blockquote><div><p> <tt>parrot punie2.pir demo.p1</tt></p></div> </blockquote><p>You'll get a match object something like:</p><blockquote><div><p> <tt>"$/" =&gt; PMC 'PGE::Rule' =&gt; "print 1;" @ 0 {<br>&nbsp; &nbsp; &lt;PunieGrammar::expr&gt; =&gt; PMC 'PunieGrammar' =&gt; "print 1" @ 0 {<br>&nbsp; &nbsp; &nbsp; &nbsp; &lt;PunieGrammar::gprint&gt; =&gt; PMC 'PunieGrammar' =&gt; "print 1" @ 0 {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;PunieGrammar::expr&gt; =&gt; PMC 'PunieGrammar' =&gt; "1" @ 6 {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;PunieGrammar::term&gt; =&gt; PMC 'PunieGrammar' =&gt; "1" @ 6<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [0] =&gt; PMC 'PunieGrammar' =&gt; "print" @ 0<br>&nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; }<br>}</tt></p></div> </blockquote><p>And an AST something like:</p><blockquote><div><p> <tt>&lt;PAST::Stmts&gt; =&gt; {<br>&nbsp; &nbsp; 'source' =&gt; 'print 1;',<br>&nbsp; &nbsp; 'pos' =&gt; '0',<br>&nbsp; &nbsp; 'children' =&gt; [<br>&nbsp; &nbsp; &nbsp; &nbsp; &lt;PAST::Stmt&gt; =&gt; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'source' =&gt; 'print 1;',<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'pos' =&gt; '0',<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'children' =&gt; [<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;PAST::Exp&gt; =&gt; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'source' =&gt; 'print 1',<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'pos' =&gt; '0',<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'children' =&gt; [<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;PAST::Op&gt; =&gt; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'source' =&gt; 'print 1',<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'pos' =&gt; '0',<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'op' =&gt; 'print',<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'children' =&gt; [<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;PAST::Exp&gt; =&gt; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'source' =&gt; '1',<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'pos' =&gt; '6',<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'children' =&gt; [<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;PAST::Val&gt; =&gt; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'source' =&gt; '1',<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'pos' =&gt; '6',<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'value' =&gt; '1',<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ]<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ]<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ]<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ]<br>&nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; ]<br>}</tt></p></div> </blockquote><p> In these <code>source</code> is the chunk of source code from the original file corresponding to the current node (good for error reporting), <code>pos</code> is the offset from the start of the source file to the point where the corresponding match node started to match, and <code>children</code> is a list of child nodes for the current node. Some node types, like <code>PAST::Op</code> and <code>PAST::Val</code> have custom attributes. </p><p> I've still got some time left to work today, so I'll start on the OST now (though, I probably won't bother to post about it unless I run across something exciting).</p> Allison 2005-11-24T04:57:40+00:00 journal TGE in Punie <p>I forgot to write about my Parrot day last week. I started work on using TGE in Punie. TGE takes care of all the steps in the compiler except the last step of compiling the low-level opcode syntax tree (OST) down to Parrot bytecode. </p><p> I'm approaching it by first implementing the steps all the way through, but only for the single statement "print 1;". So far, I'm part-way through the initial step of transforming the output from TGE into the high-level abstract syntax tree. That seems kind of slow progress (to me at least), but I spent a good bit of the time waffling on what AST nodes to use. Then I decided I'd just start with something similar to Pugs' PIL, and refine it as I go along. (Okay, I decided that when I first wrote the <a href="">draft design doc</a>, but sometimes I need to decide the same thing twice before it sticks.<nobr> <wbr></nobr>:) </p><p> This week should go faster, through the AST transformations and hopefully even on to the OST transformations.</p> Allison 2005-11-22T18:38:24+00:00 journal