Sunday, September 27, 2009

Multiple Inheritance

As an update to my previous post on subclassing PAST::Node classes, I ran into another problem. It turns out that the PAST -> POST compiler knows about, and depends on the differences between, the different Node subclasses.

For example, there are multi-methods that match on the types of their parameters, so that a PAST::Block gets processed by a different method than a PAST::Var. You get the idea.

So my original idea, of deriving a set of roughly parallel Block, Var, Val classes from a new root that was a child of PAST::Node won't work. Because while a Slam::Block may be a Slam::Node, which may be a PAST::Node, it turns out that it also has to be a PAST::Block for the other stuff to work.

Subclassing PAST::Node in NQP

One of the problems with NQP is that it's not quite perl6. And that means if you do much development, you eventually run up against a corner of the language where the sidewalk just ends.

The support for objects is an example of this. There's no problem with defining methods, or defining a class name. There's no problem with creating a new instance of the class. But that's where it stops being easy. Because the syntax for extending another class is missing.

One thing I'd like to do is subclass the PAST::Node class(es) in my own code, so I can use method invocations to call functions in a different namespace. This would change code like:
close::Compiler::Type::merge_specifiers($node1, $node2)

into something like:
$node1.merge($node2);

which would make my fingers happy, if nothing else.

Saturday, September 26, 2009

The Whitespace Hack

Every culture has certain rites of passage that they expect members to pass through before they are fully accepted. In some places, they're pretty extreme -- taking knives to your naughty bits, and the like. Fortunately, the Parrot community is a little more laid back than that. There are two rites of passage for new members to participate in. The second one, which I haven't done yet, is to code a new garbage collector. Apparently, when you've coded a new GC, you get to do
svn commit -m "Today, I am a Parrot."
and you're totally in. I haven't reached that far, but I'm here to tell you that the first rite of Parrot-hood is pretty easy: filling out a ticket on http://trac.parrot.org.

Friday, September 25, 2009

Recursive Compiling

Years ago, back when GCC was still on version 1.x, I went looking through the code. I don't remember why, but I was looking for a way to "just make a function." I had some notion that down in the bowels of the code there would be a function called "create_function" or some such, and I could pass it a return type and a name and who-knows-what-else, and it would return a function object. Or maybe it would automatically emit the function object. I don't remember what I was thinking at the time, I just remember being frustrated by the nest of snakes I uncovered, each function requiring a huge initialized data structure as input, making a small update to the tree, and returning.

The other day I was working on Close, and I needed to create a function for the namespace init code. And I thought, "what I need is a function that will just create this one thing for me." Deja vu!

Tuesday, September 22, 2009

Output ordering and Initializers

Output ordering

Today I got Close to emit functions in the same sequence they occur in the input file. That was easy.

What wasn't easy was automatically creating a namespace init function to handle initialized declarators.

If you compile code that looks like this:
int x = 10;
There's no function involved. Clearly, this is a global variable 'x', and its initial value is 10. But Parrot does not use the same model that *nix uses, of loading a file that contains a partial memory image. Since there's no data segment, any and all initialization have to be done by code.

Referencing symbols in another namespace

Today, I got this code to DWIW:
#include <std/io>
#include <std/test>

namespace test {
    namespace hll: close :: test :: nested {
        namespace deeply {
            void goodbye() {
                say("Adios, amigo.");
            }
        }
    }


Howdy

Everyone else is doing it, so why can't we?

In this case, I'll be blogging about Close - a programming language on and for the Parrot VM.