[z-machine] So-called bad practice in the Z-machine

Amir Karger amirkargerweb@yahoo.com
Thu, 18 Sep 2003 14:01:02 -0700 (PDT)


Hi.

    > VERBOSE
    Maximum verbosity.

So I'm working on this Z-machine to Perl translator. To remind you, the
difference here is that instead of being a regular old interpreter
(which is so 90's), this program will - when given a story file as
input - output a Perl script that will implement that particular game
as if it were being run in an interpreter. Kind of like Jzip does, only
with a LOT more work involved.

This is obviously a completely stupid project, because interpreters
already exist for eight gazillion platforms, in several different
languages. But it's slightly neat to have an executable Zork.  (In
theory, there might be a speed benefit in translating all the opcodes,
arguments, packed addresses, etc. beforehand, but except on the Palm, I
don't think anyone's really been suffering from speed problems. A few
years ago, Michael Edmonson did complain that Rezrov was too slow for
z5 and later games - it'll be interesting to see if my code eventually
runs faster, or whether the sheer number of opcodes.) 

Actually, I'm translating to Perl as a warmup to translate to Parrot,
which I don't know nearly as well. And once I had to translate into 2
languages, I might as well modularize the code to be able to translate
to N, right?  So I'm doing that, to the extent that you would basically
need to write a few simple strings (what your language puts at the top
& bottom of subroutines, e.g.) plus a translation of the Z-machine
opcodes (I translate jz as "goto L_OP1 if _OP0 ==0", for example, with
some post-processing to turn _OP0 into $op[0], plus handling for the
jump condition negation.) and poof! You can translate into any language
you'd like! (OK, Befunge-93 definitely won't work. Befunge-98 might,
and BASIC probably would, depending on the version.)

Um, with the caveat that fancy IO/GUI stuff is almost sure to be way
harder to translate. But if I can get to the point where you've got
full game functionality on a "super-dumb" terminal that just prints the
status line each turn, takes your input, and returns the right
responses, I'll be totally psyched.

Btw, I'm currently piping txd/infodump output into my program. Since
their license is ugly, I'll eventually need to reverse engineer their
output using the Z-spec, in order to get a fully functional translator.
But all that work will affect only the disassembling side, not the
language-specific translators.

But I (as usual) digress. I *did* have a question to ask.

I've come across a couple of places in the Z-spec that say it's "legal
but bad practice" or some such to do something. And a few other places
that allow things which would make translation more difficult.
Examples:
- jumping into a different routine
- modifying tables in dynamic memory without using opcodes like
set_attr

If I truly follow the spec in that first way, I can't use true
subroutines in other languages, which wouldn't allow jumping out of one
and into another. (Even Perl doesn't allow it, which is saying
something.)

The second means I can't do anything pretty with, say, turning game
objects into code objects (i.e., a class ZObject with attributes like
name, attr[], parent, etc.). Instead, I just need to store the
up-to-64K dynamic memory as a big string and do everything with
substring ops. Doable, but messy.

So my question is (finally!), if we grant that the programs I output
won't follow the 1.0 spec, how bad is that? How many games abuse the
Z-machine this way? If the answer is "all the Infocom games" I guess
I'll have to bite the bullet and be exacting (or write two different
translators :) But if the answer is "only the Z-machine Befunge
interpreter" then, even if I'm disappointed, I may go ahead and use
actual subroutines.

-Amir Karger

    > BRIEF
    [Beep! Unimplemented command!]

__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com