|
@@ -842,8 +842,8 @@ public:
|
|
|
_fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE);
|
|
_fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE);
|
|
|
Lex();ParseTableOrClass(_SC(','),_SC('}'));
|
|
Lex();ParseTableOrClass(_SC(','),_SC('}'));
|
|
|
break;
|
|
break;
|
|
|
- case TK_FUNCTION: FunctionExp(_token);break;
|
|
|
|
|
- case _SC('@'): FunctionExp(_token,true);break;
|
|
|
|
|
|
|
+ case TK_FUNCTION: FunctionExp();break;
|
|
|
|
|
+ case _SC('@'): FunctionExp(true);break;
|
|
|
case TK_CLASS: Lex(); ClassExp();break;
|
|
case TK_CLASS: Lex(); ClassExp();break;
|
|
|
case _SC('-'):
|
|
case _SC('-'):
|
|
|
Lex();
|
|
Lex();
|
|
@@ -989,10 +989,15 @@ public:
|
|
|
SQInteger tk = _token;
|
|
SQInteger tk = _token;
|
|
|
Lex();
|
|
Lex();
|
|
|
SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : _fs->CreateString(_SC("constructor"));
|
|
SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : _fs->CreateString(_SC("constructor"));
|
|
|
|
|
+ _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
|
|
|
|
|
+ SQInteger boundtarget = 0xFF;
|
|
|
|
|
+ if (_token == _SC('[')) {
|
|
|
|
|
+ boundtarget = ParseBindEnv();
|
|
|
|
|
+ }
|
|
|
Expect(_SC('('));
|
|
Expect(_SC('('));
|
|
|
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
|
|
|
|
|
- CreateFunction(id);
|
|
|
|
|
- _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ CreateFunction(id, boundtarget);
|
|
|
|
|
+ _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, boundtarget);
|
|
|
}
|
|
}
|
|
|
break;
|
|
break;
|
|
|
case _SC('['):
|
|
case _SC('['):
|
|
@@ -1034,11 +1039,15 @@ public:
|
|
|
SQObject varname;
|
|
SQObject varname;
|
|
|
Lex();
|
|
Lex();
|
|
|
if( _token == TK_FUNCTION) {
|
|
if( _token == TK_FUNCTION) {
|
|
|
|
|
+ SQInteger boundtarget = 0xFF;
|
|
|
Lex();
|
|
Lex();
|
|
|
- varname = Expect(TK_IDENTIFIER);
|
|
|
|
|
|
|
+ varname = Expect(TK_IDENTIFIER);
|
|
|
|
|
+ if (_token == _SC('[')) {
|
|
|
|
|
+ boundtarget = ParseBindEnv();
|
|
|
|
|
+ }
|
|
|
Expect(_SC('('));
|
|
Expect(_SC('('));
|
|
|
- CreateFunction(varname,false);
|
|
|
|
|
- _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);
|
|
|
|
|
|
|
+ CreateFunction(varname,0xFF,false);
|
|
|
|
|
+ _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, boundtarget);
|
|
|
_fs->PopTarget();
|
|
_fs->PopTarget();
|
|
|
_fs->PushLocalVariable(varname);
|
|
_fs->PushLocalVariable(varname);
|
|
|
return;
|
|
return;
|
|
@@ -1310,9 +1319,13 @@ public:
|
|
|
_fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
|
|
_fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
|
|
|
if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);
|
|
if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);
|
|
|
}
|
|
}
|
|
|
|
|
+ SQInteger boundtarget = 0xFF;
|
|
|
|
|
+ if (_token == _SC('[')) {
|
|
|
|
|
+ boundtarget = ParseBindEnv();
|
|
|
|
|
+ }
|
|
|
Expect(_SC('('));
|
|
Expect(_SC('('));
|
|
|
- CreateFunction(id);
|
|
|
|
|
- _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);
|
|
|
|
|
|
|
+ CreateFunction(id, boundtarget);
|
|
|
|
|
+ _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, boundtarget);
|
|
|
EmitDerefOp(_OP_NEWSLOT);
|
|
EmitDerefOp(_OP_NEWSLOT);
|
|
|
_fs->PopTarget();
|
|
_fs->PopTarget();
|
|
|
}
|
|
}
|
|
@@ -1438,12 +1451,26 @@ public:
|
|
|
END_SCOPE();
|
|
END_SCOPE();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- void FunctionExp(SQInteger ftype,bool lambda = false)
|
|
|
|
|
|
|
+ SQInteger ParseBindEnv()
|
|
|
|
|
+ {
|
|
|
|
|
+ SQInteger boundtarget;
|
|
|
|
|
+ Lex();
|
|
|
|
|
+ Expression();
|
|
|
|
|
+ boundtarget = _fs->TopTarget();
|
|
|
|
|
+ Expect(_SC(']'));
|
|
|
|
|
+ return boundtarget;
|
|
|
|
|
+ }
|
|
|
|
|
+ void FunctionExp(bool lambda = false)
|
|
|
{
|
|
{
|
|
|
- Lex(); Expect(_SC('('));
|
|
|
|
|
|
|
+ Lex();
|
|
|
|
|
+ SQInteger boundtarget = 0xFF;
|
|
|
|
|
+ if (_token == _SC('[')) {
|
|
|
|
|
+ boundtarget = ParseBindEnv();
|
|
|
|
|
+ }
|
|
|
|
|
+ Expect(_SC('('));
|
|
|
SQObjectPtr dummy;
|
|
SQObjectPtr dummy;
|
|
|
- CreateFunction(dummy,lambda);
|
|
|
|
|
- _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, ftype == TK_FUNCTION?0:1);
|
|
|
|
|
|
|
+ CreateFunction(dummy, boundtarget, lambda);
|
|
|
|
|
+ _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, boundtarget);
|
|
|
}
|
|
}
|
|
|
void ClassExp()
|
|
void ClassExp()
|
|
|
{
|
|
{
|
|
@@ -1508,7 +1535,7 @@ public:
|
|
|
}
|
|
}
|
|
|
_es = es;
|
|
_es = es;
|
|
|
}
|
|
}
|
|
|
- void CreateFunction(SQObject &name,bool lambda = false)
|
|
|
|
|
|
|
+ void CreateFunction(SQObject &name,SQInteger boundtarget,bool lambda = false)
|
|
|
{
|
|
{
|
|
|
SQFuncState *funcstate = _fs->PushChildState(_ss(_vm));
|
|
SQFuncState *funcstate = _fs->PushChildState(_ss(_vm));
|
|
|
funcstate->_name = name;
|
|
funcstate->_name = name;
|
|
@@ -1542,6 +1569,9 @@ public:
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
Expect(_SC(')'));
|
|
Expect(_SC(')'));
|
|
|
|
|
+ if (boundtarget != 0xFF) {
|
|
|
|
|
+ _fs->PopTarget();
|
|
|
|
|
+ }
|
|
|
for(SQInteger n = 0; n < defparams; n++) {
|
|
for(SQInteger n = 0; n < defparams; n++) {
|
|
|
_fs->PopTarget();
|
|
_fs->PopTarget();
|
|
|
}
|
|
}
|