Hi, Pleased to announce (and attached source) 'makestdlib', my first useful neko program. LOL.
SUMMARY: Automatically builds modules to wrap the standard libraries into a
single loadable module, one per module folder in the source tarball.
Read the source for full details but here's a rough guide to what it does /
how to use it :--
o Create a folder called 'foo'
o Save the attached file in this folder.
o Unpack the neko source distribution into the same folder
o Edit 'makestdlib.neko' and edit the 'root' variable to point as
instructed.
o Compile the 'makestdlib.neko' file
o Execute the 'makestdlib.n' file
Expected output :--
Module: mod_neko -- compiled OK
Module: mysql -- compiled OK
Module: regexp -- compiled OK
Module: sqlite -- compiled OK
Module: std -- compiled OK
Module: ui -- compiled OK
Module: zlib -- compiled OK
stdlib.n auto-generated: Saturday, 08 August 2008 at 09:45:55 PM
In folder foo you should now find these .N files ready to rock and roll...
-rw-r--r-- 1 seancharles seancharles 745 Aug 23 21:45 mod_neko.n
-rw-r--r-- 1 seancharles seancharles 570 Aug 23 21:45 mysql.n
-rw-r--r-- 1 seancharles seancharles 542 Aug 23 21:45 regexp.n
-rw-r--r-- 1 seancharles seancharles 545 Aug 23 21:45 sqlite.n
-rw-r--r-- 1 seancharles seancharles 2767 Aug 23 21:45 std.n
-rw-r--r-- 1 seancharles seancharles 436 Aug 23 21:45 ui.n
-rw-r--r-- 1 seancharles seancharles 563 Aug 23 21:45 zlib.n
These can be loaded in the usual way eg
mysql = $loader.loadmodule("mysql");
mysql.connect(...)
etc etc you get the idea :)
I hope this saves people time and sweat to get a project going! I have
learned loads about Neko in the time it has taken to get this utility
working and it just gets better and better! :)
One of my test cases did find a bug in the online docs about
mysql.escape()! My code decided it had two parameters but the online HTML
page says it has one! It has two, for the record, the first is the
connection and the second is the string to escape.
Hope somebody can fix that in the docs.
Enjoy!
Sean Charles.
:)
---- NODE CODE (in case attachment fails) ----
//!
//! Sean Charles @ objitsu dot com GPL/LGP/ Use it!
//!
//! Change 'root' to where you have installed the NekoVM source files and
//! do not add a trailing slash.
//!
var root = "./neko/libs";
//!
//! List of folders to scan for defined primitives.
//!
var moduleList = "mod_neko,mysql,regexp,sqlite,std,ui,zlib";
//!
//! This is a template for the module loader code.
//!
loaderSrc =
"var apiset=\"%s\";
string_split = $loader.loadprim( \"[EMAIL PROTECTED]", 2 );
sprintf = $loader.loadprim( \"[EMAIL PROTECTED]", 2 );
process_functions = function( flist ) {
if ( $istrue( flist )) {
var fn_arity = string_split( flist[0], \"/\" );
var fname = fn_arity[0];
var arity = $int( fn_arity[1][0] );
//! try/catch!
try $objset( $exports,
$hash( fname ),
$loader.loadprim( sprintf(\"[EMAIL PROTECTED]", fname), arity ))
catch e {
$print(\"LOADLIB: load-fail: \", e, \"\\n\");
}
process_functions( flist[1] ); }}
process_functions( string_split( apiset, \",\" ));";
//! 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 ); }}
//!
//! OK, let's scan for primitives, build the source file that
//! loads the primitives, compile it, load it and test it :)
//!
processModule = function( module ) {
if ( $istrue( module )) {
var folder = sprintf( "%s/%s", $array( root, module[0] ));
var nekoFile = sprintf( "%s.neko", module[0] );
var primitives = bufnew();
fileSucker( folder, dir( folder ), primitives );
var fnlist = bufstring( primitives );
var fnlist = $ssub( fnlist, 0, $ssize( fnlist )-1 );
var nekoSrc = sprintf( loaderSrc, $array( fnlist, module[0], "%s"))
var fh = fopen( sprintf( "%s.neko", module[0] ), "w" );
fputs( fh, nekoSrc, 0, $ssize( nekoSrc ));
fclose( fh );
if ( $not( exec( sprintf( "nekoc %s", nekoFile )))) {
$print( "Module: ", module[0], " -- compiled OK\n" ); }
processModule( module[1]); }}
processModule( split( moduleList, "," ));
//!
//! Small test to show that the std module bult and thus
//! hopefully all the rest did too!
//!
var std = $loader.loadmodule("std",$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 ));
makestdlib.neko
Description: Binary data
-- Neko : One VM to run them all (http://nekovm.org)
