Pleased to announce, release, whatever.

A utility that will scan the neko source installation and build a 'stdlib.n'
that contains all the primitives loaded and ready to use. This is to help
fast development setup instead of having to type yet another loadprim line!

I've removed to issues, one was to change 'neko_sprintf' to 'sprintf' and
the other was to refine the primitive extraction because the 'int32.c'
program has a semi-colon missing of the _ushr entry which caught me out.

One it has run you can copy the stdlib.n into your dev folder and just load
the one module for instance access to everything!  I may do the same for the
other libraries too if I need them anytime soon.

Cheers
Sean Charles.
:)

//!
//! Sean Charles @ objitsu dot com   GPL/LGP/ 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 parenO = $sfind( line, 0, "(");
      var parenC = $sfind( line, 0, ")");
      var slice  = $ssub( line, parenO+1, parenC-parenO-1 );
      var fndef  = split( slice, "," );
      var fname  = fndef[0];
      if ( fname == "neko_sprintf" ) {
        fname = "sprintf"; }
      var fnstr  = sprintf("%s/%s,", $array( fname, 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" );
  $print( std.sprintf( "stdlib.n auto-generated: %s\n", when ));
}
else {
  $print("\nCompile failed! Seek author assistance!  :)\n\n");
}

Attachment: makestdlib.neko
Description: Binary data

-- 
Neko : One VM to run them all
(http://nekovm.org)

Reply via email to