Merge pull request #18 from mfxmfx/master

Normalize whitespace and improve const-correctness.
This commit is contained in:
albertodemichelis 2016-02-29 23:39:34 +08:00
commit 26d018d8b5
73 changed files with 16437 additions and 16437 deletions

12
COMPILE
View File

@ -3,22 +3,22 @@ Squirrel 3.1 stable
What is in this distribution?
squirrel
static library implementing the compiler and interpreter of the language
static library implementing the compiler and interpreter of the language
sqstdlib
the standard utility libraries
the standard utility libraries
sq
stand alone interpreter
stand alone interpreter
doc
The manual
The manual
etc
a minimalistic embedding sample
a minimalistic embedding sample
samples
samples programs
samples programs
HOW TO COMPILE

40
HISTORY
View File

@ -15,7 +15,7 @@
-fixed incorrect optional semicolon after "if block"(thx Alexander)
-fixed crash bug in compiler related to compound arith operators(+=,-= etc...) (thx Jeff1)
***2015-01-10 ***
***2015-01-10 ***
***version 3.1 RC 1***
-added new header sqconfig.h for all optional type declarations(unicode, 64bits etc..)
-added sq_setsharedforeignptr sq_getsharedforeignptr
@ -32,7 +32,7 @@
-fixed bug in switch statement when using locals as case values (thx mingodad)
-fixed bug in print()(thx Lucas Cardellini)
***2013-08-30 ***
***2013-08-30 ***
***version 3.1 beta 1***
-added new scoping rule(root attached to closures)
-added closure.setroot() closure.getroot()
@ -44,7 +44,7 @@
-fixed bug in sqstd_createfile() (thx mingodad)
-minor buxfixes
***2012-11-10 ***
***2012-11-10 ***
***version 3.0.4 stable***
-sq_deleteslot slot now pops the key in case of failure
-fixed bug when _get metamethod throws null
@ -52,7 +52,7 @@
-added some error handling
-minor bugfixes
***2012-06-19 ***
***2012-06-19 ***
***version 3.1.0 alpha 1***
-changed in and instanceof operator precendence
-root object in closures
@ -75,7 +75,7 @@
-fixed obscure bug in the compiler(thx yishin)
-fixed some minor bug
***2011-11-28 ***
***2011-11-28 ***
***version 3.0.2 stable***
-added sq_gethash API
-now array.sort() is implemented with heapsort
@ -84,7 +84,7 @@
-fixed some documentation
-fixed bug in GC
***2011-09-08 ***
***2011-09-08 ***
***version 3.0.1 stable***
-added # as alternative symbol for "line comment"(mostly useful for shell scripts)
-added sq_throwobject() to throw an arbitrary object from the C API
@ -110,7 +110,7 @@
-fixed bug when using SQUSEDOUBLE and 32bits intengers
-fixed bug when invoking generators with closure.call() (thx huntercool)
***2010-12-19 ***
***2010-12-19 ***
***version 3.0 release candidate 1(RC 1)***
-improved metamethods error handling
-added parameter 'isstatic' to _newmember metamethod(thx G.Meyer)
@ -213,7 +213,7 @@ will terminate the iteration but will not be returned as foreach iteration
-fixed sq_cmp() (thx jyuill)
-fixed minor bugs
***2006-08-21 ***
***2006-08-21 ***
***version 2.1.1 stable***
-vm refactoring
-optimized internal function memory layout
@ -225,7 +225,7 @@ will terminate the iteration but will not be returned as foreach iteration
-sq_getlocal() now enumerates also outer values.
-fixed regexp library for GCC users.
***2006-03-19 ***
***2006-03-19 ***
***version 2.1 stable***
-added static class fields, new keyword static
-added 64bits architecture support
@ -250,7 +250,7 @@ will terminate the iteration but will not be returned as foreach iteration
-regular expressions operators (+,*) now have more POSIX greedyness behaviour
-class constructors are now invoked as normal functions
***2005-10-02 ***
***2005-10-02 ***
***version 2.0.5 stable***
-fixed some 64bits incompatibilities (thx sarge)
-fixed minor bug in the stdlib format() function (thx Rick)
@ -258,7 +258,7 @@ will terminate the iteration but will not be returned as foreach iteration
-added new API sq_poptop() & sq_getfreevariable()
-some performance improvements
***2005-08-14 ***
***2005-08-14 ***
***version 2.0.4 stable***
-weak references and related API calls
-added sq_objtobool()
@ -269,30 +269,30 @@ will terminate the iteration but will not be returned as foreach iteration
-fixed a bug in format()
-fixed bug in string.tointeger() and string.tofloat()
***2005-06-24 ***
***2005-06-24 ***
***version 2.0.3 stable***
-dofile() and loadfile() in the iolib now can decode ASCII, UTF8 files UCS2 big-endian and little-endian
-sq_setparamscheck() : now typemesk can check for null
-added string escape sequence \xhhhh
-fixed some C++ standard incompatibilities
***2005-05-15 ***
***2005-05-15 ***
***version 2.0.2 stable***
-performances improvements (expecially for GCC users)
-removed all dependencies from C++ exception handling
-various bugfixes
***2005-04-12 ***
***2005-04-12 ***
***version 2.0.1 stable***
-various bugfixes
-sq_setparamscheck() now allows spaces in the typemask
***2005-04-03 ***
***2005-04-03 ***
***version 2.0 stable***
-added API sq_gettypetag()
-added built-in function to the bool type(tointeger, tostring etc...)
***2005-02-27 ***
***2005-02-27 ***
***version 2.0 release candidate 1(RC 1)***
-added API sq_reseterror()
-modified sq_release()
@ -398,7 +398,7 @@ will terminate the iteration but will not be returned as foreach iteration
-the built in function collect_garbage() as been renamed collectgarbage() for consistency reasons
-new standard libraries(sqlibs are now obsolete)
***2004-02-20 ***
***2004-02-20 ***
***version 1.0 beta 1***
-fixed a bug in the compiler (thanks Martin Kofler)
-fixed bug in the switch case statement
@ -406,8 +406,8 @@ will terminate the iteration but will not be returned as foreach iteration
-fixed minor bugs in the API
-fixed automatic stack resizing
-first beta version
first pass code clean up in the VM and base lib
first pass code coverege test has been done on VM and built-in lib
first pass code clean up in the VM and base lib
first pass code coverege test has been done on VM and built-in lib
-new VM creation API sq_open() sq_close() (sq_newvm and sq_releasevm are now obsolete)
-new api allows to specifiy a "print" function to output text(sq_printfunc)
-added some small optimizations
@ -487,7 +487,7 @@ will terminate the iteration but will not be returned as foreach iteration
-optional Unicode core(define SQUNICODE or _UNICODE on Win32)
-sq_compiler uses a new reader function SQLEXREADFUNC
-the debug hook passes 'l' instead of 'line' for line callbacks
and 'c' instead of 'call' for call callbacks
and 'c' instead of 'call' for call callbacks
-new array.extend() bulit-in function
-new API sq_clone()

12
README
View File

@ -5,12 +5,12 @@ The project has been compiled and run on Windows(x86 and x64) and
Linux(x86 and x64) and Solaris(x86 and x64).
Has been tested with the following compilers:
MS Visual C++ 6.0,7.0,7.1,8.0,9.0,10.0 (32 and 64bits)
MinGW gcc 3.2 (mingw special 20020817-1)
Cygnus gcc 3.2
Linux gcc 3.2.3
Linux gcc 4.0.0 (x86 & 64bits)
Solaris gcc 4.0.0 (x86 & 64bits)
MS Visual C++ 6.0,7.0,7.1,8.0,9.0,10.0 (32 and 64bits)
MinGW gcc 3.2 (mingw special 20020817-1)
Cygnus gcc 3.2
Linux gcc 3.2.3
Linux gcc 4.0.0 (x86 & 64bits)
Solaris gcc 4.0.0 (x86 & 64bits)
Feedback and suggestions are appreciated

View File

@ -20,59 +20,59 @@
void printfunc(HSQUIRRELVM v,const SQChar *s,...)
{
va_list vl;
va_start(vl, s);
scvprintf(stdout, s, vl);
va_end(vl);
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);
va_list vl;
va_start(vl, s);
scvprintf(stderr, s, vl);
va_end(vl);
}
void call_foo(HSQUIRRELVM v, int n,float f,const SQChar *s)
{
SQInteger top = sq_gettop(v); //saves the stack size before the call
sq_pushroottable(v); //pushes the global table
sq_pushstring(v,_SC("foo"),-1);
if(SQ_SUCCEEDED(sq_get(v,-2))) { //gets the field 'foo' from the global table
sq_pushroottable(v); //push the 'this' (in this case is the global table)
sq_pushinteger(v,n);
sq_pushfloat(v,f);
sq_pushstring(v,s,-1);
sq_call(v,4,SQFalse,SQTrue); //calls the function
}
sq_settop(v,top); //restores the original stack size
SQInteger top = sq_gettop(v); //saves the stack size before the call
sq_pushroottable(v); //pushes the global table
sq_pushstring(v,_SC("foo"),-1);
if(SQ_SUCCEEDED(sq_get(v,-2))) { //gets the field 'foo' from the global table
sq_pushroottable(v); //push the 'this' (in this case is the global table)
sq_pushinteger(v,n);
sq_pushfloat(v,f);
sq_pushstring(v,s,-1);
sq_call(v,4,SQFalse,SQTrue); //calls the function
}
sq_settop(v,top); //restores the original stack size
}
int main(int argc, char* argv[])
{
HSQUIRRELVM v;
v = sq_open(1024); // creates a VM with initial stack size 1024
HSQUIRRELVM v;
v = sq_open(1024); // creates a VM with initial stack size 1024
//REGISTRATION OF STDLIB
//sq_pushroottable(v); //push the root table where the std function will be registered
//sqstd_register_iolib(v); //registers a library
// ... call here other stdlibs string,math etc...
//sq_pop(v,1); //pops the root table
//END REGISTRATION OF STDLIB
//REGISTRATION OF STDLIB
//sq_pushroottable(v); //push the root table where the std function will be registered
//sqstd_register_iolib(v); //registers a library
// ... call here other stdlibs string,math etc...
//sq_pop(v,1); //pops the root table
//END REGISTRATION OF STDLIB
sqstd_seterrorhandlers(v); //registers the default error handlers
sqstd_seterrorhandlers(v); //registers the default error handlers
sq_setprintfunc(v, printfunc,errorfunc); //sets the print function
sq_setprintfunc(v, printfunc,errorfunc); //sets the print function
sq_pushroottable(v); //push the root table(were the globals of the script will be stored)
if(SQ_SUCCEEDED(sqstd_dofile(v, _SC("test.nut"), SQFalse, SQTrue))) // also prints syntax errors if any
{
call_foo(v,1,2.5,_SC("teststring"));
}
sq_pushroottable(v); //push the root table(were the globals of the script will be stored)
if(SQ_SUCCEEDED(sqstd_dofile(v, _SC("test.nut"), SQFalse, SQTrue))) // also prints syntax errors if any
{
call_foo(v,1,2.5,_SC("teststring"));
}
sq_pop(v,1); //pops the root table
sq_close(v);
sq_pop(v,1); //pops the root table
sq_close(v);
return 0;
return 0;
}

View File

@ -59,23 +59,23 @@ typedef SQInteger SQRESULT;
typedef wchar_t SQChar;
#define scstrcmp wcscmp
#define scstrcmp wcscmp
#ifdef _MSC_VER
#define scsprintf _snwprintf
#define scsprintf _snwprintf
#else
#define scsprintf snwprintf
#define scsprintf snwprintf
#endif
#define scstrlen wcslen
#define scstrtod wcstod
#define scstrlen wcslen
#define scstrtod wcstod
#ifdef _SQ64
#define scstrtol wcstoll
#define scstrtol wcstoll
#else
#define scstrtol wcstol
#define scstrtol wcstol
#endif
#define scstrtoul wcstoul
#define scvsprintf vswprintf
#define scstrstr wcsstr
#define scprintf wprintf
#define scstrtoul wcstoul
#define scvsprintf vswprintf
#define scstrstr wcsstr
#define scprintf wprintf
#ifdef _WIN32
#define WCHAR_SIZE 2
@ -90,13 +90,13 @@ typedef wchar_t SQChar;
#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 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)
@ -104,34 +104,34 @@ typedef wchar_t SQChar;
#else
typedef char SQChar;
#define _SC(a) a
#define scstrcmp strcmp
#define scstrcmp strcmp
#ifdef _MSC_VER
#define scsprintf _snprintf
#define scsprintf _snprintf
#else
#define scsprintf snprintf
#define scsprintf snprintf
#endif
#define scstrlen strlen
#define scstrtod strtod
#define scstrlen strlen
#define scstrtod strtod
#ifdef _SQ64
#ifdef _MSC_VER
#define scstrtol _strtoi64
#define scstrtol _strtoi64
#else
#define scstrtol strtoll
#define scstrtol strtoll
#endif
#else
#define scstrtol strtol
#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 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)

View File

@ -1,4 +1,4 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQSTD_AUXLIB_H_
#define _SQSTD_AUXLIB_H_

View File

@ -1,4 +1,4 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQSTDBLOB_H_
#define _SQSTDBLOB_H_

View File

@ -1,4 +1,4 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQSTDIO_H_
#define _SQSTDIO_H_
@ -7,14 +7,14 @@
#define SQSTD_STREAM_TYPE_TAG 0x80000000
struct SQStream {
virtual SQInteger Read(void *buffer, SQInteger size) = 0;
virtual SQInteger Write(void *buffer, SQInteger size) = 0;
virtual SQInteger Flush() = 0;
virtual SQInteger Tell() = 0;
virtual SQInteger Len() = 0;
virtual SQInteger Seek(SQInteger offset, SQInteger origin) = 0;
virtual bool IsValid() = 0;
virtual bool EOS() = 0;
virtual SQInteger Read(void *buffer, SQInteger size) = 0;
virtual SQInteger Write(void *buffer, SQInteger size) = 0;
virtual SQInteger Flush() = 0;
virtual SQInteger Tell() = 0;
virtual SQInteger Len() = 0;
virtual SQInteger Seek(SQInteger offset, SQInteger origin) = 0;
virtual bool IsValid() = 0;
virtual bool EOS() = 0;
};
extern "C" {

View File

@ -1,4 +1,4 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQSTD_MATH_H_
#define _SQSTD_MATH_H_

View File

@ -1,4 +1,4 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQSTD_STRING_H_
#define _SQSTD_STRING_H_
@ -10,8 +10,8 @@ typedef unsigned int SQRexBool;
typedef struct SQRex SQRex;
typedef struct {
const SQChar *begin;
SQInteger len;
const SQChar *begin;
SQInteger len;
} SQRexMatch;
SQUIRREL_API SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error);

View File

@ -1,4 +1,4 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQSTD_SYSTEMLIB_H_
#define _SQSTD_SYSTEMLIB_H_

View File

@ -37,8 +37,8 @@ extern "C" {
#endif
#define SQTrue (1)
#define SQFalse (0)
#define SQTrue (1)
#define SQFalse (0)
struct SQVM;
struct SQTable;
@ -61,66 +61,66 @@ struct SQOuter;
#include "sqconfig.h"
#define SQUIRREL_VERSION _SC("Squirrel 3.1 stable")
#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2015 Alberto Demichelis")
#define SQUIRREL_AUTHOR _SC("Alberto Demichelis")
#define SQUIRREL_VERSION_NUMBER 310
#define SQUIRREL_VERSION _SC("Squirrel 3.1 stable")
#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2015 Alberto Demichelis")
#define SQUIRREL_AUTHOR _SC("Alberto Demichelis")
#define SQUIRREL_VERSION_NUMBER 310
#define SQ_VMSTATE_IDLE 0
#define SQ_VMSTATE_RUNNING 1
#define SQ_VMSTATE_SUSPENDED 2
#define SQ_VMSTATE_IDLE 0
#define SQ_VMSTATE_RUNNING 1
#define SQ_VMSTATE_SUSPENDED 2
#define SQUIRREL_EOB 0
#define SQ_BYTECODE_STREAM_TAG 0xFAFA
#define SQ_BYTECODE_STREAM_TAG 0xFAFA
#define SQOBJECT_REF_COUNTED 0x08000000
#define SQOBJECT_NUMERIC 0x04000000
#define SQOBJECT_DELEGABLE 0x02000000
#define SQOBJECT_CANBEFALSE 0x01000000
#define SQOBJECT_REF_COUNTED 0x08000000
#define SQOBJECT_NUMERIC 0x04000000
#define SQOBJECT_DELEGABLE 0x02000000
#define SQOBJECT_CANBEFALSE 0x01000000
#define SQ_MATCHTYPEMASKSTRING (-99999)
#define _RT_MASK 0x00FFFFFF
#define _RAW_TYPE(type) (type&_RT_MASK)
#define _RT_NULL 0x00000001
#define _RT_INTEGER 0x00000002
#define _RT_FLOAT 0x00000004
#define _RT_BOOL 0x00000008
#define _RT_STRING 0x00000010
#define _RT_TABLE 0x00000020
#define _RT_ARRAY 0x00000040
#define _RT_USERDATA 0x00000080
#define _RT_CLOSURE 0x00000100
#define _RT_NATIVECLOSURE 0x00000200
#define _RT_GENERATOR 0x00000400
#define _RT_USERPOINTER 0x00000800
#define _RT_THREAD 0x00001000
#define _RT_FUNCPROTO 0x00002000
#define _RT_CLASS 0x00004000
#define _RT_INSTANCE 0x00008000
#define _RT_WEAKREF 0x00010000
#define _RT_OUTER 0x00020000
#define _RT_NULL 0x00000001
#define _RT_INTEGER 0x00000002
#define _RT_FLOAT 0x00000004
#define _RT_BOOL 0x00000008
#define _RT_STRING 0x00000010
#define _RT_TABLE 0x00000020
#define _RT_ARRAY 0x00000040
#define _RT_USERDATA 0x00000080
#define _RT_CLOSURE 0x00000100
#define _RT_NATIVECLOSURE 0x00000200
#define _RT_GENERATOR 0x00000400
#define _RT_USERPOINTER 0x00000800
#define _RT_THREAD 0x00001000
#define _RT_FUNCPROTO 0x00002000
#define _RT_CLASS 0x00004000
#define _RT_INSTANCE 0x00008000
#define _RT_WEAKREF 0x00010000
#define _RT_OUTER 0x00020000
typedef enum tagSQObjectType{
OT_NULL = (_RT_NULL|SQOBJECT_CANBEFALSE),
OT_INTEGER = (_RT_INTEGER|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
OT_FLOAT = (_RT_FLOAT|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
OT_BOOL = (_RT_BOOL|SQOBJECT_CANBEFALSE),
OT_STRING = (_RT_STRING|SQOBJECT_REF_COUNTED),
OT_TABLE = (_RT_TABLE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
OT_ARRAY = (_RT_ARRAY|SQOBJECT_REF_COUNTED),
OT_USERDATA = (_RT_USERDATA|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
OT_CLOSURE = (_RT_CLOSURE|SQOBJECT_REF_COUNTED),
OT_NATIVECLOSURE = (_RT_NATIVECLOSURE|SQOBJECT_REF_COUNTED),
OT_GENERATOR = (_RT_GENERATOR|SQOBJECT_REF_COUNTED),
OT_USERPOINTER = _RT_USERPOINTER,
OT_THREAD = (_RT_THREAD|SQOBJECT_REF_COUNTED) ,
OT_FUNCPROTO = (_RT_FUNCPROTO|SQOBJECT_REF_COUNTED), //internal usage only
OT_CLASS = (_RT_CLASS|SQOBJECT_REF_COUNTED),
OT_INSTANCE = (_RT_INSTANCE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
OT_WEAKREF = (_RT_WEAKREF|SQOBJECT_REF_COUNTED),
OT_OUTER = (_RT_OUTER|SQOBJECT_REF_COUNTED) //internal usage only
OT_NULL = (_RT_NULL|SQOBJECT_CANBEFALSE),
OT_INTEGER = (_RT_INTEGER|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
OT_FLOAT = (_RT_FLOAT|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
OT_BOOL = (_RT_BOOL|SQOBJECT_CANBEFALSE),
OT_STRING = (_RT_STRING|SQOBJECT_REF_COUNTED),
OT_TABLE = (_RT_TABLE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
OT_ARRAY = (_RT_ARRAY|SQOBJECT_REF_COUNTED),
OT_USERDATA = (_RT_USERDATA|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
OT_CLOSURE = (_RT_CLOSURE|SQOBJECT_REF_COUNTED),
OT_NATIVECLOSURE = (_RT_NATIVECLOSURE|SQOBJECT_REF_COUNTED),
OT_GENERATOR = (_RT_GENERATOR|SQOBJECT_REF_COUNTED),
OT_USERPOINTER = _RT_USERPOINTER,
OT_THREAD = (_RT_THREAD|SQOBJECT_REF_COUNTED) ,
OT_FUNCPROTO = (_RT_FUNCPROTO|SQOBJECT_REF_COUNTED), //internal usage only
OT_CLASS = (_RT_CLASS|SQOBJECT_REF_COUNTED),
OT_INSTANCE = (_RT_INSTANCE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
OT_WEAKREF = (_RT_WEAKREF|SQOBJECT_REF_COUNTED),
OT_OUTER = (_RT_OUTER|SQOBJECT_REF_COUNTED) //internal usage only
}SQObjectType;
#define ISREFCOUNTED(t) (t&SQOBJECT_REF_COUNTED)
@ -128,43 +128,43 @@ typedef enum tagSQObjectType{
typedef union tagSQObjectValue
{
struct SQTable *pTable;
struct SQArray *pArray;
struct SQClosure *pClosure;
struct SQOuter *pOuter;
struct SQGenerator *pGenerator;
struct SQNativeClosure *pNativeClosure;
struct SQString *pString;
struct SQUserData *pUserData;
SQInteger nInteger;
SQFloat fFloat;
SQUserPointer pUserPointer;
struct SQFunctionProto *pFunctionProto;
struct SQRefCounted *pRefCounted;
struct SQDelegable *pDelegable;
struct SQVM *pThread;
struct SQClass *pClass;
struct SQInstance *pInstance;
struct SQWeakRef *pWeakRef;
SQRawObjectVal raw;
struct SQTable *pTable;
struct SQArray *pArray;
struct SQClosure *pClosure;
struct SQOuter *pOuter;
struct SQGenerator *pGenerator;
struct SQNativeClosure *pNativeClosure;
struct SQString *pString;
struct SQUserData *pUserData;
SQInteger nInteger;
SQFloat fFloat;
SQUserPointer pUserPointer;
struct SQFunctionProto *pFunctionProto;
struct SQRefCounted *pRefCounted;
struct SQDelegable *pDelegable;
struct SQVM *pThread;
struct SQClass *pClass;
struct SQInstance *pInstance;
struct SQWeakRef *pWeakRef;
SQRawObjectVal raw;
}SQObjectValue;
typedef struct tagSQObject
{
SQObjectType _type;
SQObjectValue _unVal;
SQObjectType _type;
SQObjectValue _unVal;
}SQObject;
typedef struct tagSQMemberHandle{
SQBool _static;
SQInteger _index;
SQBool _static;
SQInteger _index;
}SQMemberHandle;
typedef struct tagSQStackInfos{
const SQChar* funcname;
const SQChar* source;
SQInteger line;
const SQChar* funcname;
const SQChar* source;
SQInteger line;
}SQStackInfos;
typedef struct SQVM* HSQUIRRELVM;
@ -181,17 +181,17 @@ typedef SQInteger (*SQREADFUNC)(SQUserPointer,SQUserPointer,SQInteger);
typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer);
typedef struct tagSQRegFunction{
const SQChar *name;
SQFUNCTION f;
SQInteger nparamscheck;
const SQChar *typemask;
const SQChar *name;
SQFUNCTION f;
SQInteger nparamscheck;
const SQChar *typemask;
}SQRegFunction;
typedef struct tagSQFunctionInfo {
SQUserPointer funcid;
const SQChar *name;
const SQChar *source;
SQInteger line;
SQUserPointer funcid;
const SQChar *name;
const SQChar *source;
SQInteger line;
}SQFunctionInfo;
/*vm*/

View File

@ -22,7 +22,7 @@ for (i = 0; i < n; i+=1) {
for (k = 0 ; k < n; k+=1) {
for (i = n-1; i >= 0; i-=1) {
y[i] = y[i]+ x[i];
y[i] = y[i]+ x[i];
}
}
print(y[0].tostring()+" "+y[n-1]);

View File

@ -1,33 +1,33 @@
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
class BaseVector {
constructor(...)
{
if(vargv.len() >= 3) {
x = vargv[0];
y = vargv[1];
z = vargv[2];
}
}
constructor(...)
{
if(vargv.len() >= 3) {
x = vargv[0];
y = vargv[1];
z = vargv[2];
}
}
x = 0;
y = 0;
z = 0;
x = 0;
y = 0;
z = 0;
}
class Vector3 extends BaseVector {
function _add(other)
{
if(other instanceof this.getclass())
return ::Vector3(x+other.x,y+other.y,z+other.z);
else
throw "wrong parameter";
}
function Print()
{
::print(x+","+y+","+z+"\n");
}
function _add(other)
{
if(other instanceof this.getclass())
return ::Vector3(x+other.x,y+other.y,z+other.z);
else
throw "wrong parameter";
}
function Print()
{
::print(x+","+y+","+z+"\n");
}
}
local v0 = Vector3(1,2,3)
@ -36,14 +36,14 @@ local v2 = v0 + v1;
v2.Print();
FakeNamespace <- {
Utils = {}
Utils = {}
}
class FakeNamespace.Utils.SuperClass {
constructor()
{
::print("FakeNamespace.Utils.SuperClass")
}
constructor()
{
::print("FakeNamespace.Utils.SuperClass")
}
}
local testy = FakeNamespace.Utils.SuperClass();

View File

@ -1,35 +1,35 @@
class Foo {
//constructor
constructor(a)
{
testy = ["stuff",1,2,3];
}
//attributes of PrintTesty
</ test = "freakin attribute"/>
function PrintTesty()
{
foreach(i,val in testy)
{
::print("idx = "+i+" = "+val+" \n");
}
}
//attributes of testy
</ flippy = 10 , second = [1,2,3] />
testy = null;
//constructor
constructor(a)
{
testy = ["stuff",1,2,3];
}
//attributes of PrintTesty
</ test = "freakin attribute"/>
function PrintTesty()
{
foreach(i,val in testy)
{
::print("idx = "+i+" = "+val+" \n");
}
}
//attributes of testy
</ flippy = 10 , second = [1,2,3] />
testy = null;
}
foreach(member,val in Foo)
{
::print(member+"\n");
local attr;
if((attr = Foo.getattributes(member)) != null) {
foreach(i,v in attr)
{
::print("\t"+i+" = "+(typeof v)+"\n");
}
}
else {
::print("\t<no attributes>\n")
}
::print(member+"\n");
local attr;
if((attr = Foo.getattributes(member)) != null) {
foreach(i,v in attr)
{
::print("\t"+i+" = "+(typeof v)+"\n");
}
}
else {
::print("\t<no attributes>\n")
}
}

View File

@ -1,13 +1,13 @@
function coroutine_test(a,b)
{
::print(a+" "+b+"\n");
local ret = ::suspend("suspend 1");
::print("the coroutine says "+ret+"\n");
ret = ::suspend("suspend 2");
::print("the coroutine says "+ret+"\n");
ret = ::suspend("suspend 3");
::print("the coroutine says "+ret+"\n");
return "I'm done"
::print(a+" "+b+"\n");
local ret = ::suspend("suspend 1");
::print("the coroutine says "+ret+"\n");
ret = ::suspend("suspend 2");
::print("the coroutine says "+ret+"\n");
ret = ::suspend("suspend 3");
::print("the coroutine says "+ret+"\n");
return "I'm done"
}
local coro = ::newthread(coroutine_test);
@ -17,9 +17,9 @@ local susparam = coro.call("test","coroutine"); //starts the coroutine
local i = 1;
do
{
::print("suspend passed ["+susparam+"]\n")
susparam = coro.wakeup("ciao "+i);
++i;
::print("suspend passed ["+susparam+"]\n")
susparam = coro.wakeup("ciao "+i);
++i;
}while(coro.getstatus()=="suspended")
::print("return passed ["+susparam+"]\n")

View File

@ -1,45 +1,45 @@
PEntity <- {
name="noname"
pos={x=0,y=0,z=0}
type="entity"
//methamethod
_typeof=function()
{
return type;
}
name="noname"
pos={x=0,y=0,z=0}
type="entity"
//methamethod
_typeof=function()
{
return type;
}
}
function PEntity::PrintPos()
{
::print("x="+pos.x+" y="+pos.y+" z="+pos.z+"\n");
::print("x="+pos.x+" y="+pos.y+" z="+pos.z+"\n");
}
function PEntity::new(name,pos)
{
local newentity=clone ::PEntity;
if(name)
newentity.name=name;
if(pos)
newentity.pos=pos;
return newentity;
local newentity=clone ::PEntity;
if(name)
newentity.name=name;
if(pos)
newentity.pos=pos;
return newentity;
}
PPlayer <- {
model="warrior.mdl"
weapon="fist"
health=100
armor=0
//overrides the parent type
type="player"
model="warrior.mdl"
weapon="fist"
health=100
armor=0
//overrides the parent type
type="player"
}
function PPlayer::new(name,pos)
{
local p = clone ::PPlayer;
local newplayer = ::PEntity.new(name,pos);
newplayer.setdelegate(p);
return newplayer;
local newplayer = ::PEntity.new(name,pos);
newplayer.setdelegate(p);
return newplayer;
}
local player=PPlayer.new("godzilla",{x=10,y=20,z=30});

View File

@ -1,29 +1,29 @@
function min(x,y)
return x<y?x:y;
return x<y?x:y;
function max(x,y)
return x>y?x:y;
return x>y?x:y;
if(min(100,200)>max(50,20))
print("I'm useless statement just to show up the if/else\n");
print("I'm useless statement just to show up the if/else\n");
else
print("squirrel!!\n");
print("squirrel!!\n");
print("\n")
function typy(obj)
{
switch(typeof obj)
{
case "integer":
case "float":
return "is a number";
case "table":
case "array":
return "is a container";
default:
return "is other stuff"
}
switch(typeof obj)
{
case "integer":
case "float":
return "is a number";
case "table":
case "array":
return "is a container";
default:
return "is other stuff"
}
}
local a=1,b={},c=function(a,b){return a+b;}

View File

@ -4,13 +4,13 @@
*/
function gen_random(max) {
local last=42
local IM = 139968;
local IA = 3877;
local IC = 29573;
for(;;){ //loops forever
yield (max * (last = (last * IA + IC) % IM) / IM);
}
local last=42
local IM = 139968;
local IA = 3877;
local IC = 29573;
for(;;){ //loops forever
yield (max * (last = (last * IA + IC) % IM) / IM);
}
}
local randtor=gen_random(100);
@ -18,25 +18,25 @@ local randtor=gen_random(100);
print("RAND NUMBERS \n")
for(local i=0;i<10;i+=1)
print(">"+resume randtor+"\n");
print(">"+resume randtor+"\n");
print("FIBONACCI \n")
function fiboz(n)
{
local prev=0;
local curr=1;
yield 1;
local prev=0;
local curr=1;
yield 1;
for(local i=0;i<n-1;i+=1)
{
local res=prev+curr;
prev=curr;
yield curr=res;
}
return prev+curr;
for(local i=0;i<n-1;i+=1)
{
local res=prev+curr;
prev=curr;
yield curr=res;
}
return prev+curr;
}
foreach(val in fiboz(10))
{
::print(">"+val+"\n");
::print(">"+val+"\n");
}

View File

@ -3,38 +3,38 @@
function compare_arr(a1,a2)
{
foreach(i,val in a1)
if(val!=a2[i])return null;
return 1;
foreach(i,val in a1)
if(val!=a2[i])return null;
return 1;
}
function test()
{
local size=10000
local l1=[]; l1.resize(size);
for(local i=0;i<size;i+=1) l1[i]=i;
local l2=clone l1;
local l3=[]
local size=10000
local l1=[]; l1.resize(size);
for(local i=0;i<size;i+=1) l1[i]=i;
local l2=clone l1;
local l3=[]
l2.reverse();
while(l2.len()>0)
l3.append(l2.pop());
while(l3.len()>0)
l2.append(l3.pop());
l1.reverse();
l2.reverse();
while(l2.len()>0)
l3.append(l2.pop());
while(l3.len()>0)
l2.append(l3.pop());
l1.reverse();
if(compare_arr(l1,l2))
return l1.len();
return null;
if(compare_arr(l1,l2))
return l1.len();
return null;
}
local n = vargv.len()!=0?vargv[0].tointeger():1
for(local i=0;i<n;i+=1)
if(!test())
{
print("failed");
return;
}
if(!test())
{
print("failed");
return;
}
print("oki doki");

View File

@ -4,14 +4,14 @@ local arr=["one","two","three"]
foreach(i,val in arr)
{
::print("index ["+i+"]="+val+"\n");
::print("index ["+i+"]="+val+"\n");
}
::print("FOR\n");
for(local i=0;i<arr.len();i+=1)
{
::print("index ["+i+"]="+arr[i]+"\n");
::print("index ["+i+"]="+arr[i]+"\n");
}
::print("WHILE\n");
@ -19,14 +19,14 @@ for(local i=0;i<arr.len();i+=1)
local i=0;
while(i<arr.len())
{
::print("index ["+i+"]="+arr[i]+"\n");
i+=1;
::print("index ["+i+"]="+arr[i]+"\n");
i+=1;
}
::print("DO WHILE\n");
local i=0;
do
{
::print("index ["+i+"]="+arr[i]+"\n");
i+=1;
::print("index ["+i+"]="+arr[i]+"\n");
i+=1;
}while(i<arr.len());

View File

@ -23,7 +23,7 @@ function mmult(rows, cols, m1, m2, m3) {
for (j = 0; j < cols; j+=1) {
val = 0;
for (k = 0; k < cols; k+=1) {
val += m1[i][k] * m2[k][j];
val += m1[i][k] * m2[k][j];
}
m3[i][j] = val;
}

View File

@ -1,68 +1,68 @@
local base_vec={
function _add(n)
{
return {
x=x+n.x,
y=y+n.y,
z=z+n.z,
}
}
function _sub(n)
{
return {
x=x-n.x,
y=y-n.y,
z=z-n.z,
}
}
function _div(n)
{
return {
x=x/n.x,
y=y/n.y,
z=z/n.z,
}
}
function _mul(n)
{
return {
x=x*n.x,
y=y*n.y,
z=z*n.z,
}
}
function _modulo(n)
{
return {
x=x%n,
y=y%n,
z=z%n,
}
}
function _typeof() {return "vector";}
function _get(key)
{
if(key==100)
{
return test_field;
}
},
function _set(key,val)
{
::print("key = "+key+"\n");
::print("val = "+val+"\n")
if(key==100)
{
return test_field=val;
}
}
test_field="nothing"
function _add(n)
{
return {
x=x+n.x,
y=y+n.y,
z=z+n.z,
}
}
function _sub(n)
{
return {
x=x-n.x,
y=y-n.y,
z=z-n.z,
}
}
function _div(n)
{
return {
x=x/n.x,
y=y/n.y,
z=z/n.z,
}
}
function _mul(n)
{
return {
x=x*n.x,
y=y*n.y,
z=z*n.z,
}
}
function _modulo(n)
{
return {
x=x%n,
y=y%n,
z=z%n,
}
}
function _typeof() {return "vector";}
function _get(key)
{
if(key==100)
{
return test_field;
}
},
function _set(key,val)
{
::print("key = "+key+"\n");
::print("val = "+val+"\n")
if(key==100)
{
return test_field=val;
}
}
test_field="nothing"
}
function vector(_x,_y,_z)
{
return {x=_x,y=_y,z=_z }.setdelegate(base_vec);
return {x=_x,y=_y,z=_z }.setdelegate(base_vec);
}
////////////////////////////////////////////////////////////
@ -74,35 +74,35 @@ local r=v1+v2;
foreach(i,val in r)
{
print(i+" = "+val+"\n");
print(i+" = "+val+"\n");
}
r=v1*v2;
foreach(i,val in r)
{
print(i+" = "+val+"\n");
print(i+" = "+val+"\n");
}
r=v1/v2;
foreach(i,val in r)
{
print(i+" = "+val+"\n");
print(i+" = "+val+"\n");
}
r=v1-v2;
foreach(i,val in r)
{
print(i+" = "+val+"\n");
print(i+" = "+val+"\n");
}
r=v1%2;
foreach(i,val in r)
{
print(i+" = "+val+"\n");
print(i+" = "+val+"\n");
}
print(v1[100]+"\n");
@ -110,6 +110,6 @@ v1[100]="set SUCCEEDED";
print(v1[100]+"\n");
if(typeof v1=="vector")
print("<SUCCEEDED>\n");
print("<SUCCEEDED>\n");
else
print("<FAILED>\n");
print("<FAILED>\n");

View File

@ -2,36 +2,36 @@
*/
class Toggle {
bool=null
bool=null
}
function Toggle::constructor(startstate) {
bool = startstate
bool = startstate
}
function Toggle::value() {
return bool;
return bool;
}
function Toggle::activate() {
bool = !bool;
return this;
bool = !bool;
return this;
}
class NthToggle extends Toggle {
count_max=null
count=0
count_max=null
count=0
}
function NthToggle::constructor(start_state,max_counter)
{
base.constructor(start_state);
count_max = max_counter
base.constructor(start_state);
count_max = max_counter
}
function NthToggle::activate ()
{
++count;
++count;
if (count >= count_max ) {
base.activate();
count = 0;
@ -41,26 +41,26 @@ function NthToggle::activate ()
function main() {
local n = vargv.len()!=0?vargv[0].tointeger():1
local n = vargv.len()!=0?vargv[0].tointeger():1
local val = 1;
local toggle = Toggle(val);
local i = n;
while(i--) {
val = toggle.activate().value();
local val = 1;
local toggle = Toggle(val);
local i = n;
while(i--) {
val = toggle.activate().value();
}
print(toggle.value() ? "true\n" : "false\n");
}
print(toggle.value() ? "true\n" : "false\n");
val = 1;
local ntoggle = NthToggle(val, 3);
i = n;
while(i--) {
val = ntoggle.activate().value();
}
print(ntoggle.value() ? "true\n" : "false\n");
val = 1;
local ntoggle = NthToggle(val, 3);
i = n;
while(i--) {
val = ntoggle.activate().value();
}
print(ntoggle.value() ? "true\n" : "false\n");
}
local start=clock();

View File

@ -1,19 +1,19 @@
function state1()
{
::suspend("state1");
return state2();
::suspend("state1");
return state2();
}
function state2()
{
::suspend("state2");
return state3();
::suspend("state2");
return state3();
}
function state3()
{
::suspend("state3");
return state1();
::suspend("state3");
return state1();
}
local statethread = ::newthread(state1)
@ -21,4 +21,4 @@ local statethread = ::newthread(state1)
::print(statethread.call()+"\n");
for(local i = 0; i < 10000; i++)
::print(statethread.wakeup()+"\n");
::print(statethread.wakeup()+"\n");

478
sq/sq.c
View File

@ -1,4 +1,4 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#include <stdio.h>
#include <stdlib.h>
@ -32,51 +32,51 @@ void PrintVersionInfos();
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;
//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;
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);
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);
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)));
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"));
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
@ -85,266 +85,266 @@ void PrintUsage()
//<<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;
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)
{
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;
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++;
}
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
// src file
if(arg<argc) {
const SQChar *filename=NULL;
if(arg<argc) {
const SQChar *filename=NULL;
#ifdef SQUNICODE
mbstowcs(temp,argv[arg],strlen(argv[arg]));
filename=temp;
mbstowcs(temp,argv[arg],strlen(argv[arg]));
filename=temp;
#else
filename=argv[arg];
filename=argv[arg];
#endif
arg++;
arg++;
//sq_pushstring(v,_SC("ARGS"),-1);
//sq_newarray(v,0);
//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) {
//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);
int len = (int)(strlen(output)+1);
mbstowcs(sq_getscratchpad(v,len*sizeof(SQChar)),output,len);
outfile = sq_getscratchpad(v,-1);
#else
outfile = output;
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;
}
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');
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];
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;
}
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;
}
}
}
}
//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;
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();
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);
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');
{
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),(size_t)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"));
}
}
if(buffer[0]==_SC('=')){
scsprintf(sq_getscratchpad(v,MAXINPUT),(size_t)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);
}
}
sq_settop(v,oldtop);
}
}
}
int main(int argc, char* argv[])
{
HSQUIRRELVM v;
SQInteger retval = 0;
const SQChar *filename=NULL;
HSQUIRRELVM v;
SQInteger retval = 0;
const SQChar *filename=NULL;
#if defined(_MSC_VER) && defined(_DEBUG)
_CrtSetAllocHook(MemAllocHook);
_CrtSetAllocHook(MemAllocHook);
#endif
v=sq_open(1024);
sq_setprintfunc(v,printfunc,errorfunc);
v=sq_open(1024);
sq_setprintfunc(v,printfunc,errorfunc);
sq_pushroottable(v);
sq_pushroottable(v);
sqstd_register_bloblib(v);
sqstd_register_iolib(v);
sqstd_register_systemlib(v);
sqstd_register_mathlib(v);
sqstd_register_stringlib(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);
//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;
}
//gets arguments
switch(getargs(v,argc,argv,&retval))
{
case _INTERACTIVE:
Interactive(v);
break;
case _DONE:
case _ERROR:
default:
break;
}
sq_close(v);
sq_close(v);
#if defined(_MSC_VER) && defined(_DEBUG)
_getch();
_CrtMemDumpAllObjectsSince( NULL );
_getch();
_CrtMemDumpAllObjectsSince( NULL );
#endif
return retval;
return retval;
}

View File

@ -5,126 +5,126 @@
void sqstd_printcallstack(HSQUIRRELVM v)
{
SQPRINTFUNCTION pf = sq_geterrorfunc(v);
if(pf) {
SQStackInfos si;
SQInteger i;
SQFloat f;
const SQChar *s;
SQInteger level=1; //1 is to skip this function that is level 0
const SQChar *name=0;
SQInteger seq=0;
pf(v,_SC("\nCALLSTACK\n"));
while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si)))
{
const SQChar *fn=_SC("unknown");
const SQChar *src=_SC("unknown");
if(si.funcname)fn=si.funcname;
if(si.source)src=si.source;
pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line);
level++;
}
level=0;
pf(v,_SC("\nLOCALS\n"));
SQPRINTFUNCTION pf = sq_geterrorfunc(v);
if(pf) {
SQStackInfos si;
SQInteger i;
SQFloat f;
const SQChar *s;
SQInteger level=1; //1 is to skip this function that is level 0
const SQChar *name=0;
SQInteger seq=0;
pf(v,_SC("\nCALLSTACK\n"));
while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si)))
{
const SQChar *fn=_SC("unknown");
const SQChar *src=_SC("unknown");
if(si.funcname)fn=si.funcname;
if(si.source)src=si.source;
pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line);
level++;
}
level=0;
pf(v,_SC("\nLOCALS\n"));
for(level=0;level<10;level++){
seq=0;
while((name = sq_getlocal(v,level,seq)))
{
seq++;
switch(sq_gettype(v,-1))
{
case OT_NULL:
pf(v,_SC("[%s] NULL\n"),name);
break;
case OT_INTEGER:
sq_getinteger(v,-1,&i);
pf(v,_SC("[%s] %d\n"),name,i);
break;
case OT_FLOAT:
sq_getfloat(v,-1,&f);
pf(v,_SC("[%s] %.14g\n"),name,f);
break;
case OT_USERPOINTER:
pf(v,_SC("[%s] USERPOINTER\n"),name);
break;
case OT_STRING:
sq_getstring(v,-1,&s);
pf(v,_SC("[%s] \"%s\"\n"),name,s);
break;
case OT_TABLE:
pf(v,_SC("[%s] TABLE\n"),name);
break;
case OT_ARRAY:
pf(v,_SC("[%s] ARRAY\n"),name);
break;
case OT_CLOSURE:
pf(v,_SC("[%s] CLOSURE\n"),name);
break;
case OT_NATIVECLOSURE:
pf(v,_SC("[%s] NATIVECLOSURE\n"),name);
break;
case OT_GENERATOR:
pf(v,_SC("[%s] GENERATOR\n"),name);
break;
case OT_USERDATA:
pf(v,_SC("[%s] USERDATA\n"),name);
break;
case OT_THREAD:
pf(v,_SC("[%s] THREAD\n"),name);
break;
case OT_CLASS:
pf(v,_SC("[%s] CLASS\n"),name);
break;
case OT_INSTANCE:
pf(v,_SC("[%s] INSTANCE\n"),name);
break;
case OT_WEAKREF:
pf(v,_SC("[%s] WEAKREF\n"),name);
break;
case OT_BOOL:{
SQBool bval;
sq_getbool(v,-1,&bval);
pf(v,_SC("[%s] %s\n"),name,bval == SQTrue ? _SC("true"):_SC("false"));
}
break;
default: assert(0); break;
}
sq_pop(v,1);
}
}
}
for(level=0;level<10;level++){
seq=0;
while((name = sq_getlocal(v,level,seq)))
{
seq++;
switch(sq_gettype(v,-1))
{
case OT_NULL:
pf(v,_SC("[%s] NULL\n"),name);
break;
case OT_INTEGER:
sq_getinteger(v,-1,&i);
pf(v,_SC("[%s] %d\n"),name,i);
break;
case OT_FLOAT:
sq_getfloat(v,-1,&f);
pf(v,_SC("[%s] %.14g\n"),name,f);
break;
case OT_USERPOINTER:
pf(v,_SC("[%s] USERPOINTER\n"),name);
break;
case OT_STRING:
sq_getstring(v,-1,&s);
pf(v,_SC("[%s] \"%s\"\n"),name,s);
break;
case OT_TABLE:
pf(v,_SC("[%s] TABLE\n"),name);
break;
case OT_ARRAY:
pf(v,_SC("[%s] ARRAY\n"),name);
break;
case OT_CLOSURE:
pf(v,_SC("[%s] CLOSURE\n"),name);
break;
case OT_NATIVECLOSURE:
pf(v,_SC("[%s] NATIVECLOSURE\n"),name);
break;
case OT_GENERATOR:
pf(v,_SC("[%s] GENERATOR\n"),name);
break;
case OT_USERDATA:
pf(v,_SC("[%s] USERDATA\n"),name);
break;
case OT_THREAD:
pf(v,_SC("[%s] THREAD\n"),name);
break;
case OT_CLASS:
pf(v,_SC("[%s] CLASS\n"),name);
break;
case OT_INSTANCE:
pf(v,_SC("[%s] INSTANCE\n"),name);
break;
case OT_WEAKREF:
pf(v,_SC("[%s] WEAKREF\n"),name);
break;
case OT_BOOL:{
SQBool bval;
sq_getbool(v,-1,&bval);
pf(v,_SC("[%s] %s\n"),name,bval == SQTrue ? _SC("true"):_SC("false"));
}
break;
default: assert(0); break;
}
sq_pop(v,1);
}
}
}
}
static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v)
{
SQPRINTFUNCTION pf = sq_geterrorfunc(v);
if(pf) {
const SQChar *sErr = 0;
if(sq_gettop(v)>=1) {
if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) {
pf(v,_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr);
}
else{
pf(v,_SC("\nAN ERROR HAS OCCURED [unknown]\n"));
}
sqstd_printcallstack(v);
}
}
return 0;
SQPRINTFUNCTION pf = sq_geterrorfunc(v);
if(pf) {
const SQChar *sErr = 0;
if(sq_gettop(v)>=1) {
if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) {
pf(v,_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr);
}
else{
pf(v,_SC("\nAN ERROR HAS OCCURED [unknown]\n"));
}
sqstd_printcallstack(v);
}
}
return 0;
}
void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column)
{
SQPRINTFUNCTION pf = sq_geterrorfunc(v);
if(pf) {
pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr);
}
SQPRINTFUNCTION pf = sq_geterrorfunc(v);
if(pf) {
pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr);
}
}
void sqstd_seterrorhandlers(HSQUIRRELVM v)
{
sq_setcompilererrorhandler(v,_sqstd_compiler_error);
sq_newclosure(v,_sqstd_aux_printerror,0);
sq_seterrorhandler(v);
sq_setcompilererrorhandler(v,_sqstd_compiler_error);
sq_newclosure(v,_sqstd_aux_printerror,0);
sq_seterrorhandler(v);
}

View File

@ -13,166 +13,166 @@
#define SETUP_BLOB(v) \
SQBlob *self = NULL; \
{ if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) \
return sq_throwerror(v,_SC("invalid type tag")); } \
if(!self || !self->IsValid()) \
return sq_throwerror(v,_SC("the blob is invalid"));
SQBlob *self = NULL; \
{ if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) \
return sq_throwerror(v,_SC("invalid type tag")); } \
if(!self || !self->IsValid()) \
return sq_throwerror(v,_SC("the blob is invalid"));
static SQInteger _blob_resize(HSQUIRRELVM v)
{
SETUP_BLOB(v);
SQInteger size;
sq_getinteger(v,2,&size);
if(!self->Resize(size))
return sq_throwerror(v,_SC("resize failed"));
return 0;
SETUP_BLOB(v);
SQInteger size;
sq_getinteger(v,2,&size);
if(!self->Resize(size))
return sq_throwerror(v,_SC("resize failed"));
return 0;
}
static void __swap_dword(unsigned int *n)
{
*n=(unsigned int)(((*n&0xFF000000)>>24) |
((*n&0x00FF0000)>>8) |
((*n&0x0000FF00)<<8) |
((*n&0x000000FF)<<24));
*n=(unsigned int)(((*n&0xFF000000)>>24) |
((*n&0x00FF0000)>>8) |
((*n&0x0000FF00)<<8) |
((*n&0x000000FF)<<24));
}
static void __swap_word(unsigned short *n)
{
*n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00);
*n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00);
}
static SQInteger _blob_swap4(HSQUIRRELVM v)
{
SETUP_BLOB(v);
SQInteger num=(self->Len()-(self->Len()%4))>>2;
unsigned int *t=(unsigned int *)self->GetBuf();
for(SQInteger i = 0; i < num; i++) {
__swap_dword(&t[i]);
}
return 0;
SETUP_BLOB(v);
SQInteger num=(self->Len()-(self->Len()%4))>>2;
unsigned int *t=(unsigned int *)self->GetBuf();
for(SQInteger i = 0; i < num; i++) {
__swap_dword(&t[i]);
}
return 0;
}
static SQInteger _blob_swap2(HSQUIRRELVM v)
{
SETUP_BLOB(v);
SQInteger num=(self->Len()-(self->Len()%2))>>1;
unsigned short *t = (unsigned short *)self->GetBuf();
for(SQInteger i = 0; i < num; i++) {
__swap_word(&t[i]);
}
return 0;
SETUP_BLOB(v);
SQInteger num=(self->Len()-(self->Len()%2))>>1;
unsigned short *t = (unsigned short *)self->GetBuf();
for(SQInteger i = 0; i < num; i++) {
__swap_word(&t[i]);
}
return 0;
}
static SQInteger _blob__set(HSQUIRRELVM v)
{
SETUP_BLOB(v);
SQInteger idx,val;
sq_getinteger(v,2,&idx);
sq_getinteger(v,3,&val);
if(idx < 0 || idx >= self->Len())
return sq_throwerror(v,_SC("index out of range"));
((unsigned char *)self->GetBuf())[idx] = (unsigned char) val;
sq_push(v,3);
return 1;
SETUP_BLOB(v);
SQInteger idx,val;
sq_getinteger(v,2,&idx);
sq_getinteger(v,3,&val);
if(idx < 0 || idx >= self->Len())
return sq_throwerror(v,_SC("index out of range"));
((unsigned char *)self->GetBuf())[idx] = (unsigned char) val;
sq_push(v,3);
return 1;
}
static SQInteger _blob__get(HSQUIRRELVM v)
{
SETUP_BLOB(v);
SQInteger idx;
sq_getinteger(v,2,&idx);
if(idx < 0 || idx >= self->Len())
return sq_throwerror(v,_SC("index out of range"));
sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]);
return 1;
SETUP_BLOB(v);
SQInteger idx;
sq_getinteger(v,2,&idx);
if(idx < 0 || idx >= self->Len())
return sq_throwerror(v,_SC("index out of range"));
sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]);
return 1;
}
static SQInteger _blob__nexti(HSQUIRRELVM v)
{
SETUP_BLOB(v);
if(sq_gettype(v,2) == OT_NULL) {
sq_pushinteger(v, 0);
return 1;
}
SQInteger idx;
if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) {
if(idx+1 < self->Len()) {
sq_pushinteger(v, idx+1);
return 1;
}
sq_pushnull(v);
return 1;
}
return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type"));
SETUP_BLOB(v);
if(sq_gettype(v,2) == OT_NULL) {
sq_pushinteger(v, 0);
return 1;
}
SQInteger idx;
if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) {
if(idx+1 < self->Len()) {
sq_pushinteger(v, idx+1);
return 1;
}
sq_pushnull(v);
return 1;
}
return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type"));
}
static SQInteger _blob__typeof(HSQUIRRELVM v)
{
sq_pushstring(v,_SC("blob"),-1);
return 1;
sq_pushstring(v,_SC("blob"),-1);
return 1;
}
static SQInteger _blob_releasehook(SQUserPointer p, SQInteger size)
{
SQBlob *self = (SQBlob*)p;
self->~SQBlob();
sq_free(self,sizeof(SQBlob));
return 1;
SQBlob *self = (SQBlob*)p;
self->~SQBlob();
sq_free(self,sizeof(SQBlob));
return 1;
}
static SQInteger _blob_constructor(HSQUIRRELVM v)
{
SQInteger nparam = sq_gettop(v);
SQInteger size = 0;
if(nparam == 2) {
sq_getinteger(v, 2, &size);
}
if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size"));
//SQBlob *b = new SQBlob(size);
SQInteger nparam = sq_gettop(v);
SQInteger size = 0;
if(nparam == 2) {
sq_getinteger(v, 2, &size);
}
if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size"));
//SQBlob *b = new SQBlob(size);
SQBlob *b = new (sq_malloc(sizeof(SQBlob)))SQBlob(size);
if(SQ_FAILED(sq_setinstanceup(v,1,b))) {
b->~SQBlob();
sq_free(b,sizeof(SQBlob));
return sq_throwerror(v, _SC("cannot create blob"));
}
sq_setreleasehook(v,1,_blob_releasehook);
return 0;
SQBlob *b = new (sq_malloc(sizeof(SQBlob)))SQBlob(size);
if(SQ_FAILED(sq_setinstanceup(v,1,b))) {
b->~SQBlob();
sq_free(b,sizeof(SQBlob));
return sq_throwerror(v, _SC("cannot create blob"));
}
sq_setreleasehook(v,1,_blob_releasehook);
return 0;
}
static SQInteger _blob__cloned(HSQUIRRELVM v)
{
SQBlob *other = NULL;
{
if(SQ_FAILED(sq_getinstanceup(v,2,(SQUserPointer*)&other,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
return SQ_ERROR;
}
//SQBlob *thisone = new SQBlob(other->Len());
SQBlob *thisone = new (sq_malloc(sizeof(SQBlob)))SQBlob(other->Len());
memcpy(thisone->GetBuf(),other->GetBuf(),thisone->Len());
if(SQ_FAILED(sq_setinstanceup(v,1,thisone))) {
thisone->~SQBlob();
sq_free(thisone,sizeof(SQBlob));
return sq_throwerror(v, _SC("cannot clone blob"));
}
sq_setreleasehook(v,1,_blob_releasehook);
return 0;
SQBlob *other = NULL;
{
if(SQ_FAILED(sq_getinstanceup(v,2,(SQUserPointer*)&other,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
return SQ_ERROR;
}
//SQBlob *thisone = new SQBlob(other->Len());
SQBlob *thisone = new (sq_malloc(sizeof(SQBlob)))SQBlob(other->Len());
memcpy(thisone->GetBuf(),other->GetBuf(),thisone->Len());
if(SQ_FAILED(sq_setinstanceup(v,1,thisone))) {
thisone->~SQBlob();
sq_free(thisone,sizeof(SQBlob));
return sq_throwerror(v, _SC("cannot clone blob"));
}
sq_setreleasehook(v,1,_blob_releasehook);
return 0;
}
#define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck}
static SQRegFunction _blob_methods[] = {
_DECL_BLOB_FUNC(constructor,-1,_SC("xn")),
_DECL_BLOB_FUNC(resize,2,_SC("xn")),
_DECL_BLOB_FUNC(swap2,1,_SC("x")),
_DECL_BLOB_FUNC(swap4,1,_SC("x")),
_DECL_BLOB_FUNC(_set,3,_SC("xnn")),
_DECL_BLOB_FUNC(_get,2,_SC("xn")),
_DECL_BLOB_FUNC(_typeof,1,_SC("x")),
_DECL_BLOB_FUNC(_nexti,2,_SC("x")),
_DECL_BLOB_FUNC(_cloned,2,_SC("xx")),
{0,0,0,0}
static const SQRegFunction _blob_methods[] = {
_DECL_BLOB_FUNC(constructor,-1,_SC("xn")),
_DECL_BLOB_FUNC(resize,2,_SC("xn")),
_DECL_BLOB_FUNC(swap2,1,_SC("x")),
_DECL_BLOB_FUNC(swap4,1,_SC("x")),
_DECL_BLOB_FUNC(_set,3,_SC("xnn")),
_DECL_BLOB_FUNC(_get,2,_SC("xn")),
_DECL_BLOB_FUNC(_typeof,1,_SC("x")),
_DECL_BLOB_FUNC(_nexti,2,_SC("x")),
_DECL_BLOB_FUNC(_cloned,2,_SC("xx")),
{0,0,0,0}
};
@ -181,97 +181,97 @@ static SQRegFunction _blob_methods[] = {
static SQInteger _g_blob_casti2f(HSQUIRRELVM v)
{
SQInteger i;
sq_getinteger(v,2,&i);
sq_pushfloat(v,*((SQFloat *)&i));
return 1;
SQInteger i;
sq_getinteger(v,2,&i);
sq_pushfloat(v,*((const SQFloat *)&i));
return 1;
}
static SQInteger _g_blob_castf2i(HSQUIRRELVM v)
{
SQFloat f;
sq_getfloat(v,2,&f);
sq_pushinteger(v,*((SQInteger *)&f));
return 1;
SQFloat f;
sq_getfloat(v,2,&f);
sq_pushinteger(v,*((const SQInteger *)&f));
return 1;
}
static SQInteger _g_blob_swap2(HSQUIRRELVM v)
{
SQInteger i;
sq_getinteger(v,2,&i);
short s=(short)i;
sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF));
return 1;
SQInteger i;
sq_getinteger(v,2,&i);
short s=(short)i;
sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF));
return 1;
}
static SQInteger _g_blob_swap4(HSQUIRRELVM v)
{
SQInteger i;
sq_getinteger(v,2,&i);
unsigned int t4 = (unsigned int)i;
__swap_dword(&t4);
sq_pushinteger(v,(SQInteger)t4);
return 1;
SQInteger i;
sq_getinteger(v,2,&i);
unsigned int t4 = (unsigned int)i;
__swap_dword(&t4);
sq_pushinteger(v,(SQInteger)t4);
return 1;
}
static SQInteger _g_blob_swapfloat(HSQUIRRELVM v)
{
SQFloat f;
sq_getfloat(v,2,&f);
__swap_dword((unsigned int *)&f);
sq_pushfloat(v,f);
return 1;
SQFloat f;
sq_getfloat(v,2,&f);
__swap_dword((unsigned int *)&f);
sq_pushfloat(v,f);
return 1;
}
#define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck}
static SQRegFunction bloblib_funcs[]={
_DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")),
_DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")),
_DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")),
_DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")),
_DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")),
{0,0}
static const SQRegFunction bloblib_funcs[]={
_DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")),
_DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")),
_DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")),
_DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")),
_DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")),
{0,0}
};
SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr)
{
SQBlob *blob;
if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
return -1;
*ptr = blob->GetBuf();
return SQ_OK;
SQBlob *blob;
if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
return -1;
*ptr = blob->GetBuf();
return SQ_OK;
}
SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx)
{
SQBlob *blob;
if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
return -1;
return blob->Len();
SQBlob *blob;
if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
return -1;
return blob->Len();
}
SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size)
{
SQInteger top = sq_gettop(v);
sq_pushregistrytable(v);
sq_pushstring(v,_SC("std_blob"),-1);
if(SQ_SUCCEEDED(sq_get(v,-2))) {
sq_remove(v,-2); //removes the registry
sq_push(v,1); // push the this
sq_pushinteger(v,size); //size
SQBlob *blob = NULL;
if(SQ_SUCCEEDED(sq_call(v,2,SQTrue,SQFalse))
&& SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) {
sq_remove(v,-2);
return blob->GetBuf();
}
}
sq_settop(v,top);
return NULL;
SQInteger top = sq_gettop(v);
sq_pushregistrytable(v);
sq_pushstring(v,_SC("std_blob"),-1);
if(SQ_SUCCEEDED(sq_get(v,-2))) {
sq_remove(v,-2); //removes the registry
sq_push(v,1); // push the this
sq_pushinteger(v,size); //size
SQBlob *blob = NULL;
if(SQ_SUCCEEDED(sq_call(v,2,SQTrue,SQFalse))
&& SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) {
sq_remove(v,-2);
return blob->GetBuf();
}
}
sq_settop(v,top);
return NULL;
}
SQRESULT sqstd_register_bloblib(HSQUIRRELVM v)
{
return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs);
return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs);
}

View File

@ -1,108 +1,108 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQSTD_BLOBIMPL_H_
#define _SQSTD_BLOBIMPL_H_
struct SQBlob : public SQStream
{
SQBlob(SQInteger size) {
_size = size;
_allocated = size;
_buf = (unsigned char *)sq_malloc(size);
memset(_buf, 0, _size);
_ptr = 0;
_owns = true;
}
virtual ~SQBlob() {
sq_free(_buf, _allocated);
}
SQInteger Write(void *buffer, SQInteger size) {
if(!CanAdvance(size)) {
GrowBufOf(_ptr + size - _size);
}
memcpy(&_buf[_ptr], buffer, size);
_ptr += size;
return size;
}
SQInteger Read(void *buffer,SQInteger size) {
SQInteger n = size;
if(!CanAdvance(size)) {
if((_size - _ptr) > 0)
n = _size - _ptr;
else return 0;
}
memcpy(buffer, &_buf[_ptr], n);
_ptr += n;
return n;
}
bool Resize(SQInteger n) {
if(!_owns) return false;
if(n != _allocated) {
unsigned char *newbuf = (unsigned char *)sq_malloc(n);
memset(newbuf,0,n);
if(_size > n)
memcpy(newbuf,_buf,n);
else
memcpy(newbuf,_buf,_size);
sq_free(_buf,_allocated);
_buf=newbuf;
_allocated = n;
if(_size > _allocated)
_size = _allocated;
if(_ptr > _allocated)
_ptr = _allocated;
}
return true;
}
bool GrowBufOf(SQInteger n)
{
bool ret = true;
if(_size + n > _allocated) {
if(_size + n > _size * 2)
ret = Resize(_size + n);
else
ret = Resize(_size * 2);
}
_size = _size + n;
return ret;
}
bool CanAdvance(SQInteger n) {
if(_ptr+n>_size)return false;
return true;
}
SQInteger Seek(SQInteger offset, SQInteger origin) {
switch(origin) {
case SQ_SEEK_SET:
if(offset > _size || offset < 0) return -1;
_ptr = offset;
break;
case SQ_SEEK_CUR:
if(_ptr + offset > _size || _ptr + offset < 0) return -1;
_ptr += offset;
break;
case SQ_SEEK_END:
if(_size + offset > _size || _size + offset < 0) return -1;
_ptr = _size + offset;
break;
default: return -1;
}
return 0;
}
bool IsValid() {
return _buf?true:false;
}
bool EOS() {
return _ptr == _size;
}
SQInteger Flush() { return 0; }
SQInteger Tell() { return _ptr; }
SQInteger Len() { return _size; }
SQUserPointer GetBuf(){ return _buf; }
SQBlob(SQInteger size) {
_size = size;
_allocated = size;
_buf = (unsigned char *)sq_malloc(size);
memset(_buf, 0, _size);
_ptr = 0;
_owns = true;
}
virtual ~SQBlob() {
sq_free(_buf, _allocated);
}
SQInteger Write(void *buffer, SQInteger size) {
if(!CanAdvance(size)) {
GrowBufOf(_ptr + size - _size);
}
memcpy(&_buf[_ptr], buffer, size);
_ptr += size;
return size;
}
SQInteger Read(void *buffer,SQInteger size) {
SQInteger n = size;
if(!CanAdvance(size)) {
if((_size - _ptr) > 0)
n = _size - _ptr;
else return 0;
}
memcpy(buffer, &_buf[_ptr], n);
_ptr += n;
return n;
}
bool Resize(SQInteger n) {
if(!_owns) return false;
if(n != _allocated) {
unsigned char *newbuf = (unsigned char *)sq_malloc(n);
memset(newbuf,0,n);
if(_size > n)
memcpy(newbuf,_buf,n);
else
memcpy(newbuf,_buf,_size);
sq_free(_buf,_allocated);
_buf=newbuf;
_allocated = n;
if(_size > _allocated)
_size = _allocated;
if(_ptr > _allocated)
_ptr = _allocated;
}
return true;
}
bool GrowBufOf(SQInteger n)
{
bool ret = true;
if(_size + n > _allocated) {
if(_size + n > _size * 2)
ret = Resize(_size + n);
else
ret = Resize(_size * 2);
}
_size = _size + n;
return ret;
}
bool CanAdvance(SQInteger n) {
if(_ptr+n>_size)return false;
return true;
}
SQInteger Seek(SQInteger offset, SQInteger origin) {
switch(origin) {
case SQ_SEEK_SET:
if(offset > _size || offset < 0) return -1;
_ptr = offset;
break;
case SQ_SEEK_CUR:
if(_ptr + offset > _size || _ptr + offset < 0) return -1;
_ptr += offset;
break;
case SQ_SEEK_END:
if(_size + offset > _size || _size + offset < 0) return -1;
_ptr = _size + offset;
break;
default: return -1;
}
return 0;
}
bool IsValid() {
return _buf?true:false;
}
bool EOS() {
return _ptr == _size;
}
SQInteger Flush() { return 0; }
SQInteger Tell() { return _ptr; }
SQInteger Len() { return _size; }
SQUserPointer GetBuf(){ return _buf; }
private:
SQInteger _size;
SQInteger _allocated;
SQInteger _ptr;
unsigned char *_buf;
bool _owns;
SQInteger _size;
SQInteger _allocated;
SQInteger _ptr;
unsigned char *_buf;
bool _owns;
};
#endif //_SQSTD_BLOBIMPL_H_

View File

@ -10,476 +10,476 @@
SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode)
{
#ifndef SQUNICODE
return (SQFILE)fopen(filename,mode);
return (SQFILE)fopen(filename,mode);
#else
return (SQFILE)_wfopen(filename,mode);
return (SQFILE)_wfopen(filename,mode);
#endif
}
SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file)
{
SQInteger ret = (SQInteger)fread(buffer,size,count,(FILE *)file);
return ret;
SQInteger ret = (SQInteger)fread(buffer,size,count,(FILE *)file);
return ret;
}
SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file)
{
return (SQInteger)fwrite(buffer,size,count,(FILE *)file);
return (SQInteger)fwrite(buffer,size,count,(FILE *)file);
}
SQInteger sqstd_fseek(SQFILE file, SQInteger offset, SQInteger origin)
{
SQInteger realorigin;
switch(origin) {
case SQ_SEEK_CUR: realorigin = SEEK_CUR; break;
case SQ_SEEK_END: realorigin = SEEK_END; break;
case SQ_SEEK_SET: realorigin = SEEK_SET; break;
default: return -1; //failed
}
return fseek((FILE *)file,(long)offset,(int)realorigin);
SQInteger realorigin;
switch(origin) {
case SQ_SEEK_CUR: realorigin = SEEK_CUR; break;
case SQ_SEEK_END: realorigin = SEEK_END; break;
case SQ_SEEK_SET: realorigin = SEEK_SET; break;
default: return -1; //failed
}
return fseek((FILE *)file,(long)offset,(int)realorigin);
}
SQInteger sqstd_ftell(SQFILE file)
{
return ftell((FILE *)file);
return ftell((FILE *)file);
}
SQInteger sqstd_fflush(SQFILE file)
{
return fflush((FILE *)file);
return fflush((FILE *)file);
}
SQInteger sqstd_fclose(SQFILE file)
{
return fclose((FILE *)file);
return fclose((FILE *)file);
}
SQInteger sqstd_feof(SQFILE file)
{
return feof((FILE *)file);
return feof((FILE *)file);
}
//File
struct SQFile : public SQStream {
SQFile() { _handle = NULL; _owns = false;}
SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;}
virtual ~SQFile() { Close(); }
bool Open(const SQChar *filename ,const SQChar *mode) {
Close();
if( (_handle = sqstd_fopen(filename,mode)) ) {
_owns = true;
return true;
}
return false;
}
void Close() {
if(_handle && _owns) {
sqstd_fclose(_handle);
_handle = NULL;
_owns = false;
}
}
SQInteger Read(void *buffer,SQInteger size) {
return sqstd_fread(buffer,1,size,_handle);
}
SQInteger Write(void *buffer,SQInteger size) {
return sqstd_fwrite(buffer,1,size,_handle);
}
SQInteger Flush() {
return sqstd_fflush(_handle);
}
SQInteger Tell() {
return sqstd_ftell(_handle);
}
SQInteger Len() {
SQInteger prevpos=Tell();
Seek(0,SQ_SEEK_END);
SQInteger size=Tell();
Seek(prevpos,SQ_SEEK_SET);
return size;
}
SQInteger Seek(SQInteger offset, SQInteger origin) {
return sqstd_fseek(_handle,offset,origin);
}
bool IsValid() { return _handle?true:false; }
bool EOS() { return Tell()==Len()?true:false;}
SQFILE GetHandle() {return _handle;}
SQFile() { _handle = NULL; _owns = false;}
SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;}
virtual ~SQFile() { Close(); }
bool Open(const SQChar *filename ,const SQChar *mode) {
Close();
if( (_handle = sqstd_fopen(filename,mode)) ) {
_owns = true;
return true;
}
return false;
}
void Close() {
if(_handle && _owns) {
sqstd_fclose(_handle);
_handle = NULL;
_owns = false;
}
}
SQInteger Read(void *buffer,SQInteger size) {
return sqstd_fread(buffer,1,size,_handle);
}
SQInteger Write(void *buffer,SQInteger size) {
return sqstd_fwrite(buffer,1,size,_handle);
}
SQInteger Flush() {
return sqstd_fflush(_handle);
}
SQInteger Tell() {
return sqstd_ftell(_handle);
}
SQInteger Len() {
SQInteger prevpos=Tell();
Seek(0,SQ_SEEK_END);
SQInteger size=Tell();
Seek(prevpos,SQ_SEEK_SET);
return size;
}
SQInteger Seek(SQInteger offset, SQInteger origin) {
return sqstd_fseek(_handle,offset,origin);
}
bool IsValid() { return _handle?true:false; }
bool EOS() { return Tell()==Len()?true:false;}
SQFILE GetHandle() {return _handle;}
private:
SQFILE _handle;
bool _owns;
SQFILE _handle;
bool _owns;
};
static SQInteger _file__typeof(HSQUIRRELVM v)
{
sq_pushstring(v,_SC("file"),-1);
return 1;
sq_pushstring(v,_SC("file"),-1);
return 1;
}
static SQInteger _file_releasehook(SQUserPointer p, SQInteger size)
{
SQFile *self = (SQFile*)p;
self->~SQFile();
sq_free(self,sizeof(SQFile));
return 1;
SQFile *self = (SQFile*)p;
self->~SQFile();
sq_free(self,sizeof(SQFile));
return 1;
}
static SQInteger _file_constructor(HSQUIRRELVM v)
{
const SQChar *filename,*mode;
bool owns = true;
SQFile *f;
SQFILE newf;
if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) {
sq_getstring(v, 2, &filename);
sq_getstring(v, 3, &mode);
newf = sqstd_fopen(filename, mode);
if(!newf) return sq_throwerror(v, _SC("cannot open file"));
} else if(sq_gettype(v,2) == OT_USERPOINTER) {
owns = !(sq_gettype(v,3) == OT_NULL);
sq_getuserpointer(v,2,&newf);
} else {
return sq_throwerror(v,_SC("wrong parameter"));
}
const SQChar *filename,*mode;
bool owns = true;
SQFile *f;
SQFILE newf;
if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) {
sq_getstring(v, 2, &filename);
sq_getstring(v, 3, &mode);
newf = sqstd_fopen(filename, mode);
if(!newf) return sq_throwerror(v, _SC("cannot open file"));
} else if(sq_gettype(v,2) == OT_USERPOINTER) {
owns = !(sq_gettype(v,3) == OT_NULL);
sq_getuserpointer(v,2,&newf);
} else {
return sq_throwerror(v,_SC("wrong parameter"));
}
f = new (sq_malloc(sizeof(SQFile)))SQFile(newf,owns);
if(SQ_FAILED(sq_setinstanceup(v,1,f))) {
f->~SQFile();
sq_free(f,sizeof(SQFile));
return sq_throwerror(v, _SC("cannot create blob with negative size"));
}
sq_setreleasehook(v,1,_file_releasehook);
return 0;
f = new (sq_malloc(sizeof(SQFile)))SQFile(newf,owns);
if(SQ_FAILED(sq_setinstanceup(v,1,f))) {
f->~SQFile();
sq_free(f,sizeof(SQFile));
return sq_throwerror(v, _SC("cannot create blob with negative size"));
}
sq_setreleasehook(v,1,_file_releasehook);
return 0;
}
static SQInteger _file_close(HSQUIRRELVM v)
{
SQFile *self = NULL;
if(SQ_SUCCEEDED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_FILE_TYPE_TAG))
&& self != NULL)
{
self->Close();
}
return 0;
SQFile *self = NULL;
if(SQ_SUCCEEDED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_FILE_TYPE_TAG))
&& self != NULL)
{
self->Close();
}
return 0;
}
//bindings
#define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck}
static SQRegFunction _file_methods[] = {
_DECL_FILE_FUNC(constructor,3,_SC("x")),
_DECL_FILE_FUNC(_typeof,1,_SC("x")),
_DECL_FILE_FUNC(close,1,_SC("x")),
{0,0,0,0},
static const SQRegFunction _file_methods[] = {
_DECL_FILE_FUNC(constructor,3,_SC("x")),
_DECL_FILE_FUNC(_typeof,1,_SC("x")),
_DECL_FILE_FUNC(close,1,_SC("x")),
{0,0,0,0},
};
SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own)
{
SQInteger top = sq_gettop(v);
sq_pushregistrytable(v);
sq_pushstring(v,_SC("std_file"),-1);
if(SQ_SUCCEEDED(sq_get(v,-2))) {
sq_remove(v,-2); //removes the registry
sq_pushroottable(v); // push the this
sq_pushuserpointer(v,file); //file
if(own){
sq_pushinteger(v,1); //true
}
else{
sq_pushnull(v); //false
}
if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) {
sq_remove(v,-2);
return SQ_OK;
}
}
sq_settop(v,top);
return SQ_ERROR;
SQInteger top = sq_gettop(v);
sq_pushregistrytable(v);
sq_pushstring(v,_SC("std_file"),-1);
if(SQ_SUCCEEDED(sq_get(v,-2))) {
sq_remove(v,-2); //removes the registry
sq_pushroottable(v); // push the this
sq_pushuserpointer(v,file); //file
if(own){
sq_pushinteger(v,1); //true
}
else{
sq_pushnull(v); //false
}
if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) {
sq_remove(v,-2);
return SQ_OK;
}
}
sq_settop(v,top);
return SQ_ERROR;
}
SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file)
{
SQFile *fileobj = NULL;
if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG))) {
*file = fileobj->GetHandle();
return SQ_OK;
}
return sq_throwerror(v,_SC("not a file"));
SQFile *fileobj = NULL;
if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG))) {
*file = fileobj->GetHandle();
return SQ_OK;
}
return sq_throwerror(v,_SC("not a file"));
}
#define IO_BUFFER_SIZE 2048
struct IOBuffer {
unsigned char buffer[IO_BUFFER_SIZE];
SQInteger size;
SQInteger ptr;
SQFILE file;
unsigned char buffer[IO_BUFFER_SIZE];
SQInteger size;
SQInteger ptr;
SQFILE file;
};
SQInteger _read_byte(IOBuffer *iobuffer)
{
if(iobuffer->ptr < iobuffer->size) {
if(iobuffer->ptr < iobuffer->size) {
SQInteger ret = iobuffer->buffer[iobuffer->ptr];
iobuffer->ptr++;
return ret;
}
else {
if( (iobuffer->size = sqstd_fread(iobuffer->buffer,1,IO_BUFFER_SIZE,iobuffer->file )) > 0 )
{
SQInteger ret = iobuffer->buffer[0];
iobuffer->ptr = 1;
return ret;
}
}
SQInteger ret = iobuffer->buffer[iobuffer->ptr];
iobuffer->ptr++;
return ret;
}
else {
if( (iobuffer->size = sqstd_fread(iobuffer->buffer,1,IO_BUFFER_SIZE,iobuffer->file )) > 0 )
{
SQInteger ret = iobuffer->buffer[0];
iobuffer->ptr = 1;
return ret;
}
}
return 0;
return 0;
}
SQInteger _read_two_bytes(IOBuffer *iobuffer)
{
if(iobuffer->ptr < iobuffer->size) {
if(iobuffer->size < 2) return 0;
SQInteger ret = *((wchar_t*)&iobuffer->buffer[iobuffer->ptr]);
iobuffer->ptr += 2;
return ret;
}
else {
if( (iobuffer->size = sqstd_fread(iobuffer->buffer,1,IO_BUFFER_SIZE,iobuffer->file )) > 0 )
{
if(iobuffer->size < 2) return 0;
SQInteger ret = *((wchar_t*)&iobuffer->buffer[0]);
iobuffer->ptr = 2;
return ret;
}
}
if(iobuffer->ptr < iobuffer->size) {
if(iobuffer->size < 2) return 0;
SQInteger ret = *((const wchar_t*)&iobuffer->buffer[iobuffer->ptr]);
iobuffer->ptr += 2;
return ret;
}
else {
if( (iobuffer->size = sqstd_fread(iobuffer->buffer,1,IO_BUFFER_SIZE,iobuffer->file )) > 0 )
{
if(iobuffer->size < 2) return 0;
SQInteger ret = *((const wchar_t*)&iobuffer->buffer[0]);
iobuffer->ptr = 2;
return ret;
}
}
return 0;
return 0;
}
static SQInteger _io_file_lexfeed_PLAIN(SQUserPointer iobuf)
{
IOBuffer *iobuffer = (IOBuffer *)iobuf;
return _read_byte(iobuffer);
IOBuffer *iobuffer = (IOBuffer *)iobuf;
return _read_byte(iobuffer);
}
#ifdef SQUNICODE
static SQInteger _io_file_lexfeed_UTF8(SQUserPointer iobuf)
{
IOBuffer *iobuffer = (IOBuffer *)iobuf;
IOBuffer *iobuffer = (IOBuffer *)iobuf;
#define READ(iobuf) \
if((inchar = (unsigned char)_read_byte(iobuf)) == 0) \
return 0;
if((inchar = (unsigned char)_read_byte(iobuf)) == 0) \
return 0;
static const SQInteger utf8_lengths[16] =
{
1,1,1,1,1,1,1,1, /* 0000 to 0111 : 1 byte (plain ASCII) */
0,0,0,0, /* 1000 to 1011 : not valid */
2,2, /* 1100, 1101 : 2 bytes */
3, /* 1110 : 3 bytes */
4 /* 1111 :4 bytes */
};
static unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07};
unsigned char inchar;
SQInteger c = 0;
READ(iobuffer);
c = inchar;
//
if(c >= 0x80) {
SQInteger tmp;
SQInteger codelen = utf8_lengths[c>>4];
if(codelen == 0)
return 0;
//"invalid UTF-8 stream";
tmp = c&byte_masks[codelen];
for(SQInteger n = 0; n < codelen-1; n++) {
tmp<<=6;
READ(iobuffer);
tmp |= inchar & 0x3F;
}
c = tmp;
}
return c;
static const SQInteger utf8_lengths[16] =
{
1,1,1,1,1,1,1,1, /* 0000 to 0111 : 1 byte (plain ASCII) */
0,0,0,0, /* 1000 to 1011 : not valid */
2,2, /* 1100, 1101 : 2 bytes */
3, /* 1110 : 3 bytes */
4 /* 1111 :4 bytes */
};
static const unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07};
unsigned char inchar;
SQInteger c = 0;
READ(iobuffer);
c = inchar;
//
if(c >= 0x80) {
SQInteger tmp;
SQInteger codelen = utf8_lengths[c>>4];
if(codelen == 0)
return 0;
//"invalid UTF-8 stream";
tmp = c&byte_masks[codelen];
for(SQInteger n = 0; n < codelen-1; n++) {
tmp<<=6;
READ(iobuffer);
tmp |= inchar & 0x3F;
}
c = tmp;
}
return c;
}
#endif
static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer iobuf)
{
SQInteger ret;
IOBuffer *iobuffer = (IOBuffer *)iobuf;
if( (ret = _read_two_bytes(iobuffer)) > 0 )
return ret;
return 0;
SQInteger ret;
IOBuffer *iobuffer = (IOBuffer *)iobuf;
if( (ret = _read_two_bytes(iobuffer)) > 0 )
return ret;
return 0;
}
static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer iobuf)
{
SQInteger c;
IOBuffer *iobuffer = (IOBuffer *)iobuf;
if( (c = _read_two_bytes(iobuffer)) > 0 ) {
c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00);
return c;
}
return 0;
SQInteger c;
IOBuffer *iobuffer = (IOBuffer *)iobuf;
if( (c = _read_two_bytes(iobuffer)) > 0 ) {
c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00);
return c;
}
return 0;
}
SQInteger file_read(SQUserPointer file,SQUserPointer buf,SQInteger size)
{
SQInteger ret;
if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret;
return -1;
SQInteger ret;
if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret;
return -1;
}
SQInteger file_write(SQUserPointer file,SQUserPointer p,SQInteger size)
{
return sqstd_fwrite(p,1,size,(SQFILE)file);
return sqstd_fwrite(p,1,size,(SQFILE)file);
}
SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror)
{
SQFILE file = sqstd_fopen(filename,_SC("rb"));
SQFILE file = sqstd_fopen(filename,_SC("rb"));
SQInteger ret;
unsigned short us;
unsigned char uc;
SQLEXREADFUNC func = _io_file_lexfeed_PLAIN;
if(file){
ret = sqstd_fread(&us,1,2,file);
if(ret != 2) {
//probably an empty file
us = 0;
}
if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE
sqstd_fseek(file,0,SQ_SEEK_SET);
if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) {
sqstd_fclose(file);
return SQ_OK;
}
}
else { //SCRIPT
SQInteger ret;
unsigned short us;
unsigned char uc;
SQLEXREADFUNC func = _io_file_lexfeed_PLAIN;
if(file){
ret = sqstd_fread(&us,1,2,file);
if(ret != 2) {
//probably an empty file
us = 0;
}
if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE
sqstd_fseek(file,0,SQ_SEEK_SET);
if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) {
sqstd_fclose(file);
return SQ_OK;
}
}
else { //SCRIPT
switch(us)
{
//gotta swap the next 2 lines on BIG endian machines
case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian;
case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian;
case 0xBBEF:
if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) {
sqstd_fclose(file);
return sq_throwerror(v,_SC("io error"));
}
if(uc != 0xBF) {
sqstd_fclose(file);
return sq_throwerror(v,_SC("Unrecognozed ecoding"));
}
switch(us)
{
//gotta swap the next 2 lines on BIG endian machines
case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian;
case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian;
case 0xBBEF:
if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) {
sqstd_fclose(file);
return sq_throwerror(v,_SC("io error"));
}
if(uc != 0xBF) {
sqstd_fclose(file);
return sq_throwerror(v,_SC("Unrecognozed ecoding"));
}
#ifdef SQUNICODE
func = _io_file_lexfeed_UTF8;
func = _io_file_lexfeed_UTF8;
#else
func = _io_file_lexfeed_PLAIN;
func = _io_file_lexfeed_PLAIN;
#endif
break;//UTF-8 ;
default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii
}
IOBuffer buffer;
buffer.ptr = 0;
buffer.size = 0;
buffer.file = file;
if(SQ_SUCCEEDED(sq_compile(v,func,&buffer,filename,printerror))){
sqstd_fclose(file);
return SQ_OK;
}
}
sqstd_fclose(file);
return SQ_ERROR;
}
return sq_throwerror(v,_SC("cannot open the file"));
break;//UTF-8 ;
default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii
}
IOBuffer buffer;
buffer.ptr = 0;
buffer.size = 0;
buffer.file = file;
if(SQ_SUCCEEDED(sq_compile(v,func,&buffer,filename,printerror))){
sqstd_fclose(file);
return SQ_OK;
}
}
sqstd_fclose(file);
return SQ_ERROR;
}
return sq_throwerror(v,_SC("cannot open the file"));
}
SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror)
{
if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) {
sq_push(v,-2);
if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) {
sq_remove(v,retval?-2:-1); //removes the closure
return 1;
}
sq_pop(v,1); //removes the closure
}
return SQ_ERROR;
if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) {
sq_push(v,-2);
if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) {
sq_remove(v,retval?-2:-1); //removes the closure
return 1;
}
sq_pop(v,1); //removes the closure
}
return SQ_ERROR;
}
SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename)
{
SQFILE file = sqstd_fopen(filename,_SC("wb+"));
if(!file) return sq_throwerror(v,_SC("cannot open the file"));
if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) {
sqstd_fclose(file);
return SQ_OK;
}
sqstd_fclose(file);
return SQ_ERROR; //forward the error
SQFILE file = sqstd_fopen(filename,_SC("wb+"));
if(!file) return sq_throwerror(v,_SC("cannot open the file"));
if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) {
sqstd_fclose(file);
return SQ_OK;
}
sqstd_fclose(file);
return SQ_ERROR; //forward the error
}
SQInteger _g_io_loadfile(HSQUIRRELVM v)
{
const SQChar *filename;
SQBool printerror = SQFalse;
sq_getstring(v,2,&filename);
if(sq_gettop(v) >= 3) {
sq_getbool(v,3,&printerror);
}
if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror)))
return 1;
return SQ_ERROR; //propagates the error
const SQChar *filename;
SQBool printerror = SQFalse;
sq_getstring(v,2,&filename);
if(sq_gettop(v) >= 3) {
sq_getbool(v,3,&printerror);
}
if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror)))
return 1;
return SQ_ERROR; //propagates the error
}
SQInteger _g_io_writeclosuretofile(HSQUIRRELVM v)
{
const SQChar *filename;
sq_getstring(v,2,&filename);
if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,filename)))
return 1;
return SQ_ERROR; //propagates the error
const SQChar *filename;
sq_getstring(v,2,&filename);
if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,filename)))
return 1;
return SQ_ERROR; //propagates the error
}
SQInteger _g_io_dofile(HSQUIRRELVM v)
{
const SQChar *filename;
SQBool printerror = SQFalse;
sq_getstring(v,2,&filename);
if(sq_gettop(v) >= 3) {
sq_getbool(v,3,&printerror);
}
sq_push(v,1); //repush the this
if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror)))
return 1;
return SQ_ERROR; //propagates the error
const SQChar *filename;
SQBool printerror = SQFalse;
sq_getstring(v,2,&filename);
if(sq_gettop(v) >= 3) {
sq_getbool(v,3,&printerror);
}
sq_push(v,1); //repush the this
if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror)))
return 1;
return SQ_ERROR; //propagates the error
}
#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck}
static SQRegFunction iolib_funcs[]={
_DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")),
_DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")),
_DECL_GLOBALIO_FUNC(writeclosuretofile,3,_SC(".sc")),
{0,0}
static const SQRegFunction iolib_funcs[]={
_DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")),
_DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")),
_DECL_GLOBALIO_FUNC(writeclosuretofile,3,_SC(".sc")),
{0,0}
};
SQRESULT sqstd_register_iolib(HSQUIRRELVM v)
{
SQInteger top = sq_gettop(v);
//create delegate
declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs);
sq_pushstring(v,_SC("stdout"),-1);
sqstd_createfile(v,stdout,SQFalse);
sq_newslot(v,-3,SQFalse);
sq_pushstring(v,_SC("stdin"),-1);
sqstd_createfile(v,stdin,SQFalse);
sq_newslot(v,-3,SQFalse);
sq_pushstring(v,_SC("stderr"),-1);
sqstd_createfile(v,stderr,SQFalse);
sq_newslot(v,-3,SQFalse);
sq_settop(v,top);
return SQ_OK;
SQInteger top = sq_gettop(v);
//create delegate
declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs);
sq_pushstring(v,_SC("stdout"),-1);
sqstd_createfile(v,stdout,SQFalse);
sq_newslot(v,-3,SQFalse);
sq_pushstring(v,_SC("stdin"),-1);
sqstd_createfile(v,stdin,SQFalse);
sq_newslot(v,-3,SQFalse);
sq_pushstring(v,_SC("stderr"),-1);
sqstd_createfile(v,stderr,SQFalse);
sq_newslot(v,-3,SQFalse);
sq_settop(v,top);
return SQ_OK;
}

View File

@ -5,41 +5,41 @@
#include <sqstdmath.h>
#define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \
SQFloat f; \
sq_getfloat(v,2,&f); \
sq_pushfloat(v,(SQFloat)_funcname(f)); \
return 1; \
SQFloat f; \
sq_getfloat(v,2,&f); \
sq_pushfloat(v,(SQFloat)_funcname(f)); \
return 1; \
}
#define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \
SQFloat p1,p2; \
sq_getfloat(v,2,&p1); \
sq_getfloat(v,3,&p2); \
sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \
return 1; \
SQFloat p1,p2; \
sq_getfloat(v,2,&p1); \
sq_getfloat(v,3,&p2); \
sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \
return 1; \
}
static SQInteger math_srand(HSQUIRRELVM v)
{
SQInteger i;
if(SQ_FAILED(sq_getinteger(v,2,&i)))
return sq_throwerror(v,_SC("invalid param"));
srand((unsigned int)i);
return 0;
SQInteger i;
if(SQ_FAILED(sq_getinteger(v,2,&i)))
return sq_throwerror(v,_SC("invalid param"));
srand((unsigned int)i);
return 0;
}
static SQInteger math_rand(HSQUIRRELVM v)
{
sq_pushinteger(v,rand());
return 1;
sq_pushinteger(v,rand());
return 1;
}
static SQInteger math_abs(HSQUIRRELVM v)
{
SQInteger n;
sq_getinteger(v,2,&n);
sq_pushinteger(v,(SQInteger)abs((int)n));
return 1;
SQInteger n;
sq_getinteger(v,2,&n);
sq_pushinteger(v,(SQInteger)abs((int)n));
return 1;
}
SINGLE_ARG_FUNC(sqrt)
@ -59,26 +59,26 @@ SINGLE_ARG_FUNC(ceil)
SINGLE_ARG_FUNC(exp)
#define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck}
static SQRegFunction mathlib_funcs[] = {
_DECL_FUNC(sqrt,2,_SC(".n")),
_DECL_FUNC(sin,2,_SC(".n")),
_DECL_FUNC(cos,2,_SC(".n")),
_DECL_FUNC(asin,2,_SC(".n")),
_DECL_FUNC(acos,2,_SC(".n")),
_DECL_FUNC(log,2,_SC(".n")),
_DECL_FUNC(log10,2,_SC(".n")),
_DECL_FUNC(tan,2,_SC(".n")),
_DECL_FUNC(atan,2,_SC(".n")),
_DECL_FUNC(atan2,3,_SC(".nn")),
_DECL_FUNC(pow,3,_SC(".nn")),
_DECL_FUNC(floor,2,_SC(".n")),
_DECL_FUNC(ceil,2,_SC(".n")),
_DECL_FUNC(exp,2,_SC(".n")),
_DECL_FUNC(srand,2,_SC(".n")),
_DECL_FUNC(rand,1,NULL),
_DECL_FUNC(fabs,2,_SC(".n")),
_DECL_FUNC(abs,2,_SC(".n")),
{0,0},
static const SQRegFunction mathlib_funcs[] = {
_DECL_FUNC(sqrt,2,_SC(".n")),
_DECL_FUNC(sin,2,_SC(".n")),
_DECL_FUNC(cos,2,_SC(".n")),
_DECL_FUNC(asin,2,_SC(".n")),
_DECL_FUNC(acos,2,_SC(".n")),
_DECL_FUNC(log,2,_SC(".n")),
_DECL_FUNC(log10,2,_SC(".n")),
_DECL_FUNC(tan,2,_SC(".n")),
_DECL_FUNC(atan,2,_SC(".n")),
_DECL_FUNC(atan2,3,_SC(".nn")),
_DECL_FUNC(pow,3,_SC(".nn")),
_DECL_FUNC(floor,2,_SC(".n")),
_DECL_FUNC(ceil,2,_SC(".n")),
_DECL_FUNC(exp,2,_SC(".n")),
_DECL_FUNC(srand,2,_SC(".n")),
_DECL_FUNC(rand,1,NULL),
_DECL_FUNC(fabs,2,_SC(".n")),
_DECL_FUNC(abs,2,_SC(".n")),
{0,0},
};
#undef _DECL_FUNC
@ -88,20 +88,20 @@ static SQRegFunction mathlib_funcs[] = {
SQRESULT sqstd_register_mathlib(HSQUIRRELVM v)
{
SQInteger i=0;
while(mathlib_funcs[i].name!=0) {
sq_pushstring(v,mathlib_funcs[i].name,-1);
sq_newclosure(v,mathlib_funcs[i].f,0);
sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask);
sq_setnativeclosurename(v,-1,mathlib_funcs[i].name);
sq_newslot(v,-3,SQFalse);
i++;
}
sq_pushstring(v,_SC("RAND_MAX"),-1);
sq_pushinteger(v,RAND_MAX);
sq_newslot(v,-3,SQFalse);
sq_pushstring(v,_SC("PI"),-1);
sq_pushfloat(v,(SQFloat)M_PI);
sq_newslot(v,-3,SQFalse);
return SQ_OK;
SQInteger i=0;
while(mathlib_funcs[i].name!=0) {
sq_pushstring(v,mathlib_funcs[i].name,-1);
sq_newclosure(v,mathlib_funcs[i].f,0);
sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask);
sq_setnativeclosurename(v,-1,mathlib_funcs[i].name);
sq_newslot(v,-3,SQFalse);
i++;
}
sq_pushstring(v,_SC("RAND_MAX"),-1);
sq_pushinteger(v,RAND_MAX);
sq_newslot(v,-3,SQFalse);
sq_pushstring(v,_SC("PI"),-1);
sq_pushfloat(v,(SQFloat)M_PI);
sq_newslot(v,-3,SQFalse);
return SQ_OK;
}

File diff suppressed because it is too large Load Diff

View File

@ -10,327 +10,327 @@
#include "sqstdblobimpl.h"
#define SETUP_STREAM(v) \
SQStream *self = NULL; \
if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_STREAM_TYPE_TAG))) \
return sq_throwerror(v,_SC("invalid type tag")); \
if(!self || !self->IsValid()) \
return sq_throwerror(v,_SC("the stream is invalid"));
SQStream *self = NULL; \
if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_STREAM_TYPE_TAG))) \
return sq_throwerror(v,_SC("invalid type tag")); \
if(!self || !self->IsValid()) \
return sq_throwerror(v,_SC("the stream is invalid"));
SQInteger _stream_readblob(HSQUIRRELVM v)
{
SETUP_STREAM(v);
SQUserPointer data,blobp;
SQInteger size,res;
sq_getinteger(v,2,&size);
if(size > self->Len()) {
size = self->Len();
}
data = sq_getscratchpad(v,size);
res = self->Read(data,size);
if(res <= 0)
return sq_throwerror(v,_SC("no data left to read"));
blobp = sqstd_createblob(v,res);
memcpy(blobp,data,res);
return 1;
SETUP_STREAM(v);
SQUserPointer data,blobp;
SQInteger size,res;
sq_getinteger(v,2,&size);
if(size > self->Len()) {
size = self->Len();
}
data = sq_getscratchpad(v,size);
res = self->Read(data,size);
if(res <= 0)
return sq_throwerror(v,_SC("no data left to read"));
blobp = sqstd_createblob(v,res);
memcpy(blobp,data,res);
return 1;
}
#define SAFE_READN(ptr,len) { \
if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \
}
if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \
}
SQInteger _stream_readn(HSQUIRRELVM v)
{
SETUP_STREAM(v);
SQInteger format;
sq_getinteger(v, 2, &format);
switch(format) {
case 'l': {
SQInteger i;
SAFE_READN(&i, sizeof(i));
sq_pushinteger(v, i);
}
break;
case 'i': {
SQInt32 i;
SAFE_READN(&i, sizeof(i));
sq_pushinteger(v, i);
}
break;
case 's': {
short s;
SAFE_READN(&s, sizeof(short));
sq_pushinteger(v, s);
}
break;
case 'w': {
unsigned short w;
SAFE_READN(&w, sizeof(unsigned short));
sq_pushinteger(v, w);
}
break;
case 'c': {
char c;
SAFE_READN(&c, sizeof(char));
sq_pushinteger(v, c);
}
break;
case 'b': {
unsigned char c;
SAFE_READN(&c, sizeof(unsigned char));
sq_pushinteger(v, c);
}
break;
case 'f': {
float f;
SAFE_READN(&f, sizeof(float));
sq_pushfloat(v, f);
}
break;
case 'd': {
double d;
SAFE_READN(&d, sizeof(double));
sq_pushfloat(v, (SQFloat)d);
}
break;
default:
return sq_throwerror(v, _SC("invalid format"));
}
return 1;
SETUP_STREAM(v);
SQInteger format;
sq_getinteger(v, 2, &format);
switch(format) {
case 'l': {
SQInteger i;
SAFE_READN(&i, sizeof(i));
sq_pushinteger(v, i);
}
break;
case 'i': {
SQInt32 i;
SAFE_READN(&i, sizeof(i));
sq_pushinteger(v, i);
}
break;
case 's': {
short s;
SAFE_READN(&s, sizeof(short));
sq_pushinteger(v, s);
}
break;
case 'w': {
unsigned short w;
SAFE_READN(&w, sizeof(unsigned short));
sq_pushinteger(v, w);
}
break;
case 'c': {
char c;
SAFE_READN(&c, sizeof(char));
sq_pushinteger(v, c);
}
break;
case 'b': {
unsigned char c;
SAFE_READN(&c, sizeof(unsigned char));
sq_pushinteger(v, c);
}
break;
case 'f': {
float f;
SAFE_READN(&f, sizeof(float));
sq_pushfloat(v, f);
}
break;
case 'd': {
double d;
SAFE_READN(&d, sizeof(double));
sq_pushfloat(v, (SQFloat)d);
}
break;
default:
return sq_throwerror(v, _SC("invalid format"));
}
return 1;
}
SQInteger _stream_writeblob(HSQUIRRELVM v)
{
SQUserPointer data;
SQInteger size;
SETUP_STREAM(v);
if(SQ_FAILED(sqstd_getblob(v,2,&data)))
return sq_throwerror(v,_SC("invalid parameter"));
size = sqstd_getblobsize(v,2);
if(self->Write(data,size) != size)
return sq_throwerror(v,_SC("io error"));
sq_pushinteger(v,size);
return 1;
SQUserPointer data;
SQInteger size;
SETUP_STREAM(v);
if(SQ_FAILED(sqstd_getblob(v,2,&data)))
return sq_throwerror(v,_SC("invalid parameter"));
size = sqstd_getblobsize(v,2);
if(self->Write(data,size) != size)
return sq_throwerror(v,_SC("io error"));
sq_pushinteger(v,size);
return 1;
}
SQInteger _stream_writen(HSQUIRRELVM v)
{
SETUP_STREAM(v);
SQInteger format, ti;
SQFloat tf;
sq_getinteger(v, 3, &format);
switch(format) {
case 'l': {
SQInteger i;
sq_getinteger(v, 2, &ti);
i = ti;
self->Write(&i, sizeof(SQInteger));
}
break;
case 'i': {
SQInt32 i;
sq_getinteger(v, 2, &ti);
i = (SQInt32)ti;
self->Write(&i, sizeof(SQInt32));
}
break;
case 's': {
short s;
sq_getinteger(v, 2, &ti);
s = (short)ti;
self->Write(&s, sizeof(short));
}
break;
case 'w': {
unsigned short w;
sq_getinteger(v, 2, &ti);
w = (unsigned short)ti;
self->Write(&w, sizeof(unsigned short));
}
break;
case 'c': {
char c;
sq_getinteger(v, 2, &ti);
c = (char)ti;
self->Write(&c, sizeof(char));
}
break;
case 'b': {
unsigned char b;
sq_getinteger(v, 2, &ti);
b = (unsigned char)ti;
self->Write(&b, sizeof(unsigned char));
}
break;
case 'f': {
float f;
sq_getfloat(v, 2, &tf);
f = (float)tf;
self->Write(&f, sizeof(float));
}
break;
case 'd': {
double d;
sq_getfloat(v, 2, &tf);
d = tf;
self->Write(&d, sizeof(double));
}
break;
default:
return sq_throwerror(v, _SC("invalid format"));
}
return 0;
SETUP_STREAM(v);
SQInteger format, ti;
SQFloat tf;
sq_getinteger(v, 3, &format);
switch(format) {
case 'l': {
SQInteger i;
sq_getinteger(v, 2, &ti);
i = ti;
self->Write(&i, sizeof(SQInteger));
}
break;
case 'i': {
SQInt32 i;
sq_getinteger(v, 2, &ti);
i = (SQInt32)ti;
self->Write(&i, sizeof(SQInt32));
}
break;
case 's': {
short s;
sq_getinteger(v, 2, &ti);
s = (short)ti;
self->Write(&s, sizeof(short));
}
break;
case 'w': {
unsigned short w;
sq_getinteger(v, 2, &ti);
w = (unsigned short)ti;
self->Write(&w, sizeof(unsigned short));
}
break;
case 'c': {
char c;
sq_getinteger(v, 2, &ti);
c = (char)ti;
self->Write(&c, sizeof(char));
}
break;
case 'b': {
unsigned char b;
sq_getinteger(v, 2, &ti);
b = (unsigned char)ti;
self->Write(&b, sizeof(unsigned char));
}
break;
case 'f': {
float f;
sq_getfloat(v, 2, &tf);
f = (float)tf;
self->Write(&f, sizeof(float));
}
break;
case 'd': {
double d;
sq_getfloat(v, 2, &tf);
d = tf;
self->Write(&d, sizeof(double));
}
break;
default:
return sq_throwerror(v, _SC("invalid format"));
}
return 0;
}
SQInteger _stream_seek(HSQUIRRELVM v)
{
SETUP_STREAM(v);
SQInteger offset, origin = SQ_SEEK_SET;
sq_getinteger(v, 2, &offset);
if(sq_gettop(v) > 2) {
SQInteger t;
sq_getinteger(v, 3, &t);
switch(t) {
case 'b': origin = SQ_SEEK_SET; break;
case 'c': origin = SQ_SEEK_CUR; break;
case 'e': origin = SQ_SEEK_END; break;
default: return sq_throwerror(v,_SC("invalid origin"));
}
}
sq_pushinteger(v, self->Seek(offset, origin));
return 1;
SETUP_STREAM(v);
SQInteger offset, origin = SQ_SEEK_SET;
sq_getinteger(v, 2, &offset);
if(sq_gettop(v) > 2) {
SQInteger t;
sq_getinteger(v, 3, &t);
switch(t) {
case 'b': origin = SQ_SEEK_SET; break;
case 'c': origin = SQ_SEEK_CUR; break;
case 'e': origin = SQ_SEEK_END; break;
default: return sq_throwerror(v,_SC("invalid origin"));
}
}
sq_pushinteger(v, self->Seek(offset, origin));
return 1;
}
SQInteger _stream_tell(HSQUIRRELVM v)
{
SETUP_STREAM(v);
sq_pushinteger(v, self->Tell());
return 1;
SETUP_STREAM(v);
sq_pushinteger(v, self->Tell());
return 1;
}
SQInteger _stream_len(HSQUIRRELVM v)
{
SETUP_STREAM(v);
sq_pushinteger(v, self->Len());
return 1;
SETUP_STREAM(v);
sq_pushinteger(v, self->Len());
return 1;
}
SQInteger _stream_flush(HSQUIRRELVM v)
{
SETUP_STREAM(v);
if(!self->Flush())
sq_pushinteger(v, 1);
else
sq_pushnull(v);
return 1;
SETUP_STREAM(v);
if(!self->Flush())
sq_pushinteger(v, 1);
else
sq_pushnull(v);
return 1;
}
SQInteger _stream_eos(HSQUIRRELVM v)
{
SETUP_STREAM(v);
if(self->EOS())
sq_pushinteger(v, 1);
else
sq_pushnull(v);
return 1;
SETUP_STREAM(v);
if(self->EOS())
sq_pushinteger(v, 1);
else
sq_pushnull(v);
return 1;
}
SQInteger _stream__cloned(HSQUIRRELVM v)
{
return sq_throwerror(v,_SC("this object cannot be cloned"));
return sq_throwerror(v,_SC("this object cannot be cloned"));
}
static SQRegFunction _stream_methods[] = {
_DECL_STREAM_FUNC(readblob,2,_SC("xn")),
_DECL_STREAM_FUNC(readn,2,_SC("xn")),
_DECL_STREAM_FUNC(writeblob,-2,_SC("xx")),
_DECL_STREAM_FUNC(writen,3,_SC("xnn")),
_DECL_STREAM_FUNC(seek,-2,_SC("xnn")),
_DECL_STREAM_FUNC(tell,1,_SC("x")),
_DECL_STREAM_FUNC(len,1,_SC("x")),
_DECL_STREAM_FUNC(eos,1,_SC("x")),
_DECL_STREAM_FUNC(flush,1,_SC("x")),
_DECL_STREAM_FUNC(_cloned,0,NULL),
{0,0}
static const SQRegFunction _stream_methods[] = {
_DECL_STREAM_FUNC(readblob,2,_SC("xn")),
_DECL_STREAM_FUNC(readn,2,_SC("xn")),
_DECL_STREAM_FUNC(writeblob,-2,_SC("xx")),
_DECL_STREAM_FUNC(writen,3,_SC("xnn")),
_DECL_STREAM_FUNC(seek,-2,_SC("xnn")),
_DECL_STREAM_FUNC(tell,1,_SC("x")),
_DECL_STREAM_FUNC(len,1,_SC("x")),
_DECL_STREAM_FUNC(eos,1,_SC("x")),
_DECL_STREAM_FUNC(flush,1,_SC("x")),
_DECL_STREAM_FUNC(_cloned,0,NULL),
{0,0}
};
void init_streamclass(HSQUIRRELVM v)
{
sq_pushregistrytable(v);
sq_pushstring(v,_SC("std_stream"),-1);
if(SQ_FAILED(sq_get(v,-2))) {
sq_pushstring(v,_SC("std_stream"),-1);
sq_newclass(v,SQFalse);
sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG);
SQInteger i = 0;
while(_stream_methods[i].name != 0) {
SQRegFunction &f = _stream_methods[i];
sq_pushstring(v,f.name,-1);
sq_newclosure(v,f.f,0);
sq_setparamscheck(v,f.nparamscheck,f.typemask);
sq_newslot(v,-3,SQFalse);
i++;
}
sq_newslot(v,-3,SQFalse);
sq_pushroottable(v);
sq_pushstring(v,_SC("stream"),-1);
sq_pushstring(v,_SC("std_stream"),-1);
sq_get(v,-4);
sq_newslot(v,-3,SQFalse);
sq_pop(v,1);
}
else {
sq_pop(v,1); //result
}
sq_pop(v,1);
sq_pushregistrytable(v);
sq_pushstring(v,_SC("std_stream"),-1);
if(SQ_FAILED(sq_get(v,-2))) {
sq_pushstring(v,_SC("std_stream"),-1);
sq_newclass(v,SQFalse);
sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG);
SQInteger i = 0;
while(_stream_methods[i].name != 0) {
const SQRegFunction &f = _stream_methods[i];
sq_pushstring(v,f.name,-1);
sq_newclosure(v,f.f,0);
sq_setparamscheck(v,f.nparamscheck,f.typemask);
sq_newslot(v,-3,SQFalse);
i++;
}
sq_newslot(v,-3,SQFalse);
sq_pushroottable(v);
sq_pushstring(v,_SC("stream"),-1);
sq_pushstring(v,_SC("std_stream"),-1);
sq_get(v,-4);
sq_newslot(v,-3,SQFalse);
sq_pop(v,1);
}
else {
sq_pop(v,1); //result
}
sq_pop(v,1);
}
SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals)
SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,const SQRegFunction *methods,const SQRegFunction *globals)
{
if(sq_gettype(v,-1) != OT_TABLE)
return sq_throwerror(v,_SC("table expected"));
SQInteger top = sq_gettop(v);
//create delegate
if(sq_gettype(v,-1) != OT_TABLE)
return sq_throwerror(v,_SC("table expected"));
SQInteger top = sq_gettop(v);
//create delegate
init_streamclass(v);
sq_pushregistrytable(v);
sq_pushstring(v,reg_name,-1);
sq_pushstring(v,_SC("std_stream"),-1);
if(SQ_SUCCEEDED(sq_get(v,-3))) {
sq_newclass(v,SQTrue);
sq_settypetag(v,-1,typetag);
SQInteger i = 0;
while(methods[i].name != 0) {
SQRegFunction &f = methods[i];
sq_pushstring(v,f.name,-1);
sq_newclosure(v,f.f,0);
sq_setparamscheck(v,f.nparamscheck,f.typemask);
sq_setnativeclosurename(v,-1,f.name);
sq_newslot(v,-3,SQFalse);
i++;
}
sq_newslot(v,-3,SQFalse);
sq_pop(v,1);
sq_pushregistrytable(v);
sq_pushstring(v,reg_name,-1);
sq_pushstring(v,_SC("std_stream"),-1);
if(SQ_SUCCEEDED(sq_get(v,-3))) {
sq_newclass(v,SQTrue);
sq_settypetag(v,-1,typetag);
SQInteger i = 0;
while(methods[i].name != 0) {
const SQRegFunction &f = methods[i];
sq_pushstring(v,f.name,-1);
sq_newclosure(v,f.f,0);
sq_setparamscheck(v,f.nparamscheck,f.typemask);
sq_setnativeclosurename(v,-1,f.name);
sq_newslot(v,-3,SQFalse);
i++;
}
sq_newslot(v,-3,SQFalse);
sq_pop(v,1);
i = 0;
while(globals[i].name!=0)
{
SQRegFunction &f = globals[i];
sq_pushstring(v,f.name,-1);
sq_newclosure(v,f.f,0);
sq_setparamscheck(v,f.nparamscheck,f.typemask);
sq_setnativeclosurename(v,-1,f.name);
sq_newslot(v,-3,SQFalse);
i++;
}
//register the class in the target table
sq_pushstring(v,name,-1);
sq_pushregistrytable(v);
sq_pushstring(v,reg_name,-1);
sq_get(v,-2);
sq_remove(v,-2);
sq_newslot(v,-3,SQFalse);
i = 0;
while(globals[i].name!=0)
{
const SQRegFunction &f = globals[i];
sq_pushstring(v,f.name,-1);
sq_newclosure(v,f.f,0);
sq_setparamscheck(v,f.nparamscheck,f.typemask);
sq_setnativeclosurename(v,-1,f.name);
sq_newslot(v,-3,SQFalse);
i++;
}
//register the class in the target table
sq_pushstring(v,name,-1);
sq_pushregistrytable(v);
sq_pushstring(v,reg_name,-1);
sq_get(v,-2);
sq_remove(v,-2);
sq_newslot(v,-3,SQFalse);
sq_settop(v,top);
return SQ_OK;
}
sq_settop(v,top);
return SQ_ERROR;
sq_settop(v,top);
return SQ_OK;
}
sq_settop(v,top);
return SQ_ERROR;
}

View File

@ -1,4 +1,4 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQSTD_STREAM_H_
#define _SQSTD_STREAM_H_
@ -14,5 +14,5 @@ SQInteger _stream_eos(HSQUIRRELVM v);
SQInteger _stream_flush(HSQUIRRELVM v);
#define _DECL_STREAM_FUNC(name,nparams,typecheck) {_SC(#name),_stream_##name,nparams,typecheck}
SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals);
SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,const SQRegFunction *methods,const SQRegFunction *globals);
#endif /*_SQSTD_STREAM_H_*/

View File

@ -7,482 +7,482 @@
#include <ctype.h>
#include <assert.h>
#define MAX_FORMAT_LEN 20
#define MAX_WFORMAT_LEN 3
#define MAX_FORMAT_LEN 20
#define MAX_WFORMAT_LEN 3
#define ADDITIONAL_FORMAT_SPACE (100*sizeof(SQChar))
static SQBool isfmtchr(SQChar ch)
{
switch(ch) {
case '-': case '+': case ' ': case '#': case '0': return SQTrue;
}
return SQFalse;
switch(ch) {
case '-': case '+': case ' ': case '#': case '0': return SQTrue;
}
return SQFalse;
}
static SQInteger validate_format(HSQUIRRELVM v, SQChar *fmt, const SQChar *src, SQInteger n,SQInteger &width)
{
SQChar *dummy;
SQChar swidth[MAX_WFORMAT_LEN];
SQInteger wc = 0;
SQInteger start = n;
fmt[0] = '%';
while (isfmtchr(src[n])) n++;
while (scisdigit(src[n])) {
swidth[wc] = src[n];
n++;
wc++;
if(wc>=MAX_WFORMAT_LEN)
return sq_throwerror(v,_SC("width format too long"));
}
swidth[wc] = '\0';
if(wc > 0) {
width = scstrtol(swidth,&dummy,10);
}
else
width = 0;
if (src[n] == '.') {
n++;
SQChar *dummy;
SQChar swidth[MAX_WFORMAT_LEN];
SQInteger wc = 0;
SQInteger start = n;
fmt[0] = '%';
while (isfmtchr(src[n])) n++;
while (scisdigit(src[n])) {
swidth[wc] = src[n];
n++;
wc++;
if(wc>=MAX_WFORMAT_LEN)
return sq_throwerror(v,_SC("width format too long"));
}
swidth[wc] = '\0';
if(wc > 0) {
width = scstrtol(swidth,&dummy,10);
}
else
width = 0;
if (src[n] == '.') {
n++;
wc = 0;
while (scisdigit(src[n])) {
swidth[wc] = src[n];
n++;
wc++;
if(wc>=MAX_WFORMAT_LEN)
return sq_throwerror(v,_SC("precision format too long"));
}
swidth[wc] = '\0';
if(wc > 0) {
width += scstrtol(swidth,&dummy,10);
wc = 0;
while (scisdigit(src[n])) {
swidth[wc] = src[n];
n++;
wc++;
if(wc>=MAX_WFORMAT_LEN)
return sq_throwerror(v,_SC("precision format too long"));
}
swidth[wc] = '\0';
if(wc > 0) {
width += scstrtol(swidth,&dummy,10);
}
}
if (n-start > MAX_FORMAT_LEN )
return sq_throwerror(v,_SC("format too long"));
memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(SQChar));
fmt[(n-start)+2] = '\0';
return n;
}
}
if (n-start > MAX_FORMAT_LEN )
return sq_throwerror(v,_SC("format too long"));
memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(SQChar));
fmt[(n-start)+2] = '\0';
return n;
}
SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output)
{
const SQChar *format;
SQChar *dest;
SQChar fmt[MAX_FORMAT_LEN];
sq_getstring(v,nformatstringidx,&format);
SQInteger format_size = sq_getsize(v,nformatstringidx);
SQInteger allocated = (format_size+2)*sizeof(SQChar);
dest = sq_getscratchpad(v,allocated);
SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0;
//while(format[n] != '\0')
while(n < format_size)
{
if(format[n] != '%') {
assert(i < allocated);
dest[i++] = format[n];
n++;
}
else if(format[n+1] == '%') { //handles %%
dest[i++] = '%';
n += 2;
}
else {
n++;
if( nparam > sq_gettop(v) )
return sq_throwerror(v,_SC("not enough paramters for the given format string"));
n = validate_format(v,fmt,format,n,w);
if(n < 0) return -1;
SQInteger addlen = 0;
SQInteger valtype = 0;
const SQChar *ts;
SQInteger ti;
SQFloat tf;
switch(format[n]) {
case 's':
if(SQ_FAILED(sq_getstring(v,nparam,&ts)))
return sq_throwerror(v,_SC("string expected for the specified format"));
addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar));
valtype = 's';
break;
case 'i': case 'd': case 'o': case 'u': case 'x': case 'X':
const SQChar *format;
SQChar *dest;
SQChar fmt[MAX_FORMAT_LEN];
sq_getstring(v,nformatstringidx,&format);
SQInteger format_size = sq_getsize(v,nformatstringidx);
SQInteger allocated = (format_size+2)*sizeof(SQChar);
dest = sq_getscratchpad(v,allocated);
SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0;
//while(format[n] != '\0')
while(n < format_size)
{
if(format[n] != '%') {
assert(i < allocated);
dest[i++] = format[n];
n++;
}
else if(format[n+1] == '%') { //handles %%
dest[i++] = '%';
n += 2;
}
else {
n++;
if( nparam > sq_gettop(v) )
return sq_throwerror(v,_SC("not enough paramters for the given format string"));
n = validate_format(v,fmt,format,n,w);
if(n < 0) return -1;
SQInteger addlen = 0;
SQInteger valtype = 0;
const SQChar *ts;
SQInteger ti;
SQFloat tf;
switch(format[n]) {
case 's':
if(SQ_FAILED(sq_getstring(v,nparam,&ts)))
return sq_throwerror(v,_SC("string expected for the specified format"));
addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar));
valtype = 's';
break;
case 'i': case 'd': case 'o': case 'u': case 'x': case 'X':
#ifdef _SQ64
{
size_t flen = scstrlen(fmt);
SQInteger fpos = flen - 1;
SQChar f = fmt[fpos];
SQChar *prec = (SQChar *)_PRINT_INT_PREC;
while(*prec != _SC('\0')) {
fmt[fpos++] = *prec++;
}
fmt[fpos++] = f;
fmt[fpos++] = _SC('\0');
}
{
size_t flen = scstrlen(fmt);
SQInteger fpos = flen - 1;
SQChar f = fmt[fpos];
const SQChar *prec = (const SQChar *)_PRINT_INT_PREC;
while(*prec != _SC('\0')) {
fmt[fpos++] = *prec++;
}
fmt[fpos++] = f;
fmt[fpos++] = _SC('\0');
}
#endif
case 'c':
if(SQ_FAILED(sq_getinteger(v,nparam,&ti)))
return sq_throwerror(v,_SC("integer expected for the specified format"));
addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
valtype = 'i';
break;
case 'f': case 'g': case 'G': case 'e': case 'E':
if(SQ_FAILED(sq_getfloat(v,nparam,&tf)))
return sq_throwerror(v,_SC("float expected for the specified format"));
addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
valtype = 'f';
break;
default:
return sq_throwerror(v,_SC("invalid format"));
}
n++;
allocated += addlen + sizeof(SQChar);
dest = sq_getscratchpad(v,allocated);
switch(valtype) {
case 's': i += scsprintf(&dest[i],allocated,fmt,ts); break;
case 'i': i += scsprintf(&dest[i],allocated,fmt,ti); break;
case 'f': i += scsprintf(&dest[i],allocated,fmt,tf); break;
};
nparam ++;
}
}
*outlen = i;
dest[i] = '\0';
*output = dest;
return SQ_OK;
case 'c':
if(SQ_FAILED(sq_getinteger(v,nparam,&ti)))
return sq_throwerror(v,_SC("integer expected for the specified format"));
addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
valtype = 'i';
break;
case 'f': case 'g': case 'G': case 'e': case 'E':
if(SQ_FAILED(sq_getfloat(v,nparam,&tf)))
return sq_throwerror(v,_SC("float expected for the specified format"));
addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
valtype = 'f';
break;
default:
return sq_throwerror(v,_SC("invalid format"));
}
n++;
allocated += addlen + sizeof(SQChar);
dest = sq_getscratchpad(v,allocated);
switch(valtype) {
case 's': i += scsprintf(&dest[i],allocated,fmt,ts); break;
case 'i': i += scsprintf(&dest[i],allocated,fmt,ti); break;
case 'f': i += scsprintf(&dest[i],allocated,fmt,tf); break;
};
nparam ++;
}
}
*outlen = i;
dest[i] = '\0';
*output = dest;
return SQ_OK;
}
static SQInteger _string_format(HSQUIRRELVM v)
{
SQChar *dest = NULL;
SQInteger length = 0;
if(SQ_FAILED(sqstd_format(v,2,&length,&dest)))
return -1;
sq_pushstring(v,dest,length);
return 1;
SQChar *dest = NULL;
SQInteger length = 0;
if(SQ_FAILED(sqstd_format(v,2,&length,&dest)))
return -1;
sq_pushstring(v,dest,length);
return 1;
}
static void __strip_l(const SQChar *str,const SQChar **start)
{
const SQChar *t = str;
while(((*t) != '\0') && scisspace(*t)){ t++; }
*start = t;
const SQChar *t = str;
while(((*t) != '\0') && scisspace(*t)){ t++; }
*start = t;
}
static void __strip_r(const SQChar *str,SQInteger len,const SQChar **end)
{
if(len == 0) {
*end = str;
return;
}
const SQChar *t = &str[len-1];
while(t >= str && scisspace(*t)) { t--; }
*end = t + 1;
if(len == 0) {
*end = str;
return;
}
const SQChar *t = &str[len-1];
while(t >= str && scisspace(*t)) { t--; }
*end = t + 1;
}
static SQInteger _string_strip(HSQUIRRELVM v)
{
const SQChar *str,*start,*end;
sq_getstring(v,2,&str);
SQInteger len = sq_getsize(v,2);
__strip_l(str,&start);
__strip_r(str,len,&end);
sq_pushstring(v,start,end - start);
return 1;
const SQChar *str,*start,*end;
sq_getstring(v,2,&str);
SQInteger len = sq_getsize(v,2);
__strip_l(str,&start);
__strip_r(str,len,&end);
sq_pushstring(v,start,end - start);
return 1;
}
static SQInteger _string_lstrip(HSQUIRRELVM v)
{
const SQChar *str,*start;
sq_getstring(v,2,&str);
__strip_l(str,&start);
sq_pushstring(v,start,-1);
return 1;
const SQChar *str,*start;
sq_getstring(v,2,&str);
__strip_l(str,&start);
sq_pushstring(v,start,-1);
return 1;
}
static SQInteger _string_rstrip(HSQUIRRELVM v)
{
const SQChar *str,*end;
sq_getstring(v,2,&str);
SQInteger len = sq_getsize(v,2);
__strip_r(str,len,&end);
sq_pushstring(v,str,end - str);
return 1;
const SQChar *str,*end;
sq_getstring(v,2,&str);
SQInteger len = sq_getsize(v,2);
__strip_r(str,len,&end);
sq_pushstring(v,str,end - str);
return 1;
}
static SQInteger _string_split(HSQUIRRELVM v)
{
const SQChar *str,*seps;
SQChar *stemp;
sq_getstring(v,2,&str);
sq_getstring(v,3,&seps);
SQInteger sepsize = sq_getsize(v,3);
if(sepsize == 0) return sq_throwerror(v,_SC("empty separators string"));
SQInteger memsize = (sq_getsize(v,2)+1)*sizeof(SQChar);
stemp = sq_getscratchpad(v,memsize);
memcpy(stemp,str,memsize);
SQChar *start = stemp;
SQChar *end = stemp;
sq_newarray(v,0);
while(*end != '\0')
{
SQChar cur = *end;
for(SQInteger i = 0; i < sepsize; i++)
{
if(cur == seps[i])
{
*end = 0;
sq_pushstring(v,start,-1);
sq_arrayappend(v,-2);
start = end + 1;
break;
}
}
end++;
}
if(end != start)
{
sq_pushstring(v,start,-1);
sq_arrayappend(v,-2);
}
return 1;
const SQChar *str,*seps;
SQChar *stemp;
sq_getstring(v,2,&str);
sq_getstring(v,3,&seps);
SQInteger sepsize = sq_getsize(v,3);
if(sepsize == 0) return sq_throwerror(v,_SC("empty separators string"));
SQInteger memsize = (sq_getsize(v,2)+1)*sizeof(SQChar);
stemp = sq_getscratchpad(v,memsize);
memcpy(stemp,str,memsize);
SQChar *start = stemp;
SQChar *end = stemp;
sq_newarray(v,0);
while(*end != '\0')
{
SQChar cur = *end;
for(SQInteger i = 0; i < sepsize; i++)
{
if(cur == seps[i])
{
*end = 0;
sq_pushstring(v,start,-1);
sq_arrayappend(v,-2);
start = end + 1;
break;
}
}
end++;
}
if(end != start)
{
sq_pushstring(v,start,-1);
sq_arrayappend(v,-2);
}
return 1;
}
static SQInteger _string_escape(HSQUIRRELVM v)
{
const SQChar *str;
SQChar *dest,*resstr;
SQInteger size;
sq_getstring(v,2,&str);
size = sq_getsize(v,2);
if(size == 0) {
sq_push(v,2);
return 1;
}
SQInteger destcharsize = (size * 6); //assumes every char could be escaped
resstr = dest = (SQChar *)sq_getscratchpad(v,destcharsize * sizeof(SQChar));
SQChar c;
SQChar escch;
SQInteger escaped = 0;
for(int n = 0; n < size; n++){
c = *str++;
escch = 0;
if(scisprint(c) || c == 0) {
switch(c) {
case '\a': escch = 'a'; break;
case '\b': escch = 'b'; break;
case '\t': escch = 't'; break;
case '\n': escch = 'n'; break;
case '\v': escch = 'v'; break;
case '\f': escch = 'f'; break;
case '\r': escch = 'r'; break;
case '\\': escch = '\\'; break;
case '\"': escch = '\"'; break;
case '\'': escch = '\''; break;
case 0: escch = '0'; break;
}
if(escch) {
*dest++ = '\\';
*dest++ = escch;
escaped++;
}
else {
*dest++ = c;
}
}
else {
dest += scsprintf(dest,destcharsize,_SC("\\x%x"),c);
escaped++;
}
}
const SQChar *str;
SQChar *dest,*resstr;
SQInteger size;
sq_getstring(v,2,&str);
size = sq_getsize(v,2);
if(size == 0) {
sq_push(v,2);
return 1;
}
SQInteger destcharsize = (size * 6); //assumes every char could be escaped
resstr = dest = (SQChar *)sq_getscratchpad(v,destcharsize * sizeof(SQChar));
SQChar c;
SQChar escch;
SQInteger escaped = 0;
for(int n = 0; n < size; n++){
c = *str++;
escch = 0;
if(scisprint(c) || c == 0) {
switch(c) {
case '\a': escch = 'a'; break;
case '\b': escch = 'b'; break;
case '\t': escch = 't'; break;
case '\n': escch = 'n'; break;
case '\v': escch = 'v'; break;
case '\f': escch = 'f'; break;
case '\r': escch = 'r'; break;
case '\\': escch = '\\'; break;
case '\"': escch = '\"'; break;
case '\'': escch = '\''; break;
case 0: escch = '0'; break;
}
if(escch) {
*dest++ = '\\';
*dest++ = escch;
escaped++;
}
else {
*dest++ = c;
}
}
else {
dest += scsprintf(dest,destcharsize,_SC("\\x%x"),c);
escaped++;
}
}
if(escaped) {
sq_pushstring(v,resstr,dest - resstr);
}
else {
sq_push(v,2); //nothing escaped
}
return 1;
if(escaped) {
sq_pushstring(v,resstr,dest - resstr);
}
else {
sq_push(v,2); //nothing escaped
}
return 1;
}
static SQInteger _string_startswith(HSQUIRRELVM v)
{
const SQChar *str,*cmp;
sq_getstring(v,2,&str);
sq_getstring(v,3,&cmp);
SQInteger len = sq_getsize(v,2);
SQInteger cmplen = sq_getsize(v,3);
SQBool ret = SQFalse;
if(cmplen <= len) {
ret = memcmp(str,cmp,sq_rsl(cmplen)) == 0 ? SQTrue : SQFalse;
}
sq_pushbool(v,ret);
return 1;
const SQChar *str,*cmp;
sq_getstring(v,2,&str);
sq_getstring(v,3,&cmp);
SQInteger len = sq_getsize(v,2);
SQInteger cmplen = sq_getsize(v,3);
SQBool ret = SQFalse;
if(cmplen <= len) {
ret = memcmp(str,cmp,sq_rsl(cmplen)) == 0 ? SQTrue : SQFalse;
}
sq_pushbool(v,ret);
return 1;
}
static SQInteger _string_endswith(HSQUIRRELVM v)
{
const SQChar *str,*cmp;
sq_getstring(v,2,&str);
sq_getstring(v,3,&cmp);
SQInteger len = sq_getsize(v,2);
SQInteger cmplen = sq_getsize(v,3);
SQBool ret = SQFalse;
if(cmplen <= len) {
ret = memcmp(&str[len - cmplen],cmp,sq_rsl(cmplen)) == 0 ? SQTrue : SQFalse;
}
sq_pushbool(v,ret);
return 1;
const SQChar *str,*cmp;
sq_getstring(v,2,&str);
sq_getstring(v,3,&cmp);
SQInteger len = sq_getsize(v,2);
SQInteger cmplen = sq_getsize(v,3);
SQBool ret = SQFalse;
if(cmplen <= len) {
ret = memcmp(&str[len - cmplen],cmp,sq_rsl(cmplen)) == 0 ? SQTrue : SQFalse;
}
sq_pushbool(v,ret);
return 1;
}
#define SETUP_REX(v) \
SQRex *self = NULL; \
sq_getinstanceup(v,1,(SQUserPointer *)&self,0);
SQRex *self = NULL; \
sq_getinstanceup(v,1,(SQUserPointer *)&self,0);
static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger size)
{
SQRex *self = ((SQRex *)p);
sqstd_rex_free(self);
return 1;
SQRex *self = ((SQRex *)p);
sqstd_rex_free(self);
return 1;
}
static SQInteger _regexp_match(HSQUIRRELVM v)
{
SETUP_REX(v);
const SQChar *str;
sq_getstring(v,2,&str);
if(sqstd_rex_match(self,str) == SQTrue)
{
sq_pushbool(v,SQTrue);
return 1;
}
sq_pushbool(v,SQFalse);
return 1;
SETUP_REX(v);
const SQChar *str;
sq_getstring(v,2,&str);
if(sqstd_rex_match(self,str) == SQTrue)
{
sq_pushbool(v,SQTrue);
return 1;
}
sq_pushbool(v,SQFalse);
return 1;
}
static void _addrexmatch(HSQUIRRELVM v,const SQChar *str,const SQChar *begin,const SQChar *end)
{
sq_newtable(v);
sq_pushstring(v,_SC("begin"),-1);
sq_pushinteger(v,begin - str);
sq_rawset(v,-3);
sq_pushstring(v,_SC("end"),-1);
sq_pushinteger(v,end - str);
sq_rawset(v,-3);
sq_newtable(v);
sq_pushstring(v,_SC("begin"),-1);
sq_pushinteger(v,begin - str);
sq_rawset(v,-3);
sq_pushstring(v,_SC("end"),-1);
sq_pushinteger(v,end - str);
sq_rawset(v,-3);
}
static SQInteger _regexp_search(HSQUIRRELVM v)
{
SETUP_REX(v);
const SQChar *str,*begin,*end;
SQInteger start = 0;
sq_getstring(v,2,&str);
if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
_addrexmatch(v,str,begin,end);
return 1;
}
return 0;
SETUP_REX(v);
const SQChar *str,*begin,*end;
SQInteger start = 0;
sq_getstring(v,2,&str);
if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
_addrexmatch(v,str,begin,end);
return 1;
}
return 0;
}
static SQInteger _regexp_capture(HSQUIRRELVM v)
{
SETUP_REX(v);
const SQChar *str,*begin,*end;
SQInteger start = 0;
sq_getstring(v,2,&str);
if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
SQInteger n = sqstd_rex_getsubexpcount(self);
SQRexMatch match;
sq_newarray(v,0);
for(SQInteger i = 0;i < n; i++) {
sqstd_rex_getsubexp(self,i,&match);
if(match.len > 0)
_addrexmatch(v,str,match.begin,match.begin+match.len);
else
_addrexmatch(v,str,str,str); //empty match
sq_arrayappend(v,-2);
}
return 1;
}
return 0;
SETUP_REX(v);
const SQChar *str,*begin,*end;
SQInteger start = 0;
sq_getstring(v,2,&str);
if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
SQInteger n = sqstd_rex_getsubexpcount(self);
SQRexMatch match;
sq_newarray(v,0);
for(SQInteger i = 0;i < n; i++) {
sqstd_rex_getsubexp(self,i,&match);
if(match.len > 0)
_addrexmatch(v,str,match.begin,match.begin+match.len);
else
_addrexmatch(v,str,str,str); //empty match
sq_arrayappend(v,-2);
}
return 1;
}
return 0;
}
static SQInteger _regexp_subexpcount(HSQUIRRELVM v)
{
SETUP_REX(v);
sq_pushinteger(v,sqstd_rex_getsubexpcount(self));
return 1;
SETUP_REX(v);
sq_pushinteger(v,sqstd_rex_getsubexpcount(self));
return 1;
}
static SQInteger _regexp_constructor(HSQUIRRELVM v)
{
const SQChar *error,*pattern;
sq_getstring(v,2,&pattern);
SQRex *rex = sqstd_rex_compile(pattern,&error);
if(!rex) return sq_throwerror(v,error);
sq_setinstanceup(v,1,rex);
sq_setreleasehook(v,1,_rexobj_releasehook);
return 0;
const SQChar *error,*pattern;
sq_getstring(v,2,&pattern);
SQRex *rex = sqstd_rex_compile(pattern,&error);
if(!rex) return sq_throwerror(v,error);
sq_setinstanceup(v,1,rex);
sq_setreleasehook(v,1,_rexobj_releasehook);
return 0;
}
static SQInteger _regexp__typeof(HSQUIRRELVM v)
{
sq_pushstring(v,_SC("regexp"),-1);
return 1;
sq_pushstring(v,_SC("regexp"),-1);
return 1;
}
#define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask}
static SQRegFunction rexobj_funcs[]={
_DECL_REX_FUNC(constructor,2,_SC(".s")),
_DECL_REX_FUNC(search,-2,_SC("xsn")),
_DECL_REX_FUNC(match,2,_SC("xs")),
_DECL_REX_FUNC(capture,-2,_SC("xsn")),
_DECL_REX_FUNC(subexpcount,1,_SC("x")),
_DECL_REX_FUNC(_typeof,1,_SC("x")),
{0,0}
static const SQRegFunction rexobj_funcs[]={
_DECL_REX_FUNC(constructor,2,_SC(".s")),
_DECL_REX_FUNC(search,-2,_SC("xsn")),
_DECL_REX_FUNC(match,2,_SC("xs")),
_DECL_REX_FUNC(capture,-2,_SC("xsn")),
_DECL_REX_FUNC(subexpcount,1,_SC("x")),
_DECL_REX_FUNC(_typeof,1,_SC("x")),
{0,0}
};
#undef _DECL_REX_FUNC
#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask}
static SQRegFunction stringlib_funcs[]={
_DECL_FUNC(format,-2,_SC(".s")),
_DECL_FUNC(strip,2,_SC(".s")),
_DECL_FUNC(lstrip,2,_SC(".s")),
_DECL_FUNC(rstrip,2,_SC(".s")),
_DECL_FUNC(split,3,_SC(".ss")),
_DECL_FUNC(escape,2,_SC(".s")),
_DECL_FUNC(startswith,3,_SC(".ss")),
_DECL_FUNC(endswith,3,_SC(".ss")),
{0,0}
static const SQRegFunction stringlib_funcs[]={
_DECL_FUNC(format,-2,_SC(".s")),
_DECL_FUNC(strip,2,_SC(".s")),
_DECL_FUNC(lstrip,2,_SC(".s")),
_DECL_FUNC(rstrip,2,_SC(".s")),
_DECL_FUNC(split,3,_SC(".ss")),
_DECL_FUNC(escape,2,_SC(".s")),
_DECL_FUNC(startswith,3,_SC(".ss")),
_DECL_FUNC(endswith,3,_SC(".ss")),
{0,0}
};
#undef _DECL_FUNC
SQInteger sqstd_register_stringlib(HSQUIRRELVM v)
{
sq_pushstring(v,_SC("regexp"),-1);
sq_newclass(v,SQFalse);
SQInteger i = 0;
while(rexobj_funcs[i].name != 0) {
SQRegFunction &f = rexobj_funcs[i];
sq_pushstring(v,f.name,-1);
sq_newclosure(v,f.f,0);
sq_setparamscheck(v,f.nparamscheck,f.typemask);
sq_setnativeclosurename(v,-1,f.name);
sq_newslot(v,-3,SQFalse);
i++;
}
sq_newslot(v,-3,SQFalse);
sq_pushstring(v,_SC("regexp"),-1);
sq_newclass(v,SQFalse);
SQInteger i = 0;
while(rexobj_funcs[i].name != 0) {
const SQRegFunction &f = rexobj_funcs[i];
sq_pushstring(v,f.name,-1);
sq_newclosure(v,f.f,0);
sq_setparamscheck(v,f.nparamscheck,f.typemask);
sq_setnativeclosurename(v,-1,f.name);
sq_newslot(v,-3,SQFalse);
i++;
}
sq_newslot(v,-3,SQFalse);
i = 0;
while(stringlib_funcs[i].name!=0)
{
sq_pushstring(v,stringlib_funcs[i].name,-1);
sq_newclosure(v,stringlib_funcs[i].f,0);
sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask);
sq_setnativeclosurename(v,-1,stringlib_funcs[i].name);
sq_newslot(v,-3,SQFalse);
i++;
}
return 1;
i = 0;
while(stringlib_funcs[i].name!=0)
{
sq_pushstring(v,stringlib_funcs[i].name,-1);
sq_newclosure(v,stringlib_funcs[i].f,0);
sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask);
sq_setnativeclosurename(v,-1,stringlib_funcs[i].name);
sq_newslot(v,-3,SQFalse);
i++;
}
return 1;
}

View File

@ -22,89 +22,89 @@
static SQInteger _system_getenv(HSQUIRRELVM v)
{
const SQChar *s;
if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
const SQChar *s;
if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
sq_pushstring(v,scgetenv(s),-1);
return 1;
}
return 0;
return 1;
}
return 0;
}
static SQInteger _system_system(HSQUIRRELVM v)
{
const SQChar *s;
if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
sq_pushinteger(v,scsystem(s));
return 1;
}
return sq_throwerror(v,_SC("wrong param"));
const SQChar *s;
if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
sq_pushinteger(v,scsystem(s));
return 1;
}
return sq_throwerror(v,_SC("wrong param"));
}
static SQInteger _system_clock(HSQUIRRELVM v)
{
sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC);
return 1;
sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC);
return 1;
}
static SQInteger _system_time(HSQUIRRELVM v)
{
SQInteger t = (SQInteger)time(NULL);
sq_pushinteger(v,t);
return 1;
SQInteger t = (SQInteger)time(NULL);
sq_pushinteger(v,t);
return 1;
}
static SQInteger _system_remove(HSQUIRRELVM v)
{
const SQChar *s;
sq_getstring(v,2,&s);
if(scremove(s)==-1)
return sq_throwerror(v,_SC("remove() failed"));
return 0;
const SQChar *s;
sq_getstring(v,2,&s);
if(scremove(s)==-1)
return sq_throwerror(v,_SC("remove() failed"));
return 0;
}
static SQInteger _system_rename(HSQUIRRELVM v)
{
const SQChar *oldn,*newn;
sq_getstring(v,2,&oldn);
sq_getstring(v,3,&newn);
if(screname(oldn,newn)==-1)
return sq_throwerror(v,_SC("rename() failed"));
return 0;
const SQChar *oldn,*newn;
sq_getstring(v,2,&oldn);
sq_getstring(v,3,&newn);
if(screname(oldn,newn)==-1)
return sq_throwerror(v,_SC("rename() failed"));
return 0;
}
static void _set_integer_slot(HSQUIRRELVM v,const SQChar *name,SQInteger val)
{
sq_pushstring(v,name,-1);
sq_pushinteger(v,val);
sq_rawset(v,-3);
sq_pushstring(v,name,-1);
sq_pushinteger(v,val);
sq_rawset(v,-3);
}
static SQInteger _system_date(HSQUIRRELVM v)
{
time_t t;
SQInteger it;
SQInteger format = 'l';
if(sq_gettop(v) > 1) {
sq_getinteger(v,2,&it);
t = it;
if(sq_gettop(v) > 2) {
sq_getinteger(v,3,(SQInteger*)&format);
}
}
else {
time(&t);
}
tm *date;
time_t t;
SQInteger it;
SQInteger format = 'l';
if(sq_gettop(v) > 1) {
sq_getinteger(v,2,&it);
t = it;
if(sq_gettop(v) > 2) {
sq_getinteger(v,3,(SQInteger*)&format);
}
}
else {
time(&t);
}
tm *date;
if(format == 'u')
date = gmtime(&t);
else
date = localtime(&t);
if(!date)
return sq_throwerror(v,_SC("crt api failure"));
sq_newtable(v);
_set_integer_slot(v, _SC("sec"), date->tm_sec);
date = gmtime(&t);
else
date = localtime(&t);
if(!date)
return sq_throwerror(v,_SC("crt api failure"));
sq_newtable(v);
_set_integer_slot(v, _SC("sec"), date->tm_sec);
_set_integer_slot(v, _SC("min"), date->tm_min);
_set_integer_slot(v, _SC("hour"), date->tm_hour);
_set_integer_slot(v, _SC("day"), date->tm_mday);
@ -112,35 +112,35 @@ static SQInteger _system_date(HSQUIRRELVM v)
_set_integer_slot(v, _SC("year"), date->tm_year+1900);
_set_integer_slot(v, _SC("wday"), date->tm_wday);
_set_integer_slot(v, _SC("yday"), date->tm_yday);
return 1;
return 1;
}
#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask}
static SQRegFunction systemlib_funcs[]={
_DECL_FUNC(getenv,2,_SC(".s")),
_DECL_FUNC(system,2,_SC(".s")),
_DECL_FUNC(clock,0,NULL),
_DECL_FUNC(time,1,NULL),
_DECL_FUNC(date,-1,_SC(".nn")),
_DECL_FUNC(remove,2,_SC(".s")),
_DECL_FUNC(rename,3,_SC(".ss")),
{0,0}
static const SQRegFunction systemlib_funcs[]={
_DECL_FUNC(getenv,2,_SC(".s")),
_DECL_FUNC(system,2,_SC(".s")),
_DECL_FUNC(clock,0,NULL),
_DECL_FUNC(time,1,NULL),
_DECL_FUNC(date,-1,_SC(".nn")),
_DECL_FUNC(remove,2,_SC(".s")),
_DECL_FUNC(rename,3,_SC(".ss")),
{0,0}
};
#undef _DECL_FUNC
SQInteger sqstd_register_systemlib(HSQUIRRELVM v)
{
SQInteger i=0;
while(systemlib_funcs[i].name!=0)
{
sq_pushstring(v,systemlib_funcs[i].name,-1);
sq_newclosure(v,systemlib_funcs[i].f,0);
sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask);
sq_setnativeclosurename(v,-1,systemlib_funcs[i].name);
sq_newslot(v,-3,SQFalse);
i++;
}
return 1;
SQInteger i=0;
while(systemlib_funcs[i].name!=0)
{
sq_pushstring(v,systemlib_funcs[i].name,-1);
sq_newclosure(v,systemlib_funcs[i].f,0);
sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask);
sq_setnativeclosurename(v,-1,systemlib_funcs[i].name);
sq_newslot(v,-3,SQFalse);
i++;
}
return 1;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,94 +1,94 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQARRAY_H_
#define _SQARRAY_H_
struct SQArray : public CHAINABLE_OBJ
{
private:
SQArray(SQSharedState *ss,SQInteger nsize){_values.resize(nsize); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
~SQArray()
{
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
}
SQArray(SQSharedState *ss,SQInteger nsize){_values.resize(nsize); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
~SQArray()
{
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
}
public:
static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){
SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray));
new (newarray) SQArray(ss,nInitialSize);
return newarray;
}
static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){
SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray));
new (newarray) SQArray(ss,nInitialSize);
return newarray;
}
#ifndef NO_GARBAGE_COLLECTOR
void Mark(SQCollectable **chain);
SQObjectType GetType() {return OT_ARRAY;}
void Mark(SQCollectable **chain);
SQObjectType GetType() {return OT_ARRAY;}
#endif
void Finalize(){
_values.resize(0);
}
bool Get(const SQInteger nidx,SQObjectPtr &val)
{
if(nidx>=0 && nidx<(SQInteger)_values.size()){
SQObjectPtr &o = _values[nidx];
val = _realval(o);
return true;
}
else return false;
}
bool Set(const SQInteger nidx,const SQObjectPtr &val)
{
if(nidx>=0 && nidx<(SQInteger)_values.size()){
_values[nidx]=val;
return true;
}
else return false;
}
SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval)
{
SQUnsignedInteger idx=TranslateIndex(refpos);
while(idx<_values.size()){
//first found
outkey=(SQInteger)idx;
SQObjectPtr &o = _values[idx];
outval = _realval(o);
//return idx for the next iteration
return ++idx;
}
//nothing to iterate anymore
return -1;
}
SQArray *Clone(){SQArray *anew=Create(_opt_ss(this),0); anew->_values.copy(_values); return anew; }
SQInteger Size() const {return _values.size();}
void Resize(SQInteger size)
{
SQObjectPtr _null;
Resize(size,_null);
}
void Resize(SQInteger size,SQObjectPtr &fill) { _values.resize(size,fill); ShrinkIfNeeded(); }
void Reserve(SQInteger size) { _values.reserve(size); }
void Append(const SQObject &o){_values.push_back(o);}
void Extend(const SQArray *a);
SQObjectPtr &Top(){return _values.top();}
void Pop(){_values.pop_back(); ShrinkIfNeeded(); }
bool Insert(SQInteger idx,const SQObject &val){
if(idx < 0 || idx > (SQInteger)_values.size())
return false;
_values.insert(idx,val);
return true;
}
void ShrinkIfNeeded() {
if(_values.size() <= _values.capacity()>>2) //shrink the array
_values.shrinktofit();
}
bool Remove(SQInteger idx){
if(idx < 0 || idx >= (SQInteger)_values.size())
return false;
_values.remove(idx);
ShrinkIfNeeded();
return true;
}
void Release()
{
sq_delete(this,SQArray);
}
void Finalize(){
_values.resize(0);
}
bool Get(const SQInteger nidx,SQObjectPtr &val)
{
if(nidx>=0 && nidx<(SQInteger)_values.size()){
SQObjectPtr &o = _values[nidx];
val = _realval(o);
return true;
}
else return false;
}
bool Set(const SQInteger nidx,const SQObjectPtr &val)
{
if(nidx>=0 && nidx<(SQInteger)_values.size()){
_values[nidx]=val;
return true;
}
else return false;
}
SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval)
{
SQUnsignedInteger idx=TranslateIndex(refpos);
while(idx<_values.size()){
//first found
outkey=(SQInteger)idx;
SQObjectPtr &o = _values[idx];
outval = _realval(o);
//return idx for the next iteration
return ++idx;
}
//nothing to iterate anymore
return -1;
}
SQArray *Clone(){SQArray *anew=Create(_opt_ss(this),0); anew->_values.copy(_values); return anew; }
SQInteger Size() const {return _values.size();}
void Resize(SQInteger size)
{
SQObjectPtr _null;
Resize(size,_null);
}
void Resize(SQInteger size,SQObjectPtr &fill) { _values.resize(size,fill); ShrinkIfNeeded(); }
void Reserve(SQInteger size) { _values.reserve(size); }
void Append(const SQObject &o){_values.push_back(o);}
void Extend(const SQArray *a);
SQObjectPtr &Top(){return _values.top();}
void Pop(){_values.pop_back(); ShrinkIfNeeded(); }
bool Insert(SQInteger idx,const SQObject &val){
if(idx < 0 || idx > (SQInteger)_values.size())
return false;
_values.insert(idx,val);
return true;
}
void ShrinkIfNeeded() {
if(_values.size() <= _values.capacity()>>2) //shrink the array
_values.shrinktofit();
}
bool Remove(SQInteger idx){
if(idx < 0 || idx >= (SQInteger)_values.size())
return false;
_values.remove(idx);
ShrinkIfNeeded();
return true;
}
void Release()
{
sq_delete(this,SQArray);
}
SQObjectPtrVec _values;
SQObjectPtrVec _values;
};
#endif //_SQARRAY_H_

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
see copyright notice in squirrel.h
see copyright notice in squirrel.h
*/
#include "sqpcheader.h"
#include "sqvm.h"
@ -12,199 +12,199 @@
SQClass::SQClass(SQSharedState *ss,SQClass *base)
{
_base = base;
_typetag = 0;
_hook = NULL;
_udsize = 0;
_locked = false;
_constructoridx = -1;
if(_base) {
_constructoridx = _base->_constructoridx;
_udsize = _base->_udsize;
_defaultvalues.copy(base->_defaultvalues);
_methods.copy(base->_methods);
_COPY_VECTOR(_metamethods,base->_metamethods,MT_LAST);
__ObjAddRef(_base);
}
_members = base?base->_members->Clone() : SQTable::Create(ss,0);
__ObjAddRef(_members);
_base = base;
_typetag = 0;
_hook = NULL;
_udsize = 0;
_locked = false;
_constructoridx = -1;
if(_base) {
_constructoridx = _base->_constructoridx;
_udsize = _base->_udsize;
_defaultvalues.copy(base->_defaultvalues);
_methods.copy(base->_methods);
_COPY_VECTOR(_metamethods,base->_metamethods,MT_LAST);
__ObjAddRef(_base);
}
_members = base?base->_members->Clone() : SQTable::Create(ss,0);
__ObjAddRef(_members);
INIT_CHAIN();
ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
INIT_CHAIN();
ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
}
void SQClass::Finalize() {
_attributes.Null();
_NULL_SQOBJECT_VECTOR(_defaultvalues,_defaultvalues.size());
_methods.resize(0);
_NULL_SQOBJECT_VECTOR(_metamethods,MT_LAST);
__ObjRelease(_members);
if(_base) {
__ObjRelease(_base);
}
_attributes.Null();
_NULL_SQOBJECT_VECTOR(_defaultvalues,_defaultvalues.size());
_methods.resize(0);
_NULL_SQOBJECT_VECTOR(_metamethods,MT_LAST);
__ObjRelease(_members);
if(_base) {
__ObjRelease(_base);
}
}
SQClass::~SQClass()
{
REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
Finalize();
REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
Finalize();
}
bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic)
{
SQObjectPtr temp;
bool belongs_to_static_table = type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE || bstatic;
if(_locked && !belongs_to_static_table)
return false; //the class already has an instance so cannot be modified
if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value
{
_defaultvalues[_member_idx(temp)].val = val;
return true;
}
if(belongs_to_static_table) {
SQInteger mmidx;
if((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) &&
(mmidx = ss->GetMetaMethodIdxByName(key)) != -1) {
_metamethods[mmidx] = val;
}
else {
SQObjectPtr theval = val;
if(_base && type(val) == OT_CLOSURE) {
theval = _closure(val)->Clone();
_closure(theval)->_base = _base;
__ObjAddRef(_base); //ref for the closure
}
if(type(temp) == OT_NULL) {
bool isconstructor;
SQVM::IsEqual(ss->_constructoridx, key, isconstructor);
if(isconstructor) {
_constructoridx = (SQInteger)_methods.size();
}
SQClassMember m;
m.val = theval;
_members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size())));
_methods.push_back(m);
}
else {
_methods[_member_idx(temp)].val = theval;
}
}
return true;
}
SQClassMember m;
m.val = val;
_members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size())));
_defaultvalues.push_back(m);
return true;
SQObjectPtr temp;
bool belongs_to_static_table = type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE || bstatic;
if(_locked && !belongs_to_static_table)
return false; //the class already has an instance so cannot be modified
if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value
{
_defaultvalues[_member_idx(temp)].val = val;
return true;
}
if(belongs_to_static_table) {
SQInteger mmidx;
if((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) &&
(mmidx = ss->GetMetaMethodIdxByName(key)) != -1) {
_metamethods[mmidx] = val;
}
else {
SQObjectPtr theval = val;
if(_base && type(val) == OT_CLOSURE) {
theval = _closure(val)->Clone();
_closure(theval)->_base = _base;
__ObjAddRef(_base); //ref for the closure
}
if(type(temp) == OT_NULL) {
bool isconstructor;
SQVM::IsEqual(ss->_constructoridx, key, isconstructor);
if(isconstructor) {
_constructoridx = (SQInteger)_methods.size();
}
SQClassMember m;
m.val = theval;
_members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size())));
_methods.push_back(m);
}
else {
_methods[_member_idx(temp)].val = theval;
}
}
return true;
}
SQClassMember m;
m.val = val;
_members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size())));
_defaultvalues.push_back(m);
return true;
}
SQInstance *SQClass::CreateInstance()
{
if(!_locked) Lock();
return SQInstance::Create(_opt_ss(this),this);
if(!_locked) Lock();
return SQInstance::Create(_opt_ss(this),this);
}
SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
{
SQObjectPtr oval;
SQInteger idx = _members->Next(false,refpos,outkey,oval);
if(idx != -1) {
if(_ismethod(oval)) {
outval = _methods[_member_idx(oval)].val;
}
else {
SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val;
outval = _realval(o);
}
}
return idx;
SQObjectPtr oval;
SQInteger idx = _members->Next(false,refpos,outkey,oval);
if(idx != -1) {
if(_ismethod(oval)) {
outval = _methods[_member_idx(oval)].val;
}
else {
SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val;
outval = _realval(o);
}
}
return idx;
}
bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val)
{
SQObjectPtr idx;
if(_members->Get(key,idx)) {
if(_isfield(idx))
_defaultvalues[_member_idx(idx)].attrs = val;
else
_methods[_member_idx(idx)].attrs = val;
return true;
}
return false;
SQObjectPtr idx;
if(_members->Get(key,idx)) {
if(_isfield(idx))
_defaultvalues[_member_idx(idx)].attrs = val;
else
_methods[_member_idx(idx)].attrs = val;
return true;
}
return false;
}
bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval)
{
SQObjectPtr idx;
if(_members->Get(key,idx)) {
outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs);
return true;
}
return false;
SQObjectPtr idx;
if(_members->Get(key,idx)) {
outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs);
return true;
}
return false;
}
///////////////////////////////////////////////////////////////////////
void SQInstance::Init(SQSharedState *ss)
{
_userpointer = NULL;
_hook = NULL;
__ObjAddRef(_class);
_delegate = _class->_members;
INIT_CHAIN();
ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
_userpointer = NULL;
_hook = NULL;
__ObjAddRef(_class);
_delegate = _class->_members;
INIT_CHAIN();
ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
}
SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize)
{
_memsize = memsize;
_class = c;
SQUnsignedInteger nvalues = _class->_defaultvalues.size();
for(SQUnsignedInteger n = 0; n < nvalues; n++) {
new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val);
}
Init(ss);
_memsize = memsize;
_class = c;
SQUnsignedInteger nvalues = _class->_defaultvalues.size();
for(SQUnsignedInteger n = 0; n < nvalues; n++) {
new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val);
}
Init(ss);
}
SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize)
{
_memsize = memsize;
_class = i->_class;
SQUnsignedInteger nvalues = _class->_defaultvalues.size();
for(SQUnsignedInteger n = 0; n < nvalues; n++) {
new (&_values[n]) SQObjectPtr(i->_values[n]);
}
Init(ss);
_memsize = memsize;
_class = i->_class;
SQUnsignedInteger nvalues = _class->_defaultvalues.size();
for(SQUnsignedInteger n = 0; n < nvalues; n++) {
new (&_values[n]) SQObjectPtr(i->_values[n]);
}
Init(ss);
}
void SQInstance::Finalize()
{
SQUnsignedInteger nvalues = _class->_defaultvalues.size();
__ObjRelease(_class);
_NULL_SQOBJECT_VECTOR(_values,nvalues);
SQUnsignedInteger nvalues = _class->_defaultvalues.size();
__ObjRelease(_class);
_NULL_SQOBJECT_VECTOR(_values,nvalues);
}
SQInstance::~SQInstance()
{
REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
if(_class){ Finalize(); } //if _class is null it was already finalized by the GC
REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
if(_class){ Finalize(); } //if _class is null it was already finalized by the GC
}
bool SQInstance::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res)
{
if(type(_class->_metamethods[mm]) != OT_NULL) {
res = _class->_metamethods[mm];
return true;
}
return false;
if(type(_class->_metamethods[mm]) != OT_NULL) {
res = _class->_metamethods[mm];
return true;
}
return false;
}
bool SQInstance::InstanceOf(SQClass *trg)
{
SQClass *parent = _class;
while(parent != NULL) {
if(parent == trg)
return true;
parent = parent->_base;
}
return false;
SQClass *parent = _class;
while(parent != NULL) {
if(parent == trg)
return true;
parent = parent->_base;
}
return false;
}

View File

@ -1,16 +1,16 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQCLASS_H_
#define _SQCLASS_H_
struct SQInstance;
struct SQClassMember {
SQObjectPtr val;
SQObjectPtr attrs;
void Null() {
val.Null();
attrs.Null();
}
SQObjectPtr val;
SQObjectPtr attrs;
void Null() {
val.Null();
attrs.Null();
}
};
typedef sqvector<SQClassMember> SQClassMemberVec;
@ -27,136 +27,136 @@ typedef sqvector<SQClassMember> SQClassMemberVec;
struct SQClass : public CHAINABLE_OBJ
{
SQClass(SQSharedState *ss,SQClass *base);
SQClass(SQSharedState *ss,SQClass *base);
public:
static SQClass* Create(SQSharedState *ss,SQClass *base) {
SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass));
new (newclass) SQClass(ss, base);
return newclass;
}
~SQClass();
bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic);
bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
if(_members->Get(key,val)) {
if(_isfield(val)) {
SQObjectPtr &o = _defaultvalues[_member_idx(val)].val;
val = _realval(o);
}
else {
val = _methods[_member_idx(val)].val;
}
return true;
}
return false;
}
bool GetConstructor(SQObjectPtr &ctor)
{
if(_constructoridx != -1) {
ctor = _methods[_constructoridx].val;
return true;
}
return false;
}
bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val);
bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval);
void Lock() { _locked = true; if(_base) _base->Lock(); }
void Release() {
if (_hook) { _hook(_typetag,0);}
sq_delete(this, SQClass);
}
void Finalize();
static SQClass* Create(SQSharedState *ss,SQClass *base) {
SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass));
new (newclass) SQClass(ss, base);
return newclass;
}
~SQClass();
bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic);
bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
if(_members->Get(key,val)) {
if(_isfield(val)) {
SQObjectPtr &o = _defaultvalues[_member_idx(val)].val;
val = _realval(o);
}
else {
val = _methods[_member_idx(val)].val;
}
return true;
}
return false;
}
bool GetConstructor(SQObjectPtr &ctor)
{
if(_constructoridx != -1) {
ctor = _methods[_constructoridx].val;
return true;
}
return false;
}
bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val);
bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval);
void Lock() { _locked = true; if(_base) _base->Lock(); }
void Release() {
if (_hook) { _hook(_typetag,0);}
sq_delete(this, SQClass);
}
void Finalize();
#ifndef NO_GARBAGE_COLLECTOR
void Mark(SQCollectable ** );
SQObjectType GetType() {return OT_CLASS;}
void Mark(SQCollectable ** );
SQObjectType GetType() {return OT_CLASS;}
#endif
SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
SQInstance *CreateInstance();
SQTable *_members;
SQClass *_base;
SQClassMemberVec _defaultvalues;
SQClassMemberVec _methods;
SQObjectPtr _metamethods[MT_LAST];
SQObjectPtr _attributes;
SQUserPointer _typetag;
SQRELEASEHOOK _hook;
bool _locked;
SQInteger _constructoridx;
SQInteger _udsize;
SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
SQInstance *CreateInstance();
SQTable *_members;
SQClass *_base;
SQClassMemberVec _defaultvalues;
SQClassMemberVec _methods;
SQObjectPtr _metamethods[MT_LAST];
SQObjectPtr _attributes;
SQUserPointer _typetag;
SQRELEASEHOOK _hook;
bool _locked;
SQInteger _constructoridx;
SQInteger _udsize;
};
#define calcinstancesize(_theclass_) \
(_theclass_->_udsize + sq_aligning(sizeof(SQInstance) + (sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0))))
(_theclass_->_udsize + sq_aligning(sizeof(SQInstance) + (sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0))))
struct SQInstance : public SQDelegable
{
void Init(SQSharedState *ss);
SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize);
SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize);
void Init(SQSharedState *ss);
SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize);
SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize);
public:
static SQInstance* Create(SQSharedState *ss,SQClass *theclass) {
static SQInstance* Create(SQSharedState *ss,SQClass *theclass) {
SQInteger size = calcinstancesize(theclass);
SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
new (newinst) SQInstance(ss, theclass,size);
if(theclass->_udsize) {
newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize);
}
return newinst;
}
SQInstance *Clone(SQSharedState *ss)
{
SQInteger size = calcinstancesize(_class);
SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
new (newinst) SQInstance(ss, this,size);
if(_class->_udsize) {
newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize);
}
return newinst;
}
~SQInstance();
bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
if(_class->_members->Get(key,val)) {
if(_isfield(val)) {
SQObjectPtr &o = _values[_member_idx(val)];
val = _realval(o);
}
else {
val = _class->_methods[_member_idx(val)].val;
}
return true;
}
return false;
}
bool Set(const SQObjectPtr &key,const SQObjectPtr &val) {
SQObjectPtr idx;
if(_class->_members->Get(key,idx) && _isfield(idx)) {
SQInteger size = calcinstancesize(theclass);
SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
new (newinst) SQInstance(ss, theclass,size);
if(theclass->_udsize) {
newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize);
}
return newinst;
}
SQInstance *Clone(SQSharedState *ss)
{
SQInteger size = calcinstancesize(_class);
SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
new (newinst) SQInstance(ss, this,size);
if(_class->_udsize) {
newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize);
}
return newinst;
}
~SQInstance();
bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
if(_class->_members->Get(key,val)) {
if(_isfield(val)) {
SQObjectPtr &o = _values[_member_idx(val)];
val = _realval(o);
}
else {
val = _class->_methods[_member_idx(val)].val;
}
return true;
}
return false;
}
bool Set(const SQObjectPtr &key,const SQObjectPtr &val) {
SQObjectPtr idx;
if(_class->_members->Get(key,idx) && _isfield(idx)) {
_values[_member_idx(idx)] = val;
return true;
}
return false;
}
void Release() {
_uiRef++;
if (_hook) { _hook(_userpointer,0);}
_uiRef--;
if(_uiRef > 0) return;
SQInteger size = _memsize;
this->~SQInstance();
SQ_FREE(this, size);
}
void Finalize();
return true;
}
return false;
}
void Release() {
_uiRef++;
if (_hook) { _hook(_userpointer,0);}
_uiRef--;
if(_uiRef > 0) return;
SQInteger size = _memsize;
this->~SQInstance();
SQ_FREE(this, size);
}
void Finalize();
#ifndef NO_GARBAGE_COLLECTOR
void Mark(SQCollectable ** );
SQObjectType GetType() {return OT_INSTANCE;}
void Mark(SQCollectable ** );
SQObjectType GetType() {return OT_INSTANCE;}
#endif
bool InstanceOf(SQClass *trg);
bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
bool InstanceOf(SQClass *trg);
bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
SQClass *_class;
SQUserPointer _userpointer;
SQRELEASEHOOK _hook;
SQInteger _memsize;
SQObjectPtr _values[1];
SQClass *_class;
SQUserPointer _userpointer;
SQRELEASEHOOK _hook;
SQInteger _memsize;
SQObjectPtr _values[1];
};
#endif //_SQCLASS_H_

View File

@ -1,4 +1,4 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQCLOSURE_H_
#define _SQCLOSURE_H_
@ -10,64 +10,64 @@ struct SQClass;
struct SQClosure : public CHAINABLE_OBJ
{
private:
SQClosure(SQSharedState *ss,SQFunctionProto *func){_function = func; __ObjAddRef(_function); _base = NULL; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL; _root=NULL;}
SQClosure(SQSharedState *ss,SQFunctionProto *func){_function = func; __ObjAddRef(_function); _base = NULL; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL; _root=NULL;}
public:
static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func,SQWeakRef *root){
SQInteger size = _CALC_CLOSURE_SIZE(func);
SQClosure *nc=(SQClosure*)SQ_MALLOC(size);
new (nc) SQClosure(ss,func);
nc->_outervalues = (SQObjectPtr *)(nc + 1);
nc->_defaultparams = &nc->_outervalues[func->_noutervalues];
nc->_root = root;
__ObjAddRef(nc->_root);
_CONSTRUCT_VECTOR(SQObjectPtr,func->_noutervalues,nc->_outervalues);
_CONSTRUCT_VECTOR(SQObjectPtr,func->_ndefaultparams,nc->_defaultparams);
return nc;
}
void Release(){
SQFunctionProto *f = _function;
SQInteger size = _CALC_CLOSURE_SIZE(f);
_DESTRUCT_VECTOR(SQObjectPtr,f->_noutervalues,_outervalues);
_DESTRUCT_VECTOR(SQObjectPtr,f->_ndefaultparams,_defaultparams);
__ObjRelease(_function);
this->~SQClosure();
sq_vm_free(this,size);
}
void SetRoot(SQWeakRef *r)
{
__ObjRelease(_root);
_root = r;
__ObjAddRef(_root);
}
SQClosure *Clone()
{
SQFunctionProto *f = _function;
SQClosure * ret = SQClosure::Create(_opt_ss(this),f,_root);
ret->_env = _env;
if(ret->_env) __ObjAddRef(ret->_env);
_COPY_VECTOR(ret->_outervalues,_outervalues,f->_noutervalues);
_COPY_VECTOR(ret->_defaultparams,_defaultparams,f->_ndefaultparams);
return ret;
}
~SQClosure();
static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func,SQWeakRef *root){
SQInteger size = _CALC_CLOSURE_SIZE(func);
SQClosure *nc=(SQClosure*)SQ_MALLOC(size);
new (nc) SQClosure(ss,func);
nc->_outervalues = (SQObjectPtr *)(nc + 1);
nc->_defaultparams = &nc->_outervalues[func->_noutervalues];
nc->_root = root;
__ObjAddRef(nc->_root);
_CONSTRUCT_VECTOR(SQObjectPtr,func->_noutervalues,nc->_outervalues);
_CONSTRUCT_VECTOR(SQObjectPtr,func->_ndefaultparams,nc->_defaultparams);
return nc;
}
void Release(){
SQFunctionProto *f = _function;
SQInteger size = _CALC_CLOSURE_SIZE(f);
_DESTRUCT_VECTOR(SQObjectPtr,f->_noutervalues,_outervalues);
_DESTRUCT_VECTOR(SQObjectPtr,f->_ndefaultparams,_defaultparams);
__ObjRelease(_function);
this->~SQClosure();
sq_vm_free(this,size);
}
void SetRoot(SQWeakRef *r)
{
__ObjRelease(_root);
_root = r;
__ObjAddRef(_root);
}
SQClosure *Clone()
{
SQFunctionProto *f = _function;
SQClosure * ret = SQClosure::Create(_opt_ss(this),f,_root);
ret->_env = _env;
if(ret->_env) __ObjAddRef(ret->_env);
_COPY_VECTOR(ret->_outervalues,_outervalues,f->_noutervalues);
_COPY_VECTOR(ret->_defaultparams,_defaultparams,f->_ndefaultparams);
return ret;
}
~SQClosure();
bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
#ifndef NO_GARBAGE_COLLECTOR
void Mark(SQCollectable **chain);
void Finalize(){
SQFunctionProto *f = _function;
_NULL_SQOBJECT_VECTOR(_outervalues,f->_noutervalues);
_NULL_SQOBJECT_VECTOR(_defaultparams,f->_ndefaultparams);
}
SQObjectType GetType() {return OT_CLOSURE;}
void Mark(SQCollectable **chain);
void Finalize(){
SQFunctionProto *f = _function;
_NULL_SQOBJECT_VECTOR(_outervalues,f->_noutervalues);
_NULL_SQOBJECT_VECTOR(_defaultparams,f->_ndefaultparams);
}
SQObjectType GetType() {return OT_CLOSURE;}
#endif
SQWeakRef *_env;
SQWeakRef *_root;
SQClass *_base;
SQFunctionProto *_function;
SQObjectPtr *_outervalues;
SQObjectPtr *_defaultparams;
SQWeakRef *_env;
SQWeakRef *_root;
SQClass *_base;
SQFunctionProto *_function;
SQObjectPtr *_outervalues;
SQObjectPtr *_defaultparams;
};
//////////////////////////////////////////////
@ -75,71 +75,71 @@ struct SQOuter : public CHAINABLE_OBJ
{
private:
SQOuter(SQSharedState *ss, SQObjectPtr *outer){_valptr = outer; _next = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); }
SQOuter(SQSharedState *ss, SQObjectPtr *outer){_valptr = outer; _next = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); }
public:
static SQOuter *Create(SQSharedState *ss, SQObjectPtr *outer)
{
SQOuter *nc = (SQOuter*)SQ_MALLOC(sizeof(SQOuter));
new (nc) SQOuter(ss, outer);
return nc;
}
~SQOuter() { REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); }
static SQOuter *Create(SQSharedState *ss, SQObjectPtr *outer)
{
SQOuter *nc = (SQOuter*)SQ_MALLOC(sizeof(SQOuter));
new (nc) SQOuter(ss, outer);
return nc;
}
~SQOuter() { REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); }
void Release()
{
this->~SQOuter();
sq_vm_free(this,sizeof(SQOuter));
}
void Release()
{
this->~SQOuter();
sq_vm_free(this,sizeof(SQOuter));
}
#ifndef NO_GARBAGE_COLLECTOR
void Mark(SQCollectable **chain);
void Finalize() { _value.Null(); }
SQObjectType GetType() {return OT_OUTER;}
void Mark(SQCollectable **chain);
void Finalize() { _value.Null(); }
SQObjectType GetType() {return OT_OUTER;}
#endif
SQObjectPtr *_valptr; /* pointer to value on stack, or _value below */
SQInteger _idx; /* idx in stack array, for relocation */
SQObjectPtr _value; /* value of outer after stack frame is closed */
SQOuter *_next; /* pointer to next outer when frame is open */
SQObjectPtr *_valptr; /* pointer to value on stack, or _value below */
SQInteger _idx; /* idx in stack array, for relocation */
SQObjectPtr _value; /* value of outer after stack frame is closed */
SQOuter *_next; /* pointer to next outer when frame is open */
};
//////////////////////////////////////////////
struct SQGenerator : public CHAINABLE_OBJ
{
enum SQGeneratorState{eRunning,eSuspended,eDead};
enum SQGeneratorState{eRunning,eSuspended,eDead};
private:
SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=NULL;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=NULL;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
public:
static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){
SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));
new (nc) SQGenerator(ss,closure);
return nc;
}
~SQGenerator()
{
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
}
static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){
SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));
new (nc) SQGenerator(ss,closure);
return nc;
}
~SQGenerator()
{
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
}
void Kill(){
_state=eDead;
_stack.resize(0);
_closure.Null();}
void Release(){
sq_delete(this,SQGenerator);
}
_state=eDead;
_stack.resize(0);
_closure.Null();}
void Release(){
sq_delete(this,SQGenerator);
}
bool Yield(SQVM *v,SQInteger target);
bool Resume(SQVM *v,SQObjectPtr &dest);
bool Yield(SQVM *v,SQInteger target);
bool Resume(SQVM *v,SQObjectPtr &dest);
#ifndef NO_GARBAGE_COLLECTOR
void Mark(SQCollectable **chain);
void Finalize(){_stack.resize(0);_closure.Null();}
SQObjectType GetType() {return OT_GENERATOR;}
void Mark(SQCollectable **chain);
void Finalize(){_stack.resize(0);_closure.Null();}
SQObjectType GetType() {return OT_GENERATOR;}
#endif
SQObjectPtr _closure;
SQObjectPtrVec _stack;
SQVM::CallInfo _ci;
ExceptionsTraps _etraps;
SQGeneratorState _state;
SQObjectPtr _closure;
SQObjectPtrVec _stack;
SQVM::CallInfo _ci;
ExceptionsTraps _etraps;
SQGeneratorState _state;
};
#define _CALC_NATVIVECLOSURE_SIZE(noutervalues) (sizeof(SQNativeClosure) + (noutervalues*sizeof(SQObjectPtr)))
@ -147,53 +147,53 @@ public:
struct SQNativeClosure : public CHAINABLE_OBJ
{
private:
SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;}
SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;}
public:
static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func,SQInteger nouters)
{
SQInteger size = _CALC_NATVIVECLOSURE_SIZE(nouters);
SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(size);
new (nc) SQNativeClosure(ss,func);
nc->_outervalues = (SQObjectPtr *)(nc + 1);
nc->_noutervalues = nouters;
_CONSTRUCT_VECTOR(SQObjectPtr,nc->_noutervalues,nc->_outervalues);
return nc;
}
SQNativeClosure *Clone()
{
SQNativeClosure * ret = SQNativeClosure::Create(_opt_ss(this),_function,_noutervalues);
ret->_env = _env;
if(ret->_env) __ObjAddRef(ret->_env);
ret->_name = _name;
_COPY_VECTOR(ret->_outervalues,_outervalues,_noutervalues);
ret->_typecheck.copy(_typecheck);
ret->_nparamscheck = _nparamscheck;
return ret;
}
~SQNativeClosure()
{
__ObjRelease(_env);
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
}
void Release(){
SQInteger size = _CALC_NATVIVECLOSURE_SIZE(_noutervalues);
_DESTRUCT_VECTOR(SQObjectPtr,_noutervalues,_outervalues);
this->~SQNativeClosure();
sq_free(this,size);
}
static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func,SQInteger nouters)
{
SQInteger size = _CALC_NATVIVECLOSURE_SIZE(nouters);
SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(size);
new (nc) SQNativeClosure(ss,func);
nc->_outervalues = (SQObjectPtr *)(nc + 1);
nc->_noutervalues = nouters;
_CONSTRUCT_VECTOR(SQObjectPtr,nc->_noutervalues,nc->_outervalues);
return nc;
}
SQNativeClosure *Clone()
{
SQNativeClosure * ret = SQNativeClosure::Create(_opt_ss(this),_function,_noutervalues);
ret->_env = _env;
if(ret->_env) __ObjAddRef(ret->_env);
ret->_name = _name;
_COPY_VECTOR(ret->_outervalues,_outervalues,_noutervalues);
ret->_typecheck.copy(_typecheck);
ret->_nparamscheck = _nparamscheck;
return ret;
}
~SQNativeClosure()
{
__ObjRelease(_env);
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
}
void Release(){
SQInteger size = _CALC_NATVIVECLOSURE_SIZE(_noutervalues);
_DESTRUCT_VECTOR(SQObjectPtr,_noutervalues,_outervalues);
this->~SQNativeClosure();
sq_free(this,size);
}
#ifndef NO_GARBAGE_COLLECTOR
void Mark(SQCollectable **chain);
void Finalize() { _NULL_SQOBJECT_VECTOR(_outervalues,_noutervalues); }
SQObjectType GetType() {return OT_NATIVECLOSURE;}
void Mark(SQCollectable **chain);
void Finalize() { _NULL_SQOBJECT_VECTOR(_outervalues,_noutervalues); }
SQObjectType GetType() {return OT_NATIVECLOSURE;}
#endif
SQInteger _nparamscheck;
SQIntVec _typecheck;
SQObjectPtr *_outervalues;
SQUnsignedInteger _noutervalues;
SQWeakRef *_env;
SQFUNCTION _function;
SQObjectPtr _name;
SQInteger _nparamscheck;
SQIntVec _typecheck;
SQObjectPtr *_outervalues;
SQUnsignedInteger _noutervalues;
SQWeakRef *_env;
SQFUNCTION _function;
SQObjectPtr _name;
};

File diff suppressed because it is too large Load Diff

View File

@ -1,43 +1,43 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQCOMPILER_H_
#define _SQCOMPILER_H_
struct SQVM;
#define TK_IDENTIFIER 258
#define TK_STRING_LITERAL 259
#define TK_INTEGER 260
#define TK_FLOAT 261
#define TK_BASE 262
#define TK_DELETE 263
#define TK_EQ 264
#define TK_NE 265
#define TK_LE 266
#define TK_GE 267
#define TK_SWITCH 268
#define TK_ARROW 269
#define TK_AND 270
#define TK_OR 271
#define TK_IF 272
#define TK_ELSE 273
#define TK_WHILE 274
#define TK_BREAK 275
#define TK_FOR 276
#define TK_DO 277
#define TK_NULL 278
#define TK_FOREACH 279
#define TK_IN 280
#define TK_NEWSLOT 281
#define TK_MODULO 282
#define TK_LOCAL 283
#define TK_CLONE 284
#define TK_FUNCTION 285
#define TK_RETURN 286
#define TK_TYPEOF 287
#define TK_UMINUS 288
#define TK_PLUSEQ 289
#define TK_MINUSEQ 290
#define TK_CONTINUE 291
#define TK_IDENTIFIER 258
#define TK_STRING_LITERAL 259
#define TK_INTEGER 260
#define TK_FLOAT 261
#define TK_BASE 262
#define TK_DELETE 263
#define TK_EQ 264
#define TK_NE 265
#define TK_LE 266
#define TK_GE 267
#define TK_SWITCH 268
#define TK_ARROW 269
#define TK_AND 270
#define TK_OR 271
#define TK_IF 272
#define TK_ELSE 273
#define TK_WHILE 274
#define TK_BREAK 275
#define TK_FOR 276
#define TK_DO 277
#define TK_NULL 278
#define TK_FOREACH 279
#define TK_IN 280
#define TK_NEWSLOT 281
#define TK_MODULO 282
#define TK_LOCAL 283
#define TK_CLONE 284
#define TK_FUNCTION 285
#define TK_RETURN 286
#define TK_TYPEOF 287
#define TK_UMINUS 288
#define TK_PLUSEQ 289
#define TK_MINUSEQ 290
#define TK_CONTINUE 291
#define TK_YIELD 292
#define TK_TRY 293
#define TK_CATCH 294

View File

@ -1,5 +1,5 @@
/*
see copyright notice in squirrel.h
see copyright notice in squirrel.h
*/
#include "sqpcheader.h"
#include <stdarg.h>
@ -10,109 +10,109 @@
SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger level,SQFunctionInfo *fi)
{
SQInteger cssize = v->_callsstacksize;
if (cssize > level) {
SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];
if(sq_isclosure(ci._closure)) {
SQClosure *c = _closure(ci._closure);
SQFunctionProto *proto = c->_function;
fi->funcid = proto;
fi->name = type(proto->_name) == OT_STRING?_stringval(proto->_name):_SC("unknown");
fi->source = type(proto->_sourcename) == OT_STRING?_stringval(proto->_sourcename):_SC("unknown");
fi->line = proto->_lineinfos[0]._line;
return SQ_OK;
}
}
return sq_throwerror(v,_SC("the object is not a closure"));
SQInteger cssize = v->_callsstacksize;
if (cssize > level) {
SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];
if(sq_isclosure(ci._closure)) {
SQClosure *c = _closure(ci._closure);
SQFunctionProto *proto = c->_function;
fi->funcid = proto;
fi->name = type(proto->_name) == OT_STRING?_stringval(proto->_name):_SC("unknown");
fi->source = type(proto->_sourcename) == OT_STRING?_stringval(proto->_sourcename):_SC("unknown");
fi->line = proto->_lineinfos[0]._line;
return SQ_OK;
}
}
return sq_throwerror(v,_SC("the object is not a closure"));
}
SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si)
{
SQInteger cssize = v->_callsstacksize;
if (cssize > level) {
memset(si, 0, sizeof(SQStackInfos));
SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];
switch (type(ci._closure)) {
case OT_CLOSURE:{
SQFunctionProto *func = _closure(ci._closure)->_function;
if (type(func->_name) == OT_STRING)
si->funcname = _stringval(func->_name);
if (type(func->_sourcename) == OT_STRING)
si->source = _stringval(func->_sourcename);
si->line = func->GetLine(ci._ip);
}
break;
case OT_NATIVECLOSURE:
si->source = _SC("NATIVE");
si->funcname = _SC("unknown");
if(type(_nativeclosure(ci._closure)->_name) == OT_STRING)
si->funcname = _stringval(_nativeclosure(ci._closure)->_name);
si->line = -1;
break;
default: break; //shutup compiler
}
return SQ_OK;
}
return SQ_ERROR;
SQInteger cssize = v->_callsstacksize;
if (cssize > level) {
memset(si, 0, sizeof(SQStackInfos));
SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];
switch (type(ci._closure)) {
case OT_CLOSURE:{
SQFunctionProto *func = _closure(ci._closure)->_function;
if (type(func->_name) == OT_STRING)
si->funcname = _stringval(func->_name);
if (type(func->_sourcename) == OT_STRING)
si->source = _stringval(func->_sourcename);
si->line = func->GetLine(ci._ip);
}
break;
case OT_NATIVECLOSURE:
si->source = _SC("NATIVE");
si->funcname = _SC("unknown");
if(type(_nativeclosure(ci._closure)->_name) == OT_STRING)
si->funcname = _stringval(_nativeclosure(ci._closure)->_name);
si->line = -1;
break;
default: break; //shutup compiler
}
return SQ_OK;
}
return SQ_ERROR;
}
void SQVM::Raise_Error(const SQChar *s, ...)
{
va_list vl;
va_start(vl, s);
SQInteger buffersize = (SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2);
scvsprintf(_sp(sq_rsl(buffersize)),buffersize, s, vl);
va_end(vl);
_lasterror = SQString::Create(_ss(this),_spval,-1);
va_list vl;
va_start(vl, s);
SQInteger buffersize = (SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2);
scvsprintf(_sp(sq_rsl(buffersize)),buffersize, s, vl);
va_end(vl);
_lasterror = SQString::Create(_ss(this),_spval,-1);
}
void SQVM::Raise_Error(const SQObjectPtr &desc)
{
_lasterror = desc;
_lasterror = desc;
}
SQString *SQVM::PrintObjVal(const SQObjectPtr &o)
{
switch(type(o)) {
case OT_STRING: return _string(o);
case OT_INTEGER:
scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)),sq_rsl(NUMBER_MAX_CHAR), _PRINT_INT_FMT, _integer(o));
return SQString::Create(_ss(this), _spval);
break;
case OT_FLOAT:
scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)), sq_rsl(NUMBER_MAX_CHAR), _SC("%.14g"), _float(o));
return SQString::Create(_ss(this), _spval);
break;
default:
return SQString::Create(_ss(this), GetTypeName(o));
}
switch(type(o)) {
case OT_STRING: return _string(o);
case OT_INTEGER:
scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)),sq_rsl(NUMBER_MAX_CHAR), _PRINT_INT_FMT, _integer(o));
return SQString::Create(_ss(this), _spval);
break;
case OT_FLOAT:
scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)), sq_rsl(NUMBER_MAX_CHAR), _SC("%.14g"), _float(o));
return SQString::Create(_ss(this), _spval);
break;
default:
return SQString::Create(_ss(this), GetTypeName(o));
}
}
void SQVM::Raise_IdxError(const SQObjectPtr &o)
{
SQObjectPtr oval = PrintObjVal(o);
Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval));
SQObjectPtr oval = PrintObjVal(o);
Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval));
}
void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2)
{
SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2);
Raise_Error(_SC("comparison between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2));
SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2);
Raise_Error(_SC("comparison between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2));
}
void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type)
{
SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1);
SQInteger found = 0;
for(SQInteger i=0; i<16; i++)
{
SQInteger mask = 0x00000001 << i;
if(typemask & (mask)) {
if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes);
found ++;
StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes);
}
}
Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes));
SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1);
SQInteger found = 0;
for(SQInteger i=0; i<16; i++)
{
SQInteger mask = 0x00000001 << i;
if(typemask & (mask)) {
if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes);
found ++;
StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes);
}
}
Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes));
}

View File

@ -1,49 +1,49 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQFUNCTION_H_
#define _SQFUNCTION_H_
#include "sqopcodes.h"
enum SQOuterType {
otLOCAL = 0,
otOUTER = 1
otLOCAL = 0,
otOUTER = 1
};
struct SQOuterVar
{
SQOuterVar(){}
SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t)
{
_name = name;
_src=src;
_type=t;
}
SQOuterVar(const SQOuterVar &ov)
{
_type=ov._type;
_src=ov._src;
_name=ov._name;
}
SQOuterType _type;
SQObjectPtr _name;
SQObjectPtr _src;
SQOuterVar(){}
SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t)
{
_name = name;
_src=src;
_type=t;
}
SQOuterVar(const SQOuterVar &ov)
{
_type=ov._type;
_src=ov._src;
_name=ov._name;
}
SQOuterType _type;
SQObjectPtr _name;
SQObjectPtr _src;
};
struct SQLocalVarInfo
{
SQLocalVarInfo():_start_op(0),_end_op(0),_pos(0){}
SQLocalVarInfo(const SQLocalVarInfo &lvi)
{
_name=lvi._name;
_start_op=lvi._start_op;
_end_op=lvi._end_op;
_pos=lvi._pos;
}
SQObjectPtr _name;
SQUnsignedInteger _start_op;
SQUnsignedInteger _end_op;
SQUnsignedInteger _pos;
SQLocalVarInfo():_start_op(0),_end_op(0),_pos(0){}
SQLocalVarInfo(const SQLocalVarInfo &lvi)
{
_name=lvi._name;
_start_op=lvi._start_op;
_end_op=lvi._end_op;
_pos=lvi._pos;
}
SQObjectPtr _name;
SQUnsignedInteger _start_op;
SQUnsignedInteger _end_op;
SQUnsignedInteger _pos;
};
struct SQLineInfo { SQInteger _line;SQInteger _op; };
@ -53,102 +53,102 @@ typedef sqvector<SQLocalVarInfo> SQLocalVarInfoVec;
typedef sqvector<SQLineInfo> SQLineInfoVec;
#define _FUNC_SIZE(ni,nl,nparams,nfuncs,nouters,nlineinf,localinf,defparams) (sizeof(SQFunctionProto) \
+((ni-1)*sizeof(SQInstruction))+(nl*sizeof(SQObjectPtr)) \
+(nparams*sizeof(SQObjectPtr))+(nfuncs*sizeof(SQObjectPtr)) \
+(nouters*sizeof(SQOuterVar))+(nlineinf*sizeof(SQLineInfo)) \
+(localinf*sizeof(SQLocalVarInfo))+(defparams*sizeof(SQInteger)))
+((ni-1)*sizeof(SQInstruction))+(nl*sizeof(SQObjectPtr)) \
+(nparams*sizeof(SQObjectPtr))+(nfuncs*sizeof(SQObjectPtr)) \
+(nouters*sizeof(SQOuterVar))+(nlineinf*sizeof(SQLineInfo)) \
+(localinf*sizeof(SQLocalVarInfo))+(defparams*sizeof(SQInteger)))
struct SQFunctionProto : public CHAINABLE_OBJ
{
private:
SQFunctionProto(SQSharedState *ss);
~SQFunctionProto();
SQFunctionProto(SQSharedState *ss);
~SQFunctionProto();
public:
static SQFunctionProto *Create(SQSharedState *ss,SQInteger ninstructions,
SQInteger nliterals,SQInteger nparameters,
SQInteger nfunctions,SQInteger noutervalues,
SQInteger nlineinfos,SQInteger nlocalvarinfos,SQInteger ndefaultparams)
{
SQFunctionProto *f;
//I compact the whole class and members in a single memory allocation
f = (SQFunctionProto *)sq_vm_malloc(_FUNC_SIZE(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams));
new (f) SQFunctionProto(ss);
f->_ninstructions = ninstructions;
f->_literals = (SQObjectPtr*)&f->_instructions[ninstructions];
f->_nliterals = nliterals;
f->_parameters = (SQObjectPtr*)&f->_literals[nliterals];
f->_nparameters = nparameters;
f->_functions = (SQObjectPtr*)&f->_parameters[nparameters];
f->_nfunctions = nfunctions;
f->_outervalues = (SQOuterVar*)&f->_functions[nfunctions];
f->_noutervalues = noutervalues;
f->_lineinfos = (SQLineInfo *)&f->_outervalues[noutervalues];
f->_nlineinfos = nlineinfos;
f->_localvarinfos = (SQLocalVarInfo *)&f->_lineinfos[nlineinfos];
f->_nlocalvarinfos = nlocalvarinfos;
f->_defaultparams = (SQInteger *)&f->_localvarinfos[nlocalvarinfos];
f->_ndefaultparams = ndefaultparams;
static SQFunctionProto *Create(SQSharedState *ss,SQInteger ninstructions,
SQInteger nliterals,SQInteger nparameters,
SQInteger nfunctions,SQInteger noutervalues,
SQInteger nlineinfos,SQInteger nlocalvarinfos,SQInteger ndefaultparams)
{
SQFunctionProto *f;
//I compact the whole class and members in a single memory allocation
f = (SQFunctionProto *)sq_vm_malloc(_FUNC_SIZE(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams));
new (f) SQFunctionProto(ss);
f->_ninstructions = ninstructions;
f->_literals = (SQObjectPtr*)&f->_instructions[ninstructions];
f->_nliterals = nliterals;
f->_parameters = (SQObjectPtr*)&f->_literals[nliterals];
f->_nparameters = nparameters;
f->_functions = (SQObjectPtr*)&f->_parameters[nparameters];
f->_nfunctions = nfunctions;
f->_outervalues = (SQOuterVar*)&f->_functions[nfunctions];
f->_noutervalues = noutervalues;
f->_lineinfos = (SQLineInfo *)&f->_outervalues[noutervalues];
f->_nlineinfos = nlineinfos;
f->_localvarinfos = (SQLocalVarInfo *)&f->_lineinfos[nlineinfos];
f->_nlocalvarinfos = nlocalvarinfos;
f->_defaultparams = (SQInteger *)&f->_localvarinfos[nlocalvarinfos];
f->_ndefaultparams = ndefaultparams;
_CONSTRUCT_VECTOR(SQObjectPtr,f->_nliterals,f->_literals);
_CONSTRUCT_VECTOR(SQObjectPtr,f->_nparameters,f->_parameters);
_CONSTRUCT_VECTOR(SQObjectPtr,f->_nfunctions,f->_functions);
_CONSTRUCT_VECTOR(SQOuterVar,f->_noutervalues,f->_outervalues);
//_CONSTRUCT_VECTOR(SQLineInfo,f->_nlineinfos,f->_lineinfos); //not required are 2 integers
_CONSTRUCT_VECTOR(SQLocalVarInfo,f->_nlocalvarinfos,f->_localvarinfos);
return f;
}
void Release(){
_DESTRUCT_VECTOR(SQObjectPtr,_nliterals,_literals);
_DESTRUCT_VECTOR(SQObjectPtr,_nparameters,_parameters);
_DESTRUCT_VECTOR(SQObjectPtr,_nfunctions,_functions);
_DESTRUCT_VECTOR(SQOuterVar,_noutervalues,_outervalues);
//_DESTRUCT_VECTOR(SQLineInfo,_nlineinfos,_lineinfos); //not required are 2 integers
_DESTRUCT_VECTOR(SQLocalVarInfo,_nlocalvarinfos,_localvarinfos);
SQInteger size = _FUNC_SIZE(_ninstructions,_nliterals,_nparameters,_nfunctions,_noutervalues,_nlineinfos,_nlocalvarinfos,_ndefaultparams);
this->~SQFunctionProto();
sq_vm_free(this,size);
}
_CONSTRUCT_VECTOR(SQObjectPtr,f->_nliterals,f->_literals);
_CONSTRUCT_VECTOR(SQObjectPtr,f->_nparameters,f->_parameters);
_CONSTRUCT_VECTOR(SQObjectPtr,f->_nfunctions,f->_functions);
_CONSTRUCT_VECTOR(SQOuterVar,f->_noutervalues,f->_outervalues);
//_CONSTRUCT_VECTOR(SQLineInfo,f->_nlineinfos,f->_lineinfos); //not required are 2 integers
_CONSTRUCT_VECTOR(SQLocalVarInfo,f->_nlocalvarinfos,f->_localvarinfos);
return f;
}
void Release(){
_DESTRUCT_VECTOR(SQObjectPtr,_nliterals,_literals);
_DESTRUCT_VECTOR(SQObjectPtr,_nparameters,_parameters);
_DESTRUCT_VECTOR(SQObjectPtr,_nfunctions,_functions);
_DESTRUCT_VECTOR(SQOuterVar,_noutervalues,_outervalues);
//_DESTRUCT_VECTOR(SQLineInfo,_nlineinfos,_lineinfos); //not required are 2 integers
_DESTRUCT_VECTOR(SQLocalVarInfo,_nlocalvarinfos,_localvarinfos);
SQInteger size = _FUNC_SIZE(_ninstructions,_nliterals,_nparameters,_nfunctions,_noutervalues,_nlineinfos,_nlocalvarinfos,_ndefaultparams);
this->~SQFunctionProto();
sq_vm_free(this,size);
}
const SQChar* GetLocal(SQVM *v,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop);
SQInteger GetLine(SQInstruction *curr);
bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
const SQChar* GetLocal(SQVM *v,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop);
SQInteger GetLine(SQInstruction *curr);
bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
#ifndef NO_GARBAGE_COLLECTOR
void Mark(SQCollectable **chain);
void Finalize(){ _NULL_SQOBJECT_VECTOR(_literals,_nliterals); }
SQObjectType GetType() {return OT_FUNCPROTO;}
void Mark(SQCollectable **chain);
void Finalize(){ _NULL_SQOBJECT_VECTOR(_literals,_nliterals); }
SQObjectType GetType() {return OT_FUNCPROTO;}
#endif
SQObjectPtr _sourcename;
SQObjectPtr _name;
SQObjectPtr _sourcename;
SQObjectPtr _name;
SQInteger _stacksize;
bool _bgenerator;
SQInteger _varparams;
bool _bgenerator;
SQInteger _varparams;
SQInteger _nlocalvarinfos;
SQLocalVarInfo *_localvarinfos;
SQInteger _nlocalvarinfos;
SQLocalVarInfo *_localvarinfos;
SQInteger _nlineinfos;
SQLineInfo *_lineinfos;
SQInteger _nlineinfos;
SQLineInfo *_lineinfos;
SQInteger _nliterals;
SQObjectPtr *_literals;
SQInteger _nliterals;
SQObjectPtr *_literals;
SQInteger _nparameters;
SQObjectPtr *_parameters;
SQInteger _nparameters;
SQObjectPtr *_parameters;
SQInteger _nfunctions;
SQObjectPtr *_functions;
SQInteger _nfunctions;
SQObjectPtr *_functions;
SQInteger _noutervalues;
SQOuterVar *_outervalues;
SQInteger _noutervalues;
SQOuterVar *_outervalues;
SQInteger _ndefaultparams;
SQInteger *_defaultparams;
SQInteger _ndefaultparams;
SQInteger *_defaultparams;
SQInteger _ninstructions;
SQInstruction _instructions[1];
SQInteger _ninstructions;
SQInstruction _instructions[1];
};
#endif //_SQFUNCTION_H_

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQFUNCSTATE_H_
#define _SQFUNCSTATE_H_
///////////////////////////////////
@ -6,84 +6,84 @@
struct SQFuncState
{
SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed);
~SQFuncState();
SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed);
~SQFuncState();
#ifdef _DEBUG_DUMP
void Dump(SQFunctionProto *func);
void Dump(SQFunctionProto *func);
#endif
void Error(const SQChar *err);
SQFuncState *PushChildState(SQSharedState *ss);
void PopChildState();
void AddInstruction(SQOpcode _op,SQInteger arg0=0,SQInteger arg1=0,SQInteger arg2=0,SQInteger arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);AddInstruction(i);}
void AddInstruction(SQInstruction &i);
void SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2=0,SQInteger arg3=0);
void SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val);
SQInstruction &GetInstruction(SQInteger pos){return _instructions[pos];}
void PopInstructions(SQInteger size){for(SQInteger i=0;i<size;i++)_instructions.pop_back();}
void SetStackSize(SQInteger n);
SQInteger CountOuters(SQInteger stacksize);
void SnoozeOpt(){_optimization=false;}
void AddDefaultParam(SQInteger trg) { _defaultparams.push_back(trg); }
SQInteger GetDefaultParamCount() { return _defaultparams.size(); }
SQInteger GetCurrentPos(){return _instructions.size()-1;}
SQInteger GetNumericConstant(const SQInteger cons);
SQInteger GetNumericConstant(const SQFloat cons);
SQInteger PushLocalVariable(const SQObject &name);
void AddParameter(const SQObject &name);
//void AddOuterValue(const SQObject &name);
SQInteger GetLocalVariable(const SQObject &name);
void MarkLocalAsOuter(SQInteger pos);
SQInteger GetOuterVariable(const SQObject &name);
SQInteger GenerateCode();
SQInteger GetStackSize();
SQInteger CalcStackFrameSize();
void AddLineInfos(SQInteger line,bool lineop,bool force=false);
SQFunctionProto *BuildProto();
SQInteger AllocStackPos();
SQInteger PushTarget(SQInteger n=-1);
SQInteger PopTarget();
SQInteger TopTarget();
SQInteger GetUpTarget(SQInteger n);
void DiscardTarget();
bool IsLocal(SQUnsignedInteger stkpos);
SQObject CreateString(const SQChar *s,SQInteger len = -1);
SQObject CreateTable();
bool IsConstant(const SQObject &name,SQObject &e);
SQInteger _returnexp;
SQLocalVarInfoVec _vlocals;
SQIntVec _targetstack;
SQInteger _stacksize;
bool _varparams;
bool _bgenerator;
SQIntVec _unresolvedbreaks;
SQIntVec _unresolvedcontinues;
SQObjectPtrVec _functions;
SQObjectPtrVec _parameters;
SQOuterVarVec _outervalues;
SQInstructionVec _instructions;
SQLocalVarInfoVec _localvarinfos;
SQObjectPtr _literals;
SQObjectPtr _strings;
SQObjectPtr _name;
SQObjectPtr _sourcename;
SQInteger _nliterals;
SQLineInfoVec _lineinfos;
SQFuncState *_parent;
SQIntVec _scope_blocks;
SQIntVec _breaktargets;
SQIntVec _continuetargets;
SQIntVec _defaultparams;
SQInteger _lastline;
SQInteger _traps; //contains number of nested exception traps
SQInteger _outers;
bool _optimization;
SQSharedState *_sharedstate;
sqvector<SQFuncState*> _childstates;
SQInteger GetConstant(const SQObject &cons);
void Error(const SQChar *err);
SQFuncState *PushChildState(SQSharedState *ss);
void PopChildState();
void AddInstruction(SQOpcode _op,SQInteger arg0=0,SQInteger arg1=0,SQInteger arg2=0,SQInteger arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);AddInstruction(i);}
void AddInstruction(SQInstruction &i);
void SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2=0,SQInteger arg3=0);
void SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val);
SQInstruction &GetInstruction(SQInteger pos){return _instructions[pos];}
void PopInstructions(SQInteger size){for(SQInteger i=0;i<size;i++)_instructions.pop_back();}
void SetStackSize(SQInteger n);
SQInteger CountOuters(SQInteger stacksize);
void SnoozeOpt(){_optimization=false;}
void AddDefaultParam(SQInteger trg) { _defaultparams.push_back(trg); }
SQInteger GetDefaultParamCount() { return _defaultparams.size(); }
SQInteger GetCurrentPos(){return _instructions.size()-1;}
SQInteger GetNumericConstant(const SQInteger cons);
SQInteger GetNumericConstant(const SQFloat cons);
SQInteger PushLocalVariable(const SQObject &name);
void AddParameter(const SQObject &name);
//void AddOuterValue(const SQObject &name);
SQInteger GetLocalVariable(const SQObject &name);
void MarkLocalAsOuter(SQInteger pos);
SQInteger GetOuterVariable(const SQObject &name);
SQInteger GenerateCode();
SQInteger GetStackSize();
SQInteger CalcStackFrameSize();
void AddLineInfos(SQInteger line,bool lineop,bool force=false);
SQFunctionProto *BuildProto();
SQInteger AllocStackPos();
SQInteger PushTarget(SQInteger n=-1);
SQInteger PopTarget();
SQInteger TopTarget();
SQInteger GetUpTarget(SQInteger n);
void DiscardTarget();
bool IsLocal(SQUnsignedInteger stkpos);
SQObject CreateString(const SQChar *s,SQInteger len = -1);
SQObject CreateTable();
bool IsConstant(const SQObject &name,SQObject &e);
SQInteger _returnexp;
SQLocalVarInfoVec _vlocals;
SQIntVec _targetstack;
SQInteger _stacksize;
bool _varparams;
bool _bgenerator;
SQIntVec _unresolvedbreaks;
SQIntVec _unresolvedcontinues;
SQObjectPtrVec _functions;
SQObjectPtrVec _parameters;
SQOuterVarVec _outervalues;
SQInstructionVec _instructions;
SQLocalVarInfoVec _localvarinfos;
SQObjectPtr _literals;
SQObjectPtr _strings;
SQObjectPtr _name;
SQObjectPtr _sourcename;
SQInteger _nliterals;
SQLineInfoVec _lineinfos;
SQFuncState *_parent;
SQIntVec _scope_blocks;
SQIntVec _breaktargets;
SQIntVec _continuetargets;
SQIntVec _defaultparams;
SQInteger _lastline;
SQInteger _traps; //contains number of nested exception traps
SQInteger _outers;
bool _optimization;
SQSharedState *_sharedstate;
sqvector<SQFuncState*> _childstates;
SQInteger GetConstant(const SQObject &cons);
private:
CompilerErrorFunc _errfunc;
void *_errtarget;
SQSharedState *_ss;
CompilerErrorFunc _errfunc;
void *_errtarget;
SQSharedState *_ss;
};

View File

@ -1,5 +1,5 @@
/*
see copyright notice in squirrel.h
see copyright notice in squirrel.h
*/
#include "sqpcheader.h"
#include <ctype.h>
@ -21,384 +21,384 @@
SQLexer::SQLexer(){}
SQLexer::~SQLexer()
{
_keywords->Release();
_keywords->Release();
}
void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed)
{
_errfunc = efunc;
_errtarget = ed;
_sharedstate = ss;
_keywords = SQTable::Create(ss, 37);
ADD_KEYWORD(while, TK_WHILE);
ADD_KEYWORD(do, TK_DO);
ADD_KEYWORD(if, TK_IF);
ADD_KEYWORD(else, TK_ELSE);
ADD_KEYWORD(break, TK_BREAK);
ADD_KEYWORD(continue, TK_CONTINUE);
ADD_KEYWORD(return, TK_RETURN);
ADD_KEYWORD(null, TK_NULL);
ADD_KEYWORD(function, TK_FUNCTION);
ADD_KEYWORD(local, TK_LOCAL);
ADD_KEYWORD(for, TK_FOR);
ADD_KEYWORD(foreach, TK_FOREACH);
ADD_KEYWORD(in, TK_IN);
ADD_KEYWORD(typeof, TK_TYPEOF);
ADD_KEYWORD(base, TK_BASE);
ADD_KEYWORD(delete, TK_DELETE);
ADD_KEYWORD(try, TK_TRY);
ADD_KEYWORD(catch, TK_CATCH);
ADD_KEYWORD(throw, TK_THROW);
ADD_KEYWORD(clone, TK_CLONE);
ADD_KEYWORD(yield, TK_YIELD);
ADD_KEYWORD(resume, TK_RESUME);
ADD_KEYWORD(switch, TK_SWITCH);
ADD_KEYWORD(case, TK_CASE);
ADD_KEYWORD(default, TK_DEFAULT);
ADD_KEYWORD(this, TK_THIS);
ADD_KEYWORD(class,TK_CLASS);
ADD_KEYWORD(extends,TK_EXTENDS);
ADD_KEYWORD(constructor,TK_CONSTRUCTOR);
ADD_KEYWORD(instanceof,TK_INSTANCEOF);
ADD_KEYWORD(true,TK_TRUE);
ADD_KEYWORD(false,TK_FALSE);
ADD_KEYWORD(static,TK_STATIC);
ADD_KEYWORD(enum,TK_ENUM);
ADD_KEYWORD(const,TK_CONST);
ADD_KEYWORD(__LINE__,TK___LINE__);
_errfunc = efunc;
_errtarget = ed;
_sharedstate = ss;
_keywords = SQTable::Create(ss, 37);
ADD_KEYWORD(while, TK_WHILE);
ADD_KEYWORD(do, TK_DO);
ADD_KEYWORD(if, TK_IF);
ADD_KEYWORD(else, TK_ELSE);
ADD_KEYWORD(break, TK_BREAK);
ADD_KEYWORD(continue, TK_CONTINUE);
ADD_KEYWORD(return, TK_RETURN);
ADD_KEYWORD(null, TK_NULL);
ADD_KEYWORD(function, TK_FUNCTION);
ADD_KEYWORD(local, TK_LOCAL);
ADD_KEYWORD(for, TK_FOR);
ADD_KEYWORD(foreach, TK_FOREACH);
ADD_KEYWORD(in, TK_IN);
ADD_KEYWORD(typeof, TK_TYPEOF);
ADD_KEYWORD(base, TK_BASE);
ADD_KEYWORD(delete, TK_DELETE);
ADD_KEYWORD(try, TK_TRY);
ADD_KEYWORD(catch, TK_CATCH);
ADD_KEYWORD(throw, TK_THROW);
ADD_KEYWORD(clone, TK_CLONE);
ADD_KEYWORD(yield, TK_YIELD);
ADD_KEYWORD(resume, TK_RESUME);
ADD_KEYWORD(switch, TK_SWITCH);
ADD_KEYWORD(case, TK_CASE);
ADD_KEYWORD(default, TK_DEFAULT);
ADD_KEYWORD(this, TK_THIS);
ADD_KEYWORD(class,TK_CLASS);
ADD_KEYWORD(extends,TK_EXTENDS);
ADD_KEYWORD(constructor,TK_CONSTRUCTOR);
ADD_KEYWORD(instanceof,TK_INSTANCEOF);
ADD_KEYWORD(true,TK_TRUE);
ADD_KEYWORD(false,TK_FALSE);
ADD_KEYWORD(static,TK_STATIC);
ADD_KEYWORD(enum,TK_ENUM);
ADD_KEYWORD(const,TK_CONST);
ADD_KEYWORD(__LINE__,TK___LINE__);
ADD_KEYWORD(__FILE__,TK___FILE__);
_readf = rg;
_up = up;
_lasttokenline = _currentline = 1;
_currentcolumn = 0;
_prevtoken = -1;
_reached_eof = SQFalse;
Next();
_readf = rg;
_up = up;
_lasttokenline = _currentline = 1;
_currentcolumn = 0;
_prevtoken = -1;
_reached_eof = SQFalse;
Next();
}
void SQLexer::Error(const SQChar *err)
{
_errfunc(_errtarget,err);
_errfunc(_errtarget,err);
}
void SQLexer::Next()
{
SQInteger t = _readf(_up);
if(t > MAX_CHAR) Error(_SC("Invalid character"));
if(t != 0) {
_currdata = (LexChar)t;
return;
}
_currdata = SQUIRREL_EOB;
_reached_eof = SQTrue;
SQInteger t = _readf(_up);
if(t > MAX_CHAR) Error(_SC("Invalid character"));
if(t != 0) {
_currdata = (LexChar)t;
return;
}
_currdata = SQUIRREL_EOB;
_reached_eof = SQTrue;
}
const SQChar *SQLexer::Tok2Str(SQInteger tok)
{
SQObjectPtr itr, key, val;
SQInteger nitr;
while((nitr = _keywords->Next(false,itr, key, val)) != -1) {
itr = (SQInteger)nitr;
if(((SQInteger)_integer(val)) == tok)
return _stringval(key);
}
return NULL;
SQObjectPtr itr, key, val;
SQInteger nitr;
while((nitr = _keywords->Next(false,itr, key, val)) != -1) {
itr = (SQInteger)nitr;
if(((SQInteger)_integer(val)) == tok)
return _stringval(key);
}
return NULL;
}
void SQLexer::LexBlockComment()
{
bool done = false;
while(!done) {
switch(CUR_CHAR) {
case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue;
case _SC('\n'): _currentline++; NEXT(); continue;
case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment"));
default: NEXT();
}
}
bool done = false;
while(!done) {
switch(CUR_CHAR) {
case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue;
case _SC('\n'): _currentline++; NEXT(); continue;
case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment"));
default: NEXT();
}
}
}
void SQLexer::LexLineComment()
{
do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB()));
do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB()));
}
SQInteger SQLexer::Lex()
{
_lasttokenline = _currentline;
while(CUR_CHAR != SQUIRREL_EOB) {
switch(CUR_CHAR){
case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue;
case _SC('\n'):
_currentline++;
_prevtoken=_curtoken;
_curtoken=_SC('\n');
NEXT();
_currentcolumn=1;
continue;
case _SC('#'): LexLineComment(); continue;
case _SC('/'):
NEXT();
switch(CUR_CHAR){
case _SC('*'):
NEXT();
LexBlockComment();
continue;
case _SC('/'):
LexLineComment();
continue;
case _SC('='):
NEXT();
RETURN_TOKEN(TK_DIVEQ);
continue;
case _SC('>'):
NEXT();
RETURN_TOKEN(TK_ATTR_CLOSE);
continue;
default:
RETURN_TOKEN('/');
}
case _SC('='):
NEXT();
if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') }
else { NEXT(); RETURN_TOKEN(TK_EQ); }
case _SC('<'):
NEXT();
switch(CUR_CHAR) {
case _SC('='):
NEXT();
if(CUR_CHAR == _SC('>')) {
NEXT();
RETURN_TOKEN(TK_3WAYSCMP);
}
RETURN_TOKEN(TK_LE)
break;
case _SC('-'): NEXT(); RETURN_TOKEN(TK_NEWSLOT); break;
case _SC('<'): NEXT(); RETURN_TOKEN(TK_SHIFTL); break;
case _SC('/'): NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); break;
}
RETURN_TOKEN('<');
case _SC('>'):
NEXT();
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);}
else if(CUR_CHAR == _SC('>')){
NEXT();
if(CUR_CHAR == _SC('>')){
NEXT();
RETURN_TOKEN(TK_USHIFTR);
}
RETURN_TOKEN(TK_SHIFTR);
}
else { RETURN_TOKEN('>') }
case _SC('!'):
NEXT();
if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')}
else { NEXT(); RETURN_TOKEN(TK_NE); }
case _SC('@'): {
SQInteger stype;
NEXT();
if(CUR_CHAR != _SC('"')) {
RETURN_TOKEN('@');
}
if((stype=ReadString('"',true))!=-1) {
RETURN_TOKEN(stype);
}
Error(_SC("error parsing the string"));
}
case _SC('"'):
case _SC('\''): {
SQInteger stype;
if((stype=ReadString(CUR_CHAR,false))!=-1){
RETURN_TOKEN(stype);
}
Error(_SC("error parsing the string"));
}
case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'):
case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'):
{SQInteger ret = CUR_CHAR;
NEXT(); RETURN_TOKEN(ret); }
case _SC('.'):
NEXT();
if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') }
NEXT();
if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); }
NEXT();
RETURN_TOKEN(TK_VARPARAMS);
case _SC('&'):
NEXT();
if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') }
else { NEXT(); RETURN_TOKEN(TK_AND); }
case _SC('|'):
NEXT();
if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') }
else { NEXT(); RETURN_TOKEN(TK_OR); }
case _SC(':'):
NEXT();
if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') }
else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); }
case _SC('*'):
NEXT();
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);}
else RETURN_TOKEN('*');
case _SC('%'):
NEXT();
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);}
else RETURN_TOKEN('%');
case _SC('-'):
NEXT();
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);}
else if (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);}
else RETURN_TOKEN('-');
case _SC('+'):
NEXT();
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);}
else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);}
else RETURN_TOKEN('+');
case SQUIRREL_EOB:
return 0;
default:{
if (scisdigit(CUR_CHAR)) {
SQInteger ret = ReadNumber();
RETURN_TOKEN(ret);
}
else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) {
SQInteger t = ReadID();
RETURN_TOKEN(t);
}
else {
SQInteger c = CUR_CHAR;
if (sciscntrl((int)c)) Error(_SC("unexpected character(control)"));
NEXT();
RETURN_TOKEN(c);
}
RETURN_TOKEN(0);
}
}
}
return 0;
_lasttokenline = _currentline;
while(CUR_CHAR != SQUIRREL_EOB) {
switch(CUR_CHAR){
case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue;
case _SC('\n'):
_currentline++;
_prevtoken=_curtoken;
_curtoken=_SC('\n');
NEXT();
_currentcolumn=1;
continue;
case _SC('#'): LexLineComment(); continue;
case _SC('/'):
NEXT();
switch(CUR_CHAR){
case _SC('*'):
NEXT();
LexBlockComment();
continue;
case _SC('/'):
LexLineComment();
continue;
case _SC('='):
NEXT();
RETURN_TOKEN(TK_DIVEQ);
continue;
case _SC('>'):
NEXT();
RETURN_TOKEN(TK_ATTR_CLOSE);
continue;
default:
RETURN_TOKEN('/');
}
case _SC('='):
NEXT();
if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') }
else { NEXT(); RETURN_TOKEN(TK_EQ); }
case _SC('<'):
NEXT();
switch(CUR_CHAR) {
case _SC('='):
NEXT();
if(CUR_CHAR == _SC('>')) {
NEXT();
RETURN_TOKEN(TK_3WAYSCMP);
}
RETURN_TOKEN(TK_LE)
break;
case _SC('-'): NEXT(); RETURN_TOKEN(TK_NEWSLOT); break;
case _SC('<'): NEXT(); RETURN_TOKEN(TK_SHIFTL); break;
case _SC('/'): NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); break;
}
RETURN_TOKEN('<');
case _SC('>'):
NEXT();
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);}
else if(CUR_CHAR == _SC('>')){
NEXT();
if(CUR_CHAR == _SC('>')){
NEXT();
RETURN_TOKEN(TK_USHIFTR);
}
RETURN_TOKEN(TK_SHIFTR);
}
else { RETURN_TOKEN('>') }
case _SC('!'):
NEXT();
if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')}
else { NEXT(); RETURN_TOKEN(TK_NE); }
case _SC('@'): {
SQInteger stype;
NEXT();
if(CUR_CHAR != _SC('"')) {
RETURN_TOKEN('@');
}
if((stype=ReadString('"',true))!=-1) {
RETURN_TOKEN(stype);
}
Error(_SC("error parsing the string"));
}
case _SC('"'):
case _SC('\''): {
SQInteger stype;
if((stype=ReadString(CUR_CHAR,false))!=-1){
RETURN_TOKEN(stype);
}
Error(_SC("error parsing the string"));
}
case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'):
case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'):
{SQInteger ret = CUR_CHAR;
NEXT(); RETURN_TOKEN(ret); }
case _SC('.'):
NEXT();
if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') }
NEXT();
if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); }
NEXT();
RETURN_TOKEN(TK_VARPARAMS);
case _SC('&'):
NEXT();
if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') }
else { NEXT(); RETURN_TOKEN(TK_AND); }
case _SC('|'):
NEXT();
if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') }
else { NEXT(); RETURN_TOKEN(TK_OR); }
case _SC(':'):
NEXT();
if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') }
else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); }
case _SC('*'):
NEXT();
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);}
else RETURN_TOKEN('*');
case _SC('%'):
NEXT();
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);}
else RETURN_TOKEN('%');
case _SC('-'):
NEXT();
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);}
else if (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);}
else RETURN_TOKEN('-');
case _SC('+'):
NEXT();
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);}
else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);}
else RETURN_TOKEN('+');
case SQUIRREL_EOB:
return 0;
default:{
if (scisdigit(CUR_CHAR)) {
SQInteger ret = ReadNumber();
RETURN_TOKEN(ret);
}
else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) {
SQInteger t = ReadID();
RETURN_TOKEN(t);
}
else {
SQInteger c = CUR_CHAR;
if (sciscntrl((int)c)) Error(_SC("unexpected character(control)"));
NEXT();
RETURN_TOKEN(c);
}
RETURN_TOKEN(0);
}
}
}
return 0;
}
SQInteger SQLexer::GetIDType(const SQChar *s,SQInteger len)
{
SQObjectPtr t;
if(_keywords->GetStr(s,len, t)) {
return SQInteger(_integer(t));
}
return TK_IDENTIFIER;
SQObjectPtr t;
if(_keywords->GetStr(s,len, t)) {
return SQInteger(_integer(t));
}
return TK_IDENTIFIER;
}
SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
{
INIT_TEMP_STRING();
NEXT();
if(IS_EOB()) return -1;
for(;;) {
while(CUR_CHAR != ndelim) {
switch(CUR_CHAR) {
case SQUIRREL_EOB:
Error(_SC("unfinished string"));
return -1;
case _SC('\n'):
if(!verbatim) Error(_SC("newline in a constant"));
APPEND_CHAR(CUR_CHAR); NEXT();
_currentline++;
break;
case _SC('\\'):
if(verbatim) {
APPEND_CHAR('\\'); NEXT();
}
else {
NEXT();
switch(CUR_CHAR) {
case _SC('x'): NEXT(); {
if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected"));
const SQInteger maxdigits = 4;
SQChar temp[maxdigits+1];
SQInteger n = 0;
while(isxdigit(CUR_CHAR) && n < maxdigits) {
temp[n] = CUR_CHAR;
n++;
NEXT();
}
temp[n] = 0;
SQChar *sTemp;
APPEND_CHAR((SQChar)scstrtoul(temp,&sTemp,16));
}
break;
case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break;
case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break;
case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break;
case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break;
case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break;
case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break;
case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break;
case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break;
case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break;
case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break;
case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break;
default:
Error(_SC("unrecognised escaper char"));
break;
}
}
break;
default:
APPEND_CHAR(CUR_CHAR);
NEXT();
}
}
NEXT();
if(verbatim && CUR_CHAR == '"') { //double quotation
APPEND_CHAR(CUR_CHAR);
NEXT();
}
else {
break;
}
}
TERMINATE_BUFFER();
SQInteger len = _longstr.size()-1;
if(ndelim == _SC('\'')) {
if(len == 0) Error(_SC("empty constant"));
if(len > 1) Error(_SC("constant too long"));
_nvalue = _longstr[0];
return TK_INTEGER;
}
_svalue = &_longstr[0];
return TK_STRING_LITERAL;
INIT_TEMP_STRING();
NEXT();
if(IS_EOB()) return -1;
for(;;) {
while(CUR_CHAR != ndelim) {
switch(CUR_CHAR) {
case SQUIRREL_EOB:
Error(_SC("unfinished string"));
return -1;
case _SC('\n'):
if(!verbatim) Error(_SC("newline in a constant"));
APPEND_CHAR(CUR_CHAR); NEXT();
_currentline++;
break;
case _SC('\\'):
if(verbatim) {
APPEND_CHAR('\\'); NEXT();
}
else {
NEXT();
switch(CUR_CHAR) {
case _SC('x'): NEXT(); {
if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected"));
const SQInteger maxdigits = 4;
SQChar temp[maxdigits+1];
SQInteger n = 0;
while(isxdigit(CUR_CHAR) && n < maxdigits) {
temp[n] = CUR_CHAR;
n++;
NEXT();
}
temp[n] = 0;
SQChar *sTemp;
APPEND_CHAR((SQChar)scstrtoul(temp,&sTemp,16));
}
break;
case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break;
case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break;
case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break;
case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break;
case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break;
case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break;
case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break;
case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break;
case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break;
case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break;
case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break;
default:
Error(_SC("unrecognised escaper char"));
break;
}
}
break;
default:
APPEND_CHAR(CUR_CHAR);
NEXT();
}
}
NEXT();
if(verbatim && CUR_CHAR == '"') { //double quotation
APPEND_CHAR(CUR_CHAR);
NEXT();
}
else {
break;
}
}
TERMINATE_BUFFER();
SQInteger len = _longstr.size()-1;
if(ndelim == _SC('\'')) {
if(len == 0) Error(_SC("empty constant"));
if(len > 1) Error(_SC("constant too long"));
_nvalue = _longstr[0];
return TK_INTEGER;
}
_svalue = &_longstr[0];
return TK_STRING_LITERAL;
}
void LexHexadecimal(const SQChar *s,SQUnsignedInteger *res)
{
*res = 0;
while(*s != 0)
{
if(scisdigit(*s)) *res = (*res)*16+((*s++)-'0');
else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-'A'+10);
else { assert(0); }
}
*res = 0;
while(*s != 0)
{
if(scisdigit(*s)) *res = (*res)*16+((*s++)-'0');
else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-'A'+10);
else { assert(0); }
}
}
void LexInteger(const SQChar *s,SQUnsignedInteger *res)
{
*res = 0;
while(*s != 0)
{
*res = (*res)*10+((*s++)-'0');
}
*res = 0;
while(*s != 0)
{
*res = (*res)*10+((*s++)-'0');
}
}
SQInteger scisodigit(SQInteger c) { return c >= _SC('0') && c <= _SC('7'); }
void LexOctal(const SQChar *s,SQUnsignedInteger *res)
{
*res = 0;
while(*s != 0)
{
if(scisodigit(*s)) *res = (*res)*8+((*s++)-'0');
else { assert(0); }
}
*res = 0;
while(*s != 0)
{
if(scisodigit(*s)) *res = (*res)*8+((*s++)-'0');
else { assert(0); }
}
}
SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; }
@ -412,80 +412,80 @@ SQInteger SQLexer::ReadNumber()
#define THEX 3
#define TSCIENTIFIC 4
#define TOCTAL 5
SQInteger type = TINT, firstchar = CUR_CHAR;
SQChar *sTemp;
INIT_TEMP_STRING();
NEXT();
if(firstchar == _SC('0') && (toupper(CUR_CHAR) == _SC('X') || scisodigit(CUR_CHAR)) ) {
if(scisodigit(CUR_CHAR)) {
type = TOCTAL;
while(scisodigit(CUR_CHAR)) {
APPEND_CHAR(CUR_CHAR);
NEXT();
}
if(scisdigit(CUR_CHAR)) Error(_SC("invalid octal number"));
}
else {
NEXT();
type = THEX;
while(isxdigit(CUR_CHAR)) {
APPEND_CHAR(CUR_CHAR);
NEXT();
}
if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number"));
}
}
else {
APPEND_CHAR((int)firstchar);
while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) {
SQInteger type = TINT, firstchar = CUR_CHAR;
SQChar *sTemp;
INIT_TEMP_STRING();
NEXT();
if(firstchar == _SC('0') && (toupper(CUR_CHAR) == _SC('X') || scisodigit(CUR_CHAR)) ) {
if(scisodigit(CUR_CHAR)) {
type = TOCTAL;
while(scisodigit(CUR_CHAR)) {
APPEND_CHAR(CUR_CHAR);
NEXT();
}
if(scisdigit(CUR_CHAR)) Error(_SC("invalid octal number"));
}
else {
NEXT();
type = THEX;
while(isxdigit(CUR_CHAR)) {
APPEND_CHAR(CUR_CHAR);
NEXT();
}
if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number"));
}
}
else {
APPEND_CHAR((int)firstchar);
while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) {
if(CUR_CHAR == _SC('.') || isexponent(CUR_CHAR)) type = TFLOAT;
if(isexponent(CUR_CHAR)) {
if(type != TFLOAT) Error(_SC("invalid numeric format"));
type = TSCIENTIFIC;
APPEND_CHAR(CUR_CHAR);
NEXT();
if(CUR_CHAR == '+' || CUR_CHAR == '-'){
APPEND_CHAR(CUR_CHAR);
NEXT();
}
if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected"));
}
if(isexponent(CUR_CHAR)) {
if(type != TFLOAT) Error(_SC("invalid numeric format"));
type = TSCIENTIFIC;
APPEND_CHAR(CUR_CHAR);
NEXT();
if(CUR_CHAR == '+' || CUR_CHAR == '-'){
APPEND_CHAR(CUR_CHAR);
NEXT();
}
if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected"));
}
APPEND_CHAR(CUR_CHAR);
NEXT();
}
}
TERMINATE_BUFFER();
switch(type) {
case TSCIENTIFIC:
case TFLOAT:
_fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp);
return TK_FLOAT;
case TINT:
LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
return TK_INTEGER;
case THEX:
LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
return TK_INTEGER;
case TOCTAL:
LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
return TK_INTEGER;
}
return 0;
APPEND_CHAR(CUR_CHAR);
NEXT();
}
}
TERMINATE_BUFFER();
switch(type) {
case TSCIENTIFIC:
case TFLOAT:
_fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp);
return TK_FLOAT;
case TINT:
LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
return TK_INTEGER;
case THEX:
LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
return TK_INTEGER;
case TOCTAL:
LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
return TK_INTEGER;
}
return 0;
}
SQInteger SQLexer::ReadID()
{
SQInteger res;
INIT_TEMP_STRING();
do {
APPEND_CHAR(CUR_CHAR);
NEXT();
} while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_'));
TERMINATE_BUFFER();
res = GetIDType(&_longstr[0],_longstr.size() - 1);
if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) {
_svalue = &_longstr[0];
}
return res;
SQInteger res;
INIT_TEMP_STRING();
do {
APPEND_CHAR(CUR_CHAR);
NEXT();
} while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_'));
TERMINATE_BUFFER();
res = GetIDType(&_longstr[0],_longstr.size() - 1);
if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) {
_svalue = &_longstr[0];
}
return res;
}

View File

@ -1,47 +1,47 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQLEXER_H_
#define _SQLEXER_H_
#ifdef SQUNICODE
typedef SQChar LexChar;
#else
typedef unsigned char LexChar;
typedef unsigned char LexChar;
#endif
struct SQLexer
{
SQLexer();
~SQLexer();
void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed);
void Error(const SQChar *err);
SQInteger Lex();
const SQChar *Tok2Str(SQInteger tok);
SQLexer();
~SQLexer();
void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed);
void Error(const SQChar *err);
SQInteger Lex();
const SQChar *Tok2Str(SQInteger tok);
private:
SQInteger GetIDType(const SQChar *s,SQInteger len);
SQInteger ReadString(SQInteger ndelim,bool verbatim);
SQInteger ReadNumber();
void LexBlockComment();
void LexLineComment();
SQInteger ReadID();
void Next();
SQInteger _curtoken;
SQTable *_keywords;
SQBool _reached_eof;
SQInteger GetIDType(const SQChar *s,SQInteger len);
SQInteger ReadString(SQInteger ndelim,bool verbatim);
SQInteger ReadNumber();
void LexBlockComment();
void LexLineComment();
SQInteger ReadID();
void Next();
SQInteger _curtoken;
SQTable *_keywords;
SQBool _reached_eof;
public:
SQInteger _prevtoken;
SQInteger _currentline;
SQInteger _lasttokenline;
SQInteger _currentcolumn;
const SQChar *_svalue;
SQInteger _nvalue;
SQFloat _fvalue;
SQLEXREADFUNC _readf;
SQUserPointer _up;
LexChar _currdata;
SQSharedState *_sharedstate;
sqvector<SQChar> _longstr;
CompilerErrorFunc _errfunc;
void *_errtarget;
SQInteger _prevtoken;
SQInteger _currentline;
SQInteger _lasttokenline;
SQInteger _currentcolumn;
const SQChar *_svalue;
SQInteger _nvalue;
SQFloat _fvalue;
SQLEXREADFUNC _readf;
SQUserPointer _up;
LexChar _currdata;
SQSharedState *_sharedstate;
sqvector<SQChar> _longstr;
CompilerErrorFunc _errfunc;
void *_errtarget;
};
#endif

View File

@ -1,11 +1,11 @@
/*
see copyright notice in squirrel.h
see copyright notice in squirrel.h
*/
#include "sqpcheader.h"
#ifndef SQ_EXCLUDE_DEFAULT_MEMFUNCTIONS
void *sq_vm_malloc(SQUnsignedInteger size){ return malloc(size); }
void *sq_vm_malloc(SQUnsignedInteger size){ return malloc(size); }
void *sq_vm_realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger size){ return realloc(p, size); }
void sq_vm_free(void *p, SQUnsignedInteger size){ free(p); }
void sq_vm_free(void *p, SQUnsignedInteger size){ free(p); }
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQOBJECT_H_
#define _SQOBJECT_H_
@ -17,115 +17,115 @@
struct SQSharedState;
enum SQMetaMethod{
MT_ADD=0,
MT_SUB=1,
MT_MUL=2,
MT_DIV=3,
MT_UNM=4,
MT_MODULO=5,
MT_SET=6,
MT_GET=7,
MT_TYPEOF=8,
MT_NEXTI=9,
MT_CMP=10,
MT_CALL=11,
MT_CLONED=12,
MT_NEWSLOT=13,
MT_DELSLOT=14,
MT_TOSTRING=15,
MT_NEWMEMBER=16,
MT_INHERITED=17,
MT_LAST = 18
MT_ADD=0,
MT_SUB=1,
MT_MUL=2,
MT_DIV=3,
MT_UNM=4,
MT_MODULO=5,
MT_SET=6,
MT_GET=7,
MT_TYPEOF=8,
MT_NEXTI=9,
MT_CMP=10,
MT_CALL=11,
MT_CLONED=12,
MT_NEWSLOT=13,
MT_DELSLOT=14,
MT_TOSTRING=15,
MT_NEWMEMBER=16,
MT_INHERITED=17,
MT_LAST = 18
};
#define MM_ADD _SC("_add")
#define MM_SUB _SC("_sub")
#define MM_MUL _SC("_mul")
#define MM_DIV _SC("_div")
#define MM_UNM _SC("_unm")
#define MM_MODULO _SC("_modulo")
#define MM_SET _SC("_set")
#define MM_GET _SC("_get")
#define MM_TYPEOF _SC("_typeof")
#define MM_NEXTI _SC("_nexti")
#define MM_CMP _SC("_cmp")
#define MM_CALL _SC("_call")
#define MM_CLONED _SC("_cloned")
#define MM_NEWSLOT _SC("_newslot")
#define MM_DELSLOT _SC("_delslot")
#define MM_TOSTRING _SC("_tostring")
#define MM_ADD _SC("_add")
#define MM_SUB _SC("_sub")
#define MM_MUL _SC("_mul")
#define MM_DIV _SC("_div")
#define MM_UNM _SC("_unm")
#define MM_MODULO _SC("_modulo")
#define MM_SET _SC("_set")
#define MM_GET _SC("_get")
#define MM_TYPEOF _SC("_typeof")
#define MM_NEXTI _SC("_nexti")
#define MM_CMP _SC("_cmp")
#define MM_CALL _SC("_call")
#define MM_CLONED _SC("_cloned")
#define MM_NEWSLOT _SC("_newslot")
#define MM_DELSLOT _SC("_delslot")
#define MM_TOSTRING _SC("_tostring")
#define MM_NEWMEMBER _SC("_newmember")
#define MM_INHERITED _SC("_inherited")
#define _CONSTRUCT_VECTOR(type,size,ptr) { \
for(SQInteger n = 0; n < ((SQInteger)size); n++) { \
new (&ptr[n]) type(); \
} \
for(SQInteger n = 0; n < ((SQInteger)size); n++) { \
new (&ptr[n]) type(); \
} \
}
#define _DESTRUCT_VECTOR(type,size,ptr) { \
for(SQInteger nl = 0; nl < ((SQInteger)size); nl++) { \
ptr[nl].~type(); \
} \
for(SQInteger nl = 0; nl < ((SQInteger)size); nl++) { \
ptr[nl].~type(); \
} \
}
#define _COPY_VECTOR(dest,src,size) { \
for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \
dest[_n_] = src[_n_]; \
} \
for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \
dest[_n_] = src[_n_]; \
} \
}
#define _NULL_SQOBJECT_VECTOR(vec,size) { \
for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \
vec[_n_].Null(); \
} \
for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \
vec[_n_].Null(); \
} \
}
#define MINPOWER2 4
struct SQRefCounted
{
SQUnsignedInteger _uiRef;
struct SQWeakRef *_weakref;
SQRefCounted() { _uiRef = 0; _weakref = NULL; }
virtual ~SQRefCounted();
SQWeakRef *GetWeakRef(SQObjectType type);
virtual void Release()=0;
SQUnsignedInteger _uiRef;
struct SQWeakRef *_weakref;
SQRefCounted() { _uiRef = 0; _weakref = NULL; }
virtual ~SQRefCounted();
SQWeakRef *GetWeakRef(SQObjectType type);
virtual void Release()=0;
};
struct SQWeakRef : SQRefCounted
{
void Release();
SQObject _obj;
void Release();
SQObject _obj;
};
#define _realval(o) (type((o)) != OT_WEAKREF?(SQObject)o:_weakref(o)->_obj)
struct SQObjectPtr;
#define __AddRef(type,unval) if(ISREFCOUNTED(type)) \
{ \
unval.pRefCounted->_uiRef++; \
}
#define __AddRef(type,unval) if(ISREFCOUNTED(type)) \
{ \
unval.pRefCounted->_uiRef++; \
}
#define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)==0)) \
{ \
unval.pRefCounted->Release(); \
}
#define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)==0)) \
{ \
unval.pRefCounted->Release(); \
}
#define __ObjRelease(obj) { \
if((obj)) { \
(obj)->_uiRef--; \
if((obj)->_uiRef == 0) \
(obj)->Release(); \
(obj) = NULL; \
} \
if((obj)) { \
(obj)->_uiRef--; \
if((obj)->_uiRef == 0) \
(obj)->Release(); \
(obj) = NULL; \
} \
}
#define __ObjAddRef(obj) { \
(obj)->_uiRef++; \
(obj)->_uiRef++; \
}
#define type(obj) ((obj)._type)
@ -160,168 +160,168 @@ struct SQObjectPtr;
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
#if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64)
#define SQ_REFOBJECT_INIT() SQ_OBJECT_RAWINIT()
#define SQ_REFOBJECT_INIT() SQ_OBJECT_RAWINIT()
#else
#define SQ_REFOBJECT_INIT()
#endif
#define _REF_TYPE_DECL(type,_class,sym) \
SQObjectPtr(_class * x) \
{ \
SQ_OBJECT_RAWINIT() \
_type=type; \
_unVal.sym = x; \
assert(_unVal.pTable); \
_unVal.pRefCounted->_uiRef++; \
} \
inline SQObjectPtr& operator=(_class *x) \
{ \
SQObjectType tOldType; \
SQObjectValue unOldVal; \
tOldType=_type; \
unOldVal=_unVal; \
_type = type; \
SQ_REFOBJECT_INIT() \
_unVal.sym = x; \
_unVal.pRefCounted->_uiRef++; \
__Release(tOldType,unOldVal); \
return *this; \
}
SQObjectPtr(_class * x) \
{ \
SQ_OBJECT_RAWINIT() \
_type=type; \
_unVal.sym = x; \
assert(_unVal.pTable); \
_unVal.pRefCounted->_uiRef++; \
} \
inline SQObjectPtr& operator=(_class *x) \
{ \
SQObjectType tOldType; \
SQObjectValue unOldVal; \
tOldType=_type; \
unOldVal=_unVal; \
_type = type; \
SQ_REFOBJECT_INIT() \
_unVal.sym = x; \
_unVal.pRefCounted->_uiRef++; \
__Release(tOldType,unOldVal); \
return *this; \
}
#define _SCALAR_TYPE_DECL(type,_class,sym) \
SQObjectPtr(_class x) \
{ \
SQ_OBJECT_RAWINIT() \
_type=type; \
_unVal.sym = x; \
} \
inline SQObjectPtr& operator=(_class x) \
{ \
__Release(_type,_unVal); \
_type = type; \
SQ_OBJECT_RAWINIT() \
_unVal.sym = x; \
return *this; \
}
SQObjectPtr(_class x) \
{ \
SQ_OBJECT_RAWINIT() \
_type=type; \
_unVal.sym = x; \
} \
inline SQObjectPtr& operator=(_class x) \
{ \
__Release(_type,_unVal); \
_type = type; \
SQ_OBJECT_RAWINIT() \
_unVal.sym = x; \
return *this; \
}
struct SQObjectPtr : public SQObject
{
SQObjectPtr()
{
SQ_OBJECT_RAWINIT()
_type=OT_NULL;
_unVal.pUserPointer=NULL;
}
SQObjectPtr(const SQObjectPtr &o)
{
_type = o._type;
_unVal = o._unVal;
__AddRef(_type,_unVal);
}
SQObjectPtr(const SQObject &o)
{
_type = o._type;
_unVal = o._unVal;
__AddRef(_type,_unVal);
}
_REF_TYPE_DECL(OT_TABLE,SQTable,pTable)
_REF_TYPE_DECL(OT_CLASS,SQClass,pClass)
_REF_TYPE_DECL(OT_INSTANCE,SQInstance,pInstance)
_REF_TYPE_DECL(OT_ARRAY,SQArray,pArray)
_REF_TYPE_DECL(OT_CLOSURE,SQClosure,pClosure)
_REF_TYPE_DECL(OT_NATIVECLOSURE,SQNativeClosure,pNativeClosure)
_REF_TYPE_DECL(OT_OUTER,SQOuter,pOuter)
_REF_TYPE_DECL(OT_GENERATOR,SQGenerator,pGenerator)
_REF_TYPE_DECL(OT_STRING,SQString,pString)
_REF_TYPE_DECL(OT_USERDATA,SQUserData,pUserData)
_REF_TYPE_DECL(OT_WEAKREF,SQWeakRef,pWeakRef)
_REF_TYPE_DECL(OT_THREAD,SQVM,pThread)
_REF_TYPE_DECL(OT_FUNCPROTO,SQFunctionProto,pFunctionProto)
SQObjectPtr()
{
SQ_OBJECT_RAWINIT()
_type=OT_NULL;
_unVal.pUserPointer=NULL;
}
SQObjectPtr(const SQObjectPtr &o)
{
_type = o._type;
_unVal = o._unVal;
__AddRef(_type,_unVal);
}
SQObjectPtr(const SQObject &o)
{
_type = o._type;
_unVal = o._unVal;
__AddRef(_type,_unVal);
}
_REF_TYPE_DECL(OT_TABLE,SQTable,pTable)
_REF_TYPE_DECL(OT_CLASS,SQClass,pClass)
_REF_TYPE_DECL(OT_INSTANCE,SQInstance,pInstance)
_REF_TYPE_DECL(OT_ARRAY,SQArray,pArray)
_REF_TYPE_DECL(OT_CLOSURE,SQClosure,pClosure)
_REF_TYPE_DECL(OT_NATIVECLOSURE,SQNativeClosure,pNativeClosure)
_REF_TYPE_DECL(OT_OUTER,SQOuter,pOuter)
_REF_TYPE_DECL(OT_GENERATOR,SQGenerator,pGenerator)
_REF_TYPE_DECL(OT_STRING,SQString,pString)
_REF_TYPE_DECL(OT_USERDATA,SQUserData,pUserData)
_REF_TYPE_DECL(OT_WEAKREF,SQWeakRef,pWeakRef)
_REF_TYPE_DECL(OT_THREAD,SQVM,pThread)
_REF_TYPE_DECL(OT_FUNCPROTO,SQFunctionProto,pFunctionProto)
_SCALAR_TYPE_DECL(OT_INTEGER,SQInteger,nInteger)
_SCALAR_TYPE_DECL(OT_FLOAT,SQFloat,fFloat)
_SCALAR_TYPE_DECL(OT_USERPOINTER,SQUserPointer,pUserPointer)
_SCALAR_TYPE_DECL(OT_INTEGER,SQInteger,nInteger)
_SCALAR_TYPE_DECL(OT_FLOAT,SQFloat,fFloat)
_SCALAR_TYPE_DECL(OT_USERPOINTER,SQUserPointer,pUserPointer)
SQObjectPtr(bool bBool)
{
SQ_OBJECT_RAWINIT()
_type = OT_BOOL;
_unVal.nInteger = bBool?1:0;
}
inline SQObjectPtr& operator=(bool b)
{
__Release(_type,_unVal);
SQ_OBJECT_RAWINIT()
_type = OT_BOOL;
_unVal.nInteger = b?1:0;
return *this;
}
SQObjectPtr(bool bBool)
{
SQ_OBJECT_RAWINIT()
_type = OT_BOOL;
_unVal.nInteger = bBool?1:0;
}
inline SQObjectPtr& operator=(bool b)
{
__Release(_type,_unVal);
SQ_OBJECT_RAWINIT()
_type = OT_BOOL;
_unVal.nInteger = b?1:0;
return *this;
}
~SQObjectPtr()
{
__Release(_type,_unVal);
}
~SQObjectPtr()
{
__Release(_type,_unVal);
}
inline SQObjectPtr& operator=(const SQObjectPtr& obj)
{
SQObjectType tOldType;
SQObjectValue unOldVal;
tOldType=_type;
unOldVal=_unVal;
_unVal = obj._unVal;
_type = obj._type;
__AddRef(_type,_unVal);
__Release(tOldType,unOldVal);
return *this;
}
inline SQObjectPtr& operator=(const SQObject& obj)
{
SQObjectType tOldType;
SQObjectValue unOldVal;
tOldType=_type;
unOldVal=_unVal;
_unVal = obj._unVal;
_type = obj._type;
__AddRef(_type,_unVal);
__Release(tOldType,unOldVal);
return *this;
}
inline void Null()
{
SQObjectType tOldType = _type;
SQObjectValue unOldVal = _unVal;
_type = OT_NULL;
_unVal.raw = (SQRawObjectVal)NULL;
__Release(tOldType ,unOldVal);
}
private:
SQObjectPtr(const SQChar *){} //safety
inline SQObjectPtr& operator=(const SQObjectPtr& obj)
{
SQObjectType tOldType;
SQObjectValue unOldVal;
tOldType=_type;
unOldVal=_unVal;
_unVal = obj._unVal;
_type = obj._type;
__AddRef(_type,_unVal);
__Release(tOldType,unOldVal);
return *this;
}
inline SQObjectPtr& operator=(const SQObject& obj)
{
SQObjectType tOldType;
SQObjectValue unOldVal;
tOldType=_type;
unOldVal=_unVal;
_unVal = obj._unVal;
_type = obj._type;
__AddRef(_type,_unVal);
__Release(tOldType,unOldVal);
return *this;
}
inline void Null()
{
SQObjectType tOldType = _type;
SQObjectValue unOldVal = _unVal;
_type = OT_NULL;
_unVal.raw = (SQRawObjectVal)NULL;
__Release(tOldType ,unOldVal);
}
private:
SQObjectPtr(const SQChar *){} //safety
};
inline void _Swap(SQObject &a,SQObject &b)
{
SQObjectType tOldType = a._type;
SQObjectValue unOldVal = a._unVal;
a._type = b._type;
a._unVal = b._unVal;
b._type = tOldType;
b._unVal = unOldVal;
SQObjectType tOldType = a._type;
SQObjectValue unOldVal = a._unVal;
a._type = b._type;
a._unVal = b._unVal;
b._type = tOldType;
b._unVal = unOldVal;
}
/////////////////////////////////////////////////////////////////////////////////////
#ifndef NO_GARBAGE_COLLECTOR
#define MARK_FLAG 0x80000000
struct SQCollectable : public SQRefCounted {
SQCollectable *_next;
SQCollectable *_prev;
SQSharedState *_sharedstate;
virtual SQObjectType GetType()=0;
virtual void Release()=0;
virtual void Mark(SQCollectable **chain)=0;
void UnMark();
virtual void Finalize()=0;
static void AddToChain(SQCollectable **chain,SQCollectable *c);
static void RemoveFromChain(SQCollectable **chain,SQCollectable *c);
SQCollectable *_next;
SQCollectable *_prev;
SQSharedState *_sharedstate;
virtual SQObjectType GetType()=0;
virtual void Release()=0;
virtual void Mark(SQCollectable **chain)=0;
void UnMark();
virtual void Finalize()=0;
static void AddToChain(SQCollectable **chain,SQCollectable *c);
static void RemoveFromChain(SQCollectable **chain,SQCollectable *c);
};
@ -338,9 +338,9 @@ struct SQCollectable : public SQRefCounted {
#endif
struct SQDelegable : public CHAINABLE_OBJ {
bool SetDelegate(SQTable *m);
virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
SQTable *_delegate;
bool SetDelegate(SQTable *m);
virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
SQTable *_delegate;
};
SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx);

View File

@ -1,4 +1,4 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQOPCODES_H_
#define _SQOPCODES_H_
@ -6,127 +6,127 @@
#define MAX_LITERALS ((SQInteger)0x7FFFFFFF)
enum BitWiseOP {
BW_AND = 0,
BW_OR = 2,
BW_XOR = 3,
BW_SHIFTL = 4,
BW_SHIFTR = 5,
BW_USHIFTR = 6
BW_AND = 0,
BW_OR = 2,
BW_XOR = 3,
BW_SHIFTL = 4,
BW_SHIFTR = 5,
BW_USHIFTR = 6
};
enum CmpOP {
CMP_G = 0,
CMP_GE = 2,
CMP_L = 3,
CMP_LE = 4,
CMP_3W = 5
CMP_G = 0,
CMP_GE = 2,
CMP_L = 3,
CMP_LE = 4,
CMP_3W = 5
};
enum NewObjectType {
NOT_TABLE = 0,
NOT_ARRAY = 1,
NOT_CLASS = 2
NOT_TABLE = 0,
NOT_ARRAY = 1,
NOT_CLASS = 2
};
enum AppendArrayType {
AAT_STACK = 0,
AAT_LITERAL = 1,
AAT_INT = 2,
AAT_FLOAT = 3,
AAT_BOOL = 4
AAT_STACK = 0,
AAT_LITERAL = 1,
AAT_INT = 2,
AAT_FLOAT = 3,
AAT_BOOL = 4
};
enum SQOpcode
{
_OP_LINE= 0x00,
_OP_LOAD= 0x01,
_OP_LOADINT= 0x02,
_OP_LOADFLOAT= 0x03,
_OP_DLOAD= 0x04,
_OP_TAILCALL= 0x05,
_OP_CALL= 0x06,
_OP_PREPCALL= 0x07,
_OP_PREPCALLK= 0x08,
_OP_GETK= 0x09,
_OP_MOVE= 0x0A,
_OP_NEWSLOT= 0x0B,
_OP_DELETE= 0x0C,
_OP_SET= 0x0D,
_OP_GET= 0x0E,
_OP_EQ= 0x0F,
_OP_NE= 0x10,
_OP_ADD= 0x11,
_OP_SUB= 0x12,
_OP_MUL= 0x13,
_OP_DIV= 0x14,
_OP_MOD= 0x15,
_OP_BITW= 0x16,
_OP_RETURN= 0x17,
_OP_LOADNULLS= 0x18,
_OP_LOADROOT= 0x19,
_OP_LOADBOOL= 0x1A,
_OP_DMOVE= 0x1B,
_OP_JMP= 0x1C,
//_OP_JNZ= 0x1D,
_OP_JCMP= 0x1D,
_OP_JZ= 0x1E,
_OP_SETOUTER= 0x1F,
_OP_GETOUTER= 0x20,
_OP_NEWOBJ= 0x21,
_OP_APPENDARRAY= 0x22,
_OP_COMPARITH= 0x23,
_OP_INC= 0x24,
_OP_INCL= 0x25,
_OP_PINC= 0x26,
_OP_PINCL= 0x27,
_OP_CMP= 0x28,
_OP_EXISTS= 0x29,
_OP_INSTANCEOF= 0x2A,
_OP_AND= 0x2B,
_OP_OR= 0x2C,
_OP_NEG= 0x2D,
_OP_NOT= 0x2E,
_OP_BWNOT= 0x2F,
_OP_CLOSURE= 0x30,
_OP_YIELD= 0x31,
_OP_RESUME= 0x32,
_OP_FOREACH= 0x33,
_OP_POSTFOREACH= 0x34,
_OP_CLONE= 0x35,
_OP_TYPEOF= 0x36,
_OP_PUSHTRAP= 0x37,
_OP_POPTRAP= 0x38,
_OP_THROW= 0x39,
_OP_NEWSLOTA= 0x3A,
_OP_GETBASE= 0x3B,
_OP_CLOSE= 0x3C
_OP_LINE= 0x00,
_OP_LOAD= 0x01,
_OP_LOADINT= 0x02,
_OP_LOADFLOAT= 0x03,
_OP_DLOAD= 0x04,
_OP_TAILCALL= 0x05,
_OP_CALL= 0x06,
_OP_PREPCALL= 0x07,
_OP_PREPCALLK= 0x08,
_OP_GETK= 0x09,
_OP_MOVE= 0x0A,
_OP_NEWSLOT= 0x0B,
_OP_DELETE= 0x0C,
_OP_SET= 0x0D,
_OP_GET= 0x0E,
_OP_EQ= 0x0F,
_OP_NE= 0x10,
_OP_ADD= 0x11,
_OP_SUB= 0x12,
_OP_MUL= 0x13,
_OP_DIV= 0x14,
_OP_MOD= 0x15,
_OP_BITW= 0x16,
_OP_RETURN= 0x17,
_OP_LOADNULLS= 0x18,
_OP_LOADROOT= 0x19,
_OP_LOADBOOL= 0x1A,
_OP_DMOVE= 0x1B,
_OP_JMP= 0x1C,
//_OP_JNZ= 0x1D,
_OP_JCMP= 0x1D,
_OP_JZ= 0x1E,
_OP_SETOUTER= 0x1F,
_OP_GETOUTER= 0x20,
_OP_NEWOBJ= 0x21,
_OP_APPENDARRAY= 0x22,
_OP_COMPARITH= 0x23,
_OP_INC= 0x24,
_OP_INCL= 0x25,
_OP_PINC= 0x26,
_OP_PINCL= 0x27,
_OP_CMP= 0x28,
_OP_EXISTS= 0x29,
_OP_INSTANCEOF= 0x2A,
_OP_AND= 0x2B,
_OP_OR= 0x2C,
_OP_NEG= 0x2D,
_OP_NOT= 0x2E,
_OP_BWNOT= 0x2F,
_OP_CLOSURE= 0x30,
_OP_YIELD= 0x31,
_OP_RESUME= 0x32,
_OP_FOREACH= 0x33,
_OP_POSTFOREACH= 0x34,
_OP_CLONE= 0x35,
_OP_TYPEOF= 0x36,
_OP_PUSHTRAP= 0x37,
_OP_POPTRAP= 0x38,
_OP_THROW= 0x39,
_OP_NEWSLOTA= 0x3A,
_OP_GETBASE= 0x3B,
_OP_CLOSE= 0x3C
};
struct SQInstructionDesc {
const SQChar *name;
const SQChar *name;
};
struct SQInstruction
{
SQInstruction(){};
SQInstruction(SQOpcode _op,SQInteger a0=0,SQInteger a1=0,SQInteger a2=0,SQInteger a3=0)
{ op = _op;
_arg0 = (unsigned char)a0;_arg1 = (SQInt32)a1;
_arg2 = (unsigned char)a2;_arg3 = (unsigned char)a3;
}
SQInstruction(){};
SQInstruction(SQOpcode _op,SQInteger a0=0,SQInteger a1=0,SQInteger a2=0,SQInteger a3=0)
{ op = _op;
_arg0 = (unsigned char)a0;_arg1 = (SQInt32)a1;
_arg2 = (unsigned char)a2;_arg3 = (unsigned char)a3;
}
SQInt32 _arg1;
unsigned char op;
unsigned char _arg0;
unsigned char _arg2;
unsigned char _arg3;
SQInt32 _arg1;
unsigned char op;
unsigned char _arg0;
unsigned char _arg2;
unsigned char _arg3;
};
#include "squtils.h"
typedef sqvector<SQInstruction> SQInstructionVec;
#define NEW_SLOT_ATTRIBUTES_FLAG 0x01
#define NEW_SLOT_STATIC_FLAG 0x02
#define NEW_SLOT_ATTRIBUTES_FLAG 0x01
#define NEW_SLOT_STATIC_FLAG 0x02
#endif // _SQOPCODES_H_

View File

@ -1,4 +1,4 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQPCHEADER_H_
#define _SQPCHEADER_H_

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQSTATE_H_
#define _SQSTATE_H_
@ -11,44 +11,44 @@ struct SQTable;
struct SQStringTable
{
SQStringTable(SQSharedState*ss);
~SQStringTable();
SQString *Add(const SQChar *,SQInteger len);
void Remove(SQString *);
SQStringTable(SQSharedState*ss);
~SQStringTable();
SQString *Add(const SQChar *,SQInteger len);
void Remove(SQString *);
private:
void Resize(SQInteger size);
void AllocNodes(SQInteger size);
SQString **_strings;
SQUnsignedInteger _numofslots;
SQUnsignedInteger _slotused;
SQSharedState *_sharedstate;
void Resize(SQInteger size);
void AllocNodes(SQInteger size);
SQString **_strings;
SQUnsignedInteger _numofslots;
SQUnsignedInteger _slotused;
SQSharedState *_sharedstate;
};
struct RefTable {
struct RefNode {
SQObjectPtr obj;
SQUnsignedInteger refs;
struct RefNode *next;
};
RefTable();
~RefTable();
void AddRef(SQObject &obj);
SQBool Release(SQObject &obj);
SQUnsignedInteger GetRefCount(SQObject &obj);
struct RefNode {
SQObjectPtr obj;
SQUnsignedInteger refs;
struct RefNode *next;
};
RefTable();
~RefTable();
void AddRef(SQObject &obj);
SQBool Release(SQObject &obj);
SQUnsignedInteger GetRefCount(SQObject &obj);
#ifndef NO_GARBAGE_COLLECTOR
void Mark(SQCollectable **chain);
void Mark(SQCollectable **chain);
#endif
void Finalize();
void Finalize();
private:
RefNode *Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add);
RefNode *Add(SQHash mainpos,SQObject &obj);
void Resize(SQUnsignedInteger size);
void AllocNodes(SQUnsignedInteger size);
SQUnsignedInteger _numofslots;
SQUnsignedInteger _slotused;
RefNode *_nodes;
RefNode *_freelist;
RefNode **_buckets;
RefNode *Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add);
RefNode *Add(SQHash mainpos,SQObject &obj);
void Resize(SQUnsignedInteger size);
void AllocNodes(SQUnsignedInteger size);
SQUnsignedInteger _numofslots;
SQUnsignedInteger _slotused;
RefNode *_nodes;
RefNode *_freelist;
RefNode **_buckets;
};
#define ADD_STRING(ss,str,len) ss->_stringtable->Add(str,len)
@ -58,77 +58,77 @@ struct SQObjectPtr;
struct SQSharedState
{
SQSharedState();
~SQSharedState();
void Init();
SQSharedState();
~SQSharedState();
void Init();
public:
SQChar* GetScratchPad(SQInteger size);
SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name);
SQChar* GetScratchPad(SQInteger size);
SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name);
#ifndef NO_GARBAGE_COLLECTOR
SQInteger CollectGarbage(SQVM *vm);
void RunMark(SQVM *vm,SQCollectable **tchain);
SQInteger ResurrectUnreachable(SQVM *vm);
static void MarkObject(SQObjectPtr &o,SQCollectable **chain);
SQInteger CollectGarbage(SQVM *vm);
void RunMark(SQVM *vm,SQCollectable **tchain);
SQInteger ResurrectUnreachable(SQVM *vm);
static void MarkObject(SQObjectPtr &o,SQCollectable **chain);
#endif
SQObjectPtrVec *_metamethods;
SQObjectPtr _metamethodsmap;
SQObjectPtrVec *_systemstrings;
SQObjectPtrVec *_types;
SQStringTable *_stringtable;
RefTable _refs_table;
SQObjectPtr _registry;
SQObjectPtr _consts;
SQObjectPtr _constructoridx;
SQObjectPtrVec *_metamethods;
SQObjectPtr _metamethodsmap;
SQObjectPtrVec *_systemstrings;
SQObjectPtrVec *_types;
SQStringTable *_stringtable;
RefTable _refs_table;
SQObjectPtr _registry;
SQObjectPtr _consts;
SQObjectPtr _constructoridx;
#ifndef NO_GARBAGE_COLLECTOR
SQCollectable *_gc_chain;
SQCollectable *_gc_chain;
#endif
SQObjectPtr _root_vm;
SQObjectPtr _table_default_delegate;
static SQRegFunction _table_default_delegate_funcz[];
SQObjectPtr _array_default_delegate;
static SQRegFunction _array_default_delegate_funcz[];
SQObjectPtr _string_default_delegate;
static SQRegFunction _string_default_delegate_funcz[];
SQObjectPtr _number_default_delegate;
static SQRegFunction _number_default_delegate_funcz[];
SQObjectPtr _generator_default_delegate;
static SQRegFunction _generator_default_delegate_funcz[];
SQObjectPtr _closure_default_delegate;
static SQRegFunction _closure_default_delegate_funcz[];
SQObjectPtr _thread_default_delegate;
static SQRegFunction _thread_default_delegate_funcz[];
SQObjectPtr _class_default_delegate;
static SQRegFunction _class_default_delegate_funcz[];
SQObjectPtr _instance_default_delegate;
static SQRegFunction _instance_default_delegate_funcz[];
SQObjectPtr _weakref_default_delegate;
static SQRegFunction _weakref_default_delegate_funcz[];
SQObjectPtr _root_vm;
SQObjectPtr _table_default_delegate;
static const SQRegFunction _table_default_delegate_funcz[];
SQObjectPtr _array_default_delegate;
static const SQRegFunction _array_default_delegate_funcz[];
SQObjectPtr _string_default_delegate;
static const SQRegFunction _string_default_delegate_funcz[];
SQObjectPtr _number_default_delegate;
static const SQRegFunction _number_default_delegate_funcz[];
SQObjectPtr _generator_default_delegate;
static const SQRegFunction _generator_default_delegate_funcz[];
SQObjectPtr _closure_default_delegate;
static const SQRegFunction _closure_default_delegate_funcz[];
SQObjectPtr _thread_default_delegate;
static const SQRegFunction _thread_default_delegate_funcz[];
SQObjectPtr _class_default_delegate;
static const SQRegFunction _class_default_delegate_funcz[];
SQObjectPtr _instance_default_delegate;
static const SQRegFunction _instance_default_delegate_funcz[];
SQObjectPtr _weakref_default_delegate;
static const SQRegFunction _weakref_default_delegate_funcz[];
SQCOMPILERERROR _compilererrorhandler;
SQPRINTFUNCTION _printfunc;
SQPRINTFUNCTION _errorfunc;
bool _debuginfo;
bool _notifyallexceptions;
SQUserPointer _foreignptr;
SQRELEASEHOOK _releasehook;
SQCOMPILERERROR _compilererrorhandler;
SQPRINTFUNCTION _printfunc;
SQPRINTFUNCTION _errorfunc;
bool _debuginfo;
bool _notifyallexceptions;
SQUserPointer _foreignptr;
SQRELEASEHOOK _releasehook;
private:
SQChar *_scratchpad;
SQInteger _scratchpadsize;
SQChar *_scratchpad;
SQInteger _scratchpadsize;
};
#define _sp(s) (_sharedstate->GetScratchPad(s))
#define _spval (_sharedstate->GetScratchPad(-1))
#define _table_ddel _table(_sharedstate->_table_default_delegate)
#define _array_ddel _table(_sharedstate->_array_default_delegate)
#define _string_ddel _table(_sharedstate->_string_default_delegate)
#define _number_ddel _table(_sharedstate->_number_default_delegate)
#define _generator_ddel _table(_sharedstate->_generator_default_delegate)
#define _closure_ddel _table(_sharedstate->_closure_default_delegate)
#define _thread_ddel _table(_sharedstate->_thread_default_delegate)
#define _class_ddel _table(_sharedstate->_class_default_delegate)
#define _instance_ddel _table(_sharedstate->_instance_default_delegate)
#define _weakref_ddel _table(_sharedstate->_weakref_default_delegate)
#define _table_ddel _table(_sharedstate->_table_default_delegate)
#define _array_ddel _table(_sharedstate->_array_default_delegate)
#define _string_ddel _table(_sharedstate->_string_default_delegate)
#define _number_ddel _table(_sharedstate->_number_default_delegate)
#define _generator_ddel _table(_sharedstate->_generator_default_delegate)
#define _closure_ddel _table(_sharedstate->_closure_default_delegate)
#define _thread_ddel _table(_sharedstate->_thread_default_delegate)
#define _class_ddel _table(_sharedstate->_class_default_delegate)
#define _instance_ddel _table(_sharedstate->_instance_default_delegate)
#define _weakref_ddel _table(_sharedstate->_weakref_default_delegate)
bool CompileTypemask(SQIntVec &res,const SQChar *typemask);

View File

@ -1,29 +1,29 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQSTRING_H_
#define _SQSTRING_H_
inline SQHash _hashstr (const SQChar *s, size_t l)
{
SQHash h = (SQHash)l; /* seed */
size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */
for (; l>=step; l-=step)
h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++));
return h;
SQHash h = (SQHash)l; /* seed */
size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */
for (; l>=step; l-=step)
h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++));
return h;
}
struct SQString : public SQRefCounted
{
SQString(){}
~SQString(){}
SQString(){}
~SQString(){}
public:
static SQString *Create(SQSharedState *ss, const SQChar *, SQInteger len = -1 );
SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
void Release();
SQSharedState *_sharedstate;
SQString *_next; //chain for the string table
SQInteger _len;
SQHash _hash;
SQChar _val[1];
static SQString *Create(SQSharedState *ss, const SQChar *, SQInteger len = -1 );
SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
void Release();
SQSharedState *_sharedstate;
SQString *_next; //chain for the string table
SQInteger _len;
SQHash _hash;
SQChar _val[1];
};

View File

@ -9,213 +9,213 @@ see copyright notice in squirrel.h
SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize)
{
SQInteger pow2size=MINPOWER2;
while(nInitialSize>pow2size)pow2size=pow2size<<1;
AllocNodes(pow2size);
_usednodes = 0;
_delegate = NULL;
INIT_CHAIN();
ADD_TO_CHAIN(&_sharedstate->_gc_chain,this);
SQInteger pow2size=MINPOWER2;
while(nInitialSize>pow2size)pow2size=pow2size<<1;
AllocNodes(pow2size);
_usednodes = 0;
_delegate = NULL;
INIT_CHAIN();
ADD_TO_CHAIN(&_sharedstate->_gc_chain,this);
}
void SQTable::Remove(const SQObjectPtr &key)
{
_HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
if (n) {
n->val.Null();
n->key.Null();
_usednodes--;
Rehash(false);
}
_HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
if (n) {
n->val.Null();
n->key.Null();
_usednodes--;
Rehash(false);
}
}
void SQTable::AllocNodes(SQInteger nSize)
{
_HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize);
for(SQInteger i=0;i<nSize;i++){
_HashNode &n = nodes[i];
new (&n) _HashNode;
n.next=NULL;
}
_numofnodes=nSize;
_nodes=nodes;
_firstfree=&_nodes[_numofnodes-1];
_HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize);
for(SQInteger i=0;i<nSize;i++){
_HashNode &n = nodes[i];
new (&n) _HashNode;
n.next=NULL;
}
_numofnodes=nSize;
_nodes=nodes;
_firstfree=&_nodes[_numofnodes-1];
}
void SQTable::Rehash(bool force)
{
SQInteger oldsize=_numofnodes;
//prevent problems with the integer division
if(oldsize<4)oldsize=4;
_HashNode *nold=_nodes;
SQInteger nelems=CountUsed();
if (nelems >= oldsize-oldsize/4) /* using more than 3/4? */
AllocNodes(oldsize*2);
else if (nelems <= oldsize/4 && /* less than 1/4? */
oldsize > MINPOWER2)
AllocNodes(oldsize/2);
else if(force)
AllocNodes(oldsize);
else
return;
_usednodes = 0;
for (SQInteger i=0; i<oldsize; i++) {
_HashNode *old = nold+i;
if (type(old->key) != OT_NULL)
NewSlot(old->key,old->val);
}
for(SQInteger k=0;k<oldsize;k++)
nold[k].~_HashNode();
SQ_FREE(nold,oldsize*sizeof(_HashNode));
SQInteger oldsize=_numofnodes;
//prevent problems with the integer division
if(oldsize<4)oldsize=4;
_HashNode *nold=_nodes;
SQInteger nelems=CountUsed();
if (nelems >= oldsize-oldsize/4) /* using more than 3/4? */
AllocNodes(oldsize*2);
else if (nelems <= oldsize/4 && /* less than 1/4? */
oldsize > MINPOWER2)
AllocNodes(oldsize/2);
else if(force)
AllocNodes(oldsize);
else
return;
_usednodes = 0;
for (SQInteger i=0; i<oldsize; i++) {
_HashNode *old = nold+i;
if (type(old->key) != OT_NULL)
NewSlot(old->key,old->val);
}
for(SQInteger k=0;k<oldsize;k++)
nold[k].~_HashNode();
SQ_FREE(nold,oldsize*sizeof(_HashNode));
}
SQTable *SQTable::Clone()
{
SQTable *nt=Create(_opt_ss(this),_numofnodes);
SQTable *nt=Create(_opt_ss(this),_numofnodes);
#ifdef _FAST_CLONE
_HashNode *basesrc = _nodes;
_HashNode *basedst = nt->_nodes;
_HashNode *src = _nodes;
_HashNode *dst = nt->_nodes;
SQInteger n = 0;
for(n = 0; n < _numofnodes; n++) {
dst->key = src->key;
dst->val = src->val;
if(src->next) {
assert(src->next > basesrc);
dst->next = basedst + (src->next - basesrc);
assert(dst != dst->next);
}
dst++;
src++;
}
assert(_firstfree > basesrc);
assert(_firstfree != NULL);
nt->_firstfree = basedst + (_firstfree - basesrc);
nt->_usednodes = _usednodes;
_HashNode *basesrc = _nodes;
_HashNode *basedst = nt->_nodes;
_HashNode *src = _nodes;
_HashNode *dst = nt->_nodes;
SQInteger n = 0;
for(n = 0; n < _numofnodes; n++) {
dst->key = src->key;
dst->val = src->val;
if(src->next) {
assert(src->next > basesrc);
dst->next = basedst + (src->next - basesrc);
assert(dst != dst->next);
}
dst++;
src++;
}
assert(_firstfree > basesrc);
assert(_firstfree != NULL);
nt->_firstfree = basedst + (_firstfree - basesrc);
nt->_usednodes = _usednodes;
#else
SQInteger ridx=0;
SQObjectPtr key,val;
while((ridx=Next(true,ridx,key,val))!=-1){
nt->NewSlot(key,val);
}
SQInteger ridx=0;
SQObjectPtr key,val;
while((ridx=Next(true,ridx,key,val))!=-1){
nt->NewSlot(key,val);
}
#endif
nt->SetDelegate(_delegate);
return nt;
nt->SetDelegate(_delegate);
return nt;
}
bool SQTable::Get(const SQObjectPtr &key,SQObjectPtr &val)
{
if(type(key) == OT_NULL)
return false;
_HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
if (n) {
val = _realval(n->val);
return true;
}
return false;
if(type(key) == OT_NULL)
return false;
_HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
if (n) {
val = _realval(n->val);
return true;
}
return false;
}
bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
{
assert(type(key) != OT_NULL);
SQHash h = HashObj(key) & (_numofnodes - 1);
_HashNode *n = _Get(key, h);
if (n) {
n->val = val;
return false;
}
_HashNode *mp = &_nodes[h];
n = mp;
assert(type(key) != OT_NULL);
SQHash h = HashObj(key) & (_numofnodes - 1);
_HashNode *n = _Get(key, h);
if (n) {
n->val = val;
return false;
}
_HashNode *mp = &_nodes[h];
n = mp;
//key not found I'll insert it
//main pos is not free
//key not found I'll insert it
//main pos is not free
if(type(mp->key) != OT_NULL) {
n = _firstfree; /* get a free place */
SQHash mph = HashObj(mp->key) & (_numofnodes - 1);
_HashNode *othern; /* main position of colliding node */
if(type(mp->key) != OT_NULL) {
n = _firstfree; /* get a free place */
SQHash mph = HashObj(mp->key) & (_numofnodes - 1);
_HashNode *othern; /* main position of colliding node */
if (mp > n && (othern = &_nodes[mph]) != mp){
/* yes; move colliding node into free position */
while (othern->next != mp){
assert(othern->next != NULL);
othern = othern->next; /* find previous */
}
othern->next = n; /* redo the chain with `n' in place of `mp' */
n->key = mp->key;
n->val = mp->val;/* copy colliding node into free pos. (mp->next also goes) */
n->next = mp->next;
mp->key.Null();
mp->val.Null();
mp->next = NULL; /* now `mp' is free */
}
else{
/* new node will go into free position */
n->next = mp->next; /* chain new position */
mp->next = n;
mp = n;
}
}
mp->key = key;
if (mp > n && (othern = &_nodes[mph]) != mp){
/* yes; move colliding node into free position */
while (othern->next != mp){
assert(othern->next != NULL);
othern = othern->next; /* find previous */
}
othern->next = n; /* redo the chain with `n' in place of `mp' */
n->key = mp->key;
n->val = mp->val;/* copy colliding node into free pos. (mp->next also goes) */
n->next = mp->next;
mp->key.Null();
mp->val.Null();
mp->next = NULL; /* now `mp' is free */
}
else{
/* new node will go into free position */
n->next = mp->next; /* chain new position */
mp->next = n;
mp = n;
}
}
mp->key = key;
for (;;) { /* correct `firstfree' */
if (type(_firstfree->key) == OT_NULL && _firstfree->next == NULL) {
mp->val = val;
_usednodes++;
return true; /* OK; table still has a free place */
}
else if (_firstfree == _nodes) break; /* cannot decrement from here */
else (_firstfree)--;
}
Rehash(true);
return NewSlot(key, val);
for (;;) { /* correct `firstfree' */
if (type(_firstfree->key) == OT_NULL && _firstfree->next == NULL) {
mp->val = val;
_usednodes++;
return true; /* OK; table still has a free place */
}
else if (_firstfree == _nodes) break; /* cannot decrement from here */
else (_firstfree)--;
}
Rehash(true);
return NewSlot(key, val);
}
SQInteger SQTable::Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
{
SQInteger idx = (SQInteger)TranslateIndex(refpos);
while (idx < _numofnodes) {
if(type(_nodes[idx].key) != OT_NULL) {
//first found
_HashNode &n = _nodes[idx];
outkey = n.key;
outval = getweakrefs?(SQObject)n.val:_realval(n.val);
//return idx for the next iteration
return ++idx;
}
++idx;
}
//nothing to iterate anymore
return -1;
SQInteger idx = (SQInteger)TranslateIndex(refpos);
while (idx < _numofnodes) {
if(type(_nodes[idx].key) != OT_NULL) {
//first found
_HashNode &n = _nodes[idx];
outkey = n.key;
outval = getweakrefs?(SQObject)n.val:_realval(n.val);
//return idx for the next iteration
return ++idx;
}
++idx;
}
//nothing to iterate anymore
return -1;
}
bool SQTable::Set(const SQObjectPtr &key, const SQObjectPtr &val)
{
_HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
if (n) {
n->val = val;
return true;
}
return false;
_HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
if (n) {
n->val = val;
return true;
}
return false;
}
void SQTable::_ClearNodes()
{
for(SQInteger i = 0;i < _numofnodes; i++) { _HashNode &n = _nodes[i]; n.key.Null(); n.val.Null(); }
for(SQInteger i = 0;i < _numofnodes; i++) { _HashNode &n = _nodes[i]; n.key.Null(); n.val.Null(); }
}
void SQTable::Finalize()
{
_ClearNodes();
SetDelegate(NULL);
_ClearNodes();
SetDelegate(NULL);
}
void SQTable::Clear()
{
_ClearNodes();
_usednodes = 0;
Rehash(true);
_ClearNodes();
_usednodes = 0;
Rehash(true);
}

View File

@ -1,4 +1,4 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQTABLE_H_
#define _SQTABLE_H_
/*
@ -14,96 +14,96 @@
inline SQHash HashObj(const SQObjectPtr &key)
{
switch(type(key)) {
case OT_STRING: return _string(key)->_hash;
case OT_FLOAT: return (SQHash)((SQInteger)_float(key));
case OT_BOOL: case OT_INTEGER: return (SQHash)((SQInteger)_integer(key));
default: return hashptr(key._unVal.pRefCounted);
}
switch(type(key)) {
case OT_STRING: return _string(key)->_hash;
case OT_FLOAT: return (SQHash)((SQInteger)_float(key));
case OT_BOOL: case OT_INTEGER: return (SQHash)((SQInteger)_integer(key));
default: return hashptr(key._unVal.pRefCounted);
}
}
struct SQTable : public SQDelegable
{
private:
struct _HashNode
{
_HashNode() { next = NULL; }
SQObjectPtr val;
SQObjectPtr key;
_HashNode *next;
};
_HashNode *_firstfree;
_HashNode *_nodes;
SQInteger _numofnodes;
SQInteger _usednodes;
struct _HashNode
{
_HashNode() { next = NULL; }
SQObjectPtr val;
SQObjectPtr key;
_HashNode *next;
};
_HashNode *_firstfree;
_HashNode *_nodes;
SQInteger _numofnodes;
SQInteger _usednodes;
///////////////////////////
void AllocNodes(SQInteger nSize);
void Rehash(bool force);
SQTable(SQSharedState *ss, SQInteger nInitialSize);
void _ClearNodes();
void AllocNodes(SQInteger nSize);
void Rehash(bool force);
SQTable(SQSharedState *ss, SQInteger nInitialSize);
void _ClearNodes();
public:
static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize)
{
SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));
new (newtable) SQTable(ss, nInitialSize);
newtable->_delegate = NULL;
return newtable;
}
void Finalize();
SQTable *Clone();
~SQTable()
{
SetDelegate(NULL);
REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();
SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));
}
static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize)
{
SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));
new (newtable) SQTable(ss, nInitialSize);
newtable->_delegate = NULL;
return newtable;
}
void Finalize();
SQTable *Clone();
~SQTable()
{
SetDelegate(NULL);
REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();
SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));
}
#ifndef NO_GARBAGE_COLLECTOR
void Mark(SQCollectable **chain);
SQObjectType GetType() {return OT_TABLE;}
void Mark(SQCollectable **chain);
SQObjectType GetType() {return OT_TABLE;}
#endif
inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash)
{
_HashNode *n = &_nodes[hash];
do{
if(_rawval(n->key) == _rawval(key) && type(n->key) == type(key)){
return n;
}
}while((n = n->next));
return NULL;
}
//for compiler use
inline bool GetStr(const SQChar* key,SQInteger keylen,SQObjectPtr &val)
{
SQHash hash = _hashstr(key,keylen);
_HashNode *n = &_nodes[hash & (_numofnodes - 1)];
_HashNode *res = NULL;
do{
if(type(n->key) == OT_STRING && (scstrcmp(_stringval(n->key),key) == 0)){
res = n;
break;
}
}while((n = n->next));
if (res) {
val = _realval(res->val);
return true;
}
return false;
}
bool Get(const SQObjectPtr &key,SQObjectPtr &val);
void Remove(const SQObjectPtr &key);
bool Set(const SQObjectPtr &key, const SQObjectPtr &val);
//returns true if a new slot has been created false if it was already present
bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val);
SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash)
{
_HashNode *n = &_nodes[hash];
do{
if(_rawval(n->key) == _rawval(key) && type(n->key) == type(key)){
return n;
}
}while((n = n->next));
return NULL;
}
//for compiler use
inline bool GetStr(const SQChar* key,SQInteger keylen,SQObjectPtr &val)
{
SQHash hash = _hashstr(key,keylen);
_HashNode *n = &_nodes[hash & (_numofnodes - 1)];
_HashNode *res = NULL;
do{
if(type(n->key) == OT_STRING && (scstrcmp(_stringval(n->key),key) == 0)){
res = n;
break;
}
}while((n = n->next));
if (res) {
val = _realval(res->val);
return true;
}
return false;
}
bool Get(const SQObjectPtr &key,SQObjectPtr &val);
void Remove(const SQObjectPtr &key);
bool Set(const SQObjectPtr &key, const SQObjectPtr &val);
//returns true if a new slot has been created false if it was already present
bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val);
SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
SQInteger CountUsed(){ return _usednodes;}
void Clear();
void Release()
{
sq_delete(this, SQTable);
}
SQInteger CountUsed(){ return _usednodes;}
void Clear();
void Release()
{
sq_delete(this, SQTable);
}
};

View File

@ -1,40 +1,40 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQUSERDATA_H_
#define _SQUSERDATA_H_
struct SQUserData : SQDelegable
{
SQUserData(SQSharedState *ss){ _delegate = 0; _hook = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); }
~SQUserData()
{
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this);
SetDelegate(NULL);
}
static SQUserData* Create(SQSharedState *ss, SQInteger size)
{
SQUserData* ud = (SQUserData*)SQ_MALLOC(sq_aligning(sizeof(SQUserData))+size);
new (ud) SQUserData(ss);
ud->_size = size;
ud->_typetag = 0;
return ud;
}
SQUserData(SQSharedState *ss){ _delegate = 0; _hook = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); }
~SQUserData()
{
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this);
SetDelegate(NULL);
}
static SQUserData* Create(SQSharedState *ss, SQInteger size)
{
SQUserData* ud = (SQUserData*)SQ_MALLOC(sq_aligning(sizeof(SQUserData))+size);
new (ud) SQUserData(ss);
ud->_size = size;
ud->_typetag = 0;
return ud;
}
#ifndef NO_GARBAGE_COLLECTOR
void Mark(SQCollectable **chain);
void Finalize(){SetDelegate(NULL);}
SQObjectType GetType(){ return OT_USERDATA;}
void Mark(SQCollectable **chain);
void Finalize(){SetDelegate(NULL);}
SQObjectType GetType(){ return OT_USERDATA;}
#endif
void Release() {
if (_hook) _hook((SQUserPointer)sq_aligning(this + 1),_size);
SQInteger tsize = _size;
this->~SQUserData();
SQ_FREE(this, sq_aligning(sizeof(SQUserData)) + tsize);
}
void Release() {
if (_hook) _hook((SQUserPointer)sq_aligning(this + 1),_size);
SQInteger tsize = _size;
this->~SQUserData();
SQ_FREE(this, sq_aligning(sizeof(SQUserData)) + tsize);
}
SQInteger _size;
SQRELEASEHOOK _hook;
SQUserPointer _typetag;
//SQChar _val[1];
SQInteger _size;
SQRELEASEHOOK _hook;
SQUserPointer _typetag;
//SQChar _val[1];
};
#endif //_SQUSERDATA_H_

View File

@ -1,4 +1,4 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQUTILS_H_
#define _SQUTILS_H_
@ -18,99 +18,99 @@ void sq_vm_free(void *p,SQUnsignedInteger size);
template<typename T> class sqvector
{
public:
sqvector()
{
_vals = NULL;
_size = 0;
_allocated = 0;
}
sqvector(const sqvector<T>& v)
{
copy(v);
}
void copy(const sqvector<T>& v)
{
if(_size) {
resize(0); //destroys all previous stuff
}
//resize(v._size);
if(v._size > _allocated) {
_realloc(v._size);
}
for(SQUnsignedInteger i = 0; i < v._size; i++) {
new ((void *)&_vals[i]) T(v._vals[i]);
}
_size = v._size;
}
~sqvector()
{
if(_allocated) {
for(SQUnsignedInteger i = 0; i < _size; i++)
_vals[i].~T();
SQ_FREE(_vals, (_allocated * sizeof(T)));
}
}
void reserve(SQUnsignedInteger newsize) { _realloc(newsize); }
void resize(SQUnsignedInteger newsize, const T& fill = T())
{
if(newsize > _allocated)
_realloc(newsize);
if(newsize > _size) {
while(_size < newsize) {
new ((void *)&_vals[_size]) T(fill);
_size++;
}
}
else{
for(SQUnsignedInteger i = newsize; i < _size; i++) {
_vals[i].~T();
}
_size = newsize;
}
}
void shrinktofit() { if(_size > 4) { _realloc(_size); } }
T& top() const { return _vals[_size - 1]; }
inline SQUnsignedInteger size() const { return _size; }
bool empty() const { return (_size <= 0); }
inline T &push_back(const T& val = T())
{
if(_allocated <= _size)
_realloc(_size * 2);
return *(new ((void *)&_vals[_size++]) T(val));
}
inline void pop_back()
{
_size--; _vals[_size].~T();
}
void insert(SQUnsignedInteger idx, const T& val)
{
resize(_size + 1);
for(SQUnsignedInteger i = _size - 1; i > idx; i--) {
_vals[i] = _vals[i - 1];
}
_vals[idx] = val;
}
void remove(SQUnsignedInteger idx)
{
_vals[idx].~T();
if(idx < (_size - 1)) {
memmove(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1));
}
_size--;
}
SQUnsignedInteger capacity() { return _allocated; }
inline T &back() const { return _vals[_size - 1]; }
inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; }
T* _vals;
sqvector()
{
_vals = NULL;
_size = 0;
_allocated = 0;
}
sqvector(const sqvector<T>& v)
{
copy(v);
}
void copy(const sqvector<T>& v)
{
if(_size) {
resize(0); //destroys all previous stuff
}
//resize(v._size);
if(v._size > _allocated) {
_realloc(v._size);
}
for(SQUnsignedInteger i = 0; i < v._size; i++) {
new ((void *)&_vals[i]) T(v._vals[i]);
}
_size = v._size;
}
~sqvector()
{
if(_allocated) {
for(SQUnsignedInteger i = 0; i < _size; i++)
_vals[i].~T();
SQ_FREE(_vals, (_allocated * sizeof(T)));
}
}
void reserve(SQUnsignedInteger newsize) { _realloc(newsize); }
void resize(SQUnsignedInteger newsize, const T& fill = T())
{
if(newsize > _allocated)
_realloc(newsize);
if(newsize > _size) {
while(_size < newsize) {
new ((void *)&_vals[_size]) T(fill);
_size++;
}
}
else{
for(SQUnsignedInteger i = newsize; i < _size; i++) {
_vals[i].~T();
}
_size = newsize;
}
}
void shrinktofit() { if(_size > 4) { _realloc(_size); } }
T& top() const { return _vals[_size - 1]; }
inline SQUnsignedInteger size() const { return _size; }
bool empty() const { return (_size <= 0); }
inline T &push_back(const T& val = T())
{
if(_allocated <= _size)
_realloc(_size * 2);
return *(new ((void *)&_vals[_size++]) T(val));
}
inline void pop_back()
{
_size--; _vals[_size].~T();
}
void insert(SQUnsignedInteger idx, const T& val)
{
resize(_size + 1);
for(SQUnsignedInteger i = _size - 1; i > idx; i--) {
_vals[i] = _vals[i - 1];
}
_vals[idx] = val;
}
void remove(SQUnsignedInteger idx)
{
_vals[idx].~T();
if(idx < (_size - 1)) {
memmove(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1));
}
_size--;
}
SQUnsignedInteger capacity() { return _allocated; }
inline T &back() const { return _vals[_size - 1]; }
inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; }
T* _vals;
private:
void _realloc(SQUnsignedInteger newsize)
{
newsize = (newsize > 0)?newsize:4;
_vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T));
_allocated = newsize;
}
SQUnsignedInteger _size;
SQUnsignedInteger _allocated;
void _realloc(SQUnsignedInteger newsize)
{
newsize = (newsize > 0)?newsize:4;
_vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T));
_allocated = newsize;
}
SQUnsignedInteger _size;
SQUnsignedInteger _allocated;
};
#endif //_SQUTILS_H_

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* see copyright notice in squirrel.h */
/* see copyright notice in squirrel.h */
#ifndef _SQVM_H_
#define _SQVM_H_
@ -11,19 +11,19 @@
#define DONT_FALL_BACK 666
//#define EXISTS_FALL_BACK -1
#define GET_FLAG_RAW 0x00000001
#define GET_FLAG_DO_NOT_RAISE_ERROR 0x00000002
#define GET_FLAG_RAW 0x00000001
#define GET_FLAG_DO_NOT_RAISE_ERROR 0x00000002
//base lib
void sq_base_register(HSQUIRRELVM v);
struct SQExceptionTrap{
SQExceptionTrap() {}
SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;}
SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et; }
SQInteger _stackbase;
SQInteger _stacksize;
SQInstruction *_ip;
SQInteger _extarget;
SQExceptionTrap() {}
SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;}
SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et; }
SQInteger _stackbase;
SQInteger _stacksize;
SQInstruction *_ip;
SQInteger _extarget;
};
#define _INLINE
@ -35,155 +35,155 @@ typedef sqvector<SQExceptionTrap> ExceptionsTraps;
struct SQVM : public CHAINABLE_OBJ
{
struct CallInfo{
//CallInfo() { _generator = NULL;}
SQInstruction *_ip;
SQObjectPtr *_literals;
SQObjectPtr _closure;
SQGenerator *_generator;
SQInt32 _etraps;
SQInt32 _prevstkbase;
SQInt32 _prevtop;
SQInt32 _target;
SQInt32 _ncalls;
SQBool _root;
};
struct CallInfo{
//CallInfo() { _generator = NULL;}
SQInstruction *_ip;
SQObjectPtr *_literals;
SQObjectPtr _closure;
SQGenerator *_generator;
SQInt32 _etraps;
SQInt32 _prevstkbase;
SQInt32 _prevtop;
SQInt32 _target;
SQInt32 _ncalls;
SQBool _root;
};
typedef sqvector<CallInfo> CallInfoVec;
public:
void DebugHookProxy(SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname);
static void _DebugHookProxy(HSQUIRRELVM v, SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname);
enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM,ET_RESUME_THROW_VM };
SQVM(SQSharedState *ss);
~SQVM();
bool Init(SQVM *friendvm, SQInteger stacksize);
bool Execute(SQObjectPtr &func, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL);
//starts a native call return when the NATIVE closure returns
bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger newbase, SQObjectPtr &retval,bool &suspend);
//starts a SQUIRREL call in the same "Execution loop"
bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall);
bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor);
//call a generic closure pure SQUIRREL or NATIVE
bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror);
SQRESULT Suspend();
void DebugHookProxy(SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname);
static void _DebugHookProxy(HSQUIRRELVM v, SQInteger type, const SQChar * sourcename, SQInteger line, const SQChar * funcname);
enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM,ET_RESUME_THROW_VM };
SQVM(SQSharedState *ss);
~SQVM();
bool Init(SQVM *friendvm, SQInteger stacksize);
bool Execute(SQObjectPtr &func, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL);
//starts a native call return when the NATIVE closure returns
bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger newbase, SQObjectPtr &retval,bool &suspend);
//starts a SQUIRREL call in the same "Execution loop"
bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall);
bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor);
//call a generic closure pure SQUIRREL or NATIVE
bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror);
SQRESULT Suspend();
void CallDebugHook(SQInteger type,SQInteger forcedline=0);
void CallErrorHandler(SQObjectPtr &e);
bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, SQUnsignedInteger getflags, SQInteger selfidx);
SQInteger FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest);
bool InvokeDefaultDelegate(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest);
bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, SQInteger selfidx);
SQInteger FallBackSet(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val);
bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic);
bool NewSlotA(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,const SQObjectPtr &attrs,bool bstatic,bool raw);
bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res);
bool Clone(const SQObjectPtr &self, SQObjectPtr &target);
bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res);
bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);
static bool IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2,bool &res);
bool ToString(const SQObjectPtr &o,SQObjectPtr &res);
SQString *PrintObjVal(const SQObjectPtr &o);
void CallDebugHook(SQInteger type,SQInteger forcedline=0);
void CallErrorHandler(SQObjectPtr &e);
bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, SQUnsignedInteger getflags, SQInteger selfidx);
SQInteger FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest);
bool InvokeDefaultDelegate(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest);
bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, SQInteger selfidx);
SQInteger FallBackSet(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val);
bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic);
bool NewSlotA(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,const SQObjectPtr &attrs,bool bstatic,bool raw);
bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res);
bool Clone(const SQObjectPtr &self, SQObjectPtr &target);
bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res);
bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);
static bool IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2,bool &res);
bool ToString(const SQObjectPtr &o,SQObjectPtr &res);
SQString *PrintObjVal(const SQObjectPtr &o);
void Raise_Error(const SQChar *s, ...);
void Raise_Error(const SQObjectPtr &desc);
void Raise_IdxError(const SQObjectPtr &o);
void Raise_CompareError(const SQObject &o1, const SQObject &o2);
void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type);
void Raise_Error(const SQChar *s, ...);
void Raise_Error(const SQObjectPtr &desc);
void Raise_IdxError(const SQObjectPtr &o);
void Raise_CompareError(const SQObject &o1, const SQObject &o2);
void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type);
void FindOuter(SQObjectPtr &target, SQObjectPtr *stackindex);
void RelocateOuters();
void CloseOuters(SQObjectPtr *stackindex);
void FindOuter(SQObjectPtr &target, SQObjectPtr *stackindex);
void RelocateOuters();
void CloseOuters(SQObjectPtr *stackindex);
bool TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest);
bool CallMetaMethod(SQObjectPtr &closure, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres);
bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);
bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval);
//new stuff
_INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
_INLINE bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
_INLINE bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1);
_INLINE bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res);
bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func);
bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs);
//return true if the loop is finished
bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump);
//_INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
_INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
_INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix,SQInteger arg0);
bool TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest);
bool CallMetaMethod(SQObjectPtr &closure, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres);
bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);
bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval);
//new stuff
_INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
_INLINE bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
_INLINE bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1);
_INLINE bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res);
bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func);
bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs);
//return true if the loop is finished
bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump);
//_INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
_INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
_INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix,SQInteger arg0);
#ifdef _DEBUG_DUMP
void dumpstack(SQInteger stackbase=-1, bool dumpall = false);
void dumpstack(SQInteger stackbase=-1, bool dumpall = false);
#endif
#ifndef NO_GARBAGE_COLLECTOR
void Mark(SQCollectable **chain);
SQObjectType GetType() {return OT_THREAD;}
void Mark(SQCollectable **chain);
SQObjectType GetType() {return OT_THREAD;}
#endif
void Finalize();
void GrowCallStack() {
SQInteger newsize = _alloccallsstacksize*2;
_callstackdata.resize(newsize);
_callsstack = &_callstackdata[0];
_alloccallsstacksize = newsize;
}
bool EnterFrame(SQInteger newbase, SQInteger newtop, bool tailcall);
void LeaveFrame();
void Release(){ sq_delete(this,SQVM); }
void Finalize();
void GrowCallStack() {
SQInteger newsize = _alloccallsstacksize*2;
_callstackdata.resize(newsize);
_callsstack = &_callstackdata[0];
_alloccallsstacksize = newsize;
}
bool EnterFrame(SQInteger newbase, SQInteger newtop, bool tailcall);
void LeaveFrame();
void Release(){ sq_delete(this,SQVM); }
////////////////////////////////////////////////////////////////////////////
//stack functions for the api
void Remove(SQInteger n);
//stack functions for the api
void Remove(SQInteger n);
static bool IsFalse(SQObjectPtr &o);
static bool IsFalse(SQObjectPtr &o);
void Pop();
void Pop(SQInteger n);
void Push(const SQObjectPtr &o);
void PushNull();
SQObjectPtr &Top();
SQObjectPtr &PopGet();
SQObjectPtr &GetUp(SQInteger n);
SQObjectPtr &GetAt(SQInteger n);
void Pop();
void Pop(SQInteger n);
void Push(const SQObjectPtr &o);
void PushNull();
SQObjectPtr &Top();
SQObjectPtr &PopGet();
SQObjectPtr &GetUp(SQInteger n);
SQObjectPtr &GetAt(SQInteger n);
SQObjectPtrVec _stack;
SQObjectPtrVec _stack;
SQInteger _top;
SQInteger _stackbase;
SQOuter *_openouters;
SQObjectPtr _roottable;
SQObjectPtr _lasterror;
SQObjectPtr _errorhandler;
SQInteger _top;
SQInteger _stackbase;
SQOuter *_openouters;
SQObjectPtr _roottable;
SQObjectPtr _lasterror;
SQObjectPtr _errorhandler;
bool _debughook;
SQDEBUGHOOK _debughook_native;
SQObjectPtr _debughook_closure;
bool _debughook;
SQDEBUGHOOK _debughook_native;
SQObjectPtr _debughook_closure;
SQObjectPtr temp_reg;
SQObjectPtr temp_reg;
CallInfo* _callsstack;
SQInteger _callsstacksize;
SQInteger _alloccallsstacksize;
sqvector<CallInfo> _callstackdata;
CallInfo* _callsstack;
SQInteger _callsstacksize;
SQInteger _alloccallsstacksize;
sqvector<CallInfo> _callstackdata;
ExceptionsTraps _etraps;
CallInfo *ci;
SQUserPointer _foreignptr;
//VMs sharing the same state
SQSharedState *_sharedstate;
SQInteger _nnativecalls;
SQInteger _nmetamethodscall;
SQRELEASEHOOK _releasehook;
//suspend infos
SQBool _suspended;
SQBool _suspended_root;
SQInteger _suspended_target;
SQInteger _suspended_traps;
ExceptionsTraps _etraps;
CallInfo *ci;
SQUserPointer _foreignptr;
//VMs sharing the same state
SQSharedState *_sharedstate;
SQInteger _nnativecalls;
SQInteger _nmetamethodscall;
SQRELEASEHOOK _releasehook;
//suspend infos
SQBool _suspended;
SQBool _suspended_root;
SQInteger _suspended_target;
SQInteger _suspended_traps;
};
struct AutoDec{
AutoDec(SQInteger *n) { _n = n; }
~AutoDec() { (*_n)--; }
SQInteger *_n;
AutoDec(SQInteger *n) { _n = n; }
~AutoDec() { (*_n)--; }
SQInteger *_n;
};
inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));}
@ -197,18 +197,18 @@ inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->
#endif
#define PUSH_CALLINFO(v,nci){ \
SQInteger css = v->_callsstacksize; \
if(css == v->_alloccallsstacksize) { \
v->GrowCallStack(); \
} \
v->ci = &v->_callsstack[css]; \
*(v->ci) = nci; \
v->_callsstacksize++; \
SQInteger css = v->_callsstacksize; \
if(css == v->_alloccallsstacksize) { \
v->GrowCallStack(); \
} \
v->ci = &v->_callsstack[css]; \
*(v->ci) = nci; \
v->_callsstacksize++; \
}
#define POP_CALLINFO(v){ \
SQInteger css = --v->_callsstacksize; \
v->ci->_closure.Null(); \
v->ci = css?&v->_callsstack[css-1]:NULL; \
SQInteger css = --v->_callsstacksize; \
v->ci->_closure.Null(); \
v->ci = css?&v->_callsstack[css-1]:NULL; \
}
#endif //_SQVM_H_