*/\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
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
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
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
_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
}\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
}\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
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
}\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
ClassStatement();\r
break;\r
case _SC('{'):{\r
- int stacksize = _fs->GetStackSize();\r
+ SQInteger stacksize = _fs->GetStackSize();\r
Lex();\r
Statements();\r
Expect(_SC('}'));\r
}\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
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
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
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
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
}\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
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
//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
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
{\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
}\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
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
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
_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
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
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
\r
void FunctionCallArgs()\r
{\r
- int nargs = 1;//this\r
+ SQInteger nargs = 1;//this\r
while(_token != _SC(')')) {\r
Expression(true);\r
MoveIfCurrentTargetIsLocal();\r
}\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
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
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
}\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
}\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
}\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
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
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
}\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
}\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
{\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
}\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
_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
_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
}\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
}\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
}\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
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
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
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
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
}\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
}\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