updated squirrel version
authorMatthias Braun <matze@braunis.de>
Sun, 26 Jun 2005 00:24:47 +0000 (00:24 +0000)
committerMatthias Braun <matze@braunis.de>
Sun, 26 Jun 2005 00:24:47 +0000 (00:24 +0000)
SVN-Revision: 2641

54 files changed:
data/levels/test/script.stl
data/levels/test/yeti.stl
src/audio/sound_manager.cpp
src/audio/sound_manager.h
src/badguy/badguy.cpp
src/badguy/bomb.cpp
src/badguy/jumpy.cpp
src/badguy/mriceblock.cpp
src/badguy/mrtree.cpp
src/badguy/nolok_01.cpp
src/badguy/rocketexplosion.cpp
src/badguy/yeti.cpp
src/object/block.cpp
src/object/fireworks.cpp
src/object/flower.cpp
src/object/growup.cpp
src/object/invisible_block.cpp
src/object/player.cpp
src/object/powerup.cpp
src/player_status.cpp
src/sector.cpp
src/squirrel/Jamfile
src/squirrel/include/sqstdio.h
src/squirrel/include/squirrel.h
src/squirrel/sqstdlib/sqstdaux.cpp
src/squirrel/sqstdlib/sqstdblob.cpp
src/squirrel/sqstdlib/sqstdio.cpp
src/squirrel/sqstdlib/sqstdlib.dsp [deleted file]
src/squirrel/sqstdlib/sqstdmath.cpp
src/squirrel/sqstdlib/sqstdrex.c
src/squirrel/sqstdlib/sqstdstream.cpp
src/squirrel/sqstdlib/sqstdstring.cpp
src/squirrel/sqstdlib/sqstdsystem.cpp
src/squirrel/squirrel/sqapi.cpp
src/squirrel/squirrel/sqbaselib.cpp
src/squirrel/squirrel/sqclass.cpp
src/squirrel/squirrel/sqclass.h
src/squirrel/squirrel/sqcompiler.cpp
src/squirrel/squirrel/sqcompiler.h
src/squirrel/squirrel/sqdebug.cpp
src/squirrel/squirrel/sqfuncstate.cpp
src/squirrel/squirrel/sqfuncstate.h
src/squirrel/squirrel/sqlexer.cpp
src/squirrel/squirrel/sqlexer.h
src/squirrel/squirrel/sqmem.cpp
src/squirrel/squirrel/sqobject.cpp
src/squirrel/squirrel/sqobject.h
src/squirrel/squirrel/sqopcodes.h
src/squirrel/squirrel/sqstate.cpp
src/squirrel/squirrel/sqtable.h
src/squirrel/squirrel/squtils.h
src/squirrel/squirrel/sqvm.cpp
src/squirrel/squirrel/sqvm.h
src/worldmap.cpp

index 85b490b..ceca520 100644 (file)
@@ -148,7 +148,7 @@ NOLOK.set_visible(true);
 tuxjumps <- 2;
 while(true) {
   wait(0.8);
-  Sound.play_sound(\"jump\");
+  Sound.play(\"jump\");
   if(tuxjumps >= 0) {
     TUX.set_velocity(50, 300);
   } else {
@@ -165,7 +165,7 @@ while(true) {
   } else if(PENNY.get_animation() == \"jump\") {
     PENNY.set_animation(\"dead\");
   } else {
-    Sound.play_sound(\"grow\");
+    Sound.play(\"grow\");
     PENNY.set_animation(\"stand\");
     PENNY.set_velocity(0, 900);
   }
index 8b9eca3..24c2171 100644 (file)
@@ -107,7 +107,7 @@ DisplayEffect.fade_in(2.5);
          (x 2)
          (y 177)
          (dead-script "
-Sound.play_sound(\"invincible\");
+Sound.play(\"sounds/invincible.wav\");
 Text.set_text(\"You made it!\");
 Text.set_font(\"big\");
 Text.fade_in(1.5);
index 7d95724..3803fdf 100644 (file)
@@ -106,11 +106,8 @@ SoundManager::create_sound_source(const std::string& filename)
 }
 
 void
-SoundManager::play(const std::string& soundname, const Vector& pos)
+SoundManager::play(const std::string& filename, const Vector& pos)
 {
-  std::string filename = "sounds/";
-  filename += soundname;
-  filename += ".wav";
   try {
     SoundSource* source = create_sound_source(filename);
     if(source == 0)
index 7542527..1f53285 100644 (file)
@@ -32,7 +32,7 @@ public:
   SoundSource* create_sound_source(const std::string& filename);
   /**
    * Convenience function to simply play a sound at a given position.
-   * This functions constructs prepends sounds/ to the name and adds .wav
+   * This functions prepends sounds/ to the name and adds .wav
    */
   void play(const std::string& name, const Vector& pos = Vector(-1, -1));
 
index f20a798..3a4ae69 100644 (file)
@@ -181,7 +181,7 @@ BadGuy::collision_squished(Player& )
 void
 BadGuy::kill_squished(Player& player)
 {
-  sound_manager->play("squish", get_pos());
+  sound_manager->play("sounds/squish.wav", get_pos());
   physic.enable_gravity(true);
   physic.set_velocity_x(0);
   physic.set_velocity_y(0);
@@ -193,7 +193,7 @@ BadGuy::kill_squished(Player& player)
 void
 BadGuy::kill_fall()
 {
-  sound_manager->play("fall", get_pos());
+  sound_manager->play("sounds/fall.wav", get_pos());
   global_stats.add_points(BADGUYS_KILLED_STAT, 1);
   physic.set_velocity_y(0);
   physic.enable_gravity(true);
index 45eca33..d6884a5 100644 (file)
@@ -92,7 +92,7 @@ Bomb::explode()
 {
   state = 1;
   sprite->set_action("explosion");
-  sound_manager->play("explosion", get_pos());
+  sound_manager->play("sounds/explosion.wav", get_pos());
   timer.start(EXPLOSIONTIME);
 }
 
index 07f126f..7958c5e 100644 (file)
@@ -70,7 +70,7 @@ Jumpy::hit(const CollisionHit& chit)
     
     physic.set_velocity_y(JUMPSPEED);
     // TODO create a nice sound for this...
-    //sound_manager->play("skid");
+    //sound_manager->play("sounds/skid.wav");
   } else if(chit.normal.y < .5) { // bumped on roof
     physic.set_velocity_y(0);
   }
index c392646..0dcd96e 100644 (file)
@@ -105,7 +105,7 @@ MrIceBlock::collision_solid(GameObject& object, const CollisionHit& hit)
       dir = dir == LEFT ? RIGHT : LEFT;
       sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
       physic.set_velocity_x(-physic.get_velocity_x());
-      sound_manager->play("ricochet", get_pos());
+      sound_manager->play("sounds/ricochet.wav", get_pos());
       break;
     }
     case ICESTATE_FLAT:
@@ -152,7 +152,7 @@ MrIceBlock::collision_squished(Player& player)
       }
 
       // flatten
-      sound_manager->play("stomp", get_pos());
+      sound_manager->play("sounds/stomp.wav", get_pos());
       physic.set_velocity_x(0);
       physic.set_velocity_y(0); 
       
@@ -162,7 +162,7 @@ MrIceBlock::collision_squished(Player& player)
       break;
     case ICESTATE_FLAT:
       // kick
-      sound_manager->play("kick", get_pos());
+      sound_manager->play("sounds/kick.wav", get_pos());
 
       if(player.get_pos().x < get_pos().x) {
         dir = RIGHT;
index 509eda9..ba396b1 100644 (file)
@@ -64,7 +64,7 @@ MrTree::collision_squished(Player& player)
     mystate = STATE_NORMAL;
     activate();
 
-    sound_manager->play("squish", get_pos());
+    sound_manager->play("sounds/squish.wav", get_pos());
     player.bounce(*this);
   } else {
     sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
index 7882cd4..e88a0ab 100644 (file)
@@ -147,7 +147,7 @@ Nolok_01::kill_fall()
   bullet_hitpoints--;
   if (bullet_hitpoints <= 0) {
    hitpoints = 0;
-   sound_manager->play("fall", this,
+   sound_manager->play("sounds/fall.wav", this,
                              Sector::current()->player->get_pos());
    physic.set_velocity_y(0);
    physic.enable_gravity(true);
index 8827693..f1d79e7 100644 (file)
@@ -76,7 +76,7 @@ void
 RocketExplosion::explode()
 {
   sprite->set_action(dir == LEFT ? "explosion-left" : "explosion-right");
-  sound_manager->play("explosion", get_pos());
+  sound_manager->play("sounds/explosion.wav", get_pos());
   timer.start(EXPLOSIONTIME, true);
 }
 
index c6f0834..60fac3e 100644 (file)
@@ -89,7 +89,7 @@ Yeti::active_update(float elapsed_time)
     case ANGRY_JUMPING:
       if(timer.check()) {
         // jump
-        sound_manager->play("yeti_gna");
+        sound_manager->play("sounds/yeti_gna.wav");
         physic.set_velocity_y(JUMP_VEL1);
       }
       break;
@@ -141,7 +141,7 @@ Yeti::collision_squished(Player& player)
     return true;
 
   player.bounce(*this);
-  sound_manager->play("yeti_roar");
+  sound_manager->play("sounds/yeti_roar.wav");
   hit_points--;
   if(hit_points <= 0) {
     sprite->set_action("dead");
index ed0ea70..78512ad 100644 (file)
@@ -203,7 +203,7 @@ void
 BonusBlock::try_open()
 {
   if(sprite->get_action_name() == "empty") {
-    sound_manager->play("brick");
+    sound_manager->play("sounds/brick.wav");
     return;
   }
   
@@ -224,7 +224,7 @@ BonusBlock::try_open()
             get_pos(), new Flower(Flower::FIREFLOWER));
         sector->add_object(riser);
       }
-      sound_manager->play("upgrade");
+      sound_manager->play("sounds/upgrade.wav");
       break;
 
     case CONTENT_ICEGROW:
@@ -236,7 +236,7 @@ BonusBlock::try_open()
             get_pos(), new Flower(Flower::ICEFLOWER));
         sector->add_object(riser);
       }      
-      sound_manager->play("upgrade");
+      sound_manager->play("sounds/upgrade.wav");
       break;
 
     case CONTENT_STAR:
@@ -251,7 +251,7 @@ BonusBlock::try_open()
       SpecialRiser* riser = new SpecialRiser(get_pos(), object);
       object = 0;
       sector->add_object(riser);
-      sound_manager->play("upgrade");
+      sound_manager->play("sounds/upgrade.wav");
       break;
 
     //default:
@@ -292,7 +292,7 @@ Brick::try_break(bool playerhit)
   if(sprite->get_action_name() == "empty")
     return;
   
-  sound_manager->play("brick");
+  sound_manager->play("sounds/brick.wav");
   Sector* sector = Sector::current();
   Player& player = *(sector->player);
   if(coin_counter > 0) {
index c322671..f31cea0 100644 (file)
@@ -51,7 +51,7 @@ Fireworks::update(float )
         sector->add_object(new Particles(pos, 0, 360, Vector(140, 140),
                 Vector(0, 0), 45, Color(red, green, 0), 3, 1.3,
                 LAYER_FOREGROUND1+1));
-        sound_manager->play("fireworks");
+        sound_manager->play("sounds/fireworks.wav");
         timer.start(((float) rand() / RAND_MAX) + .5);
     }
 }
index 8c68307..8235eb1 100644 (file)
@@ -67,7 +67,7 @@ Flower::collision(GameObject& other, const CollisionHit& )
   else
     player->set_bonus(ICE_BONUS, true);
   
-  sound_manager->play("fire-flower");
+  sound_manager->play("sounds/fire-flower.wav");
   remove_me();
   return ABORT_MOVE;
 }
index db90163..aab2769 100644 (file)
@@ -64,7 +64,7 @@ GrowUp::collision(GameObject& other, const CollisionHit& hit)
   Player* player = dynamic_cast<Player*>(&other);
   if(player != 0) {
     player->set_bonus(GROWUP_BONUS, true);
-    sound_manager->play("grow");
+    sound_manager->play("sounds/grow.wav");
     remove_me();
     
     return ABORT_MOVE;
index f68b241..d92b3c2 100644 (file)
@@ -49,7 +49,7 @@ InvisibleBlock::hit(Player& )
     return;
 
   sprite->set_action("empty");
-  sound_manager->play("brick");
+  sound_manager->play("sounds/brick.wav");
   start_bounce();
   flags |= FLAG_SOLID;
   visible = true;
index 49bb5a0..9bf0c13 100644 (file)
@@ -270,7 +270,7 @@ Player::handle_horizontal_input()
     // let's skid!
     if(fabs(vx)>SKID_XM && !skidding_timer.started()) {
       skidding_timer.start(SKID_TIME);
-      sound_manager->play("skid");
+      sound_manager->play("sounds/skid.wav");
       // dust some partcles
       Sector::current()->add_object(
         new Particles(
@@ -366,9 +366,9 @@ Player::handle_vertical_input()
     can_flap = false;
     flaps_nb = 0; // Ricardo's flapping
     if (is_big())
-      sound_manager->play("bigjump");
+      sound_manager->play("sounds/bigjump.wav");
     else
-      sound_manager->play("jump");
+      sound_manager->play("sounds/jump.wav");
   } else if(!controller->hold(Controller::JUMP)) { // Let go of jump key
     if (!flapping && !duck && !falling_from_flap && !on_ground()) {
       can_flap = true;
@@ -790,7 +790,7 @@ Player::collision(GameObject& other, const CollisionHit& hit)
 void
 Player::make_invincible()
 {
-  sound_manager->play("invincible");
+  sound_manager->play("sounds/invincible.wav");
   invincible_timer.start(TUX_INVINCIBLE_TIME);
   Sector::current()->play_music(HERRING_MUSIC);               
 }
@@ -806,7 +806,7 @@ Player::kill(HurtMode mode)
           safe_timer.get_timeleft() > 0 || invincible_timer.get_timeleft() > 0)
     return;                          
   
-  sound_manager->play("hurt");
+  sound_manager->play("sounds/hurt.wav");
 
   physic.set_velocity_x(0);
 
index 1f338a6..6b944e0 100644 (file)
@@ -74,10 +74,10 @@ PowerUp::collision(GameObject& other, const CollisionHit& hit)
   // some defaults if no script has been set
   if (sprite->get_name() == "egg") {
     player->set_bonus(GROWUP_BONUS, true);
-    sound_manager->play("grow");
+    sound_manager->play("sounds/grow.wav");
   } else if (sprite->get_name() == "fireflower") {
     player->set_bonus(FIRE_BONUS, true);
-    sound_manager->play("fire-flower");
+    sound_manager->play("sounds/fire-flower.wav");
   } else if (sprite->get_name() == "star") {
     player->make_invincible();
   } else if (sprite->get_name() == "1up") {
index c953d92..72b6a07 100644 (file)
@@ -55,7 +55,7 @@ PlayerStatus::incLives()
 {
   if(lives < MAX_LIVES)
     ++lives;
-  sound_manager->play("lifeup");
+  sound_manager->play("sounds/lifeup.wav");
 }
 
 void
@@ -66,7 +66,7 @@ PlayerStatus::incCoins()
     incLives();
     coins = 0;
   }
-  sound_manager->play("coin");
+  sound_manager->play("sounds/coin.wav");
 }
 
 void
index 8ab9caa..e9c35c1 100644 (file)
@@ -769,7 +769,7 @@ Sector::add_bullet(const Vector& pos, float xm, Direction dir)
   }
   add_object(new_bullet);
 
-  sound_manager->play("shoot");
+  sound_manager->play("sounds/shoot.wav");
 
   return true;
 }
index 2e7038e..c6709c9 100644 (file)
@@ -5,4 +5,8 @@ Library squirrel
       [ Wildcard sqstdlib : *.cpp *.c *.h ]
     : noinstall
 ;
+CXXFLAGS on $(squirrel_OBJECTS) 
+       = [ Filter [ on $(squirrel_OBJECTS) GetVar CXXFLAGS ] : -Wall -W -Werror ] ;
+CFLAGS on $(squirrel_OBJECTS) 
+       = [ Filter [ on $(squirrel_OBJECTS) GetVar CFLAGS ] : -Wall -W -Werror ] ;      
 IncludeDir squirrel : include ;
index 471bf86..cbc8069 100644 (file)
@@ -7,8 +7,8 @@
 #define SQSTD_STREAM_TYPE_TAG 0x80000000
 
 struct SQStream {
-       virtual ~SQStream()
-       {}
+       virtual ~SQStream() {}
+
        virtual SQInteger Read(void *buffer, SQInteger size) = 0;
        virtual SQInteger Write(void *buffer, SQInteger size) = 0;
        virtual int Flush() = 0;
index 5f2b069..8f23fb9 100644 (file)
@@ -105,7 +105,7 @@ typedef char SQChar;
 #define MAX_CHAR 0xFF
 #endif
 
-#define SQUIRREL_VERSION       _SC("Squirrel 2.0.1 stable")
+#define SQUIRREL_VERSION       _SC("Squirrel 2.0.3 stable")
 #define SQUIRREL_COPYRIGHT     _SC("Copyright (C) 2003-2005 Alberto Demichelis")
 #define SQUIRREL_AUTHOR                _SC("Alberto Demichelis")
 
@@ -117,30 +117,31 @@ typedef char SQChar;
 #define SQ_BYTECODE_STREAM_TAG 0xFAFA
 
 #define SQOBJECT_REF_COUNTED   0x00800000
-#define SQOBJECT_NUMERIC               0x00080000
-#define SQOBJECT_DELEGABLE             0x08000000
-#define SQOBJECT_CANBEFALSE            0x80000000
-//typedef unsigned int SQObjectType;
+#define SQOBJECT_NUMERIC               0x00400000
+#define SQOBJECT_DELEGABLE             0x00200000
+#define SQOBJECT_CANBEFALSE            0x00100000
+
+#define SQ_MATCHTYPEMASKSTRING (-99999)
 
 #define _RT_MASK 0x0000FFFF
 #define _RAW_TYPE(type) (type&_RT_MASK)
 
-#define _RT_NULL                       0x00000000
-#define _RT_INTEGER                    0x00000001
-#define _RT_FLOAT                      0x00000002
-#define _RT_BOOL                       0x00000004
-#define _RT_STRING                     0x00000008
-#define _RT_TABLE                      0x00000010
-#define _RT_ARRAY                      0x00000020
-#define _RT_USERDATA           0x00000040
-#define _RT_CLOSURE                    0x00000080
-#define _RT_NATIVECLOSURE      0x00000100
-#define _RT_GENERATOR          0x00000200
-#define _RT_USERPOINTER                0x00000400
-#define _RT_THREAD                     0x00000800
-#define _RT_FUNCPROTO          0x00001000
-#define _RT_CLASS                      0x00002000
-#define _RT_INSTANCE           0x00004000
+#define _RT_NULL                       0x00000001
+#define _RT_INTEGER                    0x00000002
+#define _RT_FLOAT                      0x00000004
+#define _RT_BOOL                       0x00000008
+#define _RT_STRING                     0x00000010
+#define _RT_TABLE                      0x00000020
+#define _RT_ARRAY                      0x00000040
+#define _RT_USERDATA           0x00000080
+#define _RT_CLOSURE                    0x00000100
+#define _RT_NATIVECLOSURE      0x00000200
+#define _RT_GENERATOR          0x00000400
+#define _RT_USERPOINTER                0x00000800
+#define _RT_THREAD                     0x00001000
+#define _RT_FUNCPROTO          0x00002000
+#define _RT_CLASS                      0x00004000
+#define _RT_INSTANCE           0x00008000
 
 typedef enum {
        OT_NULL =                       (_RT_NULL|SQOBJECT_CANBEFALSE),
index 3f1b5aa..62a1598 100644 (file)
@@ -28,7 +28,7 @@ void sqstd_printcallstack(HSQUIRRELVM v)
 
                for(level=0;level<10;level++){
                        seq=0;
-                       while( (name=sq_getlocal(v,level,seq)) )
+                       while(name=sq_getlocal(v,level,seq))
                        {
                                seq++;
                                switch(sq_gettype(v,-1))
@@ -75,8 +75,6 @@ void sqstd_printcallstack(HSQUIRRELVM v)
                                case OT_INSTANCE:
                                        pf(v,_SC("[%s] INSTANCE\n"),name);
                                        break;
-                               default:
-                                       break;
                                }
                                sq_pop(v,1);
                        }
index 4631f87..6dfb760 100644 (file)
@@ -112,7 +112,7 @@ static int _blob__typeof(HSQUIRRELVM v)
        return 1;
 }
 
-static int _blob_releasehook(SQUserPointer p, int )
+static int _blob_releasehook(SQUserPointer p, int size)
 {
        SQBlob *self = (SQBlob*)p;
        delete self;
@@ -203,7 +203,7 @@ static SQRegFunction bloblib_funcs[]={
        _DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")),
        _DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")),
        _DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")),
-       {0,0,0,0}
+       {0,0}
 };
 
 SQRESULT sqstd_getblob(HSQUIRRELVM v,int idx,SQUserPointer *ptr)
index f3903e2..7534697 100644 (file)
@@ -62,10 +62,10 @@ SQInteger sqstd_feof(SQFILE file)
 struct SQFile : public SQStream {
        SQFile() { _handle = NULL; _owns = false;}
        SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;}
-       virtual ~SQFile() { Close(); }
+       ~SQFile() { Close(); }
        bool Open(const SQChar *filename ,const SQChar *mode) {
                Close();
-               if( (_handle = sqstd_fopen(filename,mode)) ) {
+               if(_handle = sqstd_fopen(filename,mode)) {
                        _owns = true;
                        return true;
                }
@@ -116,7 +116,6 @@ static int _file__typeof(HSQUIRRELVM v)
 
 static int _file_releasehook(SQUserPointer p, int size)
 {
-       (void) size;
        SQFile *self = (SQFile*)p;
        delete self;
        return 1;
@@ -193,6 +192,7 @@ SQRESULT sqstd_getfile(HSQUIRRELVM v, int idx, SQFILE *file)
 }
 
 
+
 static SQInteger _io_file_lexfeedASCII(SQUserPointer file)
 {
        int ret;
@@ -202,7 +202,44 @@ static SQInteger _io_file_lexfeedASCII(SQUserPointer file)
        return 0;
 }
 
-static SQInteger _io_file_lexfeedWCHAR(SQUserPointer file)
+static SQInteger _io_file_lexfeed_UTF8(SQUserPointer file)
+{
+#define READ() \
+       if(sqstd_fread(&inchar,sizeof(inchar),1,(FILE *)file) != 1) \
+               return 0;
+
+       static const int utf8_lengths[16] =
+       {
+               1,1,1,1,1,1,1,1,        /* 0000 to 0111 : 1 byte (plain ASCII) */
+               0,0,0,0,                /* 1000 to 1011 : not valid */
+               2,2,                    /* 1100, 1101 : 2 bytes */
+               3,                      /* 1110 : 3 bytes */
+               4                       /* 1111 :4 bytes */
+       };
+       static unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07};
+       unsigned char inchar;
+       int c = 0;
+       READ();
+       c = inchar;
+       //
+       if(c >= 0x80) {
+               int tmp;
+               int codelen = utf8_lengths[c>>4];
+               if(codelen == 0) 
+                       return 0;
+                       //"invalid UTF-8 stream";
+               tmp = c&byte_masks[codelen];
+               for(int n = 0; n < codelen-1; n++) {
+                       tmp<<=6;
+                       READ();
+                       tmp |= inchar & 0x3F;
+               }
+               c = tmp;
+       }
+       return c;
+}
+
+static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer file)
 {
        int ret;
        wchar_t c;
@@ -211,6 +248,17 @@ static SQInteger _io_file_lexfeedWCHAR(SQUserPointer file)
        return 0;
 }
 
+static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer file)
+{
+       int ret;
+       unsigned short c;
+       if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) {
+               c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00);
+               return (SQChar)c;
+       }
+       return 0;
+}
+
 int file_read(SQUserPointer file,SQUserPointer buf,int size)
 {
        int ret;
@@ -227,14 +275,15 @@ SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror)
 {
        SQFILE file = sqstd_fopen(filename,_SC("rb"));
        int ret;
-       unsigned short uc;
-       SQLEXREADFUNC func = _io_file_lexfeedASCII;
-       if(file && (ret=sqstd_fread(&uc,1,2,file))){
-               if(ret!=2) {
+       unsigned short us;
+       unsigned char uc;
+       SQLEXREADFUNC func = _io_file_lexfeed_UTF8;
+       if(file && (ret = sqstd_fread(&us,1,2,file))){
+               if(ret != 2) {
                        sqstd_fclose(file);
                        return sq_throwerror(v,_SC("io error"));
                }
-               if(uc==SQ_BYTECODE_STREAM_TAG) { //BYTECODE
+               if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE
                        sqstd_fseek(file,0,SQ_SEEK_SET);
                        if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) {
                                sqstd_fclose(file);
@@ -242,10 +291,24 @@ SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror)
                        }
                }
                else { //SCRIPT
-                       if(uc==0xFEFF)
-                               func = _io_file_lexfeedWCHAR;
-                       else
-                               sqstd_fseek(file,0,SQ_SEEK_SET);
+                       switch(us)
+                       {
+                               //gotta swap the next 2 lines on BIG endian machines
+                               case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian;
+                               case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian;
+                               case 0xBBEF: 
+                                       if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) { 
+                                               sqstd_fclose(file); 
+                                               return sq_throwerror(v,_SC("io error")); 
+                                       }
+                                       if(uc != 0xBF) { 
+                                               sqstd_fclose(file); 
+                                               return sq_throwerror(v,_SC("Unrecognozed ecoding")); 
+                                       }
+                                       func = _io_file_lexfeed_UTF8;
+                                       break;//UTF-8 ;
+                               default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii
+                       }
 
                        if(SQ_SUCCEEDED(sq_compile(v,func,file,filename,printerror))){
                                sqstd_fclose(file);
@@ -262,7 +325,7 @@ SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool
 {
        if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) {
                sq_push(v,-2);
-               //int ntop = sq_gettop(v);
+               int ntop = sq_gettop(v);
                if(SQ_SUCCEEDED(sq_call(v,1,retval))) {
                        sq_remove(v,retval?-2:-1); //removes the closure
                        return 1;
@@ -315,7 +378,7 @@ int _g_io_dofile(HSQUIRRELVM v)
 static SQRegFunction iolib_funcs[]={
        _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")),
        _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")),
-       {0,0,0,0}
+       {0,0}
 };
 
 SQRESULT sqstd_register_iolib(HSQUIRRELVM v)
@@ -324,13 +387,13 @@ SQRESULT sqstd_register_iolib(HSQUIRRELVM v)
        //create delegate
        declare_stream(v,_SC("file"),SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs);
        sq_pushstring(v,_SC("stdout"),-1);
-       sqstd_createfile(v,stdout,0);
+       sqstd_createfile(v,stdout,SQFalse);
        sq_createslot(v,-3);
        sq_pushstring(v,_SC("stdin"),-1);
-       sqstd_createfile(v,stdin,0);
+       sqstd_createfile(v,stdin,SQFalse);
        sq_createslot(v,-3);
        sq_pushstring(v,_SC("stderr"),-1);
-       sqstd_createfile(v,stderr,0);
+       sqstd_createfile(v,stderr,SQFalse);
        sq_createslot(v,-3);
        sq_settop(v,top);
        return SQ_OK;
diff --git a/src/squirrel/sqstdlib/sqstdlib.dsp b/src/squirrel/sqstdlib/sqstdlib.dsp
deleted file mode 100644 (file)
index 99527ee..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-# Microsoft Developer Studio Project File - Name="sqstdlib" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=sqstdlib - Win32 Release
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "sqstdlib.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "sqstdlib.mak" CFG="sqstdlib - Win32 Release"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "sqstdlib - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "sqstdlib - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_LocalPath ".."
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "sqstdlib - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /W3 /GX /O2 /I "..\include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD BASE RSC /l 0x410 /d "NDEBUG"
-# ADD RSC /l 0x410 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\lib\sqstdlib.lib"
-
-!ELSEIF  "$(CFG)" == "sqstdlib - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x410 /d "_DEBUG"
-# ADD RSC /l 0x410 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\lib\sqstdlib.lib"
-
-!ENDIF 
-
-# Begin Target
-
-# Name "sqstdlib - Win32 Release"
-# Name "sqstdlib - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\sqstdblob.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\sqstdio.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\sqstdmath.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\sqstdrex.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\sqstdstream.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\sqstdstring.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\sqstdaux.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\sqstdsystem.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\sqstdblobimpl.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\sqstdstream.h
-# End Source File
-# End Group
-# End Target
-# End Project
index 802f9ca..f6d4d71 100644 (file)
@@ -77,7 +77,7 @@ static SQRegFunction mathlib_funcs[] = {
        _DECL_FUNC(rand,1,NULL),
        _DECL_FUNC(fabs,2,_SC(".n")),
        _DECL_FUNC(abs,2,_SC(".n")),
-       {0,0,0,0},
+       {0,0},
 };
 
 #ifndef M_PI
index d7e9436..534f17d 100644 (file)
-/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <string.h>
-#include <ctype.h>
-#include <setjmp.h>
-#include "sqstdstring.h"
-
-#ifdef _DEBUG
-#include <stdio.h>
-
-static const SQChar *g_nnames[] =
-{
-       _SC("NONE"),_SC("OP_GREEDY"),   _SC("OP_OR"),
-       _SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"),       _SC("OP_CLASS"),
-       _SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"),
-       _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB")
-};
-
-#endif
-
-#define OP_GREEDY              MAX_CHAR+1 // * + ? {n}
-#define OP_OR                  MAX_CHAR+2
-#define OP_EXPR                        MAX_CHAR+3 //parentesis ()
-#define OP_NOCAPEXPR   MAX_CHAR+4 //parentesis (?:)
-#define OP_DOT                 MAX_CHAR+5
-#define OP_CLASS               MAX_CHAR+6
-#define OP_CCLASS              MAX_CHAR+7
-#define OP_NCLASS              MAX_CHAR+8 //negates class the [^
-#define OP_RANGE               MAX_CHAR+9
-#define OP_CHAR                        MAX_CHAR+10
-#define OP_EOL                 MAX_CHAR+11
-#define OP_BOL                 MAX_CHAR+12
-#define OP_WB                  MAX_CHAR+13
-
-#define SQREX_SYMBOL_ANY_CHAR '.'
-#define SQREX_SYMBOL_GREEDY_ONE_OR_MORE '+'
-#define SQREX_SYMBOL_GREEDY_ZERO_OR_MORE '*'
-#define SQREX_SYMBOL_GREEDY_ZERO_OR_ONE '?'
-#define SQREX_SYMBOL_BRANCH '|'
-#define SQREX_SYMBOL_END_OF_STRING '$'
-#define SQREX_SYMBOL_BEGINNING_OF_STRING '^'
-#define SQREX_SYMBOL_ESCAPE_CHAR '\\'
-
-
-typedef int SQRexNodeType;
-
-typedef struct tagSQRexNode{
-       SQRexNodeType type;
-       long left;
-       long right;
-       int next;
-}SQRexNode;
-
-struct SQRex{
-       const SQChar *_eol;
-       const SQChar *_bol;
-       const SQChar *_p;
-       int _first;
-       int _op;
-       SQRexNode *_nodes;
-       int _nallocated;
-       int _nsize;
-       int _nsubexpr;
-       SQRexMatch *_matches;
-       int _currsubexp;
-       void *_jmpbuf;
-       const SQChar **_error;
-};
-
-static int sqstd_rex_list(SQRex *exp);
-
-static int sqstd_rex_newnode(SQRex *exp, SQRexNodeType type)
-{
-       SQRexNode n;
-       n.type = type;
-       n.next = n.right = n.left = -1;
-       if(type == OP_EXPR)
-               n.right = exp->_nsubexpr++;
-       if(exp->_nallocated < (exp->_nsize + 1)) {
-               int oldsize = exp->_nallocated;
-               exp->_nallocated *= 2;
-               exp->_nodes = (SQRexNode *)sq_realloc(exp->_nodes, oldsize * sizeof(SQRexNode) ,exp->_nallocated * sizeof(SQRexNode));
-       }
-       exp->_nodes[exp->_nsize++] = n;
-       return (int)exp->_nsize - 1;
-}
-
-static void sqstd_rex_error(SQRex *exp,const SQChar *error)
-{
-       if(exp->_error) *exp->_error = error;
-       longjmp(*((jmp_buf*)exp->_jmpbuf),-1);
-}
-
-static void sqstd_rex_expect(SQRex *exp, int n){
-       if((*exp->_p) != n) 
-               sqstd_rex_error(exp, _SC("expected paren"));
-       exp->_p++;
-}
-
-static SQBool sqstd_rex_ischar(SQChar c)
-{
-       switch(c) {
-       case SQREX_SYMBOL_BRANCH:case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE:
-       case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE:case SQREX_SYMBOL_GREEDY_ONE_OR_MORE:
-       case SQREX_SYMBOL_BEGINNING_OF_STRING:case SQREX_SYMBOL_END_OF_STRING:
-       case SQREX_SYMBOL_ANY_CHAR:case SQREX_SYMBOL_ESCAPE_CHAR:case '(':case ')':case '[':case '{': case '}':
-               return SQFalse;
-    }
-       return SQTrue;
-}
-
-static SQChar sqstd_rex_escapechar(SQRex *exp)
-{
-       if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR){
-               exp->_p++;
-               switch(*exp->_p) {
-               case 'v': exp->_p++; return '\v';
-               case 'n': exp->_p++; return '\n';
-               case 't': exp->_p++; return '\t';
-               case 'r': exp->_p++; return '\r';
-               case 'f': exp->_p++; return '\f';
-               default: return (*exp->_p++);
-               }
-       } else if(!sqstd_rex_ischar(*exp->_p)) sqstd_rex_error(exp,_SC("letter expected"));
-       return (*exp->_p++);
-}
-
-static int sqstd_rex_charclass(SQRex *exp,int classid)
-{
-       int n = sqstd_rex_newnode(exp,OP_CCLASS);
-       exp->_nodes[n].left = classid;
-       return n;
-}
-
-static int sqstd_rex_charnode(SQRex *exp,SQBool isclass)
-{
-       if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR) {
-               exp->_p++;
-               switch(*exp->_p) {
-                       case 'n': exp->_p++; return sqstd_rex_newnode(exp,'\n');
-                       case 't': exp->_p++; return sqstd_rex_newnode(exp,'\t');
-                       case 'r': exp->_p++; return sqstd_rex_newnode(exp,'\r');
-                       case 'f': exp->_p++; return sqstd_rex_newnode(exp,'\f');
-                       case 'v': exp->_p++; return sqstd_rex_newnode(exp,'\v');
-                       case 'a': case 'A': case 'w': case 'W': case 's': case 'S': 
-                       case 'd': case 'D': case 'x': case 'X': case 'c': case 'C': 
-                       case 'p': case 'P': case 'l': case 'u': 
-                               {
-                               SQChar t = *exp->_p;
-                               exp->_p++; 
-                               return sqstd_rex_charclass(exp,t);
-                               }
-                       case 'b': 
-                       case 'B':
-                               if(!isclass) {
-                                       int node = sqstd_rex_newnode(exp,OP_WB);
-                                       exp->_nodes[node].left = *exp->_p;
-                                       exp->_p++; 
-                                       return node;
-                               } //else default
-                       default: return sqstd_rex_newnode(exp,(*exp->_p++));
-               }
-       }
-       else if(!sqstd_rex_ischar(*exp->_p)) {
-               
-               sqstd_rex_error(exp,_SC("letter expected"));
-       }
-       return sqstd_rex_newnode(exp,*exp->_p++);
-}
-static int sqstd_rex_class(SQRex *exp)
-{
-       int ret = -1;
-       int first = -1,chain;
-       if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING){
-               ret = sqstd_rex_newnode(exp,OP_NCLASS);
-               exp->_p++;
-       }else ret = sqstd_rex_newnode(exp,OP_CLASS);
-       
-       if(*exp->_p == ']' || *exp->_p == '-'){
-               first = *exp->_p;
-               exp->_p++;
-       }
-       chain = ret;
-       while(*exp->_p != ']' && exp->_p != exp->_eol) {
-               if(*exp->_p == '-' && first != -1){ 
-                       int r;
-                       if(*exp->_p++ == ']') sqstd_rex_error(exp,_SC("unfinished range"));
-                       r = sqstd_rex_newnode(exp,OP_RANGE);
-                       if(first>*exp->_p) sqstd_rex_error(exp,_SC("invalid range"));
-                       if(exp->_nodes[first].type == OP_CCLASS) sqstd_rex_error(exp,_SC("cannot use character classes in ranges"));
-                       exp->_nodes[r].left = exp->_nodes[first].type;
-                       exp->_nodes[r].right = sqstd_rex_escapechar(exp);
-            exp->_nodes[chain].next = r;
-                       chain = r;
-                       first = -1;
-               }
-               else{
-                       if(first!=-1){
-                               int c = first;
-                               exp->_nodes[chain].next = c;
-                               chain = c;
-                               first = sqstd_rex_charnode(exp,SQTrue);
-                       }
-                       else{
-                               first = sqstd_rex_charnode(exp,SQTrue);
-                       }
-               }
-       }
-       if(first!=-1){
-               int c = first;
-               exp->_nodes[chain].next = c;
-               chain = c;
-               first = -1;
-       }
-       /* hack? */
-       exp->_nodes[ret].left = exp->_nodes[ret].next;
-       exp->_nodes[ret].next = -1;
-       return ret;
-}
-
-static int sqstd_rex_parsenumber(SQRex *exp)
-{
-       int ret = *exp->_p-'0';
-       int positions = 10;
-       exp->_p++;
-       while(isdigit(*exp->_p)) {
-               ret = ret*10+(*exp->_p++-'0');
-               if(positions==1000000000) sqstd_rex_error(exp,_SC("overflow in numeric constant"));
-               positions *= 10;
-       };
-       return ret;
-}
-
-static int sqstd_rex_element(SQRex *exp)
-{
-       int ret;
-       switch(*exp->_p)
-       {
-       case '(': {
-               int expr;
-               exp->_p++;
-               
-               
-               if(*exp->_p =='?') {
-                       exp->_p++;
-                       sqstd_rex_expect(exp,':');
-                       expr = sqstd_rex_newnode(exp,OP_NOCAPEXPR);
-               }
-               else
-                       expr = sqstd_rex_newnode(exp,OP_EXPR);
-               exp->_nodes[expr].left = sqstd_rex_list(exp);
-               ret = expr;
-               sqstd_rex_expect(exp,')');
-       }
-               break;
-       case '[':
-               exp->_p++;
-               ret = sqstd_rex_class(exp);
-               sqstd_rex_expect(exp,']');
-               break;
-       case SQREX_SYMBOL_END_OF_STRING: exp->_p++; ret = sqstd_rex_newnode(exp,OP_EOL);break;
-       case SQREX_SYMBOL_ANY_CHAR: exp->_p++; ret = sqstd_rex_newnode(exp,OP_DOT);break;
-       default:
-               ret = sqstd_rex_charnode(exp,SQFalse);
-               break;
-       }
-       /* scope block */
-       {
-               int op;
-               unsigned short p0 = 0, p1 = 0;
-               switch(*exp->_p){
-               case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; goto __end;
-               case SQREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; goto __end;
-               case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; goto __end;
-               case '{':{
-                       exp->_p++;
-                       if(!isdigit(*exp->_p)) sqstd_rex_error(exp,_SC("number expected"));
-                       p0 = sqstd_rex_parsenumber(exp);
-                       switch(*exp->_p) {
-                       case '}':
-                               p1 = p0; exp->_p++;
-                               goto __end;
-                       case ',':
-                               exp->_p++;
-                               p1 = 0xFFFF;
-                               if(isdigit(*exp->_p)){
-                                       p1 = sqstd_rex_parsenumber(exp);
-                               }
-                               sqstd_rex_expect(exp,'}');
-                               goto __end;
-                       default:
-                               sqstd_rex_error(exp,_SC(", or } expected"));
-                       }
-               }
-               __end: {
-                               int nnode = sqstd_rex_newnode(exp,OP_GREEDY);
-                               op = OP_GREEDY;
-                               exp->_nodes[nnode].left = ret;
-                               exp->_nodes[nnode].right = ((p0)<<16)|p1;
-                               ret = nnode;
-                       }
-               }
-       }
-       if(*exp->_p != SQREX_SYMBOL_BRANCH && *exp->_p != ')' && *exp->_p != SQREX_SYMBOL_GREEDY_ZERO_OR_MORE && *exp->_p != SQREX_SYMBOL_GREEDY_ONE_OR_MORE && *exp->_p != '\0')
-               exp->_nodes[ret].next = sqstd_rex_element(exp);
-       return ret;
-}
-
-static int sqstd_rex_list(SQRex *exp)
-{
-       int ret=-1,e;
-       if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING) {
-               exp->_p++;
-               ret = sqstd_rex_newnode(exp,OP_BOL);
-       }
-       e = sqstd_rex_element(exp);
-       if(ret != -1) {
-               exp->_nodes[ret].next = e;
-       }
-       else ret = e;
-
-       if(*exp->_p == SQREX_SYMBOL_BRANCH) {
-               int temp;
-               exp->_p++;
-               temp = sqstd_rex_newnode(exp,OP_OR);
-               exp->_nodes[temp].left = ret;
-               exp->_nodes[temp].right = sqstd_rex_list(exp);
-               ret = temp;
-       }
-       return ret;
-}
-
-static SQBool sqstd_rex_matchcclass(int cclass,SQChar c)
-{
-       switch(cclass) {
-       case 'a': return isalpha(c)?SQTrue:SQFalse;
-       case 'A': return !isalpha(c)?SQTrue:SQFalse;
-       case 'w': return (isalnum(c) || c == '_')?SQTrue:SQFalse;
-       case 'W': return (!isalnum(c) && c != '_')?SQTrue:SQFalse;
-       case 's': return isspace(c)?SQTrue:SQFalse;
-       case 'S': return !isspace(c)?SQTrue:SQFalse;
-       case 'd': return isdigit(c)?SQTrue:SQFalse;
-       case 'D': return !isdigit(c)?SQTrue:SQFalse;
-       case 'x': return isxdigit(c)?SQTrue:SQFalse;
-       case 'X': return !isxdigit(c)?SQTrue:SQFalse;
-       case 'c': return iscntrl(c)?SQTrue:SQFalse;
-       case 'C': return !iscntrl(c)?SQTrue:SQFalse;
-       case 'p': return ispunct(c)?SQTrue:SQFalse;
-       case 'P': return !ispunct(c)?SQTrue:SQFalse;
-       case 'l': return islower(c)?SQTrue:SQFalse;
-       case 'u': return isupper(c)?SQTrue:SQFalse;
-       }
-       return SQFalse; /*cannot happen*/
-}
-
-static SQBool sqstd_rex_matchclass(SQRex* exp,SQRexNode *node,SQChar c)
-{
-       do {
-               switch(node->type) {
-                       case OP_RANGE:
-                               if(c >= node->left && c <= node->right) return SQTrue;
-                               break;
-                       case OP_CCLASS:
-                               if(sqstd_rex_matchcclass(node->left,c)) return SQTrue;
-                               break;
-                       default:
-                               if(c == node->type)return SQTrue;
-               }
-       } while((node->next != -1) && (node = &exp->_nodes[node->next]));
-       return SQFalse;
-}
-
-static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar *str)
-{
-       SQRexNodeType type = node->type;
-       switch(type) {
-       case OP_GREEDY: {
-               int p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0;
-               const SQChar *s=str, *good = str;
-               while((nmaches == 0xFFFF || nmaches < p1) 
-                       && (s = sqstd_rex_matchnode(exp,&exp->_nodes[node->left],s))) {
-                       good=s;
-                       nmaches++;
-                       if(s >= exp->_eol)
-                               break;
-               }
-               if(p0 == p1 && p0 == nmaches) return good;
-               else if(nmaches >= p0 && p1 == 0xFFFF) return good;
-               else if(nmaches >= p0 && nmaches <= p1) return good;
-               return NULL;
-       }
-       case OP_OR: {
-                       const SQChar *asd = str;
-                       SQRexNode *temp=&exp->_nodes[node->left];
-                       while( (asd = sqstd_rex_matchnode(exp,temp,asd)) ) {
-                               if(temp->next != -1)
-                                       temp = &exp->_nodes[temp->next];
-                               else
-                                       return asd;
-                       }
-                       asd = str;
-                       temp = &exp->_nodes[node->right];
-                       while( (asd = sqstd_rex_matchnode(exp,temp,asd)) ) {
-                               if(temp->next != -1)
-                                       temp = &exp->_nodes[temp->next];
-                               else
-                                       return asd;
-                       }
-                       return NULL;
-                       break;
-       }
-       case OP_EXPR:
-       case OP_NOCAPEXPR:{
-                       SQRexNode *n = &exp->_nodes[node->left];
-                       const SQChar *cur = str;
-                       int capture = -1;
-                       if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) {
-                               capture = exp->_currsubexp;
-                               exp->_matches[capture].begin = cur;
-                               exp->_currsubexp++;
-                       }
-
-                       do {
-                               if(!(cur = sqstd_rex_matchnode(exp,n,cur))) {
-                                       if(capture != -1){
-                                               exp->_matches[capture].begin = 0;
-                                               exp->_matches[capture].len = 0;
-                                       }
-                                       return NULL;
-                               }
-                       } while((n->next != -1) && (n = &exp->_nodes[n->next]));
-
-                       if(capture != -1) 
-                               exp->_matches[capture].len = cur - exp->_matches[capture].begin;
-                       return cur;
-       }                                
-       case OP_WB:
-               if((str == exp->_bol && !isspace(*str))
-                || (str == exp->_eol && !isspace(*(str-1)))
-                || ((!isspace(*str) && isspace(*(str+1))))
-                || ((isspace(*str) && !isspace(*(str+1)))) ) {
-                       return (node->left == 'b')?str:NULL;
-               }
-               return (node->left == 'b')?NULL:str;
-       case OP_BOL:
-               if(str == exp->_bol) return str;
-               return NULL;
-       case OP_EOL:
-               if(str == exp->_eol) return str;
-               return NULL;
-       case OP_DOT:
-               *str++;
-               return str;
-       case OP_NCLASS:
-       case OP_CLASS:
-               if(sqstd_rex_matchclass(exp,&exp->_nodes[node->left],*str)?(type == OP_CLASS?SQTrue:SQFalse):(type == OP_NCLASS?SQTrue:SQFalse)) {
-                       *str++;
-                       return str;
-               }
-               return NULL;
-       case OP_CCLASS:
-               if(sqstd_rex_matchcclass(node->left,*str)) {
-                       *str++;
-                       return str;
-               }
-               return NULL;
-       default: /* char */
-               if(*str != node->type) return NULL;
-               *str++;
-               return str;
-       }
-       return NULL;
-}
-
-/* public api */
-SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error)
-{
-       SQRex *exp = (SQRex *)sq_malloc(sizeof(SQRex));
-       exp->_p = pattern;
-       exp->_nallocated = (int)scstrlen(pattern) * sizeof(SQChar);
-       exp->_nodes = (SQRexNode *)sq_malloc(exp->_nallocated * sizeof(SQRexNode));
-       exp->_nsize = 0;
-       exp->_matches = 0;
-       exp->_nsubexpr = 0;
-       exp->_first = sqstd_rex_newnode(exp,OP_EXPR);
-       exp->_error = error;
-       exp->_jmpbuf = sq_malloc(sizeof(jmp_buf));
-       if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) {
-               exp->_nodes[exp->_first].left=sqstd_rex_list(exp);
-               if(*exp->_p!='\0')
-                       sqstd_rex_error(exp,_SC("unexpected character"));
-#ifdef _DEBUG
-               {
-                       int nsize,i;
-                       SQRexNode *t;
-                       nsize = exp->_nsize;
-                       t = &exp->_nodes[0];
-                       scprintf(_SC("\n"));
-                       for(i = 0;i < nsize; i++) {
-                               if(exp->_nodes[i].type>MAX_CHAR)
-                                       scprintf(_SC("[%02d] %10s "),i,g_nnames[exp->_nodes[i].type-MAX_CHAR]);
-                               else
-                                       scprintf(_SC("[%02d] %10c "),i,exp->_nodes[i].type);
-                               scprintf(_SC("left %02d right %02d next %02d\n"),exp->_nodes[i].left,exp->_nodes[i].right,exp->_nodes[i].next);
-                       }
-                       scprintf(_SC("\n"));
-               }
-#endif
-               exp->_matches = (SQRexMatch *) sq_malloc(exp->_nsubexpr * sizeof(SQRexMatch));
-               memset(exp->_matches,0,exp->_nsubexpr * sizeof(SQRexMatch));
-       }
-       else{
-               sqstd_rex_free(exp);
-               return NULL;
-       }
-       return exp;
-}
-
-void sqstd_rex_free(SQRex *exp)
-{
-       if(exp) {
-               if(exp->_nodes) sq_free(exp->_nodes,exp->_nallocated * sizeof(SQRexNode));
-               if(exp->_jmpbuf) sq_free(exp->_jmpbuf,sizeof(jmp_buf));
-               if(exp->_matches) sq_free(exp->_matches,exp->_nsubexpr * sizeof(SQRexMatch));
-               sq_free(exp,sizeof(SQRex));
-       }
-}
-
-SQBool sqstd_rex_match(SQRex* exp,const SQChar* text)
-{
-       const SQChar* res = NULL;
-       exp->_bol = text;
-       exp->_eol = text + scstrlen(text);
-       exp->_currsubexp = 0;
-       res = sqstd_rex_matchnode(exp,exp->_nodes,text);
-       if(res == NULL || res != exp->_eol)
-               return SQFalse;
-       return SQTrue;
-}
-
-SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end)
-{
-       const SQChar *cur = NULL;
-       int node = exp->_first;
-       if(text_begin >= text_end) return SQFalse;
-       exp->_bol = text_begin;
-       exp->_eol = text_end;
-       do {
-               cur = text_begin;
-               while(node != -1) {
-                       exp->_currsubexp = 0;
-                       cur = sqstd_rex_matchnode(exp,&exp->_nodes[node],cur);
-                       if(!cur)
-                               break;
-                       node = exp->_nodes[node].next;
-               }
-               *text_begin++;
-       } while(cur == NULL && text_begin != text_end);
-
-       if(cur == NULL)
-               return SQFalse;
-
-       --text_begin;
-
-       if(out_begin) *out_begin = text_begin;
-       if(out_end) *out_end = cur;
-       return SQTrue;
-}
-
-SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end)
-{
-       return sqstd_rex_searchrange(exp,text,text + scstrlen(text),out_begin,out_end);
-}
-
-int sqstd_rex_getsubexpcount(SQRex* exp)
-{
-       return exp->_nsubexpr;
-}
-
-SQBool sqstd_rex_getsubexp(SQRex* exp, int n, SQRexMatch *subexp)
-{
-       if( n<0 || n >= exp->_nsubexpr) return SQFalse;
-       *subexp = exp->_matches[n];
-       return SQTrue;
-}
-
+/* see copyright notice in squirrel.h */\r
+#include <squirrel.h>\r
+#include <string.h>\r
+#include <ctype.h>\r
+#include <setjmp.h>\r
+#include "sqstdstring.h"\r
+\r
+#ifdef _DEBUG\r
+#include <stdio.h>\r
+\r
+static const SQChar *g_nnames[] =\r
+{\r
+       _SC("NONE"),_SC("OP_GREEDY"),   _SC("OP_OR"),\r
+       _SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"),       _SC("OP_CLASS"),\r
+       _SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"),\r
+       _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB")\r
+};\r
+\r
+#endif\r
+\r
+#define OP_GREEDY              MAX_CHAR+1 // * + ? {n}\r
+#define OP_OR                  MAX_CHAR+2\r
+#define OP_EXPR                        MAX_CHAR+3 //parentesis ()\r
+#define OP_NOCAPEXPR   MAX_CHAR+4 //parentesis (?:)\r
+#define OP_DOT                 MAX_CHAR+5\r
+#define OP_CLASS               MAX_CHAR+6\r
+#define OP_CCLASS              MAX_CHAR+7\r
+#define OP_NCLASS              MAX_CHAR+8 //negates class the [^\r
+#define OP_RANGE               MAX_CHAR+9\r
+#define OP_CHAR                        MAX_CHAR+10\r
+#define OP_EOL                 MAX_CHAR+11\r
+#define OP_BOL                 MAX_CHAR+12\r
+#define OP_WB                  MAX_CHAR+13\r
+\r
+#define SQREX_SYMBOL_ANY_CHAR '.'\r
+#define SQREX_SYMBOL_GREEDY_ONE_OR_MORE '+'\r
+#define SQREX_SYMBOL_GREEDY_ZERO_OR_MORE '*'\r
+#define SQREX_SYMBOL_GREEDY_ZERO_OR_ONE '?'\r
+#define SQREX_SYMBOL_BRANCH '|'\r
+#define SQREX_SYMBOL_END_OF_STRING '$'\r
+#define SQREX_SYMBOL_BEGINNING_OF_STRING '^'\r
+#define SQREX_SYMBOL_ESCAPE_CHAR '\\'\r
+\r
+\r
+typedef int SQRexNodeType;\r
+\r
+typedef struct tagSQRexNode{\r
+       SQRexNodeType type;\r
+       long left;\r
+       long right;\r
+       int next;\r
+}SQRexNode;\r
+\r
+struct SQRex{\r
+       const SQChar *_eol;\r
+       const SQChar *_bol;\r
+       const SQChar *_p;\r
+       int _first;\r
+       int _op;\r
+       SQRexNode *_nodes;\r
+       int _nallocated;\r
+       int _nsize;\r
+       int _nsubexpr;\r
+       SQRexMatch *_matches;\r
+       int _currsubexp;\r
+       void *_jmpbuf;\r
+       const SQChar **_error;\r
+};\r
+\r
+static int sqstd_rex_list(SQRex *exp);\r
+\r
+static int sqstd_rex_newnode(SQRex *exp, SQRexNodeType type)\r
+{\r
+       SQRexNode n;\r
+       n.type = type;\r
+       n.next = n.right = n.left = -1;\r
+       if(type == OP_EXPR)\r
+               n.right = exp->_nsubexpr++;\r
+       if(exp->_nallocated < (exp->_nsize + 1)) {\r
+               int oldsize = exp->_nallocated;\r
+               exp->_nallocated *= 2;\r
+               exp->_nodes = (SQRexNode *)sq_realloc(exp->_nodes, oldsize * sizeof(SQRexNode) ,exp->_nallocated * sizeof(SQRexNode));\r
+       }\r
+       exp->_nodes[exp->_nsize++] = n;\r
+       return (int)exp->_nsize - 1;\r
+}\r
+\r
+static void sqstd_rex_error(SQRex *exp,const SQChar *error)\r
+{\r
+       if(exp->_error) *exp->_error = error;\r
+       longjmp(*((jmp_buf*)exp->_jmpbuf),-1);\r
+}\r
+\r
+static void sqstd_rex_expect(SQRex *exp, int n){\r
+       if((*exp->_p) != n) \r
+               sqstd_rex_error(exp, _SC("expected paren"));\r
+       exp->_p++;\r
+}\r
+\r
+static SQBool sqstd_rex_ischar(SQChar c)\r
+{\r
+       switch(c) {\r
+       case SQREX_SYMBOL_BRANCH:case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE:\r
+       case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE:case SQREX_SYMBOL_GREEDY_ONE_OR_MORE:\r
+       case SQREX_SYMBOL_BEGINNING_OF_STRING:case SQREX_SYMBOL_END_OF_STRING:\r
+       case SQREX_SYMBOL_ANY_CHAR:case SQREX_SYMBOL_ESCAPE_CHAR:case '(':case ')':case '[':case '{': case '}':\r
+               return SQFalse;\r
+    }\r
+       return SQTrue;\r
+}\r
+\r
+static SQChar sqstd_rex_escapechar(SQRex *exp)\r
+{\r
+       if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR){\r
+               exp->_p++;\r
+               switch(*exp->_p) {\r
+               case 'v': exp->_p++; return '\v';\r
+               case 'n': exp->_p++; return '\n';\r
+               case 't': exp->_p++; return '\t';\r
+               case 'r': exp->_p++; return '\r';\r
+               case 'f': exp->_p++; return '\f';\r
+               default: return (*exp->_p++);\r
+               }\r
+       } else if(!sqstd_rex_ischar(*exp->_p)) sqstd_rex_error(exp,_SC("letter expected"));\r
+       return (*exp->_p++);\r
+}\r
+\r
+static int sqstd_rex_charclass(SQRex *exp,int classid)\r
+{\r
+       int n = sqstd_rex_newnode(exp,OP_CCLASS);\r
+       exp->_nodes[n].left = classid;\r
+       return n;\r
+}\r
+\r
+static int sqstd_rex_charnode(SQRex *exp,SQBool isclass)\r
+{\r
+       if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR) {\r
+               exp->_p++;\r
+               switch(*exp->_p) {\r
+                       case 'n': exp->_p++; return sqstd_rex_newnode(exp,'\n');\r
+                       case 't': exp->_p++; return sqstd_rex_newnode(exp,'\t');\r
+                       case 'r': exp->_p++; return sqstd_rex_newnode(exp,'\r');\r
+                       case 'f': exp->_p++; return sqstd_rex_newnode(exp,'\f');\r
+                       case 'v': exp->_p++; return sqstd_rex_newnode(exp,'\v');\r
+                       case 'a': case 'A': case 'w': case 'W': case 's': case 'S': \r
+                       case 'd': case 'D': case 'x': case 'X': case 'c': case 'C': \r
+                       case 'p': case 'P': case 'l': case 'u': \r
+                               {\r
+                               SQChar t = *exp->_p;\r
+                               exp->_p++; \r
+                               return sqstd_rex_charclass(exp,t);\r
+                               }\r
+                       case 'b': \r
+                       case 'B':\r
+                               if(!isclass) {\r
+                                       int node = sqstd_rex_newnode(exp,OP_WB);\r
+                                       exp->_nodes[node].left = *exp->_p;\r
+                                       exp->_p++; \r
+                                       return node;\r
+                               } //else default\r
+                       default: return sqstd_rex_newnode(exp,(*exp->_p++));\r
+               }\r
+       }\r
+       else if(!sqstd_rex_ischar(*exp->_p)) {\r
+               \r
+               sqstd_rex_error(exp,_SC("letter expected"));\r
+       }\r
+       return sqstd_rex_newnode(exp,*exp->_p++);\r
+}\r
+static int sqstd_rex_class(SQRex *exp)\r
+{\r
+       int ret = -1;\r
+       int first = -1,chain;\r
+       if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING){\r
+               ret = sqstd_rex_newnode(exp,OP_NCLASS);\r
+               exp->_p++;\r
+       }else ret = sqstd_rex_newnode(exp,OP_CLASS);\r
+       \r
+       if(*exp->_p == ']' || *exp->_p == '-'){\r
+               first = *exp->_p;\r
+               exp->_p++;\r
+       }\r
+       chain = ret;\r
+       while(*exp->_p != ']' && exp->_p != exp->_eol) {\r
+               if(*exp->_p == '-' && first != -1){ \r
+                       int r;\r
+                       if(*exp->_p++ == ']') sqstd_rex_error(exp,_SC("unfinished range"));\r
+                       r = sqstd_rex_newnode(exp,OP_RANGE);\r
+                       if(first>*exp->_p) sqstd_rex_error(exp,_SC("invalid range"));\r
+                       if(exp->_nodes[first].type == OP_CCLASS) sqstd_rex_error(exp,_SC("cannot use character classes in ranges"));\r
+                       exp->_nodes[r].left = exp->_nodes[first].type;\r
+                       exp->_nodes[r].right = sqstd_rex_escapechar(exp);\r
+            exp->_nodes[chain].next = r;\r
+                       chain = r;\r
+                       first = -1;\r
+               }\r
+               else{\r
+                       if(first!=-1){\r
+                               int c = first;\r
+                               exp->_nodes[chain].next = c;\r
+                               chain = c;\r
+                               first = sqstd_rex_charnode(exp,SQTrue);\r
+                       }\r
+                       else{\r
+                               first = sqstd_rex_charnode(exp,SQTrue);\r
+                       }\r
+               }\r
+       }\r
+       if(first!=-1){\r
+               int c = first;\r
+               exp->_nodes[chain].next = c;\r
+               chain = c;\r
+               first = -1;\r
+       }\r
+       /* hack? */\r
+       exp->_nodes[ret].left = exp->_nodes[ret].next;\r
+       exp->_nodes[ret].next = -1;\r
+       return ret;\r
+}\r
+\r
+static int sqstd_rex_parsenumber(SQRex *exp)\r
+{\r
+       int ret = *exp->_p-'0';\r
+       int positions = 10;\r
+       exp->_p++;\r
+       while(isdigit(*exp->_p)) {\r
+               ret = ret*10+(*exp->_p++-'0');\r
+               if(positions==1000000000) sqstd_rex_error(exp,_SC("overflow in numeric constant"));\r
+               positions *= 10;\r
+       };\r
+       return ret;\r
+}\r
+\r
+static int sqstd_rex_element(SQRex *exp)\r
+{\r
+       int ret;\r
+       switch(*exp->_p)\r
+       {\r
+       case '(': {\r
+               int expr;\r
+               exp->_p++;\r
+               \r
+               \r
+               if(*exp->_p =='?') {\r
+                       exp->_p++;\r
+                       sqstd_rex_expect(exp,':');\r
+                       expr = sqstd_rex_newnode(exp,OP_NOCAPEXPR);\r
+               }\r
+               else\r
+                       expr = sqstd_rex_newnode(exp,OP_EXPR);\r
+               exp->_nodes[expr].left = sqstd_rex_list(exp);\r
+               ret = expr;\r
+               sqstd_rex_expect(exp,')');\r
+       }\r
+               break;\r
+       case '[':\r
+               exp->_p++;\r
+               ret = sqstd_rex_class(exp);\r
+               sqstd_rex_expect(exp,']');\r
+               break;\r
+       case SQREX_SYMBOL_END_OF_STRING: exp->_p++; ret = sqstd_rex_newnode(exp,OP_EOL);break;\r
+       case SQREX_SYMBOL_ANY_CHAR: exp->_p++; ret = sqstd_rex_newnode(exp,OP_DOT);break;\r
+       default:\r
+               ret = sqstd_rex_charnode(exp,SQFalse);\r
+               break;\r
+       }\r
+       /* scope block */\r
+       {\r
+               int op;\r
+               unsigned short p0 = 0, p1 = 0;\r
+               switch(*exp->_p){\r
+               case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; goto __end;\r
+               case SQREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; goto __end;\r
+               case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; goto __end;\r
+               case '{':{\r
+                       exp->_p++;\r
+                       if(!isdigit(*exp->_p)) sqstd_rex_error(exp,_SC("number expected"));\r
+                       p0 = sqstd_rex_parsenumber(exp);\r
+                       switch(*exp->_p) {\r
+                       case '}':\r
+                               p1 = p0; exp->_p++;\r
+                               goto __end;\r
+                       case ',':\r
+                               exp->_p++;\r
+                               p1 = 0xFFFF;\r
+                               if(isdigit(*exp->_p)){\r
+                                       p1 = sqstd_rex_parsenumber(exp);\r
+                               }\r
+                               sqstd_rex_expect(exp,'}');\r
+                               goto __end;\r
+                       default:\r
+                               sqstd_rex_error(exp,_SC(", or } expected"));\r
+                       }\r
+               }\r
+               __end: {\r
+                               int nnode = sqstd_rex_newnode(exp,OP_GREEDY);\r
+                               op = OP_GREEDY;\r
+                               exp->_nodes[nnode].left = ret;\r
+                               exp->_nodes[nnode].right = ((p0)<<16)|p1;\r
+                               ret = nnode;\r
+                       }\r
+               }\r
+       }\r
+       if(*exp->_p != SQREX_SYMBOL_BRANCH && *exp->_p != ')' && *exp->_p != SQREX_SYMBOL_GREEDY_ZERO_OR_MORE && *exp->_p != SQREX_SYMBOL_GREEDY_ONE_OR_MORE && *exp->_p != '\0')\r
+               exp->_nodes[ret].next = sqstd_rex_element(exp);\r
+       return ret;\r
+}\r
+\r
+static int sqstd_rex_list(SQRex *exp)\r
+{\r
+       int ret=-1,e;\r
+       if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING) {\r
+               exp->_p++;\r
+               ret = sqstd_rex_newnode(exp,OP_BOL);\r
+       }\r
+       e = sqstd_rex_element(exp);\r
+       if(ret != -1) {\r
+               exp->_nodes[ret].next = e;\r
+       }\r
+       else ret = e;\r
+\r
+       if(*exp->_p == SQREX_SYMBOL_BRANCH) {\r
+               int temp;\r
+               exp->_p++;\r
+               temp = sqstd_rex_newnode(exp,OP_OR);\r
+               exp->_nodes[temp].left = ret;\r
+               exp->_nodes[temp].right = sqstd_rex_list(exp);\r
+               ret = temp;\r
+       }\r
+       return ret;\r
+}\r
+\r
+static SQBool sqstd_rex_matchcclass(int cclass,SQChar c)\r
+{\r
+       switch(cclass) {\r
+       case 'a': return isalpha(c)?SQTrue:SQFalse;\r
+       case 'A': return !isalpha(c)?SQTrue:SQFalse;\r
+       case 'w': return (isalnum(c) || c == '_')?SQTrue:SQFalse;\r
+       case 'W': return (!isalnum(c) && c != '_')?SQTrue:SQFalse;\r
+       case 's': return isspace(c)?SQTrue:SQFalse;\r
+       case 'S': return !isspace(c)?SQTrue:SQFalse;\r
+       case 'd': return isdigit(c)?SQTrue:SQFalse;\r
+       case 'D': return !isdigit(c)?SQTrue:SQFalse;\r
+       case 'x': return isxdigit(c)?SQTrue:SQFalse;\r
+       case 'X': return !isxdigit(c)?SQTrue:SQFalse;\r
+       case 'c': return iscntrl(c)?SQTrue:SQFalse;\r
+       case 'C': return !iscntrl(c)?SQTrue:SQFalse;\r
+       case 'p': return ispunct(c)?SQTrue:SQFalse;\r
+       case 'P': return !ispunct(c)?SQTrue:SQFalse;\r
+       case 'l': return islower(c)?SQTrue:SQFalse;\r
+       case 'u': return isupper(c)?SQTrue:SQFalse;\r
+       }\r
+       return SQFalse; /*cannot happen*/\r
+}\r
+\r
+static SQBool sqstd_rex_matchclass(SQRex* exp,SQRexNode *node,SQChar c)\r
+{\r
+       do {\r
+               switch(node->type) {\r
+                       case OP_RANGE:\r
+                               if(c >= node->left && c <= node->right) return SQTrue;\r
+                               break;\r
+                       case OP_CCLASS:\r
+                               if(sqstd_rex_matchcclass(node->left,c)) return SQTrue;\r
+                               break;\r
+                       default:\r
+                               if(c == node->type)return SQTrue;\r
+               }\r
+       } while((node->next != -1) && (node = &exp->_nodes[node->next]));\r
+       return SQFalse;\r
+}\r
+\r
+static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar *str)\r
+{\r
+       SQRexNodeType type = node->type;\r
+       switch(type) {\r
+       case OP_GREEDY: {\r
+               int p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0;\r
+               const SQChar *s=str, *good = str;\r
+               while((nmaches == 0xFFFF || nmaches < p1) \r
+                       && (s = sqstd_rex_matchnode(exp,&exp->_nodes[node->left],s))) {\r
+                       good=s;\r
+                       nmaches++;\r
+                       if(s >= exp->_eol)\r
+                               break;\r
+               }\r
+               if(p0 == p1 && p0 == nmaches) return good;\r
+               else if(nmaches >= p0 && p1 == 0xFFFF) return good;\r
+               else if(nmaches >= p0 && nmaches <= p1) return good;\r
+               return NULL;\r
+       }\r
+       case OP_OR: {\r
+                       const SQChar *asd = str;\r
+                       SQRexNode *temp=&exp->_nodes[node->left];\r
+                       while(asd = sqstd_rex_matchnode(exp,temp,asd)) {\r
+                               if(temp->next != -1)\r
+                                       temp = &exp->_nodes[temp->next];\r
+                               else\r
+                                       return asd;\r
+                       }\r
+                       asd = str;\r
+                       temp = &exp->_nodes[node->right];\r
+                       while(asd = sqstd_rex_matchnode(exp,temp,asd)) {\r
+                               if(temp->next != -1)\r
+                                       temp = &exp->_nodes[temp->next];\r
+                               else\r
+                                       return asd;\r
+                       }\r
+                       return NULL;\r
+                       break;\r
+       }\r
+       case OP_EXPR:\r
+       case OP_NOCAPEXPR:{\r
+                       SQRexNode *n = &exp->_nodes[node->left];\r
+                       const SQChar *cur = str;\r
+                       int capture = -1;\r
+                       if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) {\r
+                               capture = exp->_currsubexp;\r
+                               exp->_matches[capture].begin = cur;\r
+                               exp->_currsubexp++;\r
+                       }\r
+\r
+                       do {\r
+                               if(!(cur = sqstd_rex_matchnode(exp,n,cur))) {\r
+                                       if(capture != -1){\r
+                                               exp->_matches[capture].begin = 0;\r
+                                               exp->_matches[capture].len = 0;\r
+                                       }\r
+                                       return NULL;\r
+                               }\r
+                       } while((n->next != -1) && (n = &exp->_nodes[n->next]));\r
+\r
+                       if(capture != -1) \r
+                               exp->_matches[capture].len = cur - exp->_matches[capture].begin;\r
+                       return cur;\r
+       }                                \r
+       case OP_WB:\r
+               if(str == exp->_bol && !isspace(*str)\r
+                || (str == exp->_eol && !isspace(*(str-1)))\r
+                || (!isspace(*str) && isspace(*(str+1)))\r
+                || (isspace(*str) && !isspace(*(str+1))) ) {\r
+                       return (node->left == 'b')?str:NULL;\r
+               }\r
+               return (node->left == 'b')?NULL:str;\r
+       case OP_BOL:\r
+               if(str == exp->_bol) return str;\r
+               return NULL;\r
+       case OP_EOL:\r
+               if(str == exp->_eol) return str;\r
+               return NULL;\r
+       case OP_DOT:\r
+               *str++;\r
+               return str;\r
+       case OP_NCLASS:\r
+       case OP_CLASS:\r
+               if(sqstd_rex_matchclass(exp,&exp->_nodes[node->left],*str)?(type == OP_CLASS?SQTrue:SQFalse):(type == OP_NCLASS?SQTrue:SQFalse)) {\r
+                       *str++;\r
+                       return str;\r
+               }\r
+               return NULL;\r
+       case OP_CCLASS:\r
+               if(sqstd_rex_matchcclass(node->left,*str)) {\r
+                       *str++;\r
+                       return str;\r
+               }\r
+               return NULL;\r
+       default: /* char */\r
+               if(*str != node->type) return NULL;\r
+               *str++;\r
+               return str;\r
+       }\r
+       return NULL;\r
+}\r
+\r
+/* public api */\r
+SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error)\r
+{\r
+       SQRex *exp = (SQRex *)sq_malloc(sizeof(SQRex));\r
+       exp->_p = pattern;\r
+       exp->_nallocated = (int)scstrlen(pattern) * sizeof(SQChar);\r
+       exp->_nodes = (SQRexNode *)sq_malloc(exp->_nallocated * sizeof(SQRexNode));\r
+       exp->_nsize = 0;\r
+       exp->_matches = 0;\r
+       exp->_nsubexpr = 0;\r
+       exp->_first = sqstd_rex_newnode(exp,OP_EXPR);\r
+       exp->_error = error;\r
+       exp->_jmpbuf = sq_malloc(sizeof(jmp_buf));\r
+       if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) {\r
+               exp->_nodes[exp->_first].left=sqstd_rex_list(exp);\r
+               if(*exp->_p!='\0')\r
+                       sqstd_rex_error(exp,_SC("unexpected character"));\r
+#ifdef _DEBUG\r
+               {\r
+                       int nsize,i;\r
+                       SQRexNode *t;\r
+                       nsize = exp->_nsize;\r
+                       t = &exp->_nodes[0];\r
+                       scprintf(_SC("\n"));\r
+                       for(i = 0;i < nsize; i++) {\r
+                               if(exp->_nodes[i].type>MAX_CHAR)\r
+                                       scprintf(_SC("[%02d] %10s "),i,g_nnames[exp->_nodes[i].type-MAX_CHAR]);\r
+                               else\r
+                                       scprintf(_SC("[%02d] %10c "),i,exp->_nodes[i].type);\r
+                               scprintf(_SC("left %02d right %02d next %02d\n"),exp->_nodes[i].left,exp->_nodes[i].right,exp->_nodes[i].next);\r
+                       }\r
+                       scprintf(_SC("\n"));\r
+               }\r
+#endif\r
+               exp->_matches = (SQRexMatch *) sq_malloc(exp->_nsubexpr * sizeof(SQRexMatch));\r
+               memset(exp->_matches,0,exp->_nsubexpr * sizeof(SQRexMatch));\r
+       }\r
+       else{\r
+               sqstd_rex_free(exp);\r
+               return NULL;\r
+       }\r
+       return exp;\r
+}\r
+\r
+void sqstd_rex_free(SQRex *exp)\r
+{\r
+       if(exp) {\r
+               if(exp->_nodes) sq_free(exp->_nodes,exp->_nallocated * sizeof(SQRexNode));\r
+               if(exp->_jmpbuf) sq_free(exp->_jmpbuf,sizeof(jmp_buf));\r
+               if(exp->_matches) sq_free(exp->_matches,exp->_nsubexpr * sizeof(SQRexMatch));\r
+               sq_free(exp,sizeof(SQRex));\r
+       }\r
+}\r
+\r
+SQBool sqstd_rex_match(SQRex* exp,const SQChar* text)\r
+{\r
+       const SQChar* res = NULL;\r
+       exp->_bol = text;\r
+       exp->_eol = text + scstrlen(text);\r
+       exp->_currsubexp = 0;\r
+       res = sqstd_rex_matchnode(exp,exp->_nodes,text);\r
+       if(res == NULL || res != exp->_eol)\r
+               return SQFalse;\r
+       return SQTrue;\r
+}\r
+\r
+SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end)\r
+{\r
+       const SQChar *cur = NULL;\r
+       int node = exp->_first;\r
+       if(text_begin >= text_end) return SQFalse;\r
+       exp->_bol = text_begin;\r
+       exp->_eol = text_end;\r
+       do {\r
+               cur = text_begin;\r
+               while(node != -1) {\r
+                       exp->_currsubexp = 0;\r
+                       cur = sqstd_rex_matchnode(exp,&exp->_nodes[node],cur);\r
+                       if(!cur)\r
+                               break;\r
+                       node = exp->_nodes[node].next;\r
+               }\r
+               *text_begin++;\r
+       } while(cur == NULL && text_begin != text_end);\r
+\r
+       if(cur == NULL)\r
+               return SQFalse;\r
+\r
+       --text_begin;\r
+\r
+       if(out_begin) *out_begin = text_begin;\r
+       if(out_end) *out_end = cur;\r
+       return SQTrue;\r
+}\r
+\r
+SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end)\r
+{\r
+       return sqstd_rex_searchrange(exp,text,text + scstrlen(text),out_begin,out_end);\r
+}\r
+\r
+int sqstd_rex_getsubexpcount(SQRex* exp)\r
+{\r
+       return exp->_nsubexpr;\r
+}\r
+\r
+SQBool sqstd_rex_getsubexp(SQRex* exp, int n, SQRexMatch *subexp)\r
+{\r
+       if( n<0 || n >= exp->_nsubexpr) return SQFalse;\r
+       *subexp = exp->_matches[n];\r
+       return SQTrue;\r
+}\r
+\r
index f9c5d0d..fea88f8 100644 (file)
@@ -42,7 +42,7 @@ int _stream_readstr(HSQUIRRELVM v)
                break;
        case _SC('u'): {
                wchar_t *temp;
-               if(self->Read(sq_getscratchpad(v, (size + 1) * sizeof(wchar_t)), size * sizeof(wchar_t)) != (int) (size * sizeof(wchar_t)))
+               if(self->Read(sq_getscratchpad(v, (size + 1) * sizeof(wchar_t)),size * sizeof(wchar_t)) != (size * sizeof(wchar_t)))
                        return sq_throwerror(v, _SC("io failure"));
                
 #ifdef _UNICODE
@@ -315,7 +315,7 @@ static SQRegFunction _stream_methods[] = {
        _DECL_STREAM_FUNC(len,1,_SC("x")),
        _DECL_STREAM_FUNC(eos,1,_SC("x")),
        _DECL_STREAM_FUNC(flush,1,_SC("x")),
-       {0,0,0,0}
+       {0,0}
 };
 
 void init_streamclass(HSQUIRRELVM v)
index b8a42a4..9caef54 100644 (file)
@@ -133,7 +133,6 @@ static int _string_format(HSQUIRRELVM v)
 
 static int _rexobj_releasehook(SQUserPointer p, int size)
 {
-       (void) size;
        SQRex *self = ((SQRex *)p);
        sqstd_rex_free(self);
        return 1;
@@ -233,13 +232,13 @@ static SQRegFunction rexobj_funcs[]={
        _DECL_REX_FUNC(capture,-2,_SC("xsn")),
        _DECL_REX_FUNC(subexpcount,1,_SC("x")),
        _DECL_REX_FUNC(_typeof,1,_SC("x")),
-       {0,0,0,0}
+       {0,0}
 };
 
 #define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask}
 static SQRegFunction stringlib_funcs[]={
        _DECL_FUNC(format,-2,_SC(".s")),
-       {0,0,0,0}
+       {0,0}
 };
 
 
index 1f9cf23..075a880 100644 (file)
@@ -125,7 +125,7 @@ static SQRegFunction systemlib_funcs[]={
        _DECL_FUNC(date,-1,_SC(".nn")),
        _DECL_FUNC(remove,2,_SC(".s")),
        _DECL_FUNC(rename,3,_SC(".ss")),
-       {0,0,0,0}
+       {0,0}
 };
 
 
index 85d642b..1234d99 100644 (file)
@@ -9,8 +9,8 @@
 #include "sqfuncproto.h"
 #include "sqclosure.h"
 #include "squserdata.h"
-#include "sqfuncstate.h"
 #include "sqcompiler.h"
+#include "sqfuncstate.h"
 #include "sqclass.h"
 
 bool sq_aux_gettypedarg(HSQUIRRELVM v,int idx,SQObjectType type,SQObjectPtr **o)
@@ -363,6 +363,9 @@ SQRESULT sq_setparamscheck(HSQUIRRELVM v,int nparamscheck,const SQChar *typemask
        else {
                nc->_typecheck.resize(0);
        }
+       if(nparamscheck == SQ_MATCHTYPEMASKSTRING) {
+               nc->_nparamscheck = nc->_typecheck.size();
+       }
        return SQ_OK;
 }
 
@@ -705,8 +708,6 @@ SQRESULT sq_getdelegate(HSQUIRRELVM v,int idx)
                v->Push(SQObjectPtr(_userdata(self)->_delegate));
                return SQ_OK;
                break;
-       default:
-               break;
        }
        return sq_throwerror(v,_SC("wrong type"));
 }
@@ -874,8 +875,6 @@ void sq_setreleasehook(HSQUIRRELVM v,int idx,SQRELEASEHOOK hook)
                case OT_INSTANCE:
                        _instance(ud)->_hook = hook;
                        break;
-               default:
-                       break;
                }
        }
 }
@@ -889,7 +888,7 @@ SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up)
 {
        SQObjectPtr *o = NULL;
        _GETSAFE_OBJ(v, -1, OT_CLOSURE,o);
-       //SQClosure *c=_closure(*o);
+       SQClosure *c=_closure(*o);
        unsigned short tag = SQ_BYTECODE_STREAM_TAG;
        if(w(up,&tag,2) != 2)
                return sq_throwerror(v,_SC("io error"));
index be7241e..01bce2c 100644 (file)
@@ -99,7 +99,7 @@ static int base_getstackinfos(HSQUIRRELVM v)
                sq_pushstring(v, _SC("locals"), -1);
                sq_newtable(v);
                seq=0;
-               while ( (name = sq_getlocal(v, level, seq)) ) {
+               while (name = sq_getlocal(v, level, seq)) {
                        sq_pushstring(v, name, -1);
                        sq_push(v, -2);
                        sq_createslot(v, -4);
@@ -236,7 +236,7 @@ static SQRegFunction base_funcs[]={
 #ifndef NO_GARBAGE_COLLECTOR
        {_SC("collectgarbage"),base_collectgarbage,1, _SC("t")},
 #endif
-       {0,0,0,0}
+       {0,0}
 };
 
 void sq_base_register(HSQUIRRELVM v)
@@ -381,7 +381,7 @@ SQRegFunction SQSharedState::_table_default_delegate_funcz[]={
        {_SC("rawset"),table_rawset,3, _SC("t")},
        {_SC("rawdelete"),table_rawdelete,2, _SC("t")},
        {_SC("rawin"),container_rawexists,2, _SC("t")},
-       {0,0,0,0}
+       {0,0}
 };
 
 //ARRAY DEFAULT DELEGATE///////////////////////////////////////
@@ -458,8 +458,6 @@ static int array_resize(HSQUIRRELVM v)
 //QSORT ala Sedgewick
 bool _qsort_compare(HSQUIRRELVM v,SQObjectPtr &arr,SQObjectPtr &a,SQObjectPtr &b,int func,int &ret)
 {
-       (void) arr;
-
        if(func < 0) {
                if(!v->ObjCmp(a,b,ret)) return false;
        }
@@ -559,7 +557,7 @@ SQRegFunction SQSharedState::_array_default_delegate_funcz[]={
        {_SC("reverse"),array_reverse,1, _SC("a")},
        {_SC("sort"),array_sort,-1, _SC("ac")},
        {_SC("slice"),array_slice,-1, _SC("ann")},
-       {0,0,0,0}
+       {0,0}
 };
 
 //STRING DEFAULT DELEGATE//////////////////////////
@@ -618,7 +616,7 @@ SQRegFunction SQSharedState::_string_default_delegate_funcz[]={
        {_SC("find"),string_find,-2, _SC("s s n ")},
        {_SC("tolower"),string_tolower,1, _SC("s")},
        {_SC("toupper"),string_toupper,1, _SC("s")},
-       {0,0,0,0}
+       {0,0}
 };
 
 //INTEGER DEFAULT DELEGATE//////////////////////////
@@ -627,7 +625,7 @@ SQRegFunction SQSharedState::_number_default_delegate_funcz[]={
        {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")},
        {_SC("tostring"),default_delegate_tostring,1, _SC("n|b")},
        {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")},
-       {0,0,0,0}
+       {0,0}
 };
 
 //CLOSURE DEFAULT DELEGATE//////////////////////////
@@ -648,7 +646,7 @@ static int closure_acall(HSQUIRRELVM v)
 SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={
        {_SC("call"),closure_call,-1, _SC("c")},
        {_SC("acall"),closure_acall,2, _SC("ca")},
-       {0,0,0,0}
+       {0,0}
 };
 
 //GENERATOR DEFAULT DELEGATE
@@ -665,7 +663,7 @@ static int generator_getstatus(HSQUIRRELVM v)
 
 SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={
        {_SC("getstatus"),generator_getstatus,1, _SC("g")},
-       {0,0,0,0}
+       {0,0}
 };
 
 //THREAD DEFAULT DELEGATE
@@ -744,7 +742,7 @@ SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = {
        {_SC("call"), thread_call, -1, _SC("v")},
        {_SC("wakeup"), thread_wakeup, -1, _SC("v")},
        {_SC("getstatus"), thread_getstatus, 1, _SC("v")},
-       {0,0,0,0},
+       {0,0},
 };
 
 static int class_getattributes(HSQUIRRELVM v)
@@ -765,7 +763,7 @@ SQRegFunction SQSharedState::_class_default_delegate_funcz[] = {
        {_SC("getattributes"), class_getattributes, 2, _SC("y.")},
        {_SC("setattributes"), class_setattributes, 3, _SC("y..")},
        {_SC("rawin"),container_rawexists,2, _SC("y")},
-       {0,0,0,0}
+       {0,0}
 };
 
 static int instance_getclass(HSQUIRRELVM v)
@@ -778,6 +776,6 @@ static int instance_getclass(HSQUIRRELVM v)
 SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = {
        {_SC("getclass"), instance_getclass, 1, _SC("x")},
        {_SC("rawin"),container_rawexists,2, _SC("x")},
-       {0,0,0,0}
+       {0,0}
 };
 
index 6bc84db..11d4095 100644 (file)
@@ -60,18 +60,18 @@ bool SQClass::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
                } 
                else {
                        if(type(temp) == OT_NULL) {
-                               SQClassMember m;
+                               SQClassMemeber m;
                                m.val = val;
-                               _members->NewSlot(key, SQObjectPtr((SQUserPointer)_methods.size()));
+                               _members->NewSlot(key,SQObjectPtr((SQUserPointer)_methods.size()));
                                _methods.push_back(m);
                        }
                        else {
-                               _methods[_integer(temp)].val = val;
+                               _methods[(int)_userpointer(temp)].val = val;
                        }
                }
                return true;
        }
-       SQClassMember m;
+       SQClassMemeber m;
        m.val = val;
        _members->NewSlot(key,SQObjectPtr((SQInteger)_defaultvalues.size()));
        _defaultvalues.push_back(m);
@@ -90,7 +90,7 @@ int SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &o
        int idx = _members->Next(refpos,outkey,oval);
        if(idx != -1) {
                if(type(oval) != OT_INTEGER) {
-                       outval = _methods[_integer(oval)].val;
+                       outval = _methods[(int)_userpointer(oval)].val;
                }
                else {
                        outval = _defaultvalues[_integer(oval)].val;
@@ -106,7 +106,7 @@ bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val)
                if(type(idx) == OT_INTEGER)
                        _defaultvalues[_integer(idx)].attrs = val;
                else
-                       _methods[_integer(idx)].attrs = val;
+                       _methods[(int)_userpointer(idx)].attrs = val;
                return true;
        }
        return false;
index c9de102..5c12d7e 100644 (file)
@@ -4,9 +4,9 @@
 
 struct SQInstance;
 
-struct SQClassMember {
-       SQClassMember(){}
-       SQClassMember(const SQClassMember &o) {
+struct SQClassMemeber {
+       SQClassMemeber(){}
+       SQClassMemeber(const SQClassMemeber &o) {
                val = o.val;
                attrs = o.attrs;
        }
@@ -14,7 +14,7 @@ struct SQClassMember {
        SQObjectPtr attrs;
 };
 
-typedef sqvector<SQClassMember> SQClassMemberVec;
+typedef sqvector<SQClassMemeber> SQClassMemeberVec;
 
 struct SQClass : public CHAINABLE_OBJ
 {
@@ -29,7 +29,7 @@ public:
        bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val);
        bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
                if(_members->Get(key,val)) {
-                       val = (type(val) == OT_INTEGER?_defaultvalues[_integer(val)].val:_methods[_integer(val)].val);
+                       val = (type(val) == OT_INTEGER?_defaultvalues[_integer(val)].val:_methods[(int)_userpointer(val)].val);
                        return true;
                }
                return false;
@@ -45,8 +45,8 @@ public:
        SQTable *_members;
        //SQTable *_properties;
        SQClass *_base;
-       SQClassMemberVec _defaultvalues;
-       SQClassMemberVec _methods;
+       SQClassMemeberVec _defaultvalues;
+       SQClassMemeberVec _methods;
        SQObjectPtrVec _metamethods;
        SQObjectPtr _attributes;
        unsigned int _typetag;
@@ -73,7 +73,7 @@ public:
        ~SQInstance();
        bool Get(const SQObjectPtr &key,SQObjectPtr &val)  {
                if(_class->_members->Get(key,val)) {
-                       val = (type(val) == OT_INTEGER?_values[_integer(val)]:_class->_methods[_integer(val)].val);
+                       val = (type(val) == OT_INTEGER?_values[_integer(val)]:_class->_methods[(int)_userpointer(val)].val);
                        return true;
                }
                return false;
index 40c8d49..1f20728 100644 (file)
@@ -3,11 +3,12 @@
 */
 #include "sqpcheader.h"
 #include <stdarg.h>
+#include <setjmp.h>
 #include "sqopcodes.h"
 #include "sqstring.h"
 #include "sqfuncproto.h"
-#include "sqfuncstate.h"
 #include "sqcompiler.h"
+#include "sqfuncstate.h"
 #include "sqlexer.h"
 #include "sqvm.h"
 
@@ -49,9 +50,14 @@ public:
        SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo)
        {
                _vm=v;
-               _lex.Init(_ss(v), rg, up);
+               _lex.Init(_ss(v), rg, up,ThrowError,this);
                _sourcename = SQString::Create(_ss(v), sourcename);
                _lineinfo = lineinfo;_raiseerror = raiseerror;
+               compilererror = NULL;
+       }
+       static void ThrowError(void *ud, const SQChar *s) {
+               SQCompiler *c = (SQCompiler *)ud;
+               c->Error(s);
        }
        void Error(const SQChar *s, ...)
        {
@@ -60,7 +66,8 @@ public:
                va_start(vl, s);
                scvsprintf(temp, s, vl);
                va_end(vl);
-               throw ParserException(temp);
+               compilererror = temp;
+               longjmp(_errorjmp,1);
        }
        void Lex(){     _token = _lex.Lex();}
        void PushExpState(){ _expstates.push_back(ExpState()); }
@@ -78,51 +85,53 @@ public:
                _expstates.pop_back();
                return ret;
        }
-       SQObjectPtr Expect(int tok)
+       SQObject Expect(int tok)
        {
-               SQObjectPtr ret;
+               
                if(_token != tok) {
                        if(_token == TK_CONSTRUCTOR && tok == TK_IDENTIFIER) {
                                //ret = SQString::Create(_ss(_vm),_SC("constructor"));
                                //do nothing
                        }
                        else {
+                               const SQChar *etypename;
                                if(tok > 255) {
                                        switch(tok)
                                        {
                                        case TK_IDENTIFIER:
-                                               ret = SQString::Create(_ss(_vm), _SC("IDENTIFIER"));
+                                               etypename = _SC("IDENTIFIER");
                                                break;
                                        case TK_STRING_LITERAL:
-                                               ret = SQString::Create(_ss(_vm), _SC("STRING_LITERAL"));
+                                               etypename = _SC("STRING_LITERAL");
                                                break;
                                        case TK_INTEGER:
-                                               ret = SQString::Create(_ss(_vm), _SC("INTEGER"));
+                                               etypename = _SC("INTEGER");
                                                break;
                                        case TK_FLOAT:
-                                               ret = SQString::Create(_ss(_vm), _SC("FLOAT"));
+                                               etypename = _SC("FLOAT");
                                                break;
                                        default:
-                                               ret = _lex.Tok2Str(tok);
+                                               etypename = _lex.Tok2Str(tok);
                                        }
-                                       Error(_SC("expected '%s'"), _stringval(ret));
+                                       Error(_SC("expected '%s'"), etypename);
                                }
                                Error(_SC("expected '%c'"), tok);
                        }
                }
+               SQObjectPtr ret;
                switch(tok)
                {
                case TK_IDENTIFIER:
-                       ret = SQString::Create(_ss(_vm), _lex._svalue);
+                       ret = _fs->CreateString(_lex._svalue);
                        break;
                case TK_STRING_LITERAL:
-                       ret = SQString::Create(_ss(_vm), _lex._svalue,_lex._longstr.size()-1);
+                       ret = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1);
                        break;
                case TK_INTEGER:
-                       ret = _lex._nvalue;
+                       ret = SQObjectPtr(_lex._nvalue);
                        break;
                case TK_FLOAT:
-                       ret = _lex._fvalue;
+                       ret = SQObjectPtr(_lex._fvalue);
                        break;
                }
                Lex();
@@ -145,16 +154,17 @@ public:
        }
        bool Compile(SQObjectPtr &o)
        {
-               SQ_TRY {
-                       _debugline = 1;
-                       _debugop = 0;
+               _debugline = 1;
+               _debugop = 0;
+
+               SQFuncState funcstate(_ss(_vm), SQFunctionProto::Create(), NULL,ThrowError,this);
+               _funcproto(funcstate._func)->_name = SQString::Create(_ss(_vm), _SC("main"));
+               _fs = &funcstate;
+               _fs->AddParameter(_fs->CreateString(_SC("this")));
+               _funcproto(_fs->_func)->_sourcename = _sourcename;
+               int stacksize = _fs->GetStackSize();
+               if(setjmp(_errorjmp) == 0) {
                        Lex();
-                       SQFuncState funcstate(_ss(_vm), SQFunctionProto::Create(), NULL);
-                       _funcproto(funcstate._func)->_name = SQString::Create(_ss(_vm), _SC("main"));
-                       _fs = &funcstate;
-                       _fs->AddParameter(SQString::Create(_ss(_vm), _SC("this")));
-                       _funcproto(_fs->_func)->_sourcename = _sourcename;
-                       int stacksize = _fs->GetStackSize();
                        while(_token > 0){
                                Statement();
                                if(_lex._prevtoken != _SC('}')) OptionalSemicolon();
@@ -170,13 +180,12 @@ public:
                        _fs->Dump();
 #endif
                }
-               SQ_CATCH(ParserException,ex){
-                       if(_raiseerror && _ss(_vm)->_compilererrorhandler){
-                               SQObjectPtr ret;
-                               _ss(_vm)->_compilererrorhandler(_vm, ex.desc, type(_sourcename) == OT_STRING?_stringval(_sourcename):_SC("unknown"),
+               else {
+                       if(_raiseerror && _ss(_vm)->_compilererrorhandler) {
+                               _ss(_vm)->_compilererrorhandler(_vm, compilererror, type(_sourcename) == OT_STRING?_stringval(_sourcename):_SC("unknown"),
                                        _lex._currentline, _lex._currentcolumn);
                        }
-                       _vm->_lasterror = SQString::Create(_ss(_vm), ex.desc, -1);
+                       _vm->_lasterror = SQString::Create(_ss(_vm), compilererror, -1);
                        return false;
                }
                return true;
@@ -296,7 +305,7 @@ public:
                case TK_MULEQ: oper = '*'; break;
                case TK_DIVEQ: oper = '/'; break;
                case TK_MODEQ: oper = '%'; break;
-               default: oper = 0; assert(0); break;
+               default: assert(0); break;
                };
                if(deref) {
                        int val = _fs->PopTarget();
@@ -504,7 +513,6 @@ public:
                        switch(_token) {
                        case _SC('.'): {
                                pos = -1;
-                               SQObjectPtr idx;
                                Lex(); 
                                if(_token == TK_PARENT) {
                                        Lex();
@@ -514,8 +522,7 @@ public:
                                        _fs->AddInstruction(_OP_GETPARENT, _fs->PushTarget(), src);
                                }
                                else {
-                                       idx = Expect(TK_IDENTIFIER); 
-                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetStringConstant(_stringval(idx)));
+                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));
                                        if(NeedGet()) Emit2ArgsOP(_OP_GET);
                                }
                                _exst._deref = DEREF_FIELD;
@@ -574,8 +581,8 @@ public:
                switch(_token)
                {
                case TK_STRING_LITERAL: {
-                               SQObjectPtr id(SQString::Create(_ss(_vm), _lex._svalue,_lex._longstr.size()-1));
-                               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetStringConstant(_stringval(id)));
+                               //SQObjectPtr id(SQString::Create(_ss(_vm), _lex._svalue,_lex._longstr.size()-1));
+                               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_fs->CreateString(_lex._svalue,_lex._longstr.size()-1)));
                                Lex(); 
                        }
                        break;
@@ -592,11 +599,11 @@ public:
                case TK_CONSTRUCTOR:
                case TK_THIS:{
                        _exst._freevar = false;
-                       SQObjectPtr id;
+                       SQObject id;
                                switch(_token) {
-                                       case TK_IDENTIFIER: id = SQString::Create(_ss(_vm), _lex._svalue); break;
-                                       case TK_THIS: id = SQString::Create(_ss(_vm), _SC("this")); break;
-                                       case TK_CONSTRUCTOR: id = SQString::Create(_ss(_vm), _SC("constructor")); break;
+                                       case TK_IDENTIFIER: id = _fs->CreateString(_lex._svalue); break;
+                                       case TK_THIS: id = _fs->CreateString(_SC("this")); break;
+                                       case TK_CONSTRUCTOR: id = _fs->CreateString(_SC("constructor")); break;
                                }
                                int pos = -1;
                                Lex();
@@ -608,7 +615,7 @@ public:
                                                _exst._freevar = true;
                                        } else {
                                                _fs->PushTarget(0);
-                                               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetStringConstant(_stringval(id)));
+                                               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
                                                if(NeedGet()) Emit2ArgsOP(_OP_GET);
                                                _exst._deref = DEREF_FIELD;
                                        }
@@ -733,9 +740,9 @@ public:
                                case TK_CONSTRUCTOR:{
                                        int tk = _token;
                                        Lex();
-                                       SQObjectPtr id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : SQString::Create(_ss(_vm),_SC("constructor"));
+                                       SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : _fs->CreateString(_SC("constructor"));
                                        Expect(_SC('('));
-                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetStringConstant(_stringval(id)));
+                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
                                        CreateFunction(id);
                                        _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);
                                                                  }
@@ -745,7 +752,7 @@ public:
                                        Expect(_SC('=')); Expression();
                                        break;
                                default :
-                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetStringConstant(_stringval(Expect(TK_IDENTIFIER))));
+                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));
                                        Expect(_SC('=')); Expression();
                        }
 
@@ -765,7 +772,7 @@ public:
        }
        void LocalDeclStatement()
        {
-               SQObjectPtr varname;
+               SQObject varname;
                do {
                        Lex(); varname = Expect(TK_IDENTIFIER);
                        if(_token == _SC('=')) {
@@ -890,14 +897,14 @@ public:
        }
        void ForEachStatement()
        {
-               SQObjectPtr idxname, valname;
+               SQObject idxname, valname;
                Lex(); Expect(_SC('(')); valname = Expect(TK_IDENTIFIER);
                if(_token == _SC(',')) {
                        idxname = valname;
                        Lex(); valname = Expect(TK_IDENTIFIER);
                }
                else{
-                       idxname = SQString::Create(_ss(_vm), _SC("@INDEX@"));
+                       idxname = _fs->CreateString(_SC("@INDEX@"));
                }
                Expect(TK_IN);
                
@@ -913,7 +920,7 @@ public:
                int valuepos = _fs->PushLocalVariable(valname);
                _fs->AddInstruction(_OP_LOADNULLS, valuepos,1);
                //push reference index
-               int itrpos = _fs->PushLocalVariable(SQString::Create(_ss(_vm), _SC("@ITERATOR@"))); //use invalid id to make it inaccessible
+               int itrpos = _fs->PushLocalVariable(_fs->CreateString(_SC("@ITERATOR@"))); //use invalid id to make it inaccessible
                _fs->AddInstruction(_OP_LOADNULLS, itrpos,1);
                int jmppos = _fs->GetCurrentPos();
                _fs->AddInstruction(_OP_FOREACH, container, 0, indexpos);
@@ -975,16 +982,16 @@ public:
        }
        void FunctionStatement()
        {
-               SQObjectPtr id;
+               SQObject id;
                Lex(); id = Expect(TK_IDENTIFIER);
                _fs->PushTarget(0);
-               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetStringConstant(_stringval(id)));
+               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
                if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);
                
                while(_token == TK_DOUBLE_COLON) {
                        Lex();
                        id = Expect(TK_IDENTIFIER);
-                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetStringConstant(_stringval(id)));
+                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
                        if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);
                }
                Expect(_SC('('));
@@ -1011,7 +1018,7 @@ public:
        }
        void TryCatchStatement()
        {
-               SQObjectPtr exid;
+               SQObject exid;
                Lex();
                _fs->AddInstruction(_OP_PUSHTRAP,0,0);
                _fs->_traps++;
@@ -1094,23 +1101,24 @@ public:
                        _fs->AddInstruction(_OP_INCL, _fs->PushTarget(), src, 0, token == TK_MINUSMINUS?-1:1);
                }
        }
-       void CreateFunction(SQObjectPtr name)
+       void CreateFunction(SQObject &name)
        {
-               SQFuncState funcstate(_ss(_vm), SQFunctionProto::Create(), _fs);
-               _funcproto(funcstate._func)->_name = name;
-               SQObjectPtr paramname;
-               funcstate.AddParameter(SQString::Create(_ss(_vm), _SC("this")));
-               _funcproto(funcstate._func)->_sourcename = _sourcename;
+               
+               SQFuncState *funcstate = _fs->PushChildState(_ss(_vm), SQFunctionProto::Create());
+               _funcproto(funcstate->_func)->_name = name;
+               SQObject paramname;
+               funcstate->AddParameter(_fs->CreateString(_SC("this")));
+               _funcproto(funcstate->_func)->_sourcename = _sourcename;
                while(_token!=_SC(')')) {
                        if(_token == TK_VARPARAMS) {
-                               funcstate._varparams = true;
+                               funcstate->_varparams = true;
                                Lex();
                                if(_token != _SC(')')) Error(_SC("expected ')'"));
                                break;
                        }
                        else {
                                paramname = Expect(TK_IDENTIFIER);
-                               funcstate.AddParameter(paramname);
+                               funcstate->AddParameter(paramname);
                                if(_token == _SC(',')) Lex();
                                else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));
                        }
@@ -1122,7 +1130,7 @@ public:
                        while(_token != _SC(')')) {
                                paramname = Expect(TK_IDENTIFIER);
                                //outers are treated as implicit local variables
-                               funcstate.AddOuterValue(paramname);
+                               funcstate->AddOuterValue(paramname);
                                if(_token == _SC(',')) Lex();
                                else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));
                        }
@@ -1130,18 +1138,19 @@ public:
                }
                
                SQFuncState *currchunk = _fs;
-               _fs = &funcstate;
+               _fs = funcstate;
                Statement();
-               funcstate.AddLineInfos(_lex._prevtoken == _SC('\n')?_lex._lasttokenline:_lex._currentline, _lineinfo, true);
-        funcstate.AddInstruction(_OP_RETURN, -1);
-               funcstate.SetStackSize(0);
+               funcstate->AddLineInfos(_lex._prevtoken == _SC('\n')?_lex._lasttokenline:_lex._currentline, _lineinfo, true);
+        funcstate->AddInstruction(_OP_RETURN, -1);
+               funcstate->SetStackSize(0);
                _funcproto(_fs->_func)->_stacksize = _fs->_stacksize;
-               funcstate.Finalize();
+               funcstate->Finalize();
 #ifdef _DEBUG_DUMP
-               funcstate.Dump();
+               funcstate->Dump();
 #endif
                _fs = currchunk;
-               _fs->_functions.push_back(funcstate._func);
+               _fs->_functions.push_back(funcstate->_func);
+               _fs->PopChildState();
        }
        void CleanStack(int stacksize)
        {
@@ -1178,6 +1187,8 @@ private:
        int _debugline;
        int _debugop;
        ExpStateVec _expstates;
+       SQChar *compilererror;
+       jmp_buf _errorjmp;
        SQVM *_vm;
 };
 
index b3658be..595d9c4 100644 (file)
@@ -69,6 +69,6 @@ struct SQVM;
 #define TK_ATTR_CLOSE 321
 
 
-struct ParserException{ SQChar *desc; ParserException(SQChar *err):desc(err) {} };
+typedef void(*CompilerErrorFunc)(void *ud, const SQChar *s);
 bool Compile(SQVM *vm, SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo);
 #endif //_SQCOMPILER_H_
index d4eecc7..88daf9e 100644 (file)
@@ -31,8 +31,6 @@ SQRESULT sq_stackinfos(HSQUIRRELVM v, int level, SQStackInfos *si)
                                si->funcname = _stringval(_nativeclosure(ci._closure)->_name);
                        si->line = -1;
                        break;
-               default:
-                       break;
                }
                return SQ_OK;
        }
index d9b3585..9823fd3 100644 (file)
@@ -76,14 +76,14 @@ void DumpLiteral(SQObjectPtr &o)
                case OT_STRING: scprintf(_SC("\"%s\""),_stringval(o));break;
                case OT_FLOAT: scprintf(_SC("{%f}"),_float(o));break;
                case OT_INTEGER: scprintf(_SC("{%d}"),_integer(o));break;
-               default: break;
        }
 }
 
-SQFuncState::SQFuncState(SQSharedState *ss,SQFunctionProto *func,SQFuncState *parent)
+SQFuncState::SQFuncState(SQSharedState *ss,SQFunctionProto *func,SQFuncState *parent,CompilerErrorFunc efunc,void *ed)
 {
                _nliterals = 0;
                _literals = SQTable::Create(ss,0);
+               _strings =  SQTable::Create(ss,0);
                _sharedstate = ss;
                _lastline = 0;
                _optimization = true;
@@ -93,6 +93,14 @@ SQFuncState::SQFuncState(SQSharedState *ss,SQFunctionProto *func,SQFuncState *pa
                _traps = 0;
                _returnexp = 0;
                _varparams = false;
+               _errfunc = efunc;
+               _errtarget = ed;
+
+}
+
+void SQFuncState::Error(const SQChar *err)
+{
+       _errfunc(_errtarget,err);
 }
 
 #ifdef _DEBUG_DUMP
@@ -173,31 +181,34 @@ void SQFuncState::Dump()
        scprintf(_SC("--------------------------------------------------------------------\n\n"));
 }
 #endif
-int SQFuncState::GetStringConstant(const SQChar *cons)
+/*int SQFuncState::GetStringConstant(SQObjectPtr &cons)
 {
-       return GetConstant(SQString::Create(_sharedstate,cons));
-}
+       return GetConstant(cons);
+}*/
 
 int SQFuncState::GetNumericConstant(const SQInteger cons)
 {
-       return GetConstant(cons);
+       return GetConstant(SQObjectPtr(cons));
 }
 
 int SQFuncState::GetNumericConstant(const SQFloat cons)
 {
-       return GetConstant(cons);
+       return GetConstant(SQObjectPtr(cons));
 }
 
-int SQFuncState::GetConstant(SQObjectPtr cons)
+int SQFuncState::GetConstant(const SQObject &cons)
 {
-       // int n=0;
+       int n=0;
        SQObjectPtr val;
        if(!_table(_literals)->Get(cons,val))
        {
                val = _nliterals;
                _table(_literals)->NewSlot(cons,val);
                _nliterals++;
-               if(_nliterals > MAX_LITERALS) throw ParserException(_SC("internal compiler error: too many literals"));
+               if(_nliterals > MAX_LITERALS) {
+                       val.Null();
+                       Error(_SC("internal compiler error: too many literals"));
+               }
        }
        return _integer(val);
 }
@@ -226,7 +237,7 @@ int SQFuncState::AllocStackPos()
        int npos=_vlocals.size();
        _vlocals.push_back(SQLocalVarInfo());
        if(_vlocals.size()>((unsigned int)_stacksize)) {
-               if(_stacksize>MAX_FUNC_STACKSIZE) throw ParserException(_SC("internal compiler error: too many locals"));
+               if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC("internal compiler error: too many locals"));
                _stacksize=_vlocals.size();
        }
        return npos;
@@ -287,7 +298,7 @@ bool SQFuncState::IsLocal(unsigned int stkpos)
        return false;
 }
 
-int SQFuncState::PushLocalVariable(const SQObjectPtr &name)
+int SQFuncState::PushLocalVariable(const SQObject &name)
 {
        int pos=_vlocals.size();
        SQLocalVarInfo lvi;
@@ -300,7 +311,7 @@ int SQFuncState::PushLocalVariable(const SQObjectPtr &name)
        return pos;
 }
 
-int SQFuncState::GetLocalVariable(const SQObjectPtr &name)
+int SQFuncState::GetLocalVariable(const SQObject &name)
 {
        int locals=_vlocals.size();
        while(locals>=1){
@@ -312,7 +323,7 @@ int SQFuncState::GetLocalVariable(const SQObjectPtr &name)
        return -1;
 }
 
-int SQFuncState::GetOuterVariable(const SQObjectPtr &name)
+int SQFuncState::GetOuterVariable(const SQObject &name)
 {
        int outers = _outervalues.size();
        for(int i = 0; i<outers; i++) {
@@ -322,7 +333,7 @@ int SQFuncState::GetOuterVariable(const SQObjectPtr &name)
        return -1;
 }
 
-void SQFuncState::AddOuterValue(const SQObjectPtr &name)
+void SQFuncState::AddOuterValue(const SQObject &name)
 {
        //AddParameter(name);
        int pos=-1;
@@ -343,7 +354,7 @@ void SQFuncState::AddOuterValue(const SQObjectPtr &name)
        _outervalues.push_back(SQOuterVar(name,name,otSYMBOL)); //global
 }
 
-void SQFuncState::AddParameter(const SQObjectPtr &name)
+void SQFuncState::AddParameter(const SQObject &name)
 {
        PushLocalVariable(name);
        _parameters.push_back(name);
@@ -450,10 +461,10 @@ void SQFuncState::AddInstruction(SQInstruction &i)
        _instructions.push_back(i);
 }
 
-SQObject SQFuncState::CreateString(const SQChar *s)
+SQObject SQFuncState::CreateString(const SQChar *s,int len)
 {
-       SQObjectPtr ns(SQString::Create(_sharedstate,s));
-       _stringrefs.push_back(ns);
+       SQObjectPtr ns(SQString::Create(_sharedstate,s,len));
+       _table(_strings)->NewSlot(ns,1);
        return ns;
 }
 
@@ -481,3 +492,26 @@ void SQFuncState::Finalize()
        f->_lineinfos.copy(_lineinfos);
        f->_varparams = _varparams;
 }
+
+SQFuncState *SQFuncState::PushChildState(SQSharedState *ss,SQFunctionProto *func)
+{
+       SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState));
+       new (child) SQFuncState(ss,func,this,_errfunc,_errtarget);
+       _childstates.push_back(child);
+       return child;
+}
+
+void SQFuncState::PopChildState()
+{
+       SQFuncState *child = _childstates.back();
+       sq_delete(child,SQFuncState);
+       _childstates.pop_back();
+}
+
+SQFuncState::~SQFuncState()
+{
+       while(_childstates.size() > 0)
+       {
+               PopChildState();
+       }
+}
index 6839e19..4324eaa 100644 (file)
@@ -4,14 +4,16 @@
 ///////////////////////////////////
 #include "squtils.h"
 
-
-
 struct SQFuncState
 {
-       SQFuncState(SQSharedState *ss,SQFunctionProto *func,SQFuncState *parent);
+       SQFuncState(SQSharedState *ss,SQFunctionProto *func,SQFuncState *parent,CompilerErrorFunc efunc,void *ed);
+       ~SQFuncState();
 #ifdef _DEBUG_DUMP
        void Dump();
 #endif
+       void Error(const SQChar *err);
+       SQFuncState *PushChildState(SQSharedState *ss,SQFunctionProto *func);
+       void PopChildState();
        void AddInstruction(SQOpcode _op,int arg0=0,int arg1=0,int arg2=0,int arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);AddInstruction(i);}
        void AddInstruction(SQInstruction &i);
        void SetIntructionParams(int pos,int arg0,int arg1,int arg2=0,int arg3=0);
@@ -21,14 +23,14 @@ struct SQFuncState
        void SetStackSize(int n);
        void SnoozeOpt(){_optimization=false;}
        int GetCurrentPos(){return _instructions.size()-1;}
-       int GetStringConstant(const SQChar *cons);
+       //int GetStringConstant(const SQChar *cons);
        int GetNumericConstant(const SQInteger cons);
        int GetNumericConstant(const SQFloat cons);
-       int PushLocalVariable(const SQObjectPtr &name);
-       void AddParameter(const SQObjectPtr &name);
-       void AddOuterValue(const SQObjectPtr &name);
-       int GetLocalVariable(const SQObjectPtr &name);
-       int GetOuterVariable(const SQObjectPtr &name);
+       int PushLocalVariable(const SQObject &name);
+       void AddParameter(const SQObject &name);
+       void AddOuterValue(const SQObject &name);
+       int GetLocalVariable(const SQObject &name);
+       int GetOuterVariable(const SQObject &name);
        int GenerateCode();
        int GetStackSize();
        int CalcStackFrameSize();
@@ -40,7 +42,7 @@ struct SQFuncState
        int TopTarget();
        int GetUpTarget(int n);
        bool IsLocal(unsigned int stkpos);
-       SQObject CreateString(const SQChar *s);
+       SQObject CreateString(const SQChar *s,int len = -1);
        int _returnexp;
        SQLocalVarInfoVec _vlocals;
        SQIntVec _targetstack;
@@ -50,11 +52,11 @@ struct SQFuncState
        SQIntVec _unresolvedcontinues;
        SQObjectPtrVec _functions;
        SQObjectPtrVec _parameters;
-       SQObjectPtrVec _stringrefs;
        SQOuterVarVec _outervalues;
        SQInstructionVec _instructions;
        SQLocalVarInfoVec _localvarinfos;
        SQObjectPtr _literals;
+       SQObjectPtr _strings;
        SQInteger _nliterals;
        SQLineInfoVec _lineinfos;
        SQObjectPtr _func;
@@ -65,8 +67,11 @@ struct SQFuncState
        int _traps;
        bool _optimization;
        SQSharedState *_sharedstate;
+       sqvector<SQFuncState*> _childstates;
+       int GetConstant(const SQObject &cons);
 private:
-       int GetConstant(SQObjectPtr cons);
+       CompilerErrorFunc _errfunc;
+       void *_errtarget;
 };
 
 
index c9cac24..a0a53f1 100644 (file)
@@ -24,8 +24,10 @@ SQLexer::~SQLexer()
        _keywords->Release();
 }
 
-void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up)
+void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed)
 {
+       _errfunc = efunc;
+       _errtarget = ed;
        _sharedstate = ss;
        _keywords = SQTable::Create(ss, 26);
        ADD_KEYWORD(while, TK_WHILE);
@@ -72,10 +74,15 @@ void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up)
        Next();
 }
 
+void SQLexer::Error(const SQChar *err)
+{
+       _errfunc(_errtarget,err);
+}
+
 void SQLexer::Next()
 {
        SQInteger t = _readf(_up);
-       if(t > MAX_CHAR) throw ParserException(_SC("Invalid character"));
+       if(t > MAX_CHAR) Error(_SC("Invalid character"));
        if(t != 0) {
                _currdata = t;
                return;
@@ -83,16 +90,16 @@ void SQLexer::Next()
        _currdata = SQUIRREL_EOB;
 }
 
-SQObjectPtr SQLexer::Tok2Str(int tok)
+const SQChar *SQLexer::Tok2Str(int tok)
 {
        SQObjectPtr itr, key, val;
        int nitr;
        while((nitr = _keywords->Next(itr, key, val)) != -1) {
                itr = (SQInteger)nitr;
                if(((int)_integer(val)) == tok)
-                       return key;
+                       return _stringval(key);
        }
-       return SQObjectPtr();
+       return NULL;
 }
 
 void SQLexer::LexBlockComment()
@@ -103,7 +110,7 @@ void SQLexer::LexBlockComment()
                        case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue;
                        //case _SC('/'): { NEXT(); if(CUR_CHAR == _SC('*')) { nest++; NEXT(); }}; continue;
                        case _SC('\n'): _currentline++; NEXT(); continue;
-                       case SQUIRREL_EOB: throw ParserException(_SC("missing \"*/\" in comment"));
+                       case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment"));
                        default: NEXT();
                }
        }
@@ -175,11 +182,11 @@ int SQLexer::Lex()
                        int stype;
                        NEXT(); 
                        if(CUR_CHAR != _SC('"'))
-                               throw ParserException(_SC("string expected"));
+                               Error(_SC("string expected"));
                        if((stype=ReadString('"',true))!=-1) {
                                RETURN_TOKEN(stype);
                        }
-                       throw ParserException(_SC("error parsing the string"));
+                       Error(_SC("error parsing the string"));
                                           }
                case _SC('"'):
                case _SC('\''): {
@@ -187,7 +194,7 @@ int SQLexer::Lex()
                        if((stype=ReadString(CUR_CHAR,false))!=-1){
                                RETURN_TOKEN(stype);
                        }
-                       throw ParserException(_SC("error parsing the string"));
+                       Error(_SC("error parsing the string"));
                        }
                case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'):
                case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'):
@@ -197,7 +204,7 @@ int SQLexer::Lex()
                        NEXT();
                        if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') }
                        NEXT();
-                       if (CUR_CHAR != _SC('.')){ throw ParserException(_SC("invalid token '..'")); }
+                       if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); }
                        NEXT();
                        RETURN_TOKEN(TK_VARPARAMS);
                case _SC('&'):
@@ -243,7 +250,7 @@ int SQLexer::Lex()
                                }
                                else {
                                        int c = CUR_CHAR;
-                                       if (sciscntrl(c)) throw ParserException(_SC("unexpected character(control)"));
+                                       if (sciscntrl(c)) Error(_SC("unexpected character(control)"));
                                        NEXT();
                                        RETURN_TOKEN(c);  
                                }
@@ -273,10 +280,10 @@ int SQLexer::ReadString(int ndelim,bool verbatim)
                while(CUR_CHAR != ndelim) {
                        switch(CUR_CHAR) {
                        case SQUIRREL_EOB:
-                               throw ParserException(_SC("unfinished string"));
+                               Error(_SC("unfinished string"));
                                return -1;
                        case _SC('\n'): 
-                               if(!verbatim) throw ParserException(_SC("newline in a constant")); 
+                               if(!verbatim) Error(_SC("newline in a constant")); 
                                APPEND_CHAR(CUR_CHAR); NEXT(); 
                                break;
                        case _SC('\\'):
@@ -284,9 +291,23 @@ int SQLexer::ReadString(int ndelim,bool verbatim)
                                        APPEND_CHAR('\\'); NEXT(); 
                                }
                                else {
-
                                        NEXT();
                                        switch(CUR_CHAR) {
+                                       case _SC('x'): NEXT(); {
+                                               if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected")); 
+                                               const int maxdigits = 4;
+                                               SQChar temp[maxdigits+1];
+                                               int n = 0;
+                                               while(isxdigit(CUR_CHAR) && n < maxdigits) {
+                                                       temp[n] = CUR_CHAR;
+                                                       n++;
+                                                       NEXT();
+                                               }
+                                               temp[n] = 0;
+                                               SQChar *sTemp;
+                                               APPEND_CHAR((SQChar)scstrtoul(temp,&sTemp,16));
+                                       }
+                                   break;
                                        case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break;
                                        case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break;
                                        case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break;
@@ -299,7 +320,7 @@ int SQLexer::ReadString(int ndelim,bool verbatim)
                                        case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break;
                                        case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break;
                                        default:
-                                               throw ParserException(_SC("unrecognised escaper char"));
+                                               Error(_SC("unrecognised escaper char"));
                                        break;
                                        }
                                }
@@ -321,8 +342,8 @@ int SQLexer::ReadString(int ndelim,bool verbatim)
        TERMINATE_BUFFER();
        int len = _longstr.size()-1;
        if(ndelim == _SC('\'')) {
-               if(len == 0) throw ParserException(_SC("empty constant"));
-               if(len > 1) throw ParserException(_SC("constant too long"));
+               if(len == 0) Error(_SC("empty constant"));
+               if(len > 1) Error(_SC("constant too long"));
                _nvalue = _longstr[0];
                return TK_INTEGER;
        }
@@ -339,7 +360,7 @@ int SQLexer::ReadNumber()
 #define THEX 3
 #define TSCIENTIFIC 4
        int type = TINT, firstchar = CUR_CHAR;
-       //bool isfloat = false;
+       bool isfloat = false;
        SQChar *sTemp;
        INIT_TEMP_STRING();
        NEXT();
@@ -350,14 +371,14 @@ int SQLexer::ReadNumber()
                        APPEND_CHAR(CUR_CHAR);
                        NEXT();
                }
-               if(_longstr.size() > 8) throw ParserException(_SC("Hex number over 8 digits"));
+               if(_longstr.size() > 8) Error(_SC("Hex number over 8 digits"));
        }
        else {
                APPEND_CHAR(firstchar);
                while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) {
             if(CUR_CHAR == _SC('.')) type = TFLOAT;
                        if(isexponent(CUR_CHAR)) {
-                               if(type != TFLOAT) throw ParserException(_SC("invalid numeric format"));
+                               if(type != TFLOAT) Error(_SC("invalid numeric format"));
                                type = TSCIENTIFIC;
                                APPEND_CHAR(CUR_CHAR);
                                NEXT();
@@ -365,7 +386,7 @@ int SQLexer::ReadNumber()
                                        APPEND_CHAR(CUR_CHAR);
                                        NEXT();
                                }
-                               if(!scisdigit(CUR_CHAR)) throw ParserException(_SC("exponent expected"));
+                               if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected"));
                        }
                        
                        APPEND_CHAR(CUR_CHAR);
@@ -390,8 +411,7 @@ int SQLexer::ReadNumber()
 
 int SQLexer::ReadID()
 {
-       int res;
-       // int size = 0;
+       int res, size = 0;
        INIT_TEMP_STRING();
        do {
                APPEND_CHAR(CUR_CHAR);
index fdc92d4..9182420 100644 (file)
@@ -4,13 +4,16 @@
 
 #define MAX_STRING 2024
 
+
+
 struct SQLexer
 {
        SQLexer();
        ~SQLexer();
-       void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up);
+       void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed);
+       void Error(const SQChar *err);
        int Lex();
-       SQObjectPtr Tok2Str(int tok);
+       const SQChar *Tok2Str(int tok);
 private:
        int GetIDType(SQChar *s);
        int ReadString(int ndelim,bool verbatim);
@@ -37,6 +40,8 @@ public:
 #endif
        SQSharedState *_sharedstate;
        sqvector<SQChar> _longstr;
+       CompilerErrorFunc _errfunc;
+       void *_errtarget;
 };
 
 #endif
index 2a2f3f7..b955a29 100644 (file)
@@ -4,6 +4,6 @@
 #include "sqpcheader.h"
 void *sq_vm_malloc(unsigned int size){ return malloc(size); }
 
-void *sq_vm_realloc(void *p, unsigned int , unsigned int size){ return realloc(p, size); }
+void *sq_vm_realloc(void *p, unsigned int oldsize, unsigned int size){ return realloc(p, size); }
 
-void sq_vm_free(void *p, unsigned int ){       free(p); }
+void sq_vm_free(void *p, unsigned int size){   free(p); }
index 327e060..209c1e5 100644 (file)
@@ -30,8 +30,6 @@ unsigned int TranslateIndex(const SQObjectPtr &idx)
                        return 0;
                case OT_INTEGER:
                        return (unsigned int)_integer(idx);
-               default:
-                       break;
        }
        assert(0);
        return 0;
index 3e83d96..9f5823d 100644 (file)
@@ -8,9 +8,6 @@
 #define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T'))
 #define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L'))
 
-#define SQ_TRY try
-#define SQ_CATCH(type, ex) catch(type &ex)
-
 struct SQSharedState;
 
 enum SQMetaMethod{
@@ -52,8 +49,6 @@ enum SQMetaMethod{
 
 struct SQRefCounted
 {
-       virtual ~SQRefCounted()
-       {}
        unsigned int _uiRef;
        virtual void Release()=0;
 };
@@ -231,13 +226,13 @@ struct SQObjectPtr : public SQObject
        {
                __Release(_type,_unVal);
        }
-       void Null()
+       inline void Null()
        {
                __Release(_type,_unVal);
                _type=OT_NULL;
                _unVal.pUserPointer=NULL;
        }
-       SQObjectPtr& operator=(const SQObjectPtr& obj)
+       inline SQObjectPtr& operator=(const SQObjectPtr& obj)
        { 
                SQObjectType tOldType;
                SQObjectValue unOldVal;
@@ -249,7 +244,7 @@ struct SQObjectPtr : public SQObject
                __Release(tOldType,unOldVal);
                return *this;
        }
-       SQObjectPtr& operator=(const SQObject& obj)
+       inline SQObjectPtr& operator=(const SQObject& obj)
        { 
                SQObjectType tOldType;
                SQObjectValue unOldVal;
index db4930c..dbb7d0c 100644 (file)
@@ -2,10 +2,8 @@
 #ifndef _SQOPCODES_H_
 #define _SQOPCODES_H_
 
-#include <limits.h>
-
 #define MAX_FUNC_STACKSIZE 0xFF
-#define MAX_LITERALS INT_MAX
+#define MAX_LITERALS 0xFFFFFFFF
 
 enum BitWiseOP {
        BW_AND = 0,
index 038f28a..db8e5b2 100644 (file)
@@ -42,6 +42,7 @@ bool CompileTypemask(SQIntVec &res,const SQChar *typemask)
        while(typemask[i] != 0) {
                
                switch(typemask[i]){
+                               case 'o': mask |= _RT_NULL; break;
                                case 'i': mask |= _RT_INTEGER; break;
                                case 'f': mask |= _RT_FLOAT; break;
                                case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break;
@@ -229,14 +230,12 @@ void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain)
        case OT_THREAD:_thread(o)->Mark(chain);break;
        case OT_CLASS:_class(o)->Mark(chain);break;
        case OT_INSTANCE:_instance(o)->Mark(chain);break;
-       default: break;
        }
 }
 
 
 int SQSharedState::CollectGarbage(SQVM *vm)
 {
-       (void) vm;
        int n=0;
        SQCollectable *tchain=NULL;
        SQVM *vms=_thread(_root_vm);
index 099cfb7..820639c 100644 (file)
@@ -58,14 +58,14 @@ public:
                        default:                        return hashptr(key._unVal.pRefCounted);
                }
        }
-       _HashNode *_Get(const SQObjectPtr &key,unsigned long hash)
+       inline _HashNode *_Get(const SQObjectPtr &key,unsigned long hash)
        {
                _HashNode *n = &_nodes[hash];
                do{
                        if(_rawval(n->key) == _rawval(key) && type(n->key) == type(key)){
                                return n;
                        }
-               }while( (n = n->next) );
+               }while(n = n->next);
                return NULL;
        }
        bool Get(const SQObjectPtr &key,SQObjectPtr &val);
index 093deb0..71938fa 100644 (file)
@@ -60,11 +60,11 @@ public:
        T& top() const { return _vals[_size - 1]; }
        inline unsigned int size() const { return _size; }
        bool empty() const { return (_size <= 0); }
-       inline void push_back(const T& val = T())
+       inline T &push_back(const T& val = T())
        {
                if(_allocated <= _size)
                        _realloc(_size * 2);
-               new ((void *)&_vals[_size++]) T(val);
+               return *(new ((void *)&_vals[_size++]) T(val));
        }
        inline void pop_back()
        {
@@ -88,7 +88,7 @@ public:
        }
        unsigned int capacity() { return _allocated; }
        inline T &back() const { return _vals[_size - 1]; }
-       T& operator[](unsigned int pos) const{ return _vals[pos]; }
+       inline T& operator[](unsigned int pos) const{ return _vals[pos]; }
        T* _vals;
 private:
        void _realloc(unsigned int newsize)
index 8ee23c9..725cad0 100644 (file)
@@ -4,7 +4,6 @@
 #include "sqpcheader.h"
 #include <math.h>
 #include <stdlib.h>
-#include <assert.h>
 #include "sqopcodes.h"
 #include "sqfuncproto.h"
 #include "sqvm.h"
@@ -76,9 +75,9 @@ SQObjectPtr &stack_get(HSQUIRRELVM v,int idx){return ((idx>=0)?(v->GetAt(idx+v->
 SQVM::SQVM(SQSharedState *ss)
 {
        _sharedstate=ss;
-       _suspended=false;
+       _suspended = SQFalse;
        _suspended_target=-1;
-       _suspended_root=false;
+       _suspended_root = SQFalse;
        _suspended_traps=-1;
        _foreignptr=NULL;
        _nnativecalls=0;
@@ -116,7 +115,6 @@ bool SQVM::ArithMetaMethod(int op,const SQObjectPtr &o1,const SQObjectPtr &o2,SQ
                case _SC('/'): mm=MT_DIV; break;
                case _SC('*'): mm=MT_MUL; break;
                case _SC('%'): mm=MT_MODULO; break;
-                default: mm=MT_ADD; assert(0); break;
        }
        if(is_delegable(o1) && _delegable(o1)->_delegate) {
                Push(o1);Push(o2);
@@ -146,8 +144,7 @@ bool SQVM::NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o)
                        }
                }
                return true;
-       default:
-               break;
+
        }
        Raise_Error(_SC("attempt to negate a %s"), GetTypeName(o));
        return false;
@@ -172,8 +169,6 @@ bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,int &result)
                        Push(o1);Push(o2);
                        if(_delegable(o1)->_delegate)CallMetaMethod(_delegable(o1),MT_CMP,2,res);
                        break;
-               default:
-                       break;
                }
                if(type(res)!=OT_INTEGER) { Raise_CompareError(o1,o2); return false; }
                _RET_SUCCEED(_integer(res));
@@ -323,7 +318,7 @@ bool SQVM::StartCall(SQClosure *closure,int target,int nargs,int stackbase,bool
        //const int outerssize = func->_outervalues.size();
 
        const int paramssize = func->_parameters.size();
-       // const int oldtop = _top;
+       const int oldtop = _top;
        const int newtop = stackbase + func->_stacksize;
        
        
@@ -353,7 +348,7 @@ bool SQVM::StartCall(SQClosure *closure,int target,int nargs,int stackbase,bool
                ci->_target = target;
                ci->_prevtop = _top - _stackbase;
                ci->_ncalls = 1;
-               ci->_root = false;
+               ci->_root = SQFalse;
        }
        else {
                ci->_ncalls++;
@@ -381,13 +376,13 @@ bool SQVM::Return(int _arg0, int _arg1, SQObjectPtr &retval)
                for(int i=0;i<ci->_ncalls;i++)
                        CallDebugHook(_SC('r'));
                                                
-       bool broot = ci->_root;
+       SQBool broot = ci->_root;
        int last_top = _top;
        int target = ci->_target;
        int oldstackbase = _stackbase;
        _stackbase -= ci->_prevstkbase;
        _top = _stackbase + ci->_prevtop;
-       PopVarArgs(ci->_vargs);
+       if(ci->_vargs.size) PopVarArgs(ci->_vargs);
        POP_CALLINFO(this);
        if (broot) {
                if (_arg0 != MAX_FUNC_STACKSIZE) retval = _stack[oldstackbase+_arg1];
@@ -402,7 +397,7 @@ bool SQVM::Return(int _arg0, int _arg1, SQObjectPtr &retval)
 
        while (last_top >= _top) _stack[last_top--].Null();
        assert(oldstackbase >= _stackbase); 
-       return broot;
+       return broot?true:false;
 }
 
 #define _RET_ON_FAIL(exp) { if(!exp) return false; }
@@ -504,8 +499,6 @@ bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr
                        _generator(o1)->Resume(this, arg_2+1);
                        _FINISH(false);
                }
-       default:
-               break;
        }
        Raise_Error(_SC("cannot iterate %s"), GetTypeName(o1));
        return false; //cannot be hit(just to avoid warnings)
@@ -542,7 +535,7 @@ bool SQVM::CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func)
 {
        int nouters;
        SQClosure *closure = SQClosure::Create(_ss(this), func);
-       if( (nouters = func->_outervalues.size()) ) {
+       if(nouters = func->_outervalues.size()) {
                closure->_outervalues.reserve(nouters);
                for(int i = 0; i<nouters; i++) {
                        SQOuterVar &v = func->_outervalues[i];
@@ -644,18 +637,18 @@ bool SQVM::Execute(SQObjectPtr &closure, int target, int nargs, int stackbase,SQ
                                if(ci == NULL) CallErrorHandler(_lasterror);
                                return false;
                        }
-                       ci->_root = true;
+                       ci->_root = SQTrue;
                        break;
-               case ET_RESUME_GENERATOR: _generator(closure)->Resume(this, target); ci->_root = true; traps += ci->_etraps; break;
+               case ET_RESUME_GENERATOR: _generator(closure)->Resume(this, target); ci->_root = SQTrue; traps += ci->_etraps; break;
                case ET_RESUME_VM:
                        traps = _suspended_traps;
                        ci->_root = _suspended_root;
-                       _suspended = false;
+                       _suspended = SQFalse;
                        break;
        }
        
 exception_restore:
-       //SQ_TRY 
+       //
        {
                for(;;)
                {
@@ -673,7 +666,7 @@ exception_restore:
                                temp_reg = STK(arg1);
                                if (type(temp_reg) == OT_CLOSURE){ 
                                        ct_tailcall = true;
-                                       PopVarArgs(ci->_vargs);
+                                       if(ci->_vargs.size) PopVarArgs(ci->_vargs);
                                        for (int i = 0; i < arg3; i++) STK(i) = STK(arg2 + i);
                                        ct_target = ci->_target;
                                        goto common_call;
@@ -686,7 +679,7 @@ common_call:
                                        int last_top = _top;
                                        switch (type(temp_reg)) {
                                        case OT_CLOSURE:{
-                                               StartCall(_closure(temp_reg), ct_target, arg3, ct_tailcall?_stackbase:_stackbase+arg2, ct_tailcall);
+                                               _GUARD(StartCall(_closure(temp_reg), ct_target, arg3, ct_tailcall?_stackbase:_stackbase+arg2, ct_tailcall));
                                                if (_funcproto(_closure(temp_reg)->_function)->_bgenerator) {
                                                        SQGenerator *gen = SQGenerator::Create(_ss(this), _closure(temp_reg));
                                                        _GUARD(gen->Yield(this));
@@ -703,7 +696,7 @@ common_call:
                                                bool suspend;
                                                _GUARD(CallNative(_nativeclosure(temp_reg), arg3, _stackbase+arg2, ct_tailcall, temp_reg,suspend));
                                                if(suspend){
-                                                       _suspended = true;
+                                                       _suspended = SQTrue;
                                                        _suspended_target = ct_target;
                                                        _suspended_root = ci->_root;
                                                        _suspended_traps = traps;
@@ -822,8 +815,6 @@ common_prepcall:
                                        continue;
                                case OT_CLASS: TARGET = _class(STK(arg1))->_base?_class(STK(arg1))->_base:_null_;
                                        continue;
-                               default:
-                                       break;
                                }
                                Raise_Error(_SC("the %s type doesn't have a parent slot"), GetTypeName(STK(arg1)));
                                SQ_THROW();
@@ -952,7 +943,7 @@ exception_trap:
                        CallErrorHandler(currerror);
                        //remove call stack until a C function is found or the cstack is empty
                        if(ci) do{
-                               bool exitafterthisone = ci->_root;
+                               SQBool exitafterthisone = ci->_root;
                                if(type(ci->_generator) == OT_GENERATOR) _generator(ci->_generator)->Kill();
                                _stackbase -= ci->_prevstkbase;
                                _top = _stackbase + ci->_prevtop;
@@ -1004,7 +995,6 @@ void SQVM::CallDebugHook(int type,int forcedline)
 
 bool SQVM::CallNative(SQNativeClosure *nclosure,int nargs,int stackbase,bool tailcall,SQObjectPtr &retval,bool &suspend)
 {
-       (void) tailcall;
        if (_nnativecalls + 1 > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; }
        int nparamscheck = nclosure->_nparamscheck;
        if(((nparamscheck > 0) && (nparamscheck != nargs))
@@ -1014,7 +1004,7 @@ bool SQVM::CallNative(SQNativeClosure *nclosure,int nargs,int stackbase,bool tai
                }
 
        int tcs;
-       if( (tcs = nclosure->_typecheck.size()) ) {
+       if(tcs = nclosure->_typecheck.size()) {
                for(int i = 0; i < nargs && i < tcs; i++)
                        if((nclosure->_typecheck[i] != -1) && !(type(_stack[stackbase+i]) & nclosure->_typecheck[i])) {
                 Raise_ParamTypeError(i,nclosure->_typecheck[i],type(_stack[stackbase+i]));
@@ -1075,8 +1065,6 @@ bool SQVM::Get(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,
        case OT_INSTANCE:
                if(_instance(self)->Get(key,dest)) return true;
                break;
-       default:
-               break;
        }
        if(FallBackGet(self,key,dest,raw)) return true;
 
@@ -1337,15 +1325,6 @@ bool SQVM::CallMetaMethod(SQDelegable *del,SQMetaMethod mm,int nparams,SQObjectP
        return false;
 }
 
-void SQVM::Pop() {
-       _stack[--_top] = _null_;
-}
-void SQVM::Pop(int n) {
-       for(int i = 0; i < n; i++){
-               _stack[--_top] = _null_;
-       }
-}
-
 void SQVM::Remove(int n) {
        n = (n >= 0)?n + _stackbase - 1:_top + n;
        for(int i = n; i < _top; i++){
@@ -1355,11 +1334,6 @@ void SQVM::Remove(int n) {
        _top--;
 }
 
-void SQVM::Push(const SQObjectPtr &o) { _stack[_top++] = o; }
-SQObjectPtr &SQVM::Top() { return _stack[_top-1]; }
-SQObjectPtr &SQVM::PopGet() { return _stack[--_top]; }
-SQObjectPtr &SQVM::GetUp(int n) { return _stack[_top+n]; }
-SQObjectPtr &SQVM::GetAt(int n) { return _stack[n]; }
 
 #ifdef _DEBUG_DUMP
 void SQVM::dumpstack(int stackbase,bool dumpall)
index ffcdb6e..d46f2a2 100644 (file)
@@ -48,7 +48,7 @@ struct SQVM : public CHAINABLE_OBJ
                int _target;
                SQInstruction *_ip;
                int _ncalls;
-               bool _root;
+               SQBool _root;
                VarArgs _vargs;
        };
 
@@ -92,22 +92,21 @@ public:
        void TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest);
        bool CallMetaMethod(SQDelegable *del, SQMetaMethod mm, int nparams, SQObjectPtr &outres);
        bool ArithMetaMethod(int op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);
-       //void Modulo(const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);
        bool Return(int _arg0, int _arg1, SQObjectPtr &retval);
        //new stuff
-       bool ARITH_OP(unsigned int op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
-       bool BW_OP(unsigned int op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
-       bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1);
-       bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res);
+       inline bool ARITH_OP(unsigned int op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
+       inline bool BW_OP(unsigned int op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
+       inline bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1);
+       inline bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res);
        bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func);
        bool GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &idx,CallInfo *ci);
        bool CLASS_OP(SQObjectPtr &target,int base,int attrs);
        //return true if the loop is finished
        bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,int arg_2,bool &finished);
        bool DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2);
-       bool LOCAL_INC(int op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
-       bool PLOCAL_INC(int op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
-       bool DerefInc(int op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix);
+       inline bool LOCAL_INC(int op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
+       inline bool PLOCAL_INC(int op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
+       inline bool DerefInc(int op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix);
        void PopVarArgs(VarArgs &vargs);
 #ifdef _DEBUG_DUMP
        void dumpstack(int stackbase=-1, bool dumpall = false);
@@ -121,15 +120,23 @@ public:
        void Release(){ sq_delete(this,SQVM); } //does nothing
 ////////////////////////////////////////////////////////////////////////////
        //stack functions for the api
-       void Pop();
-       void Pop(int n);
        void Remove(int n);
 
-       void Push(const SQObjectPtr &o);
-       SQObjectPtr &Top();
-       SQObjectPtr &PopGet();
-       SQObjectPtr &GetUp(int n);
-       SQObjectPtr &GetAt(int n);
+       inline void Pop() {
+               _stack[--_top] = _null_;
+       }
+
+       inline void Pop(int n) {
+               for(int i = 0; i < n; i++){
+                       _stack[--_top] = _null_;
+               }
+       }
+
+       inline void Push(const SQObjectPtr &o) { _stack[_top++] = o; }
+       inline SQObjectPtr &Top() { return _stack[_top-1]; }
+       inline SQObjectPtr &PopGet() { return _stack[--_top]; }
+       inline SQObjectPtr &GetUp(int n) { return _stack[_top+n]; }
+       inline SQObjectPtr &GetAt(int n) { return _stack[n]; }
 
        SQObjectPtrVec _stack;
        SQObjectPtrVec _vargsstack;
@@ -150,8 +157,8 @@ public:
        SQSharedState *_sharedstate;
        int _nnativecalls;
        //suspend infos
-       bool _suspended;
-       bool _suspended_root;
+       SQBool _suspended;
+       SQBool _suspended_root;
        int _suspended_target;
        int _suspended_traps;
 };
@@ -175,8 +182,7 @@ const SQChar *IdType2Name(SQObjectType type);
 #endif
 
 #define PUSH_CALLINFO(v,nci){ \
-       v->_callsstack.push_back(nci); \
-       v->ci = &v->_callsstack.back(); \
+       v->ci = &v->_callsstack.push_back(nci); \
 }
 
 #define POP_CALLINFO(v){ \
index 9058902..9e5c0ee 100644 (file)
@@ -713,7 +713,7 @@ WorldMap::update(float delta)
         if (special_tile->teleport_dest != Vector(-1,-1))
           {
           // TODO: an animation, camera scrolling or a fading would be a nice touch
-          sound_manager->play("warp");
+          sound_manager->play("sounds/warp.wav");
           tux->back_direction = D_NONE;
           tux->set_tile_pos(special_tile->teleport_dest);
           SDL_Delay(1000);