We had issues way back about this and we worked 'em out, at least to some extent. Now that I'm digging into it a bit more I see we need to hash out some more stuff.
Morph itself is simple enough--it's just a message to a PMC telling it to turn itself into another type, maintaining its value as best as possible. (Which may well not be very good) So doing something like:
morph $P0, .Integer
will turn the PMC in $P0 into a PMC of type Integer, with the integer value (hopefully) that the PMC originally contained. Or it should throw an exception if it doesn't allow that.
That's all really swell, except... how the heck is this supposed to happen?
The easy out is to say that it's all PMC dependent and you should just write the code to do what you want. That kinda works, but it's a cop-out, and it'd be sub-optimal to leave it that way. It's also a bit error-prone, since there's no good way to make sure the morphed PMC is properly set up under the hood with an extension segment if it needs one.
Generally I can see a morph looking (in sloppy pseudo-code) either like:
morph (INTVAL newtype) { TEMPVAR temp; temp = SELF.temp_value; SELF.vtable = master_tables[newtype] VTABLE_init(INTERP, SELF); VTABLE_set_x(INTERP, SELF, temp); }
i.e. pulling out the value, forcing the PMC to the new type, and assigning the new value in, or:
morph (INTVAL newtype) { PMC *temp; temp = shallow_clone(SELF); SELF.vtable = master_tables[newtype]; VTABLE_init(INTERP, SELF); VTABLE_set_pmc(INTERP, self, temp); }
where we make a shallow copy of the source PMC (basically just the PMC struct itself), force the original PMC to the new type, and then assigning the newly made shallow copy back to the original. (With the temp likely dying next DOD run as it's probably unanchored)
The problems are twofold:
1) We have no good documented way for non-allocator code to go messing with PMCs to make sure the re-init works right. (base flag settings, ext areas, and whatnot)
2) We don't have a documented way to make the sort of shallow copy that is needed in the second, more complex example above.
There's a third problem, in that it's possible that there are PMCs where neither method above is workable, which can happen in those cases where a PMC is ultimately self-referential, but I think those cases are going to be pretty rare and for morph to work they'd need to have custom code anyway, so I'm willing to actively ignore that for the moment.
This seem sane, and is there anything I may be missing? If not, I'll see about getting the code to do this put in, and some example PMC classes that use it in place. (Including the long-rumored, fabled generic Undef class :)
--
Dan
--------------------------------------"it's like this"------------------- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk