~ubuntu-branches/ubuntu/raring/codeblocks/raring-proposed

« back to all changes in this revision

Viewing changes to src/sdk/scripting/squirrel/sqcompiler.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Cosme Domínguez Díaz
  • Date: 2010-08-09 04:38:38 UTC
  • mfrom: (1.1.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20100809043838-a59ygguym4eg0jgw
Tags: 10.05-0ubuntu1
* New upstream release. Closes (LP: #322350)
 - Switch to dpkg-source 3.0 (quilt) format
 - Remove unneeded README.source
 - Add debian/get-source-orig script that removes all
   Windows prebuilt binaries
* Bump Standards-Version to 3.9.1
 - Stop shipping *.la files
* debian/control
 - Add cdbs package as Build-Depend
 - Add libbz2-dev and zlib1g-dev packages as
   Build-Depends (needed by libhelp_plugin.so)
 - Remove dpatch package of Build-Depends
 - Add codeblocks-contrib-debug package
 - Split architecture-independent files of codeblocks
   package in codeblocks-common package
* debian/rules
 - Switch to CDBS rules system
 - Add parallel build support
 - Add a call to debian/get-source-orig script
 - Use lzma compression (saves 23,5 MB of free space)
* debian/patches
 - Refresh 01_codeblocks_plugin_path
 - Add 02_no_Makefiles_in_debian_dir to remove any link
   in codeblocks build system to deleted Makefiles of debian directory
 - Drop 02_ftbfs_gcc44 and 03_ftbfs_glib221 (merged in upstream)
* debian/watch
 - Update to use the new host (berlios.de)

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
#include "sqfuncstate.h"
12
12
#include "sqlexer.h"
13
13
#include "sqvm.h"
 
14
#include "sqtable.h"
14
15
 
15
16
#define DEREF_NO_DEREF  -1
16
17
#define DEREF_FIELD             -2
87
88
        }
88
89
        SQObject Expect(SQInteger tok)
89
90
        {
90
 
                
 
91
 
91
92
                if(_token != tok) {
92
93
                        if(_token == TK_CONSTRUCTOR && tok == TK_IDENTIFIER) {
93
94
                                //ret = SQString::Create(_ss(_vm),_SC("constructor"));
212
213
                        SQOpcode op;
213
214
                        if(_token == TK_RETURN) {
214
215
                                op = _OP_RETURN;
215
 
                                
 
216
 
216
217
                        }
217
218
                        else {
218
219
                                op = _OP_YIELD;
227
228
                                _fs->_returnexp = retexp;
228
229
                                _fs->AddInstruction(op, 1, _fs->PopTarget());
229
230
                        }
230
 
                        else{ 
 
231
                        else{
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);
235
236
                        }
236
237
                        break;}
237
238
                case TK_BREAK:
258
259
                case TK_CLASS:
259
260
                        ClassStatement();
260
261
                        break;
 
262
                case TK_ENUM:
 
263
                        EnumStatement();
 
264
                        break;
261
265
                case _SC('{'):{
262
266
                                SQInteger stacksize = _fs->GetStackSize();
263
267
                                Lex();
274
278
                        CommaExpr();
275
279
                        _fs->AddInstruction(_OP_THROW, _fs->PopTarget());
276
280
                        break;
 
281
                case TK_CONST:
 
282
                        {
 
283
                        Lex();
 
284
                        SQObject id = Expect(TK_IDENTIFIER);
 
285
                        Expect('=');
 
286
                        SQObject val = ExpectScalar();
 
287
                        OptionalSemicolon();
 
288
                        SQTable *enums = _table(_ss(_vm)->_consts);
 
289
                        SQObjectPtr strongid = id;
 
290
                        enums->NewSlot(strongid,SQObjectPtr(val));
 
291
                        strongid.Null();
 
292
                        }
 
293
                        break;
277
294
                default:
278
295
                        CommaExpr();
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;
475
 
                default: return;        
 
492
                default: return;
476
493
                }
477
494
        }
478
495
        void ShiftExp()
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;
485
 
                default: return;        
 
502
                default: return;
486
503
                }
487
504
        }
488
505
        void PlusExp()
494
511
                default: return;
495
512
                }
496
513
        }
497
 
        
 
514
 
498
515
        void MultExp()
499
516
        {
500
517
                PrefixedExpr();
512
529
                        switch(_token) {
513
530
                        case _SC('.'): {
514
531
                                pos = -1;
515
 
                                Lex(); 
 
532
                                Lex();
516
533
                                if(_token == TK_PARENT) {
517
534
                                        Lex();
518
535
                                        if(!NeedGet())
530
547
                                break;
531
548
                        case _SC('['):
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(']'));
534
551
                                pos = -1;
535
552
                                if(NeedGet()) Emit2ArgsOP(_OP_GET);
536
553
                                _exst._deref = DEREF_FIELD;
538
555
                                break;
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();
543
560
                                if(pos < 0)
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);
548
565
                                }
549
 
                                
 
566
 
550
567
                        }
551
568
                        return;
552
 
                        break;  
553
 
                        case _SC('('): 
 
569
                        break;
 
570
                        case _SC('('):
554
571
                                {
555
572
                                if(_exst._deref != DEREF_NO_DEREF) {
556
573
                                        if(pos<0) {
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)));
585
 
                                Lex(); 
 
602
                                Lex();
586
603
                        }
587
604
                        break;
588
605
                case TK_VARGC: Lex(); _fs->AddInstruction(_OP_VARGC, _fs->PushTarget()); break;
599
616
                case TK_THIS:{
600
617
                        _exst._freevar = false;
601
618
                        SQObject id;
 
619
                        SQObject constant;
602
620
                                switch(_token) {
603
621
                                        case TK_IDENTIFIER: id = _fs->CreateString(_lex._svalue); break;
604
622
                                        case TK_THIS: id = _fs->CreateString(_SC("this")); 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;
615
 
                                        } else {
 
631
                                                _fs->AddInstruction(_OP_LOADFREEVAR, _exst._deref ,pos);
 
632
                                                _exst._freevar = true;
 
633
                                        }
 
634
                                        else if(_fs->IsConstant(id,constant)) { //line 634
 
635
                                                SQObjectPtr constval;
 
636
                                                SQObject constid;
 
637
                                                if(type(constant) == OT_TABLE) {
 
638
                                                        Expect('.'); constid = Expect(TK_IDENTIFIER);
 
639
                                                        if(!_table(constant)->Get(constid,constval)) {
 
640
                                                                constval.Null();
 
641
                                                                Error(_SC("invalid constant [%s.%s]"), _stringval(id),_stringval(constid));
 
642
                                                        }
 
643
                                                }
 
644
                                                else {
 
645
                                                        constval = constant;
 
646
                                                }
 
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));
 
651
                                                }
 
652
                                                else if(ctype == OT_FLOAT && sizeof(SQFloat) == sizeof(SQInt32)) {
 
653
                                                        SQFloat f = _float(constval);
 
654
                                                        _fs->AddInstruction(_OP_LOADFLOAT, _exst._deref,*((SQInt32 *)&f));
 
655
                                                }
 
656
                                                else {
 
657
                                                        _fs->AddInstruction(_OP_LOAD, _exst._deref, _fs->GetConstant(constval));
 
658
                                                }
 
659
 
 
660
                                                _exst._freevar = true;
 
661
                                        }
 
662
                                        else {
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;
620
667
                                        }
621
668
                                }
 
669
 
622
670
                                else{
623
671
                                        _fs->PushTarget(pos);
624
672
                                        _exst._deref = pos;
633
681
                        _token = _SC('.'); //hack
634
682
                        return -1;
635
683
                        break;
636
 
                case TK_NULL: 
 
684
                case TK_NULL:
637
685
                        _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1);
638
686
                        Lex();
639
687
                        break;
665
713
                                SQInteger apos = _fs->GetCurrentPos(),key = 0;
666
714
                                Lex();
667
715
                                while(_token != _SC(']')) {
668
 
                    Expression(); 
 
716
                    Expression();
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;
692
 
                case TK_MINUSMINUS : 
 
740
                case TK_MINUSMINUS :
693
741
                case TK_PLUSPLUS :PrefixIncDec(_token); break;
694
742
                case TK_DELETE : DeleteExpr(); break;
695
743
                case TK_DELEGATE : DelegateExpr(); break;
714
762
                }
715
763
                return (!_exst._class_or_delete) || (_exst._class_or_delete && (_token == _SC('.') || _token == _SC('[')));
716
764
        }
717
 
        
 
765
 
718
766
        void FunctionCallArgs()
719
767
        {
720
768
                SQInteger nargs = 1;//this
721
769
                 while(_token != _SC(')')) {
722
770
                         Expression(true);
723
771
                         MoveIfCurrentTargetIsLocal();
724
 
                         nargs++; 
725
 
                         if(_token == _SC(',')){ 
726
 
                                 Lex(); 
 
772
                         nargs++;
 
773
                         if(_token == _SC(',')){
 
774
                                 Lex();
727
775
                                 if(_token == ')') Error(_SC("expression expected, found ')'"));
728
776
                         }
729
777
                 }
736
784
        void ParseTableOrClass(SQInteger separator,SQInteger terminator = '}')
737
785
        {
738
786
                SQInteger tpos = _fs->GetCurrentPos(),nkeys = 0;
739
 
                
 
787
 
740
788
                while(_token != terminator) {
741
789
                        bool hasattrs = false;
742
790
                        bool isstatic = false;
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();
804
854
                        }
805
855
                        _fs->PopTarget();
806
856
                        _fs->PushLocalVariable(varname);
807
 
                
 
857
 
808
858
                } while(_token == _SC(','));
809
859
        }
810
860
        void IfStatement()
815
865
                _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
816
866
                SQInteger jnepos = _fs->GetCurrentPos();
817
867
                SQInteger stacksize = _fs->GetStackSize();
818
 
                
 
868
 
819
869
                Statement();
820
870
                //
821
871
                if(_token != _SC('}') && _token != TK_ELSE) OptionalSemicolon();
822
 
                
 
872
 
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(')'));
843
 
                
 
893
 
844
894
                BEGIN_BREAKBLE_BLOCK();
845
895
                _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
846
896
                jzpos = _fs->GetCurrentPos();
847
897
                stacksize = _fs->GetStackSize();
848
 
                
 
898
 
849
899
                Statement();
850
 
                
 
900
 
851
901
                CleanStack(stacksize);
852
902
                _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1);
853
903
                _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos);
854
 
                
 
904
 
855
905
                END_BREAKBLE_BLOCK(jmppos);
856
906
        }
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);
913
 
                
 
963
 
914
964
                END_BREAKBLE_BLOCK(continuetrg);
915
965
        }
916
966
        void ForEachStatement()
925
975
                        idxname = _fs->CreateString(_SC("@INDEX@"));
926
976
                }
927
977
                Expect(TK_IN);
928
 
                
 
978
 
929
979
                //save the stack size
930
980
                SQInteger stacksize = _fs->GetStackSize();
931
981
                //put the table in the stack(evaluate the table expression)
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()
948
999
                Statement();
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);
998
1050
                __nbreaks__ = _fs->_unresolvedbreaks.size() - __nbreaks__;
999
1051
                if(__nbreaks__ > 0)ResolveBreaks(_fs, __nbreaks__);
1000
1052
                _fs->_breaktargets.pop_back();
1001
 
                
 
1053
 
1002
1054
        }
1003
1055
        void FunctionStatement()
1004
1056
        {
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);
1010
 
                
 
1062
 
1011
1063
                while(_token == TK_DOUBLE_COLON) {
1012
1064
                        Lex();
1013
1065
                        id = Expect(TK_IDENTIFIER);
1036
1088
                }
1037
1089
                else Error(_SC("cannot create a class in a local with the syntax(class <local>)"));
1038
1090
        }
 
1091
        SQObject ExpectScalar()
 
1092
        {
 
1093
                SQObject val;
 
1094
                switch(_token) {
 
1095
                        case TK_INTEGER:
 
1096
                                val._type = OT_INTEGER;
 
1097
                                val._unVal.nInteger = _lex._nvalue;
 
1098
                                break;
 
1099
                        case TK_FLOAT:
 
1100
                                val._type = OT_FLOAT;
 
1101
                                val._unVal.fFloat = _lex._fvalue;
 
1102
                                break;
 
1103
                        case TK_STRING_LITERAL:
 
1104
                                val = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1);
 
1105
                                break;
 
1106
                        case '-':
 
1107
                                Lex();
 
1108
                                switch(_token)
 
1109
                                {
 
1110
                                case TK_INTEGER:
 
1111
                                        val._type = OT_INTEGER;
 
1112
                                        val._unVal.nInteger = -_lex._nvalue;
 
1113
                                break;
 
1114
                                case TK_FLOAT:
 
1115
                                        val._type = OT_FLOAT;
 
1116
                                        val._unVal.fFloat = -_lex._fvalue;
 
1117
                                break;
 
1118
                                default:
 
1119
                                        Error(_SC("scalar expected : integer,float"));
 
1120
                                }
 
1121
                                break;
 
1122
                        default:
 
1123
                        Error(_SC("scalar expected : integer,float or string"));
 
1124
                }
 
1125
                Lex();
 
1126
                return val;
 
1127
        }
 
1128
        void EnumStatement()
 
1129
        {
 
1130
 
 
1131
                Lex();
 
1132
                SQObject id = Expect(TK_IDENTIFIER);
 
1133
                Expect(_SC('{'));
 
1134
 
 
1135
                SQObject table = _fs->CreateTable();
 
1136
                SQInteger nval = 0;
 
1137
                while(_token != _SC('}')) {
 
1138
                        SQObject key = Expect(TK_IDENTIFIER);
 
1139
                        SQObject val;
 
1140
                        if(_token == _SC('=')) {
 
1141
                                Lex();
 
1142
                                val = ExpectScalar();
 
1143
                        }
 
1144
                        else {
 
1145
                                val._type = OT_INTEGER;
 
1146
                                val._unVal.nInteger = nval++;
 
1147
                        }
 
1148
                        _table(table)->NewSlot(SQObjectPtr(key),SQObjectPtr(val));
 
1149
                        if(_token == ',') Lex();
 
1150
                }
 
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"));
 
1157
                }*/
 
1158
                enums->NewSlot(SQObjectPtr(strongid),SQObjectPtr(table));
 
1159
                strongid.Null();
 
1160
                Lex();
 
1161
 
 
1162
        }
1039
1163
        void TryCatchStatement()
1040
1164
        {
1041
1165
                SQObject exid;
1123
1247
        }
1124
1248
        void CreateFunction(SQObject &name)
1125
1249
        {
1126
 
                
 
1250
 
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;
1135
1261
                                Lex();
1136
1262
                                if(_token != _SC(')')) Error(_SC("expected ')'"));
1139
1265
                        else {
1140
1266
                                paramname = Expect(TK_IDENTIFIER);
1141
1267
                                funcstate->AddParameter(paramname);
 
1268
                                if(_token == _SC('=')) {
 
1269
                                        Lex();
 
1270
                                        Expression();
 
1271
                                        funcstate->AddDefaultParam(_fs->TopTarget());
 
1272
                                        defparams++;
 
1273
                                }
 
1274
                                else {
 
1275
                                        if(defparams > 0) Error(_SC("expected '='"));
 
1276
                                }
1142
1277
                                if(_token == _SC(',')) Lex();
1143
1278
                                else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));
1144
1279
                        }
1145
1280
                }
1146
1281
                Expect(_SC(')'));
 
1282
                for(SQInteger n = 0; n < defparams; n++) {
 
1283
                        _fs->PopTarget();
 
1284
                }
1147
1285
                //outer values
1148
1286
                if(_token == _SC(':')) {
1149
1287
                        Lex(); Expect(_SC('('));
1156
1294
                        }
1157
1295
                        Lex();
1158
1296
                }
1159
 
                
 
1297
 
1160
1298
                SQFuncState *currchunk = _fs;
1161
1299
                _fs = funcstate;
1162
1300
                Statement();