1) semantics of assign
This is achieved by VTABLE_assign_pmc( [INTERP, SELF,] value ) [1], which is desribed in pdd06_pasm roughly as:
assign actually does a value assignment, as:
$foo = $bar;
X's assign vtable method is invoked and it does whatever is appropriate.
The current implementation in classes/scalar.pmc does basically this:
assign Px, Py:
if y.isa("Integer") val = y.get_integer x.set_integer_native(val) else if y.sa("Float") val = y.get_number x.set_number_native(val) ...
The "set_<type>_native" functions morph themselves to the appropriate PMC and then set the value. Works fine for Integer and Float. But e.g. a Boolean PMC doesn't morph itself to the value, it sets it's boolean value according to the passed in value:
void set_integer_native (INTVAL value) { PMC_int_val(SELF) = (value != 0); }
String was similar, it did set self's value to a string representaion of the value.
These differing semantics cause a lot of exceptions in C<assign_pmc> and it's error prone as all unhandled types might do it differently.
As a side-node: it seems to me that C<assign_pmc> is easier to implement, when the vtable is called on the value, which then morphs the destination according to it's own type and then sets the value. I.e.
assign_pmc(PMC* dest)
set C<dest>'s value to C<SELF>'s value. Or:
assign Px, Py <=> Py->vtable->assign_pmc(Px)
With this implemetation only one type has to be considered, e.g.
Integer.assign_pmc(dest) { v = SELF.get_integer dest.morph(Integer_type) dest.set_integer_native(v) }
2) semantics of logical_*
Currently (if *dest == NULL) a clone of the result PMC is returned. I'm not sure, if HLL's wouldn't need the original PMC (i.e. the reference). I tried this but a few tests broke, which didn't cope with this behavior.
3) PIR syntax
It was already discussed a few times that we might change PIR syntax:
current:
Px = Py set Px, Py alias Px and Py Px = assign Py assign Px, Py copy values
future:
Px := Py set Px, Py Px = Py assign Px, Py
This would much more resemble the HLL's (and programmers) POV.
Comments very welcome, leo
[1] it used to be C<set_pmc>, which is still called as a default, if C<assign_pmc> isn't implemented.