Made Mr_Tree graphic smaller, from 99 to 85 pixels.
[supertux.git] / src / squirrel / squirrel / sqcompiler.cpp
index 116bac8..ed99a73 100644 (file)
@@ -3,11 +3,12 @@
 */\r
 #include "sqpcheader.h"\r
 #include <stdarg.h>\r
+#include <setjmp.h>\r
 #include "sqopcodes.h"\r
 #include "sqstring.h"\r
 #include "sqfuncproto.h"\r
-#include "sqfuncstate.h"\r
 #include "sqcompiler.h"\r
+#include "sqfuncstate.h"\r
 #include "sqlexer.h"\r
 #include "sqvm.h"\r
 \r
@@ -26,15 +27,15 @@ struct ExpState
        bool _class_or_delete;\r
        bool _funcarg;\r
        bool _freevar;\r
-       int _deref;\r
+       SQInteger _deref;\r
 };\r
 \r
 typedef sqvector<ExpState> ExpStateVec;\r
 \r
 #define _exst (_expstates.top())\r
 \r
-#define BEGIN_BREAKBLE_BLOCK() int __nbreaks__=_fs->_unresolvedbreaks.size(); \\r
-                                                       int __ncontinues__=_fs->_unresolvedcontinues.size(); \\r
+#define BEGIN_BREAKBLE_BLOCK() SQInteger __nbreaks__=_fs->_unresolvedbreaks.size(); \\r
+                                                       SQInteger __ncontinues__=_fs->_unresolvedcontinues.size(); \\r
                                                        _fs->_breaktargets.push_back(0);_fs->_continuetargets.push_back(0);\r
 \r
 #define END_BREAKBLE_BLOCK(continue_target) {__nbreaks__=_fs->_unresolvedbreaks.size()-__nbreaks__; \\r
@@ -49,9 +50,14 @@ public:
        SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo)\r
        {\r
                _vm=v;\r
-               _lex.Init(_ss(v), rg, up);\r
+               _lex.Init(_ss(v), rg, up,ThrowError,this);\r
                _sourcename = SQString::Create(_ss(v), sourcename);\r
                _lineinfo = lineinfo;_raiseerror = raiseerror;\r
+               compilererror = NULL;\r
+       }\r
+       static void ThrowError(void *ud, const SQChar *s) {\r
+               SQCompiler *c = (SQCompiler *)ud;\r
+               c->Error(s);\r
        }\r
        void Error(const SQChar *s, ...)\r
        {\r
@@ -60,11 +66,12 @@ public:
                va_start(vl, s);\r
                scvsprintf(temp, s, vl);\r
                va_end(vl);\r
-               throw ParserException(temp);\r
+               compilererror = temp;\r
+               longjmp(_errorjmp,1);\r
        }\r
        void Lex(){     _token = _lex.Lex();}\r
        void PushExpState(){ _expstates.push_back(ExpState()); }\r
-       bool IsDerefToken(int tok)\r
+       bool IsDerefToken(SQInteger tok)\r
        {\r
                switch(tok){\r
                case _SC('='): case _SC('('): case TK_NEWSLOT:\r
@@ -78,51 +85,53 @@ public:
                _expstates.pop_back();\r
                return ret;\r
        }\r
-       SQObjectPtr Expect(int tok)\r
+       SQObject Expect(SQInteger tok)\r
        {\r
-               SQObjectPtr ret;\r
+               \r
                if(_token != tok) {\r
                        if(_token == TK_CONSTRUCTOR && tok == TK_IDENTIFIER) {\r
                                //ret = SQString::Create(_ss(_vm),_SC("constructor"));\r
                                //do nothing\r
                        }\r
                        else {\r
+                               const SQChar *etypename;\r
                                if(tok > 255) {\r
                                        switch(tok)\r
                                        {\r
                                        case TK_IDENTIFIER:\r
-                                               ret = SQString::Create(_ss(_vm), _SC("IDENTIFIER"));\r
+                                               etypename = _SC("IDENTIFIER");\r
                                                break;\r
                                        case TK_STRING_LITERAL:\r
-                                               ret = SQString::Create(_ss(_vm), _SC("STRING_LITERAL"));\r
+                                               etypename = _SC("STRING_LITERAL");\r
                                                break;\r
                                        case TK_INTEGER:\r
-                                               ret = SQString::Create(_ss(_vm), _SC("INTEGER"));\r
+                                               etypename = _SC("INTEGER");\r
                                                break;\r
                                        case TK_FLOAT:\r
-                                               ret = SQString::Create(_ss(_vm), _SC("FLOAT"));\r
+                                               etypename = _SC("FLOAT");\r
                                                break;\r
                                        default:\r
-                                               ret = _lex.Tok2Str(tok);\r
+                                               etypename = _lex.Tok2Str(tok);\r
                                        }\r
-                                       Error(_SC("expected '%s'"), _stringval(ret));\r
+                                       Error(_SC("expected '%s'"), etypename);\r
                                }\r
                                Error(_SC("expected '%c'"), tok);\r
                        }\r
                }\r
+               SQObjectPtr ret;\r
                switch(tok)\r
                {\r
                case TK_IDENTIFIER:\r
-                       ret = SQString::Create(_ss(_vm), _lex._svalue);\r
+                       ret = _fs->CreateString(_lex._svalue);\r
                        break;\r
                case TK_STRING_LITERAL:\r
-                       ret = SQString::Create(_ss(_vm), _lex._svalue,_lex._longstr.size()-1);\r
+                       ret = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1);\r
                        break;\r
                case TK_INTEGER:\r
-                       ret = _lex._nvalue;\r
+                       ret = SQObjectPtr(_lex._nvalue);\r
                        break;\r
                case TK_FLOAT:\r
-                       ret = _lex._fvalue;\r
+                       ret = SQObjectPtr(_lex._fvalue);\r
                        break;\r
                }\r
                Lex();\r
@@ -137,7 +146,7 @@ public:
                }\r
        }\r
        void MoveIfCurrentTargetIsLocal() {\r
-               int trg = _fs->TopTarget();\r
+               SQInteger trg = _fs->TopTarget();\r
                if(_fs->IsLocal(trg)) {\r
                        trg = _fs->PopTarget(); //no pops the target and move it\r
                        _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), trg);\r
@@ -145,16 +154,17 @@ public:
        }\r
        bool Compile(SQObjectPtr &o)\r
        {\r
-               SQ_TRY {\r
-                       _debugline = 1;\r
-                       _debugop = 0;\r
+               _debugline = 1;\r
+               _debugop = 0;\r
+\r
+               SQFuncState funcstate(_ss(_vm), NULL,ThrowError,this);\r
+               funcstate._name = SQString::Create(_ss(_vm), _SC("main"));\r
+               _fs = &funcstate;\r
+               _fs->AddParameter(_fs->CreateString(_SC("this")));\r
+               _fs->_sourcename = _sourcename;\r
+               SQInteger stacksize = _fs->GetStackSize();\r
+               if(setjmp(_errorjmp) == 0) {\r
                        Lex();\r
-                       SQFuncState funcstate(_ss(_vm), SQFunctionProto::Create(), NULL);\r
-                       _funcproto(funcstate._func)->_name = SQString::Create(_ss(_vm), _SC("main"));\r
-                       _fs = &funcstate;\r
-                       _fs->AddParameter(SQString::Create(_ss(_vm), _SC("this")));\r
-                       _funcproto(_fs->_func)->_sourcename = _sourcename;\r
-                       int stacksize = _fs->GetStackSize();\r
                        while(_token > 0){\r
                                Statement();\r
                                if(_lex._prevtoken != _SC('}')) OptionalSemicolon();\r
@@ -162,21 +172,18 @@ public:
                        CleanStack(stacksize);\r
                        _fs->AddLineInfos(_lex._currentline, _lineinfo, true);\r
                        _fs->AddInstruction(_OP_RETURN, 0xFF);\r
-                       _funcproto(_fs->_func)->_stacksize = _fs->_stacksize;\r
                        _fs->SetStackSize(0);\r
-                       _fs->Finalize();\r
-                       o = _fs->_func;\r
+                       o =_fs->BuildProto();\r
 #ifdef _DEBUG_DUMP\r
-                       _fs->Dump();\r
+                       _fs->Dump(_funcproto(o));\r
 #endif\r
                }\r
-               SQ_CATCH(ParserException,ex){\r
-                       if(_raiseerror && _ss(_vm)->_compilererrorhandler){\r
-                               SQObjectPtr ret;\r
-                               _ss(_vm)->_compilererrorhandler(_vm, ex.desc, type(_sourcename) == OT_STRING?_stringval(_sourcename):_SC("unknown"),\r
+               else {\r
+                       if(_raiseerror && _ss(_vm)->_compilererrorhandler) {\r
+                               _ss(_vm)->_compilererrorhandler(_vm, compilererror, type(_sourcename) == OT_STRING?_stringval(_sourcename):_SC("unknown"),\r
                                        _lex._currentline, _lex._currentcolumn);\r
                        }\r
-                       _vm->_lasterror = SQString::Create(_ss(_vm), ex.desc, -1);\r
+                       _vm->_lasterror = SQString::Create(_ss(_vm), compilererror, -1);\r
                        return false;\r
                }\r
                return true;\r
@@ -209,11 +216,11 @@ public:
                        }\r
                        else {\r
                                op = _OP_YIELD;\r
-                               _funcproto(_fs->_func)->_bgenerator = true;\r
+                               _fs->_bgenerator = true;\r
                        }\r
                        Lex();\r
                        if(!IsEndOfStatement()) {\r
-                               int retexp = _fs->GetCurrentPos()+1;\r
+                               SQInteger retexp = _fs->GetCurrentPos()+1;\r
                                CommaExpr();\r
                                if(op == _OP_RETURN && _fs->_traps > 0)\r
                                        _fs->AddInstruction(_OP_POPTRAP, _fs->_traps, 0);\r
@@ -252,7 +259,7 @@ public:
                        ClassStatement();\r
                        break;\r
                case _SC('{'):{\r
-                               int stacksize = _fs->GetStackSize();\r
+                               SQInteger stacksize = _fs->GetStackSize();\r
                                Lex();\r
                                Statements();\r
                                Expect(_SC('}'));\r
@@ -276,20 +283,20 @@ public:
        }\r
        void EmitDerefOp(SQOpcode op)\r
        {\r
-               int val = _fs->PopTarget();\r
-               int key = _fs->PopTarget();\r
-               int src = _fs->PopTarget();\r
+               SQInteger val = _fs->PopTarget();\r
+               SQInteger key = _fs->PopTarget();\r
+               SQInteger src = _fs->PopTarget();\r
         _fs->AddInstruction(op,_fs->PushTarget(),src,key,val);\r
        }\r
-       void Emit2ArgsOP(SQOpcode op, int p3 = 0)\r
+       void Emit2ArgsOP(SQOpcode op, SQInteger p3 = 0)\r
        {\r
-               int p2 = _fs->PopTarget(); //src in OP_GET\r
-               int p1 = _fs->PopTarget(); //key in OP_GET\r
+               SQInteger p2 = _fs->PopTarget(); //src in OP_GET\r
+               SQInteger p1 = _fs->PopTarget(); //key in OP_GET\r
                _fs->AddInstruction(op,_fs->PushTarget(), p1, p2, p3);\r
        }\r
-       void EmitCompoundArith(int tok,bool deref)\r
+       void EmitCompoundArith(SQInteger tok,bool deref)\r
        {\r
-               int oper;\r
+               SQInteger oper;\r
                switch(tok){\r
                case TK_MINUSEQ: oper = '-'; break;\r
                case TK_PLUSEQ: oper = '+'; break;\r
@@ -299,9 +306,9 @@ public:
                default: assert(0); break;\r
                };\r
                if(deref) {\r
-                       int val = _fs->PopTarget();\r
-                       int key = _fs->PopTarget();\r
-                       int src = _fs->PopTarget();\r
+                       SQInteger val = _fs->PopTarget();\r
+                       SQInteger key = _fs->PopTarget();\r
+                       SQInteger src = _fs->PopTarget();\r
                        //mixes dest obj and source val in the arg1(hack?)\r
                        _fs->AddInstruction(_OP_COMPARITH,_fs->PushTarget(),(src<<16)|val,key,oper);\r
                }\r
@@ -328,8 +335,8 @@ public:
                case TK_DIVEQ:\r
                case TK_MODEQ:\r
                {\r
-                               int op = _token;\r
-                               int ds = _exst._deref;\r
+                               SQInteger op = _token;\r
+                               SQInteger ds = _exst._deref;\r
                                bool freevar = _exst._freevar;\r
                                if(ds == DEREF_NO_DEREF) Error(_SC("can't assign expression"));\r
                                Lex(); Expression();\r
@@ -347,8 +354,8 @@ public:
                                        if(ds == DEREF_FIELD)\r
                                                EmitDerefOp(_OP_SET);\r
                                        else {//if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local\r
-                                               int p2 = _fs->PopTarget(); //src in OP_GET\r
-                                               int p1 = _fs->TopTarget(); //key in OP_GET\r
+                                               SQInteger p2 = _fs->PopTarget(); //src in OP_GET\r
+                                               SQInteger p1 = _fs->TopTarget(); //key in OP_GET\r
                                                _fs->AddInstruction(_OP_MOVE, p1, p2);\r
                                        }\r
                                        break;\r
@@ -365,17 +372,17 @@ public:
                case _SC('?'): {\r
                        Lex();\r
                        _fs->AddInstruction(_OP_JZ, _fs->PopTarget());\r
-                       int jzpos = _fs->GetCurrentPos();\r
-                       int trg = _fs->PushTarget();\r
+                       SQInteger jzpos = _fs->GetCurrentPos();\r
+                       SQInteger trg = _fs->PushTarget();\r
                        Expression();\r
-                       int first_exp = _fs->PopTarget();\r
+                       SQInteger first_exp = _fs->PopTarget();\r
                        if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);\r
-                       int endfirstexp = _fs->GetCurrentPos();\r
+                       SQInteger endfirstexp = _fs->GetCurrentPos();\r
                        _fs->AddInstruction(_OP_JMP, 0, 0);\r
                        Expect(_SC(':'));\r
-                       int jmppos = _fs->GetCurrentPos();\r
+                       SQInteger jmppos = _fs->GetCurrentPos();\r
                        Expression();\r
-                       int second_exp = _fs->PopTarget();\r
+                       SQInteger second_exp = _fs->PopTarget();\r
                        if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);\r
                        _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos);\r
                        _fs->SetIntructionParam(jzpos, 1, endfirstexp - jzpos + 1);\r
@@ -385,24 +392,24 @@ public:
                }\r
                return PopExpState();\r
        }\r
-       void BIN_EXP(SQOpcode op, void (SQCompiler::*f)(void),int op3 = 0)\r
+       void BIN_EXP(SQOpcode op, void (SQCompiler::*f)(void),SQInteger op3 = 0)\r
        {\r
                Lex(); (this->*f)();\r
-               int op1 = _fs->PopTarget();int op2 = _fs->PopTarget();\r
+               SQInteger op1 = _fs->PopTarget();SQInteger op2 = _fs->PopTarget();\r
                _fs->AddInstruction(op, _fs->PushTarget(), op1, op2, op3);\r
        }\r
        void LogicalOrExp()\r
        {\r
                LogicalAndExp();\r
                for(;;) if(_token == TK_OR) {\r
-                       int first_exp = _fs->PopTarget();\r
-                       int trg = _fs->PushTarget();\r
+                       SQInteger first_exp = _fs->PopTarget();\r
+                       SQInteger trg = _fs->PushTarget();\r
                        _fs->AddInstruction(_OP_OR, trg, 0, first_exp, 0);\r
-                       int jpos = _fs->GetCurrentPos();\r
+                       SQInteger jpos = _fs->GetCurrentPos();\r
                        if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);\r
                        Lex(); LogicalOrExp();\r
                        _fs->SnoozeOpt();\r
-                       int second_exp = _fs->PopTarget();\r
+                       SQInteger second_exp = _fs->PopTarget();\r
                        if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);\r
                        _fs->SnoozeOpt();\r
                        _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));\r
@@ -414,14 +421,14 @@ public:
                BitwiseOrExp();\r
                for(;;) switch(_token) {\r
                case TK_AND: {\r
-                       int first_exp = _fs->PopTarget();\r
-                       int trg = _fs->PushTarget();\r
+                       SQInteger first_exp = _fs->PopTarget();\r
+                       SQInteger trg = _fs->PushTarget();\r
                        _fs->AddInstruction(_OP_AND, trg, 0, first_exp, 0);\r
-                       int jpos = _fs->GetCurrentPos();\r
+                       SQInteger jpos = _fs->GetCurrentPos();\r
                        if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);\r
                        Lex(); LogicalAndExp();\r
                        _fs->SnoozeOpt();\r
-                       int second_exp = _fs->PopTarget();\r
+                       SQInteger second_exp = _fs->PopTarget();\r
                        if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);\r
                        _fs->SnoozeOpt();\r
                        _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));\r
@@ -499,23 +506,21 @@ public:
        //if 'pos' != -1 the previous variable is a local variable\r
        void PrefixedExpr()\r
        {\r
-               int pos = Factor();\r
+               SQInteger pos = Factor();\r
                for(;;) {\r
                        switch(_token) {\r
                        case _SC('.'): {\r
                                pos = -1;\r
-                               SQObjectPtr idx;\r
                                Lex(); \r
                                if(_token == TK_PARENT) {\r
                                        Lex();\r
                                        if(!NeedGet())\r
                                                Error(_SC("parent cannot be set"));\r
-                                       int src = _fs->PopTarget();\r
+                                       SQInteger src = _fs->PopTarget();\r
                                        _fs->AddInstruction(_OP_GETPARENT, _fs->PushTarget(), src);\r
                                }\r
                                else {\r
-                                       idx = Expect(TK_IDENTIFIER); \r
-                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetStringConstant(_stringval(idx)));\r
+                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));\r
                                        if(NeedGet()) Emit2ArgsOP(_OP_GET);\r
                                }\r
                                _exst._deref = DEREF_FIELD;\r
@@ -533,11 +538,11 @@ public:
                        case TK_MINUSMINUS:\r
                        case TK_PLUSPLUS:\r
                        if(_exst._deref != DEREF_NO_DEREF && !IsEndOfStatement()) { \r
-                               int tok = _token; Lex();\r
+                               SQInteger tok = _token; Lex();\r
                                if(pos < 0)\r
                                        Emit2ArgsOP(_OP_PINC,tok == TK_MINUSMINUS?-1:1);\r
                                else {//if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local\r
-                                       int src = _fs->PopTarget();\r
+                                       SQInteger src = _fs->PopTarget();\r
                                        _fs->AddInstruction(_OP_PINCL, _fs->PushTarget(), src, 0, tok == TK_MINUSMINUS?-1:1);\r
                                }\r
                                \r
@@ -548,10 +553,10 @@ public:
                                {\r
                                if(_exst._deref != DEREF_NO_DEREF) {\r
                                        if(pos<0) {\r
-                                               int key = _fs->PopTarget(); //key\r
-                                               int table = _fs->PopTarget(); //table etc...\r
-                                               int closure = _fs->PushTarget();\r
-                                               int ttarget = _fs->PushTarget();\r
+                                               SQInteger key = _fs->PopTarget(); //key\r
+                                               SQInteger table = _fs->PopTarget(); //table etc...\r
+                                               SQInteger closure = _fs->PushTarget();\r
+                                               SQInteger ttarget = _fs->PushTarget();\r
                                                _fs->AddInstruction(_OP_PREPCALL, closure, key, table, ttarget);\r
                                        }\r
                                        else{\r
@@ -569,13 +574,13 @@ public:
                        }\r
                }\r
        }\r
-       int Factor()\r
+       SQInteger Factor()\r
        {\r
                switch(_token)\r
                {\r
                case TK_STRING_LITERAL: {\r
-                               SQObjectPtr id(SQString::Create(_ss(_vm), _lex._svalue,_lex._longstr.size()-1));\r
-                               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetStringConstant(_stringval(id)));\r
+                               //SQObjectPtr id(SQString::Create(_ss(_vm), _lex._svalue,_lex._longstr.size()-1));\r
+                               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_fs->CreateString(_lex._svalue,_lex._longstr.size()-1)));\r
                                Lex(); \r
                        }\r
                        break;\r
@@ -584,7 +589,7 @@ public:
                        Expect(_SC('['));\r
                        Expression();\r
                        Expect(_SC(']'));\r
-                       int src = _fs->PopTarget();\r
+                       SQInteger src = _fs->PopTarget();\r
                        _fs->AddInstruction(_OP_GETVARGV, _fs->PushTarget(), src);\r
                                           }\r
                        break;\r
@@ -592,13 +597,13 @@ public:
                case TK_CONSTRUCTOR:\r
                case TK_THIS:{\r
                        _exst._freevar = false;\r
-                       SQObjectPtr id;\r
+                       SQObject id;\r
                                switch(_token) {\r
-                                       case TK_IDENTIFIER: id = SQString::Create(_ss(_vm), _lex._svalue); break;\r
-                                       case TK_THIS: id = SQString::Create(_ss(_vm), _SC("this")); break;\r
-                                       case TK_CONSTRUCTOR: id = SQString::Create(_ss(_vm), _SC("constructor")); break;\r
+                                       case TK_IDENTIFIER: id = _fs->CreateString(_lex._svalue); break;\r
+                                       case TK_THIS: id = _fs->CreateString(_SC("this")); break;\r
+                                       case TK_CONSTRUCTOR: id = _fs->CreateString(_SC("constructor")); break;\r
                                }\r
-                               int pos = -1;\r
+                               SQInteger pos = -1;\r
                                Lex();\r
                                if((pos = _fs->GetLocalVariable(id)) == -1) {\r
                                        //checks if is a free variable\r
@@ -608,7 +613,7 @@ public:
                                                _exst._freevar = true;\r
                                        } else {\r
                                                _fs->PushTarget(0);\r
-                                               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetStringConstant(_stringval(id)));\r
+                                               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));\r
                                                if(NeedGet()) Emit2ArgsOP(_OP_GET);\r
                                                _exst._deref = DEREF_FIELD;\r
                                        }\r
@@ -645,13 +650,13 @@ public:
                        break;\r
                case _SC('['): {\r
                                _fs->AddInstruction(_OP_NEWARRAY, _fs->PushTarget());\r
-                               int apos = _fs->GetCurrentPos(),key = 0;\r
+                               SQInteger apos = _fs->GetCurrentPos(),key = 0;\r
                                Lex();\r
                                while(_token != _SC(']')) {\r
                     Expression(); \r
                                        if(_token == _SC(',')) Lex();\r
-                                       int val = _fs->PopTarget();\r
-                                       int array = _fs->TopTarget();\r
+                                       SQInteger val = _fs->PopTarget();\r
+                                       SQInteger array = _fs->TopTarget();\r
                                        _fs->AddInstruction(_OP_APPENDARRAY, array, val);\r
                                        key++;\r
                                }\r
@@ -685,7 +690,7 @@ public:
        void UnaryOP(SQOpcode op)\r
        {\r
                Lex(); PrefixedExpr();\r
-               int src = _fs->PopTarget();\r
+               SQInteger src = _fs->PopTarget();\r
                _fs->AddInstruction(op, _fs->PushTarget(), src);\r
        }\r
        bool NeedGet()\r
@@ -700,7 +705,7 @@ public:
        \r
        void FunctionCallArgs()\r
        {\r
-               int nargs = 1;//this\r
+               SQInteger nargs = 1;//this\r
                 while(_token != _SC(')')) {\r
                         Expression(true);\r
                         MoveIfCurrentTargetIsLocal();\r
@@ -711,14 +716,14 @@ public:
                         }\r
                 }\r
                 Lex();\r
-                for(int i = 0; i < (nargs - 1); i++) _fs->PopTarget();\r
-                int stackbase = _fs->PopTarget();\r
-                int closure = _fs->PopTarget();\r
+                for(SQInteger i = 0; i < (nargs - 1); i++) _fs->PopTarget();\r
+                SQInteger stackbase = _fs->PopTarget();\r
+                SQInteger closure = _fs->PopTarget();\r
          _fs->AddInstruction(_OP_CALL, _fs->PushTarget(), closure, stackbase, nargs);\r
        }\r
-       void ParseTableOrClass(int separator,int terminator = '}')\r
+       void ParseTableOrClass(SQInteger separator,SQInteger terminator = '}')\r
        {\r
-               int tpos = _fs->GetCurrentPos(),nkeys = 0;\r
+               SQInteger tpos = _fs->GetCurrentPos(),nkeys = 0;\r
                \r
                while(_token != terminator) {\r
                        bool hasattrs = false;\r
@@ -731,11 +736,11 @@ public:
                        switch(_token) {\r
                                case TK_FUNCTION:\r
                                case TK_CONSTRUCTOR:{\r
-                                       int tk = _token;\r
+                                       SQInteger tk = _token;\r
                                        Lex();\r
-                                       SQObjectPtr id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : SQString::Create(_ss(_vm),_SC("constructor"));\r
+                                       SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : _fs->CreateString(_SC("constructor"));\r
                                        Expect(_SC('('));\r
-                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetStringConstant(_stringval(id)));\r
+                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));\r
                                        CreateFunction(id);\r
                                        _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);\r
                                                                  }\r
@@ -745,17 +750,17 @@ public:
                                        Expect(_SC('=')); Expression();\r
                                        break;\r
                                default :\r
-                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetStringConstant(_stringval(Expect(TK_IDENTIFIER))));\r
+                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));\r
                                        Expect(_SC('=')); Expression();\r
                        }\r
 \r
                        if(_token == separator) Lex();//optional comma/semicolon\r
                        nkeys++;\r
-                       int val = _fs->PopTarget();\r
-                       int key = _fs->PopTarget();\r
-                       int attrs = hasattrs ? _fs->PopTarget():-1;\r
+                       SQInteger val = _fs->PopTarget();\r
+                       SQInteger key = _fs->PopTarget();\r
+                       SQInteger attrs = hasattrs ? _fs->PopTarget():-1;\r
                        assert(hasattrs && attrs == key-1 || !hasattrs);\r
-                       int table = _fs->TopTarget(); //<<BECAUSE OF THIS NO COMMON EMIT FUNC IS POSSIBLE\r
+                       SQInteger table = _fs->TopTarget(); //<<BECAUSE OF THIS NO COMMON EMIT FUNC IS POSSIBLE\r
                        _fs->AddInstruction(hasattrs?_OP_NEWSLOTA:_OP_NEWSLOT, _fs->PushTarget(), table, key, val);\r
                        _fs->PopTarget();\r
                }\r
@@ -765,13 +770,13 @@ public:
        }\r
        void LocalDeclStatement()\r
        {\r
-               SQObjectPtr varname;\r
+               SQObject varname;\r
                do {\r
                        Lex(); varname = Expect(TK_IDENTIFIER);\r
                        if(_token == _SC('=')) {\r
                                Lex(); Expression();\r
-                               int src = _fs->PopTarget();\r
-                               int dest = _fs->PushTarget();\r
+                               SQInteger src = _fs->PopTarget();\r
+                               SQInteger dest = _fs->PushTarget();\r
                                if(dest != src) _fs->AddInstruction(_OP_MOVE, dest, src);\r
                        }\r
                        else{\r
@@ -784,19 +789,19 @@ public:
        }\r
        void IfStatement()\r
        {\r
-               int jmppos;\r
+               SQInteger jmppos;\r
                bool haselse = false;\r
                Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));\r
                _fs->AddInstruction(_OP_JZ, _fs->PopTarget());\r
-               int jnepos = _fs->GetCurrentPos();\r
-               int stacksize = _fs->GetStackSize();\r
+               SQInteger jnepos = _fs->GetCurrentPos();\r
+               SQInteger stacksize = _fs->GetStackSize();\r
                \r
                Statement();\r
                //\r
                if(_token != _SC('}') && _token != TK_ELSE) OptionalSemicolon();\r
                \r
                CleanStack(stacksize);\r
-               int endifblock = _fs->GetCurrentPos();\r
+               SQInteger endifblock = _fs->GetCurrentPos();\r
                if(_token == TK_ELSE){\r
                        haselse = true;\r
                        stacksize = _fs->GetStackSize();\r
@@ -811,8 +816,8 @@ public:
        }\r
        void WhileStatement()\r
        {\r
-               int jzpos, jmppos;\r
-               int stacksize = _fs->GetStackSize();\r
+               SQInteger jzpos, jmppos;\r
+               SQInteger stacksize = _fs->GetStackSize();\r
                jmppos = _fs->GetCurrentPos();\r
                Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));\r
                \r
@@ -832,13 +837,13 @@ public:
        void DoWhileStatement()\r
        {\r
                Lex();\r
-               int jzpos = _fs->GetCurrentPos();\r
-               int stacksize = _fs->GetStackSize();\r
+               SQInteger jzpos = _fs->GetCurrentPos();\r
+               SQInteger stacksize = _fs->GetStackSize();\r
                BEGIN_BREAKBLE_BLOCK()\r
                Statement();\r
                CleanStack(stacksize);\r
                Expect(TK_WHILE);\r
-               int continuetrg = _fs->GetCurrentPos();\r
+               SQInteger continuetrg = _fs->GetCurrentPos();\r
                Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));\r
                _fs->AddInstruction(_OP_JNZ, _fs->PopTarget(), jzpos - _fs->GetCurrentPos() - 1);\r
                END_BREAKBLE_BLOCK(continuetrg);\r
@@ -846,7 +851,7 @@ public:
        void ForStatement()\r
        {\r
                Lex();\r
-               int stacksize = _fs->GetStackSize();\r
+               SQInteger stacksize = _fs->GetStackSize();\r
                Expect(_SC('('));\r
                if(_token == TK_LOCAL) LocalDeclStatement();\r
                else if(_token != _SC(';')){\r
@@ -855,31 +860,31 @@ public:
                }\r
                Expect(_SC(';'));\r
                _fs->SnoozeOpt();\r
-               int jmppos = _fs->GetCurrentPos();\r
-               int jzpos = -1;\r
+               SQInteger jmppos = _fs->GetCurrentPos();\r
+               SQInteger jzpos = -1;\r
                if(_token != _SC(';')) { CommaExpr(); _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); jzpos = _fs->GetCurrentPos(); }\r
                Expect(_SC(';'));\r
                _fs->SnoozeOpt();\r
-               int expstart = _fs->GetCurrentPos() + 1;\r
+               SQInteger expstart = _fs->GetCurrentPos() + 1;\r
                if(_token != _SC(')')) {\r
                        CommaExpr();\r
                        _fs->PopTarget();\r
                }\r
                Expect(_SC(')'));\r
                _fs->SnoozeOpt();\r
-               int expend = _fs->GetCurrentPos();\r
-               int expsize = (expend - expstart) + 1;\r
+               SQInteger expend = _fs->GetCurrentPos();\r
+               SQInteger expsize = (expend - expstart) + 1;\r
                SQInstructionVec exp;\r
                if(expsize > 0) {\r
-                       for(int i = 0; i < expsize; i++)\r
+                       for(SQInteger i = 0; i < expsize; i++)\r
                                exp.push_back(_fs->GetInstruction(expstart + i));\r
                        _fs->PopInstructions(expsize);\r
                }\r
                BEGIN_BREAKBLE_BLOCK()\r
                Statement();\r
-               int continuetrg = _fs->GetCurrentPos();\r
+               SQInteger continuetrg = _fs->GetCurrentPos();\r
                if(expsize > 0) {\r
-                       for(int i = 0; i < expsize; i++)\r
+                       for(SQInteger i = 0; i < expsize; i++)\r
                                _fs->AddInstruction(exp[i]);\r
                }\r
                _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1, 0);\r
@@ -890,34 +895,34 @@ public:
        }\r
        void ForEachStatement()\r
        {\r
-               SQObjectPtr idxname, valname;\r
+               SQObject idxname, valname;\r
                Lex(); Expect(_SC('(')); valname = Expect(TK_IDENTIFIER);\r
                if(_token == _SC(',')) {\r
                        idxname = valname;\r
                        Lex(); valname = Expect(TK_IDENTIFIER);\r
                }\r
                else{\r
-                       idxname = SQString::Create(_ss(_vm), _SC("@INDEX@"));\r
+                       idxname = _fs->CreateString(_SC("@INDEX@"));\r
                }\r
                Expect(TK_IN);\r
                \r
                //save the stack size\r
-               int stacksize = _fs->GetStackSize();\r
+               SQInteger stacksize = _fs->GetStackSize();\r
                //put the table in the stack(evaluate the table expression)\r
                Expression(); Expect(_SC(')'));\r
-               int container = _fs->TopTarget();\r
+               SQInteger container = _fs->TopTarget();\r
                //push the index local var\r
-               int indexpos = _fs->PushLocalVariable(idxname);\r
+               SQInteger indexpos = _fs->PushLocalVariable(idxname);\r
                _fs->AddInstruction(_OP_LOADNULLS, indexpos,1);\r
                //push the value local var\r
-               int valuepos = _fs->PushLocalVariable(valname);\r
+               SQInteger valuepos = _fs->PushLocalVariable(valname);\r
                _fs->AddInstruction(_OP_LOADNULLS, valuepos,1);\r
                //push reference index\r
-               int itrpos = _fs->PushLocalVariable(SQString::Create(_ss(_vm), _SC("@ITERATOR@"))); //use invalid id to make it inaccessible\r
+               SQInteger itrpos = _fs->PushLocalVariable(_fs->CreateString(_SC("@ITERATOR@"))); //use invalid id to make it inaccessible\r
                _fs->AddInstruction(_OP_LOADNULLS, itrpos,1);\r
-               int jmppos = _fs->GetCurrentPos();\r
+               SQInteger jmppos = _fs->GetCurrentPos();\r
                _fs->AddInstruction(_OP_FOREACH, container, 0, indexpos);\r
-               int foreachpos = _fs->GetCurrentPos();\r
+               SQInteger foreachpos = _fs->GetCurrentPos();\r
                //generate the statement code\r
                BEGIN_BREAKBLE_BLOCK()\r
                Statement();\r
@@ -931,11 +936,11 @@ public:
        {\r
                Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));\r
                Expect(_SC('{'));\r
-               int expr = _fs->TopTarget();\r
+               SQInteger expr = _fs->TopTarget();\r
                bool bfirst = true;\r
-               int tonextcondjmp = -1;\r
-               int skipcondjmp = -1;\r
-               int __nbreaks__ = _fs->_unresolvedbreaks.size();\r
+               SQInteger tonextcondjmp = -1;\r
+               SQInteger skipcondjmp = -1;\r
+               SQInteger __nbreaks__ = _fs->_unresolvedbreaks.size();\r
                _fs->_breaktargets.push_back(0);\r
                while(_token == TK_CASE) {\r
                        if(!bfirst) {\r
@@ -945,7 +950,7 @@ public:
                        }\r
                        //condition\r
                        Lex(); Expression(); Expect(_SC(':'));\r
-                       int trg = _fs->PopTarget();\r
+                       SQInteger trg = _fs->PopTarget();\r
                        _fs->AddInstruction(_OP_EQ, trg, trg, expr);\r
                        _fs->AddInstruction(_OP_JZ, trg, 0);\r
                        //end condition\r
@@ -953,7 +958,7 @@ public:
                                _fs->SetIntructionParam(skipcondjmp, 1, (_fs->GetCurrentPos() - skipcondjmp));\r
                        }\r
                        tonextcondjmp = _fs->GetCurrentPos();\r
-                       int stacksize = _fs->GetStackSize();\r
+                       SQInteger stacksize = _fs->GetStackSize();\r
                        Statements();\r
                        _fs->SetStackSize(stacksize);\r
                        bfirst = false;\r
@@ -962,7 +967,7 @@ public:
                        _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp);\r
                if(_token == TK_DEFAULT) {\r
                        Lex(); Expect(_SC(':'));\r
-                       int stacksize = _fs->GetStackSize();\r
+                       SQInteger stacksize = _fs->GetStackSize();\r
                        Statements();\r
                        _fs->SetStackSize(stacksize);\r
                }\r
@@ -975,16 +980,16 @@ public:
        }\r
        void FunctionStatement()\r
        {\r
-               SQObjectPtr id;\r
+               SQObject id;\r
                Lex(); id = Expect(TK_IDENTIFIER);\r
                _fs->PushTarget(0);\r
-               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetStringConstant(_stringval(id)));\r
+               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));\r
                if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);\r
                \r
                while(_token == TK_DOUBLE_COLON) {\r
                        Lex();\r
                        id = Expect(TK_IDENTIFIER);\r
-                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetStringConstant(_stringval(id)));\r
+                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));\r
                        if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);\r
                }\r
                Expect(_SC('('));\r
@@ -1011,30 +1016,30 @@ public:
        }\r
        void TryCatchStatement()\r
        {\r
-               SQObjectPtr exid;\r
+               SQObject exid;\r
                Lex();\r
                _fs->AddInstruction(_OP_PUSHTRAP,0,0);\r
                _fs->_traps++;\r
                if(_fs->_breaktargets.size()) _fs->_breaktargets.top()++;\r
                if(_fs->_continuetargets.size()) _fs->_continuetargets.top()++;\r
-               int trappos = _fs->GetCurrentPos();\r
+               SQInteger trappos = _fs->GetCurrentPos();\r
                Statement();\r
                _fs->_traps--;\r
                _fs->AddInstruction(_OP_POPTRAP, 1, 0);\r
                if(_fs->_breaktargets.size()) _fs->_breaktargets.top()--;\r
                if(_fs->_continuetargets.size()) _fs->_continuetargets.top()--;\r
                _fs->AddInstruction(_OP_JMP, 0, 0);\r
-               int jmppos = _fs->GetCurrentPos();\r
+               SQInteger jmppos = _fs->GetCurrentPos();\r
                _fs->SetIntructionParam(trappos, 1, (_fs->GetCurrentPos() - trappos));\r
                Expect(TK_CATCH); Expect(_SC('(')); exid = Expect(TK_IDENTIFIER); Expect(_SC(')'));\r
-               int stacksize = _fs->GetStackSize();\r
-               int ex_target = _fs->PushLocalVariable(exid);\r
+               SQInteger stacksize = _fs->GetStackSize();\r
+               SQInteger ex_target = _fs->PushLocalVariable(exid);\r
                _fs->SetIntructionParam(trappos, 0, ex_target);\r
                Statement();\r
                _fs->SetIntructionParams(jmppos, 0, (_fs->GetCurrentPos() - jmppos), 0);\r
                CleanStack(stacksize);\r
        }\r
-       void FunctionExp(int ftype)\r
+       void FunctionExp(SQInteger ftype)\r
        {\r
                Lex(); Expect(_SC('('));\r
                CreateFunction(_null_);\r
@@ -1042,8 +1047,8 @@ public:
        }\r
        void ClassExp()\r
        {\r
-               int base = -1;\r
-               int attrs = -1;\r
+               SQInteger base = -1;\r
+               SQInteger attrs = -1;\r
                if(_token == TK_EXTENDS) {\r
                        Lex(); Expression();\r
                        base = _fs->TopTarget();\r
@@ -1065,7 +1070,7 @@ public:
                Lex(); CommaExpr();\r
                Expect(_SC(':'));\r
                CommaExpr();\r
-               int table = _fs->PopTarget(), delegate = _fs->PopTarget();\r
+               SQInteger table = _fs->PopTarget(), delegate = _fs->PopTarget();\r
                _fs->AddInstruction(_OP_DELEGATE, _fs->PushTarget(), table, delegate);\r
        }\r
        void DeleteExpr()\r
@@ -1080,7 +1085,7 @@ public:
                if(es._deref == DEREF_FIELD) Emit2ArgsOP(_OP_DELETE);\r
                else Error(_SC("cannot delete a local"));\r
        }\r
-       void PrefixIncDec(int token)\r
+       void PrefixIncDec(SQInteger token)\r
        {\r
                ExpState es;\r
                Lex(); PushExpState();\r
@@ -1090,27 +1095,28 @@ public:
                es = PopExpState();\r
                if(es._deref == DEREF_FIELD) Emit2ArgsOP(_OP_INC,token == TK_MINUSMINUS?-1:1);\r
                else {\r
-                       int src = _fs->PopTarget();\r
+                       SQInteger src = _fs->PopTarget();\r
                        _fs->AddInstruction(_OP_INCL, _fs->PushTarget(), src, 0, token == TK_MINUSMINUS?-1:1);\r
                }\r
        }\r
-       void CreateFunction(SQObjectPtr name)\r
+       void CreateFunction(SQObject &name)\r
        {\r
-               SQFuncState funcstate(_ss(_vm), SQFunctionProto::Create(), _fs);\r
-               _funcproto(funcstate._func)->_name = name;\r
-               SQObjectPtr paramname;\r
-               funcstate.AddParameter(SQString::Create(_ss(_vm), _SC("this")));\r
-               _funcproto(funcstate._func)->_sourcename = _sourcename;\r
+               \r
+               SQFuncState *funcstate = _fs->PushChildState(_ss(_vm));\r
+               funcstate->_name = name;\r
+               SQObject paramname;\r
+               funcstate->AddParameter(_fs->CreateString(_SC("this")));\r
+               funcstate->_sourcename = _sourcename;\r
                while(_token!=_SC(')')) {\r
                        if(_token == TK_VARPARAMS) {\r
-                               funcstate._varparams = true;\r
+                               funcstate->_varparams = true;\r
                                Lex();\r
                                if(_token != _SC(')')) Error(_SC("expected ')'"));\r
                                break;\r
                        }\r
                        else {\r
                                paramname = Expect(TK_IDENTIFIER);\r
-                               funcstate.AddParameter(paramname);\r
+                               funcstate->AddParameter(paramname);\r
                                if(_token == _SC(',')) Lex();\r
                                else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));\r
                        }\r
@@ -1122,7 +1128,7 @@ public:
                        while(_token != _SC(')')) {\r
                                paramname = Expect(TK_IDENTIFIER);\r
                                //outers are treated as implicit local variables\r
-                               funcstate.AddOuterValue(paramname);\r
+                               funcstate->AddOuterValue(paramname);\r
                                if(_token == _SC(',')) Lex();\r
                                else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));\r
                        }\r
@@ -1130,38 +1136,39 @@ public:
                }\r
                \r
                SQFuncState *currchunk = _fs;\r
-               _fs = &funcstate;\r
+               _fs = funcstate;\r
                Statement();\r
-               funcstate.AddLineInfos(_lex._prevtoken == _SC('\n')?_lex._lasttokenline:_lex._currentline, _lineinfo, true);\r
-        funcstate.AddInstruction(_OP_RETURN, -1);\r
-               funcstate.SetStackSize(0);\r
-               _funcproto(_fs->_func)->_stacksize = _fs->_stacksize;\r
-               funcstate.Finalize();\r
+               funcstate->AddLineInfos(_lex._prevtoken == _SC('\n')?_lex._lasttokenline:_lex._currentline, _lineinfo, true);\r
+        funcstate->AddInstruction(_OP_RETURN, -1);\r
+               funcstate->SetStackSize(0);\r
+               //_fs->->_stacksize = _fs->_stacksize;\r
+               SQFunctionProto *func = funcstate->BuildProto();\r
 #ifdef _DEBUG_DUMP\r
-               funcstate.Dump();\r
+               funcstate->Dump(func);\r
 #endif\r
                _fs = currchunk;\r
-               _fs->_functions.push_back(funcstate._func);\r
+               _fs->_functions.push_back(func);\r
+               _fs->PopChildState();\r
        }\r
-       void CleanStack(int stacksize)\r
+       void CleanStack(SQInteger stacksize)\r
        {\r
                if(_fs->GetStackSize() != stacksize)\r
                        _fs->SetStackSize(stacksize);\r
        }\r
-       void ResolveBreaks(SQFuncState *funcstate, int ntoresolve)\r
+       void ResolveBreaks(SQFuncState *funcstate, SQInteger ntoresolve)\r
        {\r
                while(ntoresolve > 0) {\r
-                       int pos = funcstate->_unresolvedbreaks.back();\r
+                       SQInteger pos = funcstate->_unresolvedbreaks.back();\r
                        funcstate->_unresolvedbreaks.pop_back();\r
                        //set the jmp instruction\r
                        funcstate->SetIntructionParams(pos, 0, funcstate->GetCurrentPos() - pos, 0);\r
                        ntoresolve--;\r
                }\r
        }\r
-       void ResolveContinues(SQFuncState *funcstate, int ntoresolve, int targetpos)\r
+       void ResolveContinues(SQFuncState *funcstate, SQInteger ntoresolve, SQInteger targetpos)\r
        {\r
                while(ntoresolve > 0) {\r
-                       int pos = funcstate->_unresolvedcontinues.back();\r
+                       SQInteger pos = funcstate->_unresolvedcontinues.back();\r
                        funcstate->_unresolvedcontinues.pop_back();\r
                        //set the jmp instruction\r
                        funcstate->SetIntructionParams(pos, 0, targetpos - pos, 0);\r
@@ -1169,15 +1176,17 @@ public:
                }\r
        }\r
 private:\r
-       int _token;\r
+       SQInteger _token;\r
        SQFuncState *_fs;\r
        SQObjectPtr _sourcename;\r
        SQLexer _lex;\r
        bool _lineinfo;\r
        bool _raiseerror;\r
-       int _debugline;\r
-       int _debugop;\r
+       SQInteger _debugline;\r
+       SQInteger _debugop;\r
        ExpStateVec _expstates;\r
+       SQChar *compilererror;\r
+       jmp_buf _errorjmp;\r
        SQVM *_vm;\r
 };\r
 \r