aptitude 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."I've spent a good part of the past week answering Pugs legal questions. Still haven't cleared up all the confusion there, but we're close.
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.
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. (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.)
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.
elsif and else 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:if (1) {
print "is true\n";
} elsif (2) {
print "else is true\n";
} else {
print "is false\n";
}
translates to something like this bit of PIR code:
unless 1 goto is_false
# if
print "is true\n"
goto end_if
is_false:
unless 2 goto else_is_false
# elsif
print "else is true\n"
goto end_elsif
else_is_false:
# else
print "is false\n"
end_elsif:
end_if:
This is far easier to generate from a tree than the alternative:
if 1 goto is_true
if 2 goto else_is_true
# else
print "is false\n"
goto end_if
else_is_true:
# elsif
print "else is true\n"
goto end_if
is_true:
print "is true\n"
end_if:
I've noticed this in general when writing PIR code --that unless gives me a control flow more similar to the if of a high-level language. It's because the actual meaning is reversed: HLL if means "if X is true do the following chunk of code" while the assembly if means "if X is true skip over the following chunk of code to label Y".
Today I added a tool for TGE (compilers/tge/tgc.pir) 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.
Before: Files=19, Tests=55, 48 wallclock secs (28.47 cusr + 5.01 csys = 33.48 CPU)
After: Files=19, Tests=55, 26 wallclock secs (11.48 cusr + 4.53 csys = 16.01 CPU)
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.
Hey, why not? All the cool kids are doing it!
I would like to announce my candidacy for the presidency of The Perl Foundation. My platform is as follows:
"Hi, I'd like to volunteer."
"Great! What would you like to do?"
"I don't know."
"How about X?"
"I don't want to do *that*."
Or:
"Hi, I'd like to volunteer to do Y."
"Great!" 1 month later: "Hey, how's Y going?"
<silence>
Thanks for listening, and I look forward to your support in the 2002 elections!
else and elsif 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.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!
I also did some documentation updates and code cleanup, since we have a Parrot release coming up soon.
print 1 + 2 + 3;
and
print 1 - 2, "\n", 7 - 1, "\n";
and
if (42 + 11) {
print "ok 1\n";
}
I first implemented it with most of the work happening in the POST->PIR transformation, but that turned out to be pretty hacky. So, I redid the bottom half with most of the work in the PAST->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->POST transformation. Both the operator implementation and the print statement refactor rely heavily on the new POST::Ops node, so it is turning out to be quite useful.
Whoops, no journal entries in a while. Mostly I've been working on bug fixes. 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.
Today I added simple do block support. One "ah-ha" moment in there resulted in me adding a new POST node type: Ops. 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 print of a list that turns into multiple independent print statements in POST). Adding POST::Ops 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.)
I also added simple conditional support today, such as:
if (1) {
print "hello world";
}
unless (0) {
print "hello world";
}
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 else or elsif 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.