Version 6 (modified by cotto, 13 years ago)

change existing example to minimize changes to nqp, add pmc_new

Introduction

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

nqp syntax

/* 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.

PMC Creation

nqp syntax

/* original C code */
PMC *p = pmc_new(INTERP, enum_class_Env);

/* possible nqp function */
my $p := pmc_new('Env'); /*