One of the main goals of the pmc_pct branch is the ability to use a prescription-strength compiler to compile PMCs into L1 and C, rather than the Perl5-based pmc2c. Once pmcc is a viable replacement for pmc2c, we can start modifying it to support functions written in other languages such as nqp. However, nqp as it stands it not adequate for doing everything that we currently do in C-based PMCs. The purpose of this page is to document the known shortcomings of nqp in this area and to suggest possible ways to extend its syntax to handle these cases. To accomplish this, we are attempting to rewrite three representative PMCs (Hash, ResizablePMCArray and String) in nqp by translating the C into nqp as directly as possible.
List of Shortcomings
Direct C Function Calls
/* original C code */ nextkey = key_next( INTERP, key); /* from hash.pmc:get_number_keyed */ /* possible equivalent nqp-like code */ $nextkey := key_next($INTERP, $key); /* Alternative syntax requiring special-case treatement of "c" namespace */ $nextkey := c::key_next($INTERP, $key);
Much of Parrot will continue to be written in C well after our PMCs and ops are implemented in L1, and that L1 code (and any HLLs that compile down to L1) will need an efficient way to call those C functions directly.
equivalent L1 code
# NOTE: This code may be plausible and it may be terrible. It's just an idea. # Also, it's late and I wanted to try writing some L1. c_arg INTERP #set INTERP as the first arg to whatever function is called next c_arg key #set key to the second arg c_return nextkey #stick the return value into nextkey find_cfunc $P0, 'next_key' #find the function or get it from a cache or something call_cfunc $P0 #call it!
Another possible L1 code:
# NOTE: See above # NOTE2: We use some kind of C-function-proxy object to encapsulate call. find_cfunc $P0, 'next_key' #find the function or get it from a cache or something push_c_arg $P0, INTERP #set INTERP as the first arg to whatever function is called next push_c_arg $P0, key #set key to the second arg c_return $P0, nextkey #stick the return value into nextkey call_cfunc $P0 #call it!
The equivalent L1 code will need to deal with C calling conventions and efficiently looking up (and caching) the appropriate symbol.
/* original C code */ PMC *p = pmc_new(INTERP, enum_class_Env); /* possible nqp function */ my $p := pmc_new('Env'); /*