Hi,

I have written a utility which scans through the source distribution of neko
and :-

 -- locates ".C" files
 -- locates DEFINE_PRIM entries and extracts them
 -- creates another neko file containing a 'primitive' loader
 -- compiles the generated file
 -- loads and tests a few entry points.

It all works well and I am using it for my development but there is one fly
in the ointment that I can't figure out regarding the name of the sprintf
function. I have attached it in case it is useful...it basically builds a
MONSTER MODULE ;) that aids programming sessions by providing a
one-stop-shop. It's useful for me anyways! :)

When I run the above makestdlib.n file I get these two messages from my
loader :-

  STDLIB: load-fail: load.c(338) : Primitive not found : [EMAIL PROTECTED](0)
  STDLIB: load-fail: load.c(338) : Primitive not found : [EMAIL PROTECTED](2)

The docs say 'sprintf' but the source says 'neko_sprintf' and the
makestdlib.neko manually does a load on "[EMAIL PROTECTED]" which works!

So, is there some fakery going on to presumably avoid a clash between the
C-library sprintf and the internal one ? I must admit to not having scanned
the neko sources that hard (yet) to find there answer.

Cheers
Sean Charles.
----------------------- MAKESTDLIB.NEKO ---------------------
//!
//! Author: Sean Charles (objitsu.com)    GPL/LGPL/Use it!
//!
//! Change this to where you have installed the NekoVM source files.
//! You can obtain these from this location:
//!
http://www.nekovm.org/_media/neko-1.7.1.tar.gz?id=download&cache=cache
//!
var src = "./neko/libs/std";


//! Load up the required functions for this module.
//!
exec      = $loader.loadprim("[EMAIL PROTECTED]",1);
fget      = $loader.loadprim("[EMAIL PROTECTED]",1);
exit      = $loader.loadprim("[EMAIL PROTECTED]",1);
fopen     = $loader.loadprim("[EMAIL PROTECTED]",2);
fputs     = $loader.loadprim("[EMAIL PROTECTED]",4);
fclose    = $loader.loadprim("[EMAIL PROTECTED]",1);
fdelete   = $loader.loadprim("[EMAIL PROTECTED]",1);
fcontents = $loader.loadprim("[EMAIL PROTECTED]",1);
ftype     = $loader.loadprim("[EMAIL PROTECTED]",1);
split     = $loader.loadprim("[EMAIL PROTECTED]",2);
dir       = $loader.loadprim("[EMAIL PROTECTED]",1);
systype   = $loader.loadprim("[EMAIL PROTECTED]",0);
sprintf   = $loader.loadprim("[EMAIL PROTECTED]",2);
bufnew    = $loader.loadprim("[EMAIL PROTECTED]",0);
bufaddsub = $loader.loadprim("[EMAIL PROTECTED]",4);
bufstring = $loader.loadprim("[EMAIL PROTECTED]",1);


//!
//! Predicate test: does fname end with .[cC] ?
//!
isCFile = function( fname ) {
 return switch $ssub( fname, $ssize( fname )-2, 2 ) {
   ".C" => true
   ".c" => true
   default => false }}

//!
//! Platform specific line-ending for splitting the C file
//!
EOL = switch systype() {
 "Windows" => "\r\n"
  default => "\n" }

//!
//! Trigger for extracting a primitive.
//!
PRIM = "DEFINE_PRIM(";
PLEN = $ssize( PRIM );

//!
//! Process each line from a C file searching for lines
//! that start with DEFINE_PRIM as these are to be included
//! in the standard library object that this module 'is'!
//!
extractPrimitives = function( lines, acc ) {
 if ( $istrue( lines )) {
   var line = lines[0];
   if ( $ssize(line) >= PLEN && $ssub( line, 0, PLEN) == PRIM ) {
     var slice = $ssub( line, PLEN, $ssize(line)-PLEN-2 );
     var fndef = split( slice, "," );
     var fnstr = sprintf("%s/%s,", $array( fndef[0], fndef[1][0]));
     bufaddsub( acc, fnstr, 0, $ssize( fnstr )); }
   extractPrimitives( lines[1], acc ); }}

//!
//! Trawl from the installation libs folder looking for files
//! to scan for DEFINE_PRIM entries... these will be turned into
//! the equivalient loadprim() call.
//!
fileSucker = function( root, flist, acc ) {
 if ( $istrue( flist )) {
   var filename = sprintf( "%s/%s", $array( root, flist[0] ));
   switch ftype( filename ) {
     "dir"  => fileSucker( filename, dir( filename ), acc )
     "file" => {
       if ( isCFile( filename )) {
         extractPrimitives(
           split( fcontents( filename ), EOL ),
           acc );
   }}}
   fileSucker( root, flist[1], acc ); }}

//!
//! STDLIB.NEKO source file
//!
stdlibSrc = $array(
"var apiset=\"%s\";\n",
"string_split = $loader.loadprim( \"[EMAIL PROTECTED]", 2 );\n",
"sprintf      = $loader.loadprim( \"[EMAIL PROTECTED]", 2 );\n",
"process_functions = function( flist ) {\n",
"  if ( $istrue( flist )) {\n",
"    var fn_arity = string_split( flist[0], \"/\" );\n",
"    var fname    = fn_arity[0];\n",
"    var arity    = $int( fn_arity[1][0] );\n",
"    //! try/catch!\n",
"    try $objset( $exports,\n",
"     $hash( fname ),\n",
"     $loader.loadprim( sprintf(\"[EMAIL PROTECTED]", fname), arity ))\n",
"    catch e {\n",
"      $print(\"STDLIB: load-fail: \", e, \"\\n\");\n",
"    }\n",
"    process_functions( flist[1] ); }}\n",
"process_functions( string_split( apiset, \",\" ));\n" );

//!
//! OK, let's scan for primitives, build the source file that
//! loads the primitives, compile it, load it and test it :)
//!
primitives = bufnew();
fileSucker( src, dir( src ), primitives );
fnlist = bufstring( primitives );

//!
//! Update the source code with the final list of primitives
//! remembering to remove the trailing COMMA character.
//!
stdlibSrc[0] =
 sprintf( stdlibSrc[0],
          $ssub( fnlist, 0, $ssize(fnlist)-1));

srcWrite = function( code, i, fh ) {
 if ( i < $asize( code )) {
   fputs( fh, code[i], 0, $ssize(code[i]));
   srcWrite( code, i+1, fh );
 }
}

fh = fopen( "stdlib.neko", "w" );
srcWrite( stdlibSrc, 0, fh );
fclose( fh );

//!
//! Now compile the file and load it into memory as a test
//!
if ( $not( exec("nekoc stdlib.neko"))) {
 var std = $loader.loadmodule("stdlib",$loader);
 var when = std.date_format( std.date_now(), "%A, %m %B %Y at %r" );
 //problem area here!!!
 $print( "NEKO_SPRINTF?  -- ", std.neko_sprintf, "\n" );
 $print( "SPRINTF?  -- ", std.sprintf, "\n" );
 $print( sprintf( "stdlib.n auto-generated: %s\n", when ));
}
else {
 $print("\nCompile failed! Seek author assistance!  :)\n\n");
}
-- 
Neko : One VM to run them all
(http://nekovm.org)

Reply via email to