I currently have some special handling for when a user defines a proc in Tcl.
Right now, when someone defines a proc, I parse out the body of the proc immediately, and save it and some metadata in a global hash. Then, at interpreter time, I have special logic that (a) checks to see if it the proc called is one of the builtins, and, failing that, I (b) check my global hashen and if I find an entry for a user defined proc, the interpreter has some special logic to setup arguments for the preparsed body. This wonkery (along with lots of the "design") dates back to the dark ages of parrot.
Now that we can dynamically generate PIR subroutines, I can elevate these user defined procs to equivalence with the builtins, which will reduce the complexity in the interpreter even further. (Another step on the way to replacing it with a compiler)
I've come across a stumbling block implementing this, though -- the plan (for now) was to get the pre-parsed body as a variable local to the .sub, so that the .sub could do what the interpreter proc was doing - setup the variables, create a new pad, call the __interpreter again, then clean up -- but I can't seem to get the pre-parsed body (which happens to be an array of arrays of language/tcl/lib/tclword.imc objects) into the dynamically created .sub
This sample program shows my issue:
bash-2.05a$ cat coke.imc .namespace [ "Coke" ]
.sub _main @MAIN
.local pmc original
.local string frozen_pmc
.local string sub_def
.local pmc compiler
.local pmc compiled_sub
.local pmc thawed_pmc
.local pmc dumper_sub
original = new PerlArray
original[0] = 3.14
frozen_pmc = freeze original
sub_def = ".namespace [ \"Coke\" ]\n.sub _joe\nthaw $P1, \""
sub_def.= frozen_pmc
sub_def .= "\"\n.pcc_begin_return\n.return $P1\n.pcc_end_return\n"
print "FUNC:\n"
print sub_def
print "--\n"
compiler = compreg "PIR"
$P1 = compile compiler, sub_def
compiled_sub = find_global "Coke", "_joe"
thawed_pmc = compiled_sub()
dumper_sub = find_global "_dumper"
dumper_sub( thawed_pmc )
end
.end
.include "library/dumper.imc"
--
When this is run, it prints out the function as I'd expect to see it, but I get the error:
error:imcc:parse error, unexpected $undefined
in file 'EVAL_1' line 3
Which corresponds to the thaw. Now, if I remove the generated PIR here, and go with the simpler example:
bash-2.05a$ cat freeze.imc .sub main @MAIN
.local pmc original
.local string frozen_pmc
.local pmc thawed_pmc
original = new PerlArray
original[0] = 3.14
frozen_pmc = freeze original
print frozen_pmc
print "\n"
thawed_pmc = thaw frozen_pmc
_dumper(thawed_pmc)
end
.end
.include "library/dumper.imc"
I get the expected output. Now, the frozen pmcs don't look exactly the same, but without knowing the guts of how freeze works, I'm guessing that's not exactly the problem.
I tried escaping the frozen_pmc in the first example with Data::Escape::String, got the same result.
Any comments, on either my issue with freeze/thaw or the idea in general?
I suppose in the meantime, I could manually recreate the array of array of tclwords, but I'd like to avoid writing a custom freeze/thaw, when I could (hopefully) just use the existing opcodes.