Upgraded to Squirrel 2.2
authorChristoph Sommer <mail@christoph-sommer.de>
Wed, 2 Apr 2008 18:13:45 +0000 (18:13 +0000)
committerChristoph Sommer <mail@christoph-sommer.de>
Wed, 2 Apr 2008 18:13:45 +0000 (18:13 +0000)
SVN-Revision: 5382

25 files changed:
src/squirrel/COPYRIGHT
src/squirrel/HISTORY
src/squirrel/README
src/squirrel/include/sqstdio.h
src/squirrel/include/squirrel.h
src/squirrel/sqstdlib/sqstdaux.cpp
src/squirrel/sqstdlib/sqstdio.cpp
src/squirrel/sqstdlib/sqstdmath.cpp
src/squirrel/sqstdlib/sqstdstring.cpp
src/squirrel/squirrel/sqapi.cpp
src/squirrel/squirrel/sqbaselib.cpp
src/squirrel/squirrel/sqclosure.h
src/squirrel/squirrel/sqcompiler.cpp
src/squirrel/squirrel/sqcompiler.h
src/squirrel/squirrel/sqfuncproto.h
src/squirrel/squirrel/sqfuncstate.cpp
src/squirrel/squirrel/sqfuncstate.h
src/squirrel/squirrel/sqlexer.cpp
src/squirrel/squirrel/sqlexer.h
src/squirrel/squirrel/sqobject.cpp
src/squirrel/squirrel/sqobject.h
src/squirrel/squirrel/sqstate.cpp
src/squirrel/squirrel/sqstate.h
src/squirrel/squirrel/sqvm.cpp
src/squirrel/squirrel/sqvm.h

index 31e565a..8bd2081 100644 (file)
@@ -1,4 +1,4 @@
-Copyright (c) 2003-2007 Alberto Demichelis\r
+Copyright (c) 2003-2008 Alberto Demichelis\r
 \r
 This software is provided 'as-is', without any \r
 express or implied warranty. In no event will the \r
index a76d0ff..718834b 100644 (file)
@@ -1,3 +1,13 @@
+***version 2.2 stable***\r
+-added _newslot metamethod in classes\r
+-added enums added constants\r
+-added sq_pushconsttable, sq_setconsttable\r
+-added default param\r
+-added octal literals(thx Dinosaur)\r
+-fixed debug hook, 'calls' and 'returns' are properly notified in the same number.\r
+-fixed a coroutine bug\r
+\r
+***2007-07-29          ***\r
 ***version 2.1.2 stable***\r
 -new behaviour for generators iteration using foreach\r
 now when a generator is iterated by foreach the value returned by a 'return val' statement\r
index 3d984d9..759c6ef 100644 (file)
@@ -1,4 +1,4 @@
-The programming language SQUIRREL 2.1.2 stable\r
+The programming language SQUIRREL 2.2 stable\r
 \r
 --------------------------------------------------\r
 The project has been compiled and run on Windows(Windows XP/2000 on Intel x86 Windows XP Pro on AMD x64) and\r
@@ -16,7 +16,7 @@ Feedback and suggestions are appreciated
 project page - http://www.squirrel-lang.org\r
 community forums - http://www.squirrel-lang.org/Forums\r
 wiki - http://wiki.squirrel-lang.org\r
-author - alberto@ademichelis.com\r
+author - alberto@demichelis.net\r
 \r
 END OF README\r
 \r
index 6da1872..2cb744b 100644 (file)
@@ -7,10 +7,6 @@
 #define SQSTD_STREAM_TYPE_TAG 0x80000000
 
 struct SQStream {
-
-       // [SuperTux] Added virtual destructor to avoid compiler warnings
-       virtual ~SQStream() { };
-
        virtual SQInteger Read(void *buffer, SQInteger size) = 0;
        virtual SQInteger Write(void *buffer, SQInteger size) = 0;
        virtual SQInteger Flush() = 0;
index 5150312..d164400 100644 (file)
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2003-2007 Alberto Demichelis
+Copyright (c) 2003-2008 Alberto Demichelis
 
 This software is provided 'as-is', without any 
 express or implied warranty. In no event will the 
@@ -57,6 +57,7 @@ typedef unsigned int SQUnsignedInteger;
 typedef unsigned int SQHash; /*should be the same size of a pointer*/
 #endif
 
+
 typedef float SQFloat;
 typedef void* SQUserPointer;
 typedef SQUnsignedInteger SQBool;
@@ -65,7 +66,6 @@ typedef SQInteger SQRESULT;
 #define SQTrue (1)
 #define SQFalse        (0)
 
-
 struct SQVM;
 struct SQTable;
 struct SQArray;
@@ -136,8 +136,8 @@ typedef char SQChar;
 #define MAX_CHAR 0xFF
 #endif
 
-#define SQUIRREL_VERSION       _SC("Squirrel 2.1.2 stable")
-#define SQUIRREL_COPYRIGHT     _SC("Copyright (C) 2003-2007 Alberto Demichelis")
+#define SQUIRREL_VERSION       _SC("Squirrel 2.2 stable")
+#define SQUIRREL_COPYRIGHT     _SC("Copyright (C) 2003-2008 Alberto Demichelis")
 #define SQUIRREL_AUTHOR                _SC("Alberto Demichelis")
 
 #define SQ_VMSTATE_IDLE                        0
@@ -316,6 +316,7 @@ SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedIn
 SQUIRREL_API SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name);
 SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p);
 SQUIRREL_API SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag);
+SQUIRREL_API SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize);
 SQUIRREL_API SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase);
 SQUIRREL_API SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx);
 SQUIRREL_API SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx);
@@ -327,7 +328,9 @@ SQUIRREL_API SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t);
 /*object manipulation*/
 SQUIRREL_API void sq_pushroottable(HSQUIRRELVM v);
 SQUIRREL_API void sq_pushregistrytable(HSQUIRRELVM v);
+SQUIRREL_API void sq_pushconsttable(HSQUIRRELVM v);
 SQUIRREL_API SQRESULT sq_setroottable(HSQUIRRELVM v);
+SQUIRREL_API SQRESULT sq_setconsttable(HSQUIRRELVM v);
 SQUIRREL_API SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic);
 SQUIRREL_API SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
 SQUIRREL_API SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx);
index 6d3ea31..f024713 100644 (file)
@@ -65,7 +65,7 @@ void sqstd_printcallstack(HSQUIRRELVM v)
                                        pf(v,_SC("[%s] NATIVECLOSURE\n"),name);
                                        break;
                                case OT_GENERATOR:
-                                       pf(v,_SC("[%s] NATIVECLOSURE\n"),name);
+                                       pf(v,_SC("[%s] GENERATOR\n"),name);
                                        break;
                                case OT_USERDATA:
                                        pf(v,_SC("[%s] USERDATA\n"),name);
index 81ed732..4a0a184 100644 (file)
@@ -9,7 +9,7 @@
 //basic API
 SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode)
 {
-#ifndef _UNICODE
+#ifndef SQUNICODE
        return (SQFILE)fopen(filename,mode);
 #else
        return (SQFILE)_wfopen(filename,mode);
index 2ad9f02..69c46f5 100644 (file)
@@ -22,7 +22,8 @@
 static SQInteger math_srand(HSQUIRRELVM v)
 {
        SQInteger i;
-       if(!sq_getinteger(v,2,&i))return sq_throwerror(v,_SC("invalid param"));
+       if(SQ_FAILED(sq_getinteger(v,2,&i)))
+               return sq_throwerror(v,_SC("invalid param"));
        srand((unsigned int)i);
        return 0;
 }
index 31735e1..58e935f 100644 (file)
@@ -7,7 +7,7 @@
 #include <ctype.h>
 #include <assert.h>
 
-#ifdef _UNICODE
+#ifdef SQUNICODE
 #define scstrchr wcschr
 #define scsnprintf wsnprintf
 #define scatoi _wtoi
index d6b08a7..ff461e7 100644 (file)
@@ -425,6 +425,11 @@ void sq_pushregistrytable(HSQUIRRELVM v)
        v->Push(_ss(v)->_registry);
 }
 
+void sq_pushconsttable(HSQUIRRELVM v)
+{
+       v->Push(_ss(v)->_consts);
+}
+
 SQRESULT sq_setroottable(HSQUIRRELVM v)
 {
        SQObject o = stack_get(v, -1);
@@ -436,6 +441,17 @@ SQRESULT sq_setroottable(HSQUIRRELVM v)
        return sq_throwerror(v, _SC("ivalid type"));
 }
 
+SQRESULT sq_setconsttable(HSQUIRRELVM v)
+{
+       SQObject o = stack_get(v, -1);
+       if(sq_istable(o)) {
+               _ss(v)->_consts = o;
+               v->Pop();
+               return SQ_OK;
+       }
+       return sq_throwerror(v, _SC("ivalid type, expected table"));
+}
+
 void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p)
 {
        v->_foreignptr = p;
@@ -635,7 +651,7 @@ void sq_settop(HSQUIRRELVM v, SQInteger newtop)
        if(top > newtop)
                sq_pop(v, top - newtop);
        else
-               while(top < newtop) sq_pushnull(v);
+               while(top++ < newtop) sq_pushnull(v);
 }
 
 void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop)
@@ -916,7 +932,9 @@ SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror)
 {
        SQObjectPtr res;
        if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false)){
-               v->Pop(params);//pop closure and args
+               if(!v->_suspended) {
+                       v->Pop(params);//pop closure and args
+               }
                if(retval){
                        v->Push(res); return SQ_OK;
                }
index ee49b2d..cda52da 100644 (file)
@@ -49,6 +49,13 @@ static SQInteger base_getroottable(HSQUIRRELVM v)
        return 1;
 }
 
+static SQInteger base_getconsttable(HSQUIRRELVM v)
+{
+       v->Push(_ss(v)->_consts);
+       return 1;
+}
+
+
 static SQInteger base_setroottable(HSQUIRRELVM v)
 {
        SQObjectPtr &o=stack_get(v,2);
@@ -57,6 +64,14 @@ static SQInteger base_setroottable(HSQUIRRELVM v)
        return 1;
 }
 
+static SQInteger base_setconsttable(HSQUIRRELVM v)
+{
+       SQObjectPtr &o=stack_get(v,2);
+       if(SQ_FAILED(sq_setconsttable(v))) return SQ_ERROR;
+       v->Push(o);
+       return 1;
+}
+
 static SQInteger base_seterrorhandler(HSQUIRRELVM v)
 {
        sq_seterrorhandler(v);
@@ -215,6 +230,8 @@ static SQRegFunction base_funcs[]={
        {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")},
        {_SC("getroottable"),base_getroottable,1, NULL},
        {_SC("setroottable"),base_setroottable,2, NULL},
+       {_SC("getconsttable"),base_getconsttable,1, NULL},
+       {_SC("setconsttable"),base_setconsttable,2, NULL},
        {_SC("assert"),base_assert,2, NULL},
        {_SC("print"),base_print,2, NULL},
        {_SC("compilestring"),base_compilestring,-2, _SC(".ss")},
@@ -525,9 +542,11 @@ static SQInteger array_slice(HSQUIRRELVM v)
        SQInteger sidx,eidx;
        SQObjectPtr o;
        if(get_slice_params(v,sidx,eidx,o)==-1)return -1;
-       if(sidx<0)sidx=_array(o)->Size()+sidx;
-       if(eidx<0)eidx=_array(o)->Size()+eidx;
+       SQInteger alen = _array(o)->Size();
+       if(sidx < 0)sidx = alen + sidx;
+       if(eidx < 0)eidx = alen + eidx;
        if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes"));
+       if(eidx > alen)return sq_throwerror(v,_SC("slice out of range"));
        SQArray *arr=SQArray::Create(_ss(v),eidx-sidx);
        SQObjectPtr t;
        SQInteger count=0;
@@ -565,10 +584,11 @@ static SQInteger string_slice(HSQUIRRELVM v)
        SQInteger sidx,eidx;
        SQObjectPtr o;
        if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1;
-       if(sidx<0)sidx=_string(o)->_len+sidx;
-       if(eidx<0)eidx=_string(o)->_len+eidx;
-       if(eidx<sidx)
-               return sq_throwerror(v,_SC("wrong indexes"));
+       SQInteger slen = _string(o)->_len;
+       if(sidx < 0)sidx = slen + sidx;
+       if(eidx < 0)eidx = slen + eidx;
+       if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes"));
+       if(eidx > slen) return sq_throwerror(v,_SC("slice out of range"));
        v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx));
        return 1;
 }
index 1c9eaa9..8db7ca2 100644 (file)
@@ -22,6 +22,7 @@ public:
                SQClosure * ret = SQClosure::Create(_opt_ss(this),_funcproto(_function));
                ret->_env = _env;
                ret->_outervalues.copy(_outervalues);
+               ret->_defaultparams.copy(_defaultparams);
                return ret;
        }
        ~SQClosure()
@@ -37,6 +38,7 @@ public:
        SQObjectPtr _env;
        SQObjectPtr _function;
        SQObjectPtrVec _outervalues;
+       SQObjectPtrVec _defaultparams;
 };
 //////////////////////////////////////////////
 struct SQGenerator : public CHAINABLE_OBJ 
index 7137c53..5c468e1 100644 (file)
@@ -11,6 +11,7 @@
 #include "sqfuncstate.h"
 #include "sqlexer.h"
 #include "sqvm.h"
+#include "sqtable.h"
 
 #define DEREF_NO_DEREF -1
 #define DEREF_FIELD            -2
@@ -258,6 +259,9 @@ public:
                case TK_CLASS:
                        ClassStatement();
                        break;
+               case TK_ENUM:
+                       EnumStatement();
+                       break;
                case _SC('{'):{
                                SQInteger stacksize = _fs->GetStackSize();
                                Lex();
@@ -274,6 +278,19 @@ public:
                        CommaExpr();
                        _fs->AddInstruction(_OP_THROW, _fs->PopTarget());
                        break;
+               case TK_CONST:
+                       {
+                       Lex();
+                       SQObject id = Expect(TK_IDENTIFIER);
+                       Expect('=');
+                       SQObject val = ExpectScalar();
+                       OptionalSemicolon();
+                       SQTable *enums = _table(_ss(_vm)->_consts);
+                       SQObjectPtr strongid = id; 
+                       enums->NewSlot(strongid,SQObjectPtr(val));
+                       strongid.Null();
+                       }
+                       break;
                default:
                        CommaExpr();
                        _fs->PopTarget();
@@ -599,6 +616,7 @@ public:
                case TK_THIS:{
                        _exst._freevar = false;
                        SQObject id;
+                       SQObject constant;
                                switch(_token) {
                                        case TK_IDENTIFIER: id = _fs->CreateString(_lex._svalue); break;
                                        case TK_THIS: id = _fs->CreateString(_SC("this")); break;
@@ -612,13 +630,43 @@ public:
                                                _exst._deref = _fs->PushTarget();
                                                _fs->AddInstruction(_OP_LOADFREEVAR, _exst._deref ,pos);        
                                                _exst._freevar = true;
-                                       } else {
+                                       }
+                                       else if(_fs->IsConstant(id,constant)) { //line 634
+                                               SQObjectPtr constval;
+                                               SQObject constid;
+                                               if(type(constant) == OT_TABLE) {
+                                                       Expect('.'); constid = Expect(TK_IDENTIFIER);
+                                                       if(!_table(constant)->Get(constid,constval)) {
+                                                               constval.Null();
+                                                               Error(_SC("invalid constant [%s.%s]"), _stringval(id),_stringval(constid));
+                                                       }
+                                               }
+                                               else {
+                                                       constval = constant;
+                                               }
+                                               _exst._deref = _fs->PushTarget();
+                                               SQObjectType ctype = type(constval);
+                                               if(ctype == OT_INTEGER && (_integer(constval) & (~0x7FFFFFFF)) == 0) {
+                                                       _fs->AddInstruction(_OP_LOADINT, _exst._deref,_integer(constval));
+                                               }
+                                               else if(ctype == OT_FLOAT && sizeof(SQFloat) == sizeof(SQInt32)) {
+                                                       SQFloat f = _float(constval);
+                                                       _fs->AddInstruction(_OP_LOADFLOAT, _exst._deref,*((SQInt32 *)&f));
+                                               }
+                                               else {
+                                                       _fs->AddInstruction(_OP_LOAD, _exst._deref, _fs->GetConstant(constval));
+                                               }
+
+                                               _exst._freevar = true;
+                                       }
+                                       else {
                                                _fs->PushTarget(0);
                                                _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
                                                if(NeedGet()) Emit2ArgsOP(_OP_GET);
                                                _exst._deref = DEREF_FIELD;
                                        }
                                }
+                               
                                else{
                                        _fs->PushTarget(pos);
                                        _exst._deref = pos;
@@ -1038,6 +1086,62 @@ public:
                }
                else Error(_SC("cannot create a class in a local with the syntax(class <local>)"));
        }
+       SQObject ExpectScalar()
+       {
+               SQObject val;
+               switch(_token) {
+                       case TK_INTEGER:
+                               val._type = OT_INTEGER;
+                               val._unVal.nInteger = _lex._nvalue;
+                               break;
+                       case TK_FLOAT:
+                               val._type = OT_FLOAT;
+                               val._unVal.fFloat = _lex._fvalue;
+                               break;
+                       case TK_STRING_LITERAL:
+                               val = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1);
+                               break;
+                       default:
+                       Error(_SC("scalar expected : integer,float or string"));
+               }
+               Lex();
+               return val;
+       }
+       void EnumStatement()
+       {
+               
+               Lex(); 
+               SQObject id = Expect(TK_IDENTIFIER);
+               Expect(_SC('{'));
+               
+               SQObject table = _fs->CreateTable();
+               SQInteger nval = 0;
+               while(_token != _SC('}')) {
+                       SQObject key = Expect(TK_IDENTIFIER);
+                       SQObject val;
+                       if(_token == _SC('=')) {
+                               Lex();
+                               val = ExpectScalar();
+                       }
+                       else {
+                               val._type = OT_INTEGER;
+                               val._unVal.nInteger = nval++;
+                       }
+                       _table(table)->NewSlot(SQObjectPtr(key),SQObjectPtr(val));
+                       if(_token == ',') Lex();
+               }
+               SQTable *enums = _table(_ss(_vm)->_consts);
+               SQObjectPtr strongid = id; 
+               /*SQObjectPtr dummy;
+               if(enums->Get(strongid,dummy)) {
+                       dummy.Null(); strongid.Null();
+                       Error(_SC("enumeration already exists"));
+               }*/
+               enums->NewSlot(SQObjectPtr(strongid),SQObjectPtr(table));
+               strongid.Null();
+               Lex();
+               
+       }
        void TryCatchStatement()
        {
                SQObject exid;
@@ -1131,8 +1235,10 @@ public:
                SQObject paramname;
                funcstate->AddParameter(_fs->CreateString(_SC("this")));
                funcstate->_sourcename = _sourcename;
+               SQInteger defparams = 0;
                while(_token!=_SC(')')) {
                        if(_token == TK_VARPARAMS) {
+                               if(defparams > 0) Error(_SC("function with default parameters cannot have variable number of parameters"));
                                funcstate->_varparams = true;
                                Lex();
                                if(_token != _SC(')')) Error(_SC("expected ')'"));
@@ -1141,11 +1247,23 @@ public:
                        else {
                                paramname = Expect(TK_IDENTIFIER);
                                funcstate->AddParameter(paramname);
+                               if(_token == _SC('=')) { 
+                                       Lex();
+                                       Expression();
+                                       funcstate->AddDefaultParam(_fs->TopTarget());
+                                       defparams++;
+                               }
+                               else {
+                                       if(defparams > 0) Error(_SC("expected '='"));
+                               }
                                if(_token == _SC(',')) Lex();
                                else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));
                        }
                }
                Expect(_SC(')'));
+               for(SQInteger n = 0; n < defparams; n++) {
+                       _fs->PopTarget();
+               }
                //outer values
                if(_token == _SC(':')) {
                        Lex(); Expect(_SC('('));
index ed2a89b..dd55888 100644 (file)
@@ -68,6 +68,8 @@ struct SQVM;
 #define TK_ATTR_OPEN 320
 #define TK_ATTR_CLOSE 321
 #define TK_STATIC 322
+#define TK_ENUM 323
+#define TK_CONST 324
 
 
 typedef void(*CompilerErrorFunc)(void *ud, const SQChar *s);
index 367b818..6092dbe 100644 (file)
@@ -53,11 +53,11 @@ typedef sqvector<SQOuterVar> SQOuterVarVec;
 typedef sqvector<SQLocalVarInfo> SQLocalVarInfoVec;
 typedef sqvector<SQLineInfo> SQLineInfoVec;
 
-#define _FUNC_SIZE(ni,nl,nparams,nfuncs,nouters,nlineinf,localinf) (sizeof(SQFunctionProto) \
+#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)))
+               +(localinf*sizeof(SQLocalVarInfo))+(defparams*sizeof(SQInteger)))
 
 #define _CONSTRUCT_VECTOR(type,size,ptr) { \
        for(SQInteger n = 0; n < size; n++) { \
@@ -80,11 +80,11 @@ public:
        static SQFunctionProto *Create(SQInteger ninstructions,
                SQInteger nliterals,SQInteger nparameters,
                SQInteger nfunctions,SQInteger noutervalues,
-               SQInteger nlineinfos,SQInteger nlocalvarinfos)
+               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));
+               f = (SQFunctionProto *)sq_vm_malloc(_FUNC_SIZE(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams));
                new (f) SQFunctionProto;
                f->_ninstructions = ninstructions;
                f->_literals = (SQObjectPtr*)&f->_instructions[ninstructions];
@@ -99,6 +99,8 @@ public:
                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);
@@ -115,7 +117,7 @@ public:
                _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);
+               SQInteger size = _FUNC_SIZE(_ninstructions,_nliterals,_nparameters,_nfunctions,_noutervalues,_nlineinfos,_nlocalvarinfos,_ndefaultparams);
                this->~SQFunctionProto();
                sq_vm_free(this,size);
        }
@@ -147,6 +149,9 @@ public:
 
        SQInteger _noutervalues;
        SQOuterVar *_outervalues;
+
+       SQInteger _ndefaultparams;
+       SQInteger *_defaultparams;
        
        SQInteger _ninstructions;
        SQInstruction _instructions[1];
index 962a6cd..d8354b0 100644 (file)
@@ -80,7 +80,8 @@ void DumpLiteral(SQObjectPtr &o)
                case OT_STRING: scprintf(_SC("\"%s\""),_stringval(o));break;
                case OT_FLOAT: scprintf(_SC("{%f}"),_float(o));break;
                case OT_INTEGER: scprintf(_SC("{%d}"),_integer(o));break;
-               default: assert(0); break; //shut up compiler
+               case OT_BOOL: scprintf(_SC("%s"),_integer(o)?_SC("true"):_SC("false"));break;
+               default: scprintf(_SC("(%s %p)"),GetTypeName(o),_rawval(o));break; break; //shut up compiler
        }
 }
 
@@ -310,6 +311,16 @@ void SQFuncState::SetStackSize(SQInteger n)
        }
 }
 
+bool SQFuncState::IsConstant(const SQObject &name,SQObject &e)
+{
+       SQObjectPtr val;
+       if(_table(_sharedstate->_consts)->Get(name,val)) {
+               e = val;
+               return true;
+       }
+       return false;
+}
+
 bool SQFuncState::IsLocal(SQUnsignedInteger stkpos)
 {
        if(stkpos>=_vlocals.size())return false;
@@ -492,11 +503,18 @@ SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len)
        return ns;
 }
 
+SQObject SQFuncState::CreateTable()
+{
+       SQObjectPtr nt(SQTable::Create(_sharedstate,0));
+       _table(_strings)->NewSlot(nt,(SQInteger)1);
+       return nt;
+}
+
 SQFunctionProto *SQFuncState::BuildProto()
 {
        SQFunctionProto *f=SQFunctionProto::Create(_instructions.size(),
                _nliterals,_parameters.size(),_functions.size(),_outervalues.size(),
-               _lineinfos.size(),_localvarinfos.size());
+               _lineinfos.size(),_localvarinfos.size(),_defaultparams.size());
 
        SQObjectPtr refidx,key,val;
        SQInteger idx;
@@ -516,6 +534,7 @@ SQFunctionProto *SQFuncState::BuildProto()
        for(SQUnsignedInteger no = 0; no < _outervalues.size(); no++) f->_outervalues[no] = _outervalues[no];
        for(SQUnsignedInteger no = 0; no < _localvarinfos.size(); no++) f->_localvarinfos[no] = _localvarinfos[no];
        for(SQUnsignedInteger no = 0; no < _lineinfos.size(); no++) f->_lineinfos[no] = _lineinfos[no];
+       for(SQUnsignedInteger no = 0; no < _defaultparams.size(); no++) f->_defaultparams[no] = _defaultparams[no];
 
        memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(SQInstruction));
 
index 96eb552..c0bf1e5 100644 (file)
@@ -22,6 +22,8 @@ struct SQFuncState
        void PopInstructions(SQInteger size){for(SQInteger i=0;i<size;i++)_instructions.pop_back();}
        void SetStackSize(SQInteger n);
        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);
@@ -42,6 +44,8 @@ struct SQFuncState
        SQInteger GetUpTarget(SQInteger n);
        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;
@@ -64,6 +68,7 @@ struct SQFuncState
        SQFuncState *_parent;
        SQIntVec _breaktargets;
        SQIntVec _continuetargets;
+       SQIntVec _defaultparams;
        SQInteger _lastline;
        SQInteger _traps; //contains number of nested exception traps
        bool _optimization;
index 701dc79..50bc246 100644 (file)
@@ -66,6 +66,8 @@ void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,Compile
        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);
 
        _readf = rg;
        _up = up;
@@ -372,7 +374,21 @@ void LexInteger(const SQChar *s,SQUnsignedInteger *res)
        }
 }
 
+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); }
+       }
+}
+
 SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; }
+
+
 #define MAX_HEX_DIGITS (sizeof(SQInteger)*2)
 SQInteger SQLexer::ReadNumber()
 {
@@ -380,18 +396,29 @@ SQInteger SQLexer::ReadNumber()
 #define TFLOAT 2
 #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')) {
-               NEXT();
-               type = THEX;
-               while(isxdigit(CUR_CHAR)) {
-                       APPEND_CHAR(CUR_CHAR);
+       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"));
                }
-               if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number"));
        }
        else {
                APPEND_CHAR((int)firstchar);
@@ -425,6 +452,9 @@ SQInteger SQLexer::ReadNumber()
        case THEX:
                LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
                return TK_INTEGER;
+       case TOCTAL:
+               LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
+               return TK_INTEGER;
        }
        return 0;
 }
index 52993e5..eb3bc87 100644 (file)
@@ -2,7 +2,7 @@
 #ifndef _SQLEXER_H_
 #define _SQLEXER_H_
 
-#ifdef _UNICODE
+#ifdef SQUNICODE
 typedef SQChar LexChar;
 #else
 typedef        unsigned char LexChar;
index 7bfc19d..1e1a638 100644 (file)
 #include "sqclass.h"
 #include "sqclosure.h"
 
+
+const SQChar *IdType2Name(SQObjectType type)
+{
+       switch(_RAW_TYPE(type))
+       {
+       case _RT_NULL:return _SC("null");
+       case _RT_INTEGER:return _SC("integer");
+       case _RT_FLOAT:return _SC("float");
+       case _RT_BOOL:return _SC("bool");
+       case _RT_STRING:return _SC("string");
+       case _RT_TABLE:return _SC("table");
+       case _RT_ARRAY:return _SC("array");
+       case _RT_GENERATOR:return _SC("generator");
+       case _RT_CLOSURE:
+       case _RT_NATIVECLOSURE:
+               return _SC("function");
+       case _RT_USERDATA:
+       case _RT_USERPOINTER:
+               return _SC("userdata");
+       case _RT_THREAD: return _SC("thread");
+       case _RT_FUNCPROTO: return _SC("function");
+       case _RT_CLASS: return _SC("class");
+       case _RT_INSTANCE: return _SC("instance");
+       case _RT_WEAKREF: return _SC("weakref");
+       default:
+               return NULL;
+       }
+}
+
+const SQChar *GetTypeName(const SQObjectPtr &obj1)
+{
+       return IdType2Name(type(obj1)); 
+}
+
 SQString *SQString::Create(SQSharedState *ss,const SQChar *s,SQInteger len)
 {
        SQString *str=ADD_STRING(ss,s,len);
@@ -148,6 +182,9 @@ bool SQGenerator::Resume(SQVM *v,SQInteger target)
        v->ci->_prevtop = (SQInt32)prevtop;
        v->ci->_prevstkbase = (SQInt32)(v->_stackbase - oldstackbase);
        _state=eRunning;
+       if (type(v->_debughook) != OT_NULL && _rawval(v->_debughook) != _rawval(v->ci->_closure))
+               v->CallDebugHook(_SC('c'));
+
        return true;
 }
 
@@ -301,6 +338,7 @@ bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
        SQInteger i,nliterals = _nliterals,nparameters = _nparameters;
        SQInteger noutervalues = _noutervalues,nlocalvarinfos = _nlocalvarinfos;
        SQInteger nlineinfos=_nlineinfos,ninstructions = _ninstructions,nfunctions=_nfunctions;
+       SQInteger ndefaultparams = _ndefaultparams;
        _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
        _CHECK_IO(WriteObject(v,up,write,_sourcename));
        _CHECK_IO(WriteObject(v,up,write,_name));
@@ -310,6 +348,7 @@ bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
        _CHECK_IO(SafeWrite(v,write,up,&noutervalues,sizeof(noutervalues)));
        _CHECK_IO(SafeWrite(v,write,up,&nlocalvarinfos,sizeof(nlocalvarinfos)));
        _CHECK_IO(SafeWrite(v,write,up,&nlineinfos,sizeof(nlineinfos)));
+       _CHECK_IO(SafeWrite(v,write,up,&ndefaultparams,sizeof(ndefaultparams)));
        _CHECK_IO(SafeWrite(v,write,up,&ninstructions,sizeof(ninstructions)));
        _CHECK_IO(SafeWrite(v,write,up,&nfunctions,sizeof(nfunctions)));
        _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
@@ -342,6 +381,9 @@ bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
        _CHECK_IO(SafeWrite(v,write,up,_lineinfos,sizeof(SQLineInfo)*nlineinfos));
 
        _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
+       _CHECK_IO(SafeWrite(v,write,up,_defaultparams,sizeof(SQInteger)*ndefaultparams));
+
+       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
        _CHECK_IO(SafeWrite(v,write,up,_instructions,sizeof(SQInstruction)*ninstructions));
 
        _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
@@ -358,7 +400,7 @@ bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr
 {
        SQInteger i, nliterals,nparameters;
        SQInteger noutervalues ,nlocalvarinfos ;
-       SQInteger nlineinfos,ninstructions ,nfunctions ;
+       SQInteger nlineinfos,ninstructions ,nfunctions,ndefaultparams ;
        SQObjectPtr sourcename, name;
        SQObjectPtr o;
        _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
@@ -371,10 +413,13 @@ bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr
        _CHECK_IO(SafeRead(v,read,up, &noutervalues, sizeof(noutervalues)));
        _CHECK_IO(SafeRead(v,read,up, &nlocalvarinfos, sizeof(nlocalvarinfos)));
        _CHECK_IO(SafeRead(v,read,up, &nlineinfos, sizeof(nlineinfos)));
+       _CHECK_IO(SafeRead(v,read,up, &ndefaultparams, sizeof(ndefaultparams)));
        _CHECK_IO(SafeRead(v,read,up, &ninstructions, sizeof(ninstructions)));
        _CHECK_IO(SafeRead(v,read,up, &nfunctions, sizeof(nfunctions)));
+       
 
-       SQFunctionProto *f = SQFunctionProto::Create(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos);
+       SQFunctionProto *f = SQFunctionProto::Create(ninstructions,nliterals,nparameters,
+                       nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams);
        SQObjectPtr proto = f; //gets a ref in case of failure
        f->_sourcename = sourcename;
        f->_name = name;
@@ -415,6 +460,9 @@ bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr
        _CHECK_IO(SafeRead(v,read,up, f->_lineinfos, sizeof(SQLineInfo)*nlineinfos));
 
        _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
+       _CHECK_IO(SafeRead(v,read,up, f->_defaultparams, sizeof(SQInteger)*ndefaultparams));
+
+       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
        _CHECK_IO(SafeRead(v,read,up, f->_instructions, sizeof(SQInstruction)*ninstructions));
 
        _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
@@ -425,6 +473,7 @@ bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr
        _CHECK_IO(SafeRead(v,read,up, &f->_stacksize, sizeof(f->_stacksize)));
        _CHECK_IO(SafeRead(v,read,up, &f->_bgenerator, sizeof(f->_bgenerator)));
        _CHECK_IO(SafeRead(v,read,up, &f->_varparams, sizeof(f->_varparams)));
+       
        ret = f;
        return true;
 }
@@ -513,6 +562,7 @@ void SQClosure::Mark(SQCollectable **chain)
 {
        START_MARK()
                for(SQUnsignedInteger i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain);
+               for(SQUnsignedInteger i = 0; i < _defaultparams.size(); i++) SQSharedState::MarkObject(_defaultparams[i], chain);
        END_MARK()
 }
 
index 02d5967..271bf41 100644 (file)
@@ -344,6 +344,9 @@ struct SQDelegable : public CHAINABLE_OBJ {
 SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx);
 typedef sqvector<SQObjectPtr> SQObjectPtrVec;
 typedef sqvector<SQInteger> SQIntVec;
+const SQChar *GetTypeName(const SQObjectPtr &obj1);
+const SQChar *IdType2Name(SQObjectType type);
+
 
 
 #endif //_SQOBJECT_H_
index 150bb56..4a25ae1 100644 (file)
@@ -145,26 +145,28 @@ void SQSharedState::Init()
 
        _constructoridx = SQString::Create(this,_SC("constructor"));
        _registry = SQTable::Create(this,0);
-       _table_default_delegate=CreateDefaultDelegate(this,_table_default_delegate_funcz);
-       _array_default_delegate=CreateDefaultDelegate(this,_array_default_delegate_funcz);
-       _string_default_delegate=CreateDefaultDelegate(this,_string_default_delegate_funcz);
-       _number_default_delegate=CreateDefaultDelegate(this,_number_default_delegate_funcz);
-       _closure_default_delegate=CreateDefaultDelegate(this,_closure_default_delegate_funcz);
-       _generator_default_delegate=CreateDefaultDelegate(this,_generator_default_delegate_funcz);
-       _thread_default_delegate=CreateDefaultDelegate(this,_thread_default_delegate_funcz);
-       _class_default_delegate=CreateDefaultDelegate(this,_class_default_delegate_funcz);
-       _instance_default_delegate=CreateDefaultDelegate(this,_instance_default_delegate_funcz);
-       _weakref_default_delegate=CreateDefaultDelegate(this,_weakref_default_delegate_funcz);
+       _consts = SQTable::Create(this,0);
+       _table_default_delegate = CreateDefaultDelegate(this,_table_default_delegate_funcz);
+       _array_default_delegate = CreateDefaultDelegate(this,_array_default_delegate_funcz);
+       _string_default_delegate = CreateDefaultDelegate(this,_string_default_delegate_funcz);
+       _number_default_delegate = CreateDefaultDelegate(this,_number_default_delegate_funcz);
+       _closure_default_delegate = CreateDefaultDelegate(this,_closure_default_delegate_funcz);
+       _generator_default_delegate = CreateDefaultDelegate(this,_generator_default_delegate_funcz);
+       _thread_default_delegate = CreateDefaultDelegate(this,_thread_default_delegate_funcz);
+       _class_default_delegate = CreateDefaultDelegate(this,_class_default_delegate_funcz);
+       _instance_default_delegate = CreateDefaultDelegate(this,_instance_default_delegate_funcz);
+       _weakref_default_delegate = CreateDefaultDelegate(this,_weakref_default_delegate_funcz);
 
 }
 
 SQSharedState::~SQSharedState()
 {
        _constructoridx = _null_;
-       _refs_table.Finalize();
        _table(_registry)->Finalize();
+       _table(_consts)->Finalize();
        _table(_metamethodsmap)->Finalize();
        _registry = _null_;
+       _consts = _null_;
        _metamethodsmap = _null_;
        while(!_systemstrings->empty()) {
                _systemstrings->back()=_null_;
@@ -172,24 +174,24 @@ SQSharedState::~SQSharedState()
        }
        _thread(_root_vm)->Finalize();
        _root_vm = _null_;
-       _table_default_delegate=_null_;
-       _array_default_delegate=_null_;
-       _string_default_delegate=_null_;
-       _number_default_delegate=_null_;
-       _closure_default_delegate=_null_;
-       _generator_default_delegate=_null_;
-       _thread_default_delegate=_null_;
-       _class_default_delegate=_null_;
-       _instance_default_delegate=_null_;
-       _weakref_default_delegate=_null_;
-       
+       _table_default_delegate = _null_;
+       _array_default_delegate = _null_;
+       _string_default_delegate = _null_;
+       _number_default_delegate = _null_;
+       _closure_default_delegate = _null_;
+       _generator_default_delegate = _null_;
+       _thread_default_delegate = _null_;
+       _class_default_delegate = _null_;
+       _instance_default_delegate = _null_;
+       _weakref_default_delegate = _null_;
+       _refs_table.Finalize();
 #ifndef NO_GARBAGE_COLLECTOR
-       SQCollectable *t=_gc_chain;
-       SQCollectable *nx=NULL;
+       SQCollectable *t = _gc_chain;
+       SQCollectable *nx = NULL;
        while(t) {
                t->_uiRef++;
                t->Finalize();
-               nx=t->_next;
+               nx = t->_next;
                if(--t->_uiRef == 0)
                        t->Release();
                t=nx;
@@ -249,6 +251,7 @@ SQInteger SQSharedState::CollectGarbage(SQVM *vm)
        SQInteger x = _table(_thread(_root_vm)->_roottable)->CountUsed();
        _refs_table.Mark(&tchain);
        MarkObject(_registry,&tchain);
+       MarkObject(_consts,&tchain);
        MarkObject(_metamethodsmap,&tchain);
        MarkObject(_table_default_delegate,&tchain);
        MarkObject(_array_default_delegate,&tchain);
index fb67665..a0b739c 100644 (file)
@@ -73,6 +73,7 @@ public:
        StringTable *_stringtable;
        RefTable _refs_table;
        SQObjectPtr _registry;
+       SQObjectPtr _consts;
        SQObjectPtr _constructoridx;
 #ifndef NO_GARBAGE_COLLECTOR
        SQCollectable *_gc_chain;
index 25ebcf9..4e96fbb 100644 (file)
@@ -267,39 +267,6 @@ bool SQVM::StringCat(const SQObjectPtr &str,const SQObjectPtr &obj,SQObjectPtr &
        return true;
 }
 
-const SQChar *IdType2Name(SQObjectType type)
-{
-       switch(_RAW_TYPE(type))
-       {
-       case _RT_NULL:return _SC("null");
-       case _RT_INTEGER:return _SC("integer");
-       case _RT_FLOAT:return _SC("float");
-       case _RT_BOOL:return _SC("bool");
-       case _RT_STRING:return _SC("string");
-       case _RT_TABLE:return _SC("table");
-       case _RT_ARRAY:return _SC("array");
-       case _RT_GENERATOR:return _SC("generator");
-       case _RT_CLOSURE:
-       case _RT_NATIVECLOSURE:
-               return _SC("function");
-       case _RT_USERDATA:
-       case _RT_USERPOINTER:
-               return _SC("userdata");
-       case _RT_THREAD: return _SC("thread");
-       case _RT_FUNCPROTO: return _SC("function");
-       case _RT_CLASS: return _SC("class");
-       case _RT_INSTANCE: return _SC("instance");
-       case _RT_WEAKREF: return _SC("weakref");
-       default:
-               return NULL;
-       }
-}
-
-const SQChar *GetTypeName(const SQObjectPtr &obj1)
-{
-       return IdType2Name(type(obj1)); 
-}
-
 void SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest)
 {
        if(is_delegable(obj1) && _delegable(obj1)->_delegate) {
@@ -333,16 +300,22 @@ bool SQVM::Init(SQVM *friendvm, SQInteger stacksize)
 
 extern SQInstructionDesc g_InstrDesc[];
 
-bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger nargs,SQInteger stackbase,bool tailcall)
+bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger args,SQInteger stackbase,bool tailcall)
 {
        SQFunctionProto *func = _funcproto(closure->_function);
        
        const SQInteger paramssize = func->_nparameters;
        const SQInteger newtop = stackbase + func->_stacksize;
-       
-       
+       SQInteger nargs = args;
        if (paramssize != nargs) {
-               if(func->_varparams)
+               SQInteger ndef = func->_ndefaultparams;
+               if(ndef && nargs < paramssize) {
+                       SQInteger diff = paramssize - nargs;
+                       for(SQInteger n = ndef - diff; n < ndef; n++) {
+                               _stack._vals[stackbase + (nargs++)] = closure->_defaultparams[n];
+                       }
+               }
+               else if(func->_varparams)
                {
                        if (nargs < paramssize) {
                                Raise_Error(_SC("wrong number of parameters"));
@@ -377,7 +350,7 @@ bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger nargs,SQInteg
                ci->_ncalls++;
        }
        ci->_vargs.size = (SQInt32)(nargs - paramssize);
-       ci->_vargs.base = (SQInt32) (_vargsstack.size()-(ci->_vargs.size));
+       ci->_vargs.base = (SQInt32)(_vargsstack.size()-(ci->_vargs.size));
        ci->_closure._unVal.pClosure = closure;
        ci->_closure._type = OT_CLOSURE;
        ci->_literals = func->_literals;
@@ -389,6 +362,8 @@ bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger nargs,SQInteg
                
        _top = newtop;
        _stackbase = stackbase;
+       if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))
+               CallDebugHook(_SC('c'));
        return true;
 }
 
@@ -579,6 +554,14 @@ bool SQVM::CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func)
                        }
                }
        }
+       SQInteger ndefparams;
+       if((ndefparams = func->_ndefaultparams)) {
+               closure->_defaultparams.reserve(ndefparams);
+               for(SQInteger i = 0; i < ndefparams; i++) {
+                       SQInteger spos = func->_defaultparams[i];
+                       closure->_defaultparams.push_back(_stack._vals[_stackbase + spos]);
+               }
+       }
        target = closure;
        return true;
 
@@ -730,46 +713,41 @@ exception_restore:
                                        ct_stackbase = _stackbase+arg2;
 
 common_call:
+                                       SQObjectPtr clo = temp_reg;
                                        SQInteger last_top = _top;
-                                       switch (type(temp_reg)) {
+                                       switch (type(clo)) {
                                        case OT_CLOSURE:{
-                                               _GUARD(StartCall(_closure(temp_reg), ct_target, arg3, ct_stackbase, ct_tailcall));
-                                               if (_funcproto(_closure(temp_reg)->_function)->_bgenerator) {
-                                                       SQGenerator *gen = SQGenerator::Create(_ss(this), _closure(temp_reg));
+                                               _GUARD(StartCall(_closure(clo), ct_target, arg3, ct_stackbase, ct_tailcall));
+                                               if (_funcproto(_closure(clo)->_function)->_bgenerator) {
+                                                       SQGenerator *gen = SQGenerator::Create(_ss(this), _closure(clo));
                                                        _GUARD(gen->Yield(this));
-                                                       Return(1, ct_target, temp_reg);
-
-
-
-
+                                                       Return(1, ct_target, clo);
                                                        STK(ct_target) = gen;
                                                        while (last_top >= _top) _stack._vals[last_top--].Null();
                                                        continue;
                                                }
-                                               if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))
-                                                       CallDebugHook(_SC('c'));
                                                }
                                                continue;
                                        case OT_NATIVECLOSURE: {
                                                bool suspend;
-                                               _GUARD(CallNative(_nativeclosure(temp_reg), arg3, ct_stackbase, temp_reg,suspend));
+                                               _GUARD(CallNative(_nativeclosure(clo), arg3, ct_stackbase, clo,suspend));
                                                if(suspend){
                                                        _suspended = SQTrue;
                                                        _suspended_target = ct_target;
                                                        _suspended_root = ci->_root;
                                                        _suspended_traps = traps;
                                                        _suspend_varargs = ci->_vargs;
-                                                       outres = temp_reg;
+                                                       outres = clo;
                                                        return true;
                                                }
                                                if(ct_target != -1) { //skip return value for constructors
-                                                       STK(ct_target) = temp_reg;
+                                                       STK(ct_target) = clo;
                                                }
                                                                                   }
                                                continue;
                                        case OT_CLASS:{
                                                SQObjectPtr inst;
-                                               _GUARD(CreateClassInstance(_class(temp_reg),inst,temp_reg));
+                                               _GUARD(CreateClassInstance(_class(clo),inst,temp_reg));
                                                STK(ct_target) = inst;
                                                ct_target = -1; //fakes return value target so that is not overwritten by the constructor
                                                if(type(temp_reg) != OT_NULL) {
@@ -782,17 +760,17 @@ common_call:
                                        case OT_USERDATA:
                                        case OT_INSTANCE:
                                                {
-                                               Push(temp_reg);
+                                               Push(clo);
                                                for (SQInteger i = 0; i < arg3; i++) Push(STK(arg2 + i));
-                                               if (_delegable(temp_reg) && CallMetaMethod(_delegable(temp_reg), MT_CALL, arg3+1, temp_reg)){
-                                                       STK(ct_target) = temp_reg;
+                                               if (_delegable(clo) && CallMetaMethod(_delegable(clo), MT_CALL, arg3+1, clo)){
+                                                       STK(ct_target) = clo;
                                                        break;
                                                }
-                                               Raise_Error(_SC("attempt to call '%s'"), GetTypeName(temp_reg));
+                                               Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo));
                                                SQ_THROW();
                                          }
                                        default:
-                                               Raise_Error(_SC("attempt to call '%s'"), GetTypeName(temp_reg));
+                                               Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo));
                                                SQ_THROW();
                                        }
                                }
@@ -1316,6 +1294,14 @@ bool SQVM::NewSlot(const SQObjectPtr &self,const SQObjectPtr &key,const SQObject
                if(rawcall) _table(self)->NewSlot(key,val); //cannot fail
                
                break;}
+       case OT_INSTANCE: {
+               SQObjectPtr res;
+               Push(self);Push(key);Push(val);
+               if(!CallMetaMethod(_instance(self),MT_NEWSLOT,3,res)) {
+                       Raise_Error(_SC("class instances do not support the new slot operator"));
+                       return false;
+               }
+               break;}
        case OT_CLASS: 
                if(!_class(self)->NewSlot(_ss(this),key,val,bstatic)) {
                        if(_class(self)->_locked) {
@@ -1475,7 +1461,7 @@ void SQVM::dumpstack(SQInteger stackbase,bool dumpall)
                case OT_CLOSURE:                scprintf(_SC("CLOSURE [%p]"),_closure(obj));break;
                case OT_NATIVECLOSURE:  scprintf(_SC("NATIVECLOSURE"));break;
                case OT_USERDATA:               scprintf(_SC("USERDATA %p[%p]"),_userdataval(obj),_userdata(obj)->_delegate);break;
-               case OT_GENERATOR:              scprintf(_SC("GENERATOR"));break;
+               case OT_GENERATOR:              scprintf(_SC("GENERATOR %p"),_generator(obj));break;
                case OT_THREAD:                 scprintf(_SC("THREAD [%p]"),_thread(obj));break;
                case OT_USERPOINTER:    scprintf(_SC("USERPOINTER %p"),_userpointer(obj));break;
                case OT_CLASS:                  scprintf(_SC("CLASS %p"),_class(obj));break;
index 89710ff..80bc594 100644 (file)
@@ -173,8 +173,6 @@ struct AutoDec{
 };
 
 inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));}
-const SQChar *GetTypeName(const SQObjectPtr &obj1);
-const SQChar *IdType2Name(SQObjectType type);
 
 #define _ss(_vm_) (_vm_)->_sharedstate