The Squirrel interpreter. See http://www.squirrel-lang.org/

Dependents:   Squirrel

Revision:
0:97a4f8cc534c
Child:
1:8a2835ae5c5d
diff -r 000000000000 -r 97a4f8cc534c sq/sq.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sq/sq.c	Tue Dec 16 10:20:34 2014 +0000
@@ -0,0 +1,352 @@
+/*	see copyright notice in squirrel.h */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#if defined(_MSC_VER) && defined(_DEBUG)
+#include <crtdbg.h>
+#include <conio.h>
+#endif
+#include <squirrel.h>
+#include <sqstdblob.h>
+#include <sqstdsystem.h>
+#include <sqstdio.h>
+#include <sqstdmath.h>	
+#include <sqstdstring.h>
+#include <sqstdaux.h>
+
+#ifdef SQUNICODE
+#define scfprintf fwprintf
+#define scfopen	_wfopen
+#define scvprintf vfwprintf
+#else
+#define scfprintf fprintf
+#define scfopen	fopen
+#define scvprintf vfprintf
+#endif
+
+
+void PrintVersionInfos();
+
+#if defined(_MSC_VER) && defined(_DEBUG)
+int MemAllocHook( int allocType, void *userData, size_t size, int blockType, 
+   long requestNumber, const unsigned char *filename, int lineNumber)
+{
+	//if(requestNumber==769)_asm int 3;
+	return 1;
+}
+#endif
+
+
+SQInteger quit(HSQUIRRELVM v)
+{
+	int *done;
+	sq_getuserpointer(v,-1,(SQUserPointer*)&done);
+	*done=1;
+	return 0;
+}
+
+void printfunc(HSQUIRRELVM v,const SQChar *s,...)
+{
+	va_list vl;
+	va_start(vl, s);
+	scvprintf(stdout, s, vl);
+	va_end(vl);
+}
+
+void errorfunc(HSQUIRRELVM v,const SQChar *s,...)
+{
+	va_list vl;
+	va_start(vl, s);
+	scvprintf(stderr, s, vl);
+	va_end(vl);
+}
+
+void PrintVersionInfos()
+{
+	scfprintf(stdout,_SC("%s %s (%d bits)\n"),SQUIRREL_VERSION,SQUIRREL_COPYRIGHT,((int)(sizeof(SQInteger)*8)));
+}
+
+void PrintUsage()
+{
+	scfprintf(stderr,_SC("usage: sq <options> <scriptpath [args]>.\n")
+		_SC("Available options are:\n")
+		_SC("   -c              compiles the file to bytecode(default output 'out.cnut')\n")
+		_SC("   -o              specifies output file for the -c option\n")
+		_SC("   -c              compiles only\n")
+		_SC("   -d              generates debug infos\n")
+		_SC("   -v              displays version infos\n")
+		_SC("   -h              prints help\n"));
+}
+
+#define _INTERACTIVE 0
+#define _DONE 2
+#define _ERROR 3
+//<<FIXME>> this func is a mess
+int getargs(HSQUIRRELVM v,int argc, char* argv[],SQInteger *retval)
+{
+	int i;
+	int compiles_only = 0;
+	static SQChar temp[500];
+	const SQChar *ret=NULL;
+	char * output = NULL;
+	int lineinfo=0;
+	*retval = 0;
+	if(argc>1)
+	{
+		int arg=1,exitloop=0;
+		
+		while(arg < argc && !exitloop)
+		{
+
+			if(argv[arg][0]=='-')
+			{
+				switch(argv[arg][1])
+				{
+				case 'd': //DEBUG(debug infos)
+					sq_enabledebuginfo(v,1);
+					break;
+				case 'c':
+					compiles_only = 1;
+					break;
+				case 'o':
+					if(arg < argc) {
+						arg++;
+						output = argv[arg];
+					}
+					break;
+				case 'v':
+					PrintVersionInfos();
+					return _DONE;
+				
+				case 'h':
+					PrintVersionInfos();
+					PrintUsage();
+					return _DONE;
+				default:
+					PrintVersionInfos();
+					scprintf(_SC("unknown prameter '-%c'\n"),argv[arg][1]);
+					PrintUsage();
+					*retval = -1;
+					return _ERROR;
+				}
+			}else break;
+			arg++;
+		}
+
+		// src file
+		
+		if(arg<argc) {
+			const SQChar *filename=NULL;
+#ifdef SQUNICODE
+			mbstowcs(temp,argv[arg],strlen(argv[arg]));
+			filename=temp;
+#else
+			filename=argv[arg];
+#endif
+
+			arg++;
+			
+			//sq_pushstring(v,_SC("ARGS"),-1);
+			//sq_newarray(v,0);
+			
+			//sq_createslot(v,-3);
+			//sq_pop(v,1);
+			if(compiles_only) {
+				if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,SQTrue))){
+					const SQChar *outfile = _SC("out.cnut");
+					if(output) {
+#ifdef SQUNICODE
+						int len = (int)(strlen(output)+1);
+						mbstowcs(sq_getscratchpad(v,len*sizeof(SQChar)),output,len);
+						outfile = sq_getscratchpad(v,-1);
+#else
+						outfile = output;
+#endif
+					}
+					if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,outfile)))
+						return _DONE;
+				}
+			}
+			else {
+				//if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQFalse,SQTrue))) {
+					//return _DONE;
+				//}
+				if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,SQTrue))) {
+					int callargs = 1;
+					sq_pushroottable(v);
+					for(i=arg;i<argc;i++)
+					{
+						const SQChar *a;
+#ifdef SQUNICODE
+						int alen=(int)strlen(argv[i]);
+						a=sq_getscratchpad(v,(int)(alen*sizeof(SQChar)));
+						mbstowcs(sq_getscratchpad(v,-1),argv[i],alen);
+						sq_getscratchpad(v,-1)[alen] = _SC('\0');
+#else
+						a=argv[i];
+#endif
+						sq_pushstring(v,a,-1);
+						callargs++;
+						//sq_arrayappend(v,-2);
+					}
+					if(SQ_SUCCEEDED(sq_call(v,callargs,SQTrue,SQTrue))) {
+						SQObjectType type = sq_gettype(v,-1);
+						if(type == OT_INTEGER) {
+							*retval = type;
+							sq_getinteger(v,-1,retval);
+						}
+						return _DONE;
+					}
+					else{
+						return _ERROR;
+					}
+					
+				}
+			}
+			//if this point is reached an error occured
+			{
+				const SQChar *err;
+				sq_getlasterror(v);
+				if(SQ_SUCCEEDED(sq_getstring(v,-1,&err))) {
+					scprintf(_SC("Error [%s]\n"),err);
+					*retval = -2;
+					return _ERROR;
+				}
+			}
+			
+		}
+	}
+
+	return _INTERACTIVE;
+}
+
+void Interactive(HSQUIRRELVM v)
+{
+	
+#define MAXINPUT 1024
+	SQChar buffer[MAXINPUT];
+	SQInteger blocks =0;
+	SQInteger string=0;
+	SQInteger retval=0;
+	SQInteger done=0;
+	PrintVersionInfos();
+		
+	sq_pushroottable(v);
+	sq_pushstring(v,_SC("quit"),-1);
+	sq_pushuserpointer(v,&done);
+	sq_newclosure(v,quit,1);
+	sq_setparamscheck(v,1,NULL);
+	sq_newslot(v,-3,SQFalse);
+	sq_pop(v,1);
+
+    while (!done) 
+	{
+		SQInteger i = 0;
+		scprintf(_SC("\nsq>"));
+		for(;;) {
+			int c;
+			if(done)return;
+			c = getchar();
+			if (c == _SC('\n')) {
+				if (i>0 && buffer[i-1] == _SC('\\'))
+				{
+					buffer[i-1] = _SC('\n');
+				}
+				else if(blocks==0)break;
+				buffer[i++] = _SC('\n');
+			}
+			else if (c==_SC('}')) {blocks--; buffer[i++] = (SQChar)c;}
+			else if(c==_SC('{') && !string){
+					blocks++;
+					buffer[i++] = (SQChar)c;
+			}
+			else if(c==_SC('"') || c==_SC('\'')){
+					string=!string;
+					buffer[i++] = (SQChar)c;
+			}
+			else if (i >= MAXINPUT-1) {
+				scfprintf(stderr, _SC("sq : input line too long\n"));
+				break;
+			}
+			else{
+				buffer[i++] = (SQChar)c;
+			}
+		}
+		buffer[i] = _SC('\0');
+		
+		if(buffer[0]==_SC('=')){
+			scsprintf(sq_getscratchpad(v,MAXINPUT),_SC("return (%s)"),&buffer[1]);
+			memcpy(buffer,sq_getscratchpad(v,-1),(scstrlen(sq_getscratchpad(v,-1))+1)*sizeof(SQChar));
+			retval=1;
+		}
+		i=scstrlen(buffer);
+		if(i>0){
+			SQInteger oldtop=sq_gettop(v);
+			if(SQ_SUCCEEDED(sq_compilebuffer(v,buffer,i,_SC("interactive console"),SQTrue))){
+				sq_pushroottable(v);
+				if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue)) &&	retval){
+					scprintf(_SC("\n"));
+					sq_pushroottable(v);
+					sq_pushstring(v,_SC("print"),-1);
+					sq_get(v,-2);
+					sq_pushroottable(v);
+					sq_push(v,-4);
+					sq_call(v,2,SQFalse,SQTrue);
+					retval=0;
+					scprintf(_SC("\n"));
+				}
+			}
+			
+			sq_settop(v,oldtop);
+		}
+	}
+}
+
+int main(int argc, char* argv[])
+{
+	HSQUIRRELVM v;
+	SQInteger retval = 0;
+	const SQChar *filename=NULL;
+#if defined(_MSC_VER) && defined(_DEBUG)
+	_CrtSetAllocHook(MemAllocHook);
+#endif
+	
+	v=sq_open(1024);
+	sq_setprintfunc(v,printfunc,errorfunc);
+
+	sq_pushroottable(v);
+
+	sqstd_register_bloblib(v);
+	sqstd_register_iolib(v);
+	sqstd_register_systemlib(v);
+	sqstd_register_mathlib(v);
+	sqstd_register_stringlib(v);
+
+	//aux library
+	//sets error handlers
+	sqstd_seterrorhandlers(v);
+
+	//gets arguments
+	switch(getargs(v,argc,argv,&retval))
+	{
+	case _INTERACTIVE:
+		Interactive(v);
+		break;
+	case _DONE:
+	case _ERROR:
+	default: 
+		break;
+	}
+
+	sq_close(v);
+	
+#if defined(_MSC_VER) && defined(_DEBUG)
+	_getch();
+	_CrtMemDumpAllObjectsSince( NULL );
+#endif
+	return retval;
+}
+