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)
