Yeah, you can go the other way too.
runtime/parrot/library/Perl5.pir
.namespace [ 'Perl5'; 'NCI' ] .macro store_nci_func( func_name, signature ) c_func_name = prefix . .func_name dlfunc c_function, lib, c_func_name, .signature store_global .func_name, c_function .endm .sub '_init' :load .local pmc lib .local pmc c_function loadlib lib, 'libperl' .local string prefix prefix = 'perl_' .local string c_func_name .store_nci_func( 'alloc', 'pv' ) .store_nci_func( 'construct', 'vp' ) .store_nci_func( 'parse', 'vpiipi' ) .store_nci_func( 'run', 'vp' ) .store_nci_func( 'destruct', 'vp' ) .store_nci_func( 'free', 'vp' ) .end
examples/libperl.pir
.include 'datatypes.pasm' .macro import_func( name ) func = find_global [ 'Perl5'; 'NCI' ], .name store_global .name, func .endm .sub main :main load_bytecode 'runtime/parrot/library/Perl5.pir' .local pmc func .import_func( 'alloc' ) .import_func( 'construct' ) .import_func( 'parse' ) .import_func( 'run' ) .import_func( 'destruct' ) .import_func( 'free' ) .local pmc perl_interp perl_interp = alloc() construct( perl_interp ) .local pmc args_shape args_shape = new .ResizablePMCArray push args_shape, .DATATYPE_CSTR push args_shape, 0 push args_shape, 0 push args_shape, .DATATYPE_CSTR push args_shape, 0 push args_shape, 0 push args_shape, .DATATYPE_CSTR push args_shape, 0 push args_shape, 0 .local pmc args args = new .ManagedStruct, args_shape args[0] = "\x0" args[1] = "-e\x0" args[2] = "print \"Hello from Parrot!\\n\"\x0" parse( perl_interp, 0, 3, args, 0 ) run( perl_interp ) destruct( perl_interp ) free( perl_interp ) .end