227
228
_fs->_returnexp = retexp;
228
229
_fs->AddInstruction(op, 1, _fs->PopTarget());
231
232
if(op == _OP_RETURN && _fs->_traps > 0)
232
233
_fs->AddInstruction(_OP_POPTRAP, _fs->_traps ,0);
233
234
_fs->_returnexp = -1;
234
_fs->AddInstruction(op, 0xFF);
235
_fs->AddInstruction(op, 0xFF);
275
279
_fs->AddInstruction(_OP_THROW, _fs->PopTarget());
284
SQObject id = Expect(TK_IDENTIFIER);
286
SQObject val = ExpectScalar();
288
SQTable *enums = _table(_ss(_vm)->_consts);
289
SQObjectPtr strongid = id;
290
enums->NewSlot(strongid,SQObjectPtr(val));
279
296
_fs->PopTarget();
472
489
case TK_GE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_GE); break;
473
490
case TK_LE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_LE); break;
474
491
case TK_NE: BIN_EXP(_OP_NE, &SQCompiler::ShiftExp); break;
482
499
case TK_USHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_USHIFTR); break;
483
500
case TK_SHIFTL: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTL); break;
484
501
case TK_SHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTR); break;
532
549
if(_lex._prevtoken == _SC('\n')) Error(_SC("cannot brake deref/or comma needed after [exp]=exp slot declaration"));
533
Lex(); Expression(); Expect(_SC(']'));
550
Lex(); Expression(); Expect(_SC(']'));
535
552
if(NeedGet()) Emit2ArgsOP(_OP_GET);
536
553
_exst._deref = DEREF_FIELD;
539
556
case TK_MINUSMINUS:
540
557
case TK_PLUSPLUS:
541
if(_exst._deref != DEREF_NO_DEREF && !IsEndOfStatement()) {
558
if(_exst._deref != DEREF_NO_DEREF && !IsEndOfStatement()) {
542
559
SQInteger tok = _token; Lex();
544
561
Emit2ArgsOP(_OP_PINC,tok == TK_MINUSMINUS?-1:1);
546
563
SQInteger src = _fs->PopTarget();
547
564
_fs->AddInstruction(_OP_PINCL, _fs->PushTarget(), src, 0, tok == TK_MINUSMINUS?-1:1);
555
572
if(_exst._deref != DEREF_NO_DEREF) {
582
599
case TK_STRING_LITERAL: {
583
600
//SQObjectPtr id(SQString::Create(_ss(_vm), _lex._svalue,_lex._longstr.size()-1));
584
601
_fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_fs->CreateString(_lex._svalue,_lex._longstr.size()-1)));
588
605
case TK_VARGC: Lex(); _fs->AddInstruction(_OP_VARGC, _fs->PushTarget()); break;
610
628
//checks if is a free variable
611
629
if((pos = _fs->GetOuterVariable(id)) != -1) {
612
630
_exst._deref = _fs->PushTarget();
613
_fs->AddInstruction(_OP_LOADFREEVAR, _exst._deref ,pos);
614
_exst._freevar = true;
631
_fs->AddInstruction(_OP_LOADFREEVAR, _exst._deref ,pos);
632
_exst._freevar = true;
634
else if(_fs->IsConstant(id,constant)) { //line 634
635
SQObjectPtr constval;
637
if(type(constant) == OT_TABLE) {
638
Expect('.'); constid = Expect(TK_IDENTIFIER);
639
if(!_table(constant)->Get(constid,constval)) {
641
Error(_SC("invalid constant [%s.%s]"), _stringval(id),_stringval(constid));
647
_exst._deref = _fs->PushTarget();
648
SQObjectType ctype = type(constval);
649
if(ctype == OT_INTEGER && (_integer(constval) & (~0x7FFFFFFF)) == 0) {
650
_fs->AddInstruction(_OP_LOADINT, _exst._deref,_integer(constval));
652
else if(ctype == OT_FLOAT && sizeof(SQFloat) == sizeof(SQInt32)) {
653
SQFloat f = _float(constval);
654
_fs->AddInstruction(_OP_LOADFLOAT, _exst._deref,*((SQInt32 *)&f));
657
_fs->AddInstruction(_OP_LOAD, _exst._deref, _fs->GetConstant(constval));
660
_exst._freevar = true;
616
663
_fs->PushTarget(0);
617
664
_fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
618
665
if(NeedGet()) Emit2ArgsOP(_OP_GET);
619
666
_exst._deref = DEREF_FIELD;
623
671
_fs->PushTarget(pos);
624
672
_exst._deref = pos;
665
713
SQInteger apos = _fs->GetCurrentPos(),key = 0;
667
715
while(_token != _SC(']')) {
669
717
if(_token == _SC(',')) Lex();
670
718
SQInteger val = _fs->PopTarget();
671
719
SQInteger array = _fs->TopTarget();
689
737
case TK_TYPEOF : UnaryOP(_OP_TYPEOF); break;
690
738
case TK_RESUME : UnaryOP(_OP_RESUME); break;
691
739
case TK_CLONE : UnaryOP(_OP_CLONE); break;
693
741
case TK_PLUSPLUS :PrefixIncDec(_token); break;
694
742
case TK_DELETE : DeleteExpr(); break;
695
743
case TK_DELEGATE : DelegateExpr(); break;
715
763
return (!_exst._class_or_delete) || (_exst._class_or_delete && (_token == _SC('.') || _token == _SC('[')));
718
766
void FunctionCallArgs()
720
768
SQInteger nargs = 1;//this
721
769
while(_token != _SC(')')) {
722
770
Expression(true);
723
771
MoveIfCurrentTargetIsLocal();
725
if(_token == _SC(',')){
773
if(_token == _SC(',')){
727
775
if(_token == ')') Error(_SC("expression expected, found ')'"));
778
826
SQInteger val = _fs->PopTarget();
779
827
SQInteger key = _fs->PopTarget();
780
828
SQInteger attrs = hasattrs ? _fs->PopTarget():-1;
781
assert(hasattrs && attrs == key-1 || !hasattrs);
782
unsigned char flags = (hasattrs?NEW_SLOT_ATTRIBUTES_FLAG:0)|(isstatic?NEW_SLOT_STATIC_FLAG:0);
829
// C::B patch: Eliminate compiler warnings
830
assert((hasattrs && (attrs == key-1)) || !hasattrs);
831
// C::B patch: Eliminate compiler warnings
832
int flags = (hasattrs?NEW_SLOT_ATTRIBUTES_FLAG:0)|(isstatic?NEW_SLOT_STATIC_FLAG:0);
783
833
SQInteger table = _fs->TopTarget(); //<<BECAUSE OF THIS NO COMMON EMIT FUNC IS POSSIBLE
784
834
_fs->AddInstruction(_OP_NEWSLOTA, flags, table, key, val);
785
835
//_fs->PopTarget();
815
865
_fs->AddInstruction(_OP_JZ, _fs->PopTarget());
816
866
SQInteger jnepos = _fs->GetCurrentPos();
817
867
SQInteger stacksize = _fs->GetStackSize();
821
871
if(_token != _SC('}') && _token != TK_ELSE) OptionalSemicolon();
823
873
CleanStack(stacksize);
824
874
SQInteger endifblock = _fs->GetCurrentPos();
825
875
if(_token == TK_ELSE){
840
890
SQInteger stacksize = _fs->GetStackSize();
841
891
jmppos = _fs->GetCurrentPos();
842
892
Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
844
894
BEGIN_BREAKBLE_BLOCK();
845
895
_fs->AddInstruction(_OP_JZ, _fs->PopTarget());
846
896
jzpos = _fs->GetCurrentPos();
847
897
stacksize = _fs->GetStackSize();
851
901
CleanStack(stacksize);
852
902
_fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1);
853
903
_fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos);
855
905
END_BREAKBLE_BLOCK(jmppos);
857
907
void DoWhileStatement()
910
960
_fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1, 0);
911
961
if(jzpos> 0) _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos);
912
962
CleanStack(stacksize);
914
964
END_BREAKBLE_BLOCK(continuetrg);
916
966
void ForEachStatement()
943
993
SQInteger jmppos = _fs->GetCurrentPos();
944
994
_fs->AddInstruction(_OP_FOREACH, container, 0, indexpos);
945
995
SQInteger foreachpos = _fs->GetCurrentPos();
996
_fs->AddInstruction(_OP_POSTFOREACH, container, 0, indexpos);
946
997
//generate the statement code
947
998
BEGIN_BREAKBLE_BLOCK()
949
1000
_fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1);
950
1001
_fs->SetIntructionParam(foreachpos, 1, _fs->GetCurrentPos() - foreachpos);
1002
_fs->SetIntructionParam(foreachpos + 1, 1, _fs->GetCurrentPos() - foreachpos);
951
1003
//restore the local variable stack(remove index,val and ref idx)
952
1004
CleanStack(stacksize);
953
1005
END_BREAKBLE_BLOCK(foreachpos - 1);
1007
1059
_fs->PushTarget(0);
1008
1060
_fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
1009
1061
if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);
1011
1063
while(_token == TK_DOUBLE_COLON) {
1013
1065
id = Expect(TK_IDENTIFIER);
1037
1089
else Error(_SC("cannot create a class in a local with the syntax(class <local>)"));
1091
SQObject ExpectScalar()
1096
val._type = OT_INTEGER;
1097
val._unVal.nInteger = _lex._nvalue;
1100
val._type = OT_FLOAT;
1101
val._unVal.fFloat = _lex._fvalue;
1103
case TK_STRING_LITERAL:
1104
val = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1);
1111
val._type = OT_INTEGER;
1112
val._unVal.nInteger = -_lex._nvalue;
1115
val._type = OT_FLOAT;
1116
val._unVal.fFloat = -_lex._fvalue;
1119
Error(_SC("scalar expected : integer,float"));
1123
Error(_SC("scalar expected : integer,float or string"));
1128
void EnumStatement()
1132
SQObject id = Expect(TK_IDENTIFIER);
1135
SQObject table = _fs->CreateTable();
1137
while(_token != _SC('}')) {
1138
SQObject key = Expect(TK_IDENTIFIER);
1140
if(_token == _SC('=')) {
1142
val = ExpectScalar();
1145
val._type = OT_INTEGER;
1146
val._unVal.nInteger = nval++;
1148
_table(table)->NewSlot(SQObjectPtr(key),SQObjectPtr(val));
1149
if(_token == ',') Lex();
1151
SQTable *enums = _table(_ss(_vm)->_consts);
1152
SQObjectPtr strongid = id;
1153
/*SQObjectPtr dummy;
1154
if(enums->Get(strongid,dummy)) {
1155
dummy.Null(); strongid.Null();
1156
Error(_SC("enumeration already exists"));
1158
enums->NewSlot(SQObjectPtr(strongid),SQObjectPtr(table));
1039
1163
void TryCatchStatement()
1124
1248
void CreateFunction(SQObject &name)
1127
1251
SQFuncState *funcstate = _fs->PushChildState(_ss(_vm));
1128
1252
funcstate->_name = name;
1129
1253
SQObject paramname;
1130
1254
funcstate->AddParameter(_fs->CreateString(_SC("this")));
1131
1255
funcstate->_sourcename = _sourcename;
1256
SQInteger defparams = 0;
1132
1257
while(_token!=_SC(')')) {
1133
1258
if(_token == TK_VARPARAMS) {
1259
if(defparams > 0) Error(_SC("function with default parameters cannot have variable number of parameters"));
1134
1260
funcstate->_varparams = true;
1136
1262
if(_token != _SC(')')) Error(_SC("expected ')'"));
1140
1266
paramname = Expect(TK_IDENTIFIER);
1141
1267
funcstate->AddParameter(paramname);
1268
if(_token == _SC('=')) {
1271
funcstate->AddDefaultParam(_fs->TopTarget());
1275
if(defparams > 0) Error(_SC("expected '='"));
1142
1277
if(_token == _SC(',')) Lex();
1143
1278
else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));
1146
1281
Expect(_SC(')'));
1282
for(SQInteger n = 0; n < defparams; n++) {
1148
1286
if(_token == _SC(':')) {
1149
1287
Lex(); Expect(_SC('('));