Преглед изворни кода

Add/update several script examples.

mingodad пре 10 година
родитељ
комит
ec1914f248
36 измењених фајлова са 2838 додато и 17 уклоњено
  1. 8 1
      SquiLu-ourbiz/companies-uk.nut
  2. 150 0
      SquiLu/include/sqconfig.h
  3. 54 0
      SquiLu/samples/binary-tree2.nut
  4. 82 0
      SquiLu/samples/class-cursor-kind.nut
  5. 216 0
      SquiLu/samples/count-html-tags.nut
  6. 113 0
      SquiLu/samples/dump-har.nut
  7. 804 0
      SquiLu/samples/editor-fltk.nut
  8. 61 0
      SquiLu/samples/gen-class-hashtable.nut
  9. 243 0
      SquiLu/samples/generate-cpp-class-wrapper.nut
  10. 24 0
      SquiLu/samples/get-files-recursing.nut
  11. 68 0
      SquiLu/samples/k-nucleotide.nut
  12. 93 0
      SquiLu/samples/libcurl.nut
  13. 132 0
      SquiLu/samples/nanomsg.nut
  14. 6 0
      SquiLu/samples/test-assginment.nut
  15. 29 0
      SquiLu/samples/test-bug-local-loop.nut
  16. 48 0
      SquiLu/samples/test-bug-recursion.nut
  17. 18 0
      SquiLu/samples/test-bug-semicolon.nut
  18. 7 4
      SquiLu/samples/test-class-destructor.nut
  19. 11 0
      SquiLu/samples/test-class-name-resolution.nut
  20. 4 3
      SquiLu/samples/test-delayed-release-hooks.nut
  21. 256 0
      SquiLu/samples/test-fltk-list-search.nut
  22. 1 1
      SquiLu/samples/test-fltk.nut
  23. 45 0
      SquiLu/samples/test-gumbo.nut
  24. 4 0
      SquiLu/samples/test-match.nut
  25. 72 0
      SquiLu/samples/test-miniz.nut
  26. 43 0
      SquiLu/samples/test-mysql.nut
  27. 11 0
      SquiLu/samples/test-nested-functions.nut
  28. 13 0
      SquiLu/samples/test-postgresql-local.nut
  29. 19 3
      SquiLu/samples/test-postgresql.nut
  30. 9 0
      SquiLu/samples/test-regex.nut
  31. 9 0
      SquiLu/samples/test-set-global.nut
  32. 104 0
      SquiLu/samples/test-signal-handling.nut
  33. 3 3
      SquiLu/samples/test-socket-udp-echo-server.nut
  34. 27 0
      SquiLu/samples/test-socket-udp-syslog-server.nut
  35. 44 2
      SquiLu/samples/test-sqlite3.nut
  36. 7 0
      SquiLu/samples/uuid-generator.nut

+ 8 - 1
SquiLu-ourbiz/companies-uk.nut

@@ -10,6 +10,12 @@
 
 local globals = getroottable();
 
+local function sqliteTrace(udata, sql)
+{
+	if(sql == "-- TRIGGER ") return;
+	debug_print(udata, ":", sql, "\n");
+}
+
 local function getCompaniesUkDBFileName(){
 	if (globals.rawget("jniLog", false)) return APP_CODE_FOLDER + "/companies-uk-RG.db";
 	if (globals.rawget("WIN32", false)) return APP_CODE_FOLDER + "/../../companies-uk/companies-uk-RG.db";
@@ -24,6 +30,7 @@ local companiesUkDB = null;
 local function getCompaniesUkDB(){
 	if(!companiesUkDB) {
 		companiesUkDB = SQLite3(getCompaniesUkDBFileName());
+		if(AT_DEV_DBG) companiesUkDB.trace(sqliteTrace, "SQL", false);
 		//companiesUkDB.exec_dml("PRAGMA cache_size = 4000;");
 	}
 	return companiesUkDB;
@@ -37,7 +44,7 @@ local function getCachedStmt(stmt_key, sql_or_func){
 		local sql;
 		if (type(sql_or_func) == "function") sql = sql_or_func();
 		else sql = sql_or_func;
-		//debug_print("\n", sql);
+		//debug_print("\nsql: ", sql);
 		stmt = getCompaniesUkDB().prepare(sql);
 		__stmtCache.stmt_key <- stmt;
 	}

+ 150 - 0
SquiLu/include/sqconfig.h

@@ -0,0 +1,150 @@
+
+#ifdef _SQ64
+
+#ifdef _MSC_VER
+typedef __int64 SQInteger;
+typedef unsigned __int64 SQUnsignedInteger;
+typedef unsigned __int64 SQHash; /*should be the same size of a pointer*/
+#else
+typedef long long SQInteger;
+typedef unsigned long long SQUnsignedInteger;
+typedef unsigned long long SQHash; /*should be the same size of a pointer*/
+#endif
+typedef int SQInt32; 
+typedef unsigned int SQUnsignedInteger32;
+#else 
+typedef int SQInteger;
+typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/
+typedef unsigned int SQUnsignedInteger32; /*must be 32 bits(also on 64bits processors)*/
+typedef unsigned int SQUnsignedInteger;
+typedef unsigned int SQHash; /*should be the same size of a pointer*/
+#endif
+
+
+#ifdef SQUSEDOUBLE
+typedef double SQFloat;
+#else
+typedef float SQFloat;
+#endif
+
+#if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64)
+#ifdef _MSC_VER
+typedef __int64 SQRawObjectVal; //must be 64bits
+#else
+typedef long long SQRawObjectVal; //must be 64bits
+#endif
+#define SQ_OBJECT_RAWINIT() { _unVal.raw = 0; }
+#else
+typedef SQUnsignedInteger SQRawObjectVal; //is 32 bits on 32 bits builds and 64 bits otherwise
+#define SQ_OBJECT_RAWINIT()
+#endif
+
+#ifndef SQ_ALIGNMENT // SQ_ALIGNMENT shall be less than or equal to SQ_MALLOC alignments, and its value shall be power of 2.
+#if defined(SQUSEDOUBLE) || defined(_SQ64)
+#define SQ_ALIGNMENT 8
+#else
+#define SQ_ALIGNMENT 4
+#endif
+#endif
+
+typedef void* SQUserPointer;
+typedef SQUnsignedInteger SQBool;
+typedef SQInteger SQRESULT;
+
+#ifdef SQUNICODE
+#include <wchar.h>
+#include <wctype.h>
+
+
+typedef wchar_t SQChar;
+
+
+#define	scstrcmp	wcscmp
+#ifdef _MSC_VER
+#define scsprintf	_snwprintf
+#define scvfprintf	_vfwprintf
+#else
+#define scsprintf	snwprintf
+#define scvfprintf	vfwprintf
+#endif
+#define scstrlen	wcslen
+#define scstrtod	wcstod
+#ifdef _SQ64
+#define scstrtol	wcstoll
+#else
+#define scstrtol	wcstol
+#endif
+#define scstrtoul	wcstoul
+#define scvsprintf	vswprintf
+#define scstrstr	wcsstr
+#define scprintf	wprintf
+
+#ifdef _WIN32
+#define WCHAR_SIZE 2
+#define WCHAR_SHIFT_MUL 1
+#define MAX_CHAR 0xFFFF
+#else
+#define WCHAR_SIZE 4
+#define WCHAR_SHIFT_MUL 2
+#define MAX_CHAR 0xFFFFFFFF
+#endif
+
+#define _SC(a) L##a
+
+
+#define scisspace	iswspace
+#define scisdigit	iswdigit
+#define scisprint	iswprint
+#define scisxdigit	iswxdigit
+#define scisalpha	iswalpha
+#define sciscntrl	iswcntrl
+#define scisalnum	iswalnum
+
+
+#define sq_rsl(l) ((l)<<WCHAR_SHIFT_MUL)
+
+#else
+typedef char SQChar;
+#define _SC(a) a
+#define	scstrcmp	strcmp
+#ifdef _MSC_VER
+#define scsprintf	_snprintf
+#define scvfprintf	_vfprintf
+#else
+#define scsprintf	snprintf
+#define scvfprintf	vfprintf
+#endif
+#define scstrlen	strlen
+#define scstrtod	strtod
+#ifdef _SQ64
+#ifdef _MSC_VER
+#define scstrtol	_strtoi64
+#else
+#define scstrtol	strtoll
+#endif
+#else
+#define scstrtol	strtol
+#endif
+#define scstrtoul	strtoul
+#define scvsprintf	vsnprintf
+#define scstrstr	strstr
+#define scisspace	isspace
+#define scisdigit	isdigit
+#define scisprint	isprint
+#define scisxdigit	isxdigit
+#define sciscntrl	iscntrl
+#define scisalpha	isalpha
+#define scisalnum	isalnum
+#define scprintf	printf
+#define MAX_CHAR 0xFF
+
+#define sq_rsl(l) (l)
+
+#endif
+
+#ifdef _SQ64
+#define _PRINT_INT_PREC _SC("ll")
+#define _PRINT_INT_FMT _SC("%lld")
+#else
+#define _PRINT_INT_FMT _SC("%d")
+#endif

+ 54 - 0
SquiLu/samples/binary-tree2.nut

@@ -0,0 +1,54 @@
+// The Computer Language Benchmarks Game
+// http://benchmarksgame.alioth.debian.org/
+// contributed by Mike Pall
+
+local BottomUpTree_count = 0;
+local function BottomUpTree(item, depth){
+  ++BottomUpTree_count;
+  if (depth > 0){
+    local i = item + item;
+    --depth;
+    return [ item, BottomUpTree(i-1, depth),  BottomUpTree(i, depth) ];
+  }
+  return [ item ];
+}
+
+local ItemCheck_count = 0;
+local function ItemCheck(tree){
+  ++ItemCheck_count;
+  if (tree.get(1, false))  return tree[0] + ItemCheck(tree[1]) - ItemCheck(tree[2])
+  return tree[0]
+}
+
+local start = os.clock()
+//check_delayed_release_hooks(false);
+
+local N = vargv.get(1, 14).tointeger();
+local mindepth = 4
+local maxdepth = mindepth + 2
+if (maxdepth < N) maxdepth = N
+
+{
+  local stretchdepth = maxdepth + 1
+  local stretchtree = BottomUpTree(0, stretchdepth)
+  print(format("stretch tree of depth %d\t check: %d",
+    stretchdepth, ItemCheck(stretchtree)))
+}
+
+local longlivedtree = BottomUpTree(0, maxdepth)
+
+for(local depth=mindepth; depth <= maxdepth; depth += 2){
+  local iterations = math.pow(2, (maxdepth - depth + mindepth)).tointeger()
+  local check = 0
+  for(local i=0; i < iterations; ++i){
+    check += ItemCheck(BottomUpTree(1, depth)) +
+            ItemCheck(BottomUpTree(-1, depth))
+  }
+  print(format("%d\t trees of depth %d\t check: %d",
+    iterations*2, depth, check))
+}
+
+print(format("long lived tree of depth %d\t check: %d\n",
+  maxdepth, ItemCheck(longlivedtree)))
+
+print("binary-tree", N, os.clock()-start, BottomUpTree_count, ItemCheck_count)

+ 82 - 0
SquiLu/samples/class-cursor-kind.nut

@@ -0,0 +1,82 @@
+class CursorKind
+{
+    /*
+    A CursorKind describes the kind of entity that a cursor points to.
+    */
+
+    # The required BaseEnumeration declarations.
+    _kinds = [];
+    _name_map = null;
+    
+    constructor(BaseEnumeration)
+    {
+    }
+
+    static function get_all_kinds()
+    {
+        //Return all CursorKind enumeration instances.
+        return filter(null, CursorKind._kinds)
+    }
+
+    function is_declaration()
+    {
+        //Test if this is a declaration kind.
+        return conf.lib.clang_isDeclaration();
+    }
+
+    function is_reference()
+    {
+        //Test if this is a reference kind.
+        return conf.lib.clang_isReference();
+    }
+
+    function is_expression()
+    {
+        //Test if this is an expression kind.
+        return conf.lib.clang_isExpression();
+    }
+
+    function is_statement()
+    {
+        //Test if this is a statement kind.
+        return conf.lib.clang_isStatement();
+    }
+
+    function is_attribute()
+    {
+        //Test if this is an attribute kind.
+        return conf.lib.clang_isAttribute();
+    }
+
+    function is_invalid()
+    {
+        //Test if this is an invalid kind.
+        return conf.lib.clang_isInvalid();
+    }
+
+    function is_translation_unit()
+    {
+        //Test if this is a translation unit kind.
+        return conf.lib.clang_isTranslationUnit();
+    }
+
+    function is_preprocessing()
+    {
+        //Test if this is a preprocessing kind.
+        return conf.lib.clang_isPreprocessing();
+    }
+
+    function is_unexposed()
+    {
+        //Test if this is an unexposed kind.
+        return conf.lib.clang_isUnexposed();
+    }
+
+    function tostring()
+    {
+        return format("CursorKind.%s", name);
+    }
+}
+
+dofile("generate-cpp-class-wrapper.nut");
+generateCppClassWrapper(CursorKind, "CursorKind");

+ 216 - 0
SquiLu/samples/count-html-tags.nut

@@ -0,0 +1,216 @@
+socket.open();
+
+local db = SQLite3("/home/mingo/dev/tribiq/tribiq.com.webcontent.db");
+db.exec_dml("begin;");
+db.exec_dml("create table if not exists webcontent(id integer primary key, link text, content text, unique(link));");
+local stmt = db.prepare("insert into webcontent(link) values(?);");
+local stmt_content = db.prepare("update webcontent set content=? where link=?;");
+
+function download(host, file, extra_header=null){
+	local sock = socket.tcp();
+	sock.connect(host, 80);
+	local info = sock.getpeername()
+	print("info", info.address, info.port);
+	//sock.settimeout(1, "t");
+
+	local count = 0;    // counts number of bytes read
+	local req = "GET " + file + " HTTP/1.1\r\nHost: " + host + "\r\n";
+	if (extra_header) req += extra_header + "\r\n";
+	req += "\r\n";
+	//print("req", req.len(), req);
+	sock.send(req);
+	local s, rc;
+	local tbl = {};
+	local len = 0;
+	while (true){
+		rc = sock.receive("*l");
+		s = rc[0];
+		print("s", s, rc[1]);
+		//if err == "closed" then break end
+		if (s.len() == 0) break;
+		//if (rc[1] == socket.IO_CLOSED) break;
+		local slen = s.match("Content%-Length: (%d+)");
+		local sid = s.match("Set%-Cookie: session_id=([^;]+)");
+		if(sid) session_id = sid;
+		if (slen) {
+			len = slen.tointeger();
+		}
+	}
+	rc = sock.receive(len);
+	s = rc[0];
+	//print("len", len, rc[1], s.len());
+	sock.close();
+	//print(file, count)
+	return s;
+}
+
+function downloadChunked(host, file, extra_header=null){
+	local sock = socket.tcp();
+	sock.settimeout(1000);
+	sock.connect(host, 80);
+
+	local count = 0;    // counts number of bytes read
+	local req;
+	if (extra_header) req = extra_header;
+	else req = format("GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", file, host);
+	
+	print("REQUEST:", req)
+	sock.send(req);
+	local s, rc;
+	local data = [];
+	while (true){
+		rc = sock.receive("*a");
+		s = rc[0];
+		//print("s", s, rc[1]);
+		if (s.len() == 0) break;
+		data.push(s);
+	}
+	sock.close();
+	//print(file, count)
+	return data.concat("\n");
+}
+
+function count_html_links(content){
+	local lines = [];
+	local line_pos = 0;
+	while((line_pos = content.find("\n", line_pos))){
+		lines.push(line_pos++);
+	}
+	if(line_pos < content.len()) lines.push(content.len());
+	print("Lines :", lines.len());
+	
+	local tag_re = "<a href=\"([^\"]+)\"";
+	local tags = {};
+	content.find_lua(tag_re, function(start, end, m){
+		if(m != "#"){
+			local start_pos = start;
+			local line = lines.bsearch(start_pos);
+			if(line < 0){
+				//binary search didn't found an exact match
+				//but returned the closest element it was tried
+				//turned in negative value
+				line = -line;
+				while(lines[line] < start_pos) ++line;
+			}
+			//find the character position on the line
+			start_pos -= (line > 0 ? lines[line-1] : 0);
+			
+			if(!tags.get(m, false)){
+				stmt.reset();
+				stmt.bind(1, m);
+				stmt.step();
+				
+				tags[m] <- [start, end, line];
+				//print(start, end, line+1, start_pos, m);
+			}
+		}
+		return true;
+	});
+	return tags;
+}
+
+function count_html_tags(content){
+	local lines = [];
+	local line_pos = 0;
+	while((line_pos = content.find("\n", line_pos))){
+		lines.push(line_pos++);
+	}
+	if(line_pos < content.len()) lines.push(content.len());
+	print("Lines :", lines.len());
+	
+	local tag_re = "(</?div[^>]*>)";
+	local tags = [];
+	content.find_lua(tag_re, function(start, end, m){
+		local start_pos = start;
+		local line = lines.bsearch(start_pos);
+		if(line < 0){
+			//binary search didn't found an exact match
+			//but returned the closest element it was tried
+			//turned in negative value
+			line = -line;
+			while(lines[line] < start_pos) ++line;
+		}
+		//find the character position on the line
+		start_pos -= (line > 0 ? lines[line-1] : 0);
+		
+		tags.push([start, end, line, m]);
+		//print(start, end, m[1] == '/' ? "close" : "open", line+1, start_pos, m);
+		return true;
+	});
+	return tags;
+}
+
+function count_html_tags_from_file(fn){
+	local fd = file(fn, "r");
+	local content = fd.read(fd.len());
+	fd.close();
+	
+	return count_html_tags(content);
+}
+
+function count_html_tags_from_http(host, fn){
+	local content = downloadChunked(host, fn);
+	return count_html_tags(content);
+}
+
+//local tags = count_html_tags_from_file("/var/www/tribiq2/index2.html");
+//local tags = count_html_tags_from_http("tribiq.com", "/");
+
+local content = downloadChunked("tribiq.com", "/");
+
+local divs = count_html_tags(content);
+print("Html divs :", divs.len());
+
+local links = count_html_links(content);
+print("Html links :", links.len());
+
+foreach(k,v in links){
+	if(!k.startswith("http://")){
+		local fn = k[0] == '/' ? k : "/" + k;
+		local page_content = downloadChunked("tribiq.com", fn);
+		local page_divs = count_html_tags(page_content);
+
+		local found;
+		foreach(idx, rec in page_divs){
+			local tag = rec[3];
+			if(tag.find("\"Main\"")){
+				found = idx
+				break;
+			}
+		}
+
+		if(found){
+			local start_pos = page_divs[found][1] +1; //end of start tag
+			local nested = 1;
+			for(local i=found+1, count=page_divs.len(); i < count; ++i){
+				local rec = page_divs[i];
+				local tag = rec[3];
+				if(tag[1] == '/') --nested;
+				else ++nested;
+				if(nested == 0){
+					local end_pos = rec[0]; //start of closing tag
+					local div_content = page_content.slice(start_pos, end_pos);
+					div_content = div_content.gsub("\n%s+", "");
+					//print( div_content );
+					print("Link:", k, start_pos, end_pos, div_content);
+					stmt_content.reset();
+					stmt_content.bind(1, div_content);
+					stmt_content.bind(2, k);
+					stmt_content.step();
+					break;
+				}
+			} 
+		}
+	}
+}
+
+
+if (vargv.len() > 1){ 
+	count_html_tags(vargv[1]);
+}
+
+stmt.finalize();
+stmt_content.finalize();
+db.exec_dml("commit;");
+db.close();
+socket.close();

+ 113 - 0
SquiLu/samples/dump-har.nut

@@ -0,0 +1,113 @@
+//local har_fn = "/home/mingo/Downloads/builder.yaml.de.har";
+
+local dest_folder = "/tmp/har-tmp/";
+os.system(format("mkdir %s", dest_folder));
+
+local fd = file(har_fn, "r");
+local fc = fd.read(fd.len());
+fd.close();
+
+function json2var(json) {
+	local vm = SlaveVM();
+	local slave_func = "getTable";
+	
+	//debug_print(json, "\n");
+	//convert new data from json to squilu table for merge
+	vm.compilestring(slave_func, "return " + json);
+	local tbl = vm.call(true, slave_func);
+	return tbl;
+}
+
+function dumpVar(vtd)
+{
+	local vtype = type(vtd);
+	if( vtype == "table" )
+	{
+		foreach(k,v in vtd)
+		{
+			print(k, (v || "").tostring().len());
+			dumpVar(v);
+		}
+	}
+	else if( vtype == "array" )
+	{
+		foreach(k,v in vtd)
+		{
+			print(k, (v || "").tostring().len());
+			dumpVar(v);
+		}
+	}
+}
+
+
+local folders_made = {};
+
+function getPath(url)
+{
+	local ary = url.split('/');
+	for(local i = 2, len = ary.len()-1; i < len; ++i)
+	{
+		print(i,ary[i]);
+		local folder = ary.slice(2, i+1).join("/");
+		local cmd = format("mkdir %s", dest_folder + folder);
+		if(!folders_made.rawget(folder, false))
+		{
+			print(cmd);
+			os.system(cmd);
+			folders_made.rawset(folder, true);
+		}
+	}
+	local path = ary.slice(2).join("/");
+	//print(path);
+	return path;
+}
+
+function dumpContent(vhar)
+{
+	local entries = vhar.log.entries;
+	foreach(k, ventry in entries)
+	{
+		local url = ventry.request.url;
+		local path = getPath(url);
+		if(path.endswith("/"))
+		{
+			path += "index.html";
+		}
+		if( ventry.response.content.mimeType == "text/html")
+		{
+			if(!path.indexOf(".htm"))
+			{
+				path = getPath(url + "/index.html");
+			}
+		}
+		local idx = path.indexOf("@");
+		if(idx < 0) idx = path.indexOf("?");
+		
+		if(idx > 0)
+		{
+			path = path.slice(0, idx);
+		}
+		
+		local content = ventry.response.content.rawget("text", false);
+		
+		if(content)
+		{
+			if(ventry.response.content.rawget("encoding", "") == "base64")
+			{
+				content = base64.decode(content);
+			}
+			
+			print(path, content.len());
+			
+			local full_path = dest_folder + path;
+			local fdc = file(full_path, "w");
+			fdc.write(content);
+			fdc.close();
+		}
+	}
+}
+
+local har_json = json2var(fc);
+
+//dumpVar(har_json);
+dumpContent(har_json);

+ 804 - 0
SquiLu/samples/editor-fltk.nut

@@ -0,0 +1,804 @@
+//
+// "$Id: editor.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+//
+// A simple text editor program for the Fast Light Tool Kit (FLTK).
+//
+// This program is described in Chapter 4 of the FLTK Programmer's Guide.
+//
+// Copyright 1998-2010 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file.  If this
+// file is missing or damaged, see the license at:
+//
+//     http://www.fltk.org/COPYING.php
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+//
+// Include necessary headers...
+//
+/*
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#ifdef __MWERKS__
+# define FL_DLL
+#endif
+
+#include <FL/Fl.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Double_Window.H>
+#include <FL/fl_ask.H>
+#include <FL/Fl_Native_File_Chooser.H>
+#include <FL/Fl_Menu_Bar.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Text_Buffer.H>
+#include <FL/Fl_Text_Editor.H>
+#include <FL/filename.H>
+*/
+local WIN32 = os.getenv("WINDIR") != null
+local __APPLE__ = os.getenv("MAC??") != null
+
+local                changed = 0;
+local               filename = "";
+local               title="";
+local		textbuf = null;
+
+
+// Syntax highlighting stuff...
+const TS = 14; // default editor textsize
+local stylebuf = null;
+local styletable = [	// Style table
+		     [ FL_BLACK,      FL_COURIER,           TS ], // A - Plain
+		     [ FL_DARK_GREEN, FL_HELVETICA_ITALIC,  TS ], // B - Line comments
+		     [ FL_DARK_GREEN, FL_HELVETICA_ITALIC,  TS ], // C - Block comments
+		     [ FL_BLUE,       FL_COURIER,           TS ], // D - Strings
+		     [ FL_DARK_RED,   FL_COURIER,           TS ], // E - Directives
+		     [ FL_DARK_RED,   FL_COURIER_BOLD,      TS ], // F - Types
+		     [ FL_BLUE,       FL_COURIER_BOLD,      TS ], // G - Keywords
+		   ];
+local code_keywords = [	// List of known C/C++ keywords...
+		     "and",
+		     "and_eq",
+		     "asm",
+		     "bitand",
+		     "bitor",
+		     "break",
+		     "case",
+		     "catch",
+		     "compl",
+		     "continue",
+		     "default",
+		     "delete",
+		     "do",
+		     "else",
+		     "false",
+		     "for",
+		     "goto",
+		     "if",
+		     "new",
+		     "not",
+		     "not_eq",
+		     "operator",
+		     "or",
+		     "or_eq",
+		     "return",
+		     "switch",
+		     "template",
+		     "this",
+		     "throw",
+		     "true",
+		     "try",
+		     "while",
+		     "xor",
+		     "xor_eq"
+		   ];
+local code_types = [	// List of known C/C++ types...
+		     "auto",
+		     "bool",
+		     "char",
+		     "class",
+		     "const",
+		     "const_cast",
+		     "double",
+		     "dynamic_cast",
+		     "enum",
+		     "explicit",
+		     "extern",
+		     "float",
+		     "friend",
+		     "inline",
+		     "int",
+		     "long",
+		     "mutable",
+		     "namespace",
+		     "private",
+		     "protected",
+		     "public",
+		     "register",
+		     "short",
+		     "signed",
+		     "sizeof",
+		     "static",
+		     "static_cast",
+		     "struct",
+		     "template",
+		     "typedef",
+		     "typename",
+		     "union",
+		     "unsigned",
+		     "virtual",
+		     "void",
+		     "volatile"
+		   ];
+
+
+//
+// 'compare_keywords()' - Compare two keywords...
+//
+
+//extern "C" {
+//  int
+function compare_keywords(a, b) { return a <=> b; }
+//}
+
+//
+// 'style_parse()' - Parse text and produce style data.
+//
+
+//void
+function style_parse(text, style, length) {
+  local	     current;
+  local	     col;
+  local	     last;
+  local	     buf, bufptr;
+  local temp;
+  local istyle = 0;
+  local itext = 0;
+
+  // Style letters:
+  //
+  // A - Plain
+  // B - Line comments
+  // C - Block comments
+  // D - Strings
+  // E - Directives
+  // F - Types
+  // G - Keywords
+
+  //~ for (current = style[istyle], col = 0, last = 0; length > 0; length --, itext ++) {
+    //~ if (current == 'B' || current == 'F' || current == 'G') current = 'A';
+    //~ if (current == 'A') {
+      //~ // Check for directives, comments, strings, and keywords...
+      //~ if (col == 0 && text[itext] == '#') {
+        //~ // Set style to directive
+        //~ current = 'E';
+      //~ } else if (strncmp(text, "//", 2) == 0) {
+        //~ current = 'B';
+	//~ for (; length > 0 && text[itext] != '\n'; length --, itext ++) istyle++ = 'B';
+
+        //~ if (length == 0) break;
+      //~ } else if (strncmp(text, "/*", 2) == 0) {
+        //~ current = 'C';
+      //~ } else if (strncmp(text, "\\\"", 2) == 0) {
+        //~ // Quoted quote...
+	//~ style[istyle++] = current;
+	//~ style[style++] = current;
+	//~ itext ++;
+	//~ length --;
+	//~ col += 2;
+	//~ continue;
+      //~ } else if (text[itext] == '\"') {
+        //~ current = 'D';
+      //~ } else if (!last && (islower((text[itext])&255) || text[itext] == '_')) {
+        //~ // Might be a keyword...
+	//~ for (temp = text[itext], bufptr = buf;
+	     //~ (islower((temp)&255) || temp == '_') && bufptr < (buf + sizeof(buf) - 1);
+	     //~ *bufptr++ = *temp++);
+
+        //~ if (!islower((*temp)&255) && *temp != '_') {
+	  //~ *bufptr = '\0';
+
+          //~ bufptr = buf;
+
+	  //~ if (bsearch(&bufptr, code_types,
+	              //~ sizeof(code_types) / sizeof(code_types[0]),
+		      //~ sizeof(code_types[0]), compare_keywords)) {
+	    //~ while (text < temp) {
+	      //~ style[istyle++] = 'F';
+	      //~ itext ++;
+	      //~ length --;
+	      //~ col ++;
+	    //~ }
+
+	    //~ itext --;
+	    //~ length ++;
+	    //~ last = 1;
+	    //~ continue;
+	  //~ } else if (bsearch(&bufptr, code_keywords,
+	                     //~ sizeof(code_keywords) / sizeof(code_keywords[0]),
+		             //~ sizeof(code_keywords[0]), compare_keywords)) {
+	    //~ while (text < temp) {
+	      //~ style[istyle++] = 'G';
+	      //~ itext ++;
+	      //~ length --;
+	      //~ col ++;
+	    //~ }
+
+	    //~ itext --;
+	    //~ length ++;
+	    //~ last = 1;
+	    //~ continue;
+	  //~ }
+	//~ }
+      //~ }
+    //~ } else if (current == 'C' && strncmp(text, "*/", 2) == 0) {
+      //~ // Close a C comment...
+      //~ style[istyle++] = current;
+      //~ istyle++ = current;
+      //~ itext ++;
+      //~ length --;
+      //~ current = 'A';
+      //~ col += 2;
+      //~ continue;
+    //~ } else if (current == 'D') {
+      //~ // Continuing in string...
+      //~ if (strncmp(text[itext], "\\\"", 2) == 0) {
+        //~ // Quoted end quote...
+	//~ style[istyle++] = current;
+	//~ style[istyle++] = current;
+	//~ itext ++;
+	//~ length --;
+	//~ col += 2;
+	//~ continue;
+      //~ } else if (text[itext] == '\"') {
+        //~ // End quote...
+	//~ style[istyle++] = current;
+	//~ col ++;
+	//~ current = 'A';
+	//~ continue;
+      //~ }
+    //~ }
+
+    //~ // Copy style info...
+    //~ if (current == 'A' && (text[itext] == '{' || text[itext] == '}')) style[style++] = 'G';
+    //~ else style[istyle++] = current;
+    //~ col ++;
+
+    //~ last = isalnum((text[itext])&255) || text[itext] == '_' || text[itext] == '.';
+
+    //~ if (text[itext] == '\n') {
+      //~ // Reset column and possibly reset the style
+      //~ col = 0;
+      //~ if (current == 'B' || current == 'E') current = 'A';
+    //~ }
+  //~ }
+}
+
+
+//
+// 'style_init()' - Initialize the style buffer...
+//
+
+//void
+function style_init() {
+  local style = new blob(textbuf->length()+1);
+  local text = textbuf->text();
+
+  style.memset(0, 'A', textbuf->length());
+  style[textbuf->length()] = '\0';
+
+  if (!stylebuf) stylebuf = new Fl_Text_Buffer(textbuf->length());
+
+  style_parse(text, style, textbuf->length());
+
+  stylebuf->text(style.tostring());
+  //delete[] style;
+  //free(text);
+}
+
+
+//
+// 'style_unfinished_cb()' - Update unfinished styles.
+//
+
+//void
+function style_unfinished_cb(pint, pvoid) {
+}
+
+
+//
+// 'style_update()' - Update the style buffer...
+//
+
+//void
+function style_update(pos,		// I - Position of update
+             nInserted,	// I - Number of inserted chars
+	     nDeleted,	// I - Number of deleted chars
+             nRestyled,	// I - Number of restyled chars
+	     deletedText,// I - Text that was deleted
+             cbArg) {	// I - Callback data
+  local	start,				// Start of text
+	end;				// End of text
+  local	last,				// Last style on line
+	style,				// Style data
+	text;				// Text data
+
+
+  // If this is just a selection change, just unselect the style buffer...
+  if (nInserted == 0 && nDeleted == 0) {
+    stylebuf->unselect();
+    return;
+  }
+
+  // Track changes in the text buffer...
+  if (nInserted > 0) {
+    // Insert characters into the style buffer...
+    style = new char[nInserted + 1];
+    memset(style, 'A', nInserted);
+    style[nInserted] = '\0';
+
+    stylebuf->replace(pos, pos + nDeleted, style);
+    //delete[] style;
+  } else {
+    // Just delete characters in the style buffer...
+    stylebuf->remove(pos, pos + nDeleted);
+  }
+
+  // Select the area that was just updated to avoid unnecessary
+  // callbacks...
+  stylebuf->select(pos, pos + nInserted - nDeleted);
+
+  // Re-parse the changed region; we do this by parsing from the
+  // beginning of the previous line of the changed region to the end of
+  // the line of the changed region...  Then we check the last
+  // style character and keep updating if we have a multi-line
+  // comment character...
+  start = textbuf->line_start(pos);
+//  if (start > 0) start = textbuf->line_start(start - 1);
+  end   = textbuf->line_end(pos + nInserted);
+  text  = textbuf->text_range(start, end);
+  style = stylebuf->text_range(start, end);
+  if (start==end)
+    last = 0;
+  else
+    last  = style[end - start - 1];
+
+//  printf("start = %d, end = %d, text = \"%s\", style = \"%s\", last='%c'...\n",
+//         start, end, text, style, last);
+
+  style_parse(text, style, end - start);
+
+//  printf("new style = \"%s\", new last='%c'...\n",
+//         style, style[end - start - 1]);
+
+  stylebuf->replace(start, end, style);
+  /*((Fl_Text_Editor *)*/cbArg->redisplay_range(start, end);
+
+  if (start==end || last != style[end - start - 1]) {
+//    printf("Recalculate the rest of the buffer style\n");
+    // Either the user deleted some text, or the last character
+    // on the line changed styles, so reparse the
+    // remainder of the buffer...
+    //free(text);
+    //free(style);
+
+    end   = textbuf->length();
+    text  = textbuf->text_range(start, end);
+    style = stylebuf->text_range(start, end);
+
+    style_parse(text, style, end - start);
+
+    stylebuf->replace(start, end, style);
+    /*((Fl_Text_Editor *)*/cbArg->redisplay_range(start, end);
+  }
+
+  //free(text);
+  //free(style);
+}
+
+
+// Editor window functions and class...
+/*
+void save_cb();
+void saveas_cb();
+void find2_cb(Fl_Widget*, void*);
+void replall_cb(Fl_Widget*, void*);
+void replace2_cb(Fl_Widget*, void*);
+void replcan_cb(Fl_Widget*, void*);
+*/
+class EditorWindow extends Fl_Double_Window {
+  //public:
+    replace_dlg = null;
+    replace_find = null;
+    replace_with = null;
+    replace_all = null;
+    replace_next = null;
+    replace_cancel = null;
+
+    editor = null;
+    search = null;
+
+constructor(iw, ih, t) {
+  base.constructor(iw, ih, t);
+  replace_dlg = new Fl_Window(300, 105, "Replace");
+    replace_find = new Fl_Input(80, 10, 210, 25, "Find:");
+    replace_find->align(FL_ALIGN_LEFT);
+
+    replace_with = new Fl_Input(80, 40, 210, 25, "Replace:");
+    replace_with->align(FL_ALIGN_LEFT);
+
+    replace_all = new Fl_Button(10, 70, 90, 25, "Replace All");
+    replace_all->callback(replall_cb, this);
+
+    replace_next = new Fl_Return_Button(105, 70, 120, 25, "Replace Next");
+    replace_next->callback(replace2_cb, this);
+
+    replace_cancel = new Fl_Button(230, 70, 60, 25, "Cancel");
+    replace_cancel->callback(replcan_cb, this);
+  replace_dlg->end();
+  replace_dlg->set_non_modal();
+  editor = 0;
+  search = "";
+}
+
+//destructor() {
+//  delete replace_dlg;
+//}
+};
+
+function check_save() {
+  if (!changed) return 1;
+
+  local r = fl_choice("The current file has not been saved.\nWould you like to save it now?",
+                    "Cancel", "Save", "Don't Save");
+
+  if (r == 1) {
+    save_cb(); // Save the file...
+    return !changed;
+  }
+
+  return (r == 2) ? 1 : 0;
+}
+
+local loading = 0;
+function load_file(newfile, ipos) {
+  loading = 1;
+  local insert = (ipos != -1);
+  changed = insert;
+  if (!insert) filename = "";
+  local r;
+  if (!insert) r = textbuf->loadfile(newfile);
+  else r = textbuf->insertfile(newfile, ipos);
+  changed = changed || textbuf->input_file_was_transcoded;
+  if (r)
+    fl_alert("Error reading from file \'%s\':\n%s.", newfile, strerror(errno));
+  else
+    if (!insert) filename = newfile;
+  loading = 0;
+  //textbuf->call_modify_callbacks();
+}
+
+function save_file(newfile) {
+  if (textbuf->savefile(newfile))
+    fl_alert("Error writing to file \'%s\':\n%s.", newfile, strerror(errno));
+  else
+    filename = newfile;
+  changed = 0;
+  textbuf->call_modify_callbacks();
+}
+
+function copy_cb(sender, e) {
+  Fl_Text_Editor.kf_copy(0, e->editor);
+}
+
+function cut_cb(sender, e) {
+  Fl_Text_Editor.kf_cut(0, e->editor);
+}
+
+function delete_cb(sender, v) {
+  textbuf->remove_selection();
+}
+
+function find_cb(w, e) {
+  local val;
+
+  val = fl_input("Search String:", e->search);
+  if (val != null) {
+    // User entered a string - go find it!
+    e->search = val;
+    find2_cb(w, v);
+  }
+}
+
+function find2_cb(w, e) {
+  if (e->search.len() == 0) {
+    // Search string is blank; get a new one...
+    find_cb(w, v);
+    return;
+  }
+
+  local pos = e->editor->insert_position();
+  local found = textbuf->search_forward(pos, e->search/*, &pos*/);
+  if (found) {
+    // Found a match; select and update the position...
+    textbuf->select(pos, pos+strlen(e->search));
+    e->editor->insert_position(pos+e->search.len());
+    e->editor->show_insert_position();
+  }
+  else fl_alert("No occurrences of \'%s\' found!", e->search);
+}
+
+function set_title(w) {
+  if (filename.len() == 0) title = "Untitled";
+  else {
+    local slash = filename.rfind("/");
+    if( WIN32 && slash == null) slash = filename.find("\\");
+    if (slash != null) title = filename.slice(slash + 1);
+    else title = filename;
+  }
+
+  if (changed) title += " (modified)";
+
+  w->label(title);
+}
+
+function changed_cb(iparam, nInserted, nDeleted, iparam2, strparam, w) {
+  if ((nInserted || nDeleted) && !loading) changed = 1;
+  set_title(w);
+  if (loading) w->editor->show_insert_position();
+}
+
+function new_cb(sender, udata) {
+  if (!check_save()) return;
+
+  filename = "";
+  textbuf->select(0, textbuf->length());
+  textbuf->remove_selection();
+  changed = 0;
+  textbuf->call_modify_callbacks();
+}
+
+function open_cb(sender, udata) {
+  if (!check_save()) return;
+  local  fnfc = Fl_Native_File_Chooser();
+  fnfc.title("Open file");
+  fnfc.type(Fl_Native_File_Chooser.BROWSE_FILE);
+  if ( fnfc.show() ) return;
+  load_file(fnfc.filename(), -1);
+
+}
+
+function insert_cb(sender, w) {
+  local fnfc = Fl_Native_File_Chooser();
+  fnfc.title("Insert file");
+  fnfc.type(Fl_Native_File_Chooser.BROWSE_FILE);
+  if ( fnfc.show() ) return;
+  load_file(fnfc.filename(), w->editor->insert_position());
+}
+
+function paste_cb(sender, e) {
+  Fl_Text_Editor.kf_paste(0, e->editor);
+}
+
+local num_windows = 0;
+
+function close_cb(sender, w) {
+
+  if (num_windows == 1) {
+    if (!check_save())
+      return;
+  }
+
+  w->hide();
+  w->editor->buffer(0);
+  textbuf->remove_modify_callback(style_update, w->editor);
+  textbuf->remove_modify_callback(changed_cb, w);
+  Fl.delete_widget(w);
+
+  num_windows--;
+  if (!num_windows) os.exit(0);
+}
+
+function quit_cb(sender, udata) {
+  if (changed && !check_save())
+    return;
+
+  os.exit(0);
+}
+
+function replace_cb(sender, e) {
+  e->replace_dlg->show();
+}
+
+function replace2_cb(sender, e) {
+  local find = e->replace_find->value();
+  local replace = e->replace_with->value();
+
+  if (find.len() == 0) {
+    // Search string is blank; get a new one...
+    e->replace_dlg->show();
+    return;
+  }
+
+  e->replace_dlg->hide();
+
+  local pos = e->editor->insert_position();
+  local found = textbuf->search_forward(pos, find /*, &pos*/);
+
+  if (found) {
+    // Found a match; update the position and replace text...
+    textbuf->select(pos, pos+strlen(find));
+    textbuf->remove_selection();
+    textbuf->insert(pos, replace);
+    textbuf->select(pos, pos+replace.len());
+    e->editor->insert_position(pos+replace.len());
+    e->editor->show_insert_position();
+  }
+  else fl_alert("No occurrences of \'%s\' found!", find);
+}
+
+function replall_cb(sender, e) {
+  local find = e->replace_find->value();
+  local replace = e->replace_with->value();
+
+  find = e->replace_find->value();
+  if (find.len() == 0) {
+    // Search string is blank; get a new one...
+    e->replace_dlg->show();
+    return;
+  }
+
+  e->replace_dlg->hide();
+
+  e->editor->insert_position(0);
+  local times = 0;
+
+  // Loop through the whole string
+  for (local found = 1; found;) {
+    local pos = e->editor->insert_position();
+    found = textbuf->search_forward(pos, find/*, &pos*/);
+
+    if (found) {
+      // Found a match; update the position and replace text...
+      textbuf->select(pos, pos+strlen(find));
+      textbuf->remove_selection();
+      textbuf->insert(pos, replace);
+      e->editor->insert_position(pos+strlen(replace));
+      e->editor->show_insert_position();
+      times++;
+    }
+  }
+
+  if (times) fl_message("Replaced %d occurrences.", times);
+  else fl_alert("No occurrences of \'%s\' found!", find);
+}
+
+function replcan_cb(sender, e) {
+  e->replace_dlg->hide();
+}
+
+function save_cb() {
+  if (filename.len() == 0) {
+    // No filename - get one!
+    saveas_cb();
+    return;
+  }
+  else save_file(filename);
+}
+
+function saveas_cb() {
+  local fnfc = Fl_Native_File_Chooser();
+  fnfc.title("Save File As?");
+  fnfc.type(Fl_Native_File_Chooser.BROWSE_SAVE_FILE);
+  if ( fnfc.show() ) return;
+  save_file(fnfc.filename());
+}
+
+function view_cb(sender, udata) {
+  local w = new_view();
+  w->show();
+}
+
+
+local menuitems = [
+  [ "&File",              0, 0, 0, FL_SUBMENU ],
+    [ "&New File",        0, new_cb ],
+    [ "&Open File...",    FL_COMMAND + 'o', open_cb ],
+    [ "&Insert File...",  FL_COMMAND + 'i', insert_cb, 0, FL_MENU_DIVIDER ],
+    [ "&Save File",       FL_COMMAND + 's', save_cb ],
+    [ "Save File &As...", FL_COMMAND + FL_SHIFT + 's', saveas_cb, 0, FL_MENU_DIVIDER ],
+    [ "New &View",        FL_ALT + (__APPLE__ ? FL_COMMAND : 0) + 'v', view_cb, 0 ],
+    [ "&Close View",      FL_COMMAND + 'w', close_cb, 0, FL_MENU_DIVIDER ],
+    [ "E&xit",            FL_COMMAND + 'q', quit_cb, 0 ],
+    [ 0 ],
+
+  [ "&Edit", 0, 0, 0, FL_SUBMENU ],
+    [ "Cu&t",             FL_COMMAND + 'x', cut_cb ],
+    [ "&Copy",            FL_COMMAND + 'c', copy_cb ],
+    [ "&Paste",           FL_COMMAND + 'v', paste_cb ],
+    [ "&Delete",          0, delete_cb ],
+    [ 0 ],
+
+  [ "&Search", 0, 0, 0, FL_SUBMENU ],
+    [ "&Find...",         FL_COMMAND + 'f', find_cb ],
+    [ "F&ind Again",      FL_COMMAND + 'g', find2_cb ],
+    [ "&Replace...",      FL_COMMAND + 'r', replace_cb ],
+    [ "Re&place Again",   FL_COMMAND + 't', replace2_cb ],
+    [ 0 ],
+
+  [ 0 ]
+];
+
+function mergerSubMenu(prefix, amenu, curr_pos, last_pos){
+	for(; curr_pos < last_pos; ++curr_pos){
+		local item = amenu[curr_pos];
+		if(!item[0]) break;
+		if(prefix){
+			item[0] = prefix + "/" + item[0];
+		}
+		if(item.len() > 4 && item[4] & FL_SUBMENU){
+			curr_pos = mergerSubMenu(item[0], amenu, ++curr_pos, last_pos);
+		}
+	}
+	return curr_pos;
+}
+mergerSubMenu(null, menuitems, 0, menuitems.len());
+
+
+function new_view() {
+  local w = new EditorWindow(660, 400, title);
+    w->begin();
+    local m = new Fl_Menu_Bar(0, 0, 660, 30);
+    m->copy(menuitems, w);
+    w->editor = new Fl_Text_Editor(0, 30, 660, 370);
+    w->editor->textfont(FL_COURIER);
+    w->editor->textsize(TS);
+  //w->editor->wrap_mode(Fl_Text_Editor::WRAP_AT_BOUNDS, 250);
+    w->editor->buffer(textbuf);
+    w->editor->highlight_data(stylebuf, styletable, styletable.len(),
+			      'A', style_unfinished_cb, 0);
+  textbuf->text();
+  style_init();
+  w->end();
+  w->resizable(w->editor);
+ 
+  //w->callback(close_cb, w);
+
+  //textbuf->add_modify_callback(style_update, w->editor);
+  //textbuf->add_modify_callback(changed_cb, w);
+  //textbuf->call_modify_callbacks();
+  num_windows++;
+  return w;
+}
+
+function main(argc, argv) {
+  textbuf = new Fl_Text_Buffer();
+//textbuf->transcoding_warning_action = NULL;
+  style_init();
+
+  local window = new_view();
+
+  //window->show(1, argv);
+  window->show();
+
+  if (argc > 0) load_file(argv[0], -1);
+load_file("editor-fltk.nut", -1);
+
+  return Fl.run();
+}
+
+main(vargv.len(), vargv);
+
+//
+// End of "$Id: editor.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+//

+ 61 - 0
SquiLu/samples/gen-class-hashtable.nut

@@ -0,0 +1,61 @@
+class HashTable
+{
+    /*
+    A CursorKind describes the kind of entity that a cursor points to.
+    */
+
+    # The required BaseEnumeration declarations.
+    _ht = null;
+    
+    constructor(int_size = 0)
+    {
+	_ht = {};
+    }
+
+    function len(int_size)
+    {
+        //Test if this is a declaration kind.
+        return _ht.len();
+    }
+
+    function newSlot(str_key, value)
+    {
+	_ht.rawset(str_key, value);
+    }
+
+    function set(str_key, value)
+    {
+	_ht.rawset(str_key, value);
+    }
+
+    function get(str_key, default_value)
+    {
+	return _ht.rawget(str_key, default_value);
+    }
+
+    function exists(str_key)
+    {
+	return _ht.rawget(str_key);
+    }
+
+    function remove(key)
+    {
+	_ht.rawdelete(key);
+    }
+
+    function clear()
+    {
+    }
+
+    function next()
+    {
+    }
+
+    function tostring()
+    {
+        return format("HashTable.%s", name);
+    }
+}
+
+dofile("generate-cpp-class-wrapper.nut");
+generateCppClassWrapper(HashTable, "HashTable");

+ 243 - 0
SquiLu/samples/generate-cpp-class-wrapper.nut

@@ -0,0 +1,243 @@
+
+function generateCppClassWrapper(klass, klass_name="klass")
+{
+	local dbg = function(...)
+	{
+		return;
+		foreach(k, v in vargv)
+		{
+			if(k) stdout.write("\t");
+			stdout.write(v);
+		}
+		stdout.write("\n");
+	}
+	
+	local rename_code = function(code)
+	{
+		return code.gsub("KLASS", klass_name.toupper()).gsub("klass", klass_name);
+	}
+	
+	local print_code = function(code)
+	{
+		print(rename_code(code));
+	}
+	
+	local get_var_type = function(var_name, to_declare=false)
+	{
+		if(var_name.startswith("int_"))
+		{
+			return to_declare ? "i" : "INTEGER";
+		}
+		if(var_name.startswith("float_"))
+		{
+			return to_declare ? "f" : "FLOAT";
+		}
+		if(var_name.startswith("str_"))
+		{
+			return to_declare ? "s" : "STRING";
+		}
+		return to_declare ? "." : "STRING";
+	}
+	
+	local members = [];
+
+	foreach(k,v in klass)
+	{
+		members.push(k);
+	}
+	
+	members.sort();
+	
+	print_code([==[
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef USE_KLASS
+
+#include "squirrel.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>  /* for malloc */
+#include <assert.h>  /* for a few sanity tests */
+
+#include "klass.h"
+
+static const SQChar SQ_LIBNAME[] = _SC("klass");
+
+SQ_OPT_STRING_STRLEN();
+
+static const SQChar SSL_CTX_Tag[]   = _SC("sq_klass_ctx");
+#define GET_klass_INSTANCE() SQ_GET_INSTANCE(v, 1, KLASS, KLASS_Tag) \
+	if(self == NULL) return sq_throwerror(v, _SC("klass object already closed"));
+
+
+static SQRESULT klass_release_hook(SQUserPointer p, SQInteger size, HSQUIRRELVM v)
+{
+	KLASS *self = (KLASS*)p;
+	if(self) klass_free(self);
+	return 0;
+}
+
+static SQRESULT klass_free(HSQUIRRELVM v)
+{
+	SQ_FUNC_VARS_NO_TOP(v);
+	GET_ssl_INSTANCE();
+	klass_release_hook(self, 0, v);
+	sq_setinstanceup(v, 1, 0);
+	return 0;
+}
+
+static SQRESULT klass_constructor(HSQUIRRELVM v, KLASS *klass, int free_on_gc)
+{
+    if(!klass)
+        return sq_throwerror(v, _SC("Could'nt create an klass object."));
+
+    sq_pushstring(v, SQ_LIBNAME, -1);
+    if(sq_getonroottable(v) == SQ_OK){
+        sq_pushstring(v, klass_NAME, -1);
+        if(sq_get(v, -2) == SQ_OK){
+            if(sq_createinstance(v, -1) == SQ_OK){
+                sq_setinstanceup(v, -1, ssl);
+                if(free_on_gc) sq_setreleasehook(v,-1, klass_release_hook);
+                return 1;
+            }
+        }
+    }
+	return SQ_ERROR;
+}
+
+]==]);
+	
+	foreach(k,v in members)
+	{
+		dbg(k,v);
+		v = klass[v];
+		local v_type = type(v);
+		if(v_type == "function")
+		{
+			local info = v.getinfos();
+			local ndefparams = info.defparams.len();
+			print_code(format("static SQRESULT sq_klass_%s(HSQUIRRELVM v){", info.name));
+			if(ndefparams) print("\tSQ_FUNC_VARS(v);");
+			else print("\tSQ_FUNC_VARS_NO_TOP(v);");
+			print_code("\tGET_klass_INSTANCE();\n");
+			
+			local nparams = info.parameters.len();
+			if(nparams > 1)
+			{
+				local firstDefParam = nparams - ndefparams;
+				for(local i=1; i < nparams; ++i)
+				{
+					local hasDefParam = ndefparams && (i >= firstDefParam);
+					local vtype = get_var_type(info.parameters[i]);
+					if(hasDefParam) print(format("\tSQ_OPT_%s(v, %d, %s, %q);", vtype, i+1, info.parameters[i], info.defparams[i - firstDefParam].tostring()));
+					else print(format("\tSQ_GET_%s(v, %d, %s);", vtype, i+1, info.parameters[i]));
+				}
+			}
+			
+			foreach(k2,v2 in info)
+			{
+				dbg("", k2, v2);
+				if(type(v2) == "array")
+				{
+					foreach(k3,v3 in v2)
+					{
+						dbg("","", k3, v3);
+					}
+				}
+			}
+			//local return_type = 
+			local attr = klass.getattributes(info.name);
+			if(attr && attr.rawin("cfunc")) print("//", attr.rawget("cfunc"));
+			print("\n\treturn 0;\n}\n");
+		}
+	}
+	
+	print_code( [==[
+#define _DECL_KLASS_FUNC(name,nparams,pmask) {_SC(#name),sq_klass_##name,nparams,pmask}
+static SQRegFunction klass_obj_funcs[]={
+]==]);
+	
+	foreach(k,v in members)
+	{
+		v = klass[v];
+		if(type(v) == "function")
+		{
+			local info = v.getinfos();
+			local ndefparams = info.defparams.len();
+			local nparams = info.parameters.len();
+			local nreqparams = nparams - ndefparams;
+			if(ndefparams) nreqparams *= -1;
+			stdout.write(rename_code(format("\t_DECL_KLASS_FUNC(%s, %d, _SC(\".", info.name, nreqparams)));
+			
+			for(local i=1; i < nparams; ++i)
+			{
+				stdout.write(get_var_type(info.parameters[i], true));
+			}
+			stdout.write("\")),\n");
+		}
+	}
+	
+	print_code([==[
+	{0,0}
+};
+#undef _DECL_KLASS_FUNC
+
+typedef struct {
+  const SQChar *Str;
+  SQInteger Val;
+} KeyIntType, * KeyIntPtrType;
+
+static KeyIntType klass_constants[] = {
+    #define MK_CONST(c) {_SC(#c), c}
+    //MK_CONST(SSL_SESSION_ID_SIZE),
+]==]);
+	foreach(k,v in klass)
+	{
+		//print(k, v);
+		local v_type = type(v);
+		if(v_type == "integer")
+		{
+			if(k.startswith("const_"))
+			{
+				local const_name = k.replace("const_", "");
+				print(format("\tMK_CONST(v, %s);", const_name));
+			}
+		}
+	}
+	print_code([==[
+    {0,0}
+};
+
+/* This defines a function that opens up your library. */
+SQRESULT sqext_register_klass (HSQUIRRELVM v) {
+	//add a namespace klass
+	sq_pushstring(v, SQ_LIBNAME, -1);
+	sq_newtable(v);
+
+	sq_insert_reg_funcs(v, klass_obj_funcs);
+
+	//add constants
+	KeyIntPtrType KeyIntPtr;
+	for (KeyIntPtr = klass_constants; KeyIntPtr->Str; KeyIntPtr++) {
+		sq_pushstring(v, KeyIntPtr->Str, -1);    //first the key
+		sq_pushinteger(v, KeyIntPtr->Val);       //then the value
+		sq_newslot(v, -3, SQFalse);              //store then
+	}
+
+	sq_newslot(v,-3,SQFalse); //add klass table to the root table
+
+	return SQ_OK;
+}
+
+#ifdef __cplusplus
+}
+
+#endif //USE_KLASS
+
+#endif
+
+]==]);
+	
+}

+ 24 - 0
SquiLu/samples/get-files-recursing.nut

@@ -0,0 +1,24 @@
+function getFilesRecursing(base_dir, files)
+{
+	foreach(fname in sqfs.dir(base_dir)){
+		if(fname == "." || fname == "..")
+		{
+			continue;
+		}
+		var file_full_path = base_dir + "/" + fname;
+		if(sqfs.attributes(file_full_path, "mode") == "directory")
+		{
+			getFilesRecursing(file_full_path, files);
+		} else {
+			files.append(file_full_path);
+		}
+	}
+}
+
+var files = [];
+getFilesRecursing(".", files);
+
+for(var i=0, len=files.len(); i < len; ++i)
+{
+	print(files[i]);
+}

+ 68 - 0
SquiLu/samples/k-nucleotide.nut

@@ -0,0 +1,68 @@
+// The Great Computer Language Shootout
+// http://shootout.alioth.debian.org/
+// contributed by Mike Pall
+
+local function kfrequency(seq, freq, k, frame){
+  //local sub = string.sub
+  local k1 = k - 1
+  for(local i=frame, len= seq.len()-k1; i < len; i += k){
+    local c = seq.slice(i, i+k1);
+    freq[c]++;
+  }
+}
+
+local freq_delegate = {
+	_get = function(x) {return 0;}
+}
+
+local function count(seq, frag){
+  local k = frag.len()
+  local freq = {};
+  freq.setdelegate(freq_delegate)
+  for(local frame=0; frame < k; ++frame) kfrequency(seq, freq, k, frame);
+  print(freq.get(frag, 0), "\t", frag, "\n")
+}
+
+local function frequency(seq, k){
+  local freq = {};
+  freq.setdelegate(freq_delegate)
+  for(local frame=0; frame < k; ++frame) kfrequency(seq, freq, k, frame);
+  local sfreq = [], sn = 0
+  foreach( c,v in freq) sfreq[sn++] <- c;
+  sfreq.sort(function(a, b){
+    local fa = freq[a], fb = freq[b]
+    return fa == fb && a > b || fa > fb
+  })
+  sum = seq.len()-k+1
+  foreach(c in sfreq){
+    print(format("%s %0.3f\n", c, (freq[c]*100)/sum))
+  }
+  print("\n")
+}
+
+local function readseq(){
+  //local sub = string.sub
+  for line in io.lines() do
+    if sub(line, 1, 1) == ">" and sub(line, 2, 6) == "THREE" then break end
+  end
+  local lines, ln = {}, 0
+  for line in io.lines() do
+    local c = sub(line, 1, 1)
+    if c == ">" then
+      break
+    elseif c ~= ";" then
+      ln = ln + 1
+      lines[ln] = line
+    end
+  end
+  return string.upper(table.concat(lines, "", 1, ln))
+}
+
+local seq = readseq()
+frequency(seq, 1)
+frequency(seq, 2)
+count(seq, "GGT")
+count(seq, "GGTA")
+count(seq, "GGTATT")
+count(seq, "GGTATTTTAATT")
+count(seq, "GGTATTTTAATTTATAGT")

+ 93 - 0
SquiLu/samples/libcurl.nut

@@ -0,0 +1,93 @@
+class EasyCurl {
+	const_CURLAUTH_NONE = 0;
+	const_CURLAUTH_BASIC = 0;
+	const_CURLAUTH_DIGEST = 0;
+	const_CURLAUTH_NEGOTIATE = 0;
+	/* Deprecated since the advent of CURLAUTH_NEGOTIATE */
+	const_CURLAUTH_GSSNEGOTIATE = 0;
+	const_CURLAUTH_NTLM = 0;
+	const_CURLAUTH_DIGEST_IE = 0;
+	const_CURLAUTH_NTLM_WB = 0;
+	const_CURLAUTH_ONLY = 0;
+	const_CURLAUTH_ANY = 0;
+	const_CURLAUTH_ANYSAFE = 0;
+
+	const_CURLSSH_AUTH_ANY = 0;
+	const_CURLSSH_AUTH_NONE = 0;
+	const_CURLSSH_AUTH_PUBLICKEY = 0;
+	const_CURLSSH_AUTH_PASSWORD = 0;
+	const_CURLSSH_AUTH_HOST = 0;
+	const_CURLSSH_AUTH_KEYBOARD = 0;
+	const_CURLSSH_AUTH_AGENT = 0;
+	const_CURLSSH_AUTH_DEFAULT = 0;
+
+	const_CURLGSSAPI_DELEGATION_NONE = 0;
+	const_CURLGSSAPI_DELEGATION_POLICY_FLAG = 0;
+	const_CURLGSSAPI_DELEGATION_FLAG = 0;
+	
+	const_CURLHEADER_UNIFIED = 0;
+	const_CURLHEADER_SEPARATE = 0;
+
+	/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */
+	const_CURLPROTO_HTTP = 0;
+	const_CURLPROTO_HTTPS = 0;
+	const_CURLPROTO_FTP = 0;
+	const_CURLPROTO_FTPS = 0;
+	const_CURLPROTO_SCP = 0;
+	const_CURLPROTO_SFTP = 0;
+	const_CURLPROTO_TELNET = 0;
+	const_CURLPROTO_LDAP = 0;
+	const_CURLPROTO_LDAPS = 0;
+	const_CURLPROTO_DICT = 0;
+	const_CURLPROTO_FILE = 0;
+	const_CURLPROTO_TFTP = 0;
+	const_CURLPROTO_IMAP = 0;
+	const_CURLPROTO_IMAPS = 0;
+	const_CURLPROTO_POP3 = 0;
+	const_CURLPROTO_POP3S = 0;
+	const_CURLPROTO_SMTP = 0;
+	const_CURLPROTO_SMTPS = 0;
+	const_CURLPROTO_RTSP = 0;
+	const_CURLPROTO_RTMP = 0;
+	const_CURLPROTO_RTMPT = 0;
+	const_CURLPROTO_RTMPE = 0;
+	const_CURLPROTO_RTMPTE = 0;
+	const_CURLPROTO_RTMPS = 0;
+	const_CURLPROTO_RTMPTS = 0;
+	const_CURLPROTO_GOPHER = 0;
+	const_CURLPROTO_SMB = 0;
+	const_CURLPROTO_SMBS = 0;
+	const_CURLPROTO_ALL = 0;
+	
+	
+	constructor()
+	{
+	}
+
+	destructor()
+	{
+	}
+	
+	</ cfunc = "CURL *curl_easy_init(void)" />
+	function easy_init() {}
+	</ cfunc = "CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...)" />
+	function easy_setopt(option, ...) {}
+	</ cfunc = "CURLcode curl_easy_perform(CURL *curl)" />
+	function perform () {}
+	</ cfunc = "void curl_easy_cleanup(CURL *curl)" />
+	function cleanup () {}
+	</ cfunc = "CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)" />
+	function easy_getinfo (info, ...) {}
+	</ cfunc = "CURL* curl_easy_duphandle(CURL *curl)" />
+	function easy_duphandle ()  {}
+	</ cfunc = "void curl_easy_reset(CURL *curl)" />
+	function easy_reset () : msg {}
+	</ cfunc = "CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n)" />
+	function easy_recv () {}
+		
+	</ cfunc = "CURLcode curl_easy_send(CURL *curl, const void *buffer, size_t buflen, size_t *n)" />
+	function easy_send (buffer) : int {}
+}
+
+dofile("generate-cpp-class-wrapper.nut");
+generateCppClassWrapper(EasyCurl, "EasyCurl");

+ 132 - 0
SquiLu/samples/nanomsg.nut

@@ -0,0 +1,132 @@
+class NanoMsg {
+	/*  Constants that are returned in `ns` member of nn_symbol_properties */
+	const_NN_NS_NAMESPACE = 0;
+	const_NN_NS_VERSION = 1;
+	const_NN_NS_DOMAIN = 2;
+	const_NN_NS_TRANSPORT = 3;
+	const_NN_NS_PROTOCOL = 4;
+	const_NN_NS_OPTION_LEVEL = 5;
+	const_NN_NS_SOCKET_OPTION = 6;
+	const_NN_NS_TRANSPORT_OPTION = 7;
+	const_NN_NS_OPTION_TYPE = 8;
+	const_NN_NS_OPTION_UNIT = 9;
+	const_NN_NS_FLAG = 10;
+	const_NN_NS_ERROR = 11;
+	const_NN_NS_LIMIT = 12;
+	const_NN_NS_EVENT = 13;
+
+	/*  Constants that are returned in `type` member of nn_symbol_properties */
+	const_NN_TYPE_NONE = 0;
+	const_NN_TYPE_INT = 1;
+	const_NN_TYPE_STR = 2;
+
+	/*  Constants that are returned in the `unit` member of nn_symbol_properties  */
+	const_NN_UNIT_NONE = 0;
+	const_NN_UNIT_BYTES = 1;
+	const_NN_UNIT_MILLISECONDS = 2;
+	const_NN_UNIT_PRIORITY = 3;
+	const_NN_UNIT_BOOLEAN = 4;
+	
+	const_NN_MSG = -1;
+	
+	/*  SP address families. */
+	const_AF_SP = 1;
+	const_AF_SP_RAW = 2;
+
+	/*  Max size of an SP address. */
+	const_NN_SOCKADDR_MAX = 128;
+
+	/*  Socket option levels: Negative numbers are reserved for transports,
+	    positive for socket types. */
+	const_NN_SOL_SOCKET = 0;
+
+	/*  Generic socket options (NN_SOL_SOCKET level). */
+	const_NN_LINGER = 1;
+	const_NN_SNDBUF = 2;
+	const_NN_RCVBUF = 3;
+	const_NN_SNDTIMEO = 4;
+	const_NN_RCVTIMEO = 5;
+	const_NN_RECONNECT_IVL = 6;
+	const_NN_RECONNECT_IVL_MAX = 7;
+	const_NN_SNDPRIO = 8;
+	const_NN_RCVPRIO = 9;
+	const_NN_SNDFD = 10;
+	const_NN_RCVFD = 11;
+	const_NN_DOMAIN = 12;
+	const_NN_PROTOCOL = 13;
+	const_NN_IPV4ONLY = 14;
+	const_NN_SOCKET_NAME = 15;
+
+	/*  Send/recv options. */
+	const_NN_DONTWAIT = 1;
+
+	/*  Ancillary data. */
+	const_PROTO_SP = 1;
+	const_SP_HDR = 1;
+	
+	/*  Socket mutliplexing support. */
+	const_NN_POLLIN = 1;
+	const_NN_POLLOUT = 2;	
+	
+	</ cfunc = "int nn_socket (int domain, int protocol)" />
+	constructor(int_domain, int_protocol)
+	{
+	}
+
+	</ cfunc = "int nn_close (int s)" />
+	destructor()
+	{
+	}
+	
+	</ cfunc = "int nn_errno (void)" />
+	function errno() {}
+	</ cfunc = "const char *nn_strerror (int errnum)" />
+	function strerror(int_errnum) {}
+	</ cfunc = "const char *nn_symbol (int i, int *value)" />
+	function symbol (int_i, value : intPtr) : string {}
+	</ cfunc = "int nn_symbol_info (int i, struct nn_symbol_properties *buf, int buflen)" />
+	function symbol_info (int_i) : nn_symbol_properties {}
+	</ cfunc = "void nn_term (void)" />
+	function term () {}
+	</ cfunc = "void *nn_allocmsg (size_t size, int type)" />
+	function allocmsg (int_size, int_the_type) : msg {}
+	</ cfunc = "void *nn_reallocmsg (void *msg, size_t size)" />
+	function reallocmsg (msg : msg, size : size_t) : msg {}
+	</ cfunc = "int nn_freemsg (void *msg)" />
+	function freemsg (msg) {}
+		
+	</ cfunc = "int nn_socket (int domain, int protocol)" />
+	function socket (int_domain, int_protocol) : int {}
+	</ cfunc = "int nn_close (int s)" />
+	function close () : int {}
+	</ cfunc = "int nn_setsockopt (int s, int level, int option, const void *optval, size_t optvallen)" />
+	function setsockopt (int_level, int_option, optval : voidPtr,  optvallen : size_t) : int {}
+	</ cfunc = "int nn_getsockopt (int s, int level, int option, void *optval, size_t *optvallen)" />
+	function getsockopt (int_level, int_option, optval : voidPtr, optvallen: size_tPtr) : int {}
+	</ cfunc = "int nn_bind (int s, const char *addr)"/>
+	function bind (str_addr) : int {}
+	</ cfunc = "int nn_connect (int s, const char *addr)" />
+	function connect (str_addr) : int {}
+	</ cfunc = "int nn_shutdown (int s, int how)" />
+	function shutdown (int_how) : int {}
+	</ cfunc = "int nn_send (int s, const void *buf, size_t len, int flags)" />
+	function send (str_buf, int_flags) : int {}
+	</ cfunc = "int nn_recv (int s, void *buf, size_t len, int flags)" />
+	function recv (int_flags) : string {}
+	</ cfunc = "int nn_sendmsg (int s, const struct nn_msghdr *msghdr, int flags)" />
+	function sendmsg (msghdr : nn_msghdr, flags : int) : int {}
+	</ cfunc = "int nn_recvmsg (int s, struct nn_msghdr *msghdr, int flags)" />
+	function recvmsg (int_flags) : nn_msghdr {}
+		
+	</ cfunc = "int nn_poll (struct nn_pollfd *fds, int nfds, int timeout)" />
+	function pollfd(fds, int_timeout) {}
+		
+	</ cfunc = "int nn_device (int s1, int s2)" />
+	function device(int_s1, int_s2) {}
+		
+	</ cfunc = "int nn_tcpmuxd (int port)" />
+	function tcpmuxd(int_port) {}
+}
+
+dofile("generate-cpp-class-wrapper.nut");
+generateCppClassWrapper(NanoMsg, "NanoMsg");

+ 6 - 0
SquiLu/samples/test-assginment.nut

@@ -0,0 +1,6 @@
+local count = 100000000;
+local bval = true;
+
+local start = os.clock();
+for(local i=0; i< count; ++i) bval = !bval;
+print("Time spent :", os.clock() -start, count);

+ 29 - 0
SquiLu/samples/test-bug-local-loop.nut

@@ -0,0 +1,29 @@
+local count = 10;
+local last_count = 0;
+
+while(count > 0 && last_count != count){
+	print(__LINE__, last_count, count);
+	last_count = count;
+	print(__LINE__, last_count, count);
+	os.sleep(10);
+}
+
+local m_State = 0;
+
+function pump( data, start, datasize ){
+	assert( datasize != 0 );
+	local count = datasize;
+	local data_idx = 0;
+	local last_count = 0;
+
+	while( count > 0 && m_State != 2  && last_count != count)
+	{
+print(__LINE__, count, last_count, data)
+		last_count = count;
+print(__LINE__, count, last_count, data)
+		os.sleep(10);
+	}
+}
+
+local str = "<pre>";
+pump(str, 0, 173);

+ 48 - 0
SquiLu/samples/test-bug-recursion.nut

@@ -0,0 +1,48 @@
+local print = print;
+local myvar = "outer ?";
+print(959876);
+local function bugRecursionLocal(str, num=993.56){
+	print(str, num, myvar);
+	if(str == "recurse33")  bugRecursionLocal("1recurring with recurse", 959876);
+	if(str == "recurse334")  bugRecursionLocal("2recurring with recurse", 959.876);
+	if(str == myvar) print("str == myvar");
+}
+
+function bugRecursion(str, num=973){
+	print(str, num);
+	if(str == "recurse")  bugRecursion("3recurring with recurse", 95);
+	return 8888.4;
+}
+
+bugRecursion("dad");
+bugRecursion("recurse");
+
+bugRecursionLocal("dad");
+bugRecursionLocal("recurse");
+
+enum bcode {ba, bb, bc};
+const XX = 999;
+local int_var = 983;
+local float_var = 932456.3123;
+local float_var2 = 0.0;
+print(float_var2);
+local aritVar = (XX + float_var) / 2 * int_var -3;
+local d1 = Decimal(33.3);
+local d2 = Decimal(2);
+print(d1*d2/d1-d2);
+local str_var = "DAD";
+local bool_var = true;
+local array_var = [9,1.5,2,3];
+local table_var = {name="color"};
+
+print(int_var)
+
+local function funcLocal(str){
+	bugRecursion("dad");
+	bugRecursion("recurse");
+
+	bugRecursionLocal("dad");
+	bugRecursionLocal("recurse");
+}
+
+funcLocal("dad");

+ 18 - 0
SquiLu/samples/test-bug-semicolon.nut

@@ -0,0 +1,18 @@
+if (1) {print(1)} else if (1) {print(2)} else {print(3)}; print(4);
+
+class X {
+    function _add(x) {
+        print("add("+x+")\n");
+        return this;
+    }
+};
+
+class Y extends X {
+    function f() {
+        base += 3; // troublesome
+    }
+};
+
+y <- Y();
+y += 3;
+y.f();

+ 7 - 4
SquiLu/samples/test-class-destructor.nut

@@ -25,10 +25,13 @@ class MyDerivedClass extends MyClass {
 		print("derived destructor", this);
 	}	
 }
-
+{
 local a = MyClass();
-print(a._num);
+print(a._num, type(a));
 //a.destructor();
 local b = MyDerivedClass();
-print(b._num);
-//b.destructor();
+print(b._num, type(b));
+//b.destructor();
+}
+
+print("Done");

+ 11 - 0
SquiLu/samples/test-class-name-resolution.nut

@@ -0,0 +1,11 @@
+class A {
+	_value = null;
+	constructor(){
+		print(dad.last)
+		local last = dad.last;
+		_value = dad.last;
+	}
+}
+
+local a = A();
+print(a._value);

+ 4 - 3
SquiLu/samples/test-delayed-release-hooks.nut

@@ -4,16 +4,17 @@ function doIT(line){
 	print(dad_utils, dad_utils.gc_scope_alert);
 	local gca = dad_utils.gc_scope_alert(@(ud) print(ud), "<<Gone !>> : " + line);
 	print("Done !", line);
-	gca = null;
-	local a = 3;
-	print(a);
+	//gca = null;
+	print(line);
 }
 function doIT2(line){
 	local gca2 = dad_utils.gc_scope_alert(@(ud) print(ud), "<<Gone2 !>> : " + line);
 	print("Done2 !", line);
 	//gca2 = null;
+	print(line);
 }
 doIT(__LINE__);
+//call_delayed_release_hooks();
 print("At line:", __LINE__);
 doIT(__LINE__);
 print("At line:", __LINE__);

+ 256 - 0
SquiLu/samples/test-fltk-list-search.nut

@@ -0,0 +1,256 @@
+function _tr(str){ return str;}
+
+class Fl_Data_Table extends Flv_Table {
+	_forPrint = null;
+	
+	constructor(px, py, pw, ph, pl=""){
+		base.constructor(px, py, pw, ph, pl);
+		_forPrint=false;
+	}
+}
+
+class Fl_Box_ClearLabel extends Fl_Box {
+	constructor(px, py, pw, ph, pl=""){
+		base.constructor(px, py, pw, ph, pl);
+	}
+}
+
+class Flu_Combo_List extends Fl_Box {
+	constructor(px, py, pw, ph, pl=""){
+		base.constructor(px, py, pw, ph, pl);
+	}
+}
+
+class Fl_Image_Box extends Fl_Box {
+	constructor(px, py, pw, ph, pl=""){
+		base.constructor(px, py, pw, ph, pl);
+	}
+}
+
+
+class Fl_Choice_Int extends Fl_Button {
+	constructor(px, py, pw, ph, pl=""){
+		base.constructor(px, py, pw, ph, pl);
+	}
+}
+
+class Fl_Float_Input_Fmt extends Fl_Float_Input {
+	constructor(px, py, pw, ph, pl=""){
+		base.constructor(px, py, pw, ph, pl);
+	}
+}
+
+class My_Fl_Float_Input extends Fl_Float_Input {
+	constructor(px, py, pw, ph, pl=""){
+		base.constructor(px, py, pw, ph, pl);
+	}
+}
+
+
+class My_Fl_Return_Button extends Fl_Button {
+	constructor(px, py, pw, ph, pl=""){
+		base.constructor(px, py, pw, ph, pl);
+	}
+}
+
+class Fl_Choice_Str extends Fl_Button {
+	constructor(px, py, pw, ph, pl=""){
+		base.constructor(px, py, pw, ph, pl);
+	}
+}
+
+class Flu_Combo_Box extends Fl_Button {
+	constructor(px, py, pw, ph, pl=""){
+		base.constructor(px, py, pw, ph, pl);
+	}
+}
+
+
+function add_input_field_to_map(tbl, fldname, fld){
+}
+	
+class ListSearchWindow extends Fl_Window {
+  // Declaration of class members
+  topGroup = null;
+  group_filter = null;
+  query_limit = null;
+  btnNotes = null;
+  middleGroup = null;
+  grid = null;
+  bottomGroup = null;
+  pack_search_options = null;
+  search_str = null;
+  btnSearch = null;
+  btnSelect = null;
+  btnUpdate = null;
+  btnInsert = null;
+  btnThumbImage = null;
+  pack_search_options2 = null;
+  
+  constructor(){
+    base.constructor(132, 118, 800, 560);
+    // Create member functions and widgets
+    {
+      local o = Fl_Group(0, 0, 800, 35);
+      topGroup = o;
+      o.labelsize(16);
+      {
+        {
+          local o = Flu_Combo_Tree(5, 5, 675, 25);
+          group_filter = o;
+          o.textsize(16);
+          o.labeltype(FL_NO_LABEL);
+          o.labelsize(16);
+        }
+        {
+          local o = Fl_Int_Input(690, 6, 60, 25);
+          query_limit = o;
+          o.textsize(16);
+          o.labeltype(FL_NO_LABEL);
+          o.labelsize(16);
+          o->value("50");
+        }
+        {
+          local o = Fl_Button(760, 6, 35, 25, _tr ("?"));
+          btnNotes = o;
+          o.labelsize(16);
+        }
+      }
+      o.end();
+    }
+    {
+      local o = Fl_Group(0, 41, 800, 409);
+      middleGroup = o;
+      o.labelsize(16);
+      {
+        {
+          local o = Fl_Data_Table(5, 41, 790, 389);
+          grid = o;
+          o.textsize(16);
+          o.labeltype(FL_NO_LABEL);
+          o.labelsize(16);
+          o.end();
+          Fl_Group.current().resizable(o);
+        }
+      }
+      o.end();
+      Fl_Group.current().resizable(o);
+    }
+    {
+      local o = Fl_Group(4, 440, 790, 115);
+      bottomGroup = o;
+      o.box(FL_ENGRAVED_BOX);
+      o.labelsize(16);
+      o.color(246);
+      {
+        {
+          local o = Fl_Pack(14, 450, 320, 25);
+          pack_search_options = o;
+          o.type(1);
+          o.labelsize(16);
+          o->spacing(10);
+          o.end();
+        }
+        {
+          local o = Fl_Input(35, 485, 299, 25, _tr ("@search"));
+          search_str = o;
+          o.textsize(16);
+          o.when(8);
+          o.labelsize(16);
+          o.callback(function(sender, udata){
+            on_search();
+          });
+        }
+        {
+          local o = Fl_Button(345, 485, 100, 25, _tr ("Search"));
+          btnSearch = o;
+          o.labelsize(16);
+          o.callback(function(sender, udata){
+            on_search();
+          });
+        }
+        {
+          local o = Fl_Button(14, 520, 100, 25, _tr ("Select"));
+          btnSelect = o;
+          o.labelsize(16);
+          o.callback(function(sender, udata){
+            on_select();
+          });
+        }
+        {
+          local o = Fl_Button(124, 520, 100, 25, _tr ("Update"));
+          btnUpdate = o;
+          o.labelsize(16);
+          o.callback(function(sender, udata){
+            on_update();
+          });
+        }
+        {
+          local o = Fl_Button(234, 520, 100, 25, _tr ("Insert"));
+          btnInsert = o;
+          o.labelsize(16);
+          o.callback(function(sender, udata){
+            on_insert();
+          });
+        }
+        {
+          local o = Fl_Image_Box(663, 445, 125, 105);
+          btnThumbImage = o;
+          o.box(FL_NO_BOX);
+          o.align(80);
+        }
+        {
+          local o = Fl_Box(650, 445, 5, 105);
+          o.align(80);
+          o.labeltype(FL_NO_LABEL);
+          o.labelsize(16);
+          Fl_Group.current().resizable(o);
+        }
+        {
+          local o = Fl_Pack(345, 520, 300, 25);
+          pack_search_options2 = o;
+          o.type(1);
+          o.labelsize(16);
+          o->spacing(10);
+          o.end();
+        }
+      }
+      o.end();
+    }
+    group_filter->textfont(group_filter->labelfont());
+    group_filter->textsize(group_filter->labelsize());
+
+  };
+  
+}
+
+//local win = new MainWindow(10, 50, 330, 320, "OURBIZ");
+local win = new ListSearchWindow();
+win->resizable(win);
+win->show_main();
+
+local tree = win->group_filter->tree();
+tree->show_root(true);
+tree->auto_branches(true);
+tree->show_branches(true);
+tree->all_branches_always_open(true);
+local node = tree->get_root();
+print(node)
+local node2 = tree->add(node, "DAD");
+print(node2)
+local node3 = tree->add(node2, "TAIS");
+print(node3)
+local node22 = tree->add(node, "LIINUX");
+print(node22)
+
+math.number_format_set_dec_point(",");
+math.number_format_set_thousand_sep(".");
+Fl_Input.default_number_format("\0x02,.");
+//Fl:scheme("plastic");
+Fl.scheme("gtk+");
+//use partial match to find verdana font
+Fl.visual(FL_RGB);
+//allow arrow keys navigation
+Fl.option(Fl.OPTION_ARROW_FOCUS, true);
+
+Fl.run();

+ 1 - 1
SquiLu/samples/test-fltk.nut

@@ -179,7 +179,7 @@ function MyNewWin(){
 	tabs.end();
 
 
-          local o = Fl_Pack2(5, 380, 790, 25);
+          local o = Fl_Pack(5, 380, 790, 25);
           o.type(1);
           o.labelsize(16);
           o->spacing(5);

+ 45 - 0
SquiLu/samples/test-gumbo.nut

@@ -0,0 +1,45 @@
+local input = [==[
+    <TITlE>Test Document</TITLe>
+    <h1>Test Heading</h1>
+    <p><a href=foobar.html>Quux</a></p>
+    <iNValID foo="bar">abc</invalid>
+    <p class=empty></p>
+]==];
+
+//local document = assert(gumbo.parse(input))
+local document = gumbo.parse(input);
+foreach(k,v in document) print(k,v);
+//local root = assert(document.root)
+print(document.root.len());
+local root = document.root
+local head = root.children[0];
+local body = root.children[1];
+
+assert(root.tag == "html")
+assert(head.tag == "head")
+assert(body.tag == "body")
+print("head.children[0].tag", head.children[0].tag);
+assert(head.children[0].tag == "title")
+assert(head.children[0].children[0] == "Test Document")
+assert(body.children[0].tag == "h1")
+assert(body.children[0].children[0] == "Test Heading")
+assert(body.children[1].tag == "p")
+assert(body.children[1].children[0].attr.href == "foobar.html")
+assert(body.children[2].tag == "iNValID")
+assert(body.children[2].attr.foo == "bar")
+assert(body.children[2].children[0] == "abc")
+assert(body.children[3].children.len() == 0)
+assert(body.children[3].attr["class"] == "empty")
+
+assert(gumbo.parse("<h1>Hello</h1>").root.children[1].children[0].children[0] == "Hello")
+//assert(! gumbo.parse_file( "non-existent-file"))
+
+document = gumbo.parse_file( "/home/mingo/Downloads/Components · Bootstrap-3.0.html");
+foreach(k,v in document) print(k,v);
+root = document.root
+head = root.children[0];
+foreach(k,v in head.children) print(k,v);
+foreach(k,v in head) print(k,v);
+body = root.children[1];
+foreach(k,v in body) print(k,v);
+foreach(k,v in body.children) print(k,v, v ? v.rawget("tag", "?") : "??");

+ 4 - 0
SquiLu/samples/test-match.nut

@@ -15,6 +15,10 @@ local line = "HTTP/1.1 301 Moved Permanently";
 rc = line.match("%s*(%S+)%s+(%d+)%s+(.+)");
 print(rc);
 
+line = "3.";
+rc = line.match("(%d+)%.");
+print("3. => (%d+)%.", rc);
+
 i <- 2;
 //print(i/0);
 print(i%0);

+ 72 - 0
SquiLu/samples/test-miniz.nut

@@ -0,0 +1,72 @@
+ local txt = [==[
+ UKCompaniesHouseRegisteredNumber|08270000|00000827
+EntityCurrentLegalOrRegisteredName|current-period|BRAHMAPOOTRA TEA COMPANY LIMITED
+BalanceSheetDate|current-mud|2013-12-31
+EntityDormant|current-period|false
+StartDateForPeriodCoveredByReport|current-mud|2013-01-01
+EndDateForPeriodCoveredByReport|current-mud|2013-12-31
+EntityTrading|current-period|true
+Debtors|current-mud|197,994
+Debtors|previous-mud|197,994
+CurrentAssets|current-mud|197,994
+CurrentAssets|previous-mud|197,994
+CreditorsDueWithinOneYear|current-mud|83,494
+CreditorsDueWithinOneYear|previous-mud|83,494
+NetCurrentAssetsLiabilities|current-mud|114,500
+NetCurrentAssetsLiabilities|previous-mud|114,500
+TotalAssetsLessCurrentLiabilities|current-mud|114,500
+TotalAssetsLessCurrentLiabilities|previous-mud|114,500
+NetAssetsLiabilitiesIncludingPensionAssetLiability|current-mud|114,500
+NetAssetsLiabilitiesIncludingPensionAssetLiability|previous-mud|114,500
+CalledUpShareCapital|current-mud|114,500
+CalledUpShareCapital|previous-mud|114,500
+ShareholderFunds|current-mud|114,500
+ShareholderFunds|previous-mud|114,500
+CompanyEntitledToExemptionUnderSection477CompaniesAct2006|current-period|For the year ending 31 December 2013 the company was entitled to exemption under section 477 of the Companies Act 2006 relating to small companies.
+MembersHaveNotRequiredCompanyToObtainAnAudit|current-period|The members have not required the company to obtain an audit in accordance with section 476 of the Companies Act 2006.
+DirectorsAcknowledgeTheirResponsibilitiesUnderCompaniesAct|current-period|The directors acknowledge their responsibilities for complying with the requirements of the Act with respect to accounting records and the preparation of accounts.
+AccountsAreInAccordanceWithSpecialProvisionsCompaniesActRelatingToSmallCompanies|current-period|These accounts have been prepared in accordance with the provisions applicable to companies subject to the small companies regime.
+DateApprovalAccounts|current-mud|27 January 2014
+NameEntityOfficer|current-period-director1|V K Mundhra
+ ]==];
+ 
+ local zipedTxt = zlib.deflate(txt);
+ //zipedTxt = miniz.deflate(txt);
+ local unzipedTxt = zlib.inflate(zipedTxt);
+ 
+ print(txt.len(), zipedTxt.len(), unzipedTxt.len(), unzipedTxt == txt);
+ 
+ /*
+ zipedTxt = miniz.deflate(txt);
+ //zipedTxt = zlib.deflate(txt);
+ unzipedTxt = miniz.inflate(zipedTxt);
+ 
+ print(txt.len(), zipedTxt.len(), unzipedTxt.len(), unzipedTxt == txt);
+ 
+ local za = miniz.ZipArchive("/home/mingo/dev/companies-uk/Accounts_Monthly_Data-January2014.zip");
+ local file_count = za.get_num_files();
+ print(file_count);
+ for(local i=0; i < file_count; ++i)
+ {
+	print(za.get_file_name(i), za.get_file_size(i));
+ }
+ za.destroy();
+ */
+ 
+ local uza = zlib.Unzip("/home/mingo/dev/companies-uk/Accounts_Monthly_Data-January2014.zip");
+ local file_count = uza.get_num_files();
+ print(__LINE__, file_count);
+ print(uza.goto_first_file());
+ local x = 0;
+ do
+ {
+ 	local finfo = uza.get_file_info();
+ 	print(finfo.name,finfo.size, finfo.is_dir);
+	if(x == 0)
+	{
+		print(uza.extract_file());
+	}
+	++x;
+} while(uza.goto_next_file());
+uza.destroy();
+ 

+ 43 - 0
SquiLu/samples/test-mysql.nut

@@ -0,0 +1,43 @@
+local db = MySQL("localhost",  "tribiqtrunk", "password", "tribiqtrunk");
+print(db.version());
+print(db.exec_scalar("select count(*) from tribiq_content;"));
+local qry = db.exec_query("select * from tribiq_content;");
+local col_count = qry.col_count();
+while(qry.next_row()){
+	for(local i=0; i < col_count; ++i){
+		print1(qry.col_value(i));
+		print1("|");
+	}
+	print1("\n");
+}
+print("row_as_array");
+qry._curr_row = -1;
+while(qry.next_row()){
+	foreach(v in qry.row_as_array()){
+		print1(v);
+		print1("|");
+	}
+	print1("\n");
+}
+
+local stmt = db.prepare("select * from tribiq_content;");
+qry = stmt.execute();
+col_count = qry.col_count();
+while(qry.next_row()){
+	for(local i=0; i < col_count; ++i){
+		print1(qry.col_value(i));
+		print1("|");
+	}
+	print1("\n");
+}
+print("row_as_array");
+qry._curr_row = -1;
+while(qry.next_row()){
+	foreach(v in qry.row_as_array()){
+		print1(v);
+		print1("|");
+	}
+	print1("\n");
+}
+
+db.close();

+ 11 - 0
SquiLu/samples/test-nested-functions.nut

@@ -0,0 +1,11 @@
+function z() {
+    function y() {
+        return 3;
+    }
+    return y();
+}
+
+print(z());
+print("z'd\n");
+print(y());
+print("y'd\n");

+ 13 - 0
SquiLu/samples/test-postgresql-local.nut

@@ -0,0 +1,13 @@
+//local db = PostgreSQL("host=localhost dbname=mingo user=mingo port=7432");
+local db = PostgreSQL("host=/tmp dbname=mingo user=mingo port=7432");
+
+
+for(local i=0; i < 10000; ++i)
+{
+    local qry = db.exec_query("select t from test where i=1;");
+    qry.next_row();
+    //print(qry.col_value(0));
+    qry.close();
+}
+
+db.close();

+ 19 - 3
SquiLu/samples/test-postgresql.nut

@@ -1,8 +1,22 @@
-local db = PostgreSQL("host=localhost dbname=ourbiz user=ourbiz password=ourbiz2");
+//local db = PostgreSQL("host=localhost dbname=ourbiz user=ourbiz password=ourbiz2");
+//local db = PostgreSQL("host=localhost port=7432 dbname=mingo user=mingo password=password");
+//local db = PostgreSQL("port=7432 dbname=odoo");
+local db = PostgreSQL("port=7432 dbname=odoo");
+local start = os.clock();
 print(db.version());
 print(db.exec_scalar("select count(*) from pg_type;"));
-local qry = db.exec_query("select * from pg_type;");
+//local qry = db.exec_query("select * from pg_type;");
+//local qry = db.exec_query("select * from pg_views where schemaname='public';");
+//::regclass
+local qry = db.exec_query("select pgc.oid, pgt.* from pg_tables as pgt join pg_class as pgc on pgt.tablename = pgc.relname where schemaname='public';");
+//local qry = db.exec_query("select tablename from pg_tables where schemaname='public';");
+//local qry = db.exec_query("SELECT * FROM information_schema.columns WHERE table_schema = 'public'  AND table_name   = 'account_account'");
 local col_count = qry.col_count();
+for(local i=0; i < col_count; ++i){
+	print1(qry.col_name(i));
+	print1("|");
+}
+print1("\n");
 while(qry.next_row()){
 	for(local i=0; i < col_count; ++i){
 		print1(qry.col_value(i));
@@ -19,5 +33,7 @@ while(qry.next_row()){
 	}
 	print1("\n");
 }
+qry.close();
 
-db.close();
+db.close();
+print("Total time", os.clock() - start);

+ 9 - 0
SquiLu/samples/test-regex.nut

@@ -0,0 +1,9 @@
+local ex = regexp("[a-zA-Z]+");
+local string = "123 Test; strlen(str);";
+local res = ex.search(string);
+print(string.slice(res.begin,res.end)); //prints "Test"
+print("\n");
+ex = regexp(@"\m()");
+string = "123 Test; strlen(str);";
+res = ex.search(string);
+print(string.slice(res.begin,res.end)); //prints "(str)"

+ 9 - 0
SquiLu/samples/test-set-global.nut

@@ -0,0 +1,9 @@
+global <- 0;
+class Test {
+  static function Go() {
+    print(global + "\n");
+    global = 1;
+    print(global + "\n");
+  }
+}
+Test.Go();

+ 104 - 0
SquiLu/samples/test-signal-handling.nut

@@ -0,0 +1,104 @@
+print(os.get_signal_received());
+os.set_signal_received(2);
+print(os.get_signal_received());
+
+os.set_signal_received(0);
+local sig_alarm = os.signal_str2int("SIGALRM");
+os.signal(sig_alarm);
+
+print(os.get_signal_received());
+
+for(local i=0; i < 10; ++i) {
+	if(i % 3) {
+		os.raise("SIGALRM");
+	}
+	local sig_received = os.get_signal_received();
+	print(i, sig_received, sig_received ? os.signal_int2str(sig_received) : "");
+	os.set_signal_received(0);
+	os.sleep(100);
+}
+
+os.set_signal_received(0);
+
+local SIGINT = os.signal_str2int("SIGINT");
+print(SIGINT, os.signal(SIGINT));
+
+local SIGQUIT = os.signal_str2int("SIGQUIT");
+print(SIGQUIT, os.signal(SIGQUIT));
+
+local SIGTERM = os.signal_str2int("SIGTERM");
+print(SIGTERM, os.signal(SIGTERM));
+
+local SIGALRM = os.signal_str2int("SIGALRM");
+print(SIGALRM, os.signal(SIGALRM));
+
+local SIGHUP = os.signal_str2int("SIGHUP");
+print(SIGHUP, os.signal(SIGHUP));
+
+local run_loop = true;
+while(run_loop) {
+	local signal_received = os.get_signal_received();
+	print(run_loop, signal_received, signal_received ? os.signal_int2str(signal_received) : "", SIGINT, SIGQUIT, SIGTERM);
+
+	if(signal_received) {
+		local sig_name = os.signal_int2str(signal_received);
+		switch(sig_name) {
+			case "SIGINT":
+			case "SIGQUIT":
+			case "SIGTERM":
+				run_loop = false;
+			break;
+			case "SIGALRM":
+				run_loop = false;
+			break;
+			case "SIGHUP":
+				run_loop = false;
+			break;
+		}
+	}
+/*
+	switch(signal_received) {
+		case SIGINT:
+		case SIGQUIT:
+		case SIGTERM:
+			run_loop = false;
+		break;
+		case SIGALRM:
+			run_loop = false;
+		break;
+		case SIGHUP:
+			run_loop = false;
+		break;
+	}
+*/
+	if(run_loop) {
+		os.sleep(100);
+	}
+}
+
+/*
+run_loop = true;
+os.set_signal_received(0);
+while(run_loop) {
+	local signal_received = os.get_signal_received();
+	print(run_loop, signal_received, signal_received ? os.signal_int2str(signal_received) : "", SIGINT, SIGQUIT, SIGTERM);
+	switch(signal_received) {
+		case SIGINT:
+		case SIGQUIT:
+		case SIGTERM:
+			run_loop = false;
+		break;
+		case SIGALRM:
+			run_loop = false;
+		break;
+		case SIGHUP:
+			run_loop = false;
+		break;
+	}
+	if(run_loop) {
+		os.sleep(100);
+	} else {
+		print(signal_received, os.signal_int2str(signal_received));
+	}
+}
+*/

+ 3 - 3
SquiLu/samples/test-socket-udp-echo-server.nut

@@ -6,9 +6,9 @@
 ////////////////////////////////////////////////////////////////////////////-
 local host = "127.0.0.1"
 local port = 20007;
-if (vargv.len() > 0){
-    host = vargv[0] || host;
-    port = vargv[1] || port;
+if (vargv.len() > 1){
+    host = vargv[1] || host;
+    port = vargv[2] || port;
 }
 print("Binding to host '" + host + "' and port " + port + "...");
 local udp = socket.udp();

+ 27 - 0
SquiLu/samples/test-socket-udp-syslog-server.nut

@@ -0,0 +1,27 @@
+////////////////////////////////////////////////////////////////////////////-
+// UDP sample: echo protocol client
+// LuaSocket sample files
+// Author: Diego Nehab
+// RCS ID: $Id: echoclnt.lua,v 1.10 2005/01/02 22:44:00 diego Exp $
+////////////////////////////////////////////////////////////////////////////-
+local host = "127.0.0.1"
+local port = 20007;
+
+if (vargv.len() > 1){
+    host = vargv[1] || host;
+    port = vargv[2].tointeger() || port;
+}
+print("Binding to host '" + host + "' and port " + port + "...");
+local udp = socket.udp();
+udp.setsockname(host, port);
+//udp.settimeout(5);
+local sockname = udp.getsockname();
+print("Waiting packets on " + sockname.address + ":" + sockname.port + "...");
+while (true){
+	local dgram = udp.receivefrom();
+	if (dgram) {
+		print(dgram.address + " : " + dgram.data);
+		//udp.sendto(dgram.data, dgram.address, dgram.port);
+	}
+	else print(ip);
+}

+ 44 - 2
SquiLu/samples/test-sqlite3.nut

@@ -61,9 +61,30 @@ local function multiply3_Multiply3(ctx,a,b,c){
 
 local function multiply3(ctx,a,b,c){
 	//print(ctx.user_data());
-	//ctx.result_double(a*b*c);
+	ctx.result_double(a*b*c);
+}
+
+local function sq_multiply3(a,b,c){
+	//print(ctx.user_data());
+	return (a*b*c);
+}
+
+local function showall(ctx,...){
+	for(local i = 0; i< vargv.len(); i++)
+	{
+		::print("varparam "+i+" = "+vargv[i]+"\n");
+	}
+	//print(ctx.user_data());
+	ctx.result_null();
 }
 
+db.create_function("showall",-1, showall);
+db.exec_get_one("select showall(1,'two', 3, 'four')");
+db.exec_dml("create table tr(id integer primary key, name text);");
+db.exec_dml("create trigger tr_trigger before insert on tr begin select showall(new.id, new.name); end;");
+db.exec_dml("insert into tr(id,name) values(1, 'dad'), (2, 'car');");
+//db.exec_get_one("select showall(*) from tr");
+
 //db.create_function("multiply3",3, multiply3_MultiplyDecimal3, MultiplyDecimal3());
 //db.create_function("multiply3",3, multiply3_Multiply3, Multiply3());
 db.create_function("multiply3",3, multiply3);
@@ -75,14 +96,23 @@ local stmt = db.prepare(sql);
 local stmt_squilu = db.prepare(sql_squilu);
 
 print(db.exec_get_one(sql_squilu));
+print(db.exec_get_one(sql));
 
 local count = 100000;
 
 local now = os.clock();
+print("top", getstacktop(), dostring("return 1.2*2.5*3.6;", true));
+for(local i=0; i<count; ++i){
+	local val = dostring("return 1.2*2.5*3.6;", true);
+}
+print("top", getstacktop());
+print("SquiLu function eval took:", os.clock() -now);
+
+now = os.clock();
 for(local i=0; i<count; ++i){
 	local val = db.exec_get_one(sql_squilu);
 }
-print("SquiLu function took:", os.clock() -now);
+print("SquiLu sqlite function took:", os.clock() -now);
 
 now = os.clock();
 for(local i=0; i<count; ++i){
@@ -94,6 +124,18 @@ stmt_squilu.reset();
 stmt_squilu.step()
 print(stmt_squilu.col(0));
 
+now = os.clock();
+for(local i=0; i<count; ++i){
+	local val = sq_multiply3(1.2,2.5,3.6);
+}
+print("SquiLu function took:", os.clock() -now);
+
+now = os.clock();
+for(local i=0; i<count; ++i){
+	local val = (1.2*2.5*3.6);
+}
+print("SquiLu direct calc took:", os.clock() -now);
+
 now = os.clock();
 for(local i=0; i<count; ++i){
 	stmt_squilu.reset();

+ 7 - 0
SquiLu/samples/uuid-generator.nut

@@ -0,0 +1,7 @@
+function pseudoUuid(){
+	return os.time() + "-" + (math.random()*1000000).tointeger() + "-" + (math.random()*1000000).tointeger();
+}
+
+for(var i=0; i < 10; ++i) print(os.getuuid());
+
+for(var i=0; i < 10; ++i) print(pseudoUuid());