On Thu, 19 Dec 2002, Leopold Toetsch wrote: > David Robins wrote: > > On Wed, 18 Dec 2002, Leopold Toetsch wrote: > >> morph "dest" to be a "ret"? > >>unimplemented, unused, but your examples seems to be a typical test case. > > "dest" could be any type, so it's not reasonable to expect any type to be > > able to morph to my chosen destination PMC type (unless default->morph can > > be changed to do a standard new for the type). > In pdd02_vtables.pod morph() is defined to do exactly this.
I was looking at the default.pmc code. I'll read the doc. Doc says that This method is primarily used when the interpreter has need of coercing a PMC to a particular type, and isn't meant as a general purpose casting tool. Compilers should only emit valid transformations. which doesn't seem to indicate that morph is the Right Thing, at least conceptually (since I want to destroy the old PMC and create a new one all the time, so I don't want the PMC wasting time trying to convert itself into the new type if I'm just going to clobber the value anyway). > > Maybe the ops should instead be changed to be > > > > PMC* binaryOp(PMC* rhs) and > > PMC* unaryOp(void) > > > > after all, most of the time _someone_ has to create a destination PMC, and > > except for the reuse angle (and 'new' is probably quite fast), the PMC > > handling the op is in the best place to do it. > > The question is, how often may a PMC be reused, and how often has it to > be a new one. And for which vtable to you call above Op?. Well, if the HL (or even IMCC) is "$a = $b + $c", how should that be translated? The existing type of $a sure shouldn't influence the result. Supposing $b is a PerlInt, and $a maps to P0, $b to P1, and $c to P2, then: add P0,P1,P2 calls PerlInt's add op, which in most cases wants the result to be a PerlInt, except in some (when P2 is a float) it should be a PerlFloat, say: PMC* add(PMC* value) { if(value is not a float) { PMC* ret = SELF.clone(); ret->cache.int_val += value->vtable->get_integer(INTERP); return ret; } /* since addition commutes, flip it around so we get a float back */ return value->vtable->add(INTERP,SELF); } "value is not a float" is intentionally nebulous, there's no way to check if a value is a float, except maybe by comparing the get_number/get_integer returns, but that's slow and float roundoff will get you anyway. For PerlInt it might suffice to check that 'value' is not a PerlFloat. Not that C++ is a paragon of virtue, but operators in C++ work this way, as does Perl5's overload extension. Even in the existing case, the '$b' vtable will be called; that should not be changed. > The HL normally has smome rules, what the LHS has to be, so normally, > you do a "new Px, .Type" for the LHS and you have already a PMC of the > correct type. When the HL has different concepts, this might not be useful. The (or one of the) subjects of the op has a better idea of the result type than the caller (for example, $b and $c could be floats, or integers, and the target should match, but the HL doesn't know which they are at compile time). Another interesting question: interoperability between languages. What do you get when you add a PerlInteger and a RubyInteger? This seems like an interesting can of worms, actually - the best idea I can come up with is that a whole lot of morphing should be done at the interface ("interface" defined as "the place where the two languages meet", in this case). > leo Dave Isa. 40:31