This test file describes an improvement for the directive .const
when an HLL is using.
In Lua, all types are implemented as PMC,
no Lua type is mapped with Parrot primitive type.
Lua PMC are derived from existing PMC, for example :
pmclass LuaNumber extends Float does float dynpmc group lua_group hll Lua
maps Float
pmclass LuaFunction extends Sub does sub dynpmc group lua_group hll Lua
maps Sub
But the directive .const seems to support only Parrot PMC.
In Lua, functions are "first class values".
So, it's important to instanciate and initialize them
with the PMC LuaFunction.
Is it a dream ?
Is it a future & planned feature ?
Or is it possible with an other syntax ?
(Lua supports closure & coroutine, it's allow to check their implementation
in Parrot with another language.)
François Perrad.
=cut
use strict;
use Parrot::Test tests => 3;
use Test::More;
pir_output_is(<<'CODE', <<'OUT', '.const with Parrot PMC' );
.sub foo :main
.const .Integer i = "12"
$S0 = typeof i
print $S0
print "\n"
print i
print "\n"
.const .Sub _test = "_test"
$S0 = typeof _test
print $S0
print "\n"
$P0 = _test
$P0()
print "ok\n"
.end
.sub _test
print "test\n"
.end
CODE
Integer
12
Sub
test
ok
OUT
TODO: {
local $TODO = "my expected behavior";
pir_output_is(<<'CODE', <<'OUT', '.const with Lua PMC' );
.HLL "Lua", "lua_group"
.sub foo :main
.const .LuaNumber n = "12.34"
$S0 = typeof n
print $S0
print "\n"
print n
print "\n"
.const .LuaFunction _test = "_test"
$S0 = typeof _test
print $S0
print "\n"
$P0 = _test
$P0()
print "ok\n"
.end
.sub _test
print "test\n"
.end
CODE
number
12.34
function
test
ok
OUT
}
pir_output_is(<<'CODE', <<'OUT', 'my current usage with Lua' );
.HLL "Lua", "lua_group"
.sub foo :main
new $P0, .LuaNumber
$P0 = 12.34
$S0 = typeof $P0
print $S0
print "\n"
print $P0
print "\n"
.const .Sub _test = "_test"
new $P0, .LuaFunction # useless
$P0 = _test
$S0 = typeof $P0
print $S0
print "\n"
$P0()
print "ok\n"
.end
.sub _test
print "test\n"
.end
CODE
number
12.34
Sub
test
ok
OUT
> =head1 DESCRIPTION
>
> This test file describes an improvement for the directive .const
> when an HLL is using.
Not really - see below.
> .const .Integer i = "12"
The Integer PMC implements the constructor "new_from_string", which is
called at compile time to create a possibly constant PMC item with the
given value. PMC constants are frozen/thawed as usual, and above just
works. The .const pmc directive is just sugar for
set_p_pc Px, <pmc_constant>
> .const .Sub _test = "_test"
A .Sub is a bit special, as the Sub PMC is already created, when a .sub
directive is encountered during codegen. So this is again just a
C<set_p_pc> opcode.
> .const .LuaNumber n = "12.34"
I presume LuaNumber doesn't have new_from_string (Float hasn't either).
> .const .LuaFunction _test = "_test"
Creation of Sub PMCs currently doesn't honor HLL mappings. There are a
few hardcoded references of "Sub", "Closure", and "Coroutine" in the
compiler and in packfile.c. These should be easily to spot. Explicit
tests against enum_class_Sub need to be replaced by VTABLE_isa or
_does.
leo
.const .LuaNumber n = "12.34"
kind regards,
klaas-jan
I start with the following patch, but I am not happy with it.
does_isa() isn't a public function (I haven't found a handle for a pmc).
It allows the expected syntax but the behavior isn't good :
the created pmc is a Sub not a LuaFunction.
François.
Index: imcparser.c
===================================================================
--- imcparser.c (revision 11318)
+++ imcparser.c (working copy)
@@ -392,6 +392,9 @@
return INS(interpreter, unit, opname, fmt, r, n, keyvec, 1);
}
+extern INTVAL
+does_isa (Interp* interpreter, STRING *method, STRING *what);
+
static Instruction*
mk_pmc_const(Parrot_Interp interp, IMC_Unit *unit,
char *type, SymReg *left, char *constant)
@@ -426,6 +429,17 @@
rhs->pmc_type = type_enum;
rhs->usage = U_FIXUP;
return INS(interp, unit, "set_p_pc", "", r, 2, 0, 1);
+ default:
+ {
+ VTABLE *vtable = Parrot_base_vtables[type_enum];
+ if (does_isa(interp, const_string(interp, "sub"),
vtable->does_str)) {
+ rhs = mk_const(interp, name, 'p');
+ r[1] = rhs;
+ rhs->pmc_type = type_enum;
+ rhs->usage = U_FIXUP;
+ return INS(interp, unit, "set_p_pc", "", r, 2, 0, 1);
+ }
+ }
}
rhs = mk_const(interp, name, 'P');
r[1] = rhs;
>leo
>
>
> I start with the following patch, but I am not happy with it.
> does_isa() isn't a public function (I haven't found a handle for a
> pmc).
> It allows the expected syntax but the behavior isn't good :
> the created pmc is a Sub not a LuaFunction.
>
> François.
>
> Index: imcparser.c
And worse, imcparser.c is created from imcc.y ;)
pbc.c has some more code that deals with the type of subroutines.
The actual creation of the PMC is done in src/packfile.c, where a few
more tests for enum_class_Sub are present.
leo