fix cr/lfs and remove trailing whitespaces...
authorMatthias Braun <matze@braunis.de>
Fri, 21 Jul 2006 11:45:14 +0000 (11:45 +0000)
committerMatthias Braun <matze@braunis.de>
Fri, 21 Jul 2006 11:45:14 +0000 (11:45 +0000)
SVN-Revision: 4059

377 files changed:
data/levels/bonus1/extro.txt
data/levels/world1/extro.txt
data/levels/world1/intro.txt
src/audio/dummy_sound_source.cpp
src/audio/dummy_sound_source.hpp
src/audio/openal_sound_source.hpp
src/audio/sound_file.cpp
src/audio/sound_file.hpp
src/audio/sound_manager.cpp
src/audio/sound_manager.hpp
src/audio/sound_source.hpp
src/audio/stream_sound_source.cpp
src/audio/stream_sound_source.hpp
src/badguy/angrystone.cpp
src/badguy/angrystone.hpp
src/badguy/badguy.cpp
src/badguy/badguy.hpp
src/badguy/bomb.cpp
src/badguy/bomb.hpp
src/badguy/bouncing_snowball.cpp
src/badguy/bouncing_snowball.hpp
src/badguy/dart.cpp
src/badguy/dart.hpp
src/badguy/darttrap.cpp
src/badguy/darttrap.hpp
src/badguy/dispenser.cpp
src/badguy/dispenser.hpp
src/badguy/fish.cpp
src/badguy/fish.hpp
src/badguy/flame.cpp
src/badguy/flame.hpp
src/badguy/flyingsnowball.cpp
src/badguy/flyingsnowball.hpp
src/badguy/igel.cpp
src/badguy/igel.hpp
src/badguy/jumpy.cpp
src/badguy/jumpy.hpp
src/badguy/kugelblitz.cpp
src/badguy/kugelblitz.hpp
src/badguy/mrbomb.cpp
src/badguy/mrbomb.hpp
src/badguy/mriceblock.cpp
src/badguy/mriceblock.hpp
src/badguy/mrrocket.hpp
src/badguy/mrtree.cpp
src/badguy/plant.cpp
src/badguy/plant.hpp
src/badguy/rocketexplosion.cpp
src/badguy/rocketexplosion.hpp
src/badguy/skullyhop.cpp
src/badguy/skullyhop.hpp
src/badguy/snail.cpp
src/badguy/snail.hpp
src/badguy/snowball.hpp
src/badguy/spidermite.cpp
src/badguy/spidermite.hpp
src/badguy/sspiky.cpp
src/badguy/stalactite.cpp
src/badguy/stalactite.hpp
src/badguy/stumpy.cpp
src/badguy/stumpy.hpp
src/badguy/totem.cpp
src/badguy/totem.hpp
src/badguy/walking_badguy.cpp
src/badguy/walking_badguy.hpp
src/badguy/willowisp.cpp
src/badguy/willowisp.hpp
src/badguy/yeti.cpp
src/badguy/yeti.hpp
src/badguy/yeti_stalactite.hpp
src/badguy/zeekling.cpp
src/badguy/zeekling.hpp
src/collision.cpp
src/collision.hpp
src/collision_hit.hpp
src/console.cpp
src/console.hpp
src/control/codecontroller.hpp
src/control/controller.hpp
src/control/joystickkeyboardcontroller.cpp
src/control/joystickkeyboardcontroller.hpp
src/fadeout.cpp
src/fadeout.hpp
src/file_system.cpp
src/file_system.hpp
src/flip_level_transformer.cpp
src/flip_level_transformer.hpp
src/game_object.hpp
src/game_session.cpp
src/game_session.hpp
src/gameconfig.cpp
src/gameconfig.hpp
src/gettext.hpp
src/gui/button.cpp
src/gui/button.hpp
src/gui/menu.cpp
src/gui/menu.hpp
src/gui/mousecursor.cpp
src/gui/mousecursor.hpp
src/level.cpp
src/level_transformer.cpp
src/level_transformer.hpp
src/lisp/lexer.cpp
src/lisp/lexer.hpp
src/lisp/lisp.cpp
src/lisp/lisp.hpp
src/lisp/list_iterator.hpp
src/lisp/parser.cpp
src/lisp/parser.hpp
src/lisp/writer.cpp
src/lisp/writer.hpp
src/log.cpp
src/log.hpp
src/main.cpp
src/mainloop.cpp
src/mainloop.hpp
src/math/aatriangle.hpp
src/math/rect.hpp
src/math/vector.hpp
src/moving_object.hpp
src/object/ambient_light.hpp
src/object/ambient_sound.cpp
src/object/ambient_sound.hpp
src/object/anchor_point.cpp
src/object/anchor_point.hpp
src/object/background.cpp
src/object/background.hpp
src/object/block.cpp
src/object/block.hpp
src/object/bullet.cpp
src/object/bullet.hpp
src/object/camera.cpp
src/object/camera.hpp
src/object/candle.hpp
src/object/coin.cpp
src/object/coin.hpp
src/object/display_effect.cpp
src/object/display_effect.hpp
src/object/electrifier.cpp
src/object/electrifier.hpp
src/object/firefly.cpp
src/object/firefly.hpp
src/object/fireworks.hpp
src/object/floating_image.cpp
src/object/floating_image.hpp
src/object/flower.cpp
src/object/flower.hpp
src/object/gameobjs.cpp
src/object/gameobjs.hpp
src/object/gradient.cpp
src/object/gradient.hpp
src/object/growup.cpp
src/object/growup.hpp
src/object/hurting_platform.hpp
src/object/infoblock.cpp
src/object/infoblock.hpp
src/object/invisible_block.cpp
src/object/invisible_block.hpp
src/object/level_time.cpp
src/object/level_time.hpp
src/object/light.cpp
src/object/light.hpp
src/object/moving_sprite.cpp
src/object/moving_sprite.hpp
src/object/oneup.cpp
src/object/particles.cpp
src/object/particles.hpp
src/object/particlesystem.cpp
src/object/particlesystem.hpp
src/object/particlesystem_interactive.cpp
src/object/particlesystem_interactive.hpp
src/object/path.cpp
src/object/path.hpp
src/object/path_walker.cpp
src/object/path_walker.hpp
src/object/platform.cpp
src/object/platform.hpp
src/object/player.cpp
src/object/player.hpp
src/object/portable.hpp
src/object/powerup.cpp
src/object/powerup.hpp
src/object/rainsplash.cpp
src/object/rainsplash.hpp
src/object/rock.cpp
src/object/rock.hpp
src/object/scripted_object.cpp
src/object/scripted_object.hpp
src/object/skull_tile.cpp
src/object/skull_tile.hpp
src/object/specialriser.cpp
src/object/specialriser.hpp
src/object/spotlight.cpp
src/object/spotlight.hpp
src/object/sprite_particle.cpp
src/object/sprite_particle.hpp
src/object/star.cpp
src/object/text_object.cpp
src/object/text_object.hpp
src/object/thunderstorm.cpp
src/object/thunderstorm.hpp
src/object/tilemap.cpp
src/object/tilemap.hpp
src/object/trampoline.cpp
src/object/trampoline.hpp
src/object/unstable_tile.hpp
src/object/weak_block.hpp
src/object/wind.hpp
src/object_factory.cpp
src/object_factory.hpp
src/object_remove_listener.hpp
src/physfs/physfs_sdl.cpp
src/physfs/physfs_sdl.hpp
src/physfs/physfs_stream.cpp
src/physfs/physfs_stream.hpp
src/physic.cpp
src/player_status.cpp
src/player_status.hpp
src/random_generator.cpp
src/random_generator.hpp
src/ref.hpp
src/refcounter.hpp
src/resources.cpp
src/screen.hpp
src/screen_fade.hpp
src/script_interface.hpp
src/scripting/ambient_sound.hpp
src/scripting/anchor_points.hpp
src/scripting/camera.cpp
src/scripting/camera.hpp
src/scripting/candle.cpp
src/scripting/candle.hpp
src/scripting/display_effect.hpp
src/scripting/floating_image.cpp
src/scripting/floating_image.hpp
src/scripting/functions.cpp
src/scripting/functions.hpp
src/scripting/level.hpp
src/scripting/platform.cpp
src/scripting/platform.hpp
src/scripting/player.hpp
src/scripting/scripted_object.hpp
src/scripting/serialize.cpp
src/scripting/serialize.hpp
src/scripting/squirrel_error.hpp
src/scripting/squirrel_util.cpp
src/scripting/squirrel_util.hpp
src/scripting/text.hpp
src/scripting/thread_queue.cpp
src/scripting/thread_queue.hpp
src/scripting/thunderstorm.hpp
src/scripting/time_scheduler.cpp
src/scripting/time_scheduler.hpp
src/scripting/wind.cpp
src/scripting/wind.hpp
src/scripting/wrapper.interface.hpp
src/sector.cpp
src/sector.hpp
src/serializable.hpp
src/shrinkfade.cpp
src/shrinkfade.hpp
src/spawn_point.hpp
src/sprite/sprite.cpp
src/sprite/sprite.hpp
src/sprite/sprite_data.cpp
src/sprite/sprite_data.hpp
src/sprite/sprite_manager.cpp
src/sprite/sprite_manager.hpp
src/squirrel/include/sqstdaux.h
src/squirrel/include/sqstdblob.h
src/squirrel/include/sqstdio.h
src/squirrel/include/sqstdmath.h
src/squirrel/include/sqstdstring.h
src/squirrel/include/sqstdsystem.h
src/squirrel/include/squirrel.h
src/squirrel/sqdbg/sqdbgserver.cpp
src/squirrel/sqdbg/sqdbgserver.h
src/squirrel/sqdbg/sqrdbg.cpp
src/squirrel/sqdbg/sqrdbg.h
src/squirrel/sqstdlib/sqstdaux.cpp
src/squirrel/sqstdlib/sqstdblob.cpp
src/squirrel/sqstdlib/sqstdblobimpl.h
src/squirrel/sqstdlib/sqstdio.cpp
src/squirrel/sqstdlib/sqstdmath.cpp
src/squirrel/sqstdlib/sqstdrex.cpp
src/squirrel/sqstdlib/sqstdstream.cpp
src/squirrel/sqstdlib/sqstdstream.h
src/squirrel/sqstdlib/sqstdstring.cpp
src/squirrel/sqstdlib/sqstdsystem.cpp
src/squirrel/squirrel/sqapi.cpp
src/squirrel/squirrel/sqarray.h
src/squirrel/squirrel/sqbaselib.cpp
src/squirrel/squirrel/sqclass.cpp
src/squirrel/squirrel/sqclass.h
src/squirrel/squirrel/sqclosure.h
src/squirrel/squirrel/sqcompiler.cpp
src/squirrel/squirrel/sqcompiler.h
src/squirrel/squirrel/sqdebug.cpp
src/squirrel/squirrel/sqfuncproto.h
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/sqpcheader.h
src/squirrel/squirrel/sqstate.cpp
src/squirrel/squirrel/sqstate.h
src/squirrel/squirrel/sqstring.h
src/squirrel/squirrel/sqtable.cpp
src/squirrel/squirrel/sqtable.h
src/squirrel/squirrel/squserdata.h
src/squirrel/squirrel/squtils.h
src/squirrel/squirrel/sqvm.cpp
src/squirrel/squirrel/sqvm.h
src/statistics.cpp
src/statistics.hpp
src/textscroller.cpp
src/textscroller.hpp
src/tile.cpp
src/tile.hpp
src/tile_manager.cpp
src/tile_manager.hpp
src/timer.cpp
src/timer.hpp
src/tinygettext/findlocale.cpp
src/tinygettext/tinygettext.cpp
src/tinygettext/tinygettext.hpp
src/title.cpp
src/title.hpp
src/trigger/door.cpp
src/trigger/door.hpp
src/trigger/scripttrigger.cpp
src/trigger/scripttrigger.hpp
src/trigger/secretarea_trigger.hpp
src/trigger/sequence_trigger.hpp
src/trigger/switch.cpp
src/trigger/switch.hpp
src/trigger/trigger_base.cpp
src/trigger/trigger_base.hpp
src/video/color.hpp
src/video/drawing_context.cpp
src/video/drawing_context.hpp
src/video/font.cpp
src/video/font.hpp
src/video/glutil.hpp
src/video/image_texture.hpp
src/video/surface.cpp
src/video/surface.hpp
src/video/texture.cpp
src/video/texture.hpp
src/video/texture_manager.cpp
src/video/texture_manager.hpp
src/world.cpp
src/world.hpp
src/worldmap/level.cpp
src/worldmap/level.hpp
src/worldmap/special_tile.cpp
src/worldmap/special_tile.hpp
src/worldmap/sprite_change.cpp
src/worldmap/sprite_change.hpp
src/worldmap/teleporter.cpp
src/worldmap/teleporter.hpp
src/worldmap/tux.cpp
src/worldmap/tux.hpp
src/worldmap/worldmap.cpp
src/worldmap/worldmap.hpp
tools/miniswig/create_docu.cpp
tools/miniswig/create_wrapper.cpp
tools/miniswig/create_wrapper.hpp
tools/miniswig/globals.hpp
tools/miniswig/main.cpp
tools/miniswig/tree.hpp
tools/miniswig/xmlwriter.cpp
tools/miniswig/xmlwriter.hpp

index 45b1f9c..97fa464 100644 (file)
        Abednego
        Matr1x
 
-       
+
 #If you didn't clear all levels yet,
-#find your way back home and take 
+#find your way back home and take
 #another path. There is still more
 #challenge waiting for you!
 
 #And there is a secret level to be
 #found as well...
-       
+
 #A big \"Thank you\" goes out to
 #everyone who contributed to this
 #release. We hope you enjoyed it!"))
 )
-
index b0a6a68..725af4d 100644 (file)
@@ -37,4 +37,3 @@
 #hand. No, he decided, he would not give
 #up. Penny was counting on him."))
 )
-
index 5749058..495149b 100644 (file)
@@ -24,4 +24,3 @@
 #the distance. Determined to save his
 #beloved Penny, he begins his journey."))
 )
-
index 0ca6392..1a9c274 100644 (file)
@@ -32,12 +32,12 @@ public:
   {
     is_playing = true;
   }
-  
+
   virtual void stop()
   {
     is_playing = false;
   }
-  
+
   virtual bool playing()
   {
     return is_playing;
@@ -79,4 +79,3 @@ SoundSource* create_dummy_sound_source()
 {
   return new DummySoundSource();
 }
-
index 53a3e91..458c1e8 100644 (file)
@@ -1,4 +1,4 @@
-//  $Id: sound_source.hpp 3462 2006-04-28 19:38:41Z sommer $
+//  $Id$
 //
 //  SuperTux
 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
@@ -24,4 +24,3 @@
 SoundSource* create_dummy_sound_source();
 
 #endif
-
index 75b6ef6..f70dd0f 100644 (file)
@@ -1,4 +1,4 @@
-//  $Id: sound_source.hpp 3462 2006-04-28 19:38:41Z sommer $
+//  $Id$
 //
 //  SuperTux
 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
@@ -45,9 +45,8 @@ public:
 
 protected:
   friend class SoundManager;
-  
+
   ALuint source;
 };
 
 #endif
-
index 01a4032..48c2e9e 100644 (file)
@@ -44,7 +44,7 @@ public:
 
 private:
   PHYSFS_file* file;
-  
+
   PHYSFS_sint64 datastart;
 };
 
@@ -80,7 +80,7 @@ WavSoundFile::WavSoundFile(PHYSFS_file* file)
 
   uint32_t wavelen = read32LE(file);
   (void) wavelen;
-  
+
   if(PHYSFS_read(file, magic, sizeof(magic), 1) != 1)
     throw std::runtime_error("Couldn't read chunk header (not a wav file?)");
   if(strncmp(magic, "WAVE", 4) != 0)
@@ -92,9 +92,9 @@ WavSoundFile::WavSoundFile(PHYSFS_file* file)
   // search audio data format chunk
   do {
     if(PHYSFS_read(file, chunkmagic, sizeof(chunkmagic), 1) != 1)
-      throw std::runtime_error("EOF while searching format chunk");    
+      throw std::runtime_error("EOF while searching format chunk");
     chunklen = read32LE(file);
-    
+
     if(strncmp(chunkmagic, "fmt ", 4) == 0)
       break;
 
@@ -106,11 +106,11 @@ WavSoundFile::WavSoundFile(PHYSFS_file* file)
     } else {
       throw std::runtime_error("complex WAVE files not supported");
     }
-  } while(true); 
+  } while(true);
 
   if(chunklen < 16)
     throw std::runtime_error("Format chunk too short");
+
   // parse format
   uint16_t encoding = read16LE(file);
   if(encoding != 1)
@@ -131,7 +131,7 @@ WavSoundFile::WavSoundFile(PHYSFS_file* file)
   // set file offset to DATA chunk data
   do {
     if(PHYSFS_read(file, chunkmagic, sizeof(chunkmagic), 1) != 1)
-      throw std::runtime_error("EOF while searching data chunk");    
+      throw std::runtime_error("EOF while searching data chunk");
     chunklen = read32LE(file);
 
     if(strncmp(chunkmagic, "data", 4) == 0)
@@ -165,7 +165,7 @@ WavSoundFile::read(void* buffer, size_t buffer_size)
   PHYSFS_sint64 cur = PHYSFS_tell(file);
   if(cur >= end)
     return 0;
-  
+
   size_t readsize = std::min(static_cast<size_t> (end - cur), buffer_size);
   if(PHYSFS_read(file, buffer, readsize, 1) != 1)
     throw std::runtime_error("read error while reading samples");
@@ -206,7 +206,7 @@ private:
   static int cb_seek(void* source, ogg_int64_t offset, int whence);
   static int cb_close(void* source);
   static long cb_tell(void* source);
-  
+
   PHYSFS_file* file;
   OggVorbis_File vorbis_file;
 };
@@ -238,7 +238,7 @@ OggSoundFile::read(void* _buffer, size_t buffer_size)
   size_t totalBytesRead= 0;
 
   while(buffer_size>0){
-    long bytesRead 
+    long bytesRead
       = ov_read(&vorbis_file, buffer, static_cast<int> (buffer_size),
 #ifdef WORDS_BIGENDIAN
 1,
@@ -253,7 +253,7 @@ OggSoundFile::read(void* _buffer, size_t buffer_size)
     buffer += bytesRead;
     totalBytesRead += bytesRead;
   }
-  
+
   return totalBytesRead;
 }
 
@@ -267,8 +267,8 @@ size_t
 OggSoundFile::cb_read(void* ptr, size_t size, size_t nmemb, void* source)
 {
   PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
-  
-  PHYSFS_sint64 res 
+
+  PHYSFS_sint64 res
     = PHYSFS_read(file, ptr, static_cast<PHYSFS_uint32> (size),
         static_cast<PHYSFS_uint32> (nmemb));
   if(res <= 0)
@@ -304,7 +304,7 @@ OggSoundFile::cb_seek(void* source, ogg_int64_t offset, int whence)
   }
   return 0;
 }
-  
+
 int
 OggSoundFile::cb_close(void* source)
 {
@@ -331,7 +331,7 @@ SoundFile* load_sound_file(const std::string& filename)
     msg << "Couldn't open '" << filename << "': " << PHYSFS_getLastError();
     throw std::runtime_error(msg.str());
   }
-    
+
   try {
     char magic[4];
     if(PHYSFS_read(file, magic, sizeof(magic), 1) != 1)
@@ -349,4 +349,3 @@ SoundFile* load_sound_file(const std::string& filename)
     throw std::runtime_error(msg.str());
   }
 }
-
index f10e22a..fd777b2 100644 (file)
@@ -42,4 +42,3 @@ public:
 SoundFile* load_sound_file(const std::string& filename);
 
 #endif
-
index 3976eb6..cc9dc40 100644 (file)
@@ -118,8 +118,8 @@ SoundManager::create_sound_source(const std::string& filename)
     return create_dummy_sound_source();
 
   ALuint buffer;
-  
-  // reuse an existing static sound buffer            
+
+  // reuse an existing static sound buffer
   SoundBuffers::iterator i = buffers.find(filename);
   if(i != buffers.end()) {
     buffer = i->second;
@@ -141,10 +141,10 @@ SoundManager::create_sound_source(const std::string& filename)
       return create_dummy_sound_source();
     }
   }
-  
+
   OpenALSoundSource* source = new OpenALSoundSource();
   alSourcei(source->source, AL_BUFFER, buffer);
-  return source;  
+  return source;
 }
 
 void
@@ -152,7 +152,7 @@ SoundManager::preload(const std::string& filename)
 {
   if(!sound_enabled)
     return;
-  
+
   SoundBuffers::iterator i = buffers.find(filename);
   // already loaded?
   if(i != buffers.end())
@@ -172,11 +172,11 @@ SoundManager::play(const std::string& filename, const Vector& pos)
 {
   if(!sound_enabled)
     return;
-  
+
   try {
-    std::auto_ptr<OpenALSoundSource> source 
+    std::auto_ptr<OpenALSoundSource> source
       (static_cast<OpenALSoundSource*> (create_sound_source(filename)));
-    
+
     if(pos == Vector(-1, -1)) {
       source->set_rollof_factor(0);
     } else {
@@ -193,18 +193,18 @@ void
 SoundManager::manage_source(SoundSource* source)
 {
   assert(source != NULL);
-  
+
   OpenALSoundSource* openal_source = dynamic_cast<OpenALSoundSource*> (source);
   if(openal_source != NULL) {
     sources.push_back(openal_source);
   }
 }
 
-void 
+void
 SoundManager::register_for_update( StreamSoundSource* sss ){
   if( sss != NULL ){
     update_list.push_back( sss );
-  } 
+  }
 }
 
 void
@@ -218,7 +218,7 @@ SoundManager::remove_from_update( StreamSoundSource* sss  ){
         i++;
       }
     }
-  }    
+  }
 }
 
 void
@@ -300,7 +300,7 @@ SoundManager::set_listener_position(const Vector& pos)
   Uint32 current_ticks = SDL_GetTicks();
   if(current_ticks - lastticks < 300)
     return;
-  lastticks = current_ticks;                 
+  lastticks = current_ticks;
 
   alListener3f(AL_POSITION, pos.x, pos.y, 0);
 }
@@ -325,7 +325,7 @@ SoundManager::update()
     OpenALSoundSource* source = *i;
 
     source->update();
-    
+
     if(!source->playing()) {
       delete source;
       i = sources.erase(i);
@@ -343,7 +343,7 @@ SoundManager::update()
     alcProcessContext(context);
     check_alc_error("Error while processing audio context: ");
   }
-  
+
   //run update() for stream_sound_source
   StreamSoundSources::iterator s = update_list.begin();
   while( s != update_list.end() ){
@@ -372,7 +372,7 @@ SoundManager::get_sample_format(SoundFile* file)
       throw std::runtime_error("Only 16 and 8 bit samples supported");
     }
   }
-  
+
   throw std::runtime_error("Only 1 and 2 channel samples supported");
 }
 
@@ -393,7 +393,7 @@ SoundManager::check_alc_error(const char* message)
     std::stringstream msg;
     msg << message << alcGetString(device, err);
     throw std::runtime_error(msg.str());
-  }                
+  }
 }
 
 void
@@ -404,6 +404,5 @@ SoundManager::check_al_error(const char* message)
     std::stringstream msg;
     msg << message << alGetString(err);
     throw std::runtime_error(msg.str());
-  }  
+  }
 }
-
index 153bf36..657ca06 100644 (file)
@@ -66,7 +66,7 @@ public:
   void play_music(const std::string& filename, bool fade = false);
   void stop_music(float fadetime = 0);
 
-  bool is_music_enabled() { return music_enabled; } 
+  bool is_music_enabled() { return music_enabled; }
   bool is_sound_enabled() { return sound_enabled; }
 
   bool is_audio_enabled() {
@@ -74,7 +74,7 @@ public:
   }
 
   void update();
-  
+
   /*
    * Tell soundmanager to call update() for stream_sound_source.
    */
@@ -116,4 +116,3 @@ private:
 extern SoundManager* sound_manager;
 
 #endif
-
index 3569ecd..958ef6f 100644 (file)
@@ -78,8 +78,8 @@ StreamSoundSource::update()
   if(!playing()) {
     if(processed == 0 || !looping)
       return;
-    
-    // we might have to restart the source if we had a buffer underrun  
+
+    // we might have to restart the source if we had a buffer underrun
     log_info << "Restarting audio source because of buffer underrun" << std::endl;
     play();
   }
@@ -142,4 +142,3 @@ StreamSoundSource::fillBufferAndQueue(ALuint buffer)
   // return false if there aren't more buffers to fill
   return bytesread >= STREAMFRAGMENTSIZE;
 }
-
index de1dbc0..aa621b3 100644 (file)
@@ -51,11 +51,11 @@ public:
   {
     return looping;
   }
-  
+
 private:
   static const size_t STREAMBUFFERSIZE = 1024 * 500;
   static const size_t STREAMFRAGMENTS = 5;
-  static const size_t STREAMFRAGMENTSIZE 
+  static const size_t STREAMFRAGMENTSIZE
     = STREAMBUFFERSIZE / STREAMFRAGMENTS;
 
   bool fillBufferAndQueue(ALuint buffer);
@@ -69,4 +69,3 @@ private:
 };
 
 #endif
-
index bcf6d90..865e430 100644 (file)
@@ -59,7 +59,7 @@ AngryStone::collision_solid(const CollisionHit& hit)
   // TODO
   (void) hit;
 #if 0
-  if ((state == ATTACKING) && 
+  if ((state == ATTACKING) &&
       (hit.normal.x == -attackDirection.x) && (hit.normal.y == attackDirection.y)) {
     state = IDLE;
     sprite->set_action("idle");
@@ -89,7 +89,7 @@ AngryStone::collision_badguy(BadGuy& badguy, const CollisionHit& )
   return FORCE_MOVE;
 }
 
-void 
+void
 AngryStone::active_update(float elapsed_time) {
   BadGuy::active_update(elapsed_time);
 
index 3b1c974..7abd8f1 100644 (file)
@@ -50,7 +50,7 @@ protected:
     RECOVERING
   };
   AngryStoneState state;
-  
+
 };
 
 #endif
index a74cce2..f0d5eac 100644 (file)
@@ -34,7 +34,7 @@ static const float X_OFFSCREEN_DISTANCE = 1600;
 static const float Y_OFFSCREEN_DISTANCE = 1200;
 
 BadGuy::BadGuy(const Vector& pos, const std::string& sprite_name, int layer)
-  : MovingSprite(pos, sprite_name, layer, COLGROUP_DISABLED), countMe(true), dir(LEFT), start_dir(AUTO), state(STATE_INIT), on_ground_flag(false) 
+  : MovingSprite(pos, sprite_name, layer, COLGROUP_DISABLED), countMe(true), dir(LEFT), start_dir(AUTO), state(STATE_INIT), on_ground_flag(false)
 {
   start_position = bbox.p1;
 
@@ -93,7 +93,7 @@ BadGuy::update(float elapsed_time)
     if (state == STATE_ACTIVE) deactivate();
     set_state(STATE_INACTIVE);
   }
-  
+
   switch(state) {
     case STATE_ACTIVE:
       active_update(elapsed_time);
@@ -125,11 +125,11 @@ BadGuy::str2dir( std::string dir_str )
     return AUTO;
   if( dir_str == "left" )
     return LEFT;
-  if( dir_str == "right" ) 
+  if( dir_str == "right" )
     return RIGHT;
 
   //default to "auto"
-  log_warning << "Badguy::str2dir: unknown direction \"" << dir_str << "\"" << std::endl;;    
+  log_warning << "Badguy::str2dir: unknown direction \"" << dir_str << "\"" << std::endl;;
   return AUTO;
 }
 
@@ -305,7 +305,7 @@ BadGuy::is_offscreen()
 {
   float scroll_x = Sector::current()->camera->get_translation().x;
   float scroll_y = Sector::current()->camera->get_translation().y;
-     
+
   if(bbox.p2.x < scroll_x - X_OFFSCREEN_DISTANCE
       || bbox.p1.x > scroll_x + X_OFFSCREEN_DISTANCE
       || bbox.p2.y < scroll_y - Y_OFFSCREEN_DISTANCE
@@ -325,7 +325,7 @@ BadGuy::try_activate()
    * the effect of having badguys suddenly popping up from nowhere.
    */
   //Badguy left of screen
-  if (start_position.x > scroll_x - X_OFFSCREEN_DISTANCE && 
+  if (start_position.x > scroll_x - X_OFFSCREEN_DISTANCE &&
       start_position.x < scroll_x - bbox.get_width() &&
       start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE &&
       start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) {
@@ -377,7 +377,7 @@ BadGuy::try_activate()
     }
     set_state(STATE_ACTIVE);
     activate();
-  } 
+  }
 }
 
 bool
@@ -400,7 +400,7 @@ BadGuy::might_fall(int height)
   return Sector::current()->is_free_space(Rect(x1, y1, x2, y2));
 }
 
-Player* 
+Player*
 BadGuy::get_nearest_player()
 {
   // FIXME: does not really return nearest player
@@ -414,7 +414,7 @@ BadGuy::get_nearest_player()
   return 0;
 }
 
-void 
+void
 BadGuy::update_on_ground_flag(const CollisionHit& hit)
 {
   if (hit.bottom) on_ground_flag = true;
@@ -425,4 +425,3 @@ BadGuy::on_ground()
 {
   return on_ground_flag;
 }
-
index 5152139..d5cf873 100644 (file)
@@ -88,7 +88,7 @@ public:
   {
     start_position = vec;
   }
-  
+
   /** Count this badguy to the statistics? This value should not be changed
    * during runtime. */
   bool countMe;
@@ -101,14 +101,14 @@ protected:
     STATE_SQUISHED,
     STATE_FALLING
   };
+
   /** Called when the badguy collided with a player */
   virtual HitResponse collision_player(Player& player, const CollisionHit& hit);
   /** Called when the badguy collided with solid ground */
   virtual void collision_solid(const CollisionHit& hit);
   /** Called when the badguy collided with another badguy */
   virtual HitResponse collision_badguy(BadGuy& other, const CollisionHit& hit);
+
   /** Called when the player hit the badguy from above. You should return true
    * if the badguy was squished, false if squishing wasn't possible
    */
@@ -135,12 +135,12 @@ protected:
   void set_state(State state);
   State get_state() const
   { return state; }
-    
+
   /**
    * returns a pointer to the nearest player or 0 if no player is available
    */
   Player* get_nearest_player();
-  
+
   Physic physic;
 
   /// is the enemy activated
@@ -170,7 +170,7 @@ protected:
 
   /**
    *  Get Direction from String.
-   */ 
+   */
   Direction str2dir( std::string dir_str );
 
   /**
@@ -187,11 +187,10 @@ protected:
 
 private:
   void try_activate();
-  
+
   State state;
   Timer state_timer;
   bool on_ground_flag;
 };
 
 #endif
-
index c9e2c8a..c26fe15 100644 (file)
@@ -96,7 +96,7 @@ Bomb::active_update(float )
         remove_me();
       }
       break;
-  } 
+  }
 }
 
 void
@@ -129,4 +129,3 @@ Bomb::kill_fall()
   if (state != STATE_EXPLODING)  // we don't want it exploding again
     explode();
 }
-
index 40b29d0..430c270 100644 (file)
@@ -41,11 +41,10 @@ private:
     STATE_TICKING,
     STATE_EXPLODING
   };
-  
+
   State state;
 
   std::auto_ptr<SoundSource> ticking;
 };
 
 #endif
-
index 616d63e..72d1acf 100644 (file)
@@ -26,7 +26,7 @@ static const float WALKSPEED = 80;
 
 BouncingSnowball::BouncingSnowball(const lisp::Lisp& reader)
        : BadGuy(reader, "images/creatures/bouncing_snowball/bouncing_snowball.sprite")
-{ 
+{
 }
 
 BouncingSnowball::BouncingSnowball(const Vector& pos, Direction d)
@@ -72,7 +72,7 @@ BouncingSnowball::collision_solid(const CollisionHit& hit)
   } else if(hit.top) {
     physic.set_velocity_y(0);
   }
-  
+
   if(hit.left || hit.right) { // left or right collision
     dir = dir == LEFT ? RIGHT : LEFT;
     sprite->set_action(dir == LEFT ? "left" : "right");
@@ -88,4 +88,3 @@ BouncingSnowball::collision_badguy(BadGuy& , const CollisionHit& hit)
 }
 
 IMPLEMENT_FACTORY(BouncingSnowball, "bouncingsnowball")
-
index 992d774..393474e 100644 (file)
@@ -28,7 +28,7 @@ namespace {
 
 static const std::string SOUNDFILE = "sounds/flame.wav";
 
-Dart::Dart(const lisp::Lisp& reader) 
+Dart::Dart(const lisp::Lisp& reader)
        : BadGuy(reader, "images/creatures/dart/dart.sprite"), parent(0)
 {
   physic.enable_gravity(false);
@@ -58,7 +58,7 @@ Dart::~Dart()
 {
 }
 
-bool 
+bool
 Dart::updatePointers(const GameObject* from_object, GameObject* to_object)
 {
   if (from_object == parent) {
@@ -79,7 +79,7 @@ Dart::write(lisp::Writer& writer)
 
 void
 Dart::activate()
-{ 
+{
   physic.set_velocity_x(dir == LEFT ? -::SPEED : ::SPEED);
   sprite->set_action(dir == LEFT ? "flying-left" : "flying-right");
 
@@ -93,12 +93,12 @@ Dart::activate()
 
 void
 Dart::deactivate()
-{  
+{
   sound_source.reset();
   remove_me();
 }
 
-void 
+void
 Dart::active_update(float elapsed_time)
 {
   BadGuy::active_update(elapsed_time);
@@ -112,7 +112,7 @@ Dart::collision_solid(const CollisionHit& )
   remove_me();
 }
 
-HitResponse 
+HitResponse
 Dart::collision_badguy(BadGuy& badguy, const CollisionHit& )
 {
   // ignore collisions with parent
@@ -125,7 +125,7 @@ Dart::collision_badguy(BadGuy& badguy, const CollisionHit& )
   return ABORT_MOVE;
 }
 
-HitResponse 
+HitResponse
 Dart::collision_player(Player& player, const CollisionHit& hit)
 {
   sound_manager->play("sounds/stomp.wav", get_pos());
@@ -134,4 +134,3 @@ Dart::collision_player(Player& player, const CollisionHit& hit)
 }
 
 IMPLEMENT_FACTORY(Dart, "dart")
-
index bfed41f..bbab1df 100644 (file)
@@ -54,4 +54,3 @@ protected:
 };
 
 #endif
-
index abada3b..9bb2eaa 100644 (file)
@@ -26,7 +26,7 @@ namespace {
   const float MUZZLE_Y = 28; /**< [px] muzzle y-offset from top */
 }
 
-DartTrap::DartTrap(const lisp::Lisp& reader) 
+DartTrap::DartTrap(const lisp::Lisp& reader)
        : BadGuy(reader, "images/creatures/darttrap/darttrap.sprite", LAYER_TILES-1), initial_delay(0), fire_delay(2), ammo(-1), state(IDLE)
 {
   reader.get("initial-delay", initial_delay);
@@ -60,7 +60,7 @@ DartTrap::activate()
   fire_timer.start(initial_delay);
 }
 
-HitResponse 
+HitResponse
 DartTrap::collision_player(Player& , const CollisionHit& )
 {
   return ABORT_MOVE;
@@ -105,4 +105,3 @@ DartTrap::fire()
 }
 
 IMPLEMENT_FACTORY(DartTrap, "darttrap")
-
index b891de4..7f2b80e 100644 (file)
@@ -45,7 +45,7 @@ protected:
 
   void load(); /**< load a shot */
   void fire(); /**< fire a shot */
-  
+
   float initial_delay; /**< time to wait before firing first shot */
   float fire_delay; /**< reload time */
   int ammo; /**< ammo left (-1 means unlimited) */
@@ -55,4 +55,3 @@ protected:
 };
 
 #endif
-
index 1bcf021..0483bb1 100644 (file)
@@ -58,7 +58,7 @@ Dispenser::write(lisp::Writer& writer)
 
 void
 Dispenser::activate()
-{  
+{
    dispense_timer.start(cycle, true);
    launch_badguy();
 }
index f79e8e6..c01e19e 100644 (file)
@@ -43,4 +43,3 @@ protected:
 };
 
 #endif
-
index 4f23778..b603125 100644 (file)
@@ -107,10 +107,10 @@ Fish::active_update(float elapsed_time)
   if(waiting.check()) {
     jump();
   }
-  
+
   // set sprite
   sprite->set_action(physic.get_velocity_y() < 0 ? "normal" : "down");
-  
+
   // we can't afford flying out of the tilemap, 'cause the engine would remove us.
   if ((get_pos().y - 31.8) < 0) // too high, let us fall
   {
index 117d1d5..413b5c2 100644 (file)
@@ -43,7 +43,7 @@ private:
   HitResponse hit(const CollisionHit& );
   void start_waiting();
   void jump();
-  
+
   Timer waiting;
   float stop_y; /**< y-coordinate to stop at */
 };
index 9acd1c6..85e470c 100644 (file)
@@ -84,4 +84,3 @@ Flame::kill_fall()
 }
 
 IMPLEMENT_FACTORY(Flame, "flame")
-
index b099eae..ac8a8fc 100644 (file)
@@ -43,4 +43,3 @@ private:
 };
 
 #endif
-
index 66a2db5..517f6b9 100644 (file)
@@ -57,7 +57,7 @@ FlyingSnowBall::write(lisp::Writer& writer)
   writer.end_list("flyingsnowball");
 }
 
-void 
+void
 FlyingSnowBall::activate()
 {
   sprite->set_action(dir == LEFT ? "left" : "right");
@@ -84,7 +84,7 @@ FlyingSnowBall::collision_solid(const CollisionHit& hit)
 }
 
 void
-FlyingSnowBall::active_update(float elapsed_time) 
+FlyingSnowBall::active_update(float elapsed_time)
 {
   if(timer.check()) {
     if(mode == FLY_UP) {
@@ -93,7 +93,7 @@ FlyingSnowBall::active_update(float elapsed_time)
 
       // stop puffing
       puff_timer.stop();
-      
+
     } else if(mode == FLY_DOWN) {
       mode = FLY_UP;
       physic.set_velocity_y(FLYSPEED);
index f43aea2..2451065 100644 (file)
@@ -98,7 +98,7 @@ Igel::active_update(float elapsed_time)
     BadGuy::active_update(elapsed_time);
     return;
   }
-  
+
   // else adhere to default behaviour
   WalkingBadguy::active_update(elapsed_time);
 }
index 6da2df1..0c83cef 100644 (file)
@@ -51,4 +51,3 @@ private:
 };
 
 #endif
-
index 233a672..012adaa 100644 (file)
@@ -62,7 +62,7 @@ Jumpy::hit(const CollisionHit& chit)
       pos_groundhit = get_pos();
       groundhit_pos_set = true;
     }
-    
+
     physic.set_velocity_y(JUMPSPEED);
     // TODO create a nice sound for this...
     //sound_manager->play("sounds/skid.wav");
@@ -77,19 +77,19 @@ void
 Jumpy::active_update(float elapsed_time)
 {
   BadGuy::active_update(elapsed_time);
-  
+
   Player* player = this->get_nearest_player();
   if (player)
   {
     dir = (player->get_pos().x > get_pos().x) ? RIGHT : LEFT;
   }
-    
+
   if (!groundhit_pos_set)
   {
     sprite->set_action(dir == LEFT ? "left-middle" : "right-middle");
     return;
   }
-  
+
   if ( get_pos().y < (pos_groundhit.y - JUMPY_MID_TOLERANCE ) )
     sprite->set_action(dir == LEFT ? "left-up" : "right-up");
   else if ( get_pos().y >= (pos_groundhit.y - JUMPY_MID_TOLERANCE) &&
index 494559b..fa39085 100644 (file)
@@ -42,4 +42,3 @@ private:
 };
 
 #endif
-
index e9fac15..c6242e6 100644 (file)
@@ -150,7 +150,7 @@ Kugelblitz::active_update(float elapsed_time)
     }
     */
   }
-  BadGuy::active_update(elapsed_time);  
+  BadGuy::active_update(elapsed_time);
 }
 
 void
index 2e7b3ee..5f327f2 100644 (file)
@@ -54,4 +54,3 @@ private:
 };
 
 #endif
-
index 90db30f..0cbb71e 100644 (file)
@@ -37,7 +37,7 @@ MrBomb::MrBomb(const lisp::Lisp& reader)
     sprite_name = "images/creatures/mr_cherry/juicebox.sprite";
     return;
   }
-  //Replace sprite 
+  //Replace sprite
   sprite = sprite_manager->create( sprite_name );
 }
 
index 63c4364..845c063 100644 (file)
@@ -38,4 +38,3 @@ protected:
 };
 
 #endif
-
index 472aa17..0e46ba6 100644 (file)
@@ -31,7 +31,7 @@ MrIceBlock::MrIceBlock(const lisp::Lisp& reader)
   : WalkingBadguy(reader, "images/creatures/mr_iceblock/mr_iceblock.sprite", "left", "right"), ice_state(ICESTATE_NORMAL), squishcount(0)
 {
   walk_speed = 80;
-  max_drop_height = 600; 
+  max_drop_height = 600;
   sound_manager->preload("sounds/iceblock_bump.wav");
   sound_manager->preload("sounds/stomp.wav");
   sound_manager->preload("sounds/kick.wav");
@@ -40,8 +40,8 @@ MrIceBlock::MrIceBlock(const lisp::Lisp& reader)
 MrIceBlock::MrIceBlock(const Vector& pos, Direction d)
   : WalkingBadguy(pos, d, "images/creatures/mr_iceblock/mr_iceblock.sprite", "left", "right"), ice_state(ICESTATE_NORMAL), squishcount(0)
 {
-  walk_speed = 80; 
-  max_drop_height = 600; 
+  walk_speed = 80;
+  max_drop_height = 600;
   sound_manager->preload("sounds/iceblock_bump.wav");
   sound_manager->preload("sounds/stomp.wav");
   sound_manager->preload("sounds/kick.wav");
@@ -151,7 +151,7 @@ MrIceBlock::collision_player(Player& player, const CollisionHit& hit)
       return FORCE_MOVE;
     }
   }
-  
+
   return BadGuy::collision_player(player, hit);
 }
 
@@ -209,7 +209,7 @@ MrIceBlock::set_state(IceState state)
 {
   if(ice_state == state)
     return;
-  
+
   if(state == ICESTATE_FLAT)
     flags |= FLAG_PORTABLE;
   else
@@ -222,8 +222,8 @@ MrIceBlock::set_state(IceState state)
     case ICESTATE_FLAT:
       sound_manager->play("sounds/stomp.wav", get_pos());
       physic.set_velocity_x(0);
-      physic.set_velocity_y(0); 
-      
+      physic.set_velocity_y(0);
+
       sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
       flat_timer.start(4);
       break;
index 98c4225..26546c4 100644 (file)
@@ -37,7 +37,7 @@ public:
   HitResponse collision_player(Player& player, const CollisionHit& hit);
 
   void active_update(float elapsed_time);
-  
+
   void grab(MovingObject& object, const Vector& pos, Direction dir);
   void ungrab(MovingObject& object, Direction dir);
   bool can_break();
@@ -56,11 +56,10 @@ private:
   };
 
   void set_state(IceState state);
+
   IceState ice_state;
   Timer flat_timer;
   int squishcount;
 };
 
 #endif
-
index 77a7634..11ae037 100644 (file)
@@ -43,4 +43,3 @@ protected:
 };
 
 #endif
-
index 7b8763f..775c821 100644 (file)
@@ -63,7 +63,7 @@ MrTree::collision_squished(Player& player)
   // give Feedback
   sound_manager->play("sounds/mr_tree.ogg", get_pos());
   player.bounce(*this);
-  
+
   // spawn some particles
   // TODO: provide convenience function in MovingSprite or MovingObject?
   for (int px = (int)stumpy->get_bbox().p1.x; px < (int)stumpy->get_bbox().p2.x; px+=10) {
@@ -85,7 +85,7 @@ MrTree::collision_squished(Player& player)
     leaf1 = leaf1;
     Sector::current()->add_object(leaf1);
   }
-  
+
   // spawn PoisonIvy
   Vector leaf2_pos = Vector(stumpy_pos.x + sprite->get_current_hitbox_width() + 1, stumpy_pos.y - POISONIVY_Y_OFFSET);
   Rect leaf2_bbox = Rect(leaf2_pos.x, leaf2_pos.y, leaf2_pos.x + POISONIVY_WIDTH, leaf2_pos.y + POISONIVY_HEIGHT);
@@ -99,4 +99,3 @@ MrTree::collision_squished(Player& player)
 }
 
 IMPLEMENT_FACTORY(MrTree, "mrtree")
-  
index 91cb1c9..5830d2b 100644 (file)
@@ -78,7 +78,7 @@ Plant::collision_badguy(BadGuy& , const CollisionHit& hit)
   return CONTINUE;
 }
 
-void 
+void
 Plant::active_update(float elapsed_time) {
   BadGuy::active_update(elapsed_time);
 
index 75d77e3..7216514 100644 (file)
@@ -44,7 +44,7 @@ protected:
     PLANT_WALKING
   };
   PlantState state;
-  
+
 };
 
 #endif
index 4e0520c..2c24ccb 100644 (file)
@@ -70,4 +70,3 @@ void
 RocketExplosion::kill_fall()
 {
 }
-
index 63e6435..a1fab84 100644 (file)
@@ -103,7 +103,7 @@ SkullyHop::collision_solid(const CollisionHit& hit)
     set_state(STANDING);
   }
   // check if we hit the roof while climbing
-  if(hit.top) { 
+  if(hit.top) {
     physic.set_velocity_y(0);
   }
 
@@ -139,7 +139,7 @@ SkullyHop::active_update(float elapsed_time)
   if ((state == CHARGING) && (sprite->animation_done())) {
     set_state(JUMPING);
     return;
-  } 
+  }
 }
 
 IMPLEMENT_FACTORY(SkullyHop, "skullyhop")
index 805cf35..1ceab05 100644 (file)
@@ -55,4 +55,3 @@ protected:
 };
 
 #endif
-
index cb34a8f..e40a24d 100644 (file)
@@ -78,10 +78,10 @@ Snail::be_flat()
   state = STATE_FLAT;
   sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
   sprite->set_fps(64);
-  
+
   physic.set_velocity_x(0);
-  physic.set_velocity_y(0); 
-  
+  physic.set_velocity_y(0);
+
   flat_timer.start(4);
 }
 
@@ -93,8 +93,8 @@ Snail::be_kicked()
   sprite->set_fps(64);
 
   physic.set_velocity_x(0);
-  physic.set_velocity_y(0); 
+  physic.set_velocity_y(0);
+
   // start a timer to delay addition of upward movement until we are (hopefully) out from under the player
   kicked_delay_timer.start(0.05);
 }
@@ -183,7 +183,7 @@ Snail::collision_solid(const CollisionHit& hit)
       }
       break;
   }
-  
+
 }
 
 HitResponse
@@ -221,7 +221,7 @@ Snail::collision_squished(Player& player)
       sound_manager->play("sounds/stomp.wav", get_pos());
       be_flat();
       break;
-      
+
     case STATE_FLAT:
       sound_manager->play("sounds/kick.wav", get_pos());
 
@@ -235,7 +235,7 @@ Snail::collision_squished(Player& player)
 
     case STATE_KICKED_DELAY:
       break;
-      
+
   }
 
   player.bounce(*this);
index 7427f02..0e80409 100644 (file)
@@ -61,4 +61,3 @@ private:
 };
 
 #endif
-
index bdb9b57..a68bc3e 100644 (file)
@@ -37,4 +37,3 @@ protected:
 };
 
 #endif
-
index 70feda7..42210d2 100644 (file)
@@ -48,7 +48,7 @@ SpiderMite::write(lisp::Writer& writer)
   writer.end_list("spidermite");
 }
 
-void 
+void
 SpiderMite::activate()
 {
   sprite->set_action(dir == LEFT ? "left" : "right");
@@ -74,7 +74,7 @@ SpiderMite::collision_solid(const CollisionHit& hit)
 }
 
 void
-SpiderMite::active_update(float elapsed_time) 
+SpiderMite::active_update(float elapsed_time)
 {
   if(timer.check()) {
     if(mode == FLY_UP) {
index 84f313d..91333aa 100644 (file)
@@ -47,4 +47,3 @@ private:
 };
 
 #endif
-
index 292767f..c81ea1d 100644 (file)
@@ -65,7 +65,7 @@ SSpiky::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
   return WalkingBadguy::collision_badguy(badguy, hit);
 }
 
-void 
+void
 SSpiky::active_update(float elapsed_time) {
 
   if(state == SSPIKY_WALKING) {
@@ -91,7 +91,7 @@ SSpiky::active_update(float elapsed_time) {
         state = SSPIKY_WAKING;
       }
     }
-  
+
     BadGuy::active_update(elapsed_time);
   }
 
index 289135b..c0fd7be 100644 (file)
@@ -73,7 +73,7 @@ Stalactite::collision_solid(const CollisionHit& hit)
 {
   if(state != STALACTITE_FALLING && state != STALACTITE_SQUISHED)
     return;
-  
+
   if(hit.bottom) { // hit floor?
     state = STALACTITE_SQUISHED;
     set_group(COLGROUP_MOVING_ONLY_STATIC);
@@ -104,7 +104,7 @@ Stalactite::draw(DrawingContext& context)
 {
   if(get_state() != STATE_ACTIVE)
     return;
-    
+
   if(state == STALACTITE_SHAKING) {
     sprite->draw(context, get_pos() + Vector(systemRandom.rand(-3,3), 0), LAYER_OBJECTS);
   } else {
index 74803c2..ef48ede 100644 (file)
@@ -26,7 +26,7 @@ class Stalactite : public BadGuy
 {
 public:
   Stalactite(const lisp::Lisp& reader);
+
   void active_update(float elapsed_time);
   void write(lisp::Writer& writer);
   void collision_solid(const CollisionHit& hit);
@@ -51,4 +51,3 @@ protected:
 };
 
 #endif
-
index 342879f..282b3a6 100644 (file)
@@ -164,4 +164,3 @@ Stumpy::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
 }
 
 IMPLEMENT_FACTORY(Stumpy, "stumpy")
-  
index a3bd203..25ca246 100644 (file)
@@ -43,7 +43,7 @@ protected:
   MyState mystate;
 
   Timer invincible_timer;
-   
+
   bool collision_squished(Player& player);
 };
 
index b209914..279038b 100644 (file)
@@ -1,5 +1,5 @@
 //  $Id$
-// 
+//
 //  SuperTux - "Totem" Badguy
 //  Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
 //
@@ -12,7 +12,7 @@
 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 //  GNU General Public License for more details.
-// 
+//
 //  You should have received a copy of the GNU General Public License
 //  along with this program; if not, write to the Free Software
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -42,13 +42,13 @@ Totem::Totem(const Totem& other)
   sound_manager->preload( LAND_ON_TOTEM_SOUND );
 }
 
-Totem::~Totem() 
+Totem::~Totem()
 {
   if (carrying) carrying->jump_off();
   if (carried_by) jump_off();
 }
 
-bool 
+bool
 Totem::updatePointers(const GameObject* from_object, GameObject* to_object)
 {
   if (from_object == carrying) {
@@ -101,14 +101,14 @@ Totem::active_update(float elapsed_time)
 
     Sector* s = Sector::current();
     if (s) {
-      // jump a bit if we find a suitable totem 
+      // jump a bit if we find a suitable totem
       for (std::vector<MovingObject*>::iterator i = s->moving_objects.begin(); i != s->moving_objects.end(); i++) {
        Totem* t = dynamic_cast<Totem*>(*i);
        if (!t) continue;
-       
+
        // skip if we are not approaching each other
        if (!((this->dir == LEFT) && (t->dir == RIGHT))) continue;
-       
+
        Vector p1 = this->get_pos();
        Vector p2 = t->get_pos();
 
@@ -165,7 +165,7 @@ Totem::collision_solid(const CollisionHit& hit)
     return;
   }
 
-  // If we hit something from above or below: stop moving in this direction 
+  // If we hit something from above or below: stop moving in this direction
   if (hit.top || hit.bottom) {
     physic.set_velocity_y(0);
   }
@@ -189,7 +189,7 @@ Totem::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
     carried_by->collision_badguy(badguy, hit);
     return CONTINUE;
   }
+
   // if we hit a Totem that is not from our stack: have our base jump on its top
   Totem* totem = dynamic_cast<Totem*>(&badguy);
   if (totem) {
@@ -223,23 +223,23 @@ Totem::kill_fall()
   BadGuy::kill_fall();
 }
 
-void 
+void
 Totem::jump_on(Totem* target)
 {
   if (target->carrying) {
     log_warning << "target is already carrying someone" << std::endl;
     return;
   }
-  
+
   target->carrying = this;
 
   this->carried_by = target;
   this->activate();
   bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
+
   sound_manager->play( LAND_ON_TOTEM_SOUND , get_pos());
 
-  
+
   this->synchronize_with(target);
 }
 
@@ -261,7 +261,7 @@ Totem::jump_off() {
   physic.set_velocity_y(JUMP_OFF_SPEED_Y);
 }
 
-void 
+void
 Totem::synchronize_with(Totem* base)
 {
 
@@ -269,7 +269,7 @@ Totem::synchronize_with(Totem* base)
     dir = base->dir;
     sprite->set_action(dir == LEFT ? "stacked-left" : "stacked-right");
   }
-  
+
   Vector pos = base->get_pos();
   pos.y -= sprite->get_current_hitbox_height();
   set_pos(pos);
@@ -280,4 +280,3 @@ Totem::synchronize_with(Totem* base)
 
 
 IMPLEMENT_FACTORY(Totem, "totem")
-  
index 044c000..89ef732 100644 (file)
@@ -1,5 +1,5 @@
 //  $Id$
-// 
+//
 //  SuperTux - "Totem" Badguy
 //  Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
 //
@@ -12,7 +12,7 @@
 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 //  GNU General Public License for more details.
-// 
+//
 //  You should have received a copy of the GNU General Public License
 //  along with this program; if not, write to the Free Software
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -56,4 +56,3 @@ protected:
 };
 
 #endif
-
index 1105110..66cc3f9 100644 (file)
@@ -73,11 +73,11 @@ WalkingBadguy::collision_solid(const CollisionHit& hit)
 
   update_on_ground_flag(hit);
 
-  if (hit.top || hit.bottom) { 
+  if (hit.top || hit.bottom) {
     physic.set_velocity_y(0);
   }
 
-  if ((hit.left && dir == LEFT) || (hit.right && dir == RIGHT)) { 
+  if ((hit.left && dir == LEFT) || (hit.right && dir == RIGHT)) {
     turn_around();
   }
 
@@ -87,7 +87,7 @@ HitResponse
 WalkingBadguy::collision_badguy(BadGuy& , const CollisionHit& hit)
 {
 
-  if ((hit.left && (dir == LEFT)) || (hit.right && (dir == RIGHT))) { 
+  if ((hit.left && (dir == LEFT)) || (hit.right && (dir == RIGHT))) {
     turn_around();
   }
 
@@ -101,4 +101,3 @@ WalkingBadguy::turn_around()
   sprite->set_action(dir == LEFT ? walk_left_action : walk_right_action);
   physic.set_velocity_x(dir == LEFT ? -walk_speed : walk_speed);
 }
-
index 98d694f..6f023a8 100644 (file)
@@ -39,7 +39,7 @@ public:
   HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
 
 protected:
-  void turn_around(); 
+  void turn_around();
 
   std::string walk_left_action;
   std::string walk_right_action;
index 6480c16..6e069e8 100644 (file)
@@ -1,5 +1,5 @@
 //  $Id$
-// 
+//
 //  SuperTux - "Will-O-Wisp" Badguy
 //  Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
 //
@@ -12,7 +12,7 @@
 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 //  GNU General Public License for more details.
-// 
+//
 //  You should have received a copy of the GNU General Public License
 //  along with this program; if not, write to the Free Software
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -55,12 +55,12 @@ void
 WillOWisp::draw(DrawingContext& context)
 {
   sprite->draw(context, get_pos(), layer);
-  
+
   context.push_target();
   context.set_target(DrawingContext::LIGHTMAP);
 
   sprite->draw(context, get_pos(), layer);
-  
+
   context.pop_target();
 }
 
@@ -78,7 +78,7 @@ WillOWisp::active_update(float elapsed_time)
       mystate = STATE_TRACKING;
     }
   }
-  
+
   if (mystate == STATE_TRACKING) {
     if (dist.norm() <= VANISH_RANGE) {
       Vector dir = dist.unit();
@@ -101,7 +101,7 @@ WillOWisp::active_update(float elapsed_time)
       remove_me();
     }
   }
-  
+
 }
 
 void
@@ -156,4 +156,3 @@ WillOWisp::collision_player(Player& player, const CollisionHit& ) {
 }
 
 IMPLEMENT_FACTORY(WillOWisp, "willowisp")
-
index ced7230..51bdc1f 100644 (file)
@@ -1,5 +1,5 @@
 //  $Id$
-// 
+//
 //  SuperTux - "Will-O-Wisp" Badguy
 //  Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
 //
@@ -12,7 +12,7 @@
 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 //  GNU General Public License for more details.
-// 
+//
 //  You should have received a copy of the GNU General Public License
 //  along with this program; if not, write to the Free Software
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -53,4 +53,3 @@ private:
 };
 
 #endif
-
index 909fbe2..2b18b98 100644 (file)
@@ -1,5 +1,5 @@
 //  $Id$
-// 
+//
 //  SuperTux - Boss "Yeti"
 //  Copyright (C) 2005 Matthias Braun <matze@braunis.de>
 //  Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
@@ -13,7 +13,7 @@
 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 //  GNU General Public License for more details.
-// 
+//
 //  You should have received a copy of the GNU General Public License
 //  along with this program; if not, write to the Free Software
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -42,7 +42,7 @@ namespace {
   const float STOMP_VY = -250; /** vertical speed while stomping on the dais */
 
   const float LEFT_STAND_X = 16; /**< x-coordinate of left dais' end position */
-  const float RIGHT_STAND_X = 800-60-16; /**< x-coordinate of right dais' end position */ 
+  const float RIGHT_STAND_X = 800-60-16; /**< x-coordinate of right dais' end position */
   const float LEFT_JUMP_X = LEFT_STAND_X+224; /**< x-coordinate of from where to jump on the left dais */
   const float RIGHT_JUMP_X = RIGHT_STAND_X-224; /**< x-coordinate of from where to jump on the right dais */
   const float STOMP_WAIT = .5; /**< time we stay on the dais before jumping again */
@@ -191,7 +191,7 @@ void Yeti::take_hit(Player& )
     physic.enable_gravity(true);
     physic.set_velocity_x(0);
     physic.set_velocity_y(0);
-    
+
     state = SQUISHED;
     state_timer.start(SQUISH_TIME);
     set_group(COLGROUP_MOVING_ONLY_STATIC);
@@ -249,7 +249,7 @@ Yeti::drop_stalactite()
       i != sector->gameobjects.end(); ++i) {
     YetiStalactite* stalactite = dynamic_cast<YetiStalactite*> (*i);
     if(stalactite && stalactite->is_hanging()) {
-      float sdist 
+      float sdist
         = fabsf(stalactite->get_pos().x - player->get_pos().x);
       if(sdist < dist) {
         nearest = stalactite;
@@ -265,7 +265,7 @@ Yeti::drop_stalactite()
 void
 Yeti::collision_solid(const CollisionHit& hit)
 {
-  if(hit.top || hit.bottom) { 
+  if(hit.top || hit.bottom) {
     // hit floor or roof
     physic.set_velocity_y(0);
     switch (state) {
index 74d8b19..d7e16ce 100644 (file)
@@ -49,7 +49,7 @@ private:
   void jump_down();
 
   void take_hit(Player& player);
-  
+
   enum YetiState {
     JUMP_DOWN,
     RUN,
@@ -66,4 +66,3 @@ private:
 };
 
 #endif
-
index 4d78943..85b2d47 100644 (file)
@@ -66,7 +66,7 @@ Zeekling::collision_squished(Player& player)
   return true;
 }
 
-void 
+void
 Zeekling::onBumpHorizontal() {
   if (state == FLYING) {
     dir = (dir == LEFT ? RIGHT : LEFT);
@@ -89,7 +89,7 @@ Zeekling::onBumpHorizontal() {
   }
 }
 
-void 
+void
 Zeekling::onBumpVertical() {
   if (state == FLYING) {
     physic.set_velocity_y(0);
@@ -109,7 +109,7 @@ void
 Zeekling::collision_solid(const CollisionHit& hit)
 {
   if(hit.top || hit.bottom) {
-    onBumpVertical(); 
+    onBumpVertical();
   } else if(hit.left || hit.right) {
     onBumpHorizontal();
   }
@@ -118,7 +118,7 @@ Zeekling::collision_solid(const CollisionHit& hit)
 /**
  * linear prediction of player and badguy positions to decide if we should enter the DIVING state
  */
-bool 
+bool
 Zeekling::should_we_dive() {
   const MovingObject* player = this->get_nearest_player();
   if (!player) return false;
@@ -144,7 +144,7 @@ Zeekling::should_we_dive() {
 
   // guess number of frames to descend to same height as player
   float estFrames = height / relSpeed;
-  
+
   // guess where the player would be at this time
   float estPx = (playerPos.x + (estFrames * playerMov.x));
 
@@ -157,7 +157,7 @@ Zeekling::should_we_dive() {
   return false;
 }
 
-void 
+void
 Zeekling::active_update(float elapsed_time) {
   if (state == FLYING) {
     if (should_we_dive()) {
index 1784237..fd0f287 100644 (file)
@@ -57,4 +57,3 @@ private:
 };
 
 #endif
-
index 8ae5e91..e9c25fb 100644 (file)
@@ -52,7 +52,7 @@ namespace {
   {
     n = Vector(p2.y-p1.y, p1.x-p2.x);
     c = -(p2 * n);
-    float nval = n.norm();             
+    float nval = n.norm();
     n /= nval;
     c /= nval;
   }
@@ -93,8 +93,8 @@ bool rectangle_aatriangle(Constraints* constraints, const Rect& rect,
       break;
     default:
       assert(false);
-  } 
-  
+  }
+
   switch(triangle.dir & AATriangle::DIRECTION_MASK) {
     case AATriangle::SOUTHWEST:
       p1 = Vector(rect.p1.x, rect.p2.y);
@@ -152,7 +152,7 @@ bool rectangle_aatriangle(Constraints* constraints, const Rect& rect,
     }
     constraints->hit.slope_normal = normal;
   }
-  
+
   return true;
 }
 
index cc5bcd0..73c966d 100644 (file)
@@ -55,10 +55,10 @@ public:
 
 /** checks if 2 rectangle intersect each other */
 bool intersects(const Rect& r1, const Rect& r2);
-  
+
 /** does collision detection between a rectangle and an axis aligned triangle
  * Returns true in case of a collision and fills in the hit structure then.
- */                                                                         
+ */
 bool rectangle_aatriangle(Constraints* constraints, const Rect& rect,
                                    const AATriangle& triangle);
 
@@ -68,4 +68,3 @@ void set_rectangle_rectangle_constraints(Constraints* constraints,
 }
 
 #endif
-
index ba29e9f..0287903 100644 (file)
@@ -32,7 +32,7 @@ enum HitResponse
   /// don't move the object
   ABORT_MOVE = 0,
   /// move object out of collision and check for collisions again
-  /// if this happens to often then the move will just be aborted    
+  /// if this happens to often then the move will just be aborted
   CONTINUE,
   /// do the move ignoring the collision
   FORCE_MOVE,
@@ -67,4 +67,3 @@ public:
 };
 
 #endif
-
index cc88905..d6b2238 100644 (file)
 static const float FADE_SPEED = 1;
 
 Console::Console()
-  : history_position(history.end()), vm(NULL), backgroundOffset(0), 
+  : history_position(history.end()), vm(NULL), backgroundOffset(0),
     height(0), alpha(1.0), offset(0), focused(false), stayOpen(0) {
   fontheight = 8;
 }
 
-Console::~Console() 
+Console::~Console()
 {
   if(vm != NULL) {
     sq_release(Scripting::global_vm, &vm_object);
@@ -56,8 +56,8 @@ Console::init_graphics()
   background2.reset(new Surface("images/engine/console2.png"));
 }
 
-void 
-Console::flush(ConsoleStreamBuffer* buffer) 
+void
+Console::flush(ConsoleStreamBuffer* buffer)
 {
   if (buffer == &outputBuffer) {
     std::string s = outputBuffer.str();
@@ -93,7 +93,7 @@ Console::ready_vm()
       throw Scripting::SquirrelError(vm, "Couldn't get vm object for console");
     sq_addref(vm, &vm_object);
     sq_pop(vm, 1);
-    
+
     // create new roottable for thread
     sq_newtable(new_vm);
     sq_pushroottable(new_vm);
@@ -103,7 +103,7 @@ Console::ready_vm()
     sq_setroottable(new_vm);
 
     vm = new_vm;
-    
+
     try {
       std::string filename = "scripts/console.nut";
       IFileStream stream(filename);
@@ -119,15 +119,15 @@ Console::execute_script(const std::string& command)
 {
   using namespace Scripting;
 
-  ready_vm(); 
+  ready_vm();
 
-  SQInteger oldtop = sq_gettop(vm); 
+  SQInteger oldtop = sq_gettop(vm);
   try {
     if(SQ_FAILED(sq_compilebuffer(vm, command.c_str(), command.length(),
                  "", SQTrue)))
       throw SquirrelError(vm, "Couldn't compile command");
 
-    sq_pushroottable(vm); 
+    sq_pushroottable(vm);
     if(SQ_FAILED(sq_call(vm, 1, SQTrue, SQTrue)))
       throw SquirrelError(vm, "Problem while executing command");
 
@@ -244,7 +244,7 @@ sq_insert_commands(std::list<std::string>& cmds, HSQUIRRELVM vm, std::string tab
 }
 
 
-} 
+}
 // End of Console::autocomplete helper functions
 
 void
@@ -294,16 +294,16 @@ Console::autocomplete()
   }
 }
 
-void 
-Console::addLines(std::string s) 
+void
+Console::addLines(std::string s)
 {
   std::istringstream iss(s);
   std::string line;
   while (std::getline(iss, line, '\n')) addLine(line);
 }
 
-void 
-Console::addLine(std::string s) 
+void
+Console::addLine(std::string s)
 {
   // output line to stderr
   std::cerr << s << std::endl;
@@ -318,7 +318,7 @@ Console::addLine(std::string s)
   // trim scrollback buffer
   while (lines.size() >= 1000)
     lines.pop_back();
+
   // increase console height if necessary
   if (height < 64) {
     if(height < 4)
@@ -335,7 +335,7 @@ Console::addLine(std::string s)
 }
 
 void
-Console::parse(std::string s) 
+Console::parse(std::string s)
 {
   // make sure we actually have something to parse
   if (s.length() == 0) return;
@@ -380,7 +380,7 @@ Console::parse(std::string s)
 }
 
 bool
-Console::consoleCommand(std::string command, std::vector<std::string> arguments) 
+Console::consoleCommand(std::string command, std::vector<std::string> arguments)
 {
   if (command == "ccrs") {
     if (arguments.size() != 1) {
@@ -409,7 +409,7 @@ Console::consoleCommand(std::string command, std::vector<std::string> arguments)
 }
 
 bool
-Console::hasFocus() 
+Console::hasFocus()
 {
   return focused;
 }
@@ -423,7 +423,7 @@ Console::show()
   SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
 }
 
-void 
+void
 Console::hide()
 {
   focused = false;
@@ -435,13 +435,13 @@ Console::hide()
   SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
 }
 
-void 
+void
 Console::toggle()
 {
   if (Console::hasFocus()) {
-    Console::hide(); 
-  } 
-  else { 
+    Console::hide();
+  }
+  else {
     Console::show();
   }
 }
@@ -462,7 +462,7 @@ Console::update(float elapsed_time)
   }
 }
 
-void 
+void
 Console::draw(DrawingContext& context)
 {
   if (height == 0)
@@ -498,13 +498,13 @@ Console::draw(DrawingContext& context)
   context.pop_transform();
 }
 
-void 
+void
 Console::registerCommand(std::string command, ConsoleCommandReceiver* ccr)
 {
   commands[command].push_front(ccr);
 }
 
-void 
+void
 Console::unregisterCommand(std::string command, ConsoleCommandReceiver* ccr)
 {
   std::map<std::string, std::list<ConsoleCommandReceiver*> >::iterator i = commands.find(command);
@@ -520,7 +520,7 @@ Console::unregisterCommand(std::string command, ConsoleCommandReceiver* ccr)
   i->second.erase(j);
 }
 
-void 
+void
 Console::unregisterCommands(ConsoleCommandReceiver* ccr)
 {
   for (std::map<std::string, std::list<ConsoleCommandReceiver*> >::iterator i = commands.begin(); i != commands.end(); i++) {
@@ -537,4 +537,3 @@ ConsoleStreamBuffer Console::inputBuffer;
 ConsoleStreamBuffer Console::outputBuffer;
 std::ostream Console::input(&Console::inputBuffer);
 std::ostream Console::output(&Console::outputBuffer);
-
index a128d60..15d9791 100644 (file)
@@ -35,7 +35,7 @@ class DrawingContext;
 class Surface;
 class Font;
 
-class Console 
+class Console
 {
 public:
   Console();
@@ -55,7 +55,7 @@ public:
 
   void draw(DrawingContext& context); /**< draw the console in a DrawingContext */
   void update(float elapsed_time);
-  
+
   void show(); /**< display the console */
   void hide(); /**< hide the console */
   void toggle(); /**< display the console if hidden, hide otherwise */
@@ -90,13 +90,13 @@ private:
   std::list<std::string>::iterator history_position; /**< item of command history that is currently displayed */
   std::list<std::string> lines; /**< backbuffer of lines sent to the console. New lines get added to front. */
   std::map<std::string, std::list<ConsoleCommandReceiver*> > commands; /**< map of console commands and a list of associated ConsoleCommandReceivers */
-  
+
   std::auto_ptr<Surface> background; /**< console background image */
   std::auto_ptr<Surface> background2; /**< second, moving console background image */
 
   HSQUIRRELVM vm; /**< squirrel thread for the console (with custom roottable) */
   HSQOBJECT vm_object;
-  
+
   int backgroundOffset; /**< current offset of scrolling background image */
   float height; /**< height of the console in px */
   float alpha;
@@ -113,23 +113,23 @@ private:
   void addLines(std::string s); /**< display a string of (potentially) multiple lines in the console */
   void addLine(std::string s); /**< display a line in the console */
   void parse(std::string s); /**< react to a given command */
-   
+
   /** ready a virtual machine instance, creating a new thread and loading default .nut files if needed */
   void ready_vm();
 
   /** execute squirrel script and output result */
   void execute_script(const std::string& s);
-    
+
   bool consoleCommand(std::string command, std::vector<std::string> arguments); /**< process internal command; return false if command was unknown, true otherwise */
 
   friend class ConsoleStreamBuffer;
   void flush(ConsoleStreamBuffer* buffer); /**< act upon changes in a ConsoleStreamBuffer */
 };
 
-class ConsoleStreamBuffer : public std::stringbuf 
+class ConsoleStreamBuffer : public std::stringbuf
 {
   public:
-    int sync() 
+    int sync()
     {
       int result = std::stringbuf::sync();
       if(Console::instance != NULL)
@@ -145,7 +145,7 @@ public:
   {
     Console::instance->unregisterCommands(this);
   }
-   
+
   /**
    * callback from Console; return false if command was unknown,
    * true otherwise
index 7cdb4c4..fdc0893 100644 (file)
@@ -26,7 +26,7 @@
  * This is a dummy controler that doesn't react to any user input but should
  * be controlled by code
  */
-class CodeController : public Controller 
+class CodeController : public Controller
 {
 public:
   CodeController();
index deeb8e6..9f3a07f 100644 (file)
@@ -24,7 +24,7 @@ class Controller
 {
 public:
   static const char* controlNames[];
-  
+
   enum Control {
     LEFT = 0,
     RIGHT,
@@ -37,7 +37,7 @@ public:
     CONSOLE,
     PEEK_LEFT,
     PEEK_RIGHT,
-    
+
     CONTROLCOUNT
   };
 
@@ -48,7 +48,7 @@ public:
   bool hold(Control control);
   /** returns true if the control has just been pressed down this frame */
   bool pressed(Control control);
-  /** returns true if the control has just been released this frame */ 
+  /** returns true if the control has just been released this frame */
   bool released(Control control);
 
   virtual void reset();
index c62153d..7bd5961 100644 (file)
@@ -52,7 +52,7 @@ public:
   virtual void menu_action(MenuItem* item);
   JoystickKeyboardController* controller;
 };
-  
+
 JoystickKeyboardController::JoystickKeyboardController()
   : wait_for_key(-1), wait_for_joybutton(-1), key_options_menu(0),
     joystick_options_menu(0)
@@ -67,13 +67,13 @@ JoystickKeyboardController::JoystickKeyboardController()
   keymap.insert(std::make_pair(SDLK_LALT, ACTION));
   keymap.insert(std::make_pair(SDLK_ESCAPE, PAUSE_MENU));
   keymap.insert(std::make_pair(SDLK_p, PAUSE_MENU));
-  keymap.insert(std::make_pair(SDLK_PAUSE, PAUSE_MENU));  
+  keymap.insert(std::make_pair(SDLK_PAUSE, PAUSE_MENU));
   keymap.insert(std::make_pair(SDLK_RETURN, MENU_SELECT));
   keymap.insert(std::make_pair(SDLK_KP_ENTER, MENU_SELECT));
   keymap.insert(std::make_pair(SDLK_CARET, CONSOLE));
   keymap.insert(std::make_pair(SDLK_DELETE, PEEK_LEFT));
   keymap.insert(std::make_pair(SDLK_END, PEEK_RIGHT));
-  
+
   int joystick_count = SDL_NumJoysticks();
   min_joybuttons = -1;
   max_joybuttons = -1;
@@ -93,7 +93,7 @@ JoystickKeyboardController::JoystickKeyboardController()
       SDL_JoystickClose(joystick);
       continue;
     }
-    
+
     if(min_joybuttons < 0 || SDL_JoystickNumButtons(joystick) < min_joybuttons)
       min_joybuttons = SDL_JoystickNumButtons(joystick);
     if(SDL_JoystickNumButtons(joystick) > max_joybuttons) {
@@ -108,7 +108,7 @@ JoystickKeyboardController::JoystickKeyboardController()
   joyaxis_y = 1;
   dead_zone_x = 1000;
   dead_zone_y = 1000;
-  
+
   joy_button_map.insert(std::make_pair(0, JUMP));
   joy_button_map.insert(std::make_pair(1, ACTION));
   // 6 or more Buttons
@@ -123,7 +123,7 @@ JoystickKeyboardController::JoystickKeyboardController()
       if( i != min_joybuttons-1 && i !=4  && i!= 5 )
         joy_button_map.insert(std::make_pair(i, MENU_SELECT));
     }
-    
+
   } else {
     // map the last 2 buttons to menu and pause
     if(min_joybuttons > 2)
@@ -209,12 +209,12 @@ JoystickKeyboardController::read(const lisp::Lisp& lisp)
           log_warning << "Invalid button '" << button << "' in buttonmap" << std::endl;
           continue;
         }
-        
+
         int i = 0;
         for(i = 0; controlNames[i] != 0; ++i) {
           if(control == controlNames[i])
             break;
-        }                                                                           
+        }
         if(controlNames[i] == 0) {
           log_warning << "Invalid control '" << control << "' in buttonmap" << std::endl;
           continue;
@@ -249,7 +249,7 @@ JoystickKeyboardController::write(lisp::Writer& writer)
     writer.write_string("control", controlNames[i->second]);
     writer.end_list("map");
   }
-  writer.end_list("joystick");  
+  writer.end_list("joystick");
 }
 
 void
@@ -296,7 +296,7 @@ JoystickKeyboardController::process_event(const SDL_Event& event)
     case SDL_JOYHATMOTION:
       if(!use_hat)
         break;
-      
+
       if(event.jhat.value & SDL_HAT_UP) {
         controls[UP] = true;
         controls[DOWN] = false;
@@ -341,7 +341,7 @@ JoystickKeyboardController::process_event(const SDL_Event& event)
         log_debug << "Unmapped joybutton " << (int)event.jbutton.button << " pressed" << std::endl;
         return;
       }
-      
+
       controls[i->second] =
         event.type == SDL_JOYBUTTONDOWN ? true : false;
       break;
@@ -368,10 +368,10 @@ JoystickKeyboardController::process_key_event(const SDL_Event& event)
   if (Console::instance->hasFocus()) {
     process_console_key_event(event);
     return;
-  } 
+  }
 
   // if menu mode: send key there
-  if (Menu::current()) { 
+  if (Menu::current()) {
     process_menu_key_event(event);
     return;
   }
@@ -432,7 +432,7 @@ JoystickKeyboardController::process_menu_key_event(const SDL_Event& event)
     if(event.type == SDL_KEYUP)
       return;
 
-    if(event.key.keysym.sym != SDLK_ESCAPE                      
+    if(event.key.keysym.sym != SDLK_ESCAPE
         && event.key.keysym.sym != SDLK_PAUSE) {
       reset_key(event.key.keysym.sym, (Control) wait_for_key);
     }
@@ -440,7 +440,7 @@ JoystickKeyboardController::process_menu_key_event(const SDL_Event& event)
     key_options_menu->update();
     wait_for_key = -1;
     return;
-  } 
+  }
   if(wait_for_joybutton >= 0) {
     if(event.key.keysym.sym == SDLK_ESCAPE) {
       reset();
@@ -449,7 +449,7 @@ JoystickKeyboardController::process_menu_key_event(const SDL_Event& event)
     }
     return;
   }
+
   Control control;
   /* we use default keys when the menu is open (to avoid problems when
    * redefining keys to invalid settings
@@ -699,7 +699,7 @@ JoystickKeyboardController::JoystickMenu::get_button_name(int button)
 {
   if(button < 0)
     return _("None");
-    
+
   std::ostringstream name;
   name << "Button " << button;
   return name.str();
@@ -731,4 +731,3 @@ JoystickKeyboardController::JoystickMenu::update()
   get_item_by_id((int) Controller::PEEK_RIGHT).change_input(get_button_name(
     controller->reversemap_joybutton(Controller::PEEK_RIGHT)));
 }
-
index e113d42..7d88932 100644 (file)
@@ -50,12 +50,12 @@ private:
   void process_key_event(const SDL_Event& event);
   void process_console_key_event(const SDL_Event& event);
   void process_menu_key_event(const SDL_Event& event);
-  
+
   typedef std::map<SDLKey, Control> KeyMap;
   KeyMap keymap;
 
   std::vector<SDL_Joystick*> joysticks;
-    
+
   typedef std::map<int, Control> ButtonMap;
   ButtonMap joy_button_map;
   std::string name;
@@ -95,7 +95,7 @@ private:
 
   class KeyboardMenu;
   class JoystickMenu;
-  
+
   KeyboardMenu* key_options_menu;
   JoystickMenu* joystick_options_menu;
   friend class KeyboardMenu;
@@ -103,4 +103,3 @@ private:
 };
 
 #endif
-
index 25165e2..283771e 100644 (file)
@@ -54,4 +54,3 @@ FadeOut::done()
 {
   return accum_time >= fade_time;
 }
-
index 130cac0..b005b8c 100644 (file)
@@ -33,7 +33,7 @@ public:
 
   virtual void update(float elapsed_time);
   virtual void draw(DrawingContext& context);
-  
+
   /// returns true if the effect is completed
   virtual bool done();
 
@@ -44,4 +44,3 @@ private:
 };
 
 #endif
-
index cb8f426..266da81 100644 (file)
@@ -32,9 +32,9 @@ namespace FileSystem
 std::string dirname(const std::string& filename)
 {
   std::string::size_type p = filename.find_last_of('/');
-  if(p == std::string::npos)                              
+  if(p == std::string::npos)
     return "";
-  
+
   return filename.substr(0, p+1);
 }
 
@@ -76,11 +76,11 @@ std::string normalize(const std::string& filename)
     size_t len = p - pstart;
     if(len == 0)
       break;
-    
+
     std::string pathelem(pstart, p-pstart);
     if(pathelem == ".")
       continue;
-    
+
     if(pathelem == "..") {
       if(path_stack.empty()) {
 
@@ -108,4 +108,3 @@ std::string normalize(const std::string& filename)
 }
 
 }
-
index 9c14bac..b821188 100644 (file)
@@ -41,4 +41,3 @@ namespace FileSystem
 }
 
 #endif
-
index 0baa388..00d1004 100644 (file)
@@ -31,7 +31,7 @@ void
 FlipLevelTransformer::transform_sector(Sector* sector)
 {
   float height = sector->get_height();
-  
+
   for(Sector::GameObjects::iterator i = sector->gameobjects.begin();
       i != sector->gameobjects.end(); ++i) {
     GameObject* object = *i;
@@ -117,7 +117,7 @@ FlipLevelTransformer::transform_moving_object(float height, MovingObject*object)
   object->set_pos(pos);
 }
 
-void 
+void
 FlipLevelTransformer::transform_platform(float height, Platform& platform)
 {
   Path& path = platform.get_path();
@@ -127,7 +127,7 @@ FlipLevelTransformer::transform_platform(float height, Platform& platform)
   }
 }
 
-void 
+void
 FlipLevelTransformer::transform_block(float height, Block& block)
 {
   block.original_y = height - block.original_y - block.get_bbox().get_height();
index 7d4b05f..d9541ed 100644 (file)
@@ -59,14 +59,14 @@ public:
   {
     return !wants_to_die;
   }
-  
+
   /** schedules this object to be removed at the end of the frame */
   void remove_me()
   {
     wants_to_die = true;
   }
-  
-  /** registers a remove listener which will be called if the object 
+
+  /** registers a remove listener which will be called if the object
    * gets removed/destroyed
    */
   void add_remove_listener(ObjectRemoveListener* listener)
@@ -77,18 +77,18 @@ public:
 
     remove_listeners = entry;
   }
-  
+
   // flags
   enum {
     /// the tile so you can stand on it
     FLAG_SOLID       = (1 << 0),
     /// the object can be carried around (inherits from Portable)
     FLAG_PORTABLE    = (1 << 1)
-  };                     
+  };
 
   int get_flags() const
   {
-    return flags;            
+    return flags;
   }
 
 private:
@@ -109,4 +109,3 @@ protected:
 };
 
 #endif /*SUPERTUX_GAMEOBJECT_H*/
-
index fe24f25..c2aaebd 100644 (file)
@@ -90,7 +90,7 @@ GameSession::GameSession(const std::string& levelfile_, Statistics* statistics)
 {
   current_ = this;
   currentsector = NULL;
-  
+
   game_pause = false;
 
   statistics_backdrop.reset(new Surface("images/engine/menu/score-backdrop.png"));
@@ -122,7 +122,8 @@ GameSession::restart_level(bool fromBeginning)
   level->stats.total_badguys = level->get_total_badguys();
   level->stats.total_secrets = level->get_total_count<SecretAreaTrigger>();
   level->stats.reset();
-  if (!fromBeginning) level->stats.declare_invalid();
+  if (!fromBeginning)
+    level->stats.declare_invalid();
 
   if (fromBeginning) reset_sector="";
   if(reset_sector != "") {
@@ -139,7 +140,7 @@ GameSession::restart_level(bool fromBeginning)
       throw std::runtime_error("Couldn't find main sector");
     currentsector->activate("main");
   }
-  
+
   //levelintro();
 
   currentsector->play_music(LEVEL_MUSIC);
@@ -169,8 +170,8 @@ void
 GameSession::record_demo(const std::string& filename)
 {
   delete capture_demo_stream;
-  
-  capture_demo_stream = new std::ofstream(filename.c_str()); 
+
+  capture_demo_stream = new std::ofstream(filename.c_str());
   if(!capture_demo_stream->good()) {
     std::stringstream msg;
     msg << "Couldn't open demo file '" << filename << "' for writing.";
@@ -208,7 +209,7 @@ GameSession::play_demo(const std::string& filename)
 {
   delete playback_demo_stream;
   delete demo_controller;
-  
+
   playback_demo_stream = new std::ifstream(filename.c_str());
   if(!playback_demo_stream->good()) {
     std::stringstream msg;
@@ -259,7 +260,7 @@ GameSession::levelintro()
 
   if((level->get_author().size()) && (level->get_author() != "SuperTux Team"))
     context.draw_text(white_small_text,
-      std::string(_("contributed by ")) + level->get_author(), 
+      std::string(_("contributed by ")) + level->get_author(),
       Vector(SCREEN_WIDTH/2, 350), CENTER_ALLIGN, LAYER_FOREGROUND1);
 
   if(best_level_statistics != NULL)
@@ -281,7 +282,7 @@ GameSession::on_escape_press()
     toggle_pause();
   }
 }
-  
+
 void
 GameSession::toggle_pause()
 {
@@ -342,9 +343,9 @@ GameSession::process_events()
     }
 
     end_sequence_controller->press(Controller::RIGHT);
-    
+
     if (int(last_x_pos) == int(tux.get_pos().x))
-      end_sequence_controller->press(Controller::JUMP);    
+      end_sequence_controller->press(Controller::JUMP);
     last_x_pos = tux.get_pos().x;
   }
 
@@ -377,7 +378,7 @@ GameSession::process_events()
     capture_demo_stream ->put(main_controller->hold(Controller::RIGHT));
     capture_demo_stream ->put(main_controller->hold(Controller::UP));
     capture_demo_stream ->put(main_controller->hold(Controller::DOWN));
-    capture_demo_stream ->put(main_controller->hold(Controller::JUMP));   
+    capture_demo_stream ->put(main_controller->hold(Controller::JUMP));
     capture_demo_stream ->put(main_controller->hold(Controller::ACTION));
   }
 }
@@ -392,20 +393,20 @@ GameSession::check_end_conditions()
     finish(true);
     return;
   } else if (!end_sequence && tux->is_dead()) {
-    if (player_status->coins < 0) { 
+    if (player_status->coins < 0) {
       // No more coins: restart level from beginning
       player_status->coins = 0;
       restart_level(true);
-    } else { 
+    } else {
       // Still has coins: restart level from last reset point
       restart_level(false);
     }
-    
+
     return;
   }
 }
 
-void 
+void
 GameSession::draw(DrawingContext& context)
 {
   currentsector->draw(context);
@@ -422,7 +423,7 @@ GameSession::draw_pause(DrawingContext& context)
       Vector(0,0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
       Color(.2, .2, .2, .5), LAYER_FOREGROUND1);
 }
-  
+
 void
 GameSession::process_menu()
 {
@@ -462,7 +463,7 @@ GameSession::update(float elapsed_time)
   // handle controller
   if(main_controller->pressed(Controller::PAUSE_MENU))
     on_escape_press();
-  
+
   process_events();
   process_menu();
 
@@ -483,14 +484,9 @@ GameSession::update(float elapsed_time)
 
   // Update the world state and all objects in the world
   if(!game_pause) {
-    // Update the world
-    if (end_sequence == ENDSEQUENCE_RUNNING) {
-      currentsector->update(elapsed_time/2);
-    } else if(end_sequence == NO_ENDSEQUENCE) {
-      play_time += elapsed_time; //TODO: make sure we don't count cutscene time
-      level->stats.time = play_time;
-      currentsector->update(elapsed_time);
-    } 
+    currentsector->update(elapsed_time * speed_factor);
+    play_time += elapsed_time;
+    currentsector->update(elapsed_time);
   }
 
   // update sounds
@@ -499,7 +495,7 @@ GameSession::update(float elapsed_time)
   /* Handle music: */
   if (end_sequence)
     return;
-  
+
   if(currentsector->player->invincible_timer.started()) {
     if(currentsector->player->invincible_timer.get_timeleft() <=
        TUX_INVINCIBLE_TIME_WARNING) {
@@ -521,7 +517,7 @@ GameSession::finish(bool win)
     if(WorldMap::current())
       WorldMap::current()->finished_level(level.get());
   }
-  
+
   main_loop->exit_screen();
 }
 
@@ -552,7 +548,7 @@ GameSession::display_info_box(const std::string& text)
 
   bool running = true;
   DrawingContext context;
-  
+
   while(running)  {
 
     // TODO make a screen out of this, another mainloop is ugly
@@ -589,6 +585,7 @@ GameSession::start_sequence(const std::string& sequencename)
     if(end_sequence)
       return;
 
+    speed_factor = 0.5;
     end_sequence = ENDSEQUENCE_RUNNING;
     endsequence_timer.start(7.3);
     last_x_pos = -1;
@@ -631,4 +628,3 @@ GameSession::drawstatus(DrawingContext& context)
     level->stats.draw_endseq_panel(context, best_level_statistics, statistics_backdrop.get());
   }
 }
-
index 59a4642..92a0b69 100644 (file)
@@ -63,7 +63,7 @@ public:
   void respawn(const std::string& sectorname, const std::string& spawnpointname);
   void set_reset_point(const std::string& sectorname, const Vector& pos);
   void display_info_box(const std::string& text);
-  
+
   Sector* get_current_sector()
   { return currentsector; }
 
@@ -82,6 +82,12 @@ public:
 
   void toggle_pause();
 
+  /**
+   * Allows adjusting the game speed with a factor. 1.0 means normal speed
+   * 0.0 means the game is stopped.
+   */
+  void adjust_game_speed(float factor);
+
 private:
   void check_end_conditions();
   void process_events();
@@ -127,6 +133,9 @@ private:
   std::string reset_sector;
   Vector reset_pos;
 
+  /// speed factos
+  float speed_factor;
+
   // the sector and spawnpoint we should spawn after this frame
   std::string newsector;
   std::string newspawnpoint;
@@ -146,4 +155,3 @@ private:
 };
 
 #endif /*SUPERTUX_GAMELOOP_H*/
-
index c2d1431..f4c28ca 100644 (file)
@@ -110,6 +110,6 @@ Config::save()
     main_controller->write(writer);
     writer.end_list("control");
   }
-  
+
   writer.end_list("supertux-config");
 }
index 1602787..7865c4d 100644 (file)
@@ -26,7 +26,7 @@ class Config
 public:
   Config();
   ~Config();
-  
+
   void load();
   void save();
 
index a3353e1..a2bd003 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published
    by the Free Software Foundation; either version 2, or (at your option)
index 148ac84..05ef76c 100644 (file)
@@ -61,7 +61,7 @@ if(state == BT_SHOW_INFO)
     offset = Vector(size.x, - 10);
   else if(pos.x + tanslation.x < 100)
     offset = Vector(size.x, 0);
-  else 
+  else
     offset = Vector(-30, -size.y/2);
   context.draw_text(info_font, info, pos + offset, LEFT_ALLIGN, LAYER_GUI+2);
   if(binding != 0)
@@ -178,7 +178,7 @@ switch(event.type)
 
     if(mouse_left_button)
       {
-      pos.x += int(event.motion.xrel * float(SCREEN_WIDTH)/screen->w); 
+      pos.x += int(event.motion.xrel * float(SCREEN_WIDTH)/screen->w);
       pos.y += int(event.motion.yrel * float(SCREEN_HEIGHT)/screen->h);
       caught_event = true;
       }
index 6f086b9..b81f51d 100644 (file)
@@ -42,7 +42,7 @@ class Button
 public:
   Button(Surface* image_, std::string info_, SDLKey binding_);
   ~Button();
-  
+
   void draw(DrawingContext& context, bool selected);
   int event(SDL_Event& event, int x_offset = 0, int y_offset = 0);
 
@@ -72,7 +72,7 @@ public:
 
   void add_button(Button button, int id, bool select = false);
   void add_pair_of_buttons(Button button1, int id1, Button button2, int id2);
-  
+
   int selected_id();
   void set_unselected();
   bool is_hover();
index 1738a26..1fb5ae6 100644 (file)
@@ -64,7 +64,7 @@ bool confirm_dialog(Surface *background, std::string text)
   dialog->add_entry(true, _("Yes"));
   dialog->add_entry(false, _("No"));
   dialog->add_hl();
-  
+
   Menu::set_current(dialog);
 
   DrawingContext context;
@@ -234,7 +234,7 @@ Menu::additem(MenuItem* item)
    * selectable item added
    */
   if (active_item == -1
-      && item->kind != MN_HL 
+      && item->kind != MN_HL
       && item->kind != MN_LABEL
       && item->kind != MN_DEACTIVE) {
     active_item = items.size() - 1;
@@ -327,16 +327,16 @@ Menu::update()
     menuaction = MENU_ACTION_UP;
     menu_repeat_time = real_time + MENU_REPEAT_INITIAL;
   }
-  if(main_controller->hold(Controller::UP) && 
+  if(main_controller->hold(Controller::UP) &&
       menu_repeat_time != 0 && real_time > menu_repeat_time) {
     menuaction = MENU_ACTION_UP;
     menu_repeat_time = real_time + MENU_REPEAT_RATE;
-  } 
+  }
   if(main_controller->pressed(Controller::DOWN)) {
     menuaction = MENU_ACTION_DOWN;
     menu_repeat_time = real_time + MENU_REPEAT_INITIAL;
   }
-  if(main_controller->hold(Controller::DOWN) && 
+  if(main_controller->hold(Controller::DOWN) &&
       menu_repeat_time != 0 && real_time > menu_repeat_time) {
     menuaction = MENU_ACTION_DOWN;
     menu_repeat_time = real_time + MENU_REPEAT_RATE;
@@ -353,7 +353,7 @@ Menu::update()
   hit_item = -1;
   if(items.size() == 0)
     return;
-  
+
   int last_active_item = active_item;
   switch(menuaction) {
     case MENU_ACTION_UP:
@@ -362,13 +362,13 @@ Menu::update()
           --active_item;
         else
           active_item = int(items.size())-1;
-      } while ((items[active_item]->kind == MN_HL 
+      } while ((items[active_item]->kind == MN_HL
                 || items[active_item]->kind == MN_LABEL
                 || items[active_item]->kind == MN_DEACTIVE)
                && (active_item != last_active_item));
-      
+
       break;
-      
+
     case MENU_ACTION_DOWN:
       do {
         if(active_item < int(items.size())-1 )
@@ -379,9 +379,9 @@ Menu::update()
                 || items[active_item]->kind == MN_LABEL
                 || items[active_item]->kind == MN_DEACTIVE)
                && (active_item != last_active_item));
-      
+
       break;
-      
+
     case MENU_ACTION_LEFT:
       if(items[active_item]->kind == MN_STRINGSELECT) {
         if(items[active_item]->selected > 0)
@@ -390,7 +390,7 @@ Menu::update()
           items[active_item]->selected = items[active_item]->list.size()-1;
       }
       break;
-      
+
     case MENU_ACTION_RIGHT:
       if(items[active_item]->kind == MN_STRINGSELECT) {
         if(items[active_item]->selected+1 < items[active_item]->list.size())
@@ -399,7 +399,7 @@ Menu::update()
           items[active_item]->selected = 0;
       }
       break;
-      
+
     case MENU_ACTION_HIT: {
       hit_item = active_item;
       switch (items[active_item]->kind) {
@@ -407,26 +407,26 @@ Menu::update()
           assert(items[active_item]->target_menu != 0);
           Menu::push_current(items[active_item]->target_menu);
           break;
-          
+
         case MN_TOGGLE:
           items[active_item]->toggled = !items[active_item]->toggled;
           menu_action(items[active_item]);
           break;
-          
+
         case MN_CONTROLFIELD:
           menu_action(items[active_item]);
           break;
-          
+
         case MN_ACTION:
           menu_action(items[active_item]);
           break;
-          
+
         case MN_TEXTFIELD:
         case MN_NUMFIELD:
           menuaction = MENU_ACTION_DOWN;
           update();
           break;
-          
+
         case MN_BACK:
           Menu::pop_current();
           break;
@@ -435,7 +435,7 @@ Menu::update()
       }
       break;
     }
-    
+
     case MENU_ACTION_REMOVE:
       if(items[active_item]->kind == MN_TEXTFIELD
          || items[active_item]->kind == MN_NUMFIELD)
@@ -443,7 +443,7 @@ Menu::update()
         if(!items[active_item]->input.empty())
         {
           int i = items[active_item]->input.size();
-          
+
           while(delete_character > 0)  /* remove charactes */
           {
             items[active_item]->input.resize(i-1);
@@ -452,16 +452,16 @@ Menu::update()
         }
       }
       break;
-      
+
     case MENU_ACTION_INPUT:
       if(items[active_item]->kind == MN_TEXTFIELD
-         || (items[active_item]->kind == MN_NUMFIELD 
+         || (items[active_item]->kind == MN_NUMFIELD
              && mn_input_char >= '0' && mn_input_char <= '9'))
       {
         items[active_item]->input.push_back(mn_input_char);
       }
       break;
-      
+
     case MENU_ACTION_BACK:
       Menu::pop_current();
       break;
@@ -491,7 +491,7 @@ void
 Menu::draw_item(DrawingContext& context, int index)
 {
   float menu_height = get_height();
-  float menu_width = get_width();  
+  float menu_width = get_width();
 
   MenuItem& pitem = *(items[index]);
 
@@ -515,7 +515,7 @@ Menu::draw_item(DrawingContext& context, int index)
   if(pitem.list.size() > 0) {
     list_width = (int) text_font->get_text_width(pitem.list[pitem.selected]);
   }
-  
+
   if (arrange_left)
     x_pos += 24 - menu_width/2 + (text_width + input_width + list_width)/2;
 
@@ -684,11 +684,11 @@ float Menu::get_width() const
         label_font->get_text_width(items[i]->input) + 16;
     if(items[i]->kind == MN_TOGGLE)
       w += 32;
-    
+
     if(w > menu_width)
       menu_width = w;
   }
-  
+
   return menu_width + 24;
 }
 
@@ -704,9 +704,9 @@ Menu::draw(DrawingContext& context)
   if(MouseCursor::current()) {
     MouseCursor::current()->draw(context);
   }
-  
+
   float menu_height = get_height();
-  float menu_width = get_width();  
+  float menu_width = get_width();
 
   /* Draw a transparent background */
   context.draw_filled_rect(
@@ -726,7 +726,7 @@ Menu::get_item_by_id(int id)
   for(std::vector<MenuItem*>::iterator i = items.begin();
       i != items.end(); ++i) {
     MenuItem& item = **i;
-    
+
     if(item.id == id)
       return item;
   }
@@ -740,7 +740,7 @@ Menu::get_item_by_id(int id) const
   for(std::vector<MenuItem*>::const_iterator i = items.begin();
       i != items.end(); ++i) {
     const MenuItem& item = **i;
-    
+
     if(item.id == id)
       return item;
   }
@@ -792,15 +792,15 @@ Menu::event(const SDL_Event& event)
             y > pos_y - get_height()/2 &&
             y < pos_y + get_height()/2)
           {
-            int new_active_item 
+            int new_active_item
               = static_cast<int> ((y - (pos_y - get_height()/2)) / 24);
-          
+
             /* only change the mouse focus to a selectable item */
             if ((items[new_active_item]->kind != MN_HL)
                 && (items[new_active_item]->kind != MN_LABEL)
                 && (items[new_active_item]->kind != MN_DEACTIVE))
               active_item = new_active_item;
-            
+
             if(MouseCursor::current())
               MouseCursor::current()->set_state(MC_LINK);
           }
index 55d97e2..5e85fa1 100644 (file)
@@ -57,22 +57,22 @@ class MenuItem
 public:
   MenuItem(MenuItemKind kind, int id = -1);
   MenuItemKind kind;
-  int id;   // item id      
+  int id;   // item id
   bool toggled;
   std::string text;
   std::string input;
-  
+
   std::vector<std::string> list; // list of values for a STRINGSELECT item
   size_t selected; // currently selected item
-  
+
   Menu* target_menu;
-  
+
   void change_text (const std::string& text);
   void change_input(const std::string& text);
-  
+
   static MenuItem* create(MenuItemKind kind, const std::string& text,
                           int init_toggle, Menu* target_menu, int id, int key);
-  
+
   std::string get_input_with_symbol(bool active_item);   // returns the text with an input symbol
 
 private:
@@ -90,21 +90,21 @@ class Menu
 private:
   static std::vector<Menu*> last_menus;
   static Menu* current_;
-  
+
   static void pop_current();
-  
+
 public:
   /** Set the current menu, if pmenu is NULL, hide the current menu */
   static void set_current(Menu* pmenu);
 
-  static void push_current(Menu* pmenu); 
-  
+  static void push_current(Menu* pmenu);
+
   /** Return the current active menu or NULL if none is active */
   static Menu* current()
   {
     return current_;
   }
-  
+
 private:
   /* Action done on the menu */
   enum MenuAction {
@@ -118,18 +118,18 @@ private:
     MENU_ACTION_REMOVE,
     MENU_ACTION_BACK
   };
-  
+
   /** Number of the item that got 'hit' (ie. pressed) in the last
       event()/update() call, -1 if none */
   int hit_item;
-  
+
   // position of the menu (ie. center of the menu, not top/left)
   float pos_x;
   float pos_y;
-  
+
   /** input event for the menu (up, down, left, right, etc.) */
   MenuAction menuaction;
-  
+
   /* input implementation variables */
   int delete_character;
   char mn_input_char;
@@ -143,10 +143,10 @@ public:
   static Font* field_font;
 
   std::vector<MenuItem*> items;
-  
+
   Menu();
   virtual ~Menu();
-  
+
   void add_hl();
   void add_label(const std::string& text);
   void add_entry(int id, const std::string& text);
@@ -158,40 +158,40 @@ public:
                        const std::string& mapping = "");
 
   virtual void menu_action(MenuItem* item);
-  
+
   void update();
-  
+
   /** Remove all entries from the menu */
   void clear();
-  
+
   /** Return the index of the menu item that was 'hit' (ie. the user
       clicked on it) in the last event() call */
   int check ();
-  
+
   MenuItem& get_item(int index)
   {
     return *(items[index]);
   }
   MenuItem& get_item_by_id(int id);
   const MenuItem& get_item_by_id(int id) const;
-  
+
   int get_active_item_id();
   void set_active_item(int id);
-  
-  void draw(DrawingContext& context);  
+
+  void draw(DrawingContext& context);
   void set_pos(float x, float y, float rw = 0, float rh = 0);
-  
+
   void event(const SDL_Event& event);
 
   bool is_toggled(int id) const;
 
 protected:
-  void additem(MenuItem* pmenu_item);  
+  void additem(MenuItem* pmenu_item);
   float get_width() const;
   float get_height() const;
 
 private:
-  void check_controlfield_change_event(const SDL_Event& event);  
+  void check_controlfield_change_event(const SDL_Event& event);
   void draw_item(DrawingContext& context, int index);
   float effect_time;
   int arrange_left;
index 902f867..b2010c5 100644 (file)
@@ -29,7 +29,7 @@ extern SDL_Surface* screen;
 MouseCursor::MouseCursor(std::string cursor_file) : mid_x(0), mid_y(0)
 {
   cursor = new Surface(cursor_file);
-  
+
   cur_state = MC_NORMAL;
 
   SDL_ShowCursor(SDL_DISABLE);
index 49b9e8f..b3cb53b 100644 (file)
@@ -25,7 +25,7 @@
 #include "video/surface.hpp"
 
 #define MC_STATES_NB 3
+
 enum {
   MC_NORMAL = 0,
   MC_CLICK,
index dccfbd8..1a81bca 100644 (file)
@@ -93,7 +93,7 @@ Level::load(const std::string& filepath)
         continue;
       }
     }
-    
+
   } catch(std::exception& e) {
     std::stringstream msg;
     msg << "Problem when reading level '" << filepath << "': " << e.what();
index 2b8b14b..a9366f5 100644 (file)
@@ -34,4 +34,3 @@ LevelTransformer::transform(Level* level)
     transform_sector(level->get_sector(i));
   }
 }
-
index b178ecd..53f06b7 100644 (file)
@@ -32,9 +32,9 @@ class LevelTransformer
 {
 public:
   virtual ~LevelTransformer();
-  
+
   /** transform a complete Level, the standard implementation just calls
-   * transformSector on each sector in the level. 
+   * transformSector on each sector in the level.
    */
   virtual void transform(Level* level);
 
@@ -42,4 +42,3 @@ public:
 };
 
 #endif
-
index 05d687b..de3243e 100644 (file)
@@ -57,7 +57,7 @@ Lexer::nextChar()
       throw EOFException();
     stream.read(buffer, BUFFER_SIZE);
     size_t bytes_read = stream.gcount();
-    
+
     c = buffer;
     bufend = buffer + bytes_read;
 
@@ -83,9 +83,9 @@ Lexer::getNextToken()
         ++linenumber;
       nextChar();
     };
-    
+
     token_length = 0;
-    
+
     switch(*c) {
       case ';': // comment
         while(true) {
@@ -138,7 +138,7 @@ Lexer::getNextToken()
       case '#': // constant
         try {
           nextChar();
-          
+
           while(isalnum(*c) || *c == '_') {
             if(token_length < MAX_TOKEN_LENGTH)
               token_string[token_length++] = *c;
@@ -171,15 +171,15 @@ Lexer::getNextToken()
           bool have_nondigits = false;
           bool have_digits = false;
           int have_floating_point = 0;
-          
+
           do {
             if(isdigit(*c))
               have_digits = true;
             else if(*c == '.')
               ++have_floating_point;
             else if(isalnum(*c) || *c == '_')
-              have_nondigits = true;  
-            
+              have_nondigits = true;
+
             if(token_length < MAX_TOKEN_LENGTH)
               token_string[token_length++] = *c;
 
@@ -187,7 +187,7 @@ Lexer::getNextToken()
           } while(!isspace(*c) && !strchr(delims, *c));
 
           token_string[token_length] = 0;
-          
+
           // no nextChar
 
           if(have_nondigits || !have_digits || have_floating_point > 1)
@@ -203,11 +203,11 @@ Lexer::getNextToken()
             nextChar();
           } while(!isspace(*c) && !strchr(delims, *c));
           token_string[token_length] = 0;
-          
+
           // no nextChar
 
           return TOKEN_SYMBOL;
-        }       
+        }
     }
   } catch(EOFException& ) {
     return TOKEN_EOF;
@@ -215,4 +215,3 @@ Lexer::getNextToken()
 }
 
 } // end of namespace lisp
-
index 8128b13..f541abd 100644 (file)
@@ -37,7 +37,7 @@ public:
     TOKEN_TRUE,
     TOKEN_FALSE
   };
-    
+
   Lexer(std::istream& stream);
   ~Lexer();
 
@@ -46,15 +46,15 @@ public:
   { return token_string; }
   int getLineNumber() const
   { return linenumber; }
-    
+
 private:
   enum {
     MAX_TOKEN_LENGTH = 16384,
     BUFFER_SIZE = 1024
   };
-    
+
   inline void nextChar();
-    
+
   std::istream& stream;
   bool eof;
   int linenumber;
@@ -68,4 +68,3 @@ private:
 } // end of namespace lisp
 
 #endif
-
index fcf5cee..39313d2 100644 (file)
@@ -23,7 +23,7 @@
 
 namespace lisp
 {
-    
+
 Lisp::Lisp(LispType newtype)
   : type(newtype)
 {
@@ -65,7 +65,7 @@ Lisp::print(int indent) const
 {
   for(int i = 0; i < indent; ++i)
     printf(" ");
-  
+
   if(type == TYPE_CONS) {
     printf("(\n");
     const Lisp* lisp = this;
index 2f14625..c01170f 100644 (file)
@@ -31,7 +31,7 @@ class Lisp
 {
 public:
   ~Lisp();
-    
+
   enum LispType {
     TYPE_CONS,
     TYPE_SYMBOL,
@@ -42,27 +42,27 @@ public:
   };
 
   LispType get_type() const
-  { return type; } 
+  { return type; }
 
   Lisp* get_car() const
   { return v.cons.car; }
   Lisp* get_cdr() const
   { return v.cons.cdr; }
-  
+
   bool get(std::string& val) const
-  { 
+  {
     if(type != TYPE_STRING && type != TYPE_SYMBOL)
       return false;
     val = v.string;
     return true;
   }
-  
+
   std::string get_string() const
   {
     assert(type == TYPE_STRING);
     return v.string;
   }
-  
+
   bool get(unsigned int& val) const
   {
     if(type != TYPE_INTEGER)
@@ -70,7 +70,7 @@ public:
     val = v.integer;
     return true;
   }
-  
+
   bool get(int& val) const
   {
     if(type != TYPE_INTEGER)
@@ -84,7 +84,7 @@ public:
     assert(type == TYPE_INTEGER);
     return v.integer;
   }
-  
+
   bool get(float& val) const
   {
     if(type != TYPE_REAL) {
@@ -145,11 +145,11 @@ public:
   bool get_vector(const char* name, std::vector<T>& vec) const
   {
     vec.clear();
-    
+
     const Lisp* child = get_lisp(name);
     if(!child)
       return false;
-    
+
     for( ; child != 0; child = child->get_cdr()) {
       T val;
       if(!child->get_car())
@@ -158,10 +158,10 @@ public:
         vec.push_back(val);
       }
     }
-    
+
     return true;
   }
-  
+
   Lisp* get_lisp(const char* name) const;
   Lisp* get_lisp(const std::string& name) const
   { return get_lisp(name.c_str()); }
@@ -192,4 +192,3 @@ private:
 } // end of namespace lisp
 
 #endif
-
index c11594e..092b672 100644 (file)
@@ -33,7 +33,7 @@ class ListIterator
 {
 public:
   ListIterator(const lisp::Lisp* cur);
-  
+
   const std::string& item() const
   { return current_item; }
   lisp::Lisp* lisp() const
@@ -51,4 +51,3 @@ private:
 }
 
 #endif
-
index dbed7ac..d108ba0 100644 (file)
@@ -71,7 +71,7 @@ Parser::parse(const std::string& filename)
     dictionary_manager->add_directory(dirname(filename));
     dictionary = & (dictionary_manager->get_dictionary());
   }
-  
+
   return parse(in);
 }
 
@@ -85,11 +85,11 @@ Parser::parse(std::istream& stream)
   Lisp* result = new Lisp(Lisp::TYPE_CONS);
   result->v.cons.car = read();
   result->v.cons.cdr = 0;
-  
+
   delete lexer;
   lexer = 0;
 
-  return result;    
+  return result;
 }
 
 Lisp*
@@ -111,7 +111,7 @@ Parser::read()
     }
     case Lexer::TOKEN_OPEN_PAREN: {
       result = new Lisp(Lisp::TYPE_CONS);
-      
+
       token = lexer->getNextToken();
       if(token == Lexer::TOKEN_CLOSE_PAREN) {
         result->v.cons.car = 0;
@@ -125,14 +125,14 @@ Parser::read()
         token = lexer->getNextToken();
         if(token != Lexer::TOKEN_STRING)
           throw std::runtime_error("Expected string after '(_'");
-        
+
         result = new Lisp(Lisp::TYPE_STRING);
         if(dictionary) {
           std::string translation = dictionary->translate(lexer->getString());
           result->v.string = new char[translation.size()+1];
           memcpy(result->v.string, translation.c_str(), translation.size()+1);
         } else {
-          size_t len = strlen(lexer->getString()) + 1;                                
+          size_t len = strlen(lexer->getString()) + 1;
           result->v.string = new char[len];
           memcpy(result->v.string, lexer->getString(), len);
         }
index b6d0209..fc808b1 100644 (file)
@@ -44,7 +44,7 @@ public:
 
 private:
   Lisp* read();
-    
+
   Lexer* lexer;
   TinyGetText::DictionaryManager* dictionary_manager;
   TinyGetText::Dictionary* dictionary;
@@ -54,4 +54,3 @@ private:
 } // end of namespace lisp
 
 #endif
-
index 4126b7f..5792c47 100644 (file)
@@ -34,7 +34,7 @@ Writer::Writer(const std::string& filename)
   out_owned = true;
   indent_depth = 0;
 }
-  
+
 Writer::Writer(std::ostream* newout)
 {
   out = newout;
@@ -84,7 +84,7 @@ Writer::end_list(const std::string& listname)
     return;
   }
   lists.pop_back();
-  
+
   indent_depth -= 2;
   indent();
   *out << ")\n";
index 758a70e..ba5d327 100644 (file)
@@ -59,8 +59,7 @@ namespace lisp
     int indent_depth;
     std::vector<std::string> lists;
   };
-  
+
 } //namespace lisp
 
 #endif //SUPERTUX_LISPWRITER_H
-
index 9b03ff8..ca54b1d 100644 (file)
@@ -35,4 +35,3 @@ std::ostream& operator<<(std::ostream& out, const Rect& rect)
              << rect.get_right() << "," << rect.get_bottom() << "]";
   return out;
 }
-
index 4d4b74b..7093dc0 100644 (file)
@@ -85,4 +85,3 @@ class Rect;
 std::ostream& operator<< (std::ostream& str, const Rect& rect);
 
 #endif
-
index 1eadf1a..fabccdd 100644 (file)
@@ -99,17 +99,17 @@ static void init_physfs(const char* argv0)
     sprintf(mkdir, ".%s", application);
     if(!PHYSFS_setWriteDir(userdir) || !PHYSFS_mkdir(mkdir)) {
       std::ostringstream msg;
-      msg << "Failed creating configuration directory '" 
+      msg << "Failed creating configuration directory '"
           << writedir << "': " << PHYSFS_getLastError();
       delete[] writedir;
       delete[] mkdir;
       throw std::runtime_error(msg.str());
     }
     delete[] mkdir;
-    
+
     if(!PHYSFS_setWriteDir(writedir)) {
       std::ostringstream msg;
-      msg << "Failed to use configuration directory '" 
+      msg << "Failed to use configuration directory '"
           <<  writedir << "': " << PHYSFS_getLastError();
       delete[] writedir;
       throw std::runtime_error(msg.str());
@@ -136,7 +136,7 @@ static void init_physfs(const char* argv0)
       }
     }
   }
-  
+
   PHYSFS_freeList(rc);
 
   // when started from source dir...
@@ -302,12 +302,12 @@ void init_video()
 {
   if(texture_manager != NULL)
     texture_manager->save_textures();
-  
-  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 
+
+  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
   SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
   SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
   SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
-  
+
   int flags = SDL_OPENGL;
   if(config->use_fullscreen)
     flags |= SDL_FULLSCREEN;
@@ -365,7 +365,7 @@ void init_video()
 static void init_audio()
 {
   sound_manager = new SoundManager();
-  
+
   sound_manager->enable_sound(config->sound_enabled);
   sound_manager->enable_music(config->music_enabled);
 }
@@ -381,7 +381,7 @@ static void quit_audio()
 void wait_for_event(float min_delay, float max_delay)
 {
   assert(min_delay <= max_delay);
-  
+
   Uint32 min = (Uint32) (min_delay * 1000);
   Uint32 max = (Uint32) (max_delay * 1000);
 
@@ -425,7 +425,7 @@ static const char* last_timelog_component = 0;
 static inline void timelog(const char* component)
 {
   Uint32 current_ticks = SDL_GetTicks();
-  
+
   if(last_timelog_component != 0) {
     log_info << "Component '" << last_timelog_component <<  "' finished after " << (current_ticks - last_timelog_ticks) / 1000.0 << " seconds" << std::endl;
   }
@@ -439,17 +439,17 @@ static inline void timelog(const char* )
 }
 #endif
 
-int main(int argc, char** argv) 
+int main(int argc, char** argv)
 {
   int result = 0;
-    
+
   try {
     Console::instance = new Console();
     init_physfs(argv[0]);
     init_sdl();
-    
+
     timelog("controller");
-    main_controller = new JoystickKeyboardController();    
+    main_controller = new JoystickKeyboardController();
     timelog("config");
     init_config();
     timelog("tinygettext");
@@ -461,14 +461,14 @@ int main(int argc, char** argv)
     init_audio();
     timelog("video");
     init_video();
-    Console::instance->init_graphics(); 
+    Console::instance->init_graphics();
     timelog("scripting");
     Scripting::init_squirrel(config->enable_script_debugger);
     timelog("resources");
-    load_shared(); 
+    load_shared();
     timelog(0);
 
-    main_loop = new MainLoop(); 
+    main_loop = new MainLoop();
     if(config->start_level != "") {
       // we have a normal path specified at commandline not physfs paths.
       // So we simply mount that path here...
@@ -485,7 +485,7 @@ int main(int argc, char** argv)
         // rain particles before we do this:
         std::auto_ptr<GameSession> session (
                 new GameSession(FileSystem::basename(config->start_level)));
-        
+
         config->random_seed =session->get_demo_random_seed(config->start_demo);
         init_rand();//initialise generator with seed from session
 
@@ -532,6 +532,6 @@ int main(int argc, char** argv)
   texture_manager = NULL;
   SDL_Quit();
   PHYSFS_deinit();
-  
+
   return result;
 }
index f9a54f1..9f8be24 100644 (file)
@@ -115,21 +115,21 @@ MainLoop::draw_fps(DrawingContext& context, float fps_fps)
   snprintf(str, sizeof(str), "%3.1f", fps_fps);
   const char* fpstext = "FPS";
   context.draw_text(white_text, fpstext, Vector(SCREEN_WIDTH - white_text->get_text_width(fpstext) - gold_text->get_text_width(" 99999") - BORDER_X, BORDER_Y + 20), LEFT_ALLIGN, LAYER_FOREGROUND1);
-  context.draw_text(gold_text, str, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y + 20), RIGHT_ALLIGN, LAYER_FOREGROUND1);                    
+  context.draw_text(gold_text, str, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y + 20), RIGHT_ALLIGN, LAYER_FOREGROUND1);
 }
 
 void
 MainLoop::run()
 {
-  DrawingContext context; 
-  
+  DrawingContext context;
+
   unsigned int frame_count = 0;
   float fps_fps = 0;
   Uint32 fps_ticks = SDL_GetTicks();
   Uint32 fps_nextframe_ticks = SDL_GetTicks();
   Uint32 ticks;
   bool skipdraw = false;
-  
+
   running = true;
   while(running) {
     while( (next_screen.get() != NULL || nextpop == true) &&
@@ -149,7 +149,7 @@ MainLoop::run()
       if(nextpush && current_screen.get() != NULL) {
         screen_stack.push_back(current_screen.release());
       }
+
       nextpush = false;
       nextpop = false;
       speed = 1.0;
@@ -163,7 +163,7 @@ MainLoop::run()
 
     if(!running || current_screen.get() == NULL)
       break;
-      
+
     float elapsed_time = 1.0 / LOGICAL_FPS;
     ticks = SDL_GetTicks();
     if(ticks > fps_nextframe_ticks) {
@@ -206,7 +206,7 @@ MainLoop::run()
       if(config->show_fps)
       {
         ++frame_count;
-        
+
         if(SDL_GetTicks() - fps_ticks >= 500)
         {
           fps_fps = (float) frame_count / .5;
@@ -219,14 +219,14 @@ MainLoop::run()
     real_time += elapsed_time;
     elapsed_time *= speed;
     game_time += elapsed_time;
-    
+
     Scripting::update_debugger();
     Scripting::TimeScheduler::instance->update(game_time);
     current_screen->update(elapsed_time);
     if(screen_fade.get() != NULL)
       screen_fade->update(elapsed_time);
     Console::instance->update(elapsed_time);
+
     main_controller->update();
     SDL_Event event;
     while(SDL_PollEvent(&event)) {
@@ -242,4 +242,3 @@ MainLoop::run()
     //log_info << "== periodic rand() = " << systemRandom.rand() << std::endl;
   }
 }
-
index 47621f3..a69baaf 100644 (file)
@@ -33,7 +33,7 @@ class MainLoop
 public:
   MainLoop();
   ~MainLoop();
-  
+
   void run();
   void exit_screen(ScreenFade* fade = NULL);
   void quit(ScreenFade* fade = NULL);
@@ -48,7 +48,7 @@ public:
 
 private:
   void draw_fps(DrawingContext& context, float fps);
-  
+
   bool running;
   float speed;
   bool nextpop;
@@ -63,4 +63,3 @@ private:
 extern MainLoop* main_loop;
 
 #endif
-
index 06aa12d..15a0db6 100644 (file)
@@ -32,7 +32,7 @@ public:
   /** Directions:
    *
    *    SOUTHEWEST    NORTHEAST   SOUTHEAST    NORTHWEST
-   *    *      or      *---*   or      *    or *---* 
+   *    *      or      *---*   or      *    or *---*
    *    | \             \  |         / |       |  /
    *    |  \             \ |        /  |       | /
    *    *---*              *       *---*       *
@@ -65,4 +65,3 @@ public:
 };
 
 #endif
-
index 79e422a..2c30258 100644 (file)
@@ -83,7 +83,7 @@ public:
   {
     set_width(width);
     set_height(height);
-  }    
+  }
   Vector get_size()
   {
     return Vector(get_width(), get_height());
@@ -108,7 +108,7 @@ public:
 
     return true;
   }
-   
+
   // leave these 2 public to safe the headaches of set/get functions for such
   // simple things :)
 
@@ -119,4 +119,3 @@ public:
 };
 
 #endif
-
index a2aeb44..817bb4d 100644 (file)
@@ -120,4 +120,3 @@ public:
 };
 
 #endif
-
index 46abffb..22a8c3e 100644 (file)
@@ -63,7 +63,7 @@ enum CollisionGroup {
    * coins
    */
   COLGROUP_TOUCHABLE,
-  
+
   /**
    * Should be used for tilemaps
    */
@@ -92,23 +92,23 @@ public:
   {
     (void) tile_attributes;
   }
-  
+
   const Vector& get_pos() const
   {
     return bbox.p1;
   }
-  
+
   /** returns the bounding box of the Object */
   const Rect& get_bbox() const
   {
     return bbox;
   }
-  
+
   const Vector& get_movement() const
   {
     return movement;
   }
-  
+
   /** places the moving object at a specific position. Be carefull when
    * using this function. There are no collision detection checks performed
    * here so bad things could happen.
@@ -150,12 +150,12 @@ public:
   {
     this->group = group;
   }
-  
+
 protected:
   friend class Sector;
   friend class CollisionGrid;
   friend class Platform;
-  
+
   /** The bounding box of the object (as used for collision detection, this
    * isn't necessarily the bounding box for graphics)
    */
index 8fad2a9..b423186 100644 (file)
@@ -61,12 +61,12 @@ AmbientSound::AmbientSound(const lisp::Lisp& lisp)
   lisp.get("volume"         ,maximumvolume  );
 
   // set dimension to zero if smaller than 64, which is default size in flexlay
-  
+
   if ((dimension.x <= 64) || (dimension.y <= 64)) {
     dimension.x = 0;
     dimension.y = 0;
   }
-  
+
   // square all distances (saves us a sqrt later)
 
   distance_bias*=distance_bias;
@@ -78,7 +78,7 @@ AmbientSound::AmbientSound(const lisp::Lisp& lisp)
     silence_distance = 10e99;
   else
     silence_distance = 1/distance_factor;
-  
+
   lisp.get("silence_distance",silence_distance);
 
   sound_source = 0; // not playing at the beginning
@@ -97,7 +97,7 @@ AmbientSound::AmbientSound(Vector pos, float factor, float bias, float vol, std:
   distance_bias=bias*bias;
   maximumvolume=vol;
   sample=file;
-  
+
   // set default silence_distance
 
   if (distance_factor == 0)
@@ -131,7 +131,7 @@ AmbientSound::start_playing()
     sound_source = sound_manager->create_sound_source(sample);
     if(!sound_source)
       throw std::runtime_error("file not found");
-   
+
     sound_source->set_gain(0);
     sound_source->set_looping(true);
     currentvolume=targetvolume=1e-20;
@@ -145,8 +145,8 @@ AmbientSound::start_playing()
 }
 
 void
-AmbientSound::update(float deltat) 
-{ 
+AmbientSound::update(float deltat)
+{
   if (latency-- <= 0) {
     float px,py;
     float rx,ry;
@@ -168,7 +168,7 @@ AmbientSound::update(float deltat)
     // inside the bias: full volume (distance 0)
     if (sqrdistance<0)
       sqrdistance=0;
-    
+
     // calculate target volume - will never become 0
     targetvolume=1/(1+sqrdistance*distance_factor);
     float rise=targetvolume/currentvolume;
@@ -194,7 +194,7 @@ AmbientSound::update(float deltat)
        latency=(int)(0.001/distance_factor);
       //(int)(10*((sqrdistance-silence_distance)/silence_distance));
     }
-  } 
+  }
 
   // heuristically measured "good" latency maximum
 
@@ -203,7 +203,7 @@ AmbientSound::update(float deltat)
 }
 
 void
-AmbientSound::draw(DrawingContext &) 
+AmbientSound::draw(DrawingContext &)
 {
 }
 
@@ -223,7 +223,7 @@ AmbientSound::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
 void
 AmbientSound::set_pos(float x, float y){
   position.x = x;
-  position.y = y; 
+  position.y = y;
 }
 
 float
index 2a58788..fc34923 100644 (file)
 /**
  *  Ambient Sound Source, gamma version. Features:
  *
- *  - "rounded rectancle" geometry with position, dimension and 
- *    "rounding radius" (extending in all directions) of a 100% 
- *    volume area, adjustable maximum volume, inverse square 
+ *  - "rounded rectancle" geometry with position, dimension and
+ *    "rounding radius" (extending in all directions) of a 100%
+ *    volume area, adjustable maximum volume, inverse square
  *    falloff outside area.
- *  
+ *
  *  - degenerates gracefully to a disc for dimension=0
- *  
+ *
  *  - parameters:
  *
  *    x, y               position
@@ -36,8 +36,8 @@
  *    distance_bias      high = big "100% disc"
  *    silence_distance   defaults reasonably.
  *    sample             sample to be played back in loop mode
- * 
- *      basti_ 
+ *
+ *      basti_
  */
 
 #ifndef __AMBIENT_SOUND_H__
@@ -57,7 +57,7 @@ public:
   AmbientSound(const lisp::Lisp& lisp);
   AmbientSound(Vector pos, float factor, float bias, float vol, std::string file);
   ~AmbientSound();
-  
+
   void set_pos(Vector newpos)
   {
     position=newpos;
@@ -92,7 +92,7 @@ private:
 
   float distance_factor;  /// distance scaling
   float distance_bias;    /// 100% volume disc radius
-  float silence_distance; /// not implemented yet 
+  float silence_distance; /// not implemented yet
 
   float maximumvolume; /// maximum volume
   float targetvolume;  /// how loud we want to be
@@ -102,4 +102,3 @@ private:
 };
 
 #endif
-
index 110fb42..4c42edb 100644 (file)
@@ -71,7 +71,7 @@ AnchorPoint string_to_anchor_point(const std::string& str)
     return ANCHOR_BOTTOM;
   else if(str == "bottomright")
     return ANCHOR_BOTTOM_RIGHT;
-    
+
   std::ostringstream msg;
   msg << "Unknown anchor '" << str << "'";
   throw std::runtime_error(msg.str());
@@ -80,7 +80,7 @@ AnchorPoint string_to_anchor_point(const std::string& str)
 Vector get_anchor_pos(const Rect& rect, AnchorPoint point)
 {
   Vector result;
-  
+
   switch(point & ANCHOR_V_MASK) {
     case ANCHOR_LEFT:
       result.x = rect.get_left();
@@ -118,7 +118,7 @@ Vector get_anchor_pos(const Rect& rect, AnchorPoint point)
       result.y = rect.get_top();
       break;
   }
-  
+
   return result;
 }
 
@@ -126,7 +126,7 @@ Vector get_anchor_pos(const Rect& destrect, float width, float height,
                       AnchorPoint point)
 {
   Vector result;
-  
+
   switch(point & ANCHOR_V_MASK) {
     case ANCHOR_LEFT:
       result.x = destrect.get_left();
@@ -164,7 +164,6 @@ Vector get_anchor_pos(const Rect& destrect, float width, float height,
       result.y = destrect.get_top();
       break;
   }
-  
-  return result; 
-}
 
+  return result;
+}
index 256c9fe..5b8baee 100644 (file)
@@ -33,7 +33,7 @@ enum AnchorPoint {
   ANCHOR_LEFT   = 0x0001,
   ANCHOR_RIGHT  = 0x0002,
   ANCHOR_MIDDLE = 0x0000,
-  
+
   ANCHOR_TOP_LEFT = ANCHOR_TOP | ANCHOR_LEFT,
   ANCHOR_TOP_RIGHT = ANCHOR_TOP | ANCHOR_RIGHT,
   ANCHOR_BOTTOM_LEFT = ANCHOR_BOTTOM | ANCHOR_LEFT,
@@ -47,4 +47,3 @@ Vector get_anchor_pos(const Rect& destrect, float width, float height,
                       AnchorPoint point);
 
 #endif
-
index f42de1a..f60f184 100644 (file)
@@ -51,7 +51,7 @@ Background::Background(const lisp::Lisp& reader)
   reader.get("layer", layer);
   if(!reader.get("image", imagefile) || !reader.get("speed", speed))
     throw std::runtime_error("Must specify image and speed for background");
-  
+
   set_image(imagefile, speed);
   reader.get("speed-y", speed_y);
   if (reader.get("image-top", imagefile_top)) {
@@ -73,7 +73,7 @@ Background::write(lisp::Writer& writer)
 
   if (image_top.get() != NULL)
     writer.write_string("image-top", imagefile_top);
-    
+
   writer.write_string("image", imagefile);
   if (image_bottom.get() != NULL)
     writer.write_string("image-bottom", imagefile_bottom);
@@ -81,7 +81,7 @@ Background::write(lisp::Writer& writer)
   writer.write_float("speed", speed);
   writer.write_float("speed-y", speed_y);
   writer.write_int("layer", layer);
-  
+
   writer.end_list("background");
 }
 
@@ -104,7 +104,7 @@ Background::draw(DrawingContext& context)
 {
   if(image.get() == NULL)
     return;
-    
+
   int w = (int) image->get_width();
   int h = (int) image->get_height();
   int sx = int(pos.x-context.get_translation().x * speed) % w - w;
@@ -118,7 +118,7 @@ Background::draw(DrawingContext& context)
       if (image_top.get() != NULL && (y < center_image_py)) {
         context.draw_surface(image_top.get(), Vector(x, y), layer);
         continue;
-      } 
+      }
       if (image_bottom.get() != NULL && (y >= bottom_image_py)) {
         context.draw_surface(image_bottom.get(), Vector(x, y), layer);
         continue;
index 4310b4c..6b4625e 100644 (file)
@@ -66,4 +66,3 @@ private:
 };
 
 #endif /*SUPERTUX_BACKGROUND_H*/
-
index 17cb7ad..4bd1409 100644 (file)
@@ -92,7 +92,7 @@ Block::update(float elapsed_time)
 {
   if(!bouncing)
     return;
-  
+
   float offset = original_y - get_pos().y;
   if(offset > BOUNCY_BRICK_MAX_OFFSET) {
     bounce_dir = BOUNCY_BRICK_SPEED;
@@ -138,7 +138,7 @@ BonusBlock::BonusBlock(const Vector& pos, int data)
       log_warning << "Invalid box contents" << std::endl;
       contents = CONTENT_COIN;
       break;
-  }          
+  }
 }
 
 BonusBlock::BonusBlock(const lisp::Lisp& lisp)
@@ -182,12 +182,12 @@ BonusBlock::BonusBlock(const lisp::Lisp& lisp)
       } else {
         log_warning << "Invalid element '" << token << "' in bonusblock" << std::endl;
       }
-    }  
+    }
   }
 
   if(contents == CONTENT_CUSTOM && object == 0)
     throw std::runtime_error("Need to specify content object for custom block");
-  
+
   bbox.set_pos(pos);
 }
 
@@ -205,7 +205,7 @@ BonusBlock::hit(Player& )
 HitResponse
 BonusBlock::collision(GameObject& other, const CollisionHit& hit){
     BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
-    if(badguy) { 
+    if(badguy) {
       // hit contains no information for collisions with blocks.
       // Badguy's bottom has to be below the top of the bonusblock
       // +7 is required to slide over one tile gaps.
@@ -223,7 +223,7 @@ BonusBlock::try_open()
     sound_manager->play("sounds/brick.wav");
     return;
   }
-  
+
   Sector* sector = Sector::current();
   assert(sector);
   assert(sector->player);
@@ -251,12 +251,12 @@ BonusBlock::try_open()
     case CONTENT_ICEGROW:
       if(player.get_status()->bonus == NO_BONUS) {
         SpecialRiser* riser = new SpecialRiser(get_pos(), new GrowUp(direction));
-        sector->add_object(riser);                                            
+        sector->add_object(riser);
       } else {
         SpecialRiser* riser = new SpecialRiser(
             get_pos(), new Flower(ICE_BONUS));
         sector->add_object(riser);
-      }      
+      }
       sound_manager->play("sounds/upgrade.wav");
       break;
 
@@ -300,7 +300,7 @@ Brick::hit(Player& )
 {
   if(sprite->get_action() == "empty")
     return;
-  
+
   try_break(true);
 }
 
@@ -323,7 +323,7 @@ Brick::try_break(bool playerhit)
 {
   if(sprite->get_action() == "empty")
     return;
-  
+
   sound_manager->play("sounds/brick.wav");
   Sector* sector = Sector::current();
   Player& player = *(sector->player);
@@ -356,4 +356,3 @@ Brick::try_break(bool playerhit)
 }
 
 //IMPLEMENT_FACTORY(Brick, "brick");
-
index 462e8ff..c00cce7 100644 (file)
@@ -94,4 +94,3 @@ private:
 };
 
 #endif
-
index ef7b52f..7f0e491 100644 (file)
@@ -37,7 +37,7 @@ Bullet::Bullet(const Vector& pos, float xm, int dir)
   : life_count(3)
 {
   sprite.reset(sprite_manager->create("images/objects/bullets/firebullet.sprite"));
-  
+
   bbox.set_pos(pos);
   bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
 
@@ -99,5 +99,3 @@ Bullet::collision(GameObject& , const CollisionHit& )
 {
   return FORCE_MOVE;
 }
-
-
index 3664f33..c5eb76d 100644 (file)
@@ -29,7 +29,7 @@ class Bullet : public MovingObject
 public:
   Bullet(const Vector& pos, float xm, int dir);
   ~Bullet();
-  
+
   void update(float elapsed_time);
   void draw(DrawingContext& context);
   void collision_solid(const CollisionHit& hit);
index 7f836b5..ef22b8f 100644 (file)
@@ -72,7 +72,7 @@ void
 Camera::parse(const lisp::Lisp& reader)
 {
   std::string modename;
-  
+
   reader.get("mode", modename);
   if(modename == "normal") {
     mode = NORMAL;
@@ -102,7 +102,7 @@ void
 Camera::write(lisp::Writer& writer)
 {
   writer.start_list("camera");
-  
+
   if(mode == NORMAL) {
     writer.write_string("mode", "normal");
     writer.write_bool("backscrolling", do_backscrolling);
@@ -112,7 +112,7 @@ Camera::write(lisp::Writer& writer)
   } else if(mode == MANUAL) {
     writer.write_string("mode", "manual");
   }
-                     
+
   writer.end_list("camera");
 }
 
@@ -177,12 +177,12 @@ Camera::keep_in_bounds(Vector& translation)
   // don't scroll before the start or after the level's end
   if(translation.y > height - SCREEN_HEIGHT)
     translation.y = height - SCREEN_HEIGHT;
-  if(translation.y < 0)                                      
-    translation.y = 0; 
+  if(translation.y < 0)
+    translation.y = 0;
   if(translation.x > width - SCREEN_WIDTH)
     translation.x = width - SCREEN_WIDTH;
   if(translation.x < 0)
-    translation.x = 0;                                         
+    translation.x = 0;
 }
 
 void
@@ -199,7 +199,7 @@ Camera::update_scroll_normal(float elapsed_time)
 {
   assert(sector != 0);
   Player* player = sector->player;
-  
+
   // check that we don't have division by zero later
   if(elapsed_time < EPSILON)
     return;
@@ -227,7 +227,7 @@ Camera::update_scroll_normal(float elapsed_time)
     float speed_y = delta_y / elapsed_time;
 
     // limit the camera speed when jumping upwards
-    if(player->fall_mode != Player::FALLING 
+    if(player->fall_mode != Player::FALLING
         && player->fall_mode != Player::TRAMPOLINE_JUMP) {
       if(speed_y > max_speed_y)
         speed_y = max_speed_y;
@@ -246,7 +246,7 @@ Camera::update_scroll_normal(float elapsed_time)
   /****** Horizontal scrolling part *******/
 
   // our camera is either in leftscrolling, rightscrolling or nonscrollingmode.
-  
+
   // when suddenly changing directions while scrolling into the other direction.
   // abort scrolling, since tux might be going left/right at a relatively small
   // part of the map (like when jumping upwards)
@@ -289,7 +289,7 @@ Camera::update_scroll_normal(float elapsed_time)
   if( player->peeking_direction() == ::RIGHT ){
         speed_x = -maxv;
   }
-  
+
   // apply scrolling
   translation.x -= speed_x * elapsed_time;
 
@@ -304,7 +304,7 @@ Camera::update_scroll_normal(float elapsed_time)
 void
 Camera::update_scroll_autoscroll(float elapsed_time)
 {
-  Player* player = sector->player; 
+  Player* player = sector->player;
   if(player->is_dying())
     return;
 
@@ -326,4 +326,3 @@ Camera::update_scroll_to(float elapsed_time)
 
   translation = scroll_from + (scroll_goal - scroll_from) * scroll_to_pos;
 }
-
index 07a92d0..de6c43d 100644 (file)
@@ -124,4 +124,3 @@ private:
 };
 
 #endif /*SUPERTUX_CAMERA_H*/
-
index 38ea325..9c3547a 100644 (file)
@@ -34,7 +34,7 @@ class Candle : public MovingSprite, public ScriptInterface
 public:
   Candle(const lisp::Lisp& lisp);
   virtual Candle* clone() const { return new Candle(*this); }
-  
+
   HitResponse collision(GameObject& other, const CollisionHit& hit);
 
   virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
@@ -52,4 +52,3 @@ private:
 };
 
 #endif
-
index e9e0a0d..c75312f 100644 (file)
@@ -52,7 +52,7 @@ Coin::collect()
 {
   // TODO: commented out musical code. Maybe fork this for a special "MusicalCoin" object?
   /*
-  static Timer sound_timer; 
+  static Timer sound_timer;
   static int pitch_one = 128;
   static float last_pitch = 1;
   float pitch = 1;
@@ -63,11 +63,11 @@ Coin::collect()
     pitch_one = tile;
     pitch = 1;
     last_pitch = 1;
-  } 
+  }
   else if (sound_timer.get_timegone() < 0.02) {
     pitch = last_pitch;
-  } 
-  else 
+  }
+  else
   {
     switch ((pitch_one - tile) % 7) {
       case -6:
index 9c3106f..16d04c9 100644 (file)
@@ -35,4 +35,3 @@ public:
 };
 
 #endif
-
index 88a17d1..ca3125d 100644 (file)
@@ -94,12 +94,12 @@ DisplayEffect::update(float elapsed_time)
                 borders = false;
                 border_fade = NO_FADE;
             }
-            border_size = (border_fadetime - border_fading) 
+            border_size = (border_fadetime - border_fading)
                 / border_fadetime * BORDER_SIZE;
             break;
         default:
             assert(false);
-    }       
+    }
 }
 
 void
@@ -108,7 +108,7 @@ DisplayEffect::draw(DrawingContext& context)
     context.push_transform();
     context.set_translation(Vector(0, 0));
 
-    if(black || screen_fade != NO_FADE) {    
+    if(black || screen_fade != NO_FADE) {
       float alpha;
       if(black) {
           alpha = 1.0f;
@@ -196,4 +196,3 @@ DisplayEffect::four_to_three(float fadetime)
     border_fading = border_fadetime;
   }
 }
-
index 017daff..40510cc 100644 (file)
@@ -55,10 +55,9 @@ private:
     float border_fadetime;
     float border_fading;
     float border_size;
-    
+
     bool black;
     bool borders;
 };
 
 #endif
-
index 0a7feca..f1b8c1c 100644 (file)
@@ -31,12 +31,12 @@ Electrifier::Electrifier(uint32_t oldtile, uint32_t newtile, float seconds)
   change_to = newtile;
   Sector::current()->change_solid_tiles(change_from,change_to);
 }
-  
+
 Electrifier::~Electrifier() {
 }
 
 void
-Electrifier::update(float ) 
+Electrifier::update(float )
 {
   if (duration.check()) {
     Sector::current()->change_solid_tiles(change_to,change_from);
@@ -45,6 +45,6 @@ Electrifier::update(float )
 }
 
 void
-Electrifier::draw(DrawingContext& ) 
+Electrifier::draw(DrawingContext& )
 {
 }
index 46ce291..3ad746c 100644 (file)
@@ -32,7 +32,7 @@ class Electrifier : public GameObject
 public:
   Electrifier(uint32_t oldtile, uint32_t newtile, float seconds);
   ~Electrifier();
-protected:  
+protected:
   virtual void update(float time);
   virtual void draw(DrawingContext& context);
 private:
@@ -42,4 +42,3 @@ private:
 };
 
 #endif
-
index ae98d75..49299fb 100644 (file)
@@ -33,7 +33,7 @@
 Firefly::Firefly(const lisp::Lisp& lisp)
        : MovingSprite(lisp, "images/objects/resetpoints/default-resetpoint.sprite", LAYER_TILES, COLGROUP_TOUCHABLE), activated(false)
 {
-  
+
   if( !lisp.get( "sprite", sprite_name ) ){
     return;
   }
@@ -41,7 +41,7 @@ Firefly::Firefly(const lisp::Lisp& lisp)
     sprite_name = "images/objects/resetpoints/default-resetpoint.sprite";
     return;
   }
-  //Replace sprite 
+  //Replace sprite
   sprite = sprite_manager->create( sprite_name );
   bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
 }
@@ -60,7 +60,7 @@ Firefly::collision(GameObject& other, const CollisionHit& )
 {
   if(activated)
     return ABORT_MOVE;
-  
+
   Player* player = dynamic_cast<Player*> (&other);
   if(player) {
     activated = true;
@@ -81,7 +81,7 @@ Firefly::collision(GameObject& other, const CollisionHit& )
     GameSession::current()->set_reset_point(Sector::current()->get_name(),
         get_pos());
   }
-  
+
   return ABORT_MOVE;
 }
 
index 89a3882..f77a574 100644 (file)
@@ -43,4 +43,3 @@ private:
 };
 
 #endif
-
index 882ef5f..4128c83 100644 (file)
@@ -29,7 +29,7 @@ class Fireworks : public GameObject
 public:
   Fireworks();
   ~Fireworks();
-    
+
   virtual void update(float elapsed_time);
   virtual void draw(DrawingContext& context);
 
@@ -38,4 +38,3 @@ private:
 };
 
 #endif
-
index 6041bae..5798784 100644 (file)
@@ -29,7 +29,7 @@
 #include "lisp/lisp.hpp"
 #include "floating_image.hpp"
 
-FloatingImage::FloatingImage(const std::string& spritefile) 
+FloatingImage::FloatingImage(const std::string& spritefile)
   : layer(LAYER_FOREGROUND1 + 1), visible(false), anchor(ANCHOR_MIDDLE)
 {
   sprite.reset(sprite_manager->create(spritefile));
index 7e7ddc3..db37066 100644 (file)
@@ -36,7 +36,7 @@ public:
   void set_layer(int layer) {
     this->layer = layer;
   }
-  
+
   int get_layer() const {
     return layer;
   }
@@ -47,7 +47,7 @@ public:
   const Vector& get_pos() const {
     return pos;
   }
-  
+
   void set_anchor_point(AnchorPoint anchor) {
     this->anchor = anchor;
   }
@@ -77,4 +77,3 @@ private:
 };
 
 #endif
-
index b5830e0..71cacf2 100644 (file)
@@ -39,7 +39,7 @@ Flower::Flower(BonusType _type)
     sound_manager->preload("sounds/fire-flower.wav");
   }
   else if(type == ICE_BONUS) {
-    sprite = sprite_manager->create("images/powerups/iceflower/iceflower.sprite"); 
+    sprite = sprite_manager->create("images/powerups/iceflower/iceflower.sprite");
   } else {
     assert(false);
   }
@@ -72,9 +72,8 @@ Flower::collision(GameObject& other, const CollisionHit& )
 
   if(!player->add_bonus(type, true))
     return FORCE_MOVE;
-  
+
   sound_manager->play("sounds/fire-flower.wav");
   remove_me();
   return ABORT_MOVE;
 }
-
index 4411ef9..46a2e6c 100644 (file)
@@ -41,4 +41,3 @@ private:
 };
 
 #endif
-
index caf93ed..bcbbdd5 100644 (file)
@@ -175,4 +175,3 @@ SmokeCloud::draw(DrawingContext& context)
 {
   sprite->draw(context, position, LAYER_OBJECTS+1);
 }
-
index 2fa10da..d15ed27 100644 (file)
@@ -69,14 +69,14 @@ class FloatingText : public GameObject
 public:
   FloatingText(const Vector& pos, const std::string& text_);
   FloatingText(const Vector& pos, int s);  // use this for score, for instance
-  
+
   virtual void update(float elapsed_time);
   virtual void draw(DrawingContext& context);
 
 private:
   Vector position;
   std::string text;
-  Timer timer;  
+  Timer timer;
 };
 
 class SmokeCloud : public GameObject
@@ -84,7 +84,7 @@ class SmokeCloud : public GameObject
 public:
   SmokeCloud(const Vector& pos);
   ~SmokeCloud();
-  
+
   virtual void update(float elapsed_time);
   virtual void draw(DrawingContext& context);
 
@@ -94,7 +94,7 @@ private:
   Vector position;
 };
 
-#endif 
+#endif
 
 /* Local Variables: */
 /* mode:c++ */
index c383895..d89996b 100644 (file)
@@ -68,7 +68,7 @@ Gradient::write(lisp::Writer& writer)
   writer.write_float_vector("bottom_color", bkgd_bottom_color);
 
   writer.write_int("layer", layer);
-  
+
   writer.end_list("gradient");
 }
 
@@ -82,7 +82,7 @@ Gradient::set_gradient(Color top, Color bottom)
 {
   gradient_top = top;
   gradient_bottom = bottom;
-  
+
   if (gradient_top.red > 1.0 || gradient_top.green > 1.0
    || gradient_top.blue > 1.0 || gradient_top.alpha > 1.0)
     log_warning << "top gradient color has values above 1.0" << std::endl;
index a0037fd..6feba31 100644 (file)
@@ -45,7 +45,7 @@ public:
 
   Color get_gradient_top() const
   { return gradient_top; }
-  
+
   Color get_gradient_bottom() const
   { return gradient_bottom; }
 
@@ -59,4 +59,3 @@ private:
 };
 
 #endif /*SUPERTUX_BACKGROUND_H*/
-
index 6af5b5b..1d256db 100644 (file)
@@ -60,10 +60,9 @@ GrowUp::collision(GameObject& other, const CollisionHit& )
 
     sound_manager->play("sounds/grow.wav");
     remove_me();
-    
+
     return ABORT_MOVE;
   }
 
   return FORCE_MOVE;
 }
-
index df21d60..315740d 100644 (file)
@@ -33,10 +33,9 @@ public:
   virtual void update(float elapsed_time);
   virtual void collision_solid(const CollisionHit& hit);
   virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
-  
+
 private:
   Physic physic;
 };
 
 #endif
-
index 04c48fe..71cbf84 100644 (file)
@@ -1,4 +1,4 @@
-//  $Id: hurting_platform.hpp 3506 2006-05-12 01:41:09Z sommer $
+//  $Id$
 //
 //  SuperTux - Hurting Platform
 //  Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
@@ -39,4 +39,3 @@ private:
 };
 
 #endif
-
index aff82ac..c332f3a 100644 (file)
@@ -41,7 +41,7 @@ InfoBlock::InfoBlock(const lisp::Lisp& lisp)
   }
   //stopped = false;
   //ringing = new AmbientSound(get_pos(), 0.5, 300, 1, "sounds/phone.wav");
-  //Sector::current()->add_object(ringing);  
+  //Sector::current()->add_object(ringing);
 }
 
 InfoBlock::~InfoBlock()
index 4aa6d4e..7f9b051 100644 (file)
@@ -28,7 +28,7 @@ class InfoBlock : public Block
 public:
   InfoBlock(const lisp::Lisp& lisp);
   virtual ~InfoBlock();
-  
+
 protected:
   virtual void hit(Player& player);
   std::string message;
@@ -37,4 +37,3 @@ protected:
 };
 
 #endif
-
index fe17ba6..73ccf56 100644 (file)
@@ -62,7 +62,7 @@ InvisibleBlock::collision(GameObject& other, const CollisionHit& hit)
 void
 InvisibleBlock::hit(Player& )
 {
-  sound_manager->play("sounds/brick.wav"); 
+  sound_manager->play("sounds/brick.wav");
 
   if(visible)
     return;
index 0b7f09c..1f1034b 100644 (file)
@@ -72,7 +72,7 @@ LevelTime::draw(DrawingContext& context)
   context.set_translation(Vector(0, 0));
 
   char str[60];
-    
+
   if(get_remaining_time() < 0) {
     context.draw_text(white_text, _("TIME's UP"), Vector(SCREEN_WIDTH/2, BORDER_Y),
         CENTER_ALLIGN, LAYER_FOREGROUND1);
index 928fee8..b4741ec 100644 (file)
@@ -43,4 +43,3 @@ private:
 };
 
 #endif
-
index 8b3983f..ba08bc6 100644 (file)
@@ -47,9 +47,9 @@ Light::draw(DrawingContext& context)
 {
   context.push_target();
   context.set_target(DrawingContext::LIGHTMAP);
-  
+
   sprite->draw(context, Sector::current()->player->get_pos(), 0);
-  
+
   context.pop_target();
 }
 
index cac9a71..b24891f 100644 (file)
@@ -39,4 +39,3 @@ private:
 };
 
 #endif
-
index 853de73..953d556 100644 (file)
@@ -81,7 +81,7 @@ MovingSprite::MovingSprite(const MovingSprite& other)
   sprite = new Sprite(*other.sprite);
 }
 
-MovingSprite& 
+MovingSprite&
 MovingSprite::operator=(const MovingSprite& other)
 {
   if (this == &other) return *this;
@@ -105,19 +105,19 @@ MovingSprite::draw(DrawingContext& context)
   sprite->draw(context, get_pos(), layer);
 }
 
-void 
+void
 MovingSprite::update(float )
 {
 }
 
-void 
+void
 MovingSprite::set_action(const std::string& action, int loops)
 {
   sprite->set_action(action, loops);
   set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
 }
 
-void 
+void
 MovingSprite::set_action_centered(const std::string& action, int loops)
 {
   Vector old_size = bbox.get_size();
@@ -125,4 +125,3 @@ MovingSprite::set_action_centered(const std::string& action, int loops)
   set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
   set_pos(get_pos() - (bbox.get_size() - old_size) / 2);
 }
-
index 3ce81fa..bdbaa5e 100644 (file)
@@ -38,7 +38,7 @@ OneUp::update(float elapsed_time)
   if(!Sector::current()->inside(bbox))
     remove_me();
 
-  movement = physic.get_movement(elapsed_time); 
+  movement = physic.get_movement(elapsed_time);
 }
 
 HitResponse
@@ -52,4 +52,3 @@ OneUp::collision(GameObject& other, const CollisionHit& )
   }
   return FORCE_MOVE;
 }
-
index cea6c82..f6f066b 100644 (file)
@@ -102,4 +102,3 @@ Particles::draw(DrawingContext& context)
     context.draw_filled_rect((*i)->pos, Vector(size,size), color,drawing_layer);
   }
 }
-
index 4e4d3a2..9c353ee 100644 (file)
@@ -33,7 +33,7 @@ public:
             int number, Color color, int size, float life_time,
             int drawing_layer);
   ~Particles();
-  
+
   virtual void update(float elapsed_time);
   virtual void draw(DrawingContext& context);
 
index a58a7d4..a63afa0 100644 (file)
@@ -138,7 +138,7 @@ void SnowParticleSystem::update(float elapsed_time)
 
     particle->pos.y += particle->speed * elapsed_time;
     particle->pos.x += particle->wobble * elapsed_time /* * particle->speed * 0.125*/;
-    
+
     anchor_delta = (particle->anchorx - particle->pos.x);
     particle->wobble += (4 * anchor_delta * 0.05) + systemRandom.randf(-0.5, 0.5);
     particle->wobble *= 0.99;
index dd356f8..b3f49a5 100644 (file)
@@ -54,7 +54,7 @@ class ParticleSystem : public GameObject
 public:
     ParticleSystem(float max_particle_size = 60);
     virtual ~ParticleSystem();
-    
+
     virtual void draw(DrawingContext& context);
 
 protected:
@@ -70,7 +70,7 @@ protected:
         Vector pos;
         Surface* texture;
     };
-    
+
     std::vector<Particle*> particles;
     float virtual_width, virtual_height;
 };
@@ -88,7 +88,7 @@ public:
 
     std::string type() const
     { return "SnowParticleSystem"; }
-    
+
 private:
     class SnowParticle : public Particle
     {
@@ -98,7 +98,7 @@ private:
        float anchorx;
        float drift_speed;
     };
-    
+
     Surface* snowimages[3];
 };
 
@@ -115,14 +115,14 @@ public:
 
     std::string type() const
     { return "GhostParticleSystem"; }
-    
+
 private:
     class GhostParticle : public Particle
     {
     public:
         float speed;
     };
-    
+
     Surface* ghosts[2];
 };
 
@@ -138,17 +138,16 @@ public:
     virtual void update(float elapsed_time);
 
     std::string type() const
-    { return "CloudParticleSystem"; }    
-    
+    { return "CloudParticleSystem"; }
+
 private:
     class CloudParticle : public Particle
     {
     public:
         float speed;
     };
-    
+
     Surface* cloudimage;
 };
 
 #endif
-
index 0a45cb5..2d4a3c2 100644 (file)
@@ -61,7 +61,7 @@ ParticleSystem_Interactive::~ParticleSystem_Interactive()
 void ParticleSystem_Interactive::draw(DrawingContext& context)
 {
   context.push_transform();
-  
+
     std::vector<Particle*>::iterator i;
     for(i = particles.begin(); i != particles.end(); ++i) {
         Particle* particle = *i;
@@ -121,7 +121,7 @@ ParticleSystem_Interactive::collision(Particle* object, Vector movement)
          if(intersects(dest, rect)) {
            if(tile->getAttributes() & Tile::WATER)
              water = true;
-           set_rectangle_rectangle_constraints(&constraints, dest, rect); 
+           set_rectangle_rectangle_constraints(&constraints, dest, rect);
          }
        }
       }
index 3bb7313..55bf3c5 100644 (file)
@@ -50,7 +50,7 @@ class ParticleSystem_Interactive : public GameObject
 public:
     ParticleSystem_Interactive();
     virtual ~ParticleSystem_Interactive();
-    
+
     virtual void draw(DrawingContext& context);
 
 protected:
@@ -65,7 +65,7 @@ protected:
         Vector pos;
         Surface* texture;
     };
-    
+
     std::vector<Particle*> particles;
     float virtual_width, virtual_height;
     int collision(Particle* particle, Vector movement);
@@ -84,14 +84,14 @@ public:
 
     std::string type() const
     { return "RainParticleSystem"; }
-    
+
 private:
     class RainParticle : public Particle
     {
     public:
         float speed;
     };
-    
+
     Surface* rainimages[2];
 };
 
@@ -108,16 +108,15 @@ public:
 
     std::string type() const
     { return "CometParticleSystem"; }
-    
+
 private:
     class CometParticle : public Particle
     {
     public:
         float speed;
     };
-    
+
     Surface* cometimages[2];
 };
 
 #endif
-
index 5f7cc09..6529cf3 100644 (file)
@@ -66,7 +66,7 @@ Path::read(const lisp::Lisp& reader)
       }
       continue;
     }
-    
+
     if(iter.item() != "node") {
       log_warning << "unknown token '" << iter.item() << "' in Path nodes list. Ignored." << std::endl;
       continue;
@@ -130,7 +130,6 @@ Path::get_base() const
 {
   if(nodes.empty())
     return Vector(0, 0);
-  
+
   return nodes[0].position;
 }
-
index 5ac0fe0..f599c76 100644 (file)
@@ -1,5 +1,5 @@
 //  $Id$
-// 
+//
 //  SuperTux Path
 //  Copyright (C) 2005 Philipp <balinor@pnxs.de>
 //  Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
@@ -14,7 +14,7 @@
 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 //  GNU General Public License for more details.
-// 
+//
 //  You should have received a copy of the GNU General Public License
 //  along with this program; if not, write to the Free Software
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -66,4 +66,3 @@ private:
 };
 
 #endif
-
index 29ee6fc..0c8ae25 100644 (file)
@@ -43,7 +43,7 @@ PathWalker::advance(float elapsed_time)
   assert(elapsed_time >= 0);
 
   elapsed_time *= fabsf(walking_speed);
-  
+
   const Path::Node* current_node = & (path->nodes[current_node_nr]);
   while(node_time + elapsed_time * node_mult >= 1) {
     elapsed_time -= (1 - node_time) / node_mult;
@@ -62,17 +62,17 @@ PathWalker::advance(float elapsed_time)
       node_mult = 1 / path->nodes[next_node_nr].time;
     }
   }
-  
+
   const Path::Node* next_node = & (path->nodes[next_node_nr]);
   node_time += elapsed_time * node_mult;
-  Vector new_pos = current_node->position + 
+
+  Vector new_pos = current_node->position +
     (next_node->position - current_node->position) * node_time;
-    
+
   return new_pos;
 }
 
-void 
+void
 PathWalker::goto_node(int node_no)
 {
   if (node_no == stop_at_node_nr) return;
@@ -80,14 +80,14 @@ PathWalker::goto_node(int node_no)
   stop_at_node_nr = node_no;
 }
 
-void 
+void
 PathWalker::start_moving()
 {
   running = true;
   stop_at_node_nr = -1;
 }
 
-void 
+void
 PathWalker::stop_moving()
 {
   stop_at_node_nr = next_node_nr;
index 5bb3300..f3bdf9e 100644 (file)
@@ -55,7 +55,7 @@ public:
 private:
   void advance_node();
   void goback_node();
+
   /**
    * set to false to immediately stop advancing
    */
index 08469b6..6d04777 100644 (file)
@@ -47,7 +47,7 @@ Platform::Platform(const lisp::Lisp& reader)
   path->read(*pathLisp);
   walker.reset(new PathWalker(path.get(), running));
   bbox.set_pos(path->get_base());
+
   flags |= FLAG_SOLID;
 }
 
index f5e1d24..ad1d999 100644 (file)
@@ -69,4 +69,3 @@ private:
 };
 
 #endif
-
index 093e12e..48f9035 100644 (file)
@@ -160,7 +160,7 @@ Player::init()
   backflip_direction = 0;
   visible = true;
   swimming = false;
-  
+
   on_ground_flag = false;
   grabbed_object = NULL;
 
@@ -192,8 +192,13 @@ Player::adjust_height(float new_height)
   Rect bbox2 = bbox;
   bbox2.move(Vector(0, bbox.get_height() - new_height));
   bbox2.set_height(new_height);
-  if (!Sector::current()->is_free_space(bbox2))
-    return false;
+
+  if(new_height > bbox.get_height()) {
+    Rect additional_space = bbox2;
+    additional_space.set_height(new_height - bbox.get_height());
+    if(!Sector::current()->is_free_space(additional_space))
+      return false;
+  }
 
   // adjust bbox accordingly
   // note that we use members of moving_object for this, so we can run this during CD, too
@@ -209,7 +214,7 @@ Player::update(float elapsed_time)
     swimming = false;
   }
   no_water = true;
-  
+
   if(dying && dying_timer.check()) {
     dead = true;
     return;
@@ -240,8 +245,8 @@ Player::update(float elapsed_time)
 
   // handle backflipping
   if (backflipping) {
-    //prevent player from changing direction when backflipping 
-    dir = (backflip_direction == 1) ? LEFT : RIGHT; 
+    //prevent player from changing direction when backflipping
+    dir = (backflip_direction == 1) ? LEFT : RIGHT;
     if (backflip_timer.started()) physic.set_velocity_x(100 * backflip_direction);
   }
 
@@ -257,66 +262,27 @@ Player::update(float elapsed_time)
   }
 
   // check if we landed
-  if(on_ground()) { 
+  if(on_ground()) {
     jumping = false;
     if (backflipping && (!backflip_timer.started())) {
       backflipping = false;
       backflip_direction = 0;
 
       // if controls are currently deactivated, we take care of standing up ourselves
-      if (deactivated) do_standup();
+      if (deactivated)
+        do_standup();
     }
   }
-#if 0
-  // Do butt jump
-  if (butt_jump && on_ground() && is_big()) {
-    // Add a smoke cloud
-    if (duck) 
-      Sector::current()->add_smoke_cloud(Vector(get_pos().x - 32, get_pos().y));
-    else 
-      Sector::current()->add_smoke_cloud(
-        Vector(get_pos().x - 32, get_pos().y + 32));
-    
-    butt_jump = false;
-    
-    // Break bricks beneath Tux
-    if(Sector::current()->trybreakbrick(
-         Vector(base.x + 1, base.y + base.height), false)
-       || Sector::current()->trybreakbrick(
-         Vector(base.x + base.width - 1, base.y + base.height), false)) {
-      physic.set_velocity_y(-2);
-      butt_jump = true;
-    }
-    
-    // Kill nearby badguys
-    std::vector<GameObject*> gameobjects = Sector::current()->gameobjects;
-    for (std::vector<GameObject*>::iterator i = gameobjects.begin();
-         i != gameobjects.end();
-         i++) {
-      BadGuy* badguy = dynamic_cast<BadGuy*> (*i);
-      if(badguy) {
-        // don't kill when badguys are already dying or in a certain mode
-        if(badguy->dying == DYING_NOT && badguy->mode != BadGuy::BOMB_TICKING &&
-           badguy->mode != BadGuy::BOMB_EXPLODE) {
-          if (fabsf(base.x - badguy->base.x) < 96 &&
-              fabsf(base.y - badguy->base.y) < 64)
-            badguy->kill_me(25);
-        }
-      }
-    }
-  }
-#endif
 
   // calculate movement for this frame
   movement = physic.get_movement(elapsed_time);
 
   if(grabbed_object != NULL && !dying) {
-    Vector pos = get_pos() + 
+    Vector pos = get_pos() +
       Vector(dir == LEFT ? -16 : 16, get_bbox().get_height()*0.66666 - 32);
     grabbed_object->grab(*this, pos, dir);
   }
-  
+
   if(grabbed_object != NULL && dying){
     grabbed_object->ungrab(*this, dir);
     grabbed_object = NULL;
@@ -345,7 +311,7 @@ Player::update(float elapsed_time)
         Sector::current()->add_object(new SpriteParticle("images/objects/particles/sparkle.sprite", "dark", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS+1+5));
       }
     }
-  } 
+  }
 
 }
 
@@ -375,22 +341,6 @@ Player::apply_friction()
   } else {
     physic.set_acceleration_x(WALK_ACCELERATION_X * -1.5);
   }
-
-#if 0
-  // if we're on ice slow down acceleration or deceleration
-  if (isice(base.x, base.y + base.height))
-  {
-    /* the acceleration/deceleration rate on ice is inversely proportional to
-     * the current velocity.
-     */
-
-    // increasing 1 will increase acceleration/deceleration rate
-    // decreasing 1 will decrease acceleration/deceleration rate
-    //  must stay above zero, though
-    if (ax != 0) ax *= 1 / fabs(vx);
-  }
-#endif
-
 }
 
 void
@@ -456,7 +406,7 @@ Player::handle_horizontal_input()
           dir == RIGHT ? 270+20 : 90-40, dir == RIGHT ? 270+40 : 90-20,
           Vector(280, -260), Vector(0, 300), 3, Color(.4, .4, .4), 3, .8,
           LAYER_OBJECTS+1));
-      
+
       ax *= 2.5;
     } else {
       ax *= 2;
@@ -483,11 +433,15 @@ Player::do_cheer()
 
 void
 Player::do_duck() {
-  if (duck) return;
-  if (!is_big()) return;
+  if (duck)
+    return;
+  if (!is_big())
+    return;
 
-  if (physic.get_velocity_y() != 0) return;
-  if (!on_ground()) return;
+  if (physic.get_velocity_y() != 0)
+    return;
+  if (!on_ground())
+    return;
 
   if (adjust_height(31.8)) {
     duck = true;
@@ -497,11 +451,14 @@ Player::do_duck() {
   }
 }
 
-void 
+void
 Player::do_standup() {
-  if (!duck) return;
-  if (!is_big()) return;
-  if (backflipping) return;
+  if (!duck)
+    return;
+  if (!is_big())
+    return;
+  if (backflipping)
+    return;
 
   if (adjust_height(63.8)) {
     duck = false;
@@ -510,7 +467,7 @@ Player::do_standup() {
     // if timer is not already running, start it.
     if (unduck_hurt_timer.get_period() == 0) {
       unduck_hurt_timer.start(UNDUCK_HURT_TIME);
-    } 
+    }
     else if (unduck_hurt_timer.check()) {
       kill(false);
     }
@@ -520,8 +477,10 @@ Player::do_standup() {
 
 void
 Player::do_backflip() {
-  if (!duck) return;
-  if (!on_ground()) return;
+  if (!duck)
+    return;
+  if (!on_ground())
+    return;
 
   // TODO: we don't have an animation for firetux backflipping, so let's revert to bigtux
   set_bonus(GROWUP_BONUS, true);
@@ -535,7 +494,8 @@ Player::do_backflip() {
 
 void
 Player::do_jump(float yspeed) {
-  if (!on_ground()) return;
+  if (!on_ground())
+    return;
 
   physic.set_velocity_y(yspeed);
   //bbox.move(Vector(0, -1));
@@ -557,16 +517,16 @@ Player::handle_vertical_input()
 
   // Press jump key
   if(controller->pressed(Controller::JUMP) && (can_jump)) {
-    if (duck) { 
+    if (duck) {
       // when running, only jump a little bit; else do a backflip
       if (physic.get_velocity_x() != 0) do_jump(-300); else do_backflip();
     } else {
       // jump a bit higher if we are running; else do a normal jump
       if (fabs(physic.get_velocity_x()) > MAX_WALK_XM) do_jump(-580); else do_jump(-520);
     }
-  } 
+  }
   // Let go of jump key
-  else if(!controller->hold(Controller::JUMP)) { 
+  else if(!controller->hold(Controller::JUMP)) {
     if (!backflipping && jumping && physic.get_velocity_y() < 0) {
       jumping = false;
       physic.set_velocity_y(0);
@@ -578,7 +538,7 @@ Player::handle_vertical_input()
   if (controller->hold(Controller::DOWN) && !butt_jump && !duck && is_big() && jumping) {
     butt_jump = true;
   }
-  
+
   /* When Down is not held anymore, disable butt jump */
   if(butt_jump && !controller->hold(Controller::DOWN))
     butt_jump = false;
@@ -594,7 +554,7 @@ Player::handle_input()
 
   if(!controller->hold(Controller::ACTION) && grabbed_object) {
     // move the grabbed object a bit away from tux
-    Vector pos = get_pos() + 
+    Vector pos = get_pos() +
         Vector(dir == LEFT ? -bbox.get_width()-1 : bbox.get_width()+1,
                 bbox.get_height()*0.66666 - 32);
     Rect dest(pos, pos + Vector(32, 32));
@@ -613,20 +573,20 @@ Player::handle_input()
   /* Peeking */
   if( controller->released( Controller::PEEK_LEFT ) ) {
     peeking = AUTO;
-  } 
+  }
   if( controller->released( Controller::PEEK_RIGHT ) ) {
     peeking = AUTO;
   }
   if( controller->pressed( Controller::PEEK_LEFT ) ) {
     peeking = LEFT;
-  } 
+  }
   if( controller->pressed( Controller::PEEK_RIGHT ) ) {
     peeking = RIGHT;
   }
+
   /* Handle horizontal movement: */
   if (!backflipping) handle_horizontal_input();
-  
+
   /* Jump/jumping? */
   if (on_ground() && !controller->hold(Controller::JUMP))
     can_jump = true;
@@ -637,12 +597,12 @@ Player::handle_input()
   /* Shoot! */
   if (controller->pressed(Controller::ACTION) && player_status->bonus == FIRE_BONUS) {
     if(Sector::current()->add_bullet(
-         get_pos() + ((dir == LEFT)? Vector(0, bbox.get_height()/2) 
+         get_pos() + ((dir == LEFT)? Vector(0, bbox.get_height()/2)
                       : Vector(32, bbox.get_height()/2)),
          physic.get_velocity_x(), dir))
       shooting_timer.start(SHOOTING_TIME);
   }
-  
+
   /* Duck or Standup! */
   if (controller->hold(Controller::DOWN)) do_duck(); else do_standup();
 
@@ -653,13 +613,13 @@ Player::handle_input_ghost()
 {
   float vx = 0;
   float vy = 0;
-  if (controller->hold(Controller::LEFT)) { 
-    dir = LEFT; 
-    vx -= MAX_RUN_XM * 2; 
+  if (controller->hold(Controller::LEFT)) {
+    dir = LEFT;
+    vx -= MAX_RUN_XM * 2;
   }
-  if (controller->hold(Controller::RIGHT)) { 
-    dir = RIGHT; 
-    vx += MAX_RUN_XM * 2; 
+  if (controller->hold(Controller::RIGHT)) {
+    dir = RIGHT;
+    vx += MAX_RUN_XM * 2;
   }
   if ((controller->hold(Controller::UP)) || (controller->hold(Controller::JUMP))) {
     vy -= MAX_RUN_XM * 2;
@@ -684,7 +644,7 @@ bool
 Player::add_bonus(const std::string& bonustype)
 {
   BonusType type = NO_BONUS;
-  
+
   if(bonustype == "grow") {
     type = GROWUP_BONUS;
   } else if(bonustype == "fireflower") {
@@ -698,7 +658,7 @@ Player::add_bonus(const std::string& bonustype)
     msg << "Unknown bonus type "  << bonustype;
     throw std::runtime_error(msg.str());
   }
-  
+
   return add_bonus(type);
 }
 
@@ -713,7 +673,7 @@ Player::add_bonus(BonusType type, bool animate)
   // ignore GROWUP_BONUS if we're already big
   if (type == GROWUP_BONUS) {
     if (player_status->bonus == GROWUP_BONUS)
-      return true; 
+      return true;
     if (player_status->bonus == FIRE_BONUS)
       return true;
     if (player_status->bonus == ICE_BONUS)
@@ -758,7 +718,7 @@ void
 Player::set_visible(bool visible)
 {
   this->visible = visible;
-  if( visible ) 
+  if( visible )
     set_group(COLGROUP_MOVING);
   else
     set_group(COLGROUP_DISABLED);
@@ -783,7 +743,7 @@ Player::draw(DrawingContext& context)
     return;
 
   TuxBodyParts* tux_body;
-          
+
   if (player_status->bonus == GROWUP_BONUS)
     tux_body = big_tux;
   else if (player_status->bonus == FIRE_BONUS)
@@ -891,7 +851,7 @@ Player::draw(DrawingContext& context)
   /* Draw Tux */
   if(dying) {
     smalltux_gameover->draw(context, get_pos(), LAYER_FLOATINGOBJECTS + 1);
-  } 
+  }
   else if ((growing_timer.get_timeleft() > 0) && (!duck)) {
       if (dir == RIGHT) {
         context.draw_surface(growingtux_right[int((growing_timer.get_timegone() *
@@ -913,8 +873,8 @@ Player::collision_tile(uint32_t tile_attributes)
 {
   if(tile_attributes & Tile::HURTS)
     kill(false);
-    
-  if( swimming ){ 
+
+  if( swimming ){
     if( tile_attributes & Tile::WATER ){
       no_water = false;
     } else {
@@ -979,7 +939,7 @@ Player::collision(GameObject& other, const CollisionHit& hit)
 #ifdef DEBUG
   assert(dynamic_cast<MovingObject*> (&other) != NULL);
 #endif
-  MovingObject* moving_object = static_cast<MovingObject*> (&other); 
+  MovingObject* moving_object = static_cast<MovingObject*> (&other);
   if(moving_object->get_group() == COLGROUP_TOUCHABLE) {
     TriggerBase* trigger = dynamic_cast<TriggerBase*> (&other);
     if(trigger) {
@@ -1006,7 +966,7 @@ Player::make_invincible()
 {
   sound_manager->play("sounds/invincible.wav");
   invincible_timer.start(TUX_INVINCIBLE_TIME);
-  Sector::current()->play_music(HERRING_MUSIC);               
+  Sector::current()->play_music(HERRING_MUSIC);
 }
 
 /* Kill Player! */
@@ -1017,8 +977,8 @@ Player::kill(bool completely)
     return;
 
   if(!completely && (safe_timer.started() || invincible_timer.started()))
-    return;                          
-  
+    return;
+
   sound_manager->play("sounds/hurt.wav");
 
   physic.set_velocity_x(0);
@@ -1039,8 +999,8 @@ Player::kill(bool completely)
     for (int i = 0; (i < 5) && (i < player_status->coins); i++)
     {
       // the numbers: starting x, starting y, velocity y
-      Sector::current()->add_object(new FallingCoin(get_pos() + 
-            Vector(systemRandom.rand(5), systemRandom.rand(-32,18)), 
+      Sector::current()->add_object(new FallingCoin(get_pos() +
+            Vector(systemRandom.rand(5), systemRandom.rand(-32,18)),
             systemRandom.rand(-100,100)));
     }
     physic.enable_gravity(true);
@@ -1085,35 +1045,21 @@ Player::check_bounds(Camera* camera)
     set_pos(Vector(0, get_pos().y));
   }
 
-  /* Keep in-bounds, vertically: */
+  /* fallen out of the level? */
   if (get_pos().y > Sector::current()->get_height()) {
     kill(true);
     return;
   }
 
-  bool adjust = false;
   // can happen if back scrolling is disabled
   if(get_pos().x < camera->get_translation().x) {
     set_pos(Vector(camera->get_translation().x, get_pos().y));
-    adjust = true;
   }
   if(get_pos().x >= camera->get_translation().x + SCREEN_WIDTH - bbox.get_width())
   {
     set_pos(Vector(
           camera->get_translation().x + SCREEN_WIDTH - bbox.get_width(),
           get_pos().y));
-    adjust = true;
-  }
-
-  if(adjust) {
-    // FIXME
-#if 0
-    // squished now?
-    if(collision_object_map(bbox)) {
-      kill(KILL);
-      return;
-    }
-#endif
   }
 }
 
@@ -1126,10 +1072,14 @@ Player::add_velocity(const Vector& velocity)
 void
 Player::add_velocity(const Vector& velocity, const Vector& end_speed)
 {
-  if (end_speed.x > 0) physic.set_velocity_x(std::min(physic.get_velocity_x() + velocity.x, end_speed.x));
-  if (end_speed.x < 0) physic.set_velocity_x(std::max(physic.get_velocity_x() + velocity.x, end_speed.x));
-  if (end_speed.y > 0) physic.set_velocity_y(std::min(physic.get_velocity_y() + velocity.y, end_speed.y));
-  if (end_speed.y < 0) physic.set_velocity_y(std::max(physic.get_velocity_y() + velocity.y, end_speed.y));
+  if (end_speed.x > 0)
+    physic.set_velocity_x(std::min(physic.get_velocity_x() + velocity.x, end_speed.x));
+  if (end_speed.x < 0)
+    physic.set_velocity_x(std::max(physic.get_velocity_x() + velocity.x, end_speed.x));
+  if (end_speed.y > 0)
+    physic.set_velocity_y(std::min(physic.get_velocity_y() + velocity.y, end_speed.y));
+  if (end_speed.y < 0)
+    physic.set_velocity_y(std::max(physic.get_velocity_y() + velocity.y, end_speed.y));
 }
 
 void
@@ -1146,7 +1096,8 @@ Player::bounce(BadGuy& )
 void
 Player::deactivate()
 {
-  if (deactivated) return;
+  if (deactivated)
+    return;
   deactivated = true;
   physic.set_velocity_x(0);
   physic.set_velocity_y(0);
@@ -1157,7 +1108,8 @@ Player::deactivate()
 void
 Player::activate()
 {
-  if (!deactivated) return;
+  if (!deactivated)
+    return;
   deactivated = false;
 }
 
@@ -1169,7 +1121,9 @@ void Player::walk(float speed)
 void
 Player::set_ghost_mode(bool enable)
 {
-  if (ghost_mode == enable) return;
+  if (ghost_mode == enable)
+    return;
+
   if (enable) {
     ghost_mode = true;
     set_group(COLGROUP_DISABLED);
@@ -1182,4 +1136,3 @@ Player::set_ghost_mode(bool enable)
     log_debug << "You feel solid again." << std::endl;
   }
 }
-
index 885d41e..866a0bf 100644 (file)
@@ -97,7 +97,7 @@ private:
   int  backflip_direction;
   Direction peeking;
   bool swimming;
-  
+
 public:
   Direction dir;
   Direction old_dir;
@@ -120,7 +120,7 @@ public:
   Timer idle_timer;
   Timer backflip_timer;
   Physic physic;
-  
+
 public:
   Player(PlayerStatus* player_status);
   virtual ~Player();
@@ -153,25 +153,25 @@ public:
   {
     return peeking;
   }
-  
+
   void kill(bool completely);
   void check_bounds(Camera* camera);
   void move(const Vector& vector);
 
   virtual bool add_bonus(const std::string& bonus);
   virtual void add_coins(int count);
-  
+
   /**
    * picks up a bonus, taking care not to pick up lesser bonus items than we already have
    *
    * @returns true if the bonus has been set (or was already good enough)
    *          false if the bonus could not be set (for example no space for big tux)
    */
-  bool add_bonus(BonusType type, bool animate = false); 
+  bool add_bonus(BonusType type, bool animate = false);
   /**
    * like add_bonus, but can also downgrade the bonus items carried
-   */  
-  bool set_bonus(BonusType type, bool animate = false); 
+   */
+  bool set_bonus(BonusType type, bool animate = false);
 
   PlayerStatus* get_status()
   {
@@ -180,7 +180,7 @@ public:
   // set kick animation
   void kick();
 
-  /** 
+  /**
    * play cheer animation.
    * This might need some space and behave in an unpredictable way. Best to use this at level end.
    */
@@ -235,7 +235,7 @@ public:
   }
 
   /**
-   * Switches ghost mode on/off. 
+   * Switches ghost mode on/off.
    * Lets Tux float around and through solid objects.
    */
   void set_ghost_mode(bool enable);
@@ -255,9 +255,9 @@ private:
   void handle_input();
   void handle_input_ghost(); /**< input handling while in ghost mode */
   bool deactivated;
-  
+
   void init();
-  
+
   void handle_horizontal_input();
   void handle_vertical_input();
 
index 6358b9d..52802ba 100644 (file)
@@ -35,7 +35,7 @@ class Portable
 public:
   virtual ~Portable()
   { }
-  
+
   /**
    * called each frame when the object has been grabbed.
    */
index b865ba8..09a7470 100644 (file)
@@ -93,4 +93,3 @@ PowerUp::update(float elapsed_time)
 }
 
 IMPLEMENT_FACTORY(PowerUp, "powerup");
-
index 04ccb35..5ed2b49 100644 (file)
@@ -33,7 +33,7 @@ public:
   virtual void update(float elapsed_time);
   virtual void collision_solid(const CollisionHit& hit);
   virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
-  
+
 private:
   Physic physic;
   std::string script;
@@ -41,4 +41,3 @@ private:
 };
 
 #endif
-
index b4241f6..913baea 100644 (file)
@@ -27,7 +27,7 @@ RainSplash::RainSplash(Vector pos, bool vertical)
   if (vertical) sprite = sprite_manager->create("images/objects/particles/rainsplash-vertical.sprite");
   else sprite = sprite_manager->create("images/objects/particles/rainsplash.sprite");
 }
-  
+
 RainSplash::~RainSplash() {
   remove_me();
 }
@@ -38,7 +38,7 @@ RainSplash::hit(Player& )
 }
 
 void
-RainSplash::update(float time) 
+RainSplash::update(float time)
 {
   time = 0;//just so i don't get an "unused variable" error - don't know how to circumvent this
   frame++;
@@ -46,7 +46,7 @@ RainSplash::update(float time)
 }
 
 void
-RainSplash::draw(DrawingContext& context) 
+RainSplash::draw(DrawingContext& context)
 {
    sprite->draw(context, position, LAYER_OBJECTS);
 }
index 180b292..61e438f 100644 (file)
@@ -33,7 +33,7 @@ class RainSplash : public GameObject
 public:
   RainSplash(Vector pos, bool vertical);
   ~RainSplash();
-protected:  
+protected:
   virtual void hit(Player& );
   virtual void update(float time);
   virtual void draw(DrawingContext& context);
@@ -44,4 +44,3 @@ private:
 };
 
 #endif
-
index c05cea6..f0b6c2c 100644 (file)
@@ -53,7 +53,7 @@ Rock::update(float elapsed_time)
 {
   if( grabbed )
     return;
-  
+
   movement = physic.get_movement(elapsed_time);
 }
 
@@ -66,7 +66,7 @@ Rock::collision_solid(const CollisionHit& hit)
     physic.set_velocity_x( 0 );
   if( hit.crush )
     physic.set_velocity(0, 0);
-  
+
   if( hit.bottom  && !on_ground ){
     sound_manager->play( ROCK_SOUND, get_pos() );
     on_ground = true;
@@ -79,16 +79,16 @@ Rock::collision(GameObject& other, const CollisionHit& hit)
   if( !on_ground ){
       return FORCE_MOVE;
   }
-  
-  //Fake being solid for moving_object. 
+
+  //Fake being solid for moving_object.
   MovingObject* moving_object = dynamic_cast<MovingObject*> (&other);
   if( moving_object ){
       if( hit.top ){
         float inside = moving_object->get_bbox().get_bottom() - get_bbox().get_top();
         if( inside > 0 ){
           Vector pos = moving_object->get_pos();
-          pos.y -= inside; 
-          moving_object->set_pos( pos );    
+          pos.y -= inside;
+          moving_object->set_pos( pos );
         }
       }
       CollisionHit hit_other = hit;
@@ -106,7 +106,7 @@ Rock::grab(MovingObject& , const Vector& pos, Direction)
   set_group( COLGROUP_DISABLED );
   on_ground = true;
   grabbed = true;
+
 }
 
 void
@@ -118,4 +118,3 @@ Rock::ungrab(MovingObject& , Direction ){
 }
 
 IMPLEMENT_FACTORY(Rock, "rock");
-
index 13c0840..8ce1cb4 100644 (file)
@@ -38,7 +38,7 @@ public:
   HitResponse collision(GameObject& other, const CollisionHit& hit);
   void update(float elapsed_time);
   void write(lisp::Writer& writer);
-    
+
   void grab(MovingObject& object, const Vector& pos, Direction dir);
   void ungrab(MovingObject& object, Direction dir);
 
index 90875f2..67963ec 100644 (file)
@@ -35,7 +35,7 @@ ScriptedObject::ScriptedObject(const lisp::Lisp& lisp)
   lisp.get("name", name);
   if(name == "")
     throw std::runtime_error("Scripted object must have a name specified");
-  
+
   // FIXME: do we need this? bbox is already set via .sprite file
   float width = sprite->get_width();
   float height = sprite->get_height();
index 7231d3d..1e432a7 100644 (file)
@@ -39,7 +39,7 @@ public:
 
   void update(float elapsed_time);
   void draw(DrawingContext& context);
-  
+
   void collision_solid(const CollisionHit& hit);
   HitResponse collision(GameObject& other, const CollisionHit& hit);
 
@@ -73,4 +73,3 @@ private:
 };
 
 #endif
-
index abbddd8..04f140c 100644 (file)
@@ -54,7 +54,7 @@ SkullTile::draw(DrawingContext& context)
   // shacking
   if(timer.get_timegone() > CRACKTIME) {
     pos.x += systemRandom.rand(-3, 3);
-  } 
+  }
 
   sprite->draw(context, pos, layer);
 }
@@ -71,7 +71,7 @@ SkullTile::update(float elapsed_time)
   } else if(hit) {
     if(timer.check()) {
       falling = true;
-      physic.enable_gravity(true);      
+      physic.enable_gravity(true);
       flags &= ~FLAG_SOLID;
       timer.stop();
     } else if(!timer.started()) {
index 183ae34..f9a19fc 100644 (file)
@@ -46,4 +46,3 @@ private:
 };
 
 #endif
-
index 9cb3690..60c7861 100644 (file)
@@ -56,4 +56,3 @@ SpecialRiser::draw(DrawingContext& context)
   child->draw(context);
   context.pop_transform();
 }
-
index 6a29688..6903aa8 100644 (file)
@@ -40,7 +40,7 @@ Spotlight::Spotlight(const lisp::Lisp& lisp)
   lisp.get("green", color.green);
   lisp.get("blue",  color.blue);
   lisp.get("alpha", color.alpha);
-  
+
   center    = sprite_manager->create("images/objects/spotlight/spotlight_center.sprite");
   base      = sprite_manager->create("images/objects/spotlight/spotlight_base.sprite");
   lights    = sprite_manager->create("images/objects/spotlight/spotlight_lights.sprite");
@@ -68,9 +68,9 @@ Spotlight::update(float delta)
 void
 Spotlight::draw(DrawingContext& context)
 {
-  context.push_target(); 
+  context.push_target();
   context.set_target(DrawingContext::LIGHTMAP);
+
   light->set_color(color);
   light->set_blend(Blend(GL_SRC_ALPHA, GL_ONE));
   light->set_angle(angle);
@@ -78,7 +78,7 @@ Spotlight::draw(DrawingContext& context)
 
   //lightcone->set_angle(angle);
   //lightcone->draw(context, position, 0);
-  
+
   context.set_target(DrawingContext::NORMAL);
 
   lights->set_angle(angle);
index 2cfabb4..bb4e7ce 100644 (file)
@@ -49,4 +49,3 @@ private:
 };
 
 #endif
-
index 0babaf2..18d7b88 100644 (file)
@@ -25,7 +25,7 @@
 #include "main.hpp"
 #include "log.hpp"
 
-SpriteParticle::SpriteParticle(std::string sprite_name, std::string action, Vector position, AnchorPoint anchor, Vector velocity, Vector acceleration, int drawing_layer) 
+SpriteParticle::SpriteParticle(std::string sprite_name, std::string action, Vector position, AnchorPoint anchor, Vector velocity, Vector acceleration, int drawing_layer)
        : position(position), velocity(velocity), acceleration(acceleration), drawing_layer(drawing_layer)
 {
   sprite = sprite_manager->create(sprite_name);
@@ -35,8 +35,8 @@ SpriteParticle::SpriteParticle(std::string sprite_name, std::string action, Vect
 
   this->position -= get_anchor_pos(sprite->get_current_hitbox(), anchor);
 }
-  
-SpriteParticle::~SpriteParticle() 
+
+SpriteParticle::~SpriteParticle()
 {
   remove_me();
 }
@@ -47,7 +47,7 @@ SpriteParticle::hit(Player& )
 }
 
 void
-SpriteParticle::update(float elapsed_time) 
+SpriteParticle::update(float elapsed_time)
 {
   // die when animation is complete
   if (sprite->animation_done()) {
@@ -63,7 +63,7 @@ SpriteParticle::update(float elapsed_time)
 
   // die when too far offscreen
   Vector camera = Sector::current()->camera->get_translation();
-  if ((position.x < camera.x - 128) || (position.x > SCREEN_WIDTH + camera.x + 128) || 
+  if ((position.x < camera.x - 128) || (position.x > SCREEN_WIDTH + camera.x + 128) ||
       (position.y < camera.y - 128) || (position.y > SCREEN_HEIGHT + camera.y + 128)) {
     remove_me();
     return;
@@ -71,7 +71,7 @@ SpriteParticle::update(float elapsed_time)
 }
 
 void
-SpriteParticle::draw(DrawingContext& context) 
+SpriteParticle::draw(DrawingContext& context)
 {
    sprite->draw(context, position, drawing_layer);
 }
index a09b049..dba9caa 100644 (file)
@@ -35,7 +35,7 @@ class SpriteParticle : public GameObject
 public:
   SpriteParticle(std::string sprite_name, std::string action, Vector position, AnchorPoint anchor, Vector velocity, Vector acceleration, int drawing_layer = LAYER_OBJECTS-1);
   ~SpriteParticle();
-protected:  
+protected:
   virtual void hit(Player& player);
   virtual void update(float elapsed_time);
   virtual void draw(DrawingContext& context);
@@ -48,4 +48,3 @@ private:
 };
 
 #endif
-
index 617704c..316f572 100644 (file)
@@ -66,4 +66,3 @@ Star::collision(GameObject& other, const CollisionHit& )
 
   return FORCE_MOVE;
 }
-
index ef591ee..af35643 100644 (file)
@@ -145,4 +145,3 @@ TextObject::update(float elapsed_time)
     }
   }
 }
-
index c324e83..e649ef1 100644 (file)
@@ -58,4 +58,3 @@ private:
 };
 
 #endif
-
index 1aec362..f86279c 100644 (file)
@@ -74,8 +74,8 @@ Thunderstorm::update(float )
   }
 }
 
-void 
-Thunderstorm::draw(DrawingContext& context) 
+void
+Thunderstorm::draw(DrawingContext& context)
 {
   if (!flash_display_timer.started()) return;
 
@@ -149,4 +149,3 @@ Thunderstorm::electrify()
 }
 
 IMPLEMENT_FACTORY(Thunderstorm, "thunderstorm");
-
index 77f8f68..ee14303 100644 (file)
@@ -44,7 +44,7 @@ public:
      * Start playing thunder and lightning at configured interval
      */
     void start();
-    
+
     /**
      * Stop playing thunder and lightning at configured interval
      */
@@ -74,11 +74,10 @@ private:
     std::string name; /**< user-defined name for use in scripts or empty string if not scriptable */
     bool running; /**< whether we currently automatically trigger lightnings */
     float interval; /**< time between two lightnings */
-    
+
     Timer time_to_thunder; /**< counts down until next thunder */
     Timer time_to_lightning; /**< counts down until next lightning */
     Timer flash_display_timer; /**< counts down while flash is displayed */
 };
 
 #endif
-
index d971282..96a5153 100644 (file)
@@ -66,7 +66,7 @@ TileMap::TileMap(const lisp::Lisp& reader, TileManager* new_tile_manager)
   }
   if(solid)
     flags |= FLAG_SOLID;
+
   reader.get("width", width);
   reader.get("height", height);
   if(width < 0 || height < 0)
@@ -89,11 +89,11 @@ TileMap::TileMap(std::string name, int z_pos, bool solid, size_t width, size_t h
     x_offset(0), y_offset(0), drawing_effect(NO_EFFECT)
 {
   tilemanager = tile_manager;
-  
+
   resize(width, height);
 
   if(solid)
-    flags |= FLAG_SOLID;  
+    flags |= FLAG_SOLID;
 }
 
 TileMap::~TileMap()
@@ -112,7 +112,7 @@ TileMap::write(lisp::Writer& writer)
   writer.write_int("width", width);
   writer.write_int("height", height);
   writer.write_int_vector("tiles", tiles);
-  
+
   writer.end_list("tilemap");
 }
 
@@ -132,7 +132,7 @@ TileMap::draw(DrawingContext& context)
 {
   context.push_transform();
 
-  if(drawing_effect != 0) context.set_drawing_effect(drawing_effect); 
+  if(drawing_effect != 0) context.set_drawing_effect(drawing_effect);
   float trans_x = roundf(context.get_translation().x);
   float trans_y = roundf(context.get_translation().y);
   context.set_translation(Vector(trans_x * speed, trans_y * speed));
@@ -180,7 +180,7 @@ TileMap::set(int newwidth, int newheight, const std::vector<unsigned int>&newt,
 
   // make sure all tiles are loaded
   for(Tiles::iterator i = tiles.begin(); i != tiles.end(); ++i)
-    tilemanager->get(*i);                                        
+    tilemanager->get(*i);
 }
 
 void
@@ -194,9 +194,9 @@ TileMap::resize(int new_width, int new_height)
       }
     }
   }
-                                                                                
+
   tiles.resize(new_width * new_height);
-                                                                                
+
   if(new_width > width) {
     // remap tiles
     for(int y = std::min(height, new_height)-1; y >= 0; --y) {
@@ -205,7 +205,7 @@ TileMap::resize(int new_width, int new_height)
           tiles[y * new_width + x] = 0;
           continue;
         }
-        
+
         tiles[y * new_width + x] = tiles[y * width + x];
       }
     }
index 9817493..cb87573 100644 (file)
@@ -66,10 +66,10 @@ public:
 
   size_t get_height() const
   { return height; }
-  
+
   float get_x_offset() const
   { return x_offset; }
-  
+
   float get_y_offset() const
   { return y_offset; }
 
@@ -81,7 +81,7 @@ public:
 
   int get_layer() const
   { return z_pos; }
-  
+
   bool is_solid() const
   { return solid; }
 
@@ -115,7 +115,7 @@ public:
 private:
   typedef std::vector<uint32_t> Tiles;
   Tiles tiles;
-  
+
 private:
   TileManager* tilemanager;
   std::string name;
@@ -130,4 +130,3 @@ private:
 };
 
 #endif /*SUPERTUX_TILEMAP_H*/
-
index 0260e95..ed83793 100644 (file)
@@ -2,7 +2,7 @@
 //
 //  SuperTux - Trampoline
 //  Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
-//  
+//
 //  This program is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU General Public License
 //  as published by the Free Software Foundation; either version 2
@@ -25,7 +25,7 @@
 #include "audio/sound_manager.hpp"
 #include "sprite/sprite_manager.hpp"
 
-/* Trampoline will accelerate player to to VY_INITIAL, if 
+/* Trampoline will accelerate player to to VY_INITIAL, if
  * he jumps on it to VY_MIN. */
 namespace {
   const std::string TRAMPOLINE_SOUND = "sounds/trampoline.wav";
@@ -77,7 +77,7 @@ Trampoline::collision(GameObject& other, const CollisionHit& hit )
     float vy = player->physic.get_velocity_y();
     //player is falling down on trampoline
     if(hit.top && vy > 0) {
-      if(player->get_controller()->hold(Controller::JUMP)) { 
+      if(player->get_controller()->hold(Controller::JUMP)) {
         vy = VY_MIN;
       } else {
         vy = VY_INITIAL;
@@ -88,15 +88,15 @@ Trampoline::collision(GameObject& other, const CollisionHit& hit )
       return FORCE_MOVE;
     }
   }
-  //Fake being solid for moving_object. 
+  //Fake being solid for moving_object.
   MovingObject* moving_object = dynamic_cast<MovingObject*> (&other);
   if( moving_object ){
       if( hit.top ){
         float inside = moving_object->get_bbox().get_bottom() - get_bbox().get_top();
         if( inside > 0 ){
           Vector pos = moving_object->get_pos();
-          pos.y -= inside; 
-          moving_object->set_pos( pos );    
+          pos.y -= inside;
+          moving_object->set_pos( pos );
         }
       }
       CollisionHit hit_other = hit;
@@ -107,12 +107,12 @@ Trampoline::collision(GameObject& other, const CollisionHit& hit )
   return FORCE_MOVE;
 }
 
-void 
+void
 Trampoline::collision_solid( const CollisionHit& hit ){
   if( hit.bottom ){
      on_ground = true;
   }
-} 
+}
 
 void
 Trampoline::grab( MovingObject&, const Vector& pos, Direction ){
index f856ca0..8f846c6 100644 (file)
 #include "object/portable.hpp"
 #include "physic.hpp"
 
-/** 
+/**
  * Jumping on a trampolin makes tux jump higher.
  */
-class Trampoline : public MovingSprite, 
+class Trampoline : public MovingSprite,
                    public Portable
-                 
+
 {
 public:
   Trampoline(const lisp::Lisp& reader);
-  
+
   HitResponse collision(GameObject& other, const CollisionHit& hit);
   void collision_solid( const CollisionHit& hit );
   void update( float elapsed_time );
 
   void grab( MovingObject&, const Vector& pos, Direction );
   void ungrab(MovingObject& , Direction );
-  
+
 private:
   Physic physic;
   bool on_ground;
 };
 
 #endif
-
index cd19c4e..9c6e0bd 100644 (file)
@@ -26,7 +26,7 @@
 #include "physic.hpp"
 #include "timer.hpp"
 
-/** 
+/**
  * A block that disintegrates when stood on
  */
 class UnstableTile : public MovingSprite
@@ -50,4 +50,3 @@ private:
 };
 
 #endif
-
index cc5baf8..e36d1eb 100644 (file)
@@ -26,7 +26,7 @@
 #include "physic.hpp"
 #include "timer.hpp"
 
-/** 
+/**
  * A block that can be destroyed by Bullet hits
  */
 class WeakBlock : public MovingSprite
@@ -60,4 +60,3 @@ private:
 };
 
 #endif
-
index 2da07d9..8411ca2 100644 (file)
@@ -28,7 +28,7 @@
 
 class Player;
 
-/** 
+/**
  * Defines an area that will gently push Players in one direction
  */
 class Wind : public MovingObject, public ScriptInterface
@@ -39,12 +39,12 @@ public:
   void update(float elapsed_time);
   void draw(DrawingContext& context);
   HitResponse collision(GameObject& other, const CollisionHit& hit);
-  
+
   /**
    * start blowing
    */
   void start();
-  
+
   /**
    * stop blowing
    */
@@ -52,10 +52,10 @@ public:
 
   virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
   virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
+
 private:
   std::string name; /**< user-defined name for use in scripts or empty string if not scriptable */
+
   bool blowing; /**< true if wind is currently switched on */
   Vector speed;
   float acceleration;
@@ -64,4 +64,3 @@ private:
 };
 
 #endif
-
index afae27f..0b69169 100644 (file)
@@ -46,7 +46,7 @@ GameObject* create_object(const std::string& name, const Vector& pos)
   lisptext << "(" << name
            << " (x " << pos.x << ")"
            << " (y " << pos.y << "))";
-  
+
   lisp::Parser parser;
   std::auto_ptr<lisp::Lisp> lisp (parser.parse(lisptext));
   return create_object(name, *lisp);
index 922eec4..7e06739 100644 (file)
@@ -32,7 +32,7 @@ class Factory
 public:
   virtual ~Factory()
   { }
-    
+
   /** Creates a new gameobject from a lisp node.
    * Remember to delete the objects later
    */
index 2a22af6..5ac1308 100644 (file)
@@ -68,7 +68,7 @@ static int funcRead(struct SDL_RWops* context, void* ptr, int size, int maxnum)
 static int funcClose(struct SDL_RWops* context)
 {
     PHYSFS_file* file = (PHYSFS_file*) context->hidden.unknown.data1;
-    
+
     PHYSFS_close(file);
     delete context;
 
@@ -84,7 +84,7 @@ SDL_RWops* get_physfs_SDLRWops(const std::string& filename)
             << PHYSFS_getLastError();
         throw std::runtime_error(msg.str());
     }
-    
+
     SDL_RWops* ops = new SDL_RWops();
     ops->type = 0;
     ops->hidden.unknown.data1 = file;
index 5707e7d..214d0b1 100644 (file)
@@ -26,4 +26,3 @@
 SDL_RWops* get_physfs_SDLRWops(const std::string& filename);
 
 #endif
-
index acb2670..3a3c74b 100644 (file)
@@ -48,7 +48,7 @@ IFileStreambuf::underflow()
     if(PHYSFS_eof(file)) {
         return traits_type::eof();
     }
-   
+
     PHYSFS_sint64 bytesread = (size_t) PHYSFS_read(file, buf, 1, sizeof(buf));
     if(bytesread <= 0) {
         return traits_type::eof();
@@ -76,7 +76,7 @@ IFileStreambuf::seekoff(off_type off, std::ios_base::seekdir dir,
 {
   off_type pos = off;
   PHYSFS_sint64 ptell = PHYSFS_tell(file);
-  
+
   switch(dir) {
     case std::ios_base::beg:
       break;
@@ -110,7 +110,7 @@ OFileStreambuf::OFileStreambuf(const std::string& filename)
             << PHYSFS_getLastError();
         throw std::runtime_error(msg.str());
     }
-    
+
     setp(buf, buf+sizeof(buf));
 }
 
@@ -130,7 +130,7 @@ OFileStreambuf::overflow(int c)
     PHYSFS_sint64 res = PHYSFS_write(file, pbase(), 1, size);
     if(res <= 0)
         return traits_type::eof();
-    
+
     if(c != traits_type::eof()) {
         PHYSFS_sint64 res = PHYSFS_write(file, &c, 1, 1);
         if(res <= 0)
@@ -170,4 +170,3 @@ OFileStream::~OFileStream()
 {
     delete rdbuf();
 }
-
index 3f4bd18..077a876 100644 (file)
@@ -34,7 +34,7 @@ class IFileStreambuf : public std::streambuf
 public:
     IFileStreambuf(const std::string& filename);
     ~IFileStreambuf();
-    
+
 protected:
     virtual int underflow();
     virtual pos_type seekoff(off_type pos, std::ios_base::seekdir,
@@ -76,4 +76,3 @@ public:
 };
 
 #endif
-
index 518ce83..358b41c 100644 (file)
@@ -145,14 +145,13 @@ Vector
 Physic::get_movement(float elapsed_time)
 {
   float grav = gravity_enabled_flag ? 1000 : 0;
-  
+
   Vector result(
       vx * elapsed_time + ax * elapsed_time * elapsed_time,
       vy * elapsed_time + (ay + grav) * elapsed_time * elapsed_time
   );
   vx += ax * elapsed_time;
-  vy += (ay + grav) * elapsed_time;  
+  vy += (ay + grav) * elapsed_time;
 
   return result;
 }
-
index f39ded0..ee86477 100644 (file)
@@ -45,7 +45,7 @@ PlayerStatus::PlayerStatus()
     max_score_multiplier(1)
 {
   reset();
-  
+
   tux_life.reset(sprite_manager->create("images/creatures/tux_small/tux-life.sprite"));
 
   Console::instance->registerCommand("coins", this);
@@ -97,7 +97,7 @@ PlayerStatus::write(lisp::Writer& writer)
   }
   writer.write_int("fireflowers", max_fire_bullets);
   writer.write_int("iceflowers", max_ice_bullets);
-  
+
   writer.write_int("coins", coins);
   writer.write_int("max-score-multiplier", max_score_multiplier);
 }
@@ -106,7 +106,7 @@ void
 PlayerStatus::read(const lisp::Lisp& lisp)
 {
   reset();
-  
+
   std::string bonusname;
   if(lisp.get("bonus", bonusname)) {
     if(bonusname == "none") {
@@ -136,7 +136,7 @@ PlayerStatus::draw(DrawingContext& context)
   context.set_translation(Vector(0, 0));
 
   char str[60];
+
   int displayCoins = std::max(player_status->coins, 0);
   snprintf(str, sizeof(str), "%d", displayCoins);
   const char* coinstext = _("COINS");
@@ -168,4 +168,3 @@ PlayerStatus::consoleCommand(std::string command, std::vector<std::string> argum
   }
   return false;
 }
-
index 16cb906..1559725 100644 (file)
@@ -36,7 +36,7 @@ enum BonusType {
 };
 class DrawingContext;
 
-/** 
+/**
  * This class memorizes player status between different game sessions (for
  * example when switching maps in the worldmap)
  */
@@ -45,7 +45,7 @@ class PlayerStatus : public Serializable, public ConsoleCommandReceiver
 public:
   PlayerStatus();
   ~PlayerStatus();
-  void reset();     
+  void reset();
   void add_coins(int count, bool play_sound = true);
 
   void write(lisp::Writer& writer);
@@ -54,7 +54,7 @@ public:
   void draw(DrawingContext& context);
 
   bool consoleCommand(std::string command, std::vector<std::string> arguments); /**< callback from Console; return false if command was unknown, true otherwise */
-  
+
   int  coins;
   BonusType bonus;
   int max_fire_bullets; /**< maximum number of fire bullets in play */
@@ -64,11 +64,11 @@ public:
   int max_score_multiplier;
 
   void operator= (const PlayerStatus& other);
-  
+
 private:
   // don't use this
   PlayerStatus(const PlayerStatus& other);
-  
+
   std::auto_ptr<Sprite> tux_life;
 };
 
index 69bd840..0fd8dc5 100644 (file)
@@ -1,5 +1,5 @@
 // $Id$
-// 
+//
 // A strong random number generator
 //
 // Copyright (C) 2006 Allen King
@@ -9,16 +9,16 @@
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions
 // are met:
-// 
-// 1. Redistributions of source code must retain the above copyright 
-//    notice, this list of conditions and the following disclaimer.  
+//
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
 // 2. Redistributions in binary form must reproduce the above copyright
 //    notice, this list of conditions and the following disclaimer in the
-//    documentation and/or other materials provided with the distribution.  
+//    documentation and/or other materials provided with the distribution.
 // 3. Neither the name of the project nor the names of its contributors
 //    may be used to endorse or promote products derived from this software
-//    without specific prior written permission. 
-// 
+//    without specific prior written permission.
+//
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -28,7 +28,7 @@
 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 // SUCH DAMAGE.
 
 // Transliterated into C++ Allen King 060417, from sources on
@@ -58,7 +58,7 @@ int RandomGenerator::srand(int x)    {
         x = time(0) % RandomGenerator::rand_max; // randomize with time
 
     if (debug > 0)
-        printf("==== srand(%10d) (%10d) rand_max=%x =====\n", 
+        printf("==== srand(%10d) (%10d) rand_max=%x =====\n",
                x, x0, RandomGenerator::rand_max);
 
     RandomGenerator::srandom(x);
@@ -86,7 +86,7 @@ int RandomGenerator::rand(int v) {
 }
 
 int RandomGenerator::rand(int u, int v) {
-    assert(v > u);    
+    assert(v > u);
     return u + RandomGenerator::rand(v-u);
 }
 
@@ -106,23 +106,23 @@ double RandomGenerator::randf(double u, double v) {
 }
 
 //-----------------------------------------------------------------------
-//        
+//
 // Copyright (C) 2002 Michael Ringgaard. All rights reserved.
 // Copyright (C) 1983, 1993 The Regents of the University of California.
 //
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions
 // are met:
-// 
-// 1. Redistributions of source code must retain the above copyright 
-//    notice, this list of conditions and the following disclaimer.  
+//
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
 // 2. Redistributions in binary form must reproduce the above copyright
 //    notice, this list of conditions and the following disclaimer in the
-//    documentation and/or other materials provided with the distribution.  
+//    documentation and/or other materials provided with the distribution.
 // 3. Neither the name of the project nor the names of its contributors
 //    may be used to endorse or promote products derived from this software
-//    without specific prior written permission. 
-// 
+//    without specific prior written permission.
+//
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -132,9 +132,9 @@ double RandomGenerator::randf(double u, double v) {
 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 // SUCH DAMAGE.
-// 
+//
 
 //**#include <os.h>
 
@@ -250,7 +250,7 @@ void RandomGenerator::initialize() {
     randtbl[30] =  0x535b6b41;
     randtbl[31] =  0xf3bec5da;
 
-// static long randtbl[DEG_3 + 1] = 
+// static long randtbl[DEG_3 + 1] =
 // {
 //   TYPE_3;
 //   0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
@@ -340,7 +340,7 @@ void RandomGenerator::srandom(unsigned long x)
   state[0] = x;
   if (rand_type == TYPE_0)
     lim = NSHUFF;
-  else 
+  else
   {
     for (i = 1; i < rand_deg; i++) state[i] = good_rand(state[i - 1]);
     fptr = &state[rand_sep];
@@ -380,13 +380,13 @@ void RandomGenerator::srandomdev()
 
   done = 0;
   fd = open("/dev/urandom", O_RDONLY);
-  if (fd >= 0) 
+  if (fd >= 0)
    {
      if (read(fd, state, len) == len) done = 1;
      close(fd);
    }
 
-  if (!done) 
+  if (!done)
   {
     struct timeval tv;
 
@@ -395,7 +395,7 @@ void RandomGenerator::srandomdev()
     return;
   }
 
-  if (rand_type != TYPE_0) 
+  if (rand_type != TYPE_0)
   {
     fptr = &state[rand_sep];
     rptr = &state[0];
@@ -435,37 +435,37 @@ char * RandomGenerator::initstate(unsigned long seed, char *arg_state, long n)
 
   if (n < BREAK_0) return NULL;
 
-  if (n < BREAK_1) 
+  if (n < BREAK_1)
   {
     rand_type = TYPE_0;
     rand_deg = DEG_0;
     rand_sep = SEP_0;
-  } 
-  else if (n < BREAK_2) 
+  }
+  else if (n < BREAK_2)
   {
     rand_type = TYPE_1;
     rand_deg = DEG_1;
     rand_sep = SEP_1;
-  } 
-  else if (n < BREAK_3) 
+  }
+  else if (n < BREAK_3)
   {
     rand_type = TYPE_2;
     rand_deg = DEG_2;
     rand_sep = SEP_2;
-  } 
-  else if (n < BREAK_4) 
+  }
+  else if (n < BREAK_4)
   {
     rand_type = TYPE_3;
     rand_deg = DEG_3;
     rand_sep = SEP_3;
-  } 
-  else 
+  }
+  else
   {
     rand_type = TYPE_4;
     rand_deg = DEG_4;
     rand_sep = SEP_4;
   }
-  
+
   state = (long *) (long_arg_state + 1); // First location
   end_ptr = &state[rand_deg]; // Must set end_ptr before srandom
   srandom(seed);
@@ -507,7 +507,7 @@ char * RandomGenerator::setstate(char *arg_state)
   else
     state[-1] = MAX_TYPES * (rptr - state) + rand_type;
 
-  switch(type) 
+  switch(type)
   {
     case TYPE_0:
     case TYPE_1:
@@ -521,7 +521,7 @@ char * RandomGenerator::setstate(char *arg_state)
   }
 
   state = (long *) (new_state + 1);
-  if (rand_type != TYPE_0) 
+  if (rand_type != TYPE_0)
   {
     rptr = &state[rear];
     fptr = &state[(rear + rand_sep) % rand_deg];
@@ -558,22 +558,22 @@ long RandomGenerator::random()
       throw std::runtime_error("uninitialized RandomGenerator object");
   }
 
-  if (rand_type == TYPE_0) 
+  if (rand_type == TYPE_0)
   {
     i = state[0];
     state[0] = i = (good_rand(i)) & 0x7fffffff;
-  } 
-  else 
+  }
+  else
   {
     f = fptr; r = rptr;
     *f += *r;
     i = (*f >> 1) & 0x7fffffff; // Chucking least random bit
-    if (++f >= end_ptr) 
+    if (++f >= end_ptr)
     {
       f = state;
       ++r;
     }
-    else if (++r >= end_ptr) 
+    else if (++r >= end_ptr)
       r = state;
 
     fptr = f; rptr = r;
index 4bf605e..480a53e 100644 (file)
@@ -1,5 +1,5 @@
 // $Id$
-// 
+//
 // A strong random number generator
 //
 // Copyright (C) 2006 Allen King
@@ -9,16 +9,16 @@
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions
 // are met:
-// 
-// 1. Redistributions of source code must retain the above copyright 
-//    notice, this list of conditions and the following disclaimer.  
+//
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
 // 2. Redistributions in binary form must reproduce the above copyright
 //    notice, this list of conditions and the following disclaimer in the
-//    documentation and/or other materials provided with the distribution.  
+//    documentation and/or other materials provided with the distribution.
 // 3. Neither the name of the project nor the names of its contributors
 //    may be used to endorse or promote products derived from this software
-//    without specific prior written permission. 
-// 
+//    without specific prior written permission.
+//
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -28,7 +28,7 @@
 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 // SUCH DAMAGE.
 
 #ifndef __RANDOM_GENERATOR__
index 76f5677..4e15c0f 100644 (file)
@@ -85,4 +85,3 @@ private:
 };
 
 #endif
-
index c6d9598..0a56b06 100644 (file)
@@ -1,5 +1,5 @@
 //  $Id$
-// 
+//
 //  Windstille - A Jump'n Shoot Game
 //  Copyright (C) 2005 Matthias Braun <matze@braunis.de>
 //
@@ -12,7 +12,7 @@
 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 //  GNU General Public License for more details.
-// 
+//
 //  You should have received a copy of the GNU General Public License
 //  along with this program; if not, write to the Free Software
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
index 94e85e1..5c49081 100644 (file)
@@ -47,7 +47,7 @@ void load_shared()
   /* Load global images: */
   gold_text = new Font("images/engine/fonts/gold.png",
                        "images/engine/fonts/shadow.png", 16, 18);
-  blue_text = new Font("images/engine/fonts/blue.png", 
+  blue_text = new Font("images/engine/fonts/blue.png",
                        "images/engine/fonts/shadow.png", 16, 18, 3);
   white_text = new Font("images/engine/fonts/white.png",
                         "images/engine/fonts/shadow.png", 16, 18);
@@ -63,7 +63,7 @@ void load_shared()
   Menu::deactive_font = gray_text;
   Menu::label_font = white_big_text;
   Menu::field_font = gold_text;
-  
+
   Button::info_font = white_small_text;
 
   sprite_manager = new SpriteManager();
@@ -136,4 +136,3 @@ void unload_shared()
   /* Free mouse-cursor */
   delete mouse_cursor;
 }
-
index 8eebc1b..a2b753c 100644 (file)
@@ -51,4 +51,3 @@ public:
 };
 
 #endif
-
index 5a91489..952d034 100644 (file)
@@ -30,10 +30,9 @@ class ScreenFade : public Screen
 public:
   virtual ~ScreenFade()
   {}
-  
+
   /// returns true if the effect is completed
   virtual bool done() = 0;
 };
 
 #endif
-
index 6122670..3f47bcf 100644 (file)
@@ -31,10 +31,9 @@ class ScriptInterface
 public:
   virtual ~ScriptInterface()
   {}
-  
+
   virtual void expose(HSQUIRRELVM vm, SQInteger table_idx) = 0;
   virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx) = 0;
 };
 
 #endif
-
index 73ef049..a0dff38 100644 (file)
@@ -36,4 +36,3 @@ static const int ANCHOR_BOTTOM_RIGHT = 0x0022;
 }
 
 #endif
-
index cb4a93b..814284b 100644 (file)
@@ -35,13 +35,13 @@ namespace Scripting
 
   Camera::~Camera()
   { }
-  
+
   void
   Camera::shake(float , float , float )
   {
     NOIMPL;
   }
-  
+
   void
   Camera::set_pos(float , float )
   {
index cdd10e0..325ef6f 100644 (file)
@@ -53,4 +53,3 @@ public:
 }
 
 #endif
-
index cab136c..0223521 100644 (file)
@@ -36,13 +36,13 @@ namespace Scripting
 
   Candle::~Candle()
   { }
-  bool Candle::get_burning() 
+
+  bool Candle::get_burning()
   {
     return candle->get_burning();
   }
 
-  void Candle::set_burning(bool burning) 
+  void Candle::set_burning(bool burning)
   {
     candle->set_burning(burning);
   }
index c7c022e..be64bab 100644 (file)
@@ -47,4 +47,3 @@ public:
 }
 
 #endif
-
index 1647685..3b40344 100644 (file)
@@ -31,7 +31,7 @@ namespace Scripting
 FloatingImage::FloatingImage(const std::string& spritefile)
 {
   using namespace WorldMapNS;
-  
+
   floating_image = new _FloatingImage(spritefile);
   if(Sector::current() != NULL) {
     Sector::current()->add_object(floating_image.get());
index 68d82f0..7434a84 100644 (file)
@@ -49,7 +49,7 @@ public:
   bool get_visible();
   void set_action(const std::string& action);
   std::string get_action();
-  
+
 #ifndef SCRIPTING_API
 private:
   Ref<_FloatingImage> floating_image;
@@ -59,4 +59,3 @@ private:
 }
 
 #endif
-
index 5dd10ed..236a12a 100644 (file)
@@ -131,11 +131,11 @@ static SQInteger squirrel_read_char(SQUserPointer file)
 void import(HSQUIRRELVM vm, const std::string& filename)
 {
   IFileStream in(filename);
-    
+
   if(SQ_FAILED(sq_compile(vm, squirrel_read_char, &in,
           filename.c_str(), SQTrue)))
     throw SquirrelError(vm, "Couldn't parse script");
-    
+
   sq_pushroottable(vm);
   if(SQ_FAILED(sq_call(vm, 1, SQFalse, SQTrue))) {
     sq_pop(vm, 1);
@@ -162,7 +162,7 @@ void debug_draw_solids_only(bool enable)
 void save_state()
 {
   using namespace WorldMapNS;
-  
+
   if(World::current() == NULL)
     throw std::runtime_error("Can't save state without active World");
 
@@ -272,4 +272,3 @@ int rand()
 }
 
 }
-
index 70c07d0..2cdc258 100644 (file)
@@ -44,4 +44,3 @@ public:
 }
 
 #endif
-
index cb20a73..fa44f2b 100644 (file)
@@ -36,18 +36,18 @@ namespace Scripting
 
   Platform::~Platform()
   { }
-  void Platform::goto_node(int node_no) 
+
+  void Platform::goto_node(int node_no)
   {
     platform->goto_node(node_no);
   }
 
-  void Platform::start_moving() 
+  void Platform::start_moving()
   {
     platform->start_moving();
   }
 
-  void Platform::stop_moving() 
+  void Platform::stop_moving()
   {
     platform->stop_moving();
   }
index d90784c..8b36aa7 100644 (file)
@@ -73,7 +73,7 @@ public:
   virtual void kill(bool completely) = 0;
 
   /**
-   * Switches ghost mode on/off. 
+   * Switches ghost mode on/off.
    * Lets Tux float around and through solid objects.
    */
   virtual void set_ghost_mode(bool enable) = 0;
@@ -83,7 +83,7 @@ public:
    */
   virtual bool get_ghost_mode() = 0;
 
-  /** 
+  /**
    * play cheer animation.
    * This might need some space and behave in an unpredictable way. Best to use this at level end.
    */
@@ -117,4 +117,3 @@ public:
 }
 
 #endif
-
index 4fe3261..c398443 100644 (file)
@@ -38,11 +38,11 @@ public:
   virtual void set_pos(float x, float y) = 0;
   virtual float get_pos_x() = 0;
   virtual float get_pos_y() = 0;
-  
+
   virtual void set_velocity(float x, float y) = 0;
   virtual float get_velocity_x() = 0;
   virtual float get_velocity_y() = 0;
-  
+
   virtual void set_visible(bool visible) = 0;
   virtual bool is_visible() = 0;
 
@@ -55,4 +55,3 @@ public:
 }
 
 #endif
-
index 79be04c..3455d2f 100644 (file)
@@ -36,8 +36,8 @@ void load_squirrel_table(HSQUIRRELVM vm, SQInteger table_idx, const lisp::Lisp*
   using namespace lisp;
 
   if(table_idx < 0)
-    table_idx -= 2; 
+    table_idx -= 2;
+
   lisp::ListIterator iter(lisp);
   while(iter.next() && iter.lisp() != NULL) {
     const std::string& token = iter.item();
@@ -80,7 +80,7 @@ void save_squirrel_table(HSQUIRRELVM vm, SQInteger table_idx, lisp::Writer& writ
   // offset because of sq_pushnull
   if(table_idx < 0)
     table_idx -= 1;
-  
+
   //iterator table
   sq_pushnull(vm);
   while(SQ_SUCCEEDED(sq_next(vm, table_idx))) {
@@ -136,4 +136,3 @@ void save_squirrel_table(HSQUIRRELVM vm, SQInteger table_idx, lisp::Writer& writ
 }
 
 }
-
index 3e9142a..d34b00f 100644 (file)
@@ -34,5 +34,3 @@ namespace Scripting
 }
 
 #endif
-
-
index b3cf9c1..f16bb63 100644 (file)
@@ -66,7 +66,7 @@ void init_squirrel(bool enable_debugger)
     debugger = sq_rdbg_init(global_vm, 1234, SQFalse);
     if(debugger == NULL)
       throw SquirrelError(global_vm, "Couldn't initialize squirrel debugger");
-  
+
     sq_enabledebuginfo(global_vm, SQTrue);
     log_info << "Waiting for debug client..." << std::endl;
     if(SQ_FAILED(sq_rdbg_waitforconnections(debugger)))
@@ -88,13 +88,13 @@ void init_squirrel(bool enable_debugger)
   sq_deleteslot(global_vm, -2, SQFalse);
   sq_pushstring(global_vm, "rand", -1);
   sq_deleteslot(global_vm, -2, SQFalse);
-  
+
   // register supertux API
   register_supertux_wrapper(global_vm);
 
   // TODO remove this at some point... it shoud just be functions not an object
   expose_object(global_vm, -1, new Scripting::Level(), "Level", true);
-  
+
   sq_pop(global_vm, 1);
 
   // register print function
@@ -141,12 +141,12 @@ std::string squirrel2string(HSQUIRRELVM v, SQInteger i)
   switch(sq_gettype(v, i))
     {
     case OT_NULL:
-      os << "<null>";        
+      os << "<null>";
       break;
     case OT_BOOL: {
       SQBool p;
       sq_getbool(v, i, &p);
-      if (p) 
+      if (p)
         os << "true";
       else
         os << "false";
@@ -168,7 +168,7 @@ std::string squirrel2string(HSQUIRRELVM v, SQInteger i)
       const SQChar* val;
       sq_getstring(v, i, &val);
       os << "\"" << val << "\"";
-      break;    
+      break;
     }
     case OT_TABLE: {
       bool first = true;
@@ -182,9 +182,9 @@ std::string squirrel2string(HSQUIRRELVM v, SQInteger i)
           first = false;
 
           //here -1 is the value and -2 is the key
-          os << squirrel2string(v, -2) << " => " 
+          os << squirrel2string(v, -2) << " => "
              << squirrel2string(v, -1);
-                              
+
           sq_pop(v,2); //pops key and val before the nex iteration
         }
       sq_pop(v, 1);
@@ -205,7 +205,7 @@ std::string squirrel2string(HSQUIRRELVM v, SQInteger i)
           //here -1 is the value and -2 is the key
           // we ignore the key, since that is just the index in an array
           os << squirrel2string(v, -1);
-                              
+
           sq_pop(v,2); //pops key and val before the nex iteration
         }
       sq_pop(v, 1);
@@ -215,7 +215,7 @@ std::string squirrel2string(HSQUIRRELVM v, SQInteger i)
     case OT_USERDATA:
       os << "<userdata>";
       break;
-    case OT_CLOSURE:        
+    case OT_CLOSURE:
       os << "<closure>";
       break;
     case OT_NATIVECLOSURE:
@@ -255,7 +255,7 @@ void print_squirrel_stack(HSQUIRRELVM v)
         switch(sq_gettype(v, i))
         {
             case OT_NULL:
-                printf("null");        
+                printf("null");
                 break;
             case OT_INTEGER: {
                 SQInteger val;
@@ -273,7 +273,7 @@ void print_squirrel_stack(HSQUIRRELVM v)
                 const SQChar* val;
                 sq_getstring(v, i, &val);
                 printf("string (%s)", val);
-                break;    
+                break;
             }
             case OT_TABLE:
                 printf("table");
@@ -284,8 +284,8 @@ void print_squirrel_stack(HSQUIRRELVM v)
             case OT_USERDATA:
                 printf("userdata");
                 break;
-            case OT_CLOSURE:        
-                printf("closure(function)");    
+            case OT_CLOSURE:
+                printf("closure(function)");
                 break;
             case OT_NATIVECLOSURE:
                 printf("native closure(C function)");
@@ -329,14 +329,14 @@ static SQInteger squirrel_read_char(SQUserPointer file)
 void compile_script(HSQUIRRELVM vm, std::istream& in, const std::string& sourcename)
 {
   if(SQ_FAILED(sq_compile(vm, squirrel_read_char, &in, sourcename.c_str(), true)))
-    throw SquirrelError(vm, "Couldn't parse script");  
+    throw SquirrelError(vm, "Couldn't parse script");
 }
 
 void compile_and_run(HSQUIRRELVM vm, std::istream& in,
                      const std::string& sourcename)
 {
   compile_script(vm, in, sourcename);
-  
+
   SQInteger oldtop = sq_gettop(vm);
 
   try {
@@ -365,7 +365,7 @@ HSQOBJECT create_thread(HSQUIRRELVM vm)
   if(SQ_FAILED(sq_getstackobj(vm, -1, &vm_object)))
     throw SquirrelError(vm, "Couldn't get squirrel thread from stack");
   sq_addref(vm, &vm_object);
-  
+
   sq_pop(vm, 1);
 
   return vm_object;
index 874bb8e..5ebb44a 100644 (file)
@@ -39,7 +39,7 @@ namespace Scripting
   void print_squirrel_stack(HSQUIRRELVM vm);
 
   HSQOBJECT create_thread(HSQUIRRELVM vm);
-  SQObject vm_to_object(HSQUIRRELVM vm); 
+  SQObject vm_to_object(HSQUIRRELVM vm);
   HSQUIRRELVM object_to_vm(HSQOBJECT object);
 
   void compile_script(HSQUIRRELVM vm, std::istream& in,
@@ -69,10 +69,10 @@ namespace Scripting
                                      const std::string& name)
   {
     sq_pushstring(v, name.c_str(), name.length());
-    
+
     if(table_idx < 0)
       table_idx -= 1;
-    
+
     if(SQ_FAILED(sq_deleteslot(v, table_idx, SQFalse))) {
       std::ostringstream msg;
       msg << "Couldn't unregister object '" << name << "' in squirrel root table";
index 5a7f1b7..d25febf 100644 (file)
@@ -30,7 +30,7 @@ public:
   virtual ~Text()
   { }
 #endif
-  
+
   virtual void set_text(const std::string& text) = 0;
   virtual void set_font(const std::string& fontname) = 0;
   virtual void fade_in(float fadetime) = 0;
@@ -42,4 +42,3 @@ public:
 }
 
 #endif
-
index f14e971..6ecaef3 100644 (file)
@@ -46,10 +46,10 @@ ThreadQueue::add(HSQUIRRELVM vm)
     sq_pop(global_vm, 2);
     throw SquirrelError(global_vm, "Couldn't get thread weakref from vm");
   }
-  sq_addref(global_vm, &object); 
+  sq_addref(global_vm, &object);
   threads.push_back(object);
 
-  sq_pop(global_vm, 2);                  
+  sq_pop(global_vm, 2);
 }
 
 void
@@ -63,7 +63,7 @@ ThreadQueue::wakeup()
   size_t size_begin = threads.size();
   while(i != end) {
     HSQOBJECT object = threads[i];
-    
+
     sq_pushobject(global_vm, object);
     sq_getweakrefval(global_vm, -1);
 
@@ -74,7 +74,7 @@ ThreadQueue::wakeup()
         log_warning << "Couldn't wakeup scheduled squirrel VM" << std::endl;
       }
     }
-  
+
     sq_release(global_vm, &object);
     sq_pop(global_vm, 1);
     i--;
@@ -84,4 +84,3 @@ ThreadQueue::wakeup()
 }
 
 }
-
index 24a4d2e..50c32ea 100644 (file)
@@ -40,7 +40,7 @@ public:
      * Start playing thunder and lightning at configured interval
      */
     void start();
-    
+
     /**
      * Stop playing thunder and lightning at configured interval
      */
@@ -74,4 +74,3 @@ public:
 }
 
 #endif
-
index 8c3314b..d28308b 100644 (file)
@@ -98,4 +98,3 @@ TimeScheduler::schedule_thread(HSQUIRRELVM scheduled_vm, float time)
 }
 
 }
-
index e3bf895..d26cb76 100644 (file)
@@ -54,7 +54,7 @@ private:
       return wakeup_time > other.wakeup_time;
     }
   };
-  
+
   typedef std::vector<ScheduleEntry> ScheduleHeap;
   ScheduleHeap schedule;
 };
@@ -62,4 +62,3 @@ private:
 }
 
 #endif
-
index 6140108..a0a33bf 100644 (file)
@@ -36,13 +36,13 @@ namespace Scripting
 
   Wind::~Wind()
   { }
-  void Wind::start() 
+
+  void Wind::start()
   {
     wind->start();
   }
 
-  void Wind::stop() 
+  void Wind::stop()
   {
     wind->stop();
   }
index 0ad7494..e1b02d1 100644 (file)
@@ -50,4 +50,3 @@ public:
 }
 
 #endif
-
index 9da2ff2..88e9665 100644 (file)
@@ -13,4 +13,3 @@
 #include "wind.hpp"
 #include "ambient_sound.hpp"
 #include "thunderstorm.hpp"
-
index 5d98d0c..f9aaf7c 100644 (file)
@@ -96,7 +96,7 @@ Sector::Sector(Level* parent)
 Sector::~Sector()
 {
   using namespace Scripting;
-  
+
   deactivate();
 
   for(ScriptList::iterator i = scripts.begin();
@@ -106,7 +106,7 @@ Sector::~Sector()
   }
   sq_release(global_vm, &sector_table);
   sq_collectgarbage(global_vm);
+
   update_game_objects();
   assert(gameobjects_new.size() == 0);
 
@@ -157,20 +157,20 @@ Sector::parse_object(const std::string& name, const lisp::Lisp& reader)
     return partsys;
   } else if(name == "money") { // for compatibility with old maps
     return new Jumpy(reader);
-  } 
+  }
 
   try {
     return create_object(name, reader);
   } catch(std::exception& e) {
     log_warning << e.what() << "" << std::endl;
   }
-  
+
   return 0;
 }
 
 void
 Sector::parse(const lisp::Lisp& sector)
-{  
+{
   lisp::ListIterator iter(&sector);
   while(iter.next()) {
     const std::string& token = iter.item();
@@ -227,14 +227,14 @@ Sector::parse_old_format(const lisp::Lisp& reader)
   bkgd_top.red = static_cast<float> (r) / 255.0f;
   bkgd_top.green = static_cast<float> (g) / 255.0f;
   bkgd_top.blue = static_cast<float> (b) / 255.0f;
-  
+
   reader.get("bkgd_red_bottom",  r);
   reader.get("bkgd_green_bottom", g);
   reader.get("bkgd_blue_bottom", b);
   bkgd_bottom.red = static_cast<float> (r) / 255.0f;
   bkgd_bottom.green = static_cast<float> (g) / 255.0f;
   bkgd_bottom.blue = static_cast<float> (b) / 255.0f;
-  
+
   if(backgroundimage != "") {
     Background* background = new Background();
     background->set_image(
@@ -271,7 +271,7 @@ Sector::parse_old_format(const lisp::Lisp& reader)
   int width = 30, height = 15;
   reader.get("width", width);
   reader.get("height", height);
-  
+
   std::vector<unsigned int> tiles;
   if(reader.get_vector("interactive-tm", tiles)
       || reader.get_vector("tilemap", tiles)) {
@@ -414,10 +414,10 @@ Sector::run_script(std::istream& in, const std::string& sourcename)
       i = scripts.erase(i);
       continue;
     }
-    
+
     ++i;
   }
-  
+
   HSQOBJECT object = create_thread(global_vm);
   scripts.push_back(object);
 
@@ -465,7 +465,7 @@ Sector::activate(const std::string& spawnpoint)
       sp = *i;
       break;
     }
-  }                                                                           
+  }
   if(!sp) {
     log_warning << "Spawnpoint '" << spawnpoint << "' not found." << std::endl;
     if(spawnpoint != "main") {
@@ -527,11 +527,11 @@ Sector::deactivate()
   if(SQ_FAILED(sq_deleteslot(vm, -2, SQFalse)))
     throw Scripting::SquirrelError(vm, "Couldn't unset sector in roottable");
   sq_pop(vm, 1);
-  
+
   for(GameObjects::iterator i = gameobjects.begin();
       i != gameobjects.end(); ++i) {
     GameObject* object = *i;
-    
+
     try_unexpose(object);
   }
 
@@ -557,10 +557,10 @@ Sector::update(float elapsed_time)
     GameObject* object = *i;
     if(!object->is_valid())
       continue;
-    
+
     object->update(elapsed_time);
   }
-  
+
   /* Handle all possible collisions. */
   handle_collisions();
   update_game_objects();
@@ -593,14 +593,14 @@ Sector::update_game_objects()
   for(std::vector<GameObject*>::iterator i = gameobjects.begin();
       i != gameobjects.end(); /* nothing */) {
     GameObject* object = *i;
-    
+
     if(object->is_valid()) {
       ++i;
       continue;
     }
 
     before_object_remove(object);
-    
+
     object->unref();
     i = gameobjects.erase(i);
   }
@@ -612,7 +612,7 @@ Sector::update_game_objects()
     GameObject* object = *i;
 
     before_object_add(object);
-    
+
     gameobjects.push_back(object);
   }
   gameobjects_new.clear();
@@ -629,7 +629,7 @@ Sector::before_object_add(GameObject* object)
   if(movingobject) {
     moving_objects.push_back(movingobject);
   }
-  
+
   TileMap* tilemap = dynamic_cast<TileMap*> (object);
   if(tilemap && tilemap->is_solid()) solid_tilemaps.push_back(tilemap);
 
@@ -654,7 +654,7 @@ Sector::before_object_add(GameObject* object)
   if(_current == this) {
     try_expose(object);
   }
-  
+
   return true;
 }
 
@@ -692,7 +692,7 @@ Sector::try_unexpose(GameObject* object)
     }
     sq_settop(vm, oldtop);
   }
-} 
+}
 
 void
 Sector::draw(DrawingContext& context)
@@ -702,7 +702,7 @@ Sector::draw(DrawingContext& context)
 
   for(GameObjects::iterator i = gameobjects.begin();
       i != gameobjects.end(); ++i) {
-    GameObject* object = *i; 
+    GameObject* object = *i;
     if(!object->is_valid())
       continue;
 
@@ -731,7 +731,7 @@ Sector::draw(DrawingContext& context)
 }
 
 /*-------------------------------------------------------------------------
- * Collision Detection 
+ * Collision Detection
  *-------------------------------------------------------------------------*/
 
 static const float SHIFT_DELTA = 7.0f;
@@ -918,7 +918,7 @@ void
 Sector::collision_object(MovingObject* object1, MovingObject* object2) const
 {
   using namespace collision;
-  
+
   const Rect& r1 = object1->dest;
   const Rect& r2 = object2->dest;
 
@@ -961,13 +961,13 @@ Sector::collision_static(collision::Constraints* constraints,
     if(moving_object->get_group() != COLGROUP_STATIC
         || !moving_object->is_valid())
       continue;
-  
+
     check_collisions(constraints, movement, dest, moving_object->dest,
         &object, moving_object);
   }
 }
 
-void 
+void
 Sector::collision_static_constrains(MovingObject& object)
 {
   using namespace collision;
@@ -1037,11 +1037,11 @@ Sector::collision_static_constrains(MovingObject& object)
   }
 
   if(constraints.has_constraints()) {
-    if( constraints.hit.left || constraints.hit.right 
-        || constraints.hit.top || constraints.hit.bottom 
+    if( constraints.hit.left || constraints.hit.right
+        || constraints.hit.top || constraints.hit.bottom
         || constraints.hit.crush )
       object.collision_solid(constraints.hit);
-  }    
+  }
 
   // an extra pass to make sure we're not crushed horizontally
   constraints = Constraints();
@@ -1054,7 +1054,7 @@ Sector::collision_static_constrains(MovingObject& object)
       h.top = true;
       h.bottom = true;
       h.crush = true;
-      object.collision_solid(h); 
+      object.collision_solid(h);
     }
   }
 }
@@ -1063,7 +1063,7 @@ void
 Sector::handle_collisions()
 {
   using namespace collision;
-  
+
   // calculate destination positions of the objects
   for(MovingObjects::iterator i = moving_objects.begin();
       i != moving_objects.end(); ++i) {
@@ -1124,7 +1124,7 @@ Sector::handle_collisions()
         moving_object->collision(*moving_object_2, hit);
         moving_object_2->collision(*moving_object, hit);
       }
-    } 
+    }
   }
 
   // part3: COLGROUP_MOVING vs COLGROUP_MOVING
@@ -1144,7 +1144,7 @@ Sector::handle_collisions()
         continue;
 
       collision_object(moving_object, moving_object_2);
-    }    
+    }
   }
 
   // apply object movement
@@ -1161,7 +1161,7 @@ bool
 Sector::is_free_space(const Rect& rect) const
 {
   using namespace collision;
-  
+
   for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
     TileMap* solids = *i;
 
@@ -1299,7 +1299,7 @@ Sector::get_height() const
   return height;
 }
 
-void 
+void
 Sector::change_solid_tiles(uint32_t old_tile_id, uint32_t new_tile_id)
 {
   for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
index 00b4ff6..57a2665 100644 (file)
@@ -107,10 +107,10 @@ public:
 
   void play_music(MusicType musictype);
   MusicType get_music_type();
-  
+
   bool add_bullet(const Vector& pos, float xm, Direction dir);
   bool add_smoke_cloud(const Vector& pos);
+
   /** get currently activated sector. */
   static Sector* current()
   { return _current; }
@@ -150,7 +150,7 @@ public:
    * returns the width (in px) of a sector)
    */
   float get_width() const;
-  
+
   /**
    * returns the height (in px) of a sector)
    */
@@ -174,12 +174,12 @@ private:
 
   void try_expose(GameObject* object);
   void try_unexpose(GameObject* object);
-  
+
   /** Checks for all possible collisions. And calls the
       collision_handlers, which the collision_objects provide for this
       case (or not). */
   void handle_collisions();
+
   /**
    * Does collision detection between 2 objects and does instant
    * collision response handling in case of a collision
@@ -199,13 +199,13 @@ private:
       const Vector& movement, const Rect& dest, GameObject& object);
 
   void collision_static_constrains(MovingObject& object);
-  
+
   GameObject* parse_object(const std::string& name, const lisp::Lisp& lisp);
 
   void fix_old_tiles();
 
   static Sector* _current;
-  
+
   std::string name;
 
   std::vector<Bullet*> bullets;
@@ -214,7 +214,7 @@ private:
 
   /// container for newly created objects, they'll be added in Sector::update
   GameObjects gameobjects_new;
+
   MusicType currentmusic;
 
   HSQOBJECT sector_table;
@@ -226,10 +226,10 @@ public: // TODO make this private again
   /// show collision rectangles of moving objects (for debugging)
   static bool show_collrects;
   static bool draw_solids_only;
-  
+
   GameObjects gameobjects;
   MovingObjects moving_objects;
-  SpawnPoints spawnpoints;                       
+  SpawnPoints spawnpoints;
 
   std::string music;
   float gravity;
@@ -242,4 +242,3 @@ public: // TODO make this private again
 };
 
 #endif
-
index 612f457..ce4d3b7 100644 (file)
@@ -26,9 +26,8 @@ class Serializable
 public:
   virtual ~Serializable()
   { }
-    
+
   virtual void write(lisp::Writer& writer) = 0;
 };
 
 #endif /*SUPERTUX_SERIALIZABLE_H*/
-
index 9486b15..d921efb 100644 (file)
@@ -51,7 +51,7 @@ ShrinkFade::draw(DrawingContext& context)
   float top = speedtop * accum_time;
   float right = SCREEN_WIDTH - speedright * accum_time;
   float bottom = SCREEN_HEIGHT - speedbottom * accum_time;
-  
+
   context.draw_filled_rect(Vector(0, 0),
                            Vector(left, SCREEN_HEIGHT),
                            black, LAYER_GUI+1);
index 8860f5b..7afe642 100644 (file)
@@ -44,4 +44,3 @@ private:
 };
 
 #endif
-
index b1708ca..17d4908 100644 (file)
@@ -35,4 +35,3 @@ public:
 };
 
 #endif
-
index 0c011ef..7b81827 100644 (file)
@@ -33,9 +33,9 @@
 
 Sprite::Sprite(SpriteData& newdata)
   : data(newdata),
-    frame(0), 
-    animation_loops(-1), 
-    angle(0.0f), 
+    frame(0),
+    animation_loops(-1),
+    angle(0.0f),
     color(1.0f, 1.0f, 1.0f, 1.0f)
 {
   action = data.get_action("normal");
@@ -94,7 +94,7 @@ Sprite::update()
 
   if(frame >= get_frames()) {
     frame = fmodf(frame, get_frames());
-      
+
     animation_loops--;
     if(animation_done())
       frame = get_frames()-1;
@@ -126,7 +126,7 @@ Sprite::draw_part(DrawingContext& context, const Vector& source,
   update();
 
   int frameidx = (int) frame;
-  
+
   if(frameidx >= get_frames() || frameidx < 0) {
 #ifndef DEBUG
     // in optimized mode we get some small rounding errors in floating point
@@ -135,7 +135,7 @@ Sprite::draw_part(DrawingContext& context, const Vector& source,
 #endif
     frameidx = get_frames() - 1;
   }
-    
+
   context.draw_surface_part(action->surfaces[frameidx], source, size,
       pos - Vector(action->x_offset, action->y_offset),
       layer + action->z_order);
index a43df0a..f37c473 100644 (file)
@@ -109,14 +109,14 @@ public:
   { return (int)frame; }
   /** Set current frame */
   void set_frame(int frame)
-  { 
-    this->frame = (frame % get_frames()); 
+  {
+    this->frame = (frame % get_frames());
   }
   Surface* get_frame(unsigned int frame)
   {
     assert(frame < action->surfaces.size());
     return action->surfaces[frame];
-  }    
+  }
 
 private:
   void update();
@@ -134,4 +134,3 @@ private:
 };
 
 #endif
-
index 599e4e1..8d223af 100644 (file)
@@ -36,7 +36,7 @@ SpriteData::Action::Action()
   y_offset = 0;
   hitbox_w = 0;
   hitbox_h = 0;
-  z_order = 0;   
+  z_order = 0;
   fps = 10;
 }
 
@@ -143,4 +143,3 @@ SpriteData::get_action(std::string act)
   }
   return i->second;
 }
-
index 3f73f4c..bc5ccb3 100644 (file)
@@ -79,4 +79,3 @@ private:
 };
 
 #endif
-
index 411255b..5b37441 100644 (file)
@@ -61,7 +61,7 @@ SpriteManager::create(const std::string& name)
   } else {
     data = i->second;
   }
-  
+
   return new Sprite(*data);
 }
 
@@ -81,7 +81,6 @@ SpriteManager::load(const std::string& filename)
   std::auto_ptr<SpriteData> data (
       new SpriteData(sprite, FileSystem::dirname(filename)) );
   sprites[filename] = data.release();
-  
+
   return sprites[filename];
 }
-
index 4ebe6c0..7b5c1e4 100644 (file)
@@ -30,7 +30,7 @@ class SpriteManager
 private:
   typedef std::map<std::string, SpriteData*> Sprites;
   Sprites sprites;
-  
+
 public:
   SpriteManager();
   ~SpriteManager();
index b900348..c16b043 100644 (file)
@@ -1,16 +1,16 @@
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQSTD_AUXLIB_H_\r
-#define _SQSTD_AUXLIB_H_\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-SQUIRREL_API void sqstd_seterrorhandlers(HSQUIRRELVM v);\r
-SQUIRREL_API void sqstd_printcallstack(HSQUIRRELVM v);\r
-\r
-#ifdef __cplusplus\r
-} /*extern "C"*/\r
-#endif\r
-\r
-#endif /* _SQSTD_AUXLIB_H_ */\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQSTD_AUXLIB_H_
+#define _SQSTD_AUXLIB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SQUIRREL_API void sqstd_seterrorhandlers(HSQUIRRELVM v);
+SQUIRREL_API void sqstd_printcallstack(HSQUIRRELVM v);
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif /* _SQSTD_AUXLIB_H_ */
index eda4cc9..e54d7be 100644 (file)
@@ -1,20 +1,19 @@
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQSTDBLOB_H_\r
-#define _SQSTDBLOB_H_\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-SQUIRREL_API SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size);\r
-SQUIRREL_API SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr);\r
-SQUIRREL_API SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx);\r
-\r
-SQUIRREL_API SQRESULT sqstd_register_bloblib(HSQUIRRELVM v);\r
-\r
-#ifdef __cplusplus\r
-} /*extern "C"*/\r
-#endif\r
-\r
-#endif /*_SQSTDBLOB_H_*/\r
-\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQSTDBLOB_H_
+#define _SQSTDBLOB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SQUIRREL_API SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size);
+SQUIRREL_API SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr);
+SQUIRREL_API SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx);
+
+SQUIRREL_API SQRESULT sqstd_register_bloblib(HSQUIRRELVM v);
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif /*_SQSTDBLOB_H_*/
index 5f64612..c3137f1 100644 (file)
@@ -1,54 +1,53 @@
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQSTDIO_H_\r
-#define _SQSTDIO_H_\r
-\r
-#ifdef __cplusplus\r
-\r
-#define SQSTD_STREAM_TYPE_TAG 0x80000000\r
-\r
-struct SQStream {\r
-       virtual ~SQStream() { };\r
-       virtual SQInteger Read(void *buffer, SQInteger size) = 0;\r
-       virtual SQInteger Write(void *buffer, SQInteger size) = 0;\r
-       virtual SQInteger Flush() = 0;\r
-       virtual SQInteger Tell() = 0;\r
-       virtual SQInteger Len() = 0;\r
-       virtual SQInteger Seek(SQInteger offset, SQInteger origin) = 0;\r
-       virtual bool IsValid() = 0;\r
-       virtual bool EOS() = 0;\r
-};\r
-\r
-extern "C" {\r
-#endif\r
-\r
-#define SQ_SEEK_CUR 0\r
-#define SQ_SEEK_END 1\r
-#define SQ_SEEK_SET 2\r
-\r
-typedef void* SQFILE;\r
-\r
-SQUIRREL_API SQFILE sqstd_fopen(const SQChar *,const SQChar *);\r
-SQUIRREL_API SQInteger sqstd_fread(SQUserPointer, SQInteger, SQInteger, SQFILE);\r
-SQUIRREL_API SQInteger sqstd_fwrite(const SQUserPointer, SQInteger, SQInteger, SQFILE);\r
-SQUIRREL_API SQInteger sqstd_fseek(SQFILE , SQInteger , SQInteger);\r
-SQUIRREL_API SQInteger sqstd_ftell(SQFILE);\r
-SQUIRREL_API SQInteger sqstd_fflush(SQFILE);\r
-SQUIRREL_API SQInteger sqstd_fclose(SQFILE);\r
-SQUIRREL_API SQInteger sqstd_feof(SQFILE);\r
-\r
-SQUIRREL_API SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own);\r
-SQUIRREL_API SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file);\r
-\r
-//compiler helpers\r
-SQUIRREL_API SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror);\r
-SQUIRREL_API SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror);\r
-SQUIRREL_API SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename);\r
-\r
-SQUIRREL_API SQRESULT sqstd_register_iolib(HSQUIRRELVM v);\r
-\r
-#ifdef __cplusplus\r
-} /*extern "C"*/\r
-#endif\r
-\r
-#endif /*_SQSTDIO_H_*/\r
-\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQSTDIO_H_
+#define _SQSTDIO_H_
+
+#ifdef __cplusplus
+
+#define SQSTD_STREAM_TYPE_TAG 0x80000000
+
+struct SQStream {
+       virtual ~SQStream() { };
+       virtual SQInteger Read(void *buffer, SQInteger size) = 0;
+       virtual SQInteger Write(void *buffer, SQInteger size) = 0;
+       virtual SQInteger Flush() = 0;
+       virtual SQInteger Tell() = 0;
+       virtual SQInteger Len() = 0;
+       virtual SQInteger Seek(SQInteger offset, SQInteger origin) = 0;
+       virtual bool IsValid() = 0;
+       virtual bool EOS() = 0;
+};
+
+extern "C" {
+#endif
+
+#define SQ_SEEK_CUR 0
+#define SQ_SEEK_END 1
+#define SQ_SEEK_SET 2
+
+typedef void* SQFILE;
+
+SQUIRREL_API SQFILE sqstd_fopen(const SQChar *,const SQChar *);
+SQUIRREL_API SQInteger sqstd_fread(SQUserPointer, SQInteger, SQInteger, SQFILE);
+SQUIRREL_API SQInteger sqstd_fwrite(const SQUserPointer, SQInteger, SQInteger, SQFILE);
+SQUIRREL_API SQInteger sqstd_fseek(SQFILE , SQInteger , SQInteger);
+SQUIRREL_API SQInteger sqstd_ftell(SQFILE);
+SQUIRREL_API SQInteger sqstd_fflush(SQFILE);
+SQUIRREL_API SQInteger sqstd_fclose(SQFILE);
+SQUIRREL_API SQInteger sqstd_feof(SQFILE);
+
+SQUIRREL_API SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own);
+SQUIRREL_API SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file);
+
+//compiler helpers
+SQUIRREL_API SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror);
+SQUIRREL_API SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror);
+SQUIRREL_API SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename);
+
+SQUIRREL_API SQRESULT sqstd_register_iolib(HSQUIRRELVM v);
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif /*_SQSTDIO_H_*/
index 420f2ce..65de6fd 100644 (file)
@@ -1,15 +1,15 @@
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQSTD_MATH_H_\r
-#define _SQSTD_MATH_H_\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-SQUIRREL_API SQRESULT sqstd_register_mathlib(HSQUIRRELVM v);\r
-\r
-#ifdef __cplusplus\r
-} /*extern "C"*/\r
-#endif\r
-\r
-#endif /*_SQSTD_MATH_H_*/\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQSTD_MATH_H_
+#define _SQSTD_MATH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SQUIRREL_API SQRESULT sqstd_register_mathlib(HSQUIRRELVM v);
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif /*_SQSTD_MATH_H_*/
index 9db0ffc..ab68d16 100644 (file)
@@ -1,34 +1,34 @@
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQSTD_STRING_H_\r
-#define _SQSTD_STRING_H_\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-//#define SQRex_True 1\r
-//#define SQRex_False 0\r
-\r
-typedef unsigned int SQRexBool;\r
-typedef struct SQRex SQRex;\r
-\r
-typedef struct {\r
-       const SQChar *begin;\r
-       SQInteger len;\r
-} SQRexMatch;\r
-\r
-SQUIRREL_API SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error);\r
-SQUIRREL_API void sqstd_rex_free(SQRex *exp);\r
-SQUIRREL_API SQBool sqstd_rex_match(SQRex* exp,const SQChar* text);\r
-SQUIRREL_API SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end);\r
-SQUIRREL_API SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end);\r
-SQUIRREL_API SQInteger sqstd_rex_getsubexpcount(SQRex* exp);\r
-SQUIRREL_API SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp);\r
-\r
-SQUIRREL_API SQRESULT sqstd_register_stringlib(HSQUIRRELVM v);\r
-\r
-#ifdef __cplusplus\r
-} /*extern "C"*/\r
-#endif\r
-\r
-#endif /*_SQSTD_STRING_H_*/\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQSTD_STRING_H_
+#define _SQSTD_STRING_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//#define SQRex_True 1
+//#define SQRex_False 0
+
+typedef unsigned int SQRexBool;
+typedef struct SQRex SQRex;
+
+typedef struct {
+       const SQChar *begin;
+       SQInteger len;
+} SQRexMatch;
+
+SQUIRREL_API SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error);
+SQUIRREL_API void sqstd_rex_free(SQRex *exp);
+SQUIRREL_API SQBool sqstd_rex_match(SQRex* exp,const SQChar* text);
+SQUIRREL_API SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end);
+SQUIRREL_API SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end);
+SQUIRREL_API SQInteger sqstd_rex_getsubexpcount(SQRex* exp);
+SQUIRREL_API SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp);
+
+SQUIRREL_API SQRESULT sqstd_register_stringlib(HSQUIRRELVM v);
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif /*_SQSTD_STRING_H_*/
index daefa0f..b155a91 100644 (file)
@@ -1,15 +1,15 @@
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQSTD_SYSTEMLIB_H_\r
-#define _SQSTD_SYSTEMLIB_H_\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-SQUIRREL_API SQInteger sqstd_register_systemlib(HSQUIRRELVM v);\r
-\r
-#ifdef __cplusplus\r
-} /*extern "C"*/\r
-#endif\r
-\r
-#endif /* _SQSTD_SYSTEMLIB_H_ */\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQSTD_SYSTEMLIB_H_
+#define _SQSTD_SYSTEMLIB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SQUIRREL_API SQInteger sqstd_register_systemlib(HSQUIRRELVM v);
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif /* _SQSTD_SYSTEMLIB_H_ */
index 12fb4d5..1a7efc5 100644 (file)
-/*\r
-Copyright (c) 2003-2006 Alberto Demichelis\r
-\r
-This software is provided 'as-is', without any \r
-express or implied warranty. In no event will the \r
-authors be held liable for any damages arising from \r
-the use of this software.\r
-\r
-Permission is granted to anyone to use this software \r
-for any purpose, including commercial applications, \r
-and to alter it and redistribute it freely, subject \r
-to the following restrictions:\r
-\r
-               1. The origin of this software must not be \r
-               misrepresented; you must not claim that \r
-               you wrote the original software. If you \r
-               use this software in a product, an \r
-               acknowledgment in the product \r
-               documentation would be appreciated but is \r
-               not required.\r
-\r
-               2. Altered source versions must be plainly \r
-               marked as such, and must not be \r
-               misrepresented as being the original \r
-               software.\r
-\r
-               3. This notice may not be removed or \r
-               altered from any source distribution.\r
-\r
-*/\r
-#ifndef _SQUIRREL_H_\r
-#define _SQUIRREL_H_\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-#ifndef SQUIRREL_API\r
-#define SQUIRREL_API extern\r
-#endif\r
-\r
-#ifdef _SQ64\r
-#ifdef _MSC_VER\r
-typedef __int64 SQInteger;\r
-typedef unsigned __int64 SQUnsignedInteger;\r
-typedef unsigned __int64 SQHash; /*should be the same size of a pointer*/\r
-#else\r
-typedef long SQInteger;\r
-typedef unsigned long SQUnsignedInteger;\r
-typedef unsigned long SQHash; /*should be the same size of a pointer*/\r
-#endif\r
-typedef int SQInt32; \r
-#else \r
-typedef int SQInteger;\r
-typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/\r
-typedef unsigned int SQUnsignedInteger;\r
-typedef unsigned int SQHash; /*should be the same size of a pointer*/\r
-#endif\r
-\r
-typedef float SQFloat;\r
-typedef void* SQUserPointer;\r
-typedef SQUnsignedInteger SQBool;\r
-typedef SQInteger SQRESULT;\r
-\r
-#define SQTrue (1)\r
-#define SQFalse        (0)\r
-\r
-\r
-struct SQVM;\r
-struct SQTable;\r
-struct SQArray;\r
-struct SQString;\r
-struct SQClosure;\r
-struct SQGenerator;\r
-struct SQNativeClosure;\r
-struct SQUserData;\r
-struct SQFunctionProto;\r
-struct SQRefCounted;\r
-struct SQClass;\r
-struct SQInstance;\r
-struct SQDelegable;\r
-\r
-#ifdef _UNICODE\r
-#define SQUNICODE\r
-#endif\r
-\r
-#ifdef SQUNICODE\r
-#if defined(wchar_t) //this is if the compiler considers wchar_t as native type\r
-#define wchar_t unsigned short\r
-#endif\r
-typedef wchar_t SQChar;\r
-#define _SC(a) L##a\r
-#define        scstrcmp        wcscmp\r
-#define scsprintf      swprintf\r
-#define scstrlen       wcslen\r
-#define scstrtod       wcstod\r
-#define scstrtol       wcstol\r
-#define scatoi         _wtoi\r
-#define scstrtoul      wcstoul\r
-#define scvsprintf     vswprintf\r
-#define scstrstr       wcsstr\r
-#define scisspace      iswspace\r
-#define scisdigit      iswdigit\r
-#define scisxdigit     iswxdigit\r
-#define scisalpha      iswalpha\r
-#define sciscntrl      iswcntrl\r
-#define scisalnum      iswalnum\r
-#define scprintf       wprintf\r
-#define MAX_CHAR 0xFFFF\r
-#else\r
-typedef char SQChar;\r
-#define _SC(a) a\r
-#define        scstrcmp        strcmp\r
-#define scsprintf      sprintf\r
-#define scstrlen       strlen\r
-#define scstrtod       strtod\r
-#define scstrtol       strtol\r
-#define scatoi         atoi\r
-#define scstrtoul      strtoul\r
-#define scvsprintf     vsprintf\r
-#define scstrstr       strstr\r
-#define scisspace      isspace\r
-#define scisdigit      isdigit\r
-#define scisxdigit     isxdigit\r
-#define sciscntrl      iscntrl\r
-#define scisalpha      isalpha\r
-#define scisalnum      isalnum\r
-#define scprintf       printf\r
-#define MAX_CHAR 0xFF\r
-#endif\r
-\r
-#define SQUIRREL_VERSION       _SC("Squirrel 2.1 stable")\r
-#define SQUIRREL_COPYRIGHT     _SC("Copyright (C) 2003-2006 Alberto Demichelis")\r
-#define SQUIRREL_AUTHOR                _SC("Alberto Demichelis")\r
-\r
-#define SQ_VMSTATE_IDLE                        0\r
-#define SQ_VMSTATE_RUNNING             1\r
-#define SQ_VMSTATE_SUSPENDED   2\r
-\r
-#define SQUIRREL_EOB 0\r
-#define SQ_BYTECODE_STREAM_TAG 0xFAFA\r
-\r
-#define SQOBJECT_REF_COUNTED   0x08000000\r
-#define SQOBJECT_NUMERIC               0x04000000\r
-#define SQOBJECT_DELEGABLE             0x02000000\r
-#define SQOBJECT_CANBEFALSE            0x01000000\r
-\r
-#define SQ_MATCHTYPEMASKSTRING (-99999)\r
-\r
-#define _RT_MASK 0x00FFFFFF\r
-#define _RAW_TYPE(type) (type&_RT_MASK)\r
-\r
-#define _RT_NULL                       0x00000001\r
-#define _RT_INTEGER                    0x00000002\r
-#define _RT_FLOAT                      0x00000004\r
-#define _RT_BOOL                       0x00000008\r
-#define _RT_STRING                     0x00000010\r
-#define _RT_TABLE                      0x00000020\r
-#define _RT_ARRAY                      0x00000040\r
-#define _RT_USERDATA           0x00000080\r
-#define _RT_CLOSURE                    0x00000100\r
-#define _RT_NATIVECLOSURE      0x00000200\r
-#define _RT_GENERATOR          0x00000400\r
-#define _RT_USERPOINTER                0x00000800\r
-#define _RT_THREAD                     0x00001000\r
-#define _RT_FUNCPROTO          0x00002000\r
-#define _RT_CLASS                      0x00004000\r
-#define _RT_INSTANCE           0x00008000\r
-#define _RT_WEAKREF                    0x00010000\r
-\r
-typedef enum tagSQObjectType{\r
-       OT_NULL =                       (_RT_NULL|SQOBJECT_CANBEFALSE),\r
-       OT_INTEGER =            (_RT_INTEGER|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),\r
-       OT_FLOAT =                      (_RT_FLOAT|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),\r
-       OT_BOOL =                       (_RT_BOOL|SQOBJECT_CANBEFALSE),\r
-       OT_STRING =                     (_RT_STRING|SQOBJECT_REF_COUNTED),\r
-       OT_TABLE =                      (_RT_TABLE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),\r
-       OT_ARRAY =                      (_RT_ARRAY|SQOBJECT_REF_COUNTED),\r
-       OT_USERDATA =           (_RT_USERDATA|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),\r
-       OT_CLOSURE =            (_RT_CLOSURE|SQOBJECT_REF_COUNTED),\r
-       OT_NATIVECLOSURE =      (_RT_NATIVECLOSURE|SQOBJECT_REF_COUNTED),\r
-       OT_GENERATOR =          (_RT_GENERATOR|SQOBJECT_REF_COUNTED),\r
-       OT_USERPOINTER =        _RT_USERPOINTER,\r
-       OT_THREAD =                     (_RT_THREAD|SQOBJECT_REF_COUNTED) ,\r
-       OT_FUNCPROTO =          (_RT_FUNCPROTO|SQOBJECT_REF_COUNTED), //internal usage only\r
-       OT_CLASS =                      (_RT_CLASS|SQOBJECT_REF_COUNTED),\r
-       OT_INSTANCE =           (_RT_INSTANCE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),\r
-       OT_WEAKREF =            (_RT_WEAKREF|SQOBJECT_REF_COUNTED)\r
-}SQObjectType;\r
-\r
-#define ISREFCOUNTED(t) (t&SQOBJECT_REF_COUNTED)\r
-\r
-\r
-typedef union tagSQObjectValue\r
-{\r
-       struct SQTable *pTable;\r
-       struct SQArray *pArray;\r
-       struct SQClosure *pClosure;\r
-       struct SQGenerator *pGenerator;\r
-       struct SQNativeClosure *pNativeClosure;\r
-       struct SQString *pString;\r
-       struct SQUserData *pUserData;\r
-       SQInteger nInteger;\r
-       SQFloat fFloat;\r
-       SQUserPointer pUserPointer;\r
-       struct SQFunctionProto *pFunctionProto;\r
-       struct SQRefCounted *pRefCounted;\r
-       struct SQDelegable *pDelegable;\r
-       struct SQVM *pThread;\r
-       struct SQClass *pClass;\r
-       struct SQInstance *pInstance;\r
-       struct SQWeakRef *pWeakRef;\r
-}SQObjectValue;\r
-\r
-\r
-typedef struct tagSQObject\r
-{\r
-       SQObjectValue _unVal;\r
-       SQObjectType _type;\r
-}SQObject;\r
-\r
-typedef struct tagSQStackInfos{\r
-       const SQChar* funcname;\r
-       const SQChar* source;\r
-       SQInteger line;\r
-}SQStackInfos;\r
-\r
-typedef struct SQVM* HSQUIRRELVM;\r
-typedef SQObject HSQOBJECT;\r
-typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM);\r
-typedef SQInteger (*SQRELEASEHOOK)(SQUserPointer,SQInteger size);\r
-typedef void (*SQCOMPILERERROR)(HSQUIRRELVM,const SQChar * /*desc*/,const SQChar * /*source*/,SQInteger /*line*/,SQInteger /*column*/);\r
-typedef void (*SQPRINTFUNCTION)(HSQUIRRELVM,const SQChar * ,...);\r
-\r
-typedef SQInteger (*SQWRITEFUNC)(SQUserPointer,SQUserPointer,SQInteger);\r
-typedef SQInteger (*SQREADFUNC)(SQUserPointer,SQUserPointer,SQInteger);\r
-\r
-typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer);\r
-\r
-typedef struct tagSQRegFunction{\r
-       const SQChar *name;\r
-       SQFUNCTION f;\r
-       SQInteger nparamscheck;\r
-       const SQChar *typemask;\r
-}SQRegFunction;\r
-\r
-/*vm*/\r
-SQUIRREL_API HSQUIRRELVM sq_open(SQInteger initialstacksize);\r
-SQUIRREL_API HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize);\r
-SQUIRREL_API void sq_seterrorhandler(HSQUIRRELVM v);\r
-SQUIRREL_API void sq_close(HSQUIRRELVM v);\r
-SQUIRREL_API void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p);\r
-SQUIRREL_API SQUserPointer sq_getforeignptr(HSQUIRRELVM v);\r
-SQUIRREL_API void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc);\r
-SQUIRREL_API SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v);\r
-SQUIRREL_API SQRESULT sq_suspendvm(HSQUIRRELVM v);\r
-SQUIRREL_API SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool resumedret,SQBool retval,SQBool raiseerror);\r
-SQUIRREL_API SQInteger sq_getvmstate(HSQUIRRELVM v);\r
-\r
-/*compiler*/\r
-SQUIRREL_API SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror);\r
-SQUIRREL_API SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror);\r
-SQUIRREL_API void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable);\r
-SQUIRREL_API void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable);\r
-SQUIRREL_API void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f);\r
-\r
-/*stack operations*/\r
-SQUIRREL_API void sq_push(HSQUIRRELVM v,SQInteger idx);\r
-SQUIRREL_API void sq_pop(HSQUIRRELVM v,SQInteger nelemstopop);\r
-SQUIRREL_API void sq_poptop(HSQUIRRELVM v);\r
-SQUIRREL_API void sq_remove(HSQUIRRELVM v,SQInteger idx);\r
-SQUIRREL_API SQInteger sq_gettop(HSQUIRRELVM v);\r
-SQUIRREL_API void sq_settop(HSQUIRRELVM v,SQInteger newtop);\r
-SQUIRREL_API void sq_reservestack(HSQUIRRELVM v,SQInteger nsize);\r
-SQUIRREL_API SQInteger sq_cmp(HSQUIRRELVM v);\r
-SQUIRREL_API void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx);\r
-\r
-/*object creation handling*/\r
-SQUIRREL_API SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size);\r
-SQUIRREL_API void sq_newtable(HSQUIRRELVM v);\r
-SQUIRREL_API void sq_newarray(HSQUIRRELVM v,SQInteger size);\r
-SQUIRREL_API void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars);\r
-SQUIRREL_API SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask);\r
-SQUIRREL_API SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx);\r
-SQUIRREL_API void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len);\r
-SQUIRREL_API void sq_pushfloat(HSQUIRRELVM v,SQFloat f);\r
-SQUIRREL_API void sq_pushinteger(HSQUIRRELVM v,SQInteger n);\r
-SQUIRREL_API void sq_pushbool(HSQUIRRELVM v,SQBool b);\r
-SQUIRREL_API void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p);\r
-SQUIRREL_API void sq_pushnull(HSQUIRRELVM v);\r
-SQUIRREL_API SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx);\r
-SQUIRREL_API SQInteger sq_getsize(HSQUIRRELVM v,SQInteger idx);\r
-SQUIRREL_API SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx);\r
-SQUIRREL_API SQBool sq_instanceof(HSQUIRRELVM v);\r
-SQUIRREL_API void sq_tostring(HSQUIRRELVM v,SQInteger idx);\r
-SQUIRREL_API void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b);\r
-SQUIRREL_API SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c);\r
-SQUIRREL_API SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i);\r
-SQUIRREL_API SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f);\r
-SQUIRREL_API SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b);\r
-SQUIRREL_API SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread);\r
-SQUIRREL_API SQRESULT sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p);\r
-SQUIRREL_API SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag);\r
-SQUIRREL_API SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag);\r
-SQUIRREL_API SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag);\r
-SQUIRREL_API void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook);\r
-SQUIRREL_API SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize);\r
-SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars);\r
-SQUIRREL_API SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name);\r
-SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p);\r
-SQUIRREL_API SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag);\r
-SQUIRREL_API SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase);\r
-SQUIRREL_API SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx);\r
-SQUIRREL_API SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx);\r
-SQUIRREL_API SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx);\r
-SQUIRREL_API SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx);\r
-SQUIRREL_API void sq_weakref(HSQUIRRELVM v,SQInteger idx);\r
-SQUIRREL_API SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t);\r
-\r
-/*object manipulation*/\r
-SQUIRREL_API void sq_pushroottable(HSQUIRRELVM v);\r
-SQUIRREL_API void sq_pushregistrytable(HSQUIRRELVM v);\r
-SQUIRREL_API SQRESULT sq_setroottable(HSQUIRRELVM v);\r
-/*SQUIRREL_API SQRESULT sq_createslot(HSQUIRRELVM v,SQInteger idx);*/\r
-SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic);\r
-SQUIRREL_API SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);\r
-SQUIRREL_API SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx);\r
-SQUIRREL_API SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx);\r
-SQUIRREL_API SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx);\r
-SQUIRREL_API SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx);\r
-SQUIRREL_API SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);\r
-SQUIRREL_API SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx);\r
-SQUIRREL_API SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval); \r
-SQUIRREL_API SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize); \r
-SQUIRREL_API SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx); \r
-SQUIRREL_API SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx);\r
-SQUIRREL_API SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx);\r
-SQUIRREL_API SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx);\r
-SQUIRREL_API SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval);\r
-SQUIRREL_API SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx);\r
-SQUIRREL_API SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx);\r
-\r
-/*calls*/\r
-SQUIRREL_API SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror);\r
-SQUIRREL_API SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror);\r
-SQUIRREL_API const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx);\r
-SQUIRREL_API const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval);\r
-SQUIRREL_API SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err);\r
-SQUIRREL_API void sq_reseterror(HSQUIRRELVM v);\r
-SQUIRREL_API void sq_getlasterror(HSQUIRRELVM v);\r
-\r
-/*raw object handling*/\r
-SQUIRREL_API SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po);\r
-SQUIRREL_API void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj);\r
-SQUIRREL_API void sq_addref(HSQUIRRELVM v,HSQOBJECT *po);\r
-SQUIRREL_API SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po);\r
-SQUIRREL_API void sq_resetobject(HSQOBJECT *po);\r
-SQUIRREL_API const SQChar *sq_objtostring(HSQOBJECT *o);\r
-SQUIRREL_API SQBool sq_objtobool(HSQOBJECT *o);\r
-SQUIRREL_API SQInteger sq_objtointeger(HSQOBJECT *o);\r
-SQUIRREL_API SQFloat sq_objtofloat(HSQOBJECT *o);\r
-SQUIRREL_API SQRESULT sq_getobjtypetag(HSQOBJECT *o,SQUserPointer * typetag);\r
-\r
-/*GC*/\r
-SQUIRREL_API SQInteger sq_collectgarbage(HSQUIRRELVM v);\r
-\r
-/*serialization*/\r
-SQUIRREL_API SQRESULT sq_writeclosure(HSQUIRRELVM vm,SQWRITEFUNC writef,SQUserPointer up);\r
-SQUIRREL_API SQRESULT sq_readclosure(HSQUIRRELVM vm,SQREADFUNC readf,SQUserPointer up);\r
-\r
-/*mem allocation*/\r
-SQUIRREL_API void *sq_malloc(SQUnsignedInteger size);\r
-SQUIRREL_API void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize);\r
-SQUIRREL_API void sq_free(void *p,SQUnsignedInteger size);\r
-\r
-/*debug*/\r
-SQUIRREL_API SQRESULT sq_stackinfos(HSQUIRRELVM v,SQInteger level,SQStackInfos *si);\r
-SQUIRREL_API void sq_setdebughook(HSQUIRRELVM v);\r
-\r
-/*UTILITY MACRO*/\r
-#define sq_isnumeric(o) ((o)._type&SQOBJECT_NUMERIC)\r
-#define sq_istable(o) ((o)._type==OT_TABLE)\r
-#define sq_isarray(o) ((o)._type==OT_ARRAY)\r
-#define sq_isfunction(o) ((o)._type==OT_FUNCPROTO)\r
-#define sq_isclosure(o) ((o)._type==OT_CLOSURE)\r
-#define sq_isgenerator(o) ((o)._type==OT_GENERATOR)\r
-#define sq_isnativeclosure(o) ((o)._type==OT_NATIVECLOSURE)\r
-#define sq_isstring(o) ((o)._type==OT_STRING)\r
-#define sq_isinteger(o) ((o)._type==OT_INTEGER)\r
-#define sq_isfloat(o) ((o)._type==OT_FLOAT)\r
-#define sq_isuserpointer(o) ((o)._type==OT_USERPOINTER)\r
-#define sq_isuserdata(o) ((o)._type==OT_USERDATA)\r
-#define sq_isthread(o) ((o)._type==OT_THREAD)\r
-#define sq_isnull(o) ((o)._type==OT_NULL)\r
-#define sq_isclass(o) ((o)._type==OT_CLASS)\r
-#define sq_isinstance(o) ((o)._type==OT_INSTANCE)\r
-#define sq_isbool(o) ((o)._type==OT_BOOL)\r
-#define sq_isweakref(o) ((o)._type==OT_WEAKREF)\r
-#define sq_type(o) ((o)._type)\r
-\r
-/* deprecated */\r
-#define sq_createslot(v,n) sq_newslot(v,n,SQFalse)\r
-\r
-#define SQ_OK (0)\r
-#define SQ_ERROR (-1)\r
-\r
-#define SQ_FAILED(res) (res<0)\r
-#define SQ_SUCCEEDED(res) (res>=0)\r
-\r
-#ifdef __cplusplus\r
-} /*extern "C"*/\r
-#endif\r
-\r
-#endif /*_SQUIRREL_H_*/\r
+/*
+Copyright (c) 2003-2006 Alberto Demichelis
+
+This software is provided 'as-is', without any
+express or implied warranty. In no event will the
+authors be held liable for any damages arising from
+the use of this software.
+
+Permission is granted to anyone to use this software
+for any purpose, including commercial applications,
+and to alter it and redistribute it freely, subject
+to the following restrictions:
+
+               1. The origin of this software must not be
+               misrepresented; you must not claim that
+               you wrote the original software. If you
+               use this software in a product, an
+               acknowledgment in the product
+               documentation would be appreciated but is
+               not required.
+
+               2. Altered source versions must be plainly
+               marked as such, and must not be
+               misrepresented as being the original
+               software.
+
+               3. This notice may not be removed or
+               altered from any source distribution.
+
+*/
+#ifndef _SQUIRREL_H_
+#define _SQUIRREL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef SQUIRREL_API
+#define SQUIRREL_API extern
+#endif
+
+#ifdef _SQ64
+#ifdef _MSC_VER
+typedef __int64 SQInteger;
+typedef unsigned __int64 SQUnsignedInteger;
+typedef unsigned __int64 SQHash; /*should be the same size of a pointer*/
+#else
+typedef long SQInteger;
+typedef unsigned long SQUnsignedInteger;
+typedef unsigned long SQHash; /*should be the same size of a pointer*/
+#endif
+typedef int SQInt32;
+#else
+typedef int SQInteger;
+typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/
+typedef unsigned int SQUnsignedInteger;
+typedef unsigned int SQHash; /*should be the same size of a pointer*/
+#endif
+
+typedef float SQFloat;
+typedef void* SQUserPointer;
+typedef SQUnsignedInteger SQBool;
+typedef SQInteger SQRESULT;
+
+#define SQTrue (1)
+#define SQFalse        (0)
+
+
+struct SQVM;
+struct SQTable;
+struct SQArray;
+struct SQString;
+struct SQClosure;
+struct SQGenerator;
+struct SQNativeClosure;
+struct SQUserData;
+struct SQFunctionProto;
+struct SQRefCounted;
+struct SQClass;
+struct SQInstance;
+struct SQDelegable;
+
+#ifdef _UNICODE
+#define SQUNICODE
+#endif
+
+#ifdef SQUNICODE
+#if defined(wchar_t) //this is if the compiler considers wchar_t as native type
+#define wchar_t unsigned short
+#endif
+typedef wchar_t SQChar;
+#define _SC(a) L##a
+#define        scstrcmp        wcscmp
+#define scsprintf      swprintf
+#define scstrlen       wcslen
+#define scstrtod       wcstod
+#define scstrtol       wcstol
+#define scatoi         _wtoi
+#define scstrtoul      wcstoul
+#define scvsprintf     vswprintf
+#define scstrstr       wcsstr
+#define scisspace      iswspace
+#define scisdigit      iswdigit
+#define scisxdigit     iswxdigit
+#define scisalpha      iswalpha
+#define sciscntrl      iswcntrl
+#define scisalnum      iswalnum
+#define scprintf       wprintf
+#define MAX_CHAR 0xFFFF
+#else
+typedef char SQChar;
+#define _SC(a) a
+#define        scstrcmp        strcmp
+#define scsprintf      sprintf
+#define scstrlen       strlen
+#define scstrtod       strtod
+#define scstrtol       strtol
+#define scatoi         atoi
+#define scstrtoul      strtoul
+#define scvsprintf     vsprintf
+#define scstrstr       strstr
+#define scisspace      isspace
+#define scisdigit      isdigit
+#define scisxdigit     isxdigit
+#define sciscntrl      iscntrl
+#define scisalpha      isalpha
+#define scisalnum      isalnum
+#define scprintf       printf
+#define MAX_CHAR 0xFF
+#endif
+
+#define SQUIRREL_VERSION       _SC("Squirrel 2.1 stable")
+#define SQUIRREL_COPYRIGHT     _SC("Copyright (C) 2003-2006 Alberto Demichelis")
+#define SQUIRREL_AUTHOR                _SC("Alberto Demichelis")
+
+#define SQ_VMSTATE_IDLE                        0
+#define SQ_VMSTATE_RUNNING             1
+#define SQ_VMSTATE_SUSPENDED   2
+
+#define SQUIRREL_EOB 0
+#define SQ_BYTECODE_STREAM_TAG 0xFAFA
+
+#define SQOBJECT_REF_COUNTED   0x08000000
+#define SQOBJECT_NUMERIC               0x04000000
+#define SQOBJECT_DELEGABLE             0x02000000
+#define SQOBJECT_CANBEFALSE            0x01000000
+
+#define SQ_MATCHTYPEMASKSTRING (-99999)
+
+#define _RT_MASK 0x00FFFFFF
+#define _RAW_TYPE(type) (type&_RT_MASK)
+
+#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
+#define _RT_WEAKREF                    0x00010000
+
+typedef enum tagSQObjectType{
+       OT_NULL =                       (_RT_NULL|SQOBJECT_CANBEFALSE),
+       OT_INTEGER =            (_RT_INTEGER|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
+       OT_FLOAT =                      (_RT_FLOAT|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
+       OT_BOOL =                       (_RT_BOOL|SQOBJECT_CANBEFALSE),
+       OT_STRING =                     (_RT_STRING|SQOBJECT_REF_COUNTED),
+       OT_TABLE =                      (_RT_TABLE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
+       OT_ARRAY =                      (_RT_ARRAY|SQOBJECT_REF_COUNTED),
+       OT_USERDATA =           (_RT_USERDATA|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
+       OT_CLOSURE =            (_RT_CLOSURE|SQOBJECT_REF_COUNTED),
+       OT_NATIVECLOSURE =      (_RT_NATIVECLOSURE|SQOBJECT_REF_COUNTED),
+       OT_GENERATOR =          (_RT_GENERATOR|SQOBJECT_REF_COUNTED),
+       OT_USERPOINTER =        _RT_USERPOINTER,
+       OT_THREAD =                     (_RT_THREAD|SQOBJECT_REF_COUNTED) ,
+       OT_FUNCPROTO =          (_RT_FUNCPROTO|SQOBJECT_REF_COUNTED), //internal usage only
+       OT_CLASS =                      (_RT_CLASS|SQOBJECT_REF_COUNTED),
+       OT_INSTANCE =           (_RT_INSTANCE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
+       OT_WEAKREF =            (_RT_WEAKREF|SQOBJECT_REF_COUNTED)
+}SQObjectType;
+
+#define ISREFCOUNTED(t) (t&SQOBJECT_REF_COUNTED)
+
+
+typedef union tagSQObjectValue
+{
+       struct SQTable *pTable;
+       struct SQArray *pArray;
+       struct SQClosure *pClosure;
+       struct SQGenerator *pGenerator;
+       struct SQNativeClosure *pNativeClosure;
+       struct SQString *pString;
+       struct SQUserData *pUserData;
+       SQInteger nInteger;
+       SQFloat fFloat;
+       SQUserPointer pUserPointer;
+       struct SQFunctionProto *pFunctionProto;
+       struct SQRefCounted *pRefCounted;
+       struct SQDelegable *pDelegable;
+       struct SQVM *pThread;
+       struct SQClass *pClass;
+       struct SQInstance *pInstance;
+       struct SQWeakRef *pWeakRef;
+}SQObjectValue;
+
+
+typedef struct tagSQObject
+{
+       SQObjectValue _unVal;
+       SQObjectType _type;
+}SQObject;
+
+typedef struct tagSQStackInfos{
+       const SQChar* funcname;
+       const SQChar* source;
+       SQInteger line;
+}SQStackInfos;
+
+typedef struct SQVM* HSQUIRRELVM;
+typedef SQObject HSQOBJECT;
+typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM);
+typedef SQInteger (*SQRELEASEHOOK)(SQUserPointer,SQInteger size);
+typedef void (*SQCOMPILERERROR)(HSQUIRRELVM,const SQChar * /*desc*/,const SQChar * /*source*/,SQInteger /*line*/,SQInteger /*column*/);
+typedef void (*SQPRINTFUNCTION)(HSQUIRRELVM,const SQChar * ,...);
+
+typedef SQInteger (*SQWRITEFUNC)(SQUserPointer,SQUserPointer,SQInteger);
+typedef SQInteger (*SQREADFUNC)(SQUserPointer,SQUserPointer,SQInteger);
+
+typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer);
+
+typedef struct tagSQRegFunction{
+       const SQChar *name;
+       SQFUNCTION f;
+       SQInteger nparamscheck;
+       const SQChar *typemask;
+}SQRegFunction;
+
+/*vm*/
+SQUIRREL_API HSQUIRRELVM sq_open(SQInteger initialstacksize);
+SQUIRREL_API HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize);
+SQUIRREL_API void sq_seterrorhandler(HSQUIRRELVM v);
+SQUIRREL_API void sq_close(HSQUIRRELVM v);
+SQUIRREL_API void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p);
+SQUIRREL_API SQUserPointer sq_getforeignptr(HSQUIRRELVM v);
+SQUIRREL_API void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc);
+SQUIRREL_API SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v);
+SQUIRREL_API SQRESULT sq_suspendvm(HSQUIRRELVM v);
+SQUIRREL_API SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool resumedret,SQBool retval,SQBool raiseerror);
+SQUIRREL_API SQInteger sq_getvmstate(HSQUIRRELVM v);
+
+/*compiler*/
+SQUIRREL_API SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror);
+SQUIRREL_API SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror);
+SQUIRREL_API void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable);
+SQUIRREL_API void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable);
+SQUIRREL_API void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f);
+
+/*stack operations*/
+SQUIRREL_API void sq_push(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API void sq_pop(HSQUIRRELVM v,SQInteger nelemstopop);
+SQUIRREL_API void sq_poptop(HSQUIRRELVM v);
+SQUIRREL_API void sq_remove(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQInteger sq_gettop(HSQUIRRELVM v);
+SQUIRREL_API void sq_settop(HSQUIRRELVM v,SQInteger newtop);
+SQUIRREL_API void sq_reservestack(HSQUIRRELVM v,SQInteger nsize);
+SQUIRREL_API SQInteger sq_cmp(HSQUIRRELVM v);
+SQUIRREL_API void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx);
+
+/*object creation handling*/
+SQUIRREL_API SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size);
+SQUIRREL_API void sq_newtable(HSQUIRRELVM v);
+SQUIRREL_API void sq_newarray(HSQUIRRELVM v,SQInteger size);
+SQUIRREL_API void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars);
+SQUIRREL_API SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask);
+SQUIRREL_API SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len);
+SQUIRREL_API void sq_pushfloat(HSQUIRRELVM v,SQFloat f);
+SQUIRREL_API void sq_pushinteger(HSQUIRRELVM v,SQInteger n);
+SQUIRREL_API void sq_pushbool(HSQUIRRELVM v,SQBool b);
+SQUIRREL_API void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p);
+SQUIRREL_API void sq_pushnull(HSQUIRRELVM v);
+SQUIRREL_API SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQInteger sq_getsize(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQBool sq_instanceof(HSQUIRRELVM v);
+SQUIRREL_API void sq_tostring(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b);
+SQUIRREL_API SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c);
+SQUIRREL_API SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i);
+SQUIRREL_API SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f);
+SQUIRREL_API SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b);
+SQUIRREL_API SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread);
+SQUIRREL_API SQRESULT sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p);
+SQUIRREL_API SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag);
+SQUIRREL_API SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag);
+SQUIRREL_API SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag);
+SQUIRREL_API void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook);
+SQUIRREL_API SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize);
+SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars);
+SQUIRREL_API SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name);
+SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p);
+SQUIRREL_API SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag);
+SQUIRREL_API SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase);
+SQUIRREL_API SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API void sq_weakref(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t);
+
+/*object manipulation*/
+SQUIRREL_API void sq_pushroottable(HSQUIRRELVM v);
+SQUIRREL_API void sq_pushregistrytable(HSQUIRRELVM v);
+SQUIRREL_API SQRESULT sq_setroottable(HSQUIRRELVM v);
+/*SQUIRREL_API SQRESULT sq_createslot(HSQUIRRELVM v,SQInteger idx);*/
+SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic);
+SQUIRREL_API SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
+SQUIRREL_API SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
+SQUIRREL_API SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
+SQUIRREL_API SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize);
+SQUIRREL_API SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval);
+SQUIRREL_API SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx);
+
+/*calls*/
+SQUIRREL_API SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror);
+SQUIRREL_API SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror);
+SQUIRREL_API const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx);
+SQUIRREL_API const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval);
+SQUIRREL_API SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err);
+SQUIRREL_API void sq_reseterror(HSQUIRRELVM v);
+SQUIRREL_API void sq_getlasterror(HSQUIRRELVM v);
+
+/*raw object handling*/
+SQUIRREL_API SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po);
+SQUIRREL_API void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj);
+SQUIRREL_API void sq_addref(HSQUIRRELVM v,HSQOBJECT *po);
+SQUIRREL_API SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po);
+SQUIRREL_API void sq_resetobject(HSQOBJECT *po);
+SQUIRREL_API const SQChar *sq_objtostring(HSQOBJECT *o);
+SQUIRREL_API SQBool sq_objtobool(HSQOBJECT *o);
+SQUIRREL_API SQInteger sq_objtointeger(HSQOBJECT *o);
+SQUIRREL_API SQFloat sq_objtofloat(HSQOBJECT *o);
+SQUIRREL_API SQRESULT sq_getobjtypetag(HSQOBJECT *o,SQUserPointer * typetag);
+
+/*GC*/
+SQUIRREL_API SQInteger sq_collectgarbage(HSQUIRRELVM v);
+
+/*serialization*/
+SQUIRREL_API SQRESULT sq_writeclosure(HSQUIRRELVM vm,SQWRITEFUNC writef,SQUserPointer up);
+SQUIRREL_API SQRESULT sq_readclosure(HSQUIRRELVM vm,SQREADFUNC readf,SQUserPointer up);
+
+/*mem allocation*/
+SQUIRREL_API void *sq_malloc(SQUnsignedInteger size);
+SQUIRREL_API void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize);
+SQUIRREL_API void sq_free(void *p,SQUnsignedInteger size);
+
+/*debug*/
+SQUIRREL_API SQRESULT sq_stackinfos(HSQUIRRELVM v,SQInteger level,SQStackInfos *si);
+SQUIRREL_API void sq_setdebughook(HSQUIRRELVM v);
+
+/*UTILITY MACRO*/
+#define sq_isnumeric(o) ((o)._type&SQOBJECT_NUMERIC)
+#define sq_istable(o) ((o)._type==OT_TABLE)
+#define sq_isarray(o) ((o)._type==OT_ARRAY)
+#define sq_isfunction(o) ((o)._type==OT_FUNCPROTO)
+#define sq_isclosure(o) ((o)._type==OT_CLOSURE)
+#define sq_isgenerator(o) ((o)._type==OT_GENERATOR)
+#define sq_isnativeclosure(o) ((o)._type==OT_NATIVECLOSURE)
+#define sq_isstring(o) ((o)._type==OT_STRING)
+#define sq_isinteger(o) ((o)._type==OT_INTEGER)
+#define sq_isfloat(o) ((o)._type==OT_FLOAT)
+#define sq_isuserpointer(o) ((o)._type==OT_USERPOINTER)
+#define sq_isuserdata(o) ((o)._type==OT_USERDATA)
+#define sq_isthread(o) ((o)._type==OT_THREAD)
+#define sq_isnull(o) ((o)._type==OT_NULL)
+#define sq_isclass(o) ((o)._type==OT_CLASS)
+#define sq_isinstance(o) ((o)._type==OT_INSTANCE)
+#define sq_isbool(o) ((o)._type==OT_BOOL)
+#define sq_isweakref(o) ((o)._type==OT_WEAKREF)
+#define sq_type(o) ((o)._type)
+
+/* deprecated */
+#define sq_createslot(v,n) sq_newslot(v,n,SQFalse)
+
+#define SQ_OK (0)
+#define SQ_ERROR (-1)
+
+#define SQ_FAILED(res) (res<0)
+#define SQ_SUCCEEDED(res) (res>=0)
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif /*_SQUIRREL_H_*/
index c76ff0b..d6d141c 100644 (file)
-#include <squirrel.h>\r
-#include <assert.h>\r
-#include <sqstdblob.h>\r
-#include "sqrdbg.h"\r
-#include "sqdbgserver.h"\r
-\r
-\r
-#ifndef _UNICODE\r
-#define scstrcpy strcpy\r
-#else\r
-#define scstrcpy wcscpy\r
-#endif\r
-struct XMLEscape{\r
-       const SQChar c;\r
-       const SQChar *esc;\r
-};\r
-\r
-#define SQDBG_DEBUG_HOOK _SC("_sqdbg_debug_hook_")\r
-#define SQDBG_ERROR_HANDLER _SC("_sqdbg_error_handler_")\r
-\r
-XMLEscape g_escapes[]={\r
-       {_SC('<'),_SC("&lt;")},{'>',_SC("&gt;")},{_SC('&'),_SC("&amp;")},{_SC('\''),_SC("&apos;")},{_SC('\"'),_SC("&quot;")},{_SC('\n'),_SC("&quot;n")},{_SC('\r'),_SC("&quot;r")},{0, NULL}\r
-};\r
-\r
-const SQChar *IntToString(int n)\r
-{\r
-       static SQChar temp[256];\r
-       scsprintf(temp,_SC("%d"),n);\r
-       return temp;\r
-}\r
-\r
-int debug_hook(HSQUIRRELVM v);\r
-int error_handler(HSQUIRRELVM v);\r
-\r
-int beginelement(HSQUIRRELVM v)\r
-{\r
-       SQUserPointer up;\r
-       const SQChar *name;\r
-       sq_getuserpointer(v,-1,&up);\r
-       SQDbgServer *self = (SQDbgServer*)up;\r
-       sq_getuserpointer(v,-1,&up);\r
-       sq_getstring(v,2,&name);\r
-       self->BeginElement(name);\r
-       return 0;\r
-}\r
-\r
-int endelement(HSQUIRRELVM v)\r
-{\r
-       SQUserPointer up;\r
-       const SQChar *name;\r
-       sq_getuserpointer(v,-1,&up);\r
-       SQDbgServer *self = (SQDbgServer*)up;\r
-       sq_getuserpointer(v,-1,&up);\r
-       sq_getstring(v,2,&name);\r
-       self->EndElement(name);\r
-       return 0;\r
-}\r
-\r
-int attribute(HSQUIRRELVM v)\r
-{\r
-       SQUserPointer up;\r
-       const SQChar *name,*value;\r
-       sq_getuserpointer(v,-1,&up);\r
-       SQDbgServer *self = (SQDbgServer*)up;\r
-       sq_getuserpointer(v,-1,&up);\r
-       sq_getstring(v,2,&name);\r
-       sq_getstring(v,3,&value);\r
-       self->Attribute(name,value);\r
-       return 0;\r
-}\r
-\r
-const SQChar *EscapeXMLString(HSQUIRRELVM v,const SQChar *s)\r
-{\r
-       \r
-       SQChar *temp=sq_getscratchpad(v,((int)scstrlen(s)*6) + sizeof(SQChar));\r
-       SQChar *dest=temp;\r
-       while(*s!=_SC('\0')){\r
-               int i=0;\r
-               bool escaped=false;\r
-               while(g_escapes[i].esc!=NULL){\r
-                       if(*s==g_escapes[i].c){\r
-                               scstrcpy(dest,g_escapes[i].esc);\r
-                               dest+=scstrlen(g_escapes[i].esc);\r
-                               escaped=true;\r
-                               break;\r
-                       }\r
-                       i++;\r
-               }\r
-               if(!escaped){*dest=*s;*dest++;}\r
-               *s++;\r
-       }\r
-       *dest=_SC('\0');\r
-       return temp;\r
-}\r
-\r
-SQDbgServer::SQDbgServer(HSQUIRRELVM v)\r
-{\r
-       _ready = false;\r
-       _nestedcalls = 0;\r
-       _autoupdate = false;\r
-       _v = v;\r
-       _state = eDBG_Running;\r
-       _accept = INVALID_SOCKET;\r
-       _endpoint = INVALID_SOCKET;\r
-       _maxrecursion = 10;\r
-       sq_resetobject(&_debugroot);\r
-}\r
-\r
-SQDbgServer::~SQDbgServer()\r
-{\r
-       sq_release(_v,&_debugroot);\r
-       if(_accept != INVALID_SOCKET)\r
-               sqdbg_closesocket(_accept);\r
-       if(_endpoint != INVALID_SOCKET)\r
-               sqdbg_closesocket(_endpoint);\r
-}\r
-\r
-bool SQDbgServer::Init()\r
-{\r
-       //creates  an environment table for the debugger\r
-       \r
-       sq_newtable(_v);\r
-       sq_getstackobj(_v,-1,&_debugroot);\r
-       sq_addref(_v,&_debugroot);\r
-\r
-       //creates a emptyslot to store the watches\r
-       sq_pushstring(_v,_SC("watches"),-1);\r
-       sq_pushnull(_v);\r
-       sq_createslot(_v,-3);\r
-\r
-       sq_pushstring(_v,_SC("beginelement"),-1);\r
-       sq_pushuserpointer(_v,this);\r
-       sq_newclosure(_v,beginelement,1);\r
-       sq_setparamscheck(_v,2,_SC(".s"));\r
-       sq_createslot(_v,-3);\r
-\r
-       sq_pushstring(_v,_SC("endelement"),-1);\r
-       sq_pushuserpointer(_v,this);\r
-       sq_newclosure(_v,endelement,1);\r
-       sq_setparamscheck(_v,2,_SC(".s"));\r
-       sq_createslot(_v,-3);\r
-\r
-       sq_pushstring(_v,_SC("attribute"),-1);\r
-       sq_pushuserpointer(_v,this);\r
-       sq_newclosure(_v,attribute,1);\r
-       sq_setparamscheck(_v,3,_SC(".ss"));\r
-       sq_createslot(_v,-3);\r
-\r
-       sq_pop(_v,1);\r
-\r
-       //stores debug hook and error handler in the registry\r
-       sq_pushregistrytable(_v);\r
-\r
-       sq_pushstring(_v,SQDBG_DEBUG_HOOK,-1);\r
-       sq_pushuserpointer(_v,this);\r
-       sq_newclosure(_v,debug_hook,1);\r
-       sq_createslot(_v,-3);\r
-       \r
-       sq_pushstring(_v,SQDBG_ERROR_HANDLER,-1);\r
-       sq_pushuserpointer(_v,this);\r
-       sq_newclosure(_v,error_handler,1);\r
-       sq_createslot(_v,-3);\r
-\r
-       \r
-       sq_pop(_v,1);\r
-\r
-       //sets the error handlers\r
-       SetErrorHandlers();\r
-       return true;\r
-}\r
-\r
-bool SQDbgServer::ReadMsg()\r
-{\r
-       return false;\r
-}\r
-\r
-void SQDbgServer::BusyWait()\r
-{\r
-       while( !ReadMsg() )\r
-               sleep(0);\r
-}\r
-\r
-void SQDbgServer::SendChunk(const SQChar *chunk)\r
-{\r
-       char *buf=NULL;\r
-       int buf_len=0;\r
-#ifdef _UNICODE\r
-       buf_len=(int)scstrlen(chunk)+1;\r
-       buf=(char *)sq_getscratchpad(_v,(buf_len)*3);\r
-       wcstombs((char *)buf,chunk,buf_len);\r
-#else\r
-       buf_len=(int)scstrlen(chunk);\r
-       buf=(char *)chunk;\r
-#endif\r
-       send(_endpoint,(const char*)buf,(int)strlen((const char *)buf),0);\r
-}\r
-\r
-\r
-void SQDbgServer::Terminated()\r
-{\r
-       BeginElement(_SC("terminated"));\r
-       EndElement(_SC("terminated"));\r
-       ::usleep(200);\r
-}\r
-\r
-void SQDbgServer::Hook(int type,int line,const SQChar *src,const SQChar *func)\r
-{\r
-       switch(_state){\r
-       case eDBG_Running:\r
-               if(type==_SC('l') && _breakpoints.size()) {\r
-                       BreakPointSetItor itr = _breakpoints.find(BreakPoint(line,src));\r
-                       if(itr != _breakpoints.end()) {\r
-                               Break(line,src,_SC("breakpoint"));\r
-                               BreakExecution();\r
-                       }\r
-               }\r
-               break;\r
-       case eDBG_Suspended:\r
-               _nestedcalls=0;\r
-       case eDBG_StepOver:\r
-               switch(type){\r
-               case _SC('l'):\r
-                       if(_nestedcalls==0) {\r
-                               Break(line,src,_SC("step"));\r
-                               BreakExecution();\r
-                       }\r
-                       break;\r
-               case _SC('c'):\r
-                       _nestedcalls++;\r
-                       break;\r
-               case _SC('r'):\r
-                       if(_nestedcalls==0){\r
-                               _nestedcalls=0;\r
-                               \r
-                       }else{\r
-                               _nestedcalls--;\r
-                       }\r
-                       break;\r
-               }\r
-               break;\r
-       case eDBG_StepInto:\r
-               switch(type){\r
-               case _SC('l'):\r
-                       _nestedcalls=0;\r
-                       Break(line,src,_SC("step"));\r
-                       BreakExecution();\r
-                       break;\r
-               \r
-               }\r
-               break;\r
-       case eDBG_StepReturn:\r
-               switch(type){\r
-               case _SC('l'):\r
-                       break;\r
-               case _SC('c'):\r
-                       _nestedcalls++;\r
-                       break;\r
-               case _SC('r'):\r
-                       if(_nestedcalls==0){\r
-                               _nestedcalls=0;\r
-                               _state=eDBG_StepOver;\r
-                       }else{\r
-                               _nestedcalls--;\r
-                       }\r
-                       \r
-                       break;\r
-               }\r
-               break;\r
-       case eDBG_Disabled:\r
-               break;\r
-       }\r
-}\r
-\r
-\r
-#define MSG_ID(x,y) ((y<<8)|x)\r
-//ab Add Breakpoint\r
-//rb Remove Breakpoint\r
-//sp Suspend\r
-void SQDbgServer::ParseMsg(const char *msg)\r
-{\r
-       \r
-       switch(*((unsigned short *)msg)){\r
-               case MSG_ID('a','b'): {\r
-                       BreakPoint bp;\r
-                       if(ParseBreakpoint(msg+3,bp)){\r
-                               AddBreakpoint(bp);\r
-                               scprintf(_SC("added bp %d %s\n"),bp._line,bp._src.c_str());\r
-                       }\r
-                       else\r
-                               scprintf(_SC("error parsing add breakpoint"));\r
-                                                        }\r
-                       break;\r
-               case MSG_ID('r','b'): {\r
-                       BreakPoint bp;\r
-                       if(ParseBreakpoint(msg+3,bp)){\r
-                               RemoveBreakpoint(bp);\r
-                               scprintf(_SC("removed bp %d %s\n"),bp._line,bp._src.c_str());\r
-                       }else\r
-                               scprintf(_SC("error parsing remove breakpoint"));\r
-                                                       }\r
-                       break;\r
-               case MSG_ID('g','o'):\r
-                       if(_state!=eDBG_Running){\r
-                               _state=eDBG_Running;\r
-                               BeginDocument();\r
-                                       BeginElement(_SC("resumed"));\r
-                                       EndElement(_SC("resumed"));\r
-                               EndDocument();\r
-//                             Send(_SC("<resumed/>\r\n"));\r
-                               scprintf(_SC("go (execution resumed)\n"));\r
-                       }\r
-                       break;\r
-               case MSG_ID('s','p'):\r
-                       if(_state!=eDBG_Suspended){\r
-                               _state=eDBG_Suspended;\r
-                               scprintf(_SC("suspend\n"));\r
-                       }\r
-                       break;\r
-               case MSG_ID('s','o'):\r
-                       if(_state==eDBG_Suspended){\r
-                               _state=eDBG_StepOver;\r
-                       }\r
-                       break;\r
-               case MSG_ID('s','i'):\r
-                       if(_state==eDBG_Suspended){\r
-                               _state=eDBG_StepInto;\r
-                               scprintf(_SC("step into\n"));\r
-                       }\r
-                       break;\r
-               case MSG_ID('s','r'):\r
-                       if(_state==eDBG_Suspended){\r
-                               _state=eDBG_StepReturn;\r
-                               scprintf(_SC("step return\n"));\r
-                       }\r
-                       break;\r
-               case MSG_ID('d','i'):\r
-                       if(_state!=eDBG_Disabled){\r
-                               _state=eDBG_Disabled;\r
-                               scprintf(_SC("disabled\n"));\r
-                       }\r
-                       break;\r
-               case MSG_ID('a','w'): {\r
-                       Watch w;\r
-                       if(ParseWatch(msg+3,w))\r
-                       {\r
-                               AddWatch(w);\r
-                               scprintf(_SC("added watch %d %s\n"),w._id,w._exp.c_str());\r
-                       }\r
-                       else\r
-                               scprintf(_SC("error parsing add watch"));\r
-                                                               }\r
-                       break;\r
-               case MSG_ID('r','w'): {\r
-                       int id;\r
-                       if(ParseRemoveWatch(msg+3,id))\r
-                       {\r
-                               RemoveWatch(id);\r
-                               scprintf(_SC("added watch %d\n"),id);\r
-                       }\r
-                       else\r
-                               scprintf(_SC("error parsing remove watch"));\r
-                                                               }\r
-                       break;\r
-               case MSG_ID('t','r'):\r
-                       scprintf(_SC("terminate from user\n"));\r
-                       break;\r
-               case MSG_ID('r','d'):\r
-                       scprintf(_SC("ready\n"));\r
-                       _ready=true;\r
-                       break;\r
-               default:\r
-                       scprintf(_SC("unknown packet"));\r
-\r
-       }\r
-}\r
-\r
-/*\r
-       see copyright notice in sqrdbg.h\r
-*/\r
-bool SQDbgServer::ParseBreakpoint(const char *msg,BreakPoint &out)\r
-{\r
-       static char stemp[MAX_BP_PATH];\r
-       char *ep=NULL;\r
-       out._line=strtoul(msg,&ep,16);\r
-       if(ep==msg || (*ep)!=':')return false;\r
-       \r
-       char *dest=stemp;\r
-       ep++;\r
-       while((*ep)!='\n' && (*ep)!='\0')\r
-       {\r
-               *dest=*ep;\r
-               *dest++;*ep++;\r
-       }\r
-       *dest='\0';\r
-       *dest++;\r
-       *dest='\0';\r
-#ifdef _UNICODE\r
-       int len=(int)strlen(stemp);\r
-       SQChar *p=sq_getscratchpad(_v,(SQInteger)(mbstowcs(NULL,stemp,len)+2)*sizeof(SQChar));\r
-       size_t destlen=mbstowcs(p,stemp,len);\r
-       p[destlen]=_SC('\0');\r
-       out._src=p;\r
-#else\r
-       out._src=stemp;\r
-#endif\r
-       return true;\r
-}\r
-\r
-bool SQDbgServer::ParseWatch(const char *msg,Watch &out)\r
-{\r
-       char *ep=NULL;\r
-       out._id=strtoul(msg,&ep,16);\r
-       if(ep==msg || (*ep)!=':')return false;\r
-\r
-       //char *dest=out._src;\r
-       ep++;\r
-       while((*ep)!='\n' && (*ep)!='\0')\r
-       {\r
-               out._exp.append(1,*ep);\r
-               *ep++;\r
-       }\r
-       return true;\r
-}\r
-\r
-bool SQDbgServer::ParseRemoveWatch(const char *msg,int &id)\r
-{\r
-       char *ep=NULL;\r
-       id=strtoul(msg,&ep,16);\r
-       if(ep==msg)return false;\r
-       return true;\r
-}\r
-\r
-\r
-void SQDbgServer::BreakExecution()\r
-{\r
-       _state=eDBG_Suspended;\r
-       while(_state==eDBG_Suspended){\r
-               if(SQ_FAILED(sq_rdbg_update(this)))\r
-                       exit(0);\r
-               usleep(10);\r
-       }\r
-}\r
-\r
-//COMMANDS\r
-void SQDbgServer::AddBreakpoint(BreakPoint &bp)\r
-{\r
-       _breakpoints.insert(bp);\r
-       BeginDocument();\r
-               BeginElement(_SC("addbreakpoint"));\r
-                       Attribute(_SC("line"),IntToString(bp._line));\r
-                       Attribute(_SC("src"),bp._src.c_str());\r
-               EndElement(_SC("addbreakpoint"));\r
-       EndDocument();\r
-}\r
-\r
-void SQDbgServer::AddWatch(Watch &w)\r
-{\r
-       _watches.insert(w);\r
-}\r
-\r
-void SQDbgServer::RemoveWatch(int id)\r
-{\r
-       WatchSetItor itor=_watches.find(Watch(id,_SC("")));\r
-       if(itor==_watches.end()){\r
-               BeginDocument();\r
-               BeginElement(_SC("error"));\r
-                       Attribute(_SC("desc"),_SC("the watch does not exists"));\r
-               EndElement(_SC("error"));\r
-       EndDocument();\r
-       }\r
-       else{\r
-               _watches.erase(itor);\r
-               scprintf(_SC("removed watch %d\n"),id);\r
-       }\r
-}\r
-\r
-void SQDbgServer::RemoveBreakpoint(BreakPoint &bp)\r
-{\r
-       BreakPointSetItor itor=_breakpoints.find(bp);\r
-       if(itor==_breakpoints.end()){\r
-               BeginDocument();\r
-                       BeginElement(_SC("break"));\r
-                               Attribute(_SC("desc"),_SC("the breakpoint doesn't exists"));\r
-                       EndElement(_SC("break"));\r
-               EndDocument();\r
-       }\r
-       else{\r
-               BeginDocument();\r
-                       BeginElement(_SC("removebreakpoint"));\r
-                               Attribute(_SC("line"),IntToString(bp._line));\r
-                               Attribute(_SC("src"),bp._src.c_str());\r
-                       EndElement(_SC("removebreakpoint"));\r
-               EndDocument();\r
-               _breakpoints.erase(itor);\r
-       }\r
-}\r
-\r
-void SQDbgServer::Break(int line,const SQChar *src,const SQChar *type,const SQChar *error)\r
-{\r
-       if(!error){\r
-               BeginDocument();\r
-                       BeginElement(_SC("break"));\r
-                               Attribute(_SC("line"),IntToString(line));\r
-                               Attribute(_SC("src"),src);\r
-                               Attribute(_SC("type"),type);\r
-                               SerializeState();\r
-                       EndElement(_SC("break"));\r
-               EndDocument();\r
-       }else{\r
-               BeginDocument();\r
-                       BeginElement(_SC("break"));\r
-                               Attribute(_SC("line"),IntToString(line));\r
-                               Attribute(_SC("src"),src);\r
-                               Attribute(_SC("type"),type);\r
-                               Attribute(_SC("error"),error);\r
-                               SerializeState();\r
-                       EndElement(_SC("break"));\r
-               EndDocument();\r
-       }\r
-}\r
-\r
-void SQDbgServer::SerializeState()\r
-{\r
-       sq_pushnull(_v);\r
-       sq_setdebughook(_v);\r
-       sq_pushnull(_v);\r
-       sq_seterrorhandler(_v);\r
-       const SQChar *sz;\r
-       sq_pushobject(_v,_serializefunc);\r
-       sq_pushobject(_v,_debugroot);\r
-       sq_pushstring(_v,_SC("watches"),-1);\r
-       sq_newtable(_v);\r
-       for(WatchSetItor i=_watches.begin(); i!=_watches.end(); ++i)\r
-       {\r
-               sq_pushinteger(_v,i->_id);\r
-               sq_pushstring(_v,i->_exp.c_str(),(int)i->_exp.length());\r
-               sq_createslot(_v,-3);\r
-       }\r
-       sq_rawset(_v,-3);\r
-       if(SQ_SUCCEEDED(sq_call(_v,1,SQTrue,SQTrue))){\r
-               if(SQ_SUCCEEDED(sqstd_getblob(_v,-1,(SQUserPointer*)&sz)))\r
-                       SendChunk(sz);\r
-       }\r
-       sq_pop(_v,2);\r
-       \r
-       SetErrorHandlers();\r
-}\r
-\r
-\r
-void SQDbgServer::SetErrorHandlers()\r
-{\r
-       sq_pushregistrytable(_v);\r
-       sq_pushstring(_v,SQDBG_DEBUG_HOOK,-1);\r
-       sq_rawget(_v,-2);\r
-       sq_setdebughook(_v);\r
-       sq_pushstring(_v,SQDBG_ERROR_HANDLER,-1);\r
-       sq_rawget(_v,-2);\r
-       sq_seterrorhandler(_v);\r
-       sq_pop(_v,1);\r
-}\r
-\r
-void SQDbgServer::BeginElement(const SQChar *name)\r
-{\r
-       _xmlcurrentement++;\r
-       XMLElementState *self = &xmlstate[_xmlcurrentement];\r
-       scstrcpy(self->name,name);\r
-       self->haschildren = false;\r
-       if(_xmlcurrentement > 0) {\r
-               XMLElementState *parent = &xmlstate[_xmlcurrentement-1];\r
-               if(!parent->haschildren) {\r
-                       SendChunk(_SC(">")); // closes the parent tag\r
-                       parent->haschildren = true;\r
-               }\r
-       }\r
-       _scratchstring.resize(2+scstrlen(name));\r
-       scsprintf(&_scratchstring[0],_SC("<%s"),name);\r
-       SendChunk(&_scratchstring[0]);\r
-}\r
-\r
-void SQDbgServer::Attribute(const SQChar *name,const SQChar *value)\r
-{\r
-       XMLElementState *self = &xmlstate[_xmlcurrentement];\r
-       assert(!self->haschildren); //cannot have attributes if already has children\r
-       const SQChar *escval = escape_xml(value);\r
-       _scratchstring.resize(5+scstrlen(name)+scstrlen(escval));\r
-       scsprintf(&_scratchstring[0],_SC(" %s=\"%s\""),name,escval);\r
-       SendChunk(&_scratchstring[0]);\r
-}\r
-\r
-void SQDbgServer::EndElement(const SQChar *name)\r
-{\r
-       XMLElementState *self = &xmlstate[_xmlcurrentement];\r
-       assert(scstrcmp(self->name,name) == 0);\r
-       if(self->haschildren) {\r
-               _scratchstring.resize(4+scstrlen(name));\r
-               scsprintf(&_scratchstring[0],_SC("</%s>"),name);\r
-               SendChunk(&_scratchstring[0]);\r
-               \r
-       }\r
-       else {\r
-               SendChunk(_SC("/>"));\r
-       }\r
-       _xmlcurrentement--;\r
-}\r
-\r
-void SQDbgServer::EndDocument()\r
-{\r
-       SendChunk(_SC("\r\n"));\r
-}\r
-\r
-//this can be done much better/faster(do we need that?)\r
-const SQChar *SQDbgServer::escape_xml(const SQChar *s)\r
-{\r
-       SQChar *temp=sq_getscratchpad(_v,((int)scstrlen(s)*6) + sizeof(SQChar));\r
-       SQChar *dest=temp;\r
-       while(*s!=_SC('\0')){\r
-               int i=0;\r
-               bool escaped=false;\r
-               while(g_escapes[i].esc!=NULL){\r
-                       if(*s==g_escapes[i].c){\r
-                               scstrcpy(dest,g_escapes[i].esc);\r
-                               dest+=scstrlen(g_escapes[i].esc);\r
-                               escaped=true;\r
-                               break;\r
-                       }\r
-                       i++;\r
-               }\r
-               if(!escaped){*dest=*s;*dest++;}\r
-               *s++;\r
-       }\r
-       *dest=_SC('\0');\r
-       return temp;\r
-       \r
-}\r
+#include <squirrel.h>
+#include <assert.h>
+#include <sqstdblob.h>
+#include "sqrdbg.h"
+#include "sqdbgserver.h"
+
+
+#ifndef _UNICODE
+#define scstrcpy strcpy
+#else
+#define scstrcpy wcscpy
+#endif
+struct XMLEscape{
+       const SQChar c;
+       const SQChar *esc;
+};
+
+#define SQDBG_DEBUG_HOOK _SC("_sqdbg_debug_hook_")
+#define SQDBG_ERROR_HANDLER _SC("_sqdbg_error_handler_")
+
+XMLEscape g_escapes[]={
+       {_SC('<'),_SC("&lt;")},{'>',_SC("&gt;")},{_SC('&'),_SC("&amp;")},{_SC('\''),_SC("&apos;")},{_SC('\"'),_SC("&quot;")},{_SC('\n'),_SC("&quot;n")},{_SC('\r'),_SC("&quot;r")},{0, NULL}
+};
+
+const SQChar *IntToString(int n)
+{
+       static SQChar temp[256];
+       scsprintf(temp,_SC("%d"),n);
+       return temp;
+}
+
+int debug_hook(HSQUIRRELVM v);
+int error_handler(HSQUIRRELVM v);
+
+int beginelement(HSQUIRRELVM v)
+{
+       SQUserPointer up;
+       const SQChar *name;
+       sq_getuserpointer(v,-1,&up);
+       SQDbgServer *self = (SQDbgServer*)up;
+       sq_getuserpointer(v,-1,&up);
+       sq_getstring(v,2,&name);
+       self->BeginElement(name);
+       return 0;
+}
+
+int endelement(HSQUIRRELVM v)
+{
+       SQUserPointer up;
+       const SQChar *name;
+       sq_getuserpointer(v,-1,&up);
+       SQDbgServer *self = (SQDbgServer*)up;
+       sq_getuserpointer(v,-1,&up);
+       sq_getstring(v,2,&name);
+       self->EndElement(name);
+       return 0;
+}
+
+int attribute(HSQUIRRELVM v)
+{
+       SQUserPointer up;
+       const SQChar *name,*value;
+       sq_getuserpointer(v,-1,&up);
+       SQDbgServer *self = (SQDbgServer*)up;
+       sq_getuserpointer(v,-1,&up);
+       sq_getstring(v,2,&name);
+       sq_getstring(v,3,&value);
+       self->Attribute(name,value);
+       return 0;
+}
+
+const SQChar *EscapeXMLString(HSQUIRRELVM v,const SQChar *s)
+{
+
+       SQChar *temp=sq_getscratchpad(v,((int)scstrlen(s)*6) + sizeof(SQChar));
+       SQChar *dest=temp;
+       while(*s!=_SC('\0')){
+               int i=0;
+               bool escaped=false;
+               while(g_escapes[i].esc!=NULL){
+                       if(*s==g_escapes[i].c){
+                               scstrcpy(dest,g_escapes[i].esc);
+                               dest+=scstrlen(g_escapes[i].esc);
+                               escaped=true;
+                               break;
+                       }
+                       i++;
+               }
+               if(!escaped){*dest=*s;*dest++;}
+               *s++;
+       }
+       *dest=_SC('\0');
+       return temp;
+}
+
+SQDbgServer::SQDbgServer(HSQUIRRELVM v)
+{
+       _ready = false;
+       _nestedcalls = 0;
+       _autoupdate = false;
+       _v = v;
+       _state = eDBG_Running;
+       _accept = INVALID_SOCKET;
+       _endpoint = INVALID_SOCKET;
+       _maxrecursion = 10;
+       sq_resetobject(&_debugroot);
+}
+
+SQDbgServer::~SQDbgServer()
+{
+       sq_release(_v,&_debugroot);
+       if(_accept != INVALID_SOCKET)
+               sqdbg_closesocket(_accept);
+       if(_endpoint != INVALID_SOCKET)
+               sqdbg_closesocket(_endpoint);
+}
+
+bool SQDbgServer::Init()
+{
+       //creates  an environment table for the debugger
+
+       sq_newtable(_v);
+       sq_getstackobj(_v,-1,&_debugroot);
+       sq_addref(_v,&_debugroot);
+
+       //creates a emptyslot to store the watches
+       sq_pushstring(_v,_SC("watches"),-1);
+       sq_pushnull(_v);
+       sq_createslot(_v,-3);
+
+       sq_pushstring(_v,_SC("beginelement"),-1);
+       sq_pushuserpointer(_v,this);
+       sq_newclosure(_v,beginelement,1);
+       sq_setparamscheck(_v,2,_SC(".s"));
+       sq_createslot(_v,-3);
+
+       sq_pushstring(_v,_SC("endelement"),-1);
+       sq_pushuserpointer(_v,this);
+       sq_newclosure(_v,endelement,1);
+       sq_setparamscheck(_v,2,_SC(".s"));
+       sq_createslot(_v,-3);
+
+       sq_pushstring(_v,_SC("attribute"),-1);
+       sq_pushuserpointer(_v,this);
+       sq_newclosure(_v,attribute,1);
+       sq_setparamscheck(_v,3,_SC(".ss"));
+       sq_createslot(_v,-3);
+
+       sq_pop(_v,1);
+
+       //stores debug hook and error handler in the registry
+       sq_pushregistrytable(_v);
+
+       sq_pushstring(_v,SQDBG_DEBUG_HOOK,-1);
+       sq_pushuserpointer(_v,this);
+       sq_newclosure(_v,debug_hook,1);
+       sq_createslot(_v,-3);
+
+       sq_pushstring(_v,SQDBG_ERROR_HANDLER,-1);
+       sq_pushuserpointer(_v,this);
+       sq_newclosure(_v,error_handler,1);
+       sq_createslot(_v,-3);
+
+
+       sq_pop(_v,1);
+
+       //sets the error handlers
+       SetErrorHandlers();
+       return true;
+}
+
+bool SQDbgServer::ReadMsg()
+{
+       return false;
+}
+
+void SQDbgServer::BusyWait()
+{
+       while( !ReadMsg() )
+               sleep(0);
+}
+
+void SQDbgServer::SendChunk(const SQChar *chunk)
+{
+       char *buf=NULL;
+       int buf_len=0;
+#ifdef _UNICODE
+       buf_len=(int)scstrlen(chunk)+1;
+       buf=(char *)sq_getscratchpad(_v,(buf_len)*3);
+       wcstombs((char *)buf,chunk,buf_len);
+#else
+       buf_len=(int)scstrlen(chunk);
+       buf=(char *)chunk;
+#endif
+       send(_endpoint,(const char*)buf,(int)strlen((const char *)buf),0);
+}
+
+
+void SQDbgServer::Terminated()
+{
+       BeginElement(_SC("terminated"));
+       EndElement(_SC("terminated"));
+       ::usleep(200);
+}
+
+void SQDbgServer::Hook(int type,int line,const SQChar *src,const SQChar *func)
+{
+       switch(_state){
+       case eDBG_Running:
+               if(type==_SC('l') && _breakpoints.size()) {
+                       BreakPointSetItor itr = _breakpoints.find(BreakPoint(line,src));
+                       if(itr != _breakpoints.end()) {
+                               Break(line,src,_SC("breakpoint"));
+                               BreakExecution();
+                       }
+               }
+               break;
+       case eDBG_Suspended:
+               _nestedcalls=0;
+       case eDBG_StepOver:
+               switch(type){
+               case _SC('l'):
+                       if(_nestedcalls==0) {
+                               Break(line,src,_SC("step"));
+                               BreakExecution();
+                       }
+                       break;
+               case _SC('c'):
+                       _nestedcalls++;
+                       break;
+               case _SC('r'):
+                       if(_nestedcalls==0){
+                               _nestedcalls=0;
+
+                       }else{
+                               _nestedcalls--;
+                       }
+                       break;
+               }
+               break;
+       case eDBG_StepInto:
+               switch(type){
+               case _SC('l'):
+                       _nestedcalls=0;
+                       Break(line,src,_SC("step"));
+                       BreakExecution();
+                       break;
+
+               }
+               break;
+       case eDBG_StepReturn:
+               switch(type){
+               case _SC('l'):
+                       break;
+               case _SC('c'):
+                       _nestedcalls++;
+                       break;
+               case _SC('r'):
+                       if(_nestedcalls==0){
+                               _nestedcalls=0;
+                               _state=eDBG_StepOver;
+                       }else{
+                               _nestedcalls--;
+                       }
+
+                       break;
+               }
+               break;
+       case eDBG_Disabled:
+               break;
+       }
+}
+
+
+#define MSG_ID(x,y) ((y<<8)|x)
+//ab Add Breakpoint
+//rb Remove Breakpoint
+//sp Suspend
+void SQDbgServer::ParseMsg(const char *msg)
+{
+
+       switch(*((unsigned short *)msg)){
+               case MSG_ID('a','b'): {
+                       BreakPoint bp;
+                       if(ParseBreakpoint(msg+3,bp)){
+                               AddBreakpoint(bp);
+                               scprintf(_SC("added bp %d %s\n"),bp._line,bp._src.c_str());
+                       }
+                       else
+                               scprintf(_SC("error parsing add breakpoint"));
+                                                        }
+                       break;
+               case MSG_ID('r','b'): {
+                       BreakPoint bp;
+                       if(ParseBreakpoint(msg+3,bp)){
+                               RemoveBreakpoint(bp);
+                               scprintf(_SC("removed bp %d %s\n"),bp._line,bp._src.c_str());
+                       }else
+                               scprintf(_SC("error parsing remove breakpoint"));
+                                                       }
+                       break;
+               case MSG_ID('g','o'):
+                       if(_state!=eDBG_Running){
+                               _state=eDBG_Running;
+                               BeginDocument();
+                                       BeginElement(_SC("resumed"));
+                                       EndElement(_SC("resumed"));
+                               EndDocument();
+//                             Send(_SC("<resumed/>\r\n"));
+                               scprintf(_SC("go (execution resumed)\n"));
+                       }
+                       break;
+               case MSG_ID('s','p'):
+                       if(_state!=eDBG_Suspended){
+                               _state=eDBG_Suspended;
+                               scprintf(_SC("suspend\n"));
+                       }
+                       break;
+               case MSG_ID('s','o'):
+                       if(_state==eDBG_Suspended){
+                               _state=eDBG_StepOver;
+                       }
+                       break;
+               case MSG_ID('s','i'):
+                       if(_state==eDBG_Suspended){
+                               _state=eDBG_StepInto;
+                               scprintf(_SC("step into\n"));
+                       }
+                       break;
+               case MSG_ID('s','r'):
+                       if(_state==eDBG_Suspended){
+                               _state=eDBG_StepReturn;
+                               scprintf(_SC("step return\n"));
+                       }
+                       break;
+               case MSG_ID('d','i'):
+                       if(_state!=eDBG_Disabled){
+                               _state=eDBG_Disabled;
+                               scprintf(_SC("disabled\n"));
+                       }
+                       break;
+               case MSG_ID('a','w'): {
+                       Watch w;
+                       if(ParseWatch(msg+3,w))
+                       {
+                               AddWatch(w);
+                               scprintf(_SC("added watch %d %s\n"),w._id,w._exp.c_str());
+                       }
+                       else
+                               scprintf(_SC("error parsing add watch"));
+                                                               }
+                       break;
+               case MSG_ID('r','w'): {
+                       int id;
+                       if(ParseRemoveWatch(msg+3,id))
+                       {
+                               RemoveWatch(id);
+                               scprintf(_SC("added watch %d\n"),id);
+                       }
+                       else
+                               scprintf(_SC("error parsing remove watch"));
+                                                               }
+                       break;
+               case MSG_ID('t','r'):
+                       scprintf(_SC("terminate from user\n"));
+                       break;
+               case MSG_ID('r','d'):
+                       scprintf(_SC("ready\n"));
+                       _ready=true;
+                       break;
+               default:
+                       scprintf(_SC("unknown packet"));
+
+       }
+}
+
+/*
+       see copyright notice in sqrdbg.h
+*/
+bool SQDbgServer::ParseBreakpoint(const char *msg,BreakPoint &out)
+{
+       static char stemp[MAX_BP_PATH];
+       char *ep=NULL;
+       out._line=strtoul(msg,&ep,16);
+       if(ep==msg || (*ep)!=':')return false;
+
+       char *dest=stemp;
+       ep++;
+       while((*ep)!='\n' && (*ep)!='\0')
+       {
+               *dest=*ep;
+               *dest++;*ep++;
+       }
+       *dest='\0';
+       *dest++;
+       *dest='\0';
+#ifdef _UNICODE
+       int len=(int)strlen(stemp);
+       SQChar *p=sq_getscratchpad(_v,(SQInteger)(mbstowcs(NULL,stemp,len)+2)*sizeof(SQChar));
+       size_t destlen=mbstowcs(p,stemp,len);
+       p[destlen]=_SC('\0');
+       out._src=p;
+#else
+       out._src=stemp;
+#endif
+       return true;
+}
+
+bool SQDbgServer::ParseWatch(const char *msg,Watch &out)
+{
+       char *ep=NULL;
+       out._id=strtoul(msg,&ep,16);
+       if(ep==msg || (*ep)!=':')return false;
+
+       //char *dest=out._src;
+       ep++;
+       while((*ep)!='\n' && (*ep)!='\0')
+       {
+               out._exp.append(1,*ep);
+               *ep++;
+       }
+       return true;
+}
+
+bool SQDbgServer::ParseRemoveWatch(const char *msg,int &id)
+{
+       char *ep=NULL;
+       id=strtoul(msg,&ep,16);
+       if(ep==msg)return false;
+       return true;
+}
+
+
+void SQDbgServer::BreakExecution()
+{
+       _state=eDBG_Suspended;
+       while(_state==eDBG_Suspended){
+               if(SQ_FAILED(sq_rdbg_update(this)))
+                       exit(0);
+               usleep(10);
+       }
+}
+
+//COMMANDS
+void SQDbgServer::AddBreakpoint(BreakPoint &bp)
+{
+       _breakpoints.insert(bp);
+       BeginDocument();
+               BeginElement(_SC("addbreakpoint"));
+                       Attribute(_SC("line"),IntToString(bp._line));
+                       Attribute(_SC("src"),bp._src.c_str());
+               EndElement(_SC("addbreakpoint"));
+       EndDocument();
+}
+
+void SQDbgServer::AddWatch(Watch &w)
+{
+       _watches.insert(w);
+}
+
+void SQDbgServer::RemoveWatch(int id)
+{
+       WatchSetItor itor=_watches.find(Watch(id,_SC("")));
+       if(itor==_watches.end()){
+               BeginDocument();
+               BeginElement(_SC("error"));
+                       Attribute(_SC("desc"),_SC("the watch does not exists"));
+               EndElement(_SC("error"));
+       EndDocument();
+       }
+       else{
+               _watches.erase(itor);
+               scprintf(_SC("removed watch %d\n"),id);
+       }
+}
+
+void SQDbgServer::RemoveBreakpoint(BreakPoint &bp)
+{
+       BreakPointSetItor itor=_breakpoints.find(bp);
+       if(itor==_breakpoints.end()){
+               BeginDocument();
+                       BeginElement(_SC("break"));
+                               Attribute(_SC("desc"),_SC("the breakpoint doesn't exists"));
+                       EndElement(_SC("break"));
+               EndDocument();
+       }
+       else{
+               BeginDocument();
+                       BeginElement(_SC("removebreakpoint"));
+                               Attribute(_SC("line"),IntToString(bp._line));
+                               Attribute(_SC("src"),bp._src.c_str());
+                       EndElement(_SC("removebreakpoint"));
+               EndDocument();
+               _breakpoints.erase(itor);
+       }
+}
+
+void SQDbgServer::Break(int line,const SQChar *src,const SQChar *type,const SQChar *error)
+{
+       if(!error){
+               BeginDocument();
+                       BeginElement(_SC("break"));
+                               Attribute(_SC("line"),IntToString(line));
+                               Attribute(_SC("src"),src);
+                               Attribute(_SC("type"),type);
+                               SerializeState();
+                       EndElement(_SC("break"));
+               EndDocument();
+       }else{
+               BeginDocument();
+                       BeginElement(_SC("break"));
+                               Attribute(_SC("line"),IntToString(line));
+                               Attribute(_SC("src"),src);
+                               Attribute(_SC("type"),type);
+                               Attribute(_SC("error"),error);
+                               SerializeState();
+                       EndElement(_SC("break"));
+               EndDocument();
+       }
+}
+
+void SQDbgServer::SerializeState()
+{
+       sq_pushnull(_v);
+       sq_setdebughook(_v);
+       sq_pushnull(_v);
+       sq_seterrorhandler(_v);
+       const SQChar *sz;
+       sq_pushobject(_v,_serializefunc);
+       sq_pushobject(_v,_debugroot);
+       sq_pushstring(_v,_SC("watches"),-1);
+       sq_newtable(_v);
+       for(WatchSetItor i=_watches.begin(); i!=_watches.end(); ++i)
+       {
+               sq_pushinteger(_v,i->_id);
+               sq_pushstring(_v,i->_exp.c_str(),(int)i->_exp.length());
+               sq_createslot(_v,-3);
+       }
+       sq_rawset(_v,-3);
+       if(SQ_SUCCEEDED(sq_call(_v,1,SQTrue,SQTrue))){
+               if(SQ_SUCCEEDED(sqstd_getblob(_v,-1,(SQUserPointer*)&sz)))
+                       SendChunk(sz);
+       }
+       sq_pop(_v,2);
+
+       SetErrorHandlers();
+}
+
+
+void SQDbgServer::SetErrorHandlers()
+{
+       sq_pushregistrytable(_v);
+       sq_pushstring(_v,SQDBG_DEBUG_HOOK,-1);
+       sq_rawget(_v,-2);
+       sq_setdebughook(_v);
+       sq_pushstring(_v,SQDBG_ERROR_HANDLER,-1);
+       sq_rawget(_v,-2);
+       sq_seterrorhandler(_v);
+       sq_pop(_v,1);
+}
+
+void SQDbgServer::BeginElement(const SQChar *name)
+{
+       _xmlcurrentement++;
+       XMLElementState *self = &xmlstate[_xmlcurrentement];
+       scstrcpy(self->name,name);
+       self->haschildren = false;
+       if(_xmlcurrentement > 0) {
+               XMLElementState *parent = &xmlstate[_xmlcurrentement-1];
+               if(!parent->haschildren) {
+                       SendChunk(_SC(">")); // closes the parent tag
+                       parent->haschildren = true;
+               }
+       }
+       _scratchstring.resize(2+scstrlen(name));
+       scsprintf(&_scratchstring[0],_SC("<%s"),name);
+       SendChunk(&_scratchstring[0]);
+}
+
+void SQDbgServer::Attribute(const SQChar *name,const SQChar *value)
+{
+       XMLElementState *self = &xmlstate[_xmlcurrentement];
+       assert(!self->haschildren); //cannot have attributes if already has children
+       const SQChar *escval = escape_xml(value);
+       _scratchstring.resize(5+scstrlen(name)+scstrlen(escval));
+       scsprintf(&_scratchstring[0],_SC(" %s=\"%s\""),name,escval);
+       SendChunk(&_scratchstring[0]);
+}
+
+void SQDbgServer::EndElement(const SQChar *name)
+{
+       XMLElementState *self = &xmlstate[_xmlcurrentement];
+       assert(scstrcmp(self->name,name) == 0);
+       if(self->haschildren) {
+               _scratchstring.resize(4+scstrlen(name));
+               scsprintf(&_scratchstring[0],_SC("</%s>"),name);
+               SendChunk(&_scratchstring[0]);
+
+       }
+       else {
+               SendChunk(_SC("/>"));
+       }
+       _xmlcurrentement--;
+}
+
+void SQDbgServer::EndDocument()
+{
+       SendChunk(_SC("\r\n"));
+}
+
+//this can be done much better/faster(do we need that?)
+const SQChar *SQDbgServer::escape_xml(const SQChar *s)
+{
+       SQChar *temp=sq_getscratchpad(_v,((int)scstrlen(s)*6) + sizeof(SQChar));
+       SQChar *dest=temp;
+       while(*s!=_SC('\0')){
+               int i=0;
+               bool escaped=false;
+               while(g_escapes[i].esc!=NULL){
+                       if(*s==g_escapes[i].c){
+                               scstrcpy(dest,g_escapes[i].esc);
+                               dest+=scstrlen(g_escapes[i].esc);
+                               escaped=true;
+                               break;
+                       }
+                       i++;
+               }
+               if(!escaped){*dest=*s;*dest++;}
+               *s++;
+       }
+       *dest=_SC('\0');
+       return temp;
+
+}
index dcfa7cf..8c3fc28 100644 (file)
-#ifndef _SQ_DBGSERVER_H_\r
-#define _SQ_DBGSERVER_H_\r
-\r
-#define MAX_BP_PATH 512\r
-#define MAX_MSG_LEN 2049\r
-\r
-#include <set>\r
-#include <string>\r
-#include <vector>\r
-\r
-#ifdef _WIN32\r
-#include <winsock.h>\r
-#define sqdbg_closesocket(x) closesocket((x))\r
-typedef socklen_t int;\r
-#else\r
-#include <unistd.h>\r
-#include <errno.h>\r
-#include <sys/socket.h>\r
-#include <sys/types.h>\r
-#include <netinet/in.h>\r
-#include <arpa/inet.h>\r
-#include <netdb.h>\r
-#include <fcntl.h>\r
-\r
-#define sqdbg_closesocket(x) close((x))\r
-typedef int SOCKET;\r
-typedef struct timeval TIMEVAL;\r
-#define SOCKET_ERROR -1\r
-#define INVALID_SOCKET -1\r
-#endif\r
-\r
-typedef std::basic_string<SQChar> SQDBGString;\r
-\r
-inline bool dbg_less(const SQChar *x,const SQChar *y)\r
-{\r
-       int n = 0;\r
-       do {\r
-               int xl = *x == '\\' ? '/' : tolower(*x);\r
-               int yl = *y == '\\' ? '/' : tolower(*y);\r
-               int diff = xl - yl;\r
-               if(diff != 0)\r
-                       return diff > 0?true:false;\r
-               x++; y++;\r
-       }while(*x != 0 && *y != 0);\r
-       return false;\r
-}\r
-\r
-struct BreakPoint{\r
-       BreakPoint(){_line=0;}\r
-       BreakPoint(int line, const SQChar *src){ _line = line; _src = src; }\r
-       BreakPoint(const BreakPoint& bp){ _line = bp._line; _src=bp._src; }\r
-       inline bool operator<(const BreakPoint& bp) const\r
-       {\r
-               if(_line<bp._line)\r
-                       return true;\r
-               if(_line==bp._line){\r
-                       return dbg_less(_src.c_str(),bp._src.c_str());\r
-               }\r
-               return false;\r
-       }\r
-       \r
-       int _line;\r
-       SQDBGString _src;\r
-};\r
-\r
-struct Watch{\r
-       Watch() { _id = 0; }\r
-       Watch(int id,const SQChar *exp) { _id = id; _exp = exp; }\r
-       Watch(const Watch &w) { _id = w._id; _exp = w._exp; }\r
-       bool operator<(const Watch& w) const { return _id<w._id; }\r
-       bool operator==(const Watch& w) const { return _id == w._id; }\r
-       int _id;\r
-       SQDBGString _exp;\r
-};\r
-\r
-typedef std::set<BreakPoint> BreakPointSet;\r
-typedef BreakPointSet::iterator BreakPointSetItor;\r
-\r
-typedef std::set<Watch> WatchSet;\r
-typedef WatchSet::iterator WatchSetItor;\r
-\r
-typedef std::vector<SQChar> SQCharVec;\r
-struct SQDbgServer{\r
-public:\r
-       enum eDbgState{\r
-               eDBG_Running,\r
-               eDBG_StepOver,\r
-               eDBG_StepInto,\r
-               eDBG_StepReturn,\r
-               eDBG_Suspended,\r
-               eDBG_Disabled,\r
-       };\r
-\r
-       SQDbgServer(HSQUIRRELVM v);\r
-       ~SQDbgServer();\r
-       bool Init();\r
-       //returns true if a message has been received\r
-       bool WaitForClient();\r
-       bool ReadMsg();\r
-       void BusyWait();\r
-       void Hook(int type,int line,const SQChar *src,const SQChar *func);\r
-       void ParseMsg(const char *msg);\r
-       bool ParseBreakpoint(const char *msg,BreakPoint &out);\r
-       bool ParseWatch(const char *msg,Watch &out);\r
-       bool ParseRemoveWatch(const char *msg,int &id);\r
-       void Terminated();\r
-       //\r
-       void BreakExecution();\r
-       void Send(const SQChar *s,...);\r
-       void SendChunk(const SQChar *chunk);\r
-       void Break(int line,const SQChar *src,const SQChar *type,const SQChar *error=NULL);\r
-       \r
-\r
-       void SerializeState();\r
-       //COMMANDS\r
-       void AddBreakpoint(BreakPoint &bp);\r
-       void AddWatch(Watch &w);\r
-       void RemoveWatch(int id);\r
-       void RemoveBreakpoint(BreakPoint &bp);\r
-\r
-       //\r
-       void SetErrorHandlers();\r
-\r
-       //XML RELATED STUFF///////////////////////\r
-       #define MAX_NESTING 10\r
-       struct XMLElementState {\r
-               SQChar name[256];\r
-               bool haschildren;\r
-       };\r
-\r
-       XMLElementState xmlstate[MAX_NESTING];\r
-       int _xmlcurrentement;\r
-\r
-       void BeginDocument() { _xmlcurrentement = -1; }\r
-       void BeginElement(const SQChar *name);\r
-       void Attribute(const SQChar *name, const SQChar *value);\r
-       void EndElement(const SQChar *name);\r
-       void EndDocument();\r
-\r
-       const SQChar *escape_xml(const SQChar *x);\r
-       //////////////////////////////////////////////\r
-       HSQUIRRELVM _v;\r
-       HSQOBJECT _debugroot;\r
-       eDbgState _state;\r
-       SOCKET _accept;\r
-       SOCKET _endpoint;\r
-       BreakPointSet _breakpoints;\r
-       WatchSet _watches;\r
-       int _recursionlevel; \r
-       int _maxrecursion;\r
-       int _nestedcalls;\r
-       bool _ready;\r
-       bool _autoupdate;\r
-       HSQOBJECT _serializefunc;\r
-       SQCharVec _scratchstring;\r
-               \r
-};\r
-\r
-#endif //_SQ_DBGSERVER_H_ \r
+#ifndef _SQ_DBGSERVER_H_
+#define _SQ_DBGSERVER_H_
+
+#define MAX_BP_PATH 512
+#define MAX_MSG_LEN 2049
+
+#include <set>
+#include <string>
+#include <vector>
+
+#ifdef _WIN32
+#include <winsock.h>
+#define sqdbg_closesocket(x) closesocket((x))
+typedef socklen_t int;
+#else
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <fcntl.h>
+
+#define sqdbg_closesocket(x) close((x))
+typedef int SOCKET;
+typedef struct timeval TIMEVAL;
+#define SOCKET_ERROR -1
+#define INVALID_SOCKET -1
+#endif
+
+typedef std::basic_string<SQChar> SQDBGString;
+
+inline bool dbg_less(const SQChar *x,const SQChar *y)
+{
+       int n = 0;
+       do {
+               int xl = *x == '\\' ? '/' : tolower(*x);
+               int yl = *y == '\\' ? '/' : tolower(*y);
+               int diff = xl - yl;
+               if(diff != 0)
+                       return diff > 0?true:false;
+               x++; y++;
+       }while(*x != 0 && *y != 0);
+       return false;
+}
+
+struct BreakPoint{
+       BreakPoint(){_line=0;}
+       BreakPoint(int line, const SQChar *src){ _line = line; _src = src; }
+       BreakPoint(const BreakPoint& bp){ _line = bp._line; _src=bp._src; }
+       inline bool operator<(const BreakPoint& bp) const
+       {
+               if(_line<bp._line)
+                       return true;
+               if(_line==bp._line){
+                       return dbg_less(_src.c_str(),bp._src.c_str());
+               }
+               return false;
+       }
+
+       int _line;
+       SQDBGString _src;
+};
+
+struct Watch{
+       Watch() { _id = 0; }
+       Watch(int id,const SQChar *exp) { _id = id; _exp = exp; }
+       Watch(const Watch &w) { _id = w._id; _exp = w._exp; }
+       bool operator<(const Watch& w) const { return _id<w._id; }
+       bool operator==(const Watch& w) const { return _id == w._id; }
+       int _id;
+       SQDBGString _exp;
+};
+
+typedef std::set<BreakPoint> BreakPointSet;
+typedef BreakPointSet::iterator BreakPointSetItor;
+
+typedef std::set<Watch> WatchSet;
+typedef WatchSet::iterator WatchSetItor;
+
+typedef std::vector<SQChar> SQCharVec;
+struct SQDbgServer{
+public:
+       enum eDbgState{
+               eDBG_Running,
+               eDBG_StepOver,
+               eDBG_StepInto,
+               eDBG_StepReturn,
+               eDBG_Suspended,
+               eDBG_Disabled,
+       };
+
+       SQDbgServer(HSQUIRRELVM v);
+       ~SQDbgServer();
+       bool Init();
+       //returns true if a message has been received
+       bool WaitForClient();
+       bool ReadMsg();
+       void BusyWait();
+       void Hook(int type,int line,const SQChar *src,const SQChar *func);
+       void ParseMsg(const char *msg);
+       bool ParseBreakpoint(const char *msg,BreakPoint &out);
+       bool ParseWatch(const char *msg,Watch &out);
+       bool ParseRemoveWatch(const char *msg,int &id);
+       void Terminated();
+       //
+       void BreakExecution();
+       void Send(const SQChar *s,...);
+       void SendChunk(const SQChar *chunk);
+       void Break(int line,const SQChar *src,const SQChar *type,const SQChar *error=NULL);
+
+
+       void SerializeState();
+       //COMMANDS
+       void AddBreakpoint(BreakPoint &bp);
+       void AddWatch(Watch &w);
+       void RemoveWatch(int id);
+       void RemoveBreakpoint(BreakPoint &bp);
+
+       //
+       void SetErrorHandlers();
+
+       //XML RELATED STUFF///////////////////////
+       #define MAX_NESTING 10
+       struct XMLElementState {
+               SQChar name[256];
+               bool haschildren;
+       };
+
+       XMLElementState xmlstate[MAX_NESTING];
+       int _xmlcurrentement;
+
+       void BeginDocument() { _xmlcurrentement = -1; }
+       void BeginElement(const SQChar *name);
+       void Attribute(const SQChar *name, const SQChar *value);
+       void EndElement(const SQChar *name);
+       void EndDocument();
+
+       const SQChar *escape_xml(const SQChar *x);
+       //////////////////////////////////////////////
+       HSQUIRRELVM _v;
+       HSQOBJECT _debugroot;
+       eDbgState _state;
+       SOCKET _accept;
+       SOCKET _endpoint;
+       BreakPointSet _breakpoints;
+       WatchSet _watches;
+       int _recursionlevel;
+       int _maxrecursion;
+       int _nestedcalls;
+       bool _ready;
+       bool _autoupdate;
+       HSQOBJECT _serializefunc;
+       SQCharVec _scratchstring;
+
+};
+
+#endif //_SQ_DBGSERVER_H_
index b58a41d..c5243fa 100644 (file)
-/*\r
-       see copyright notice in sqrdbg.h\r
-*/\r
-#include <squirrel.h>\r
-#include "sqrdbg.h"\r
-#include "sqdbgserver.h"\r
-int debug_hook(HSQUIRRELVM v);\r
-int error_handler(HSQUIRRELVM v);\r
-\r
-#include "serialize_state.inl"\r
-\r
-HSQREMOTEDBG sq_rdbg_init(HSQUIRRELVM v,unsigned short port,SQBool autoupdate)\r
-{\r
-       sockaddr_in bindaddr;\r
-#ifdef _WIN32\r
-       WSADATA wsadata;        \r
-       if (WSAStartup (MAKEWORD(1,1), &wsadata) != 0){\r
-               return NULL;\r
-       }       \r
-#endif \r
-        \r
-       SQDbgServer *rdbg = new SQDbgServer(v);\r
-       rdbg->_autoupdate = autoupdate?true:false;\r
-       rdbg->_accept = socket(AF_INET,SOCK_STREAM,0);\r
-       bindaddr.sin_family = AF_INET;\r
-       bindaddr.sin_port = htons(port);\r
-       bindaddr.sin_addr.s_addr = htonl (INADDR_ANY);\r
-       if(bind(rdbg->_accept,(sockaddr*)&bindaddr,sizeof(bindaddr))==SOCKET_ERROR){\r
-               delete rdbg;\r
-               sq_throwerror(v,_SC("failed to bind the socket"));\r
-               return NULL;\r
-       }\r
-       if(!rdbg->Init()) {\r
-               delete rdbg;\r
-               sq_throwerror(v,_SC("failed to initialize the debugger"));\r
-               return NULL;\r
-       }\r
-       \r
-    return rdbg;\r
-}\r
-\r
-SQRESULT sq_rdbg_waitforconnections(HSQREMOTEDBG rdbg)\r
-{\r
-       if(SQ_FAILED(sq_compilebuffer(rdbg->_v,serialize_state_nut,(SQInteger)scstrlen(serialize_state_nut),_SC("SERIALIZE_STATE"),SQFalse))) {\r
-               sq_throwerror(rdbg->_v,_SC("error compiling the serialization function"));\r
-       }\r
-       sq_getstackobj(rdbg->_v,-1,&rdbg->_serializefunc);\r
-       sq_addref(rdbg->_v,&rdbg->_serializefunc);\r
-       sq_pop(rdbg->_v,1);\r
-\r
-       sockaddr_in cliaddr;\r
-       socklen_t addrlen=sizeof(cliaddr);\r
-       if(listen(rdbg->_accept,0)==SOCKET_ERROR)\r
-               return sq_throwerror(rdbg->_v,_SC("error on listen(socket)"));\r
-       rdbg->_endpoint = accept(rdbg->_accept,(sockaddr*)&cliaddr,&addrlen);\r
-       //do not accept any other connection\r
-       sqdbg_closesocket(rdbg->_accept);\r
-       rdbg->_accept = INVALID_SOCKET;\r
-       if(rdbg->_endpoint==INVALID_SOCKET){\r
-               return sq_throwerror(rdbg->_v,_SC("error accept(socket)"));\r
-       }\r
-       while(!rdbg->_ready){\r
-               sq_rdbg_update(rdbg);\r
-       }\r
-       return SQ_OK;\r
-}\r
-\r
-SQRESULT sq_rdbg_update(HSQREMOTEDBG rdbg)\r
-{\r
-       TIMEVAL time;\r
-       time.tv_sec=0;\r
-       time.tv_usec=0;\r
-       fd_set read_flags;\r
-    FD_ZERO(&read_flags);\r
-       FD_SET(rdbg->_endpoint, &read_flags);\r
-       select(FD_SETSIZE, &read_flags, NULL, NULL, &time);\r
-\r
-       if(FD_ISSET(rdbg->_endpoint,&read_flags)){\r
-               char temp[1024];\r
-               int size=0;\r
-               char c,prev=0;\r
-               memset(&temp,0,sizeof(temp));\r
-               int res;\r
-               FD_CLR(rdbg->_endpoint, &read_flags);\r
-               while((res = recv(rdbg->_endpoint,&c,1,0))>0){\r
-                       \r
-                       if(c=='\n')break;\r
-                       if(c!='\r'){\r
-                               temp[size]=c;\r
-                               prev=c;\r
-                               size++;\r
-                       }\r
-               }\r
-               switch(res){\r
-               case 0:\r
-                       return sq_throwerror(rdbg->_v,_SC("disconnected"));\r
-               case SOCKET_ERROR:\r
-                       return sq_throwerror(rdbg->_v,_SC("socket error"));\r
-        }\r
-               \r
-               temp[size]=0;\r
-               temp[size+1]=0;\r
-               rdbg->ParseMsg(temp);\r
-       }\r
-       return SQ_OK;\r
-}\r
-\r
-int debug_hook(HSQUIRRELVM v)\r
-{\r
-       SQUserPointer up;\r
-       int event_type,line;\r
-       const SQChar *src,*func;\r
-       sq_getinteger(v,2,&event_type);\r
-       sq_getstring(v,3,&src);\r
-       sq_getinteger(v,4,&line);\r
-       sq_getstring(v,5,&func);\r
-       sq_getuserpointer(v,-1,&up);\r
-       HSQREMOTEDBG rdbg = (HSQREMOTEDBG)up;\r
-       rdbg->Hook(event_type,line,src,func);\r
-       if(rdbg->_autoupdate) {\r
-               if(SQ_FAILED(sq_rdbg_update(rdbg)))\r
-                       return sq_throwerror(v,_SC("socket failed"));\r
-       }\r
-       return 0;\r
-}\r
-\r
-int error_handler(HSQUIRRELVM v)\r
-{\r
-       SQUserPointer up;\r
-       const SQChar *sErr=NULL;\r
-       const SQChar *fn=_SC("unknown");\r
-       const SQChar *src=_SC("unknown");\r
-       int line=-1;\r
-       SQStackInfos si;\r
-       sq_getuserpointer(v,-1,&up);\r
-       HSQREMOTEDBG rdbg=(HSQREMOTEDBG)up;\r
-       if(SQ_SUCCEEDED(sq_stackinfos(v,1,&si)))\r
-       {\r
-               if(si.funcname)fn=si.funcname;\r
-               if(si.source)src=si.source;\r
-               line=si.line;\r
-               scprintf(_SC("*FUNCTION [%s] %s line [%d]\n"),fn,src,si.line);\r
-       }\r
-       if(sq_gettop(v)>=1){\r
-               if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr)))       {\r
-                       scprintf(_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr);\r
-                       rdbg->Break(si.line,src,_SC("error"),sErr);\r
-               }\r
-               else{\r
-                       scprintf(_SC("\nAN ERROR HAS OCCURED [unknown]\n"));\r
-                       rdbg->Break(si.line,src,_SC("error"),_SC("unknown"));\r
-               }\r
-       }\r
-       rdbg->BreakExecution();\r
-       return 0;\r
-}\r
-\r
-\r
-SQRESULT sq_rdbg_shutdown(HSQREMOTEDBG rdbg)\r
-{\r
-       delete rdbg;\r
-#ifdef _WIN32\r
-       WSACleanup();\r
-#endif\r
-       return SQ_OK;\r
-}\r
+/*
+       see copyright notice in sqrdbg.h
+*/
+#include <squirrel.h>
+#include "sqrdbg.h"
+#include "sqdbgserver.h"
+int debug_hook(HSQUIRRELVM v);
+int error_handler(HSQUIRRELVM v);
+
+#include "serialize_state.inl"
+
+HSQREMOTEDBG sq_rdbg_init(HSQUIRRELVM v,unsigned short port,SQBool autoupdate)
+{
+       sockaddr_in bindaddr;
+#ifdef _WIN32
+       WSADATA wsadata;
+       if (WSAStartup (MAKEWORD(1,1), &wsadata) != 0){
+               return NULL;
+       }
+#endif
+
+       SQDbgServer *rdbg = new SQDbgServer(v);
+       rdbg->_autoupdate = autoupdate?true:false;
+       rdbg->_accept = socket(AF_INET,SOCK_STREAM,0);
+       bindaddr.sin_family = AF_INET;
+       bindaddr.sin_port = htons(port);
+       bindaddr.sin_addr.s_addr = htonl (INADDR_ANY);
+       if(bind(rdbg->_accept,(sockaddr*)&bindaddr,sizeof(bindaddr))==SOCKET_ERROR){
+               delete rdbg;
+               sq_throwerror(v,_SC("failed to bind the socket"));
+               return NULL;
+       }
+       if(!rdbg->Init()) {
+               delete rdbg;
+               sq_throwerror(v,_SC("failed to initialize the debugger"));
+               return NULL;
+       }
+
+    return rdbg;
+}
+
+SQRESULT sq_rdbg_waitforconnections(HSQREMOTEDBG rdbg)
+{
+       if(SQ_FAILED(sq_compilebuffer(rdbg->_v,serialize_state_nut,(SQInteger)scstrlen(serialize_state_nut),_SC("SERIALIZE_STATE"),SQFalse))) {
+               sq_throwerror(rdbg->_v,_SC("error compiling the serialization function"));
+       }
+       sq_getstackobj(rdbg->_v,-1,&rdbg->_serializefunc);
+       sq_addref(rdbg->_v,&rdbg->_serializefunc);
+       sq_pop(rdbg->_v,1);
+
+       sockaddr_in cliaddr;
+       socklen_t addrlen=sizeof(cliaddr);
+       if(listen(rdbg->_accept,0)==SOCKET_ERROR)
+               return sq_throwerror(rdbg->_v,_SC("error on listen(socket)"));
+       rdbg->_endpoint = accept(rdbg->_accept,(sockaddr*)&cliaddr,&addrlen);
+       //do not accept any other connection
+       sqdbg_closesocket(rdbg->_accept);
+       rdbg->_accept = INVALID_SOCKET;
+       if(rdbg->_endpoint==INVALID_SOCKET){
+               return sq_throwerror(rdbg->_v,_SC("error accept(socket)"));
+       }
+       while(!rdbg->_ready){
+               sq_rdbg_update(rdbg);
+       }
+       return SQ_OK;
+}
+
+SQRESULT sq_rdbg_update(HSQREMOTEDBG rdbg)
+{
+       TIMEVAL time;
+       time.tv_sec=0;
+       time.tv_usec=0;
+       fd_set read_flags;
+    FD_ZERO(&read_flags);
+       FD_SET(rdbg->_endpoint, &read_flags);
+       select(FD_SETSIZE, &read_flags, NULL, NULL, &time);
+
+       if(FD_ISSET(rdbg->_endpoint,&read_flags)){
+               char temp[1024];
+               int size=0;
+               char c,prev=0;
+               memset(&temp,0,sizeof(temp));
+               int res;
+               FD_CLR(rdbg->_endpoint, &read_flags);
+               while((res = recv(rdbg->_endpoint,&c,1,0))>0){
+
+                       if(c=='\n')break;
+                       if(c!='\r'){
+                               temp[size]=c;
+                               prev=c;
+                               size++;
+                       }
+               }
+               switch(res){
+               case 0:
+                       return sq_throwerror(rdbg->_v,_SC("disconnected"));
+               case SOCKET_ERROR:
+                       return sq_throwerror(rdbg->_v,_SC("socket error"));
+        }
+
+               temp[size]=0;
+               temp[size+1]=0;
+               rdbg->ParseMsg(temp);
+       }
+       return SQ_OK;
+}
+
+int debug_hook(HSQUIRRELVM v)
+{
+       SQUserPointer up;
+       int event_type,line;
+       const SQChar *src,*func;
+       sq_getinteger(v,2,&event_type);
+       sq_getstring(v,3,&src);
+       sq_getinteger(v,4,&line);
+       sq_getstring(v,5,&func);
+       sq_getuserpointer(v,-1,&up);
+       HSQREMOTEDBG rdbg = (HSQREMOTEDBG)up;
+       rdbg->Hook(event_type,line,src,func);
+       if(rdbg->_autoupdate) {
+               if(SQ_FAILED(sq_rdbg_update(rdbg)))
+                       return sq_throwerror(v,_SC("socket failed"));
+       }
+       return 0;
+}
+
+int error_handler(HSQUIRRELVM v)
+{
+       SQUserPointer up;
+       const SQChar *sErr=NULL;
+       const SQChar *fn=_SC("unknown");
+       const SQChar *src=_SC("unknown");
+       int line=-1;
+       SQStackInfos si;
+       sq_getuserpointer(v,-1,&up);
+       HSQREMOTEDBG rdbg=(HSQREMOTEDBG)up;
+       if(SQ_SUCCEEDED(sq_stackinfos(v,1,&si)))
+       {
+               if(si.funcname)fn=si.funcname;
+               if(si.source)src=si.source;
+               line=si.line;
+               scprintf(_SC("*FUNCTION [%s] %s line [%d]\n"),fn,src,si.line);
+       }
+       if(sq_gettop(v)>=1){
+               if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr)))       {
+                       scprintf(_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr);
+                       rdbg->Break(si.line,src,_SC("error"),sErr);
+               }
+               else{
+                       scprintf(_SC("\nAN ERROR HAS OCCURED [unknown]\n"));
+                       rdbg->Break(si.line,src,_SC("error"),_SC("unknown"));
+               }
+       }
+       rdbg->BreakExecution();
+       return 0;
+}
+
+
+SQRESULT sq_rdbg_shutdown(HSQREMOTEDBG rdbg)
+{
+       delete rdbg;
+#ifdef _WIN32
+       WSACleanup();
+#endif
+       return SQ_OK;
+}
index 3d15e74..6302790 100644 (file)
@@ -1,51 +1,50 @@
-/*\r
-Copyright (c) 2003-2005 Alberto Demichelis\r
-\r
-This software is provided 'as-is', without any \r
-express or implied warranty. In no event will the \r
-authors be held liable for any damages arising from \r
-the use of this software.\r
-\r
-Permission is granted to anyone to use this software \r
-for any purpose, including commercial applications, \r
-and to alter it and redistribute it freely, subject \r
-to the following restrictions:\r
-\r
-               1. The origin of this software must not be \r
-               misrepresented; you must not claim that \r
-               you wrote the original software. If you \r
-               use this software in a product, an \r
-               acknowledgment in the product \r
-               documentation would be appreciated but is \r
-               not required.\r
-\r
-               2. Altered source versions must be plainly \r
-               marked as such, and must not be \r
-               misrepresented as being the original \r
-               software.\r
-\r
-               3. This notice may not be removed or \r
-               altered from any source distribution.\r
-\r
-*/\r
-#ifndef _SQ_RDBG_H_\r
-#define _SQ_RDBG_H_\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-struct SQDbgServer;\r
-typedef SQDbgServer* HSQREMOTEDBG;\r
-\r
-HSQREMOTEDBG sq_rdbg_init(HSQUIRRELVM v,unsigned short port,SQBool autoupdate);\r
-SQRESULT sq_rdbg_waitforconnections(HSQREMOTEDBG rdbg);\r
-SQRESULT sq_rdbg_shutdown(HSQREMOTEDBG rdbg);\r
-SQRESULT sq_rdbg_update(HSQREMOTEDBG rdbg);\r
\r
-#ifdef __cplusplus\r
-} /*extern "C"*/\r
-#endif\r
-\r
-#endif //_SQ_RDBG_H_\r
-\r
+/*
+Copyright (c) 2003-2005 Alberto Demichelis
+
+This software is provided 'as-is', without any
+express or implied warranty. In no event will the
+authors be held liable for any damages arising from
+the use of this software.
+
+Permission is granted to anyone to use this software
+for any purpose, including commercial applications,
+and to alter it and redistribute it freely, subject
+to the following restrictions:
+
+               1. The origin of this software must not be
+               misrepresented; you must not claim that
+               you wrote the original software. If you
+               use this software in a product, an
+               acknowledgment in the product
+               documentation would be appreciated but is
+               not required.
+
+               2. Altered source versions must be plainly
+               marked as such, and must not be
+               misrepresented as being the original
+               software.
+
+               3. This notice may not be removed or
+               altered from any source distribution.
+
+*/
+#ifndef _SQ_RDBG_H_
+#define _SQ_RDBG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct SQDbgServer;
+typedef SQDbgServer* HSQREMOTEDBG;
+
+HSQREMOTEDBG sq_rdbg_init(HSQUIRRELVM v,unsigned short port,SQBool autoupdate);
+SQRESULT sq_rdbg_waitforconnections(HSQREMOTEDBG rdbg);
+SQRESULT sq_rdbg_shutdown(HSQREMOTEDBG rdbg);
+SQRESULT sq_rdbg_update(HSQREMOTEDBG rdbg);
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif //_SQ_RDBG_H_
index ddfac08..da014f5 100644 (file)
-/* see copyright notice in squirrel.h */\r
-#include <squirrel.h>\r
-#include <sqstdaux.h>\r
-#include <assert.h>\r
-\r
-void sqstd_printcallstack(HSQUIRRELVM v)\r
-{\r
-       SQPRINTFUNCTION pf = sq_getprintfunc(v);\r
-       if(pf) {\r
-               SQStackInfos si;\r
-               SQInteger i;\r
-               SQFloat f;\r
-               const SQChar *s;\r
-               SQInteger level=1; //1 is to skip this function that is level 0\r
-               const SQChar *name=0; \r
-               SQInteger seq=0;\r
-               pf(v,_SC("\nCALLSTACK\n"));\r
-               while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si)))\r
-               {\r
-                       const SQChar *fn=_SC("unknown");\r
-                       const SQChar *src=_SC("unknown");\r
-                       if(si.funcname)fn=si.funcname;\r
-                       if(si.source)src=si.source;\r
-                       pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line);\r
-                       level++;\r
-               }\r
-               level=0;\r
-               pf(v,_SC("\nLOCALS\n"));\r
-\r
-               for(level=0;level<10;level++){\r
-                       seq=0;\r
-                       while((name = sq_getlocal(v,level,seq)))\r
-                       {\r
-                               seq++;\r
-                               switch(sq_gettype(v,-1))\r
-                               {\r
-                               case OT_NULL:\r
-                                       pf(v,_SC("[%s] NULL\n"),name);\r
-                                       break;\r
-                               case OT_INTEGER:\r
-                                       sq_getinteger(v,-1,&i);\r
-                                       pf(v,_SC("[%s] %d\n"),name,i);\r
-                                       break;\r
-                               case OT_FLOAT:\r
-                                       sq_getfloat(v,-1,&f);\r
-                                       pf(v,_SC("[%s] %.14g\n"),name,f);\r
-                                       break;\r
-                               case OT_USERPOINTER:\r
-                                       pf(v,_SC("[%s] USERPOINTER\n"),name);\r
-                                       break;\r
-                               case OT_STRING:\r
-                                       sq_getstring(v,-1,&s);\r
-                                       pf(v,_SC("[%s] \"%s\"\n"),name,s);\r
-                                       break;\r
-                               case OT_TABLE:\r
-                                       pf(v,_SC("[%s] TABLE\n"),name);\r
-                                       break;\r
-                               case OT_ARRAY:\r
-                                       pf(v,_SC("[%s] ARRAY\n"),name);\r
-                                       break;\r
-                               case OT_CLOSURE:\r
-                                       pf(v,_SC("[%s] CLOSURE\n"),name);\r
-                                       break;\r
-                               case OT_NATIVECLOSURE:\r
-                                       pf(v,_SC("[%s] NATIVECLOSURE\n"),name);\r
-                                       break;\r
-                               case OT_GENERATOR:\r
-                                       pf(v,_SC("[%s] NATIVECLOSURE\n"),name);\r
-                                       break;\r
-                               case OT_USERDATA:\r
-                                       pf(v,_SC("[%s] USERDATA\n"),name);\r
-                                       break;\r
-                               case OT_THREAD:\r
-                                       pf(v,_SC("[%s] THREAD\n"),name);\r
-                                       break;\r
-                               case OT_CLASS:\r
-                                       pf(v,_SC("[%s] CLASS\n"),name);\r
-                                       break;\r
-                               case OT_INSTANCE:\r
-                                       pf(v,_SC("[%s] INSTANCE\n"),name);\r
-                                       break;\r
-                               case OT_WEAKREF:\r
-                                       pf(v,_SC("[%s] INSTANCE\n"),name);\r
-                                       break;\r
-                               case OT_BOOL:{\r
-                                       sq_getinteger(v,-1,&i);\r
-                                       pf(v,_SC("[%s] %s\n"),name,i?_SC("true"):_SC("false"));\r
-                                                        }\r
-                                       break;\r
-                               default: assert(0); break;\r
-                               }\r
-                               sq_pop(v,1);\r
-                       }\r
-               }\r
-       }\r
-}\r
-\r
-static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v)\r
-{\r
-       SQPRINTFUNCTION pf = sq_getprintfunc(v);\r
-       if(pf) {\r
-               const SQChar *sErr = 0;\r
-               if(sq_gettop(v)>=1) {\r
-                       if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr)))       {\r
-                               pf(v,_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr);\r
-                       }\r
-                       else{\r
-                               pf(v,_SC("\nAN ERROR HAS OCCURED [unknown]\n"));\r
-                       }\r
-                       sqstd_printcallstack(v);\r
-               }\r
-       }\r
-       return 0;\r
-}\r
-\r
-void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column)\r
-{\r
-       SQPRINTFUNCTION pf = sq_getprintfunc(v);\r
-       if(pf) {\r
-               pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr);\r
-       }\r
-}\r
-\r
-void sqstd_seterrorhandlers(HSQUIRRELVM v)\r
-{\r
-       sq_setcompilererrorhandler(v,_sqstd_compiler_error);\r
-       sq_newclosure(v,_sqstd_aux_printerror,0);\r
-       sq_seterrorhandler(v);\r
-}\r
+/* see copyright notice in squirrel.h */
+#include <squirrel.h>
+#include <sqstdaux.h>
+#include <assert.h>
+
+void sqstd_printcallstack(HSQUIRRELVM v)
+{
+       SQPRINTFUNCTION pf = sq_getprintfunc(v);
+       if(pf) {
+               SQStackInfos si;
+               SQInteger i;
+               SQFloat f;
+               const SQChar *s;
+               SQInteger level=1; //1 is to skip this function that is level 0
+               const SQChar *name=0;
+               SQInteger seq=0;
+               pf(v,_SC("\nCALLSTACK\n"));
+               while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si)))
+               {
+                       const SQChar *fn=_SC("unknown");
+                       const SQChar *src=_SC("unknown");
+                       if(si.funcname)fn=si.funcname;
+                       if(si.source)src=si.source;
+                       pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line);
+                       level++;
+               }
+               level=0;
+               pf(v,_SC("\nLOCALS\n"));
+
+               for(level=0;level<10;level++){
+                       seq=0;
+                       while((name = sq_getlocal(v,level,seq)))
+                       {
+                               seq++;
+                               switch(sq_gettype(v,-1))
+                               {
+                               case OT_NULL:
+                                       pf(v,_SC("[%s] NULL\n"),name);
+                                       break;
+                               case OT_INTEGER:
+                                       sq_getinteger(v,-1,&i);
+                                       pf(v,_SC("[%s] %d\n"),name,i);
+                                       break;
+                               case OT_FLOAT:
+                                       sq_getfloat(v,-1,&f);
+                                       pf(v,_SC("[%s] %.14g\n"),name,f);
+                                       break;
+                               case OT_USERPOINTER:
+                                       pf(v,_SC("[%s] USERPOINTER\n"),name);
+                                       break;
+                               case OT_STRING:
+                                       sq_getstring(v,-1,&s);
+                                       pf(v,_SC("[%s] \"%s\"\n"),name,s);
+                                       break;
+                               case OT_TABLE:
+                                       pf(v,_SC("[%s] TABLE\n"),name);
+                                       break;
+                               case OT_ARRAY:
+                                       pf(v,_SC("[%s] ARRAY\n"),name);
+                                       break;
+                               case OT_CLOSURE:
+                                       pf(v,_SC("[%s] CLOSURE\n"),name);
+                                       break;
+                               case OT_NATIVECLOSURE:
+                                       pf(v,_SC("[%s] NATIVECLOSURE\n"),name);
+                                       break;
+                               case OT_GENERATOR:
+                                       pf(v,_SC("[%s] NATIVECLOSURE\n"),name);
+                                       break;
+                               case OT_USERDATA:
+                                       pf(v,_SC("[%s] USERDATA\n"),name);
+                                       break;
+                               case OT_THREAD:
+                                       pf(v,_SC("[%s] THREAD\n"),name);
+                                       break;
+                               case OT_CLASS:
+                                       pf(v,_SC("[%s] CLASS\n"),name);
+                                       break;
+                               case OT_INSTANCE:
+                                       pf(v,_SC("[%s] INSTANCE\n"),name);
+                                       break;
+                               case OT_WEAKREF:
+                                       pf(v,_SC("[%s] INSTANCE\n"),name);
+                                       break;
+                               case OT_BOOL:{
+                                       sq_getinteger(v,-1,&i);
+                                       pf(v,_SC("[%s] %s\n"),name,i?_SC("true"):_SC("false"));
+                                                        }
+                                       break;
+                               default: assert(0); break;
+                               }
+                               sq_pop(v,1);
+                       }
+               }
+       }
+}
+
+static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v)
+{
+       SQPRINTFUNCTION pf = sq_getprintfunc(v);
+       if(pf) {
+               const SQChar *sErr = 0;
+               if(sq_gettop(v)>=1) {
+                       if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr)))       {
+                               pf(v,_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr);
+                       }
+                       else{
+                               pf(v,_SC("\nAN ERROR HAS OCCURED [unknown]\n"));
+                       }
+                       sqstd_printcallstack(v);
+               }
+       }
+       return 0;
+}
+
+void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column)
+{
+       SQPRINTFUNCTION pf = sq_getprintfunc(v);
+       if(pf) {
+               pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr);
+       }
+}
+
+void sqstd_seterrorhandlers(HSQUIRRELVM v)
+{
+       sq_setcompilererrorhandler(v,_sqstd_compiler_error);
+       sq_newclosure(v,_sqstd_aux_printerror,0);
+       sq_seterrorhandler(v);
+}
index 5036db1..ded3696 100644 (file)
-/* see copyright notice in squirrel.h */\r
-#include <new>\r
-#include <squirrel.h>\r
-#include <sqstdio.h>\r
-#include <string.h>\r
-#include <sqstdblob.h>\r
-#include "sqstdstream.h"\r
-#include "sqstdblobimpl.h"\r
-\r
-#define SQSTD_BLOB_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000002)\r
-\r
-//Blob\r
-\r
-\r
-#define SETUP_BLOB(v) \\r
-       SQBlob *self = NULL; \\r
-       { if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) \\r
-               return SQ_ERROR; }\r
-\r
-\r
-static SQInteger _blob_resize(HSQUIRRELVM v)\r
-{\r
-       SETUP_BLOB(v);\r
-       SQInteger size;\r
-       sq_getinteger(v,2,&size);\r
-       if(!self->Resize(size))\r
-               return sq_throwerror(v,_SC("resize failed"));\r
-       return 0;\r
-}\r
-\r
-static void __swap_dword(unsigned int *n)\r
-{\r
-       *n=(unsigned int)(((*n&0xFF000000)>>24)  |\r
-                       ((*n&0x00FF0000)>>8)  |\r
-                       ((*n&0x0000FF00)<<8)  |\r
-                       ((*n&0x000000FF)<<24));\r
-}\r
-\r
-static void __swap_word(unsigned short *n)\r
-{\r
-       *n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00);\r
-}\r
-\r
-static SQInteger _blob_swap4(HSQUIRRELVM v)\r
-{\r
-       SETUP_BLOB(v);\r
-       SQInteger num=(self->Len()-(self->Len()%4))>>2;\r
-       unsigned int *t=(unsigned int *)self->GetBuf();\r
-       for(SQInteger i = 0; i < num; i++) {\r
-               __swap_dword(&t[i]);\r
-       }\r
-       return 0;\r
-}\r
-\r
-static SQInteger _blob_swap2(HSQUIRRELVM v)\r
-{\r
-       SETUP_BLOB(v);\r
-       SQInteger num=(self->Len()-(self->Len()%2))>>1;\r
-       unsigned short *t = (unsigned short *)self->GetBuf();\r
-       for(SQInteger i = 0; i < num; i++) {\r
-               __swap_word(&t[i]);\r
-       }\r
-       return 0;\r
-}\r
-\r
-static SQInteger _blob__set(HSQUIRRELVM v)\r
-{\r
-       SETUP_BLOB(v);\r
-       SQInteger idx,val;\r
-       sq_getinteger(v,2,&idx);\r
-       sq_getinteger(v,3,&val);\r
-       if(idx < 0 || idx >= self->Len())\r
-               return sq_throwerror(v,_SC("index out of range"));\r
-       ((unsigned char *)self->GetBuf())[idx] = (unsigned char) val;\r
-       sq_push(v,3);\r
-       return 1;\r
-}\r
-\r
-static SQInteger _blob__get(HSQUIRRELVM v)\r
-{\r
-       SETUP_BLOB(v);\r
-       SQInteger idx;\r
-       sq_getinteger(v,2,&idx);\r
-       if(idx < 0 || idx >= self->Len())\r
-               return sq_throwerror(v,_SC("index out of range"));\r
-       sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]);\r
-       return 1;\r
-}\r
-\r
-static SQInteger _blob__nexti(HSQUIRRELVM v)\r
-{\r
-       SETUP_BLOB(v);\r
-       if(sq_gettype(v,2) == OT_NULL) {\r
-               sq_pushinteger(v, 0);\r
-               return 1;\r
-       }\r
-       SQInteger idx;\r
-       if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) {\r
-               if(idx+1 < self->Len()) {\r
-                       sq_pushinteger(v, idx+1);\r
-                       return 1;\r
-               }\r
-               sq_pushnull(v);\r
-               return 1;\r
-       }\r
-       return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type"));\r
-}\r
-\r
-static SQInteger _blob__typeof(HSQUIRRELVM v)\r
-{\r
-       sq_pushstring(v,_SC("blob"),-1);\r
-       return 1;\r
-}\r
-\r
-static SQInteger _blob_releasehook(SQUserPointer p, SQInteger size)\r
-{\r
-       SQBlob *self = (SQBlob*)p;\r
-       delete self;\r
-       return 1;\r
-}\r
-\r
-static SQInteger _blob_constructor(HSQUIRRELVM v)\r
-{\r
-       SQInteger nparam = sq_gettop(v);\r
-       SQInteger size = 0;\r
-       if(nparam == 2) {\r
-               sq_getinteger(v, 2, &size);\r
-       }\r
-       if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size"));\r
-       SQBlob *b = new SQBlob(size);\r
-       if(SQ_FAILED(sq_setinstanceup(v,1,b))) {\r
-               delete b;\r
-               return sq_throwerror(v, _SC("cannot create blob with negative size"));\r
-       }\r
-       sq_setreleasehook(v,1,_blob_releasehook);\r
-       return 0;\r
-}\r
-\r
-#define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck}\r
-static SQRegFunction _blob_methods[] = {\r
-       _DECL_BLOB_FUNC(constructor,-1,_SC("xn")),\r
-       _DECL_BLOB_FUNC(resize,2,_SC("xn")),\r
-       _DECL_BLOB_FUNC(swap2,1,_SC("x")),\r
-       _DECL_BLOB_FUNC(swap4,1,_SC("x")),\r
-       _DECL_BLOB_FUNC(_set,3,_SC("xnn")),\r
-       _DECL_BLOB_FUNC(_get,2,_SC("xn")),\r
-       _DECL_BLOB_FUNC(_typeof,1,_SC("x")),\r
-       _DECL_BLOB_FUNC(_nexti,2,_SC("x")),\r
-       {0,0,0,0}\r
-};\r
-\r
-\r
-\r
-//GLOBAL FUNCTIONS\r
-\r
-static SQInteger _g_blob_casti2f(HSQUIRRELVM v)\r
-{\r
-       SQInteger i;\r
-       sq_getinteger(v,2,&i);\r
-       sq_pushfloat(v,*((SQFloat *)&i));\r
-       return 1;\r
-}\r
-\r
-static SQInteger _g_blob_castf2i(HSQUIRRELVM v)\r
-{\r
-       SQFloat f;\r
-       sq_getfloat(v,2,&f);\r
-       sq_pushinteger(v,*((SQInteger *)&f));\r
-       return 1;\r
-}\r
-\r
-static SQInteger _g_blob_swap2(HSQUIRRELVM v)\r
-{\r
-       SQInteger i;\r
-       sq_getinteger(v,2,&i);\r
-       short s=(short)i;\r
-       sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF));\r
-       return 1;\r
-}\r
-\r
-static SQInteger _g_blob_swap4(HSQUIRRELVM v)\r
-{\r
-       SQInteger i;\r
-       sq_getinteger(v,2,&i);\r
-       unsigned int t4 = (unsigned int)i;\r
-       __swap_dword(&t4);\r
-       sq_pushinteger(v,(SQInteger)t4);\r
-       return 1;\r
-}\r
-\r
-static SQInteger _g_blob_swapfloat(HSQUIRRELVM v)\r
-{\r
-       SQFloat f;\r
-       sq_getfloat(v,2,&f);\r
-       __swap_dword((unsigned int *)&f);\r
-       sq_pushfloat(v,f);\r
-       return 1;\r
-}\r
-\r
-#define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck}\r
-static SQRegFunction bloblib_funcs[]={\r
-       _DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")),\r
-       _DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")),\r
-       _DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")),\r
-       _DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")),\r
-       _DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")),\r
-       {0,0}\r
-};\r
-\r
-SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr)\r
-{\r
-       SQBlob *blob;\r
-       if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))\r
-               return -1;\r
-       *ptr = blob->GetBuf();\r
-       return SQ_OK;\r
-}\r
-\r
-SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx)\r
-{\r
-       SQBlob *blob;\r
-       if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))\r
-               return -1;\r
-       return blob->Len();\r
-}\r
-\r
-SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size)\r
-{\r
-       SQInteger top = sq_gettop(v);\r
-       sq_pushregistrytable(v);\r
-       sq_pushstring(v,_SC("std_blob"),-1);\r
-       if(SQ_SUCCEEDED(sq_get(v,-2))) {\r
-               sq_remove(v,-2); //removes the registry\r
-               sq_push(v,1); // push the this\r
-               sq_pushinteger(v,size); //size\r
-               SQBlob *blob = NULL;\r
-               if(SQ_SUCCEEDED(sq_call(v,2,SQTrue,SQFalse))\r
-                       && SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) {\r
-                       sq_remove(v,-2);\r
-                       sq_remove(v,-2);\r
-                       return blob->GetBuf();\r
-               }\r
-       }\r
-       sq_settop(v,top);\r
-       return NULL;\r
-}\r
-\r
-SQRESULT sqstd_register_bloblib(HSQUIRRELVM v)\r
-{\r
-       return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs);\r
-}\r
-\r
+/* see copyright notice in squirrel.h */
+#include <new>
+#include <squirrel.h>
+#include <sqstdio.h>
+#include <string.h>
+#include <sqstdblob.h>
+#include "sqstdstream.h"
+#include "sqstdblobimpl.h"
+
+#define SQSTD_BLOB_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000002)
+
+//Blob
+
+
+#define SETUP_BLOB(v) \
+       SQBlob *self = NULL; \
+       { if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) \
+               return SQ_ERROR; }
+
+
+static SQInteger _blob_resize(HSQUIRRELVM v)
+{
+       SETUP_BLOB(v);
+       SQInteger size;
+       sq_getinteger(v,2,&size);
+       if(!self->Resize(size))
+               return sq_throwerror(v,_SC("resize failed"));
+       return 0;
+}
+
+static void __swap_dword(unsigned int *n)
+{
+       *n=(unsigned int)(((*n&0xFF000000)>>24)  |
+                       ((*n&0x00FF0000)>>8)  |
+                       ((*n&0x0000FF00)<<8)  |
+                       ((*n&0x000000FF)<<24));
+}
+
+static void __swap_word(unsigned short *n)
+{
+       *n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00);
+}
+
+static SQInteger _blob_swap4(HSQUIRRELVM v)
+{
+       SETUP_BLOB(v);
+       SQInteger num=(self->Len()-(self->Len()%4))>>2;
+       unsigned int *t=(unsigned int *)self->GetBuf();
+       for(SQInteger i = 0; i < num; i++) {
+               __swap_dword(&t[i]);
+       }
+       return 0;
+}
+
+static SQInteger _blob_swap2(HSQUIRRELVM v)
+{
+       SETUP_BLOB(v);
+       SQInteger num=(self->Len()-(self->Len()%2))>>1;
+       unsigned short *t = (unsigned short *)self->GetBuf();
+       for(SQInteger i = 0; i < num; i++) {
+               __swap_word(&t[i]);
+       }
+       return 0;
+}
+
+static SQInteger _blob__set(HSQUIRRELVM v)
+{
+       SETUP_BLOB(v);
+       SQInteger idx,val;
+       sq_getinteger(v,2,&idx);
+       sq_getinteger(v,3,&val);
+       if(idx < 0 || idx >= self->Len())
+               return sq_throwerror(v,_SC("index out of range"));
+       ((unsigned char *)self->GetBuf())[idx] = (unsigned char) val;
+       sq_push(v,3);
+       return 1;
+}
+
+static SQInteger _blob__get(HSQUIRRELVM v)
+{
+       SETUP_BLOB(v);
+       SQInteger idx;
+       sq_getinteger(v,2,&idx);
+       if(idx < 0 || idx >= self->Len())
+               return sq_throwerror(v,_SC("index out of range"));
+       sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]);
+       return 1;
+}
+
+static SQInteger _blob__nexti(HSQUIRRELVM v)
+{
+       SETUP_BLOB(v);
+       if(sq_gettype(v,2) == OT_NULL) {
+               sq_pushinteger(v, 0);
+               return 1;
+       }
+       SQInteger idx;
+       if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) {
+               if(idx+1 < self->Len()) {
+                       sq_pushinteger(v, idx+1);
+                       return 1;
+               }
+               sq_pushnull(v);
+               return 1;
+       }
+       return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type"));
+}
+
+static SQInteger _blob__typeof(HSQUIRRELVM v)
+{
+       sq_pushstring(v,_SC("blob"),-1);
+       return 1;
+}
+
+static SQInteger _blob_releasehook(SQUserPointer p, SQInteger size)
+{
+       SQBlob *self = (SQBlob*)p;
+       delete self;
+       return 1;
+}
+
+static SQInteger _blob_constructor(HSQUIRRELVM v)
+{
+       SQInteger nparam = sq_gettop(v);
+       SQInteger size = 0;
+       if(nparam == 2) {
+               sq_getinteger(v, 2, &size);
+       }
+       if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size"));
+       SQBlob *b = new SQBlob(size);
+       if(SQ_FAILED(sq_setinstanceup(v,1,b))) {
+               delete b;
+               return sq_throwerror(v, _SC("cannot create blob with negative size"));
+       }
+       sq_setreleasehook(v,1,_blob_releasehook);
+       return 0;
+}
+
+#define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck}
+static SQRegFunction _blob_methods[] = {
+       _DECL_BLOB_FUNC(constructor,-1,_SC("xn")),
+       _DECL_BLOB_FUNC(resize,2,_SC("xn")),
+       _DECL_BLOB_FUNC(swap2,1,_SC("x")),
+       _DECL_BLOB_FUNC(swap4,1,_SC("x")),
+       _DECL_BLOB_FUNC(_set,3,_SC("xnn")),
+       _DECL_BLOB_FUNC(_get,2,_SC("xn")),
+       _DECL_BLOB_FUNC(_typeof,1,_SC("x")),
+       _DECL_BLOB_FUNC(_nexti,2,_SC("x")),
+       {0,0,0,0}
+};
+
+
+
+//GLOBAL FUNCTIONS
+
+static SQInteger _g_blob_casti2f(HSQUIRRELVM v)
+{
+       SQInteger i;
+       sq_getinteger(v,2,&i);
+       sq_pushfloat(v,*((SQFloat *)&i));
+       return 1;
+}
+
+static SQInteger _g_blob_castf2i(HSQUIRRELVM v)
+{
+       SQFloat f;
+       sq_getfloat(v,2,&f);
+       sq_pushinteger(v,*((SQInteger *)&f));
+       return 1;
+}
+
+static SQInteger _g_blob_swap2(HSQUIRRELVM v)
+{
+       SQInteger i;
+       sq_getinteger(v,2,&i);
+       short s=(short)i;
+       sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF));
+       return 1;
+}
+
+static SQInteger _g_blob_swap4(HSQUIRRELVM v)
+{
+       SQInteger i;
+       sq_getinteger(v,2,&i);
+       unsigned int t4 = (unsigned int)i;
+       __swap_dword(&t4);
+       sq_pushinteger(v,(SQInteger)t4);
+       return 1;
+}
+
+static SQInteger _g_blob_swapfloat(HSQUIRRELVM v)
+{
+       SQFloat f;
+       sq_getfloat(v,2,&f);
+       __swap_dword((unsigned int *)&f);
+       sq_pushfloat(v,f);
+       return 1;
+}
+
+#define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck}
+static SQRegFunction bloblib_funcs[]={
+       _DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")),
+       _DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")),
+       _DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")),
+       _DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")),
+       _DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")),
+       {0,0}
+};
+
+SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr)
+{
+       SQBlob *blob;
+       if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
+               return -1;
+       *ptr = blob->GetBuf();
+       return SQ_OK;
+}
+
+SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx)
+{
+       SQBlob *blob;
+       if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
+               return -1;
+       return blob->Len();
+}
+
+SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size)
+{
+       SQInteger top = sq_gettop(v);
+       sq_pushregistrytable(v);
+       sq_pushstring(v,_SC("std_blob"),-1);
+       if(SQ_SUCCEEDED(sq_get(v,-2))) {
+               sq_remove(v,-2); //removes the registry
+               sq_push(v,1); // push the this
+               sq_pushinteger(v,size); //size
+               SQBlob *blob = NULL;
+               if(SQ_SUCCEEDED(sq_call(v,2,SQTrue,SQFalse))
+                       && SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) {
+                       sq_remove(v,-2);
+                       sq_remove(v,-2);
+                       return blob->GetBuf();
+               }
+       }
+       sq_settop(v,top);
+       return NULL;
+}
+
+SQRESULT sqstd_register_bloblib(HSQUIRRELVM v)
+{
+       return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs);
+}
index b2291b7..9f22c0a 100644 (file)
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQSTD_BLOBIMPL_H_\r
-#define _SQSTD_BLOBIMPL_H_\r
-\r
-struct SQBlob : public SQStream\r
-{\r
-       SQBlob(SQInteger size) {\r
-               _size = size;\r
-               _allocated = size;\r
-               _buf = (unsigned char *)sq_malloc(size);\r
-               memset(_buf, 0, _size);\r
-               _ptr = 0;\r
-               _owns = true;\r
-       }\r
-       virtual ~SQBlob() {\r
-               sq_free(_buf, _allocated);\r
-       }\r
-       SQInteger Write(void *buffer, SQInteger size) {\r
-               if(!CanAdvance(size)) {\r
-                       GrowBufOf(_ptr + size - _size);\r
-               }\r
-               memcpy(&_buf[_ptr], buffer, size);\r
-               _ptr += size;\r
-               return size;\r
-       }\r
-       SQInteger Read(void *buffer,SQInteger size) {\r
-               SQInteger n = size;\r
-               if(!CanAdvance(size)) {\r
-                       if((_size - _ptr) > 0)\r
-                               n = _size - _ptr;\r
-                       else return 0;\r
-               }\r
-               memcpy(buffer, &_buf[_ptr], n);\r
-               _ptr += n;\r
-               return n;\r
-       }\r
-       bool Resize(SQInteger n) {\r
-               if(!_owns) return false;\r
-               if(n != _allocated) {\r
-                       unsigned char *newbuf = (unsigned char *)sq_malloc(n);\r
-                       memset(newbuf,0,n);\r
-                       if(_size > n)\r
-                               memcpy(newbuf,_buf,n);\r
-                       else\r
-                               memcpy(newbuf,_buf,_size);\r
-                       sq_free(_buf,_allocated);\r
-                       _buf=newbuf;\r
-                       _allocated = n;\r
-                       if(_size > _allocated)\r
-                               _size = _allocated;\r
-                       if(_ptr > _allocated)\r
-                               _ptr = _allocated;\r
-               }\r
-               return true;\r
-       }\r
-       bool GrowBufOf(SQInteger n)\r
-       {\r
-               bool ret = true;\r
-               if(_size + n > _allocated) {\r
-                       if(_size + n > _size * 2)\r
-                               ret = Resize(_size + n);\r
-                       else\r
-                               ret = Resize(_size * 2);\r
-               }\r
-               _size = _size + n;\r
-               return ret;\r
-       }\r
-       bool CanAdvance(SQInteger n) {\r
-               if(_ptr+n>_size)return false;\r
-               return true;\r
-       }\r
-       SQInteger Seek(SQInteger offset, SQInteger origin) {\r
-               switch(origin) {\r
-                       case SQ_SEEK_SET:\r
-                               if(offset > _size || offset < 0) return -1;\r
-                               _ptr = offset;\r
-                               break;\r
-                       case SQ_SEEK_CUR:\r
-                               if(_ptr + offset > _size || _ptr + offset < 0) return -1;\r
-                               _ptr += offset;\r
-                               break;\r
-                       case SQ_SEEK_END:\r
-                               if(_size + offset > _size || _size + offset < 0) return -1;\r
-                               _ptr = _size + offset;\r
-                               break;\r
-                       default: return -1;\r
-               }\r
-               return 0;\r
-       }\r
-       bool IsValid() {\r
-               return _buf?true:false;\r
-       }\r
-       bool EOS() {\r
-               return _ptr == _size;\r
-       }\r
-       SQInteger Flush() { return 0; }\r
-       SQInteger Tell() { return _ptr; }\r
-       SQInteger Len() { return _size; }\r
-       SQUserPointer GetBuf(){ return _buf; }\r
-private:\r
-       SQInteger _size;\r
-       SQInteger _allocated;\r
-       SQInteger _ptr;\r
-       unsigned char *_buf;\r
-       bool _owns;\r
-};\r
-\r
-#endif //_SQSTD_BLOBIMPL_H_\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQSTD_BLOBIMPL_H_
+#define _SQSTD_BLOBIMPL_H_
+
+struct SQBlob : public SQStream
+{
+       SQBlob(SQInteger size) {
+               _size = size;
+               _allocated = size;
+               _buf = (unsigned char *)sq_malloc(size);
+               memset(_buf, 0, _size);
+               _ptr = 0;
+               _owns = true;
+       }
+       virtual ~SQBlob() {
+               sq_free(_buf, _allocated);
+       }
+       SQInteger Write(void *buffer, SQInteger size) {
+               if(!CanAdvance(size)) {
+                       GrowBufOf(_ptr + size - _size);
+               }
+               memcpy(&_buf[_ptr], buffer, size);
+               _ptr += size;
+               return size;
+       }
+       SQInteger Read(void *buffer,SQInteger size) {
+               SQInteger n = size;
+               if(!CanAdvance(size)) {
+                       if((_size - _ptr) > 0)
+                               n = _size - _ptr;
+                       else return 0;
+               }
+               memcpy(buffer, &_buf[_ptr], n);
+               _ptr += n;
+               return n;
+       }
+       bool Resize(SQInteger n) {
+               if(!_owns) return false;
+               if(n != _allocated) {
+                       unsigned char *newbuf = (unsigned char *)sq_malloc(n);
+                       memset(newbuf,0,n);
+                       if(_size > n)
+                               memcpy(newbuf,_buf,n);
+                       else
+                               memcpy(newbuf,_buf,_size);
+                       sq_free(_buf,_allocated);
+                       _buf=newbuf;
+                       _allocated = n;
+                       if(_size > _allocated)
+                               _size = _allocated;
+                       if(_ptr > _allocated)
+                               _ptr = _allocated;
+               }
+               return true;
+       }
+       bool GrowBufOf(SQInteger n)
+       {
+               bool ret = true;
+               if(_size + n > _allocated) {
+                       if(_size + n > _size * 2)
+                               ret = Resize(_size + n);
+                       else
+                               ret = Resize(_size * 2);
+               }
+               _size = _size + n;
+               return ret;
+       }
+       bool CanAdvance(SQInteger n) {
+               if(_ptr+n>_size)return false;
+               return true;
+       }
+       SQInteger Seek(SQInteger offset, SQInteger origin) {
+               switch(origin) {
+                       case SQ_SEEK_SET:
+                               if(offset > _size || offset < 0) return -1;
+                               _ptr = offset;
+                               break;
+                       case SQ_SEEK_CUR:
+                               if(_ptr + offset > _size || _ptr + offset < 0) return -1;
+                               _ptr += offset;
+                               break;
+                       case SQ_SEEK_END:
+                               if(_size + offset > _size || _size + offset < 0) return -1;
+                               _ptr = _size + offset;
+                               break;
+                       default: return -1;
+               }
+               return 0;
+       }
+       bool IsValid() {
+               return _buf?true:false;
+       }
+       bool EOS() {
+               return _ptr == _size;
+       }
+       SQInteger Flush() { return 0; }
+       SQInteger Tell() { return _ptr; }
+       SQInteger Len() { return _size; }
+       SQUserPointer GetBuf(){ return _buf; }
+private:
+       SQInteger _size;
+       SQInteger _allocated;
+       SQInteger _ptr;
+       unsigned char *_buf;
+       bool _owns;
+};
+
+#endif //_SQSTD_BLOBIMPL_H_
index 306cf12..ff99542 100644 (file)
-/* see copyright notice in squirrel.h */\r
-#include <new>\r
-#include <stdio.h>\r
-#include <squirrel.h>\r
-#include <sqstdio.h>\r
-#include "sqstdstream.h"\r
-\r
-#define SQSTD_FILE_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000001)\r
-//basic API\r
-SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode)\r
-{\r
-#ifndef _UNICODE\r
-       return (SQFILE)fopen(filename,mode);\r
-#else\r
-       return (SQFILE)_wfopen(filename,mode);\r
-#endif\r
-}\r
-\r
-SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file)\r
-{\r
-       return (SQInteger)fread(buffer,size,count,(FILE *)file);\r
-}\r
-\r
-SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file)\r
-{\r
-       return (SQInteger)fwrite(buffer,size,count,(FILE *)file);\r
-}\r
-\r
-SQInteger sqstd_fseek(SQFILE file, SQInteger offset, SQInteger origin)\r
-{\r
-       SQInteger realorigin;\r
-       switch(origin) {\r
-               case SQ_SEEK_CUR: realorigin = SEEK_CUR; break;\r
-               case SQ_SEEK_END: realorigin = SEEK_END; break;\r
-               case SQ_SEEK_SET: realorigin = SEEK_SET; break;\r
-               default: return -1; //failed\r
-       }\r
-       return fseek((FILE *)file,(long)offset,(int)realorigin);\r
-}\r
-\r
-SQInteger sqstd_ftell(SQFILE file)\r
-{\r
-       return ftell((FILE *)file);\r
-}\r
-\r
-SQInteger sqstd_fflush(SQFILE file)\r
-{\r
-       return fflush((FILE *)file);\r
-}\r
-\r
-SQInteger sqstd_fclose(SQFILE file)\r
-{\r
-       return fclose((FILE *)file);\r
-}\r
-\r
-SQInteger sqstd_feof(SQFILE file)\r
-{\r
-       return feof((FILE *)file);\r
-}\r
-\r
-//File\r
-struct SQFile : public SQStream {\r
-       SQFile() { _handle = NULL; _owns = false;}\r
-       SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;}\r
-       virtual ~SQFile() { Close(); }\r
-       bool Open(const SQChar *filename ,const SQChar *mode) {\r
-               Close();\r
-               if( (_handle = sqstd_fopen(filename,mode)) ) {\r
-                       _owns = true;\r
-                       return true;\r
-               }\r
-               return false;\r
-       }\r
-       void Close() {\r
-               if(_handle && _owns) { \r
-                       sqstd_fclose(_handle);\r
-                       _handle = NULL;\r
-                       _owns = false;\r
-               }\r
-       }\r
-       SQInteger Read(void *buffer,SQInteger size) {\r
-               return sqstd_fread(buffer,1,size,_handle);\r
-       }\r
-       SQInteger Write(void *buffer,SQInteger size) {\r
-               return sqstd_fwrite(buffer,1,size,_handle);\r
-       }\r
-       SQInteger Flush() {\r
-               return sqstd_fflush(_handle);\r
-       }\r
-       SQInteger Tell() {\r
-               return sqstd_ftell(_handle);\r
-       }\r
-       SQInteger Len() {\r
-               SQInteger prevpos=Tell();\r
-               Seek(0,SQ_SEEK_END);\r
-               SQInteger size=Tell();\r
-               Seek(prevpos,SQ_SEEK_SET);\r
-               return size;\r
-       }\r
-       SQInteger Seek(SQInteger offset, SQInteger origin)      {\r
-               return sqstd_fseek(_handle,offset,origin);\r
-       }\r
-       bool IsValid() { return _handle?true:false; }\r
-       bool EOS() { return Tell()==Len()?true:false;}\r
-       SQFILE GetHandle() {return _handle;}\r
-private:\r
-       SQFILE _handle;\r
-       bool _owns;\r
-};\r
-\r
-static SQInteger _file__typeof(HSQUIRRELVM v)\r
-{\r
-       sq_pushstring(v,_SC("file"),-1);\r
-       return 1;\r
-}\r
-\r
-static SQInteger _file_releasehook(SQUserPointer p, SQInteger size)\r
-{\r
-       SQFile *self = (SQFile*)p;\r
-       delete self;\r
-       return 1;\r
-}\r
-\r
-static SQInteger _file_constructor(HSQUIRRELVM v)\r
-{\r
-       const SQChar *filename,*mode;\r
-       bool owns = true;\r
-       SQFile *f;\r
-       SQFILE newf;\r
-       if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) {\r
-               sq_getstring(v, 2, &filename);\r
-               sq_getstring(v, 3, &mode);\r
-               newf = sqstd_fopen(filename, mode);\r
-               if(!newf) return sq_throwerror(v, _SC("cannot open file"));\r
-       } else if(sq_gettype(v,2) == OT_USERPOINTER) {\r
-               owns = !(sq_gettype(v,3) == OT_NULL);\r
-               sq_getuserpointer(v,2,&newf);\r
-       } else {\r
-               return sq_throwerror(v,_SC("wrong parameter"));\r
-       }\r
-       f = new SQFile(newf,owns);\r
-       if(SQ_FAILED(sq_setinstanceup(v,1,f))) {\r
-               delete f;\r
-               return sq_throwerror(v, _SC("cannot create blob with negative size"));\r
-       }\r
-       sq_setreleasehook(v,1,_file_releasehook);\r
-       return 0;\r
-}\r
-\r
-//bindings\r
-#define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck}\r
-static SQRegFunction _file_methods[] = {\r
-       _DECL_FILE_FUNC(constructor,3,_SC("x")),\r
-       _DECL_FILE_FUNC(_typeof,1,_SC("x")),\r
-       {0,0,0,0},\r
-};\r
-\r
-\r
-\r
-SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own)\r
-{\r
-       SQInteger top = sq_gettop(v);\r
-       sq_pushregistrytable(v);\r
-       sq_pushstring(v,_SC("std_file"),-1);\r
-       if(SQ_SUCCEEDED(sq_get(v,-2))) {\r
-               sq_remove(v,-2); //removes the registry\r
-               sq_pushroottable(v); // push the this\r
-               sq_pushuserpointer(v,file); //file\r
-               if(own){\r
-                       sq_pushinteger(v,1); //true\r
-               }\r
-               else{\r
-                       sq_pushnull(v); //false\r
-               }\r
-               if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) {\r
-                       sq_remove(v,-2);\r
-                       return SQ_OK;\r
-               }\r
-       }\r
-       sq_settop(v,top);\r
-       return SQ_OK;\r
-}\r
-\r
-SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file)\r
-{\r
-       SQFile *fileobj = NULL;\r
-       if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG))) {\r
-               *file = fileobj->GetHandle();\r
-               return SQ_OK;\r
-       }\r
-       return sq_throwerror(v,_SC("not a file"));\r
-}\r
-\r
-\r
-\r
-static SQInteger _io_file_lexfeed_ASCII(SQUserPointer file)\r
-{\r
-       SQInteger ret;\r
-       char c;\r
-       if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )\r
-               return c;\r
-       return 0;\r
-}\r
-\r
-static SQInteger _io_file_lexfeed_UTF8(SQUserPointer file)\r
-{\r
-#define READ() \\r
-       if(sqstd_fread(&inchar,sizeof(inchar),1,(FILE *)file) != 1) \\r
-               return 0;\r
-\r
-       static const SQInteger utf8_lengths[16] =\r
-       {\r
-               1,1,1,1,1,1,1,1,        /* 0000 to 0111 : 1 byte (plain ASCII) */\r
-               0,0,0,0,                /* 1000 to 1011 : not valid */\r
-               2,2,                    /* 1100, 1101 : 2 bytes */\r
-               3,                      /* 1110 : 3 bytes */\r
-               4                       /* 1111 :4 bytes */\r
-       };\r
-       static unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07};\r
-       unsigned char inchar;\r
-       SQInteger c = 0;\r
-       READ();\r
-       c = inchar;\r
-       //\r
-       if(c >= 0x80) {\r
-               SQInteger tmp;\r
-               SQInteger codelen = utf8_lengths[c>>4];\r
-               if(codelen == 0) \r
-                       return 0;\r
-                       //"invalid UTF-8 stream";\r
-               tmp = c&byte_masks[codelen];\r
-               for(SQInteger n = 0; n < codelen-1; n++) {\r
-                       tmp<<=6;\r
-                       READ();\r
-                       tmp |= inchar & 0x3F;\r
-               }\r
-               c = tmp;\r
-       }\r
-       return c;\r
-}\r
-\r
-static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer file)\r
-{\r
-       SQInteger ret;\r
-       wchar_t c;\r
-       if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )\r
-               return (SQChar)c;\r
-       return 0;\r
-}\r
-\r
-static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer file)\r
-{\r
-       SQInteger ret;\r
-       unsigned short c;\r
-       if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) {\r
-               c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00);\r
-               return (SQChar)c;\r
-       }\r
-       return 0;\r
-}\r
-\r
-SQInteger file_read(SQUserPointer file,SQUserPointer buf,SQInteger size)\r
-{\r
-       SQInteger ret;\r
-       if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret;\r
-       return -1;\r
-}\r
-\r
-SQInteger file_write(SQUserPointer file,SQUserPointer p,SQInteger size)\r
-{\r
-       return sqstd_fwrite(p,1,size,(SQFILE)file);\r
-}\r
-\r
-SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror)\r
-{\r
-       SQFILE file = sqstd_fopen(filename,_SC("rb"));\r
-       SQInteger ret;\r
-       unsigned short us;\r
-       unsigned char uc;\r
-       SQLEXREADFUNC func = _io_file_lexfeed_ASCII;\r
-       if(file){\r
-               ret = sqstd_fread(&us,1,2,file);\r
-               if(ret != 2) {\r
-                       //probably an empty file\r
-                       us = 0;\r
-               }\r
-               if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE\r
-                       sqstd_fseek(file,0,SQ_SEEK_SET);\r
-                       if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) {\r
-                               sqstd_fclose(file);\r
-                               return SQ_OK;\r
-                       }\r
-               }\r
-               else { //SCRIPT\r
-                       switch(us)\r
-                       {\r
-                               //gotta swap the next 2 lines on BIG endian machines\r
-                               case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian;\r
-                               case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian;\r
-                               case 0xBBEF: \r
-                                       if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) { \r
-                                               sqstd_fclose(file); \r
-                                               return sq_throwerror(v,_SC("io error")); \r
-                                       }\r
-                                       if(uc != 0xBF) { \r
-                                               sqstd_fclose(file); \r
-                                               return sq_throwerror(v,_SC("Unrecognozed ecoding")); \r
-                                       }\r
-                                       func = _io_file_lexfeed_UTF8;\r
-                                       break;//UTF-8 ;\r
-                               default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii\r
-                       }\r
-\r
-                       if(SQ_SUCCEEDED(sq_compile(v,func,file,filename,printerror))){\r
-                               sqstd_fclose(file);\r
-                               return SQ_OK;\r
-                       }\r
-               }\r
-               sqstd_fclose(file);\r
-               return SQ_ERROR;\r
-       }\r
-       return sq_throwerror(v,_SC("cannot open the file"));\r
-}\r
-\r
-SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror)\r
-{\r
-       if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) {\r
-               sq_push(v,-2);\r
-               if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) {\r
-                       sq_remove(v,retval?-2:-1); //removes the closure\r
-                       return 1;\r
-               }\r
-               sq_pop(v,1); //removes the closure\r
-       }\r
-       return SQ_ERROR;\r
-}\r
-\r
-SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename)\r
-{\r
-       SQFILE file = sqstd_fopen(filename,_SC("wb+"));\r
-       if(!file) return sq_throwerror(v,_SC("cannot open the file"));\r
-       if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) {\r
-               sqstd_fclose(file);\r
-               return SQ_OK;\r
-       }\r
-       sqstd_fclose(file);\r
-       return SQ_ERROR; //forward the error\r
-}\r
-\r
-SQInteger _g_io_loadfile(HSQUIRRELVM v)\r
-{\r
-       const SQChar *filename;\r
-       SQBool printerror = SQFalse;\r
-       sq_getstring(v,2,&filename);\r
-       if(sq_gettop(v) >= 3) {\r
-               sq_getbool(v,3,&printerror);\r
-       }\r
-       if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror)))\r
-               return 1;\r
-       return SQ_ERROR; //propagates the error\r
-}\r
-\r
-SQInteger _g_io_writeclosuretofile(HSQUIRRELVM v)\r
-{\r
-       const SQChar *filename;\r
-       sq_getstring(v,2,&filename);\r
-       if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,filename)))\r
-               return 1;\r
-       return SQ_ERROR; //propagates the error\r
-}\r
-\r
-SQInteger _g_io_dofile(HSQUIRRELVM v)\r
-{\r
-       const SQChar *filename;\r
-       SQBool printerror = SQFalse;\r
-       sq_getstring(v,2,&filename);\r
-       if(sq_gettop(v) >= 3) {\r
-               sq_getbool(v,3,&printerror);\r
-       }\r
-       sq_push(v,1); //repush the this\r
-       if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror)))\r
-               return 1;\r
-       return SQ_ERROR; //propagates the error\r
-}\r
-\r
-#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck}\r
-static SQRegFunction iolib_funcs[]={\r
-       _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")),\r
-       _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")),\r
-       _DECL_GLOBALIO_FUNC(writeclosuretofile,3,_SC(".sc")),\r
-       {0,0}\r
-};\r
-\r
-SQRESULT sqstd_register_iolib(HSQUIRRELVM v)\r
-{\r
-       SQInteger top = sq_gettop(v);\r
-       //create delegate\r
-       declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs);\r
-       sq_pushstring(v,_SC("stdout"),-1);\r
-       sqstd_createfile(v,stdout,SQFalse);\r
-       sq_createslot(v,-3);\r
-       sq_pushstring(v,_SC("stdin"),-1);\r
-       sqstd_createfile(v,stdin,SQFalse);\r
-       sq_createslot(v,-3);\r
-       sq_pushstring(v,_SC("stderr"),-1);\r
-       sqstd_createfile(v,stderr,SQFalse);\r
-       sq_createslot(v,-3);\r
-       sq_settop(v,top);\r
-       return SQ_OK;\r
-}\r
+/* see copyright notice in squirrel.h */
+#include <new>
+#include <stdio.h>
+#include <squirrel.h>
+#include <sqstdio.h>
+#include "sqstdstream.h"
+
+#define SQSTD_FILE_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000001)
+//basic API
+SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode)
+{
+#ifndef _UNICODE
+       return (SQFILE)fopen(filename,mode);
+#else
+       return (SQFILE)_wfopen(filename,mode);
+#endif
+}
+
+SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file)
+{
+       return (SQInteger)fread(buffer,size,count,(FILE *)file);
+}
+
+SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file)
+{
+       return (SQInteger)fwrite(buffer,size,count,(FILE *)file);
+}
+
+SQInteger sqstd_fseek(SQFILE file, SQInteger offset, SQInteger origin)
+{
+       SQInteger realorigin;
+       switch(origin) {
+               case SQ_SEEK_CUR: realorigin = SEEK_CUR; break;
+               case SQ_SEEK_END: realorigin = SEEK_END; break;
+               case SQ_SEEK_SET: realorigin = SEEK_SET; break;
+               default: return -1; //failed
+       }
+       return fseek((FILE *)file,(long)offset,(int)realorigin);
+}
+
+SQInteger sqstd_ftell(SQFILE file)
+{
+       return ftell((FILE *)file);
+}
+
+SQInteger sqstd_fflush(SQFILE file)
+{
+       return fflush((FILE *)file);
+}
+
+SQInteger sqstd_fclose(SQFILE file)
+{
+       return fclose((FILE *)file);
+}
+
+SQInteger sqstd_feof(SQFILE file)
+{
+       return feof((FILE *)file);
+}
+
+//File
+struct SQFile : public SQStream {
+       SQFile() { _handle = NULL; _owns = false;}
+       SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;}
+       virtual ~SQFile() { Close(); }
+       bool Open(const SQChar *filename ,const SQChar *mode) {
+               Close();
+               if( (_handle = sqstd_fopen(filename,mode)) ) {
+                       _owns = true;
+                       return true;
+               }
+               return false;
+       }
+       void Close() {
+               if(_handle && _owns) {
+                       sqstd_fclose(_handle);
+                       _handle = NULL;
+                       _owns = false;
+               }
+       }
+       SQInteger Read(void *buffer,SQInteger size) {
+               return sqstd_fread(buffer,1,size,_handle);
+       }
+       SQInteger Write(void *buffer,SQInteger size) {
+               return sqstd_fwrite(buffer,1,size,_handle);
+       }
+       SQInteger Flush() {
+               return sqstd_fflush(_handle);
+       }
+       SQInteger Tell() {
+               return sqstd_ftell(_handle);
+       }
+       SQInteger Len() {
+               SQInteger prevpos=Tell();
+               Seek(0,SQ_SEEK_END);
+               SQInteger size=Tell();
+               Seek(prevpos,SQ_SEEK_SET);
+               return size;
+       }
+       SQInteger Seek(SQInteger offset, SQInteger origin)      {
+               return sqstd_fseek(_handle,offset,origin);
+       }
+       bool IsValid() { return _handle?true:false; }
+       bool EOS() { return Tell()==Len()?true:false;}
+       SQFILE GetHandle() {return _handle;}
+private:
+       SQFILE _handle;
+       bool _owns;
+};
+
+static SQInteger _file__typeof(HSQUIRRELVM v)
+{
+       sq_pushstring(v,_SC("file"),-1);
+       return 1;
+}
+
+static SQInteger _file_releasehook(SQUserPointer p, SQInteger size)
+{
+       SQFile *self = (SQFile*)p;
+       delete self;
+       return 1;
+}
+
+static SQInteger _file_constructor(HSQUIRRELVM v)
+{
+       const SQChar *filename,*mode;
+       bool owns = true;
+       SQFile *f;
+       SQFILE newf;
+       if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) {
+               sq_getstring(v, 2, &filename);
+               sq_getstring(v, 3, &mode);
+               newf = sqstd_fopen(filename, mode);
+               if(!newf) return sq_throwerror(v, _SC("cannot open file"));
+       } else if(sq_gettype(v,2) == OT_USERPOINTER) {
+               owns = !(sq_gettype(v,3) == OT_NULL);
+               sq_getuserpointer(v,2,&newf);
+       } else {
+               return sq_throwerror(v,_SC("wrong parameter"));
+       }
+       f = new SQFile(newf,owns);
+       if(SQ_FAILED(sq_setinstanceup(v,1,f))) {
+               delete f;
+               return sq_throwerror(v, _SC("cannot create blob with negative size"));
+       }
+       sq_setreleasehook(v,1,_file_releasehook);
+       return 0;
+}
+
+//bindings
+#define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck}
+static SQRegFunction _file_methods[] = {
+       _DECL_FILE_FUNC(constructor,3,_SC("x")),
+       _DECL_FILE_FUNC(_typeof,1,_SC("x")),
+       {0,0,0,0},
+};
+
+
+
+SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own)
+{
+       SQInteger top = sq_gettop(v);
+       sq_pushregistrytable(v);
+       sq_pushstring(v,_SC("std_file"),-1);
+       if(SQ_SUCCEEDED(sq_get(v,-2))) {
+               sq_remove(v,-2); //removes the registry
+               sq_pushroottable(v); // push the this
+               sq_pushuserpointer(v,file); //file
+               if(own){
+                       sq_pushinteger(v,1); //true
+               }
+               else{
+                       sq_pushnull(v); //false
+               }
+               if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) {
+                       sq_remove(v,-2);
+                       return SQ_OK;
+               }
+       }
+       sq_settop(v,top);
+       return SQ_OK;
+}
+
+SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file)
+{
+       SQFile *fileobj = NULL;
+       if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG))) {
+               *file = fileobj->GetHandle();
+               return SQ_OK;
+       }
+       return sq_throwerror(v,_SC("not a file"));
+}
+
+
+
+static SQInteger _io_file_lexfeed_ASCII(SQUserPointer file)
+{
+       SQInteger ret;
+       char c;
+       if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )
+               return c;
+       return 0;
+}
+
+static SQInteger _io_file_lexfeed_UTF8(SQUserPointer file)
+{
+#define READ() \
+       if(sqstd_fread(&inchar,sizeof(inchar),1,(FILE *)file) != 1) \
+               return 0;
+
+       static const SQInteger 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;
+       SQInteger c = 0;
+       READ();
+       c = inchar;
+       //
+       if(c >= 0x80) {
+               SQInteger tmp;
+               SQInteger codelen = utf8_lengths[c>>4];
+               if(codelen == 0)
+                       return 0;
+                       //"invalid UTF-8 stream";
+               tmp = c&byte_masks[codelen];
+               for(SQInteger 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)
+{
+       SQInteger ret;
+       wchar_t c;
+       if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )
+               return (SQChar)c;
+       return 0;
+}
+
+static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer file)
+{
+       SQInteger 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;
+}
+
+SQInteger file_read(SQUserPointer file,SQUserPointer buf,SQInteger size)
+{
+       SQInteger ret;
+       if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret;
+       return -1;
+}
+
+SQInteger file_write(SQUserPointer file,SQUserPointer p,SQInteger size)
+{
+       return sqstd_fwrite(p,1,size,(SQFILE)file);
+}
+
+SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror)
+{
+       SQFILE file = sqstd_fopen(filename,_SC("rb"));
+       SQInteger ret;
+       unsigned short us;
+       unsigned char uc;
+       SQLEXREADFUNC func = _io_file_lexfeed_ASCII;
+       if(file){
+               ret = sqstd_fread(&us,1,2,file);
+               if(ret != 2) {
+                       //probably an empty file
+                       us = 0;
+               }
+               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);
+                               return SQ_OK;
+                       }
+               }
+               else { //SCRIPT
+                       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);
+                               return SQ_OK;
+                       }
+               }
+               sqstd_fclose(file);
+               return SQ_ERROR;
+       }
+       return sq_throwerror(v,_SC("cannot open the file"));
+}
+
+SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror)
+{
+       if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) {
+               sq_push(v,-2);
+               if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) {
+                       sq_remove(v,retval?-2:-1); //removes the closure
+                       return 1;
+               }
+               sq_pop(v,1); //removes the closure
+       }
+       return SQ_ERROR;
+}
+
+SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename)
+{
+       SQFILE file = sqstd_fopen(filename,_SC("wb+"));
+       if(!file) return sq_throwerror(v,_SC("cannot open the file"));
+       if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) {
+               sqstd_fclose(file);
+               return SQ_OK;
+       }
+       sqstd_fclose(file);
+       return SQ_ERROR; //forward the error
+}
+
+SQInteger _g_io_loadfile(HSQUIRRELVM v)
+{
+       const SQChar *filename;
+       SQBool printerror = SQFalse;
+       sq_getstring(v,2,&filename);
+       if(sq_gettop(v) >= 3) {
+               sq_getbool(v,3,&printerror);
+       }
+       if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror)))
+               return 1;
+       return SQ_ERROR; //propagates the error
+}
+
+SQInteger _g_io_writeclosuretofile(HSQUIRRELVM v)
+{
+       const SQChar *filename;
+       sq_getstring(v,2,&filename);
+       if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,filename)))
+               return 1;
+       return SQ_ERROR; //propagates the error
+}
+
+SQInteger _g_io_dofile(HSQUIRRELVM v)
+{
+       const SQChar *filename;
+       SQBool printerror = SQFalse;
+       sq_getstring(v,2,&filename);
+       if(sq_gettop(v) >= 3) {
+               sq_getbool(v,3,&printerror);
+       }
+       sq_push(v,1); //repush the this
+       if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror)))
+               return 1;
+       return SQ_ERROR; //propagates the error
+}
+
+#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck}
+static SQRegFunction iolib_funcs[]={
+       _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")),
+       _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")),
+       _DECL_GLOBALIO_FUNC(writeclosuretofile,3,_SC(".sc")),
+       {0,0}
+};
+
+SQRESULT sqstd_register_iolib(HSQUIRRELVM v)
+{
+       SQInteger top = sq_gettop(v);
+       //create delegate
+       declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs);
+       sq_pushstring(v,_SC("stdout"),-1);
+       sqstd_createfile(v,stdout,SQFalse);
+       sq_createslot(v,-3);
+       sq_pushstring(v,_SC("stdin"),-1);
+       sqstd_createfile(v,stdin,SQFalse);
+       sq_createslot(v,-3);
+       sq_pushstring(v,_SC("stderr"),-1);
+       sqstd_createfile(v,stderr,SQFalse);
+       sq_createslot(v,-3);
+       sq_settop(v,top);
+       return SQ_OK;
+}
index ae1a219..01a808a 100644 (file)
-/* see copyright notice in squirrel.h */\r
-#include <squirrel.h>\r
-#include <math.h>\r
-#include <stdlib.h>\r
-#include <sqstdmath.h>\r
-\r
-#define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \\r
-       SQFloat f; \\r
-       sq_getfloat(v,2,&f); \\r
-       sq_pushfloat(v,(SQFloat)_funcname(f)); \\r
-       return 1; \\r
-}\r
-\r
-#define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \\r
-       SQFloat p1,p2; \\r
-       sq_getfloat(v,2,&p1); \\r
-       sq_getfloat(v,3,&p2); \\r
-       sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \\r
-       return 1; \\r
-}\r
-\r
-static SQInteger math_srand(HSQUIRRELVM v)\r
-{\r
-       SQInteger i;\r
-       if(!sq_getinteger(v,2,&i))return sq_throwerror(v,_SC("invalid param"));\r
-       srand((unsigned int)i);\r
-       return 0;\r
-}\r
-\r
-static SQInteger math_rand(HSQUIRRELVM v)\r
-{\r
-       sq_pushinteger(v,rand());\r
-       return 1;\r
-}\r
-\r
-static SQInteger math_abs(HSQUIRRELVM v)\r
-{\r
-       SQInteger n;\r
-       sq_getinteger(v,2,&n);\r
-       sq_pushinteger(v,(SQInteger)abs((int)n)); \r
-       return 1; \r
-}\r
-\r
-SINGLE_ARG_FUNC(sqrt)\r
-SINGLE_ARG_FUNC(fabs)\r
-SINGLE_ARG_FUNC(sin)\r
-SINGLE_ARG_FUNC(cos)\r
-SINGLE_ARG_FUNC(asin)\r
-SINGLE_ARG_FUNC(acos)\r
-SINGLE_ARG_FUNC(log)\r
-SINGLE_ARG_FUNC(log10)\r
-SINGLE_ARG_FUNC(tan)\r
-SINGLE_ARG_FUNC(atan)\r
-TWO_ARGS_FUNC(atan2)\r
-TWO_ARGS_FUNC(pow)\r
-SINGLE_ARG_FUNC(floor)\r
-SINGLE_ARG_FUNC(ceil)\r
-SINGLE_ARG_FUNC(exp)\r
-\r
-#define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck}\r
-static SQRegFunction mathlib_funcs[] = {\r
-       _DECL_FUNC(sqrt,2,_SC(".n")),\r
-       _DECL_FUNC(sin,2,_SC(".n")),\r
-       _DECL_FUNC(cos,2,_SC(".n")),\r
-       _DECL_FUNC(asin,2,_SC(".n")),\r
-       _DECL_FUNC(acos,2,_SC(".n")),\r
-       _DECL_FUNC(log,2,_SC(".n")),\r
-       _DECL_FUNC(log10,2,_SC(".n")),\r
-       _DECL_FUNC(tan,2,_SC(".n")),\r
-       _DECL_FUNC(atan,2,_SC(".n")),\r
-       _DECL_FUNC(atan2,3,_SC(".nn")),\r
-       _DECL_FUNC(pow,3,_SC(".nn")),\r
-       _DECL_FUNC(floor,2,_SC(".n")),\r
-       _DECL_FUNC(ceil,2,_SC(".n")),\r
-       _DECL_FUNC(exp,2,_SC(".n")),\r
-       _DECL_FUNC(srand,2,_SC(".n")),\r
-       _DECL_FUNC(rand,1,NULL),\r
-       _DECL_FUNC(fabs,2,_SC(".n")),\r
-       _DECL_FUNC(abs,2,_SC(".n")),\r
-       {0,0},\r
-};\r
-\r
-#ifndef M_PI\r
-#define M_PI (3.14159265358979323846)\r
-#endif\r
-\r
-SQRESULT sqstd_register_mathlib(HSQUIRRELVM v)\r
-{\r
-       SQInteger i=0;\r
-       while(mathlib_funcs[i].name!=0) {\r
-               sq_pushstring(v,mathlib_funcs[i].name,-1);\r
-               sq_newclosure(v,mathlib_funcs[i].f,0);\r
-               sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask);\r
-               sq_setnativeclosurename(v,-1,mathlib_funcs[i].name);\r
-               sq_createslot(v,-3);\r
-               i++;\r
-       }\r
-       sq_pushstring(v,_SC("RAND_MAX"),-1);\r
-       sq_pushinteger(v,RAND_MAX);\r
-       sq_createslot(v,-3);\r
-       sq_pushstring(v,_SC("PI"),-1);\r
-       sq_pushfloat(v,(SQFloat)M_PI);\r
-       sq_createslot(v,-3);\r
-       return SQ_OK;\r
-}\r
+/* see copyright notice in squirrel.h */
+#include <squirrel.h>
+#include <math.h>
+#include <stdlib.h>
+#include <sqstdmath.h>
+
+#define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \
+       SQFloat f; \
+       sq_getfloat(v,2,&f); \
+       sq_pushfloat(v,(SQFloat)_funcname(f)); \
+       return 1; \
+}
+
+#define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \
+       SQFloat p1,p2; \
+       sq_getfloat(v,2,&p1); \
+       sq_getfloat(v,3,&p2); \
+       sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \
+       return 1; \
+}
+
+static SQInteger math_srand(HSQUIRRELVM v)
+{
+       SQInteger i;
+       if(!sq_getinteger(v,2,&i))return sq_throwerror(v,_SC("invalid param"));
+       srand((unsigned int)i);
+       return 0;
+}
+
+static SQInteger math_rand(HSQUIRRELVM v)
+{
+       sq_pushinteger(v,rand());
+       return 1;
+}
+
+static SQInteger math_abs(HSQUIRRELVM v)
+{
+       SQInteger n;
+       sq_getinteger(v,2,&n);
+       sq_pushinteger(v,(SQInteger)abs((int)n));
+       return 1;
+}
+
+SINGLE_ARG_FUNC(sqrt)
+SINGLE_ARG_FUNC(fabs)
+SINGLE_ARG_FUNC(sin)
+SINGLE_ARG_FUNC(cos)
+SINGLE_ARG_FUNC(asin)
+SINGLE_ARG_FUNC(acos)
+SINGLE_ARG_FUNC(log)
+SINGLE_ARG_FUNC(log10)
+SINGLE_ARG_FUNC(tan)
+SINGLE_ARG_FUNC(atan)
+TWO_ARGS_FUNC(atan2)
+TWO_ARGS_FUNC(pow)
+SINGLE_ARG_FUNC(floor)
+SINGLE_ARG_FUNC(ceil)
+SINGLE_ARG_FUNC(exp)
+
+#define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck}
+static SQRegFunction mathlib_funcs[] = {
+       _DECL_FUNC(sqrt,2,_SC(".n")),
+       _DECL_FUNC(sin,2,_SC(".n")),
+       _DECL_FUNC(cos,2,_SC(".n")),
+       _DECL_FUNC(asin,2,_SC(".n")),
+       _DECL_FUNC(acos,2,_SC(".n")),
+       _DECL_FUNC(log,2,_SC(".n")),
+       _DECL_FUNC(log10,2,_SC(".n")),
+       _DECL_FUNC(tan,2,_SC(".n")),
+       _DECL_FUNC(atan,2,_SC(".n")),
+       _DECL_FUNC(atan2,3,_SC(".nn")),
+       _DECL_FUNC(pow,3,_SC(".nn")),
+       _DECL_FUNC(floor,2,_SC(".n")),
+       _DECL_FUNC(ceil,2,_SC(".n")),
+       _DECL_FUNC(exp,2,_SC(".n")),
+       _DECL_FUNC(srand,2,_SC(".n")),
+       _DECL_FUNC(rand,1,NULL),
+       _DECL_FUNC(fabs,2,_SC(".n")),
+       _DECL_FUNC(abs,2,_SC(".n")),
+       {0,0},
+};
+
+#ifndef M_PI
+#define M_PI (3.14159265358979323846)
+#endif
+
+SQRESULT sqstd_register_mathlib(HSQUIRRELVM v)
+{
+       SQInteger i=0;
+       while(mathlib_funcs[i].name!=0) {
+               sq_pushstring(v,mathlib_funcs[i].name,-1);
+               sq_newclosure(v,mathlib_funcs[i].f,0);
+               sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask);
+               sq_setnativeclosurename(v,-1,mathlib_funcs[i].name);
+               sq_createslot(v,-3);
+               i++;
+       }
+       sq_pushstring(v,_SC("RAND_MAX"),-1);
+       sq_pushinteger(v,RAND_MAX);
+       sq_createslot(v,-3);
+       sq_pushstring(v,_SC("PI"),-1);
+       sq_pushfloat(v,(SQFloat)M_PI);
+       sq_createslot(v,-3);
+       return SQ_OK;
+}
index 9c3c268..59397a7 100644 (file)
-/* 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 _UINCODE\r
-#define scisprint iswprint\r
-#else\r
-#define scisprint isprint\r
-#endif\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
-       SQInteger left;\r
-       SQInteger right;\r
-       SQInteger next;\r
-}SQRexNode;\r
-\r
-struct SQRex{\r
-       const SQChar *_eol;\r
-       const SQChar *_bol;\r
-       const SQChar *_p;\r
-       SQInteger _first;\r
-       SQInteger _op;\r
-       SQRexNode *_nodes;\r
-       SQInteger _nallocated;\r
-       SQInteger _nsize;\r
-       SQInteger _nsubexpr;\r
-       SQRexMatch *_matches;\r
-       SQInteger _currsubexp;\r
-       void *_jmpbuf;\r
-       const SQChar **_error;\r
-};\r
-\r
-static SQInteger sqstd_rex_list(SQRex *exp);\r
-\r
-static SQInteger 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
-               SQInteger 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 (SQInteger)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, SQInteger 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(!scisprint(*exp->_p)) sqstd_rex_error(exp,_SC("letter expected"));\r
-       return (*exp->_p++);\r
-}\r
-\r
-static SQInteger sqstd_rex_charclass(SQRex *exp,SQInteger classid)\r
-{\r
-       SQInteger n = sqstd_rex_newnode(exp,OP_CCLASS);\r
-       exp->_nodes[n].left = classid;\r
-       return n;\r
-}\r
-\r
-static SQInteger 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
-                                       SQInteger 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(!scisprint(*exp->_p)) {\r
-               \r
-               sqstd_rex_error(exp,_SC("letter expected"));\r
-       }\r
-       return sqstd_rex_newnode(exp,*exp->_p++);\r
-}\r
-static SQInteger sqstd_rex_class(SQRex *exp)\r
-{\r
-       SQInteger ret = -1;\r
-       SQInteger 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 == ']') sqstd_rex_error(exp,_SC("empty class"));\r
-       chain = ret;\r
-       while(*exp->_p != ']' && exp->_p != exp->_eol) {\r
-               if(*exp->_p == '-' && first != -1){ \r
-                       SQInteger 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
-                               SQInteger 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
-               SQInteger 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 SQInteger sqstd_rex_parsenumber(SQRex *exp)\r
-{\r
-       SQInteger ret = *exp->_p-'0';\r
-       SQInteger 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 SQInteger sqstd_rex_element(SQRex *exp)\r
-{\r
-       SQInteger ret;\r
-       switch(*exp->_p)\r
-       {\r
-       case '(': {\r
-               SQInteger 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
-               SQInteger 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 = (unsigned short)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 = (unsigned short)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
-                               SQInteger 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 SQInteger sqstd_rex_list(SQRex *exp)\r
-{\r
-       SQInteger 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
-               SQInteger 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(SQInteger 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,SQRexNode *next)\r
-{\r
-       \r
-       SQRexNodeType type = node->type;\r
-       switch(type) {\r
-       case OP_GREEDY: {\r
-               //SQRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL;\r
-               SQRexNode *greedystop = NULL;\r
-               SQInteger p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0;\r
-               const SQChar *s=str, *good = str;\r
-\r
-               if(node->next != -1) {\r
-                       greedystop = &exp->_nodes[node->next];\r
-               }\r
-               else {\r
-                       greedystop = next;\r
-               }\r
-\r
-               while((nmaches == 0xFFFF || nmaches < p1)) {\r
-\r
-                       const SQChar *stop;\r
-                       if(!(s = sqstd_rex_matchnode(exp,&exp->_nodes[node->left],s,greedystop)))\r
-                               break;\r
-                       nmaches++;\r
-                       good=s;\r
-                       if(greedystop) {\r
-                               //checks that 0 matches satisfy the expression(if so skips)\r
-                               //if not would always stop(for instance if is a '?')\r
-                               if(greedystop->type != OP_GREEDY ||\r
-                               (greedystop->type == OP_GREEDY && ((greedystop->right >> 16)&0x0000FFFF) != 0))\r
-                               {\r
-                                       SQRexNode *gnext = NULL;\r
-                                       if(greedystop->next != -1) {\r
-                                               gnext = &exp->_nodes[greedystop->next];\r
-                                       }else if(next && next->next != -1){\r
-                                               gnext = &exp->_nodes[next->next];\r
-                                       }\r
-                                       stop = sqstd_rex_matchnode(exp,greedystop,s,gnext);\r
-                                       if(stop) {\r
-                                               //if satisfied stop it\r
-                                               if(p0 == p1 && p0 == nmaches) break;\r
-                                               else if(nmaches >= p0 && p1 == 0xFFFF) break;\r
-                                               else if(nmaches >= p0 && nmaches <= p1) break;\r
-                                       }\r
-                               }\r
-                       }\r
-                       \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,NULL)) ) {\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,NULL)) ) {\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
-                       SQInteger 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
-                               SQRexNode *subnext = NULL;\r
-                               if(n->next != -1) {\r
-                                       subnext = &exp->_nodes[n->next];\r
-                               }else {\r
-                                       subnext = next;\r
-                               }\r
-                               if(!(cur = sqstd_rex_matchnode(exp,n,cur,subnext))) {\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
-                               }\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->_eol = exp->_bol = NULL;\r
-       exp->_p = pattern;\r
-       exp->_nallocated = (SQInteger)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
-                       SQInteger 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,NULL);\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
-       SQInteger 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,NULL);\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
-SQInteger sqstd_rex_getsubexpcount(SQRex* exp)\r
-{\r
-       return exp->_nsubexpr;\r
-}\r
-\r
-SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp)\r
-{\r
-       if( n<0 || n >= exp->_nsubexpr) return SQFalse;\r
-       *subexp = exp->_matches[n];\r
-       return SQTrue;\r
-}\r
-\r
+/* see copyright notice in squirrel.h */
+#include <squirrel.h>
+#include <string.h>
+#include <ctype.h>
+#include <setjmp.h>
+#include "sqstdstring.h"
+
+#ifdef _UINCODE
+#define scisprint iswprint
+#else
+#define scisprint isprint
+#endif
+
+#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;
+       SQInteger left;
+       SQInteger right;
+       SQInteger next;
+}SQRexNode;
+
+struct SQRex{
+       const SQChar *_eol;
+       const SQChar *_bol;
+       const SQChar *_p;
+       SQInteger _first;
+       SQInteger _op;
+       SQRexNode *_nodes;
+       SQInteger _nallocated;
+       SQInteger _nsize;
+       SQInteger _nsubexpr;
+       SQRexMatch *_matches;
+       SQInteger _currsubexp;
+       void *_jmpbuf;
+       const SQChar **_error;
+};
+
+static SQInteger sqstd_rex_list(SQRex *exp);
+
+static SQInteger 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)) {
+               SQInteger 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 (SQInteger)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, SQInteger 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(!scisprint(*exp->_p)) sqstd_rex_error(exp,_SC("letter expected"));
+       return (*exp->_p++);
+}
+
+static SQInteger sqstd_rex_charclass(SQRex *exp,SQInteger classid)
+{
+       SQInteger n = sqstd_rex_newnode(exp,OP_CCLASS);
+       exp->_nodes[n].left = classid;
+       return n;
+}
+
+static SQInteger 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) {
+                                       SQInteger 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(!scisprint(*exp->_p)) {
+
+               sqstd_rex_error(exp,_SC("letter expected"));
+       }
+       return sqstd_rex_newnode(exp,*exp->_p++);
+}
+static SQInteger sqstd_rex_class(SQRex *exp)
+{
+       SQInteger ret = -1;
+       SQInteger 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 == ']') sqstd_rex_error(exp,_SC("empty class"));
+       chain = ret;
+       while(*exp->_p != ']' && exp->_p != exp->_eol) {
+               if(*exp->_p == '-' && first != -1){
+                       SQInteger 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){
+                               SQInteger 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){
+               SQInteger 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 SQInteger sqstd_rex_parsenumber(SQRex *exp)
+{
+       SQInteger ret = *exp->_p-'0';
+       SQInteger 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 SQInteger sqstd_rex_element(SQRex *exp)
+{
+       SQInteger ret;
+       switch(*exp->_p)
+       {
+       case '(': {
+               SQInteger 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 */
+       {
+               SQInteger 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 = (unsigned short)sqstd_rex_parsenumber(exp);
+                       switch(*exp->_p) {
+                       case '}':
+                               p1 = p0; exp->_p++;
+                               goto __end;
+                       case ',':
+                               exp->_p++;
+                               p1 = 0xFFFF;
+                               if(isdigit(*exp->_p)){
+                                       p1 = (unsigned short)sqstd_rex_parsenumber(exp);
+                               }
+                               sqstd_rex_expect(exp,'}');
+                               goto __end;
+                       default:
+                               sqstd_rex_error(exp,_SC(", or } expected"));
+                       }
+               }
+               __end: {
+                               SQInteger 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 SQInteger sqstd_rex_list(SQRex *exp)
+{
+       SQInteger 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) {
+               SQInteger 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(SQInteger 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,SQRexNode *next)
+{
+
+       SQRexNodeType type = node->type;
+       switch(type) {
+       case OP_GREEDY: {
+               //SQRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL;
+               SQRexNode *greedystop = NULL;
+               SQInteger p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0;
+               const SQChar *s=str, *good = str;
+
+               if(node->next != -1) {
+                       greedystop = &exp->_nodes[node->next];
+               }
+               else {
+                       greedystop = next;
+               }
+
+               while((nmaches == 0xFFFF || nmaches < p1)) {
+
+                       const SQChar *stop;
+                       if(!(s = sqstd_rex_matchnode(exp,&exp->_nodes[node->left],s,greedystop)))
+                               break;
+                       nmaches++;
+                       good=s;
+                       if(greedystop) {
+                               //checks that 0 matches satisfy the expression(if so skips)
+                               //if not would always stop(for instance if is a '?')
+                               if(greedystop->type != OP_GREEDY ||
+                               (greedystop->type == OP_GREEDY && ((greedystop->right >> 16)&0x0000FFFF) != 0))
+                               {
+                                       SQRexNode *gnext = NULL;
+                                       if(greedystop->next != -1) {
+                                               gnext = &exp->_nodes[greedystop->next];
+                                       }else if(next && next->next != -1){
+                                               gnext = &exp->_nodes[next->next];
+                                       }
+                                       stop = sqstd_rex_matchnode(exp,greedystop,s,gnext);
+                                       if(stop) {
+                                               //if satisfied stop it
+                                               if(p0 == p1 && p0 == nmaches) break;
+                                               else if(nmaches >= p0 && p1 == 0xFFFF) break;
+                                               else if(nmaches >= p0 && nmaches <= p1) break;
+                                       }
+                               }
+                       }
+
+                       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,NULL)) ) {
+                               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,NULL)) ) {
+                               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;
+                       SQInteger capture = -1;
+                       if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) {
+                               capture = exp->_currsubexp;
+                               exp->_matches[capture].begin = cur;
+                               exp->_currsubexp++;
+                       }
+
+                       do {
+                               SQRexNode *subnext = NULL;
+                               if(n->next != -1) {
+                                       subnext = &exp->_nodes[n->next];
+                               }else {
+                                       subnext = next;
+                               }
+                               if(!(cur = sqstd_rex_matchnode(exp,n,cur,subnext))) {
+                                       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->_eol = exp->_bol = NULL;
+       exp->_p = pattern;
+       exp->_nallocated = (SQInteger)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
+               {
+                       SQInteger 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,NULL);
+       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;
+       SQInteger 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,NULL);
+                       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);
+}
+
+SQInteger sqstd_rex_getsubexpcount(SQRex* exp)
+{
+       return exp->_nsubexpr;
+}
+
+SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp)
+{
+       if( n<0 || n >= exp->_nsubexpr) return SQFalse;
+       *subexp = exp->_matches[n];
+       return SQTrue;
+}
index 669ca23..b94ab5e 100644 (file)
-/* see copyright notice in squirrel.h */\r
-#include <new>\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include <squirrel.h>\r
-#include <sqstdio.h>\r
-#include <sqstdblob.h>\r
-#include "sqstdstream.h"\r
-#include "sqstdblobimpl.h"\r
-\r
-#define SETUP_STREAM(v) \\r
-       SQStream *self = NULL; \\r
-       if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_STREAM_TYPE_TAG))) \\r
-               return sq_throwerror(v,_SC("invalid type tag")); \\r
-       if(!self->IsValid())  \\r
-               return sq_throwerror(v,_SC("the stream is invalid"));\r
-\r
-SQInteger _stream_readblob(HSQUIRRELVM v)\r
-{\r
-       SETUP_STREAM(v);\r
-       SQUserPointer data,blobp;\r
-       SQInteger size,res;\r
-       sq_getinteger(v,2,&size);\r
-       if(size > self->Len()) {\r
-               size = self->Len();\r
-       }\r
-       data = sq_getscratchpad(v,size);\r
-       res = self->Read(data,size);\r
-       if(res <= 0)\r
-               return sq_throwerror(v,_SC("no data left to read"));\r
-       blobp = sqstd_createblob(v,res);\r
-       memcpy(blobp,data,res);\r
-       return 1;\r
-}\r
-\r
-#define SAFE_READN(ptr,len) { \\r
-       if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \\r
-       }\r
-SQInteger _stream_readn(HSQUIRRELVM v)\r
-{\r
-       SETUP_STREAM(v);\r
-       SQInteger format;\r
-       sq_getinteger(v, 2, &format);\r
-       switch(format) {\r
-       case 'l': {\r
-               SQInteger i;\r
-               SAFE_READN(&i, sizeof(i));\r
-               sq_pushinteger(v, i);\r
-                         }\r
-               break;\r
-       case 'i': {\r
-               SQInt32 i;\r
-               SAFE_READN(&i, sizeof(i));\r
-               sq_pushinteger(v, i);\r
-                         }\r
-               break;\r
-       case 's': {\r
-               short s;\r
-               SAFE_READN(&s, sizeof(short));\r
-               sq_pushinteger(v, s);\r
-                         }\r
-               break;\r
-       case 'w': {\r
-               unsigned short w;\r
-               SAFE_READN(&w, sizeof(unsigned short));\r
-               sq_pushinteger(v, w);\r
-                         }\r
-               break;\r
-       case 'c': {\r
-               char c;\r
-               SAFE_READN(&c, sizeof(char));\r
-               sq_pushinteger(v, c);\r
-                         }\r
-               break;\r
-       case 'b': {\r
-               unsigned char c;\r
-               SAFE_READN(&c, sizeof(unsigned char));\r
-               sq_pushinteger(v, c);\r
-                         }\r
-               break;\r
-       case 'f': {\r
-               float f;\r
-               SAFE_READN(&f, sizeof(float));\r
-               sq_pushfloat(v, f);\r
-                         }\r
-               break;\r
-       case 'd': {\r
-               double d;\r
-               SAFE_READN(&d, sizeof(double));\r
-               sq_pushfloat(v, (SQFloat)d);\r
-                         }\r
-               break;\r
-       default:\r
-               return sq_throwerror(v, _SC("invalid format"));\r
-       }\r
-       return 1;\r
-}\r
-\r
-SQInteger _stream_writeblob(HSQUIRRELVM v)\r
-{\r
-       SQUserPointer data;\r
-       SQInteger size;\r
-       SETUP_STREAM(v);\r
-       if(SQ_FAILED(sqstd_getblob(v,2,&data)))\r
-               return sq_throwerror(v,_SC("invalid parameter"));\r
-       size = sqstd_getblobsize(v,2);\r
-       if(self->Write(data,size) != size)\r
-               return sq_throwerror(v,_SC("io error"));\r
-       sq_pushinteger(v,size);\r
-       return 1;\r
-}\r
-\r
-SQInteger _stream_writen(HSQUIRRELVM v)\r
-{\r
-       SETUP_STREAM(v);\r
-       SQInteger format, ti;\r
-       SQFloat tf;\r
-       sq_getinteger(v, 3, &format);\r
-       switch(format) {\r
-       case 'l': {\r
-               SQInteger i;\r
-               sq_getinteger(v, 2, &ti);\r
-               i = ti;\r
-               self->Write(&i, sizeof(SQInteger));\r
-                         }\r
-               break;\r
-       case 'i': {\r
-               SQInt32 i;\r
-               sq_getinteger(v, 2, &ti);\r
-               i = (SQInt32)ti;\r
-               self->Write(&i, sizeof(SQInt32));\r
-                         }\r
-               break;\r
-       case 's': {\r
-               short s;\r
-               sq_getinteger(v, 2, &ti);\r
-               s = (short)ti;\r
-               self->Write(&s, sizeof(short));\r
-                         }\r
-               break;\r
-       case 'w': {\r
-               unsigned short w;\r
-               sq_getinteger(v, 2, &ti);\r
-               w = (unsigned short)ti;\r
-               self->Write(&w, sizeof(unsigned short));\r
-                         }\r
-               break;\r
-       case 'c': {\r
-               char c;\r
-               sq_getinteger(v, 2, &ti);\r
-               c = (char)ti;\r
-               self->Write(&c, sizeof(char));\r
-                                 }\r
-               break;\r
-       case 'b': {\r
-               unsigned char b;\r
-               sq_getinteger(v, 2, &ti);\r
-               b = (unsigned char)ti;\r
-               self->Write(&b, sizeof(unsigned char));\r
-                         }\r
-               break;\r
-       case 'f': {\r
-               float f;\r
-               sq_getfloat(v, 2, &tf);\r
-               f = tf;\r
-               self->Write(&f, sizeof(float));\r
-                         }\r
-               break;\r
-       case 'd': {\r
-               double d;\r
-               sq_getfloat(v, 2, &tf);\r
-               d = tf;\r
-               self->Write(&d, sizeof(double));\r
-                         }\r
-               break;\r
-       default:\r
-               return sq_throwerror(v, _SC("invalid format"));\r
-       }\r
-       return 0;\r
-}\r
-\r
-SQInteger _stream_seek(HSQUIRRELVM v)\r
-{\r
-       SETUP_STREAM(v);\r
-       SQInteger offset, origin = SQ_SEEK_SET;\r
-       sq_getinteger(v, 2, &offset);\r
-       if(sq_gettop(v) > 2) {\r
-               SQInteger t;\r
-               sq_getinteger(v, 3, &t);\r
-               switch(t) {\r
-                       case 'b': origin = SQ_SEEK_SET; break;\r
-                       case 'c': origin = SQ_SEEK_CUR; break;\r
-                       case 'e': origin = SQ_SEEK_END; break;\r
-                       default: return sq_throwerror(v,_SC("invalid origin"));\r
-               }\r
-       }\r
-       sq_pushinteger(v, self->Seek(offset, origin));\r
-       return 1;\r
-}\r
-\r
-SQInteger _stream_tell(HSQUIRRELVM v)\r
-{\r
-       SETUP_STREAM(v);\r
-       sq_pushinteger(v, self->Tell());\r
-       return 1;\r
-}\r
-\r
-SQInteger _stream_len(HSQUIRRELVM v)\r
-{\r
-       SETUP_STREAM(v);\r
-       sq_pushinteger(v, self->Len());\r
-       return 1;\r
-}\r
-\r
-SQInteger _stream_flush(HSQUIRRELVM v)\r
-{\r
-       SETUP_STREAM(v);\r
-       if(!self->Flush())\r
-               sq_pushinteger(v, 1);\r
-       else\r
-               sq_pushnull(v);\r
-       return 1;\r
-}\r
-\r
-SQInteger _stream_eos(HSQUIRRELVM v)\r
-{\r
-       SETUP_STREAM(v);\r
-       if(self->EOS())\r
-               sq_pushinteger(v, 1);\r
-       else\r
-               sq_pushnull(v);\r
-       return 1;\r
-}\r
-\r
-static SQRegFunction _stream_methods[] = {\r
-       _DECL_STREAM_FUNC(readblob,2,_SC("xn")),\r
-       _DECL_STREAM_FUNC(readn,2,_SC("xn")),\r
-       _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")),\r
-       _DECL_STREAM_FUNC(writen,3,_SC("xnn")),\r
-       _DECL_STREAM_FUNC(seek,-2,_SC("xnn")),\r
-       _DECL_STREAM_FUNC(tell,1,_SC("x")),\r
-       _DECL_STREAM_FUNC(len,1,_SC("x")),\r
-       _DECL_STREAM_FUNC(eos,1,_SC("x")),\r
-       _DECL_STREAM_FUNC(flush,1,_SC("x")),\r
-       {0,0}\r
-};\r
-\r
-void init_streamclass(HSQUIRRELVM v)\r
-{\r
-       sq_pushregistrytable(v);\r
-       sq_pushstring(v,_SC("std_stream"),-1);\r
-       if(SQ_FAILED(sq_get(v,-2))) {\r
-               sq_pushstring(v,_SC("std_stream"),-1);\r
-               sq_newclass(v,SQFalse);\r
-               sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG);\r
-               SQInteger i = 0;\r
-               while(_stream_methods[i].name != 0) {\r
-                       SQRegFunction &f = _stream_methods[i];\r
-                       sq_pushstring(v,f.name,-1);\r
-                       sq_newclosure(v,f.f,0);\r
-                       sq_setparamscheck(v,f.nparamscheck,f.typemask);\r
-                       sq_createslot(v,-3);\r
-                       i++;\r
-               }\r
-               sq_createslot(v,-3);\r
-               sq_pushroottable(v);\r
-               sq_pushstring(v,_SC("stream"),-1);\r
-               sq_pushstring(v,_SC("std_stream"),-1);\r
-               sq_get(v,-4);\r
-               sq_createslot(v,-3);\r
-               sq_pop(v,1);\r
-       }\r
-       else {\r
-               sq_pop(v,1); //result\r
-       }\r
-       sq_pop(v,1);\r
-}\r
-\r
-SQRESULT declare_stream(HSQUIRRELVM v,SQChar* name,SQUserPointer typetag,SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals)\r
-{\r
-       if(sq_gettype(v,-1) != OT_TABLE)\r
-               return sq_throwerror(v,_SC("table expected"));\r
-       SQInteger top = sq_gettop(v);\r
-       //create delegate\r
-    init_streamclass(v);\r
-       sq_pushregistrytable(v);\r
-       sq_pushstring(v,reg_name,-1);\r
-       sq_pushstring(v,_SC("std_stream"),-1);\r
-       if(SQ_SUCCEEDED(sq_get(v,-3))) {\r
-               sq_newclass(v,SQTrue);\r
-               sq_settypetag(v,-1,typetag);\r
-               SQInteger i = 0;\r
-               while(methods[i].name != 0) {\r
-                       SQRegFunction &f = methods[i];\r
-                       sq_pushstring(v,f.name,-1);\r
-                       sq_newclosure(v,f.f,0);\r
-                       sq_setparamscheck(v,f.nparamscheck,f.typemask);\r
-                       sq_setnativeclosurename(v,-1,f.name);\r
-                       sq_createslot(v,-3);\r
-                       i++;\r
-               }\r
-               sq_createslot(v,-3);\r
-               sq_pop(v,1);\r
-               \r
-               i = 0;\r
-               while(globals[i].name!=0)\r
-               {\r
-                       SQRegFunction &f = globals[i];\r
-                       sq_pushstring(v,f.name,-1);\r
-                       sq_newclosure(v,f.f,0);\r
-                       sq_setparamscheck(v,f.nparamscheck,f.typemask);\r
-                       sq_setnativeclosurename(v,-1,f.name);\r
-                       sq_createslot(v,-3);\r
-                       i++;\r
-               }\r
-               //register the class in the target table\r
-               sq_pushstring(v,name,-1);\r
-               sq_pushregistrytable(v);\r
-               sq_pushstring(v,reg_name,-1);\r
-               sq_get(v,-2);\r
-               sq_remove(v,-2);\r
-               sq_createslot(v,-3);\r
-\r
-               sq_settop(v,top);\r
-               return SQ_OK;\r
-       }\r
-       sq_settop(v,top);\r
-       return SQ_ERROR;\r
-}\r
+/* see copyright notice in squirrel.h */
+#include <new>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <squirrel.h>
+#include <sqstdio.h>
+#include <sqstdblob.h>
+#include "sqstdstream.h"
+#include "sqstdblobimpl.h"
+
+#define SETUP_STREAM(v) \
+       SQStream *self = NULL; \
+       if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_STREAM_TYPE_TAG))) \
+               return sq_throwerror(v,_SC("invalid type tag")); \
+       if(!self->IsValid())  \
+               return sq_throwerror(v,_SC("the stream is invalid"));
+
+SQInteger _stream_readblob(HSQUIRRELVM v)
+{
+       SETUP_STREAM(v);
+       SQUserPointer data,blobp;
+       SQInteger size,res;
+       sq_getinteger(v,2,&size);
+       if(size > self->Len()) {
+               size = self->Len();
+       }
+       data = sq_getscratchpad(v,size);
+       res = self->Read(data,size);
+       if(res <= 0)
+               return sq_throwerror(v,_SC("no data left to read"));
+       blobp = sqstd_createblob(v,res);
+       memcpy(blobp,data,res);
+       return 1;
+}
+
+#define SAFE_READN(ptr,len) { \
+       if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \
+       }
+SQInteger _stream_readn(HSQUIRRELVM v)
+{
+       SETUP_STREAM(v);
+       SQInteger format;
+       sq_getinteger(v, 2, &format);
+       switch(format) {
+       case 'l': {
+               SQInteger i;
+               SAFE_READN(&i, sizeof(i));
+               sq_pushinteger(v, i);
+                         }
+               break;
+       case 'i': {
+               SQInt32 i;
+               SAFE_READN(&i, sizeof(i));
+               sq_pushinteger(v, i);
+                         }
+               break;
+       case 's': {
+               short s;
+               SAFE_READN(&s, sizeof(short));
+               sq_pushinteger(v, s);
+                         }
+               break;
+       case 'w': {
+               unsigned short w;
+               SAFE_READN(&w, sizeof(unsigned short));
+               sq_pushinteger(v, w);
+                         }
+               break;
+       case 'c': {
+               char c;
+               SAFE_READN(&c, sizeof(char));
+               sq_pushinteger(v, c);
+                         }
+               break;
+       case 'b': {
+               unsigned char c;
+               SAFE_READN(&c, sizeof(unsigned char));
+               sq_pushinteger(v, c);
+                         }
+               break;
+       case 'f': {
+               float f;
+               SAFE_READN(&f, sizeof(float));
+               sq_pushfloat(v, f);
+                         }
+               break;
+       case 'd': {
+               double d;
+               SAFE_READN(&d, sizeof(double));
+               sq_pushfloat(v, (SQFloat)d);
+                         }
+               break;
+       default:
+               return sq_throwerror(v, _SC("invalid format"));
+       }
+       return 1;
+}
+
+SQInteger _stream_writeblob(HSQUIRRELVM v)
+{
+       SQUserPointer data;
+       SQInteger size;
+       SETUP_STREAM(v);
+       if(SQ_FAILED(sqstd_getblob(v,2,&data)))
+               return sq_throwerror(v,_SC("invalid parameter"));
+       size = sqstd_getblobsize(v,2);
+       if(self->Write(data,size) != size)
+               return sq_throwerror(v,_SC("io error"));
+       sq_pushinteger(v,size);
+       return 1;
+}
+
+SQInteger _stream_writen(HSQUIRRELVM v)
+{
+       SETUP_STREAM(v);
+       SQInteger format, ti;
+       SQFloat tf;
+       sq_getinteger(v, 3, &format);
+       switch(format) {
+       case 'l': {
+               SQInteger i;
+               sq_getinteger(v, 2, &ti);
+               i = ti;
+               self->Write(&i, sizeof(SQInteger));
+                         }
+               break;
+       case 'i': {
+               SQInt32 i;
+               sq_getinteger(v, 2, &ti);
+               i = (SQInt32)ti;
+               self->Write(&i, sizeof(SQInt32));
+                         }
+               break;
+       case 's': {
+               short s;
+               sq_getinteger(v, 2, &ti);
+               s = (short)ti;
+               self->Write(&s, sizeof(short));
+                         }
+               break;
+       case 'w': {
+               unsigned short w;
+               sq_getinteger(v, 2, &ti);
+               w = (unsigned short)ti;
+               self->Write(&w, sizeof(unsigned short));
+                         }
+               break;
+       case 'c': {
+               char c;
+               sq_getinteger(v, 2, &ti);
+               c = (char)ti;
+               self->Write(&c, sizeof(char));
+                                 }
+               break;
+       case 'b': {
+               unsigned char b;
+               sq_getinteger(v, 2, &ti);
+               b = (unsigned char)ti;
+               self->Write(&b, sizeof(unsigned char));
+                         }
+               break;
+       case 'f': {
+               float f;
+               sq_getfloat(v, 2, &tf);
+               f = tf;
+               self->Write(&f, sizeof(float));
+                         }
+               break;
+       case 'd': {
+               double d;
+               sq_getfloat(v, 2, &tf);
+               d = tf;
+               self->Write(&d, sizeof(double));
+                         }
+               break;
+       default:
+               return sq_throwerror(v, _SC("invalid format"));
+       }
+       return 0;
+}
+
+SQInteger _stream_seek(HSQUIRRELVM v)
+{
+       SETUP_STREAM(v);
+       SQInteger offset, origin = SQ_SEEK_SET;
+       sq_getinteger(v, 2, &offset);
+       if(sq_gettop(v) > 2) {
+               SQInteger t;
+               sq_getinteger(v, 3, &t);
+               switch(t) {
+                       case 'b': origin = SQ_SEEK_SET; break;
+                       case 'c': origin = SQ_SEEK_CUR; break;
+                       case 'e': origin = SQ_SEEK_END; break;
+                       default: return sq_throwerror(v,_SC("invalid origin"));
+               }
+       }
+       sq_pushinteger(v, self->Seek(offset, origin));
+       return 1;
+}
+
+SQInteger _stream_tell(HSQUIRRELVM v)
+{
+       SETUP_STREAM(v);
+       sq_pushinteger(v, self->Tell());
+       return 1;
+}
+
+SQInteger _stream_len(HSQUIRRELVM v)
+{
+       SETUP_STREAM(v);
+       sq_pushinteger(v, self->Len());
+       return 1;
+}
+
+SQInteger _stream_flush(HSQUIRRELVM v)
+{
+       SETUP_STREAM(v);
+       if(!self->Flush())
+               sq_pushinteger(v, 1);
+       else
+               sq_pushnull(v);
+       return 1;
+}
+
+SQInteger _stream_eos(HSQUIRRELVM v)
+{
+       SETUP_STREAM(v);
+       if(self->EOS())
+               sq_pushinteger(v, 1);
+       else
+               sq_pushnull(v);
+       return 1;
+}
+
+static SQRegFunction _stream_methods[] = {
+       _DECL_STREAM_FUNC(readblob,2,_SC("xn")),
+       _DECL_STREAM_FUNC(readn,2,_SC("xn")),
+       _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")),
+       _DECL_STREAM_FUNC(writen,3,_SC("xnn")),
+       _DECL_STREAM_FUNC(seek,-2,_SC("xnn")),
+       _DECL_STREAM_FUNC(tell,1,_SC("x")),
+       _DECL_STREAM_FUNC(len,1,_SC("x")),
+       _DECL_STREAM_FUNC(eos,1,_SC("x")),
+       _DECL_STREAM_FUNC(flush,1,_SC("x")),
+       {0,0}
+};
+
+void init_streamclass(HSQUIRRELVM v)
+{
+       sq_pushregistrytable(v);
+       sq_pushstring(v,_SC("std_stream"),-1);
+       if(SQ_FAILED(sq_get(v,-2))) {
+               sq_pushstring(v,_SC("std_stream"),-1);
+               sq_newclass(v,SQFalse);
+               sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG);
+               SQInteger i = 0;
+               while(_stream_methods[i].name != 0) {
+                       SQRegFunction &f = _stream_methods[i];
+                       sq_pushstring(v,f.name,-1);
+                       sq_newclosure(v,f.f,0);
+                       sq_setparamscheck(v,f.nparamscheck,f.typemask);
+                       sq_createslot(v,-3);
+                       i++;
+               }
+               sq_createslot(v,-3);
+               sq_pushroottable(v);
+               sq_pushstring(v,_SC("stream"),-1);
+               sq_pushstring(v,_SC("std_stream"),-1);
+               sq_get(v,-4);
+               sq_createslot(v,-3);
+               sq_pop(v,1);
+       }
+       else {
+               sq_pop(v,1); //result
+       }
+       sq_pop(v,1);
+}
+
+SQRESULT declare_stream(HSQUIRRELVM v,SQChar* name,SQUserPointer typetag,SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals)
+{
+       if(sq_gettype(v,-1) != OT_TABLE)
+               return sq_throwerror(v,_SC("table expected"));
+       SQInteger top = sq_gettop(v);
+       //create delegate
+    init_streamclass(v);
+       sq_pushregistrytable(v);
+       sq_pushstring(v,reg_name,-1);
+       sq_pushstring(v,_SC("std_stream"),-1);
+       if(SQ_SUCCEEDED(sq_get(v,-3))) {
+               sq_newclass(v,SQTrue);
+               sq_settypetag(v,-1,typetag);
+               SQInteger i = 0;
+               while(methods[i].name != 0) {
+                       SQRegFunction &f = methods[i];
+                       sq_pushstring(v,f.name,-1);
+                       sq_newclosure(v,f.f,0);
+                       sq_setparamscheck(v,f.nparamscheck,f.typemask);
+                       sq_setnativeclosurename(v,-1,f.name);
+                       sq_createslot(v,-3);
+                       i++;
+               }
+               sq_createslot(v,-3);
+               sq_pop(v,1);
+
+               i = 0;
+               while(globals[i].name!=0)
+               {
+                       SQRegFunction &f = globals[i];
+                       sq_pushstring(v,f.name,-1);
+                       sq_newclosure(v,f.f,0);
+                       sq_setparamscheck(v,f.nparamscheck,f.typemask);
+                       sq_setnativeclosurename(v,-1,f.name);
+                       sq_createslot(v,-3);
+                       i++;
+               }
+               //register the class in the target table
+               sq_pushstring(v,name,-1);
+               sq_pushregistrytable(v);
+               sq_pushstring(v,reg_name,-1);
+               sq_get(v,-2);
+               sq_remove(v,-2);
+               sq_createslot(v,-3);
+
+               sq_settop(v,top);
+               return SQ_OK;
+       }
+       sq_settop(v,top);
+       return SQ_ERROR;
+}
index 6f562da..6b5bb9d 100644 (file)
@@ -1,18 +1,18 @@
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQSTD_STREAM_H_\r
-#define _SQSTD_STREAM_H_\r
-\r
-SQInteger _stream_readblob(HSQUIRRELVM v);\r
-SQInteger _stream_readline(HSQUIRRELVM v);\r
-SQInteger _stream_readn(HSQUIRRELVM v);\r
-SQInteger _stream_writeblob(HSQUIRRELVM v);\r
-SQInteger _stream_writen(HSQUIRRELVM v);\r
-SQInteger _stream_seek(HSQUIRRELVM v);\r
-SQInteger _stream_tell(HSQUIRRELVM v);\r
-SQInteger _stream_len(HSQUIRRELVM v);\r
-SQInteger _stream_eos(HSQUIRRELVM v);\r
-SQInteger _stream_flush(HSQUIRRELVM v);\r
-\r
-#define _DECL_STREAM_FUNC(name,nparams,typecheck) {_SC(#name),_stream_##name,nparams,typecheck}\r
-SQRESULT declare_stream(HSQUIRRELVM v,SQChar* name,SQUserPointer typetag,SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals);\r
-#endif /*_SQSTD_STREAM_H_*/\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQSTD_STREAM_H_
+#define _SQSTD_STREAM_H_
+
+SQInteger _stream_readblob(HSQUIRRELVM v);
+SQInteger _stream_readline(HSQUIRRELVM v);
+SQInteger _stream_readn(HSQUIRRELVM v);
+SQInteger _stream_writeblob(HSQUIRRELVM v);
+SQInteger _stream_writen(HSQUIRRELVM v);
+SQInteger _stream_seek(HSQUIRRELVM v);
+SQInteger _stream_tell(HSQUIRRELVM v);
+SQInteger _stream_len(HSQUIRRELVM v);
+SQInteger _stream_eos(HSQUIRRELVM v);
+SQInteger _stream_flush(HSQUIRRELVM v);
+
+#define _DECL_STREAM_FUNC(name,nparams,typecheck) {_SC(#name),_stream_##name,nparams,typecheck}
+SQRESULT declare_stream(HSQUIRRELVM v,SQChar* name,SQUserPointer typetag,SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals);
+#endif /*_SQSTD_STREAM_H_*/
index 832f3aa..d500012 100644 (file)
-/* see copyright notice in squirrel.h */\r
-#include <squirrel.h>\r
-#include <sqstdstring.h>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <ctype.h>\r
-#include <assert.h>\r
-\r
-#ifdef _UNICODE\r
-#define scstrchr wcschr\r
-#define scsnprintf wsnprintf\r
-#define scatoi _wtoi\r
-#define scstrtok wcstok\r
-#else\r
-#define scstrchr strchr\r
-#define scsnprintf snprintf\r
-#define scatoi atoi\r
-#define scstrtok strtok\r
-#endif\r
-#define MAX_FORMAT_LEN 20\r
-#define MAX_WFORMAT_LEN        3\r
-#define ADDITIONAL_FORMAT_SPACE (100*sizeof(SQChar))\r
-\r
-static SQInteger validate_format(HSQUIRRELVM v, SQChar *fmt, const SQChar *src, SQInteger n,SQInteger &width)\r
-{\r
-       SQChar swidth[MAX_WFORMAT_LEN];\r
-       SQInteger wc = 0;\r
-       SQInteger start = n;\r
-       fmt[0] = '%';\r
-       while (scstrchr(_SC("-+ #0"), src[n])) n++;\r
-       while (scisdigit(src[n])) {\r
-               swidth[wc] = src[n];\r
-               n++;\r
-               wc++;\r
-               if(wc>=MAX_WFORMAT_LEN)\r
-                       return sq_throwerror(v,_SC("width format too long"));\r
-       }\r
-       swidth[wc] = '\0';\r
-       if(wc > 0) {\r
-               width = scatoi(swidth);\r
-       }\r
-       else\r
-               width = 0;\r
-       if (src[n] == '.') {\r
-           n++;\r
-       \r
-               wc = 0;\r
-               while (scisdigit(src[n])) {\r
-                       swidth[wc] = src[n];\r
-                       n++;\r
-                       wc++;\r
-                       if(wc>=MAX_WFORMAT_LEN)\r
-                               return sq_throwerror(v,_SC("precision format too long"));\r
-               }\r
-               swidth[wc] = '\0';\r
-               if(wc > 0) {\r
-                       width += scatoi(swidth);\r
-               }\r
-       }\r
-       if (n-start > MAX_FORMAT_LEN )\r
-               return sq_throwerror(v,_SC("format too long"));\r
-       memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(SQChar));\r
-       fmt[(n-start)+2] = '\0';\r
-       return n;\r
-}\r
-\r
-static SQInteger _string_format(HSQUIRRELVM v)\r
-{\r
-       const SQChar *format;\r
-       SQChar *dest;\r
-       SQChar fmt[MAX_FORMAT_LEN];\r
-       sq_getstring(v,2,&format);\r
-       SQInteger allocated = (sq_getsize(v,2)+1)*sizeof(SQChar);\r
-       dest = sq_getscratchpad(v,allocated);\r
-       SQInteger n = 0,i = 0, nparam = 3, w = 0;\r
-       while(format[n] != '\0') {\r
-               if(format[n] != '%') {\r
-                       assert(i < allocated);\r
-                       dest[i++] = format[n];\r
-                       n++;\r
-               }\r
-               else if(format[n+1] == '%') { //handles %%\r
-                               dest[i++] = '%';\r
-                               n += 2; \r
-               }\r
-               else {\r
-                       n++;\r
-                       if( nparam > sq_gettop(v) )\r
-                               return sq_throwerror(v,_SC("not enough paramters for the given format string"));\r
-                       n = validate_format(v,fmt,format,n,w);\r
-                       if(n < 0) return -1;\r
-                       SQInteger addlen = 0;\r
-                       SQInteger valtype = 0;\r
-                       const SQChar *ts;\r
-                       SQInteger ti;\r
-                       SQFloat tf;\r
-                       switch(format[n]) {\r
-                       case 's':\r
-                               if(SQ_FAILED(sq_getstring(v,nparam,&ts))) \r
-                                       return sq_throwerror(v,_SC("string expected for the specified format"));\r
-                               addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar));\r
-                               valtype = 's';\r
-                               break;\r
-                       case 'i': case 'd': case 'c':case 'o':  case 'u':  case 'x':  case 'X':\r
-                               if(SQ_FAILED(sq_getinteger(v,nparam,&ti))) \r
-                                       return sq_throwerror(v,_SC("integer expected for the specified format"));\r
-                               addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));\r
-                               valtype = 'i';\r
-                               break;\r
-                       case 'f': case 'g': case 'G': case 'e':  case 'E':\r
-                               if(SQ_FAILED(sq_getfloat(v,nparam,&tf))) \r
-                                       return sq_throwerror(v,_SC("float expected for the specified format"));\r
-                               addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));\r
-                               valtype = 'f';\r
-                               break;\r
-                       default:\r
-                               return sq_throwerror(v,_SC("invalid format"));\r
-                       }\r
-                       n++;\r
-                       allocated += addlen;\r
-                       dest = sq_getscratchpad(v,allocated);\r
-                       switch(valtype) {\r
-                       case 's': i += scsprintf(&dest[i],fmt,ts); break;\r
-                       case 'i': i += scsprintf(&dest[i],fmt,ti); break;\r
-                       case 'f': i += scsprintf(&dest[i],fmt,tf); break;\r
-                       };\r
-                       nparam ++;\r
-               }\r
-       }\r
-       sq_pushstring(v,dest,i);\r
-       return 1;\r
-}\r
-\r
-static void __strip_l(const SQChar *str,const SQChar **start)\r
-{\r
-       const SQChar *t = str;\r
-       while(((*t) != '\0') && scisspace(*t)){ t++; }\r
-       *start = t;\r
-}\r
-\r
-static void __strip_r(const SQChar *str,SQInteger len,const SQChar **end)\r
-{\r
-       if(len == 0) {\r
-               *end = str;\r
-               return;\r
-       }\r
-       const SQChar *t = &str[len-1];\r
-       while(t != str && scisspace(*t)) { t--; }\r
-       *end = t+1;\r
-}\r
-\r
-static SQInteger _string_strip(HSQUIRRELVM v)\r
-{\r
-       const SQChar *str,*start,*end;\r
-       sq_getstring(v,2,&str);\r
-       SQInteger len = sq_getsize(v,2);\r
-       __strip_l(str,&start);\r
-       __strip_r(str,len,&end);\r
-       sq_pushstring(v,start,end - start);\r
-       return 1;\r
-}\r
-\r
-static SQInteger _string_lstrip(HSQUIRRELVM v)\r
-{\r
-       const SQChar *str,*start;\r
-       sq_getstring(v,2,&str);\r
-       __strip_l(str,&start);\r
-       sq_pushstring(v,start,-1);\r
-       return 1;\r
-}\r
-\r
-static SQInteger _string_rstrip(HSQUIRRELVM v)\r
-{\r
-       const SQChar *str,*end;\r
-       sq_getstring(v,2,&str);\r
-       SQInteger len = sq_getsize(v,2);\r
-       __strip_r(str,len,&end);\r
-       sq_pushstring(v,str,end - str);\r
-       return 1;\r
-}\r
-\r
-static SQInteger _string_split(HSQUIRRELVM v)\r
-{\r
-       const SQChar *str,*seps;\r
-       SQChar *stemp,*tok;\r
-       sq_getstring(v,2,&str);\r
-       sq_getstring(v,3,&seps);\r
-       if(sq_getsize(v,3) == 0) return sq_throwerror(v,_SC("empty separators string"));\r
-       SQInteger memsize = (sq_getsize(v,2)+1)*sizeof(SQChar);\r
-       stemp = sq_getscratchpad(v,memsize);\r
-       memcpy(stemp,str,memsize);\r
-       tok = scstrtok(stemp,seps);\r
-       sq_newarray(v,0);\r
-       while( tok != NULL ) {\r
-               sq_pushstring(v,tok,-1);\r
-               sq_arrayappend(v,-2);\r
-               tok = scstrtok( NULL, seps );\r
-       }\r
-       return 1;\r
-}\r
-\r
-#define SETUP_REX(v) \\r
-       SQRex *self = NULL; \\r
-       sq_getinstanceup(v,1,(SQUserPointer *)&self,0); \r
-\r
-static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger size)\r
-{\r
-       SQRex *self = ((SQRex *)p);\r
-       sqstd_rex_free(self);\r
-       return 1;\r
-}\r
-\r
-static SQInteger _regexp_match(HSQUIRRELVM v)\r
-{\r
-       SETUP_REX(v);\r
-       const SQChar *str;\r
-       sq_getstring(v,2,&str);\r
-       if(sqstd_rex_match(self,str) == SQTrue)\r
-       {\r
-               sq_pushbool(v,SQTrue);\r
-               return 1;\r
-       }\r
-       sq_pushbool(v,SQFalse);\r
-       return 1;\r
-}\r
-\r
-static void _addrexmatch(HSQUIRRELVM v,const SQChar *str,const SQChar *begin,const SQChar *end)\r
-{\r
-       sq_newtable(v);\r
-       sq_pushstring(v,_SC("begin"),-1);\r
-       sq_pushinteger(v,begin - str);\r
-       sq_rawset(v,-3);\r
-       sq_pushstring(v,_SC("end"),-1);\r
-       sq_pushinteger(v,end - str);\r
-       sq_rawset(v,-3);\r
-}\r
-\r
-static SQInteger _regexp_search(HSQUIRRELVM v)\r
-{\r
-       SETUP_REX(v);\r
-       const SQChar *str,*begin,*end;\r
-       SQInteger start = 0;\r
-       sq_getstring(v,2,&str);\r
-       if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);\r
-       if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {\r
-               _addrexmatch(v,str,begin,end);\r
-               return 1;\r
-       }\r
-       return 0;\r
-}\r
-\r
-static SQInteger _regexp_capture(HSQUIRRELVM v)\r
-{\r
-       SETUP_REX(v);\r
-       const SQChar *str,*begin,*end;\r
-       SQInteger start = 0;\r
-       sq_getstring(v,2,&str);\r
-       if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);\r
-       if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {\r
-               SQInteger n = sqstd_rex_getsubexpcount(self);\r
-               SQRexMatch match;\r
-               sq_newarray(v,0);\r
-               for(SQInteger i = 0;i < n; i++) {\r
-                       sqstd_rex_getsubexp(self,i,&match);\r
-                       if(match.len > 0)\r
-                               _addrexmatch(v,str,match.begin,match.begin+match.len);\r
-                       else\r
-                               _addrexmatch(v,str,str,str); //empty match\r
-                       sq_arrayappend(v,-2);\r
-               }\r
-               return 1;\r
-       }\r
-       return 0;\r
-}\r
-\r
-static SQInteger _regexp_subexpcount(HSQUIRRELVM v)\r
-{\r
-       SETUP_REX(v);\r
-       sq_pushinteger(v,sqstd_rex_getsubexpcount(self));\r
-       return 1;\r
-}\r
-\r
-static SQInteger _regexp_constructor(HSQUIRRELVM v)\r
-{\r
-       const SQChar *error,*pattern;\r
-       sq_getstring(v,2,&pattern);\r
-       SQRex *rex = sqstd_rex_compile(pattern,&error);\r
-       if(!rex) return sq_throwerror(v,error);\r
-       sq_setinstanceup(v,1,rex);\r
-       sq_setreleasehook(v,1,_rexobj_releasehook);\r
-       return 0;\r
-}\r
-\r
-static SQInteger _regexp__typeof(HSQUIRRELVM v)\r
-{\r
-       sq_pushstring(v,_SC("regexp"),-1);\r
-       return 1;\r
-}\r
-\r
-#define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask}\r
-static SQRegFunction rexobj_funcs[]={\r
-       _DECL_REX_FUNC(constructor,2,_SC(".s")),\r
-       _DECL_REX_FUNC(search,-2,_SC("xsn")),\r
-       _DECL_REX_FUNC(match,2,_SC("xs")),\r
-       _DECL_REX_FUNC(capture,-2,_SC("xsn")),\r
-       _DECL_REX_FUNC(subexpcount,1,_SC("x")),\r
-       _DECL_REX_FUNC(_typeof,1,_SC("x")),\r
-       {0,0}\r
-};\r
-\r
-#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask}\r
-static SQRegFunction stringlib_funcs[]={\r
-       _DECL_FUNC(format,-2,_SC(".s")),\r
-       _DECL_FUNC(strip,2,_SC(".s")),\r
-       _DECL_FUNC(lstrip,2,_SC(".s")),\r
-       _DECL_FUNC(rstrip,2,_SC(".s")),\r
-       _DECL_FUNC(split,3,_SC(".ss")),\r
-       {0,0}\r
-};\r
-\r
-\r
-SQInteger sqstd_register_stringlib(HSQUIRRELVM v)\r
-{\r
-       sq_pushstring(v,_SC("regexp"),-1);\r
-       sq_newclass(v,SQFalse);\r
-       SQInteger i = 0;\r
-       while(rexobj_funcs[i].name != 0) {\r
-               SQRegFunction &f = rexobj_funcs[i];\r
-               sq_pushstring(v,f.name,-1);\r
-               sq_newclosure(v,f.f,0);\r
-               sq_setparamscheck(v,f.nparamscheck,f.typemask);\r
-               sq_setnativeclosurename(v,-1,f.name);\r
-               sq_createslot(v,-3);\r
-               i++;\r
-       }\r
-       sq_createslot(v,-3);\r
-\r
-       i = 0;\r
-       while(stringlib_funcs[i].name!=0)\r
-       {\r
-               sq_pushstring(v,stringlib_funcs[i].name,-1);\r
-               sq_newclosure(v,stringlib_funcs[i].f,0);\r
-               sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask);\r
-               sq_setnativeclosurename(v,-1,stringlib_funcs[i].name);\r
-               sq_createslot(v,-3);\r
-               i++;\r
-       }\r
-       return 1;\r
-}\r
+/* see copyright notice in squirrel.h */
+#include <squirrel.h>
+#include <sqstdstring.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <assert.h>
+
+#ifdef _UNICODE
+#define scstrchr wcschr
+#define scsnprintf wsnprintf
+#define scatoi _wtoi
+#define scstrtok wcstok
+#else
+#define scstrchr strchr
+#define scsnprintf snprintf
+#define scatoi atoi
+#define scstrtok strtok
+#endif
+#define MAX_FORMAT_LEN 20
+#define MAX_WFORMAT_LEN        3
+#define ADDITIONAL_FORMAT_SPACE (100*sizeof(SQChar))
+
+static SQInteger validate_format(HSQUIRRELVM v, SQChar *fmt, const SQChar *src, SQInteger n,SQInteger &width)
+{
+       SQChar swidth[MAX_WFORMAT_LEN];
+       SQInteger wc = 0;
+       SQInteger start = n;
+       fmt[0] = '%';
+       while (scstrchr(_SC("-+ #0"), src[n])) n++;
+       while (scisdigit(src[n])) {
+               swidth[wc] = src[n];
+               n++;
+               wc++;
+               if(wc>=MAX_WFORMAT_LEN)
+                       return sq_throwerror(v,_SC("width format too long"));
+       }
+       swidth[wc] = '\0';
+       if(wc > 0) {
+               width = scatoi(swidth);
+       }
+       else
+               width = 0;
+       if (src[n] == '.') {
+           n++;
+
+               wc = 0;
+               while (scisdigit(src[n])) {
+                       swidth[wc] = src[n];
+                       n++;
+                       wc++;
+                       if(wc>=MAX_WFORMAT_LEN)
+                               return sq_throwerror(v,_SC("precision format too long"));
+               }
+               swidth[wc] = '\0';
+               if(wc > 0) {
+                       width += scatoi(swidth);
+               }
+       }
+       if (n-start > MAX_FORMAT_LEN )
+               return sq_throwerror(v,_SC("format too long"));
+       memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(SQChar));
+       fmt[(n-start)+2] = '\0';
+       return n;
+}
+
+static SQInteger _string_format(HSQUIRRELVM v)
+{
+       const SQChar *format;
+       SQChar *dest;
+       SQChar fmt[MAX_FORMAT_LEN];
+       sq_getstring(v,2,&format);
+       SQInteger allocated = (sq_getsize(v,2)+1)*sizeof(SQChar);
+       dest = sq_getscratchpad(v,allocated);
+       SQInteger n = 0,i = 0, nparam = 3, w = 0;
+       while(format[n] != '\0') {
+               if(format[n] != '%') {
+                       assert(i < allocated);
+                       dest[i++] = format[n];
+                       n++;
+               }
+               else if(format[n+1] == '%') { //handles %%
+                               dest[i++] = '%';
+                               n += 2;
+               }
+               else {
+                       n++;
+                       if( nparam > sq_gettop(v) )
+                               return sq_throwerror(v,_SC("not enough paramters for the given format string"));
+                       n = validate_format(v,fmt,format,n,w);
+                       if(n < 0) return -1;
+                       SQInteger addlen = 0;
+                       SQInteger valtype = 0;
+                       const SQChar *ts;
+                       SQInteger ti;
+                       SQFloat tf;
+                       switch(format[n]) {
+                       case 's':
+                               if(SQ_FAILED(sq_getstring(v,nparam,&ts)))
+                                       return sq_throwerror(v,_SC("string expected for the specified format"));
+                               addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar));
+                               valtype = 's';
+                               break;
+                       case 'i': case 'd': case 'c':case 'o':  case 'u':  case 'x':  case 'X':
+                               if(SQ_FAILED(sq_getinteger(v,nparam,&ti)))
+                                       return sq_throwerror(v,_SC("integer expected for the specified format"));
+                               addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
+                               valtype = 'i';
+                               break;
+                       case 'f': case 'g': case 'G': case 'e':  case 'E':
+                               if(SQ_FAILED(sq_getfloat(v,nparam,&tf)))
+                                       return sq_throwerror(v,_SC("float expected for the specified format"));
+                               addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
+                               valtype = 'f';
+                               break;
+                       default:
+                               return sq_throwerror(v,_SC("invalid format"));
+                       }
+                       n++;
+                       allocated += addlen;
+                       dest = sq_getscratchpad(v,allocated);
+                       switch(valtype) {
+                       case 's': i += scsprintf(&dest[i],fmt,ts); break;
+                       case 'i': i += scsprintf(&dest[i],fmt,ti); break;
+                       case 'f': i += scsprintf(&dest[i],fmt,tf); break;
+                       };
+                       nparam ++;
+               }
+       }
+       sq_pushstring(v,dest,i);
+       return 1;
+}
+
+static void __strip_l(const SQChar *str,const SQChar **start)
+{
+       const SQChar *t = str;
+       while(((*t) != '\0') && scisspace(*t)){ t++; }
+       *start = t;
+}
+
+static void __strip_r(const SQChar *str,SQInteger len,const SQChar **end)
+{
+       if(len == 0) {
+               *end = str;
+               return;
+       }
+       const SQChar *t = &str[len-1];
+       while(t != str && scisspace(*t)) { t--; }
+       *end = t+1;
+}
+
+static SQInteger _string_strip(HSQUIRRELVM v)
+{
+       const SQChar *str,*start,*end;
+       sq_getstring(v,2,&str);
+       SQInteger len = sq_getsize(v,2);
+       __strip_l(str,&start);
+       __strip_r(str,len,&end);
+       sq_pushstring(v,start,end - start);
+       return 1;
+}
+
+static SQInteger _string_lstrip(HSQUIRRELVM v)
+{
+       const SQChar *str,*start;
+       sq_getstring(v,2,&str);
+       __strip_l(str,&start);
+       sq_pushstring(v,start,-1);
+       return 1;
+}
+
+static SQInteger _string_rstrip(HSQUIRRELVM v)
+{
+       const SQChar *str,*end;
+       sq_getstring(v,2,&str);
+       SQInteger len = sq_getsize(v,2);
+       __strip_r(str,len,&end);
+       sq_pushstring(v,str,end - str);
+       return 1;
+}
+
+static SQInteger _string_split(HSQUIRRELVM v)
+{
+       const SQChar *str,*seps;
+       SQChar *stemp,*tok;
+       sq_getstring(v,2,&str);
+       sq_getstring(v,3,&seps);
+       if(sq_getsize(v,3) == 0) return sq_throwerror(v,_SC("empty separators string"));
+       SQInteger memsize = (sq_getsize(v,2)+1)*sizeof(SQChar);
+       stemp = sq_getscratchpad(v,memsize);
+       memcpy(stemp,str,memsize);
+       tok = scstrtok(stemp,seps);
+       sq_newarray(v,0);
+       while( tok != NULL ) {
+               sq_pushstring(v,tok,-1);
+               sq_arrayappend(v,-2);
+               tok = scstrtok( NULL, seps );
+       }
+       return 1;
+}
+
+#define SETUP_REX(v) \
+       SQRex *self = NULL; \
+       sq_getinstanceup(v,1,(SQUserPointer *)&self,0);
+
+static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger size)
+{
+       SQRex *self = ((SQRex *)p);
+       sqstd_rex_free(self);
+       return 1;
+}
+
+static SQInteger _regexp_match(HSQUIRRELVM v)
+{
+       SETUP_REX(v);
+       const SQChar *str;
+       sq_getstring(v,2,&str);
+       if(sqstd_rex_match(self,str) == SQTrue)
+       {
+               sq_pushbool(v,SQTrue);
+               return 1;
+       }
+       sq_pushbool(v,SQFalse);
+       return 1;
+}
+
+static void _addrexmatch(HSQUIRRELVM v,const SQChar *str,const SQChar *begin,const SQChar *end)
+{
+       sq_newtable(v);
+       sq_pushstring(v,_SC("begin"),-1);
+       sq_pushinteger(v,begin - str);
+       sq_rawset(v,-3);
+       sq_pushstring(v,_SC("end"),-1);
+       sq_pushinteger(v,end - str);
+       sq_rawset(v,-3);
+}
+
+static SQInteger _regexp_search(HSQUIRRELVM v)
+{
+       SETUP_REX(v);
+       const SQChar *str,*begin,*end;
+       SQInteger start = 0;
+       sq_getstring(v,2,&str);
+       if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
+       if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
+               _addrexmatch(v,str,begin,end);
+               return 1;
+       }
+       return 0;
+}
+
+static SQInteger _regexp_capture(HSQUIRRELVM v)
+{
+       SETUP_REX(v);
+       const SQChar *str,*begin,*end;
+       SQInteger start = 0;
+       sq_getstring(v,2,&str);
+       if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
+       if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
+               SQInteger n = sqstd_rex_getsubexpcount(self);
+               SQRexMatch match;
+               sq_newarray(v,0);
+               for(SQInteger i = 0;i < n; i++) {
+                       sqstd_rex_getsubexp(self,i,&match);
+                       if(match.len > 0)
+                               _addrexmatch(v,str,match.begin,match.begin+match.len);
+                       else
+                               _addrexmatch(v,str,str,str); //empty match
+                       sq_arrayappend(v,-2);
+               }
+               return 1;
+       }
+       return 0;
+}
+
+static SQInteger _regexp_subexpcount(HSQUIRRELVM v)
+{
+       SETUP_REX(v);
+       sq_pushinteger(v,sqstd_rex_getsubexpcount(self));
+       return 1;
+}
+
+static SQInteger _regexp_constructor(HSQUIRRELVM v)
+{
+       const SQChar *error,*pattern;
+       sq_getstring(v,2,&pattern);
+       SQRex *rex = sqstd_rex_compile(pattern,&error);
+       if(!rex) return sq_throwerror(v,error);
+       sq_setinstanceup(v,1,rex);
+       sq_setreleasehook(v,1,_rexobj_releasehook);
+       return 0;
+}
+
+static SQInteger _regexp__typeof(HSQUIRRELVM v)
+{
+       sq_pushstring(v,_SC("regexp"),-1);
+       return 1;
+}
+
+#define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask}
+static SQRegFunction rexobj_funcs[]={
+       _DECL_REX_FUNC(constructor,2,_SC(".s")),
+       _DECL_REX_FUNC(search,-2,_SC("xsn")),
+       _DECL_REX_FUNC(match,2,_SC("xs")),
+       _DECL_REX_FUNC(capture,-2,_SC("xsn")),
+       _DECL_REX_FUNC(subexpcount,1,_SC("x")),
+       _DECL_REX_FUNC(_typeof,1,_SC("x")),
+       {0,0}
+};
+
+#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask}
+static SQRegFunction stringlib_funcs[]={
+       _DECL_FUNC(format,-2,_SC(".s")),
+       _DECL_FUNC(strip,2,_SC(".s")),
+       _DECL_FUNC(lstrip,2,_SC(".s")),
+       _DECL_FUNC(rstrip,2,_SC(".s")),
+       _DECL_FUNC(split,3,_SC(".ss")),
+       {0,0}
+};
+
+
+SQInteger sqstd_register_stringlib(HSQUIRRELVM v)
+{
+       sq_pushstring(v,_SC("regexp"),-1);
+       sq_newclass(v,SQFalse);
+       SQInteger i = 0;
+       while(rexobj_funcs[i].name != 0) {
+               SQRegFunction &f = rexobj_funcs[i];
+               sq_pushstring(v,f.name,-1);
+               sq_newclosure(v,f.f,0);
+               sq_setparamscheck(v,f.nparamscheck,f.typemask);
+               sq_setnativeclosurename(v,-1,f.name);
+               sq_createslot(v,-3);
+               i++;
+       }
+       sq_createslot(v,-3);
+
+       i = 0;
+       while(stringlib_funcs[i].name!=0)
+       {
+               sq_pushstring(v,stringlib_funcs[i].name,-1);
+               sq_newclosure(v,stringlib_funcs[i].f,0);
+               sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask);
+               sq_setnativeclosurename(v,-1,stringlib_funcs[i].name);
+               sq_createslot(v,-3);
+               i++;
+       }
+       return 1;
+}
index c7153a6..7d4200c 100644 (file)
-/* see copyright notice in squirrel.h */\r
-#include <squirrel.h>\r
-#include <time.h>\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <sqstdsystem.h>\r
-\r
-#ifdef SQUNICODE\r
-#include <wchar.h>\r
-#define scgetenv _wgetenv\r
-#define scsystem _wsystem\r
-#define scasctime _wasctime\r
-#define scremove _wremove\r
-#define screname _wrename\r
-#else\r
-#define scgetenv getenv\r
-#define scsystem system\r
-#define scasctime asctime\r
-#define scremove remove\r
-#define screname rename\r
-#endif\r
-\r
-static SQInteger _system_getenv(HSQUIRRELVM v)\r
-{\r
-       const SQChar *s;\r
-       if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){\r
-        sq_pushstring(v,scgetenv(s),-1);\r
-               return 1;\r
-       }\r
-       return 0;\r
-}\r
-\r
-\r
-static SQInteger _system_system(HSQUIRRELVM v)\r
-{\r
-       const SQChar *s;\r
-       if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){\r
-               sq_pushinteger(v,scsystem(s));\r
-               return 1;\r
-       }\r
-       return sq_throwerror(v,_SC("wrong param"));\r
-}\r
-\r
-\r
-static SQInteger _system_clock(HSQUIRRELVM v)\r
-{\r
-       sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC);\r
-       return 1;\r
-}\r
-\r
-static SQInteger _system_time(HSQUIRRELVM v)\r
-{\r
-       time_t t;\r
-       time(&t);\r
-       sq_pushinteger(v,*((SQInteger *)&t));\r
-       return 1;\r
-}\r
-\r
-static SQInteger _system_remove(HSQUIRRELVM v)\r
-{\r
-       const SQChar *s;\r
-       sq_getstring(v,2,&s);\r
-       if(scremove(s)==-1)\r
-               return sq_throwerror(v,_SC("remove() failed"));\r
-       return 0;\r
-}\r
-\r
-static SQInteger _system_rename(HSQUIRRELVM v)\r
-{\r
-       const SQChar *oldn,*newn;\r
-       sq_getstring(v,2,&oldn);\r
-       sq_getstring(v,3,&newn);\r
-       if(screname(oldn,newn)==-1)\r
-               return sq_throwerror(v,_SC("rename() failed"));\r
-       return 0;\r
-}\r
-\r
-static void _set_integer_slot(HSQUIRRELVM v,const SQChar *name,SQInteger val)\r
-{\r
-       sq_pushstring(v,name,-1);\r
-       sq_pushinteger(v,val);\r
-       sq_rawset(v,-3);\r
-}\r
-\r
-static SQInteger _system_date(HSQUIRRELVM v)\r
-{\r
-       time_t t;\r
-       SQInteger it;\r
-       SQInteger format = 'l';\r
-       if(sq_gettop(v) > 1) {\r
-               sq_getinteger(v,2,&it);\r
-               t = it;\r
-               if(sq_gettop(v) > 2) {\r
-                       sq_getinteger(v,3,(SQInteger*)&format);\r
-               }\r
-       }\r
-       else {\r
-               time(&t);\r
-       }\r
-       tm *date;\r
-    if(format == 'u')\r
-               date = gmtime(&t);\r
-       else\r
-               date = localtime(&t);\r
-       if(!date)\r
-               return sq_throwerror(v,_SC("crt api failure"));\r
-       sq_newtable(v);\r
-       _set_integer_slot(v, _SC("sec"), date->tm_sec);\r
-    _set_integer_slot(v, _SC("min"), date->tm_min);\r
-    _set_integer_slot(v, _SC("hour"), date->tm_hour);\r
-    _set_integer_slot(v, _SC("day"), date->tm_mday);\r
-    _set_integer_slot(v, _SC("month"), date->tm_mon);\r
-    _set_integer_slot(v, _SC("year"), date->tm_year+1900);\r
-    _set_integer_slot(v, _SC("wday"), date->tm_wday);\r
-    _set_integer_slot(v, _SC("yday"), date->tm_yday);\r
-       return 1;\r
-}\r
-\r
-\r
-\r
-#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask}\r
-static SQRegFunction systemlib_funcs[]={\r
-       _DECL_FUNC(getenv,2,_SC(".s")),\r
-       _DECL_FUNC(system,2,_SC(".s")),\r
-       _DECL_FUNC(clock,1,NULL),\r
-       _DECL_FUNC(time,1,NULL),\r
-       _DECL_FUNC(date,-1,_SC(".nn")),\r
-       _DECL_FUNC(remove,2,_SC(".s")),\r
-       _DECL_FUNC(rename,3,_SC(".ss")),\r
-       {0,0}\r
-};\r
-\r
-\r
-SQInteger sqstd_register_systemlib(HSQUIRRELVM v)\r
-{\r
-       SQInteger i=0;\r
-       while(systemlib_funcs[i].name!=0)\r
-       {\r
-               sq_pushstring(v,systemlib_funcs[i].name,-1);\r
-               sq_newclosure(v,systemlib_funcs[i].f,0);\r
-               sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask);\r
-               sq_setnativeclosurename(v,-1,systemlib_funcs[i].name);\r
-               sq_createslot(v,-3);\r
-               i++;\r
-       }\r
-       return 1;\r
-}\r
+/* see copyright notice in squirrel.h */
+#include <squirrel.h>
+#include <time.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sqstdsystem.h>
+
+#ifdef SQUNICODE
+#include <wchar.h>
+#define scgetenv _wgetenv
+#define scsystem _wsystem
+#define scasctime _wasctime
+#define scremove _wremove
+#define screname _wrename
+#else
+#define scgetenv getenv
+#define scsystem system
+#define scasctime asctime
+#define scremove remove
+#define screname rename
+#endif
+
+static SQInteger _system_getenv(HSQUIRRELVM v)
+{
+       const SQChar *s;
+       if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
+        sq_pushstring(v,scgetenv(s),-1);
+               return 1;
+       }
+       return 0;
+}
+
+
+static SQInteger _system_system(HSQUIRRELVM v)
+{
+       const SQChar *s;
+       if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
+               sq_pushinteger(v,scsystem(s));
+               return 1;
+       }
+       return sq_throwerror(v,_SC("wrong param"));
+}
+
+
+static SQInteger _system_clock(HSQUIRRELVM v)
+{
+       sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC);
+       return 1;
+}
+
+static SQInteger _system_time(HSQUIRRELVM v)
+{
+       time_t t;
+       time(&t);
+       sq_pushinteger(v,*((SQInteger *)&t));
+       return 1;
+}
+
+static SQInteger _system_remove(HSQUIRRELVM v)
+{
+       const SQChar *s;
+       sq_getstring(v,2,&s);
+       if(scremove(s)==-1)
+               return sq_throwerror(v,_SC("remove() failed"));
+       return 0;
+}
+
+static SQInteger _system_rename(HSQUIRRELVM v)
+{
+       const SQChar *oldn,*newn;
+       sq_getstring(v,2,&oldn);
+       sq_getstring(v,3,&newn);
+       if(screname(oldn,newn)==-1)
+               return sq_throwerror(v,_SC("rename() failed"));
+       return 0;
+}
+
+static void _set_integer_slot(HSQUIRRELVM v,const SQChar *name,SQInteger val)
+{
+       sq_pushstring(v,name,-1);
+       sq_pushinteger(v,val);
+       sq_rawset(v,-3);
+}
+
+static SQInteger _system_date(HSQUIRRELVM v)
+{
+       time_t t;
+       SQInteger it;
+       SQInteger format = 'l';
+       if(sq_gettop(v) > 1) {
+               sq_getinteger(v,2,&it);
+               t = it;
+               if(sq_gettop(v) > 2) {
+                       sq_getinteger(v,3,(SQInteger*)&format);
+               }
+       }
+       else {
+               time(&t);
+       }
+       tm *date;
+    if(format == 'u')
+               date = gmtime(&t);
+       else
+               date = localtime(&t);
+       if(!date)
+               return sq_throwerror(v,_SC("crt api failure"));
+       sq_newtable(v);
+       _set_integer_slot(v, _SC("sec"), date->tm_sec);
+    _set_integer_slot(v, _SC("min"), date->tm_min);
+    _set_integer_slot(v, _SC("hour"), date->tm_hour);
+    _set_integer_slot(v, _SC("day"), date->tm_mday);
+    _set_integer_slot(v, _SC("month"), date->tm_mon);
+    _set_integer_slot(v, _SC("year"), date->tm_year+1900);
+    _set_integer_slot(v, _SC("wday"), date->tm_wday);
+    _set_integer_slot(v, _SC("yday"), date->tm_yday);
+       return 1;
+}
+
+
+
+#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask}
+static SQRegFunction systemlib_funcs[]={
+       _DECL_FUNC(getenv,2,_SC(".s")),
+       _DECL_FUNC(system,2,_SC(".s")),
+       _DECL_FUNC(clock,1,NULL),
+       _DECL_FUNC(time,1,NULL),
+       _DECL_FUNC(date,-1,_SC(".nn")),
+       _DECL_FUNC(remove,2,_SC(".s")),
+       _DECL_FUNC(rename,3,_SC(".ss")),
+       {0,0}
+};
+
+
+SQInteger sqstd_register_systemlib(HSQUIRRELVM v)
+{
+       SQInteger i=0;
+       while(systemlib_funcs[i].name!=0)
+       {
+               sq_pushstring(v,systemlib_funcs[i].name,-1);
+               sq_newclosure(v,systemlib_funcs[i].f,0);
+               sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask);
+               sq_setnativeclosurename(v,-1,systemlib_funcs[i].name);
+               sq_createslot(v,-3);
+               i++;
+       }
+       return 1;
+}
index b17bab9..8857c9a 100644 (file)
-/*\r
-       see copyright notice in squirrel.h\r
-*/\r
-#include "sqpcheader.h"\r
-#include "sqvm.h"\r
-#include "sqstring.h"\r
-#include "sqtable.h"\r
-#include "sqarray.h"\r
-#include "sqfuncproto.h"\r
-#include "sqclosure.h"\r
-#include "squserdata.h"\r
-#include "sqcompiler.h"\r
-#include "sqfuncstate.h"\r
-#include "sqclass.h"\r
-\r
-bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPtr **o)\r
-{\r
-       *o = &stack_get(v,idx);\r
-       if(type(**o) != type){\r
-               SQObjectPtr oval = v->PrintObjVal(**o);\r
-               v->Raise_Error(_SC("wrong argument type, expected '%s' got '%.50s'"),IdType2Name(type),_stringval(oval));\r
-               return false;\r
-       }\r
-       return true;\r
-}\r
-\r
-#define _GETSAFE_OBJ(v,idx,type,o) { if(!sq_aux_gettypedarg(v,idx,type,&o)) return SQ_ERROR; }\r
-\r
-#define sq_aux_paramscheck(v,count) \\r
-{ \\r
-       if(sq_gettop(v) < count){ v->Raise_Error(_SC("not enough params in the stack")); return SQ_ERROR; }\\r
-}              \r
-\r
-SQInteger sq_aux_throwobject(HSQUIRRELVM v,SQObjectPtr &e)\r
-{\r
-       v->_lasterror = e;\r
-       return SQ_ERROR;\r
-}\r
-\r
-SQInteger sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type)\r
-{\r
-       scsprintf(_ss(v)->GetScratchPad(100), _SC("unexpected type %s"), IdType2Name(type));\r
-       return sq_throwerror(v, _ss(v)->GetScratchPad(-1));\r
-}\r
-\r
-HSQUIRRELVM sq_open(SQInteger initialstacksize)\r
-{\r
-       SQSharedState *ss;\r
-       SQVM *v;\r
-       sq_new(ss, SQSharedState);\r
-       ss->Init();\r
-       v = (SQVM *)SQ_MALLOC(sizeof(SQVM));\r
-       new (v) SQVM(ss);\r
-       ss->_root_vm = v;\r
-       if(v->Init(NULL, initialstacksize)) {\r
-               return v;\r
-       } else {\r
-               sq_delete(v, SQVM);\r
-               return NULL;\r
-       }\r
-       return v;\r
-}\r
-\r
-HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize)\r
-{\r
-       SQSharedState *ss;\r
-       SQVM *v;\r
-       ss=_ss(friendvm);\r
-       \r
-       v= (SQVM *)SQ_MALLOC(sizeof(SQVM));\r
-       new (v) SQVM(ss);\r
-       \r
-       if(v->Init(friendvm, initialstacksize)) {\r
-               friendvm->Push(v);\r
-               return v;\r
-       } else {\r
-               sq_delete(v, SQVM);\r
-               return NULL;\r
-       }\r
-}\r
-\r
-SQInteger sq_getvmstate(HSQUIRRELVM v)\r
-{\r
-       if(v->_suspended)\r
-               return SQ_VMSTATE_SUSPENDED;\r
-       else { \r
-               if(v->_callsstack.size() != 0) return SQ_VMSTATE_RUNNING;\r
-               else return SQ_VMSTATE_IDLE;\r
-       }\r
-}\r
-\r
-void sq_seterrorhandler(HSQUIRRELVM v)\r
-{\r
-       SQObject o = stack_get(v, -1);\r
-       if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {\r
-               v->_errorhandler = o;\r
-               v->Pop();\r
-       }\r
-}\r
-\r
-void sq_setdebughook(HSQUIRRELVM v)\r
-{\r
-       SQObject o = stack_get(v,-1);\r
-       if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {\r
-               v->_debughook = o;\r
-               v->Pop();\r
-       }\r
-}\r
-\r
-void sq_close(HSQUIRRELVM v)\r
-{\r
-       SQSharedState *ss = _ss(v);\r
-       _thread(ss->_root_vm)->Finalize();\r
-       sq_delete(ss, SQSharedState);\r
-}\r
-\r
-SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror)\r
-{\r
-       SQObjectPtr o;\r
-       if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) {\r
-               v->Push(SQClosure::Create(_ss(v), _funcproto(o)));\r
-               return SQ_OK;\r
-       }\r
-       return SQ_ERROR;\r
-}\r
-\r
-void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable)\r
-{\r
-       _ss(v)->_debuginfo = enable?true:false;\r
-}\r
-\r
-void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable)\r
-{\r
-       _ss(v)->_notifyallexceptions = enable?true:false;\r
-}\r
-\r
-void sq_addref(HSQUIRRELVM v,HSQOBJECT *po)\r
-{\r
-       if(!ISREFCOUNTED(type(*po))) return;\r
-       _ss(v)->_refs_table.AddRef(*po);\r
-}\r
-\r
-SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po)\r
-{\r
-       if(!ISREFCOUNTED(type(*po))) return SQTrue;\r
-       return _ss(v)->_refs_table.Release(*po);\r
-}\r
-\r
-const SQChar *sq_objtostring(HSQOBJECT *o) \r
-{\r
-       if(sq_type(*o) == OT_STRING) {\r
-               return _stringval(*o);\r
-       }\r
-       return NULL;\r
-}\r
-\r
-SQInteger sq_objtointeger(HSQOBJECT *o) \r
-{\r
-       if(sq_isnumeric(*o)) {\r
-               return tointeger(*o);\r
-       }\r
-       return 0;\r
-}\r
-\r
-SQFloat sq_objtofloat(HSQOBJECT *o) \r
-{\r
-       if(sq_isnumeric(*o)) {\r
-               return tofloat(*o);\r
-       }\r
-       return 0;\r
-}\r
-\r
-SQBool sq_objtobool(HSQOBJECT *o) \r
-{\r
-       if(sq_isbool(*o)) {\r
-               return _integer(*o);\r
-       }\r
-       return SQFalse;\r
-}\r
-\r
-void sq_pushnull(HSQUIRRELVM v)\r
-{\r
-       v->Push(_null_);\r
-}\r
-\r
-void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len)\r
-{\r
-       if(s)\r
-               v->Push(SQObjectPtr(SQString::Create(_ss(v), s, len)));\r
-       else v->Push(_null_);\r
-}\r
-\r
-void sq_pushinteger(HSQUIRRELVM v,SQInteger n)\r
-{\r
-       v->Push(n);\r
-}\r
-\r
-void sq_pushbool(HSQUIRRELVM v,SQBool b)\r
-{\r
-       v->Push(b?true:false);\r
-}\r
-\r
-void sq_pushfloat(HSQUIRRELVM v,SQFloat n)\r
-{\r
-       v->Push(n);\r
-}\r
-\r
-void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p)\r
-{\r
-       v->Push(p);\r
-}\r
-\r
-SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size)\r
-{\r
-       SQUserData *ud = SQUserData::Create(_ss(v), size);\r
-       v->Push(ud);\r
-       return ud->_val;\r
-}\r
-\r
-void sq_newtable(HSQUIRRELVM v)\r
-{\r
-       v->Push(SQTable::Create(_ss(v), 0));    \r
-}\r
-\r
-void sq_newarray(HSQUIRRELVM v,SQInteger size)\r
-{\r
-       v->Push(SQArray::Create(_ss(v), size)); \r
-}\r
-\r
-SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase)\r
-{\r
-       SQClass *baseclass = NULL;\r
-       if(hasbase) {\r
-               SQObjectPtr &base = stack_get(v,-1);\r
-               if(type(base) != OT_CLASS)\r
-                       return sq_throwerror(v,_SC("invalid base type"));\r
-               baseclass = _class(base);\r
-       }\r
-       SQClass *newclass = SQClass::Create(_ss(v), baseclass);\r
-       if(baseclass) v->Pop();\r
-       v->Push(newclass);      \r
-       return SQ_OK;\r
-}\r
-\r
-SQBool sq_instanceof(HSQUIRRELVM v)\r
-{\r
-       SQObjectPtr &inst = stack_get(v,-1);\r
-       SQObjectPtr &cl = stack_get(v,-2);\r
-       if(type(inst) != OT_INSTANCE || type(cl) != OT_CLASS)\r
-               return sq_throwerror(v,_SC("invalid param type"));\r
-       return _instance(inst)->InstanceOf(_class(cl))?SQTrue:SQFalse;\r
-}\r
-\r
-SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx)\r
-{\r
-       sq_aux_paramscheck(v,2);\r
-       SQObjectPtr *arr;\r
-       _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);\r
-       _array(*arr)->Append(v->GetUp(-1));\r
-       v->Pop(1);\r
-       return SQ_OK;\r
-}\r
-\r
-SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval)\r
-{\r
-       sq_aux_paramscheck(v, 1);\r
-       SQObjectPtr *arr;\r
-       _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);\r
-       if(_array(*arr)->Size() > 0) {\r
-        if(pushval != 0){ v->Push(_array(*arr)->Top()); }\r
-               _array(*arr)->Pop();\r
-               return SQ_OK;\r
-       }\r
-       return sq_throwerror(v, _SC("empty array"));\r
-}\r
-\r
-SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize)\r
-{\r
-       sq_aux_paramscheck(v,1);\r
-       SQObjectPtr *arr;\r
-       _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);\r
-       if(_array(*arr)->Size() > 0) {\r
-               _array(*arr)->Resize(newsize);\r
-               return SQ_OK;\r
-       }\r
-       return SQ_OK;\r
-}\r
-\r
-SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx)\r
-{\r
-       sq_aux_paramscheck(v, 1);\r
-       SQObjectPtr *o;\r
-       _GETSAFE_OBJ(v, idx, OT_ARRAY,o);\r
-       SQArray *arr = _array(*o);\r
-       if(arr->Size() > 0) {\r
-               SQObjectPtr t;\r
-               SQInteger size = arr->Size();\r
-               SQInteger n = size >> 1; size -= 1;\r
-               for(SQInteger i = 0; i < n; i++) {\r
-                       t = arr->_values[i];\r
-                       arr->_values[i] = arr->_values[size-i];\r
-                       arr->_values[size-i] = t;\r
-               }\r
-               return SQ_OK;\r
-       }\r
-       return SQ_OK;\r
-}\r
-\r
-void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars)\r
-{\r
-       SQNativeClosure *nc = SQNativeClosure::Create(_ss(v), func);\r
-       nc->_nparamscheck = 0;\r
-       for(SQUnsignedInteger i = 0; i < nfreevars; i++) {\r
-               nc->_outervalues.push_back(v->Top());\r
-               v->Pop();\r
-       }\r
-       v->Push(SQObjectPtr(nc));       \r
-}\r
-\r
-SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars)\r
-{\r
-       SQObject o = stack_get(v, idx);\r
-       if(sq_isclosure(o)) {\r
-               SQClosure *c = _closure(o);\r
-               SQFunctionProto *proto = _funcproto(c->_function);\r
-               *nparams = (SQUnsignedInteger)proto->_parameters.size();\r
-        *nfreevars = (SQUnsignedInteger)c->_outervalues.size();\r
-               return SQ_OK;\r
-       }\r
-       return sq_throwerror(v,_SC("the object is not a closure"));\r
-}\r
-\r
-SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name)\r
-{\r
-       SQObject o = stack_get(v, idx);\r
-       if(sq_isnativeclosure(o)) {\r
-               SQNativeClosure *nc = _nativeclosure(o);\r
-               nc->_name = SQString::Create(_ss(v),name);\r
-               return SQ_OK;\r
-       }\r
-       return sq_throwerror(v,_SC("the object is not a nativeclosure"));\r
-}\r
-\r
-SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask)\r
-{\r
-       SQObject o = stack_get(v, -1);\r
-       if(!sq_isnativeclosure(o))\r
-               return sq_throwerror(v, _SC("native closure expected"));\r
-       SQNativeClosure *nc = _nativeclosure(o);\r
-       nc->_nparamscheck = nparamscheck;\r
-       if(typemask) {\r
-               SQIntVec res;\r
-               if(!CompileTypemask(res, typemask))\r
-                       return sq_throwerror(v, _SC("invalid typemask"));\r
-               nc->_typecheck.copy(res);\r
-       }\r
-       else {\r
-               nc->_typecheck.resize(0);\r
-       }\r
-       if(nparamscheck == SQ_MATCHTYPEMASKSTRING) {\r
-               nc->_nparamscheck = nc->_typecheck.size();\r
-       }\r
-       return SQ_OK;\r
-}\r
-\r
-SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx)\r
-{\r
-       SQObjectPtr &o = stack_get(v,idx);\r
-       if(!sq_isnativeclosure(o) &&\r
-               !sq_isclosure(o))\r
-               return sq_throwerror(v,_SC("the target is not a closure"));\r
-    SQObjectPtr &env = stack_get(v,-1);\r
-       if(!sq_istable(env) &&\r
-               !sq_isclass(env) &&\r
-               !sq_isinstance(env))\r
-               return sq_throwerror(v,_SC("invalid environment"));\r
-       SQObjectPtr w = _refcounted(env)->GetWeakRef(type(env));\r
-       SQObjectPtr ret;\r
-       if(sq_isclosure(o)) {\r
-               SQClosure *c = _closure(o)->Clone();\r
-               c->_env = w;\r
-               ret = c;\r
-       }\r
-       else { //then must be a native closure\r
-               SQNativeClosure *c = _nativeclosure(o)->Clone();\r
-               c->_env = w;\r
-               ret = c;\r
-       }\r
-       v->Pop();\r
-       v->Push(ret);\r
-       return SQ_OK;\r
-}\r
-\r
-void sq_pushroottable(HSQUIRRELVM v)\r
-{\r
-       v->Push(v->_roottable);\r
-}\r
-\r
-void sq_pushregistrytable(HSQUIRRELVM v)\r
-{\r
-       v->Push(_ss(v)->_registry);\r
-}\r
-\r
-SQRESULT sq_setroottable(HSQUIRRELVM v)\r
-{\r
-       SQObject o = stack_get(v, -1);\r
-       if(sq_istable(o) || sq_isnull(o)) {\r
-               v->_roottable = o;\r
-               v->Pop();\r
-               return SQ_OK;\r
-       }\r
-       return sq_throwerror(v, _SC("ivalid type"));\r
-}\r
-\r
-void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p)\r
-{\r
-       v->_foreignptr = p;\r
-}\r
-\r
-SQUserPointer sq_getforeignptr(HSQUIRRELVM v)\r
-{\r
-       return v->_foreignptr;\r
-}\r
-\r
-void sq_push(HSQUIRRELVM v,SQInteger idx)\r
-{\r
-       v->Push(stack_get(v, idx));\r
-}\r
-\r
-SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx)\r
-{\r
-       return type(stack_get(v, idx));\r
-}\r
-\r
-void sq_tostring(HSQUIRRELVM v,SQInteger idx)\r
-{\r
-       SQObjectPtr &o = stack_get(v, idx);\r
-       SQObjectPtr res;\r
-       v->ToString(o,res);\r
-       v->Push(res);\r
-}\r
-\r
-void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b)\r
-{\r
-       SQObjectPtr &o = stack_get(v, idx);\r
-       *b = v->IsFalse(o)?SQFalse:SQTrue;\r
-}\r
-\r
-SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i)\r
-{\r
-       SQObjectPtr &o = stack_get(v, idx);\r
-       if(sq_isnumeric(o)) {\r
-               *i = tointeger(o);\r
-               return SQ_OK;\r
-       }\r
-       return SQ_ERROR;\r
-}\r
-\r
-SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f)\r
-{\r
-       SQObjectPtr &o = stack_get(v, idx);\r
-       if(sq_isnumeric(o)) {\r
-               *f = tofloat(o);\r
-               return SQ_OK;\r
-       }\r
-       return SQ_ERROR;\r
-}\r
-\r
-SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b)\r
-{\r
-       SQObjectPtr &o = stack_get(v, idx);\r
-       if(sq_isbool(o)) {\r
-               *b = _integer(o);\r
-               return SQ_OK;\r
-       }\r
-       return SQ_ERROR;\r
-}\r
-\r
-SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c)\r
-{\r
-       SQObjectPtr *o = NULL;\r
-       _GETSAFE_OBJ(v, idx, OT_STRING,o);\r
-       *c = _stringval(*o);\r
-       return SQ_OK;\r
-}\r
-\r
-SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread)\r
-{\r
-       SQObjectPtr *o = NULL;\r
-       _GETSAFE_OBJ(v, idx, OT_THREAD,o);\r
-       *thread = _thread(*o);\r
-       return SQ_OK;\r
-}\r
-\r
-SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx)\r
-{\r
-       SQObjectPtr &o = stack_get(v,idx);\r
-       v->Push(_null_);\r
-       if(!v->Clone(o, stack_get(v, -1))){\r
-               v->Pop();\r
-               return sq_aux_invalidtype(v, type(o));\r
-       }\r
-       return SQ_OK;\r
-}\r
-\r
-SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx)\r
-{\r
-       SQObjectPtr &o = stack_get(v, idx);\r
-       SQObjectType type = type(o);\r
-       switch(type) {\r
-       case OT_STRING:         return _string(o)->_len;\r
-       case OT_TABLE:          return _table(o)->CountUsed();\r
-       case OT_ARRAY:          return _array(o)->Size();\r
-       case OT_USERDATA:       return _userdata(o)->_size;\r
-       default:\r
-               return sq_aux_invalidtype(v, type);\r
-       }\r
-}\r
-\r
-SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag)\r
-{\r
-       SQObjectPtr *o = NULL;\r
-       _GETSAFE_OBJ(v, idx, OT_USERDATA,o);\r
-       (*p) = _userdataval(*o);\r
-       if(typetag) *typetag = _userdata(*o)->_typetag;\r
-       return SQ_OK;\r
-}\r
-\r
-SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag)\r
-{\r
-       SQObjectPtr &o = stack_get(v,idx);\r
-       switch(type(o)) {\r
-               case OT_USERDATA:       _userdata(o)->_typetag = typetag;       break;\r
-               case OT_CLASS:          _class(o)->_typetag = typetag;          break;\r
-               default:                        return sq_throwerror(v,_SC("invalid object type"));\r
-       }\r
-       return SQ_OK;\r
-}\r
-\r
-SQRESULT sq_getobjtypetag(HSQOBJECT *o,SQUserPointer * typetag)\r
-{\r
-  switch(type(*o)) {\r
-    case OT_INSTANCE: *typetag = _instance(*o)->_class->_typetag; break;\r
-    case OT_USERDATA: *typetag = _userdata(*o)->_typetag; break;\r
-    case OT_CLASS:    *typetag = _class(*o)->_typetag; break;\r
-    default: return SQ_ERROR;\r
-  }\r
-  return SQ_OK;\r
-}\r
-\r
-SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag)\r
-{\r
-       SQObjectPtr &o = stack_get(v,idx);\r
-       if(SQ_FAILED(sq_getobjtypetag(&o,typetag)))\r
-               return sq_throwerror(v,_SC("invalid object type"));\r
-       return SQ_OK;\r
-}\r
-\r
-SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p)\r
-{\r
-       SQObjectPtr *o = NULL;\r
-       _GETSAFE_OBJ(v, idx, OT_USERPOINTER,o);\r
-       (*p) = _userpointer(*o);\r
-       return SQ_OK;\r
-}\r
-\r
-SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p)\r
-{\r
-       SQObjectPtr &o = stack_get(v,idx);\r
-       if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));\r
-       _instance(o)->_userpointer = p;\r
-       return SQ_OK;\r
-}\r
-\r
-SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag)\r
-{\r
-       SQObjectPtr &o = stack_get(v,idx);\r
-       if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));\r
-       (*p) = _instance(o)->_userpointer;\r
-       if(typetag != 0) {\r
-               SQClass *cl = _instance(o)->_class;\r
-               do{\r
-                       if(cl->_typetag == typetag)\r
-                               return SQ_OK;\r
-                       cl = cl->_base;\r
-               }while(cl != NULL);\r
-               return sq_throwerror(v,_SC("invalid type tag"));\r
-       }\r
-       return SQ_OK;\r
-}\r
-\r
-SQInteger sq_gettop(HSQUIRRELVM v)\r
-{\r
-       return (v->_top) - v->_stackbase;\r
-}\r
-\r
-void sq_settop(HSQUIRRELVM v, SQInteger newtop)\r
-{\r
-       SQInteger top = sq_gettop(v);\r
-       if(top > newtop)\r
-               sq_pop(v, top - newtop);\r
-       else\r
-               while(top < newtop) sq_pushnull(v);\r
-}\r
-\r
-void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop)\r
-{\r
-       assert(v->_top >= nelemstopop);\r
-       v->Pop(nelemstopop);\r
-}\r
-\r
-void sq_poptop(HSQUIRRELVM v)\r
-{\r
-       assert(v->_top >= 1);\r
-    v->Pop();\r
-}\r
-\r
-\r
-void sq_remove(HSQUIRRELVM v, SQInteger idx)\r
-{\r
-       v->Remove(idx);\r
-}\r
-\r
-SQInteger sq_cmp(HSQUIRRELVM v)\r
-{\r
-       SQInteger res;\r
-       v->ObjCmp(stack_get(v, -1), stack_get(v, -2),res);\r
-       return res;\r
-}\r
-\r
-SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic)\r
-{\r
-       sq_aux_paramscheck(v, 3);\r
-       SQObjectPtr &self = stack_get(v, idx);\r
-       if(type(self) == OT_TABLE || type(self) == OT_CLASS) {\r
-               SQObjectPtr &key = v->GetUp(-2);\r
-               if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));\r
-               v->NewSlot(self, key, v->GetUp(-1),bstatic?true:false);\r
-               v->Pop(2);\r
-       }\r
-       return SQ_OK;\r
-}\r
-\r
-/*SQRESULT sq_createslot(HSQUIRRELVM v, SQInteger idx)\r
-{\r
-       sq_aux_paramscheck(v, 3);\r
-       SQObjectPtr &self = stack_get(v, idx);\r
-       if(type(self) == OT_TABLE || type(self) == OT_CLASS) {\r
-               SQObjectPtr &key = v->GetUp(-2);\r
-               if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));\r
-               v->NewSlot(self, key, v->GetUp(-1));\r
-               v->Pop(2);\r
-       }\r
-       return SQ_OK;\r
-}*/\r
-\r
-SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)\r
-{\r
-       sq_aux_paramscheck(v, 2);\r
-       SQObjectPtr *self;\r
-       _GETSAFE_OBJ(v, idx, OT_TABLE,self);\r
-       SQObjectPtr &key = v->GetUp(-1);\r
-       if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));\r
-       SQObjectPtr res;\r
-       if(!v->DeleteSlot(*self, key, res)){\r
-               return SQ_ERROR;\r
-       }\r
-       if(pushval)     v->GetUp(-1) = res;\r
-       else v->Pop(1);\r
-       return SQ_OK;\r
-}\r
-\r
-SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx)\r
-{\r
-       SQObjectPtr &self = stack_get(v, idx);\r
-       if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) {\r
-               v->Pop(2);\r
-               return SQ_OK;\r
-       }\r
-       v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR;\r
-}\r
-\r
-SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx)\r
-{\r
-       SQObjectPtr &self = stack_get(v, idx);\r
-       if(type(v->GetUp(-2)) == OT_NULL) return sq_throwerror(v, _SC("null key"));\r
-       switch(type(self)) {\r
-       case OT_TABLE:\r
-               _table(self)->NewSlot(v->GetUp(-2), v->GetUp(-1));\r
-               v->Pop(2);\r
-               return SQ_OK;\r
-       break;\r
-       case OT_CLASS:\r
-               _class(self)->NewSlot(_ss(v), v->GetUp(-2), v->GetUp(-1),false);\r
-               v->Pop(2);\r
-               return SQ_OK;\r
-       break;\r
-       case OT_INSTANCE:\r
-               if(_instance(self)->Set(v->GetUp(-2), v->GetUp(-1))) {\r
-                       v->Pop(2);\r
-                       return SQ_OK;\r
-               }\r
-       break;\r
-       case OT_ARRAY:\r
-               if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) {\r
-                       v->Pop(2);\r
-                       return SQ_OK;\r
-               }\r
-       break;\r
-       default:\r
-               v->Pop(2);\r
-               return sq_throwerror(v, _SC("rawset works only on array/table/calsse and instance"));\r
-       }\r
-       v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR;\r
-}\r
-\r
-SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx)\r
-{\r
-       SQObjectPtr &self = stack_get(v, idx);\r
-       SQObjectPtr &mt = v->GetUp(-1);\r
-       SQObjectType type = type(self);\r
-       switch(type) {\r
-       case OT_TABLE:\r
-               if(type(mt) == OT_TABLE) {\r
-                       if(!_table(self)->SetDelegate(_table(mt))) return sq_throwerror(v, _SC("delagate cycle")); v->Pop();}\r
-               else if(type(mt)==OT_NULL) {\r
-                       _table(self)->SetDelegate(NULL); v->Pop(); }\r
-               else return sq_aux_invalidtype(v,type);\r
-               break;\r
-       case OT_USERDATA:\r
-               if(type(mt)==OT_TABLE) {\r
-                       _userdata(self)->SetDelegate(_table(mt)); v->Pop(); }\r
-               else if(type(mt)==OT_NULL) {\r
-                       _userdata(self)->SetDelegate(NULL); v->Pop(); }\r
-               else return sq_aux_invalidtype(v, type);\r
-               break;\r
-       default:\r
-                       return sq_aux_invalidtype(v, type);\r
-               break;\r
-       }\r
-       return SQ_OK;\r
-}\r
-\r
-SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)\r
-{\r
-       sq_aux_paramscheck(v, 2);\r
-       SQObjectPtr *self;\r
-       _GETSAFE_OBJ(v, idx, OT_TABLE,self);\r
-       SQObjectPtr &key = v->GetUp(-1);\r
-       SQObjectPtr t;\r
-       if(_table(*self)->Get(key,t)) {\r
-               _table(*self)->Remove(key);\r
-       }\r
-       if(pushval != 0)\r
-               if(pushval)     v->GetUp(-1) = t;\r
-       else\r
-               v->Pop(1);\r
-       return SQ_OK;\r
-}\r
-\r
-SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx)\r
-{\r
-       SQObjectPtr &self=stack_get(v,idx);\r
-       switch(type(self)){\r
-       case OT_TABLE:\r
-               if(!_table(self)->_delegate)break;\r
-               v->Push(SQObjectPtr(_table(self)->_delegate));\r
-               break;\r
-       case OT_USERDATA:\r
-               if(!_userdata(self)->_delegate)break;\r
-               v->Push(SQObjectPtr(_userdata(self)->_delegate));\r
-               break;\r
-       default: return sq_throwerror(v,_SC("wrong type")); break;\r
-       }\r
-       return SQ_OK;\r
-       \r
-}\r
-\r
-SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx)\r
-{\r
-       SQObjectPtr &self=stack_get(v,idx);\r
-       if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,false))\r
-               return SQ_OK;\r
-       v->Pop(1);\r
-       return sq_throwerror(v,_SC("the index doesn't exist"));\r
-}\r
-\r
-SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx)\r
-{\r
-       SQObjectPtr &self=stack_get(v,idx);\r
-       switch(type(self)) {\r
-       case OT_TABLE:\r
-               if(_table(self)->Get(v->GetUp(-1),v->GetUp(-1)))\r
-                       return SQ_OK;\r
-               break;\r
-       case OT_CLASS:\r
-               if(_class(self)->Get(v->GetUp(-1),v->GetUp(-1)))\r
-                       return SQ_OK;\r
-               break;\r
-       case OT_INSTANCE:\r
-               if(_instance(self)->Get(v->GetUp(-1),v->GetUp(-1)))\r
-                       return SQ_OK;\r
-               break;\r
-       case OT_ARRAY:\r
-               if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,false))\r
-                       return SQ_OK;\r
-               break;\r
-       default:\r
-               v->Pop(1);\r
-               return sq_throwerror(v,_SC("rawget works only on array/table/instance and class"));\r
-       }       \r
-       v->Pop(1);\r
-       return sq_throwerror(v,_SC("the index doesn't exist"));\r
-}\r
-\r
-SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po)\r
-{\r
-       *po=stack_get(v,idx);\r
-       return SQ_OK;\r
-}\r
-\r
-const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx)\r
-{\r
-       SQUnsignedInteger cstksize=v->_callsstack.size();\r
-       SQUnsignedInteger lvl=(cstksize-level)-1;\r
-       SQInteger stackbase=v->_stackbase;\r
-       if(lvl<cstksize){\r
-               for(SQUnsignedInteger i=0;i<level;i++){\r
-                       SQVM::CallInfo &ci=v->_callsstack[(cstksize-i)-1];\r
-                       stackbase-=ci._prevstkbase;\r
-               }\r
-               SQVM::CallInfo &ci=v->_callsstack[lvl];\r
-               if(type(ci._closure)!=OT_CLOSURE)\r
-                       return NULL;\r
-               SQClosure *c=_closure(ci._closure);\r
-               SQFunctionProto *func=_funcproto(c->_function);\r
-               return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions._vals)-1);\r
-       }\r
-       return NULL;\r
-}\r
-\r
-void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj)\r
-{\r
-       v->Push(SQObjectPtr(obj));\r
-}\r
-\r
-void sq_resetobject(HSQOBJECT *po)\r
-{\r
-       po->_unVal.pUserPointer=NULL;po->_type=OT_NULL;\r
-}\r
-\r
-SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err)\r
-{\r
-       v->_lasterror=SQString::Create(_ss(v),err);\r
-       return -1;\r
-}\r
-\r
-void sq_reseterror(HSQUIRRELVM v)\r
-{\r
-       v->_lasterror = _null_;\r
-}\r
-\r
-void sq_getlasterror(HSQUIRRELVM v)\r
-{\r
-       v->Push(v->_lasterror);\r
-}\r
-\r
-void sq_reservestack(HSQUIRRELVM v,SQInteger nsize)\r
-{\r
-       if (((SQUnsignedInteger)v->_top + nsize) > v->_stack.size()) {\r
-               v->_stack.resize(v->_stack.size() + ((v->_top + nsize) - v->_stack.size()));\r
-       }\r
-}\r
-\r
-SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror)\r
-{\r
-       if(type(v->GetUp(-1))==OT_GENERATOR){\r
-               v->Push(_null_); //retval\r
-               if(!v->Execute(v->GetUp(-2),v->_top,0,v->_top,v->GetUp(-1),raiseerror,SQVM::ET_RESUME_GENERATOR))\r
-               {v->Raise_Error(v->_lasterror); return SQ_ERROR;}\r
-               if(!retval)\r
-                       v->Pop();\r
-               return SQ_OK;\r
-       }\r
-       return sq_throwerror(v,_SC("only generators can be resumed"));\r
-}\r
-\r
-SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror)\r
-{\r
-       SQObjectPtr res;\r
-       if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false)){\r
-               v->Pop(params);//pop closure and args\r
-               if(retval){\r
-                       v->Push(res); return SQ_OK;\r
-               }\r
-               return SQ_OK;\r
-       }\r
-       else {\r
-               v->Pop(params);\r
-               return SQ_ERROR;\r
-       }\r
-       if(!v->_suspended)\r
-               v->Pop(params);\r
-       return sq_throwerror(v,_SC("call failed"));\r
-}\r
-\r
-SQRESULT sq_suspendvm(HSQUIRRELVM v)\r
-{\r
-       return v->Suspend();\r
-}\r
-\r
-SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseerror)\r
-{\r
-       SQObjectPtr ret;\r
-       if(!v->_suspended)\r
-               return sq_throwerror(v,_SC("cannot resume a vm that is not running any code"));\r
-       if(wakeupret) {\r
-               v->GetAt(v->_stackbase+v->_suspended_target)=v->GetUp(-1); //retval\r
-               v->Pop();\r
-       } else v->GetAt(v->_stackbase+v->_suspended_target)=_null_;\r
-       if(!v->Execute(_null_,v->_top,-1,-1,ret,raiseerror,SQVM::ET_RESUME_VM))\r
-               return SQ_ERROR;\r
-       if(sq_getvmstate(v) == SQ_VMSTATE_IDLE) {\r
-               while (v->_top > 1) v->_stack[--v->_top] = _null_;\r
-       }\r
-       if(retval)\r
-               v->Push(ret);\r
-       return SQ_OK;\r
-}\r
-\r
-void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook)\r
-{\r
-       if(sq_gettop(v) >= 1){\r
-               SQObjectPtr &ud=stack_get(v,idx);\r
-               switch( type(ud) ) {\r
-               case OT_USERDATA:       _userdata(ud)->_hook = hook;    break;\r
-               case OT_INSTANCE:       _instance(ud)->_hook = hook;    break;\r
-               case OT_CLASS:          _class(ud)->_hook = hook;               break;\r
-               default: break; //shutup compiler\r
-               }\r
-       }\r
-}\r
-\r
-void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f)\r
-{\r
-       _ss(v)->_compilererrorhandler = f;\r
-}\r
-\r
-SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up)\r
-{\r
-       SQObjectPtr *o = NULL;\r
-       _GETSAFE_OBJ(v, -1, OT_CLOSURE,o);\r
-       unsigned short tag = SQ_BYTECODE_STREAM_TAG;\r
-       if(w(up,&tag,2) != 2)\r
-               return sq_throwerror(v,_SC("io error"));\r
-       if(!_closure(*o)->Save(v,up,w))\r
-               return SQ_ERROR;\r
-       return SQ_OK;\r
-}\r
-\r
-SQRESULT sq_readclosure(HSQUIRRELVM v,SQREADFUNC r,SQUserPointer up)\r
-{\r
-       SQObjectPtr func=SQFunctionProto::Create();\r
-       SQObjectPtr closure=SQClosure::Create(_ss(v),_funcproto(func));\r
-       unsigned short tag;\r
-       if(r(up,&tag,2) != 2)\r
-               return sq_throwerror(v,_SC("io error"));\r
-       if(tag != SQ_BYTECODE_STREAM_TAG)\r
-               return sq_throwerror(v,_SC("invalid stream"));\r
-       if(!_closure(closure)->Load(v,up,r))\r
-               return SQ_ERROR;\r
-       v->Push(closure);\r
-       return SQ_OK;\r
-}\r
-\r
-SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize)\r
-{\r
-       return _ss(v)->GetScratchPad(minsize);\r
-}\r
-\r
-SQInteger sq_collectgarbage(HSQUIRRELVM v)\r
-{\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-       return _ss(v)->CollectGarbage(v);\r
-#else\r
-       return -1;\r
-#endif\r
-}\r
-\r
-const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)\r
-{\r
-       SQObjectPtr &self = stack_get(v,idx);\r
-       const SQChar *name = NULL;\r
-       if(type(self) == OT_CLOSURE) {\r
-               if(_closure(self)->_outervalues.size()>nval) {\r
-                       v->Push(_closure(self)->_outervalues[nval]);\r
-                       SQFunctionProto *fp = _funcproto(_closure(self)->_function);\r
-                       SQOuterVar &ov = fp->_outervalues[nval];\r
-                       name = _stringval(ov._name);\r
-               }\r
-       }\r
-       return name;\r
-}\r
-\r
-SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)\r
-{\r
-       SQObjectPtr &self=stack_get(v,idx);\r
-       switch(type(self))\r
-       {\r
-       case OT_CLOSURE:\r
-               if(_closure(self)->_outervalues.size()>nval){\r
-                       _closure(self)->_outervalues[nval]=stack_get(v,-1);\r
-               }\r
-               else return sq_throwerror(v,_SC("invalid free var index"));\r
-               break;\r
-       case OT_NATIVECLOSURE:\r
-               if(_nativeclosure(self)->_outervalues.size()>nval){\r
-                       _nativeclosure(self)->_outervalues[nval]=stack_get(v,-1);\r
-               }\r
-               else return sq_throwerror(v,_SC("invalid free var index"));\r
-               break;\r
-       default:\r
-               return sq_aux_invalidtype(v,type(self));\r
-       }\r
-       v->Pop(1);\r
-       return SQ_OK;\r
-}\r
-\r
-SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx)\r
-{\r
-       SQObjectPtr *o = NULL;\r
-       _GETSAFE_OBJ(v, idx, OT_CLASS,o);\r
-       SQObjectPtr &key = stack_get(v,-2);\r
-       SQObjectPtr &val = stack_get(v,-1);\r
-       SQObjectPtr attrs;\r
-       if(type(key) == OT_NULL) {\r
-               attrs = _class(*o)->_attributes;\r
-               _class(*o)->_attributes = val;\r
-               v->Pop(2);\r
-               v->Push(attrs);\r
-               return SQ_OK;\r
-       }else if(_class(*o)->GetAttributes(key,attrs)) {\r
-               _class(*o)->SetAttributes(key,val);\r
-               v->Pop(2);\r
-               v->Push(attrs);\r
-               return SQ_OK;\r
-       }\r
-       return sq_throwerror(v,_SC("wrong index"));\r
-}\r
-\r
-SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx)\r
-{\r
-       SQObjectPtr *o = NULL;\r
-       _GETSAFE_OBJ(v, idx, OT_CLASS,o);\r
-       SQObjectPtr &key = stack_get(v,-1);\r
-       SQObjectPtr attrs;\r
-       if(type(key) == OT_NULL) {\r
-               attrs = _class(*o)->_attributes;\r
-               v->Pop();\r
-               v->Push(attrs); \r
-               return SQ_OK;\r
-       }\r
-       else if(_class(*o)->GetAttributes(key,attrs)) {\r
-               v->Pop();\r
-               v->Push(attrs);\r
-               return SQ_OK;\r
-       }\r
-       return sq_throwerror(v,_SC("wrong index"));\r
-}\r
-\r
-SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx)\r
-{\r
-       SQObjectPtr *o = NULL;\r
-       _GETSAFE_OBJ(v, idx, OT_CLASS,o);\r
-       if(_class(*o)->_base)\r
-               v->Push(SQObjectPtr(_class(*o)->_base));\r
-       else\r
-               v->Push(_null_);\r
-       return SQ_OK;\r
-}\r
-\r
-SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx)\r
-{\r
-       SQObjectPtr *o = NULL;\r
-       _GETSAFE_OBJ(v, idx, OT_INSTANCE,o);\r
-       v->Push(SQObjectPtr(_instance(*o)->_class));\r
-       return SQ_OK;\r
-}\r
-\r
-SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx)\r
-{\r
-       SQObjectPtr *o = NULL;\r
-       _GETSAFE_OBJ(v, idx, OT_CLASS,o);\r
-       v->Push(_class(*o)->CreateInstance());\r
-       return SQ_OK;\r
-}\r
-\r
-void sq_weakref(HSQUIRRELVM v,SQInteger idx)\r
-{\r
-       SQObject &o=stack_get(v,idx);\r
-       if(ISREFCOUNTED(type(o))) {\r
-               v->Push(_refcounted(o)->GetWeakRef(type(o)));\r
-               return;\r
-       }\r
-       v->Push(o);\r
-}\r
-\r
-SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx)\r
-{\r
-       SQObjectPtr &o = stack_get(v,idx);\r
-       if(type(o) != OT_WEAKREF) {\r
-               return sq_throwerror(v,_SC("the object must be a weakref"));\r
-       }\r
-       v->Push(_weakref(o)->_obj);\r
-       return SQ_OK;\r
-}\r
-\r
-SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t)\r
-{\r
-       SQSharedState *ss = _ss(v);\r
-       switch(t) {\r
-       case OT_TABLE: v->Push(ss->_table_default_delegate); break;\r
-       case OT_ARRAY: v->Push(ss->_array_default_delegate); break;\r
-       case OT_STRING: v->Push(ss->_string_default_delegate); break;\r
-       case OT_INTEGER: case OT_FLOAT: v->Push(ss->_number_default_delegate); break;\r
-       case OT_GENERATOR: v->Push(ss->_generator_default_delegate); break;\r
-       case OT_CLOSURE: case OT_NATIVECLOSURE: v->Push(ss->_closure_default_delegate); break;\r
-       case OT_THREAD: v->Push(ss->_thread_default_delegate); break;\r
-       case OT_CLASS: v->Push(ss->_class_default_delegate); break;\r
-       case OT_INSTANCE: v->Push(ss->_instance_default_delegate); break;\r
-       case OT_WEAKREF: v->Push(ss->_weakref_default_delegate); break;\r
-       default: return sq_throwerror(v,_SC("the type doesn't have a default delegate"));\r
-       }\r
-       return SQ_OK;\r
-}\r
-\r
-SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx)\r
-{\r
-       SQObjectPtr o=stack_get(v,idx),&refpos = stack_get(v,-1),realkey,val;\r
-       if(type(o) == OT_GENERATOR) {\r
-               return sq_throwerror(v,_SC("cannot iterate a generator"));\r
-       }\r
-       bool finished;\r
-       if(!v->FOREACH_OP(o,realkey,val,refpos,0,finished))\r
-               return SQ_ERROR;\r
-       if(!finished) {\r
-               v->Push(realkey);\r
-               v->Push(val);\r
-               return SQ_OK;\r
-       }\r
-       return SQ_ERROR;\r
-}\r
-\r
-struct BufState{\r
-       const SQChar *buf;\r
-       SQInteger ptr;\r
-       SQInteger size;\r
-};\r
-\r
-SQInteger buf_lexfeed(SQUserPointer file)\r
-{\r
-       BufState *buf=(BufState*)file;\r
-       if(buf->size<(buf->ptr+1))\r
-               return 0;\r
-       return buf->buf[buf->ptr++];\r
-}\r
-\r
-SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror) {\r
-       BufState buf;\r
-       buf.buf = s;\r
-       buf.size = size;\r
-       buf.ptr = 0;\r
-       return sq_compile(v, buf_lexfeed, &buf, sourcename, raiseerror);\r
-}\r
-\r
-void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx)\r
-{\r
-       dest->Push(stack_get(src,idx));\r
-}\r
-\r
-void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc)\r
-{\r
-       _ss(v)->_printfunc = printfunc;\r
-}\r
-\r
-SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v)\r
-{\r
-       return _ss(v)->_printfunc;\r
-}\r
-\r
-void *sq_malloc(SQUnsignedInteger size)\r
-{\r
-       return SQ_MALLOC(size);\r
-}\r
-\r
-void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize)\r
-{\r
-       return SQ_REALLOC(p,oldsize,newsize);\r
-}\r
-void sq_free(void *p,SQUnsignedInteger size)\r
-{\r
-       SQ_FREE(p,size);\r
-}\r
+/*
+       see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include "sqvm.h"
+#include "sqstring.h"
+#include "sqtable.h"
+#include "sqarray.h"
+#include "sqfuncproto.h"
+#include "sqclosure.h"
+#include "squserdata.h"
+#include "sqcompiler.h"
+#include "sqfuncstate.h"
+#include "sqclass.h"
+
+bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPtr **o)
+{
+       *o = &stack_get(v,idx);
+       if(type(**o) != type){
+               SQObjectPtr oval = v->PrintObjVal(**o);
+               v->Raise_Error(_SC("wrong argument type, expected '%s' got '%.50s'"),IdType2Name(type),_stringval(oval));
+               return false;
+       }
+       return true;
+}
+
+#define _GETSAFE_OBJ(v,idx,type,o) { if(!sq_aux_gettypedarg(v,idx,type,&o)) return SQ_ERROR; }
+
+#define sq_aux_paramscheck(v,count) \
+{ \
+       if(sq_gettop(v) < count){ v->Raise_Error(_SC("not enough params in the stack")); return SQ_ERROR; }\
+}
+
+SQInteger sq_aux_throwobject(HSQUIRRELVM v,SQObjectPtr &e)
+{
+       v->_lasterror = e;
+       return SQ_ERROR;
+}
+
+SQInteger sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type)
+{
+       scsprintf(_ss(v)->GetScratchPad(100), _SC("unexpected type %s"), IdType2Name(type));
+       return sq_throwerror(v, _ss(v)->GetScratchPad(-1));
+}
+
+HSQUIRRELVM sq_open(SQInteger initialstacksize)
+{
+       SQSharedState *ss;
+       SQVM *v;
+       sq_new(ss, SQSharedState);
+       ss->Init();
+       v = (SQVM *)SQ_MALLOC(sizeof(SQVM));
+       new (v) SQVM(ss);
+       ss->_root_vm = v;
+       if(v->Init(NULL, initialstacksize)) {
+               return v;
+       } else {
+               sq_delete(v, SQVM);
+               return NULL;
+       }
+       return v;
+}
+
+HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize)
+{
+       SQSharedState *ss;
+       SQVM *v;
+       ss=_ss(friendvm);
+
+       v= (SQVM *)SQ_MALLOC(sizeof(SQVM));
+       new (v) SQVM(ss);
+
+       if(v->Init(friendvm, initialstacksize)) {
+               friendvm->Push(v);
+               return v;
+       } else {
+               sq_delete(v, SQVM);
+               return NULL;
+       }
+}
+
+SQInteger sq_getvmstate(HSQUIRRELVM v)
+{
+       if(v->_suspended)
+               return SQ_VMSTATE_SUSPENDED;
+       else {
+               if(v->_callsstack.size() != 0) return SQ_VMSTATE_RUNNING;
+               else return SQ_VMSTATE_IDLE;
+       }
+}
+
+void sq_seterrorhandler(HSQUIRRELVM v)
+{
+       SQObject o = stack_get(v, -1);
+       if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {
+               v->_errorhandler = o;
+               v->Pop();
+       }
+}
+
+void sq_setdebughook(HSQUIRRELVM v)
+{
+       SQObject o = stack_get(v,-1);
+       if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {
+               v->_debughook = o;
+               v->Pop();
+       }
+}
+
+void sq_close(HSQUIRRELVM v)
+{
+       SQSharedState *ss = _ss(v);
+       _thread(ss->_root_vm)->Finalize();
+       sq_delete(ss, SQSharedState);
+}
+
+SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror)
+{
+       SQObjectPtr o;
+       if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) {
+               v->Push(SQClosure::Create(_ss(v), _funcproto(o)));
+               return SQ_OK;
+       }
+       return SQ_ERROR;
+}
+
+void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable)
+{
+       _ss(v)->_debuginfo = enable?true:false;
+}
+
+void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable)
+{
+       _ss(v)->_notifyallexceptions = enable?true:false;
+}
+
+void sq_addref(HSQUIRRELVM v,HSQOBJECT *po)
+{
+       if(!ISREFCOUNTED(type(*po))) return;
+       _ss(v)->_refs_table.AddRef(*po);
+}
+
+SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po)
+{
+       if(!ISREFCOUNTED(type(*po))) return SQTrue;
+       return _ss(v)->_refs_table.Release(*po);
+}
+
+const SQChar *sq_objtostring(HSQOBJECT *o)
+{
+       if(sq_type(*o) == OT_STRING) {
+               return _stringval(*o);
+       }
+       return NULL;
+}
+
+SQInteger sq_objtointeger(HSQOBJECT *o)
+{
+       if(sq_isnumeric(*o)) {
+               return tointeger(*o);
+       }
+       return 0;
+}
+
+SQFloat sq_objtofloat(HSQOBJECT *o)
+{
+       if(sq_isnumeric(*o)) {
+               return tofloat(*o);
+       }
+       return 0;
+}
+
+SQBool sq_objtobool(HSQOBJECT *o)
+{
+       if(sq_isbool(*o)) {
+               return _integer(*o);
+       }
+       return SQFalse;
+}
+
+void sq_pushnull(HSQUIRRELVM v)
+{
+       v->Push(_null_);
+}
+
+void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len)
+{
+       if(s)
+               v->Push(SQObjectPtr(SQString::Create(_ss(v), s, len)));
+       else v->Push(_null_);
+}
+
+void sq_pushinteger(HSQUIRRELVM v,SQInteger n)
+{
+       v->Push(n);
+}
+
+void sq_pushbool(HSQUIRRELVM v,SQBool b)
+{
+       v->Push(b?true:false);
+}
+
+void sq_pushfloat(HSQUIRRELVM v,SQFloat n)
+{
+       v->Push(n);
+}
+
+void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p)
+{
+       v->Push(p);
+}
+
+SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size)
+{
+       SQUserData *ud = SQUserData::Create(_ss(v), size);
+       v->Push(ud);
+       return ud->_val;
+}
+
+void sq_newtable(HSQUIRRELVM v)
+{
+       v->Push(SQTable::Create(_ss(v), 0));
+}
+
+void sq_newarray(HSQUIRRELVM v,SQInteger size)
+{
+       v->Push(SQArray::Create(_ss(v), size));
+}
+
+SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase)
+{
+       SQClass *baseclass = NULL;
+       if(hasbase) {
+               SQObjectPtr &base = stack_get(v,-1);
+               if(type(base) != OT_CLASS)
+                       return sq_throwerror(v,_SC("invalid base type"));
+               baseclass = _class(base);
+       }
+       SQClass *newclass = SQClass::Create(_ss(v), baseclass);
+       if(baseclass) v->Pop();
+       v->Push(newclass);
+       return SQ_OK;
+}
+
+SQBool sq_instanceof(HSQUIRRELVM v)
+{
+       SQObjectPtr &inst = stack_get(v,-1);
+       SQObjectPtr &cl = stack_get(v,-2);
+       if(type(inst) != OT_INSTANCE || type(cl) != OT_CLASS)
+               return sq_throwerror(v,_SC("invalid param type"));
+       return _instance(inst)->InstanceOf(_class(cl))?SQTrue:SQFalse;
+}
+
+SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx)
+{
+       sq_aux_paramscheck(v,2);
+       SQObjectPtr *arr;
+       _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
+       _array(*arr)->Append(v->GetUp(-1));
+       v->Pop(1);
+       return SQ_OK;
+}
+
+SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
+{
+       sq_aux_paramscheck(v, 1);
+       SQObjectPtr *arr;
+       _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
+       if(_array(*arr)->Size() > 0) {
+        if(pushval != 0){ v->Push(_array(*arr)->Top()); }
+               _array(*arr)->Pop();
+               return SQ_OK;
+       }
+       return sq_throwerror(v, _SC("empty array"));
+}
+
+SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize)
+{
+       sq_aux_paramscheck(v,1);
+       SQObjectPtr *arr;
+       _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
+       if(_array(*arr)->Size() > 0) {
+               _array(*arr)->Resize(newsize);
+               return SQ_OK;
+       }
+       return SQ_OK;
+}
+
+SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx)
+{
+       sq_aux_paramscheck(v, 1);
+       SQObjectPtr *o;
+       _GETSAFE_OBJ(v, idx, OT_ARRAY,o);
+       SQArray *arr = _array(*o);
+       if(arr->Size() > 0) {
+               SQObjectPtr t;
+               SQInteger size = arr->Size();
+               SQInteger n = size >> 1; size -= 1;
+               for(SQInteger i = 0; i < n; i++) {
+                       t = arr->_values[i];
+                       arr->_values[i] = arr->_values[size-i];
+                       arr->_values[size-i] = t;
+               }
+               return SQ_OK;
+       }
+       return SQ_OK;
+}
+
+void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars)
+{
+       SQNativeClosure *nc = SQNativeClosure::Create(_ss(v), func);
+       nc->_nparamscheck = 0;
+       for(SQUnsignedInteger i = 0; i < nfreevars; i++) {
+               nc->_outervalues.push_back(v->Top());
+               v->Pop();
+       }
+       v->Push(SQObjectPtr(nc));
+}
+
+SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars)
+{
+       SQObject o = stack_get(v, idx);
+       if(sq_isclosure(o)) {
+               SQClosure *c = _closure(o);
+               SQFunctionProto *proto = _funcproto(c->_function);
+               *nparams = (SQUnsignedInteger)proto->_parameters.size();
+        *nfreevars = (SQUnsignedInteger)c->_outervalues.size();
+               return SQ_OK;
+       }
+       return sq_throwerror(v,_SC("the object is not a closure"));
+}
+
+SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name)
+{
+       SQObject o = stack_get(v, idx);
+       if(sq_isnativeclosure(o)) {
+               SQNativeClosure *nc = _nativeclosure(o);
+               nc->_name = SQString::Create(_ss(v),name);
+               return SQ_OK;
+       }
+       return sq_throwerror(v,_SC("the object is not a nativeclosure"));
+}
+
+SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask)
+{
+       SQObject o = stack_get(v, -1);
+       if(!sq_isnativeclosure(o))
+               return sq_throwerror(v, _SC("native closure expected"));
+       SQNativeClosure *nc = _nativeclosure(o);
+       nc->_nparamscheck = nparamscheck;
+       if(typemask) {
+               SQIntVec res;
+               if(!CompileTypemask(res, typemask))
+                       return sq_throwerror(v, _SC("invalid typemask"));
+               nc->_typecheck.copy(res);
+       }
+       else {
+               nc->_typecheck.resize(0);
+       }
+       if(nparamscheck == SQ_MATCHTYPEMASKSTRING) {
+               nc->_nparamscheck = nc->_typecheck.size();
+       }
+       return SQ_OK;
+}
+
+SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx)
+{
+       SQObjectPtr &o = stack_get(v,idx);
+       if(!sq_isnativeclosure(o) &&
+               !sq_isclosure(o))
+               return sq_throwerror(v,_SC("the target is not a closure"));
+    SQObjectPtr &env = stack_get(v,-1);
+       if(!sq_istable(env) &&
+               !sq_isclass(env) &&
+               !sq_isinstance(env))
+               return sq_throwerror(v,_SC("invalid environment"));
+       SQObjectPtr w = _refcounted(env)->GetWeakRef(type(env));
+       SQObjectPtr ret;
+       if(sq_isclosure(o)) {
+               SQClosure *c = _closure(o)->Clone();
+               c->_env = w;
+               ret = c;
+       }
+       else { //then must be a native closure
+               SQNativeClosure *c = _nativeclosure(o)->Clone();
+               c->_env = w;
+               ret = c;
+       }
+       v->Pop();
+       v->Push(ret);
+       return SQ_OK;
+}
+
+void sq_pushroottable(HSQUIRRELVM v)
+{
+       v->Push(v->_roottable);
+}
+
+void sq_pushregistrytable(HSQUIRRELVM v)
+{
+       v->Push(_ss(v)->_registry);
+}
+
+SQRESULT sq_setroottable(HSQUIRRELVM v)
+{
+       SQObject o = stack_get(v, -1);
+       if(sq_istable(o) || sq_isnull(o)) {
+               v->_roottable = o;
+               v->Pop();
+               return SQ_OK;
+       }
+       return sq_throwerror(v, _SC("ivalid type"));
+}
+
+void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p)
+{
+       v->_foreignptr = p;
+}
+
+SQUserPointer sq_getforeignptr(HSQUIRRELVM v)
+{
+       return v->_foreignptr;
+}
+
+void sq_push(HSQUIRRELVM v,SQInteger idx)
+{
+       v->Push(stack_get(v, idx));
+}
+
+SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx)
+{
+       return type(stack_get(v, idx));
+}
+
+void sq_tostring(HSQUIRRELVM v,SQInteger idx)
+{
+       SQObjectPtr &o = stack_get(v, idx);
+       SQObjectPtr res;
+       v->ToString(o,res);
+       v->Push(res);
+}
+
+void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b)
+{
+       SQObjectPtr &o = stack_get(v, idx);
+       *b = v->IsFalse(o)?SQFalse:SQTrue;
+}
+
+SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i)
+{
+       SQObjectPtr &o = stack_get(v, idx);
+       if(sq_isnumeric(o)) {
+               *i = tointeger(o);
+               return SQ_OK;
+       }
+       return SQ_ERROR;
+}
+
+SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f)
+{
+       SQObjectPtr &o = stack_get(v, idx);
+       if(sq_isnumeric(o)) {
+               *f = tofloat(o);
+               return SQ_OK;
+       }
+       return SQ_ERROR;
+}
+
+SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b)
+{
+       SQObjectPtr &o = stack_get(v, idx);
+       if(sq_isbool(o)) {
+               *b = _integer(o);
+               return SQ_OK;
+       }
+       return SQ_ERROR;
+}
+
+SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c)
+{
+       SQObjectPtr *o = NULL;
+       _GETSAFE_OBJ(v, idx, OT_STRING,o);
+       *c = _stringval(*o);
+       return SQ_OK;
+}
+
+SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread)
+{
+       SQObjectPtr *o = NULL;
+       _GETSAFE_OBJ(v, idx, OT_THREAD,o);
+       *thread = _thread(*o);
+       return SQ_OK;
+}
+
+SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx)
+{
+       SQObjectPtr &o = stack_get(v,idx);
+       v->Push(_null_);
+       if(!v->Clone(o, stack_get(v, -1))){
+               v->Pop();
+               return sq_aux_invalidtype(v, type(o));
+       }
+       return SQ_OK;
+}
+
+SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx)
+{
+       SQObjectPtr &o = stack_get(v, idx);
+       SQObjectType type = type(o);
+       switch(type) {
+       case OT_STRING:         return _string(o)->_len;
+       case OT_TABLE:          return _table(o)->CountUsed();
+       case OT_ARRAY:          return _array(o)->Size();
+       case OT_USERDATA:       return _userdata(o)->_size;
+       default:
+               return sq_aux_invalidtype(v, type);
+       }
+}
+
+SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag)
+{
+       SQObjectPtr *o = NULL;
+       _GETSAFE_OBJ(v, idx, OT_USERDATA,o);
+       (*p) = _userdataval(*o);
+       if(typetag) *typetag = _userdata(*o)->_typetag;
+       return SQ_OK;
+}
+
+SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag)
+{
+       SQObjectPtr &o = stack_get(v,idx);
+       switch(type(o)) {
+               case OT_USERDATA:       _userdata(o)->_typetag = typetag;       break;
+               case OT_CLASS:          _class(o)->_typetag = typetag;          break;
+               default:                        return sq_throwerror(v,_SC("invalid object type"));
+       }
+       return SQ_OK;
+}
+
+SQRESULT sq_getobjtypetag(HSQOBJECT *o,SQUserPointer * typetag)
+{
+  switch(type(*o)) {
+    case OT_INSTANCE: *typetag = _instance(*o)->_class->_typetag; break;
+    case OT_USERDATA: *typetag = _userdata(*o)->_typetag; break;
+    case OT_CLASS:    *typetag = _class(*o)->_typetag; break;
+    default: return SQ_ERROR;
+  }
+  return SQ_OK;
+}
+
+SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag)
+{
+       SQObjectPtr &o = stack_get(v,idx);
+       if(SQ_FAILED(sq_getobjtypetag(&o,typetag)))
+               return sq_throwerror(v,_SC("invalid object type"));
+       return SQ_OK;
+}
+
+SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p)
+{
+       SQObjectPtr *o = NULL;
+       _GETSAFE_OBJ(v, idx, OT_USERPOINTER,o);
+       (*p) = _userpointer(*o);
+       return SQ_OK;
+}
+
+SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p)
+{
+       SQObjectPtr &o = stack_get(v,idx);
+       if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));
+       _instance(o)->_userpointer = p;
+       return SQ_OK;
+}
+
+SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag)
+{
+       SQObjectPtr &o = stack_get(v,idx);
+       if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));
+       (*p) = _instance(o)->_userpointer;
+       if(typetag != 0) {
+               SQClass *cl = _instance(o)->_class;
+               do{
+                       if(cl->_typetag == typetag)
+                               return SQ_OK;
+                       cl = cl->_base;
+               }while(cl != NULL);
+               return sq_throwerror(v,_SC("invalid type tag"));
+       }
+       return SQ_OK;
+}
+
+SQInteger sq_gettop(HSQUIRRELVM v)
+{
+       return (v->_top) - v->_stackbase;
+}
+
+void sq_settop(HSQUIRRELVM v, SQInteger newtop)
+{
+       SQInteger top = sq_gettop(v);
+       if(top > newtop)
+               sq_pop(v, top - newtop);
+       else
+               while(top < newtop) sq_pushnull(v);
+}
+
+void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop)
+{
+       assert(v->_top >= nelemstopop);
+       v->Pop(nelemstopop);
+}
+
+void sq_poptop(HSQUIRRELVM v)
+{
+       assert(v->_top >= 1);
+    v->Pop();
+}
+
+
+void sq_remove(HSQUIRRELVM v, SQInteger idx)
+{
+       v->Remove(idx);
+}
+
+SQInteger sq_cmp(HSQUIRRELVM v)
+{
+       SQInteger res;
+       v->ObjCmp(stack_get(v, -1), stack_get(v, -2),res);
+       return res;
+}
+
+SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic)
+{
+       sq_aux_paramscheck(v, 3);
+       SQObjectPtr &self = stack_get(v, idx);
+       if(type(self) == OT_TABLE || type(self) == OT_CLASS) {
+               SQObjectPtr &key = v->GetUp(-2);
+               if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));
+               v->NewSlot(self, key, v->GetUp(-1),bstatic?true:false);
+               v->Pop(2);
+       }
+       return SQ_OK;
+}
+
+/*SQRESULT sq_createslot(HSQUIRRELVM v, SQInteger idx)
+{
+       sq_aux_paramscheck(v, 3);
+       SQObjectPtr &self = stack_get(v, idx);
+       if(type(self) == OT_TABLE || type(self) == OT_CLASS) {
+               SQObjectPtr &key = v->GetUp(-2);
+               if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));
+               v->NewSlot(self, key, v->GetUp(-1));
+               v->Pop(2);
+       }
+       return SQ_OK;
+}*/
+
+SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
+{
+       sq_aux_paramscheck(v, 2);
+       SQObjectPtr *self;
+       _GETSAFE_OBJ(v, idx, OT_TABLE,self);
+       SQObjectPtr &key = v->GetUp(-1);
+       if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));
+       SQObjectPtr res;
+       if(!v->DeleteSlot(*self, key, res)){
+               return SQ_ERROR;
+       }
+       if(pushval)     v->GetUp(-1) = res;
+       else v->Pop(1);
+       return SQ_OK;
+}
+
+SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx)
+{
+       SQObjectPtr &self = stack_get(v, idx);
+       if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) {
+               v->Pop(2);
+               return SQ_OK;
+       }
+       v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR;
+}
+
+SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx)
+{
+       SQObjectPtr &self = stack_get(v, idx);
+       if(type(v->GetUp(-2)) == OT_NULL) return sq_throwerror(v, _SC("null key"));
+       switch(type(self)) {
+       case OT_TABLE:
+               _table(self)->NewSlot(v->GetUp(-2), v->GetUp(-1));
+               v->Pop(2);
+               return SQ_OK;
+       break;
+       case OT_CLASS:
+               _class(self)->NewSlot(_ss(v), v->GetUp(-2), v->GetUp(-1),false);
+               v->Pop(2);
+               return SQ_OK;
+       break;
+       case OT_INSTANCE:
+               if(_instance(self)->Set(v->GetUp(-2), v->GetUp(-1))) {
+                       v->Pop(2);
+                       return SQ_OK;
+               }
+       break;
+       case OT_ARRAY:
+               if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) {
+                       v->Pop(2);
+                       return SQ_OK;
+               }
+       break;
+       default:
+               v->Pop(2);
+               return sq_throwerror(v, _SC("rawset works only on array/table/calsse and instance"));
+       }
+       v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR;
+}
+
+SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx)
+{
+       SQObjectPtr &self = stack_get(v, idx);
+       SQObjectPtr &mt = v->GetUp(-1);
+       SQObjectType type = type(self);
+       switch(type) {
+       case OT_TABLE:
+               if(type(mt) == OT_TABLE) {
+                       if(!_table(self)->SetDelegate(_table(mt))) return sq_throwerror(v, _SC("delagate cycle")); v->Pop();}
+               else if(type(mt)==OT_NULL) {
+                       _table(self)->SetDelegate(NULL); v->Pop(); }
+               else return sq_aux_invalidtype(v,type);
+               break;
+       case OT_USERDATA:
+               if(type(mt)==OT_TABLE) {
+                       _userdata(self)->SetDelegate(_table(mt)); v->Pop(); }
+               else if(type(mt)==OT_NULL) {
+                       _userdata(self)->SetDelegate(NULL); v->Pop(); }
+               else return sq_aux_invalidtype(v, type);
+               break;
+       default:
+                       return sq_aux_invalidtype(v, type);
+               break;
+       }
+       return SQ_OK;
+}
+
+SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
+{
+       sq_aux_paramscheck(v, 2);
+       SQObjectPtr *self;
+       _GETSAFE_OBJ(v, idx, OT_TABLE,self);
+       SQObjectPtr &key = v->GetUp(-1);
+       SQObjectPtr t;
+       if(_table(*self)->Get(key,t)) {
+               _table(*self)->Remove(key);
+       }
+       if(pushval != 0)
+               if(pushval)     v->GetUp(-1) = t;
+       else
+               v->Pop(1);
+       return SQ_OK;
+}
+
+SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx)
+{
+       SQObjectPtr &self=stack_get(v,idx);
+       switch(type(self)){
+       case OT_TABLE:
+               if(!_table(self)->_delegate)break;
+               v->Push(SQObjectPtr(_table(self)->_delegate));
+               break;
+       case OT_USERDATA:
+               if(!_userdata(self)->_delegate)break;
+               v->Push(SQObjectPtr(_userdata(self)->_delegate));
+               break;
+       default: return sq_throwerror(v,_SC("wrong type")); break;
+       }
+       return SQ_OK;
+
+}
+
+SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx)
+{
+       SQObjectPtr &self=stack_get(v,idx);
+       if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,false))
+               return SQ_OK;
+       v->Pop(1);
+       return sq_throwerror(v,_SC("the index doesn't exist"));
+}
+
+SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx)
+{
+       SQObjectPtr &self=stack_get(v,idx);
+       switch(type(self)) {
+       case OT_TABLE:
+               if(_table(self)->Get(v->GetUp(-1),v->GetUp(-1)))
+                       return SQ_OK;
+               break;
+       case OT_CLASS:
+               if(_class(self)->Get(v->GetUp(-1),v->GetUp(-1)))
+                       return SQ_OK;
+               break;
+       case OT_INSTANCE:
+               if(_instance(self)->Get(v->GetUp(-1),v->GetUp(-1)))
+                       return SQ_OK;
+               break;
+       case OT_ARRAY:
+               if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,false))
+                       return SQ_OK;
+               break;
+       default:
+               v->Pop(1);
+               return sq_throwerror(v,_SC("rawget works only on array/table/instance and class"));
+       }
+       v->Pop(1);
+       return sq_throwerror(v,_SC("the index doesn't exist"));
+}
+
+SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po)
+{
+       *po=stack_get(v,idx);
+       return SQ_OK;
+}
+
+const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx)
+{
+       SQUnsignedInteger cstksize=v->_callsstack.size();
+       SQUnsignedInteger lvl=(cstksize-level)-1;
+       SQInteger stackbase=v->_stackbase;
+       if(lvl<cstksize){
+               for(SQUnsignedInteger i=0;i<level;i++){
+                       SQVM::CallInfo &ci=v->_callsstack[(cstksize-i)-1];
+                       stackbase-=ci._prevstkbase;
+               }
+               SQVM::CallInfo &ci=v->_callsstack[lvl];
+               if(type(ci._closure)!=OT_CLOSURE)
+                       return NULL;
+               SQClosure *c=_closure(ci._closure);
+               SQFunctionProto *func=_funcproto(c->_function);
+               return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions._vals)-1);
+       }
+       return NULL;
+}
+
+void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj)
+{
+       v->Push(SQObjectPtr(obj));
+}
+
+void sq_resetobject(HSQOBJECT *po)
+{
+       po->_unVal.pUserPointer=NULL;po->_type=OT_NULL;
+}
+
+SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err)
+{
+       v->_lasterror=SQString::Create(_ss(v),err);
+       return -1;
+}
+
+void sq_reseterror(HSQUIRRELVM v)
+{
+       v->_lasterror = _null_;
+}
+
+void sq_getlasterror(HSQUIRRELVM v)
+{
+       v->Push(v->_lasterror);
+}
+
+void sq_reservestack(HSQUIRRELVM v,SQInteger nsize)
+{
+       if (((SQUnsignedInteger)v->_top + nsize) > v->_stack.size()) {
+               v->_stack.resize(v->_stack.size() + ((v->_top + nsize) - v->_stack.size()));
+       }
+}
+
+SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror)
+{
+       if(type(v->GetUp(-1))==OT_GENERATOR){
+               v->Push(_null_); //retval
+               if(!v->Execute(v->GetUp(-2),v->_top,0,v->_top,v->GetUp(-1),raiseerror,SQVM::ET_RESUME_GENERATOR))
+               {v->Raise_Error(v->_lasterror); return SQ_ERROR;}
+               if(!retval)
+                       v->Pop();
+               return SQ_OK;
+       }
+       return sq_throwerror(v,_SC("only generators can be resumed"));
+}
+
+SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror)
+{
+       SQObjectPtr res;
+       if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false)){
+               v->Pop(params);//pop closure and args
+               if(retval){
+                       v->Push(res); return SQ_OK;
+               }
+               return SQ_OK;
+       }
+       else {
+               v->Pop(params);
+               return SQ_ERROR;
+       }
+       if(!v->_suspended)
+               v->Pop(params);
+       return sq_throwerror(v,_SC("call failed"));
+}
+
+SQRESULT sq_suspendvm(HSQUIRRELVM v)
+{
+       return v->Suspend();
+}
+
+SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseerror)
+{
+       SQObjectPtr ret;
+       if(!v->_suspended)
+               return sq_throwerror(v,_SC("cannot resume a vm that is not running any code"));
+       if(wakeupret) {
+               v->GetAt(v->_stackbase+v->_suspended_target)=v->GetUp(-1); //retval
+               v->Pop();
+       } else v->GetAt(v->_stackbase+v->_suspended_target)=_null_;
+       if(!v->Execute(_null_,v->_top,-1,-1,ret,raiseerror,SQVM::ET_RESUME_VM))
+               return SQ_ERROR;
+       if(sq_getvmstate(v) == SQ_VMSTATE_IDLE) {
+               while (v->_top > 1) v->_stack[--v->_top] = _null_;
+       }
+       if(retval)
+               v->Push(ret);
+       return SQ_OK;
+}
+
+void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook)
+{
+       if(sq_gettop(v) >= 1){
+               SQObjectPtr &ud=stack_get(v,idx);
+               switch( type(ud) ) {
+               case OT_USERDATA:       _userdata(ud)->_hook = hook;    break;
+               case OT_INSTANCE:       _instance(ud)->_hook = hook;    break;
+               case OT_CLASS:          _class(ud)->_hook = hook;               break;
+               default: break; //shutup compiler
+               }
+       }
+}
+
+void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f)
+{
+       _ss(v)->_compilererrorhandler = f;
+}
+
+SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up)
+{
+       SQObjectPtr *o = NULL;
+       _GETSAFE_OBJ(v, -1, OT_CLOSURE,o);
+       unsigned short tag = SQ_BYTECODE_STREAM_TAG;
+       if(w(up,&tag,2) != 2)
+               return sq_throwerror(v,_SC("io error"));
+       if(!_closure(*o)->Save(v,up,w))
+               return SQ_ERROR;
+       return SQ_OK;
+}
+
+SQRESULT sq_readclosure(HSQUIRRELVM v,SQREADFUNC r,SQUserPointer up)
+{
+       SQObjectPtr func=SQFunctionProto::Create();
+       SQObjectPtr closure=SQClosure::Create(_ss(v),_funcproto(func));
+       unsigned short tag;
+       if(r(up,&tag,2) != 2)
+               return sq_throwerror(v,_SC("io error"));
+       if(tag != SQ_BYTECODE_STREAM_TAG)
+               return sq_throwerror(v,_SC("invalid stream"));
+       if(!_closure(closure)->Load(v,up,r))
+               return SQ_ERROR;
+       v->Push(closure);
+       return SQ_OK;
+}
+
+SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize)
+{
+       return _ss(v)->GetScratchPad(minsize);
+}
+
+SQInteger sq_collectgarbage(HSQUIRRELVM v)
+{
+#ifndef NO_GARBAGE_COLLECTOR
+       return _ss(v)->CollectGarbage(v);
+#else
+       return -1;
+#endif
+}
+
+const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
+{
+       SQObjectPtr &self = stack_get(v,idx);
+       const SQChar *name = NULL;
+       if(type(self) == OT_CLOSURE) {
+               if(_closure(self)->_outervalues.size()>nval) {
+                       v->Push(_closure(self)->_outervalues[nval]);
+                       SQFunctionProto *fp = _funcproto(_closure(self)->_function);
+                       SQOuterVar &ov = fp->_outervalues[nval];
+                       name = _stringval(ov._name);
+               }
+       }
+       return name;
+}
+
+SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
+{
+       SQObjectPtr &self=stack_get(v,idx);
+       switch(type(self))
+       {
+       case OT_CLOSURE:
+               if(_closure(self)->_outervalues.size()>nval){
+                       _closure(self)->_outervalues[nval]=stack_get(v,-1);
+               }
+               else return sq_throwerror(v,_SC("invalid free var index"));
+               break;
+       case OT_NATIVECLOSURE:
+               if(_nativeclosure(self)->_outervalues.size()>nval){
+                       _nativeclosure(self)->_outervalues[nval]=stack_get(v,-1);
+               }
+               else return sq_throwerror(v,_SC("invalid free var index"));
+               break;
+       default:
+               return sq_aux_invalidtype(v,type(self));
+       }
+       v->Pop(1);
+       return SQ_OK;
+}
+
+SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx)
+{
+       SQObjectPtr *o = NULL;
+       _GETSAFE_OBJ(v, idx, OT_CLASS,o);
+       SQObjectPtr &key = stack_get(v,-2);
+       SQObjectPtr &val = stack_get(v,-1);
+       SQObjectPtr attrs;
+       if(type(key) == OT_NULL) {
+               attrs = _class(*o)->_attributes;
+               _class(*o)->_attributes = val;
+               v->Pop(2);
+               v->Push(attrs);
+               return SQ_OK;
+       }else if(_class(*o)->GetAttributes(key,attrs)) {
+               _class(*o)->SetAttributes(key,val);
+               v->Pop(2);
+               v->Push(attrs);
+               return SQ_OK;
+       }
+       return sq_throwerror(v,_SC("wrong index"));
+}
+
+SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx)
+{
+       SQObjectPtr *o = NULL;
+       _GETSAFE_OBJ(v, idx, OT_CLASS,o);
+       SQObjectPtr &key = stack_get(v,-1);
+       SQObjectPtr attrs;
+       if(type(key) == OT_NULL) {
+               attrs = _class(*o)->_attributes;
+               v->Pop();
+               v->Push(attrs);
+               return SQ_OK;
+       }
+       else if(_class(*o)->GetAttributes(key,attrs)) {
+               v->Pop();
+               v->Push(attrs);
+               return SQ_OK;
+       }
+       return sq_throwerror(v,_SC("wrong index"));
+}
+
+SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx)
+{
+       SQObjectPtr *o = NULL;
+       _GETSAFE_OBJ(v, idx, OT_CLASS,o);
+       if(_class(*o)->_base)
+               v->Push(SQObjectPtr(_class(*o)->_base));
+       else
+               v->Push(_null_);
+       return SQ_OK;
+}
+
+SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx)
+{
+       SQObjectPtr *o = NULL;
+       _GETSAFE_OBJ(v, idx, OT_INSTANCE,o);
+       v->Push(SQObjectPtr(_instance(*o)->_class));
+       return SQ_OK;
+}
+
+SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx)
+{
+       SQObjectPtr *o = NULL;
+       _GETSAFE_OBJ(v, idx, OT_CLASS,o);
+       v->Push(_class(*o)->CreateInstance());
+       return SQ_OK;
+}
+
+void sq_weakref(HSQUIRRELVM v,SQInteger idx)
+{
+       SQObject &o=stack_get(v,idx);
+       if(ISREFCOUNTED(type(o))) {
+               v->Push(_refcounted(o)->GetWeakRef(type(o)));
+               return;
+       }
+       v->Push(o);
+}
+
+SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx)
+{
+       SQObjectPtr &o = stack_get(v,idx);
+       if(type(o) != OT_WEAKREF) {
+               return sq_throwerror(v,_SC("the object must be a weakref"));
+       }
+       v->Push(_weakref(o)->_obj);
+       return SQ_OK;
+}
+
+SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t)
+{
+       SQSharedState *ss = _ss(v);
+       switch(t) {
+       case OT_TABLE: v->Push(ss->_table_default_delegate); break;
+       case OT_ARRAY: v->Push(ss->_array_default_delegate); break;
+       case OT_STRING: v->Push(ss->_string_default_delegate); break;
+       case OT_INTEGER: case OT_FLOAT: v->Push(ss->_number_default_delegate); break;
+       case OT_GENERATOR: v->Push(ss->_generator_default_delegate); break;
+       case OT_CLOSURE: case OT_NATIVECLOSURE: v->Push(ss->_closure_default_delegate); break;
+       case OT_THREAD: v->Push(ss->_thread_default_delegate); break;
+       case OT_CLASS: v->Push(ss->_class_default_delegate); break;
+       case OT_INSTANCE: v->Push(ss->_instance_default_delegate); break;
+       case OT_WEAKREF: v->Push(ss->_weakref_default_delegate); break;
+       default: return sq_throwerror(v,_SC("the type doesn't have a default delegate"));
+       }
+       return SQ_OK;
+}
+
+SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx)
+{
+       SQObjectPtr o=stack_get(v,idx),&refpos = stack_get(v,-1),realkey,val;
+       if(type(o) == OT_GENERATOR) {
+               return sq_throwerror(v,_SC("cannot iterate a generator"));
+       }
+       bool finished;
+       if(!v->FOREACH_OP(o,realkey,val,refpos,0,finished))
+               return SQ_ERROR;
+       if(!finished) {
+               v->Push(realkey);
+               v->Push(val);
+               return SQ_OK;
+       }
+       return SQ_ERROR;
+}
+
+struct BufState{
+       const SQChar *buf;
+       SQInteger ptr;
+       SQInteger size;
+};
+
+SQInteger buf_lexfeed(SQUserPointer file)
+{
+       BufState *buf=(BufState*)file;
+       if(buf->size<(buf->ptr+1))
+               return 0;
+       return buf->buf[buf->ptr++];
+}
+
+SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror) {
+       BufState buf;
+       buf.buf = s;
+       buf.size = size;
+       buf.ptr = 0;
+       return sq_compile(v, buf_lexfeed, &buf, sourcename, raiseerror);
+}
+
+void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx)
+{
+       dest->Push(stack_get(src,idx));
+}
+
+void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc)
+{
+       _ss(v)->_printfunc = printfunc;
+}
+
+SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v)
+{
+       return _ss(v)->_printfunc;
+}
+
+void *sq_malloc(SQUnsignedInteger size)
+{
+       return SQ_MALLOC(size);
+}
+
+void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize)
+{
+       return SQ_REALLOC(p,oldsize,newsize);
+}
+void sq_free(void *p,SQUnsignedInteger size)
+{
+       SQ_FREE(p,size);
+}
index b463e81..451b07d 100644 (file)
@@ -1,79 +1,79 @@
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQARRAY_H_\r
-#define _SQARRAY_H_\r
-\r
-struct SQArray : public CHAINABLE_OBJ\r
-{\r
-private:\r
-       SQArray(SQSharedState *ss,SQInteger nsize){_values.resize(nsize); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}\r
-       ~SQArray()\r
-       {\r
-               REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);\r
-       }\r
-public:\r
-       static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){\r
-               SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray));\r
-               new (newarray) SQArray(ss,nInitialSize);\r
-               return newarray;\r
-       }\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-       void Mark(SQCollectable **chain);\r
-#endif\r
-       void Finalize(){\r
-               _values.resize(0);\r
-       }\r
-       bool Get(const SQInteger nidx,SQObjectPtr &val)\r
-       {\r
-               if(nidx>=0 && nidx<(SQInteger)_values.size()){\r
-                       SQObjectPtr &o = _values[nidx];\r
-                       val = _realval(o);\r
-                       return true;\r
-               }\r
-               else return false;\r
-       }\r
-       bool Set(const SQInteger nidx,const SQObjectPtr &val)\r
-       {\r
-               if(nidx>=0 && nidx<(SQInteger)_values.size()){\r
-                       _values[nidx]=val;\r
-                       return true;\r
-               }\r
-               else return false;\r
-       }\r
-       SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval)\r
-       {\r
-               SQUnsignedInteger idx=TranslateIndex(refpos);\r
-               while(idx<_values.size()){\r
-                       //first found\r
-                       outkey=(SQInteger)idx;\r
-                       SQObjectPtr &o = _values[idx];\r
-                       outval = _realval(o);\r
-                       //return idx for the next iteration\r
-                       return ++idx;\r
-               }\r
-               //nothing to iterate anymore\r
-               return -1;\r
-       }\r
-       SQArray *Clone(){SQArray *anew=Create(_opt_ss(this),Size()); anew->_values.copy(_values); return anew; }\r
-       SQInteger Size() const {return _values.size();}\r
-       void Resize(SQInteger size,SQObjectPtr &fill = _null_) { _values.resize(size,fill); ShrinkIfNeeded(); }\r
-       void Reserve(SQInteger size) { _values.reserve(size); }\r
-       void Append(const SQObject &o){_values.push_back(o);}\r
-       void Extend(const SQArray *a);\r
-       SQObjectPtr &Top(){return _values.top();}\r
-       void Pop(){_values.pop_back(); ShrinkIfNeeded(); }\r
-       void Insert(const SQObject& idx,const SQObject &val){_values.insert((SQUnsignedInteger)tointeger(idx),val);}\r
-       void ShrinkIfNeeded() {\r
-               if(_values.size() <= _values.capacity()>>2) //shrink the array\r
-                       _values.shrinktofit();\r
-       }\r
-       void Remove(SQUnsignedInteger idx){\r
-               _values.remove(idx);\r
-               ShrinkIfNeeded();\r
-       }\r
-       void Release()\r
-       {\r
-               sq_delete(this,SQArray);\r
-       }\r
-       SQObjectPtrVec _values;\r
-};\r
-#endif //_SQARRAY_H_\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQARRAY_H_
+#define _SQARRAY_H_
+
+struct SQArray : public CHAINABLE_OBJ
+{
+private:
+       SQArray(SQSharedState *ss,SQInteger nsize){_values.resize(nsize); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
+       ~SQArray()
+       {
+               REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
+       }
+public:
+       static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){
+               SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray));
+               new (newarray) SQArray(ss,nInitialSize);
+               return newarray;
+       }
+#ifndef NO_GARBAGE_COLLECTOR
+       void Mark(SQCollectable **chain);
+#endif
+       void Finalize(){
+               _values.resize(0);
+       }
+       bool Get(const SQInteger nidx,SQObjectPtr &val)
+       {
+               if(nidx>=0 && nidx<(SQInteger)_values.size()){
+                       SQObjectPtr &o = _values[nidx];
+                       val = _realval(o);
+                       return true;
+               }
+               else return false;
+       }
+       bool Set(const SQInteger nidx,const SQObjectPtr &val)
+       {
+               if(nidx>=0 && nidx<(SQInteger)_values.size()){
+                       _values[nidx]=val;
+                       return true;
+               }
+               else return false;
+       }
+       SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval)
+       {
+               SQUnsignedInteger idx=TranslateIndex(refpos);
+               while(idx<_values.size()){
+                       //first found
+                       outkey=(SQInteger)idx;
+                       SQObjectPtr &o = _values[idx];
+                       outval = _realval(o);
+                       //return idx for the next iteration
+                       return ++idx;
+               }
+               //nothing to iterate anymore
+               return -1;
+       }
+       SQArray *Clone(){SQArray *anew=Create(_opt_ss(this),Size()); anew->_values.copy(_values); return anew; }
+       SQInteger Size() const {return _values.size();}
+       void Resize(SQInteger size,SQObjectPtr &fill = _null_) { _values.resize(size,fill); ShrinkIfNeeded(); }
+       void Reserve(SQInteger size) { _values.reserve(size); }
+       void Append(const SQObject &o){_values.push_back(o);}
+       void Extend(const SQArray *a);
+       SQObjectPtr &Top(){return _values.top();}
+       void Pop(){_values.pop_back(); ShrinkIfNeeded(); }
+       void Insert(const SQObject& idx,const SQObject &val){_values.insert((SQUnsignedInteger)tointeger(idx),val);}
+       void ShrinkIfNeeded() {
+               if(_values.size() <= _values.capacity()>>2) //shrink the array
+                       _values.shrinktofit();
+       }
+       void Remove(SQUnsignedInteger idx){
+               _values.remove(idx);
+               ShrinkIfNeeded();
+       }
+       void Release()
+       {
+               sq_delete(this,SQArray);
+       }
+       SQObjectPtrVec _values;
+};
+#endif //_SQARRAY_H_
index b8d3421..cc8b368 100644 (file)
-/*\r
-       see copyright notice in squirrel.h\r
-*/\r
-#include "sqpcheader.h"\r
-#include "sqvm.h"\r
-#include "sqstring.h"\r
-#include "sqtable.h"\r
-#include "sqarray.h"\r
-#include "sqfuncproto.h"\r
-#include "sqclosure.h"\r
-#include "sqclass.h"\r
-#include <stdlib.h>\r
-#include <stdarg.h>\r
-#include <ctype.h>\r
-\r
-bool str2num(const SQChar *s,SQObjectPtr &res)\r
-{\r
-       SQChar *end;\r
-       if(scstrstr(s,_SC("."))){\r
-               SQFloat r = SQFloat(scstrtod(s,&end));\r
-               if(s == end) return false;\r
-               res = r;\r
-               return true;\r
-       }\r
-       else{\r
-               SQInteger r = SQInteger(scstrtol(s,&end,10));\r
-               if(s == end) return false;\r
-               res = r;\r
-               return true;\r
-       }\r
-}\r
-\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-static SQInteger base_collectgarbage(HSQUIRRELVM v)\r
-{\r
-       sq_pushinteger(v, sq_collectgarbage(v));\r
-       return 1;\r
-}\r
-#endif\r
-\r
-static SQInteger base_getroottable(HSQUIRRELVM v)\r
-{\r
-       v->Push(v->_roottable);\r
-       return 1;\r
-}\r
-\r
-static SQInteger base_setroottable(HSQUIRRELVM v)\r
-{\r
-       SQObjectPtr &o=stack_get(v,2);\r
-       if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR;\r
-       v->Push(o);\r
-       return 1;\r
-}\r
-\r
-static SQInteger base_seterrorhandler(HSQUIRRELVM v)\r
-{\r
-       sq_seterrorhandler(v);\r
-       return 0;\r
-}\r
-\r
-static SQInteger base_setdebughook(HSQUIRRELVM v)\r
-{\r
-       sq_setdebughook(v);\r
-       return 0;\r
-}\r
-\r
-static SQInteger base_enabledebuginfo(HSQUIRRELVM v)\r
-{\r
-       SQObjectPtr &o=stack_get(v,2);\r
-       sq_enabledebuginfo(v,(type(o) != OT_NULL)?1:0);\r
-       return 0;\r
-}\r
-\r
-static SQInteger base_getstackinfos(HSQUIRRELVM v)\r
-{\r
-       SQInteger level;\r
-       SQStackInfos si;\r
-       SQInteger seq = 0;\r
-       const SQChar *name = NULL;\r
-       sq_getinteger(v, -1, &level);\r
-       if (SQ_SUCCEEDED(sq_stackinfos(v, level, &si)))\r
-       {\r
-               const SQChar *fn = _SC("unknown");\r
-               const SQChar *src = _SC("unknown");\r
-               if(si.funcname)fn = si.funcname;\r
-               if(si.source)src = si.source;\r
-               sq_newtable(v);\r
-               sq_pushstring(v, _SC("func"), -1);\r
-               sq_pushstring(v, fn, -1);\r
-               sq_createslot(v, -3);\r
-               sq_pushstring(v, _SC("src"), -1);\r
-               sq_pushstring(v, src, -1);\r
-               sq_createslot(v, -3);\r
-               sq_pushstring(v, _SC("line"), -1);\r
-               sq_pushinteger(v, si.line);\r
-               sq_createslot(v, -3);\r
-               sq_pushstring(v, _SC("locals"), -1);\r
-               sq_newtable(v);\r
-               seq=0;\r
-               while ((name = sq_getlocal(v, level, seq))) {\r
-                       sq_pushstring(v, name, -1);\r
-                       sq_push(v, -2);\r
-                       sq_createslot(v, -4);\r
-                       sq_pop(v, 1);\r
-                       seq++;\r
-               }\r
-               sq_createslot(v, -3);\r
-               return 1;\r
-       }\r
-\r
-       return 0;\r
-}\r
-\r
-static SQInteger base_assert(HSQUIRRELVM v)\r
-{\r
-       if(v->IsFalse(stack_get(v,2))){\r
-               return sq_throwerror(v,_SC("assertion failed"));\r
-       }\r
-       return 0;\r
-}\r
-\r
-static SQInteger get_slice_params(HSQUIRRELVM v,SQInteger &sidx,SQInteger &eidx,SQObjectPtr &o)\r
-{\r
-       SQInteger top = sq_gettop(v);\r
-       sidx=0;\r
-       eidx=0;\r
-       o=stack_get(v,1);\r
-       SQObjectPtr &start=stack_get(v,2);\r
-       if(type(start)!=OT_NULL && sq_isnumeric(start)){\r
-               sidx=tointeger(start);\r
-       }\r
-       if(top>2){\r
-               SQObjectPtr &end=stack_get(v,3);\r
-               if(sq_isnumeric(end)){\r
-                       eidx=tointeger(end);\r
-               }\r
-       }\r
-       else {\r
-               eidx = sq_getsize(v,1);\r
-       }\r
-       return 1;\r
-}\r
-\r
-static SQInteger base_print(HSQUIRRELVM v)\r
-{\r
-       const SQChar *str;\r
-       sq_tostring(v,2);\r
-       sq_getstring(v,-1,&str);\r
-       if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%s"),str);\r
-       return 0;\r
-}\r
-\r
-static SQInteger base_compilestring(HSQUIRRELVM v)\r
-{\r
-       SQInteger nargs=sq_gettop(v);\r
-       const SQChar *src=NULL,*name=_SC("unnamedbuffer");\r
-       SQInteger size;\r
-       sq_getstring(v,2,&src);\r
-       size=sq_getsize(v,2);\r
-       if(nargs>2){\r
-               sq_getstring(v,3,&name);\r
-       }\r
-       if(SQ_SUCCEEDED(sq_compilebuffer(v,src,size,name,SQFalse)))\r
-               return 1;\r
-       else\r
-               return SQ_ERROR;\r
-}\r
-\r
-static SQInteger base_newthread(HSQUIRRELVM v)\r
-{\r
-       SQObjectPtr &func = stack_get(v,2);\r
-       SQInteger stksize = (_funcproto(_closure(func)->_function)->_stacksize << 1) +2;\r
-       HSQUIRRELVM newv = sq_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize);\r
-       sq_move(newv,v,-2);\r
-       return 1;\r
-}\r
-\r
-static SQInteger base_suspend(HSQUIRRELVM v)\r
-{\r
-       return sq_suspendvm(v);\r
-}\r
-\r
-static SQInteger base_array(HSQUIRRELVM v)\r
-{\r
-       SQArray *a;\r
-       SQObject &size = stack_get(v,2);\r
-       if(sq_gettop(v) > 2) {\r
-               a = SQArray::Create(_ss(v),0);\r
-               a->Resize(tointeger(size),stack_get(v,3));\r
-       }\r
-       else {\r
-               a = SQArray::Create(_ss(v),tointeger(size));\r
-       }\r
-       v->Push(a);\r
-       return 1;\r
-}\r
-\r
-static SQInteger base_type(HSQUIRRELVM v)\r
-{\r
-       SQObjectPtr &o = stack_get(v,2);\r
-       v->Push(SQString::Create(_ss(v),GetTypeName(o),-1));\r
-       return 1;\r
-}\r
-\r
-static SQRegFunction base_funcs[]={\r
-       //generic\r
-       {_SC("seterrorhandler"),base_seterrorhandler,2, NULL},\r
-       {_SC("setdebughook"),base_setdebughook,2, NULL},\r
-       {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL},\r
-       {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")},\r
-       {_SC("getroottable"),base_getroottable,1, NULL},\r
-       {_SC("setroottable"),base_setroottable,2, NULL},\r
-       {_SC("assert"),base_assert,2, NULL},\r
-       {_SC("print"),base_print,2, NULL},\r
-       {_SC("compilestring"),base_compilestring,-2, _SC(".ss")},\r
-       {_SC("newthread"),base_newthread,2, _SC(".c")},\r
-       {_SC("suspend"),base_suspend,-1, NULL},\r
-       {_SC("array"),base_array,-2, _SC(".n")},\r
-       {_SC("type"),base_type,2, NULL},\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-       {_SC("collectgarbage"),base_collectgarbage,1, _SC("t")},\r
-#endif\r
-       {0,0}\r
-};\r
-\r
-void sq_base_register(HSQUIRRELVM v)\r
-{\r
-       SQInteger i=0;\r
-       sq_pushroottable(v);\r
-       while(base_funcs[i].name!=0) {\r
-               sq_pushstring(v,base_funcs[i].name,-1);\r
-               sq_newclosure(v,base_funcs[i].f,0);\r
-               sq_setnativeclosurename(v,-1,base_funcs[i].name);\r
-               sq_setparamscheck(v,base_funcs[i].nparamscheck,base_funcs[i].typemask);\r
-               sq_createslot(v,-3);\r
-               i++;\r
-       }\r
-       sq_pushstring(v,_SC("_charsize_"),-1);\r
-       sq_pushinteger(v,sizeof(SQChar));\r
-       sq_createslot(v,-3);\r
-       sq_pushstring(v,_SC("_intsize_"),-1);\r
-       sq_pushinteger(v,sizeof(SQInteger));\r
-       sq_createslot(v,-3);\r
-       sq_pop(v,1);\r
-}\r
-\r
-static SQInteger default_delegate_len(HSQUIRRELVM v)\r
-{\r
-       v->Push(SQInteger(sq_getsize(v,1)));\r
-       return 1;\r
-}\r
-\r
-static SQInteger default_delegate_tofloat(HSQUIRRELVM v)\r
-{\r
-       SQObjectPtr &o=stack_get(v,1);\r
-       switch(type(o)){\r
-       case OT_STRING:{\r
-               SQObjectPtr res;\r
-               if(str2num(_stringval(o),res)){\r
-                       v->Push(SQObjectPtr(tofloat(res)));\r
-                       break;\r
-               }}\r
-               return sq_throwerror(v, _SC("cannot convert the string"));\r
-               break;\r
-       case OT_INTEGER:case OT_FLOAT:\r
-               v->Push(SQObjectPtr(tofloat(o)));\r
-               break;\r
-       case OT_BOOL:\r
-               v->Push(SQObjectPtr((SQFloat)(_integer(o)?1:0)));\r
-               break;\r
-       default:\r
-               v->Push(_null_);\r
-               break;\r
-       }\r
-       return 1;\r
-}\r
-\r
-static SQInteger default_delegate_tointeger(HSQUIRRELVM v)\r
-{\r
-       SQObjectPtr &o=stack_get(v,1);\r
-       switch(type(o)){\r
-       case OT_STRING:{\r
-               SQObjectPtr res;\r
-               if(str2num(_stringval(o),res)){\r
-                       v->Push(SQObjectPtr(tointeger(res)));\r
-                       break;\r
-               }}\r
-               return sq_throwerror(v, _SC("cannot convert the string"));\r
-               break;\r
-       case OT_INTEGER:case OT_FLOAT:\r
-               v->Push(SQObjectPtr(tointeger(o)));\r
-               break;\r
-       case OT_BOOL:\r
-               v->Push(SQObjectPtr(_integer(o)?(SQInteger)1:(SQInteger)0));\r
-               break;\r
-       default:\r
-               v->Push(_null_);\r
-               break;\r
-       }\r
-       return 1;\r
-}\r
-\r
-static SQInteger default_delegate_tostring(HSQUIRRELVM v)\r
-{\r
-       sq_tostring(v,1);\r
-       return 1;\r
-}\r
-\r
-static SQInteger obj_delegate_weakref(HSQUIRRELVM v)\r
-{\r
-       sq_weakref(v,1);\r
-       return 1;\r
-}\r
-\r
-static SQInteger number_delegate_tochar(HSQUIRRELVM v)\r
-{\r
-       SQObject &o=stack_get(v,1);\r
-       SQChar c = (SQChar)tointeger(o);\r
-       v->Push(SQString::Create(_ss(v),(const SQChar *)&c,1));\r
-       return 1;\r
-}\r
-\r
-\r
-/////////////////////////////////////////////////////////////////\r
-//TABLE DEFAULT DELEGATE\r
-\r
-static SQInteger table_rawdelete(HSQUIRRELVM v)\r
-{\r
-       if(SQ_FAILED(sq_rawdeleteslot(v,1,SQTrue)))\r
-               return SQ_ERROR;\r
-       return 1;\r
-}\r
-\r
-\r
-static SQInteger container_rawexists(HSQUIRRELVM v)\r
-{\r
-       if(SQ_SUCCEEDED(sq_rawget(v,-2))) {\r
-               sq_pushbool(v,SQTrue);\r
-               return 1;\r
-       }\r
-       sq_pushbool(v,SQFalse);\r
-       return 1;\r
-}\r
-\r
-static SQInteger table_rawset(HSQUIRRELVM v)\r
-{\r
-       return sq_rawset(v,-3);\r
-}\r
-\r
-\r
-static SQInteger table_rawget(HSQUIRRELVM v)\r
-{\r
-       return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR;\r
-}\r
-\r
-SQRegFunction SQSharedState::_table_default_delegate_funcz[]={\r
-       {_SC("len"),default_delegate_len,1, _SC("t")},\r
-       {_SC("rawget"),table_rawget,2, _SC("t")},\r
-       {_SC("rawset"),table_rawset,3, _SC("t")},\r
-       {_SC("rawdelete"),table_rawdelete,2, _SC("t")},\r
-       {_SC("rawin"),container_rawexists,2, _SC("t")},\r
-       {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
-       {_SC("tostring"),default_delegate_tostring,1, _SC(".")},\r
-       {0,0}\r
-};\r
-\r
-//ARRAY DEFAULT DELEGATE///////////////////////////////////////\r
-\r
-static SQInteger array_append(HSQUIRRELVM v)\r
-{\r
-       return sq_arrayappend(v,-2);\r
-}\r
-\r
-static SQInteger array_extend(HSQUIRRELVM v)\r
-{\r
-       _array(stack_get(v,1))->Extend(_array(stack_get(v,2)));\r
-       return 0;\r
-}\r
-\r
-static SQInteger array_reverse(HSQUIRRELVM v)\r
-{\r
-       return sq_arrayreverse(v,-1);\r
-}\r
-\r
-static SQInteger array_pop(HSQUIRRELVM v)\r
-{\r
-       return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR;\r
-}\r
-\r
-static SQInteger array_top(HSQUIRRELVM v)\r
-{\r
-       SQObject &o=stack_get(v,1);\r
-       if(_array(o)->Size()>0){\r
-               v->Push(_array(o)->Top());\r
-               return 1;\r
-       }\r
-       else return sq_throwerror(v,_SC("top() on a empty array"));\r
-}\r
-\r
-static SQInteger array_insert(HSQUIRRELVM v)\r
-{\r
-       SQObject &o=stack_get(v,1);\r
-       SQObject &idx=stack_get(v,2);\r
-       SQObject &val=stack_get(v,3);\r
-       _array(o)->Insert(idx,val);\r
-       return 0;\r
-}\r
-\r
-static SQInteger array_remove(HSQUIRRELVM v)\r
-{\r
-       SQObject &o = stack_get(v, 1);\r
-       SQObject &idx = stack_get(v, 2);\r
-       if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type"));\r
-       SQObjectPtr val;\r
-       if(_array(o)->Get(tointeger(idx), val)) {\r
-               _array(o)->Remove(tointeger(idx));\r
-               v->Push(val);\r
-               return 1;\r
-       }\r
-       return sq_throwerror(v, _SC("idx out of range"));\r
-}\r
-\r
-static SQInteger array_resize(HSQUIRRELVM v)\r
-{\r
-       SQObject &o = stack_get(v, 1);\r
-       SQObject &nsize = stack_get(v, 2);\r
-       SQObjectPtr fill;\r
-       if(sq_isnumeric(nsize)) {\r
-               if(sq_gettop(v) > 2)\r
-                       fill = stack_get(v, 3);\r
-               _array(o)->Resize(tointeger(nsize),fill);\r
-               return 0;\r
-       }\r
-       return sq_throwerror(v, _SC("size must be a number"));\r
-}\r
-\r
-\r
-//QSORT ala Sedgewick\r
-bool _qsort_compare(HSQUIRRELVM v,SQObjectPtr &arr,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret)\r
-{\r
-       if(func < 0) {\r
-               if(!v->ObjCmp(a,b,ret)) return false;\r
-       }\r
-       else {\r
-               SQInteger top = sq_gettop(v);\r
-               sq_push(v, func);\r
-               sq_pushroottable(v);\r
-               v->Push(a);\r
-               v->Push(b);\r
-               if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) {\r
-                       v->Raise_Error(_SC("compare func failed"));\r
-                       return false;\r
-               }\r
-               sq_getinteger(v, -1, &ret);\r
-               sq_settop(v, top);\r
-               return true;\r
-       }\r
-       return true;\r
-}\r
-//QSORT ala Sedgewick\r
-bool _qsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger l, SQInteger r,SQInteger func)\r
-{\r
-       SQInteger i, j;\r
-       SQArray *a=_array(arr);\r
-       SQObjectPtr pivot,t;\r
-       if( l < r ){\r
-               pivot = a->_values[l];\r
-               i = l; j = r+1;\r
-               while(1){\r
-                       SQInteger ret;\r
-                       do { \r
-                               ++i; \r
-                               if(i > r) break;\r
-                               if(!_qsort_compare(v,arr,a->_values[i],pivot,func,ret))\r
-                                       return false;\r
-                       } while( ret <= 0);\r
-                       do {\r
-                               --j; \r
-                               if(!_qsort_compare(v,arr,a->_values[j],pivot,func,ret))\r
-                                       return false;\r
-                       }\r
-                       while( ret > 0 );\r
-                       if( i >= j ) break;\r
-                       t = a->_values[i]; a->_values[i] = a->_values[j]; a->_values[j] = t;\r
-               }\r
-               t = a->_values[l]; a->_values[l] = a->_values[j]; a->_values[j] = t;\r
-               if(!_qsort( v, arr, l, j-1,func)) return false;\r
-               if(!_qsort( v, arr, j+1, r,func)) return false;\r
-       }\r
-       return true;\r
-}\r
-\r
-static SQInteger array_sort(HSQUIRRELVM v)\r
-{\r
-       SQInteger func = -1;\r
-       SQObjectPtr &o = stack_get(v,1);\r
-       SQObject &funcobj = stack_get(v,2);\r
-       if(_array(o)->Size() > 1) {\r
-               if(type(funcobj) == OT_CLOSURE || type(funcobj) == OT_NATIVECLOSURE) func = 2;\r
-               if(!_qsort(v, o, 0, _array(o)->Size()-1, func))\r
-                       return SQ_ERROR;\r
-\r
-       }\r
-       return 0;\r
-}\r
-static SQInteger array_slice(HSQUIRRELVM v)\r
-{\r
-       SQInteger sidx,eidx;\r
-       SQObjectPtr o;\r
-       if(get_slice_params(v,sidx,eidx,o)==-1)return -1;\r
-       if(sidx<0)sidx=_array(o)->Size()+sidx;\r
-       if(eidx<0)eidx=_array(o)->Size()+eidx;\r
-       if(eidx <= sidx)return sq_throwerror(v,_SC("wrong indexes"));\r
-       SQArray *arr=SQArray::Create(_ss(v),eidx-sidx);\r
-       SQObjectPtr t;\r
-       SQInteger count=0;\r
-       for(SQInteger i=sidx;i<eidx;i++){\r
-               _array(o)->Get(i,t);\r
-               arr->Set(count++,t);\r
-       }\r
-       v->Push(arr);\r
-       return 1;\r
-       \r
-}\r
-\r
-SQRegFunction SQSharedState::_array_default_delegate_funcz[]={\r
-       {_SC("len"),default_delegate_len,1, _SC("a")},\r
-       {_SC("append"),array_append,2, _SC("a")},\r
-       {_SC("extend"),array_extend,2, _SC("aa")},\r
-       {_SC("push"),array_append,2, _SC("a")},\r
-       {_SC("pop"),array_pop,1, _SC("a")},\r
-       {_SC("top"),array_top,1, _SC("a")},\r
-       {_SC("insert"),array_insert,3, _SC("an")},\r
-       {_SC("remove"),array_remove,2, _SC("an")},\r
-       {_SC("resize"),array_resize,-2, _SC("an")},\r
-       {_SC("reverse"),array_reverse,1, _SC("a")},\r
-       {_SC("sort"),array_sort,-1, _SC("ac")},\r
-       {_SC("slice"),array_slice,-1, _SC("ann")},\r
-       {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
-       {_SC("tostring"),default_delegate_tostring,1, _SC(".")},\r
-       {0,0}\r
-};\r
-\r
-//STRING DEFAULT DELEGATE//////////////////////////\r
-static SQInteger string_slice(HSQUIRRELVM v)\r
-{\r
-       SQInteger sidx,eidx;\r
-       SQObjectPtr o;\r
-       if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1;\r
-       if(sidx<0)sidx=_string(o)->_len+sidx;\r
-       if(eidx<0)eidx=_string(o)->_len+eidx;\r
-       if(eidx<sidx)\r
-               return sq_throwerror(v,_SC("wrong indexes"));\r
-       v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx));\r
-       return 1;\r
-}\r
-\r
-static SQInteger string_find(HSQUIRRELVM v)\r
-{\r
-       SQInteger top,start_idx=0;\r
-       const SQChar *str,*substr,*ret;\r
-       if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){\r
-               if(top>2)sq_getinteger(v,3,&start_idx);\r
-               if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){\r
-                       ret=scstrstr(&str[start_idx],substr);\r
-                       if(ret){\r
-                               sq_pushinteger(v,(SQInteger)(ret-str));\r
-                               return 1;\r
-                       }\r
-               }\r
-               return 0;\r
-       }\r
-       return sq_throwerror(v,_SC("invalid param"));\r
-}\r
-\r
-#define STRING_TOFUNCZ(func) static SQInteger string_##func(HSQUIRRELVM v) \\r
-{ \\r
-       SQObject str=stack_get(v,1); \\r
-       SQInteger len=_string(str)->_len; \\r
-       const SQChar *sThis=_stringval(str); \\r
-       SQChar *sNew=(_ss(v)->GetScratchPad(rsl(len))); \\r
-       for(SQInteger i=0;i<len;i++) sNew[i]=func(sThis[i]); \\r
-       v->Push(SQString::Create(_ss(v),sNew,len)); \\r
-       return 1; \\r
-}\r
-\r
-\r
-STRING_TOFUNCZ(tolower)\r
-STRING_TOFUNCZ(toupper)\r
-\r
-SQRegFunction SQSharedState::_string_default_delegate_funcz[]={\r
-       {_SC("len"),default_delegate_len,1, _SC("s")},\r
-       {_SC("tointeger"),default_delegate_tointeger,1, _SC("s")},\r
-       {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")},\r
-       {_SC("tostring"),default_delegate_tostring,1, _SC(".")},\r
-       {_SC("slice"),string_slice,-1, _SC(" s n  n")},\r
-       {_SC("find"),string_find,-2, _SC("s s n ")},\r
-       {_SC("tolower"),string_tolower,1, _SC("s")},\r
-       {_SC("toupper"),string_toupper,1, _SC("s")},\r
-       {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
-       {0,0}\r
-};\r
-\r
-//INTEGER DEFAULT DELEGATE//////////////////////////\r
-SQRegFunction SQSharedState::_number_default_delegate_funcz[]={\r
-       {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")},\r
-       {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")},\r
-       {_SC("tostring"),default_delegate_tostring,1, _SC(".")},\r
-       {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")},\r
-       {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
-       {0,0}\r
-};\r
-\r
-//CLOSURE DEFAULT DELEGATE//////////////////////////\r
-static SQInteger closure_pcall(HSQUIRRELVM v)\r
-{\r
-       return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQFalse))?1:SQ_ERROR;\r
-}\r
-\r
-static SQInteger closure_call(HSQUIRRELVM v)\r
-{\r
-       return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQTrue))?1:SQ_ERROR;\r
-}\r
-\r
-static SQInteger _closure_acall(HSQUIRRELVM v,SQBool raiseerror)\r
-{\r
-       SQArray *aparams=_array(stack_get(v,2));\r
-       SQInteger nparams=aparams->Size();\r
-       v->Push(stack_get(v,1));\r
-       for(SQInteger i=0;i<nparams;i++)v->Push(aparams->_values[i]);\r
-       return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue,raiseerror))?1:SQ_ERROR;\r
-}\r
-\r
-static SQInteger closure_acall(HSQUIRRELVM v)\r
-{\r
-       return _closure_acall(v,SQTrue);\r
-}\r
-\r
-static SQInteger closure_pacall(HSQUIRRELVM v)\r
-{\r
-       return _closure_acall(v,SQFalse);\r
-}\r
-\r
-static SQInteger closure_bindenv(HSQUIRRELVM v)\r
-{\r
-       if(SQ_FAILED(sq_bindenv(v,1)))\r
-               return SQ_ERROR;\r
-       return 1;\r
-}\r
-\r
-static SQInteger closure_getinfos(HSQUIRRELVM v) {\r
-       SQObject o = stack_get(v,1);\r
-       SQTable *res = SQTable::Create(_ss(v),4);\r
-       if(type(o) == OT_CLOSURE) {\r
-               SQFunctionProto *f = _funcproto(_closure(o)->_function);\r
-               SQInteger nparams = f->_parameters.size() + (f->_varparams?1:0);\r
-               SQObjectPtr params = SQArray::Create(_ss(v),nparams);\r
-               for(SQUnsignedInteger n = 0; n<f->_parameters.size(); n++) {\r
-                       _array(params)->Set((SQInteger)n,f->_parameters[n]);\r
-               }\r
-               if(f->_varparams) {\r
-                       _array(params)->Set(nparams-1,SQString::Create(_ss(v),_SC("..."),-1));\r
-               }\r
-               res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),false);\r
-               res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),f->_name);\r
-               res->NewSlot(SQString::Create(_ss(v),_SC("src"),-1),f->_sourcename);\r
-               res->NewSlot(SQString::Create(_ss(v),_SC("parameters"),-1),params);\r
-               res->NewSlot(SQString::Create(_ss(v),_SC("varargs"),-1),f->_varparams);\r
-       }\r
-       else { //OT_NATIVECLOSURE \r
-               SQNativeClosure *nc = _nativeclosure(o);\r
-               res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),true);\r
-               res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),nc->_name);\r
-               res->NewSlot(SQString::Create(_ss(v),_SC("paramscheck"),-1),nc->_nparamscheck);\r
-               SQObjectPtr typecheck;\r
-               if(nc->_typecheck.size() > 0) {\r
-                       typecheck =\r
-                               SQArray::Create(_ss(v), nc->_typecheck.size());\r
-                       for(SQUnsignedInteger n = 0; n<nc->_typecheck.size(); n++) {\r
-                                       _array(typecheck)->Set((SQInteger)n,nc->_typecheck[n]);\r
-                       }\r
-               }\r
-               res->NewSlot(SQString::Create(_ss(v),_SC("typecheck"),-1),typecheck);\r
-       }\r
-       v->Push(res);\r
-       return 1;\r
-}\r
-\r
-\r
-SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={\r
-       {_SC("call"),closure_call,-1, _SC("c")},\r
-       {_SC("pcall"),closure_pcall,-1, _SC("c")},\r
-       {_SC("acall"),closure_acall,2, _SC("ca")},\r
-       {_SC("pacall"),closure_pacall,2, _SC("ca")},\r
-       {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
-       {_SC("tostring"),default_delegate_tostring,1, _SC(".")},\r
-       {_SC("bindenv"),closure_bindenv,2, _SC("c x|y|t")},\r
-       {_SC("getinfos"),closure_getinfos,1, _SC("c")},\r
-       {0,0}\r
-};\r
-\r
-//GENERATOR DEFAULT DELEGATE\r
-static SQInteger generator_getstatus(HSQUIRRELVM v)\r
-{\r
-       SQObject &o=stack_get(v,1);\r
-       switch(_generator(o)->_state){\r
-               case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break;\r
-               case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break;\r
-               case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break;\r
-       }\r
-       return 1;\r
-}\r
-\r
-SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={\r
-       {_SC("getstatus"),generator_getstatus,1, _SC("g")},\r
-       {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
-       {_SC("tostring"),default_delegate_tostring,1, _SC(".")},\r
-       {0,0}\r
-};\r
-\r
-//THREAD DEFAULT DELEGATE\r
-\r
-static SQInteger thread_call(HSQUIRRELVM v)\r
-{\r
-       SQObjectPtr o = stack_get(v,1);\r
-       if(type(o) == OT_THREAD) {\r
-               SQInteger nparams = sq_gettop(v);\r
-               _thread(o)->Push(_thread(o)->_roottable);\r
-               for(SQInteger i = 2; i<(nparams+1); i++)\r
-                       sq_move(_thread(o),v,i);\r
-               if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue,SQFalse))) {\r
-                       sq_move(v,_thread(o),-1);\r
-                       return 1;\r
-               }\r
-               return SQ_ERROR;\r
-       }\r
-       return sq_throwerror(v,_SC("wrong parameter"));\r
-}\r
-\r
-static SQInteger thread_wakeup(HSQUIRRELVM v)\r
-{\r
-       SQObjectPtr o = stack_get(v,1);\r
-       if(type(o) == OT_THREAD) {\r
-               SQVM *thread = _thread(o);\r
-               SQInteger state = sq_getvmstate(thread);\r
-               if(state != SQ_VMSTATE_SUSPENDED) {\r
-                       switch(state) {\r
-                               case SQ_VMSTATE_IDLE:\r
-                                       return sq_throwerror(v,_SC("cannot wakeup a idle thread"));\r
-                               break;\r
-                               case SQ_VMSTATE_RUNNING:\r
-                                       return sq_throwerror(v,_SC("cannot wakeup a running thread"));\r
-                               break;\r
-                       }\r
-               }\r
-                       \r
-               SQInteger wakeupret = sq_gettop(v)>1?1:0;\r
-               if(wakeupret) {\r
-                       sq_move(thread,v,2);\r
-               }\r
-               if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,1,SQFalse))) {\r
-                       sq_move(v,thread,-1);\r
-                       sq_pop(thread,1);\r
-                       if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) {\r
-                               sq_pop(thread,1);\r
-                       }\r
-                       return 1;\r
-               }\r
-               return SQ_ERROR;\r
-       }\r
-       return sq_throwerror(v,_SC("wrong parameter"));\r
-}\r
-\r
-static SQInteger thread_getstatus(HSQUIRRELVM v)\r
-{\r
-       SQObjectPtr &o = stack_get(v,1);\r
-       switch(sq_getvmstate(_thread(o))) {\r
-               case SQ_VMSTATE_IDLE:\r
-                       sq_pushstring(v,_SC("idle"),-1);\r
-               break;\r
-               case SQ_VMSTATE_RUNNING:\r
-                       sq_pushstring(v,_SC("running"),-1);\r
-               break;\r
-               case SQ_VMSTATE_SUSPENDED:\r
-                       sq_pushstring(v,_SC("suspended"),-1);\r
-               break;\r
-               default:\r
-                       return sq_throwerror(v,_SC("internal VM error"));\r
-       }\r
-       return 1;\r
-}\r
-\r
-SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = {\r
-       {_SC("call"), thread_call, -1, _SC("v")},\r
-       {_SC("wakeup"), thread_wakeup, -1, _SC("v")},\r
-       {_SC("getstatus"), thread_getstatus, 1, _SC("v")},\r
-       {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
-       {_SC("tostring"),default_delegate_tostring,1, _SC(".")},\r
-       {0,0},\r
-};\r
-\r
-static SQInteger class_getattributes(HSQUIRRELVM v)\r
-{\r
-       if(SQ_SUCCEEDED(sq_getattributes(v,-2)))\r
-               return 1;\r
-       return SQ_ERROR;\r
-}\r
-\r
-static SQInteger class_setattributes(HSQUIRRELVM v)\r
-{\r
-       if(SQ_SUCCEEDED(sq_setattributes(v,-3)))\r
-               return 1;\r
-       return SQ_ERROR;\r
-}\r
-\r
-static SQInteger class_instance(HSQUIRRELVM v)\r
-{\r
-       if(SQ_SUCCEEDED(sq_createinstance(v,-1)))\r
-               return 1;\r
-       return SQ_ERROR;\r
-}\r
-\r
-SQRegFunction SQSharedState::_class_default_delegate_funcz[] = {\r
-       {_SC("getattributes"), class_getattributes, 2, _SC("y.")},\r
-       {_SC("setattributes"), class_setattributes, 3, _SC("y..")},\r
-       {_SC("rawin"),container_rawexists,2, _SC("y")},\r
-       {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
-       {_SC("tostring"),default_delegate_tostring,1, _SC(".")},\r
-       {_SC("instance"),class_instance,1, _SC("y")},\r
-       {0,0}\r
-};\r
-\r
-static SQInteger instance_getclass(HSQUIRRELVM v)\r
-{\r
-       if(SQ_SUCCEEDED(sq_getclass(v,1)))\r
-               return 1;\r
-       return SQ_ERROR;\r
-}\r
-\r
-SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = {\r
-       {_SC("getclass"), instance_getclass, 1, _SC("x")},\r
-       {_SC("rawin"),container_rawexists,2, _SC("x")},\r
-       {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
-       {_SC("tostring"),default_delegate_tostring,1, _SC(".")},\r
-       {0,0}\r
-};\r
-\r
-static SQInteger weakref_ref(HSQUIRRELVM v)\r
-{\r
-       if(SQ_FAILED(sq_getweakrefval(v,1)))\r
-               return SQ_ERROR;\r
-       return 1;\r
-}\r
-\r
-SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = {\r
-       {_SC("ref"),weakref_ref,1, _SC("r")},\r
-       {_SC("weakref"),obj_delegate_weakref,1, NULL },\r
-       {_SC("tostring"),default_delegate_tostring,1, _SC(".")},\r
-       {0,0}\r
-};\r
-\r
-\r
+/*
+       see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include "sqvm.h"
+#include "sqstring.h"
+#include "sqtable.h"
+#include "sqarray.h"
+#include "sqfuncproto.h"
+#include "sqclosure.h"
+#include "sqclass.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+bool str2num(const SQChar *s,SQObjectPtr &res)
+{
+       SQChar *end;
+       if(scstrstr(s,_SC("."))){
+               SQFloat r = SQFloat(scstrtod(s,&end));
+               if(s == end) return false;
+               res = r;
+               return true;
+       }
+       else{
+               SQInteger r = SQInteger(scstrtol(s,&end,10));
+               if(s == end) return false;
+               res = r;
+               return true;
+       }
+}
+
+#ifndef NO_GARBAGE_COLLECTOR
+static SQInteger base_collectgarbage(HSQUIRRELVM v)
+{
+       sq_pushinteger(v, sq_collectgarbage(v));
+       return 1;
+}
+#endif
+
+static SQInteger base_getroottable(HSQUIRRELVM v)
+{
+       v->Push(v->_roottable);
+       return 1;
+}
+
+static SQInteger base_setroottable(HSQUIRRELVM v)
+{
+       SQObjectPtr &o=stack_get(v,2);
+       if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR;
+       v->Push(o);
+       return 1;
+}
+
+static SQInteger base_seterrorhandler(HSQUIRRELVM v)
+{
+       sq_seterrorhandler(v);
+       return 0;
+}
+
+static SQInteger base_setdebughook(HSQUIRRELVM v)
+{
+       sq_setdebughook(v);
+       return 0;
+}
+
+static SQInteger base_enabledebuginfo(HSQUIRRELVM v)
+{
+       SQObjectPtr &o=stack_get(v,2);
+       sq_enabledebuginfo(v,(type(o) != OT_NULL)?1:0);
+       return 0;
+}
+
+static SQInteger base_getstackinfos(HSQUIRRELVM v)
+{
+       SQInteger level;
+       SQStackInfos si;
+       SQInteger seq = 0;
+       const SQChar *name = NULL;
+       sq_getinteger(v, -1, &level);
+       if (SQ_SUCCEEDED(sq_stackinfos(v, level, &si)))
+       {
+               const SQChar *fn = _SC("unknown");
+               const SQChar *src = _SC("unknown");
+               if(si.funcname)fn = si.funcname;
+               if(si.source)src = si.source;
+               sq_newtable(v);
+               sq_pushstring(v, _SC("func"), -1);
+               sq_pushstring(v, fn, -1);
+               sq_createslot(v, -3);
+               sq_pushstring(v, _SC("src"), -1);
+               sq_pushstring(v, src, -1);
+               sq_createslot(v, -3);
+               sq_pushstring(v, _SC("line"), -1);
+               sq_pushinteger(v, si.line);
+               sq_createslot(v, -3);
+               sq_pushstring(v, _SC("locals"), -1);
+               sq_newtable(v);
+               seq=0;
+               while ((name = sq_getlocal(v, level, seq))) {
+                       sq_pushstring(v, name, -1);
+                       sq_push(v, -2);
+                       sq_createslot(v, -4);
+                       sq_pop(v, 1);
+                       seq++;
+               }
+               sq_createslot(v, -3);
+               return 1;
+       }
+
+       return 0;
+}
+
+static SQInteger base_assert(HSQUIRRELVM v)
+{
+       if(v->IsFalse(stack_get(v,2))){
+               return sq_throwerror(v,_SC("assertion failed"));
+       }
+       return 0;
+}
+
+static SQInteger get_slice_params(HSQUIRRELVM v,SQInteger &sidx,SQInteger &eidx,SQObjectPtr &o)
+{
+       SQInteger top = sq_gettop(v);
+       sidx=0;
+       eidx=0;
+       o=stack_get(v,1);
+       SQObjectPtr &start=stack_get(v,2);
+       if(type(start)!=OT_NULL && sq_isnumeric(start)){
+               sidx=tointeger(start);
+       }
+       if(top>2){
+               SQObjectPtr &end=stack_get(v,3);
+               if(sq_isnumeric(end)){
+                       eidx=tointeger(end);
+               }
+       }
+       else {
+               eidx = sq_getsize(v,1);
+       }
+       return 1;
+}
+
+static SQInteger base_print(HSQUIRRELVM v)
+{
+       const SQChar *str;
+       sq_tostring(v,2);
+       sq_getstring(v,-1,&str);
+       if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%s"),str);
+       return 0;
+}
+
+static SQInteger base_compilestring(HSQUIRRELVM v)
+{
+       SQInteger nargs=sq_gettop(v);
+       const SQChar *src=NULL,*name=_SC("unnamedbuffer");
+       SQInteger size;
+       sq_getstring(v,2,&src);
+       size=sq_getsize(v,2);
+       if(nargs>2){
+               sq_getstring(v,3,&name);
+       }
+       if(SQ_SUCCEEDED(sq_compilebuffer(v,src,size,name,SQFalse)))
+               return 1;
+       else
+               return SQ_ERROR;
+}
+
+static SQInteger base_newthread(HSQUIRRELVM v)
+{
+       SQObjectPtr &func = stack_get(v,2);
+       SQInteger stksize = (_funcproto(_closure(func)->_function)->_stacksize << 1) +2;
+       HSQUIRRELVM newv = sq_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize);
+       sq_move(newv,v,-2);
+       return 1;
+}
+
+static SQInteger base_suspend(HSQUIRRELVM v)
+{
+       return sq_suspendvm(v);
+}
+
+static SQInteger base_array(HSQUIRRELVM v)
+{
+       SQArray *a;
+       SQObject &size = stack_get(v,2);
+       if(sq_gettop(v) > 2) {
+               a = SQArray::Create(_ss(v),0);
+               a->Resize(tointeger(size),stack_get(v,3));
+       }
+       else {
+               a = SQArray::Create(_ss(v),tointeger(size));
+       }
+       v->Push(a);
+       return 1;
+}
+
+static SQInteger base_type(HSQUIRRELVM v)
+{
+       SQObjectPtr &o = stack_get(v,2);
+       v->Push(SQString::Create(_ss(v),GetTypeName(o),-1));
+       return 1;
+}
+
+static SQRegFunction base_funcs[]={
+       //generic
+       {_SC("seterrorhandler"),base_seterrorhandler,2, NULL},
+       {_SC("setdebughook"),base_setdebughook,2, NULL},
+       {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL},
+       {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")},
+       {_SC("getroottable"),base_getroottable,1, NULL},
+       {_SC("setroottable"),base_setroottable,2, NULL},
+       {_SC("assert"),base_assert,2, NULL},
+       {_SC("print"),base_print,2, NULL},
+       {_SC("compilestring"),base_compilestring,-2, _SC(".ss")},
+       {_SC("newthread"),base_newthread,2, _SC(".c")},
+       {_SC("suspend"),base_suspend,-1, NULL},
+       {_SC("array"),base_array,-2, _SC(".n")},
+       {_SC("type"),base_type,2, NULL},
+#ifndef NO_GARBAGE_COLLECTOR
+       {_SC("collectgarbage"),base_collectgarbage,1, _SC("t")},
+#endif
+       {0,0}
+};
+
+void sq_base_register(HSQUIRRELVM v)
+{
+       SQInteger i=0;
+       sq_pushroottable(v);
+       while(base_funcs[i].name!=0) {
+               sq_pushstring(v,base_funcs[i].name,-1);
+               sq_newclosure(v,base_funcs[i].f,0);
+               sq_setnativeclosurename(v,-1,base_funcs[i].name);
+               sq_setparamscheck(v,base_funcs[i].nparamscheck,base_funcs[i].typemask);
+               sq_createslot(v,-3);
+               i++;
+       }
+       sq_pushstring(v,_SC("_charsize_"),-1);
+       sq_pushinteger(v,sizeof(SQChar));
+       sq_createslot(v,-3);
+       sq_pushstring(v,_SC("_intsize_"),-1);
+       sq_pushinteger(v,sizeof(SQInteger));
+       sq_createslot(v,-3);
+       sq_pop(v,1);
+}
+
+static SQInteger default_delegate_len(HSQUIRRELVM v)
+{
+       v->Push(SQInteger(sq_getsize(v,1)));
+       return 1;
+}
+
+static SQInteger default_delegate_tofloat(HSQUIRRELVM v)
+{
+       SQObjectPtr &o=stack_get(v,1);
+       switch(type(o)){
+       case OT_STRING:{
+               SQObjectPtr res;
+               if(str2num(_stringval(o),res)){
+                       v->Push(SQObjectPtr(tofloat(res)));
+                       break;
+               }}
+               return sq_throwerror(v, _SC("cannot convert the string"));
+               break;
+       case OT_INTEGER:case OT_FLOAT:
+               v->Push(SQObjectPtr(tofloat(o)));
+               break;
+       case OT_BOOL:
+               v->Push(SQObjectPtr((SQFloat)(_integer(o)?1:0)));
+               break;
+       default:
+               v->Push(_null_);
+               break;
+       }
+       return 1;
+}
+
+static SQInteger default_delegate_tointeger(HSQUIRRELVM v)
+{
+       SQObjectPtr &o=stack_get(v,1);
+       switch(type(o)){
+       case OT_STRING:{
+               SQObjectPtr res;
+               if(str2num(_stringval(o),res)){
+                       v->Push(SQObjectPtr(tointeger(res)));
+                       break;
+               }}
+               return sq_throwerror(v, _SC("cannot convert the string"));
+               break;
+       case OT_INTEGER:case OT_FLOAT:
+               v->Push(SQObjectPtr(tointeger(o)));
+               break;
+       case OT_BOOL:
+               v->Push(SQObjectPtr(_integer(o)?(SQInteger)1:(SQInteger)0));
+               break;
+       default:
+               v->Push(_null_);
+               break;
+       }
+       return 1;
+}
+
+static SQInteger default_delegate_tostring(HSQUIRRELVM v)
+{
+       sq_tostring(v,1);
+       return 1;
+}
+
+static SQInteger obj_delegate_weakref(HSQUIRRELVM v)
+{
+       sq_weakref(v,1);
+       return 1;
+}
+
+static SQInteger number_delegate_tochar(HSQUIRRELVM v)
+{
+       SQObject &o=stack_get(v,1);
+       SQChar c = (SQChar)tointeger(o);
+       v->Push(SQString::Create(_ss(v),(const SQChar *)&c,1));
+       return 1;
+}
+
+
+/////////////////////////////////////////////////////////////////
+//TABLE DEFAULT DELEGATE
+
+static SQInteger table_rawdelete(HSQUIRRELVM v)
+{
+       if(SQ_FAILED(sq_rawdeleteslot(v,1,SQTrue)))
+               return SQ_ERROR;
+       return 1;
+}
+
+
+static SQInteger container_rawexists(HSQUIRRELVM v)
+{
+       if(SQ_SUCCEEDED(sq_rawget(v,-2))) {
+               sq_pushbool(v,SQTrue);
+               return 1;
+       }
+       sq_pushbool(v,SQFalse);
+       return 1;
+}
+
+static SQInteger table_rawset(HSQUIRRELVM v)
+{
+       return sq_rawset(v,-3);
+}
+
+
+static SQInteger table_rawget(HSQUIRRELVM v)
+{
+       return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR;
+}
+
+SQRegFunction SQSharedState::_table_default_delegate_funcz[]={
+       {_SC("len"),default_delegate_len,1, _SC("t")},
+       {_SC("rawget"),table_rawget,2, _SC("t")},
+       {_SC("rawset"),table_rawset,3, _SC("t")},
+       {_SC("rawdelete"),table_rawdelete,2, _SC("t")},
+       {_SC("rawin"),container_rawexists,2, _SC("t")},
+       {_SC("weakref"),obj_delegate_weakref,1, NULL },
+       {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
+       {0,0}
+};
+
+//ARRAY DEFAULT DELEGATE///////////////////////////////////////
+
+static SQInteger array_append(HSQUIRRELVM v)
+{
+       return sq_arrayappend(v,-2);
+}
+
+static SQInteger array_extend(HSQUIRRELVM v)
+{
+       _array(stack_get(v,1))->Extend(_array(stack_get(v,2)));
+       return 0;
+}
+
+static SQInteger array_reverse(HSQUIRRELVM v)
+{
+       return sq_arrayreverse(v,-1);
+}
+
+static SQInteger array_pop(HSQUIRRELVM v)
+{
+       return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR;
+}
+
+static SQInteger array_top(HSQUIRRELVM v)
+{
+       SQObject &o=stack_get(v,1);
+       if(_array(o)->Size()>0){
+               v->Push(_array(o)->Top());
+               return 1;
+       }
+       else return sq_throwerror(v,_SC("top() on a empty array"));
+}
+
+static SQInteger array_insert(HSQUIRRELVM v)
+{
+       SQObject &o=stack_get(v,1);
+       SQObject &idx=stack_get(v,2);
+       SQObject &val=stack_get(v,3);
+       _array(o)->Insert(idx,val);
+       return 0;
+}
+
+static SQInteger array_remove(HSQUIRRELVM v)
+{
+       SQObject &o = stack_get(v, 1);
+       SQObject &idx = stack_get(v, 2);
+       if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type"));
+       SQObjectPtr val;
+       if(_array(o)->Get(tointeger(idx), val)) {
+               _array(o)->Remove(tointeger(idx));
+               v->Push(val);
+               return 1;
+       }
+       return sq_throwerror(v, _SC("idx out of range"));
+}
+
+static SQInteger array_resize(HSQUIRRELVM v)
+{
+       SQObject &o = stack_get(v, 1);
+       SQObject &nsize = stack_get(v, 2);
+       SQObjectPtr fill;
+       if(sq_isnumeric(nsize)) {
+               if(sq_gettop(v) > 2)
+                       fill = stack_get(v, 3);
+               _array(o)->Resize(tointeger(nsize),fill);
+               return 0;
+       }
+       return sq_throwerror(v, _SC("size must be a number"));
+}
+
+
+//QSORT ala Sedgewick
+bool _qsort_compare(HSQUIRRELVM v,SQObjectPtr &arr,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret)
+{
+       if(func < 0) {
+               if(!v->ObjCmp(a,b,ret)) return false;
+       }
+       else {
+               SQInteger top = sq_gettop(v);
+               sq_push(v, func);
+               sq_pushroottable(v);
+               v->Push(a);
+               v->Push(b);
+               if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) {
+                       v->Raise_Error(_SC("compare func failed"));
+                       return false;
+               }
+               sq_getinteger(v, -1, &ret);
+               sq_settop(v, top);
+               return true;
+       }
+       return true;
+}
+//QSORT ala Sedgewick
+bool _qsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger l, SQInteger r,SQInteger func)
+{
+       SQInteger i, j;
+       SQArray *a=_array(arr);
+       SQObjectPtr pivot,t;
+       if( l < r ){
+               pivot = a->_values[l];
+               i = l; j = r+1;
+               while(1){
+                       SQInteger ret;
+                       do {
+                               ++i;
+                               if(i > r) break;
+                               if(!_qsort_compare(v,arr,a->_values[i],pivot,func,ret))
+                                       return false;
+                       } while( ret <= 0);
+                       do {
+                               --j;
+                               if(!_qsort_compare(v,arr,a->_values[j],pivot,func,ret))
+                                       return false;
+                       }
+                       while( ret > 0 );
+                       if( i >= j ) break;
+                       t = a->_values[i]; a->_values[i] = a->_values[j]; a->_values[j] = t;
+               }
+               t = a->_values[l]; a->_values[l] = a->_values[j]; a->_values[j] = t;
+               if(!_qsort( v, arr, l, j-1,func)) return false;
+               if(!_qsort( v, arr, j+1, r,func)) return false;
+       }
+       return true;
+}
+
+static SQInteger array_sort(HSQUIRRELVM v)
+{
+       SQInteger func = -1;
+       SQObjectPtr &o = stack_get(v,1);
+       SQObject &funcobj = stack_get(v,2);
+       if(_array(o)->Size() > 1) {
+               if(type(funcobj) == OT_CLOSURE || type(funcobj) == OT_NATIVECLOSURE) func = 2;
+               if(!_qsort(v, o, 0, _array(o)->Size()-1, func))
+                       return SQ_ERROR;
+
+       }
+       return 0;
+}
+static SQInteger array_slice(HSQUIRRELVM v)
+{
+       SQInteger sidx,eidx;
+       SQObjectPtr o;
+       if(get_slice_params(v,sidx,eidx,o)==-1)return -1;
+       if(sidx<0)sidx=_array(o)->Size()+sidx;
+       if(eidx<0)eidx=_array(o)->Size()+eidx;
+       if(eidx <= sidx)return sq_throwerror(v,_SC("wrong indexes"));
+       SQArray *arr=SQArray::Create(_ss(v),eidx-sidx);
+       SQObjectPtr t;
+       SQInteger count=0;
+       for(SQInteger i=sidx;i<eidx;i++){
+               _array(o)->Get(i,t);
+               arr->Set(count++,t);
+       }
+       v->Push(arr);
+       return 1;
+
+}
+
+SQRegFunction SQSharedState::_array_default_delegate_funcz[]={
+       {_SC("len"),default_delegate_len,1, _SC("a")},
+       {_SC("append"),array_append,2, _SC("a")},
+       {_SC("extend"),array_extend,2, _SC("aa")},
+       {_SC("push"),array_append,2, _SC("a")},
+       {_SC("pop"),array_pop,1, _SC("a")},
+       {_SC("top"),array_top,1, _SC("a")},
+       {_SC("insert"),array_insert,3, _SC("an")},
+       {_SC("remove"),array_remove,2, _SC("an")},
+       {_SC("resize"),array_resize,-2, _SC("an")},
+       {_SC("reverse"),array_reverse,1, _SC("a")},
+       {_SC("sort"),array_sort,-1, _SC("ac")},
+       {_SC("slice"),array_slice,-1, _SC("ann")},
+       {_SC("weakref"),obj_delegate_weakref,1, NULL },
+       {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
+       {0,0}
+};
+
+//STRING DEFAULT DELEGATE//////////////////////////
+static SQInteger string_slice(HSQUIRRELVM v)
+{
+       SQInteger sidx,eidx;
+       SQObjectPtr o;
+       if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1;
+       if(sidx<0)sidx=_string(o)->_len+sidx;
+       if(eidx<0)eidx=_string(o)->_len+eidx;
+       if(eidx<sidx)
+               return sq_throwerror(v,_SC("wrong indexes"));
+       v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx));
+       return 1;
+}
+
+static SQInteger string_find(HSQUIRRELVM v)
+{
+       SQInteger top,start_idx=0;
+       const SQChar *str,*substr,*ret;
+       if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){
+               if(top>2)sq_getinteger(v,3,&start_idx);
+               if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){
+                       ret=scstrstr(&str[start_idx],substr);
+                       if(ret){
+                               sq_pushinteger(v,(SQInteger)(ret-str));
+                               return 1;
+                       }
+               }
+               return 0;
+       }
+       return sq_throwerror(v,_SC("invalid param"));
+}
+
+#define STRING_TOFUNCZ(func) static SQInteger string_##func(HSQUIRRELVM v) \
+{ \
+       SQObject str=stack_get(v,1); \
+       SQInteger len=_string(str)->_len; \
+       const SQChar *sThis=_stringval(str); \
+       SQChar *sNew=(_ss(v)->GetScratchPad(rsl(len))); \
+       for(SQInteger i=0;i<len;i++) sNew[i]=func(sThis[i]); \
+       v->Push(SQString::Create(_ss(v),sNew,len)); \
+       return 1; \
+}
+
+
+STRING_TOFUNCZ(tolower)
+STRING_TOFUNCZ(toupper)
+
+SQRegFunction SQSharedState::_string_default_delegate_funcz[]={
+       {_SC("len"),default_delegate_len,1, _SC("s")},
+       {_SC("tointeger"),default_delegate_tointeger,1, _SC("s")},
+       {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")},
+       {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
+       {_SC("slice"),string_slice,-1, _SC(" s n  n")},
+       {_SC("find"),string_find,-2, _SC("s s n ")},
+       {_SC("tolower"),string_tolower,1, _SC("s")},
+       {_SC("toupper"),string_toupper,1, _SC("s")},
+       {_SC("weakref"),obj_delegate_weakref,1, NULL },
+       {0,0}
+};
+
+//INTEGER DEFAULT DELEGATE//////////////////////////
+SQRegFunction SQSharedState::_number_default_delegate_funcz[]={
+       {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")},
+       {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")},
+       {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
+       {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")},
+       {_SC("weakref"),obj_delegate_weakref,1, NULL },
+       {0,0}
+};
+
+//CLOSURE DEFAULT DELEGATE//////////////////////////
+static SQInteger closure_pcall(HSQUIRRELVM v)
+{
+       return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQFalse))?1:SQ_ERROR;
+}
+
+static SQInteger closure_call(HSQUIRRELVM v)
+{
+       return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQTrue))?1:SQ_ERROR;
+}
+
+static SQInteger _closure_acall(HSQUIRRELVM v,SQBool raiseerror)
+{
+       SQArray *aparams=_array(stack_get(v,2));
+       SQInteger nparams=aparams->Size();
+       v->Push(stack_get(v,1));
+       for(SQInteger i=0;i<nparams;i++)v->Push(aparams->_values[i]);
+       return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue,raiseerror))?1:SQ_ERROR;
+}
+
+static SQInteger closure_acall(HSQUIRRELVM v)
+{
+       return _closure_acall(v,SQTrue);
+}
+
+static SQInteger closure_pacall(HSQUIRRELVM v)
+{
+       return _closure_acall(v,SQFalse);
+}
+
+static SQInteger closure_bindenv(HSQUIRRELVM v)
+{
+       if(SQ_FAILED(sq_bindenv(v,1)))
+               return SQ_ERROR;
+       return 1;
+}
+
+static SQInteger closure_getinfos(HSQUIRRELVM v) {
+       SQObject o = stack_get(v,1);
+       SQTable *res = SQTable::Create(_ss(v),4);
+       if(type(o) == OT_CLOSURE) {
+               SQFunctionProto *f = _funcproto(_closure(o)->_function);
+               SQInteger nparams = f->_parameters.size() + (f->_varparams?1:0);
+               SQObjectPtr params = SQArray::Create(_ss(v),nparams);
+               for(SQUnsignedInteger n = 0; n<f->_parameters.size(); n++) {
+                       _array(params)->Set((SQInteger)n,f->_parameters[n]);
+               }
+               if(f->_varparams) {
+                       _array(params)->Set(nparams-1,SQString::Create(_ss(v),_SC("..."),-1));
+               }
+               res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),false);
+               res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),f->_name);
+               res->NewSlot(SQString::Create(_ss(v),_SC("src"),-1),f->_sourcename);
+               res->NewSlot(SQString::Create(_ss(v),_SC("parameters"),-1),params);
+               res->NewSlot(SQString::Create(_ss(v),_SC("varargs"),-1),f->_varparams);
+       }
+       else { //OT_NATIVECLOSURE
+               SQNativeClosure *nc = _nativeclosure(o);
+               res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),true);
+               res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),nc->_name);
+               res->NewSlot(SQString::Create(_ss(v),_SC("paramscheck"),-1),nc->_nparamscheck);
+               SQObjectPtr typecheck;
+               if(nc->_typecheck.size() > 0) {
+                       typecheck =
+                               SQArray::Create(_ss(v), nc->_typecheck.size());
+                       for(SQUnsignedInteger n = 0; n<nc->_typecheck.size(); n++) {
+                                       _array(typecheck)->Set((SQInteger)n,nc->_typecheck[n]);
+                       }
+               }
+               res->NewSlot(SQString::Create(_ss(v),_SC("typecheck"),-1),typecheck);
+       }
+       v->Push(res);
+       return 1;
+}
+
+
+SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={
+       {_SC("call"),closure_call,-1, _SC("c")},
+       {_SC("pcall"),closure_pcall,-1, _SC("c")},
+       {_SC("acall"),closure_acall,2, _SC("ca")},
+       {_SC("pacall"),closure_pacall,2, _SC("ca")},
+       {_SC("weakref"),obj_delegate_weakref,1, NULL },
+       {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
+       {_SC("bindenv"),closure_bindenv,2, _SC("c x|y|t")},
+       {_SC("getinfos"),closure_getinfos,1, _SC("c")},
+       {0,0}
+};
+
+//GENERATOR DEFAULT DELEGATE
+static SQInteger generator_getstatus(HSQUIRRELVM v)
+{
+       SQObject &o=stack_get(v,1);
+       switch(_generator(o)->_state){
+               case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break;
+               case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break;
+               case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break;
+       }
+       return 1;
+}
+
+SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={
+       {_SC("getstatus"),generator_getstatus,1, _SC("g")},
+       {_SC("weakref"),obj_delegate_weakref,1, NULL },
+       {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
+       {0,0}
+};
+
+//THREAD DEFAULT DELEGATE
+
+static SQInteger thread_call(HSQUIRRELVM v)
+{
+       SQObjectPtr o = stack_get(v,1);
+       if(type(o) == OT_THREAD) {
+               SQInteger nparams = sq_gettop(v);
+               _thread(o)->Push(_thread(o)->_roottable);
+               for(SQInteger i = 2; i<(nparams+1); i++)
+                       sq_move(_thread(o),v,i);
+               if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue,SQFalse))) {
+                       sq_move(v,_thread(o),-1);
+                       return 1;
+               }
+               return SQ_ERROR;
+       }
+       return sq_throwerror(v,_SC("wrong parameter"));
+}
+
+static SQInteger thread_wakeup(HSQUIRRELVM v)
+{
+       SQObjectPtr o = stack_get(v,1);
+       if(type(o) == OT_THREAD) {
+               SQVM *thread = _thread(o);
+               SQInteger state = sq_getvmstate(thread);
+               if(state != SQ_VMSTATE_SUSPENDED) {
+                       switch(state) {
+                               case SQ_VMSTATE_IDLE:
+                                       return sq_throwerror(v,_SC("cannot wakeup a idle thread"));
+                               break;
+                               case SQ_VMSTATE_RUNNING:
+                                       return sq_throwerror(v,_SC("cannot wakeup a running thread"));
+                               break;
+                       }
+               }
+
+               SQInteger wakeupret = sq_gettop(v)>1?1:0;
+               if(wakeupret) {
+                       sq_move(thread,v,2);
+               }
+               if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,1,SQFalse))) {
+                       sq_move(v,thread,-1);
+                       sq_pop(thread,1);
+                       if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) {
+                               sq_pop(thread,1);
+                       }
+                       return 1;
+               }
+               return SQ_ERROR;
+       }
+       return sq_throwerror(v,_SC("wrong parameter"));
+}
+
+static SQInteger thread_getstatus(HSQUIRRELVM v)
+{
+       SQObjectPtr &o = stack_get(v,1);
+       switch(sq_getvmstate(_thread(o))) {
+               case SQ_VMSTATE_IDLE:
+                       sq_pushstring(v,_SC("idle"),-1);
+               break;
+               case SQ_VMSTATE_RUNNING:
+                       sq_pushstring(v,_SC("running"),-1);
+               break;
+               case SQ_VMSTATE_SUSPENDED:
+                       sq_pushstring(v,_SC("suspended"),-1);
+               break;
+               default:
+                       return sq_throwerror(v,_SC("internal VM error"));
+       }
+       return 1;
+}
+
+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")},
+       {_SC("weakref"),obj_delegate_weakref,1, NULL },
+       {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
+       {0,0},
+};
+
+static SQInteger class_getattributes(HSQUIRRELVM v)
+{
+       if(SQ_SUCCEEDED(sq_getattributes(v,-2)))
+               return 1;
+       return SQ_ERROR;
+}
+
+static SQInteger class_setattributes(HSQUIRRELVM v)
+{
+       if(SQ_SUCCEEDED(sq_setattributes(v,-3)))
+               return 1;
+       return SQ_ERROR;
+}
+
+static SQInteger class_instance(HSQUIRRELVM v)
+{
+       if(SQ_SUCCEEDED(sq_createinstance(v,-1)))
+               return 1;
+       return SQ_ERROR;
+}
+
+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")},
+       {_SC("weakref"),obj_delegate_weakref,1, NULL },
+       {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
+       {_SC("instance"),class_instance,1, _SC("y")},
+       {0,0}
+};
+
+static SQInteger instance_getclass(HSQUIRRELVM v)
+{
+       if(SQ_SUCCEEDED(sq_getclass(v,1)))
+               return 1;
+       return SQ_ERROR;
+}
+
+SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = {
+       {_SC("getclass"), instance_getclass, 1, _SC("x")},
+       {_SC("rawin"),container_rawexists,2, _SC("x")},
+       {_SC("weakref"),obj_delegate_weakref,1, NULL },
+       {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
+       {0,0}
+};
+
+static SQInteger weakref_ref(HSQUIRRELVM v)
+{
+       if(SQ_FAILED(sq_getweakrefval(v,1)))
+               return SQ_ERROR;
+       return 1;
+}
+
+SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = {
+       {_SC("ref"),weakref_ref,1, _SC("r")},
+       {_SC("weakref"),obj_delegate_weakref,1, NULL },
+       {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
+       {0,0}
+};
index 1672f7c..405c737 100644 (file)
-/*\r
-       see copyright notice in squirrel.h\r
-*/\r
-#include "sqpcheader.h"\r
-#include "sqvm.h"\r
-#include "sqtable.h"\r
-#include "sqclass.h"\r
-#include "sqclosure.h"\r
-\r
-SQClass::SQClass(SQSharedState *ss,SQClass *base)\r
-{\r
-       _base = base;\r
-       _typetag = 0;\r
-       _hook = NULL;\r
-       _metamethods.resize(MT_LAST); //size it to max size\r
-       if(_base) {\r
-               _defaultvalues.copy(base->_defaultvalues);\r
-               _methods.copy(base->_methods);\r
-               _metamethods.copy(base->_metamethods);\r
-               __ObjAddRef(_base);\r
-       }\r
-       _members = base?base->_members->Clone() : SQTable::Create(ss,0);\r
-       __ObjAddRef(_members);\r
-       _locked = false;\r
-       INIT_CHAIN();\r
-       ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);\r
-}\r
-\r
-void SQClass::Finalize() { \r
-       _attributes = _null_;\r
-       _defaultvalues.resize(0);\r
-       _methods.resize(0);\r
-       _metamethods.resize(0);\r
-       __ObjRelease(_members);\r
-       if(_base) {\r
-               __ObjRelease(_base);\r
-       }\r
-}\r
-\r
-SQClass::~SQClass()\r
-{\r
-       REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);\r
-       Finalize();\r
-}\r
-\r
-bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic)\r
-{\r
-       SQObjectPtr temp;\r
-       if(_locked) \r
-               return false; //the class already has an instance so cannot be modified\r
-       if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value\r
-       {\r
-               _defaultvalues[_member_idx(temp)].val = val;\r
-               return true;\r
-       }\r
-       if(type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE || bstatic) {\r
-               SQInteger mmidx;\r
-               if((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) && \r
-                       (mmidx = ss->GetMetaMethodIdxByName(key)) != -1) {\r
-                       _metamethods[mmidx] = val;\r
-               } \r
-               else {\r
-                       if(type(temp) == OT_NULL) {\r
-                               SQClassMemeber m;\r
-                               m.val = val;\r
-                               _members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size())));\r
-                               _methods.push_back(m);\r
-                       }\r
-                       else {\r
-                               _methods[_member_idx(temp)].val = val;\r
-                       }\r
-               }\r
-               return true;\r
-       }\r
-       SQClassMemeber m;\r
-       m.val = val;\r
-       _members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size())));\r
-       _defaultvalues.push_back(m);\r
-       return true;\r
-}\r
-\r
-SQInstance *SQClass::CreateInstance()\r
-{\r
-       if(!_locked) Lock();\r
-       return SQInstance::Create(_opt_ss(this),this);\r
-}\r
-\r
-SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)\r
-{\r
-       SQObjectPtr oval;\r
-       SQInteger idx = _members->Next(false,refpos,outkey,oval);\r
-       if(idx != -1) {\r
-               if(_ismethod(oval)) {\r
-                       outval = _methods[_member_idx(oval)].val;\r
-               }\r
-               else {\r
-                       SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val;\r
-                       outval = _realval(o);\r
-               }\r
-       }\r
-       return idx;\r
-}\r
-\r
-bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val)\r
-{\r
-       SQObjectPtr idx;\r
-       if(_members->Get(key,idx)) {\r
-               if(_isfield(idx))\r
-                       _defaultvalues[_member_idx(idx)].attrs = val;\r
-               else\r
-                       _methods[_member_idx(idx)].attrs = val;\r
-               return true;\r
-       }\r
-       return false;\r
-}\r
-\r
-bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval)\r
-{\r
-       SQObjectPtr idx;\r
-       if(_members->Get(key,idx)) {\r
-               outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs);\r
-               return true;\r
-       }\r
-       return false;\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////\r
-void SQInstance::Init(SQSharedState *ss)\r
-{\r
-       _userpointer = NULL;\r
-       _hook = NULL;\r
-       __ObjAddRef(_class);\r
-       _delegate = _class->_members;\r
-       INIT_CHAIN();\r
-       ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);\r
-}\r
-\r
-SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize)\r
-{\r
-       _memsize = memsize;\r
-       _class = c;\r
-       _nvalues = _class->_defaultvalues.size();\r
-       for(SQUnsignedInteger n = 0; n < _nvalues; n++) {\r
-               new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val);\r
-       }\r
-       Init(ss);\r
-}\r
-\r
-SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize)\r
-{\r
-       _memsize = memsize;\r
-       _class = i->_class;\r
-       _nvalues = _class->_defaultvalues.size();\r
-       for(SQUnsignedInteger n = 0; n < _nvalues; n++) {\r
-               new (&_values[n]) SQObjectPtr(i->_values[n]);\r
-       }\r
-       Init(ss);\r
-}\r
-\r
-void SQInstance::Finalize() \r
-{\r
-       __ObjRelease(_class);\r
-       for(SQUnsignedInteger i = 0; i < _nvalues; i++) {\r
-               _values[i] = _null_;\r
-       }\r
-}\r
-\r
-SQInstance::~SQInstance()\r
-{\r
-       REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);\r
-       Finalize();\r
-}\r
-\r
-bool SQInstance::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res)\r
-{\r
-       if(type(_class->_metamethods[mm]) != OT_NULL) {\r
-               res = _class->_metamethods[mm];\r
-               return true;\r
-       }\r
-       return false;\r
-}\r
-\r
-bool SQInstance::InstanceOf(SQClass *trg)\r
-{\r
-       SQClass *parent = _class;\r
-       while(parent != NULL) {\r
-               if(parent == trg)\r
-                       return true;\r
-               parent = parent->_base;\r
-       }\r
-       return false;\r
-}\r
+/*
+       see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include "sqvm.h"
+#include "sqtable.h"
+#include "sqclass.h"
+#include "sqclosure.h"
+
+SQClass::SQClass(SQSharedState *ss,SQClass *base)
+{
+       _base = base;
+       _typetag = 0;
+       _hook = NULL;
+       _metamethods.resize(MT_LAST); //size it to max size
+       if(_base) {
+               _defaultvalues.copy(base->_defaultvalues);
+               _methods.copy(base->_methods);
+               _metamethods.copy(base->_metamethods);
+               __ObjAddRef(_base);
+       }
+       _members = base?base->_members->Clone() : SQTable::Create(ss,0);
+       __ObjAddRef(_members);
+       _locked = false;
+       INIT_CHAIN();
+       ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
+}
+
+void SQClass::Finalize() {
+       _attributes = _null_;
+       _defaultvalues.resize(0);
+       _methods.resize(0);
+       _metamethods.resize(0);
+       __ObjRelease(_members);
+       if(_base) {
+               __ObjRelease(_base);
+       }
+}
+
+SQClass::~SQClass()
+{
+       REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
+       Finalize();
+}
+
+bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic)
+{
+       SQObjectPtr temp;
+       if(_locked)
+               return false; //the class already has an instance so cannot be modified
+       if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value
+       {
+               _defaultvalues[_member_idx(temp)].val = val;
+               return true;
+       }
+       if(type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE || bstatic) {
+               SQInteger mmidx;
+               if((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) &&
+                       (mmidx = ss->GetMetaMethodIdxByName(key)) != -1) {
+                       _metamethods[mmidx] = val;
+               }
+               else {
+                       if(type(temp) == OT_NULL) {
+                               SQClassMemeber m;
+                               m.val = val;
+                               _members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size())));
+                               _methods.push_back(m);
+                       }
+                       else {
+                               _methods[_member_idx(temp)].val = val;
+                       }
+               }
+               return true;
+       }
+       SQClassMemeber m;
+       m.val = val;
+       _members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size())));
+       _defaultvalues.push_back(m);
+       return true;
+}
+
+SQInstance *SQClass::CreateInstance()
+{
+       if(!_locked) Lock();
+       return SQInstance::Create(_opt_ss(this),this);
+}
+
+SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
+{
+       SQObjectPtr oval;
+       SQInteger idx = _members->Next(false,refpos,outkey,oval);
+       if(idx != -1) {
+               if(_ismethod(oval)) {
+                       outval = _methods[_member_idx(oval)].val;
+               }
+               else {
+                       SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val;
+                       outval = _realval(o);
+               }
+       }
+       return idx;
+}
+
+bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val)
+{
+       SQObjectPtr idx;
+       if(_members->Get(key,idx)) {
+               if(_isfield(idx))
+                       _defaultvalues[_member_idx(idx)].attrs = val;
+               else
+                       _methods[_member_idx(idx)].attrs = val;
+               return true;
+       }
+       return false;
+}
+
+bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval)
+{
+       SQObjectPtr idx;
+       if(_members->Get(key,idx)) {
+               outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs);
+               return true;
+       }
+       return false;
+}
+
+///////////////////////////////////////////////////////////////////////
+void SQInstance::Init(SQSharedState *ss)
+{
+       _userpointer = NULL;
+       _hook = NULL;
+       __ObjAddRef(_class);
+       _delegate = _class->_members;
+       INIT_CHAIN();
+       ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
+}
+
+SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize)
+{
+       _memsize = memsize;
+       _class = c;
+       _nvalues = _class->_defaultvalues.size();
+       for(SQUnsignedInteger n = 0; n < _nvalues; n++) {
+               new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val);
+       }
+       Init(ss);
+}
+
+SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize)
+{
+       _memsize = memsize;
+       _class = i->_class;
+       _nvalues = _class->_defaultvalues.size();
+       for(SQUnsignedInteger n = 0; n < _nvalues; n++) {
+               new (&_values[n]) SQObjectPtr(i->_values[n]);
+       }
+       Init(ss);
+}
+
+void SQInstance::Finalize()
+{
+       __ObjRelease(_class);
+       for(SQUnsignedInteger i = 0; i < _nvalues; i++) {
+               _values[i] = _null_;
+       }
+}
+
+SQInstance::~SQInstance()
+{
+       REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
+       Finalize();
+}
+
+bool SQInstance::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res)
+{
+       if(type(_class->_metamethods[mm]) != OT_NULL) {
+               res = _class->_metamethods[mm];
+               return true;
+       }
+       return false;
+}
+
+bool SQInstance::InstanceOf(SQClass *trg)
+{
+       SQClass *parent = _class;
+       while(parent != NULL) {
+               if(parent == trg)
+                       return true;
+               parent = parent->_base;
+       }
+       return false;
+}
index 460e591..a451eed 100644 (file)
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQCLASS_H_\r
-#define _SQCLASS_H_\r
-\r
-struct SQInstance;\r
-\r
-struct SQClassMemeber {\r
-       SQClassMemeber(){}\r
-       SQClassMemeber(const SQClassMemeber &o) {\r
-               val = o.val;\r
-               attrs = o.attrs;\r
-       }\r
-       SQObjectPtr val;\r
-       SQObjectPtr attrs;\r
-};\r
-\r
-typedef sqvector<SQClassMemeber> SQClassMemeberVec;\r
-\r
-#define MEMBER_TYPE_METHOD 0x01000000\r
-#define MEMBER_TYPE_FIELD 0x02000000\r
-\r
-#define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD)\r
-#define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD)\r
-#define _make_method_idx(i) ((SQInteger)(MEMBER_TYPE_METHOD|i))\r
-#define _make_field_idx(i) ((SQInteger)(MEMBER_TYPE_FIELD|i))\r
-#define _member_type(o) (_integer(o)&0xFF000000)\r
-#define _member_idx(o) (_integer(o)&0x00FFFFFF)\r
-\r
-struct SQClass : public CHAINABLE_OBJ\r
-{\r
-       SQClass(SQSharedState *ss,SQClass *base);\r
-public:\r
-       static SQClass* Create(SQSharedState *ss,SQClass *base) {\r
-               SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass));\r
-               new (newclass) SQClass(ss, base);\r
-               return newclass;\r
-       }\r
-       ~SQClass();\r
-       bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic);\r
-       bool Get(const SQObjectPtr &key,SQObjectPtr &val) {\r
-               if(_members->Get(key,val)) {\r
-                       if(_isfield(val)) {\r
-                               SQObjectPtr &o = _defaultvalues[_member_idx(val)].val;\r
-                               val = _realval(o);\r
-                       }\r
-                       else {\r
-                               val = _methods[_member_idx(val)].val;\r
-                       }\r
-                       return true;\r
-               }\r
-               return false;\r
-       }\r
-       bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val);\r
-       bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval);\r
-       void Lock() { _locked = true; if(_base) _base->Lock(); }\r
-       void Release() { \r
-               if (_hook) { _hook(_typetag,0);}\r
-               sq_delete(this, SQClass);       \r
-       }\r
-       void Finalize();\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-       void Mark(SQCollectable ** );\r
-#endif\r
-       SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);\r
-       SQInstance *CreateInstance();\r
-       SQTable *_members;\r
-       SQClass *_base;\r
-       SQClassMemeberVec _defaultvalues;\r
-       SQClassMemeberVec _methods;\r
-       SQObjectPtrVec _metamethods;\r
-       SQObjectPtr _attributes;\r
-       SQUserPointer _typetag;\r
-       SQRELEASEHOOK _hook;\r
-       bool _locked;\r
-};\r
-\r
-#define calcinstancesize(_theclass_) \\r
-       (sizeof(SQInstance)+(sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0)))\r
-struct SQInstance : public SQDelegable \r
-{\r
-       void Init(SQSharedState *ss);\r
-       SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize);\r
-       SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize);\r
-public:\r
-       static SQInstance* Create(SQSharedState *ss,SQClass *theclass) {\r
-               \r
-               SQInteger size = calcinstancesize(theclass);\r
-               SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);\r
-               new (newinst) SQInstance(ss, theclass,size);\r
-               return newinst;\r
-       }\r
-       SQInstance *Clone(SQSharedState *ss)\r
-       {\r
-               SQInteger size = calcinstancesize(_class);\r
-               SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);\r
-               new (newinst) SQInstance(ss, this,size);\r
-               return newinst;\r
-       }\r
-       ~SQInstance();\r
-       bool Get(const SQObjectPtr &key,SQObjectPtr &val)  {\r
-               if(_class->_members->Get(key,val)) {\r
-                       if(_isfield(val)) {\r
-                               SQObjectPtr &o = _values[_member_idx(val)];\r
-                               val = _realval(o);\r
-                       }\r
-                       else {\r
-                               val = _class->_methods[_member_idx(val)].val;\r
-                       }\r
-                       return true;\r
-               }\r
-               return false;\r
-       }\r
-       bool Set(const SQObjectPtr &key,const SQObjectPtr &val) {\r
-               SQObjectPtr idx;\r
-               if(_class->_members->Get(key,idx) && _isfield(idx)) {\r
-            _values[_member_idx(idx)] = val;\r
-                       return true;\r
-               }\r
-               return false;\r
-       }\r
-       void Release() { \r
-               if (_hook) { _hook(_userpointer,0);}\r
-               SQInteger size = _memsize;\r
-               this->~SQInstance();\r
-               SQ_FREE(this, size);\r
-       }\r
-       void Finalize();\r
-#ifndef NO_GARBAGE_COLLECTOR \r
-       void Mark(SQCollectable ** );\r
-#endif\r
-       bool InstanceOf(SQClass *trg);\r
-       bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);\r
-\r
-       SQClass *_class;\r
-       SQUserPointer _userpointer;\r
-       SQRELEASEHOOK _hook;\r
-       SQUnsignedInteger _nvalues;\r
-       SQInteger _memsize;\r
-       SQObjectPtr _values[1];\r
-};\r
-\r
-#endif //_SQCLASS_H_\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQCLASS_H_
+#define _SQCLASS_H_
+
+struct SQInstance;
+
+struct SQClassMemeber {
+       SQClassMemeber(){}
+       SQClassMemeber(const SQClassMemeber &o) {
+               val = o.val;
+               attrs = o.attrs;
+       }
+       SQObjectPtr val;
+       SQObjectPtr attrs;
+};
+
+typedef sqvector<SQClassMemeber> SQClassMemeberVec;
+
+#define MEMBER_TYPE_METHOD 0x01000000
+#define MEMBER_TYPE_FIELD 0x02000000
+
+#define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD)
+#define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD)
+#define _make_method_idx(i) ((SQInteger)(MEMBER_TYPE_METHOD|i))
+#define _make_field_idx(i) ((SQInteger)(MEMBER_TYPE_FIELD|i))
+#define _member_type(o) (_integer(o)&0xFF000000)
+#define _member_idx(o) (_integer(o)&0x00FFFFFF)
+
+struct SQClass : public CHAINABLE_OBJ
+{
+       SQClass(SQSharedState *ss,SQClass *base);
+public:
+       static SQClass* Create(SQSharedState *ss,SQClass *base) {
+               SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass));
+               new (newclass) SQClass(ss, base);
+               return newclass;
+       }
+       ~SQClass();
+       bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic);
+       bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
+               if(_members->Get(key,val)) {
+                       if(_isfield(val)) {
+                               SQObjectPtr &o = _defaultvalues[_member_idx(val)].val;
+                               val = _realval(o);
+                       }
+                       else {
+                               val = _methods[_member_idx(val)].val;
+                       }
+                       return true;
+               }
+               return false;
+       }
+       bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val);
+       bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval);
+       void Lock() { _locked = true; if(_base) _base->Lock(); }
+       void Release() {
+               if (_hook) { _hook(_typetag,0);}
+               sq_delete(this, SQClass);
+       }
+       void Finalize();
+#ifndef NO_GARBAGE_COLLECTOR
+       void Mark(SQCollectable ** );
+#endif
+       SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
+       SQInstance *CreateInstance();
+       SQTable *_members;
+       SQClass *_base;
+       SQClassMemeberVec _defaultvalues;
+       SQClassMemeberVec _methods;
+       SQObjectPtrVec _metamethods;
+       SQObjectPtr _attributes;
+       SQUserPointer _typetag;
+       SQRELEASEHOOK _hook;
+       bool _locked;
+};
+
+#define calcinstancesize(_theclass_) \
+       (sizeof(SQInstance)+(sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0)))
+struct SQInstance : public SQDelegable
+{
+       void Init(SQSharedState *ss);
+       SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize);
+       SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize);
+public:
+       static SQInstance* Create(SQSharedState *ss,SQClass *theclass) {
+
+               SQInteger size = calcinstancesize(theclass);
+               SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
+               new (newinst) SQInstance(ss, theclass,size);
+               return newinst;
+       }
+       SQInstance *Clone(SQSharedState *ss)
+       {
+               SQInteger size = calcinstancesize(_class);
+               SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
+               new (newinst) SQInstance(ss, this,size);
+               return newinst;
+       }
+       ~SQInstance();
+       bool Get(const SQObjectPtr &key,SQObjectPtr &val)  {
+               if(_class->_members->Get(key,val)) {
+                       if(_isfield(val)) {
+                               SQObjectPtr &o = _values[_member_idx(val)];
+                               val = _realval(o);
+                       }
+                       else {
+                               val = _class->_methods[_member_idx(val)].val;
+                       }
+                       return true;
+               }
+               return false;
+       }
+       bool Set(const SQObjectPtr &key,const SQObjectPtr &val) {
+               SQObjectPtr idx;
+               if(_class->_members->Get(key,idx) && _isfield(idx)) {
+            _values[_member_idx(idx)] = val;
+                       return true;
+               }
+               return false;
+       }
+       void Release() {
+               if (_hook) { _hook(_userpointer,0);}
+               SQInteger size = _memsize;
+               this->~SQInstance();
+               SQ_FREE(this, size);
+       }
+       void Finalize();
+#ifndef NO_GARBAGE_COLLECTOR
+       void Mark(SQCollectable ** );
+#endif
+       bool InstanceOf(SQClass *trg);
+       bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
+
+       SQClass *_class;
+       SQUserPointer _userpointer;
+       SQRELEASEHOOK _hook;
+       SQUnsignedInteger _nvalues;
+       SQInteger _memsize;
+       SQObjectPtr _values[1];
+};
+
+#endif //_SQCLASS_H_
index 7a5df1b..d8dc90a 100644 (file)
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQCLOSURE_H_\r
-#define _SQCLOSURE_H_\r
-\r
-struct SQFunctionProto;\r
-\r
-struct SQClosure : public CHAINABLE_OBJ\r
-{\r
-private:\r
-       SQClosure(SQSharedState *ss,SQFunctionProto *func){_function=func; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}\r
-public:\r
-       static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func){\r
-               SQClosure *nc=(SQClosure*)SQ_MALLOC(sizeof(SQClosure));\r
-               new (nc) SQClosure(ss,func);\r
-               return nc;\r
-       }\r
-       void Release(){\r
-               sq_delete(this,SQClosure);\r
-       }\r
-       SQClosure *Clone()\r
-       {\r
-               SQClosure * ret = SQClosure::Create(_opt_ss(this),_funcproto(_function));\r
-               ret->_env = _env;\r
-               ret->_outervalues.copy(_outervalues);\r
-               return ret;\r
-       }\r
-       ~SQClosure()\r
-       {\r
-               REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);\r
-       }\r
-       bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);\r
-       bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read);\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-       void Mark(SQCollectable **chain);\r
-       void Finalize(){_outervalues.resize(0); }\r
-#endif\r
-       SQObjectPtr _env;\r
-       SQObjectPtr _function;\r
-       SQObjectPtrVec _outervalues;\r
-};\r
-//////////////////////////////////////////////\r
-struct SQGenerator : public CHAINABLE_OBJ \r
-{\r
-       enum SQGeneratorState{eRunning,eSuspended,eDead};\r
-private:\r
-       SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=_null_;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}\r
-public:\r
-       static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){\r
-               SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));\r
-               new (nc) SQGenerator(ss,closure);\r
-               return nc;\r
-       }\r
-       ~SQGenerator()\r
-       {\r
-               REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);\r
-       }\r
-    void Kill(){\r
-               _state=eDead;\r
-               _stack.resize(0);\r
-               _closure=_null_;}\r
-       void Release(){\r
-               sq_delete(this,SQGenerator);\r
-       }\r
-       bool Yield(SQVM *v);\r
-       bool Resume(SQVM *v,SQInteger target);\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-       void Mark(SQCollectable **chain);\r
-       void Finalize(){_stack.resize(0);_closure=_null_;}\r
-#endif\r
-       SQObjectPtr _closure;\r
-       SQObjectPtrVec _stack;\r
-       SQObjectPtrVec _vargsstack;\r
-       SQVM::CallInfo _ci;\r
-       ExceptionsTraps _etraps;\r
-       SQGeneratorState _state;\r
-};\r
-\r
-struct SQNativeClosure : public CHAINABLE_OBJ\r
-{\r
-private:\r
-       SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);        }\r
-public:\r
-       static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func)\r
-       {\r
-               SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(sizeof(SQNativeClosure));\r
-               new (nc) SQNativeClosure(ss,func);\r
-               return nc;\r
-       }\r
-       SQNativeClosure *Clone()\r
-       {\r
-               SQNativeClosure * ret = SQNativeClosure::Create(_opt_ss(this),_function);\r
-               ret->_env = _env;\r
-               ret->_name = _name;\r
-               ret->_outervalues.copy(_outervalues);\r
-               ret->_typecheck = _typecheck;\r
-               ret->_nparamscheck = _nparamscheck;\r
-               return ret;\r
-       }\r
-       ~SQNativeClosure()\r
-       {\r
-               REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);\r
-       }\r
-       void Release(){\r
-               sq_delete(this,SQNativeClosure);\r
-       }\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-       void Mark(SQCollectable **chain);\r
-       void Finalize(){_outervalues.resize(0);}\r
-#endif\r
-       SQObjectPtr _env;\r
-       SQFUNCTION _function;\r
-       SQObjectPtr _name;\r
-       SQObjectPtrVec _outervalues;\r
-       SQIntVec _typecheck;\r
-       SQInteger _nparamscheck;\r
-};\r
-\r
-\r
-\r
-#endif //_SQCLOSURE_H_\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQCLOSURE_H_
+#define _SQCLOSURE_H_
+
+struct SQFunctionProto;
+
+struct SQClosure : public CHAINABLE_OBJ
+{
+private:
+       SQClosure(SQSharedState *ss,SQFunctionProto *func){_function=func; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
+public:
+       static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func){
+               SQClosure *nc=(SQClosure*)SQ_MALLOC(sizeof(SQClosure));
+               new (nc) SQClosure(ss,func);
+               return nc;
+       }
+       void Release(){
+               sq_delete(this,SQClosure);
+       }
+       SQClosure *Clone()
+       {
+               SQClosure * ret = SQClosure::Create(_opt_ss(this),_funcproto(_function));
+               ret->_env = _env;
+               ret->_outervalues.copy(_outervalues);
+               return ret;
+       }
+       ~SQClosure()
+       {
+               REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
+       }
+       bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
+       bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read);
+#ifndef NO_GARBAGE_COLLECTOR
+       void Mark(SQCollectable **chain);
+       void Finalize(){_outervalues.resize(0); }
+#endif
+       SQObjectPtr _env;
+       SQObjectPtr _function;
+       SQObjectPtrVec _outervalues;
+};
+//////////////////////////////////////////////
+struct SQGenerator : public CHAINABLE_OBJ
+{
+       enum SQGeneratorState{eRunning,eSuspended,eDead};
+private:
+       SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=_null_;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
+public:
+       static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){
+               SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));
+               new (nc) SQGenerator(ss,closure);
+               return nc;
+       }
+       ~SQGenerator()
+       {
+               REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
+       }
+    void Kill(){
+               _state=eDead;
+               _stack.resize(0);
+               _closure=_null_;}
+       void Release(){
+               sq_delete(this,SQGenerator);
+       }
+       bool Yield(SQVM *v);
+       bool Resume(SQVM *v,SQInteger target);
+#ifndef NO_GARBAGE_COLLECTOR
+       void Mark(SQCollectable **chain);
+       void Finalize(){_stack.resize(0);_closure=_null_;}
+#endif
+       SQObjectPtr _closure;
+       SQObjectPtrVec _stack;
+       SQObjectPtrVec _vargsstack;
+       SQVM::CallInfo _ci;
+       ExceptionsTraps _etraps;
+       SQGeneratorState _state;
+};
+
+struct SQNativeClosure : public CHAINABLE_OBJ
+{
+private:
+       SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);        }
+public:
+       static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func)
+       {
+               SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(sizeof(SQNativeClosure));
+               new (nc) SQNativeClosure(ss,func);
+               return nc;
+       }
+       SQNativeClosure *Clone()
+       {
+               SQNativeClosure * ret = SQNativeClosure::Create(_opt_ss(this),_function);
+               ret->_env = _env;
+               ret->_name = _name;
+               ret->_outervalues.copy(_outervalues);
+               ret->_typecheck = _typecheck;
+               ret->_nparamscheck = _nparamscheck;
+               return ret;
+       }
+       ~SQNativeClosure()
+       {
+               REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
+       }
+       void Release(){
+               sq_delete(this,SQNativeClosure);
+       }
+#ifndef NO_GARBAGE_COLLECTOR
+       void Mark(SQCollectable **chain);
+       void Finalize(){_outervalues.resize(0);}
+#endif
+       SQObjectPtr _env;
+       SQFUNCTION _function;
+       SQObjectPtr _name;
+       SQObjectPtrVec _outervalues;
+       SQIntVec _typecheck;
+       SQInteger _nparamscheck;
+};
+
+
+
+#endif //_SQCLOSURE_H_
index 464a0c0..a6bab09 100644 (file)
-/*\r
-       see copyright notice in squirrel.h\r
-*/\r
-#include "sqpcheader.h"\r
-#include <stdarg.h>\r
-#include <setjmp.h>\r
-#include "sqopcodes.h"\r
-#include "sqstring.h"\r
-#include "sqfuncproto.h"\r
-#include "sqcompiler.h"\r
-#include "sqfuncstate.h"\r
-#include "sqlexer.h"\r
-#include "sqvm.h"\r
-\r
-#define DEREF_NO_DEREF -1\r
-#define DEREF_FIELD            -2\r
-\r
-struct ExpState\r
-{\r
-       ExpState()\r
-       {\r
-               _deref = DEREF_NO_DEREF;\r
-               _freevar = false;\r
-               _class_or_delete = false;\r
-               _funcarg = false;\r
-       }\r
-       bool _class_or_delete;\r
-       bool _funcarg;\r
-       bool _freevar;\r
-       SQInteger _deref;\r
-};\r
-\r
-typedef sqvector<ExpState> ExpStateVec;\r
-\r
-#define _exst (_expstates.top())\r
-\r
-#define BEGIN_BREAKBLE_BLOCK() SQInteger __nbreaks__=_fs->_unresolvedbreaks.size(); \\r
-                                                       SQInteger __ncontinues__=_fs->_unresolvedcontinues.size(); \\r
-                                                       _fs->_breaktargets.push_back(0);_fs->_continuetargets.push_back(0);\r
-\r
-#define END_BREAKBLE_BLOCK(continue_target) {__nbreaks__=_fs->_unresolvedbreaks.size()-__nbreaks__; \\r
-                                       __ncontinues__=_fs->_unresolvedcontinues.size()-__ncontinues__; \\r
-                                       if(__ncontinues__>0)ResolveContinues(_fs,__ncontinues__,continue_target); \\r
-                                       if(__nbreaks__>0)ResolveBreaks(_fs,__nbreaks__); \\r
-                                       _fs->_breaktargets.pop_back();_fs->_continuetargets.pop_back();}\r
-\r
-class SQCompiler\r
-{\r
-public:\r
-       SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo)\r
-       {\r
-               _vm=v;\r
-               _lex.Init(_ss(v), rg, up,ThrowError,this);\r
-               _sourcename = SQString::Create(_ss(v), sourcename);\r
-               _lineinfo = lineinfo;_raiseerror = raiseerror;\r
-               compilererror = NULL;\r
-       }\r
-       static void ThrowError(void *ud, const SQChar *s) {\r
-               SQCompiler *c = (SQCompiler *)ud;\r
-               c->Error(s);\r
-       }\r
-       void Error(const SQChar *s, ...)\r
-       {\r
-               static SQChar temp[256];\r
-               va_list vl;\r
-               va_start(vl, s);\r
-               scvsprintf(temp, s, vl);\r
-               va_end(vl);\r
-               compilererror = temp;\r
-               longjmp(_errorjmp,1);\r
-       }\r
-       void Lex(){     _token = _lex.Lex();}\r
-       void PushExpState(){ _expstates.push_back(ExpState()); }\r
-       bool IsDerefToken(SQInteger tok)\r
-       {\r
-               switch(tok){\r
-               case _SC('='): case _SC('('): case TK_NEWSLOT:\r
-               case TK_MODEQ: case TK_MULEQ: case TK_DIVEQ: case TK_MINUSEQ: case TK_PLUSEQ: case TK_PLUSPLUS: case TK_MINUSMINUS: return true;\r
-               }\r
-               return false;\r
-       }\r
-       ExpState PopExpState()\r
-       {\r
-               ExpState ret = _expstates.top();\r
-               _expstates.pop_back();\r
-               return ret;\r
-       }\r
-       SQObject Expect(SQInteger tok)\r
-       {\r
-               \r
-               if(_token != tok) {\r
-                       if(_token == TK_CONSTRUCTOR && tok == TK_IDENTIFIER) {\r
-                               //ret = SQString::Create(_ss(_vm),_SC("constructor"));\r
-                               //do nothing\r
-                       }\r
-                       else {\r
-                               const SQChar *etypename;\r
-                               if(tok > 255) {\r
-                                       switch(tok)\r
-                                       {\r
-                                       case TK_IDENTIFIER:\r
-                                               etypename = _SC("IDENTIFIER");\r
-                                               break;\r
-                                       case TK_STRING_LITERAL:\r
-                                               etypename = _SC("STRING_LITERAL");\r
-                                               break;\r
-                                       case TK_INTEGER:\r
-                                               etypename = _SC("INTEGER");\r
-                                               break;\r
-                                       case TK_FLOAT:\r
-                                               etypename = _SC("FLOAT");\r
-                                               break;\r
-                                       default:\r
-                                               etypename = _lex.Tok2Str(tok);\r
-                                       }\r
-                                       Error(_SC("expected '%s'"), etypename);\r
-                               }\r
-                               Error(_SC("expected '%c'"), tok);\r
-                       }\r
-               }\r
-               SQObjectPtr ret;\r
-               switch(tok)\r
-               {\r
-               case TK_IDENTIFIER:\r
-                       ret = _fs->CreateString(_lex._svalue);\r
-                       break;\r
-               case TK_STRING_LITERAL:\r
-                       ret = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1);\r
-                       break;\r
-               case TK_INTEGER:\r
-                       ret = SQObjectPtr(_lex._nvalue);\r
-                       break;\r
-               case TK_FLOAT:\r
-                       ret = SQObjectPtr(_lex._fvalue);\r
-                       break;\r
-               }\r
-               Lex();\r
-               return ret;\r
-       }\r
-       bool IsEndOfStatement() { return ((_lex._prevtoken == _SC('\n')) || (_token == SQUIRREL_EOB) || (_token == _SC('}')) || (_token == _SC(';'))); }\r
-       void OptionalSemicolon()\r
-       {\r
-               if(_token == _SC(';')) { Lex(); return; }\r
-               if(!IsEndOfStatement()) {\r
-                       Error(_SC("end of statement expected (; or lf)"));\r
-               }\r
-       }\r
-       void MoveIfCurrentTargetIsLocal() {\r
-               SQInteger trg = _fs->TopTarget();\r
-               if(_fs->IsLocal(trg)) {\r
-                       trg = _fs->PopTarget(); //no pops the target and move it\r
-                       _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), trg);\r
-               }\r
-       }\r
-       bool Compile(SQObjectPtr &o)\r
-       {\r
-               _debugline = 1;\r
-               _debugop = 0;\r
-\r
-               SQFuncState funcstate(_ss(_vm), NULL,ThrowError,this);\r
-               funcstate._name = SQString::Create(_ss(_vm), _SC("main"));\r
-               _fs = &funcstate;\r
-               _fs->AddParameter(_fs->CreateString(_SC("this")));\r
-               _fs->_sourcename = _sourcename;\r
-               SQInteger stacksize = _fs->GetStackSize();\r
-               if(setjmp(_errorjmp) == 0) {\r
-                       Lex();\r
-                       while(_token > 0){\r
-                               Statement();\r
-                               if(_lex._prevtoken != _SC('}')) OptionalSemicolon();\r
-                       }\r
-                       CleanStack(stacksize);\r
-                       _fs->AddLineInfos(_lex._currentline, _lineinfo, true);\r
-                       _fs->AddInstruction(_OP_RETURN, 0xFF);\r
-                       _fs->SetStackSize(0);\r
-                       o =_fs->BuildProto();\r
-#ifdef _DEBUG_DUMP\r
-                       _fs->Dump(_funcproto(o));\r
-#endif\r
-               }\r
-               else {\r
-                       if(_raiseerror && _ss(_vm)->_compilererrorhandler) {\r
-                               _ss(_vm)->_compilererrorhandler(_vm, compilererror, type(_sourcename) == OT_STRING?_stringval(_sourcename):_SC("unknown"),\r
-                                       _lex._currentline, _lex._currentcolumn);\r
-                       }\r
-                       _vm->_lasterror = SQString::Create(_ss(_vm), compilererror, -1);\r
-                       return false;\r
-               }\r
-               return true;\r
-       }\r
-       void Statements()\r
-       {\r
-               while(_token != _SC('}') && _token != TK_DEFAULT && _token != TK_CASE) {\r
-                       Statement();\r
-                       if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon();\r
-               }\r
-       }\r
-       void Statement()\r
-       {\r
-               _fs->AddLineInfos(_lex._currentline, _lineinfo);\r
-               switch(_token){\r
-               case _SC(';'):  Lex();                                  break;\r
-               case TK_IF:             IfStatement();                  break;\r
-               case TK_WHILE:          WhileStatement();               break;\r
-               case TK_DO:             DoWhileStatement();             break;\r
-               case TK_FOR:            ForStatement();                 break;\r
-               case TK_FOREACH:        ForEachStatement();             break;\r
-               case TK_SWITCH: SwitchStatement();              break;\r
-               case TK_LOCAL:          LocalDeclStatement();   break;\r
-               case TK_RETURN:\r
-               case TK_YIELD: {\r
-                       SQOpcode op;\r
-                       if(_token == TK_RETURN) {\r
-                               op = _OP_RETURN;\r
-                               \r
-                       }\r
-                       else {\r
-                               op = _OP_YIELD;\r
-                               _fs->_bgenerator = true;\r
-                       }\r
-                       Lex();\r
-                       if(!IsEndOfStatement()) {\r
-                               SQInteger retexp = _fs->GetCurrentPos()+1;\r
-                               CommaExpr();\r
-                               if(op == _OP_RETURN && _fs->_traps > 0)\r
-                                       _fs->AddInstruction(_OP_POPTRAP, _fs->_traps, 0);\r
-                               _fs->_returnexp = retexp;\r
-                               _fs->AddInstruction(op, 1, _fs->PopTarget());\r
-                       }\r
-                       else{ \r
-                               if(op == _OP_RETURN && _fs->_traps > 0)\r
-                                       _fs->AddInstruction(_OP_POPTRAP, _fs->_traps ,0);\r
-                               _fs->_returnexp = -1;\r
-                               _fs->AddInstruction(op, 0xFF); \r
-                       }\r
-                       break;}\r
-               case TK_BREAK:\r
-                       if(_fs->_breaktargets.size() <= 0)Error(_SC("'break' has to be in a loop block"));\r
-                       if(_fs->_breaktargets.top() > 0){\r
-                               _fs->AddInstruction(_OP_POPTRAP, _fs->_breaktargets.top(), 0);\r
-                       }\r
-                       _fs->AddInstruction(_OP_JMP, 0, -1234);\r
-                       _fs->_unresolvedbreaks.push_back(_fs->GetCurrentPos());\r
-                       Lex();\r
-                       break;\r
-               case TK_CONTINUE:\r
-                       if(_fs->_continuetargets.size() <= 0)Error(_SC("'continue' has to be in a loop block"));\r
-                       if(_fs->_continuetargets.top() > 0) {\r
-                               _fs->AddInstruction(_OP_POPTRAP, _fs->_continuetargets.top(), 0);\r
-                       }\r
-                       _fs->AddInstruction(_OP_JMP, 0, -1234);\r
-                       _fs->_unresolvedcontinues.push_back(_fs->GetCurrentPos());\r
-                       Lex();\r
-                       break;\r
-               case TK_FUNCTION:\r
-                       FunctionStatement();\r
-                       break;\r
-               case TK_CLASS:\r
-                       ClassStatement();\r
-                       break;\r
-               case _SC('{'):{\r
-                               SQInteger stacksize = _fs->GetStackSize();\r
-                               Lex();\r
-                               Statements();\r
-                               Expect(_SC('}'));\r
-                               _fs->SetStackSize(stacksize);\r
-                       }\r
-                       break;\r
-               case TK_TRY:\r
-                       TryCatchStatement();\r
-                       break;\r
-               case TK_THROW:\r
-                       Lex();\r
-                       CommaExpr();\r
-                       _fs->AddInstruction(_OP_THROW, _fs->PopTarget());\r
-                       break;\r
-               default:\r
-                       CommaExpr();\r
-                       _fs->PopTarget();\r
-                       break;\r
-               }\r
-               _fs->SnoozeOpt();\r
-       }\r
-       void EmitDerefOp(SQOpcode op)\r
-       {\r
-               SQInteger val = _fs->PopTarget();\r
-               SQInteger key = _fs->PopTarget();\r
-               SQInteger src = _fs->PopTarget();\r
-        _fs->AddInstruction(op,_fs->PushTarget(),src,key,val);\r
-       }\r
-       void Emit2ArgsOP(SQOpcode op, SQInteger p3 = 0)\r
-       {\r
-               SQInteger p2 = _fs->PopTarget(); //src in OP_GET\r
-               SQInteger p1 = _fs->PopTarget(); //key in OP_GET\r
-               _fs->AddInstruction(op,_fs->PushTarget(), p1, p2, p3);\r
-       }\r
-       void EmitCompoundArith(SQInteger tok,bool deref)\r
-       {\r
-               SQInteger oper;\r
-               switch(tok){\r
-               case TK_MINUSEQ: oper = '-'; break;\r
-               case TK_PLUSEQ: oper = '+'; break;\r
-               case TK_MULEQ: oper = '*'; break;\r
-               case TK_DIVEQ: oper = '/'; break;\r
-               case TK_MODEQ: oper = '%'; break;\r
-               default: oper = 0; //shut up compiler\r
-                       assert(0); break;\r
-               };\r
-               if(deref) {\r
-                       SQInteger val = _fs->PopTarget();\r
-                       SQInteger key = _fs->PopTarget();\r
-                       SQInteger src = _fs->PopTarget();\r
-                       //mixes dest obj and source val in the arg1(hack?)\r
-                       _fs->AddInstruction(_OP_COMPARITH,_fs->PushTarget(),(src<<16)|val,key,oper);\r
-               }\r
-               else {\r
-                       Emit2ArgsOP(_OP_COMPARITHL, oper);\r
-               }\r
-       }\r
-       void CommaExpr()\r
-       {\r
-               for(Expression();_token == ',';_fs->PopTarget(), Lex(), CommaExpr());\r
-       }\r
-       ExpState Expression(bool funcarg = false)\r
-       {\r
-               PushExpState();\r
-               _exst._class_or_delete = false;\r
-               _exst._funcarg = funcarg;\r
-               LogicalOrExp();\r
-               switch(_token)  {\r
-               case _SC('='):\r
-               case TK_NEWSLOT:\r
-               case TK_MINUSEQ:\r
-               case TK_PLUSEQ:\r
-               case TK_MULEQ:\r
-               case TK_DIVEQ:\r
-               case TK_MODEQ:\r
-               {\r
-                               SQInteger op = _token;\r
-                               SQInteger ds = _exst._deref;\r
-                               bool freevar = _exst._freevar;\r
-                               if(ds == DEREF_NO_DEREF) Error(_SC("can't assign expression"));\r
-                               Lex(); Expression();\r
-\r
-                               switch(op){\r
-                               case TK_NEWSLOT:\r
-                                       if(freevar) Error(_SC("free variables cannot be modified"));\r
-                                       if(ds == DEREF_FIELD)\r
-                                               EmitDerefOp(_OP_NEWSLOT);\r
-                                       else //if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local\r
-                                               Error(_SC("can't 'create' a local slot"));\r
-                                       break;\r
-                               case _SC('='): //ASSIGN\r
-                                       if(freevar) Error(_SC("free variables cannot be modified"));\r
-                                       if(ds == DEREF_FIELD)\r
-                                               EmitDerefOp(_OP_SET);\r
-                                       else {//if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local\r
-                                               SQInteger p2 = _fs->PopTarget(); //src in OP_GET\r
-                                               SQInteger p1 = _fs->TopTarget(); //key in OP_GET\r
-                                               _fs->AddInstruction(_OP_MOVE, p1, p2);\r
-                                       }\r
-                                       break;\r
-                               case TK_MINUSEQ:\r
-                               case TK_PLUSEQ:\r
-                               case TK_MULEQ:\r
-                               case TK_DIVEQ:\r
-                               case TK_MODEQ:\r
-                                       EmitCompoundArith(op,ds == DEREF_FIELD);\r
-                                       break;\r
-                               }\r
-                       }\r
-                       break;\r
-               case _SC('?'): {\r
-                       Lex();\r
-                       _fs->AddInstruction(_OP_JZ, _fs->PopTarget());\r
-                       SQInteger jzpos = _fs->GetCurrentPos();\r
-                       SQInteger trg = _fs->PushTarget();\r
-                       Expression();\r
-                       SQInteger first_exp = _fs->PopTarget();\r
-                       if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);\r
-                       SQInteger endfirstexp = _fs->GetCurrentPos();\r
-                       _fs->AddInstruction(_OP_JMP, 0, 0);\r
-                       Expect(_SC(':'));\r
-                       SQInteger jmppos = _fs->GetCurrentPos();\r
-                       Expression();\r
-                       SQInteger second_exp = _fs->PopTarget();\r
-                       if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);\r
-                       _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos);\r
-                       _fs->SetIntructionParam(jzpos, 1, endfirstexp - jzpos + 1);\r
-                       _fs->SnoozeOpt();\r
-                       }\r
-                       break;\r
-               }\r
-               return PopExpState();\r
-       }\r
-       void BIN_EXP(SQOpcode op, void (SQCompiler::*f)(void),SQInteger op3 = 0)\r
-       {\r
-               Lex(); (this->*f)();\r
-               SQInteger op1 = _fs->PopTarget();SQInteger op2 = _fs->PopTarget();\r
-               _fs->AddInstruction(op, _fs->PushTarget(), op1, op2, op3);\r
-       }\r
-       void LogicalOrExp()\r
-       {\r
-               LogicalAndExp();\r
-               for(;;) if(_token == TK_OR) {\r
-                       SQInteger first_exp = _fs->PopTarget();\r
-                       SQInteger trg = _fs->PushTarget();\r
-                       _fs->AddInstruction(_OP_OR, trg, 0, first_exp, 0);\r
-                       SQInteger jpos = _fs->GetCurrentPos();\r
-                       if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);\r
-                       Lex(); LogicalOrExp();\r
-                       _fs->SnoozeOpt();\r
-                       SQInteger second_exp = _fs->PopTarget();\r
-                       if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);\r
-                       _fs->SnoozeOpt();\r
-                       _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));\r
-                       break;\r
-               }else return;\r
-       }\r
-       void LogicalAndExp()\r
-       {\r
-               BitwiseOrExp();\r
-               for(;;) switch(_token) {\r
-               case TK_AND: {\r
-                       SQInteger first_exp = _fs->PopTarget();\r
-                       SQInteger trg = _fs->PushTarget();\r
-                       _fs->AddInstruction(_OP_AND, trg, 0, first_exp, 0);\r
-                       SQInteger jpos = _fs->GetCurrentPos();\r
-                       if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);\r
-                       Lex(); LogicalAndExp();\r
-                       _fs->SnoozeOpt();\r
-                       SQInteger second_exp = _fs->PopTarget();\r
-                       if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);\r
-                       _fs->SnoozeOpt();\r
-                       _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));\r
-                       break;\r
-                       }\r
-               case TK_IN: BIN_EXP(_OP_EXISTS, &SQCompiler::BitwiseOrExp); break;\r
-               case TK_INSTANCEOF: BIN_EXP(_OP_INSTANCEOF, &SQCompiler::BitwiseOrExp); break;\r
-               default:\r
-                       return;\r
-               }\r
-       }\r
-       void BitwiseOrExp()\r
-       {\r
-               BitwiseXorExp();\r
-               for(;;) if(_token == _SC('|'))\r
-               {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseXorExp,BW_OR);\r
-               }else return;\r
-       }\r
-       void BitwiseXorExp()\r
-       {\r
-               BitwiseAndExp();\r
-               for(;;) if(_token == _SC('^'))\r
-               {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseAndExp,BW_XOR);\r
-               }else return;\r
-       }\r
-       void BitwiseAndExp()\r
-       {\r
-               CompExp();\r
-               for(;;) if(_token == _SC('&'))\r
-               {BIN_EXP(_OP_BITW, &SQCompiler::CompExp,BW_AND);\r
-               }else return;\r
-       }\r
-       void CompExp()\r
-       {\r
-               ShiftExp();\r
-               for(;;) switch(_token) {\r
-               case TK_EQ: BIN_EXP(_OP_EQ, &SQCompiler::ShiftExp); break;\r
-               case _SC('>'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_G); break;\r
-               case _SC('<'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_L); break;\r
-               case TK_GE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_GE); break;\r
-               case TK_LE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_LE); break;\r
-               case TK_NE: BIN_EXP(_OP_NE, &SQCompiler::ShiftExp); break;\r
-               default: return;        \r
-               }\r
-       }\r
-       void ShiftExp()\r
-       {\r
-               PlusExp();\r
-               for(;;) switch(_token) {\r
-               case TK_USHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_USHIFTR); break;\r
-               case TK_SHIFTL: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTL); break;\r
-               case TK_SHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTR); break;\r
-               default: return;        \r
-               }\r
-       }\r
-       void PlusExp()\r
-       {\r
-               MultExp();\r
-               for(;;) switch(_token) {\r
-               case _SC('+'): case _SC('-'):\r
-                       BIN_EXP(_OP_ARITH, &SQCompiler::MultExp,_token); break;\r
-               default: return;\r
-               }\r
-       }\r
-       \r
-       void MultExp()\r
-       {\r
-               PrefixedExpr();\r
-               for(;;) switch(_token) {\r
-               case _SC('*'): case _SC('/'): case _SC('%'):\r
-                       BIN_EXP(_OP_ARITH, &SQCompiler::PrefixedExpr,_token); break;\r
-               default: return;\r
-               }\r
-       }\r
-       //if 'pos' != -1 the previous variable is a local variable\r
-       void PrefixedExpr()\r
-       {\r
-               SQInteger pos = Factor();\r
-               for(;;) {\r
-                       switch(_token) {\r
-                       case _SC('.'): {\r
-                               pos = -1;\r
-                               Lex(); \r
-                               if(_token == TK_PARENT) {\r
-                                       Lex();\r
-                                       if(!NeedGet())\r
-                                               Error(_SC("parent cannot be set"));\r
-                                       SQInteger src = _fs->PopTarget();\r
-                                       _fs->AddInstruction(_OP_GETPARENT, _fs->PushTarget(), src);\r
-                               }\r
-                               else {\r
-                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));\r
-                                       if(NeedGet()) Emit2ArgsOP(_OP_GET);\r
-                               }\r
-                               _exst._deref = DEREF_FIELD;\r
-                               _exst._freevar = false;\r
-                               }\r
-                               break;\r
-                       case _SC('['):\r
-                               if(_lex._prevtoken == _SC('\n')) Error(_SC("cannot brake deref/or comma needed after [exp]=exp slot declaration"));\r
-                               Lex(); Expression(); Expect(_SC(']')); \r
-                               pos = -1;\r
-                               if(NeedGet()) Emit2ArgsOP(_OP_GET);\r
-                               _exst._deref = DEREF_FIELD;\r
-                               _exst._freevar = false;\r
-                               break;\r
-                       case TK_MINUSMINUS:\r
-                       case TK_PLUSPLUS:\r
-                       if(_exst._deref != DEREF_NO_DEREF && !IsEndOfStatement()) { \r
-                               SQInteger tok = _token; Lex();\r
-                               if(pos < 0)\r
-                                       Emit2ArgsOP(_OP_PINC,tok == TK_MINUSMINUS?-1:1);\r
-                               else {//if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local\r
-                                       SQInteger src = _fs->PopTarget();\r
-                                       _fs->AddInstruction(_OP_PINCL, _fs->PushTarget(), src, 0, tok == TK_MINUSMINUS?-1:1);\r
-                               }\r
-                               \r
-                       }\r
-                       return;\r
-                       break;  \r
-                       case _SC('('): \r
-                               {\r
-                               if(_exst._deref != DEREF_NO_DEREF) {\r
-                                       if(pos<0) {\r
-                                               SQInteger key = _fs->PopTarget(); //key\r
-                                               SQInteger table = _fs->PopTarget(); //table etc...\r
-                                               SQInteger closure = _fs->PushTarget();\r
-                                               SQInteger ttarget = _fs->PushTarget();\r
-                                               _fs->AddInstruction(_OP_PREPCALL, closure, key, table, ttarget);\r
-                                       }\r
-                                       else{\r
-                                               _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0);\r
-                                       }\r
-                               }\r
-                               else\r
-                                       _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0);\r
-                               _exst._deref = DEREF_NO_DEREF;\r
-                               Lex();\r
-                               FunctionCallArgs();\r
-                                }\r
-                               break;\r
-                       default: return;\r
-                       }\r
-               }\r
-       }\r
-       SQInteger Factor()\r
-       {\r
-               switch(_token)\r
-               {\r
-               case TK_STRING_LITERAL: {\r
-                               //SQObjectPtr id(SQString::Create(_ss(_vm), _lex._svalue,_lex._longstr.size()-1));\r
-                               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_fs->CreateString(_lex._svalue,_lex._longstr.size()-1)));\r
-                               Lex(); \r
-                       }\r
-                       break;\r
-               case TK_VARGC: Lex(); _fs->AddInstruction(_OP_VARGC, _fs->PushTarget()); break;\r
-               case TK_VARGV: { Lex();\r
-                       Expect(_SC('['));\r
-                       Expression();\r
-                       Expect(_SC(']'));\r
-                       SQInteger src = _fs->PopTarget();\r
-                       _fs->AddInstruction(_OP_GETVARGV, _fs->PushTarget(), src);\r
-                                          }\r
-                       break;\r
-               case TK_IDENTIFIER:\r
-               case TK_CONSTRUCTOR:\r
-               case TK_THIS:{\r
-                       _exst._freevar = false;\r
-                       SQObject id;\r
-                               switch(_token) {\r
-                                       case TK_IDENTIFIER: id = _fs->CreateString(_lex._svalue); break;\r
-                                       case TK_THIS: id = _fs->CreateString(_SC("this")); break;\r
-                                       case TK_CONSTRUCTOR: id = _fs->CreateString(_SC("constructor")); break;\r
-                               }\r
-                               SQInteger pos = -1;\r
-                               Lex();\r
-                               if((pos = _fs->GetLocalVariable(id)) == -1) {\r
-                                       //checks if is a free variable\r
-                                       if((pos = _fs->GetOuterVariable(id)) != -1) {\r
-                                               _exst._deref = _fs->PushTarget();\r
-                                               _fs->AddInstruction(_OP_LOADFREEVAR, _exst._deref ,pos);        \r
-                                               _exst._freevar = true;\r
-                                       } else {\r
-                                               _fs->PushTarget(0);\r
-                                               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));\r
-                                               if(NeedGet()) Emit2ArgsOP(_OP_GET);\r
-                                               _exst._deref = DEREF_FIELD;\r
-                                       }\r
-                               }\r
-                               else{\r
-                                       _fs->PushTarget(pos);\r
-                                       _exst._deref = pos;\r
-                               }\r
-                               return _exst._deref;\r
-                       }\r
-                       break;\r
-               case TK_PARENT: Lex();_fs->AddInstruction(_OP_GETPARENT, _fs->PushTarget(), 0); break;\r
-               case TK_DOUBLE_COLON:  // "::"\r
-                       _fs->AddInstruction(_OP_LOADROOTTABLE, _fs->PushTarget());\r
-                       _exst._deref = DEREF_FIELD;\r
-                       _token = _SC('.'); //hack\r
-                       return -1;\r
-                       break;\r
-               case TK_NULL: \r
-                       _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1);\r
-                       Lex();\r
-                       break;\r
-               case TK_INTEGER: {\r
-                       if((_lex._nvalue & (~0x7FFFFFFF)) == 0) { //does it fit in 32 bits?\r
-                               _fs->AddInstruction(_OP_LOADINT, _fs->PushTarget(),_lex._nvalue);\r
-                       }\r
-                       else {\r
-                               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._nvalue));\r
-                       }\r
-                       Lex();\r
-                                                }\r
-                       break;\r
-               case TK_FLOAT: \r
-                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._fvalue));\r
-                       Lex();\r
-                       break;\r
-               case TK_TRUE: case TK_FALSE:\r
-                       _fs->AddInstruction(_OP_LOADBOOL, _fs->PushTarget(),_token == TK_TRUE?1:0);\r
-                       Lex();\r
-                       break;\r
-               case _SC('['): {\r
-                               _fs->AddInstruction(_OP_NEWARRAY, _fs->PushTarget());\r
-                               SQInteger apos = _fs->GetCurrentPos(),key = 0;\r
-                               Lex();\r
-                               while(_token != _SC(']')) {\r
-                    Expression(); \r
-                                       if(_token == _SC(',')) Lex();\r
-                                       SQInteger val = _fs->PopTarget();\r
-                                       SQInteger array = _fs->TopTarget();\r
-                                       _fs->AddInstruction(_OP_APPENDARRAY, array, val);\r
-                                       key++;\r
-                               }\r
-                               _fs->SetIntructionParam(apos, 1, key);\r
-                               Lex();\r
-                       }\r
-                       break;\r
-               case _SC('{'):{\r
-                       _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget());\r
-                       Lex();ParseTableOrClass(_SC(','));\r
-                                }\r
-                       break;\r
-               case TK_FUNCTION: FunctionExp(_token);break;\r
-               case TK_CLASS: Lex(); ClassExp();break;\r
-               case _SC('-'): UnaryOP(_OP_NEG); break;\r
-               case _SC('!'): UnaryOP(_OP_NOT); break;\r
-               case _SC('~'): UnaryOP(_OP_BWNOT); break;\r
-               case TK_TYPEOF : UnaryOP(_OP_TYPEOF); break;\r
-               case TK_RESUME : UnaryOP(_OP_RESUME); break;\r
-               case TK_CLONE : UnaryOP(_OP_CLONE); break;\r
-               case TK_MINUSMINUS : \r
-               case TK_PLUSPLUS :PrefixIncDec(_token); break;\r
-               case TK_DELETE : DeleteExpr(); break;\r
-               case TK_DELEGATE : DelegateExpr(); break;\r
-               case _SC('('): Lex(); CommaExpr(); Expect(_SC(')'));\r
-                       break;\r
-               default: Error(_SC("expression expected"));\r
-               }\r
-               return -1;\r
-       }\r
-       void UnaryOP(SQOpcode op)\r
-       {\r
-               Lex(); PrefixedExpr();\r
-               SQInteger src = _fs->PopTarget();\r
-               _fs->AddInstruction(op, _fs->PushTarget(), src);\r
-       }\r
-       bool NeedGet()\r
-       {\r
-               switch(_token) {\r
-               case _SC('='): case _SC('('): case TK_NEWSLOT: case TK_PLUSPLUS: case TK_MINUSMINUS:\r
-               case TK_PLUSEQ: case TK_MINUSEQ: case TK_MULEQ: case TK_DIVEQ: case TK_MODEQ:\r
-                       return false;\r
-               }\r
-               return (!_exst._class_or_delete) || (_exst._class_or_delete && (_token == _SC('.') || _token == _SC('[')));\r
-       }\r
-       \r
-       void FunctionCallArgs()\r
-       {\r
-               SQInteger nargs = 1;//this\r
-                while(_token != _SC(')')) {\r
-                        Expression(true);\r
-                        MoveIfCurrentTargetIsLocal();\r
-                        nargs++; \r
-                        if(_token == _SC(',')){ \r
-                                Lex(); \r
-                                if(_token == ')') Error(_SC("expression expected, found ')'"));\r
-                        }\r
-                }\r
-                Lex();\r
-                for(SQInteger i = 0; i < (nargs - 1); i++) _fs->PopTarget();\r
-                SQInteger stackbase = _fs->PopTarget();\r
-                SQInteger closure = _fs->PopTarget();\r
-         _fs->AddInstruction(_OP_CALL, _fs->PushTarget(), closure, stackbase, nargs);\r
-       }\r
-       void ParseTableOrClass(SQInteger separator,SQInteger terminator = '}')\r
-       {\r
-               SQInteger tpos = _fs->GetCurrentPos(),nkeys = 0;\r
-               \r
-               while(_token != terminator) {\r
-                       bool hasattrs = false;\r
-                       bool isstatic = false;\r
-                       //check if is an attribute\r
-                       if(separator == ';') {\r
-                               if(_token == TK_ATTR_OPEN) {\r
-                                       _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget()); Lex();\r
-                                       ParseTableOrClass(',',TK_ATTR_CLOSE);\r
-                                       hasattrs = true;\r
-                               }\r
-                               if(_token == TK_STATIC) {\r
-                                       isstatic = true;\r
-                                       Lex();\r
-                               }\r
-                       }\r
-                       switch(_token) {\r
-                               case TK_FUNCTION:\r
-                               case TK_CONSTRUCTOR:{\r
-                                       SQInteger tk = _token;\r
-                                       Lex();\r
-                                       SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : _fs->CreateString(_SC("constructor"));\r
-                                       Expect(_SC('('));\r
-                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));\r
-                                       CreateFunction(id);\r
-                                       _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);\r
-                                                                 }\r
-                                                                 break;\r
-                               case _SC('['):\r
-                                       Lex(); CommaExpr(); Expect(_SC(']'));\r
-                                       Expect(_SC('=')); Expression();\r
-                                       break;\r
-                               default :\r
-                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));\r
-                                       Expect(_SC('=')); Expression();\r
-                       }\r
-\r
-                       if(_token == separator) Lex();//optional comma/semicolon\r
-                       nkeys++;\r
-                       SQInteger val = _fs->PopTarget();\r
-                       SQInteger key = _fs->PopTarget();\r
-                       SQInteger attrs = hasattrs ? _fs->PopTarget():-1;\r
-                       assert(hasattrs && attrs == key-1 || !hasattrs);\r
-                       unsigned char flags = (hasattrs?NEW_SLOT_ATTRIBUTES_FLAG:0)|(isstatic?NEW_SLOT_STATIC_FLAG:0);\r
-                       SQInteger table = _fs->TopTarget(); //<<BECAUSE OF THIS NO COMMON EMIT FUNC IS POSSIBLE\r
-                       _fs->AddInstruction(_OP_NEWSLOTA, flags, table, key, val);\r
-                       //_fs->PopTarget();\r
-               }\r
-               if(separator == _SC(',')) //hack recognizes a table from the separator\r
-                       _fs->SetIntructionParam(tpos, 1, nkeys);\r
-               Lex();\r
-       }\r
-       void LocalDeclStatement()\r
-       {\r
-               SQObject varname;\r
-               do {\r
-                       Lex(); varname = Expect(TK_IDENTIFIER);\r
-                       if(_token == _SC('=')) {\r
-                               Lex(); Expression();\r
-                               SQInteger src = _fs->PopTarget();\r
-                               SQInteger dest = _fs->PushTarget();\r
-                               if(dest != src) _fs->AddInstruction(_OP_MOVE, dest, src);\r
-                       }\r
-                       else{\r
-                               _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1);\r
-                       }\r
-                       _fs->PopTarget();\r
-                       _fs->PushLocalVariable(varname);\r
-               \r
-               } while(_token == _SC(','));\r
-       }\r
-       void IfStatement()\r
-       {\r
-               SQInteger jmppos;\r
-               bool haselse = false;\r
-               Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));\r
-               _fs->AddInstruction(_OP_JZ, _fs->PopTarget());\r
-               SQInteger jnepos = _fs->GetCurrentPos();\r
-               SQInteger stacksize = _fs->GetStackSize();\r
-               \r
-               Statement();\r
-               //\r
-               if(_token != _SC('}') && _token != TK_ELSE) OptionalSemicolon();\r
-               \r
-               CleanStack(stacksize);\r
-               SQInteger endifblock = _fs->GetCurrentPos();\r
-               if(_token == TK_ELSE){\r
-                       haselse = true;\r
-                       stacksize = _fs->GetStackSize();\r
-                       _fs->AddInstruction(_OP_JMP);\r
-                       jmppos = _fs->GetCurrentPos();\r
-                       Lex();\r
-                       Statement(); OptionalSemicolon();\r
-                       CleanStack(stacksize);\r
-                       _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos);\r
-               }\r
-               _fs->SetIntructionParam(jnepos, 1, endifblock - jnepos + (haselse?1:0));\r
-       }\r
-       void WhileStatement()\r
-       {\r
-               SQInteger jzpos, jmppos;\r
-               SQInteger stacksize = _fs->GetStackSize();\r
-               jmppos = _fs->GetCurrentPos();\r
-               Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));\r
-               \r
-               BEGIN_BREAKBLE_BLOCK();\r
-               _fs->AddInstruction(_OP_JZ, _fs->PopTarget());\r
-               jzpos = _fs->GetCurrentPos();\r
-               stacksize = _fs->GetStackSize();\r
-               \r
-               Statement();\r
-               \r
-               CleanStack(stacksize);\r
-               _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1);\r
-               _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos);\r
-               \r
-               END_BREAKBLE_BLOCK(jmppos);\r
-       }\r
-       void DoWhileStatement()\r
-       {\r
-               Lex();\r
-               SQInteger jzpos = _fs->GetCurrentPos();\r
-               SQInteger stacksize = _fs->GetStackSize();\r
-               BEGIN_BREAKBLE_BLOCK()\r
-               Statement();\r
-               CleanStack(stacksize);\r
-               Expect(TK_WHILE);\r
-               SQInteger continuetrg = _fs->GetCurrentPos();\r
-               Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));\r
-               _fs->AddInstruction(_OP_JNZ, _fs->PopTarget(), jzpos - _fs->GetCurrentPos() - 1);\r
-               END_BREAKBLE_BLOCK(continuetrg);\r
-       }\r
-       void ForStatement()\r
-       {\r
-               Lex();\r
-               SQInteger stacksize = _fs->GetStackSize();\r
-               Expect(_SC('('));\r
-               if(_token == TK_LOCAL) LocalDeclStatement();\r
-               else if(_token != _SC(';')){\r
-                       CommaExpr();\r
-                       _fs->PopTarget();\r
-               }\r
-               Expect(_SC(';'));\r
-               _fs->SnoozeOpt();\r
-               SQInteger jmppos = _fs->GetCurrentPos();\r
-               SQInteger jzpos = -1;\r
-               if(_token != _SC(';')) { CommaExpr(); _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); jzpos = _fs->GetCurrentPos(); }\r
-               Expect(_SC(';'));\r
-               _fs->SnoozeOpt();\r
-               SQInteger expstart = _fs->GetCurrentPos() + 1;\r
-               if(_token != _SC(')')) {\r
-                       CommaExpr();\r
-                       _fs->PopTarget();\r
-               }\r
-               Expect(_SC(')'));\r
-               _fs->SnoozeOpt();\r
-               SQInteger expend = _fs->GetCurrentPos();\r
-               SQInteger expsize = (expend - expstart) + 1;\r
-               SQInstructionVec exp;\r
-               if(expsize > 0) {\r
-                       for(SQInteger i = 0; i < expsize; i++)\r
-                               exp.push_back(_fs->GetInstruction(expstart + i));\r
-                       _fs->PopInstructions(expsize);\r
-               }\r
-               BEGIN_BREAKBLE_BLOCK()\r
-               Statement();\r
-               SQInteger continuetrg = _fs->GetCurrentPos();\r
-               if(expsize > 0) {\r
-                       for(SQInteger i = 0; i < expsize; i++)\r
-                               _fs->AddInstruction(exp[i]);\r
-               }\r
-               _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1, 0);\r
-               if(jzpos>  0) _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos);\r
-               CleanStack(stacksize);\r
-               \r
-               END_BREAKBLE_BLOCK(continuetrg);\r
-       }\r
-       void ForEachStatement()\r
-       {\r
-               SQObject idxname, valname;\r
-               Lex(); Expect(_SC('(')); valname = Expect(TK_IDENTIFIER);\r
-               if(_token == _SC(',')) {\r
-                       idxname = valname;\r
-                       Lex(); valname = Expect(TK_IDENTIFIER);\r
-               }\r
-               else{\r
-                       idxname = _fs->CreateString(_SC("@INDEX@"));\r
-               }\r
-               Expect(TK_IN);\r
-               \r
-               //save the stack size\r
-               SQInteger stacksize = _fs->GetStackSize();\r
-               //put the table in the stack(evaluate the table expression)\r
-               Expression(); Expect(_SC(')'));\r
-               SQInteger container = _fs->TopTarget();\r
-               //push the index local var\r
-               SQInteger indexpos = _fs->PushLocalVariable(idxname);\r
-               _fs->AddInstruction(_OP_LOADNULLS, indexpos,1);\r
-               //push the value local var\r
-               SQInteger valuepos = _fs->PushLocalVariable(valname);\r
-               _fs->AddInstruction(_OP_LOADNULLS, valuepos,1);\r
-               //push reference index\r
-               SQInteger itrpos = _fs->PushLocalVariable(_fs->CreateString(_SC("@ITERATOR@"))); //use invalid id to make it inaccessible\r
-               _fs->AddInstruction(_OP_LOADNULLS, itrpos,1);\r
-               SQInteger jmppos = _fs->GetCurrentPos();\r
-               _fs->AddInstruction(_OP_FOREACH, container, 0, indexpos);\r
-               SQInteger foreachpos = _fs->GetCurrentPos();\r
-               //generate the statement code\r
-               BEGIN_BREAKBLE_BLOCK()\r
-               Statement();\r
-               _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1);\r
-               _fs->SetIntructionParam(foreachpos, 1, _fs->GetCurrentPos() - foreachpos);\r
-               //restore the local variable stack(remove index,val and ref idx)\r
-               CleanStack(stacksize);\r
-               END_BREAKBLE_BLOCK(foreachpos - 1);\r
-       }\r
-       void SwitchStatement()\r
-       {\r
-               Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));\r
-               Expect(_SC('{'));\r
-               SQInteger expr = _fs->TopTarget();\r
-               bool bfirst = true;\r
-               SQInteger tonextcondjmp = -1;\r
-               SQInteger skipcondjmp = -1;\r
-               SQInteger __nbreaks__ = _fs->_unresolvedbreaks.size();\r
-               _fs->_breaktargets.push_back(0);\r
-               while(_token == TK_CASE) {\r
-                       //_fs->AddLineInfos(_lex._currentline, _lineinfo); think about this one\r
-                       if(!bfirst) {\r
-                               _fs->AddInstruction(_OP_JMP, 0, 0);\r
-                               skipcondjmp = _fs->GetCurrentPos();\r
-                               _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp);\r
-                       }\r
-                       //condition\r
-                       Lex(); Expression(); Expect(_SC(':'));\r
-                       SQInteger trg = _fs->PopTarget();\r
-                       _fs->AddInstruction(_OP_EQ, trg, trg, expr);\r
-                       _fs->AddInstruction(_OP_JZ, trg, 0);\r
-                       //end condition\r
-                       if(skipcondjmp != -1) {\r
-                               _fs->SetIntructionParam(skipcondjmp, 1, (_fs->GetCurrentPos() - skipcondjmp));\r
-                       }\r
-                       tonextcondjmp = _fs->GetCurrentPos();\r
-                       SQInteger stacksize = _fs->GetStackSize();\r
-                       Statements();\r
-                       _fs->SetStackSize(stacksize);\r
-                       bfirst = false;\r
-               }\r
-               if(tonextcondjmp != -1)\r
-                       _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp);\r
-               if(_token == TK_DEFAULT) {\r
-               //      _fs->AddLineInfos(_lex._currentline, _lineinfo);\r
-                       Lex(); Expect(_SC(':'));\r
-                       SQInteger stacksize = _fs->GetStackSize();\r
-                       Statements();\r
-                       _fs->SetStackSize(stacksize);\r
-               }\r
-               Expect(_SC('}'));\r
-               _fs->PopTarget();\r
-               __nbreaks__ = _fs->_unresolvedbreaks.size() - __nbreaks__;\r
-               if(__nbreaks__ > 0)ResolveBreaks(_fs, __nbreaks__);\r
-               _fs->_breaktargets.pop_back();\r
-               \r
-       }\r
-       void FunctionStatement()\r
-       {\r
-               SQObject id;\r
-               Lex(); id = Expect(TK_IDENTIFIER);\r
-               _fs->PushTarget(0);\r
-               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));\r
-               if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);\r
-               \r
-               while(_token == TK_DOUBLE_COLON) {\r
-                       Lex();\r
-                       id = Expect(TK_IDENTIFIER);\r
-                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));\r
-                       if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);\r
-               }\r
-               Expect(_SC('('));\r
-               CreateFunction(id);\r
-               _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);\r
-               EmitDerefOp(_OP_NEWSLOT);\r
-               _fs->PopTarget();\r
-       }\r
-       void ClassStatement()\r
-       {\r
-               ExpState es;\r
-               Lex(); PushExpState();\r
-               _exst._class_or_delete = true;\r
-               _exst._funcarg = false;\r
-               PrefixedExpr();\r
-               es = PopExpState();\r
-               if(es._deref == DEREF_NO_DEREF) Error(_SC("invalid class name"));\r
-               if(es._deref == DEREF_FIELD) {\r
-                       ClassExp();\r
-                       EmitDerefOp(_OP_NEWSLOT);\r
-                       _fs->PopTarget();\r
-               }\r
-               else Error(_SC("cannot create a class in a local with the syntax(class <local>)"));\r
-       }\r
-       void TryCatchStatement()\r
-       {\r
-               SQObject exid;\r
-               Lex();\r
-               _fs->AddInstruction(_OP_PUSHTRAP,0,0);\r
-               _fs->_traps++;\r
-               if(_fs->_breaktargets.size()) _fs->_breaktargets.top()++;\r
-               if(_fs->_continuetargets.size()) _fs->_continuetargets.top()++;\r
-               SQInteger trappos = _fs->GetCurrentPos();\r
-               Statement();\r
-               _fs->_traps--;\r
-               _fs->AddInstruction(_OP_POPTRAP, 1, 0);\r
-               if(_fs->_breaktargets.size()) _fs->_breaktargets.top()--;\r
-               if(_fs->_continuetargets.size()) _fs->_continuetargets.top()--;\r
-               _fs->AddInstruction(_OP_JMP, 0, 0);\r
-               SQInteger jmppos = _fs->GetCurrentPos();\r
-               _fs->SetIntructionParam(trappos, 1, (_fs->GetCurrentPos() - trappos));\r
-               Expect(TK_CATCH); Expect(_SC('(')); exid = Expect(TK_IDENTIFIER); Expect(_SC(')'));\r
-               SQInteger stacksize = _fs->GetStackSize();\r
-               SQInteger ex_target = _fs->PushLocalVariable(exid);\r
-               _fs->SetIntructionParam(trappos, 0, ex_target);\r
-               Statement();\r
-               _fs->SetIntructionParams(jmppos, 0, (_fs->GetCurrentPos() - jmppos), 0);\r
-               CleanStack(stacksize);\r
-       }\r
-       void FunctionExp(SQInteger ftype)\r
-       {\r
-               Lex(); Expect(_SC('('));\r
-               CreateFunction(_null_);\r
-               _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, ftype == TK_FUNCTION?0:1);\r
-       }\r
-       void ClassExp()\r
-       {\r
-               SQInteger base = -1;\r
-               SQInteger attrs = -1;\r
-               if(_token == TK_EXTENDS) {\r
-                       Lex(); Expression();\r
-                       base = _fs->TopTarget();\r
-               }\r
-               if(_token == TK_ATTR_OPEN) {\r
-                       Lex();\r
-                       _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget());\r
-                       ParseTableOrClass(_SC(','),TK_ATTR_CLOSE);\r
-                       attrs = _fs->TopTarget();\r
-               }\r
-               Expect(_SC('{'));\r
-               if(attrs != -1) _fs->PopTarget();\r
-               if(base != -1) _fs->PopTarget();\r
-               _fs->AddInstruction(_OP_CLASS, _fs->PushTarget(), base, attrs);\r
-               ParseTableOrClass(_SC(';'));\r
-       }\r
-       void DelegateExpr()\r
-       {\r
-               Lex(); CommaExpr();\r
-               Expect(_SC(':'));\r
-               CommaExpr();\r
-               SQInteger table = _fs->PopTarget(), delegate = _fs->PopTarget();\r
-               _fs->AddInstruction(_OP_DELEGATE, _fs->PushTarget(), table, delegate);\r
-       }\r
-       void DeleteExpr()\r
-       {\r
-               ExpState es;\r
-               Lex(); PushExpState();\r
-               _exst._class_or_delete = true;\r
-               _exst._funcarg = false;\r
-               PrefixedExpr();\r
-               es = PopExpState();\r
-               if(es._deref == DEREF_NO_DEREF) Error(_SC("can't delete an expression"));\r
-               if(es._deref == DEREF_FIELD) Emit2ArgsOP(_OP_DELETE);\r
-               else Error(_SC("cannot delete a local"));\r
-       }\r
-       void PrefixIncDec(SQInteger token)\r
-       {\r
-               ExpState es;\r
-               Lex(); PushExpState();\r
-               _exst._class_or_delete = true;\r
-               _exst._funcarg = false;\r
-               PrefixedExpr();\r
-               es = PopExpState();\r
-               if(es._deref == DEREF_FIELD) Emit2ArgsOP(_OP_INC,token == TK_MINUSMINUS?-1:1);\r
-               else {\r
-                       SQInteger src = _fs->PopTarget();\r
-                       _fs->AddInstruction(_OP_INCL, _fs->PushTarget(), src, 0, token == TK_MINUSMINUS?-1:1);\r
-               }\r
-       }\r
-       void CreateFunction(SQObject &name)\r
-       {\r
-               \r
-               SQFuncState *funcstate = _fs->PushChildState(_ss(_vm));\r
-               funcstate->_name = name;\r
-               SQObject paramname;\r
-               funcstate->AddParameter(_fs->CreateString(_SC("this")));\r
-               funcstate->_sourcename = _sourcename;\r
-               while(_token!=_SC(')')) {\r
-                       if(_token == TK_VARPARAMS) {\r
-                               funcstate->_varparams = true;\r
-                               Lex();\r
-                               if(_token != _SC(')')) Error(_SC("expected ')'"));\r
-                               break;\r
-                       }\r
-                       else {\r
-                               paramname = Expect(TK_IDENTIFIER);\r
-                               funcstate->AddParameter(paramname);\r
-                               if(_token == _SC(',')) Lex();\r
-                               else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));\r
-                       }\r
-               }\r
-               Expect(_SC(')'));\r
-               //outer values\r
-               if(_token == _SC(':')) {\r
-                       Lex(); Expect(_SC('('));\r
-                       while(_token != _SC(')')) {\r
-                               paramname = Expect(TK_IDENTIFIER);\r
-                               //outers are treated as implicit local variables\r
-                               funcstate->AddOuterValue(paramname);\r
-                               if(_token == _SC(',')) Lex();\r
-                               else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));\r
-                       }\r
-                       Lex();\r
-               }\r
-               \r
-               SQFuncState *currchunk = _fs;\r
-               _fs = funcstate;\r
-               Statement();\r
-               funcstate->AddLineInfos(_lex._prevtoken == _SC('\n')?_lex._lasttokenline:_lex._currentline, _lineinfo, true);\r
-        funcstate->AddInstruction(_OP_RETURN, -1);\r
-               funcstate->SetStackSize(0);\r
-               //_fs->->_stacksize = _fs->_stacksize;\r
-               SQFunctionProto *func = funcstate->BuildProto();\r
-#ifdef _DEBUG_DUMP\r
-               funcstate->Dump(func);\r
-#endif\r
-               _fs = currchunk;\r
-               _fs->_functions.push_back(func);\r
-               _fs->PopChildState();\r
-       }\r
-       void CleanStack(SQInteger stacksize)\r
-       {\r
-               if(_fs->GetStackSize() != stacksize)\r
-                       _fs->SetStackSize(stacksize);\r
-       }\r
-       void ResolveBreaks(SQFuncState *funcstate, SQInteger ntoresolve)\r
-       {\r
-               while(ntoresolve > 0) {\r
-                       SQInteger pos = funcstate->_unresolvedbreaks.back();\r
-                       funcstate->_unresolvedbreaks.pop_back();\r
-                       //set the jmp instruction\r
-                       funcstate->SetIntructionParams(pos, 0, funcstate->GetCurrentPos() - pos, 0);\r
-                       ntoresolve--;\r
-               }\r
-       }\r
-       void ResolveContinues(SQFuncState *funcstate, SQInteger ntoresolve, SQInteger targetpos)\r
-       {\r
-               while(ntoresolve > 0) {\r
-                       SQInteger pos = funcstate->_unresolvedcontinues.back();\r
-                       funcstate->_unresolvedcontinues.pop_back();\r
-                       //set the jmp instruction\r
-                       funcstate->SetIntructionParams(pos, 0, targetpos - pos, 0);\r
-                       ntoresolve--;\r
-               }\r
-       }\r
-private:\r
-       SQInteger _token;\r
-       SQFuncState *_fs;\r
-       SQObjectPtr _sourcename;\r
-       SQLexer _lex;\r
-       bool _lineinfo;\r
-       bool _raiseerror;\r
-       SQInteger _debugline;\r
-       SQInteger _debugop;\r
-       ExpStateVec _expstates;\r
-       SQChar *compilererror;\r
-       jmp_buf _errorjmp;\r
-       SQVM *_vm;\r
-};\r
-\r
-bool Compile(SQVM *vm,SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo)\r
-{\r
-       SQCompiler p(vm, rg, up, sourcename, raiseerror, lineinfo);\r
-       return p.Compile(out);\r
-}\r
+/*
+       see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include <stdarg.h>
+#include <setjmp.h>
+#include "sqopcodes.h"
+#include "sqstring.h"
+#include "sqfuncproto.h"
+#include "sqcompiler.h"
+#include "sqfuncstate.h"
+#include "sqlexer.h"
+#include "sqvm.h"
+
+#define DEREF_NO_DEREF -1
+#define DEREF_FIELD            -2
+
+struct ExpState
+{
+       ExpState()
+       {
+               _deref = DEREF_NO_DEREF;
+               _freevar = false;
+               _class_or_delete = false;
+               _funcarg = false;
+       }
+       bool _class_or_delete;
+       bool _funcarg;
+       bool _freevar;
+       SQInteger _deref;
+};
+
+typedef sqvector<ExpState> ExpStateVec;
+
+#define _exst (_expstates.top())
+
+#define BEGIN_BREAKBLE_BLOCK() SQInteger __nbreaks__=_fs->_unresolvedbreaks.size(); \
+                                                       SQInteger __ncontinues__=_fs->_unresolvedcontinues.size(); \
+                                                       _fs->_breaktargets.push_back(0);_fs->_continuetargets.push_back(0);
+
+#define END_BREAKBLE_BLOCK(continue_target) {__nbreaks__=_fs->_unresolvedbreaks.size()-__nbreaks__; \
+                                       __ncontinues__=_fs->_unresolvedcontinues.size()-__ncontinues__; \
+                                       if(__ncontinues__>0)ResolveContinues(_fs,__ncontinues__,continue_target); \
+                                       if(__nbreaks__>0)ResolveBreaks(_fs,__nbreaks__); \
+                                       _fs->_breaktargets.pop_back();_fs->_continuetargets.pop_back();}
+
+class SQCompiler
+{
+public:
+       SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo)
+       {
+               _vm=v;
+               _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, ...)
+       {
+               static SQChar temp[256];
+               va_list vl;
+               va_start(vl, s);
+               scvsprintf(temp, s, vl);
+               va_end(vl);
+               compilererror = temp;
+               longjmp(_errorjmp,1);
+       }
+       void Lex(){     _token = _lex.Lex();}
+       void PushExpState(){ _expstates.push_back(ExpState()); }
+       bool IsDerefToken(SQInteger tok)
+       {
+               switch(tok){
+               case _SC('='): case _SC('('): case TK_NEWSLOT:
+               case TK_MODEQ: case TK_MULEQ: case TK_DIVEQ: case TK_MINUSEQ: case TK_PLUSEQ: case TK_PLUSPLUS: case TK_MINUSMINUS: return true;
+               }
+               return false;
+       }
+       ExpState PopExpState()
+       {
+               ExpState ret = _expstates.top();
+               _expstates.pop_back();
+               return ret;
+       }
+       SQObject Expect(SQInteger tok)
+       {
+
+               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:
+                                               etypename = _SC("IDENTIFIER");
+                                               break;
+                                       case TK_STRING_LITERAL:
+                                               etypename = _SC("STRING_LITERAL");
+                                               break;
+                                       case TK_INTEGER:
+                                               etypename = _SC("INTEGER");
+                                               break;
+                                       case TK_FLOAT:
+                                               etypename = _SC("FLOAT");
+                                               break;
+                                       default:
+                                               etypename = _lex.Tok2Str(tok);
+                                       }
+                                       Error(_SC("expected '%s'"), etypename);
+                               }
+                               Error(_SC("expected '%c'"), tok);
+                       }
+               }
+               SQObjectPtr ret;
+               switch(tok)
+               {
+               case TK_IDENTIFIER:
+                       ret = _fs->CreateString(_lex._svalue);
+                       break;
+               case TK_STRING_LITERAL:
+                       ret = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1);
+                       break;
+               case TK_INTEGER:
+                       ret = SQObjectPtr(_lex._nvalue);
+                       break;
+               case TK_FLOAT:
+                       ret = SQObjectPtr(_lex._fvalue);
+                       break;
+               }
+               Lex();
+               return ret;
+       }
+       bool IsEndOfStatement() { return ((_lex._prevtoken == _SC('\n')) || (_token == SQUIRREL_EOB) || (_token == _SC('}')) || (_token == _SC(';'))); }
+       void OptionalSemicolon()
+       {
+               if(_token == _SC(';')) { Lex(); return; }
+               if(!IsEndOfStatement()) {
+                       Error(_SC("end of statement expected (; or lf)"));
+               }
+       }
+       void MoveIfCurrentTargetIsLocal() {
+               SQInteger trg = _fs->TopTarget();
+               if(_fs->IsLocal(trg)) {
+                       trg = _fs->PopTarget(); //no pops the target and move it
+                       _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), trg);
+               }
+       }
+       bool Compile(SQObjectPtr &o)
+       {
+               _debugline = 1;
+               _debugop = 0;
+
+               SQFuncState funcstate(_ss(_vm), NULL,ThrowError,this);
+               funcstate._name = SQString::Create(_ss(_vm), _SC("main"));
+               _fs = &funcstate;
+               _fs->AddParameter(_fs->CreateString(_SC("this")));
+               _fs->_sourcename = _sourcename;
+               SQInteger stacksize = _fs->GetStackSize();
+               if(setjmp(_errorjmp) == 0) {
+                       Lex();
+                       while(_token > 0){
+                               Statement();
+                               if(_lex._prevtoken != _SC('}')) OptionalSemicolon();
+                       }
+                       CleanStack(stacksize);
+                       _fs->AddLineInfos(_lex._currentline, _lineinfo, true);
+                       _fs->AddInstruction(_OP_RETURN, 0xFF);
+                       _fs->SetStackSize(0);
+                       o =_fs->BuildProto();
+#ifdef _DEBUG_DUMP
+                       _fs->Dump(_funcproto(o));
+#endif
+               }
+               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), compilererror, -1);
+                       return false;
+               }
+               return true;
+       }
+       void Statements()
+       {
+               while(_token != _SC('}') && _token != TK_DEFAULT && _token != TK_CASE) {
+                       Statement();
+                       if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon();
+               }
+       }
+       void Statement()
+       {
+               _fs->AddLineInfos(_lex._currentline, _lineinfo);
+               switch(_token){
+               case _SC(';'):  Lex();                                  break;
+               case TK_IF:             IfStatement();                  break;
+               case TK_WHILE:          WhileStatement();               break;
+               case TK_DO:             DoWhileStatement();             break;
+               case TK_FOR:            ForStatement();                 break;
+               case TK_FOREACH:        ForEachStatement();             break;
+               case TK_SWITCH: SwitchStatement();              break;
+               case TK_LOCAL:          LocalDeclStatement();   break;
+               case TK_RETURN:
+               case TK_YIELD: {
+                       SQOpcode op;
+                       if(_token == TK_RETURN) {
+                               op = _OP_RETURN;
+
+                       }
+                       else {
+                               op = _OP_YIELD;
+                               _fs->_bgenerator = true;
+                       }
+                       Lex();
+                       if(!IsEndOfStatement()) {
+                               SQInteger retexp = _fs->GetCurrentPos()+1;
+                               CommaExpr();
+                               if(op == _OP_RETURN && _fs->_traps > 0)
+                                       _fs->AddInstruction(_OP_POPTRAP, _fs->_traps, 0);
+                               _fs->_returnexp = retexp;
+                               _fs->AddInstruction(op, 1, _fs->PopTarget());
+                       }
+                       else{
+                               if(op == _OP_RETURN && _fs->_traps > 0)
+                                       _fs->AddInstruction(_OP_POPTRAP, _fs->_traps ,0);
+                               _fs->_returnexp = -1;
+                               _fs->AddInstruction(op, 0xFF);
+                       }
+                       break;}
+               case TK_BREAK:
+                       if(_fs->_breaktargets.size() <= 0)Error(_SC("'break' has to be in a loop block"));
+                       if(_fs->_breaktargets.top() > 0){
+                               _fs->AddInstruction(_OP_POPTRAP, _fs->_breaktargets.top(), 0);
+                       }
+                       _fs->AddInstruction(_OP_JMP, 0, -1234);
+                       _fs->_unresolvedbreaks.push_back(_fs->GetCurrentPos());
+                       Lex();
+                       break;
+               case TK_CONTINUE:
+                       if(_fs->_continuetargets.size() <= 0)Error(_SC("'continue' has to be in a loop block"));
+                       if(_fs->_continuetargets.top() > 0) {
+                               _fs->AddInstruction(_OP_POPTRAP, _fs->_continuetargets.top(), 0);
+                       }
+                       _fs->AddInstruction(_OP_JMP, 0, -1234);
+                       _fs->_unresolvedcontinues.push_back(_fs->GetCurrentPos());
+                       Lex();
+                       break;
+               case TK_FUNCTION:
+                       FunctionStatement();
+                       break;
+               case TK_CLASS:
+                       ClassStatement();
+                       break;
+               case _SC('{'):{
+                               SQInteger stacksize = _fs->GetStackSize();
+                               Lex();
+                               Statements();
+                               Expect(_SC('}'));
+                               _fs->SetStackSize(stacksize);
+                       }
+                       break;
+               case TK_TRY:
+                       TryCatchStatement();
+                       break;
+               case TK_THROW:
+                       Lex();
+                       CommaExpr();
+                       _fs->AddInstruction(_OP_THROW, _fs->PopTarget());
+                       break;
+               default:
+                       CommaExpr();
+                       _fs->PopTarget();
+                       break;
+               }
+               _fs->SnoozeOpt();
+       }
+       void EmitDerefOp(SQOpcode op)
+       {
+               SQInteger val = _fs->PopTarget();
+               SQInteger key = _fs->PopTarget();
+               SQInteger src = _fs->PopTarget();
+        _fs->AddInstruction(op,_fs->PushTarget(),src,key,val);
+       }
+       void Emit2ArgsOP(SQOpcode op, SQInteger p3 = 0)
+       {
+               SQInteger p2 = _fs->PopTarget(); //src in OP_GET
+               SQInteger p1 = _fs->PopTarget(); //key in OP_GET
+               _fs->AddInstruction(op,_fs->PushTarget(), p1, p2, p3);
+       }
+       void EmitCompoundArith(SQInteger tok,bool deref)
+       {
+               SQInteger oper;
+               switch(tok){
+               case TK_MINUSEQ: oper = '-'; break;
+               case TK_PLUSEQ: oper = '+'; break;
+               case TK_MULEQ: oper = '*'; break;
+               case TK_DIVEQ: oper = '/'; break;
+               case TK_MODEQ: oper = '%'; break;
+               default: oper = 0; //shut up compiler
+                       assert(0); break;
+               };
+               if(deref) {
+                       SQInteger val = _fs->PopTarget();
+                       SQInteger key = _fs->PopTarget();
+                       SQInteger src = _fs->PopTarget();
+                       //mixes dest obj and source val in the arg1(hack?)
+                       _fs->AddInstruction(_OP_COMPARITH,_fs->PushTarget(),(src<<16)|val,key,oper);
+               }
+               else {
+                       Emit2ArgsOP(_OP_COMPARITHL, oper);
+               }
+       }
+       void CommaExpr()
+       {
+               for(Expression();_token == ',';_fs->PopTarget(), Lex(), CommaExpr());
+       }
+       ExpState Expression(bool funcarg = false)
+       {
+               PushExpState();
+               _exst._class_or_delete = false;
+               _exst._funcarg = funcarg;
+               LogicalOrExp();
+               switch(_token)  {
+               case _SC('='):
+               case TK_NEWSLOT:
+               case TK_MINUSEQ:
+               case TK_PLUSEQ:
+               case TK_MULEQ:
+               case TK_DIVEQ:
+               case TK_MODEQ:
+               {
+                               SQInteger op = _token;
+                               SQInteger ds = _exst._deref;
+                               bool freevar = _exst._freevar;
+                               if(ds == DEREF_NO_DEREF) Error(_SC("can't assign expression"));
+                               Lex(); Expression();
+
+                               switch(op){
+                               case TK_NEWSLOT:
+                                       if(freevar) Error(_SC("free variables cannot be modified"));
+                                       if(ds == DEREF_FIELD)
+                                               EmitDerefOp(_OP_NEWSLOT);
+                                       else //if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local
+                                               Error(_SC("can't 'create' a local slot"));
+                                       break;
+                               case _SC('='): //ASSIGN
+                                       if(freevar) Error(_SC("free variables cannot be modified"));
+                                       if(ds == DEREF_FIELD)
+                                               EmitDerefOp(_OP_SET);
+                                       else {//if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local
+                                               SQInteger p2 = _fs->PopTarget(); //src in OP_GET
+                                               SQInteger p1 = _fs->TopTarget(); //key in OP_GET
+                                               _fs->AddInstruction(_OP_MOVE, p1, p2);
+                                       }
+                                       break;
+                               case TK_MINUSEQ:
+                               case TK_PLUSEQ:
+                               case TK_MULEQ:
+                               case TK_DIVEQ:
+                               case TK_MODEQ:
+                                       EmitCompoundArith(op,ds == DEREF_FIELD);
+                                       break;
+                               }
+                       }
+                       break;
+               case _SC('?'): {
+                       Lex();
+                       _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
+                       SQInteger jzpos = _fs->GetCurrentPos();
+                       SQInteger trg = _fs->PushTarget();
+                       Expression();
+                       SQInteger first_exp = _fs->PopTarget();
+                       if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
+                       SQInteger endfirstexp = _fs->GetCurrentPos();
+                       _fs->AddInstruction(_OP_JMP, 0, 0);
+                       Expect(_SC(':'));
+                       SQInteger jmppos = _fs->GetCurrentPos();
+                       Expression();
+                       SQInteger second_exp = _fs->PopTarget();
+                       if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
+                       _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos);
+                       _fs->SetIntructionParam(jzpos, 1, endfirstexp - jzpos + 1);
+                       _fs->SnoozeOpt();
+                       }
+                       break;
+               }
+               return PopExpState();
+       }
+       void BIN_EXP(SQOpcode op, void (SQCompiler::*f)(void),SQInteger op3 = 0)
+       {
+               Lex(); (this->*f)();
+               SQInteger op1 = _fs->PopTarget();SQInteger op2 = _fs->PopTarget();
+               _fs->AddInstruction(op, _fs->PushTarget(), op1, op2, op3);
+       }
+       void LogicalOrExp()
+       {
+               LogicalAndExp();
+               for(;;) if(_token == TK_OR) {
+                       SQInteger first_exp = _fs->PopTarget();
+                       SQInteger trg = _fs->PushTarget();
+                       _fs->AddInstruction(_OP_OR, trg, 0, first_exp, 0);
+                       SQInteger jpos = _fs->GetCurrentPos();
+                       if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
+                       Lex(); LogicalOrExp();
+                       _fs->SnoozeOpt();
+                       SQInteger second_exp = _fs->PopTarget();
+                       if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
+                       _fs->SnoozeOpt();
+                       _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));
+                       break;
+               }else return;
+       }
+       void LogicalAndExp()
+       {
+               BitwiseOrExp();
+               for(;;) switch(_token) {
+               case TK_AND: {
+                       SQInteger first_exp = _fs->PopTarget();
+                       SQInteger trg = _fs->PushTarget();
+                       _fs->AddInstruction(_OP_AND, trg, 0, first_exp, 0);
+                       SQInteger jpos = _fs->GetCurrentPos();
+                       if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
+                       Lex(); LogicalAndExp();
+                       _fs->SnoozeOpt();
+                       SQInteger second_exp = _fs->PopTarget();
+                       if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
+                       _fs->SnoozeOpt();
+                       _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));
+                       break;
+                       }
+               case TK_IN: BIN_EXP(_OP_EXISTS, &SQCompiler::BitwiseOrExp); break;
+               case TK_INSTANCEOF: BIN_EXP(_OP_INSTANCEOF, &SQCompiler::BitwiseOrExp); break;
+               default:
+                       return;
+               }
+       }
+       void BitwiseOrExp()
+       {
+               BitwiseXorExp();
+               for(;;) if(_token == _SC('|'))
+               {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseXorExp,BW_OR);
+               }else return;
+       }
+       void BitwiseXorExp()
+       {
+               BitwiseAndExp();
+               for(;;) if(_token == _SC('^'))
+               {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseAndExp,BW_XOR);
+               }else return;
+       }
+       void BitwiseAndExp()
+       {
+               CompExp();
+               for(;;) if(_token == _SC('&'))
+               {BIN_EXP(_OP_BITW, &SQCompiler::CompExp,BW_AND);
+               }else return;
+       }
+       void CompExp()
+       {
+               ShiftExp();
+               for(;;) switch(_token) {
+               case TK_EQ: BIN_EXP(_OP_EQ, &SQCompiler::ShiftExp); break;
+               case _SC('>'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_G); break;
+               case _SC('<'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_L); break;
+               case TK_GE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_GE); break;
+               case TK_LE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_LE); break;
+               case TK_NE: BIN_EXP(_OP_NE, &SQCompiler::ShiftExp); break;
+               default: return;
+               }
+       }
+       void ShiftExp()
+       {
+               PlusExp();
+               for(;;) switch(_token) {
+               case TK_USHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_USHIFTR); break;
+               case TK_SHIFTL: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTL); break;
+               case TK_SHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTR); break;
+               default: return;
+               }
+       }
+       void PlusExp()
+       {
+               MultExp();
+               for(;;) switch(_token) {
+               case _SC('+'): case _SC('-'):
+                       BIN_EXP(_OP_ARITH, &SQCompiler::MultExp,_token); break;
+               default: return;
+               }
+       }
+
+       void MultExp()
+       {
+               PrefixedExpr();
+               for(;;) switch(_token) {
+               case _SC('*'): case _SC('/'): case _SC('%'):
+                       BIN_EXP(_OP_ARITH, &SQCompiler::PrefixedExpr,_token); break;
+               default: return;
+               }
+       }
+       //if 'pos' != -1 the previous variable is a local variable
+       void PrefixedExpr()
+       {
+               SQInteger pos = Factor();
+               for(;;) {
+                       switch(_token) {
+                       case _SC('.'): {
+                               pos = -1;
+                               Lex();
+                               if(_token == TK_PARENT) {
+                                       Lex();
+                                       if(!NeedGet())
+                                               Error(_SC("parent cannot be set"));
+                                       SQInteger src = _fs->PopTarget();
+                                       _fs->AddInstruction(_OP_GETPARENT, _fs->PushTarget(), src);
+                               }
+                               else {
+                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));
+                                       if(NeedGet()) Emit2ArgsOP(_OP_GET);
+                               }
+                               _exst._deref = DEREF_FIELD;
+                               _exst._freevar = false;
+                               }
+                               break;
+                       case _SC('['):
+                               if(_lex._prevtoken == _SC('\n')) Error(_SC("cannot brake deref/or comma needed after [exp]=exp slot declaration"));
+                               Lex(); Expression(); Expect(_SC(']'));
+                               pos = -1;
+                               if(NeedGet()) Emit2ArgsOP(_OP_GET);
+                               _exst._deref = DEREF_FIELD;
+                               _exst._freevar = false;
+                               break;
+                       case TK_MINUSMINUS:
+                       case TK_PLUSPLUS:
+                       if(_exst._deref != DEREF_NO_DEREF && !IsEndOfStatement()) {
+                               SQInteger tok = _token; Lex();
+                               if(pos < 0)
+                                       Emit2ArgsOP(_OP_PINC,tok == TK_MINUSMINUS?-1:1);
+                               else {//if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local
+                                       SQInteger src = _fs->PopTarget();
+                                       _fs->AddInstruction(_OP_PINCL, _fs->PushTarget(), src, 0, tok == TK_MINUSMINUS?-1:1);
+                               }
+
+                       }
+                       return;
+                       break;
+                       case _SC('('):
+                               {
+                               if(_exst._deref != DEREF_NO_DEREF) {
+                                       if(pos<0) {
+                                               SQInteger key = _fs->PopTarget(); //key
+                                               SQInteger table = _fs->PopTarget(); //table etc...
+                                               SQInteger closure = _fs->PushTarget();
+                                               SQInteger ttarget = _fs->PushTarget();
+                                               _fs->AddInstruction(_OP_PREPCALL, closure, key, table, ttarget);
+                                       }
+                                       else{
+                                               _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0);
+                                       }
+                               }
+                               else
+                                       _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0);
+                               _exst._deref = DEREF_NO_DEREF;
+                               Lex();
+                               FunctionCallArgs();
+                                }
+                               break;
+                       default: return;
+                       }
+               }
+       }
+       SQInteger Factor()
+       {
+               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->GetConstant(_fs->CreateString(_lex._svalue,_lex._longstr.size()-1)));
+                               Lex();
+                       }
+                       break;
+               case TK_VARGC: Lex(); _fs->AddInstruction(_OP_VARGC, _fs->PushTarget()); break;
+               case TK_VARGV: { Lex();
+                       Expect(_SC('['));
+                       Expression();
+                       Expect(_SC(']'));
+                       SQInteger src = _fs->PopTarget();
+                       _fs->AddInstruction(_OP_GETVARGV, _fs->PushTarget(), src);
+                                          }
+                       break;
+               case TK_IDENTIFIER:
+               case TK_CONSTRUCTOR:
+               case TK_THIS:{
+                       _exst._freevar = false;
+                       SQObject id;
+                               switch(_token) {
+                                       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;
+                               }
+                               SQInteger pos = -1;
+                               Lex();
+                               if((pos = _fs->GetLocalVariable(id)) == -1) {
+                                       //checks if is a free variable
+                                       if((pos = _fs->GetOuterVariable(id)) != -1) {
+                                               _exst._deref = _fs->PushTarget();
+                                               _fs->AddInstruction(_OP_LOADFREEVAR, _exst._deref ,pos);
+                                               _exst._freevar = true;
+                                       } else {
+                                               _fs->PushTarget(0);
+                                               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
+                                               if(NeedGet()) Emit2ArgsOP(_OP_GET);
+                                               _exst._deref = DEREF_FIELD;
+                                       }
+                               }
+                               else{
+                                       _fs->PushTarget(pos);
+                                       _exst._deref = pos;
+                               }
+                               return _exst._deref;
+                       }
+                       break;
+               case TK_PARENT: Lex();_fs->AddInstruction(_OP_GETPARENT, _fs->PushTarget(), 0); break;
+               case TK_DOUBLE_COLON:  // "::"
+                       _fs->AddInstruction(_OP_LOADROOTTABLE, _fs->PushTarget());
+                       _exst._deref = DEREF_FIELD;
+                       _token = _SC('.'); //hack
+                       return -1;
+                       break;
+               case TK_NULL:
+                       _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1);
+                       Lex();
+                       break;
+               case TK_INTEGER: {
+                       if((_lex._nvalue & (~0x7FFFFFFF)) == 0) { //does it fit in 32 bits?
+                               _fs->AddInstruction(_OP_LOADINT, _fs->PushTarget(),_lex._nvalue);
+                       }
+                       else {
+                               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._nvalue));
+                       }
+                       Lex();
+                                                }
+                       break;
+               case TK_FLOAT:
+                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._fvalue));
+                       Lex();
+                       break;
+               case TK_TRUE: case TK_FALSE:
+                       _fs->AddInstruction(_OP_LOADBOOL, _fs->PushTarget(),_token == TK_TRUE?1:0);
+                       Lex();
+                       break;
+               case _SC('['): {
+                               _fs->AddInstruction(_OP_NEWARRAY, _fs->PushTarget());
+                               SQInteger apos = _fs->GetCurrentPos(),key = 0;
+                               Lex();
+                               while(_token != _SC(']')) {
+                    Expression();
+                                       if(_token == _SC(',')) Lex();
+                                       SQInteger val = _fs->PopTarget();
+                                       SQInteger array = _fs->TopTarget();
+                                       _fs->AddInstruction(_OP_APPENDARRAY, array, val);
+                                       key++;
+                               }
+                               _fs->SetIntructionParam(apos, 1, key);
+                               Lex();
+                       }
+                       break;
+               case _SC('{'):{
+                       _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget());
+                       Lex();ParseTableOrClass(_SC(','));
+                                }
+                       break;
+               case TK_FUNCTION: FunctionExp(_token);break;
+               case TK_CLASS: Lex(); ClassExp();break;
+               case _SC('-'): UnaryOP(_OP_NEG); break;
+               case _SC('!'): UnaryOP(_OP_NOT); break;
+               case _SC('~'): UnaryOP(_OP_BWNOT); break;
+               case TK_TYPEOF : UnaryOP(_OP_TYPEOF); break;
+               case TK_RESUME : UnaryOP(_OP_RESUME); break;
+               case TK_CLONE : UnaryOP(_OP_CLONE); break;
+               case TK_MINUSMINUS :
+               case TK_PLUSPLUS :PrefixIncDec(_token); break;
+               case TK_DELETE : DeleteExpr(); break;
+               case TK_DELEGATE : DelegateExpr(); break;
+               case _SC('('): Lex(); CommaExpr(); Expect(_SC(')'));
+                       break;
+               default: Error(_SC("expression expected"));
+               }
+               return -1;
+       }
+       void UnaryOP(SQOpcode op)
+       {
+               Lex(); PrefixedExpr();
+               SQInteger src = _fs->PopTarget();
+               _fs->AddInstruction(op, _fs->PushTarget(), src);
+       }
+       bool NeedGet()
+       {
+               switch(_token) {
+               case _SC('='): case _SC('('): case TK_NEWSLOT: case TK_PLUSPLUS: case TK_MINUSMINUS:
+               case TK_PLUSEQ: case TK_MINUSEQ: case TK_MULEQ: case TK_DIVEQ: case TK_MODEQ:
+                       return false;
+               }
+               return (!_exst._class_or_delete) || (_exst._class_or_delete && (_token == _SC('.') || _token == _SC('[')));
+       }
+
+       void FunctionCallArgs()
+       {
+               SQInteger nargs = 1;//this
+                while(_token != _SC(')')) {
+                        Expression(true);
+                        MoveIfCurrentTargetIsLocal();
+                        nargs++;
+                        if(_token == _SC(',')){
+                                Lex();
+                                if(_token == ')') Error(_SC("expression expected, found ')'"));
+                        }
+                }
+                Lex();
+                for(SQInteger i = 0; i < (nargs - 1); i++) _fs->PopTarget();
+                SQInteger stackbase = _fs->PopTarget();
+                SQInteger closure = _fs->PopTarget();
+         _fs->AddInstruction(_OP_CALL, _fs->PushTarget(), closure, stackbase, nargs);
+       }
+       void ParseTableOrClass(SQInteger separator,SQInteger terminator = '}')
+       {
+               SQInteger tpos = _fs->GetCurrentPos(),nkeys = 0;
+
+               while(_token != terminator) {
+                       bool hasattrs = false;
+                       bool isstatic = false;
+                       //check if is an attribute
+                       if(separator == ';') {
+                               if(_token == TK_ATTR_OPEN) {
+                                       _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget()); Lex();
+                                       ParseTableOrClass(',',TK_ATTR_CLOSE);
+                                       hasattrs = true;
+                               }
+                               if(_token == TK_STATIC) {
+                                       isstatic = true;
+                                       Lex();
+                               }
+                       }
+                       switch(_token) {
+                               case TK_FUNCTION:
+                               case TK_CONSTRUCTOR:{
+                                       SQInteger tk = _token;
+                                       Lex();
+                                       SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : _fs->CreateString(_SC("constructor"));
+                                       Expect(_SC('('));
+                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
+                                       CreateFunction(id);
+                                       _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);
+                                                                 }
+                                                                 break;
+                               case _SC('['):
+                                       Lex(); CommaExpr(); Expect(_SC(']'));
+                                       Expect(_SC('=')); Expression();
+                                       break;
+                               default :
+                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));
+                                       Expect(_SC('=')); Expression();
+                       }
+
+                       if(_token == separator) Lex();//optional comma/semicolon
+                       nkeys++;
+                       SQInteger val = _fs->PopTarget();
+                       SQInteger key = _fs->PopTarget();
+                       SQInteger attrs = hasattrs ? _fs->PopTarget():-1;
+                       assert(hasattrs && attrs == key-1 || !hasattrs);
+                       unsigned char flags = (hasattrs?NEW_SLOT_ATTRIBUTES_FLAG:0)|(isstatic?NEW_SLOT_STATIC_FLAG:0);
+                       SQInteger table = _fs->TopTarget(); //<<BECAUSE OF THIS NO COMMON EMIT FUNC IS POSSIBLE
+                       _fs->AddInstruction(_OP_NEWSLOTA, flags, table, key, val);
+                       //_fs->PopTarget();
+               }
+               if(separator == _SC(',')) //hack recognizes a table from the separator
+                       _fs->SetIntructionParam(tpos, 1, nkeys);
+               Lex();
+       }
+       void LocalDeclStatement()
+       {
+               SQObject varname;
+               do {
+                       Lex(); varname = Expect(TK_IDENTIFIER);
+                       if(_token == _SC('=')) {
+                               Lex(); Expression();
+                               SQInteger src = _fs->PopTarget();
+                               SQInteger dest = _fs->PushTarget();
+                               if(dest != src) _fs->AddInstruction(_OP_MOVE, dest, src);
+                       }
+                       else{
+                               _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1);
+                       }
+                       _fs->PopTarget();
+                       _fs->PushLocalVariable(varname);
+
+               } while(_token == _SC(','));
+       }
+       void IfStatement()
+       {
+               SQInteger jmppos;
+               bool haselse = false;
+               Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
+               _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
+               SQInteger jnepos = _fs->GetCurrentPos();
+               SQInteger stacksize = _fs->GetStackSize();
+
+               Statement();
+               //
+               if(_token != _SC('}') && _token != TK_ELSE) OptionalSemicolon();
+
+               CleanStack(stacksize);
+               SQInteger endifblock = _fs->GetCurrentPos();
+               if(_token == TK_ELSE){
+                       haselse = true;
+                       stacksize = _fs->GetStackSize();
+                       _fs->AddInstruction(_OP_JMP);
+                       jmppos = _fs->GetCurrentPos();
+                       Lex();
+                       Statement(); OptionalSemicolon();
+                       CleanStack(stacksize);
+                       _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos);
+               }
+               _fs->SetIntructionParam(jnepos, 1, endifblock - jnepos + (haselse?1:0));
+       }
+       void WhileStatement()
+       {
+               SQInteger jzpos, jmppos;
+               SQInteger stacksize = _fs->GetStackSize();
+               jmppos = _fs->GetCurrentPos();
+               Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
+
+               BEGIN_BREAKBLE_BLOCK();
+               _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
+               jzpos = _fs->GetCurrentPos();
+               stacksize = _fs->GetStackSize();
+
+               Statement();
+
+               CleanStack(stacksize);
+               _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1);
+               _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos);
+
+               END_BREAKBLE_BLOCK(jmppos);
+       }
+       void DoWhileStatement()
+       {
+               Lex();
+               SQInteger jzpos = _fs->GetCurrentPos();
+               SQInteger stacksize = _fs->GetStackSize();
+               BEGIN_BREAKBLE_BLOCK()
+               Statement();
+               CleanStack(stacksize);
+               Expect(TK_WHILE);
+               SQInteger continuetrg = _fs->GetCurrentPos();
+               Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
+               _fs->AddInstruction(_OP_JNZ, _fs->PopTarget(), jzpos - _fs->GetCurrentPos() - 1);
+               END_BREAKBLE_BLOCK(continuetrg);
+       }
+       void ForStatement()
+       {
+               Lex();
+               SQInteger stacksize = _fs->GetStackSize();
+               Expect(_SC('('));
+               if(_token == TK_LOCAL) LocalDeclStatement();
+               else if(_token != _SC(';')){
+                       CommaExpr();
+                       _fs->PopTarget();
+               }
+               Expect(_SC(';'));
+               _fs->SnoozeOpt();
+               SQInteger jmppos = _fs->GetCurrentPos();
+               SQInteger jzpos = -1;
+               if(_token != _SC(';')) { CommaExpr(); _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); jzpos = _fs->GetCurrentPos(); }
+               Expect(_SC(';'));
+               _fs->SnoozeOpt();
+               SQInteger expstart = _fs->GetCurrentPos() + 1;
+               if(_token != _SC(')')) {
+                       CommaExpr();
+                       _fs->PopTarget();
+               }
+               Expect(_SC(')'));
+               _fs->SnoozeOpt();
+               SQInteger expend = _fs->GetCurrentPos();
+               SQInteger expsize = (expend - expstart) + 1;
+               SQInstructionVec exp;
+               if(expsize > 0) {
+                       for(SQInteger i = 0; i < expsize; i++)
+                               exp.push_back(_fs->GetInstruction(expstart + i));
+                       _fs->PopInstructions(expsize);
+               }
+               BEGIN_BREAKBLE_BLOCK()
+               Statement();
+               SQInteger continuetrg = _fs->GetCurrentPos();
+               if(expsize > 0) {
+                       for(SQInteger i = 0; i < expsize; i++)
+                               _fs->AddInstruction(exp[i]);
+               }
+               _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1, 0);
+               if(jzpos>  0) _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos);
+               CleanStack(stacksize);
+
+               END_BREAKBLE_BLOCK(continuetrg);
+       }
+       void ForEachStatement()
+       {
+               SQObject idxname, valname;
+               Lex(); Expect(_SC('(')); valname = Expect(TK_IDENTIFIER);
+               if(_token == _SC(',')) {
+                       idxname = valname;
+                       Lex(); valname = Expect(TK_IDENTIFIER);
+               }
+               else{
+                       idxname = _fs->CreateString(_SC("@INDEX@"));
+               }
+               Expect(TK_IN);
+
+               //save the stack size
+               SQInteger stacksize = _fs->GetStackSize();
+               //put the table in the stack(evaluate the table expression)
+               Expression(); Expect(_SC(')'));
+               SQInteger container = _fs->TopTarget();
+               //push the index local var
+               SQInteger indexpos = _fs->PushLocalVariable(idxname);
+               _fs->AddInstruction(_OP_LOADNULLS, indexpos,1);
+               //push the value local var
+               SQInteger valuepos = _fs->PushLocalVariable(valname);
+               _fs->AddInstruction(_OP_LOADNULLS, valuepos,1);
+               //push reference index
+               SQInteger itrpos = _fs->PushLocalVariable(_fs->CreateString(_SC("@ITERATOR@"))); //use invalid id to make it inaccessible
+               _fs->AddInstruction(_OP_LOADNULLS, itrpos,1);
+               SQInteger jmppos = _fs->GetCurrentPos();
+               _fs->AddInstruction(_OP_FOREACH, container, 0, indexpos);
+               SQInteger foreachpos = _fs->GetCurrentPos();
+               //generate the statement code
+               BEGIN_BREAKBLE_BLOCK()
+               Statement();
+               _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1);
+               _fs->SetIntructionParam(foreachpos, 1, _fs->GetCurrentPos() - foreachpos);
+               //restore the local variable stack(remove index,val and ref idx)
+               CleanStack(stacksize);
+               END_BREAKBLE_BLOCK(foreachpos - 1);
+       }
+       void SwitchStatement()
+       {
+               Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
+               Expect(_SC('{'));
+               SQInteger expr = _fs->TopTarget();
+               bool bfirst = true;
+               SQInteger tonextcondjmp = -1;
+               SQInteger skipcondjmp = -1;
+               SQInteger __nbreaks__ = _fs->_unresolvedbreaks.size();
+               _fs->_breaktargets.push_back(0);
+               while(_token == TK_CASE) {
+                       //_fs->AddLineInfos(_lex._currentline, _lineinfo); think about this one
+                       if(!bfirst) {
+                               _fs->AddInstruction(_OP_JMP, 0, 0);
+                               skipcondjmp = _fs->GetCurrentPos();
+                               _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp);
+                       }
+                       //condition
+                       Lex(); Expression(); Expect(_SC(':'));
+                       SQInteger trg = _fs->PopTarget();
+                       _fs->AddInstruction(_OP_EQ, trg, trg, expr);
+                       _fs->AddInstruction(_OP_JZ, trg, 0);
+                       //end condition
+                       if(skipcondjmp != -1) {
+                               _fs->SetIntructionParam(skipcondjmp, 1, (_fs->GetCurrentPos() - skipcondjmp));
+                       }
+                       tonextcondjmp = _fs->GetCurrentPos();
+                       SQInteger stacksize = _fs->GetStackSize();
+                       Statements();
+                       _fs->SetStackSize(stacksize);
+                       bfirst = false;
+               }
+               if(tonextcondjmp != -1)
+                       _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp);
+               if(_token == TK_DEFAULT) {
+               //      _fs->AddLineInfos(_lex._currentline, _lineinfo);
+                       Lex(); Expect(_SC(':'));
+                       SQInteger stacksize = _fs->GetStackSize();
+                       Statements();
+                       _fs->SetStackSize(stacksize);
+               }
+               Expect(_SC('}'));
+               _fs->PopTarget();
+               __nbreaks__ = _fs->_unresolvedbreaks.size() - __nbreaks__;
+               if(__nbreaks__ > 0)ResolveBreaks(_fs, __nbreaks__);
+               _fs->_breaktargets.pop_back();
+
+       }
+       void FunctionStatement()
+       {
+               SQObject id;
+               Lex(); id = Expect(TK_IDENTIFIER);
+               _fs->PushTarget(0);
+               _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->GetConstant(id));
+                       if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);
+               }
+               Expect(_SC('('));
+               CreateFunction(id);
+               _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);
+               EmitDerefOp(_OP_NEWSLOT);
+               _fs->PopTarget();
+       }
+       void ClassStatement()
+       {
+               ExpState es;
+               Lex(); PushExpState();
+               _exst._class_or_delete = true;
+               _exst._funcarg = false;
+               PrefixedExpr();
+               es = PopExpState();
+               if(es._deref == DEREF_NO_DEREF) Error(_SC("invalid class name"));
+               if(es._deref == DEREF_FIELD) {
+                       ClassExp();
+                       EmitDerefOp(_OP_NEWSLOT);
+                       _fs->PopTarget();
+               }
+               else Error(_SC("cannot create a class in a local with the syntax(class <local>)"));
+       }
+       void TryCatchStatement()
+       {
+               SQObject exid;
+               Lex();
+               _fs->AddInstruction(_OP_PUSHTRAP,0,0);
+               _fs->_traps++;
+               if(_fs->_breaktargets.size()) _fs->_breaktargets.top()++;
+               if(_fs->_continuetargets.size()) _fs->_continuetargets.top()++;
+               SQInteger trappos = _fs->GetCurrentPos();
+               Statement();
+               _fs->_traps--;
+               _fs->AddInstruction(_OP_POPTRAP, 1, 0);
+               if(_fs->_breaktargets.size()) _fs->_breaktargets.top()--;
+               if(_fs->_continuetargets.size()) _fs->_continuetargets.top()--;
+               _fs->AddInstruction(_OP_JMP, 0, 0);
+               SQInteger jmppos = _fs->GetCurrentPos();
+               _fs->SetIntructionParam(trappos, 1, (_fs->GetCurrentPos() - trappos));
+               Expect(TK_CATCH); Expect(_SC('(')); exid = Expect(TK_IDENTIFIER); Expect(_SC(')'));
+               SQInteger stacksize = _fs->GetStackSize();
+               SQInteger ex_target = _fs->PushLocalVariable(exid);
+               _fs->SetIntructionParam(trappos, 0, ex_target);
+               Statement();
+               _fs->SetIntructionParams(jmppos, 0, (_fs->GetCurrentPos() - jmppos), 0);
+               CleanStack(stacksize);
+       }
+       void FunctionExp(SQInteger ftype)
+       {
+               Lex(); Expect(_SC('('));
+               CreateFunction(_null_);
+               _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, ftype == TK_FUNCTION?0:1);
+       }
+       void ClassExp()
+       {
+               SQInteger base = -1;
+               SQInteger attrs = -1;
+               if(_token == TK_EXTENDS) {
+                       Lex(); Expression();
+                       base = _fs->TopTarget();
+               }
+               if(_token == TK_ATTR_OPEN) {
+                       Lex();
+                       _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget());
+                       ParseTableOrClass(_SC(','),TK_ATTR_CLOSE);
+                       attrs = _fs->TopTarget();
+               }
+               Expect(_SC('{'));
+               if(attrs != -1) _fs->PopTarget();
+               if(base != -1) _fs->PopTarget();
+               _fs->AddInstruction(_OP_CLASS, _fs->PushTarget(), base, attrs);
+               ParseTableOrClass(_SC(';'));
+       }
+       void DelegateExpr()
+       {
+               Lex(); CommaExpr();
+               Expect(_SC(':'));
+               CommaExpr();
+               SQInteger table = _fs->PopTarget(), delegate = _fs->PopTarget();
+               _fs->AddInstruction(_OP_DELEGATE, _fs->PushTarget(), table, delegate);
+       }
+       void DeleteExpr()
+       {
+               ExpState es;
+               Lex(); PushExpState();
+               _exst._class_or_delete = true;
+               _exst._funcarg = false;
+               PrefixedExpr();
+               es = PopExpState();
+               if(es._deref == DEREF_NO_DEREF) Error(_SC("can't delete an expression"));
+               if(es._deref == DEREF_FIELD) Emit2ArgsOP(_OP_DELETE);
+               else Error(_SC("cannot delete a local"));
+       }
+       void PrefixIncDec(SQInteger token)
+       {
+               ExpState es;
+               Lex(); PushExpState();
+               _exst._class_or_delete = true;
+               _exst._funcarg = false;
+               PrefixedExpr();
+               es = PopExpState();
+               if(es._deref == DEREF_FIELD) Emit2ArgsOP(_OP_INC,token == TK_MINUSMINUS?-1:1);
+               else {
+                       SQInteger src = _fs->PopTarget();
+                       _fs->AddInstruction(_OP_INCL, _fs->PushTarget(), src, 0, token == TK_MINUSMINUS?-1:1);
+               }
+       }
+       void CreateFunction(SQObject &name)
+       {
+
+               SQFuncState *funcstate = _fs->PushChildState(_ss(_vm));
+               funcstate->_name = name;
+               SQObject paramname;
+               funcstate->AddParameter(_fs->CreateString(_SC("this")));
+               funcstate->_sourcename = _sourcename;
+               while(_token!=_SC(')')) {
+                       if(_token == TK_VARPARAMS) {
+                               funcstate->_varparams = true;
+                               Lex();
+                               if(_token != _SC(')')) Error(_SC("expected ')'"));
+                               break;
+                       }
+                       else {
+                               paramname = Expect(TK_IDENTIFIER);
+                               funcstate->AddParameter(paramname);
+                               if(_token == _SC(',')) Lex();
+                               else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));
+                       }
+               }
+               Expect(_SC(')'));
+               //outer values
+               if(_token == _SC(':')) {
+                       Lex(); Expect(_SC('('));
+                       while(_token != _SC(')')) {
+                               paramname = Expect(TK_IDENTIFIER);
+                               //outers are treated as implicit local variables
+                               funcstate->AddOuterValue(paramname);
+                               if(_token == _SC(',')) Lex();
+                               else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));
+                       }
+                       Lex();
+               }
+
+               SQFuncState *currchunk = _fs;
+               _fs = funcstate;
+               Statement();
+               funcstate->AddLineInfos(_lex._prevtoken == _SC('\n')?_lex._lasttokenline:_lex._currentline, _lineinfo, true);
+        funcstate->AddInstruction(_OP_RETURN, -1);
+               funcstate->SetStackSize(0);
+               //_fs->->_stacksize = _fs->_stacksize;
+               SQFunctionProto *func = funcstate->BuildProto();
+#ifdef _DEBUG_DUMP
+               funcstate->Dump(func);
+#endif
+               _fs = currchunk;
+               _fs->_functions.push_back(func);
+               _fs->PopChildState();
+       }
+       void CleanStack(SQInteger stacksize)
+       {
+               if(_fs->GetStackSize() != stacksize)
+                       _fs->SetStackSize(stacksize);
+       }
+       void ResolveBreaks(SQFuncState *funcstate, SQInteger ntoresolve)
+       {
+               while(ntoresolve > 0) {
+                       SQInteger pos = funcstate->_unresolvedbreaks.back();
+                       funcstate->_unresolvedbreaks.pop_back();
+                       //set the jmp instruction
+                       funcstate->SetIntructionParams(pos, 0, funcstate->GetCurrentPos() - pos, 0);
+                       ntoresolve--;
+               }
+       }
+       void ResolveContinues(SQFuncState *funcstate, SQInteger ntoresolve, SQInteger targetpos)
+       {
+               while(ntoresolve > 0) {
+                       SQInteger pos = funcstate->_unresolvedcontinues.back();
+                       funcstate->_unresolvedcontinues.pop_back();
+                       //set the jmp instruction
+                       funcstate->SetIntructionParams(pos, 0, targetpos - pos, 0);
+                       ntoresolve--;
+               }
+       }
+private:
+       SQInteger _token;
+       SQFuncState *_fs;
+       SQObjectPtr _sourcename;
+       SQLexer _lex;
+       bool _lineinfo;
+       bool _raiseerror;
+       SQInteger _debugline;
+       SQInteger _debugop;
+       ExpStateVec _expstates;
+       SQChar *compilererror;
+       jmp_buf _errorjmp;
+       SQVM *_vm;
+};
+
+bool Compile(SQVM *vm,SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo)
+{
+       SQCompiler p(vm, rg, up, sourcename, raiseerror, lineinfo);
+       return p.Compile(out);
+}
index ea0a831..ed2a89b 100644 (file)
@@ -1,75 +1,75 @@
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQCOMPILER_H_\r
-#define _SQCOMPILER_H_\r
-\r
-struct SQVM;\r
-\r
-#define        TK_IDENTIFIER   258\r
-#define        TK_STRING_LITERAL       259\r
-#define        TK_INTEGER      260\r
-#define        TK_FLOAT        261\r
-#define        TK_DELEGATE     262\r
-#define        TK_DELETE       263\r
-#define        TK_EQ   264\r
-#define        TK_NE   265\r
-#define        TK_LE   266\r
-#define        TK_GE   267\r
-#define        TK_SWITCH       268\r
-#define        TK_ARROW        269\r
-#define        TK_AND  270\r
-#define        TK_OR   271\r
-#define        TK_IF   272\r
-#define        TK_ELSE 273\r
-#define        TK_WHILE        274\r
-#define        TK_BREAK        275\r
-#define        TK_FOR  276\r
-#define        TK_DO   277\r
-#define        TK_NULL 278\r
-#define        TK_FOREACH      279\r
-#define        TK_IN   280\r
-#define        TK_NEWSLOT      281\r
-#define        TK_MODULO       282\r
-#define        TK_LOCAL        283\r
-#define        TK_CLONE        284\r
-#define        TK_FUNCTION     285\r
-#define        TK_RETURN       286\r
-#define        TK_TYPEOF       287\r
-#define        TK_UMINUS       288\r
-#define        TK_PLUSEQ       289\r
-#define        TK_MINUSEQ      290\r
-#define        TK_CONTINUE     291\r
-#define TK_YIELD 292\r
-#define TK_TRY 293\r
-#define TK_CATCH 294\r
-#define TK_THROW 295\r
-#define TK_SHIFTL 296\r
-#define TK_SHIFTR 297\r
-#define TK_RESUME 298\r
-#define TK_DOUBLE_COLON 299\r
-#define TK_CASE 300\r
-#define TK_DEFAULT 301\r
-#define TK_THIS 302\r
-#define TK_PLUSPLUS 303\r
-#define TK_MINUSMINUS 304\r
-#define TK_PARENT 305\r
-#define TK_USHIFTR 306\r
-#define TK_CLASS 307\r
-#define TK_EXTENDS 308\r
-#define TK_CONSTRUCTOR 310\r
-#define TK_INSTANCEOF 311\r
-#define TK_VARPARAMS 312\r
-#define TK_VARGC 313\r
-#define TK_VARGV 314\r
-#define TK_TRUE 315\r
-#define TK_FALSE 316\r
-#define TK_MULEQ 317\r
-#define TK_DIVEQ 318\r
-#define TK_MODEQ 319\r
-#define TK_ATTR_OPEN 320\r
-#define TK_ATTR_CLOSE 321\r
-#define TK_STATIC 322\r
-\r
-\r
-typedef void(*CompilerErrorFunc)(void *ud, const SQChar *s);\r
-bool Compile(SQVM *vm, SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo);\r
-#endif //_SQCOMPILER_H_\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQCOMPILER_H_
+#define _SQCOMPILER_H_
+
+struct SQVM;
+
+#define        TK_IDENTIFIER   258
+#define        TK_STRING_LITERAL       259
+#define        TK_INTEGER      260
+#define        TK_FLOAT        261
+#define        TK_DELEGATE     262
+#define        TK_DELETE       263
+#define        TK_EQ   264
+#define        TK_NE   265
+#define        TK_LE   266
+#define        TK_GE   267
+#define        TK_SWITCH       268
+#define        TK_ARROW        269
+#define        TK_AND  270
+#define        TK_OR   271
+#define        TK_IF   272
+#define        TK_ELSE 273
+#define        TK_WHILE        274
+#define        TK_BREAK        275
+#define        TK_FOR  276
+#define        TK_DO   277
+#define        TK_NULL 278
+#define        TK_FOREACH      279
+#define        TK_IN   280
+#define        TK_NEWSLOT      281
+#define        TK_MODULO       282
+#define        TK_LOCAL        283
+#define        TK_CLONE        284
+#define        TK_FUNCTION     285
+#define        TK_RETURN       286
+#define        TK_TYPEOF       287
+#define        TK_UMINUS       288
+#define        TK_PLUSEQ       289
+#define        TK_MINUSEQ      290
+#define        TK_CONTINUE     291
+#define TK_YIELD 292
+#define TK_TRY 293
+#define TK_CATCH 294
+#define TK_THROW 295
+#define TK_SHIFTL 296
+#define TK_SHIFTR 297
+#define TK_RESUME 298
+#define TK_DOUBLE_COLON 299
+#define TK_CASE 300
+#define TK_DEFAULT 301
+#define TK_THIS 302
+#define TK_PLUSPLUS 303
+#define TK_MINUSMINUS 304
+#define TK_PARENT 305
+#define TK_USHIFTR 306
+#define TK_CLASS 307
+#define TK_EXTENDS 308
+#define TK_CONSTRUCTOR 310
+#define TK_INSTANCEOF 311
+#define TK_VARPARAMS 312
+#define TK_VARGC 313
+#define TK_VARGV 314
+#define TK_TRUE 315
+#define TK_FALSE 316
+#define TK_MULEQ 317
+#define TK_DIVEQ 318
+#define TK_MODEQ 319
+#define TK_ATTR_OPEN 320
+#define TK_ATTR_CLOSE 321
+#define TK_STATIC 322
+
+
+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 732bd01..96da72d 100644 (file)
@@ -1,99 +1,99 @@
-/*\r
-       see copyright notice in squirrel.h\r
-*/\r
-#include "sqpcheader.h"\r
-#include <stdarg.h>\r
-#include "sqvm.h"\r
-#include "sqfuncproto.h"\r
-#include "sqclosure.h"\r
-#include "sqstring.h"\r
-\r
-SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si)\r
-{\r
-       SQInteger cssize = v->_callsstack.size();\r
-       if (cssize > level) {\r
-               memset(si, 0, sizeof(SQStackInfos));\r
-               SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];\r
-               switch (type(ci._closure)) {\r
-               case OT_CLOSURE:{\r
-                       SQFunctionProto *func = _funcproto(_closure(ci._closure)->_function);\r
-                       if (type(func->_name) == OT_STRING)\r
-                               si->funcname = _stringval(func->_name);\r
-                       if (type(func->_sourcename) == OT_STRING)\r
-                               si->source = _stringval(func->_sourcename);\r
-                       si->line = func->GetLine(ci._ip);\r
-                                               }\r
-                       break;\r
-               case OT_NATIVECLOSURE:\r
-                       si->source = _SC("NATIVE");\r
-                       si->funcname = _SC("unknown");\r
-                       if(type(_nativeclosure(ci._closure)->_name) == OT_STRING)\r
-                               si->funcname = _stringval(_nativeclosure(ci._closure)->_name);\r
-                       si->line = -1;\r
-                       break;\r
-               default: break; //shutup compiler\r
-               }\r
-               return SQ_OK;\r
-       }\r
-       return SQ_ERROR;\r
-}\r
-\r
-void SQVM::Raise_Error(const SQChar *s, ...)\r
-{\r
-       va_list vl;\r
-       va_start(vl, s);\r
-       scvsprintf(_sp(rsl((SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2))), s, vl);\r
-       va_end(vl);\r
-       _lasterror = SQString::Create(_ss(this),_spval,-1);\r
-}\r
-\r
-void SQVM::Raise_Error(SQObjectPtr &desc)\r
-{\r
-       _lasterror = desc;\r
-}\r
-\r
-SQString *SQVM::PrintObjVal(const SQObject &o)\r
-{\r
-       switch(type(o)) {\r
-       case OT_STRING: return _string(o);\r
-       case OT_INTEGER:\r
-               scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%d"), _integer(o));\r
-               return SQString::Create(_ss(this), _spval);\r
-               break;\r
-       case OT_FLOAT:\r
-               scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%.14g"), _float(o));\r
-               return SQString::Create(_ss(this), _spval);\r
-               break;\r
-       default:\r
-               return SQString::Create(_ss(this), GetTypeName(o));\r
-       }\r
-}\r
-\r
-void SQVM::Raise_IdxError(SQObject &o)\r
-{\r
-       SQObjectPtr oval = PrintObjVal(o);\r
-       Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval));\r
-}\r
-\r
-void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2)\r
-{\r
-       SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2);\r
-       Raise_Error(_SC("comparsion between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2));\r
-}\r
-\r
-\r
-void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type)\r
-{\r
-       SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1);\r
-       SQInteger found = 0;    \r
-       for(SQInteger i=0; i<16; i++)\r
-       {\r
-               SQInteger mask = 0x00000001 << i;\r
-               if(typemask & (mask)) {\r
-                       if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes);\r
-                       found ++;\r
-                       StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes);\r
-               }\r
-       }\r
-       Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes));\r
-}\r
+/*
+       see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include <stdarg.h>
+#include "sqvm.h"
+#include "sqfuncproto.h"
+#include "sqclosure.h"
+#include "sqstring.h"
+
+SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si)
+{
+       SQInteger cssize = v->_callsstack.size();
+       if (cssize > level) {
+               memset(si, 0, sizeof(SQStackInfos));
+               SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];
+               switch (type(ci._closure)) {
+               case OT_CLOSURE:{
+                       SQFunctionProto *func = _funcproto(_closure(ci._closure)->_function);
+                       if (type(func->_name) == OT_STRING)
+                               si->funcname = _stringval(func->_name);
+                       if (type(func->_sourcename) == OT_STRING)
+                               si->source = _stringval(func->_sourcename);
+                       si->line = func->GetLine(ci._ip);
+                                               }
+                       break;
+               case OT_NATIVECLOSURE:
+                       si->source = _SC("NATIVE");
+                       si->funcname = _SC("unknown");
+                       if(type(_nativeclosure(ci._closure)->_name) == OT_STRING)
+                               si->funcname = _stringval(_nativeclosure(ci._closure)->_name);
+                       si->line = -1;
+                       break;
+               default: break; //shutup compiler
+               }
+               return SQ_OK;
+       }
+       return SQ_ERROR;
+}
+
+void SQVM::Raise_Error(const SQChar *s, ...)
+{
+       va_list vl;
+       va_start(vl, s);
+       scvsprintf(_sp(rsl((SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2))), s, vl);
+       va_end(vl);
+       _lasterror = SQString::Create(_ss(this),_spval,-1);
+}
+
+void SQVM::Raise_Error(SQObjectPtr &desc)
+{
+       _lasterror = desc;
+}
+
+SQString *SQVM::PrintObjVal(const SQObject &o)
+{
+       switch(type(o)) {
+       case OT_STRING: return _string(o);
+       case OT_INTEGER:
+               scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%d"), _integer(o));
+               return SQString::Create(_ss(this), _spval);
+               break;
+       case OT_FLOAT:
+               scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%.14g"), _float(o));
+               return SQString::Create(_ss(this), _spval);
+               break;
+       default:
+               return SQString::Create(_ss(this), GetTypeName(o));
+       }
+}
+
+void SQVM::Raise_IdxError(SQObject &o)
+{
+       SQObjectPtr oval = PrintObjVal(o);
+       Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval));
+}
+
+void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2)
+{
+       SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2);
+       Raise_Error(_SC("comparsion between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2));
+}
+
+
+void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type)
+{
+       SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1);
+       SQInteger found = 0;
+       for(SQInteger i=0; i<16; i++)
+       {
+               SQInteger mask = 0x00000001 << i;
+               if(typemask & (mask)) {
+                       if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes);
+                       found ++;
+                       StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes);
+               }
+       }
+       Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes));
+}
index b4079b0..6444fbf 100644 (file)
@@ -1,88 +1,88 @@
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQFUNCTION_H_\r
-#define _SQFUNCTION_H_\r
-\r
-#include "sqopcodes.h"\r
-\r
-enum SQOuterType {\r
-       otLOCAL = 0,\r
-       otSYMBOL = 1,\r
-       otOUTER = 2\r
-};\r
-\r
-struct SQOuterVar\r
-{\r
-       \r
-       SQOuterVar(){}\r
-       SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t)\r
-       {\r
-               _name = name;\r
-               _src=src;\r
-               _type=t;\r
-       }\r
-       SQOuterVar(const SQOuterVar &ov)\r
-       {\r
-               _type=ov._type;\r
-               _src=ov._src;\r
-               _name=ov._name;\r
-       }\r
-       SQOuterType _type;\r
-       SQObjectPtr _name;\r
-       SQObjectPtr _src;\r
-};\r
-\r
-struct SQLocalVarInfo\r
-{\r
-       SQLocalVarInfo():_start_op(0),_end_op(0){}\r
-       SQLocalVarInfo(const SQLocalVarInfo &lvi)\r
-       {\r
-               _name=lvi._name;\r
-               _start_op=lvi._start_op;\r
-               _end_op=lvi._end_op;\r
-               _pos=lvi._pos;\r
-       }\r
-       SQObjectPtr _name;\r
-       SQUnsignedInteger _start_op;\r
-       SQUnsignedInteger _end_op;\r
-       SQUnsignedInteger _pos;\r
-};\r
-\r
-struct SQLineInfo { SQInteger _line;SQInteger _op; };\r
-\r
-typedef sqvector<SQOuterVar> SQOuterVarVec;\r
-typedef sqvector<SQLocalVarInfo> SQLocalVarInfoVec;\r
-typedef sqvector<SQLineInfo> SQLineInfoVec;\r
-\r
-struct SQFunctionProto : public SQRefCounted\r
-{\r
-private:\r
-       SQFunctionProto(){\r
-       _stacksize=0;\r
-       _bgenerator=false;}\r
-public:\r
-       static SQFunctionProto *Create()\r
-       {\r
-               SQFunctionProto *f;\r
-               sq_new(f,SQFunctionProto);\r
-               return f;\r
-       }\r
-       void Release(){ sq_delete(this,SQFunctionProto);}\r
-       const SQChar* GetLocal(SQVM *v,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop);\r
-       SQInteger GetLine(SQInstruction *curr);\r
-       bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);\r
-       bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read);\r
-       SQObjectPtrVec _literals;\r
-       SQObjectPtrVec _functions;\r
-       SQObjectPtrVec _parameters;\r
-       SQOuterVarVec _outervalues;\r
-       SQInstructionVec _instructions;\r
-       SQObjectPtr _sourcename;\r
-       SQObjectPtr _name;\r
-       SQLocalVarInfoVec _localvarinfos;\r
-       SQLineInfoVec _lineinfos;\r
-    SQInteger _stacksize;\r
-       bool _bgenerator;\r
-       bool _varparams;\r
-};\r
-\r
-#endif //_SQFUNCTION_H_\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQFUNCTION_H_
+#define _SQFUNCTION_H_
+
+#include "sqopcodes.h"
+
+enum SQOuterType {
+       otLOCAL = 0,
+       otSYMBOL = 1,
+       otOUTER = 2
+};
+
+struct SQOuterVar
+{
+
+       SQOuterVar(){}
+       SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t)
+       {
+               _name = name;
+               _src=src;
+               _type=t;
+       }
+       SQOuterVar(const SQOuterVar &ov)
+       {
+               _type=ov._type;
+               _src=ov._src;
+               _name=ov._name;
+       }
+       SQOuterType _type;
+       SQObjectPtr _name;
+       SQObjectPtr _src;
+};
+
+struct SQLocalVarInfo
+{
+       SQLocalVarInfo():_start_op(0),_end_op(0){}
+       SQLocalVarInfo(const SQLocalVarInfo &lvi)
+       {
+               _name=lvi._name;
+               _start_op=lvi._start_op;
+               _end_op=lvi._end_op;
+               _pos=lvi._pos;
+       }
+       SQObjectPtr _name;
+       SQUnsignedInteger _start_op;
+       SQUnsignedInteger _end_op;
+       SQUnsignedInteger _pos;
+};
+
+struct SQLineInfo { SQInteger _line;SQInteger _op; };
+
+typedef sqvector<SQOuterVar> SQOuterVarVec;
+typedef sqvector<SQLocalVarInfo> SQLocalVarInfoVec;
+typedef sqvector<SQLineInfo> SQLineInfoVec;
+
+struct SQFunctionProto : public SQRefCounted
+{
+private:
+       SQFunctionProto(){
+       _stacksize=0;
+       _bgenerator=false;}
+public:
+       static SQFunctionProto *Create()
+       {
+               SQFunctionProto *f;
+               sq_new(f,SQFunctionProto);
+               return f;
+       }
+       void Release(){ sq_delete(this,SQFunctionProto);}
+       const SQChar* GetLocal(SQVM *v,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop);
+       SQInteger GetLine(SQInstruction *curr);
+       bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
+       bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read);
+       SQObjectPtrVec _literals;
+       SQObjectPtrVec _functions;
+       SQObjectPtrVec _parameters;
+       SQOuterVarVec _outervalues;
+       SQInstructionVec _instructions;
+       SQObjectPtr _sourcename;
+       SQObjectPtr _name;
+       SQLocalVarInfoVec _localvarinfos;
+       SQLineInfoVec _lineinfos;
+    SQInteger _stacksize;
+       bool _bgenerator;
+       bool _varparams;
+};
+
+#endif //_SQFUNCTION_H_
index b986707..2ceb1b4 100644 (file)
-/*\r
-       see copyright notice in squirrel.h\r
-*/\r
-#include "sqpcheader.h"\r
-#include "sqcompiler.h"\r
-#include "sqfuncproto.h"\r
-#include "sqstring.h"\r
-#include "sqtable.h"\r
-#include "sqopcodes.h"\r
-#include "sqfuncstate.h"\r
-\r
-#ifdef _DEBUG_DUMP\r
-SQInstructionDesc g_InstrDesc[]={\r
-       {_SC("_OP_LINE")},\r
-       {_SC("_OP_LOAD")},\r
-       {_SC("_OP_LOADINT")},\r
-       {_SC("_OP_DLOAD")},\r
-       {_SC("_OP_TAILCALL")},\r
-       {_SC("_OP_CALL")},\r
-       {_SC("_OP_PREPCALL")},\r
-       {_SC("_OP_PREPCALLK")},\r
-       {_SC("_OP_GETK")},\r
-       {_SC("_OP_MOVE")},\r
-       {_SC("_OP_NEWSLOT")},\r
-       {_SC("_OP_DELETE")},\r
-       {_SC("_OP_SET")},\r
-       {_SC("_OP_GET")},\r
-       {_SC("_OP_EQ")},\r
-       {_SC("_OP_NE")},\r
-       {_SC("_OP_ARITH")},\r
-       {_SC("_OP_BITW")},\r
-       {_SC("_OP_RETURN")},\r
-       {_SC("_OP_LOADNULLS")},\r
-       {_SC("_OP_LOADROOTTABLE")},\r
-       {_SC("_OP_LOADBOOL")},\r
-       {_SC("_OP_DMOVE")},\r
-       {_SC("_OP_JMP")},\r
-       {_SC("_OP_JNZ")},\r
-       {_SC("_OP_JZ")},\r
-       {_SC("_OP_LOADFREEVAR")},\r
-       {_SC("_OP_VARGC")},\r
-       {_SC("_OP_GETVARGV")},\r
-       {_SC("_OP_NEWTABLE")},\r
-       {_SC("_OP_NEWARRAY")},\r
-       {_SC("_OP_APPENDARRAY")},\r
-       {_SC("_OP_GETPARENT")},\r
-       {_SC("_OP_COMPARITH")},\r
-       {_SC("_OP_COMPARITHL")},\r
-       {_SC("_OP_INC")},\r
-       {_SC("_OP_INCL")},\r
-       {_SC("_OP_PINC")},\r
-       {_SC("_OP_PINCL")},\r
-       {_SC("_OP_CMP")},\r
-       {_SC("_OP_EXISTS")},\r
-       {_SC("_OP_INSTANCEOF")},\r
-       {_SC("_OP_AND")},\r
-       {_SC("_OP_OR")},\r
-       {_SC("_OP_NEG")},\r
-       {_SC("_OP_NOT")},\r
-       {_SC("_OP_BWNOT")},\r
-       {_SC("_OP_CLOSURE")},\r
-       {_SC("_OP_YIELD")},\r
-       {_SC("_OP_RESUME")},\r
-       {_SC("_OP_FOREACH")},\r
-       {_SC("_OP_DELEGATE")},\r
-       {_SC("_OP_CLONE")},\r
-       {_SC("_OP_TYPEOF")},\r
-       {_SC("_OP_PUSHTRAP")},\r
-       {_SC("_OP_POPTRAP")},\r
-       {_SC("_OP_THROW")},\r
-       {_SC("_OP_CLASS")},\r
-       {_SC("_OP_NEWSLOTA")}\r
-};\r
-#endif\r
-void DumpLiteral(SQObjectPtr &o)\r
-{\r
-       switch(type(o)){\r
-               case OT_STRING: scprintf(_SC("\"%s\""),_stringval(o));break;\r
-               case OT_FLOAT: scprintf(_SC("{%f}"),_float(o));break;\r
-               case OT_INTEGER: scprintf(_SC("{%d}"),_integer(o));break;\r
-               default: assert(0); break; //shut up compiler\r
-       }\r
-}\r
-\r
-SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed)\r
-{\r
-               _nliterals = 0;\r
-               _literals = SQTable::Create(ss,0);\r
-               _strings =  SQTable::Create(ss,0);\r
-               _sharedstate = ss;\r
-               _lastline = 0;\r
-               _optimization = true;\r
-               _parent = parent;\r
-               _stacksize = 0;\r
-               _traps = 0;\r
-               _returnexp = 0;\r
-               _varparams = false;\r
-               _errfunc = efunc;\r
-               _errtarget = ed;\r
-               _bgenerator = false;\r
-\r
-}\r
-\r
-void SQFuncState::Error(const SQChar *err)\r
-{\r
-       _errfunc(_errtarget,err);\r
-}\r
-\r
-#ifdef _DEBUG_DUMP\r
-void SQFuncState::Dump(SQFunctionProto *func)\r
-{\r
-       SQUnsignedInteger n=0,i;\r
-       scprintf(_SC("SQInstruction sizeof %d\n"),sizeof(SQInstruction));\r
-       scprintf(_SC("SQObject sizeof %d\n"),sizeof(SQObject));\r
-       scprintf(_SC("--------------------------------------------------------------------\n"));\r
-       scprintf(_SC("*****FUNCTION [%s]\n"),type(func->_name)==OT_STRING?_stringval(func->_name):_SC("unknown"));\r
-       scprintf(_SC("-----LITERALS\n"));\r
-       SQObjectPtr refidx,key,val;\r
-       SQInteger idx;\r
-       SQObjectPtrVec templiterals;\r
-       templiterals.resize(_nliterals);\r
-       while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) {\r
-               refidx=idx;\r
-               templiterals[_integer(val)]=key;\r
-       }\r
-       for(i=0;i<templiterals.size();i++){\r
-               scprintf(_SC("[%d] "),n);\r
-               DumpLiteral(templiterals[i]);\r
-               scprintf(_SC("\n"));\r
-               n++;\r
-       }\r
-       scprintf(_SC("-----PARAMS\n"));\r
-       if(_varparams)\r
-               scprintf(_SC("<<VARPARAMS>>\n"));\r
-       n=0;\r
-       for(i=0;i<_parameters.size();i++){\r
-               scprintf(_SC("[%d] "),n);\r
-               DumpLiteral(_parameters[i]);\r
-               scprintf(_SC("\n"));\r
-               n++;\r
-       }\r
-       scprintf(_SC("-----LOCALS\n"));\r
-       for(i=0;i<func->_localvarinfos.size();i++){\r
-               SQLocalVarInfo lvi=func->_localvarinfos[i];\r
-               scprintf(_SC("[%d] %s \t%d %d\n"),lvi._pos,_stringval(lvi._name),lvi._start_op,lvi._end_op);\r
-               n++;\r
-       }\r
-       scprintf(_SC("-----LINE INFO\n"));\r
-       for(i=0;i<_lineinfos.size();i++){\r
-               SQLineInfo li=_lineinfos[i];\r
-               scprintf(_SC("op [%d] line [%d] \n"),li._op,li._line);\r
-               n++;\r
-       }\r
-       scprintf(_SC("-----dump\n"));\r
-       n=0;\r
-       for(i=0;i<_instructions.size();i++){\r
-               SQInstruction &inst=_instructions[i];\r
-               if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){\r
-                       \r
-                       SQInteger lidx = inst._arg1;\r
-                       scprintf(_SC("[%03d] %15s %d "),n,g_InstrDesc[inst.op].name,inst._arg0);\r
-                       if(lidx >= 0xFFFFFFFF)\r
-                               scprintf(_SC("null"));\r
-                       else {\r
-                               SQInteger refidx;\r
-                               SQObjectPtr val,key,refo;\r
-                               while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) {\r
-                                       refo = refidx;  \r
-                               }\r
-                               DumpLiteral(key);\r
-                       }\r
-                       if(inst.op != _OP_DLOAD) {\r
-                               scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3);\r
-                       }\r
-                       else {\r
-                               scprintf(_SC(" %d "),inst._arg2);\r
-                               lidx = inst._arg3;\r
-                               if(lidx >= 0xFFFFFFFF)\r
-                                       scprintf(_SC("null"));\r
-                               else {\r
-                                       SQInteger refidx;\r
-                                       SQObjectPtr val,key,refo;\r
-                                       while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) {\r
-                                               refo = refidx;  \r
-                               }\r
-                               DumpLiteral(key);\r
-                               scprintf(_SC("\n"));\r
-                       }\r
-                       }\r
-               }\r
-               else if(inst.op==_OP_ARITH){\r
-                       scprintf(_SC("[%03d] %15s %d %d %d %c\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);\r
-               }\r
-               else \r
-                       scprintf(_SC("[%03d] %15s %d %d %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);\r
-               n++;\r
-       }\r
-       scprintf(_SC("-----\n"));\r
-       scprintf(_SC("stack size[%d]\n"),func->_stacksize);\r
-       scprintf(_SC("--------------------------------------------------------------------\n\n"));\r
-}\r
-#endif\r
-\r
-SQInteger SQFuncState::GetNumericConstant(const SQInteger cons)\r
-{\r
-       return GetConstant(SQObjectPtr(cons));\r
-}\r
-\r
-SQInteger SQFuncState::GetNumericConstant(const SQFloat cons)\r
-{\r
-       return GetConstant(SQObjectPtr(cons));\r
-}\r
-\r
-SQInteger SQFuncState::GetConstant(const SQObject &cons)\r
-{\r
-       SQObjectPtr val;\r
-       if(!_table(_literals)->Get(cons,val))\r
-       {\r
-               val = _nliterals;\r
-               _table(_literals)->NewSlot(cons,val);\r
-               _nliterals++;\r
-               if(_nliterals > MAX_LITERALS) {\r
-                       val.Null();\r
-                       Error(_SC("internal compiler error: too many literals"));\r
-               }\r
-       }\r
-       return _integer(val);\r
-}\r
-\r
-void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3)\r
-{\r
-       _instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&arg0);\r
-       _instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&arg1);\r
-       _instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&arg2);\r
-       _instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&arg3);\r
-}\r
-\r
-void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val)\r
-{\r
-       switch(arg){\r
-               case 0:_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&val);break;\r
-               case 1:case 4:_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&val);break;\r
-               case 2:_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&val);break;\r
-               case 3:_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&val);break;\r
-       };\r
-}\r
-\r
-SQInteger SQFuncState::AllocStackPos()\r
-{\r
-       SQInteger npos=_vlocals.size();\r
-       _vlocals.push_back(SQLocalVarInfo());\r
-       if(_vlocals.size()>((SQUnsignedInteger)_stacksize)) {\r
-               if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC("internal compiler error: too many locals"));\r
-               _stacksize=_vlocals.size();\r
-       }\r
-       return npos;\r
-}\r
-\r
-SQInteger SQFuncState::PushTarget(SQInteger n)\r
-{\r
-       if(n!=-1){\r
-               _targetstack.push_back(n);\r
-               return n;\r
-       }\r
-       n=AllocStackPos();\r
-       _targetstack.push_back(n);\r
-       return n;\r
-}\r
-\r
-SQInteger SQFuncState::GetUpTarget(SQInteger n){\r
-       return _targetstack[((_targetstack.size()-1)-n)];\r
-}\r
-\r
-SQInteger SQFuncState::TopTarget(){\r
-       return _targetstack.back();\r
-}\r
-SQInteger SQFuncState::PopTarget()\r
-{\r
-       SQInteger npos=_targetstack.back();\r
-       SQLocalVarInfo t=_vlocals[_targetstack.back()];\r
-       if(type(t._name)==OT_NULL){\r
-               _vlocals.pop_back();\r
-       }\r
-       _targetstack.pop_back();\r
-       return npos;\r
-}\r
-\r
-SQInteger SQFuncState::GetStackSize()\r
-{\r
-       return _vlocals.size();\r
-}\r
-\r
-void SQFuncState::SetStackSize(SQInteger n)\r
-{\r
-       SQInteger size=_vlocals.size();\r
-       while(size>n){\r
-               size--;\r
-               SQLocalVarInfo lvi=_vlocals.back();\r
-               if(type(lvi._name)!=OT_NULL){\r
-                       lvi._end_op=GetCurrentPos();\r
-                       _localvarinfos.push_back(lvi);\r
-               }\r
-               _vlocals.pop_back();\r
-       }\r
-}\r
-\r
-bool SQFuncState::IsLocal(SQUnsignedInteger stkpos)\r
-{\r
-       if(stkpos>=_vlocals.size())return false;\r
-       else if(type(_vlocals[stkpos]._name)!=OT_NULL)return true;\r
-       return false;\r
-}\r
-\r
-SQInteger SQFuncState::PushLocalVariable(const SQObject &name)\r
-{\r
-       SQInteger pos=_vlocals.size();\r
-       SQLocalVarInfo lvi;\r
-       lvi._name=name;\r
-       lvi._start_op=GetCurrentPos()+1;\r
-       lvi._pos=_vlocals.size();\r
-       _vlocals.push_back(lvi);\r
-       if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size();\r
-       \r
-       return pos;\r
-}\r
-\r
-SQInteger SQFuncState::GetLocalVariable(const SQObject &name)\r
-{\r
-       SQInteger locals=_vlocals.size();\r
-       while(locals>=1){\r
-               if(type(_vlocals[locals-1]._name)==OT_STRING && _string(_vlocals[locals-1]._name)==_string(name)){\r
-                       return locals-1;\r
-               }\r
-               locals--;\r
-       }\r
-       return -1;\r
-}\r
-\r
-SQInteger SQFuncState::GetOuterVariable(const SQObject &name)\r
-{\r
-       SQInteger outers = _outervalues.size();\r
-       for(SQInteger i = 0; i<outers; i++) {\r
-               if(_string(_outervalues[i]._name) == _string(name))\r
-                       return i;\r
-       }\r
-       return -1;\r
-}\r
-\r
-void SQFuncState::AddOuterValue(const SQObject &name)\r
-{\r
-       SQInteger pos=-1;\r
-       if(_parent) { \r
-               pos = _parent->GetLocalVariable(name);\r
-               if(pos == -1) {\r
-                       pos = _parent->GetOuterVariable(name);\r
-                       if(pos != -1) {\r
-                               _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otOUTER)); //local\r
-                               return;\r
-                       }\r
-               }\r
-               else {\r
-                       _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otLOCAL)); //local\r
-                       return;\r
-               }\r
-       }       \r
-       _outervalues.push_back(SQOuterVar(name,name,otSYMBOL)); //global\r
-}\r
-\r
-void SQFuncState::AddParameter(const SQObject &name)\r
-{\r
-       PushLocalVariable(name);\r
-       _parameters.push_back(name);\r
-}\r
-\r
-void SQFuncState::AddLineInfos(SQInteger line,bool lineop,bool force)\r
-{\r
-       if(_lastline!=line || force){\r
-               SQLineInfo li;\r
-               li._line=line;li._op=(GetCurrentPos()+1);\r
-               if(lineop)AddInstruction(_OP_LINE,0,line);\r
-               _lineinfos.push_back(li);\r
-               _lastline=line;\r
-       }\r
-}\r
-\r
-void SQFuncState::AddInstruction(SQInstruction &i)\r
-{\r
-       SQInteger size = _instructions.size();\r
-       if(size > 0 && _optimization){ //simple optimizer\r
-               SQInstruction &pi = _instructions[size-1];//previous instruction\r
-               switch(i.op) {\r
-               case _OP_RETURN:\r
-                       if( _parent && i._arg0 != MAX_FUNC_STACKSIZE && pi.op == _OP_CALL && _returnexp < size-1) {\r
-                               pi.op = _OP_TAILCALL;\r
-                       }\r
-               break;\r
-               case _OP_GET:\r
-                       if( pi.op == _OP_LOAD && pi._arg0 == i._arg2 && (!IsLocal(pi._arg0))){\r
-                               pi._arg1 = pi._arg1;\r
-                               pi._arg2 = (unsigned char)i._arg1;\r
-                               pi.op = _OP_GETK;\r
-                               pi._arg0 = i._arg0;\r
-                               \r
-                               return;\r
-                       }\r
-               break;\r
-               case _OP_PREPCALL:\r
-                       if( pi.op == _OP_LOAD  && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){\r
-                               pi.op = _OP_PREPCALLK;\r
-                               pi._arg0 = i._arg0;\r
-                               pi._arg1 = pi._arg1;\r
-                               pi._arg2 = i._arg2;\r
-                               pi._arg3 = i._arg3;\r
-                               return;\r
-                       }\r
-                       break;\r
-               case _OP_APPENDARRAY:\r
-                       if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){\r
-                               pi.op = _OP_APPENDARRAY;\r
-                               pi._arg0 = i._arg0;\r
-                               pi._arg1 = pi._arg1;\r
-                               pi._arg2 = MAX_FUNC_STACKSIZE;\r
-                               pi._arg3 = MAX_FUNC_STACKSIZE;\r
-                               return;\r
-                       }\r
-                       break;\r
-               case _OP_MOVE: \r
-                       if((pi.op == _OP_GET || pi.op == _OP_ARITH || pi.op == _OP_BITW) && (pi._arg0 == i._arg1))\r
-                       {\r
-                               pi._arg0 = i._arg0;\r
-                               _optimization = false;\r
-                               return;\r
-                       }\r
-\r
-                       if(pi.op == _OP_MOVE)\r
-                       {\r
-                               pi.op = _OP_DMOVE;\r
-                               pi._arg2 = i._arg0;\r
-                               pi._arg3 = (unsigned char)i._arg1;\r
-                               return;\r
-                       }\r
-                       break;\r
-               case _OP_LOAD:\r
-                       if(pi.op == _OP_LOAD && i._arg1 < 256) {\r
-                               pi.op = _OP_DLOAD;\r
-                               pi._arg2 = i._arg0;\r
-                               pi._arg3 = (unsigned char)i._arg1;\r
-                               return;\r
-                       }\r
-                       break;\r
-               case _OP_EQ:case _OP_NE:\r
-                       if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0) ))\r
-                       {\r
-                               pi.op = i.op;\r
-                               pi._arg0 = i._arg0;\r
-                               pi._arg1 = pi._arg1;\r
-                               pi._arg2 = i._arg2;\r
-                               pi._arg3 = MAX_FUNC_STACKSIZE;\r
-                               return;\r
-                       }\r
-                       break;\r
-               case _OP_LOADNULLS:\r
-                       if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) {\r
-                               \r
-                               pi._arg1 = pi._arg1 + 1;\r
-                               pi.op = _OP_LOADNULLS;\r
-                               return;\r
-                       }\r
-            break;\r
-               case _OP_LINE:\r
-                       if(pi.op == _OP_LINE) {\r
-                               _instructions.pop_back();\r
-                               _lineinfos.pop_back();\r
-                       }\r
-                       break;\r
-               }\r
-       }\r
-       _optimization = true;\r
-       _instructions.push_back(i);\r
-}\r
-\r
-SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len)\r
-{\r
-       SQObjectPtr ns(SQString::Create(_sharedstate,s,len));\r
-       _table(_strings)->NewSlot(ns,(SQInteger)1);\r
-       return ns;\r
-}\r
-\r
-SQFunctionProto *SQFuncState::BuildProto()\r
-{\r
-       SQFunctionProto *f=SQFunctionProto::Create();\r
-       f->_literals.resize(_nliterals);\r
-       SQObjectPtr refidx,key,val;\r
-       SQInteger idx;\r
-\r
-       f->_stacksize = _stacksize;\r
-       f->_sourcename = _sourcename;\r
-       f->_bgenerator = _bgenerator;\r
-       f->_name = _name;\r
-\r
-       while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) {\r
-               f->_literals[_integer(val)]=key;\r
-               refidx=idx;\r
-       }\r
-\r
-       f->_functions.resize(_functions.size());\r
-       f->_functions.copy(_functions);\r
-       f->_parameters.resize(_parameters.size());\r
-       f->_parameters.copy(_parameters);\r
-       f->_outervalues.resize(_outervalues.size());\r
-       f->_outervalues.copy(_outervalues);\r
-       f->_instructions.resize(_instructions.size());\r
-       f->_instructions.copy(_instructions);\r
-       f->_localvarinfos.resize(_localvarinfos.size());\r
-       f->_localvarinfos.copy(_localvarinfos);\r
-       f->_lineinfos.resize(_lineinfos.size());\r
-       f->_lineinfos.copy(_lineinfos);\r
-       f->_varparams = _varparams;\r
-\r
-       return f;\r
-}\r
-\r
-SQFuncState *SQFuncState::PushChildState(SQSharedState *ss)\r
-{\r
-       SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState));\r
-       new (child) SQFuncState(ss,this,_errfunc,_errtarget);\r
-       _childstates.push_back(child);\r
-       return child;\r
-}\r
-\r
-void SQFuncState::PopChildState()\r
-{\r
-       SQFuncState *child = _childstates.back();\r
-       sq_delete(child,SQFuncState);\r
-       _childstates.pop_back();\r
-}\r
-\r
-SQFuncState::~SQFuncState()\r
-{\r
-       while(_childstates.size() > 0)\r
-       {\r
-               PopChildState();\r
-       }\r
-}\r
+/*
+       see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include "sqcompiler.h"
+#include "sqfuncproto.h"
+#include "sqstring.h"
+#include "sqtable.h"
+#include "sqopcodes.h"
+#include "sqfuncstate.h"
+
+#ifdef _DEBUG_DUMP
+SQInstructionDesc g_InstrDesc[]={
+       {_SC("_OP_LINE")},
+       {_SC("_OP_LOAD")},
+       {_SC("_OP_LOADINT")},
+       {_SC("_OP_DLOAD")},
+       {_SC("_OP_TAILCALL")},
+       {_SC("_OP_CALL")},
+       {_SC("_OP_PREPCALL")},
+       {_SC("_OP_PREPCALLK")},
+       {_SC("_OP_GETK")},
+       {_SC("_OP_MOVE")},
+       {_SC("_OP_NEWSLOT")},
+       {_SC("_OP_DELETE")},
+       {_SC("_OP_SET")},
+       {_SC("_OP_GET")},
+       {_SC("_OP_EQ")},
+       {_SC("_OP_NE")},
+       {_SC("_OP_ARITH")},
+       {_SC("_OP_BITW")},
+       {_SC("_OP_RETURN")},
+       {_SC("_OP_LOADNULLS")},
+       {_SC("_OP_LOADROOTTABLE")},
+       {_SC("_OP_LOADBOOL")},
+       {_SC("_OP_DMOVE")},
+       {_SC("_OP_JMP")},
+       {_SC("_OP_JNZ")},
+       {_SC("_OP_JZ")},
+       {_SC("_OP_LOADFREEVAR")},
+       {_SC("_OP_VARGC")},
+       {_SC("_OP_GETVARGV")},
+       {_SC("_OP_NEWTABLE")},
+       {_SC("_OP_NEWARRAY")},
+       {_SC("_OP_APPENDARRAY")},
+       {_SC("_OP_GETPARENT")},
+       {_SC("_OP_COMPARITH")},
+       {_SC("_OP_COMPARITHL")},
+       {_SC("_OP_INC")},
+       {_SC("_OP_INCL")},
+       {_SC("_OP_PINC")},
+       {_SC("_OP_PINCL")},
+       {_SC("_OP_CMP")},
+       {_SC("_OP_EXISTS")},
+       {_SC("_OP_INSTANCEOF")},
+       {_SC("_OP_AND")},
+       {_SC("_OP_OR")},
+       {_SC("_OP_NEG")},
+       {_SC("_OP_NOT")},
+       {_SC("_OP_BWNOT")},
+       {_SC("_OP_CLOSURE")},
+       {_SC("_OP_YIELD")},
+       {_SC("_OP_RESUME")},
+       {_SC("_OP_FOREACH")},
+       {_SC("_OP_DELEGATE")},
+       {_SC("_OP_CLONE")},
+       {_SC("_OP_TYPEOF")},
+       {_SC("_OP_PUSHTRAP")},
+       {_SC("_OP_POPTRAP")},
+       {_SC("_OP_THROW")},
+       {_SC("_OP_CLASS")},
+       {_SC("_OP_NEWSLOTA")}
+};
+#endif
+void DumpLiteral(SQObjectPtr &o)
+{
+       switch(type(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: assert(0); break; //shut up compiler
+       }
+}
+
+SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed)
+{
+               _nliterals = 0;
+               _literals = SQTable::Create(ss,0);
+               _strings =  SQTable::Create(ss,0);
+               _sharedstate = ss;
+               _lastline = 0;
+               _optimization = true;
+               _parent = parent;
+               _stacksize = 0;
+               _traps = 0;
+               _returnexp = 0;
+               _varparams = false;
+               _errfunc = efunc;
+               _errtarget = ed;
+               _bgenerator = false;
+
+}
+
+void SQFuncState::Error(const SQChar *err)
+{
+       _errfunc(_errtarget,err);
+}
+
+#ifdef _DEBUG_DUMP
+void SQFuncState::Dump(SQFunctionProto *func)
+{
+       SQUnsignedInteger n=0,i;
+       scprintf(_SC("SQInstruction sizeof %d\n"),sizeof(SQInstruction));
+       scprintf(_SC("SQObject sizeof %d\n"),sizeof(SQObject));
+       scprintf(_SC("--------------------------------------------------------------------\n"));
+       scprintf(_SC("*****FUNCTION [%s]\n"),type(func->_name)==OT_STRING?_stringval(func->_name):_SC("unknown"));
+       scprintf(_SC("-----LITERALS\n"));
+       SQObjectPtr refidx,key,val;
+       SQInteger idx;
+       SQObjectPtrVec templiterals;
+       templiterals.resize(_nliterals);
+       while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) {
+               refidx=idx;
+               templiterals[_integer(val)]=key;
+       }
+       for(i=0;i<templiterals.size();i++){
+               scprintf(_SC("[%d] "),n);
+               DumpLiteral(templiterals[i]);
+               scprintf(_SC("\n"));
+               n++;
+       }
+       scprintf(_SC("-----PARAMS\n"));
+       if(_varparams)
+               scprintf(_SC("<<VARPARAMS>>\n"));
+       n=0;
+       for(i=0;i<_parameters.size();i++){
+               scprintf(_SC("[%d] "),n);
+               DumpLiteral(_parameters[i]);
+               scprintf(_SC("\n"));
+               n++;
+       }
+       scprintf(_SC("-----LOCALS\n"));
+       for(i=0;i<func->_localvarinfos.size();i++){
+               SQLocalVarInfo lvi=func->_localvarinfos[i];
+               scprintf(_SC("[%d] %s \t%d %d\n"),lvi._pos,_stringval(lvi._name),lvi._start_op,lvi._end_op);
+               n++;
+       }
+       scprintf(_SC("-----LINE INFO\n"));
+       for(i=0;i<_lineinfos.size();i++){
+               SQLineInfo li=_lineinfos[i];
+               scprintf(_SC("op [%d] line [%d] \n"),li._op,li._line);
+               n++;
+       }
+       scprintf(_SC("-----dump\n"));
+       n=0;
+       for(i=0;i<_instructions.size();i++){
+               SQInstruction &inst=_instructions[i];
+               if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){
+
+                       SQInteger lidx = inst._arg1;
+                       scprintf(_SC("[%03d] %15s %d "),n,g_InstrDesc[inst.op].name,inst._arg0);
+                       if(lidx >= 0xFFFFFFFF)
+                               scprintf(_SC("null"));
+                       else {
+                               SQInteger refidx;
+                               SQObjectPtr val,key,refo;
+                               while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) {
+                                       refo = refidx;
+                               }
+                               DumpLiteral(key);
+                       }
+                       if(inst.op != _OP_DLOAD) {
+                               scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3);
+                       }
+                       else {
+                               scprintf(_SC(" %d "),inst._arg2);
+                               lidx = inst._arg3;
+                               if(lidx >= 0xFFFFFFFF)
+                                       scprintf(_SC("null"));
+                               else {
+                                       SQInteger refidx;
+                                       SQObjectPtr val,key,refo;
+                                       while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) {
+                                               refo = refidx;
+                               }
+                               DumpLiteral(key);
+                               scprintf(_SC("\n"));
+                       }
+                       }
+               }
+               else if(inst.op==_OP_ARITH){
+                       scprintf(_SC("[%03d] %15s %d %d %d %c\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
+               }
+               else
+                       scprintf(_SC("[%03d] %15s %d %d %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
+               n++;
+       }
+       scprintf(_SC("-----\n"));
+       scprintf(_SC("stack size[%d]\n"),func->_stacksize);
+       scprintf(_SC("--------------------------------------------------------------------\n\n"));
+}
+#endif
+
+SQInteger SQFuncState::GetNumericConstant(const SQInteger cons)
+{
+       return GetConstant(SQObjectPtr(cons));
+}
+
+SQInteger SQFuncState::GetNumericConstant(const SQFloat cons)
+{
+       return GetConstant(SQObjectPtr(cons));
+}
+
+SQInteger SQFuncState::GetConstant(const SQObject &cons)
+{
+       SQObjectPtr val;
+       if(!_table(_literals)->Get(cons,val))
+       {
+               val = _nliterals;
+               _table(_literals)->NewSlot(cons,val);
+               _nliterals++;
+               if(_nliterals > MAX_LITERALS) {
+                       val.Null();
+                       Error(_SC("internal compiler error: too many literals"));
+               }
+       }
+       return _integer(val);
+}
+
+void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3)
+{
+       _instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&arg0);
+       _instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&arg1);
+       _instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&arg2);
+       _instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&arg3);
+}
+
+void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val)
+{
+       switch(arg){
+               case 0:_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&val);break;
+               case 1:case 4:_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&val);break;
+               case 2:_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&val);break;
+               case 3:_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&val);break;
+       };
+}
+
+SQInteger SQFuncState::AllocStackPos()
+{
+       SQInteger npos=_vlocals.size();
+       _vlocals.push_back(SQLocalVarInfo());
+       if(_vlocals.size()>((SQUnsignedInteger)_stacksize)) {
+               if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC("internal compiler error: too many locals"));
+               _stacksize=_vlocals.size();
+       }
+       return npos;
+}
+
+SQInteger SQFuncState::PushTarget(SQInteger n)
+{
+       if(n!=-1){
+               _targetstack.push_back(n);
+               return n;
+       }
+       n=AllocStackPos();
+       _targetstack.push_back(n);
+       return n;
+}
+
+SQInteger SQFuncState::GetUpTarget(SQInteger n){
+       return _targetstack[((_targetstack.size()-1)-n)];
+}
+
+SQInteger SQFuncState::TopTarget(){
+       return _targetstack.back();
+}
+SQInteger SQFuncState::PopTarget()
+{
+       SQInteger npos=_targetstack.back();
+       SQLocalVarInfo t=_vlocals[_targetstack.back()];
+       if(type(t._name)==OT_NULL){
+               _vlocals.pop_back();
+       }
+       _targetstack.pop_back();
+       return npos;
+}
+
+SQInteger SQFuncState::GetStackSize()
+{
+       return _vlocals.size();
+}
+
+void SQFuncState::SetStackSize(SQInteger n)
+{
+       SQInteger size=_vlocals.size();
+       while(size>n){
+               size--;
+               SQLocalVarInfo lvi=_vlocals.back();
+               if(type(lvi._name)!=OT_NULL){
+                       lvi._end_op=GetCurrentPos();
+                       _localvarinfos.push_back(lvi);
+               }
+               _vlocals.pop_back();
+       }
+}
+
+bool SQFuncState::IsLocal(SQUnsignedInteger stkpos)
+{
+       if(stkpos>=_vlocals.size())return false;
+       else if(type(_vlocals[stkpos]._name)!=OT_NULL)return true;
+       return false;
+}
+
+SQInteger SQFuncState::PushLocalVariable(const SQObject &name)
+{
+       SQInteger pos=_vlocals.size();
+       SQLocalVarInfo lvi;
+       lvi._name=name;
+       lvi._start_op=GetCurrentPos()+1;
+       lvi._pos=_vlocals.size();
+       _vlocals.push_back(lvi);
+       if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size();
+
+       return pos;
+}
+
+SQInteger SQFuncState::GetLocalVariable(const SQObject &name)
+{
+       SQInteger locals=_vlocals.size();
+       while(locals>=1){
+               if(type(_vlocals[locals-1]._name)==OT_STRING && _string(_vlocals[locals-1]._name)==_string(name)){
+                       return locals-1;
+               }
+               locals--;
+       }
+       return -1;
+}
+
+SQInteger SQFuncState::GetOuterVariable(const SQObject &name)
+{
+       SQInteger outers = _outervalues.size();
+       for(SQInteger i = 0; i<outers; i++) {
+               if(_string(_outervalues[i]._name) == _string(name))
+                       return i;
+       }
+       return -1;
+}
+
+void SQFuncState::AddOuterValue(const SQObject &name)
+{
+       SQInteger pos=-1;
+       if(_parent) {
+               pos = _parent->GetLocalVariable(name);
+               if(pos == -1) {
+                       pos = _parent->GetOuterVariable(name);
+                       if(pos != -1) {
+                               _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otOUTER)); //local
+                               return;
+                       }
+               }
+               else {
+                       _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otLOCAL)); //local
+                       return;
+               }
+       }
+       _outervalues.push_back(SQOuterVar(name,name,otSYMBOL)); //global
+}
+
+void SQFuncState::AddParameter(const SQObject &name)
+{
+       PushLocalVariable(name);
+       _parameters.push_back(name);
+}
+
+void SQFuncState::AddLineInfos(SQInteger line,bool lineop,bool force)
+{
+       if(_lastline!=line || force){
+               SQLineInfo li;
+               li._line=line;li._op=(GetCurrentPos()+1);
+               if(lineop)AddInstruction(_OP_LINE,0,line);
+               _lineinfos.push_back(li);
+               _lastline=line;
+       }
+}
+
+void SQFuncState::AddInstruction(SQInstruction &i)
+{
+       SQInteger size = _instructions.size();
+       if(size > 0 && _optimization){ //simple optimizer
+               SQInstruction &pi = _instructions[size-1];//previous instruction
+               switch(i.op) {
+               case _OP_RETURN:
+                       if( _parent && i._arg0 != MAX_FUNC_STACKSIZE && pi.op == _OP_CALL && _returnexp < size-1) {
+                               pi.op = _OP_TAILCALL;
+                       }
+               break;
+               case _OP_GET:
+                       if( pi.op == _OP_LOAD && pi._arg0 == i._arg2 && (!IsLocal(pi._arg0))){
+                               pi._arg1 = pi._arg1;
+                               pi._arg2 = (unsigned char)i._arg1;
+                               pi.op = _OP_GETK;
+                               pi._arg0 = i._arg0;
+
+                               return;
+                       }
+               break;
+               case _OP_PREPCALL:
+                       if( pi.op == _OP_LOAD  && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){
+                               pi.op = _OP_PREPCALLK;
+                               pi._arg0 = i._arg0;
+                               pi._arg1 = pi._arg1;
+                               pi._arg2 = i._arg2;
+                               pi._arg3 = i._arg3;
+                               return;
+                       }
+                       break;
+               case _OP_APPENDARRAY:
+                       if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){
+                               pi.op = _OP_APPENDARRAY;
+                               pi._arg0 = i._arg0;
+                               pi._arg1 = pi._arg1;
+                               pi._arg2 = MAX_FUNC_STACKSIZE;
+                               pi._arg3 = MAX_FUNC_STACKSIZE;
+                               return;
+                       }
+                       break;
+               case _OP_MOVE:
+                       if((pi.op == _OP_GET || pi.op == _OP_ARITH || pi.op == _OP_BITW) && (pi._arg0 == i._arg1))
+                       {
+                               pi._arg0 = i._arg0;
+                               _optimization = false;
+                               return;
+                       }
+
+                       if(pi.op == _OP_MOVE)
+                       {
+                               pi.op = _OP_DMOVE;
+                               pi._arg2 = i._arg0;
+                               pi._arg3 = (unsigned char)i._arg1;
+                               return;
+                       }
+                       break;
+               case _OP_LOAD:
+                       if(pi.op == _OP_LOAD && i._arg1 < 256) {
+                               pi.op = _OP_DLOAD;
+                               pi._arg2 = i._arg0;
+                               pi._arg3 = (unsigned char)i._arg1;
+                               return;
+                       }
+                       break;
+               case _OP_EQ:case _OP_NE:
+                       if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0) ))
+                       {
+                               pi.op = i.op;
+                               pi._arg0 = i._arg0;
+                               pi._arg1 = pi._arg1;
+                               pi._arg2 = i._arg2;
+                               pi._arg3 = MAX_FUNC_STACKSIZE;
+                               return;
+                       }
+                       break;
+               case _OP_LOADNULLS:
+                       if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) {
+
+                               pi._arg1 = pi._arg1 + 1;
+                               pi.op = _OP_LOADNULLS;
+                               return;
+                       }
+            break;
+               case _OP_LINE:
+                       if(pi.op == _OP_LINE) {
+                               _instructions.pop_back();
+                               _lineinfos.pop_back();
+                       }
+                       break;
+               }
+       }
+       _optimization = true;
+       _instructions.push_back(i);
+}
+
+SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len)
+{
+       SQObjectPtr ns(SQString::Create(_sharedstate,s,len));
+       _table(_strings)->NewSlot(ns,(SQInteger)1);
+       return ns;
+}
+
+SQFunctionProto *SQFuncState::BuildProto()
+{
+       SQFunctionProto *f=SQFunctionProto::Create();
+       f->_literals.resize(_nliterals);
+       SQObjectPtr refidx,key,val;
+       SQInteger idx;
+
+       f->_stacksize = _stacksize;
+       f->_sourcename = _sourcename;
+       f->_bgenerator = _bgenerator;
+       f->_name = _name;
+
+       while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) {
+               f->_literals[_integer(val)]=key;
+               refidx=idx;
+       }
+
+       f->_functions.resize(_functions.size());
+       f->_functions.copy(_functions);
+       f->_parameters.resize(_parameters.size());
+       f->_parameters.copy(_parameters);
+       f->_outervalues.resize(_outervalues.size());
+       f->_outervalues.copy(_outervalues);
+       f->_instructions.resize(_instructions.size());
+       f->_instructions.copy(_instructions);
+       f->_localvarinfos.resize(_localvarinfos.size());
+       f->_localvarinfos.copy(_localvarinfos);
+       f->_lineinfos.resize(_lineinfos.size());
+       f->_lineinfos.copy(_lineinfos);
+       f->_varparams = _varparams;
+
+       return f;
+}
+
+SQFuncState *SQFuncState::PushChildState(SQSharedState *ss)
+{
+       SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState));
+       new (child) SQFuncState(ss,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 df6d2e9..fd191f2 100644 (file)
@@ -1,80 +1,79 @@
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQFUNCSTATE_H_\r
-#define _SQFUNCSTATE_H_\r
-///////////////////////////////////\r
-#include "squtils.h"\r
-\r
-struct SQFuncState\r
-{\r
-       SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed);\r
-       ~SQFuncState();\r
-#ifdef _DEBUG_DUMP\r
-       void Dump(SQFunctionProto *func);\r
-#endif\r
-       void Error(const SQChar *err);\r
-       SQFuncState *PushChildState(SQSharedState *ss);\r
-       void PopChildState();\r
-       void AddInstruction(SQOpcode _op,SQInteger arg0=0,SQInteger arg1=0,SQInteger arg2=0,SQInteger arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);AddInstruction(i);}\r
-       void AddInstruction(SQInstruction &i);\r
-       void SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2=0,SQInteger arg3=0);\r
-       void SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val);\r
-       SQInstruction &GetInstruction(SQInteger pos){return _instructions[pos];}\r
-       void PopInstructions(SQInteger size){for(SQInteger i=0;i<size;i++)_instructions.pop_back();}\r
-       void SetStackSize(SQInteger n);\r
-       void SnoozeOpt(){_optimization=false;}\r
-       SQInteger GetCurrentPos(){return _instructions.size()-1;}\r
-       SQInteger GetNumericConstant(const SQInteger cons);\r
-       SQInteger GetNumericConstant(const SQFloat cons);\r
-       SQInteger PushLocalVariable(const SQObject &name);\r
-       void AddParameter(const SQObject &name);\r
-       void AddOuterValue(const SQObject &name);\r
-       SQInteger GetLocalVariable(const SQObject &name);\r
-       SQInteger GetOuterVariable(const SQObject &name);\r
-       SQInteger GenerateCode();\r
-       SQInteger GetStackSize();\r
-       SQInteger CalcStackFrameSize();\r
-       void AddLineInfos(SQInteger line,bool lineop,bool force=false);\r
-       SQFunctionProto *BuildProto();\r
-       SQInteger AllocStackPos();\r
-       SQInteger PushTarget(SQInteger n=-1);\r
-       SQInteger PopTarget();\r
-       SQInteger TopTarget();\r
-       SQInteger GetUpTarget(SQInteger n);\r
-       bool IsLocal(SQUnsignedInteger stkpos);\r
-       SQObject CreateString(const SQChar *s,SQInteger len = -1);\r
-       SQInteger _returnexp;\r
-       SQLocalVarInfoVec _vlocals;\r
-       SQIntVec _targetstack;\r
-       SQInteger _stacksize;\r
-       bool _varparams;\r
-       bool _bgenerator;\r
-       SQIntVec _unresolvedbreaks;\r
-       SQIntVec _unresolvedcontinues;\r
-       SQObjectPtrVec _functions;\r
-       SQObjectPtrVec _parameters;\r
-       SQOuterVarVec _outervalues;\r
-       SQInstructionVec _instructions;\r
-       SQLocalVarInfoVec _localvarinfos;\r
-       SQObjectPtr _literals;\r
-       SQObjectPtr _strings;\r
-       SQObjectPtr _name;\r
-       SQObjectPtr _sourcename;\r
-       SQInteger _nliterals;\r
-       SQLineInfoVec _lineinfos;\r
-       SQFuncState *_parent;\r
-       SQIntVec _breaktargets;\r
-       SQIntVec _continuetargets;\r
-       SQInteger _lastline;\r
-       SQInteger _traps; //contains number of nested exception traps\r
-       bool _optimization;\r
-       SQSharedState *_sharedstate;\r
-       sqvector<SQFuncState*> _childstates;\r
-       SQInteger GetConstant(const SQObject &cons);\r
-private:\r
-       CompilerErrorFunc _errfunc;\r
-       void *_errtarget;\r
-};\r
-\r
-\r
-#endif //_SQFUNCSTATE_H_\r
-\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQFUNCSTATE_H_
+#define _SQFUNCSTATE_H_
+///////////////////////////////////
+#include "squtils.h"
+
+struct SQFuncState
+{
+       SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed);
+       ~SQFuncState();
+#ifdef _DEBUG_DUMP
+       void Dump(SQFunctionProto *func);
+#endif
+       void Error(const SQChar *err);
+       SQFuncState *PushChildState(SQSharedState *ss);
+       void PopChildState();
+       void AddInstruction(SQOpcode _op,SQInteger arg0=0,SQInteger arg1=0,SQInteger arg2=0,SQInteger arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);AddInstruction(i);}
+       void AddInstruction(SQInstruction &i);
+       void SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2=0,SQInteger arg3=0);
+       void SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val);
+       SQInstruction &GetInstruction(SQInteger pos){return _instructions[pos];}
+       void PopInstructions(SQInteger size){for(SQInteger i=0;i<size;i++)_instructions.pop_back();}
+       void SetStackSize(SQInteger n);
+       void SnoozeOpt(){_optimization=false;}
+       SQInteger GetCurrentPos(){return _instructions.size()-1;}
+       SQInteger GetNumericConstant(const SQInteger cons);
+       SQInteger GetNumericConstant(const SQFloat cons);
+       SQInteger PushLocalVariable(const SQObject &name);
+       void AddParameter(const SQObject &name);
+       void AddOuterValue(const SQObject &name);
+       SQInteger GetLocalVariable(const SQObject &name);
+       SQInteger GetOuterVariable(const SQObject &name);
+       SQInteger GenerateCode();
+       SQInteger GetStackSize();
+       SQInteger CalcStackFrameSize();
+       void AddLineInfos(SQInteger line,bool lineop,bool force=false);
+       SQFunctionProto *BuildProto();
+       SQInteger AllocStackPos();
+       SQInteger PushTarget(SQInteger n=-1);
+       SQInteger PopTarget();
+       SQInteger TopTarget();
+       SQInteger GetUpTarget(SQInteger n);
+       bool IsLocal(SQUnsignedInteger stkpos);
+       SQObject CreateString(const SQChar *s,SQInteger len = -1);
+       SQInteger _returnexp;
+       SQLocalVarInfoVec _vlocals;
+       SQIntVec _targetstack;
+       SQInteger _stacksize;
+       bool _varparams;
+       bool _bgenerator;
+       SQIntVec _unresolvedbreaks;
+       SQIntVec _unresolvedcontinues;
+       SQObjectPtrVec _functions;
+       SQObjectPtrVec _parameters;
+       SQOuterVarVec _outervalues;
+       SQInstructionVec _instructions;
+       SQLocalVarInfoVec _localvarinfos;
+       SQObjectPtr _literals;
+       SQObjectPtr _strings;
+       SQObjectPtr _name;
+       SQObjectPtr _sourcename;
+       SQInteger _nliterals;
+       SQLineInfoVec _lineinfos;
+       SQFuncState *_parent;
+       SQIntVec _breaktargets;
+       SQIntVec _continuetargets;
+       SQInteger _lastline;
+       SQInteger _traps; //contains number of nested exception traps
+       bool _optimization;
+       SQSharedState *_sharedstate;
+       sqvector<SQFuncState*> _childstates;
+       SQInteger GetConstant(const SQObject &cons);
+private:
+       CompilerErrorFunc _errfunc;
+       void *_errtarget;
+};
+
+
+#endif //_SQFUNCSTATE_H_
index 7244e73..2552f7d 100644 (file)
-/*\r
-       see copyright notice in squirrel.h\r
-*/\r
-#include "sqpcheader.h"\r
-#include <ctype.h>\r
-#include <stdlib.h>\r
-#include "sqtable.h"\r
-#include "sqstring.h"\r
-#include "sqcompiler.h"\r
-#include "sqlexer.h"\r
-\r
-#define CUR_CHAR (_currdata)\r
-#define RETURN_TOKEN(t) { _prevtoken = _curtoken; _curtoken = t; return t;}\r
-#define IS_EOB() (CUR_CHAR <= SQUIRREL_EOB)\r
-#define NEXT() {Next();_currentcolumn++;}\r
-#define INIT_TEMP_STRING() { _longstr.resize(0);}\r
-#define APPEND_CHAR(c) { _longstr.push_back(c);}\r
-#define TERMINATE_BUFFER() {_longstr.push_back(_SC('\0'));}\r
-#define ADD_KEYWORD(key,id) _keywords->NewSlot( SQString::Create(ss, _SC(#key)) ,SQInteger(id))\r
-\r
-SQLexer::SQLexer(){}\r
-SQLexer::~SQLexer()\r
-{\r
-       _keywords->Release();\r
-}\r
-\r
-void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed)\r
-{\r
-       _errfunc = efunc;\r
-       _errtarget = ed;\r
-       _sharedstate = ss;\r
-       _keywords = SQTable::Create(ss, 26);\r
-       ADD_KEYWORD(while, TK_WHILE);\r
-       ADD_KEYWORD(do, TK_DO);\r
-       ADD_KEYWORD(if, TK_IF);\r
-       ADD_KEYWORD(else, TK_ELSE);\r
-       ADD_KEYWORD(break, TK_BREAK);\r
-       ADD_KEYWORD(continue, TK_CONTINUE);\r
-       ADD_KEYWORD(return, TK_RETURN);\r
-       ADD_KEYWORD(null, TK_NULL);\r
-       ADD_KEYWORD(function, TK_FUNCTION);\r
-       ADD_KEYWORD(local, TK_LOCAL);\r
-       ADD_KEYWORD(for, TK_FOR);\r
-       ADD_KEYWORD(foreach, TK_FOREACH);\r
-       ADD_KEYWORD(in, TK_IN);\r
-       ADD_KEYWORD(typeof, TK_TYPEOF);\r
-       ADD_KEYWORD(delegate, TK_DELEGATE);\r
-       ADD_KEYWORD(delete, TK_DELETE);\r
-       ADD_KEYWORD(try, TK_TRY);\r
-       ADD_KEYWORD(catch, TK_CATCH);\r
-       ADD_KEYWORD(throw, TK_THROW);\r
-       ADD_KEYWORD(clone, TK_CLONE);\r
-       ADD_KEYWORD(yield, TK_YIELD);\r
-       ADD_KEYWORD(resume, TK_RESUME);\r
-       ADD_KEYWORD(switch, TK_SWITCH);\r
-       ADD_KEYWORD(case, TK_CASE);\r
-       ADD_KEYWORD(default, TK_DEFAULT);\r
-       ADD_KEYWORD(this, TK_THIS);\r
-       ADD_KEYWORD(parent,TK_PARENT);\r
-       ADD_KEYWORD(class,TK_CLASS);\r
-       ADD_KEYWORD(extends,TK_EXTENDS);\r
-       ADD_KEYWORD(constructor,TK_CONSTRUCTOR);\r
-       ADD_KEYWORD(instanceof,TK_INSTANCEOF);\r
-       ADD_KEYWORD(vargc,TK_VARGC);\r
-       ADD_KEYWORD(vargv,TK_VARGV);\r
-       ADD_KEYWORD(true,TK_TRUE);\r
-       ADD_KEYWORD(false,TK_FALSE);\r
-       ADD_KEYWORD(static,TK_STATIC);\r
-\r
-       _readf = rg;\r
-       _up = up;\r
-       _lasttokenline = _currentline = 1;\r
-       _currentcolumn = 0;\r
-       _prevtoken = -1;\r
-       Next();\r
-}\r
-\r
-void SQLexer::Error(const SQChar *err)\r
-{\r
-       _errfunc(_errtarget,err);\r
-}\r
-\r
-void SQLexer::Next()\r
-{\r
-       SQInteger t = _readf(_up);\r
-       if(t > MAX_CHAR) Error(_SC("Invalid character"));\r
-       if(t != 0) {\r
-               _currdata = (LexChar)t;\r
-               return;\r
-       }\r
-       _currdata = SQUIRREL_EOB;\r
-}\r
-\r
-const SQChar *SQLexer::Tok2Str(SQInteger tok)\r
-{\r
-       SQObjectPtr itr, key, val;\r
-       SQInteger nitr;\r
-       while((nitr = _keywords->Next(false,itr, key, val)) != -1) {\r
-               itr = (SQInteger)nitr;\r
-               if(((SQInteger)_integer(val)) == tok)\r
-                       return _stringval(key);\r
-       }\r
-       return NULL;\r
-}\r
-\r
-void SQLexer::LexBlockComment()\r
-{\r
-       bool done = false;\r
-       while(!done) {\r
-               switch(CUR_CHAR) {\r
-                       case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue;\r
-                       case _SC('\n'): _currentline++; NEXT(); continue;\r
-                       case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment"));\r
-                       default: NEXT();\r
-               }\r
-       }\r
-}\r
-\r
-SQInteger SQLexer::Lex()\r
-{\r
-       _lasttokenline = _currentline;\r
-       while(CUR_CHAR != SQUIRREL_EOB) {\r
-               switch(CUR_CHAR){\r
-               case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue;\r
-               case _SC('\n'):\r
-                       _currentline++;\r
-                       _prevtoken=_curtoken;\r
-                       _curtoken=_SC('\n');\r
-                       NEXT();\r
-                       _currentcolumn=1;\r
-                       continue;\r
-               case _SC('/'):\r
-                       NEXT();\r
-                       switch(CUR_CHAR){\r
-                       case _SC('*'):\r
-                               NEXT();\r
-                               LexBlockComment();\r
-                               continue;       \r
-                       case _SC('/'):\r
-                               do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB()));\r
-                               continue;\r
-                       case _SC('='):\r
-                               NEXT();\r
-                               RETURN_TOKEN(TK_DIVEQ);\r
-                               continue;\r
-                       case _SC('>'):\r
-                               NEXT();\r
-                               RETURN_TOKEN(TK_ATTR_CLOSE);\r
-                               continue;\r
-                       default:\r
-                               RETURN_TOKEN('/');\r
-                       }\r
-               case _SC('='):\r
-                       NEXT();\r
-                       if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') }\r
-                       else { NEXT(); RETURN_TOKEN(TK_EQ); }\r
-               case _SC('<'):\r
-                       NEXT();\r
-                       if ( CUR_CHAR == _SC('=') ) { NEXT(); RETURN_TOKEN(TK_LE) }\r
-                       else if ( CUR_CHAR == _SC('-') ) { NEXT(); RETURN_TOKEN(TK_NEWSLOT); }\r
-                       else if ( CUR_CHAR == _SC('<') ) { NEXT(); RETURN_TOKEN(TK_SHIFTL); }\r
-                       else if ( CUR_CHAR == _SC('/') ) { NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); }\r
-                       //else if ( CUR_CHAR == _SC('[') ) { NEXT(); ReadMultilineString(); RETURN_TOKEN(TK_STRING_LITERAL); }\r
-                       else { RETURN_TOKEN('<') }\r
-               case _SC('>'):\r
-                       NEXT();\r
-                       if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);}\r
-                       else if(CUR_CHAR == _SC('>')){ \r
-                               NEXT(); \r
-                               if(CUR_CHAR == _SC('>')){\r
-                                       NEXT();\r
-                                       RETURN_TOKEN(TK_USHIFTR);\r
-                               }\r
-                               RETURN_TOKEN(TK_SHIFTR);\r
-                       }\r
-                       else { RETURN_TOKEN('>') }\r
-               case _SC('!'):\r
-                       NEXT();\r
-                       if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')}\r
-                       else { NEXT(); RETURN_TOKEN(TK_NE); }\r
-               case _SC('@'): {\r
-                       SQInteger stype;\r
-                       NEXT(); \r
-                       if(CUR_CHAR != _SC('"'))\r
-                               Error(_SC("string expected"));\r
-                       if((stype=ReadString('"',true))!=-1) {\r
-                               RETURN_TOKEN(stype);\r
-                       }\r
-                       Error(_SC("error parsing the string"));\r
-                                          }\r
-               case _SC('"'):\r
-               case _SC('\''): {\r
-                       SQInteger stype;\r
-                       if((stype=ReadString(CUR_CHAR,false))!=-1){\r
-                               RETURN_TOKEN(stype);\r
-                       }\r
-                       Error(_SC("error parsing the string"));\r
-                       }\r
-               case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'):\r
-               case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'):\r
-                       {SQInteger ret = CUR_CHAR;\r
-                       NEXT(); RETURN_TOKEN(ret); }\r
-               case _SC('.'):\r
-                       NEXT();\r
-                       if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') }\r
-                       NEXT();\r
-                       if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); }\r
-                       NEXT();\r
-                       RETURN_TOKEN(TK_VARPARAMS);\r
-               case _SC('&'):\r
-                       NEXT();\r
-                       if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') }\r
-                       else { NEXT(); RETURN_TOKEN(TK_AND); }\r
-               case _SC('|'):\r
-                       NEXT();\r
-                       if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') }\r
-                       else { NEXT(); RETURN_TOKEN(TK_OR); }\r
-               case _SC(':'):\r
-                       NEXT();\r
-                       if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') }\r
-                       else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); }\r
-               case _SC('*'):\r
-                       NEXT();\r
-                       if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);}\r
-                       else RETURN_TOKEN('*');\r
-               case _SC('%'):\r
-                       NEXT();\r
-                       if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);}\r
-                       else RETURN_TOKEN('%');\r
-               case _SC('-'):\r
-                       NEXT();\r
-                       if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);}\r
-                       else if  (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);}\r
-                       else RETURN_TOKEN('-');\r
-               case _SC('+'):\r
-                       NEXT();\r
-                       if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);}\r
-                       else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);}\r
-                       else RETURN_TOKEN('+');\r
-               case SQUIRREL_EOB:\r
-                       return 0;\r
-               default:{\r
-                               if (scisdigit(CUR_CHAR)) {\r
-                                       SQInteger ret = ReadNumber();\r
-                                       RETURN_TOKEN(ret);\r
-                               }\r
-                               else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) {\r
-                                       SQInteger t = ReadID();\r
-                                       RETURN_TOKEN(t);\r
-                               }\r
-                               else {\r
-                                       SQInteger c = CUR_CHAR;\r
-                                       if (sciscntrl((int)c)) Error(_SC("unexpected character(control)"));\r
-                                       NEXT();\r
-                                       RETURN_TOKEN(c);  \r
-                               }\r
-                               RETURN_TOKEN(0);\r
-                       }\r
-               }\r
-       }\r
-       return 0;    \r
-}\r
-       \r
-SQInteger SQLexer::GetIDType(SQChar *s)\r
-{\r
-       SQObjectPtr t;\r
-       if(_keywords->Get(SQString::Create(_sharedstate, s), t)) {\r
-               return SQInteger(_integer(t));\r
-       }\r
-       return TK_IDENTIFIER;\r
-}\r
-\r
-\r
-SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)\r
-{\r
-       INIT_TEMP_STRING();\r
-       NEXT();\r
-       if(IS_EOB()) return -1;\r
-       for(;;) {\r
-               while(CUR_CHAR != ndelim) {\r
-                       switch(CUR_CHAR) {\r
-                       case SQUIRREL_EOB:\r
-                               Error(_SC("unfinished string"));\r
-                               return -1;\r
-                       case _SC('\n'): \r
-                               if(!verbatim) Error(_SC("newline in a constant")); \r
-                               APPEND_CHAR(CUR_CHAR); NEXT(); \r
-                               _currentline++;\r
-                               break;\r
-                       case _SC('\\'):\r
-                               if(verbatim) {\r
-                                       APPEND_CHAR('\\'); NEXT(); \r
-                               }\r
-                               else {\r
-                                       NEXT();\r
-                                       switch(CUR_CHAR) {\r
-                                       case _SC('x'): NEXT(); {\r
-                                               if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected")); \r
-                                               const SQInteger maxdigits = 4;\r
-                                               SQChar temp[maxdigits+1];\r
-                                               SQInteger n = 0;\r
-                                               while(isxdigit(CUR_CHAR) && n < maxdigits) {\r
-                                                       temp[n] = CUR_CHAR;\r
-                                                       n++;\r
-                                                       NEXT();\r
-                                               }\r
-                                               temp[n] = 0;\r
-                                               SQChar *sTemp;\r
-                                               APPEND_CHAR((SQChar)scstrtoul(temp,&sTemp,16));\r
-                                       }\r
-                                   break;\r
-                                       case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break;\r
-                                       case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break;\r
-                                       case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break;\r
-                                       case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break;\r
-                                       case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break;\r
-                                       case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break;\r
-                                       case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break;\r
-                                       case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break;\r
-                                       case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break;\r
-                                       case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break;\r
-                                       case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break;\r
-                                       default:\r
-                                               Error(_SC("unrecognised escaper char"));\r
-                                       break;\r
-                                       }\r
-                               }\r
-                               break;\r
-                       default:\r
-                               APPEND_CHAR(CUR_CHAR);\r
-                               NEXT();\r
-                       }\r
-               }\r
-               NEXT();\r
-               if(verbatim && CUR_CHAR == '"') { //double quotation\r
-                       APPEND_CHAR(CUR_CHAR);\r
-                       NEXT();\r
-               }\r
-               else {\r
-                       break;\r
-               }\r
-       }\r
-       TERMINATE_BUFFER();\r
-       SQInteger len = _longstr.size()-1;\r
-       if(ndelim == _SC('\'')) {\r
-               if(len == 0) Error(_SC("empty constant"));\r
-               if(len > 1) Error(_SC("constant too long"));\r
-               _nvalue = _longstr[0];\r
-               return TK_INTEGER;\r
-       }\r
-       _svalue = &_longstr[0];\r
-       return TK_STRING_LITERAL;\r
-}\r
-\r
-void LexHexadecimal(const SQChar *s,SQUnsignedInteger *res)\r
-{\r
-       *res = 0;\r
-       while(*s != 0)\r
-       {\r
-               if(scisdigit(*s)) *res = (*res)*16+((*s++)-'0');\r
-               else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-'A'+10);\r
-               else { assert(0); }\r
-       }\r
-}\r
-\r
-void LexInteger(const SQChar *s,SQUnsignedInteger *res)\r
-{\r
-       *res = 0;\r
-       while(*s != 0)\r
-       {\r
-               *res = (*res)*10+((*s++)-'0');\r
-       }\r
-}\r
-\r
-SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; }\r
-#define MAX_HEX_DIGITS (sizeof(SQInteger)*2)\r
-SQInteger SQLexer::ReadNumber()\r
-{\r
-#define TINT 1\r
-#define TFLOAT 2\r
-#define THEX 3\r
-#define TSCIENTIFIC 4\r
-       SQInteger type = TINT, firstchar = CUR_CHAR;\r
-       SQChar *sTemp;\r
-       INIT_TEMP_STRING();\r
-       NEXT();\r
-       if(firstchar == _SC('0') && toupper(CUR_CHAR) == _SC('X')) {\r
-               NEXT();\r
-               type = THEX;\r
-               while(isxdigit(CUR_CHAR)) {\r
-                       APPEND_CHAR(CUR_CHAR);\r
-                       NEXT();\r
-               }\r
-               if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number"));\r
-       }\r
-       else {\r
-               APPEND_CHAR((int)firstchar);\r
-               while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) {\r
-            if(CUR_CHAR == _SC('.')) type = TFLOAT;\r
-                       if(isexponent(CUR_CHAR)) {\r
-                               if(type != TFLOAT) Error(_SC("invalid numeric format"));\r
-                               type = TSCIENTIFIC;\r
-                               APPEND_CHAR(CUR_CHAR);\r
-                               NEXT();\r
-                               if(CUR_CHAR == '+' || CUR_CHAR == '-'){\r
-                                       APPEND_CHAR(CUR_CHAR);\r
-                                       NEXT();\r
-                               }\r
-                               if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected"));\r
-                       }\r
-                       \r
-                       APPEND_CHAR(CUR_CHAR);\r
-                       NEXT();\r
-               }\r
-       }\r
-       TERMINATE_BUFFER();\r
-       switch(type) {\r
-       case TSCIENTIFIC:\r
-       case TFLOAT:\r
-               _fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp);\r
-               return TK_FLOAT;\r
-       case TINT:\r
-               LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue);\r
-               return TK_INTEGER;\r
-       case THEX:\r
-               LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);\r
-               return TK_INTEGER;\r
-       }\r
-       return 0;\r
-}\r
-\r
-SQInteger SQLexer::ReadID()\r
-{\r
-       SQInteger res;\r
-       INIT_TEMP_STRING();\r
-       do {\r
-               APPEND_CHAR(CUR_CHAR);\r
-               NEXT();\r
-       } while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_'));\r
-       TERMINATE_BUFFER();\r
-       res = GetIDType(&_longstr[0]);\r
-       if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) {\r
-               _svalue = &_longstr[0];\r
-       }\r
-       return res;\r
-}\r
+/*
+       see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include <ctype.h>
+#include <stdlib.h>
+#include "sqtable.h"
+#include "sqstring.h"
+#include "sqcompiler.h"
+#include "sqlexer.h"
+
+#define CUR_CHAR (_currdata)
+#define RETURN_TOKEN(t) { _prevtoken = _curtoken; _curtoken = t; return t;}
+#define IS_EOB() (CUR_CHAR <= SQUIRREL_EOB)
+#define NEXT() {Next();_currentcolumn++;}
+#define INIT_TEMP_STRING() { _longstr.resize(0);}
+#define APPEND_CHAR(c) { _longstr.push_back(c);}
+#define TERMINATE_BUFFER() {_longstr.push_back(_SC('\0'));}
+#define ADD_KEYWORD(key,id) _keywords->NewSlot( SQString::Create(ss, _SC(#key)) ,SQInteger(id))
+
+SQLexer::SQLexer(){}
+SQLexer::~SQLexer()
+{
+       _keywords->Release();
+}
+
+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);
+       ADD_KEYWORD(do, TK_DO);
+       ADD_KEYWORD(if, TK_IF);
+       ADD_KEYWORD(else, TK_ELSE);
+       ADD_KEYWORD(break, TK_BREAK);
+       ADD_KEYWORD(continue, TK_CONTINUE);
+       ADD_KEYWORD(return, TK_RETURN);
+       ADD_KEYWORD(null, TK_NULL);
+       ADD_KEYWORD(function, TK_FUNCTION);
+       ADD_KEYWORD(local, TK_LOCAL);
+       ADD_KEYWORD(for, TK_FOR);
+       ADD_KEYWORD(foreach, TK_FOREACH);
+       ADD_KEYWORD(in, TK_IN);
+       ADD_KEYWORD(typeof, TK_TYPEOF);
+       ADD_KEYWORD(delegate, TK_DELEGATE);
+       ADD_KEYWORD(delete, TK_DELETE);
+       ADD_KEYWORD(try, TK_TRY);
+       ADD_KEYWORD(catch, TK_CATCH);
+       ADD_KEYWORD(throw, TK_THROW);
+       ADD_KEYWORD(clone, TK_CLONE);
+       ADD_KEYWORD(yield, TK_YIELD);
+       ADD_KEYWORD(resume, TK_RESUME);
+       ADD_KEYWORD(switch, TK_SWITCH);
+       ADD_KEYWORD(case, TK_CASE);
+       ADD_KEYWORD(default, TK_DEFAULT);
+       ADD_KEYWORD(this, TK_THIS);
+       ADD_KEYWORD(parent,TK_PARENT);
+       ADD_KEYWORD(class,TK_CLASS);
+       ADD_KEYWORD(extends,TK_EXTENDS);
+       ADD_KEYWORD(constructor,TK_CONSTRUCTOR);
+       ADD_KEYWORD(instanceof,TK_INSTANCEOF);
+       ADD_KEYWORD(vargc,TK_VARGC);
+       ADD_KEYWORD(vargv,TK_VARGV);
+       ADD_KEYWORD(true,TK_TRUE);
+       ADD_KEYWORD(false,TK_FALSE);
+       ADD_KEYWORD(static,TK_STATIC);
+
+       _readf = rg;
+       _up = up;
+       _lasttokenline = _currentline = 1;
+       _currentcolumn = 0;
+       _prevtoken = -1;
+       Next();
+}
+
+void SQLexer::Error(const SQChar *err)
+{
+       _errfunc(_errtarget,err);
+}
+
+void SQLexer::Next()
+{
+       SQInteger t = _readf(_up);
+       if(t > MAX_CHAR) Error(_SC("Invalid character"));
+       if(t != 0) {
+               _currdata = (LexChar)t;
+               return;
+       }
+       _currdata = SQUIRREL_EOB;
+}
+
+const SQChar *SQLexer::Tok2Str(SQInteger tok)
+{
+       SQObjectPtr itr, key, val;
+       SQInteger nitr;
+       while((nitr = _keywords->Next(false,itr, key, val)) != -1) {
+               itr = (SQInteger)nitr;
+               if(((SQInteger)_integer(val)) == tok)
+                       return _stringval(key);
+       }
+       return NULL;
+}
+
+void SQLexer::LexBlockComment()
+{
+       bool done = false;
+       while(!done) {
+               switch(CUR_CHAR) {
+                       case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue;
+                       case _SC('\n'): _currentline++; NEXT(); continue;
+                       case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment"));
+                       default: NEXT();
+               }
+       }
+}
+
+SQInteger SQLexer::Lex()
+{
+       _lasttokenline = _currentline;
+       while(CUR_CHAR != SQUIRREL_EOB) {
+               switch(CUR_CHAR){
+               case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue;
+               case _SC('\n'):
+                       _currentline++;
+                       _prevtoken=_curtoken;
+                       _curtoken=_SC('\n');
+                       NEXT();
+                       _currentcolumn=1;
+                       continue;
+               case _SC('/'):
+                       NEXT();
+                       switch(CUR_CHAR){
+                       case _SC('*'):
+                               NEXT();
+                               LexBlockComment();
+                               continue;
+                       case _SC('/'):
+                               do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB()));
+                               continue;
+                       case _SC('='):
+                               NEXT();
+                               RETURN_TOKEN(TK_DIVEQ);
+                               continue;
+                       case _SC('>'):
+                               NEXT();
+                               RETURN_TOKEN(TK_ATTR_CLOSE);
+                               continue;
+                       default:
+                               RETURN_TOKEN('/');
+                       }
+               case _SC('='):
+                       NEXT();
+                       if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') }
+                       else { NEXT(); RETURN_TOKEN(TK_EQ); }
+               case _SC('<'):
+                       NEXT();
+                       if ( CUR_CHAR == _SC('=') ) { NEXT(); RETURN_TOKEN(TK_LE) }
+                       else if ( CUR_CHAR == _SC('-') ) { NEXT(); RETURN_TOKEN(TK_NEWSLOT); }
+                       else if ( CUR_CHAR == _SC('<') ) { NEXT(); RETURN_TOKEN(TK_SHIFTL); }
+                       else if ( CUR_CHAR == _SC('/') ) { NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); }
+                       //else if ( CUR_CHAR == _SC('[') ) { NEXT(); ReadMultilineString(); RETURN_TOKEN(TK_STRING_LITERAL); }
+                       else { RETURN_TOKEN('<') }
+               case _SC('>'):
+                       NEXT();
+                       if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);}
+                       else if(CUR_CHAR == _SC('>')){
+                               NEXT();
+                               if(CUR_CHAR == _SC('>')){
+                                       NEXT();
+                                       RETURN_TOKEN(TK_USHIFTR);
+                               }
+                               RETURN_TOKEN(TK_SHIFTR);
+                       }
+                       else { RETURN_TOKEN('>') }
+               case _SC('!'):
+                       NEXT();
+                       if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')}
+                       else { NEXT(); RETURN_TOKEN(TK_NE); }
+               case _SC('@'): {
+                       SQInteger stype;
+                       NEXT();
+                       if(CUR_CHAR != _SC('"'))
+                               Error(_SC("string expected"));
+                       if((stype=ReadString('"',true))!=-1) {
+                               RETURN_TOKEN(stype);
+                       }
+                       Error(_SC("error parsing the string"));
+                                          }
+               case _SC('"'):
+               case _SC('\''): {
+                       SQInteger stype;
+                       if((stype=ReadString(CUR_CHAR,false))!=-1){
+                               RETURN_TOKEN(stype);
+                       }
+                       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('~'):
+                       {SQInteger ret = CUR_CHAR;
+                       NEXT(); RETURN_TOKEN(ret); }
+               case _SC('.'):
+                       NEXT();
+                       if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') }
+                       NEXT();
+                       if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); }
+                       NEXT();
+                       RETURN_TOKEN(TK_VARPARAMS);
+               case _SC('&'):
+                       NEXT();
+                       if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') }
+                       else { NEXT(); RETURN_TOKEN(TK_AND); }
+               case _SC('|'):
+                       NEXT();
+                       if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') }
+                       else { NEXT(); RETURN_TOKEN(TK_OR); }
+               case _SC(':'):
+                       NEXT();
+                       if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') }
+                       else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); }
+               case _SC('*'):
+                       NEXT();
+                       if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);}
+                       else RETURN_TOKEN('*');
+               case _SC('%'):
+                       NEXT();
+                       if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);}
+                       else RETURN_TOKEN('%');
+               case _SC('-'):
+                       NEXT();
+                       if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);}
+                       else if  (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);}
+                       else RETURN_TOKEN('-');
+               case _SC('+'):
+                       NEXT();
+                       if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);}
+                       else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);}
+                       else RETURN_TOKEN('+');
+               case SQUIRREL_EOB:
+                       return 0;
+               default:{
+                               if (scisdigit(CUR_CHAR)) {
+                                       SQInteger ret = ReadNumber();
+                                       RETURN_TOKEN(ret);
+                               }
+                               else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) {
+                                       SQInteger t = ReadID();
+                                       RETURN_TOKEN(t);
+                               }
+                               else {
+                                       SQInteger c = CUR_CHAR;
+                                       if (sciscntrl((int)c)) Error(_SC("unexpected character(control)"));
+                                       NEXT();
+                                       RETURN_TOKEN(c);
+                               }
+                               RETURN_TOKEN(0);
+                       }
+               }
+       }
+       return 0;
+}
+
+SQInteger SQLexer::GetIDType(SQChar *s)
+{
+       SQObjectPtr t;
+       if(_keywords->Get(SQString::Create(_sharedstate, s), t)) {
+               return SQInteger(_integer(t));
+       }
+       return TK_IDENTIFIER;
+}
+
+
+SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
+{
+       INIT_TEMP_STRING();
+       NEXT();
+       if(IS_EOB()) return -1;
+       for(;;) {
+               while(CUR_CHAR != ndelim) {
+                       switch(CUR_CHAR) {
+                       case SQUIRREL_EOB:
+                               Error(_SC("unfinished string"));
+                               return -1;
+                       case _SC('\n'):
+                               if(!verbatim) Error(_SC("newline in a constant"));
+                               APPEND_CHAR(CUR_CHAR); NEXT();
+                               _currentline++;
+                               break;
+                       case _SC('\\'):
+                               if(verbatim) {
+                                       APPEND_CHAR('\\'); NEXT();
+                               }
+                               else {
+                                       NEXT();
+                                       switch(CUR_CHAR) {
+                                       case _SC('x'): NEXT(); {
+                                               if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected"));
+                                               const SQInteger maxdigits = 4;
+                                               SQChar temp[maxdigits+1];
+                                               SQInteger 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;
+                                       case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break;
+                                       case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break;
+                                       case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break;
+                                       case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break;
+                                       case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break;
+                                       case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break;
+                                       case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break;
+                                       case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break;
+                                       default:
+                                               Error(_SC("unrecognised escaper char"));
+                                       break;
+                                       }
+                               }
+                               break;
+                       default:
+                               APPEND_CHAR(CUR_CHAR);
+                               NEXT();
+                       }
+               }
+               NEXT();
+               if(verbatim && CUR_CHAR == '"') { //double quotation
+                       APPEND_CHAR(CUR_CHAR);
+                       NEXT();
+               }
+               else {
+                       break;
+               }
+       }
+       TERMINATE_BUFFER();
+       SQInteger len = _longstr.size()-1;
+       if(ndelim == _SC('\'')) {
+               if(len == 0) Error(_SC("empty constant"));
+               if(len > 1) Error(_SC("constant too long"));
+               _nvalue = _longstr[0];
+               return TK_INTEGER;
+       }
+       _svalue = &_longstr[0];
+       return TK_STRING_LITERAL;
+}
+
+void LexHexadecimal(const SQChar *s,SQUnsignedInteger *res)
+{
+       *res = 0;
+       while(*s != 0)
+       {
+               if(scisdigit(*s)) *res = (*res)*16+((*s++)-'0');
+               else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-'A'+10);
+               else { assert(0); }
+       }
+}
+
+void LexInteger(const SQChar *s,SQUnsignedInteger *res)
+{
+       *res = 0;
+       while(*s != 0)
+       {
+               *res = (*res)*10+((*s++)-'0');
+       }
+}
+
+SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; }
+#define MAX_HEX_DIGITS (sizeof(SQInteger)*2)
+SQInteger SQLexer::ReadNumber()
+{
+#define TINT 1
+#define TFLOAT 2
+#define THEX 3
+#define TSCIENTIFIC 4
+       SQInteger type = TINT, firstchar = CUR_CHAR;
+       SQChar *sTemp;
+       INIT_TEMP_STRING();
+       NEXT();
+       if(firstchar == _SC('0') && toupper(CUR_CHAR) == _SC('X')) {
+               NEXT();
+               type = THEX;
+               while(isxdigit(CUR_CHAR)) {
+                       APPEND_CHAR(CUR_CHAR);
+                       NEXT();
+               }
+               if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number"));
+       }
+       else {
+               APPEND_CHAR((int)firstchar);
+               while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) {
+            if(CUR_CHAR == _SC('.')) type = TFLOAT;
+                       if(isexponent(CUR_CHAR)) {
+                               if(type != TFLOAT) Error(_SC("invalid numeric format"));
+                               type = TSCIENTIFIC;
+                               APPEND_CHAR(CUR_CHAR);
+                               NEXT();
+                               if(CUR_CHAR == '+' || CUR_CHAR == '-'){
+                                       APPEND_CHAR(CUR_CHAR);
+                                       NEXT();
+                               }
+                               if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected"));
+                       }
+
+                       APPEND_CHAR(CUR_CHAR);
+                       NEXT();
+               }
+       }
+       TERMINATE_BUFFER();
+       switch(type) {
+       case TSCIENTIFIC:
+       case TFLOAT:
+               _fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp);
+               return TK_FLOAT;
+       case TINT:
+               LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
+               return TK_INTEGER;
+       case THEX:
+               LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
+               return TK_INTEGER;
+       }
+       return 0;
+}
+
+SQInteger SQLexer::ReadID()
+{
+       SQInteger res;
+       INIT_TEMP_STRING();
+       do {
+               APPEND_CHAR(CUR_CHAR);
+               NEXT();
+       } while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_'));
+       TERMINATE_BUFFER();
+       res = GetIDType(&_longstr[0]);
+       if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) {
+               _svalue = &_longstr[0];
+       }
+       return res;
+}
index be3b188..52993e5 100644 (file)
@@ -1,45 +1,45 @@
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQLEXER_H_\r
-#define _SQLEXER_H_\r
-\r
-#ifdef _UNICODE\r
-typedef SQChar LexChar;\r
-#else\r
-typedef        unsigned char LexChar;\r
-#endif\r
-\r
-struct SQLexer\r
-{\r
-       SQLexer();\r
-       ~SQLexer();\r
-       void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed);\r
-       void Error(const SQChar *err);\r
-       SQInteger Lex();\r
-       const SQChar *Tok2Str(SQInteger tok);\r
-private:\r
-       SQInteger GetIDType(SQChar *s);\r
-       SQInteger ReadString(SQInteger ndelim,bool verbatim);\r
-       SQInteger ReadNumber();\r
-       void LexBlockComment();\r
-       SQInteger ReadID();\r
-       void Next();\r
-       SQInteger _curtoken;\r
-       SQTable *_keywords;\r
-public:\r
-       SQInteger _prevtoken;\r
-       SQInteger _currentline;\r
-       SQInteger _lasttokenline;\r
-       SQInteger _currentcolumn;\r
-       const SQChar *_svalue;\r
-       SQInteger _nvalue;\r
-       SQFloat _fvalue;\r
-       SQLEXREADFUNC _readf;\r
-       SQUserPointer _up;\r
-       LexChar _currdata;\r
-       SQSharedState *_sharedstate;\r
-       sqvector<SQChar> _longstr;\r
-       CompilerErrorFunc _errfunc;\r
-       void *_errtarget;\r
-};\r
-\r
-#endif\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQLEXER_H_
+#define _SQLEXER_H_
+
+#ifdef _UNICODE
+typedef SQChar LexChar;
+#else
+typedef        unsigned char LexChar;
+#endif
+
+struct SQLexer
+{
+       SQLexer();
+       ~SQLexer();
+       void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed);
+       void Error(const SQChar *err);
+       SQInteger Lex();
+       const SQChar *Tok2Str(SQInteger tok);
+private:
+       SQInteger GetIDType(SQChar *s);
+       SQInteger ReadString(SQInteger ndelim,bool verbatim);
+       SQInteger ReadNumber();
+       void LexBlockComment();
+       SQInteger ReadID();
+       void Next();
+       SQInteger _curtoken;
+       SQTable *_keywords;
+public:
+       SQInteger _prevtoken;
+       SQInteger _currentline;
+       SQInteger _lasttokenline;
+       SQInteger _currentcolumn;
+       const SQChar *_svalue;
+       SQInteger _nvalue;
+       SQFloat _fvalue;
+       SQLEXREADFUNC _readf;
+       SQUserPointer _up;
+       LexChar _currdata;
+       SQSharedState *_sharedstate;
+       sqvector<SQChar> _longstr;
+       CompilerErrorFunc _errfunc;
+       void *_errtarget;
+};
+
+#endif
index 520f7eb..6faf816 100644 (file)
@@ -1,9 +1,9 @@
-/*\r
-       see copyright notice in squirrel.h\r
-*/\r
-#include "sqpcheader.h"\r
-void *sq_vm_malloc(SQUnsignedInteger size){    return malloc(size); }\r
-\r
-void *sq_vm_realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger size){ return realloc(p, size); }\r
-\r
-void sq_vm_free(void *p, SQUnsignedInteger size){      free(p); }\r
+/*
+       see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+void *sq_vm_malloc(SQUnsignedInteger size){    return malloc(size); }
+
+void *sq_vm_realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger size){ return realloc(p, size); }
+
+void sq_vm_free(void *p, SQUnsignedInteger size){      free(p); }
index f01ce93..e699e35 100644 (file)
-/*\r
-       see copyright notice in squirrel.h\r
-*/\r
-#include "sqpcheader.h"\r
-#include "sqvm.h"\r
-#include "sqstring.h"\r
-#include "sqarray.h"\r
-#include "sqtable.h"\r
-#include "squserdata.h"\r
-#include "sqfuncproto.h"\r
-#include "sqclass.h"\r
-#include "sqclosure.h"\r
-\r
-SQString *SQString::Create(SQSharedState *ss,const SQChar *s,SQInteger len)\r
-{\r
-       SQString *str=ADD_STRING(ss,s,len);\r
-       str->_sharedstate=ss;\r
-       return str;\r
-}\r
-\r
-void SQString::Release()\r
-{\r
-       REMOVE_STRING(_sharedstate,this);\r
-}\r
-\r
-SQInteger SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)\r
-{\r
-       SQInteger idx = (SQInteger)TranslateIndex(refpos);\r
-       while(idx < _len){\r
-               outkey = (SQInteger)idx;\r
-               outval = SQInteger(_val[idx]);\r
-               //return idx for the next iteration\r
-               return ++idx;\r
-       }\r
-       //nothing to iterate anymore\r
-       return -1;\r
-}\r
-\r
-SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx)\r
-{\r
-       switch(type(idx)){\r
-               case OT_NULL:\r
-                       return 0;\r
-               case OT_INTEGER:\r
-                       return (SQUnsignedInteger)_integer(idx);\r
-               default: assert(0); break;\r
-       }\r
-       return 0;\r
-}\r
-\r
-SQWeakRef *SQRefCounted::GetWeakRef(SQObjectType type)\r
-{\r
-       if(!_weakref) {\r
-               sq_new(_weakref,SQWeakRef);\r
-               _weakref->_obj._type = type;\r
-               _weakref->_obj._unVal.pRefCounted = this;\r
-       }\r
-       return _weakref;\r
-}\r
-\r
-SQRefCounted::~SQRefCounted()\r
-{\r
-       if(_weakref) {\r
-               _weakref->_obj._type = OT_NULL;\r
-               _weakref->_obj._unVal.pRefCounted = NULL;\r
-       }\r
-}\r
-\r
-void SQWeakRef::Release() { \r
-       if(ISREFCOUNTED(_obj._type)) { \r
-               _obj._unVal.pRefCounted->_weakref = NULL;\r
-       } \r
-       sq_delete(this,SQWeakRef);\r
-}\r
-\r
-bool SQDelegable::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) {\r
-       if(_delegate) {\r
-               return _delegate->Get((*_ss(v)->_metamethods)[mm],res);\r
-       }\r
-       return false;\r
-}\r
-\r
-bool SQDelegable::SetDelegate(SQTable *mt)\r
-{\r
-       SQTable *temp = mt;\r
-       while (temp) {\r
-               if (temp->_delegate == this) return false; //cycle detected\r
-               temp = temp->_delegate;\r
-       }\r
-       if (mt) __ObjAddRef(mt);\r
-       __ObjRelease(_delegate);\r
-       _delegate = mt;\r
-       return true;\r
-}\r
-\r
-bool SQGenerator::Yield(SQVM *v)\r
-{\r
-       if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator"));  return false;}\r
-       if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; }\r
-       SQInteger size = v->_top-v->_stackbase;\r
-       _ci=*v->ci;\r
-       _stack.resize(size);\r
-       for(SQInteger n =0; n<size; n++) {\r
-               _stack._vals[n] = v->_stack[v->_stackbase+n];\r
-               v->_stack[v->_stackbase+n] = _null_;\r
-       }\r
-       SQInteger nvargs = v->ci->_vargs.size;\r
-       SQInteger vargsbase = v->ci->_vargs.base;\r
-       for(SQInteger j = nvargs - 1; j >= 0; j--) {\r
-               _vargsstack.push_back(v->_vargsstack[vargsbase+j]);\r
-       }\r
-       _ci._generator=_null_;\r
-       for(SQInteger i=0;i<_ci._etraps;i++) {\r
-               _etraps.push_back(v->_etraps.top());\r
-               v->_etraps.pop_back();\r
-       }\r
-       _state=eSuspended;\r
-       return true;\r
-}\r
-\r
-bool SQGenerator::Resume(SQVM *v,SQInteger target)\r
-{\r
-       SQInteger size=_stack.size();\r
-       if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; }\r
-       if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; }\r
-       SQInteger prevtop=v->_top-v->_stackbase;\r
-       PUSH_CALLINFO(v,_ci);\r
-       SQInteger oldstackbase=v->_stackbase;\r
-       v->_stackbase=v->_top;\r
-       v->ci->_target=target;\r
-       v->ci->_generator=SQObjectPtr(this);\r
-       v->ci->_vargs.size = _vargsstack.size();\r
-       \r
-       for(SQInteger i=0;i<_ci._etraps;i++) {\r
-               v->_etraps.push_back(_etraps.top());\r
-               _etraps.pop_back();\r
-       }\r
-       for(SQInteger n =0; n<size; n++) {\r
-               v->_stack[v->_stackbase+n] = _stack._vals[n];\r
-               _stack._vals[0] = _null_;\r
-       }\r
-       while(_vargsstack.size()) {\r
-               v->_vargsstack.push_back(_vargsstack.back());\r
-               _vargsstack.pop_back();\r
-       }\r
-       v->ci->_vargs.base = v->_vargsstack.size() - v->ci->_vargs.size;\r
-       v->_top=v->_stackbase+size;\r
-       v->ci->_prevtop=prevtop;\r
-       v->ci->_prevstkbase=v->_stackbase-oldstackbase;\r
-       _state=eRunning;\r
-       return true;\r
-}\r
-\r
-void SQArray::Extend(const SQArray *a){\r
-       SQInteger xlen;\r
-       if((xlen=a->Size()))\r
-               for(SQInteger i=0;i<xlen;i++)\r
-                       Append(a->_values[i]);\r
-}\r
-\r
-const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop)\r
-{\r
-       SQUnsignedInteger nvars=_localvarinfos.size();\r
-       const SQChar *res=NULL; \r
-       if(nvars>=nseq){\r
-               for(SQUnsignedInteger i=0;i<nvars;i++){\r
-                       if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop)\r
-                       {\r
-                               if(nseq==0){\r
-                                       vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]);\r
-                                       res=_stringval(_localvarinfos[i]._name);\r
-                                       break;\r
-                               }\r
-                               nseq--;\r
-                       }\r
-               }\r
-       }\r
-       return res;\r
-}\r
-\r
-SQInteger SQFunctionProto::GetLine(SQInstruction *curr)\r
-{\r
-       SQInteger op = (SQInteger)(curr-_instructions._vals);\r
-       SQInteger line=_lineinfos[0]._line;\r
-       for(SQUnsignedInteger i=1;i<_lineinfos.size();i++){\r
-               if(_lineinfos[i]._op>=op)\r
-                       return line;\r
-               line=_lineinfos[i]._line;\r
-       }\r
-       return line;\r
-}\r
-\r
-//#define _ERROR_TRAP() error_trap:\r
-#define _CHECK_IO(exp)  { if(!exp)return false; }\r
-bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size)\r
-{\r
-       if(write(up,dest,size) != size) {\r
-               v->Raise_Error(_SC("io error (write function failure)"));\r
-               return false;\r
-       }\r
-       return true;\r
-}\r
-\r
-bool SafeRead(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,SQInteger size)\r
-{\r
-       if(size && read(up,dest,size) != size) {\r
-               v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated"));\r
-               return false;\r
-       }\r
-       return true;\r
-}\r
-\r
-bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQInteger tag)\r
-{\r
-       return SafeWrite(v,write,up,&tag,sizeof(tag));\r
-}\r
-\r
-bool CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQInteger tag)\r
-{\r
-       SQInteger t;\r
-       _CHECK_IO(SafeRead(v,read,up,&t,sizeof(t)));\r
-       if(t != tag){\r
-               v->Raise_Error(_SC("invalid or corrupted closure stream"));\r
-               return false;\r
-       }\r
-       return true;\r
-}\r
-\r
-bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o)\r
-{\r
-       _CHECK_IO(SafeWrite(v,write,up,&type(o),sizeof(SQObjectType)));\r
-       switch(type(o)){\r
-       case OT_STRING:\r
-               _CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger)));\r
-               _CHECK_IO(SafeWrite(v,write,up,_stringval(o),rsl(_string(o)->_len)));\r
-               break;\r
-       case OT_INTEGER:\r
-               _CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break;\r
-       case OT_FLOAT:\r
-               _CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(SQFloat)));break;\r
-       case OT_NULL:\r
-               break;\r
-       default:\r
-               v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o));\r
-               return false;\r
-       }\r
-       return true;\r
-}\r
-\r
-bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o)\r
-{\r
-       SQObjectType t;\r
-       _CHECK_IO(SafeRead(v,read,up,&t,sizeof(SQObjectType)));\r
-       switch(t){\r
-       case OT_STRING:{\r
-               SQInteger len;\r
-               _CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger)));\r
-               _CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(rsl(len)),rsl(len)));\r
-               o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len);\r
-                                  }\r
-               break;\r
-       case OT_INTEGER:{\r
-               SQInteger i;\r
-               _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break;\r
-                                       }\r
-       case OT_FLOAT:{\r
-               SQFloat f;\r
-               _CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break;\r
-                                 }\r
-       case OT_NULL:\r
-               o=_null_;\r
-               break;\r
-       default:\r
-               v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t));\r
-               return false;\r
-       }\r
-       return true;\r
-}\r
-\r
-bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)\r
-{\r
-       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD));\r
-       _CHECK_IO(WriteTag(v,write,up,sizeof(SQChar)));\r
-       _CHECK_IO(_funcproto(_function)->Save(v,up,write));\r
-       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL));\r
-       return true;\r
-}\r
-\r
-bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read)\r
-{\r
-       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD));\r
-       _CHECK_IO(CheckTag(v,read,up,sizeof(SQChar)));\r
-       _CHECK_IO(_funcproto(_function)->Load(v,up,read));\r
-       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL));\r
-       return true;\r
-}\r
-\r
-bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)\r
-{\r
-       SQInteger i,nsize=_literals.size();\r
-       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));\r
-       _CHECK_IO(WriteObject(v,up,write,_sourcename));\r
-       _CHECK_IO(WriteObject(v,up,write,_name));\r
-       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));\r
-       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));\r
-       for(i=0;i<nsize;i++){\r
-               _CHECK_IO(WriteObject(v,up,write,_literals[i]));\r
-       }\r
-       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));\r
-       nsize=_parameters.size();\r
-       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));\r
-       for(i=0;i<nsize;i++){\r
-               _CHECK_IO(WriteObject(v,up,write,_parameters[i]));\r
-       }\r
-       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));\r
-       nsize=_outervalues.size();\r
-       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));\r
-       for(i=0;i<nsize;i++){\r
-               _CHECK_IO(SafeWrite(v,write,up,&_outervalues[i]._type,sizeof(SQUnsignedInteger)));\r
-               _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._src));\r
-               _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._name));\r
-       }\r
-       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));\r
-       nsize=_localvarinfos.size();\r
-       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));\r
-       for(i=0;i<nsize;i++){\r
-               SQLocalVarInfo &lvi=_localvarinfos[i];\r
-               _CHECK_IO(WriteObject(v,up,write,lvi._name));\r
-               _CHECK_IO(SafeWrite(v,write,up,&lvi._pos,sizeof(SQUnsignedInteger)));\r
-               _CHECK_IO(SafeWrite(v,write,up,&lvi._start_op,sizeof(SQUnsignedInteger)));\r
-               _CHECK_IO(SafeWrite(v,write,up,&lvi._end_op,sizeof(SQUnsignedInteger)));\r
-       }\r
-       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));\r
-       nsize=_lineinfos.size();\r
-       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));\r
-       _CHECK_IO(SafeWrite(v,write,up,&_lineinfos[0],sizeof(SQLineInfo)*nsize));\r
-       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));\r
-       nsize=_instructions.size();\r
-       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));\r
-       _CHECK_IO(SafeWrite(v,write,up,&_instructions[0],sizeof(SQInstruction)*nsize));\r
-       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));\r
-       nsize=_functions.size();\r
-       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));\r
-       for(i=0;i<nsize;i++){\r
-               _CHECK_IO(_funcproto(_functions[i])->Save(v,up,write));\r
-       }\r
-       _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize)));\r
-       _CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator)));\r
-       _CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams)));\r
-       return true;\r
-}\r
-\r
-bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read)\r
-{\r
-       SQInteger i, nsize = _literals.size();\r
-       SQObjectPtr o;\r
-       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));\r
-       _CHECK_IO(ReadObject(v, up, read, _sourcename));\r
-       _CHECK_IO(ReadObject(v, up, read, _name));\r
-       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));\r
-       _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize)));\r
-       for(i = 0;i < nsize; i++){\r
-               _CHECK_IO(ReadObject(v, up, read, o));\r
-               _literals.push_back(o);\r
-       }\r
-       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));\r
-       _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize)));\r
-       for(i = 0; i < nsize; i++){\r
-               _CHECK_IO(ReadObject(v, up, read, o));\r
-               _parameters.push_back(o);\r
-       }\r
-       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));\r
-       _CHECK_IO(SafeRead(v,read,up,&nsize,sizeof(nsize)));\r
-       for(i = 0; i < nsize; i++){\r
-               SQUnsignedInteger type;\r
-               SQObjectPtr name;\r
-               _CHECK_IO(SafeRead(v,read,up, &type, sizeof(SQUnsignedInteger)));\r
-               _CHECK_IO(ReadObject(v, up, read, o));\r
-               _CHECK_IO(ReadObject(v, up, read, name));\r
-               _outervalues.push_back(SQOuterVar(name,o, (SQOuterType)type));\r
-       }\r
-       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));\r
-       _CHECK_IO(SafeRead(v,read,up,&nsize, sizeof(nsize)));\r
-       for(i = 0; i < nsize; i++){\r
-               SQLocalVarInfo lvi;\r
-               _CHECK_IO(ReadObject(v, up, read, lvi._name));\r
-               _CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(SQUnsignedInteger)));\r
-               _CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(SQUnsignedInteger)));\r
-               _CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(SQUnsignedInteger)));\r
-               _localvarinfos.push_back(lvi);\r
-       }\r
-       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));\r
-       _CHECK_IO(SafeRead(v,read,up, &nsize,sizeof(nsize)));\r
-       _lineinfos.resize(nsize);\r
-       _CHECK_IO(SafeRead(v,read,up, &_lineinfos[0], sizeof(SQLineInfo)*nsize));\r
-       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));\r
-       _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize)));\r
-       _instructions.resize(nsize);\r
-       _CHECK_IO(SafeRead(v,read,up, &_instructions[0], sizeof(SQInstruction)*nsize));\r
-       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));\r
-       _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize)));\r
-       for(i = 0; i < nsize; i++){\r
-               o = SQFunctionProto::Create();\r
-               _CHECK_IO(_funcproto(o)->Load(v, up, read));\r
-               _functions.push_back(o);\r
-       }\r
-       _CHECK_IO(SafeRead(v,read,up, &_stacksize, sizeof(_stacksize)));\r
-       _CHECK_IO(SafeRead(v,read,up, &_bgenerator, sizeof(_bgenerator)));\r
-       _CHECK_IO(SafeRead(v,read,up, &_varparams, sizeof(_varparams)));\r
-       return true;\r
-}\r
-\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-\r
-#define START_MARK()   if(!(_uiRef&MARK_FLAG)){ \\r
-               _uiRef|=MARK_FLAG;\r
-\r
-#define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \\r
-               AddToChain(chain, this); }\r
-\r
-void SQVM::Mark(SQCollectable **chain)\r
-{\r
-       START_MARK()\r
-               SQSharedState::MarkObject(_lasterror,chain);\r
-               SQSharedState::MarkObject(_errorhandler,chain);\r
-               SQSharedState::MarkObject(_debughook,chain);\r
-               SQSharedState::MarkObject(_roottable, chain);\r
-               SQSharedState::MarkObject(temp_reg, chain);\r
-               for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);\r
-               for(SQUnsignedInteger j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain);\r
-       END_MARK()\r
-}\r
-\r
-void SQArray::Mark(SQCollectable **chain)\r
-{\r
-       START_MARK()\r
-               SQInteger len = _values.size();\r
-               for(SQInteger i = 0;i < len; i++) SQSharedState::MarkObject(_values[i], chain);\r
-       END_MARK()\r
-}\r
-void SQTable::Mark(SQCollectable **chain)\r
-{\r
-       START_MARK()\r
-               if(_delegate) _delegate->Mark(chain);\r
-               SQInteger len = _numofnodes;\r
-               for(SQInteger i = 0; i < len; i++){\r
-                       SQSharedState::MarkObject(_nodes[i].key, chain);\r
-                       SQSharedState::MarkObject(_nodes[i].val, chain);\r
-               }\r
-       END_MARK()\r
-}\r
-\r
-void SQClass::Mark(SQCollectable **chain)\r
-{\r
-       START_MARK()\r
-               _members->Mark(chain);\r
-               if(_base) _base->Mark(chain);\r
-               SQSharedState::MarkObject(_attributes, chain);\r
-               for(SQUnsignedInteger i =0; i< _defaultvalues.size(); i++) {\r
-                       SQSharedState::MarkObject(_defaultvalues[i].val, chain);\r
-                       SQSharedState::MarkObject(_defaultvalues[i].attrs, chain);\r
-               }\r
-               for(SQUnsignedInteger j =0; j< _methods.size(); j++) {\r
-                       SQSharedState::MarkObject(_methods[j].val, chain);\r
-                       SQSharedState::MarkObject(_methods[j].attrs, chain);\r
-               }\r
-               for(SQUnsignedInteger k =0; k< _metamethods.size(); k++) {\r
-                       SQSharedState::MarkObject(_metamethods[k], chain);\r
-               }\r
-       END_MARK()\r
-}\r
-\r
-void SQInstance::Mark(SQCollectable **chain)\r
-{\r
-       START_MARK()\r
-               _class->Mark(chain);\r
-               for(SQUnsignedInteger i =0; i< _nvalues; i++) {\r
-                       SQSharedState::MarkObject(_values[i], chain);\r
-               }\r
-       END_MARK()\r
-}\r
-\r
-void SQGenerator::Mark(SQCollectable **chain)\r
-{\r
-       START_MARK()\r
-               for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);\r
-               for(SQUnsignedInteger j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain);\r
-               SQSharedState::MarkObject(_closure, chain);\r
-       END_MARK()\r
-}\r
-\r
-void SQClosure::Mark(SQCollectable **chain)\r
-{\r
-       START_MARK()\r
-               for(SQUnsignedInteger i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain);\r
-       END_MARK()\r
-}\r
-\r
-void SQNativeClosure::Mark(SQCollectable **chain)\r
-{\r
-       START_MARK()\r
-               for(SQUnsignedInteger i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain);\r
-       END_MARK()\r
-}\r
-\r
-void SQUserData::Mark(SQCollectable **chain){\r
-       START_MARK()\r
-               if(_delegate) _delegate->Mark(chain);\r
-       END_MARK()\r
-}\r
-\r
-void SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; }\r
-\r
-#endif\r
-\r
+/*
+       see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include "sqvm.h"
+#include "sqstring.h"
+#include "sqarray.h"
+#include "sqtable.h"
+#include "squserdata.h"
+#include "sqfuncproto.h"
+#include "sqclass.h"
+#include "sqclosure.h"
+
+SQString *SQString::Create(SQSharedState *ss,const SQChar *s,SQInteger len)
+{
+       SQString *str=ADD_STRING(ss,s,len);
+       str->_sharedstate=ss;
+       return str;
+}
+
+void SQString::Release()
+{
+       REMOVE_STRING(_sharedstate,this);
+}
+
+SQInteger SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
+{
+       SQInteger idx = (SQInteger)TranslateIndex(refpos);
+       while(idx < _len){
+               outkey = (SQInteger)idx;
+               outval = SQInteger(_val[idx]);
+               //return idx for the next iteration
+               return ++idx;
+       }
+       //nothing to iterate anymore
+       return -1;
+}
+
+SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx)
+{
+       switch(type(idx)){
+               case OT_NULL:
+                       return 0;
+               case OT_INTEGER:
+                       return (SQUnsignedInteger)_integer(idx);
+               default: assert(0); break;
+       }
+       return 0;
+}
+
+SQWeakRef *SQRefCounted::GetWeakRef(SQObjectType type)
+{
+       if(!_weakref) {
+               sq_new(_weakref,SQWeakRef);
+               _weakref->_obj._type = type;
+               _weakref->_obj._unVal.pRefCounted = this;
+       }
+       return _weakref;
+}
+
+SQRefCounted::~SQRefCounted()
+{
+       if(_weakref) {
+               _weakref->_obj._type = OT_NULL;
+               _weakref->_obj._unVal.pRefCounted = NULL;
+       }
+}
+
+void SQWeakRef::Release() {
+       if(ISREFCOUNTED(_obj._type)) {
+               _obj._unVal.pRefCounted->_weakref = NULL;
+       }
+       sq_delete(this,SQWeakRef);
+}
+
+bool SQDelegable::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) {
+       if(_delegate) {
+               return _delegate->Get((*_ss(v)->_metamethods)[mm],res);
+       }
+       return false;
+}
+
+bool SQDelegable::SetDelegate(SQTable *mt)
+{
+       SQTable *temp = mt;
+       while (temp) {
+               if (temp->_delegate == this) return false; //cycle detected
+               temp = temp->_delegate;
+       }
+       if (mt) __ObjAddRef(mt);
+       __ObjRelease(_delegate);
+       _delegate = mt;
+       return true;
+}
+
+bool SQGenerator::Yield(SQVM *v)
+{
+       if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator"));  return false;}
+       if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; }
+       SQInteger size = v->_top-v->_stackbase;
+       _ci=*v->ci;
+       _stack.resize(size);
+       for(SQInteger n =0; n<size; n++) {
+               _stack._vals[n] = v->_stack[v->_stackbase+n];
+               v->_stack[v->_stackbase+n] = _null_;
+       }
+       SQInteger nvargs = v->ci->_vargs.size;
+       SQInteger vargsbase = v->ci->_vargs.base;
+       for(SQInteger j = nvargs - 1; j >= 0; j--) {
+               _vargsstack.push_back(v->_vargsstack[vargsbase+j]);
+       }
+       _ci._generator=_null_;
+       for(SQInteger i=0;i<_ci._etraps;i++) {
+               _etraps.push_back(v->_etraps.top());
+               v->_etraps.pop_back();
+       }
+       _state=eSuspended;
+       return true;
+}
+
+bool SQGenerator::Resume(SQVM *v,SQInteger target)
+{
+       SQInteger size=_stack.size();
+       if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; }
+       if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; }
+       SQInteger prevtop=v->_top-v->_stackbase;
+       PUSH_CALLINFO(v,_ci);
+       SQInteger oldstackbase=v->_stackbase;
+       v->_stackbase=v->_top;
+       v->ci->_target=target;
+       v->ci->_generator=SQObjectPtr(this);
+       v->ci->_vargs.size = _vargsstack.size();
+
+       for(SQInteger i=0;i<_ci._etraps;i++) {
+               v->_etraps.push_back(_etraps.top());
+               _etraps.pop_back();
+       }
+       for(SQInteger n =0; n<size; n++) {
+               v->_stack[v->_stackbase+n] = _stack._vals[n];
+               _stack._vals[0] = _null_;
+       }
+       while(_vargsstack.size()) {
+               v->_vargsstack.push_back(_vargsstack.back());
+               _vargsstack.pop_back();
+       }
+       v->ci->_vargs.base = v->_vargsstack.size() - v->ci->_vargs.size;
+       v->_top=v->_stackbase+size;
+       v->ci->_prevtop=prevtop;
+       v->ci->_prevstkbase=v->_stackbase-oldstackbase;
+       _state=eRunning;
+       return true;
+}
+
+void SQArray::Extend(const SQArray *a){
+       SQInteger xlen;
+       if((xlen=a->Size()))
+               for(SQInteger i=0;i<xlen;i++)
+                       Append(a->_values[i]);
+}
+
+const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop)
+{
+       SQUnsignedInteger nvars=_localvarinfos.size();
+       const SQChar *res=NULL;
+       if(nvars>=nseq){
+               for(SQUnsignedInteger i=0;i<nvars;i++){
+                       if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop)
+                       {
+                               if(nseq==0){
+                                       vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]);
+                                       res=_stringval(_localvarinfos[i]._name);
+                                       break;
+                               }
+                               nseq--;
+                       }
+               }
+       }
+       return res;
+}
+
+SQInteger SQFunctionProto::GetLine(SQInstruction *curr)
+{
+       SQInteger op = (SQInteger)(curr-_instructions._vals);
+       SQInteger line=_lineinfos[0]._line;
+       for(SQUnsignedInteger i=1;i<_lineinfos.size();i++){
+               if(_lineinfos[i]._op>=op)
+                       return line;
+               line=_lineinfos[i]._line;
+       }
+       return line;
+}
+
+//#define _ERROR_TRAP() error_trap:
+#define _CHECK_IO(exp)  { if(!exp)return false; }
+bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size)
+{
+       if(write(up,dest,size) != size) {
+               v->Raise_Error(_SC("io error (write function failure)"));
+               return false;
+       }
+       return true;
+}
+
+bool SafeRead(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,SQInteger size)
+{
+       if(size && read(up,dest,size) != size) {
+               v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated"));
+               return false;
+       }
+       return true;
+}
+
+bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQInteger tag)
+{
+       return SafeWrite(v,write,up,&tag,sizeof(tag));
+}
+
+bool CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQInteger tag)
+{
+       SQInteger t;
+       _CHECK_IO(SafeRead(v,read,up,&t,sizeof(t)));
+       if(t != tag){
+               v->Raise_Error(_SC("invalid or corrupted closure stream"));
+               return false;
+       }
+       return true;
+}
+
+bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o)
+{
+       _CHECK_IO(SafeWrite(v,write,up,&type(o),sizeof(SQObjectType)));
+       switch(type(o)){
+       case OT_STRING:
+               _CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger)));
+               _CHECK_IO(SafeWrite(v,write,up,_stringval(o),rsl(_string(o)->_len)));
+               break;
+       case OT_INTEGER:
+               _CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break;
+       case OT_FLOAT:
+               _CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(SQFloat)));break;
+       case OT_NULL:
+               break;
+       default:
+               v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o));
+               return false;
+       }
+       return true;
+}
+
+bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o)
+{
+       SQObjectType t;
+       _CHECK_IO(SafeRead(v,read,up,&t,sizeof(SQObjectType)));
+       switch(t){
+       case OT_STRING:{
+               SQInteger len;
+               _CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger)));
+               _CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(rsl(len)),rsl(len)));
+               o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len);
+                                  }
+               break;
+       case OT_INTEGER:{
+               SQInteger i;
+               _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break;
+                                       }
+       case OT_FLOAT:{
+               SQFloat f;
+               _CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break;
+                                 }
+       case OT_NULL:
+               o=_null_;
+               break;
+       default:
+               v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t));
+               return false;
+       }
+       return true;
+}
+
+bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
+{
+       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD));
+       _CHECK_IO(WriteTag(v,write,up,sizeof(SQChar)));
+       _CHECK_IO(_funcproto(_function)->Save(v,up,write));
+       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL));
+       return true;
+}
+
+bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read)
+{
+       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD));
+       _CHECK_IO(CheckTag(v,read,up,sizeof(SQChar)));
+       _CHECK_IO(_funcproto(_function)->Load(v,up,read));
+       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL));
+       return true;
+}
+
+bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
+{
+       SQInteger i,nsize=_literals.size();
+       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
+       _CHECK_IO(WriteObject(v,up,write,_sourcename));
+       _CHECK_IO(WriteObject(v,up,write,_name));
+       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
+       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
+       for(i=0;i<nsize;i++){
+               _CHECK_IO(WriteObject(v,up,write,_literals[i]));
+       }
+       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
+       nsize=_parameters.size();
+       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
+       for(i=0;i<nsize;i++){
+               _CHECK_IO(WriteObject(v,up,write,_parameters[i]));
+       }
+       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
+       nsize=_outervalues.size();
+       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
+       for(i=0;i<nsize;i++){
+               _CHECK_IO(SafeWrite(v,write,up,&_outervalues[i]._type,sizeof(SQUnsignedInteger)));
+               _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._src));
+               _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._name));
+       }
+       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
+       nsize=_localvarinfos.size();
+       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
+       for(i=0;i<nsize;i++){
+               SQLocalVarInfo &lvi=_localvarinfos[i];
+               _CHECK_IO(WriteObject(v,up,write,lvi._name));
+               _CHECK_IO(SafeWrite(v,write,up,&lvi._pos,sizeof(SQUnsignedInteger)));
+               _CHECK_IO(SafeWrite(v,write,up,&lvi._start_op,sizeof(SQUnsignedInteger)));
+               _CHECK_IO(SafeWrite(v,write,up,&lvi._end_op,sizeof(SQUnsignedInteger)));
+       }
+       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
+       nsize=_lineinfos.size();
+       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
+       _CHECK_IO(SafeWrite(v,write,up,&_lineinfos[0],sizeof(SQLineInfo)*nsize));
+       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
+       nsize=_instructions.size();
+       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
+       _CHECK_IO(SafeWrite(v,write,up,&_instructions[0],sizeof(SQInstruction)*nsize));
+       _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
+       nsize=_functions.size();
+       _CHECK_IO(SafeWrite(v,write,up,&nsize,sizeof(nsize)));
+       for(i=0;i<nsize;i++){
+               _CHECK_IO(_funcproto(_functions[i])->Save(v,up,write));
+       }
+       _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize)));
+       _CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator)));
+       _CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams)));
+       return true;
+}
+
+bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read)
+{
+       SQInteger i, nsize = _literals.size();
+       SQObjectPtr o;
+       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
+       _CHECK_IO(ReadObject(v, up, read, _sourcename));
+       _CHECK_IO(ReadObject(v, up, read, _name));
+       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
+       _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize)));
+       for(i = 0;i < nsize; i++){
+               _CHECK_IO(ReadObject(v, up, read, o));
+               _literals.push_back(o);
+       }
+       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
+       _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize)));
+       for(i = 0; i < nsize; i++){
+               _CHECK_IO(ReadObject(v, up, read, o));
+               _parameters.push_back(o);
+       }
+       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
+       _CHECK_IO(SafeRead(v,read,up,&nsize,sizeof(nsize)));
+       for(i = 0; i < nsize; i++){
+               SQUnsignedInteger type;
+               SQObjectPtr name;
+               _CHECK_IO(SafeRead(v,read,up, &type, sizeof(SQUnsignedInteger)));
+               _CHECK_IO(ReadObject(v, up, read, o));
+               _CHECK_IO(ReadObject(v, up, read, name));
+               _outervalues.push_back(SQOuterVar(name,o, (SQOuterType)type));
+       }
+       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
+       _CHECK_IO(SafeRead(v,read,up,&nsize, sizeof(nsize)));
+       for(i = 0; i < nsize; i++){
+               SQLocalVarInfo lvi;
+               _CHECK_IO(ReadObject(v, up, read, lvi._name));
+               _CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(SQUnsignedInteger)));
+               _CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(SQUnsignedInteger)));
+               _CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(SQUnsignedInteger)));
+               _localvarinfos.push_back(lvi);
+       }
+       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
+       _CHECK_IO(SafeRead(v,read,up, &nsize,sizeof(nsize)));
+       _lineinfos.resize(nsize);
+       _CHECK_IO(SafeRead(v,read,up, &_lineinfos[0], sizeof(SQLineInfo)*nsize));
+       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
+       _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize)));
+       _instructions.resize(nsize);
+       _CHECK_IO(SafeRead(v,read,up, &_instructions[0], sizeof(SQInstruction)*nsize));
+       _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
+       _CHECK_IO(SafeRead(v,read,up, &nsize, sizeof(nsize)));
+       for(i = 0; i < nsize; i++){
+               o = SQFunctionProto::Create();
+               _CHECK_IO(_funcproto(o)->Load(v, up, read));
+               _functions.push_back(o);
+       }
+       _CHECK_IO(SafeRead(v,read,up, &_stacksize, sizeof(_stacksize)));
+       _CHECK_IO(SafeRead(v,read,up, &_bgenerator, sizeof(_bgenerator)));
+       _CHECK_IO(SafeRead(v,read,up, &_varparams, sizeof(_varparams)));
+       return true;
+}
+
+#ifndef NO_GARBAGE_COLLECTOR
+
+#define START_MARK()   if(!(_uiRef&MARK_FLAG)){ \
+               _uiRef|=MARK_FLAG;
+
+#define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \
+               AddToChain(chain, this); }
+
+void SQVM::Mark(SQCollectable **chain)
+{
+       START_MARK()
+               SQSharedState::MarkObject(_lasterror,chain);
+               SQSharedState::MarkObject(_errorhandler,chain);
+               SQSharedState::MarkObject(_debughook,chain);
+               SQSharedState::MarkObject(_roottable, chain);
+               SQSharedState::MarkObject(temp_reg, chain);
+               for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);
+               for(SQUnsignedInteger j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain);
+       END_MARK()
+}
+
+void SQArray::Mark(SQCollectable **chain)
+{
+       START_MARK()
+               SQInteger len = _values.size();
+               for(SQInteger i = 0;i < len; i++) SQSharedState::MarkObject(_values[i], chain);
+       END_MARK()
+}
+void SQTable::Mark(SQCollectable **chain)
+{
+       START_MARK()
+               if(_delegate) _delegate->Mark(chain);
+               SQInteger len = _numofnodes;
+               for(SQInteger i = 0; i < len; i++){
+                       SQSharedState::MarkObject(_nodes[i].key, chain);
+                       SQSharedState::MarkObject(_nodes[i].val, chain);
+               }
+       END_MARK()
+}
+
+void SQClass::Mark(SQCollectable **chain)
+{
+       START_MARK()
+               _members->Mark(chain);
+               if(_base) _base->Mark(chain);
+               SQSharedState::MarkObject(_attributes, chain);
+               for(SQUnsignedInteger i =0; i< _defaultvalues.size(); i++) {
+                       SQSharedState::MarkObject(_defaultvalues[i].val, chain);
+                       SQSharedState::MarkObject(_defaultvalues[i].attrs, chain);
+               }
+               for(SQUnsignedInteger j =0; j< _methods.size(); j++) {
+                       SQSharedState::MarkObject(_methods[j].val, chain);
+                       SQSharedState::MarkObject(_methods[j].attrs, chain);
+               }
+               for(SQUnsignedInteger k =0; k< _metamethods.size(); k++) {
+                       SQSharedState::MarkObject(_metamethods[k], chain);
+               }
+       END_MARK()
+}
+
+void SQInstance::Mark(SQCollectable **chain)
+{
+       START_MARK()
+               _class->Mark(chain);
+               for(SQUnsignedInteger i =0; i< _nvalues; i++) {
+                       SQSharedState::MarkObject(_values[i], chain);
+               }
+       END_MARK()
+}
+
+void SQGenerator::Mark(SQCollectable **chain)
+{
+       START_MARK()
+               for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);
+               for(SQUnsignedInteger j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain);
+               SQSharedState::MarkObject(_closure, chain);
+       END_MARK()
+}
+
+void SQClosure::Mark(SQCollectable **chain)
+{
+       START_MARK()
+               for(SQUnsignedInteger i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain);
+       END_MARK()
+}
+
+void SQNativeClosure::Mark(SQCollectable **chain)
+{
+       START_MARK()
+               for(SQUnsignedInteger i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain);
+       END_MARK()
+}
+
+void SQUserData::Mark(SQCollectable **chain){
+       START_MARK()
+               if(_delegate) _delegate->Mark(chain);
+       END_MARK()
+}
+
+void SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; }
+
+#endif
index c448913..ee655b0 100644 (file)
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQOBJECT_H_\r
-#define _SQOBJECT_H_\r
-\r
-#include "squtils.h"\r
-\r
-#define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R'))\r
-#define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T'))\r
-#define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L'))\r
-\r
-struct SQSharedState;\r
-\r
-enum SQMetaMethod{\r
-       MT_ADD=0,\r
-       MT_SUB=1,\r
-       MT_MUL=2,\r
-       MT_DIV=3,\r
-       MT_UNM=4,\r
-       MT_MODULO=5,\r
-       MT_SET=6,\r
-       MT_GET=7,\r
-       MT_TYPEOF=8,\r
-       MT_NEXTI=9,\r
-       MT_CMP=10,\r
-       MT_CALL=11,\r
-       MT_CLONED=12,\r
-       MT_NEWSLOT=13,\r
-       MT_DELSLOT=14,\r
-       MT_TOSTRING=15,\r
-       MT_NEWMEMBER=16,\r
-       MT_INHERITED=17,\r
-       MT_LAST = 18\r
-};\r
-\r
-#define MM_ADD         _SC("_add")\r
-#define MM_SUB         _SC("_sub")\r
-#define MM_MUL         _SC("_mul")\r
-#define MM_DIV         _SC("_div")\r
-#define MM_UNM         _SC("_unm")\r
-#define MM_MODULO      _SC("_modulo")\r
-#define MM_SET         _SC("_set")\r
-#define MM_GET         _SC("_get")\r
-#define MM_TYPEOF      _SC("_typeof")\r
-#define MM_NEXTI       _SC("_nexti")\r
-#define MM_CMP         _SC("_cmp")\r
-#define MM_CALL                _SC("_call")\r
-#define MM_CLONED      _SC("_cloned")\r
-#define MM_NEWSLOT     _SC("_newslot")\r
-#define MM_DELSLOT     _SC("_delslot")\r
-#define MM_TOSTRING    _SC("_tostring")\r
-#define MM_NEWMEMBER _SC("_newmember")\r
-#define MM_INHERITED _SC("_inherited")\r
-\r
-#define MINPOWER2 4\r
-\r
-struct SQRefCounted\r
-{\r
-       SQRefCounted() { _uiRef = 0; _weakref = NULL; }\r
-       virtual ~SQRefCounted();\r
-       SQWeakRef *GetWeakRef(SQObjectType type);\r
-       SQUnsignedInteger _uiRef;\r
-       struct SQWeakRef *_weakref;\r
-       virtual void Release()=0;\r
-};\r
-\r
-struct SQWeakRef : SQRefCounted\r
-{\r
-       void Release();\r
-       SQObject _obj;\r
-};\r
-\r
-#define _realval(o) (type((o)) != OT_WEAKREF?(SQObject)o:_weakref(o)->_obj)\r
-\r
-struct SQObjectPtr;\r
-\r
-#define __AddRef(type,unval) if(ISREFCOUNTED(type))    \\r
-               { \\r
-                       unval.pRefCounted->_uiRef++; \\r
-               }  \r
-\r
-#define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)<=0))     \\r
-               {       \\r
-                       unval.pRefCounted->Release();   \\r
-               }\r
-\r
-#define __ObjRelease(obj) { \\r
-       if((obj)) {     \\r
-               (obj)->_uiRef--; \\r
-               if((obj)->_uiRef == 0) \\r
-                       (obj)->Release(); \\r
-               (obj) = NULL;   \\r
-       } \\r
-}\r
-\r
-#define __ObjAddRef(obj) { \\r
-       (obj)->_uiRef++; \\r
-}\r
-\r
-#define type(obj) ((obj)._type)\r
-#define is_delegable(t) (type(t)&SQOBJECT_DELEGABLE)\r
-#define raw_type(obj) _RAW_TYPE((obj)._type)\r
-\r
-#define _integer(obj) ((obj)._unVal.nInteger)\r
-#define _float(obj) ((obj)._unVal.fFloat)\r
-#define _string(obj) ((obj)._unVal.pString)\r
-#define _table(obj) ((obj)._unVal.pTable)\r
-#define _array(obj) ((obj)._unVal.pArray)\r
-#define _closure(obj) ((obj)._unVal.pClosure)\r
-#define _generator(obj) ((obj)._unVal.pGenerator)\r
-#define _nativeclosure(obj) ((obj)._unVal.pNativeClosure)\r
-#define _userdata(obj) ((obj)._unVal.pUserData)\r
-#define _userpointer(obj) ((obj)._unVal.pUserPointer)\r
-#define _thread(obj) ((obj)._unVal.pThread)\r
-#define _funcproto(obj) ((obj)._unVal.pFunctionProto)\r
-#define _class(obj) ((obj)._unVal.pClass)\r
-#define _instance(obj) ((obj)._unVal.pInstance)\r
-#define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable)\r
-#define _weakref(obj) ((obj)._unVal.pWeakRef)\r
-#define _refcounted(obj) ((obj)._unVal.pRefCounted)\r
-#define _rawval(obj) ((obj)._unVal.pRefCounted)\r
-\r
-#define _stringval(obj) (obj)._unVal.pString->_val\r
-#define _userdataval(obj) (obj)._unVal.pUserData->_val\r
-\r
-#define tofloat(num) ((type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num))\r
-#define tointeger(num) ((type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num))\r
-/////////////////////////////////////////////////////////////////////////////////////\r
-/////////////////////////////////////////////////////////////////////////////////////\r
-struct SQObjectPtr : public SQObject\r
-{\r
-       SQObjectPtr()\r
-       {\r
-               _type=OT_NULL;\r
-               _unVal.pUserPointer=NULL;\r
-       }\r
-       SQObjectPtr(const SQObjectPtr &o)\r
-       {\r
-               _type=o._type;\r
-               _unVal=o._unVal;\r
-               __AddRef(_type,_unVal);\r
-       }\r
-       SQObjectPtr(const SQObject &o)\r
-       {\r
-               _type=o._type;\r
-               _unVal=o._unVal;\r
-               __AddRef(_type,_unVal);\r
-       }\r
-       SQObjectPtr(SQTable *pTable)\r
-       {\r
-               _type=OT_TABLE;\r
-               _unVal.pTable=pTable;\r
-               assert(_unVal.pTable);\r
-               __AddRef(_type,_unVal);\r
-       }\r
-       SQObjectPtr(SQClass *pClass)\r
-       {\r
-               _type=OT_CLASS;\r
-               _unVal.pClass=pClass;\r
-               assert(_unVal.pClass);\r
-               __AddRef(_type,_unVal);\r
-       }\r
-       SQObjectPtr(SQInstance *pInstance)\r
-       {\r
-               _type=OT_INSTANCE;\r
-               _unVal.pInstance=pInstance;\r
-               assert(_unVal.pInstance);\r
-               __AddRef(_type,_unVal);\r
-       }\r
-       SQObjectPtr(SQArray *pArray)\r
-       {\r
-               _type=OT_ARRAY;\r
-               _unVal.pArray=pArray;\r
-               assert(_unVal.pArray);\r
-               __AddRef(_type,_unVal);\r
-       }\r
-       SQObjectPtr(SQClosure *pClosure)\r
-       {\r
-               _type=OT_CLOSURE;\r
-               _unVal.pClosure=pClosure;\r
-               assert(_unVal.pClosure);\r
-               __AddRef(_type,_unVal);\r
-       }\r
-       SQObjectPtr(SQGenerator *pGenerator)\r
-       {\r
-               _type=OT_GENERATOR;\r
-               _unVal.pGenerator=pGenerator;\r
-               assert(_unVal.pGenerator);\r
-               __AddRef(_type,_unVal);\r
-       }\r
-       SQObjectPtr(SQNativeClosure *pNativeClosure)\r
-       {\r
-               _type=OT_NATIVECLOSURE;\r
-               _unVal.pNativeClosure=pNativeClosure;\r
-               assert(_unVal.pNativeClosure);\r
-               __AddRef(_type,_unVal);\r
-       }\r
-       SQObjectPtr(SQString *pString)\r
-       {\r
-               _type=OT_STRING;\r
-               _unVal.pString=pString;\r
-               assert(_unVal.pString);\r
-               __AddRef(_type,_unVal);\r
-       }\r
-       SQObjectPtr(SQUserData *pUserData)\r
-       {\r
-               _type=OT_USERDATA;\r
-               _unVal.pUserData=pUserData;\r
-               assert(_unVal.pUserData);\r
-               __AddRef(_type,_unVal);\r
-       }\r
-       SQObjectPtr(SQVM *pThread)\r
-       {\r
-               _type=OT_THREAD;\r
-               _unVal.pThread=pThread;\r
-               assert(_unVal.pThread);\r
-               __AddRef(_type,_unVal);\r
-       }\r
-       SQObjectPtr(SQWeakRef *pWeakRef)\r
-       {\r
-               _type=OT_WEAKREF;\r
-               _unVal.pWeakRef=pWeakRef;\r
-               assert(_unVal.pWeakRef);\r
-               __AddRef(_type,_unVal);\r
-       }\r
-       SQObjectPtr(SQFunctionProto *pFunctionProto)\r
-       {\r
-               _type=OT_FUNCPROTO;\r
-               _unVal.pFunctionProto=pFunctionProto;\r
-               assert(_unVal.pFunctionProto);\r
-               __AddRef(_type,_unVal);\r
-       }\r
-       SQObjectPtr(SQInteger nInteger)\r
-       {\r
-               _unVal.pUserPointer=NULL;\r
-               _type=OT_INTEGER;\r
-               _unVal.nInteger=nInteger;\r
-       }\r
-       SQObjectPtr(SQFloat fFloat)\r
-       {\r
-               _unVal.pUserPointer=NULL;\r
-               _type=OT_FLOAT;\r
-               _unVal.fFloat=fFloat;\r
-       }\r
-       SQObjectPtr(bool bBool)\r
-       {\r
-               _unVal.pUserPointer=NULL;\r
-               _type = OT_BOOL;\r
-               _unVal.nInteger = bBool?1:0;\r
-       }\r
-       SQObjectPtr(SQUserPointer pUserPointer)\r
-       {\r
-               _type=OT_USERPOINTER;\r
-               _unVal.pUserPointer=pUserPointer;\r
-       }\r
-       ~SQObjectPtr()\r
-       {\r
-               __Release(_type,_unVal);\r
-       }\r
-       inline void Null()\r
-       {\r
-               __Release(_type,_unVal);\r
-               _type=OT_NULL;\r
-               _unVal.pUserPointer=NULL;\r
-       }\r
-       inline SQObjectPtr& operator=(const SQObjectPtr& obj)\r
-       { \r
-               SQObjectType tOldType;\r
-               SQObjectValue unOldVal;\r
-               tOldType=_type;\r
-               unOldVal=_unVal;\r
-               _unVal = obj._unVal;\r
-               _type = obj._type;\r
-               __AddRef(_type,_unVal);\r
-               __Release(tOldType,unOldVal);\r
-               return *this;\r
-       }\r
-       inline SQObjectPtr& operator=(const SQObject& obj)\r
-       { \r
-               SQObjectType tOldType;\r
-               SQObjectValue unOldVal;\r
-               tOldType=_type;\r
-               unOldVal=_unVal;\r
-               _unVal = obj._unVal;\r
-               _type = obj._type;\r
-               __AddRef(_type,_unVal);\r
-               __Release(tOldType,unOldVal);\r
-               return *this;\r
-       }\r
-       private:\r
-               SQObjectPtr(const SQChar *){} //safety\r
-};\r
-/////////////////////////////////////////////////////////////////////////////////////\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-#define MARK_FLAG 0x80000000\r
-struct SQCollectable : public SQRefCounted {\r
-       SQCollectable *_next;\r
-       SQCollectable *_prev;\r
-       SQSharedState *_sharedstate;\r
-       virtual void Release()=0;\r
-       virtual void Mark(SQCollectable **chain)=0;\r
-       void UnMark();\r
-       virtual void Finalize()=0;\r
-       static void AddToChain(SQCollectable **chain,SQCollectable *c);\r
-       static void RemoveFromChain(SQCollectable **chain,SQCollectable *c);\r
-};\r
-\r
-\r
-#define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj)\r
-#define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);}\r
-#define CHAINABLE_OBJ SQCollectable\r
-#define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;}\r
-#else\r
-\r
-#define ADD_TO_CHAIN(chain,obj) ((void)0)\r
-#define REMOVE_FROM_CHAIN(chain,obj) ((void)0)\r
-#define CHAINABLE_OBJ SQRefCounted\r
-#define INIT_CHAIN() ((void)0)\r
-#endif\r
-\r
-struct SQDelegable : public CHAINABLE_OBJ {\r
-       bool SetDelegate(SQTable *m);\r
-       virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);\r
-       SQTable *_delegate;\r
-};\r
-\r
-SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx);\r
-typedef sqvector<SQObjectPtr> SQObjectPtrVec;\r
-typedef sqvector<SQInteger> SQIntVec;\r
-\r
-\r
-#endif //_SQOBJECT_H_\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQOBJECT_H_
+#define _SQOBJECT_H_
+
+#include "squtils.h"
+
+#define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R'))
+#define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T'))
+#define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L'))
+
+struct SQSharedState;
+
+enum SQMetaMethod{
+       MT_ADD=0,
+       MT_SUB=1,
+       MT_MUL=2,
+       MT_DIV=3,
+       MT_UNM=4,
+       MT_MODULO=5,
+       MT_SET=6,
+       MT_GET=7,
+       MT_TYPEOF=8,
+       MT_NEXTI=9,
+       MT_CMP=10,
+       MT_CALL=11,
+       MT_CLONED=12,
+       MT_NEWSLOT=13,
+       MT_DELSLOT=14,
+       MT_TOSTRING=15,
+       MT_NEWMEMBER=16,
+       MT_INHERITED=17,
+       MT_LAST = 18
+};
+
+#define MM_ADD         _SC("_add")
+#define MM_SUB         _SC("_sub")
+#define MM_MUL         _SC("_mul")
+#define MM_DIV         _SC("_div")
+#define MM_UNM         _SC("_unm")
+#define MM_MODULO      _SC("_modulo")
+#define MM_SET         _SC("_set")
+#define MM_GET         _SC("_get")
+#define MM_TYPEOF      _SC("_typeof")
+#define MM_NEXTI       _SC("_nexti")
+#define MM_CMP         _SC("_cmp")
+#define MM_CALL                _SC("_call")
+#define MM_CLONED      _SC("_cloned")
+#define MM_NEWSLOT     _SC("_newslot")
+#define MM_DELSLOT     _SC("_delslot")
+#define MM_TOSTRING    _SC("_tostring")
+#define MM_NEWMEMBER _SC("_newmember")
+#define MM_INHERITED _SC("_inherited")
+
+#define MINPOWER2 4
+
+struct SQRefCounted
+{
+       SQRefCounted() { _uiRef = 0; _weakref = NULL; }
+       virtual ~SQRefCounted();
+       SQWeakRef *GetWeakRef(SQObjectType type);
+       SQUnsignedInteger _uiRef;
+       struct SQWeakRef *_weakref;
+       virtual void Release()=0;
+};
+
+struct SQWeakRef : SQRefCounted
+{
+       void Release();
+       SQObject _obj;
+};
+
+#define _realval(o) (type((o)) != OT_WEAKREF?(SQObject)o:_weakref(o)->_obj)
+
+struct SQObjectPtr;
+
+#define __AddRef(type,unval) if(ISREFCOUNTED(type))    \
+               { \
+                       unval.pRefCounted->_uiRef++; \
+               }
+
+#define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)<=0))     \
+               {       \
+                       unval.pRefCounted->Release();   \
+               }
+
+#define __ObjRelease(obj) { \
+       if((obj)) {     \
+               (obj)->_uiRef--; \
+               if((obj)->_uiRef == 0) \
+                       (obj)->Release(); \
+               (obj) = NULL;   \
+       } \
+}
+
+#define __ObjAddRef(obj) { \
+       (obj)->_uiRef++; \
+}
+
+#define type(obj) ((obj)._type)
+#define is_delegable(t) (type(t)&SQOBJECT_DELEGABLE)
+#define raw_type(obj) _RAW_TYPE((obj)._type)
+
+#define _integer(obj) ((obj)._unVal.nInteger)
+#define _float(obj) ((obj)._unVal.fFloat)
+#define _string(obj) ((obj)._unVal.pString)
+#define _table(obj) ((obj)._unVal.pTable)
+#define _array(obj) ((obj)._unVal.pArray)
+#define _closure(obj) ((obj)._unVal.pClosure)
+#define _generator(obj) ((obj)._unVal.pGenerator)
+#define _nativeclosure(obj) ((obj)._unVal.pNativeClosure)
+#define _userdata(obj) ((obj)._unVal.pUserData)
+#define _userpointer(obj) ((obj)._unVal.pUserPointer)
+#define _thread(obj) ((obj)._unVal.pThread)
+#define _funcproto(obj) ((obj)._unVal.pFunctionProto)
+#define _class(obj) ((obj)._unVal.pClass)
+#define _instance(obj) ((obj)._unVal.pInstance)
+#define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable)
+#define _weakref(obj) ((obj)._unVal.pWeakRef)
+#define _refcounted(obj) ((obj)._unVal.pRefCounted)
+#define _rawval(obj) ((obj)._unVal.pRefCounted)
+
+#define _stringval(obj) (obj)._unVal.pString->_val
+#define _userdataval(obj) (obj)._unVal.pUserData->_val
+
+#define tofloat(num) ((type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num))
+#define tointeger(num) ((type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num))
+/////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////
+struct SQObjectPtr : public SQObject
+{
+       SQObjectPtr()
+       {
+               _type=OT_NULL;
+               _unVal.pUserPointer=NULL;
+       }
+       SQObjectPtr(const SQObjectPtr &o)
+       {
+               _type=o._type;
+               _unVal=o._unVal;
+               __AddRef(_type,_unVal);
+       }
+       SQObjectPtr(const SQObject &o)
+       {
+               _type=o._type;
+               _unVal=o._unVal;
+               __AddRef(_type,_unVal);
+       }
+       SQObjectPtr(SQTable *pTable)
+       {
+               _type=OT_TABLE;
+               _unVal.pTable=pTable;
+               assert(_unVal.pTable);
+               __AddRef(_type,_unVal);
+       }
+       SQObjectPtr(SQClass *pClass)
+       {
+               _type=OT_CLASS;
+               _unVal.pClass=pClass;
+               assert(_unVal.pClass);
+               __AddRef(_type,_unVal);
+       }
+       SQObjectPtr(SQInstance *pInstance)
+       {
+               _type=OT_INSTANCE;
+               _unVal.pInstance=pInstance;
+               assert(_unVal.pInstance);
+               __AddRef(_type,_unVal);
+       }
+       SQObjectPtr(SQArray *pArray)
+       {
+               _type=OT_ARRAY;
+               _unVal.pArray=pArray;
+               assert(_unVal.pArray);
+               __AddRef(_type,_unVal);
+       }
+       SQObjectPtr(SQClosure *pClosure)
+       {
+               _type=OT_CLOSURE;
+               _unVal.pClosure=pClosure;
+               assert(_unVal.pClosure);
+               __AddRef(_type,_unVal);
+       }
+       SQObjectPtr(SQGenerator *pGenerator)
+       {
+               _type=OT_GENERATOR;
+               _unVal.pGenerator=pGenerator;
+               assert(_unVal.pGenerator);
+               __AddRef(_type,_unVal);
+       }
+       SQObjectPtr(SQNativeClosure *pNativeClosure)
+       {
+               _type=OT_NATIVECLOSURE;
+               _unVal.pNativeClosure=pNativeClosure;
+               assert(_unVal.pNativeClosure);
+               __AddRef(_type,_unVal);
+       }
+       SQObjectPtr(SQString *pString)
+       {
+               _type=OT_STRING;
+               _unVal.pString=pString;
+               assert(_unVal.pString);
+               __AddRef(_type,_unVal);
+       }
+       SQObjectPtr(SQUserData *pUserData)
+       {
+               _type=OT_USERDATA;
+               _unVal.pUserData=pUserData;
+               assert(_unVal.pUserData);
+               __AddRef(_type,_unVal);
+       }
+       SQObjectPtr(SQVM *pThread)
+       {
+               _type=OT_THREAD;
+               _unVal.pThread=pThread;
+               assert(_unVal.pThread);
+               __AddRef(_type,_unVal);
+       }
+       SQObjectPtr(SQWeakRef *pWeakRef)
+       {
+               _type=OT_WEAKREF;
+               _unVal.pWeakRef=pWeakRef;
+               assert(_unVal.pWeakRef);
+               __AddRef(_type,_unVal);
+       }
+       SQObjectPtr(SQFunctionProto *pFunctionProto)
+       {
+               _type=OT_FUNCPROTO;
+               _unVal.pFunctionProto=pFunctionProto;
+               assert(_unVal.pFunctionProto);
+               __AddRef(_type,_unVal);
+       }
+       SQObjectPtr(SQInteger nInteger)
+       {
+               _unVal.pUserPointer=NULL;
+               _type=OT_INTEGER;
+               _unVal.nInteger=nInteger;
+       }
+       SQObjectPtr(SQFloat fFloat)
+       {
+               _unVal.pUserPointer=NULL;
+               _type=OT_FLOAT;
+               _unVal.fFloat=fFloat;
+       }
+       SQObjectPtr(bool bBool)
+       {
+               _unVal.pUserPointer=NULL;
+               _type = OT_BOOL;
+               _unVal.nInteger = bBool?1:0;
+       }
+       SQObjectPtr(SQUserPointer pUserPointer)
+       {
+               _type=OT_USERPOINTER;
+               _unVal.pUserPointer=pUserPointer;
+       }
+       ~SQObjectPtr()
+       {
+               __Release(_type,_unVal);
+       }
+       inline void Null()
+       {
+               __Release(_type,_unVal);
+               _type=OT_NULL;
+               _unVal.pUserPointer=NULL;
+       }
+       inline SQObjectPtr& operator=(const SQObjectPtr& obj)
+       {
+               SQObjectType tOldType;
+               SQObjectValue unOldVal;
+               tOldType=_type;
+               unOldVal=_unVal;
+               _unVal = obj._unVal;
+               _type = obj._type;
+               __AddRef(_type,_unVal);
+               __Release(tOldType,unOldVal);
+               return *this;
+       }
+       inline SQObjectPtr& operator=(const SQObject& obj)
+       {
+               SQObjectType tOldType;
+               SQObjectValue unOldVal;
+               tOldType=_type;
+               unOldVal=_unVal;
+               _unVal = obj._unVal;
+               _type = obj._type;
+               __AddRef(_type,_unVal);
+               __Release(tOldType,unOldVal);
+               return *this;
+       }
+       private:
+               SQObjectPtr(const SQChar *){} //safety
+};
+/////////////////////////////////////////////////////////////////////////////////////
+#ifndef NO_GARBAGE_COLLECTOR
+#define MARK_FLAG 0x80000000
+struct SQCollectable : public SQRefCounted {
+       SQCollectable *_next;
+       SQCollectable *_prev;
+       SQSharedState *_sharedstate;
+       virtual void Release()=0;
+       virtual void Mark(SQCollectable **chain)=0;
+       void UnMark();
+       virtual void Finalize()=0;
+       static void AddToChain(SQCollectable **chain,SQCollectable *c);
+       static void RemoveFromChain(SQCollectable **chain,SQCollectable *c);
+};
+
+
+#define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj)
+#define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);}
+#define CHAINABLE_OBJ SQCollectable
+#define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;}
+#else
+
+#define ADD_TO_CHAIN(chain,obj) ((void)0)
+#define REMOVE_FROM_CHAIN(chain,obj) ((void)0)
+#define CHAINABLE_OBJ SQRefCounted
+#define INIT_CHAIN() ((void)0)
+#endif
+
+struct SQDelegable : public CHAINABLE_OBJ {
+       bool SetDelegate(SQTable *m);
+       virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
+       SQTable *_delegate;
+};
+
+SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx);
+typedef sqvector<SQObjectPtr> SQObjectPtrVec;
+typedef sqvector<SQInteger> SQIntVec;
+
+
+#endif //_SQOBJECT_H_
index 2d0ffa6..be7fe29 100644 (file)
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQOPCODES_H_\r
-#define _SQOPCODES_H_\r
-\r
-#define MAX_FUNC_STACKSIZE 0xFF\r
-#define MAX_LITERALS ((SQInteger)0x7FFFFFFF)\r
-\r
-enum BitWiseOP {\r
-       BW_AND = 0,\r
-       BW_OR = 2,      //like ADD\r
-       BW_XOR = 3,\r
-       BW_SHIFTL = 4,\r
-       BW_SHIFTR = 5,\r
-       BW_USHIFTR = 6\r
-};\r
-\r
-enum CmpOP {\r
-       CMP_G = 0,\r
-       CMP_GE = 2,     //like ADD\r
-       CMP_L = 3,\r
-       CMP_LE = 4\r
-};\r
-enum SQOpcode\r
-{\r
-       _OP_LINE=                               0x00,   \r
-       _OP_LOAD=                               0x01,\r
-       _OP_LOADINT=                    0x02,\r
-       _OP_DLOAD=                              0x03,\r
-       _OP_TAILCALL=                   0x04,   \r
-       _OP_CALL=                               0x05,   \r
-       _OP_PREPCALL=                   0x06,   \r
-       _OP_PREPCALLK=                  0x07,   \r
-       _OP_GETK=                               0x08,   \r
-       _OP_MOVE=                               0x09,   \r
-       _OP_NEWSLOT=                    0x0A,   \r
-       _OP_DELETE=                             0x0B,   \r
-       _OP_SET=                                0x0C,   \r
-       _OP_GET=                                0x0D,\r
-       _OP_EQ=                                 0x0E,\r
-       _OP_NE=                                 0x0F,\r
-       _OP_ARITH=                              0x10,\r
-       _OP_BITW=                               0x11,\r
-       _OP_RETURN=                             0x12,   \r
-       _OP_LOADNULLS=                  0x13,   \r
-       _OP_LOADROOTTABLE=              0x14,\r
-       _OP_LOADBOOL=                   0x15,\r
-       _OP_DMOVE=                              0x16,   \r
-       _OP_JMP=                                0x17,   \r
-       _OP_JNZ=                                0x18,   \r
-       _OP_JZ=                                 0x19,   \r
-       _OP_LOADFREEVAR=                0x1A,   \r
-       _OP_VARGC=                              0x1B,   \r
-       _OP_GETVARGV=                   0x1C,   \r
-       _OP_NEWTABLE=                   0x1D,   \r
-       _OP_NEWARRAY=                   0x1E,   \r
-       _OP_APPENDARRAY=                0x1F,   \r
-       _OP_GETPARENT=                  0x20,   \r
-       _OP_COMPARITH=                  0x21,   \r
-       _OP_COMPARITHL=                 0x22,   \r
-       _OP_INC=                                0x23,   \r
-       _OP_INCL=                               0x24,   \r
-       _OP_PINC=                               0x25,   \r
-       _OP_PINCL=                              0x26,   \r
-       _OP_CMP=                                0x27,\r
-       _OP_EXISTS=                             0x28,   \r
-       _OP_INSTANCEOF=                 0x29,\r
-       _OP_AND=                                0x2A,\r
-       _OP_OR=                                 0x2B,\r
-       _OP_NEG=                                0x2C,\r
-       _OP_NOT=                                0x2D,\r
-       _OP_BWNOT=                              0x2E,   \r
-       _OP_CLOSURE=                    0x2F,   \r
-       _OP_YIELD=                              0x30,   \r
-       _OP_RESUME=                             0x31,\r
-       _OP_FOREACH=                    0x32,\r
-       _OP_DELEGATE=                   0x33,\r
-       _OP_CLONE=                              0x34,\r
-       _OP_TYPEOF=                             0x35,\r
-       _OP_PUSHTRAP=                   0x36,\r
-       _OP_POPTRAP=                    0x37,\r
-       _OP_THROW=                              0x38,\r
-       _OP_CLASS=                              0x39,\r
-       _OP_NEWSLOTA=                   0x3A\r
-};                                                       \r
-\r
-struct SQInstructionDesc {       \r
-       const SQChar *name;               \r
-};                                                       \r
-\r
-struct SQInstruction \r
-{\r
-       SQInstruction(){};\r
-       SQInstruction(SQOpcode _op,SQInteger a0=0,SQInteger a1=0,SQInteger a2=0,SQInteger a3=0)\r
-       {       op = _op;\r
-               _arg0 = (unsigned char)a0;_arg1 = (SQInt32)a1;\r
-               _arg2 = (unsigned char)a2;_arg3 = (unsigned char)a3;\r
-       }\r
-    \r
-       \r
-       SQInt32 _arg1;\r
-       unsigned char op;\r
-       unsigned char _arg0;\r
-       unsigned char _arg2;\r
-       unsigned char _arg3;\r
-};\r
-\r
-#include "squtils.h"\r
-typedef sqvector<SQInstruction> SQInstructionVec;\r
-\r
-#define NEW_SLOT_ATTRIBUTES_FLAG       0x01\r
-#define NEW_SLOT_STATIC_FLAG           0x02\r
-\r
-#endif // _SQOPCODES_H_\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQOPCODES_H_
+#define _SQOPCODES_H_
+
+#define MAX_FUNC_STACKSIZE 0xFF
+#define MAX_LITERALS ((SQInteger)0x7FFFFFFF)
+
+enum BitWiseOP {
+       BW_AND = 0,
+       BW_OR = 2,      //like ADD
+       BW_XOR = 3,
+       BW_SHIFTL = 4,
+       BW_SHIFTR = 5,
+       BW_USHIFTR = 6
+};
+
+enum CmpOP {
+       CMP_G = 0,
+       CMP_GE = 2,     //like ADD
+       CMP_L = 3,
+       CMP_LE = 4
+};
+enum SQOpcode
+{
+       _OP_LINE=                               0x00,
+       _OP_LOAD=                               0x01,
+       _OP_LOADINT=                    0x02,
+       _OP_DLOAD=                              0x03,
+       _OP_TAILCALL=                   0x04,
+       _OP_CALL=                               0x05,
+       _OP_PREPCALL=                   0x06,
+       _OP_PREPCALLK=                  0x07,
+       _OP_GETK=                               0x08,
+       _OP_MOVE=                               0x09,
+       _OP_NEWSLOT=                    0x0A,
+       _OP_DELETE=                             0x0B,
+       _OP_SET=                                0x0C,
+       _OP_GET=                                0x0D,
+       _OP_EQ=                                 0x0E,
+       _OP_NE=                                 0x0F,
+       _OP_ARITH=                              0x10,
+       _OP_BITW=                               0x11,
+       _OP_RETURN=                             0x12,
+       _OP_LOADNULLS=                  0x13,
+       _OP_LOADROOTTABLE=              0x14,
+       _OP_LOADBOOL=                   0x15,
+       _OP_DMOVE=                              0x16,
+       _OP_JMP=                                0x17,
+       _OP_JNZ=                                0x18,
+       _OP_JZ=                                 0x19,
+       _OP_LOADFREEVAR=                0x1A,
+       _OP_VARGC=                              0x1B,
+       _OP_GETVARGV=                   0x1C,
+       _OP_NEWTABLE=                   0x1D,
+       _OP_NEWARRAY=                   0x1E,
+       _OP_APPENDARRAY=                0x1F,
+       _OP_GETPARENT=                  0x20,
+       _OP_COMPARITH=                  0x21,
+       _OP_COMPARITHL=                 0x22,
+       _OP_INC=                                0x23,
+       _OP_INCL=                               0x24,
+       _OP_PINC=                               0x25,
+       _OP_PINCL=                              0x26,
+       _OP_CMP=                                0x27,
+       _OP_EXISTS=                             0x28,
+       _OP_INSTANCEOF=                 0x29,
+       _OP_AND=                                0x2A,
+       _OP_OR=                                 0x2B,
+       _OP_NEG=                                0x2C,
+       _OP_NOT=                                0x2D,
+       _OP_BWNOT=                              0x2E,
+       _OP_CLOSURE=                    0x2F,
+       _OP_YIELD=                              0x30,
+       _OP_RESUME=                             0x31,
+       _OP_FOREACH=                    0x32,
+       _OP_DELEGATE=                   0x33,
+       _OP_CLONE=                              0x34,
+       _OP_TYPEOF=                             0x35,
+       _OP_PUSHTRAP=                   0x36,
+       _OP_POPTRAP=                    0x37,
+       _OP_THROW=                              0x38,
+       _OP_CLASS=                              0x39,
+       _OP_NEWSLOTA=                   0x3A
+};
+
+struct SQInstructionDesc {
+       const SQChar *name;
+};
+
+struct SQInstruction
+{
+       SQInstruction(){};
+       SQInstruction(SQOpcode _op,SQInteger a0=0,SQInteger a1=0,SQInteger a2=0,SQInteger a3=0)
+       {       op = _op;
+               _arg0 = (unsigned char)a0;_arg1 = (SQInt32)a1;
+               _arg2 = (unsigned char)a2;_arg3 = (unsigned char)a3;
+       }
+
+
+       SQInt32 _arg1;
+       unsigned char op;
+       unsigned char _arg0;
+       unsigned char _arg2;
+       unsigned char _arg3;
+};
+
+#include "squtils.h"
+typedef sqvector<SQInstruction> SQInstructionVec;
+
+#define NEW_SLOT_ATTRIBUTES_FLAG       0x01
+#define NEW_SLOT_STATIC_FLAG           0x02
+
+#endif // _SQOPCODES_H_
index f0e5cf2..db49f5e 100644 (file)
@@ -1,19 +1,19 @@
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQPCHEADER_H_\r
-#define _SQPCHEADER_H_\r
-\r
-#if defined(_MSC_VER) && defined(_DEBUG)\r
-#include <crtdbg.h>\r
-#endif \r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include <assert.h>\r
-#include <new>\r
-//squirrel stuff\r
-#include <squirrel.h>\r
-#include "sqobject.h"\r
-#include "sqstate.h"\r
-\r
-#endif //_SQPCHEADER_H_\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQPCHEADER_H_
+#define _SQPCHEADER_H_
+
+#if defined(_MSC_VER) && defined(_DEBUG)
+#include <crtdbg.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <new>
+//squirrel stuff
+#include <squirrel.h>
+#include "sqobject.h"
+#include "sqstate.h"
+
+#endif //_SQPCHEADER_H_
index 475afe9..85da8c8 100644 (file)
-/*\r
-       see copyright notice in squirrel.h\r
-*/\r
-#include "sqpcheader.h"\r
-#include "sqopcodes.h"\r
-#include "sqvm.h"\r
-#include "sqfuncproto.h"\r
-#include "sqclosure.h"\r
-#include "sqstring.h"\r
-#include "sqtable.h"\r
-#include "sqarray.h"\r
-#include "squserdata.h"\r
-#include "sqclass.h"\r
-\r
-SQObjectPtr _null_;\r
-SQObjectPtr _true_(true);\r
-SQObjectPtr _false_(false);\r
-SQObjectPtr _one_((SQInteger)1);\r
-SQObjectPtr _minusone_((SQInteger)-1);\r
-\r
-SQSharedState::SQSharedState()\r
-{\r
-       _compilererrorhandler = NULL;\r
-       _printfunc = NULL;\r
-       _debuginfo = false;\r
-       _notifyallexceptions = false;\r
-}\r
-\r
-#define newsysstring(s) {      \\r
-       _systemstrings->push_back(SQString::Create(this,s));    \\r
-       }\r
-\r
-#define newmetamethod(s) {     \\r
-       _metamethods->push_back(SQString::Create(this,s));      \\r
-       _table(_metamethodsmap)->NewSlot(_metamethods->back(),(SQInteger)(_metamethods->size()-1)); \\r
-       }\r
-\r
-bool CompileTypemask(SQIntVec &res,const SQChar *typemask)\r
-{\r
-       SQInteger i = 0;\r
-       \r
-       SQInteger mask = 0;\r
-       while(typemask[i] != 0) {\r
-               \r
-               switch(typemask[i]){\r
-                               case 'o': mask |= _RT_NULL; break;\r
-                               case 'i': mask |= _RT_INTEGER; break;\r
-                               case 'f': mask |= _RT_FLOAT; break;\r
-                               case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break;\r
-                               case 's': mask |= _RT_STRING; break;\r
-                               case 't': mask |= _RT_TABLE; break;\r
-                               case 'a': mask |= _RT_ARRAY; break;\r
-                               case 'u': mask |= _RT_USERDATA; break;\r
-                               case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break;\r
-                               case 'b': mask |= _RT_BOOL; break;\r
-                               case 'g': mask |= _RT_GENERATOR; break;\r
-                               case 'p': mask |= _RT_USERPOINTER; break;\r
-                               case 'v': mask |= _RT_THREAD; break;\r
-                               case 'x': mask |= _RT_INSTANCE; break;\r
-                               case 'y': mask |= _RT_CLASS; break;\r
-                               case 'r': mask |= _RT_WEAKREF; break;\r
-                               case '.': mask = -1; res.push_back(mask); i++; mask = 0; continue;\r
-                               case ' ': i++; continue; //ignores spaces\r
-                               default:\r
-                                       return false;\r
-               }\r
-               i++;\r
-               if(typemask[i] == '|') { \r
-                       i++; \r
-                       if(typemask[i] == 0)\r
-                               return false;\r
-                       continue; \r
-               }\r
-               res.push_back(mask);\r
-               mask = 0;\r
-               \r
-       }\r
-       return true;\r
-}\r
-\r
-SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz)\r
-{\r
-       SQInteger i=0;\r
-       SQTable *t=SQTable::Create(ss,0);\r
-       while(funcz[i].name!=0){\r
-               SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f);\r
-               nc->_nparamscheck = funcz[i].nparamscheck;\r
-               nc->_name = SQString::Create(ss,funcz[i].name);\r
-               if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask))\r
-                       return NULL;\r
-               t->NewSlot(SQString::Create(ss,funcz[i].name),nc);\r
-               i++;\r
-       }\r
-       return t;\r
-}\r
-\r
-void SQSharedState::Init()\r
-{      \r
-       _scratchpad=NULL;\r
-       _scratchpadsize=0;\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-       _gc_chain=NULL;\r
-#endif\r
-       sq_new(_stringtable,StringTable);\r
-       sq_new(_metamethods,SQObjectPtrVec);\r
-       sq_new(_systemstrings,SQObjectPtrVec);\r
-       sq_new(_types,SQObjectPtrVec);\r
-       _metamethodsmap = SQTable::Create(this,MT_LAST-1);\r
-       //adding type strings to avoid memory trashing\r
-       //types names\r
-       newsysstring(_SC("null"));\r
-       newsysstring(_SC("table"));\r
-       newsysstring(_SC("array"));\r
-       newsysstring(_SC("closure"));\r
-       newsysstring(_SC("string"));\r
-       newsysstring(_SC("userdata"));\r
-       newsysstring(_SC("integer"));\r
-       newsysstring(_SC("float"));\r
-       newsysstring(_SC("userpointer"));\r
-       newsysstring(_SC("function"));\r
-       newsysstring(_SC("generator"));\r
-       newsysstring(_SC("thread"));\r
-       newsysstring(_SC("class"));\r
-       newsysstring(_SC("instance"));\r
-       newsysstring(_SC("bool"));\r
-       //meta methods\r
-       newmetamethod(MM_ADD);\r
-       newmetamethod(MM_SUB);\r
-       newmetamethod(MM_MUL);\r
-       newmetamethod(MM_DIV);\r
-       newmetamethod(MM_UNM);\r
-       newmetamethod(MM_MODULO);\r
-       newmetamethod(MM_SET);\r
-       newmetamethod(MM_GET);\r
-       newmetamethod(MM_TYPEOF);\r
-       newmetamethod(MM_NEXTI);\r
-       newmetamethod(MM_CMP);\r
-       newmetamethod(MM_CALL);\r
-       newmetamethod(MM_CLONED);\r
-       newmetamethod(MM_NEWSLOT);\r
-       newmetamethod(MM_DELSLOT);\r
-       newmetamethod(MM_TOSTRING);\r
-       newmetamethod(MM_NEWMEMBER);\r
-       newmetamethod(MM_INHERITED);\r
-\r
-       _constructoridx = SQString::Create(this,_SC("constructor"));\r
-       _registry = SQTable::Create(this,0);\r
-       _table_default_delegate=CreateDefaultDelegate(this,_table_default_delegate_funcz);\r
-       _array_default_delegate=CreateDefaultDelegate(this,_array_default_delegate_funcz);\r
-       _string_default_delegate=CreateDefaultDelegate(this,_string_default_delegate_funcz);\r
-       _number_default_delegate=CreateDefaultDelegate(this,_number_default_delegate_funcz);\r
-       _closure_default_delegate=CreateDefaultDelegate(this,_closure_default_delegate_funcz);\r
-       _generator_default_delegate=CreateDefaultDelegate(this,_generator_default_delegate_funcz);\r
-       _thread_default_delegate=CreateDefaultDelegate(this,_thread_default_delegate_funcz);\r
-       _class_default_delegate=CreateDefaultDelegate(this,_class_default_delegate_funcz);\r
-       _instance_default_delegate=CreateDefaultDelegate(this,_instance_default_delegate_funcz);\r
-       _weakref_default_delegate=CreateDefaultDelegate(this,_weakref_default_delegate_funcz);\r
-\r
-}\r
-\r
-SQSharedState::~SQSharedState()\r
-{\r
-       _constructoridx = _null_;\r
-       _refs_table.Finalize();\r
-       _table(_registry)->Finalize();\r
-       _table(_metamethodsmap)->Finalize();\r
-//     _refs_table = _null_;\r
-       _registry = _null_;\r
-       _metamethodsmap = _null_;\r
-       while(!_systemstrings->empty()){\r
-               _systemstrings->back()=_null_;\r
-               _systemstrings->pop_back();\r
-       }\r
-       _thread(_root_vm)->Finalize();\r
-       _root_vm = _null_;\r
-       _table_default_delegate=_null_;\r
-       _array_default_delegate=_null_;\r
-       _string_default_delegate=_null_;\r
-       _number_default_delegate=_null_;\r
-       _closure_default_delegate=_null_;\r
-       _generator_default_delegate=_null_;\r
-       _thread_default_delegate=_null_;\r
-       _class_default_delegate=_null_;\r
-       _instance_default_delegate=_null_;\r
-       _weakref_default_delegate=_null_;\r
-       \r
-#ifndef NO_GARBAGE_COLLECTOR\r
-       \r
-       \r
-       SQCollectable *t=_gc_chain;\r
-       SQCollectable *nx=NULL;\r
-       while(t){\r
-               t->_uiRef++;\r
-               t->Finalize();\r
-               nx=t->_next;\r
-               if(--t->_uiRef==0)\r
-                       t->Release();\r
-               t=nx;\r
-       }\r
-       assert(_gc_chain==NULL); //just to proove a theory\r
-       while(_gc_chain){\r
-               _gc_chain->_uiRef++;\r
-               _gc_chain->Release();\r
-       }\r
-#endif\r
-       sq_delete(_types,SQObjectPtrVec);\r
-       sq_delete(_systemstrings,SQObjectPtrVec);\r
-       sq_delete(_metamethods,SQObjectPtrVec);\r
-       sq_delete(_stringtable,StringTable);\r
-       if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize);\r
-}\r
-\r
-\r
-SQInteger SQSharedState::GetMetaMethodIdxByName(const SQObjectPtr &name)\r
-{\r
-       if(type(name) != OT_STRING)\r
-               return -1;\r
-       SQObjectPtr ret;\r
-       if(_table(_metamethodsmap)->Get(name,ret)) {\r
-               return _integer(ret);\r
-       }\r
-       return -1;\r
-}\r
-\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-\r
-void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain)\r
-{\r
-       switch(type(o)){\r
-       case OT_TABLE:_table(o)->Mark(chain);break;\r
-       case OT_ARRAY:_array(o)->Mark(chain);break;\r
-       case OT_USERDATA:_userdata(o)->Mark(chain);break;\r
-       case OT_CLOSURE:_closure(o)->Mark(chain);break;\r
-       case OT_NATIVECLOSURE:_nativeclosure(o)->Mark(chain);break;\r
-       case OT_GENERATOR:_generator(o)->Mark(chain);break;\r
-       case OT_THREAD:_thread(o)->Mark(chain);break;\r
-       case OT_CLASS:_class(o)->Mark(chain);break;\r
-       case OT_INSTANCE:_instance(o)->Mark(chain);break;\r
-       default: break; //shutup compiler\r
-       }\r
-}\r
-\r
-\r
-SQInteger SQSharedState::CollectGarbage(SQVM *vm)\r
-{\r
-       SQInteger n=0;\r
-       SQCollectable *tchain=NULL;\r
-       SQVM *vms=_thread(_root_vm);\r
-       \r
-       vms->Mark(&tchain);\r
-       SQInteger x = _table(_thread(_root_vm)->_roottable)->CountUsed();\r
-       _refs_table.Mark(&tchain);\r
-       MarkObject(_registry,&tchain);\r
-       MarkObject(_metamethodsmap,&tchain);\r
-       MarkObject(_table_default_delegate,&tchain);\r
-       MarkObject(_array_default_delegate,&tchain);\r
-       MarkObject(_string_default_delegate,&tchain);\r
-       MarkObject(_number_default_delegate,&tchain);\r
-       MarkObject(_generator_default_delegate,&tchain);\r
-       MarkObject(_thread_default_delegate,&tchain);\r
-       MarkObject(_closure_default_delegate,&tchain);\r
-       MarkObject(_class_default_delegate,&tchain);\r
-       MarkObject(_instance_default_delegate,&tchain);\r
-       MarkObject(_weakref_default_delegate,&tchain);\r
-       \r
-       SQCollectable *t=_gc_chain;\r
-       SQCollectable *nx=NULL;\r
-       while(t){\r
-               t->_uiRef++;\r
-               t->Finalize();\r
-               nx=t->_next;\r
-               if(--t->_uiRef==0)\r
-                       t->Release();\r
-               t=nx;\r
-               n++;\r
-       }\r
-\r
-       t=tchain;\r
-       while(t){\r
-               t->UnMark();\r
-               t=t->_next;\r
-       }\r
-       _gc_chain=tchain;\r
-       SQInteger z = _table(_thread(_root_vm)->_roottable)->CountUsed();\r
-       assert(z == x);\r
-       return n;\r
-}\r
-#endif\r
-\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c)\r
-{\r
-    c->_prev=NULL;\r
-       c->_next=*chain;\r
-       if(*chain) (*chain)->_prev=c;\r
-       *chain=c;\r
-}\r
-\r
-void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c)\r
-{\r
-       if(c->_prev) c->_prev->_next=c->_next;\r
-       else *chain=c->_next;\r
-       if(c->_next)\r
-               c->_next->_prev=c->_prev;\r
-       c->_next=NULL;\r
-       c->_prev=NULL;\r
-}\r
-#endif\r
-\r
-SQChar* SQSharedState::GetScratchPad(SQInteger size)\r
-{\r
-       SQInteger newsize;\r
-       if(size>0){\r
-               if(_scratchpadsize<size){\r
-                       newsize=size+(size>>1);\r
-                       _scratchpad=(SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);\r
-                       _scratchpadsize=newsize;\r
-\r
-               }else if(_scratchpadsize>=(size<<5)){\r
-                       newsize=_scratchpadsize>>1;\r
-                       _scratchpad=(SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);\r
-                       _scratchpadsize=newsize;\r
-               }\r
-       }\r
-       return _scratchpad;\r
-}\r
-\r
-RefTable::RefTable()\r
-{\r
-       AllocNodes(4);\r
-}\r
-\r
-void RefTable::Finalize()\r
-{\r
-       RefNode *nodes = (RefNode *)&_buckets[_numofslots];\r
-       for(SQUnsignedInteger n = 0; n < _numofslots; n++) {\r
-               nodes->obj = _null_;\r
-               nodes++;\r
-       }\r
-}\r
-\r
-RefTable::~RefTable()\r
-{\r
-       SQ_FREE(_buckets,_buffersize);\r
-}\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-void RefTable::Mark(SQCollectable **chain)\r
-{\r
-       RefNode *nodes = (RefNode *)&_buckets[_numofslots];\r
-       for(SQUnsignedInteger n = 0; n < _numofslots; n++) {\r
-               if(type(nodes->obj) != OT_NULL) {\r
-                       SQSharedState::MarkObject(nodes->obj,chain);\r
-               }\r
-               nodes++;\r
-       }\r
-}\r
-#endif\r
-void RefTable::AddRef(SQObject &obj)\r
-{\r
-       SQHash mainpos;\r
-       RefNode *prev;\r
-       RefNode *ref = Get(obj,mainpos,&prev,true);\r
-       ref->refs++;\r
-}\r
-\r
-SQBool RefTable::Release(SQObject &obj)\r
-{\r
-       SQHash mainpos;\r
-       RefNode *prev;\r
-       RefNode *ref = Get(obj,mainpos,&prev,false);\r
-       if(ref) {\r
-               if(--ref->refs == 0) {\r
-                       ref->obj = _null_;\r
-                       if(prev) {\r
-                               prev->next = ref->next;\r
-                       }\r
-                       else {\r
-                               _buckets[mainpos] = ref->next;\r
-                       }\r
-                       ref->next = _freelist;\r
-                       _freelist = ref;\r
-                       _slotused--;\r
-                       //<<FIXME>>test for shrink?\r
-                       return SQTrue;\r
-               }\r
-       }\r
-       return SQFalse;\r
-}\r
-\r
-void RefTable::Resize(SQUnsignedInteger size)\r
-{\r
-       RefNode **oldbuffer = _buckets;\r
-       RefNode *oldnodes = (RefNode *)&_buckets[_numofslots];\r
-       SQUnsignedInteger oldnumofslots = _numofslots;\r
-       SQUnsignedInteger oldbuffersize = _buffersize;\r
-       AllocNodes(size);\r
-       //rehash\r
-       for(SQUnsignedInteger n = 0; n < oldnumofslots; n++) {\r
-               if(type(oldnodes->obj) != OT_NULL) {\r
-                       //add back;\r
-                       assert(oldnodes->refs != 0);\r
-                       RefNode *nn = Add(::HashObj(oldnodes->obj)&(_numofslots-1),oldnodes->obj);\r
-                       nn->refs = oldnodes->refs; \r
-                       oldnodes->obj = _null_;\r
-               }\r
-               oldnodes++;\r
-       }\r
-       SQ_FREE(oldbuffer,oldbuffersize);\r
-}\r
-\r
-RefTable::RefNode *RefTable::Add(SQHash mainpos,SQObject &obj)\r
-{\r
-       RefNode *t = _buckets[mainpos];\r
-       RefNode *newnode = _freelist;\r
-       newnode->obj = obj;\r
-       _buckets[mainpos] = newnode;\r
-       _freelist = _freelist->next;\r
-       newnode->next = t;\r
-       assert(newnode->refs == 0);\r
-       _slotused++;\r
-       return newnode;\r
-}\r
-\r
-RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add)\r
-{\r
-       RefNode *ref;\r
-       mainpos = ::HashObj(obj)&(_numofslots-1);\r
-       *prev = NULL;\r
-       for (ref = _buckets[mainpos]; ref; ) {\r
-               if(_rawval(ref->obj) == _rawval(obj) && type(ref->obj) == type(obj))\r
-                       break;\r
-               *prev = ref;\r
-               ref = ref->next;\r
-       }\r
-       if(ref == NULL && add) {\r
-               if(_numofslots == _slotused) {\r
-                       Resize(_numofslots*2);\r
-               }\r
-               ref = Add(mainpos,obj);\r
-       }\r
-       return ref;\r
-}\r
-\r
-void RefTable::AllocNodes(SQUnsignedInteger size)\r
-{\r
-       RefNode **bucks;\r
-       RefNode *firstnode;\r
-       _buffersize = size * sizeof(RefNode *) + size * sizeof(RefNode);\r
-       bucks = (RefNode **)SQ_MALLOC(_buffersize);\r
-       firstnode = (RefNode *)&bucks[size];\r
-       RefNode *temp = firstnode;\r
-       SQUnsignedInteger n;\r
-       for(n = 0; n < size - 1; n++) {\r
-               bucks[n] = NULL;\r
-               temp->refs = 0;\r
-               new (&temp->obj) SQObjectPtr;\r
-               temp->next = temp+1;\r
-               temp++;\r
-       }\r
-       bucks[n] = NULL;\r
-       temp->refs = 0;\r
-       new (&temp->obj) SQObjectPtr;\r
-       temp->next = NULL;\r
-       _freelist = firstnode;\r
-       _buckets = bucks;\r
-       _slotused = 0;\r
-       _numofslots = size;\r
-}\r
-//////////////////////////////////////////////////////////////////////////\r
-//StringTable\r
-/*\r
-* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)\r
-* http://www.lua.org/copyright.html#4\r
-* http://www.lua.org/source/4.0.1/src_lstring.c.html\r
-*/\r
-\r
-StringTable::StringTable()\r
-{\r
-       AllocNodes(4);\r
-       _slotused = 0;\r
-}\r
-\r
-StringTable::~StringTable()\r
-{\r
-       SQ_FREE(_strings,sizeof(SQString*)*_numofslots);\r
-       _strings=NULL;\r
-}\r
-\r
-void StringTable::AllocNodes(SQInteger size)\r
-{\r
-       _numofslots=size;\r
-       //_slotused=0;\r
-       _strings=(SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots);\r
-       memset(_strings,0,sizeof(SQString*)*_numofslots);\r
-}\r
-\r
-SQString *StringTable::Add(const SQChar *news,SQInteger len)\r
-{\r
-       if(len<0)\r
-               len = (SQInteger)scstrlen(news);\r
-       SQHash h = ::_hashstr(news,len)&(_numofslots-1);\r
-       SQString *s;\r
-       for (s = _strings[h]; s; s = s->_next){\r
-               if(s->_len == len && (!memcmp(news,s->_val,rsl(len))))\r
-                       return s; //found\r
-       }\r
-\r
-       SQString *t=(SQString *)SQ_MALLOC(rsl(len)+sizeof(SQString));\r
-       new (t) SQString;\r
-       memcpy(t->_val,news,rsl(len));\r
-       t->_val[len] = _SC('\0');\r
-       t->_len = len;\r
-       t->_hash = ::_hashstr(news,len);\r
-       t->_next = _strings[h];\r
-       _strings[h] = t;\r
-       _slotused++;\r
-       if (_slotused > _numofslots)  /* too crowded? */\r
-               Resize(_numofslots*2);\r
-       return t;\r
-}\r
-\r
-void StringTable::Resize(SQInteger size)\r
-{\r
-       SQInteger oldsize=_numofslots;\r
-       SQString **oldtable=_strings;\r
-       AllocNodes(size);\r
-       for (SQInteger i=0; i<oldsize; i++){\r
-               SQString *p = oldtable[i];\r
-               while(p){\r
-                       SQString *next = p->_next;\r
-                       SQHash h = p->_hash&(_numofslots-1);\r
-                       p->_next = _strings[h];\r
-                       _strings[h] = p;\r
-                       p = next;\r
-               }\r
-       }\r
-       SQ_FREE(oldtable,oldsize*sizeof(SQString*));\r
-}\r
-\r
-void StringTable::Remove(SQString *bs)\r
-{\r
-       SQString *s;\r
-       SQString *prev=NULL;\r
-       SQHash h = bs->_hash&(_numofslots - 1);\r
-       \r
-       for (s = _strings[h]; s; ){\r
-               if(s == bs){\r
-                       if(prev)\r
-                               prev->_next = s->_next;\r
-                       else\r
-                               _strings[h] = s->_next;\r
-                       _slotused--;\r
-                       SQInteger slen = s->_len;\r
-                       s->~SQString();\r
-                       SQ_FREE(s,sizeof(SQString) + rsl(slen));\r
-                       return;\r
-               }\r
-               prev = s;\r
-               s = s->_next;\r
-       }\r
-       assert(0);//if this fail something is wrong\r
-}\r
+/*
+       see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include "sqopcodes.h"
+#include "sqvm.h"
+#include "sqfuncproto.h"
+#include "sqclosure.h"
+#include "sqstring.h"
+#include "sqtable.h"
+#include "sqarray.h"
+#include "squserdata.h"
+#include "sqclass.h"
+
+SQObjectPtr _null_;
+SQObjectPtr _true_(true);
+SQObjectPtr _false_(false);
+SQObjectPtr _one_((SQInteger)1);
+SQObjectPtr _minusone_((SQInteger)-1);
+
+SQSharedState::SQSharedState()
+{
+       _compilererrorhandler = NULL;
+       _printfunc = NULL;
+       _debuginfo = false;
+       _notifyallexceptions = false;
+}
+
+#define newsysstring(s) {      \
+       _systemstrings->push_back(SQString::Create(this,s));    \
+       }
+
+#define newmetamethod(s) {     \
+       _metamethods->push_back(SQString::Create(this,s));      \
+       _table(_metamethodsmap)->NewSlot(_metamethods->back(),(SQInteger)(_metamethods->size()-1)); \
+       }
+
+bool CompileTypemask(SQIntVec &res,const SQChar *typemask)
+{
+       SQInteger i = 0;
+
+       SQInteger mask = 0;
+       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;
+                               case 's': mask |= _RT_STRING; break;
+                               case 't': mask |= _RT_TABLE; break;
+                               case 'a': mask |= _RT_ARRAY; break;
+                               case 'u': mask |= _RT_USERDATA; break;
+                               case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break;
+                               case 'b': mask |= _RT_BOOL; break;
+                               case 'g': mask |= _RT_GENERATOR; break;
+                               case 'p': mask |= _RT_USERPOINTER; break;
+                               case 'v': mask |= _RT_THREAD; break;
+                               case 'x': mask |= _RT_INSTANCE; break;
+                               case 'y': mask |= _RT_CLASS; break;
+                               case 'r': mask |= _RT_WEAKREF; break;
+                               case '.': mask = -1; res.push_back(mask); i++; mask = 0; continue;
+                               case ' ': i++; continue; //ignores spaces
+                               default:
+                                       return false;
+               }
+               i++;
+               if(typemask[i] == '|') {
+                       i++;
+                       if(typemask[i] == 0)
+                               return false;
+                       continue;
+               }
+               res.push_back(mask);
+               mask = 0;
+
+       }
+       return true;
+}
+
+SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz)
+{
+       SQInteger i=0;
+       SQTable *t=SQTable::Create(ss,0);
+       while(funcz[i].name!=0){
+               SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f);
+               nc->_nparamscheck = funcz[i].nparamscheck;
+               nc->_name = SQString::Create(ss,funcz[i].name);
+               if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask))
+                       return NULL;
+               t->NewSlot(SQString::Create(ss,funcz[i].name),nc);
+               i++;
+       }
+       return t;
+}
+
+void SQSharedState::Init()
+{
+       _scratchpad=NULL;
+       _scratchpadsize=0;
+#ifndef NO_GARBAGE_COLLECTOR
+       _gc_chain=NULL;
+#endif
+       sq_new(_stringtable,StringTable);
+       sq_new(_metamethods,SQObjectPtrVec);
+       sq_new(_systemstrings,SQObjectPtrVec);
+       sq_new(_types,SQObjectPtrVec);
+       _metamethodsmap = SQTable::Create(this,MT_LAST-1);
+       //adding type strings to avoid memory trashing
+       //types names
+       newsysstring(_SC("null"));
+       newsysstring(_SC("table"));
+       newsysstring(_SC("array"));
+       newsysstring(_SC("closure"));
+       newsysstring(_SC("string"));
+       newsysstring(_SC("userdata"));
+       newsysstring(_SC("integer"));
+       newsysstring(_SC("float"));
+       newsysstring(_SC("userpointer"));
+       newsysstring(_SC("function"));
+       newsysstring(_SC("generator"));
+       newsysstring(_SC("thread"));
+       newsysstring(_SC("class"));
+       newsysstring(_SC("instance"));
+       newsysstring(_SC("bool"));
+       //meta methods
+       newmetamethod(MM_ADD);
+       newmetamethod(MM_SUB);
+       newmetamethod(MM_MUL);
+       newmetamethod(MM_DIV);
+       newmetamethod(MM_UNM);
+       newmetamethod(MM_MODULO);
+       newmetamethod(MM_SET);
+       newmetamethod(MM_GET);
+       newmetamethod(MM_TYPEOF);
+       newmetamethod(MM_NEXTI);
+       newmetamethod(MM_CMP);
+       newmetamethod(MM_CALL);
+       newmetamethod(MM_CLONED);
+       newmetamethod(MM_NEWSLOT);
+       newmetamethod(MM_DELSLOT);
+       newmetamethod(MM_TOSTRING);
+       newmetamethod(MM_NEWMEMBER);
+       newmetamethod(MM_INHERITED);
+
+       _constructoridx = SQString::Create(this,_SC("constructor"));
+       _registry = SQTable::Create(this,0);
+       _table_default_delegate=CreateDefaultDelegate(this,_table_default_delegate_funcz);
+       _array_default_delegate=CreateDefaultDelegate(this,_array_default_delegate_funcz);
+       _string_default_delegate=CreateDefaultDelegate(this,_string_default_delegate_funcz);
+       _number_default_delegate=CreateDefaultDelegate(this,_number_default_delegate_funcz);
+       _closure_default_delegate=CreateDefaultDelegate(this,_closure_default_delegate_funcz);
+       _generator_default_delegate=CreateDefaultDelegate(this,_generator_default_delegate_funcz);
+       _thread_default_delegate=CreateDefaultDelegate(this,_thread_default_delegate_funcz);
+       _class_default_delegate=CreateDefaultDelegate(this,_class_default_delegate_funcz);
+       _instance_default_delegate=CreateDefaultDelegate(this,_instance_default_delegate_funcz);
+       _weakref_default_delegate=CreateDefaultDelegate(this,_weakref_default_delegate_funcz);
+
+}
+
+SQSharedState::~SQSharedState()
+{
+       _constructoridx = _null_;
+       _refs_table.Finalize();
+       _table(_registry)->Finalize();
+       _table(_metamethodsmap)->Finalize();
+//     _refs_table = _null_;
+       _registry = _null_;
+       _metamethodsmap = _null_;
+       while(!_systemstrings->empty()){
+               _systemstrings->back()=_null_;
+               _systemstrings->pop_back();
+       }
+       _thread(_root_vm)->Finalize();
+       _root_vm = _null_;
+       _table_default_delegate=_null_;
+       _array_default_delegate=_null_;
+       _string_default_delegate=_null_;
+       _number_default_delegate=_null_;
+       _closure_default_delegate=_null_;
+       _generator_default_delegate=_null_;
+       _thread_default_delegate=_null_;
+       _class_default_delegate=_null_;
+       _instance_default_delegate=_null_;
+       _weakref_default_delegate=_null_;
+
+#ifndef NO_GARBAGE_COLLECTOR
+
+
+       SQCollectable *t=_gc_chain;
+       SQCollectable *nx=NULL;
+       while(t){
+               t->_uiRef++;
+               t->Finalize();
+               nx=t->_next;
+               if(--t->_uiRef==0)
+                       t->Release();
+               t=nx;
+       }
+       assert(_gc_chain==NULL); //just to proove a theory
+       while(_gc_chain){
+               _gc_chain->_uiRef++;
+               _gc_chain->Release();
+       }
+#endif
+       sq_delete(_types,SQObjectPtrVec);
+       sq_delete(_systemstrings,SQObjectPtrVec);
+       sq_delete(_metamethods,SQObjectPtrVec);
+       sq_delete(_stringtable,StringTable);
+       if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize);
+}
+
+
+SQInteger SQSharedState::GetMetaMethodIdxByName(const SQObjectPtr &name)
+{
+       if(type(name) != OT_STRING)
+               return -1;
+       SQObjectPtr ret;
+       if(_table(_metamethodsmap)->Get(name,ret)) {
+               return _integer(ret);
+       }
+       return -1;
+}
+
+#ifndef NO_GARBAGE_COLLECTOR
+
+void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain)
+{
+       switch(type(o)){
+       case OT_TABLE:_table(o)->Mark(chain);break;
+       case OT_ARRAY:_array(o)->Mark(chain);break;
+       case OT_USERDATA:_userdata(o)->Mark(chain);break;
+       case OT_CLOSURE:_closure(o)->Mark(chain);break;
+       case OT_NATIVECLOSURE:_nativeclosure(o)->Mark(chain);break;
+       case OT_GENERATOR:_generator(o)->Mark(chain);break;
+       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; //shutup compiler
+       }
+}
+
+
+SQInteger SQSharedState::CollectGarbage(SQVM *vm)
+{
+       SQInteger n=0;
+       SQCollectable *tchain=NULL;
+       SQVM *vms=_thread(_root_vm);
+
+       vms->Mark(&tchain);
+       SQInteger x = _table(_thread(_root_vm)->_roottable)->CountUsed();
+       _refs_table.Mark(&tchain);
+       MarkObject(_registry,&tchain);
+       MarkObject(_metamethodsmap,&tchain);
+       MarkObject(_table_default_delegate,&tchain);
+       MarkObject(_array_default_delegate,&tchain);
+       MarkObject(_string_default_delegate,&tchain);
+       MarkObject(_number_default_delegate,&tchain);
+       MarkObject(_generator_default_delegate,&tchain);
+       MarkObject(_thread_default_delegate,&tchain);
+       MarkObject(_closure_default_delegate,&tchain);
+       MarkObject(_class_default_delegate,&tchain);
+       MarkObject(_instance_default_delegate,&tchain);
+       MarkObject(_weakref_default_delegate,&tchain);
+
+       SQCollectable *t=_gc_chain;
+       SQCollectable *nx=NULL;
+       while(t){
+               t->_uiRef++;
+               t->Finalize();
+               nx=t->_next;
+               if(--t->_uiRef==0)
+                       t->Release();
+               t=nx;
+               n++;
+       }
+
+       t=tchain;
+       while(t){
+               t->UnMark();
+               t=t->_next;
+       }
+       _gc_chain=tchain;
+       SQInteger z = _table(_thread(_root_vm)->_roottable)->CountUsed();
+       assert(z == x);
+       return n;
+}
+#endif
+
+#ifndef NO_GARBAGE_COLLECTOR
+void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c)
+{
+    c->_prev=NULL;
+       c->_next=*chain;
+       if(*chain) (*chain)->_prev=c;
+       *chain=c;
+}
+
+void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c)
+{
+       if(c->_prev) c->_prev->_next=c->_next;
+       else *chain=c->_next;
+       if(c->_next)
+               c->_next->_prev=c->_prev;
+       c->_next=NULL;
+       c->_prev=NULL;
+}
+#endif
+
+SQChar* SQSharedState::GetScratchPad(SQInteger size)
+{
+       SQInteger newsize;
+       if(size>0){
+               if(_scratchpadsize<size){
+                       newsize=size+(size>>1);
+                       _scratchpad=(SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
+                       _scratchpadsize=newsize;
+
+               }else if(_scratchpadsize>=(size<<5)){
+                       newsize=_scratchpadsize>>1;
+                       _scratchpad=(SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
+                       _scratchpadsize=newsize;
+               }
+       }
+       return _scratchpad;
+}
+
+RefTable::RefTable()
+{
+       AllocNodes(4);
+}
+
+void RefTable::Finalize()
+{
+       RefNode *nodes = (RefNode *)&_buckets[_numofslots];
+       for(SQUnsignedInteger n = 0; n < _numofslots; n++) {
+               nodes->obj = _null_;
+               nodes++;
+       }
+}
+
+RefTable::~RefTable()
+{
+       SQ_FREE(_buckets,_buffersize);
+}
+#ifndef NO_GARBAGE_COLLECTOR
+void RefTable::Mark(SQCollectable **chain)
+{
+       RefNode *nodes = (RefNode *)&_buckets[_numofslots];
+       for(SQUnsignedInteger n = 0; n < _numofslots; n++) {
+               if(type(nodes->obj) != OT_NULL) {
+                       SQSharedState::MarkObject(nodes->obj,chain);
+               }
+               nodes++;
+       }
+}
+#endif
+void RefTable::AddRef(SQObject &obj)
+{
+       SQHash mainpos;
+       RefNode *prev;
+       RefNode *ref = Get(obj,mainpos,&prev,true);
+       ref->refs++;
+}
+
+SQBool RefTable::Release(SQObject &obj)
+{
+       SQHash mainpos;
+       RefNode *prev;
+       RefNode *ref = Get(obj,mainpos,&prev,false);
+       if(ref) {
+               if(--ref->refs == 0) {
+                       ref->obj = _null_;
+                       if(prev) {
+                               prev->next = ref->next;
+                       }
+                       else {
+                               _buckets[mainpos] = ref->next;
+                       }
+                       ref->next = _freelist;
+                       _freelist = ref;
+                       _slotused--;
+                       //<<FIXME>>test for shrink?
+                       return SQTrue;
+               }
+       }
+       return SQFalse;
+}
+
+void RefTable::Resize(SQUnsignedInteger size)
+{
+       RefNode **oldbuffer = _buckets;
+       RefNode *oldnodes = (RefNode *)&_buckets[_numofslots];
+       SQUnsignedInteger oldnumofslots = _numofslots;
+       SQUnsignedInteger oldbuffersize = _buffersize;
+       AllocNodes(size);
+       //rehash
+       for(SQUnsignedInteger n = 0; n < oldnumofslots; n++) {
+               if(type(oldnodes->obj) != OT_NULL) {
+                       //add back;
+                       assert(oldnodes->refs != 0);
+                       RefNode *nn = Add(::HashObj(oldnodes->obj)&(_numofslots-1),oldnodes->obj);
+                       nn->refs = oldnodes->refs;
+                       oldnodes->obj = _null_;
+               }
+               oldnodes++;
+       }
+       SQ_FREE(oldbuffer,oldbuffersize);
+}
+
+RefTable::RefNode *RefTable::Add(SQHash mainpos,SQObject &obj)
+{
+       RefNode *t = _buckets[mainpos];
+       RefNode *newnode = _freelist;
+       newnode->obj = obj;
+       _buckets[mainpos] = newnode;
+       _freelist = _freelist->next;
+       newnode->next = t;
+       assert(newnode->refs == 0);
+       _slotused++;
+       return newnode;
+}
+
+RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add)
+{
+       RefNode *ref;
+       mainpos = ::HashObj(obj)&(_numofslots-1);
+       *prev = NULL;
+       for (ref = _buckets[mainpos]; ref; ) {
+               if(_rawval(ref->obj) == _rawval(obj) && type(ref->obj) == type(obj))
+                       break;
+               *prev = ref;
+               ref = ref->next;
+       }
+       if(ref == NULL && add) {
+               if(_numofslots == _slotused) {
+                       Resize(_numofslots*2);
+               }
+               ref = Add(mainpos,obj);
+       }
+       return ref;
+}
+
+void RefTable::AllocNodes(SQUnsignedInteger size)
+{
+       RefNode **bucks;
+       RefNode *firstnode;
+       _buffersize = size * sizeof(RefNode *) + size * sizeof(RefNode);
+       bucks = (RefNode **)SQ_MALLOC(_buffersize);
+       firstnode = (RefNode *)&bucks[size];
+       RefNode *temp = firstnode;
+       SQUnsignedInteger n;
+       for(n = 0; n < size - 1; n++) {
+               bucks[n] = NULL;
+               temp->refs = 0;
+               new (&temp->obj) SQObjectPtr;
+               temp->next = temp+1;
+               temp++;
+       }
+       bucks[n] = NULL;
+       temp->refs = 0;
+       new (&temp->obj) SQObjectPtr;
+       temp->next = NULL;
+       _freelist = firstnode;
+       _buckets = bucks;
+       _slotused = 0;
+       _numofslots = size;
+}
+//////////////////////////////////////////////////////////////////////////
+//StringTable
+/*
+* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)
+* http://www.lua.org/copyright.html#4
+* http://www.lua.org/source/4.0.1/src_lstring.c.html
+*/
+
+StringTable::StringTable()
+{
+       AllocNodes(4);
+       _slotused = 0;
+}
+
+StringTable::~StringTable()
+{
+       SQ_FREE(_strings,sizeof(SQString*)*_numofslots);
+       _strings=NULL;
+}
+
+void StringTable::AllocNodes(SQInteger size)
+{
+       _numofslots=size;
+       //_slotused=0;
+       _strings=(SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots);
+       memset(_strings,0,sizeof(SQString*)*_numofslots);
+}
+
+SQString *StringTable::Add(const SQChar *news,SQInteger len)
+{
+       if(len<0)
+               len = (SQInteger)scstrlen(news);
+       SQHash h = ::_hashstr(news,len)&(_numofslots-1);
+       SQString *s;
+       for (s = _strings[h]; s; s = s->_next){
+               if(s->_len == len && (!memcmp(news,s->_val,rsl(len))))
+                       return s; //found
+       }
+
+       SQString *t=(SQString *)SQ_MALLOC(rsl(len)+sizeof(SQString));
+       new (t) SQString;
+       memcpy(t->_val,news,rsl(len));
+       t->_val[len] = _SC('\0');
+       t->_len = len;
+       t->_hash = ::_hashstr(news,len);
+       t->_next = _strings[h];
+       _strings[h] = t;
+       _slotused++;
+       if (_slotused > _numofslots)  /* too crowded? */
+               Resize(_numofslots*2);
+       return t;
+}
+
+void StringTable::Resize(SQInteger size)
+{
+       SQInteger oldsize=_numofslots;
+       SQString **oldtable=_strings;
+       AllocNodes(size);
+       for (SQInteger i=0; i<oldsize; i++){
+               SQString *p = oldtable[i];
+               while(p){
+                       SQString *next = p->_next;
+                       SQHash h = p->_hash&(_numofslots-1);
+                       p->_next = _strings[h];
+                       _strings[h] = p;
+                       p = next;
+               }
+       }
+       SQ_FREE(oldtable,oldsize*sizeof(SQString*));
+}
+
+void StringTable::Remove(SQString *bs)
+{
+       SQString *s;
+       SQString *prev=NULL;
+       SQHash h = bs->_hash&(_numofslots - 1);
+
+       for (s = _strings[h]; s; ){
+               if(s == bs){
+                       if(prev)
+                               prev->_next = s->_next;
+                       else
+                               _strings[h] = s->_next;
+                       _slotused--;
+                       SQInteger slen = s->_len;
+                       s->~SQString();
+                       SQ_FREE(s,sizeof(SQString) + rsl(slen));
+                       return;
+               }
+               prev = s;
+               s = s->_next;
+       }
+       assert(0);//if this fail something is wrong
+}
index 64892c4..fc29816 100644 (file)
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQSTATE_H_\r
-#define _SQSTATE_H_\r
-\r
-#include "squtils.h"\r
-#include "sqobject.h"\r
-struct SQString;\r
-struct SQTable;\r
-//max number of character for a printed number\r
-#define NUMBER_MAX_CHAR 50\r
-\r
-struct StringTable\r
-{\r
-       StringTable();\r
-       ~StringTable();\r
-       SQString *Add(const SQChar *,SQInteger len);\r
-       void Remove(SQString *);\r
-private:\r
-       void Resize(SQInteger size);\r
-       void AllocNodes(SQInteger size);\r
-       SQString **_strings;\r
-       SQUnsignedInteger _numofslots;\r
-       SQUnsignedInteger _slotused;\r
-};\r
-\r
-struct RefTable {\r
-       struct RefNode {\r
-               SQObjectPtr obj;\r
-               SQUnsignedInteger refs;\r
-               struct RefNode *next;\r
-       };\r
-       RefTable();\r
-       ~RefTable();\r
-       void AddRef(SQObject &obj);\r
-       SQBool Release(SQObject &obj);\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-       void Mark(SQCollectable **chain);\r
-#endif\r
-       void Finalize();\r
-private:\r
-       RefNode *Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add);\r
-       RefNode *Add(SQHash mainpos,SQObject &obj);\r
-       void Resize(SQUnsignedInteger size);\r
-       void AllocNodes(SQUnsignedInteger size);\r
-       SQUnsignedInteger _numofslots;\r
-       SQUnsignedInteger _slotused;\r
-       SQUnsignedInteger _buffersize;\r
-       RefNode *_freelist;\r
-       RefNode **_buckets;\r
-};\r
-\r
-#define ADD_STRING(ss,str,len) ss->_stringtable->Add(str,len)\r
-#define REMOVE_STRING(ss,bstr) ss->_stringtable->Remove(bstr)\r
-\r
-struct SQObjectPtr;\r
-\r
-struct SQSharedState\r
-{\r
-       SQSharedState();\r
-       ~SQSharedState();\r
-       void Init();\r
-public:\r
-       SQChar* GetScratchPad(SQInteger size);\r
-       SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name);\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-       SQInteger CollectGarbage(SQVM *vm); \r
-       static void MarkObject(SQObjectPtr &o,SQCollectable **chain);\r
-#endif\r
-       SQObjectPtrVec *_metamethods;\r
-       SQObjectPtr _metamethodsmap;\r
-       SQObjectPtrVec *_systemstrings;\r
-       SQObjectPtrVec *_types;\r
-       StringTable *_stringtable;\r
-       RefTable _refs_table;\r
-       SQObjectPtr _registry;\r
-       SQObjectPtr _constructoridx;\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-       SQCollectable *_gc_chain;\r
-#endif\r
-       SQObjectPtr _root_vm;\r
-       SQObjectPtr _table_default_delegate;\r
-       static SQRegFunction _table_default_delegate_funcz[];\r
-       SQObjectPtr _array_default_delegate;\r
-       static SQRegFunction _array_default_delegate_funcz[];\r
-       SQObjectPtr _string_default_delegate;\r
-       static SQRegFunction _string_default_delegate_funcz[];\r
-       SQObjectPtr _number_default_delegate;\r
-       static SQRegFunction _number_default_delegate_funcz[];\r
-       SQObjectPtr _generator_default_delegate;\r
-       static SQRegFunction _generator_default_delegate_funcz[];\r
-       SQObjectPtr _closure_default_delegate;\r
-       static SQRegFunction _closure_default_delegate_funcz[];\r
-       SQObjectPtr _thread_default_delegate;\r
-       static SQRegFunction _thread_default_delegate_funcz[];\r
-       SQObjectPtr _class_default_delegate;\r
-       static SQRegFunction _class_default_delegate_funcz[];\r
-       SQObjectPtr _instance_default_delegate;\r
-       static SQRegFunction _instance_default_delegate_funcz[];\r
-       SQObjectPtr _weakref_default_delegate;\r
-       static SQRegFunction _weakref_default_delegate_funcz[];\r
-       \r
-       SQCOMPILERERROR _compilererrorhandler;\r
-       SQPRINTFUNCTION _printfunc;\r
-       bool _debuginfo;\r
-       bool _notifyallexceptions;\r
-private:\r
-       SQChar *_scratchpad;\r
-       SQInteger _scratchpadsize;\r
-};\r
-\r
-#define _sp(s) (_sharedstate->GetScratchPad(s))\r
-#define _spval (_sharedstate->GetScratchPad(-1))\r
-\r
-#define _table_ddel            _table(_sharedstate->_table_default_delegate) \r
-#define _array_ddel            _table(_sharedstate->_array_default_delegate) \r
-#define _string_ddel   _table(_sharedstate->_string_default_delegate) \r
-#define _number_ddel   _table(_sharedstate->_number_default_delegate) \r
-#define _generator_ddel        _table(_sharedstate->_generator_default_delegate) \r
-#define _closure_ddel  _table(_sharedstate->_closure_default_delegate) \r
-#define _thread_ddel   _table(_sharedstate->_thread_default_delegate) \r
-#define _class_ddel            _table(_sharedstate->_class_default_delegate) \r
-#define _instance_ddel _table(_sharedstate->_instance_default_delegate) \r
-#define _weakref_ddel  _table(_sharedstate->_weakref_default_delegate) \r
-\r
-#ifdef SQUNICODE //rsl REAL STRING LEN\r
-#define rsl(l) ((l)<<1)\r
-#else\r
-#define rsl(l) (l)\r
-#endif\r
-\r
-extern SQObjectPtr _null_;\r
-extern SQObjectPtr _true_;\r
-extern SQObjectPtr _false_;\r
-extern SQObjectPtr _one_;\r
-extern SQObjectPtr _minusone_;\r
-\r
-bool CompileTypemask(SQIntVec &res,const SQChar *typemask);\r
-\r
-void *sq_vm_malloc(SQUnsignedInteger size);\r
-void *sq_vm_realloc(void *p,SQUnsignedInteger oldsize,SQUnsignedInteger size);\r
-void sq_vm_free(void *p,SQUnsignedInteger size);\r
-#endif //_SQSTATE_H_\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQSTATE_H_
+#define _SQSTATE_H_
+
+#include "squtils.h"
+#include "sqobject.h"
+struct SQString;
+struct SQTable;
+//max number of character for a printed number
+#define NUMBER_MAX_CHAR 50
+
+struct StringTable
+{
+       StringTable();
+       ~StringTable();
+       SQString *Add(const SQChar *,SQInteger len);
+       void Remove(SQString *);
+private:
+       void Resize(SQInteger size);
+       void AllocNodes(SQInteger size);
+       SQString **_strings;
+       SQUnsignedInteger _numofslots;
+       SQUnsignedInteger _slotused;
+};
+
+struct RefTable {
+       struct RefNode {
+               SQObjectPtr obj;
+               SQUnsignedInteger refs;
+               struct RefNode *next;
+       };
+       RefTable();
+       ~RefTable();
+       void AddRef(SQObject &obj);
+       SQBool Release(SQObject &obj);
+#ifndef NO_GARBAGE_COLLECTOR
+       void Mark(SQCollectable **chain);
+#endif
+       void Finalize();
+private:
+       RefNode *Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add);
+       RefNode *Add(SQHash mainpos,SQObject &obj);
+       void Resize(SQUnsignedInteger size);
+       void AllocNodes(SQUnsignedInteger size);
+       SQUnsignedInteger _numofslots;
+       SQUnsignedInteger _slotused;
+       SQUnsignedInteger _buffersize;
+       RefNode *_freelist;
+       RefNode **_buckets;
+};
+
+#define ADD_STRING(ss,str,len) ss->_stringtable->Add(str,len)
+#define REMOVE_STRING(ss,bstr) ss->_stringtable->Remove(bstr)
+
+struct SQObjectPtr;
+
+struct SQSharedState
+{
+       SQSharedState();
+       ~SQSharedState();
+       void Init();
+public:
+       SQChar* GetScratchPad(SQInteger size);
+       SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name);
+#ifndef NO_GARBAGE_COLLECTOR
+       SQInteger CollectGarbage(SQVM *vm);
+       static void MarkObject(SQObjectPtr &o,SQCollectable **chain);
+#endif
+       SQObjectPtrVec *_metamethods;
+       SQObjectPtr _metamethodsmap;
+       SQObjectPtrVec *_systemstrings;
+       SQObjectPtrVec *_types;
+       StringTable *_stringtable;
+       RefTable _refs_table;
+       SQObjectPtr _registry;
+       SQObjectPtr _constructoridx;
+#ifndef NO_GARBAGE_COLLECTOR
+       SQCollectable *_gc_chain;
+#endif
+       SQObjectPtr _root_vm;
+       SQObjectPtr _table_default_delegate;
+       static SQRegFunction _table_default_delegate_funcz[];
+       SQObjectPtr _array_default_delegate;
+       static SQRegFunction _array_default_delegate_funcz[];
+       SQObjectPtr _string_default_delegate;
+       static SQRegFunction _string_default_delegate_funcz[];
+       SQObjectPtr _number_default_delegate;
+       static SQRegFunction _number_default_delegate_funcz[];
+       SQObjectPtr _generator_default_delegate;
+       static SQRegFunction _generator_default_delegate_funcz[];
+       SQObjectPtr _closure_default_delegate;
+       static SQRegFunction _closure_default_delegate_funcz[];
+       SQObjectPtr _thread_default_delegate;
+       static SQRegFunction _thread_default_delegate_funcz[];
+       SQObjectPtr _class_default_delegate;
+       static SQRegFunction _class_default_delegate_funcz[];
+       SQObjectPtr _instance_default_delegate;
+       static SQRegFunction _instance_default_delegate_funcz[];
+       SQObjectPtr _weakref_default_delegate;
+       static SQRegFunction _weakref_default_delegate_funcz[];
+
+       SQCOMPILERERROR _compilererrorhandler;
+       SQPRINTFUNCTION _printfunc;
+       bool _debuginfo;
+       bool _notifyallexceptions;
+private:
+       SQChar *_scratchpad;
+       SQInteger _scratchpadsize;
+};
+
+#define _sp(s) (_sharedstate->GetScratchPad(s))
+#define _spval (_sharedstate->GetScratchPad(-1))
+
+#define _table_ddel            _table(_sharedstate->_table_default_delegate)
+#define _array_ddel            _table(_sharedstate->_array_default_delegate)
+#define _string_ddel   _table(_sharedstate->_string_default_delegate)
+#define _number_ddel   _table(_sharedstate->_number_default_delegate)
+#define _generator_ddel        _table(_sharedstate->_generator_default_delegate)
+#define _closure_ddel  _table(_sharedstate->_closure_default_delegate)
+#define _thread_ddel   _table(_sharedstate->_thread_default_delegate)
+#define _class_ddel            _table(_sharedstate->_class_default_delegate)
+#define _instance_ddel _table(_sharedstate->_instance_default_delegate)
+#define _weakref_ddel  _table(_sharedstate->_weakref_default_delegate)
+
+#ifdef SQUNICODE //rsl REAL STRING LEN
+#define rsl(l) ((l)<<1)
+#else
+#define rsl(l) (l)
+#endif
+
+extern SQObjectPtr _null_;
+extern SQObjectPtr _true_;
+extern SQObjectPtr _false_;
+extern SQObjectPtr _one_;
+extern SQObjectPtr _minusone_;
+
+bool CompileTypemask(SQIntVec &res,const SQChar *typemask);
+
+void *sq_vm_malloc(SQUnsignedInteger size);
+void *sq_vm_realloc(void *p,SQUnsignedInteger oldsize,SQUnsignedInteger size);
+void sq_vm_free(void *p,SQUnsignedInteger size);
+#endif //_SQSTATE_H_
index 235d190..14f09e1 100644 (file)
@@ -1,31 +1,31 @@
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQSTRING_H_\r
-#define _SQSTRING_H_\r
-\r
-inline SQHash _hashstr (const SQChar *s, size_t l)\r
-{\r
-               SQHash h = (SQHash)l;  /* seed */\r
-               size_t step = (l>>5)|1;  /* if string is too long, don't hash all its chars */\r
-               for (; l>=step; l-=step)\r
-                       h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++));\r
-               return h;\r
-}\r
-\r
-struct SQString : public SQRefCounted\r
-{\r
-       SQString(){}\r
-       ~SQString(){}\r
-public:\r
-       static SQString *Create(SQSharedState *ss, const SQChar *, SQInteger len = -1 );\r
-       SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);\r
-       void Release();\r
-       SQSharedState *_sharedstate;\r
-       SQString *_next; //chain for the string table\r
-       SQInteger _len;\r
-       SQHash _hash;\r
-       SQChar _val[1];\r
-};\r
-\r
-\r
-\r
-#endif //_SQSTRING_H_\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQSTRING_H_
+#define _SQSTRING_H_
+
+inline SQHash _hashstr (const SQChar *s, size_t l)
+{
+               SQHash h = (SQHash)l;  /* seed */
+               size_t step = (l>>5)|1;  /* if string is too long, don't hash all its chars */
+               for (; l>=step; l-=step)
+                       h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++));
+               return h;
+}
+
+struct SQString : public SQRefCounted
+{
+       SQString(){}
+       ~SQString(){}
+public:
+       static SQString *Create(SQSharedState *ss, const SQChar *, SQInteger len = -1 );
+       SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
+       void Release();
+       SQSharedState *_sharedstate;
+       SQString *_next; //chain for the string table
+       SQInteger _len;
+       SQHash _hash;
+       SQChar _val[1];
+};
+
+
+
+#endif //_SQSTRING_H_
index 4d96080..71c2c0e 100644 (file)
-/*\r
-see copyright notice in squirrel.h\r
-*/\r
-#include "sqpcheader.h"\r
-#include "sqvm.h"\r
-#include "sqtable.h"\r
-#include "sqfuncproto.h"\r
-#include "sqclosure.h"\r
-\r
-SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize)\r
-{\r
-       SQInteger pow2size=MINPOWER2;\r
-       while(nInitialSize>pow2size)pow2size=pow2size<<1;\r
-       AllocNodes(pow2size);\r
-       _usednodes = 0;\r
-       _delegate = NULL;\r
-       INIT_CHAIN();\r
-       ADD_TO_CHAIN(&_sharedstate->_gc_chain,this);\r
-}\r
-\r
-void SQTable::Remove(const SQObjectPtr &key)\r
-{\r
-       \r
-       _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));\r
-       if (n) {\r
-               n->val = n->key = _null_;\r
-               _usednodes--;\r
-               Rehash(false);\r
-       }\r
-}\r
-\r
-void SQTable::AllocNodes(SQInteger nSize)\r
-{\r
-       _HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize);\r
-       for(SQInteger i=0;i<nSize;i++){\r
-               new (&nodes[i]) _HashNode;\r
-               nodes[i].next=NULL;\r
-       }\r
-       _numofnodes=nSize;\r
-       _nodes=nodes;\r
-       _firstfree=&_nodes[_numofnodes-1];\r
-}\r
-\r
-void SQTable::Rehash(bool force)\r
-{\r
-       SQInteger oldsize=_numofnodes;\r
-       //prevent problems with the integer division\r
-       if(oldsize<4)oldsize=4;\r
-       _HashNode *nold=_nodes;\r
-       SQInteger nelems=CountUsed();\r
-       if (nelems >= oldsize-oldsize/4)  /* using more than 3/4? */\r
-               AllocNodes(oldsize*2);\r
-       else if (nelems <= oldsize/4 &&  /* less than 1/4? */\r
-               oldsize > MINPOWER2)\r
-               AllocNodes(oldsize/2);\r
-       else if(force)\r
-               AllocNodes(oldsize);\r
-       else\r
-               return;\r
-       _usednodes = 0;\r
-       for (SQInteger i=0; i<oldsize; i++) {\r
-               _HashNode *old = nold+i;\r
-               if (type(old->key) != OT_NULL)\r
-                       NewSlot(old->key,old->val);\r
-       }\r
-       for(SQInteger k=0;k<oldsize;k++) \r
-               nold[k].~_HashNode();\r
-       SQ_FREE(nold,oldsize*sizeof(_HashNode));\r
-}\r
-\r
-SQTable *SQTable::Clone()\r
-{\r
-       SQTable *nt=Create(_opt_ss(this),_numofnodes);\r
-       SQInteger ridx=0;\r
-       SQObjectPtr key,val;\r
-       while((ridx=Next(true,ridx,key,val))!=-1){\r
-               nt->NewSlot(key,val);\r
-       }\r
-       nt->SetDelegate(_delegate);\r
-       return nt;\r
-}\r
-\r
-bool SQTable::Get(const SQObjectPtr &key,SQObjectPtr &val)\r
-{\r
-       if(type(key) == OT_NULL)\r
-               return false;\r
-       _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));\r
-       if (n) {\r
-               val = _realval(n->val);\r
-               return true;\r
-       }\r
-       return false;\r
-}\r
-bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)\r
-{\r
-       assert(type(key) != OT_NULL);\r
-       SQHash h = HashObj(key) & (_numofnodes - 1);\r
-       _HashNode *n = _Get(key, h);\r
-       if (n) {\r
-               n->val = val;\r
-               return false;\r
-       }\r
-       _HashNode *mp = &_nodes[h];\r
-       n = mp;\r
-\r
-\r
-       //key not found I'll insert it\r
-       //main pos is not free\r
-\r
-       if(type(mp->key) != OT_NULL) {\r
-               n = _firstfree;  /* get a free place */\r
-               SQHash mph = HashObj(mp->key) & (_numofnodes - 1);\r
-               _HashNode *othern;  /* main position of colliding node */\r
-               \r
-               if (mp > n && (othern = &_nodes[mph]) != mp){\r
-                       /* yes; move colliding node into free position */\r
-                       while (othern->next != mp){\r
-                               assert(othern->next != NULL);\r
-                               othern = othern->next;  /* find previous */\r
-                       }\r
-                       othern->next = n;  /* redo the chain with `n' in place of `mp' */\r
-                       n->key = mp->key;\r
-                       n->val = mp->val;/* copy colliding node into free pos. (mp->next also goes) */\r
-                       n->next = mp->next;\r
-                       mp->key = _null_;\r
-                       mp->val = _null_;\r
-                       mp->next = NULL;  /* now `mp' is free */\r
-               }\r
-               else{\r
-                       /* new node will go into free position */\r
-                       n->next = mp->next;  /* chain new position */\r
-                       mp->next = n;\r
-                       mp = n;\r
-               }\r
-       }\r
-       mp->key = key;\r
-\r
-       for (;;) {  /* correct `firstfree' */\r
-               if (type(_firstfree->key) == OT_NULL && _firstfree->next == NULL) {\r
-                       mp->val = val;\r
-                       _usednodes++;\r
-                       return true;  /* OK; table still has a free place */\r
-               }\r
-               else if (_firstfree == _nodes) break;  /* cannot decrement from here */\r
-               else (_firstfree)--;\r
-       }\r
-       Rehash(true);\r
-       return NewSlot(key, val);\r
-}\r
-\r
-SQInteger SQTable::Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)\r
-{\r
-       SQInteger idx = (SQInteger)TranslateIndex(refpos);\r
-       while (idx < _numofnodes) {\r
-               if(type(_nodes[idx].key) != OT_NULL) {\r
-                       //first found\r
-                       _HashNode &n = _nodes[idx];\r
-                       outkey = n.key;\r
-                       outval = getweakrefs?(SQObject)n.val:_realval(n.val);\r
-                       //return idx for the next iteration\r
-                       return ++idx;\r
-               }\r
-               ++idx;\r
-       }\r
-       //nothing to iterate anymore\r
-       return -1;\r
-}\r
-\r
-\r
-bool SQTable::Set(const SQObjectPtr &key, const SQObjectPtr &val)\r
-{\r
-       _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));\r
-       if (n) {\r
-               n->val = val;\r
-               return true;\r
-       }\r
-       return false;\r
-}\r
-\r
-void SQTable::Finalize()\r
-{\r
-       for(SQInteger i = 0;i < _numofnodes; i++) { _nodes[i].key = _null_; _nodes[i].val = _null_; }\r
-               SetDelegate(NULL);\r
-}\r
+/*
+see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include "sqvm.h"
+#include "sqtable.h"
+#include "sqfuncproto.h"
+#include "sqclosure.h"
+
+SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize)
+{
+       SQInteger pow2size=MINPOWER2;
+       while(nInitialSize>pow2size)pow2size=pow2size<<1;
+       AllocNodes(pow2size);
+       _usednodes = 0;
+       _delegate = NULL;
+       INIT_CHAIN();
+       ADD_TO_CHAIN(&_sharedstate->_gc_chain,this);
+}
+
+void SQTable::Remove(const SQObjectPtr &key)
+{
+
+       _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
+       if (n) {
+               n->val = n->key = _null_;
+               _usednodes--;
+               Rehash(false);
+       }
+}
+
+void SQTable::AllocNodes(SQInteger nSize)
+{
+       _HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize);
+       for(SQInteger i=0;i<nSize;i++){
+               new (&nodes[i]) _HashNode;
+               nodes[i].next=NULL;
+       }
+       _numofnodes=nSize;
+       _nodes=nodes;
+       _firstfree=&_nodes[_numofnodes-1];
+}
+
+void SQTable::Rehash(bool force)
+{
+       SQInteger oldsize=_numofnodes;
+       //prevent problems with the integer division
+       if(oldsize<4)oldsize=4;
+       _HashNode *nold=_nodes;
+       SQInteger nelems=CountUsed();
+       if (nelems >= oldsize-oldsize/4)  /* using more than 3/4? */
+               AllocNodes(oldsize*2);
+       else if (nelems <= oldsize/4 &&  /* less than 1/4? */
+               oldsize > MINPOWER2)
+               AllocNodes(oldsize/2);
+       else if(force)
+               AllocNodes(oldsize);
+       else
+               return;
+       _usednodes = 0;
+       for (SQInteger i=0; i<oldsize; i++) {
+               _HashNode *old = nold+i;
+               if (type(old->key) != OT_NULL)
+                       NewSlot(old->key,old->val);
+       }
+       for(SQInteger k=0;k<oldsize;k++)
+               nold[k].~_HashNode();
+       SQ_FREE(nold,oldsize*sizeof(_HashNode));
+}
+
+SQTable *SQTable::Clone()
+{
+       SQTable *nt=Create(_opt_ss(this),_numofnodes);
+       SQInteger ridx=0;
+       SQObjectPtr key,val;
+       while((ridx=Next(true,ridx,key,val))!=-1){
+               nt->NewSlot(key,val);
+       }
+       nt->SetDelegate(_delegate);
+       return nt;
+}
+
+bool SQTable::Get(const SQObjectPtr &key,SQObjectPtr &val)
+{
+       if(type(key) == OT_NULL)
+               return false;
+       _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
+       if (n) {
+               val = _realval(n->val);
+               return true;
+       }
+       return false;
+}
+bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
+{
+       assert(type(key) != OT_NULL);
+       SQHash h = HashObj(key) & (_numofnodes - 1);
+       _HashNode *n = _Get(key, h);
+       if (n) {
+               n->val = val;
+               return false;
+       }
+       _HashNode *mp = &_nodes[h];
+       n = mp;
+
+
+       //key not found I'll insert it
+       //main pos is not free
+
+       if(type(mp->key) != OT_NULL) {
+               n = _firstfree;  /* get a free place */
+               SQHash mph = HashObj(mp->key) & (_numofnodes - 1);
+               _HashNode *othern;  /* main position of colliding node */
+
+               if (mp > n && (othern = &_nodes[mph]) != mp){
+                       /* yes; move colliding node into free position */
+                       while (othern->next != mp){
+                               assert(othern->next != NULL);
+                               othern = othern->next;  /* find previous */
+                       }
+                       othern->next = n;  /* redo the chain with `n' in place of `mp' */
+                       n->key = mp->key;
+                       n->val = mp->val;/* copy colliding node into free pos. (mp->next also goes) */
+                       n->next = mp->next;
+                       mp->key = _null_;
+                       mp->val = _null_;
+                       mp->next = NULL;  /* now `mp' is free */
+               }
+               else{
+                       /* new node will go into free position */
+                       n->next = mp->next;  /* chain new position */
+                       mp->next = n;
+                       mp = n;
+               }
+       }
+       mp->key = key;
+
+       for (;;) {  /* correct `firstfree' */
+               if (type(_firstfree->key) == OT_NULL && _firstfree->next == NULL) {
+                       mp->val = val;
+                       _usednodes++;
+                       return true;  /* OK; table still has a free place */
+               }
+               else if (_firstfree == _nodes) break;  /* cannot decrement from here */
+               else (_firstfree)--;
+       }
+       Rehash(true);
+       return NewSlot(key, val);
+}
+
+SQInteger SQTable::Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
+{
+       SQInteger idx = (SQInteger)TranslateIndex(refpos);
+       while (idx < _numofnodes) {
+               if(type(_nodes[idx].key) != OT_NULL) {
+                       //first found
+                       _HashNode &n = _nodes[idx];
+                       outkey = n.key;
+                       outval = getweakrefs?(SQObject)n.val:_realval(n.val);
+                       //return idx for the next iteration
+                       return ++idx;
+               }
+               ++idx;
+       }
+       //nothing to iterate anymore
+       return -1;
+}
+
+
+bool SQTable::Set(const SQObjectPtr &key, const SQObjectPtr &val)
+{
+       _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
+       if (n) {
+               n->val = val;
+               return true;
+       }
+       return false;
+}
+
+void SQTable::Finalize()
+{
+       for(SQInteger i = 0;i < _numofnodes; i++) { _nodes[i].key = _null_; _nodes[i].val = _null_; }
+               SetDelegate(NULL);
+}
index be66843..742074f 100644 (file)
@@ -1,89 +1,89 @@
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQTABLE_H_\r
-#define _SQTABLE_H_\r
-/*\r
-* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)\r
-* http://www.lua.org/copyright.html#4\r
-* http://www.lua.org/source/4.0.1/src_ltable.c.html\r
-*/\r
-\r
-#include "sqstring.h"\r
-\r
-\r
-#define hashptr(p)  ((SQHash)(((SQInteger)p) >> 3))\r
-\r
-inline SQHash HashObj(const SQObjectPtr &key)\r
-{\r
-       switch(type(key)) {\r
-               case OT_STRING:         return _string(key)->_hash;\r
-               case OT_FLOAT:          return (SQHash)((SQInteger)_float(key));\r
-               case OT_BOOL: case OT_INTEGER:  return (SQHash)((SQInteger)_integer(key));\r
-               default:                        return hashptr(key._unVal.pRefCounted);\r
-       }\r
-}\r
-\r
-struct SQTable : public SQDelegable \r
-{\r
-private:\r
-       struct _HashNode\r
-       {\r
-               _HashNode() { next = NULL; }\r
-               SQObjectPtr val;\r
-               SQObjectPtr key;\r
-               _HashNode *next;\r
-       };\r
-       _HashNode *_firstfree;\r
-       _HashNode *_nodes;\r
-       SQInteger _numofnodes;\r
-       SQInteger _usednodes;\r
-       \r
-///////////////////////////\r
-       void AllocNodes(SQInteger nSize);\r
-       void Rehash(bool force);\r
-       SQTable(SQSharedState *ss, SQInteger nInitialSize);\r
-public:\r
-       static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize)\r
-       {\r
-               SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));\r
-               new (newtable) SQTable(ss, nInitialSize);\r
-               newtable->_delegate = NULL;\r
-               return newtable;\r
-       }\r
-       void Finalize();\r
-       SQTable *Clone();\r
-       ~SQTable()\r
-       {\r
-               SetDelegate(NULL);\r
-               REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);\r
-               for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();\r
-               SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));\r
-       }\r
-#ifndef NO_GARBAGE_COLLECTOR \r
-       void Mark(SQCollectable **chain);\r
-#endif\r
-       inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash)\r
-       {\r
-               _HashNode *n = &_nodes[hash];\r
-               do{\r
-                       if(_rawval(n->key) == _rawval(key) && type(n->key) == type(key)){\r
-                               return n;\r
-                       }\r
-               }while((n = n->next));\r
-               return NULL;\r
-       }\r
-       bool Get(const SQObjectPtr &key,SQObjectPtr &val);\r
-       void Remove(const SQObjectPtr &key);\r
-       bool Set(const SQObjectPtr &key, const SQObjectPtr &val);\r
-       //returns true if a new slot has been created false if it was already present\r
-       bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val);\r
-       SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);\r
-       \r
-       SQInteger CountUsed(){ return _usednodes;}\r
-       void Release()\r
-       {\r
-               sq_delete(this, SQTable);\r
-       }\r
-       \r
-};\r
-\r
-#endif //_SQTABLE_H_\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQTABLE_H_
+#define _SQTABLE_H_
+/*
+* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)
+* http://www.lua.org/copyright.html#4
+* http://www.lua.org/source/4.0.1/src_ltable.c.html
+*/
+
+#include "sqstring.h"
+
+
+#define hashptr(p)  ((SQHash)(((SQInteger)p) >> 3))
+
+inline SQHash HashObj(const SQObjectPtr &key)
+{
+       switch(type(key)) {
+               case OT_STRING:         return _string(key)->_hash;
+               case OT_FLOAT:          return (SQHash)((SQInteger)_float(key));
+               case OT_BOOL: case OT_INTEGER:  return (SQHash)((SQInteger)_integer(key));
+               default:                        return hashptr(key._unVal.pRefCounted);
+       }
+}
+
+struct SQTable : public SQDelegable
+{
+private:
+       struct _HashNode
+       {
+               _HashNode() { next = NULL; }
+               SQObjectPtr val;
+               SQObjectPtr key;
+               _HashNode *next;
+       };
+       _HashNode *_firstfree;
+       _HashNode *_nodes;
+       SQInteger _numofnodes;
+       SQInteger _usednodes;
+
+///////////////////////////
+       void AllocNodes(SQInteger nSize);
+       void Rehash(bool force);
+       SQTable(SQSharedState *ss, SQInteger nInitialSize);
+public:
+       static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize)
+       {
+               SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));
+               new (newtable) SQTable(ss, nInitialSize);
+               newtable->_delegate = NULL;
+               return newtable;
+       }
+       void Finalize();
+       SQTable *Clone();
+       ~SQTable()
+       {
+               SetDelegate(NULL);
+               REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
+               for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();
+               SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));
+       }
+#ifndef NO_GARBAGE_COLLECTOR
+       void Mark(SQCollectable **chain);
+#endif
+       inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash)
+       {
+               _HashNode *n = &_nodes[hash];
+               do{
+                       if(_rawval(n->key) == _rawval(key) && type(n->key) == type(key)){
+                               return n;
+                       }
+               }while((n = n->next));
+               return NULL;
+       }
+       bool Get(const SQObjectPtr &key,SQObjectPtr &val);
+       void Remove(const SQObjectPtr &key);
+       bool Set(const SQObjectPtr &key, const SQObjectPtr &val);
+       //returns true if a new slot has been created false if it was already present
+       bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val);
+       SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
+
+       SQInteger CountUsed(){ return _usednodes;}
+       void Release()
+       {
+               sq_delete(this, SQTable);
+       }
+
+};
+
+#endif //_SQTABLE_H_
index 8fe0411..8b6b431 100644 (file)
@@ -1,38 +1,38 @@
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQUSERDATA_H_\r
-#define _SQUSERDATA_H_\r
-\r
-struct SQUserData : SQDelegable\r
-{\r
-       SQUserData(SQSharedState *ss){ _delegate = 0; _hook = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); }\r
-       ~SQUserData()\r
-       {\r
-               REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this);\r
-               SetDelegate(NULL);\r
-       }\r
-       static SQUserData* Create(SQSharedState *ss, SQInteger size)\r
-       {\r
-               SQUserData* ud = (SQUserData*)SQ_MALLOC(sizeof(SQUserData)+(size-1));\r
-               new (ud) SQUserData(ss);\r
-               ud->_size = size;\r
-               ud->_typetag = 0;\r
-               return ud;\r
-       }\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-       void Mark(SQCollectable **chain);\r
-       void Finalize(){SetDelegate(NULL);}\r
-#endif\r
-       void Release() {\r
-               if (_hook) _hook(_val,_size);\r
-               SQInteger tsize = _size - 1;\r
-               this->~SQUserData();\r
-               SQ_FREE(this, sizeof(SQUserData) + tsize);\r
-       }\r
-               \r
-       SQInteger _size;\r
-       SQRELEASEHOOK _hook;\r
-       SQUserPointer _typetag;\r
-       SQChar _val[1];\r
-};\r
-\r
-#endif //_SQUSERDATA_H_\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQUSERDATA_H_
+#define _SQUSERDATA_H_
+
+struct SQUserData : SQDelegable
+{
+       SQUserData(SQSharedState *ss){ _delegate = 0; _hook = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); }
+       ~SQUserData()
+       {
+               REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this);
+               SetDelegate(NULL);
+       }
+       static SQUserData* Create(SQSharedState *ss, SQInteger size)
+       {
+               SQUserData* ud = (SQUserData*)SQ_MALLOC(sizeof(SQUserData)+(size-1));
+               new (ud) SQUserData(ss);
+               ud->_size = size;
+               ud->_typetag = 0;
+               return ud;
+       }
+#ifndef NO_GARBAGE_COLLECTOR
+       void Mark(SQCollectable **chain);
+       void Finalize(){SetDelegate(NULL);}
+#endif
+       void Release() {
+               if (_hook) _hook(_val,_size);
+               SQInteger tsize = _size - 1;
+               this->~SQUserData();
+               SQ_FREE(this, sizeof(SQUserData) + tsize);
+       }
+
+       SQInteger _size;
+       SQRELEASEHOOK _hook;
+       SQUserPointer _typetag;
+       SQChar _val[1];
+};
+
+#endif //_SQUSERDATA_H_
index 86456ba..3f86621 100644 (file)
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQUTILS_H_\r
-#define _SQUTILS_H_\r
-\r
-#define sq_new(__ptr,__type) {__ptr=(__type *)sq_vm_malloc(sizeof(__type));new (__ptr) __type;}\r
-#define sq_delete(__ptr,__type) {__ptr->~__type();sq_vm_free(__ptr,sizeof(__type));}\r
-#define SQ_MALLOC(__size) sq_vm_malloc(__size);\r
-#define SQ_FREE(__ptr,__size) sq_vm_free(__ptr,__size);\r
-#define SQ_REALLOC(__ptr,__oldsize,__size) sq_vm_realloc(__ptr,__oldsize,__size);\r
-\r
-//sqvector mini vector class, supports objects by value\r
-template<typename T> class sqvector\r
-{\r
-public:\r
-       sqvector()\r
-       {\r
-               _vals = NULL;\r
-               _size = 0;\r
-               _allocated = 0;\r
-       }\r
-       sqvector(const sqvector<T>& v)\r
-       {\r
-               copy(v);\r
-       }\r
-       void copy(const sqvector<T>& v)\r
-       {\r
-               resize(v._size);\r
-               for(SQUnsignedInteger i = 0; i < v._size; i++) {\r
-                       new ((void *)&_vals[i]) T(v._vals[i]);\r
-               }\r
-               _size = v._size;\r
-       }\r
-       ~sqvector()\r
-       {\r
-               if(_allocated) {\r
-                       for(SQUnsignedInteger i = 0; i < _size; i++)\r
-                               _vals[i].~T();\r
-                       SQ_FREE(_vals, (_allocated * sizeof(T)));\r
-               }\r
-       }\r
-       void reserve(SQUnsignedInteger newsize) { _realloc(newsize); }\r
-       void resize(SQUnsignedInteger newsize, const T& fill = T())\r
-       {\r
-               if(newsize > _allocated)\r
-                       _realloc(newsize);\r
-               if(newsize > _size) {\r
-                       while(_size < newsize) {\r
-                               new ((void *)&_vals[_size]) T(fill);\r
-                               _size++;\r
-                       }\r
-               }\r
-               else{\r
-                       for(SQUnsignedInteger i = newsize; i < _size; i++) {\r
-                               _vals[i].~T();\r
-                       }\r
-                       _size = newsize;\r
-               }\r
-       }\r
-       void shrinktofit() { if(_size > 4) { _realloc(_size); } }\r
-       T& top() const { return _vals[_size - 1]; }\r
-       inline SQUnsignedInteger size() const { return _size; }\r
-       bool empty() const { return (_size <= 0); }\r
-       inline T &push_back(const T& val = T())\r
-       {\r
-               if(_allocated <= _size)\r
-                       _realloc(_size * 2);\r
-               return *(new ((void *)&_vals[_size++]) T(val));\r
-       }\r
-       inline void pop_back()\r
-       {\r
-               _size--; _vals[_size].~T();\r
-       }\r
-       void insert(SQUnsignedInteger idx, const T& val)\r
-       {\r
-               resize(_size + 1);\r
-               for(SQUnsignedInteger i = _size - 1; i > idx; i--) {\r
-                       _vals[i] = _vals[i - 1];\r
-               }\r
-       _vals[idx] = val;\r
-       }\r
-       void remove(SQUnsignedInteger idx)\r
-       {\r
-               _vals[idx].~T();\r
-               if(idx < (_size - 1)) {\r
-                       memcpy(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1));\r
-               }\r
-               _size--;\r
-       }\r
-       SQUnsignedInteger capacity() { return _allocated; }\r
-       inline T &back() const { return _vals[_size - 1]; }\r
-       inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; }\r
-       T* _vals;\r
-private:\r
-       void _realloc(SQUnsignedInteger newsize)\r
-       {\r
-               newsize = (newsize > 0)?newsize:4;\r
-               _vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T));\r
-               _allocated = newsize;\r
-       }\r
-       SQUnsignedInteger _size;\r
-       SQUnsignedInteger _allocated;\r
-};\r
-\r
-#endif //_SQUTILS_H_\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQUTILS_H_
+#define _SQUTILS_H_
+
+#define sq_new(__ptr,__type) {__ptr=(__type *)sq_vm_malloc(sizeof(__type));new (__ptr) __type;}
+#define sq_delete(__ptr,__type) {__ptr->~__type();sq_vm_free(__ptr,sizeof(__type));}
+#define SQ_MALLOC(__size) sq_vm_malloc(__size);
+#define SQ_FREE(__ptr,__size) sq_vm_free(__ptr,__size);
+#define SQ_REALLOC(__ptr,__oldsize,__size) sq_vm_realloc(__ptr,__oldsize,__size);
+
+//sqvector mini vector class, supports objects by value
+template<typename T> class sqvector
+{
+public:
+       sqvector()
+       {
+               _vals = NULL;
+               _size = 0;
+               _allocated = 0;
+       }
+       sqvector(const sqvector<T>& v)
+       {
+               copy(v);
+       }
+       void copy(const sqvector<T>& v)
+       {
+               resize(v._size);
+               for(SQUnsignedInteger i = 0; i < v._size; i++) {
+                       new ((void *)&_vals[i]) T(v._vals[i]);
+               }
+               _size = v._size;
+       }
+       ~sqvector()
+       {
+               if(_allocated) {
+                       for(SQUnsignedInteger i = 0; i < _size; i++)
+                               _vals[i].~T();
+                       SQ_FREE(_vals, (_allocated * sizeof(T)));
+               }
+       }
+       void reserve(SQUnsignedInteger newsize) { _realloc(newsize); }
+       void resize(SQUnsignedInteger newsize, const T& fill = T())
+       {
+               if(newsize > _allocated)
+                       _realloc(newsize);
+               if(newsize > _size) {
+                       while(_size < newsize) {
+                               new ((void *)&_vals[_size]) T(fill);
+                               _size++;
+                       }
+               }
+               else{
+                       for(SQUnsignedInteger i = newsize; i < _size; i++) {
+                               _vals[i].~T();
+                       }
+                       _size = newsize;
+               }
+       }
+       void shrinktofit() { if(_size > 4) { _realloc(_size); } }
+       T& top() const { return _vals[_size - 1]; }
+       inline SQUnsignedInteger size() const { return _size; }
+       bool empty() const { return (_size <= 0); }
+       inline T &push_back(const T& val = T())
+       {
+               if(_allocated <= _size)
+                       _realloc(_size * 2);
+               return *(new ((void *)&_vals[_size++]) T(val));
+       }
+       inline void pop_back()
+       {
+               _size--; _vals[_size].~T();
+       }
+       void insert(SQUnsignedInteger idx, const T& val)
+       {
+               resize(_size + 1);
+               for(SQUnsignedInteger i = _size - 1; i > idx; i--) {
+                       _vals[i] = _vals[i - 1];
+               }
+       _vals[idx] = val;
+       }
+       void remove(SQUnsignedInteger idx)
+       {
+               _vals[idx].~T();
+               if(idx < (_size - 1)) {
+                       memcpy(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1));
+               }
+               _size--;
+       }
+       SQUnsignedInteger capacity() { return _allocated; }
+       inline T &back() const { return _vals[_size - 1]; }
+       inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; }
+       T* _vals;
+private:
+       void _realloc(SQUnsignedInteger newsize)
+       {
+               newsize = (newsize > 0)?newsize:4;
+               _vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T));
+               _allocated = newsize;
+       }
+       SQUnsignedInteger _size;
+       SQUnsignedInteger _allocated;
+};
+
+#endif //_SQUTILS_H_
index b13ae24..888d342 100644 (file)
-/*\r
-       see copyright notice in squirrel.h\r
-*/\r
-#include "sqpcheader.h"\r
-#include <math.h>\r
-#include <stdlib.h>\r
-#include "sqopcodes.h"\r
-#include "sqfuncproto.h"\r
-#include "sqvm.h"\r
-#include "sqclosure.h"\r
-#include "sqstring.h"\r
-#include "sqtable.h"\r
-#include "squserdata.h"\r
-#include "sqarray.h"\r
-#include "sqclass.h"\r
-\r
-#define TOP() (_stack[_top-1])\r
-\r
-bool SQVM::BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2)\r
-{\r
-       SQInteger res;\r
-       SQInteger i1 = _integer(o1), i2 = _integer(o2);\r
-       if((type(o1)==OT_INTEGER) && (type(o2)==OT_INTEGER))\r
-       {\r
-               switch(op) {\r
-                       case BW_AND:    res = i1 & i2; break;\r
-                       case BW_OR:             res = i1 | i2; break;\r
-                       case BW_XOR:    res = i1 ^ i2; break;\r
-                       case BW_SHIFTL: res = i1 << i2; break;\r
-                       case BW_SHIFTR: res = i1 >> i2; break;\r
-                       case BW_USHIFTR:res = (SQInteger)(*((SQUnsignedInteger*)&i1) >> i2); break;\r
-                       default: { Raise_Error(_SC("internal vm error bitwise op failed")); return false; }\r
-               }\r
-       } \r
-       else { Raise_Error(_SC("bitwise op between '%s' and '%s'"),GetTypeName(o1),GetTypeName(o2)); return false;}\r
-       trg = res;\r
-       return true;\r
-}\r
-\r
-bool SQVM::ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2)\r
-{\r
-       if(sq_isnumeric(o1) && sq_isnumeric(o2)) {\r
-                       if((type(o1)==OT_INTEGER) && (type(o2)==OT_INTEGER)) {\r
-                               switch(op) {\r
-                               case '+': trg = _integer(o1) + _integer(o2); break;\r
-                               case '-': trg = _integer(o1) - _integer(o2); break;\r
-                               case '/': if(_integer(o2) == 0) { Raise_Error(_SC("division by zero")); return false; }\r
-                                       trg = _integer(o1) / _integer(o2); \r
-                                       break;\r
-                               case '*': trg = _integer(o1) * _integer(o2); break;\r
-                               case '%': trg = _integer(o1) % _integer(o2); break;\r
-                               }\r
-                       }else{\r
-                               switch(op) {\r
-                               case '+': trg = tofloat(o1) + tofloat(o2); break;\r
-                               case '-': trg = tofloat(o1) - tofloat(o2); break;\r
-                               case '/': trg = tofloat(o1) / tofloat(o2); break;\r
-                               case '*': trg = tofloat(o1) * tofloat(o2); break;\r
-                               case '%': trg = SQFloat(fmod((double)tofloat(o1),(double)tofloat(o2))); break;\r
-                               }\r
-                       }       \r
-               } else {\r
-                       if(op == '+' && (type(o1) == OT_STRING || type(o2) == OT_STRING)){\r
-                                       if(!StringCat(o1, o2, trg)) return false;\r
-                       }\r
-                       else if(!ArithMetaMethod(op,o1,o2,trg)) { \r
-                               Raise_Error(_SC("arith op %c on between '%s' and '%s'"),op,GetTypeName(o1),GetTypeName(o2)); return false; \r
-                       }\r
-               }\r
-               return true;\r
-}\r
-\r
-SQVM::SQVM(SQSharedState *ss)\r
-{\r
-       _sharedstate=ss;\r
-       _suspended = SQFalse;\r
-       _suspended_target=-1;\r
-       _suspended_root = SQFalse;\r
-       _suspended_traps=-1;\r
-       _foreignptr=NULL;\r
-       _nnativecalls=0;\r
-       _lasterror = _null_;\r
-       _errorhandler = _null_;\r
-       _debughook = _null_;\r
-       ci = NULL;\r
-       INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);\r
-}\r
-\r
-void SQVM::Finalize()\r
-{\r
-       _roottable = _null_;\r
-       _lasterror = _null_;\r
-       _errorhandler = _null_;\r
-       _debughook = _null_;\r
-       temp_reg = _null_;\r
-       SQInteger size=_stack.size();\r
-       for(SQInteger i=0;i<size;i++)\r
-               _stack[i]=_null_;\r
-}\r
-\r
-SQVM::~SQVM()\r
-{\r
-       Finalize();\r
-       REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);\r
-}\r
-\r
-bool SQVM::ArithMetaMethod(SQInteger op,const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &dest)\r
-{\r
-       SQMetaMethod mm;\r
-       switch(op){\r
-               case _SC('+'): mm=MT_ADD; break;\r
-               case _SC('-'): mm=MT_SUB; break;\r
-               case _SC('/'): mm=MT_DIV; break;\r
-               case _SC('*'): mm=MT_MUL; break;\r
-               case _SC('%'): mm=MT_MODULO; break;\r
-               default: mm = MT_ADD; assert(0); break; //shutup compiler\r
-       }\r
-       if(is_delegable(o1) && _delegable(o1)->_delegate) {\r
-               Push(o1);Push(o2);\r
-               return CallMetaMethod(_delegable(o1),mm,2,dest);\r
-       }\r
-       return false;\r
-}\r
-\r
-bool SQVM::NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o)\r
-{\r
-       \r
-       switch(type(o)) {\r
-       case OT_INTEGER:\r
-               trg = -_integer(o);\r
-               return true;\r
-       case OT_FLOAT:\r
-               trg = -_float(o);\r
-               return true;\r
-       case OT_TABLE:\r
-       case OT_USERDATA:\r
-       case OT_INSTANCE:\r
-               if(_delegable(o)->_delegate) {\r
-                       Push(o);\r
-                       if(CallMetaMethod(_delegable(o), MT_UNM, 1, temp_reg)) {\r
-                               trg = temp_reg;\r
-                               return true;\r
-                       }\r
-               }\r
-       default:break; //shutup compiler\r
-       }\r
-       Raise_Error(_SC("attempt to negate a %s"), GetTypeName(o));\r
-       return false;\r
-}\r
-\r
-#define _RET_SUCCEED(exp) { result = (exp); return true; } \r
-bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,SQInteger &result)\r
-{\r
-       if(type(o1)==type(o2)){\r
-               if(_userpointer(o1)==_userpointer(o2))_RET_SUCCEED(0);\r
-               SQObjectPtr res;\r
-               switch(type(o1)){\r
-               case OT_STRING:\r
-                       _RET_SUCCEED(scstrcmp(_stringval(o1),_stringval(o2)));\r
-               case OT_INTEGER:\r
-                       _RET_SUCCEED(_integer(o1)-_integer(o2));\r
-               case OT_FLOAT:\r
-                       _RET_SUCCEED((_float(o1)<_float(o2))?-1:1);\r
-               case OT_TABLE:\r
-               case OT_USERDATA:\r
-               case OT_INSTANCE:\r
-                       Push(o1);Push(o2);\r
-                       if(_delegable(o1)->_delegate)CallMetaMethod(_delegable(o1),MT_CMP,2,res);\r
-                       break;\r
-               default: break; //shutup compiler\r
-               }\r
-               if(type(res)!=OT_INTEGER) { Raise_CompareError(o1,o2); return false; }\r
-                       _RET_SUCCEED(_integer(res));\r
-               \r
-       }\r
-       else{\r
-               if(sq_isnumeric(o1) && sq_isnumeric(o2)){\r
-                       if((type(o1)==OT_INTEGER) && (type(o2)==OT_FLOAT)) { \r
-                               if( _integer(o1)==_float(o2) ) { _RET_SUCCEED(0); }\r
-                               else if( _integer(o1)<_float(o2) ) { _RET_SUCCEED(-1); }\r
-                               _RET_SUCCEED(1);\r
-                       }\r
-                       else{\r
-                               if( _float(o1)==_integer(o2) ) { _RET_SUCCEED(0); }\r
-                               else if( _float(o1)<_integer(o2) ) { _RET_SUCCEED(-1); }\r
-                               _RET_SUCCEED(1);\r
-                       }\r
-               }\r
-               else if(type(o1)==OT_NULL) {_RET_SUCCEED(-1);}\r
-               else if(type(o2)==OT_NULL) {_RET_SUCCEED(1);}\r
-               else { Raise_CompareError(o1,o2); return false; }\r
-               \r
-       }\r
-       assert(0);\r
-       _RET_SUCCEED(0); //cannot happen\r
-}\r
-\r
-bool SQVM::CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res)\r
-{\r
-       SQInteger r;\r
-       if(ObjCmp(o1,o2,r)) {\r
-               switch(op) {\r
-                       case CMP_G: res = (r > 0)?_true_:_false_; return true;\r
-                       case CMP_GE: res = (r >= 0)?_true_:_false_; return true;\r
-                       case CMP_L: res = (r < 0)?_true_:_false_; return true;\r
-                       case CMP_LE: res = (r <= 0)?_true_:_false_; return true;\r
-                       \r
-               }\r
-               assert(0);\r
-       }\r
-       return false;\r
-}\r
-\r
-void SQVM::ToString(const SQObjectPtr &o,SQObjectPtr &res)\r
-{\r
-       switch(type(o)) {\r
-       case OT_STRING:\r
-               res = o;\r
-               return;\r
-       case OT_FLOAT:\r
-               scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_SC("%g"),_float(o));\r
-               break;\r
-       case OT_INTEGER:\r
-               scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_SC("%d"),_integer(o));\r
-               break;\r
-       case OT_BOOL:\r
-               scsprintf(_sp(rsl(6)),_integer(o)?_SC("true"):_SC("false"));\r
-               break;\r
-       case OT_TABLE:\r
-       case OT_USERDATA:\r
-       case OT_INSTANCE:\r
-               if(_delegable(o)->_delegate) {\r
-                       Push(o);\r
-                       if(CallMetaMethod(_delegable(o),MT_TOSTRING,1,res)) {\r
-                               if(type(res) == OT_STRING)\r
-                                       return;\r
-                               //else keeps going to the default\r
-                       }\r
-               }\r
-       default:\r
-               scsprintf(_sp(rsl(sizeof(void*)+20)),_SC("(%s : 0x%p)"),GetTypeName(o),(void*)_rawval(o));\r
-       }\r
-       res = SQString::Create(_ss(this),_spval);\r
-}\r
-\r
-\r
-bool SQVM::StringCat(const SQObjectPtr &str,const SQObjectPtr &obj,SQObjectPtr &dest)\r
-{\r
-       SQObjectPtr a, b;\r
-       ToString(str, a);\r
-       ToString(obj, b);\r
-       SQInteger l = _string(a)->_len , ol = _string(b)->_len;\r
-       SQChar *s = _sp(rsl(l + ol + 1));\r
-       memcpy(s, _stringval(a), rsl(l)); \r
-       memcpy(s + l, _stringval(b), rsl(ol));\r
-       dest = SQString::Create(_ss(this), _spval, l + ol);\r
-       return true;\r
-}\r
-\r
-const SQChar *IdType2Name(SQObjectType type)\r
-{\r
-       switch(_RAW_TYPE(type))\r
-       {\r
-       case _RT_NULL:return _SC("null");\r
-       case _RT_INTEGER:return _SC("integer");\r
-       case _RT_FLOAT:return _SC("float");\r
-       case _RT_BOOL:return _SC("bool");\r
-       case _RT_STRING:return _SC("string");\r
-       case _RT_TABLE:return _SC("table");\r
-       case _RT_ARRAY:return _SC("array");\r
-       case _RT_GENERATOR:return _SC("generator");\r
-       case _RT_CLOSURE:\r
-       case _RT_NATIVECLOSURE:\r
-               return _SC("function");\r
-       case _RT_USERDATA:\r
-       case _RT_USERPOINTER:\r
-               return _SC("userdata");\r
-       case _RT_THREAD: return _SC("thread");\r
-       case _RT_FUNCPROTO: return _SC("function");\r
-       case _RT_CLASS: return _SC("class");\r
-       case _RT_INSTANCE: return _SC("instance");\r
-       case _RT_WEAKREF: return _SC("weakref");\r
-       default:\r
-               return NULL;\r
-       }\r
-}\r
-\r
-const SQChar *GetTypeName(const SQObjectPtr &obj1)\r
-{\r
-       return IdType2Name(type(obj1)); \r
-}\r
-\r
-void SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest)\r
-{\r
-       if(is_delegable(obj1) && _delegable(obj1)->_delegate) {\r
-               Push(obj1);\r
-               if(CallMetaMethod(_delegable(obj1),MT_TYPEOF,1,dest))\r
-                       return;\r
-       }\r
-       dest = SQString::Create(_ss(this),GetTypeName(obj1));\r
-}\r
-\r
-bool SQVM::Init(SQVM *friendvm, SQInteger stacksize)\r
-{\r
-       _stack.resize(stacksize);\r
-       _callsstack.reserve(4);\r
-       _stackbase = 0;\r
-       _top = 0;\r
-       if(!friendvm) \r
-               _roottable = SQTable::Create(_ss(this), 0);\r
-       else {\r
-               _roottable = friendvm->_roottable;\r
-               _errorhandler = friendvm->_errorhandler;\r
-               _debughook = friendvm->_debughook;\r
-       }\r
-       \r
-       sq_base_register(this);\r
-       return true;\r
-}\r
-\r
-extern SQInstructionDesc g_InstrDesc[];\r
-\r
-bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger nargs,SQInteger stackbase,bool tailcall)\r
-{\r
-       SQFunctionProto *func = _funcproto(closure->_function);\r
-       \r
-       const SQInteger paramssize = func->_parameters.size();\r
-       const SQInteger newtop = stackbase + func->_stacksize;\r
-       \r
-       \r
-       if (paramssize != nargs) {\r
-               if(func->_varparams)\r
-               {\r
-                       if (nargs < paramssize) {\r
-                               Raise_Error(_SC("wrong number of parameters"));\r
-                               return false;\r
-                       }\r
-                       for(SQInteger n = 0; n < nargs - paramssize; n++) {\r
-                               _vargsstack.push_back(_stack[stackbase+paramssize+n]);\r
-                               _stack[stackbase+paramssize+n] = _null_;\r
-                       }\r
-               }\r
-               else {\r
-                       Raise_Error(_SC("wrong number of parameters"));\r
-                       return false;\r
-               }\r
-       }\r
-\r
-       if(type(closure->_env) == OT_WEAKREF) {\r
-               _stack[stackbase] = _weakref(closure->_env)->_obj;\r
-       }\r
-\r
-       if (!tailcall) {\r
-               CallInfo lc;\r
-               lc._etraps = 0;\r
-               lc._prevstkbase = stackbase - _stackbase;\r
-               lc._target = target;\r
-               lc._prevtop = _top - _stackbase;\r
-               lc._ncalls = 1;\r
-               lc._root = SQFalse;\r
-               PUSH_CALLINFO(this, lc);\r
-       }\r
-       else {\r
-               ci->_ncalls++;\r
-               if(ci->_vargs.size) PopVarArgs(ci->_vargs);\r
-       }\r
-       ci->_vargs.size = (nargs - paramssize);\r
-       ci->_vargs.base = _vargsstack.size()-(ci->_vargs.size);\r
-       ci->_closure._unVal.pClosure = closure;\r
-       ci->_closure._type = OT_CLOSURE;\r
-       ci->_iv = &func->_instructions;\r
-       ci->_literals = &func->_literals;\r
-       //grows the stack if needed\r
-       if (((SQUnsignedInteger)newtop + (func->_stacksize<<1)) > _stack.size()) {\r
-               _stack.resize(_stack.size() + (func->_stacksize<<1));\r
-       }\r
-               \r
-       _top = newtop;\r
-       _stackbase = stackbase;\r
-       ci->_ip = ci->_iv->_vals;\r
-       return true;\r
-}\r
-\r
-bool SQVM::Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval)\r
-{\r
-       if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))\r
-               for(SQInteger i=0;i<ci->_ncalls;i++)\r
-                       CallDebugHook(_SC('r'));\r
-                       \r
-       SQBool broot = ci->_root;\r
-       SQInteger last_top = _top;\r
-       SQInteger target = ci->_target;\r
-       SQInteger oldstackbase = _stackbase;\r
-       _stackbase -= ci->_prevstkbase;\r
-       _top = _stackbase + ci->_prevtop;\r
-       if(ci->_vargs.size) PopVarArgs(ci->_vargs);\r
-       POP_CALLINFO(this);\r
-       if (broot) {\r
-               if (_arg0 != MAX_FUNC_STACKSIZE) retval = _stack[oldstackbase+_arg1];\r
-               else retval = _null_;\r
-       }\r
-       else {\r
-               if(target != -1) { //-1 is when a class contructor ret value has to be ignored\r
-                       if (_arg0 != MAX_FUNC_STACKSIZE)\r
-                               STK(target) = _stack[oldstackbase+_arg1];\r
-                       else\r
-                               STK(target) = _null_;\r
-               }\r
-       }\r
-\r
-       while (last_top >= _top) _stack[last_top--].Null();\r
-       assert(oldstackbase >= _stackbase); \r
-       return broot?true:false;\r
-}\r
-\r
-#define _RET_ON_FAIL(exp) { if(!exp) return false; }\r
-\r
-bool SQVM::LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr)\r
-{\r
-       _RET_ON_FAIL(ARITH_OP( op , target, a, incr));\r
-       a = target;\r
-       return true;\r
-}\r
-\r
-bool SQVM::PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr)\r
-{\r
-       SQObjectPtr trg;\r
-       _RET_ON_FAIL(ARITH_OP( op , trg, a, incr));\r
-       target = a;\r
-       a = trg;\r
-       return true;\r
-}\r
-\r
-bool SQVM::DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix)\r
-{\r
-       SQObjectPtr tmp, tself = self, tkey = key;\r
-       if (!Get(tself, tkey, tmp, false, true)) { Raise_IdxError(tkey); return false; }\r
-       _RET_ON_FAIL(ARITH_OP( op , target, tmp, incr))\r
-       Set(tself, tkey, target,true);\r
-       if (postfix) target = tmp;\r
-       return true;\r
-}\r
-\r
-#define arg0 (_i_._arg0)\r
-#define arg1 (_i_._arg1)\r
-#define sarg1 (*((SQInt32 *)&_i_._arg1))\r
-#define arg2 (_i_._arg2)\r
-#define arg3 (_i_._arg3)\r
-#define sarg3 ((SQInteger)*((signed char *)&_i_._arg3))\r
-\r
-SQRESULT SQVM::Suspend()\r
-{\r
-       if (_suspended)\r
-               return sq_throwerror(this, _SC("cannot suspend an already suspended vm"));\r
-       if (_nnativecalls!=2)\r
-               return sq_throwerror(this, _SC("cannot suspend through native calls/metamethods"));\r
-       return SQ_SUSPEND_FLAG;\r
-}\r
-\r
-void SQVM::PopVarArgs(VarArgs &vargs)\r
-{\r
-       for(SQInteger n = 0; n< vargs.size; n++)\r
-               _vargsstack.pop_back();\r
-}\r
-\r
-#define _FINISH(stoploop) {finished = stoploop; return true; }\r
-bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr \r
-&o3,SQObjectPtr &o4,SQInteger arg_2,bool &finished)\r
-{\r
-       SQInteger nrefidx;\r
-       switch(type(o1)) {\r
-       case OT_TABLE:\r
-               if((nrefidx = _table(o1)->Next(false,o4, o2, o3)) == -1) _FINISH(true);\r
-               o4 = (SQInteger)nrefidx; _FINISH(false);\r
-       case OT_ARRAY:\r
-               if((nrefidx = _array(o1)->Next(o4, o2, o3)) == -1) _FINISH(true);\r
-               o4 = (SQInteger) nrefidx; _FINISH(false);\r
-       case OT_STRING:\r
-               if((nrefidx = _string(o1)->Next(o4, o2, o3)) == -1)_FINISH(true);\r
-               o4 = (SQInteger)nrefidx; _FINISH(false);\r
-       case OT_CLASS:\r
-               if((nrefidx = _class(o1)->Next(o4, o2, o3)) == -1)_FINISH(true);\r
-               o4 = (SQInteger)nrefidx; _FINISH(false);\r
-       case OT_USERDATA:\r
-       case OT_INSTANCE:\r
-               if(_delegable(o1)->_delegate) {\r
-                       SQObjectPtr itr;\r
-                       Push(o1);\r
-                       Push(o4);\r
-                       if(CallMetaMethod(_delegable(o1), MT_NEXTI, 2, itr)){\r
-                               o4 = o2 = itr;\r
-                               if(type(itr) == OT_NULL) _FINISH(true);\r
-                               if(!Get(o1, itr, o3, false,false)) {\r
-                                       Raise_Error(_SC("_nexti returned an invalid idx"));\r
-                                       return false;\r
-                               }\r
-                               _FINISH(false);\r
-                       }\r
-                       Raise_Error(_SC("_nexti failed"));\r
-                       return false;\r
-               }\r
-               break;\r
-       case OT_GENERATOR:\r
-               if(_generator(o1)->_state == SQGenerator::eDead) _FINISH(true);\r
-               if(_generator(o1)->_state == SQGenerator::eSuspended) {\r
-                       SQInteger idx = 0;\r
-                       if(type(o4) == OT_INTEGER) {\r
-                               idx = _integer(o4) + 1;\r
-                       }\r
-                       o2 = idx;\r
-                       o4 = idx;\r
-                       _generator(o1)->Resume(this, arg_2+1);\r
-                       _FINISH(false);\r
-               }\r
-       default: \r
-               Raise_Error(_SC("cannot iterate %s"), GetTypeName(o1));\r
-       }\r
-       return false; //cannot be hit(just to avoid warnings)\r
-}\r
-\r
-bool SQVM::DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2)\r
-{\r
-       if(type(o1) != OT_TABLE) { Raise_Error(_SC("delegating a '%s'"), GetTypeName(o1)); return false; }\r
-       switch(type(o2)) {\r
-       case OT_TABLE:\r
-               if(!_table(o1)->SetDelegate(_table(o2))){\r
-                       Raise_Error(_SC("delegate cycle detected"));\r
-                       return false;\r
-               }\r
-               break;\r
-       case OT_NULL:\r
-               _table(o1)->SetDelegate(NULL);\r
-               break;\r
-       default:\r
-               Raise_Error(_SC("using '%s' as delegate"), GetTypeName(o2));\r
-               return false;\r
-               break;\r
-       }\r
-       trg = o1;\r
-       return true;\r
-}\r
-#define COND_LITERAL (arg3!=0?(*ci->_literals)[arg1]:STK(arg1))\r
-\r
-#define _GUARD(exp) { if(!exp) { Raise_Error(_lasterror); SQ_THROW();} }\r
-\r
-#define SQ_THROW() { goto exception_trap; }\r
-\r
-bool SQVM::CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func)\r
-{\r
-       SQInteger nouters;\r
-       SQClosure *closure = SQClosure::Create(_ss(this), func);\r
-       if((nouters = func->_outervalues.size())) {\r
-               closure->_outervalues.reserve(nouters);\r
-               for(SQInteger i = 0; i<nouters; i++) {\r
-                       SQOuterVar &v = func->_outervalues[i];\r
-                       switch(v._type){\r
-                       case otSYMBOL:\r
-                               closure->_outervalues.push_back(_null_);\r
-                               if(!Get(_stack._vals[_stackbase]/*STK(0)*/, v._src, closure->_outervalues.top(), false,true))\r
-                               {Raise_IdxError(v._src); return false; }\r
-                               break;\r
-                       case otLOCAL:\r
-                               closure->_outervalues.push_back(_stack._vals[_stackbase+_integer(v._src)]);\r
-                               break;\r
-                       case otOUTER:\r
-                               closure->_outervalues.push_back(_closure(ci->_closure)->_outervalues[_integer(v._src)]);\r
-                               break;\r
-                       }\r
-               }\r
-       }\r
-       target = closure;\r
-       return true;\r
-\r
-}\r
-\r
-bool SQVM::GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &index,CallInfo *ci)\r
-{\r
-       if(ci->_vargs.size == 0) {\r
-               Raise_Error(_SC("the function doesn't have var args"));\r
-               return false;\r
-       }\r
-       if(!sq_isnumeric(index)){\r
-               Raise_Error(_SC("indexing 'vargv' with %s"),GetTypeName(index));\r
-               return false;\r
-       }\r
-       SQInteger idx = tointeger(index);\r
-       if(idx < 0 || idx >= ci->_vargs.size){ Raise_Error(_SC("vargv index out of range")); return false; }\r
-       target = _vargsstack[ci->_vargs.base+idx];\r
-       return true;\r
-}\r
-\r
-bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes)\r
-{\r
-       SQClass *base = NULL;\r
-       SQObjectPtr attrs;\r
-       if(baseclass != -1) {\r
-               if(type(_stack._vals[_stackbase+baseclass]) != OT_CLASS) { Raise_Error(_SC("trying to inherit from a %s"),GetTypeName(_stack._vals[_stackbase+baseclass])); return false; }\r
-               base = _class(_stack._vals[_stackbase + baseclass]);\r
-       }\r
-       if(attributes != MAX_FUNC_STACKSIZE) {\r
-               attrs = _stack._vals[_stackbase+attributes];\r
-       }\r
-       target = SQClass::Create(_ss(this),base);\r
-       if(type(_class(target)->_metamethods[MT_INHERITED]) != OT_NULL) {\r
-               int nparams = 2;\r
-               SQObjectPtr ret;\r
-               Push(target); Push(attrs);\r
-               Call(_class(target)->_metamethods[MT_INHERITED],nparams,_top - nparams, ret, false);\r
-               Pop(nparams);\r
-       }\r
-       _class(target)->_attributes = attrs;\r
-       return true;\r
-}\r
-\r
-\r
-\r
-bool SQVM::IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res)\r
-{\r
-       if(type(o1) == type(o2)) {\r
-               res = ((_userpointer(o1) == _userpointer(o2)?true:false));\r
-       }\r
-       else {\r
-               if(sq_isnumeric(o1) && sq_isnumeric(o2)) {\r
-                       SQInteger cmpres;\r
-                       if(!ObjCmp(o1, o2,cmpres)) return false;\r
-                       res = (cmpres == 0);\r
-               }\r
-               else {\r
-                       res = false;\r
-               }\r
-       }\r
-       return true;\r
-}\r
-\r
-bool SQVM::IsFalse(SQObjectPtr &o)\r
-{\r
-       if((type(o) & SQOBJECT_CANBEFALSE) && ( (type(o) == OT_FLOAT) && (_float(o) == SQFloat(0.0)) )\r
-               || (_integer(o) == 0) ) { //OT_NULL|OT_INTEGER|OT_BOOL\r
-               return true;\r
-       }\r
-       return false;\r
-}\r
-\r
-bool SQVM::GETPARENT_OP(SQObjectPtr &o,SQObjectPtr &target)\r
-{\r
-       switch(type(o)) {\r
-               case OT_TABLE: target = _table(o)->_delegate?SQObjectPtr(_table(o)->_delegate):_null_;\r
-                       break;\r
-               case OT_CLASS: target = _class(o)->_base?_class(o)->_base:_null_;\r
-                       break;\r
-               default:\r
-                       Raise_Error(_SC("the %s type doesn't have a parent slot"), GetTypeName(o));\r
-                       return false;\r
-       }\r
-       return true;\r
-}\r
-\r
-bool SQVM::Execute(SQObjectPtr &closure, SQInteger target, SQInteger nargs, SQInteger stackbase,SQObjectPtr &outres, SQBool raiseerror,ExecutionType et)\r
-{\r
-       if ((_nnativecalls + 1) > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; }\r
-       _nnativecalls++;\r
-       AutoDec ad(&_nnativecalls);\r
-       SQInteger traps = 0;\r
-       //temp_reg vars for OP_CALL\r
-       SQInteger ct_target;\r
-       bool ct_tailcall; \r
-\r
-       switch(et) {\r
-               case ET_CALL: \r
-                       if(!StartCall(_closure(closure), _top - nargs, nargs, stackbase, false)) { \r
-                               //call the handler if there are no calls in the stack, if not relies on the previous node\r
-                               if(ci == NULL) CallErrorHandler(_lasterror);\r
-                               return false;\r
-                       }\r
-                       ci->_root = SQTrue;\r
-                       break;\r
-               case ET_RESUME_GENERATOR: _generator(closure)->Resume(this, target); ci->_root = SQTrue; traps += ci->_etraps; break;\r
-               case ET_RESUME_VM:\r
-                       traps = _suspended_traps;\r
-                       ci->_root = _suspended_root;\r
-                       _suspended = SQFalse;\r
-                       break;\r
-       }\r
-       \r
-exception_restore:\r
-       //\r
-       {\r
-               for(;;)\r
-               {\r
-                       const SQInstruction &_i_ = *ci->_ip++;\r
-                       //dumpstack(_stackbase);\r
-                       //scprintf("\n[%d] %s %d %d %d %d\n",ci->_ip-ci->_iv->_vals,g_InstrDesc[_i_.op].name,arg0,arg1,arg2,arg3);\r
-                       switch(_i_.op)\r
-                       {\r
-                       case _OP_LINE:\r
-                               if(type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))\r
-                                       CallDebugHook(_SC('l'),arg1);\r
-                               continue;\r
-                       case _OP_LOAD: TARGET = (*ci->_literals)[arg1]; continue;\r
-                       case _OP_LOADINT: TARGET = (SQInteger)arg1; continue;\r
-                       case _OP_DLOAD: TARGET = (*ci->_literals)[arg1]; STK(arg2) = (*ci->_literals)[arg3];continue;\r
-                       case _OP_TAILCALL:\r
-                               temp_reg = STK(arg1);\r
-                               if (type(temp_reg) == OT_CLOSURE){ \r
-                                       ct_tailcall = true;\r
-                                       if(ci->_vargs.size) PopVarArgs(ci->_vargs);\r
-                                       for (SQInteger i = 0; i < arg3; i++) STK(i) = STK(arg2 + i);\r
-                                       ct_target = ci->_target;\r
-                                       goto common_call;\r
-                               }\r
-                       case _OP_CALL: {\r
-                                       ct_tailcall = false;\r
-                                       ct_target = arg0;\r
-                                       temp_reg = STK(arg1);\r
-common_call:\r
-                                       SQInteger last_top = _top;\r
-                                       switch (type(temp_reg)) {\r
-                                       case OT_CLOSURE:{\r
-                                               _GUARD(StartCall(_closure(temp_reg), ct_target, arg3, ct_tailcall?_stackbase:_stackbase+arg2, ct_tailcall));\r
-                                               if (_funcproto(_closure(temp_reg)->_function)->_bgenerator) {\r
-                                                       SQGenerator *gen = SQGenerator::Create(_ss(this), _closure(temp_reg));\r
-                                                       _GUARD(gen->Yield(this));\r
-                                                       Return(1, ct_target, temp_reg);\r
-                                                       STK(ct_target) = gen;\r
-                                                       while (last_top >= _top) _stack[last_top--].Null();\r
-                                                       continue;\r
-                                               }\r
-                                               if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))\r
-                                                       CallDebugHook(_SC('c'));\r
-                                               }\r
-                                               break;\r
-                                       case OT_NATIVECLOSURE: {\r
-                                               bool suspend;\r
-                                               _GUARD(CallNative(_nativeclosure(temp_reg), arg3, _stackbase+arg2, ct_tailcall, temp_reg,suspend));\r
-                                               if(suspend){\r
-                                                       _suspended = SQTrue;\r
-                                                       _suspended_target = ct_target;\r
-                                                       _suspended_root = ci->_root;\r
-                                                       _suspended_traps = traps;\r
-                                                       outres = temp_reg;\r
-                                                       return true;\r
-                                               }\r
-                                               if(ct_target != -1) { //skip return value for contructors\r
-                                                       STK(ct_target) = temp_reg;\r
-                                               }\r
-                                                                                  }\r
-                                               break;\r
-                                       case OT_CLASS:{\r
-                                               SQObjectPtr inst;\r
-                                               _GUARD(CreateClassInstance(_class(temp_reg),inst,temp_reg));\r
-                                               STK(ct_target) = inst;\r
-                                               ct_target = -1; //fakes return value target so that is not overwritten by the contructor\r
-                                               if(type(temp_reg) != OT_NULL) {\r
-                                                       _stack[_stackbase+arg2] = inst;\r
-                                                       goto common_call; //hard core spaghetti code(reissues the OP_CALL to invoke the contructor)\r
-                                               }\r
-                                               }\r
-                                               break;\r
-                                       case OT_TABLE:\r
-                                       case OT_USERDATA:\r
-                                       case OT_INSTANCE:\r
-                                               {\r
-                                               Push(temp_reg);\r
-                                               for (SQInteger i = 0; i < arg3; i++) Push(STK(arg2 + i));\r
-                                               if (_delegable(temp_reg) && CallMetaMethod(_delegable(temp_reg), MT_CALL, arg3+1, temp_reg)){\r
-                                                       STK(ct_target) = temp_reg;\r
-                                                       break;\r
-                                               }\r
-                                               Raise_Error(_SC("attempt to call '%s'"), GetTypeName(temp_reg));\r
-                                               SQ_THROW();\r
-                                         }\r
-                                       default:\r
-                                               Raise_Error(_SC("attempt to call '%s'"), GetTypeName(temp_reg));\r
-                                               SQ_THROW();\r
-                                       }\r
-                               }\r
-                                 continue;\r
-                       case _OP_PREPCALL:\r
-                                       if (!Get(STK(arg2), STK(arg1), temp_reg, false,true))\r
-                                       { Raise_IdxError(STK(arg1)); SQ_THROW(); }\r
-                                       goto common_prepcall;\r
-                       case _OP_PREPCALLK:\r
-                                       if (!Get(STK(arg2), (*ci->_literals)[arg1], temp_reg,false,true)) {\r
-                                               if(type(STK(arg2)) == OT_CLASS) { //hack?\r
-                                                       if(_class_ddel->Get((*ci->_literals)[arg1],temp_reg)) {\r
-                                                               STK(arg3) = STK(arg2);\r
-                                                               TARGET = temp_reg;\r
-                                                               continue;\r
-                                                       }\r
-                                               }\r
-                                               { Raise_IdxError((*ci->_literals)[arg1]); SQ_THROW();}\r
-                                       }\r
-common_prepcall:\r
-                                       if(type(STK(arg2)) == OT_CLASS) {\r
-                                               STK(arg3) = STK(0); // this\r
-                                       }\r
-                                       else {\r
-                                               STK(arg3) = STK(arg2);\r
-                                       }\r
-                                       TARGET = temp_reg;\r
-                               continue;\r
-                       case _OP_GETK:\r
-                               if (!Get(STK(arg2), (*ci->_literals)[arg1], temp_reg, false,true)) { Raise_IdxError((*ci->_literals)[arg1]); SQ_THROW();}\r
-                               TARGET = temp_reg;\r
-                               continue;\r
-                       case _OP_MOVE: TARGET = STK(arg1); continue;\r
-                       case _OP_NEWSLOT:\r
-                               _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),false));\r
-                               if(arg0 != arg3) TARGET = STK(arg3);\r
-                               continue;\r
-                       case _OP_DELETE: _GUARD(DeleteSlot(STK(arg1), STK(arg2), TARGET)); continue;\r
-                       case _OP_SET:\r
-                               if (!Set(STK(arg1), STK(arg2), STK(arg3),true)) { Raise_IdxError(STK(arg2)); SQ_THROW(); }\r
-                               if (arg0 != arg3) TARGET = STK(arg3);\r
-                               continue;\r
-                       case _OP_GET:\r
-                               if (!Get(STK(arg1), STK(arg2), temp_reg, false,true)) { Raise_IdxError(STK(arg2)); SQ_THROW(); }\r
-                               TARGET = temp_reg;\r
-                               continue;\r
-                       case _OP_EQ:{\r
-                               bool res;\r
-                               if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); }\r
-                               TARGET = res?_true_:_false_;\r
-                               }continue;\r
-                       case _OP_NE:{ \r
-                               bool res;\r
-                               if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); }\r
-                               TARGET = (!res)?_true_:_false_;\r
-                               } continue;\r
-                       case _OP_ARITH: _GUARD(ARITH_OP( arg3 , temp_reg, STK(arg2), STK(arg1))); TARGET = temp_reg; continue;\r
-                       case _OP_BITW:  _GUARD(BW_OP( arg3,TARGET,STK(arg2),STK(arg1))); continue;\r
-                       case _OP_RETURN:\r
-                               if(type((ci)->_generator) == OT_GENERATOR) {\r
-                                       _generator((ci)->_generator)->Kill();\r
-                               }\r
-                               if(Return(arg0, arg1, temp_reg)){\r
-                                       assert(traps==0);\r
-                                       outres = temp_reg;\r
-                                       return true;\r
-                               }\r
-                               continue;\r
-                       case _OP_LOADNULLS:{ for(SQInt32 n=0; n < arg1; n++) STK(arg0+n) = _null_; }continue;\r
-                       case _OP_LOADROOTTABLE: TARGET = _roottable; continue;\r
-                       case _OP_LOADBOOL: TARGET = arg1?_true_:_false_; continue;\r
-                       case _OP_DMOVE: STK(arg0) = STK(arg1); STK(arg2) = STK(arg3); continue;\r
-                       case _OP_JMP: ci->_ip += (sarg1); continue;\r
-                       case _OP_JNZ: if(!IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue;\r
-                       case _OP_JZ: if(IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue;\r
-                       case _OP_LOADFREEVAR: TARGET = _closure(ci->_closure)->_outervalues[arg1]; continue;\r
-                       case _OP_VARGC: TARGET = SQInteger(ci->_vargs.size); continue;\r
-                       case _OP_GETVARGV: \r
-                               if(!GETVARGV_OP(TARGET,STK(arg1),ci)) { SQ_THROW(); } \r
-                               continue;\r
-                       case _OP_NEWTABLE: TARGET = SQTable::Create(_ss(this), arg1); continue;\r
-                       case _OP_NEWARRAY: TARGET = SQArray::Create(_ss(this), 0); _array(TARGET)->Reserve(arg1); continue;\r
-                       case _OP_APPENDARRAY: _array(STK(arg0))->Append(COND_LITERAL);  continue;\r
-                       case _OP_GETPARENT: _GUARD(GETPARENT_OP(STK(arg1),TARGET)); continue;\r
-                       case _OP_COMPARITH: _GUARD(DerefInc(arg3, TARGET, STK((((SQUnsignedInteger)arg1&0xFFFF0000)>>16)), STK(arg2), STK(arg1&0x0000FFFF), false)); continue;\r
-                       case _OP_COMPARITHL: _GUARD(LOCAL_INC(arg3, TARGET, STK(arg1), STK(arg2))); continue;\r
-                       case _OP_INC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, false));} continue;\r
-                       case _OP_INCL: {SQObjectPtr o(sarg3); _GUARD(LOCAL_INC('+',TARGET, STK(arg1), o));} continue;\r
-                       case _OP_PINC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, true));} continue;\r
-                       case _OP_PINCL: {SQObjectPtr o(sarg3); _GUARD(PLOCAL_INC('+',TARGET, STK(arg1), o));} continue;\r
-                       case _OP_CMP:   _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg1),TARGET))  continue;\r
-                       case _OP_EXISTS: TARGET = Get(STK(arg1), STK(arg2), temp_reg, true,false)?_true_:_false_;continue;\r
-                       case _OP_INSTANCEOF: \r
-                               if(type(STK(arg1)) != OT_CLASS || type(STK(arg2)) != OT_INSTANCE)\r
-                               {Raise_Error(_SC("cannot apply instanceof between a %s and a %s"),GetTypeName(STK(arg1)),GetTypeName(STK(arg2))); SQ_THROW();}\r
-                               TARGET = _instance(STK(arg2))->InstanceOf(_class(STK(arg1)))?_true_:_false_;\r
-                               continue;\r
-                       case _OP_AND: \r
-                               if(IsFalse(STK(arg2))) {\r
-                                       TARGET = STK(arg2);\r
-                                       ci->_ip += (sarg1);\r
-                               }\r
-                               continue;\r
-                       case _OP_OR:\r
-                               if(!IsFalse(STK(arg2))) {\r
-                                       TARGET = STK(arg2);\r
-                                       ci->_ip += (sarg1);\r
-                               }\r
-                               continue;\r
-                       case _OP_NEG: _GUARD(NEG_OP(TARGET,STK(arg1))); continue;\r
-                       case _OP_NOT: TARGET = (IsFalse(STK(arg1))?_true_:_false_); continue;\r
-                       case _OP_BWNOT:\r
-                               if(type(STK(arg1)) == OT_INTEGER) {\r
-                                       SQInteger t = _integer(STK(arg1));\r
-                                       TARGET = SQInteger(~t);\r
-                                       continue;\r
-                               }\r
-                               Raise_Error(_SC("attempt to perform a bitwise op on a %s"), GetTypeName(STK(arg1)));\r
-                               SQ_THROW();\r
-                       case _OP_CLOSURE: {\r
-                               SQClosure *c = ci->_closure._unVal.pClosure;\r
-                               SQFunctionProto *fp = c->_function._unVal.pFunctionProto;\r
-                               if(!CLOSURE_OP(TARGET,fp->_functions[arg1]._unVal.pFunctionProto)) { SQ_THROW(); }\r
-                               continue;\r
-                       }\r
-                       case _OP_YIELD:{\r
-                               if(type(ci->_generator) == OT_GENERATOR) {\r
-                                       if(sarg1 != MAX_FUNC_STACKSIZE) temp_reg = STK(arg1);\r
-                                       _GUARD(_generator(ci->_generator)->Yield(this));\r
-                                       traps -= ci->_etraps;\r
-                                       if(sarg1 != MAX_FUNC_STACKSIZE) STK(arg1) = temp_reg;\r
-                               }\r
-                               else { Raise_Error(_SC("trying to yield a '%s',only genenerator can be yielded"), GetTypeName(ci->_generator)); SQ_THROW();}\r
-                               if(Return(arg0, arg1, temp_reg)){\r
-                                       assert(traps == 0);\r
-                                       outres = temp_reg;\r
-                                       return true;\r
-                               }\r
-                                       \r
-                               }\r
-                               continue;\r
-                       case _OP_RESUME:\r
-                               if(type(STK(arg1)) != OT_GENERATOR){ Raise_Error(_SC("trying to resume a '%s',only genenerator can be resumed"), GetTypeName(STK(arg1))); SQ_THROW();}\r
-                               _GUARD(_generator(STK(arg1))->Resume(this, arg0));\r
-                               traps += ci->_etraps;\r
-                continue;\r
-                       case _OP_FOREACH:{ bool finished;\r
-                               _GUARD(FOREACH_OP(STK(arg0),STK(arg2),STK(arg2+1),STK(arg2+2),arg2,finished));\r
-                               if(finished) ci->_ip += sarg1; }\r
-                               continue;\r
-                       case _OP_DELEGATE: _GUARD(DELEGATE_OP(TARGET,STK(arg1),STK(arg2))); continue;\r
-                       case _OP_CLONE:\r
-                               if(!Clone(STK(arg1), TARGET))\r
-                               { Raise_Error(_SC("cloning a %s"), GetTypeName(STK(arg1))); SQ_THROW();}\r
-                               continue;\r
-                       case _OP_TYPEOF: TypeOf(STK(arg1), TARGET); continue;\r
-                       case _OP_PUSHTRAP:\r
-                               _etraps.push_back(SQExceptionTrap(_top,_stackbase, &ci->_iv->_vals[(ci->_ip-ci->_iv->_vals)+arg1], arg0)); traps++;\r
-                               ci->_etraps++;\r
-                               continue;\r
-                       case _OP_POPTRAP:\r
-                               for(SQInteger i = 0; i < arg0; i++) {\r
-                                       _etraps.pop_back(); traps--;\r
-                                       ci->_etraps--;\r
-                               }\r
-                               continue;\r
-                       case _OP_THROW: Raise_Error(TARGET); SQ_THROW(); continue;\r
-                       case _OP_CLASS: _GUARD(CLASS_OP(TARGET,arg1,arg2)); continue;\r
-                       case _OP_NEWSLOTA:\r
-                               bool bstatic = (arg0&NEW_SLOT_STATIC_FLAG)?true:false;\r
-                               if(type(STK(arg1)) == OT_CLASS) {\r
-                                       if(type(_class(STK(arg1))->_metamethods[MT_NEWMEMBER]) != OT_NULL ) {\r
-                                               Push(STK(arg1)); Push(STK(arg2)); Push(STK(arg3));\r
-                                               Push((arg0&NEW_SLOT_ATTRIBUTES_FLAG) ? STK(arg2-1) : _null_);\r
-                                               int nparams = 4;\r
-                                               if(Call(_class(STK(arg1))->_metamethods[MT_NEWMEMBER], nparams, _top - nparams, temp_reg,SQFalse)) {\r
-                                                       Pop(nparams);\r
-                                                       continue;\r
-                                               }\r
-                                       }\r
-                               }\r
-                               _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),bstatic));\r
-                               if((arg0&NEW_SLOT_ATTRIBUTES_FLAG)) {\r
-                                       _class(STK(arg1))->SetAttributes(STK(arg2),STK(arg2-1));\r
-                               }\r
-                               continue;\r
-                       }\r
-                       \r
-               }\r
-       }\r
-exception_trap:\r
-       {\r
-               SQObjectPtr currerror = _lasterror;\r
-//             dumpstack(_stackbase);\r
-               SQInteger n = 0;\r
-               SQInteger last_top = _top;\r
-               if(ci) {\r
-                       if(_ss(this)->_notifyallexceptions) CallErrorHandler(currerror);\r
-\r
-                       if(traps) {\r
-                               do {\r
-                                       if(ci->_etraps > 0) {\r
-                                               SQExceptionTrap &et = _etraps.top();\r
-                                               ci->_ip = et._ip;\r
-                                               _top = et._stacksize;\r
-                                               _stackbase = et._stackbase;\r
-                                               _stack[_stackbase+et._extarget] = currerror;\r
-                                               _etraps.pop_back(); traps--; ci->_etraps--;\r
-                                               while(last_top >= _top) _stack[last_top--].Null();\r
-                                               goto exception_restore;\r
-                                       }\r
-                                       //if is a native closure\r
-                                       if(type(ci->_closure) != OT_CLOSURE && n)\r
-                                               break;\r
-                                       if(type(ci->_generator) == OT_GENERATOR) _generator(ci->_generator)->Kill();\r
-                                       PopVarArgs(ci->_vargs);\r
-                                       POP_CALLINFO(this);\r
-                                       n++;\r
-                               } while(_callsstack.size());\r
-                       }\r
-                       else {\r
-                               //call the hook\r
-                               if(raiseerror && !_ss(this)->_notifyallexceptions)\r
-                                       CallErrorHandler(currerror);\r
-                       }\r
-                       //remove call stack until a C function is found or the cstack is empty\r
-                       if(ci) do {\r
-                               SQBool exitafterthisone = ci->_root;\r
-                               if(type(ci->_generator) == OT_GENERATOR) _generator(ci->_generator)->Kill();\r
-                               _stackbase -= ci->_prevstkbase;\r
-                               _top = _stackbase + ci->_prevtop;\r
-                               PopVarArgs(ci->_vargs);\r
-                               POP_CALLINFO(this);\r
-                               if( (ci && type(ci->_closure) != OT_CLOSURE) || exitafterthisone) break;\r
-                       } while(_callsstack.size());\r
-\r
-                       while(last_top >= _top) _stack[last_top--].Null();\r
-               }\r
-               _lasterror = currerror;\r
-               return false;\r
-       }\r
-       assert(0);\r
-}\r
-\r
-bool SQVM::CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor)\r
-{\r
-       inst = theclass->CreateInstance();\r
-       if(!theclass->Get(_ss(this)->_constructoridx,constructor)) {\r
-               //if(!Call(constr,nargs,stackbase,constr,false))\r
-               //      return false;\r
-               constructor = _null_;\r
-       }\r
-       return true;\r
-}\r
-\r
-void SQVM::CallErrorHandler(SQObjectPtr &error)\r
-{\r
-       if(type(_errorhandler) != OT_NULL) {\r
-               SQObjectPtr out;\r
-               Push(_roottable); Push(error);\r
-               Call(_errorhandler, 2, _top-2, out,SQFalse);\r
-               Pop(2);\r
-       }\r
-}\r
-\r
-void SQVM::CallDebugHook(SQInteger type,SQInteger forcedline)\r
-{\r
-       SQObjectPtr temp_reg;\r
-       SQInteger nparams=5;\r
-       SQFunctionProto *func=_funcproto(_closure(ci->_closure)->_function);\r
-       Push(_roottable); Push(type); Push(func->_sourcename); Push(forcedline?forcedline:func->GetLine(ci->_ip)); Push(func->_name);\r
-       Call(_debughook,nparams,_top-nparams,temp_reg,SQFalse);\r
-       Pop(nparams);\r
-}\r
-\r
-bool SQVM::CallNative(SQNativeClosure *nclosure,SQInteger nargs,SQInteger stackbase,bool tailcall,SQObjectPtr &retval,bool &suspend)\r
-{\r
-       if (_nnativecalls + 1 > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; }\r
-       SQInteger nparamscheck = nclosure->_nparamscheck;\r
-       if(((nparamscheck > 0) && (nparamscheck != nargs))\r
-               || ((nparamscheck < 0) && (nargs < (-nparamscheck)))) {\r
-               Raise_Error(_SC("wrong number of parameters"));\r
-               return false;\r
-               }\r
-\r
-       SQInteger tcs;\r
-       if((tcs = nclosure->_typecheck.size())) {\r
-               for(SQInteger i = 0; i < nargs && i < tcs; i++)\r
-                       if((nclosure->_typecheck[i] != -1) && !(type(_stack[stackbase+i]) & nclosure->_typecheck[i])) {\r
-                Raise_ParamTypeError(i,nclosure->_typecheck[i],type(_stack[stackbase+i]));\r
-                               return false;\r
-                       }\r
-       }\r
-       _nnativecalls++;\r
-       if ((_top + MIN_STACK_OVERHEAD) > (SQInteger)_stack.size()) {\r
-               _stack.resize(_stack.size() + (MIN_STACK_OVERHEAD<<1));\r
-       }\r
-       SQInteger oldtop = _top;\r
-       SQInteger oldstackbase = _stackbase;\r
-       _top = stackbase + nargs;\r
-       PUSH_CALLINFO(this, CallInfo());\r
-       ci->_etraps = 0;\r
-       ci->_closure._unVal.pNativeClosure = nclosure;\r
-       ci->_closure._type = OT_NATIVECLOSURE;\r
-       ci->_prevstkbase = stackbase - _stackbase;\r
-       ci->_ncalls = 1;\r
-       _stackbase = stackbase;\r
-       //push free variables\r
-       SQInteger outers = nclosure->_outervalues.size();\r
-       for (SQInteger i = 0; i < outers; i++) {\r
-               Push(nclosure->_outervalues[i]);\r
-       }\r
-\r
-       if(type(nclosure->_env) == OT_WEAKREF) {\r
-               _stack[stackbase] = _weakref(nclosure->_env)->_obj;\r
-       }\r
-\r
-       ci->_prevtop = (oldtop - oldstackbase);\r
-       SQInteger ret = (nclosure->_function)(this);\r
-       _nnativecalls--;\r
-       suspend = false;\r
-       if( ret == SQ_SUSPEND_FLAG) suspend = true;\r
-       else if (ret < 0) { \r
-               _stackbase = oldstackbase;\r
-               _top = oldtop;\r
-               POP_CALLINFO(this);\r
-               Raise_Error(_lasterror);\r
-               return false;\r
-       }\r
-       \r
-       if (ret != 0){ retval = TOP(); }\r
-       else { retval = _null_; }\r
-       _stackbase = oldstackbase;\r
-       _top = oldtop;\r
-       POP_CALLINFO(this);\r
-       return true;\r
-}\r
-\r
-bool SQVM::Get(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw, bool fetchroot)\r
-{\r
-       switch(type(self)){\r
-       case OT_TABLE:\r
-               if(_table(self)->Get(key,dest))return true;\r
-               break;\r
-       case OT_ARRAY:\r
-               if(sq_isnumeric(key)){\r
-                       return _array(self)->Get(tointeger(key),dest);\r
-               }\r
-               break;\r
-       case OT_INSTANCE:\r
-               if(_instance(self)->Get(key,dest)) return true;\r
-               break;\r
-       default:break; //shut up compiler\r
-       }\r
-       if(FallBackGet(self,key,dest,raw)) return true;\r
-\r
-       if(fetchroot) {\r
-               if(_rawval(STK(0)) == _rawval(self) &&\r
-                       type(STK(0)) == type(self)) {\r
-                               return _table(_roottable)->Get(key,dest);\r
-               }\r
-       }\r
-       return false;\r
-}\r
-\r
-bool SQVM::FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw)\r
-{\r
-       switch(type(self)){\r
-       case OT_CLASS: \r
-               return _class(self)->Get(key,dest);\r
-               break;\r
-       case OT_TABLE:\r
-       case OT_USERDATA:\r
-        //delegation\r
-               if(_delegable(self)->_delegate) {\r
-                       if(Get(SQObjectPtr(_delegable(self)->_delegate),key,dest,raw,false))\r
-                               return true;    \r
-                       if(raw)return false;\r
-                       Push(self);Push(key);\r
-                       if(CallMetaMethod(_delegable(self),MT_GET,2,dest))\r
-                               return true;\r
-               }\r
-               if(type(self) == OT_TABLE) {\r
-                       if(raw) return false;\r
-                       return _table_ddel->Get(key,dest);\r
-               }\r
-               return false;\r
-               break;\r
-       case OT_ARRAY:\r
-               if(raw)return false;\r
-               return _array_ddel->Get(key,dest);\r
-       case OT_STRING:\r
-               if(sq_isnumeric(key)){\r
-                       SQInteger n=tointeger(key);\r
-                       if(abs((int)n)<_string(self)->_len){\r
-                               if(n<0)n=_string(self)->_len-n;\r
-                               dest=SQInteger(_stringval(self)[n]);\r
-                               return true;\r
-                       }\r
-                       return false;\r
-               }\r
-               else {\r
-                       if(raw)return false;\r
-                       return _string_ddel->Get(key,dest);\r
-               }\r
-               break;\r
-       case OT_INSTANCE:\r
-               if(raw)return false;\r
-               Push(self);Push(key);\r
-               if(!CallMetaMethod(_delegable(self),MT_GET,2,dest)) {\r
-                       return _instance_ddel->Get(key,dest);\r
-               }\r
-               return true;\r
-       case OT_INTEGER:case OT_FLOAT:case OT_BOOL: \r
-               if(raw)return false;\r
-               return _number_ddel->Get(key,dest);\r
-       case OT_GENERATOR: \r
-               if(raw)return false;\r
-               return _generator_ddel->Get(key,dest);\r
-       case OT_CLOSURE: case OT_NATIVECLOSURE: \r
-               if(raw)return false;\r
-               return _closure_ddel->Get(key,dest);\r
-       case OT_THREAD:\r
-               if(raw)return false;\r
-               return  _thread_ddel->Get(key,dest);\r
-       case OT_WEAKREF:\r
-               if(raw)return false;\r
-               return  _weakref_ddel->Get(key,dest);\r
-       default:return false;\r
-       }\r
-       return false;\r
-}\r
-\r
-bool SQVM::Set(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool fetchroot)\r
-{\r
-       switch(type(self)){\r
-       case OT_TABLE:\r
-               if(_table(self)->Set(key,val))\r
-                       return true;\r
-               if(_table(self)->_delegate) {\r
-                       if(Set(_table(self)->_delegate,key,val,false)) {\r
-                               return true;\r
-                       }\r
-               }\r
-               //keeps going\r
-       case OT_USERDATA:\r
-               if(_delegable(self)->_delegate) {\r
-                       SQObjectPtr t;\r
-                       Push(self);Push(key);Push(val);\r
-                       if(CallMetaMethod(_delegable(self),MT_SET,3,t)) return true;\r
-               }\r
-               break;\r
-       case OT_INSTANCE:{\r
-               if(_instance(self)->Set(key,val))\r
-                       return true;\r
-               SQObjectPtr t;\r
-               Push(self);Push(key);Push(val);\r
-               if(CallMetaMethod(_delegable(self),MT_SET,3,t)) return true;\r
-               }\r
-               break;\r
-       case OT_ARRAY:\r
-               if(!sq_isnumeric(key)) {Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); return false; }\r
-               return _array(self)->Set(tointeger(key),val);\r
-       default:\r
-               Raise_Error(_SC("trying to set '%s'"),GetTypeName(self));\r
-               return false;\r
-       }\r
-       if(fetchroot) {\r
-               if(_rawval(STK(0)) == _rawval(self) &&\r
-                       type(STK(0)) == type(self)) {\r
-                               return _table(_roottable)->Set(key,val);\r
-                       }\r
-       }\r
-       return false;\r
-}\r
-\r
-bool SQVM::Clone(const SQObjectPtr &self,SQObjectPtr &target)\r
-{\r
-       SQObjectPtr temp_reg;\r
-       SQObjectPtr newobj;\r
-       switch(type(self)){\r
-       case OT_TABLE:\r
-               newobj = _table(self)->Clone();\r
-               goto cloned_mt;\r
-       case OT_INSTANCE:\r
-               newobj = _instance(self)->Clone(_ss(this));\r
-cloned_mt:\r
-               if(_delegable(newobj)->_delegate){\r
-                       Push(newobj);\r
-                       Push(self);\r
-                       CallMetaMethod(_delegable(newobj),MT_CLONED,2,temp_reg);\r
-               }\r
-               target = newobj;\r
-               return true;\r
-       case OT_ARRAY: \r
-               target = _array(self)->Clone();\r
-               return true;\r
-       default: return false;\r
-       }\r
-}\r
-\r
-bool SQVM::NewSlot(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic)\r
-{\r
-       if(type(key) == OT_NULL) { Raise_Error(_SC("null cannot be used as index")); return false; }\r
-       switch(type(self)) {\r
-       case OT_TABLE: {\r
-               bool rawcall = true;\r
-               if(_table(self)->_delegate) {\r
-                       SQObjectPtr res;\r
-                       if(!_table(self)->Get(key,res)) {\r
-                               Push(self);Push(key);Push(val);\r
-                               rawcall = !CallMetaMethod(_table(self),MT_NEWSLOT,3,res);\r
-                       }\r
-               }\r
-               if(rawcall) _table(self)->NewSlot(key,val); //cannot fail\r
-               \r
-               break;}\r
-       case OT_CLASS: \r
-               if(!_class(self)->NewSlot(_ss(this),key,val,bstatic)) {\r
-                       if(_class(self)->_locked) {\r
-                               Raise_Error(_SC("trying to modify a class that has already been instantiated"));\r
-                               return false;\r
-                       }\r
-                       else {\r
-                               SQObjectPtr oval = PrintObjVal(key);\r
-                               Raise_Error(_SC("the property '%s' already exists"),_stringval(oval));\r
-                               return false;\r
-                       }\r
-               }\r
-               break;\r
-       default:\r
-               Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key));\r
-               return false;\r
-               break;\r
-       }\r
-       return true;\r
-}\r
-\r
-bool SQVM::DeleteSlot(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &res)\r
-{\r
-       switch(type(self)) {\r
-       case OT_TABLE:\r
-       case OT_INSTANCE:\r
-       case OT_USERDATA: {\r
-               SQObjectPtr t;\r
-               bool handled = false;\r
-               if(_delegable(self)->_delegate) {\r
-                       Push(self);Push(key);\r
-                       handled = CallMetaMethod(_delegable(self),MT_DELSLOT,2,t);\r
-               }\r
-\r
-               if(!handled) {\r
-                       if(type(self) == OT_TABLE) {\r
-                               if(_table(self)->Get(key,t)) {\r
-                                       _table(self)->Remove(key);\r
-                               }\r
-                               else {\r
-                                       Raise_IdxError((SQObject &)key);\r
-                                       return false;\r
-                               }\r
-                       }\r
-                       else {\r
-                               Raise_Error(_SC("cannot delete a slot from %s"),GetTypeName(self));\r
-                               return false;\r
-                       }\r
-               }\r
-               res = t;\r
-                               }\r
-               break;\r
-       default:\r
-               Raise_Error(_SC("attempt to delete a slot from a %s"),GetTypeName(self));\r
-               return false;\r
-       }\r
-       return true;\r
-}\r
-\r
-bool SQVM::Call(SQObjectPtr &closure,SQInteger nparams,SQInteger stackbase,SQObjectPtr &outres,SQBool raiseerror)\r
-{\r
-#ifdef _DEBUG\r
-SQInteger prevstackbase = _stackbase;\r
-#endif\r
-       switch(type(closure)) {\r
-       case OT_CLOSURE:\r
-               return Execute(closure, _top - nparams, nparams, stackbase,outres,raiseerror);\r
-               break;\r
-       case OT_NATIVECLOSURE:{\r
-               bool suspend;\r
-               return CallNative(_nativeclosure(closure), nparams, stackbase, false, outres,suspend);\r
-               \r
-                                                 }\r
-               break;\r
-       case OT_CLASS: {\r
-               SQObjectPtr constr;\r
-               SQObjectPtr temp;\r
-               CreateClassInstance(_class(closure),outres,constr);\r
-               if(type(constr) != OT_NULL) {\r
-                       _stack[stackbase] = outres;\r
-                       return Call(constr,nparams,stackbase,temp,raiseerror);\r
-               }\r
-               return true;\r
-                                  }\r
-               break;\r
-       default:\r
-               return false;\r
-       }\r
-#ifdef _DEBUG\r
-       if(!_suspended) {\r
-               assert(_stackbase == prevstackbase);\r
-       }\r
-#endif\r
-       return true;\r
-}\r
-\r
-bool SQVM::CallMetaMethod(SQDelegable *del,SQMetaMethod mm,SQInteger nparams,SQObjectPtr &outres)\r
-{\r
-       SQObjectPtr closure;\r
-       if(del->GetMetaMethod(this, mm, closure)) {\r
-               if(Call(closure, nparams, _top - nparams, outres, SQFalse)) {\r
-                       Pop(nparams);\r
-                       return true;\r
-               }\r
-       }\r
-       Pop(nparams);\r
-       return false;\r
-}\r
-\r
-void SQVM::Remove(SQInteger n) {\r
-       n = (n >= 0)?n + _stackbase - 1:_top + n;\r
-       for(SQInteger i = n; i < _top; i++){\r
-               _stack[i] = _stack[i+1];\r
-       }\r
-       _stack[_top] = _null_;\r
-       _top--;\r
-}\r
-\r
-void SQVM::Pop() {\r
-       _stack[--_top] = _null_;\r
-}\r
-\r
-void SQVM::Pop(SQInteger n) {\r
-       for(SQInteger i = 0; i < n; i++){\r
-               _stack[--_top] = _null_;\r
-       }\r
-}\r
-\r
-void SQVM::Push(const SQObjectPtr &o) { _stack[_top++] = o; }\r
-SQObjectPtr &SQVM::Top() { return _stack[_top-1]; }\r
-SQObjectPtr &SQVM::PopGet() { return _stack[--_top]; }\r
-SQObjectPtr &SQVM::GetUp(SQInteger n) { return _stack[_top+n]; }\r
-SQObjectPtr &SQVM::GetAt(SQInteger n) { return _stack[n]; }\r
-\r
-#ifdef _DEBUG_DUMP\r
-void SQVM::dumpstack(SQInteger stackbase,bool dumpall)\r
-{\r
-       SQInteger size=dumpall?_stack.size():_top;\r
-       SQInteger n=0;\r
-       scprintf(_SC("\n>>>>stack dump<<<<\n"));\r
-       CallInfo &ci=_callsstack.back();\r
-       scprintf(_SC("IP: %p\n"),ci._ip);\r
-       scprintf(_SC("prev stack base: %d\n"),ci._prevstkbase);\r
-       scprintf(_SC("prev top: %d\n"),ci._prevtop);\r
-       for(SQInteger i=0;i<size;i++){\r
-               SQObjectPtr &obj=_stack[i];     \r
-               if(stackbase==i)scprintf(_SC(">"));else scprintf(_SC(" "));\r
-               scprintf(_SC("[%d]:"),n);\r
-               switch(type(obj)){\r
-               case OT_FLOAT:                  scprintf(_SC("FLOAT %.3f"),_float(obj));break;\r
-               case OT_INTEGER:                scprintf(_SC("INTEGER %d"),_integer(obj));break;\r
-               case OT_BOOL:                   scprintf(_SC("BOOL %s"),_integer(obj)?"true":"false");break;\r
-               case OT_STRING:                 scprintf(_SC("STRING %s"),_stringval(obj));break;\r
-               case OT_NULL:                   scprintf(_SC("NULL"));  break;\r
-               case OT_TABLE:                  scprintf(_SC("TABLE %p[%p]"),_table(obj),_table(obj)->_delegate);break;\r
-               case OT_ARRAY:                  scprintf(_SC("ARRAY %p"),_array(obj));break;\r
-               case OT_CLOSURE:                scprintf(_SC("CLOSURE [%p]"),_closure(obj));break;\r
-               case OT_NATIVECLOSURE:  scprintf(_SC("NATIVECLOSURE"));break;\r
-               case OT_USERDATA:               scprintf(_SC("USERDATA %p[%p]"),_userdataval(obj),_userdata(obj)->_delegate);break;\r
-               case OT_GENERATOR:              scprintf(_SC("GENERATOR"));break;\r
-               case OT_THREAD:                 scprintf(_SC("THREAD [%p]"),_thread(obj));break;\r
-               case OT_USERPOINTER:    scprintf(_SC("USERPOINTER %p"),_userpointer(obj));break;\r
-               case OT_CLASS:                  scprintf(_SC("CLASS %p"),_class(obj));break;\r
-               case OT_INSTANCE:               scprintf(_SC("INSTANCE %p"),_instance(obj));break;\r
-               case OT_WEAKREF:                scprintf(_SC("WEAKERF %p"),_weakref(obj));break;\r
-               default:\r
-                       assert(0);\r
-                       break;\r
-               };\r
-               scprintf(_SC("\n"));\r
-               ++n;\r
-       }\r
-}\r
-\r
-\r
-\r
-#endif\r
+/*
+       see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include <math.h>
+#include <stdlib.h>
+#include "sqopcodes.h"
+#include "sqfuncproto.h"
+#include "sqvm.h"
+#include "sqclosure.h"
+#include "sqstring.h"
+#include "sqtable.h"
+#include "squserdata.h"
+#include "sqarray.h"
+#include "sqclass.h"
+
+#define TOP() (_stack[_top-1])
+
+bool SQVM::BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2)
+{
+       SQInteger res;
+       SQInteger i1 = _integer(o1), i2 = _integer(o2);
+       if((type(o1)==OT_INTEGER) && (type(o2)==OT_INTEGER))
+       {
+               switch(op) {
+                       case BW_AND:    res = i1 & i2; break;
+                       case BW_OR:             res = i1 | i2; break;
+                       case BW_XOR:    res = i1 ^ i2; break;
+                       case BW_SHIFTL: res = i1 << i2; break;
+                       case BW_SHIFTR: res = i1 >> i2; break;
+                       case BW_USHIFTR:res = (SQInteger)(*((SQUnsignedInteger*)&i1) >> i2); break;
+                       default: { Raise_Error(_SC("internal vm error bitwise op failed")); return false; }
+               }
+       }
+       else { Raise_Error(_SC("bitwise op between '%s' and '%s'"),GetTypeName(o1),GetTypeName(o2)); return false;}
+       trg = res;
+       return true;
+}
+
+bool SQVM::ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2)
+{
+       if(sq_isnumeric(o1) && sq_isnumeric(o2)) {
+                       if((type(o1)==OT_INTEGER) && (type(o2)==OT_INTEGER)) {
+                               switch(op) {
+                               case '+': trg = _integer(o1) + _integer(o2); break;
+                               case '-': trg = _integer(o1) - _integer(o2); break;
+                               case '/': if(_integer(o2) == 0) { Raise_Error(_SC("division by zero")); return false; }
+                                       trg = _integer(o1) / _integer(o2);
+                                       break;
+                               case '*': trg = _integer(o1) * _integer(o2); break;
+                               case '%': trg = _integer(o1) % _integer(o2); break;
+                               }
+                       }else{
+                               switch(op) {
+                               case '+': trg = tofloat(o1) + tofloat(o2); break;
+                               case '-': trg = tofloat(o1) - tofloat(o2); break;
+                               case '/': trg = tofloat(o1) / tofloat(o2); break;
+                               case '*': trg = tofloat(o1) * tofloat(o2); break;
+                               case '%': trg = SQFloat(fmod((double)tofloat(o1),(double)tofloat(o2))); break;
+                               }
+                       }
+               } else {
+                       if(op == '+' && (type(o1) == OT_STRING || type(o2) == OT_STRING)){
+                                       if(!StringCat(o1, o2, trg)) return false;
+                       }
+                       else if(!ArithMetaMethod(op,o1,o2,trg)) {
+                               Raise_Error(_SC("arith op %c on between '%s' and '%s'"),op,GetTypeName(o1),GetTypeName(o2)); return false;
+                       }
+               }
+               return true;
+}
+
+SQVM::SQVM(SQSharedState *ss)
+{
+       _sharedstate=ss;
+       _suspended = SQFalse;
+       _suspended_target=-1;
+       _suspended_root = SQFalse;
+       _suspended_traps=-1;
+       _foreignptr=NULL;
+       _nnativecalls=0;
+       _lasterror = _null_;
+       _errorhandler = _null_;
+       _debughook = _null_;
+       ci = NULL;
+       INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);
+}
+
+void SQVM::Finalize()
+{
+       _roottable = _null_;
+       _lasterror = _null_;
+       _errorhandler = _null_;
+       _debughook = _null_;
+       temp_reg = _null_;
+       SQInteger size=_stack.size();
+       for(SQInteger i=0;i<size;i++)
+               _stack[i]=_null_;
+}
+
+SQVM::~SQVM()
+{
+       Finalize();
+       REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
+}
+
+bool SQVM::ArithMetaMethod(SQInteger op,const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &dest)
+{
+       SQMetaMethod mm;
+       switch(op){
+               case _SC('+'): mm=MT_ADD; break;
+               case _SC('-'): mm=MT_SUB; break;
+               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; //shutup compiler
+       }
+       if(is_delegable(o1) && _delegable(o1)->_delegate) {
+               Push(o1);Push(o2);
+               return CallMetaMethod(_delegable(o1),mm,2,dest);
+       }
+       return false;
+}
+
+bool SQVM::NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o)
+{
+
+       switch(type(o)) {
+       case OT_INTEGER:
+               trg = -_integer(o);
+               return true;
+       case OT_FLOAT:
+               trg = -_float(o);
+               return true;
+       case OT_TABLE:
+       case OT_USERDATA:
+       case OT_INSTANCE:
+               if(_delegable(o)->_delegate) {
+                       Push(o);
+                       if(CallMetaMethod(_delegable(o), MT_UNM, 1, temp_reg)) {
+                               trg = temp_reg;
+                               return true;
+                       }
+               }
+       default:break; //shutup compiler
+       }
+       Raise_Error(_SC("attempt to negate a %s"), GetTypeName(o));
+       return false;
+}
+
+#define _RET_SUCCEED(exp) { result = (exp); return true; }
+bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,SQInteger &result)
+{
+       if(type(o1)==type(o2)){
+               if(_userpointer(o1)==_userpointer(o2))_RET_SUCCEED(0);
+               SQObjectPtr res;
+               switch(type(o1)){
+               case OT_STRING:
+                       _RET_SUCCEED(scstrcmp(_stringval(o1),_stringval(o2)));
+               case OT_INTEGER:
+                       _RET_SUCCEED(_integer(o1)-_integer(o2));
+               case OT_FLOAT:
+                       _RET_SUCCEED((_float(o1)<_float(o2))?-1:1);
+               case OT_TABLE:
+               case OT_USERDATA:
+               case OT_INSTANCE:
+                       Push(o1);Push(o2);
+                       if(_delegable(o1)->_delegate)CallMetaMethod(_delegable(o1),MT_CMP,2,res);
+                       break;
+               default: break; //shutup compiler
+               }
+               if(type(res)!=OT_INTEGER) { Raise_CompareError(o1,o2); return false; }
+                       _RET_SUCCEED(_integer(res));
+
+       }
+       else{
+               if(sq_isnumeric(o1) && sq_isnumeric(o2)){
+                       if((type(o1)==OT_INTEGER) && (type(o2)==OT_FLOAT)) {
+                               if( _integer(o1)==_float(o2) ) { _RET_SUCCEED(0); }
+                               else if( _integer(o1)<_float(o2) ) { _RET_SUCCEED(-1); }
+                               _RET_SUCCEED(1);
+                       }
+                       else{
+                               if( _float(o1)==_integer(o2) ) { _RET_SUCCEED(0); }
+                               else if( _float(o1)<_integer(o2) ) { _RET_SUCCEED(-1); }
+                               _RET_SUCCEED(1);
+                       }
+               }
+               else if(type(o1)==OT_NULL) {_RET_SUCCEED(-1);}
+               else if(type(o2)==OT_NULL) {_RET_SUCCEED(1);}
+               else { Raise_CompareError(o1,o2); return false; }
+
+       }
+       assert(0);
+       _RET_SUCCEED(0); //cannot happen
+}
+
+bool SQVM::CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res)
+{
+       SQInteger r;
+       if(ObjCmp(o1,o2,r)) {
+               switch(op) {
+                       case CMP_G: res = (r > 0)?_true_:_false_; return true;
+                       case CMP_GE: res = (r >= 0)?_true_:_false_; return true;
+                       case CMP_L: res = (r < 0)?_true_:_false_; return true;
+                       case CMP_LE: res = (r <= 0)?_true_:_false_; return true;
+
+               }
+               assert(0);
+       }
+       return false;
+}
+
+void SQVM::ToString(const SQObjectPtr &o,SQObjectPtr &res)
+{
+       switch(type(o)) {
+       case OT_STRING:
+               res = o;
+               return;
+       case OT_FLOAT:
+               scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_SC("%g"),_float(o));
+               break;
+       case OT_INTEGER:
+               scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_SC("%d"),_integer(o));
+               break;
+       case OT_BOOL:
+               scsprintf(_sp(rsl(6)),_integer(o)?_SC("true"):_SC("false"));
+               break;
+       case OT_TABLE:
+       case OT_USERDATA:
+       case OT_INSTANCE:
+               if(_delegable(o)->_delegate) {
+                       Push(o);
+                       if(CallMetaMethod(_delegable(o),MT_TOSTRING,1,res)) {
+                               if(type(res) == OT_STRING)
+                                       return;
+                               //else keeps going to the default
+                       }
+               }
+       default:
+               scsprintf(_sp(rsl(sizeof(void*)+20)),_SC("(%s : 0x%p)"),GetTypeName(o),(void*)_rawval(o));
+       }
+       res = SQString::Create(_ss(this),_spval);
+}
+
+
+bool SQVM::StringCat(const SQObjectPtr &str,const SQObjectPtr &obj,SQObjectPtr &dest)
+{
+       SQObjectPtr a, b;
+       ToString(str, a);
+       ToString(obj, b);
+       SQInteger l = _string(a)->_len , ol = _string(b)->_len;
+       SQChar *s = _sp(rsl(l + ol + 1));
+       memcpy(s, _stringval(a), rsl(l));
+       memcpy(s + l, _stringval(b), rsl(ol));
+       dest = SQString::Create(_ss(this), _spval, l + ol);
+       return true;
+}
+
+const SQChar *IdType2Name(SQObjectType type)
+{
+       switch(_RAW_TYPE(type))
+       {
+       case _RT_NULL:return _SC("null");
+       case _RT_INTEGER:return _SC("integer");
+       case _RT_FLOAT:return _SC("float");
+       case _RT_BOOL:return _SC("bool");
+       case _RT_STRING:return _SC("string");
+       case _RT_TABLE:return _SC("table");
+       case _RT_ARRAY:return _SC("array");
+       case _RT_GENERATOR:return _SC("generator");
+       case _RT_CLOSURE:
+       case _RT_NATIVECLOSURE:
+               return _SC("function");
+       case _RT_USERDATA:
+       case _RT_USERPOINTER:
+               return _SC("userdata");
+       case _RT_THREAD: return _SC("thread");
+       case _RT_FUNCPROTO: return _SC("function");
+       case _RT_CLASS: return _SC("class");
+       case _RT_INSTANCE: return _SC("instance");
+       case _RT_WEAKREF: return _SC("weakref");
+       default:
+               return NULL;
+       }
+}
+
+const SQChar *GetTypeName(const SQObjectPtr &obj1)
+{
+       return IdType2Name(type(obj1));
+}
+
+void SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest)
+{
+       if(is_delegable(obj1) && _delegable(obj1)->_delegate) {
+               Push(obj1);
+               if(CallMetaMethod(_delegable(obj1),MT_TYPEOF,1,dest))
+                       return;
+       }
+       dest = SQString::Create(_ss(this),GetTypeName(obj1));
+}
+
+bool SQVM::Init(SQVM *friendvm, SQInteger stacksize)
+{
+       _stack.resize(stacksize);
+       _callsstack.reserve(4);
+       _stackbase = 0;
+       _top = 0;
+       if(!friendvm)
+               _roottable = SQTable::Create(_ss(this), 0);
+       else {
+               _roottable = friendvm->_roottable;
+               _errorhandler = friendvm->_errorhandler;
+               _debughook = friendvm->_debughook;
+       }
+
+       sq_base_register(this);
+       return true;
+}
+
+extern SQInstructionDesc g_InstrDesc[];
+
+bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger nargs,SQInteger stackbase,bool tailcall)
+{
+       SQFunctionProto *func = _funcproto(closure->_function);
+
+       const SQInteger paramssize = func->_parameters.size();
+       const SQInteger newtop = stackbase + func->_stacksize;
+
+
+       if (paramssize != nargs) {
+               if(func->_varparams)
+               {
+                       if (nargs < paramssize) {
+                               Raise_Error(_SC("wrong number of parameters"));
+                               return false;
+                       }
+                       for(SQInteger n = 0; n < nargs - paramssize; n++) {
+                               _vargsstack.push_back(_stack[stackbase+paramssize+n]);
+                               _stack[stackbase+paramssize+n] = _null_;
+                       }
+               }
+               else {
+                       Raise_Error(_SC("wrong number of parameters"));
+                       return false;
+               }
+       }
+
+       if(type(closure->_env) == OT_WEAKREF) {
+               _stack[stackbase] = _weakref(closure->_env)->_obj;
+       }
+
+       if (!tailcall) {
+               CallInfo lc;
+               lc._etraps = 0;
+               lc._prevstkbase = stackbase - _stackbase;
+               lc._target = target;
+               lc._prevtop = _top - _stackbase;
+               lc._ncalls = 1;
+               lc._root = SQFalse;
+               PUSH_CALLINFO(this, lc);
+       }
+       else {
+               ci->_ncalls++;
+               if(ci->_vargs.size) PopVarArgs(ci->_vargs);
+       }
+       ci->_vargs.size = (nargs - paramssize);
+       ci->_vargs.base = _vargsstack.size()-(ci->_vargs.size);
+       ci->_closure._unVal.pClosure = closure;
+       ci->_closure._type = OT_CLOSURE;
+       ci->_iv = &func->_instructions;
+       ci->_literals = &func->_literals;
+       //grows the stack if needed
+       if (((SQUnsignedInteger)newtop + (func->_stacksize<<1)) > _stack.size()) {
+               _stack.resize(_stack.size() + (func->_stacksize<<1));
+       }
+
+       _top = newtop;
+       _stackbase = stackbase;
+       ci->_ip = ci->_iv->_vals;
+       return true;
+}
+
+bool SQVM::Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval)
+{
+       if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))
+               for(SQInteger i=0;i<ci->_ncalls;i++)
+                       CallDebugHook(_SC('r'));
+
+       SQBool broot = ci->_root;
+       SQInteger last_top = _top;
+       SQInteger target = ci->_target;
+       SQInteger oldstackbase = _stackbase;
+       _stackbase -= ci->_prevstkbase;
+       _top = _stackbase + ci->_prevtop;
+       if(ci->_vargs.size) PopVarArgs(ci->_vargs);
+       POP_CALLINFO(this);
+       if (broot) {
+               if (_arg0 != MAX_FUNC_STACKSIZE) retval = _stack[oldstackbase+_arg1];
+               else retval = _null_;
+       }
+       else {
+               if(target != -1) { //-1 is when a class contructor ret value has to be ignored
+                       if (_arg0 != MAX_FUNC_STACKSIZE)
+                               STK(target) = _stack[oldstackbase+_arg1];
+                       else
+                               STK(target) = _null_;
+               }
+       }
+
+       while (last_top >= _top) _stack[last_top--].Null();
+       assert(oldstackbase >= _stackbase);
+       return broot?true:false;
+}
+
+#define _RET_ON_FAIL(exp) { if(!exp) return false; }
+
+bool SQVM::LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr)
+{
+       _RET_ON_FAIL(ARITH_OP( op , target, a, incr));
+       a = target;
+       return true;
+}
+
+bool SQVM::PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr)
+{
+       SQObjectPtr trg;
+       _RET_ON_FAIL(ARITH_OP( op , trg, a, incr));
+       target = a;
+       a = trg;
+       return true;
+}
+
+bool SQVM::DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix)
+{
+       SQObjectPtr tmp, tself = self, tkey = key;
+       if (!Get(tself, tkey, tmp, false, true)) { Raise_IdxError(tkey); return false; }
+       _RET_ON_FAIL(ARITH_OP( op , target, tmp, incr))
+       Set(tself, tkey, target,true);
+       if (postfix) target = tmp;
+       return true;
+}
+
+#define arg0 (_i_._arg0)
+#define arg1 (_i_._arg1)
+#define sarg1 (*((SQInt32 *)&_i_._arg1))
+#define arg2 (_i_._arg2)
+#define arg3 (_i_._arg3)
+#define sarg3 ((SQInteger)*((signed char *)&_i_._arg3))
+
+SQRESULT SQVM::Suspend()
+{
+       if (_suspended)
+               return sq_throwerror(this, _SC("cannot suspend an already suspended vm"));
+       if (_nnativecalls!=2)
+               return sq_throwerror(this, _SC("cannot suspend through native calls/metamethods"));
+       return SQ_SUSPEND_FLAG;
+}
+
+void SQVM::PopVarArgs(VarArgs &vargs)
+{
+       for(SQInteger n = 0; n< vargs.size; n++)
+               _vargsstack.pop_back();
+}
+
+#define _FINISH(stoploop) {finished = stoploop; return true; }
+bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr
+&o3,SQObjectPtr &o4,SQInteger arg_2,bool &finished)
+{
+       SQInteger nrefidx;
+       switch(type(o1)) {
+       case OT_TABLE:
+               if((nrefidx = _table(o1)->Next(false,o4, o2, o3)) == -1) _FINISH(true);
+               o4 = (SQInteger)nrefidx; _FINISH(false);
+       case OT_ARRAY:
+               if((nrefidx = _array(o1)->Next(o4, o2, o3)) == -1) _FINISH(true);
+               o4 = (SQInteger) nrefidx; _FINISH(false);
+       case OT_STRING:
+               if((nrefidx = _string(o1)->Next(o4, o2, o3)) == -1)_FINISH(true);
+               o4 = (SQInteger)nrefidx; _FINISH(false);
+       case OT_CLASS:
+               if((nrefidx = _class(o1)->Next(o4, o2, o3)) == -1)_FINISH(true);
+               o4 = (SQInteger)nrefidx; _FINISH(false);
+       case OT_USERDATA:
+       case OT_INSTANCE:
+               if(_delegable(o1)->_delegate) {
+                       SQObjectPtr itr;
+                       Push(o1);
+                       Push(o4);
+                       if(CallMetaMethod(_delegable(o1), MT_NEXTI, 2, itr)){
+                               o4 = o2 = itr;
+                               if(type(itr) == OT_NULL) _FINISH(true);
+                               if(!Get(o1, itr, o3, false,false)) {
+                                       Raise_Error(_SC("_nexti returned an invalid idx"));
+                                       return false;
+                               }
+                               _FINISH(false);
+                       }
+                       Raise_Error(_SC("_nexti failed"));
+                       return false;
+               }
+               break;
+       case OT_GENERATOR:
+               if(_generator(o1)->_state == SQGenerator::eDead) _FINISH(true);
+               if(_generator(o1)->_state == SQGenerator::eSuspended) {
+                       SQInteger idx = 0;
+                       if(type(o4) == OT_INTEGER) {
+                               idx = _integer(o4) + 1;
+                       }
+                       o2 = idx;
+                       o4 = idx;
+                       _generator(o1)->Resume(this, arg_2+1);
+                       _FINISH(false);
+               }
+       default:
+               Raise_Error(_SC("cannot iterate %s"), GetTypeName(o1));
+       }
+       return false; //cannot be hit(just to avoid warnings)
+}
+
+bool SQVM::DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2)
+{
+       if(type(o1) != OT_TABLE) { Raise_Error(_SC("delegating a '%s'"), GetTypeName(o1)); return false; }
+       switch(type(o2)) {
+       case OT_TABLE:
+               if(!_table(o1)->SetDelegate(_table(o2))){
+                       Raise_Error(_SC("delegate cycle detected"));
+                       return false;
+               }
+               break;
+       case OT_NULL:
+               _table(o1)->SetDelegate(NULL);
+               break;
+       default:
+               Raise_Error(_SC("using '%s' as delegate"), GetTypeName(o2));
+               return false;
+               break;
+       }
+       trg = o1;
+       return true;
+}
+#define COND_LITERAL (arg3!=0?(*ci->_literals)[arg1]:STK(arg1))
+
+#define _GUARD(exp) { if(!exp) { Raise_Error(_lasterror); SQ_THROW();} }
+
+#define SQ_THROW() { goto exception_trap; }
+
+bool SQVM::CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func)
+{
+       SQInteger nouters;
+       SQClosure *closure = SQClosure::Create(_ss(this), func);
+       if((nouters = func->_outervalues.size())) {
+               closure->_outervalues.reserve(nouters);
+               for(SQInteger i = 0; i<nouters; i++) {
+                       SQOuterVar &v = func->_outervalues[i];
+                       switch(v._type){
+                       case otSYMBOL:
+                               closure->_outervalues.push_back(_null_);
+                               if(!Get(_stack._vals[_stackbase]/*STK(0)*/, v._src, closure->_outervalues.top(), false,true))
+                               {Raise_IdxError(v._src); return false; }
+                               break;
+                       case otLOCAL:
+                               closure->_outervalues.push_back(_stack._vals[_stackbase+_integer(v._src)]);
+                               break;
+                       case otOUTER:
+                               closure->_outervalues.push_back(_closure(ci->_closure)->_outervalues[_integer(v._src)]);
+                               break;
+                       }
+               }
+       }
+       target = closure;
+       return true;
+
+}
+
+bool SQVM::GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &index,CallInfo *ci)
+{
+       if(ci->_vargs.size == 0) {
+               Raise_Error(_SC("the function doesn't have var args"));
+               return false;
+       }
+       if(!sq_isnumeric(index)){
+               Raise_Error(_SC("indexing 'vargv' with %s"),GetTypeName(index));
+               return false;
+       }
+       SQInteger idx = tointeger(index);
+       if(idx < 0 || idx >= ci->_vargs.size){ Raise_Error(_SC("vargv index out of range")); return false; }
+       target = _vargsstack[ci->_vargs.base+idx];
+       return true;
+}
+
+bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes)
+{
+       SQClass *base = NULL;
+       SQObjectPtr attrs;
+       if(baseclass != -1) {
+               if(type(_stack._vals[_stackbase+baseclass]) != OT_CLASS) { Raise_Error(_SC("trying to inherit from a %s"),GetTypeName(_stack._vals[_stackbase+baseclass])); return false; }
+               base = _class(_stack._vals[_stackbase + baseclass]);
+       }
+       if(attributes != MAX_FUNC_STACKSIZE) {
+               attrs = _stack._vals[_stackbase+attributes];
+       }
+       target = SQClass::Create(_ss(this),base);
+       if(type(_class(target)->_metamethods[MT_INHERITED]) != OT_NULL) {
+               int nparams = 2;
+               SQObjectPtr ret;
+               Push(target); Push(attrs);
+               Call(_class(target)->_metamethods[MT_INHERITED],nparams,_top - nparams, ret, false);
+               Pop(nparams);
+       }
+       _class(target)->_attributes = attrs;
+       return true;
+}
+
+
+
+bool SQVM::IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res)
+{
+       if(type(o1) == type(o2)) {
+               res = ((_userpointer(o1) == _userpointer(o2)?true:false));
+       }
+       else {
+               if(sq_isnumeric(o1) && sq_isnumeric(o2)) {
+                       SQInteger cmpres;
+                       if(!ObjCmp(o1, o2,cmpres)) return false;
+                       res = (cmpres == 0);
+               }
+               else {
+                       res = false;
+               }
+       }
+       return true;
+}
+
+bool SQVM::IsFalse(SQObjectPtr &o)
+{
+       if((type(o) & SQOBJECT_CANBEFALSE) && ( (type(o) == OT_FLOAT) && (_float(o) == SQFloat(0.0)) )
+               || (_integer(o) == 0) ) { //OT_NULL|OT_INTEGER|OT_BOOL
+               return true;
+       }
+       return false;
+}
+
+bool SQVM::GETPARENT_OP(SQObjectPtr &o,SQObjectPtr &target)
+{
+       switch(type(o)) {
+               case OT_TABLE: target = _table(o)->_delegate?SQObjectPtr(_table(o)->_delegate):_null_;
+                       break;
+               case OT_CLASS: target = _class(o)->_base?_class(o)->_base:_null_;
+                       break;
+               default:
+                       Raise_Error(_SC("the %s type doesn't have a parent slot"), GetTypeName(o));
+                       return false;
+       }
+       return true;
+}
+
+bool SQVM::Execute(SQObjectPtr &closure, SQInteger target, SQInteger nargs, SQInteger stackbase,SQObjectPtr &outres, SQBool raiseerror,ExecutionType et)
+{
+       if ((_nnativecalls + 1) > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; }
+       _nnativecalls++;
+       AutoDec ad(&_nnativecalls);
+       SQInteger traps = 0;
+       //temp_reg vars for OP_CALL
+       SQInteger ct_target;
+       bool ct_tailcall;
+
+       switch(et) {
+               case ET_CALL:
+                       if(!StartCall(_closure(closure), _top - nargs, nargs, stackbase, false)) {
+                               //call the handler if there are no calls in the stack, if not relies on the previous node
+                               if(ci == NULL) CallErrorHandler(_lasterror);
+                               return false;
+                       }
+                       ci->_root = SQTrue;
+                       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 = SQFalse;
+                       break;
+       }
+
+exception_restore:
+       //
+       {
+               for(;;)
+               {
+                       const SQInstruction &_i_ = *ci->_ip++;
+                       //dumpstack(_stackbase);
+                       //scprintf("\n[%d] %s %d %d %d %d\n",ci->_ip-ci->_iv->_vals,g_InstrDesc[_i_.op].name,arg0,arg1,arg2,arg3);
+                       switch(_i_.op)
+                       {
+                       case _OP_LINE:
+                               if(type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))
+                                       CallDebugHook(_SC('l'),arg1);
+                               continue;
+                       case _OP_LOAD: TARGET = (*ci->_literals)[arg1]; continue;
+                       case _OP_LOADINT: TARGET = (SQInteger)arg1; continue;
+                       case _OP_DLOAD: TARGET = (*ci->_literals)[arg1]; STK(arg2) = (*ci->_literals)[arg3];continue;
+                       case _OP_TAILCALL:
+                               temp_reg = STK(arg1);
+                               if (type(temp_reg) == OT_CLOSURE){
+                                       ct_tailcall = true;
+                                       if(ci->_vargs.size) PopVarArgs(ci->_vargs);
+                                       for (SQInteger i = 0; i < arg3; i++) STK(i) = STK(arg2 + i);
+                                       ct_target = ci->_target;
+                                       goto common_call;
+                               }
+                       case _OP_CALL: {
+                                       ct_tailcall = false;
+                                       ct_target = arg0;
+                                       temp_reg = STK(arg1);
+common_call:
+                                       SQInteger last_top = _top;
+                                       switch (type(temp_reg)) {
+                                       case OT_CLOSURE:{
+                                               _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));
+                                                       Return(1, ct_target, temp_reg);
+                                                       STK(ct_target) = gen;
+                                                       while (last_top >= _top) _stack[last_top--].Null();
+                                                       continue;
+                                               }
+                                               if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))
+                                                       CallDebugHook(_SC('c'));
+                                               }
+                                               break;
+                                       case OT_NATIVECLOSURE: {
+                                               bool suspend;
+                                               _GUARD(CallNative(_nativeclosure(temp_reg), arg3, _stackbase+arg2, ct_tailcall, temp_reg,suspend));
+                                               if(suspend){
+                                                       _suspended = SQTrue;
+                                                       _suspended_target = ct_target;
+                                                       _suspended_root = ci->_root;
+                                                       _suspended_traps = traps;
+                                                       outres = temp_reg;
+                                                       return true;
+                                               }
+                                               if(ct_target != -1) { //skip return value for contructors
+                                                       STK(ct_target) = temp_reg;
+                                               }
+                                                                                  }
+                                               break;
+                                       case OT_CLASS:{
+                                               SQObjectPtr inst;
+                                               _GUARD(CreateClassInstance(_class(temp_reg),inst,temp_reg));
+                                               STK(ct_target) = inst;
+                                               ct_target = -1; //fakes return value target so that is not overwritten by the contructor
+                                               if(type(temp_reg) != OT_NULL) {
+                                                       _stack[_stackbase+arg2] = inst;
+                                                       goto common_call; //hard core spaghetti code(reissues the OP_CALL to invoke the contructor)
+                                               }
+                                               }
+                                               break;
+                                       case OT_TABLE:
+                                       case OT_USERDATA:
+                                       case OT_INSTANCE:
+                                               {
+                                               Push(temp_reg);
+                                               for (SQInteger i = 0; i < arg3; i++) Push(STK(arg2 + i));
+                                               if (_delegable(temp_reg) && CallMetaMethod(_delegable(temp_reg), MT_CALL, arg3+1, temp_reg)){
+                                                       STK(ct_target) = temp_reg;
+                                                       break;
+                                               }
+                                               Raise_Error(_SC("attempt to call '%s'"), GetTypeName(temp_reg));
+                                               SQ_THROW();
+                                         }
+                                       default:
+                                               Raise_Error(_SC("attempt to call '%s'"), GetTypeName(temp_reg));
+                                               SQ_THROW();
+                                       }
+                               }
+                                 continue;
+                       case _OP_PREPCALL:
+                                       if (!Get(STK(arg2), STK(arg1), temp_reg, false,true))
+                                       { Raise_IdxError(STK(arg1)); SQ_THROW(); }
+                                       goto common_prepcall;
+                       case _OP_PREPCALLK:
+                                       if (!Get(STK(arg2), (*ci->_literals)[arg1], temp_reg,false,true)) {
+                                               if(type(STK(arg2)) == OT_CLASS) { //hack?
+                                                       if(_class_ddel->Get((*ci->_literals)[arg1],temp_reg)) {
+                                                               STK(arg3) = STK(arg2);
+                                                               TARGET = temp_reg;
+                                                               continue;
+                                                       }
+                                               }
+                                               { Raise_IdxError((*ci->_literals)[arg1]); SQ_THROW();}
+                                       }
+common_prepcall:
+                                       if(type(STK(arg2)) == OT_CLASS) {
+                                               STK(arg3) = STK(0); // this
+                                       }
+                                       else {
+                                               STK(arg3) = STK(arg2);
+                                       }
+                                       TARGET = temp_reg;
+                               continue;
+                       case _OP_GETK:
+                               if (!Get(STK(arg2), (*ci->_literals)[arg1], temp_reg, false,true)) { Raise_IdxError((*ci->_literals)[arg1]); SQ_THROW();}
+                               TARGET = temp_reg;
+                               continue;
+                       case _OP_MOVE: TARGET = STK(arg1); continue;
+                       case _OP_NEWSLOT:
+                               _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),false));
+                               if(arg0 != arg3) TARGET = STK(arg3);
+                               continue;
+                       case _OP_DELETE: _GUARD(DeleteSlot(STK(arg1), STK(arg2), TARGET)); continue;
+                       case _OP_SET:
+                               if (!Set(STK(arg1), STK(arg2), STK(arg3),true)) { Raise_IdxError(STK(arg2)); SQ_THROW(); }
+                               if (arg0 != arg3) TARGET = STK(arg3);
+                               continue;
+                       case _OP_GET:
+                               if (!Get(STK(arg1), STK(arg2), temp_reg, false,true)) { Raise_IdxError(STK(arg2)); SQ_THROW(); }
+                               TARGET = temp_reg;
+                               continue;
+                       case _OP_EQ:{
+                               bool res;
+                               if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); }
+                               TARGET = res?_true_:_false_;
+                               }continue;
+                       case _OP_NE:{
+                               bool res;
+                               if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); }
+                               TARGET = (!res)?_true_:_false_;
+                               } continue;
+                       case _OP_ARITH: _GUARD(ARITH_OP( arg3 , temp_reg, STK(arg2), STK(arg1))); TARGET = temp_reg; continue;
+                       case _OP_BITW:  _GUARD(BW_OP( arg3,TARGET,STK(arg2),STK(arg1))); continue;
+                       case _OP_RETURN:
+                               if(type((ci)->_generator) == OT_GENERATOR) {
+                                       _generator((ci)->_generator)->Kill();
+                               }
+                               if(Return(arg0, arg1, temp_reg)){
+                                       assert(traps==0);
+                                       outres = temp_reg;
+                                       return true;
+                               }
+                               continue;
+                       case _OP_LOADNULLS:{ for(SQInt32 n=0; n < arg1; n++) STK(arg0+n) = _null_; }continue;
+                       case _OP_LOADROOTTABLE: TARGET = _roottable; continue;
+                       case _OP_LOADBOOL: TARGET = arg1?_true_:_false_; continue;
+                       case _OP_DMOVE: STK(arg0) = STK(arg1); STK(arg2) = STK(arg3); continue;
+                       case _OP_JMP: ci->_ip += (sarg1); continue;
+                       case _OP_JNZ: if(!IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue;
+                       case _OP_JZ: if(IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue;
+                       case _OP_LOADFREEVAR: TARGET = _closure(ci->_closure)->_outervalues[arg1]; continue;
+                       case _OP_VARGC: TARGET = SQInteger(ci->_vargs.size); continue;
+                       case _OP_GETVARGV:
+                               if(!GETVARGV_OP(TARGET,STK(arg1),ci)) { SQ_THROW(); }
+                               continue;
+                       case _OP_NEWTABLE: TARGET = SQTable::Create(_ss(this), arg1); continue;
+                       case _OP_NEWARRAY: TARGET = SQArray::Create(_ss(this), 0); _array(TARGET)->Reserve(arg1); continue;
+                       case _OP_APPENDARRAY: _array(STK(arg0))->Append(COND_LITERAL);  continue;
+                       case _OP_GETPARENT: _GUARD(GETPARENT_OP(STK(arg1),TARGET)); continue;
+                       case _OP_COMPARITH: _GUARD(DerefInc(arg3, TARGET, STK((((SQUnsignedInteger)arg1&0xFFFF0000)>>16)), STK(arg2), STK(arg1&0x0000FFFF), false)); continue;
+                       case _OP_COMPARITHL: _GUARD(LOCAL_INC(arg3, TARGET, STK(arg1), STK(arg2))); continue;
+                       case _OP_INC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, false));} continue;
+                       case _OP_INCL: {SQObjectPtr o(sarg3); _GUARD(LOCAL_INC('+',TARGET, STK(arg1), o));} continue;
+                       case _OP_PINC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, true));} continue;
+                       case _OP_PINCL: {SQObjectPtr o(sarg3); _GUARD(PLOCAL_INC('+',TARGET, STK(arg1), o));} continue;
+                       case _OP_CMP:   _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg1),TARGET))  continue;
+                       case _OP_EXISTS: TARGET = Get(STK(arg1), STK(arg2), temp_reg, true,false)?_true_:_false_;continue;
+                       case _OP_INSTANCEOF:
+                               if(type(STK(arg1)) != OT_CLASS || type(STK(arg2)) != OT_INSTANCE)
+                               {Raise_Error(_SC("cannot apply instanceof between a %s and a %s"),GetTypeName(STK(arg1)),GetTypeName(STK(arg2))); SQ_THROW();}
+                               TARGET = _instance(STK(arg2))->InstanceOf(_class(STK(arg1)))?_true_:_false_;
+                               continue;
+                       case _OP_AND:
+                               if(IsFalse(STK(arg2))) {
+                                       TARGET = STK(arg2);
+                                       ci->_ip += (sarg1);
+                               }
+                               continue;
+                       case _OP_OR:
+                               if(!IsFalse(STK(arg2))) {
+                                       TARGET = STK(arg2);
+                                       ci->_ip += (sarg1);
+                               }
+                               continue;
+                       case _OP_NEG: _GUARD(NEG_OP(TARGET,STK(arg1))); continue;
+                       case _OP_NOT: TARGET = (IsFalse(STK(arg1))?_true_:_false_); continue;
+                       case _OP_BWNOT:
+                               if(type(STK(arg1)) == OT_INTEGER) {
+                                       SQInteger t = _integer(STK(arg1));
+                                       TARGET = SQInteger(~t);
+                                       continue;
+                               }
+                               Raise_Error(_SC("attempt to perform a bitwise op on a %s"), GetTypeName(STK(arg1)));
+                               SQ_THROW();
+                       case _OP_CLOSURE: {
+                               SQClosure *c = ci->_closure._unVal.pClosure;
+                               SQFunctionProto *fp = c->_function._unVal.pFunctionProto;
+                               if(!CLOSURE_OP(TARGET,fp->_functions[arg1]._unVal.pFunctionProto)) { SQ_THROW(); }
+                               continue;
+                       }
+                       case _OP_YIELD:{
+                               if(type(ci->_generator) == OT_GENERATOR) {
+                                       if(sarg1 != MAX_FUNC_STACKSIZE) temp_reg = STK(arg1);
+                                       _GUARD(_generator(ci->_generator)->Yield(this));
+                                       traps -= ci->_etraps;
+                                       if(sarg1 != MAX_FUNC_STACKSIZE) STK(arg1) = temp_reg;
+                               }
+                               else { Raise_Error(_SC("trying to yield a '%s',only genenerator can be yielded"), GetTypeName(ci->_generator)); SQ_THROW();}
+                               if(Return(arg0, arg1, temp_reg)){
+                                       assert(traps == 0);
+                                       outres = temp_reg;
+                                       return true;
+                               }
+
+                               }
+                               continue;
+                       case _OP_RESUME:
+                               if(type(STK(arg1)) != OT_GENERATOR){ Raise_Error(_SC("trying to resume a '%s',only genenerator can be resumed"), GetTypeName(STK(arg1))); SQ_THROW();}
+                               _GUARD(_generator(STK(arg1))->Resume(this, arg0));
+                               traps += ci->_etraps;
+                continue;
+                       case _OP_FOREACH:{ bool finished;
+                               _GUARD(FOREACH_OP(STK(arg0),STK(arg2),STK(arg2+1),STK(arg2+2),arg2,finished));
+                               if(finished) ci->_ip += sarg1; }
+                               continue;
+                       case _OP_DELEGATE: _GUARD(DELEGATE_OP(TARGET,STK(arg1),STK(arg2))); continue;
+                       case _OP_CLONE:
+                               if(!Clone(STK(arg1), TARGET))
+                               { Raise_Error(_SC("cloning a %s"), GetTypeName(STK(arg1))); SQ_THROW();}
+                               continue;
+                       case _OP_TYPEOF: TypeOf(STK(arg1), TARGET); continue;
+                       case _OP_PUSHTRAP:
+                               _etraps.push_back(SQExceptionTrap(_top,_stackbase, &ci->_iv->_vals[(ci->_ip-ci->_iv->_vals)+arg1], arg0)); traps++;
+                               ci->_etraps++;
+                               continue;
+                       case _OP_POPTRAP:
+                               for(SQInteger i = 0; i < arg0; i++) {
+                                       _etraps.pop_back(); traps--;
+                                       ci->_etraps--;
+                               }
+                               continue;
+                       case _OP_THROW: Raise_Error(TARGET); SQ_THROW(); continue;
+                       case _OP_CLASS: _GUARD(CLASS_OP(TARGET,arg1,arg2)); continue;
+                       case _OP_NEWSLOTA:
+                               bool bstatic = (arg0&NEW_SLOT_STATIC_FLAG)?true:false;
+                               if(type(STK(arg1)) == OT_CLASS) {
+                                       if(type(_class(STK(arg1))->_metamethods[MT_NEWMEMBER]) != OT_NULL ) {
+                                               Push(STK(arg1)); Push(STK(arg2)); Push(STK(arg3));
+                                               Push((arg0&NEW_SLOT_ATTRIBUTES_FLAG) ? STK(arg2-1) : _null_);
+                                               int nparams = 4;
+                                               if(Call(_class(STK(arg1))->_metamethods[MT_NEWMEMBER], nparams, _top - nparams, temp_reg,SQFalse)) {
+                                                       Pop(nparams);
+                                                       continue;
+                                               }
+                                       }
+                               }
+                               _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),bstatic));
+                               if((arg0&NEW_SLOT_ATTRIBUTES_FLAG)) {
+                                       _class(STK(arg1))->SetAttributes(STK(arg2),STK(arg2-1));
+                               }
+                               continue;
+                       }
+
+               }
+       }
+exception_trap:
+       {
+               SQObjectPtr currerror = _lasterror;
+//             dumpstack(_stackbase);
+               SQInteger n = 0;
+               SQInteger last_top = _top;
+               if(ci) {
+                       if(_ss(this)->_notifyallexceptions) CallErrorHandler(currerror);
+
+                       if(traps) {
+                               do {
+                                       if(ci->_etraps > 0) {
+                                               SQExceptionTrap &et = _etraps.top();
+                                               ci->_ip = et._ip;
+                                               _top = et._stacksize;
+                                               _stackbase = et._stackbase;
+                                               _stack[_stackbase+et._extarget] = currerror;
+                                               _etraps.pop_back(); traps--; ci->_etraps--;
+                                               while(last_top >= _top) _stack[last_top--].Null();
+                                               goto exception_restore;
+                                       }
+                                       //if is a native closure
+                                       if(type(ci->_closure) != OT_CLOSURE && n)
+                                               break;
+                                       if(type(ci->_generator) == OT_GENERATOR) _generator(ci->_generator)->Kill();
+                                       PopVarArgs(ci->_vargs);
+                                       POP_CALLINFO(this);
+                                       n++;
+                               } while(_callsstack.size());
+                       }
+                       else {
+                               //call the hook
+                               if(raiseerror && !_ss(this)->_notifyallexceptions)
+                                       CallErrorHandler(currerror);
+                       }
+                       //remove call stack until a C function is found or the cstack is empty
+                       if(ci) do {
+                               SQBool exitafterthisone = ci->_root;
+                               if(type(ci->_generator) == OT_GENERATOR) _generator(ci->_generator)->Kill();
+                               _stackbase -= ci->_prevstkbase;
+                               _top = _stackbase + ci->_prevtop;
+                               PopVarArgs(ci->_vargs);
+                               POP_CALLINFO(this);
+                               if( (ci && type(ci->_closure) != OT_CLOSURE) || exitafterthisone) break;
+                       } while(_callsstack.size());
+
+                       while(last_top >= _top) _stack[last_top--].Null();
+               }
+               _lasterror = currerror;
+               return false;
+       }
+       assert(0);
+}
+
+bool SQVM::CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor)
+{
+       inst = theclass->CreateInstance();
+       if(!theclass->Get(_ss(this)->_constructoridx,constructor)) {
+               //if(!Call(constr,nargs,stackbase,constr,false))
+               //      return false;
+               constructor = _null_;
+       }
+       return true;
+}
+
+void SQVM::CallErrorHandler(SQObjectPtr &error)
+{
+       if(type(_errorhandler) != OT_NULL) {
+               SQObjectPtr out;
+               Push(_roottable); Push(error);
+               Call(_errorhandler, 2, _top-2, out,SQFalse);
+               Pop(2);
+       }
+}
+
+void SQVM::CallDebugHook(SQInteger type,SQInteger forcedline)
+{
+       SQObjectPtr temp_reg;
+       SQInteger nparams=5;
+       SQFunctionProto *func=_funcproto(_closure(ci->_closure)->_function);
+       Push(_roottable); Push(type); Push(func->_sourcename); Push(forcedline?forcedline:func->GetLine(ci->_ip)); Push(func->_name);
+       Call(_debughook,nparams,_top-nparams,temp_reg,SQFalse);
+       Pop(nparams);
+}
+
+bool SQVM::CallNative(SQNativeClosure *nclosure,SQInteger nargs,SQInteger stackbase,bool tailcall,SQObjectPtr &retval,bool &suspend)
+{
+       if (_nnativecalls + 1 > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; }
+       SQInteger nparamscheck = nclosure->_nparamscheck;
+       if(((nparamscheck > 0) && (nparamscheck != nargs))
+               || ((nparamscheck < 0) && (nargs < (-nparamscheck)))) {
+               Raise_Error(_SC("wrong number of parameters"));
+               return false;
+               }
+
+       SQInteger tcs;
+       if((tcs = nclosure->_typecheck.size())) {
+               for(SQInteger 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]));
+                               return false;
+                       }
+       }
+       _nnativecalls++;
+       if ((_top + MIN_STACK_OVERHEAD) > (SQInteger)_stack.size()) {
+               _stack.resize(_stack.size() + (MIN_STACK_OVERHEAD<<1));
+       }
+       SQInteger oldtop = _top;
+       SQInteger oldstackbase = _stackbase;
+       _top = stackbase + nargs;
+       PUSH_CALLINFO(this, CallInfo());
+       ci->_etraps = 0;
+       ci->_closure._unVal.pNativeClosure = nclosure;
+       ci->_closure._type = OT_NATIVECLOSURE;
+       ci->_prevstkbase = stackbase - _stackbase;
+       ci->_ncalls = 1;
+       _stackbase = stackbase;
+       //push free variables
+       SQInteger outers = nclosure->_outervalues.size();
+       for (SQInteger i = 0; i < outers; i++) {
+               Push(nclosure->_outervalues[i]);
+       }
+
+       if(type(nclosure->_env) == OT_WEAKREF) {
+               _stack[stackbase] = _weakref(nclosure->_env)->_obj;
+       }
+
+       ci->_prevtop = (oldtop - oldstackbase);
+       SQInteger ret = (nclosure->_function)(this);
+       _nnativecalls--;
+       suspend = false;
+       if( ret == SQ_SUSPEND_FLAG) suspend = true;
+       else if (ret < 0) {
+               _stackbase = oldstackbase;
+               _top = oldtop;
+               POP_CALLINFO(this);
+               Raise_Error(_lasterror);
+               return false;
+       }
+
+       if (ret != 0){ retval = TOP(); }
+       else { retval = _null_; }
+       _stackbase = oldstackbase;
+       _top = oldtop;
+       POP_CALLINFO(this);
+       return true;
+}
+
+bool SQVM::Get(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw, bool fetchroot)
+{
+       switch(type(self)){
+       case OT_TABLE:
+               if(_table(self)->Get(key,dest))return true;
+               break;
+       case OT_ARRAY:
+               if(sq_isnumeric(key)){
+                       return _array(self)->Get(tointeger(key),dest);
+               }
+               break;
+       case OT_INSTANCE:
+               if(_instance(self)->Get(key,dest)) return true;
+               break;
+       default:break; //shut up compiler
+       }
+       if(FallBackGet(self,key,dest,raw)) return true;
+
+       if(fetchroot) {
+               if(_rawval(STK(0)) == _rawval(self) &&
+                       type(STK(0)) == type(self)) {
+                               return _table(_roottable)->Get(key,dest);
+               }
+       }
+       return false;
+}
+
+bool SQVM::FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw)
+{
+       switch(type(self)){
+       case OT_CLASS:
+               return _class(self)->Get(key,dest);
+               break;
+       case OT_TABLE:
+       case OT_USERDATA:
+        //delegation
+               if(_delegable(self)->_delegate) {
+                       if(Get(SQObjectPtr(_delegable(self)->_delegate),key,dest,raw,false))
+                               return true;
+                       if(raw)return false;
+                       Push(self);Push(key);
+                       if(CallMetaMethod(_delegable(self),MT_GET,2,dest))
+                               return true;
+               }
+               if(type(self) == OT_TABLE) {
+                       if(raw) return false;
+                       return _table_ddel->Get(key,dest);
+               }
+               return false;
+               break;
+       case OT_ARRAY:
+               if(raw)return false;
+               return _array_ddel->Get(key,dest);
+       case OT_STRING:
+               if(sq_isnumeric(key)){
+                       SQInteger n=tointeger(key);
+                       if(abs((int)n)<_string(self)->_len){
+                               if(n<0)n=_string(self)->_len-n;
+                               dest=SQInteger(_stringval(self)[n]);
+                               return true;
+                       }
+                       return false;
+               }
+               else {
+                       if(raw)return false;
+                       return _string_ddel->Get(key,dest);
+               }
+               break;
+       case OT_INSTANCE:
+               if(raw)return false;
+               Push(self);Push(key);
+               if(!CallMetaMethod(_delegable(self),MT_GET,2,dest)) {
+                       return _instance_ddel->Get(key,dest);
+               }
+               return true;
+       case OT_INTEGER:case OT_FLOAT:case OT_BOOL:
+               if(raw)return false;
+               return _number_ddel->Get(key,dest);
+       case OT_GENERATOR:
+               if(raw)return false;
+               return _generator_ddel->Get(key,dest);
+       case OT_CLOSURE: case OT_NATIVECLOSURE:
+               if(raw)return false;
+               return _closure_ddel->Get(key,dest);
+       case OT_THREAD:
+               if(raw)return false;
+               return  _thread_ddel->Get(key,dest);
+       case OT_WEAKREF:
+               if(raw)return false;
+               return  _weakref_ddel->Get(key,dest);
+       default:return false;
+       }
+       return false;
+}
+
+bool SQVM::Set(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool fetchroot)
+{
+       switch(type(self)){
+       case OT_TABLE:
+               if(_table(self)->Set(key,val))
+                       return true;
+               if(_table(self)->_delegate) {
+                       if(Set(_table(self)->_delegate,key,val,false)) {
+                               return true;
+                       }
+               }
+               //keeps going
+       case OT_USERDATA:
+               if(_delegable(self)->_delegate) {
+                       SQObjectPtr t;
+                       Push(self);Push(key);Push(val);
+                       if(CallMetaMethod(_delegable(self),MT_SET,3,t)) return true;
+               }
+               break;
+       case OT_INSTANCE:{
+               if(_instance(self)->Set(key,val))
+                       return true;
+               SQObjectPtr t;
+               Push(self);Push(key);Push(val);
+               if(CallMetaMethod(_delegable(self),MT_SET,3,t)) return true;
+               }
+               break;
+       case OT_ARRAY:
+               if(!sq_isnumeric(key)) {Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); return false; }
+               return _array(self)->Set(tointeger(key),val);
+       default:
+               Raise_Error(_SC("trying to set '%s'"),GetTypeName(self));
+               return false;
+       }
+       if(fetchroot) {
+               if(_rawval(STK(0)) == _rawval(self) &&
+                       type(STK(0)) == type(self)) {
+                               return _table(_roottable)->Set(key,val);
+                       }
+       }
+       return false;
+}
+
+bool SQVM::Clone(const SQObjectPtr &self,SQObjectPtr &target)
+{
+       SQObjectPtr temp_reg;
+       SQObjectPtr newobj;
+       switch(type(self)){
+       case OT_TABLE:
+               newobj = _table(self)->Clone();
+               goto cloned_mt;
+       case OT_INSTANCE:
+               newobj = _instance(self)->Clone(_ss(this));
+cloned_mt:
+               if(_delegable(newobj)->_delegate){
+                       Push(newobj);
+                       Push(self);
+                       CallMetaMethod(_delegable(newobj),MT_CLONED,2,temp_reg);
+               }
+               target = newobj;
+               return true;
+       case OT_ARRAY:
+               target = _array(self)->Clone();
+               return true;
+       default: return false;
+       }
+}
+
+bool SQVM::NewSlot(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic)
+{
+       if(type(key) == OT_NULL) { Raise_Error(_SC("null cannot be used as index")); return false; }
+       switch(type(self)) {
+       case OT_TABLE: {
+               bool rawcall = true;
+               if(_table(self)->_delegate) {
+                       SQObjectPtr res;
+                       if(!_table(self)->Get(key,res)) {
+                               Push(self);Push(key);Push(val);
+                               rawcall = !CallMetaMethod(_table(self),MT_NEWSLOT,3,res);
+                       }
+               }
+               if(rawcall) _table(self)->NewSlot(key,val); //cannot fail
+
+               break;}
+       case OT_CLASS:
+               if(!_class(self)->NewSlot(_ss(this),key,val,bstatic)) {
+                       if(_class(self)->_locked) {
+                               Raise_Error(_SC("trying to modify a class that has already been instantiated"));
+                               return false;
+                       }
+                       else {
+                               SQObjectPtr oval = PrintObjVal(key);
+                               Raise_Error(_SC("the property '%s' already exists"),_stringval(oval));
+                               return false;
+                       }
+               }
+               break;
+       default:
+               Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key));
+               return false;
+               break;
+       }
+       return true;
+}
+
+bool SQVM::DeleteSlot(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &res)
+{
+       switch(type(self)) {
+       case OT_TABLE:
+       case OT_INSTANCE:
+       case OT_USERDATA: {
+               SQObjectPtr t;
+               bool handled = false;
+               if(_delegable(self)->_delegate) {
+                       Push(self);Push(key);
+                       handled = CallMetaMethod(_delegable(self),MT_DELSLOT,2,t);
+               }
+
+               if(!handled) {
+                       if(type(self) == OT_TABLE) {
+                               if(_table(self)->Get(key,t)) {
+                                       _table(self)->Remove(key);
+                               }
+                               else {
+                                       Raise_IdxError((SQObject &)key);
+                                       return false;
+                               }
+                       }
+                       else {
+                               Raise_Error(_SC("cannot delete a slot from %s"),GetTypeName(self));
+                               return false;
+                       }
+               }
+               res = t;
+                               }
+               break;
+       default:
+               Raise_Error(_SC("attempt to delete a slot from a %s"),GetTypeName(self));
+               return false;
+       }
+       return true;
+}
+
+bool SQVM::Call(SQObjectPtr &closure,SQInteger nparams,SQInteger stackbase,SQObjectPtr &outres,SQBool raiseerror)
+{
+#ifdef _DEBUG
+SQInteger prevstackbase = _stackbase;
+#endif
+       switch(type(closure)) {
+       case OT_CLOSURE:
+               return Execute(closure, _top - nparams, nparams, stackbase,outres,raiseerror);
+               break;
+       case OT_NATIVECLOSURE:{
+               bool suspend;
+               return CallNative(_nativeclosure(closure), nparams, stackbase, false, outres,suspend);
+
+                                                 }
+               break;
+       case OT_CLASS: {
+               SQObjectPtr constr;
+               SQObjectPtr temp;
+               CreateClassInstance(_class(closure),outres,constr);
+               if(type(constr) != OT_NULL) {
+                       _stack[stackbase] = outres;
+                       return Call(constr,nparams,stackbase,temp,raiseerror);
+               }
+               return true;
+                                  }
+               break;
+       default:
+               return false;
+       }
+#ifdef _DEBUG
+       if(!_suspended) {
+               assert(_stackbase == prevstackbase);
+       }
+#endif
+       return true;
+}
+
+bool SQVM::CallMetaMethod(SQDelegable *del,SQMetaMethod mm,SQInteger nparams,SQObjectPtr &outres)
+{
+       SQObjectPtr closure;
+       if(del->GetMetaMethod(this, mm, closure)) {
+               if(Call(closure, nparams, _top - nparams, outres, SQFalse)) {
+                       Pop(nparams);
+                       return true;
+               }
+       }
+       Pop(nparams);
+       return false;
+}
+
+void SQVM::Remove(SQInteger n) {
+       n = (n >= 0)?n + _stackbase - 1:_top + n;
+       for(SQInteger i = n; i < _top; i++){
+               _stack[i] = _stack[i+1];
+       }
+       _stack[_top] = _null_;
+       _top--;
+}
+
+void SQVM::Pop() {
+       _stack[--_top] = _null_;
+}
+
+void SQVM::Pop(SQInteger n) {
+       for(SQInteger i = 0; i < n; i++){
+               _stack[--_top] = _null_;
+       }
+}
+
+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(SQInteger n) { return _stack[_top+n]; }
+SQObjectPtr &SQVM::GetAt(SQInteger n) { return _stack[n]; }
+
+#ifdef _DEBUG_DUMP
+void SQVM::dumpstack(SQInteger stackbase,bool dumpall)
+{
+       SQInteger size=dumpall?_stack.size():_top;
+       SQInteger n=0;
+       scprintf(_SC("\n>>>>stack dump<<<<\n"));
+       CallInfo &ci=_callsstack.back();
+       scprintf(_SC("IP: %p\n"),ci._ip);
+       scprintf(_SC("prev stack base: %d\n"),ci._prevstkbase);
+       scprintf(_SC("prev top: %d\n"),ci._prevtop);
+       for(SQInteger i=0;i<size;i++){
+               SQObjectPtr &obj=_stack[i];
+               if(stackbase==i)scprintf(_SC(">"));else scprintf(_SC(" "));
+               scprintf(_SC("[%d]:"),n);
+               switch(type(obj)){
+               case OT_FLOAT:                  scprintf(_SC("FLOAT %.3f"),_float(obj));break;
+               case OT_INTEGER:                scprintf(_SC("INTEGER %d"),_integer(obj));break;
+               case OT_BOOL:                   scprintf(_SC("BOOL %s"),_integer(obj)?"true":"false");break;
+               case OT_STRING:                 scprintf(_SC("STRING %s"),_stringval(obj));break;
+               case OT_NULL:                   scprintf(_SC("NULL"));  break;
+               case OT_TABLE:                  scprintf(_SC("TABLE %p[%p]"),_table(obj),_table(obj)->_delegate);break;
+               case OT_ARRAY:                  scprintf(_SC("ARRAY %p"),_array(obj));break;
+               case OT_CLOSURE:                scprintf(_SC("CLOSURE [%p]"),_closure(obj));break;
+               case OT_NATIVECLOSURE:  scprintf(_SC("NATIVECLOSURE"));break;
+               case OT_USERDATA:               scprintf(_SC("USERDATA %p[%p]"),_userdataval(obj),_userdata(obj)->_delegate);break;
+               case OT_GENERATOR:              scprintf(_SC("GENERATOR"));break;
+               case OT_THREAD:                 scprintf(_SC("THREAD [%p]"),_thread(obj));break;
+               case OT_USERPOINTER:    scprintf(_SC("USERPOINTER %p"),_userpointer(obj));break;
+               case OT_CLASS:                  scprintf(_SC("CLASS %p"),_class(obj));break;
+               case OT_INSTANCE:               scprintf(_SC("INSTANCE %p"),_instance(obj));break;
+               case OT_WEAKREF:                scprintf(_SC("WEAKERF %p"),_weakref(obj));break;
+               default:
+                       assert(0);
+                       break;
+               };
+               scprintf(_SC("\n"));
+               ++n;
+       }
+}
+
+
+
+#endif
index 569bd43..20a9195 100644 (file)
-/*     see copyright notice in squirrel.h */\r
-#ifndef _SQVM_H_\r
-#define _SQVM_H_\r
-\r
-#include "sqopcodes.h"\r
-#include "sqobject.h"\r
-#define MAX_NATIVE_CALLS 100\r
-#define MIN_STACK_OVERHEAD 10\r
-\r
-#define SQ_SUSPEND_FLAG -666\r
-//base lib\r
-void sq_base_register(HSQUIRRELVM v);\r
-\r
-struct SQExceptionTrap{\r
-       SQExceptionTrap() {}\r
-       SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;}\r
-       SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et;      }\r
-       SQInteger _stackbase;\r
-       SQInteger _stacksize;\r
-       SQInstruction *_ip;\r
-       SQInteger _extarget;\r
-};\r
-\r
-#define _INLINE \r
-\r
-#define STK(a) _stack._vals[_stackbase+(a)]\r
-#define TARGET _stack._vals[_stackbase+arg0]\r
-\r
-typedef sqvector<SQExceptionTrap> ExceptionsTraps;\r
-\r
-struct SQVM : public CHAINABLE_OBJ\r
-{\r
-       struct VarArgs {\r
-               VarArgs() { size = 0; base = 0; }\r
-               SQInteger size;\r
-               SQInteger base;\r
-       };\r
-\r
-       struct CallInfo{\r
-               CallInfo() { _generator._type = OT_NULL;}\r
-               //CallInfo(const CallInfo& ci) {  }\r
-               SQInstructionVec *_iv;\r
-               SQObjectPtrVec *_literals;\r
-               SQObject _closure;\r
-               SQObject _generator;\r
-               SQInteger _etraps;\r
-               SQInteger _prevstkbase;\r
-               SQInteger _prevtop;\r
-               SQInteger _target;\r
-               SQInstruction *_ip;\r
-               SQInteger _ncalls;\r
-               SQBool _root;\r
-               VarArgs _vargs;\r
-       };\r
-       \r
-typedef sqvector<CallInfo> CallInfoVec;\r
-public:\r
-       enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM };\r
-       SQVM(SQSharedState *ss);\r
-       ~SQVM();\r
-       bool Init(SQVM *friendvm, SQInteger stacksize);\r
-       bool Execute(SQObjectPtr &func, SQInteger target, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL);\r
-       //starts a native call return when the NATIVE closure returns\r
-       bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger stackbase, bool tailcall, SQObjectPtr &retval,bool &suspend);\r
-       //starts a SQUIRREL call in the same "Execution loop"\r
-       bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall);\r
-       bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor);\r
-       //call a generic closure pure SQUIRREL or NATIVE\r
-       bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror);\r
-       SQRESULT Suspend();\r
-\r
-       void CallDebugHook(SQInteger type,SQInteger forcedline=0);\r
-       void CallErrorHandler(SQObjectPtr &e);\r
-       bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, bool raw, bool fetchroot);\r
-       bool FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw);\r
-       bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, bool fetchroot);\r
-       bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic);\r
-       bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res);\r
-       bool Clone(const SQObjectPtr &self, SQObjectPtr &target);\r
-       bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res);\r
-       bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);\r
-       bool IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res);\r
-       void ToString(const SQObjectPtr &o,SQObjectPtr &res);\r
-       SQString *PrintObjVal(const SQObject &o);\r
-\r
\r
-       void Raise_Error(const SQChar *s, ...);\r
-       void Raise_Error(SQObjectPtr &desc);\r
-       void Raise_IdxError(SQObject &o);\r
-       void Raise_CompareError(const SQObject &o1, const SQObject &o2);\r
-       void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type);\r
-\r
-       void TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest);\r
-       bool CallMetaMethod(SQDelegable *del, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres);\r
-       bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);\r
-       bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval);\r
-       //new stuff\r
-       _INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);\r
-       _INLINE bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);\r
-       _INLINE bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1);\r
-       _INLINE bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res);\r
-       bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func);\r
-       bool GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &idx,CallInfo *ci);\r
-       bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs);\r
-       bool GETPARENT_OP(SQObjectPtr &o,SQObjectPtr &target);\r
-       //return true if the loop is finished\r
-       bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,bool &finished);\r
-       bool DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2);\r
-       _INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);\r
-       _INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);\r
-       _INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix);\r
-       void PopVarArgs(VarArgs &vargs);\r
-#ifdef _DEBUG_DUMP\r
-       void dumpstack(SQInteger stackbase=-1, bool dumpall = false);\r
-#endif\r
-\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-       void Mark(SQCollectable **chain);\r
-#endif\r
-       void Finalize();\r
-\r
-       void Release(){ sq_delete(this,SQVM); } //does nothing\r
-////////////////////////////////////////////////////////////////////////////\r
-       //stack functions for the api\r
-       void Remove(SQInteger n);\r
-\r
-       bool IsFalse(SQObjectPtr &o);\r
-       \r
-       void Pop();\r
-       void Pop(SQInteger n);\r
-       void Push(const SQObjectPtr &o);\r
-       SQObjectPtr &Top();\r
-       SQObjectPtr &PopGet();\r
-       SQObjectPtr &GetUp(SQInteger n);\r
-       SQObjectPtr &GetAt(SQInteger n);\r
-\r
-       SQObjectPtrVec _stack;\r
-       SQObjectPtrVec _vargsstack;\r
-       SQInteger _top;\r
-       SQInteger _stackbase;\r
-       SQObjectPtr _roottable;\r
-       SQObjectPtr _lasterror;\r
-       SQObjectPtr _errorhandler;\r
-       SQObjectPtr _debughook;\r
-\r
-       SQObjectPtr temp_reg;\r
-       CallInfoVec _callsstack;\r
-       ExceptionsTraps _etraps;\r
-       CallInfo *ci;\r
-       void *_foreignptr;\r
-       //VMs sharing the same state\r
-       SQSharedState *_sharedstate;\r
-       SQInteger _nnativecalls;\r
-       //suspend infos\r
-       SQBool _suspended;\r
-       SQBool _suspended_root;\r
-       SQInteger _suspended_target;\r
-       SQInteger _suspended_traps;\r
-};\r
-\r
-struct AutoDec{\r
-       AutoDec(SQInteger *n) { _n = n; }\r
-       ~AutoDec() { (*_n)--; }\r
-       SQInteger *_n;\r
-};\r
-\r
-inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));}\r
-const SQChar *GetTypeName(const SQObjectPtr &obj1);\r
-const SQChar *IdType2Name(SQObjectType type);\r
-\r
-#define _ss(_vm_) (_vm_)->_sharedstate\r
-\r
-#ifndef NO_GARBAGE_COLLECTOR\r
-#define _opt_ss(_vm_) (_vm_)->_sharedstate\r
-#else\r
-#define _opt_ss(_vm_) NULL\r
-#endif\r
-\r
-#define PUSH_CALLINFO(v,nci){ \\r
-       v->ci = &v->_callsstack.push_back(nci); \\r
-}\r
-\r
-#define POP_CALLINFO(v){ \\r
-       v->_callsstack.pop_back(); \\r
-       if(v->_callsstack.size())       \\r
-               v->ci = &v->_callsstack.back() ; \\r
-       else    \\r
-               v->ci = NULL; \\r
-}\r
-#endif //_SQVM_H_\r
+/*     see copyright notice in squirrel.h */
+#ifndef _SQVM_H_
+#define _SQVM_H_
+
+#include "sqopcodes.h"
+#include "sqobject.h"
+#define MAX_NATIVE_CALLS 100
+#define MIN_STACK_OVERHEAD 10
+
+#define SQ_SUSPEND_FLAG -666
+//base lib
+void sq_base_register(HSQUIRRELVM v);
+
+struct SQExceptionTrap{
+       SQExceptionTrap() {}
+       SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;}
+       SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et;      }
+       SQInteger _stackbase;
+       SQInteger _stacksize;
+       SQInstruction *_ip;
+       SQInteger _extarget;
+};
+
+#define _INLINE
+
+#define STK(a) _stack._vals[_stackbase+(a)]
+#define TARGET _stack._vals[_stackbase+arg0]
+
+typedef sqvector<SQExceptionTrap> ExceptionsTraps;
+
+struct SQVM : public CHAINABLE_OBJ
+{
+       struct VarArgs {
+               VarArgs() { size = 0; base = 0; }
+               SQInteger size;
+               SQInteger base;
+       };
+
+       struct CallInfo{
+               CallInfo() { _generator._type = OT_NULL;}
+               //CallInfo(const CallInfo& ci) {  }
+               SQInstructionVec *_iv;
+               SQObjectPtrVec *_literals;
+               SQObject _closure;
+               SQObject _generator;
+               SQInteger _etraps;
+               SQInteger _prevstkbase;
+               SQInteger _prevtop;
+               SQInteger _target;
+               SQInstruction *_ip;
+               SQInteger _ncalls;
+               SQBool _root;
+               VarArgs _vargs;
+       };
+
+typedef sqvector<CallInfo> CallInfoVec;
+public:
+       enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM };
+       SQVM(SQSharedState *ss);
+       ~SQVM();
+       bool Init(SQVM *friendvm, SQInteger stacksize);
+       bool Execute(SQObjectPtr &func, SQInteger target, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL);
+       //starts a native call return when the NATIVE closure returns
+       bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger stackbase, bool tailcall, SQObjectPtr &retval,bool &suspend);
+       //starts a SQUIRREL call in the same "Execution loop"
+       bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall);
+       bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor);
+       //call a generic closure pure SQUIRREL or NATIVE
+       bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror);
+       SQRESULT Suspend();
+
+       void CallDebugHook(SQInteger type,SQInteger forcedline=0);
+       void CallErrorHandler(SQObjectPtr &e);
+       bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, bool raw, bool fetchroot);
+       bool FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw);
+       bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, bool fetchroot);
+       bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic);
+       bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res);
+       bool Clone(const SQObjectPtr &self, SQObjectPtr &target);
+       bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res);
+       bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);
+       bool IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res);
+       void ToString(const SQObjectPtr &o,SQObjectPtr &res);
+       SQString *PrintObjVal(const SQObject &o);
+
+
+       void Raise_Error(const SQChar *s, ...);
+       void Raise_Error(SQObjectPtr &desc);
+       void Raise_IdxError(SQObject &o);
+       void Raise_CompareError(const SQObject &o1, const SQObject &o2);
+       void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type);
+
+       void TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest);
+       bool CallMetaMethod(SQDelegable *del, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres);
+       bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);
+       bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval);
+       //new stuff
+       _INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
+       _INLINE bool BW_OP(SQUnsignedInteger 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,SQInteger base,SQInteger attrs);
+       bool GETPARENT_OP(SQObjectPtr &o,SQObjectPtr &target);
+       //return true if the loop is finished
+       bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,bool &finished);
+       bool DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2);
+       _INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
+       _INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
+       _INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix);
+       void PopVarArgs(VarArgs &vargs);
+#ifdef _DEBUG_DUMP
+       void dumpstack(SQInteger stackbase=-1, bool dumpall = false);
+#endif
+
+#ifndef NO_GARBAGE_COLLECTOR
+       void Mark(SQCollectable **chain);
+#endif
+       void Finalize();
+
+       void Release(){ sq_delete(this,SQVM); } //does nothing
+////////////////////////////////////////////////////////////////////////////
+       //stack functions for the api
+       void Remove(SQInteger n);
+
+       bool IsFalse(SQObjectPtr &o);
+
+       void Pop();
+       void Pop(SQInteger n);
+       void Push(const SQObjectPtr &o);
+       SQObjectPtr &Top();
+       SQObjectPtr &PopGet();
+       SQObjectPtr &GetUp(SQInteger n);
+       SQObjectPtr &GetAt(SQInteger n);
+
+       SQObjectPtrVec _stack;
+       SQObjectPtrVec _vargsstack;
+       SQInteger _top;
+       SQInteger _stackbase;
+       SQObjectPtr _roottable;
+       SQObjectPtr _lasterror;
+       SQObjectPtr _errorhandler;
+       SQObjectPtr _debughook;
+
+       SQObjectPtr temp_reg;
+       CallInfoVec _callsstack;
+       ExceptionsTraps _etraps;
+       CallInfo *ci;
+       void *_foreignptr;
+       //VMs sharing the same state
+       SQSharedState *_sharedstate;
+       SQInteger _nnativecalls;
+       //suspend infos
+       SQBool _suspended;
+       SQBool _suspended_root;
+       SQInteger _suspended_target;
+       SQInteger _suspended_traps;
+};
+
+struct AutoDec{
+       AutoDec(SQInteger *n) { _n = n; }
+       ~AutoDec() { (*_n)--; }
+       SQInteger *_n;
+};
+
+inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));}
+const SQChar *GetTypeName(const SQObjectPtr &obj1);
+const SQChar *IdType2Name(SQObjectType type);
+
+#define _ss(_vm_) (_vm_)->_sharedstate
+
+#ifndef NO_GARBAGE_COLLECTOR
+#define _opt_ss(_vm_) (_vm_)->_sharedstate
+#else
+#define _opt_ss(_vm_) NULL
+#endif
+
+#define PUSH_CALLINFO(v,nci){ \
+       v->ci = &v->_callsstack.push_back(nci); \
+}
+
+#define POP_CALLINFO(v){ \
+       v->_callsstack.pop_back(); \
+       if(v->_callsstack.size())       \
+               v->ci = &v->_callsstack.back() ; \
+       else    \
+               v->ci = NULL; \
+}
+#endif //_SQVM_H_
index aa21538..5539b72 100644 (file)
@@ -105,7 +105,7 @@ Statistics::draw_worldmap_info(DrawingContext& context)
 
   char caption_buf[128];
   char stat_buf[128];
-  switch (display_stat) 
+  switch (display_stat)
   {
     case 0:
       snprintf(caption_buf, sizeof(caption_buf), _("Max coins collected:"));
@@ -121,7 +121,7 @@ Statistics::draw_worldmap_info(DrawingContext& context)
        int csecs = (int)(time * 100);
        int mins = (int)(csecs / 6000);
        int secs = (csecs % 6000) / 100;
-       snprintf(stat_buf, sizeof(stat_buf), "%02d:%02d", mins,secs); 
+       snprintf(stat_buf, sizeof(stat_buf), "%02d:%02d", mins,secs);
       }
       break;
     case 3:
@@ -165,30 +165,30 @@ Statistics::draw_message_info(DrawingContext& context, std::string title)
   int py = 450 + 18;
 
   snprintf(stat_buf, sizeof(stat_buf), "%d/%d", coins, total_coins);
-  context.draw_text(white_small_text, _("Max coins collected:"), Vector(left, py), LEFT_ALLIGN, LAYER_GUI); 
-  context.draw_text(white_small_text, "%d / %d", Vector(right, py), RIGHT_ALLIGN, LAYER_GUI); 
+  context.draw_text(white_small_text, _("Max coins collected:"), Vector(left, py), LEFT_ALLIGN, LAYER_GUI);
+  context.draw_text(white_small_text, "%d / %d", Vector(right, py), RIGHT_ALLIGN, LAYER_GUI);
   py+=18;
 
   snprintf(stat_buf, sizeof(stat_buf), "%d/%d", badguys, total_badguys);
-  context.draw_text(white_small_text, _("Max fragging:"), Vector(left, py), LEFT_ALLIGN, LAYER_GUI); 
-  context.draw_text(white_small_text, "%d / %d", Vector(right, py), RIGHT_ALLIGN, LAYER_GUI); 
+  context.draw_text(white_small_text, _("Max fragging:"), Vector(left, py), LEFT_ALLIGN, LAYER_GUI);
+  context.draw_text(white_small_text, "%d / %d", Vector(right, py), RIGHT_ALLIGN, LAYER_GUI);
   py+=18;
 
   int csecs = (int)(time * 100);
   int mins = (int)(csecs / 6000);
   int secs = (csecs % 6000) / 100;
-  snprintf(stat_buf, sizeof(stat_buf), "%02d:%02d", mins,secs); 
-  context.draw_text(white_small_text, _("Min time needed:"), Vector(left, py), LEFT_ALLIGN, LAYER_GUI); 
-  context.draw_text(white_small_text, "%02d:%02d", Vector(right, py), RIGHT_ALLIGN, LAYER_GUI); 
+  snprintf(stat_buf, sizeof(stat_buf), "%02d:%02d", mins,secs);
+  context.draw_text(white_small_text, _("Min time needed:"), Vector(left, py), LEFT_ALLIGN, LAYER_GUI);
+  context.draw_text(white_small_text, "%02d:%02d", Vector(right, py), RIGHT_ALLIGN, LAYER_GUI);
   py+=18;
-  
+
   snprintf(stat_buf, sizeof(stat_buf), "%d/%d", secrets, total_secrets);
-  context.draw_text(white_small_text, _("Max secrets found:"), Vector(left, py), LEFT_ALLIGN, LAYER_GUI); 
-  context.draw_text(white_small_text, "%d / %d", Vector(right, py), RIGHT_ALLIGN, LAYER_GUI); 
+  context.draw_text(white_small_text, _("Max secrets found:"), Vector(left, py), LEFT_ALLIGN, LAYER_GUI);
+  context.draw_text(white_small_text, "%d / %d", Vector(right, py), RIGHT_ALLIGN, LAYER_GUI);
   py+=18;
 }
 
-void 
+void
 Statistics::draw_endseq_panel(DrawingContext& context, Statistics* best_stats, Surface* backdrop)
 {
   // skip draw if level was never played
@@ -260,10 +260,10 @@ Statistics::draw_endseq_panel(DrawingContext& context, Statistics* best_stats, S
 void
 Statistics::reset()
 {
-  coins = 0; 
-  badguys = 0; 
-  time = 0; 
-  secrets = 0; 
+  coins = 0;
+  badguys = 0;
+  time = 0;
+  secrets = 0;
 }
 
 void
@@ -297,4 +297,3 @@ Statistics::declare_invalid()
 {
   valid = false;
 }
-
index 5419f5b..a7b194f 100644 (file)
@@ -32,7 +32,7 @@
  *  track of stuff like scores, and minor, but funny things, like
  *  number of jumps and stuff */
 class Statistics
-{ 
+{
 public:
   int coins; /**< coins collected */
   int total_coins; /**< coins in level */
index b2d60bf..972a29d 100644 (file)
@@ -45,7 +45,7 @@ TextScroller::TextScroller(const std::string& filename)
 {
   defaultspeed = DEFAULT_SPEED;
   speed = defaultspeed;
-  
+
   std::string text;
   std::string background_file;
 
@@ -56,7 +56,7 @@ TextScroller::TextScroller(const std::string& filename)
     const lisp::Lisp* text_lisp = root->get_lisp("supertux-text");
     if(!text_lisp)
       throw std::runtime_error("File isn't a supertux-text file");
-    
+
     if(!text_lisp->get("text", text))
       throw std::runtime_error("file doesn't contain a text field");
     if(!text_lisp->get("background", background_file))
@@ -104,13 +104,13 @@ TextScroller::update(float elapsed_time)
   if(main_controller->pressed(Controller::JUMP)
       || main_controller->pressed(Controller::ACTION)
       || main_controller->pressed(Controller::MENU_SELECT))
-    scroll += SCROLL;    
+    scroll += SCROLL;
   if(main_controller->pressed(Controller::PAUSE_MENU)) {
     main_loop->exit_screen(new FadeOut(0.5));
   }
 
   scroll += speed * elapsed_time;
-    
+
   if(scroll < 0)
     scroll = 0;
 }
@@ -154,7 +154,9 @@ InfoBox::InfoBox(const std::string& text)
 
 InfoBox::~InfoBox()
 {
-  for(std::vector<InfoBoxLine*>::iterator i = lines.begin(); i != lines.end(); i++) delete *i;
+  for(std::vector<InfoBoxLine*>::iterator i = lines.begin();
+      i != lines.end(); i++)
+    delete *i;
   delete arrow_scrollup;
   delete arrow_scrolldown;
 }
@@ -219,27 +221,27 @@ InfoBoxLine::InfoBoxLine(char format_char, const std::string& text) : lineType(N
 {
   switch(format_char)
   {
-    case ' ': 
+    case ' ':
       lineType = SMALL;
       font = white_small_text;
       break;
-    case '\t': 
+    case '\t':
       lineType = NORMAL;
       font = white_text;
       break;
-    case '-': 
+    case '-':
       lineType = HEADING;
       font = white_big_text;
       break;
-    case '*': 
+    case '*':
       lineType = REFERENCE;
       font = blue_text;
       break;
-    case '#': 
+    case '#':
       lineType = NORMAL_LEFT;
       font = white_text;
       break;
-    case '!': 
+    case '!':
       lineType = IMAGE;
       image = new Surface(text);
       break;
@@ -254,7 +256,7 @@ InfoBoxLine::~InfoBoxLine()
   delete image;
 }
 
-const std::vector<InfoBoxLine*> 
+const std::vector<InfoBoxLine*>
 InfoBoxLine::split(const std::string& text, int line_length)
 {
   std::vector<InfoBoxLine*> lines;
@@ -285,12 +287,12 @@ InfoBoxLine::split(const std::string& text, int line_length)
     if (format_char == '!') {
       lines.push_back(new InfoBoxLine(format_char, s));
       continue;
-    } 
+    }
 
     // append wrapped parts of line into list
     std::string overflow;
-    do { 
-      lines.push_back(new InfoBoxLine(format_char, Font::wrap_to_chars(s, line_length, &overflow))); 
+    do {
+      lines.push_back(new InfoBoxLine(format_char, Font::wrap_to_chars(s, line_length, &overflow)));
       s = overflow;
     } while (s.length() > 0);
 
@@ -299,7 +301,7 @@ InfoBoxLine::split(const std::string& text, int line_length)
   return lines;
 }
 
-void 
+void
 InfoBoxLine::draw(DrawingContext& context, const Vector& position, int layer)
 {
   switch (lineType) {
@@ -309,7 +311,7 @@ InfoBoxLine::draw(DrawingContext& context, const Vector& position, int layer)
     case NORMAL_LEFT:
       context.draw_text(font, text, Vector(position.x, position.y), LEFT_ALLIGN, layer);
       break;
-    default: 
+    default:
       context.draw_text(font, text, Vector(SCREEN_WIDTH/2, position.y), CENTER_ALLIGN, layer);
       break;
   }
@@ -323,8 +325,7 @@ InfoBoxLine::get_height()
       return image->get_height() + ITEMS_SPACE;
     case NORMAL_LEFT:
       return font->get_height() + ITEMS_SPACE;
-    default: 
+    default:
       return font->get_height() + ITEMS_SPACE;
   }
 }
-
index b9c534c..ad7f397 100644 (file)
@@ -41,7 +41,7 @@ private:
   LineType lineType;
   Font* font;
   std::string text;
-  Surface* image; 
+  Surface* image;
 
 public:
   InfoBoxLine(char format_char, const std::string& text);
@@ -66,7 +66,7 @@ public:
   void scrollup();
   void pagedown();
   void pageup();
-  
+
 private:
   size_t firstline;
   std::vector<InfoBoxLine*> lines;
@@ -96,4 +96,3 @@ private:
 };
 
 #endif
-
index c402cf4..fa0b834 100644 (file)
@@ -59,7 +59,7 @@ Tile::parse(const lisp::Lisp& reader)
   if(!reader.get("id", id)) {
     throw std::runtime_error("Missing tile-id.");
   }
-  
+
   bool value = false;
   if(reader.get("solid", value) && value)
     attributes |= SOLID;
@@ -86,10 +86,10 @@ Tile::parse(const lisp::Lisp& reader)
     data |= WORLDMAP_SOUTH;
   if(reader.get("west", value) && value)
     data |= WORLDMAP_WEST;
-  if(reader.get("east", value) && value) 
+  if(reader.get("east", value) && value)
     data |= WORLDMAP_EAST;
   if(reader.get("stop", value) && value)
-    data |= WORLDMAP_STOP;                      
+    data |= WORLDMAP_STOP;
 
   reader.get("data", data);
   reader.get("anim-fps", anim_fps);
@@ -97,7 +97,7 @@ Tile::parse(const lisp::Lisp& reader)
   if(reader.get("slope-type", data)) {
     attributes |= SOLID | SLOPE;
   }
-  
+
   const lisp::Lisp* images = reader.get_lisp("images");
   if(images)
     parse_images(*images);
@@ -113,7 +113,7 @@ Tile::parse_images(const lisp::Lisp& images_lisp)
       std::string file;
       cur->get(file);
       imagespecs.push_back(ImageSpec(file, Rect(0, 0, 0, 0)));
-    } else if(cur->get_type() == lisp::Lisp::TYPE_CONS && 
+    } else if(cur->get_type() == lisp::Lisp::TYPE_CONS &&
         cur->get_car()->get_type() == lisp::Lisp::TYPE_SYMBOL) {
       const lisp::Lisp* ptr = cur->get_cdr();
 
@@ -129,7 +129,7 @@ Tile::parse_images(const lisp::Lisp& images_lisp)
       log_warning << "Expected string or list in images tag" << std::endl;
       continue;
     }
-    
+
     list = list->get_cdr();
   }
 }
@@ -166,4 +166,3 @@ Tile::draw(DrawingContext& context, const Vector& pos, int z_pos) const
     context.draw_surface(images[0], pos, z_pos);
   }
 }
-
index d7e3d23..c03154f 100644 (file)
@@ -38,7 +38,7 @@ class Tile
 public:
   /// bitset for tile attributes
   enum {
-    /** solid tile that is indestructable by Tux */                         
+    /** solid tile that is indestructable by Tux */
     SOLID     = 0x0001,
     /** uni-directional solid tile */
     UNISOLID  = 0x0002,
@@ -58,10 +58,10 @@ public:
 
     /* interesting flags (the following are passed to gameobjects) */
     FIRST_INTERESTING_FLAG = 0x0100,
-    
+
     /** an ice brick that makes tux sliding more than usual */
     ICE       = 0x0100,
-    /** a water tile in which tux starts to swim */                         
+    /** a water tile in which tux starts to swim */
     WATER     = 0x0200,
     /** a tile that hurts the player if he touches it */
     HURTS     = 0x0400,
@@ -83,7 +83,7 @@ public:
     WORLDMAP_CSEW  = WORLDMAP_SOUTH | WORLDMAP_EAST  | WORLDMAP_WEST,
     WORLDMAP_CNSEW = WORLDMAP_NORTH | WORLDMAP_SOUTH | WORLDMAP_EAST | WORLDMAP_WEST
   };
-  
+
   struct ImageSpec {
     ImageSpec(const std::string& newfile, const Rect& newrect)
       : file(newfile), rect(newrect)
@@ -101,15 +101,15 @@ private:
 
   /// tile attributes
   uint32_t attributes;
-  
+
   /** General purpose data attached to a tile (content of a box, type of coin)*/
   int data;
-  
+
   float anim_fps;
 
 public:
   ~Tile();
-  
+
   /** Draw a tile on the screen */
   void draw(DrawingContext& context, const Vector& pos, int z_pos) const;
 
@@ -124,7 +124,7 @@ public:
 
   /// returns the width of the tile in pixels
   int getWidth() const
-  { 
+  {
     if(!images.size())
       return 0;
     return (int) images[0]->get_width();
index 309311e..bbc3cff 100644 (file)
@@ -67,7 +67,7 @@ void TileManager::load_tileset(std::string filename)
   } else {
     tiles_path = filename.substr(0, t+1);
   }
+
   lisp::Parser parser;
   std::auto_ptr<lisp::Lisp> root (parser.parse(filename));
 
@@ -101,7 +101,7 @@ void TileManager::load_tileset(std::string filename)
       std::string image;
 
       // width and height of the image in tile units, this is used for two
-      // purposes: 
+      // purposes:
       //  a) so we don't have to load the image here to know its dimensions
       //  b) so that the resulting 'tiles' entry is more robust,
       //  ie. enlarging the image won't break the tile id mapping
@@ -137,7 +137,7 @@ void TileManager::load_tileset(std::string filename)
               tiles[ids[i]] = tile;
             }
         }
-      
+
     } else if(iter.item() == "properties") {
       // deprecated
     } else {
@@ -145,4 +145,3 @@ void TileManager::load_tileset(std::string filename)
     }
   }
 }
-
index 319b819..64906cf 100644 (file)
@@ -53,7 +53,7 @@ private:
   std::set<TileGroup> tilegroups;
 
   std::string tiles_path;
-  
+
   void load_tileset(std::string filename);
 
 public:
@@ -77,7 +77,7 @@ public:
 
     if(tile->images.size() == 0 && tile->imagespecs.size() != 0)
       tile->load_images(tiles_path);
-    
+
     return tile;
   }
 
index 105ce75..9c94f58 100644 (file)
@@ -47,7 +47,7 @@ Timer::check()
 {
   if(period == 0)
     return false;
-  
+
   if(game_time - cycle_start >= period) {
     if(cyclic) {
       cycle_start = game_time - fmodf(game_time - cycle_start, period);
@@ -59,4 +59,3 @@ Timer::check()
 
   return false;
 }
-
index 903ffa8..8dd9400 100644 (file)
@@ -62,4 +62,3 @@ private:
 };
 
 #endif
-
index 04d1fb4..e7deb55 100644 (file)
@@ -1,6 +1,6 @@
 /*
  findlocale-0.46.tar.gz from http://icculus.org/~aspirin/findlocale/
+
 Copyright (C) 2004 Adam D. Moss (the "Author").  All Rights Reserved.
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
index d51f627..a9bb964 100644 (file)
@@ -45,7 +45,7 @@ std::string convert(const std::string& text,
     return text;
 
   iconv_t cd = iconv_open(to_charset.c_str(), from_charset.c_str());
-  
+
   size_t in_len = text.length();
   size_t out_len = text.length()*3; // FIXME: cross fingers that this is enough
 
@@ -174,7 +174,7 @@ get_language_def(const std::string& name)
   else if (name == "sk") return lang_sk;
   else if (name == "pl") return lang_pl;
   else if (name == "sl") return lang_sl;
-  else return lang_en; 
+  else return lang_en;
 }
 
 DictionaryManager::DictionaryManager()
@@ -186,7 +186,7 @@ DictionaryManager::DictionaryManager()
   if( lang ){
     set_language( lang );
     return;
-  }  
+  }
   // use findlocale to setup language
   FL_Locale *locale;
   FL_FindLocale( &locale, FL_MESSAGES );
@@ -200,18 +200,18 @@ DictionaryManager::parseLocaleAliases()
 {
   // try to parse language alias list
   std::ifstream in("/usr/share/locale/locale.alias");
-  
+
   char c = ' ';
   while(in.good() && !in.eof()) {
     while(isspace(c) && !in.eof())
       in.get(c);
-    
+
     if(c == '#') { // skip comments
       while(c != '\n' && !in.eof())
         in.get(c);
       continue;
     }
-    
+
     std::string alias;
     while(!isspace(c) && !in.eof()) {
       alias += c;
@@ -230,7 +230,7 @@ DictionaryManager::parseLocaleAliases()
     set_language_alias(alias, language);
   }
 }
-  
+
 Dictionary&
 DictionaryManager::get_dictionary(const std::string& spec)
 {
@@ -252,7 +252,7 @@ DictionaryManager::get_dictionary(const std::string& spec)
       for (SearchPath::iterator p = search_path.begin(); p != search_path.end(); ++p)
         {
           char** files = PHYSFS_enumerateFiles(p->c_str());
-          if(!files) 
+          if(!files)
             {
               log_warning << "Error: enumerateFiles() failed on " << *p << std::endl;
             }
@@ -301,7 +301,7 @@ DictionaryManager::get_languages()
           }
           PHYSFS_freeList(files);
         }
-    }  
+    }
   return languages;
 }
 
@@ -341,12 +341,12 @@ DictionaryManager::get_language_from_spec(const std::string& spec)
   if(i != language_aliases.end()) {
     lang = i->second;
   }
-  
+
   std::string::size_type s = lang.find_first_of("_.");
   if(s == std::string::npos)
     return lang;
 
-  return std::string(lang, 0, s);  
+  return std::string(lang, 0, s);
 }
 
 void
@@ -388,7 +388,7 @@ Dictionary::set_language(const LanguageDef& lang)
 }
 
 std::string
-Dictionary::translate(const std::string& msgid, const std::string& msgid2, int num) 
+Dictionary::translate(const std::string& msgid, const std::string& msgid2, int num)
 {
   PluralEntries::iterator i = plural_entries.find(msgid);
   std::map<int, std::string>& msgstrs = i->second;
@@ -441,7 +441,7 @@ Dictionary::translate(const char* msgid)
 }
 
 std::string
-Dictionary::translate(const std::string& msgid) 
+Dictionary::translate(const std::string& msgid)
 {
   Entries::iterator i = entries.find(msgid);
   if (i != entries.end() && !i->second.empty())
@@ -456,7 +456,7 @@ Dictionary::translate(const std::string& msgid)
       return msgid;
     }
 }
-  
+
 void
 Dictionary::add_translation(const std::string& msgid, const std::string& ,
                             const std::map<int, std::string>& msgstrs)
@@ -466,8 +466,8 @@ Dictionary::add_translation(const std::string& msgid, const std::string& ,
   plural_entries[msgid] = msgstrs;
 }
 
-void 
-Dictionary::add_translation(const std::string& msgid, const std::string& msgstr) 
+void
+Dictionary::add_translation(const std::string& msgid, const std::string& msgstr)
 {
   entries[msgid] = msgstr;
 }
@@ -515,7 +515,7 @@ public:
     // Seperate the header in lines
     typedef std::vector<std::string> Lines;
     Lines lines;
-    
+
     std::string::size_type start = 0;
     for(std::string::size_type i = 0; i < header.length(); ++i)
       {
@@ -549,10 +549,10 @@ public:
 
   void add_token(const Token& token)
   {
-    switch(state) 
+    switch(state)
       {
       case WANT_MSGID:
-        if (token.keyword == "msgid") 
+        if (token.keyword == "msgid")
           {
             current_msgid = token.content;
             state = WANT_MSGID_PLURAL;
@@ -566,13 +566,13 @@ public:
             log_warning << "tinygettext: expected 'msgid' keyword, got " << token.keyword << " at line " << line_num << std::endl;
           }
         break;
-    
+
       case WANT_MSGID_PLURAL:
-        if (token.keyword == "msgid_plural") 
+        if (token.keyword == "msgid_plural")
           {
             current_msgid_plural = token.content;
             state = WANT_MSGSTR_PLURAL;
-          } 
+          }
         else
           {
             state = WANT_MSGSTR;
@@ -581,9 +581,9 @@ public:
         break;
 
       case WANT_MSGSTR:
-        if (token.keyword == "msgstr") 
+        if (token.keyword == "msgstr")
           {
-            if (current_msgid == "") 
+            if (current_msgid == "")
               { // .po Header is hidden in the msgid with the empty string
                 parse_header(token.content);
               }
@@ -592,7 +592,7 @@ public:
                 dict.add_translation(current_msgid, convert(token.content, from_charset, to_charset));
               }
             state = WANT_MSGID;
-          } 
+          }
         else
           {
             log_warning << "tinygettext: expected 'msgstr' keyword, got " << token.keyword << " at line " << line_num << std::endl;
@@ -600,19 +600,19 @@ public:
         break;
 
       case WANT_MSGSTR_PLURAL:
-        if (has_prefix(token.keyword, "msgstr[")) 
+        if (has_prefix(token.keyword, "msgstr["))
           {
             int num;
-            if (sscanf(token.keyword.c_str(), "msgstr[%d]", &num) != 1) 
+            if (sscanf(token.keyword.c_str(), "msgstr[%d]", &num) != 1)
               {
                 log_warning << "Error: Couldn't parse: " << token.keyword << std::endl;
-              } 
-            else 
+              }
+            else
               {
                 msgstr_plural[num] = convert(token.content, from_charset, to_charset);
               }
           }
-        else 
+        else
           {
             dict.add_translation(current_msgid, current_msgid_plural, msgstr_plural);
 
@@ -622,18 +622,18 @@ public:
         break;
       }
   }
-  
-  inline int getchar(std::istream& in) 
+
+  inline int getchar(std::istream& in)
   {
     int c = in.get();
     if (c == '\n')
       line_num += 1;
     return c;
   }
-  
+
   void tokenize_po(std::istream& in)
   {
-    enum State { READ_KEYWORD, 
+    enum State { READ_KEYWORD,
                  READ_CONTENT,
                  READ_CONTENT_IN_STRING,
                  SKIP_COMMENT };
@@ -656,8 +656,8 @@ public:
               {
                 // Read a new token
                 token = Token();
-                
-                do { // Read keyword 
+
+                do { // Read keyword
                   token.keyword += c;
                 } while((c = getchar(in)) != EOF && !isspace(c));
                 in.unget();
@@ -669,7 +669,7 @@ public:
           case READ_CONTENT:
             while((c = getchar(in)) != EOF)
               {
-                if (c == '"') { 
+                if (c == '"') {
                   // Found start of content
                   state = READ_CONTENT_IN_STRING;
                   break;
@@ -719,7 +719,7 @@ public:
   }
 };
 
-void read_po_file(Dictionary& dict_, std::istream& in) 
+void read_po_file(Dictionary& dict_, std::istream& in)
 {
   POFileReader reader(in, dict_);
 }
index ca731b9..fe0dff0 100644 (file)
@@ -81,7 +81,7 @@ public:
   std::string translate(const std::string& msgid);
   /** Translate the string \a msgid. */
   const char* translate(const char* msgid);
-    
+
   /** Add a translation from \a msgid to \a msgstr to the dictionary,
       where \a msgid is the singular form of the message, msgid2 the
       plural form and msgstrs a table of translations. The right
@@ -137,7 +137,7 @@ public:
 
   /** Add a directory to the search path for dictionaries */
   void add_directory(const std::string& pathname);
-  
+
   /** Return a set of the available languages in their country code */
   std::set<std::string> get_languages();
 
index 395836a..4b4d62a 100644 (file)
@@ -102,7 +102,7 @@ void
 TitleScreen::generate_contrib_menu()
 {
   /** Generating contrib levels list by making use of Level Subset  */
-  std::vector<std::string> level_worlds; 
+  std::vector<std::string> level_worlds;
   char** files = PHYSFS_enumerateFiles("levels/");
   for(const char* const* filename = files; *filename != 0; ++filename) {
     std::string filepath = std::string("levels/") + *filename;
@@ -116,7 +116,7 @@ TitleScreen::generate_contrib_menu()
 
   contrib_menu->add_label(_("Contrib Levels"));
   contrib_menu->add_hl();
-  
+
   int i = 0;
   for (std::vector<std::string>::iterator it = level_worlds.begin();
       it != level_worlds.end(); ++it) {
@@ -203,7 +203,7 @@ TitleScreen::check_contrib_world_menu()
         new GameSession(current_world->get_level_filename(index));
       main_loop->push_screen(session);
     }
-  }  
+  }
 }
 
 void
@@ -223,17 +223,17 @@ TitleScreen::make_tux_jump()
   controller->press(Controller::RIGHT);
 
   // Determine how far we moved since last frame
-  float dx = fabsf(last_tux_x_pos - tux->get_pos().x); 
-  float dy = fabsf(last_tux_y_pos - tux->get_pos().y); 
-  // Calculate space to check for obstacles 
+  float dx = fabsf(last_tux_x_pos - tux->get_pos().x);
+  float dy = fabsf(last_tux_y_pos - tux->get_pos().y);
+
+  // Calculate space to check for obstacles
   Rect lookahead = tux->get_bbox();
   lookahead.move(Vector(96, 0));
-  
+
   // Check if we should press the jump button
   bool randomJump = !randomWaitTimer.started();
   bool notMoving = (fabsf(dx) + fabsf(dy)) < 0.1;
-  bool pathBlocked = !sector->is_free_space(lookahead); 
+  bool pathBlocked = !sector->is_free_space(lookahead);
   if (!controller->released(Controller::JUMP)
       && (notMoving || pathBlocked || randomJump)) {
     float jumpDuration;
@@ -308,7 +308,7 @@ TitleScreen::draw(DrawingContext& context)
 {
   Sector* sector  = titlesession->get_current_sector();
   sector->draw(context);
+
   context.draw_text(white_small_text, " SuperTux " PACKAGE_VERSION "\n",
       Vector(0, SCREEN_HEIGHT - 50), LEFT_ALLIGN, LAYER_FOREGROUND1);
   context.draw_text(white_small_text,
@@ -329,11 +329,11 @@ TitleScreen::update(float elapsed_time)
   sector->update(elapsed_time);
 
   make_tux_jump();
-  
+
   Menu* menu = Menu::current();
   if(menu) {
     menu->update();
-         
+
     if(menu == main_menu.get()) {
       switch (main_menu->check()) {
         case MNID_STARTGAME:
@@ -366,7 +366,7 @@ TitleScreen::update(float elapsed_time)
         std::stringstream stream;
         stream << slot;
         std::string str = _("Are you sure you want to delete slot") + stream.str() + "?";
-        
+
         if(confirm_dialog(bkg_title, str.c_str())) {
           str = "save/slot" + stream.str() + ".stsg";
           log_debug << "Removing: " << str << std::endl;
@@ -451,4 +451,3 @@ TitleScreen::process_load_game_menu()
 
   return true;
 }
-
index 746bce7..39d0abf 100644 (file)
@@ -61,10 +61,9 @@ private:
   std::auto_ptr<World> main_world;
   std::vector<World*> contrib_worlds;
   World* current_world;
-  
+
   std::auto_ptr<CodeController> controller;
   std::auto_ptr<GameSession> titlesession;
 };
 
 #endif
-
index bd38c1b..f8d2b72 100644 (file)
@@ -40,7 +40,7 @@ Door::Door(const lisp::Lisp& reader)
 
   sprite = sprite_manager->create("images/objects/door/door.sprite");
   sprite->set_action("closed");
-  bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());  
+  bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
 }
 
 Door::Door(int x, int y, std::string sector, std::string spawnpoint)
@@ -52,7 +52,7 @@ Door::Door(int x, int y, std::string sector, std::string spawnpoint)
 
   sprite = sprite_manager->create("images/objects/door/door.sprite");
   sprite->set_action("closed");
-  bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());  
+  bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
 }
 
 Door::~Door()
@@ -69,7 +69,7 @@ Door::write(lisp::Writer& writer)
   writer.write_float("y", bbox.p1.y);
   writer.write_float("width", bbox.get_width());
   writer.write_float("height", bbox.get_height());
-  
+
   writer.write_string("sector", target_sector);
   writer.write_string("spawnpoint", target_spawnpoint);
   sound_manager->preload("sounds/door.wav");
index 9186129..925edd6 100644 (file)
@@ -37,12 +37,12 @@ public:
   virtual ~Door();
 
   virtual void write(lisp::Writer& writer);
-  
+
   virtual void update(float elapsed_time);
   virtual void draw(DrawingContext& context);
   virtual void event(Player& player, EventType type);
   virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
+
 private:
   enum DoorState {
     CLOSED,
index cc330a2..afac8ae 100644 (file)
@@ -1,93 +1,92 @@
-//  $Id$\r
-//\r
-//  SuperTux\r
-//  Copyright (C) 2006 Matthias Braun <matze@braunis.de>\r
-//\r
-//  This program is free software; you can redistribute it and/or\r
-//  modify it under the terms of the GNU General Public License\r
-//  as published by the Free Software Foundation; either version 2\r
-//  of the License, or (at your option) any later version.\r
-//\r
-//  This program is distributed in the hope that it will be useful,\r
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-//  GNU General Public License for more details.\r
-//\r
-//  You should have received a copy of the GNU General Public License\r
-//  along with this program; if not, write to the Free Software\r
-//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
-\r
-#include <config.h>\r
-\r
-#include <sstream>\r
-#include <stdexcept>\r
-#include <memory>\r
-\r
-#include "scripttrigger.hpp"\r
-#include "game_session.hpp"\r
-#include "lisp/lisp.hpp"\r
-#include "lisp/writer.hpp"\r
-#include "object_factory.hpp"\r
-#include "sector.hpp"\r
-\r
-ScriptTrigger::ScriptTrigger(const lisp::Lisp& reader)\r
-{\r
-  bool must_activate = false;\r
-  \r
-  reader.get("x", bbox.p1.x);\r
-  reader.get("y", bbox.p1.y);\r
-  float w = 0, h = 0;\r
-  reader.get("width", w);\r
-  reader.get("height", h);\r
-  bbox.set_size(w, h);\r
-  reader.get("script", script);\r
-  reader.get("button", must_activate);\r
-  if(script == "") {\r
-    throw std::runtime_error("Need to specify a script for trigger object");\r
-  }\r
-  \r
-  if (must_activate)\r
-    triggerevent = EVENT_ACTIVATE;\r
-  else\r
-    triggerevent = EVENT_TOUCH;\r
-}\r
-\r
-ScriptTrigger::ScriptTrigger(const Vector& pos, const std::string& script)\r
-{\r
-  bbox.set_pos(pos);\r
-  bbox.set_size(32, 32);\r
-  this->script = script;\r
-  triggerevent = EVENT_TOUCH;\r
-}\r
-\r
-ScriptTrigger::~ScriptTrigger()\r
-{\r
-}\r
-\r
-void\r
-ScriptTrigger::write(lisp::Writer& writer)\r
-{\r
-  writer.start_list("scripttrigger");\r
-\r
-  writer.write_float("x", bbox.p1.x);\r
-  writer.write_float("y", bbox.p1.y);\r
-  writer.write_float("width", bbox.get_width());\r
-  writer.write_float("height", bbox.get_height());\r
-  writer.write_string("script", script);\r
-  writer.write_bool("button", (triggerevent == EVENT_ACTIVATE) ? true : false);\r
-\r
-  writer.end_list("scripttrigger");\r
-}\r
-\r
-void\r
-ScriptTrigger::event(Player& , EventType type)\r
-{\r
-  if(type != triggerevent)\r
-    return;\r
-\r
-  std::istringstream stream(script);\r
-  Sector::current()->run_script(stream, "ScriptTrigger");\r
-}\r
-\r
-IMPLEMENT_FACTORY(ScriptTrigger, "scripttrigger");\r
-\r
+//  $Id$
+//
+//  SuperTux
+//  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License
+//  as published by the Free Software Foundation; either version 2
+//  of the License, or (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#include <config.h>
+
+#include <sstream>
+#include <stdexcept>
+#include <memory>
+
+#include "scripttrigger.hpp"
+#include "game_session.hpp"
+#include "lisp/lisp.hpp"
+#include "lisp/writer.hpp"
+#include "object_factory.hpp"
+#include "sector.hpp"
+
+ScriptTrigger::ScriptTrigger(const lisp::Lisp& reader)
+{
+  bool must_activate = false;
+
+  reader.get("x", bbox.p1.x);
+  reader.get("y", bbox.p1.y);
+  float w = 0, h = 0;
+  reader.get("width", w);
+  reader.get("height", h);
+  bbox.set_size(w, h);
+  reader.get("script", script);
+  reader.get("button", must_activate);
+  if(script == "") {
+    throw std::runtime_error("Need to specify a script for trigger object");
+  }
+
+  if (must_activate)
+    triggerevent = EVENT_ACTIVATE;
+  else
+    triggerevent = EVENT_TOUCH;
+}
+
+ScriptTrigger::ScriptTrigger(const Vector& pos, const std::string& script)
+{
+  bbox.set_pos(pos);
+  bbox.set_size(32, 32);
+  this->script = script;
+  triggerevent = EVENT_TOUCH;
+}
+
+ScriptTrigger::~ScriptTrigger()
+{
+}
+
+void
+ScriptTrigger::write(lisp::Writer& writer)
+{
+  writer.start_list("scripttrigger");
+
+  writer.write_float("x", bbox.p1.x);
+  writer.write_float("y", bbox.p1.y);
+  writer.write_float("width", bbox.get_width());
+  writer.write_float("height", bbox.get_height());
+  writer.write_string("script", script);
+  writer.write_bool("button", (triggerevent == EVENT_ACTIVATE) ? true : false);
+
+  writer.end_list("scripttrigger");
+}
+
+void
+ScriptTrigger::event(Player& , EventType type)
+{
+  if(type != triggerevent)
+    return;
+
+  std::istringstream stream(script);
+  Sector::current()->run_script(stream, "ScriptTrigger");
+}
+
+IMPLEMENT_FACTORY(ScriptTrigger, "scripttrigger");
index edf0394..7394734 100644 (file)
@@ -29,10 +29,10 @@ public:
   ScriptTrigger(const lisp::Lisp& reader);
   ScriptTrigger(const Vector& pos, const std::string& script);
   ~ScriptTrigger();
-  
+
   void write(lisp::Writer& writer);
   void event(Player& player, EventType type);
-  
+
 private:
   EventType triggerevent;
   std::string script;
index 993f1f4..da8423f 100644 (file)
@@ -32,15 +32,14 @@ public:
   SecretAreaTrigger(const lisp::Lisp& reader);
   SecretAreaTrigger(const Rect& area);
   ~SecretAreaTrigger();
+
   void write(lisp::Writer& writer);
   void event(Player& player, EventType type);
   void draw(DrawingContext& context);
-  
+
 private:
   Timer message_timer;
   bool message_displayed;
 };
 
 #endif
-
index 46f18c2..5b8c022 100644 (file)
@@ -30,14 +30,13 @@ public:
   SequenceTrigger(const lisp::Lisp& reader);
   SequenceTrigger(const Vector& pos, const std::string& sequence);
   ~SequenceTrigger();
+
   void write(lisp::Writer& writer);
   void event(Player& player, EventType type);
-  
+
 private:
   EventType triggerevent;
   std::string sequence_name;
 };
 
 #endif
-
index e11a5b6..49205fb 100644 (file)
@@ -111,4 +111,3 @@ Switch::event(Player& , EventType type)
 }
 
 IMPLEMENT_FACTORY(Switch, "switch");
-
index d7e6895..8742f80 100644 (file)
@@ -36,7 +36,7 @@ public:
   virtual ~Switch();
 
   virtual void write(lisp::Writer& writer);
-  
+
   virtual void update(float elapsed_time);
   virtual void draw(DrawingContext& context);
   virtual void event(Player& player, EventType type);
@@ -52,7 +52,7 @@ private:
   std::string sprite_name;
   Sprite* sprite;
   std::string script;
-  
+
   SwitchState state;
 
 };
index d60e14e..480cd90 100644 (file)
@@ -61,4 +61,3 @@ TriggerBase::collision(GameObject& other, const CollisionHit& )
 
   return ABORT_MOVE;
 }
-
index f4c4795..887f413 100644 (file)
@@ -35,14 +35,14 @@ public:
   enum EventType {
     EVENT_TOUCH, EVENT_ACTIVATE
   };
-  
+
   TriggerBase();
   ~TriggerBase();
 
   void update(float elapsed_time);
   void draw(DrawingContext& context);
   HitResponse collision(GameObject& other, const CollisionHit& hit);
-  
+
   /**
    * Receive trigger events
    */
@@ -55,4 +55,3 @@ private:
 };
 
 #endif /*SUPERTUX_INTERACTIVE_OBJECT_H*/
-
index dc912f7..1178fab 100644 (file)
@@ -62,4 +62,3 @@ public:
 };
 
 #endif
-
index 1214c20..7bb36e4 100644 (file)
@@ -41,7 +41,7 @@ static inline int next_po2(int val)
   int result = 1;
   while(result < val)
     result *= 2;
-  
+
   return result;
 }
 
@@ -70,19 +70,19 @@ DrawingContext::~DrawingContext()
 }
 
 void
-DrawingContext::draw_surface(const Surface* surface, const Vector& position, 
+DrawingContext::draw_surface(const Surface* surface, const Vector& position,
                              float angle, const Color& color, const Blend& blend,
                              int layer)
 {
   assert(surface != 0);
-  
+
   DrawingRequest request;
 
   request.type = SURFACE;
   request.pos = transform.apply(position);
 
   if(request.pos.x >= SCREEN_WIDTH || request.pos.y >= SCREEN_HEIGHT
-      || request.pos.x + surface->get_width() < 0 
+      || request.pos.x + surface->get_width() < 0
       || request.pos.y + surface->get_height() < 0)
     return;
 
@@ -93,13 +93,13 @@ DrawingContext::draw_surface(const Surface* surface, const Vector& position,
   request.color = color;
   request.blend = blend;
 
-  request.request_data = const_cast<Surface*> (surface);  
+  request.request_data = const_cast<Surface*> (surface);
 
   requests->push_back(request);
 }
 
 void
-DrawingContext::draw_surface(const Surface* surface, const Vector& position, 
+DrawingContext::draw_surface(const Surface* surface, const Vector& position,
     int layer)
 {
   draw_surface(surface, position, 0.0f, Color(1.0f, 1.0f, 1.0f), Blend(), layer);
@@ -118,7 +118,7 @@ DrawingContext::draw_surface_part(const Surface* surface, const Vector& source,
   request.layer = layer;
   request.drawing_effect = transform.drawing_effect;
   request.alpha = transform.alpha;
-  
+
   SurfacePartRequest* surfacepartrequest = new SurfacePartRequest();
   surfacepartrequest->size = size;
   surfacepartrequest->source = source;
@@ -204,7 +204,7 @@ DrawingContext::draw_filled_rect(const Vector& topleft, const Vector& size,
   request.layer = layer;
 
   request.drawing_effect = transform.drawing_effect;
-  request.alpha = transform.alpha;                    
+  request.alpha = transform.alpha;
 
   FillRectRequest* fillrectrequest = new FillRectRequest;
   fillrectrequest->size = size;
@@ -226,7 +226,7 @@ DrawingContext::draw_filled_rect(const Rect& rect, const Color& color,
   request.layer = layer;
 
   request.drawing_effect = transform.drawing_effect;
-  request.alpha = transform.alpha;                    
+  request.alpha = transform.alpha;
 
   FillRectRequest* fillrectrequest = new FillRectRequest;
   fillrectrequest->size = Vector(rect.get_width(), rect.get_height());
@@ -258,7 +258,7 @@ DrawingContext::draw_gradient(DrawingRequest& request)
   GradientRequest* gradientrequest = (GradientRequest*) request.request_data;
   const Color& top = gradientrequest->top;
   const Color& bottom = gradientrequest->bottom;
-  
+
   glDisable(GL_TEXTURE_2D);
   glBegin(GL_QUADS);
   glColor4f(top.red, top.green, top.blue, top.alpha);
@@ -297,7 +297,7 @@ DrawingContext::draw_filled_rect(DrawingRequest& request)
   glDisable(GL_TEXTURE_2D);
   glColor4f(fillrectrequest->color.red, fillrectrequest->color.green,
             fillrectrequest->color.blue, fillrectrequest->color.alpha);
+
   glBegin(GL_QUADS);
   glVertex2f(x, y);
   glVertex2f(x+w, y);
@@ -320,12 +320,12 @@ DrawingContext::do_drawing()
   target_stack.clear();
 
   bool use_lightmap = lightmap_requests.size() != 0;
-  
+
   // PART1: create lightmap
   if(use_lightmap) {
     glViewport(0, screen->h - lightmap_height, lightmap_width, lightmap_height);
     glMatrixMode(GL_PROJECTION);
-    glLoadIdentity();               
+    glLoadIdentity();
     glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
@@ -335,16 +335,16 @@ DrawingContext::do_drawing()
     glClear(GL_COLOR_BUFFER_BIT);
     handle_drawing_requests(lightmap_requests);
     lightmap_requests.clear();
-  
+
     glDisable(GL_BLEND);
     glBindTexture(GL_TEXTURE_2D, lightmap->get_handle());
     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, screen->h - lightmap_height, lightmap_width, lightmap_height);
 
     glViewport(0, 0, screen->w, screen->h);
     glMatrixMode(GL_PROJECTION);
-    glLoadIdentity();               
+    glLoadIdentity();
     glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
-    glMatrixMode(GL_MODELVIEW);    
+    glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
     glEnable(GL_BLEND);
   }
@@ -356,7 +356,7 @@ DrawingContext::do_drawing()
   if(use_lightmap) {
     // multiple the lightmap with the framebuffer
     glBlendFunc(GL_DST_COLOR, GL_ZERO);
-     
+
     glBindTexture(GL_TEXTURE_2D, lightmap->get_handle());
     glBegin(GL_QUADS);
 
@@ -371,7 +371,7 @@ DrawingContext::do_drawing()
 
     glTexCoord2f(0, 0);
     glVertex2f(0, SCREEN_HEIGHT);
-    
+
     glEnd();
 
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -386,7 +386,7 @@ void
 DrawingContext::handle_drawing_requests(DrawingRequests& requests)
 {
   std::stable_sort(requests.begin(), requests.end());
-  
+
   for(DrawingRequests::iterator i = requests.begin();
       i != requests.end(); ++i) {
     switch(i->type) {
@@ -476,4 +476,3 @@ DrawingContext::set_target(Target target)
   else
     requests = &drawing_requests;
 }
-
index a8c7e56..df31225 100644 (file)
@@ -57,7 +57,7 @@ class Blend
 public:
   GLenum sfactor;
   GLenum dfactor;
-  
+
   Blend()
     : sfactor(GL_SRC_ALPHA), dfactor(GL_ONE_MINUS_SRC_ALPHA)
   {}
@@ -78,10 +78,10 @@ public:
   ~DrawingContext();
 
   /// Adds a drawing request for a surface into the request list.
-  void draw_surface(const Surface* surface, const Vector& position, 
+  void draw_surface(const Surface* surface, const Vector& position,
                     int layer);
   /// Adds a drawing request for a surface into the request list.
-  void draw_surface(const Surface* surface, const Vector& position, 
+  void draw_surface(const Surface* surface, const Vector& position,
                     float angle, const Color& color, const Blend& blend,
                     int layer);
   /// Adds a drawing request for part of a surface.
@@ -90,7 +90,7 @@ public:
   /// Draws a text.
   void draw_text(const Font* font, const std::string& text,
                  const Vector& position, FontAlignment alignment, int layer);
-  
+
   /// Draws text on screen center (feed Vector.x with a 0).
   /// This is the same as draw_text() with a SCREEN_WIDTH/2 position and
   /// alignment set to LEFT_ALLIGN
@@ -102,19 +102,19 @@ public:
   void draw_filled_rect(const Vector& topleft, const Vector& size,
                         const Color& color, int layer);
   void draw_filled_rect(const Rect& rect, const Color& color, int layer);
-  
+
   /// Processes all pending drawing requests and flushes the list.
   void do_drawing();
-  
+
   const Vector& get_translation() const
   {  return transform.translation;  }
-  
+
   void set_translation(const Vector& newtranslation)
   {  transform.translation = newtranslation;  }
-  
+
   void push_transform();
   void pop_transform();
-  
+
   /// Apply that effect in the next draws (effects are listed on surface.h).
   void set_drawing_effect(DrawingEffect effect);
   /// return currently applied drawing effect
@@ -130,7 +130,7 @@ public:
   void push_target();
   void pop_target();
   void set_target(Target target);
-  
+
 private:
   class Transform
   {
@@ -138,17 +138,17 @@ private:
     Vector translation;
     DrawingEffect drawing_effect;
     float alpha;
-    
+
     Transform()
       : drawing_effect(NO_EFFECT), alpha(1.0f)
     { }
-    
+
     Vector apply(const Vector& v) const
     {
       return v - translation;
     }
   };
-  
+
   /// the transform stack
   std::vector<Transform> transformstack;
   /// the currently active transform
@@ -156,42 +156,42 @@ private:
 
   std::vector<Blend> blend_stack;
   Blend blend_mode;
-  
+
   enum RequestType
   {
     SURFACE, SURFACE_PART, TEXT, GRADIENT, FILLRECT
   };
-  
+
   struct SurfacePartRequest
   {
     const Surface* surface;
     Vector source, size;
   };
-  
+
   struct TextRequest
   {
     const Font* font;
     std::string text;
     FontAlignment alignment;
   };
-  
+
   struct GradientRequest
   {
     Color top, bottom;
     Vector size;
   };
-  
+
   struct FillRectRequest
   {
     Color color;
     Vector size;
   };
-  
+
   struct DrawingRequest
   {
     RequestType type;
-    Vector pos;                
-    
+    Vector pos;
+
     int layer;
     DrawingEffect drawing_effect;
     float alpha;
@@ -205,7 +205,7 @@ private:
       : angle(0.0f),
         color(1.0f, 1.0f, 1.0f, 1.0f)
     {}
-    
+
     bool operator<(const DrawingRequest& other) const
     {
       return layer < other.layer;
@@ -213,14 +213,14 @@ private:
   };
 
   typedef std::vector<DrawingRequest> DrawingRequests;
-  
+
   void handle_drawing_requests(DrawingRequests& requests);
   void draw_surface_part(DrawingRequest& request);
   void draw_text(DrawingRequest& request);
   void draw_text_center(DrawingRequest& request);
   void draw_gradient(DrawingRequest& request);
   void draw_filled_rect(DrawingRequest& request);
-  
+
   DrawingRequests drawing_requests;
   DrawingRequests lightmap_requests;
 
index 5e844df..c61ee43 100644 (file)
@@ -36,7 +36,7 @@ Font::Font(const std::string& file, const std::string& shadowfile,
 {
   chars = new Surface(file);
   shadow_chars = new Surface(shadowfile);
+
   first_char = 32;
   char_count = ((int) chars->get_height() / h) * 16;
 }
@@ -145,9 +145,9 @@ Font::draw(const std::string& text, const Vector& pos_, FontAlignment alignment,
 
     if(l > sizeof(temp)-1)
       l = sizeof(temp)-1;
-    
+
     temp[text.copy(temp, l - i, i)] = '\0';
-    
+
     // calculate X positions based on the alignment type
     Vector pos = Vector(pos_);
     if(alignment == CENTER_ALLIGN)
@@ -163,7 +163,7 @@ Font::draw(const std::string& text, const Vector& pos_, FontAlignment alignment,
 }
 
 void
-Font::draw_text(const std::string& text, const Vector& pos, 
+Font::draw_text(const std::string& text, const Vector& pos,
                 DrawingEffect drawing_effect, float alpha) const
 {
   if(shadowsize > 0)
@@ -182,7 +182,7 @@ bool has_multibyte_mark(unsigned char c) {
   return ((c & 0300) == 0200);
 }
 
-/** 
+/**
  * gets unicode character at byte position @a p of UTF-8 encoded @a text, then advances @a p to the next character.
  * @throws std::runtime_error if decoding fails.
  * See unicode standard section 3.10 table 3-5 and 3-6 for details.
@@ -197,7 +197,7 @@ uint32_t decode_utf8(const std::string& text, size_t& p)
     // 0xxx.xxxx: 1 byte sequence
     p+=1;
     return c1;
-  } 
+  }
   else if ((c1 & 0340) == 0300) {
     // 110x.xxxx: 2 byte sequence
     if(p+1 >= text.size()) throw std::range_error("Malformed utf-8 sequence");
@@ -243,7 +243,7 @@ Font::draw_chars(Surface* pchars, const std::string& text, const Vector& pos,
     uint32_t c;
     try {
      c = decode_utf8(text, i);
-    } 
+    }
     catch (std::runtime_error) {
      log_debug << "Malformed utf-8 sequence beginning with " << *((uint32_t*)(text.c_str() + i)) << " found " << std::endl;
      c = 0;
@@ -252,7 +252,7 @@ Font::draw_chars(Surface* pchars, const std::string& text, const Vector& pos,
     ssize_t font_index;
 
     // a non-printable character?
-    if(c == '\n') {                                      
+    if(c == '\n') {
       p.x = pos.x;
       p.y += h + 2;
       continue;
@@ -271,11 +271,11 @@ Font::draw_chars(Surface* pchars, const std::string& text, const Vector& pos,
         font_index = 0;
       }
     }
-        
+
     if(font_index < 0 || font_index >= (ssize_t) char_count) {
       log_debug << "Unsupported utf-8 character found" << std::endl;
       font_index = 0;
-    }                   
+    }
 
     int source_x = (font_index % 16) * w;
     int source_y = (font_index / 16) * h;
index c39df1a..fffcc1f 100644 (file)
@@ -38,14 +38,14 @@ public:
   Font(const std::string& file, const std::string& shadowfile,
        int w, int h, int shadowsize = 2);
   ~Font();
-  
+
   /** returns the width of a given text. (Note that I won't add a normal
    * get_width function here, as we might switch to variable width fonts in the
    * future.)
    * Supports breaklines.
    */
   float get_text_width(const std::string& text) const;
-  
+
   /** returns the height of a given text. This function supports breaklines.
    * In case, you are positive that your text doesn't use break lines, you can
    * just use get_height().
@@ -53,7 +53,7 @@ public:
   float get_text_height(const std::string& text) const;
   /// returns the height of the font.
   float get_height() const;
+
   /**
    * returns the given string, truncated (preferrably at whitespace) to be at most max_width pixels long
    */
@@ -63,31 +63,31 @@ public:
    * returns the given string, truncated (preferrably at whitespace) to be at most max_chars characters long
    */
   static std::string wrap_to_chars(const std::string& text, int max_chars, std::string* overflow);
-  
+
   /** Draws the given text to the screen. Also needs the position.
    * Type of alignment, drawing effect and alpha are optional. */
   void draw(const std::string& text, const Vector& pos,
             FontAlignment allignment = LEFT_ALLIGN,
             DrawingEffect drawing_effect = NO_EFFECT,
             float alpha = 1.0f) const;
-  
+
 private:
   friend class DrawingContext;
-  
+
   void draw_text(const std::string& text, const Vector& pos,
                  DrawingEffect drawing_effect = NO_EFFECT,
                  float alpha = 1.0f) const;
-  
+
   void draw_chars(Surface* pchars, const std::string& text,
                   const Vector& position, DrawingEffect drawing_effect,
                   float alpha) const;
-  
+
   Surface* chars;
   Surface* shadow_chars;
   int w;
   int h;
   int shadowsize;
-  
+
   /// the number of the first character that is represented in the font
   uint32_t first_char;
   /// the number of the last character that is represented in the font
index 0ccb630..6c2122f 100644 (file)
@@ -56,11 +56,11 @@ static inline void check_gl_error(const char* message)
       case GL_TABLE_TOO_LARGE:
         msg << "TABLE_TOO_LARGE: table is too large";
         break;
-#endif                        
+#endif
       default:
         msg << "Unknown error (code " << error << ")";
     }
-        
+
     throw std::runtime_error(msg.str());
   }
 #endif
index ef8019c..dccc9bf 100644 (file)
@@ -42,12 +42,12 @@ public:
   {
     return image_height;
   }
-  
+
   float get_uv_right() const
   {
     return image_width / static_cast<float> (get_width());
   }
-  
+
   float get_uv_bottom() const
   {
     return image_height / static_cast<float> (get_height());
@@ -68,7 +68,7 @@ public:
 
 private:
   friend class TextureManager;
-  
+
   ImageTexture(SDL_Surface* surface);
   virtual ~ImageTexture();
 
@@ -76,4 +76,3 @@ private:
 };
 
 #endif
-
index ff89f8c..23ff693 100644 (file)
@@ -116,11 +116,11 @@ static inline void intern_draw(float left, float top, float right, float bottom,
   if(effect & VERTICAL_FLIP) {
     std::swap(uv_top, uv_bottom);
   }
-  
+
   glBegin(GL_QUADS);
   glTexCoord2f(uv_left, uv_top);
   glVertex2f(left, top);
-  
+
   glTexCoord2f(uv_right, uv_top);
   glVertex2f(right, top);
 
@@ -145,10 +145,10 @@ static inline void intern_draw2(float left, float top, float right, float bottom
   if(effect & VERTICAL_FLIP) {
     std::swap(uv_top, uv_bottom);
   }
-  
+
   float center_x = (left + right) / 2;
   float center_y = (top + bottom) / 2;
-  
+
   float sa = sinf(angle/180.0f*M_PI);
   float ca = cosf(angle/180.0f*M_PI);
 
@@ -164,7 +164,7 @@ static inline void intern_draw2(float left, float top, float right, float bottom
   glTexCoord2f(uv_left, uv_top);
   glVertex2f(left*ca - top*sa + center_x,
              left*sa + top*ca + center_y);
-  
+
   glTexCoord2f(uv_right, uv_top);
   glVertex2f(right*ca - top*sa + center_x,
              right*sa + top*ca + center_y);
@@ -177,7 +177,7 @@ static inline void intern_draw2(float left, float top, float right, float bottom
   glVertex2f(left*ca - bottom*sa + center_x,
              left*sa + bottom*ca + center_y);
   glEnd();
-  
+
   // FIXME: find a better way to restore the blend mode
   glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -191,10 +191,10 @@ Surface::draw(float x, float y, float alpha, float angle, const Color& color, co
 
   intern_draw2(x, y,
                x + width, y + height,
-               uv_left, uv_top, uv_right, uv_bottom, 
+               uv_left, uv_top, uv_right, uv_bottom,
                angle,
                color,
-               blend, 
+               blend,
                effect);
 }
 
@@ -216,17 +216,16 @@ Surface::draw_part(float src_x, float src_y, float dst_x, float dst_y,
 {
   float uv_width = uv_right - uv_left;
   float uv_height = uv_bottom - uv_top;
-  
+
   float uv_left = this->uv_left + (uv_width * src_x) / this->width;
   float uv_top = this->uv_top + (uv_height * src_y) / this->height;
   float uv_right = this->uv_left + (uv_width * (src_x + width)) / this->width;
   float uv_bottom = this->uv_top + (uv_height * (src_y + height)) / this->height;
-  
+
   glColor4f(1.0f, 1.0f, 1.0f, alpha);
-  glBindTexture(GL_TEXTURE_2D, texture->get_handle());  
-  
+  glBindTexture(GL_TEXTURE_2D, texture->get_handle());
+
   intern_draw(dst_x, dst_y,
               dst_x + width, dst_y + height,
               uv_left, uv_top, uv_right, uv_bottom, effect);
 }
-
index 0945253..650f931 100644 (file)
@@ -1,5 +1,5 @@
 //  $Id$
-// 
+//
 //  SuperTux
 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
 //
@@ -12,7 +12,7 @@
 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 //  GNU General Public License for more details.
-// 
+//
 //  You should have received a copy of the GNU General Public License
 //  along with this program; if not, write to the Free Software
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -69,7 +69,7 @@ public:
 
   /** flip the surface horizontally */
   void hflip();
-  
+
   const Surface& operator= (const Surface& other);
 
   float get_width() const
index 8e792b8..9c41ddd 100644 (file)
@@ -37,10 +37,10 @@ Texture::Texture(unsigned int w, unsigned int h, GLenum glformat)
 
   this->width = w;
   this->height = h;
-  
+
   assert_gl("before creating texture");
   glGenTextures(1, &handle);
-  
+
   try {
     glBindTexture(GL_TEXTURE_2D, handle);
 
@@ -61,13 +61,13 @@ Texture::Texture(SDL_Surface* image, GLenum glformat)
     throw std::runtime_error("image has no power of 2 size");
   if(format->BitsPerPixel != 24 && format->BitsPerPixel != 32)
     throw std::runtime_error("image has no 24 or 32 bit color depth");
-  
+
   this->width = image->w;
   this->height = image->h;
 
   assert_gl("before creating texture");
   glGenTextures(1, &handle);
-  
+
   try {
     GLenum sdl_format;
     if(format->BytesPerPixel == 3)
@@ -85,7 +85,7 @@ Texture::Texture(SDL_Surface* image, GLenum glformat)
 
     assert_gl("creating texture");
 
-    set_texture_params();    
+    set_texture_params();
   } catch(...) {
     glDeleteTextures(1, &handle);
     throw;
@@ -107,4 +107,3 @@ Texture::set_texture_params()
 
   assert_gl("set texture params");
 }
-
index 0e4dd89..bf87c65 100644 (file)
@@ -40,7 +40,7 @@ public:
   Texture(unsigned int width, unsigned int height, GLenum glformat);
   Texture(SDL_Surface* surface, GLenum glformat);
   virtual ~Texture();
-  
+
   GLuint get_handle() const
   {
     return handle;
@@ -61,4 +61,3 @@ private:
 };
 
 #endif
-
index 1f78be0..d45eb84 100644 (file)
@@ -137,7 +137,7 @@ TextureManager::create_image_texture(const std::string& filename)
     SDL_FreeSurface(convert);
     throw;
   }
-  
+
   SDL_FreeSurface(convert);
   return result;
 }
@@ -183,7 +183,7 @@ TextureManager::save_texture(Texture* texture)
 
   size_t pixelssize = saved_texture.width * saved_texture.height * 4;
   saved_texture.pixels = new char[pixelssize];
-  
+
   glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 saved_texture.pixels);
 
@@ -204,11 +204,11 @@ TextureManager::reload_textures()
   glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
   glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-  
+
   for(std::vector<SavedTexture>::iterator i = saved_textures.begin();
       i != saved_textures.end(); ++i) {
     SavedTexture& saved_texture = *i;
-    
+
     GLuint handle;
     glGenTextures(1, &handle);
     assert_gl("creating texture handle");
@@ -236,4 +236,3 @@ TextureManager::reload_textures()
 
   saved_textures.clear();
 }
-
index 32280f4..ee75655 100644 (file)
@@ -36,7 +36,7 @@ public:
   ~TextureManager();
 
   ImageTexture* get(const std::string& filename);
-  
+
   void register_texture(Texture* texture);
   void remove_texture(Texture* texture);
 
@@ -46,7 +46,7 @@ public:
 private:
   friend class ImageTexture;
   void release(ImageTexture* texture);
-  
+
   typedef std::map<std::string, ImageTexture*> ImageTextures;
   ImageTextures image_textures;
 
@@ -61,7 +61,7 @@ private:
     GLint width;
     GLint height;
     char* pixels;
-    GLint border;                              
+    GLint border;
 
     GLint min_filter;
     GLint mag_filter;
@@ -76,4 +76,3 @@ private:
 extern TextureManager* texture_manager;
 
 #endif
-
index 8b68b08..121718e 100644 (file)
@@ -72,7 +72,7 @@ World::set_savegame_filename(const std::string& filename)
           throw std::runtime_error(msg.str());
       }
   }
+
   if(!PHYSFS_isDirectory(dirname.c_str())) {
       std::ostringstream msg;
       msg << "Savegame path '" << dirname << "' is not a directory";
@@ -84,7 +84,7 @@ void
 World::load(const std::string& filename)
 {
   basedir = FileSystem::dirname(filename);
-  
+
   lisp::Parser parser;
   std::auto_ptr<lisp::Lisp> root (parser.parse(filename));
 
@@ -105,7 +105,7 @@ World::load(const std::string& filename)
 
   // Level info file doesn't define any levels, so read the
   // directory to see what we can find
-      
+
   std::string path = basedir + "/";
   char** files = PHYSFS_enumerateFiles(path.c_str());
   if(!files) {
@@ -127,7 +127,7 @@ World::run()
   using namespace Scripting;
 
   current_ = this;
-  
+
   // create new squirrel table for persisten game state
   HSQUIRRELVM vm = Scripting::global_vm;
 
@@ -139,7 +139,7 @@ World::run()
   sq_pop(vm, 1);
 
   load_state();
-  
+
   std::string filename = basedir + "/world.nut";
   try {
     IFileStream in(filename);
@@ -163,12 +163,12 @@ World::save_state()
 
   writer.start_list("supertux-savegame");
   writer.write_int("version", 1);
-  
+
   using namespace WorldMapNS;
   if(WorldMap::current() != NULL) {
     std::ostringstream title;
     title << WorldMap::current()->get_title();
-    title << " (" << WorldMap::current()->solved_level_count() 
+    title << " (" << WorldMap::current()->solved_level_count()
           << "/" << WorldMap::current()->level_count() << ")";
     writer.write_string("title", title.str());
   }
@@ -178,7 +178,7 @@ World::save_state()
   writer.end_list("tux");
 
   writer.start_list("state");
-  
+
   sq_pushroottable(global_vm);
   sq_pushstring(global_vm, "state", -1);
   if(SQ_SUCCEEDED(sq_get(global_vm, -2))) {
@@ -187,7 +187,7 @@ World::save_state()
   }
   sq_pop(global_vm, 1);
   writer.end_list("state");
-  
+
   writer.end_list("supertux-savegame");
 }
 
@@ -217,18 +217,18 @@ World::load_state()
     const lisp::Lisp* state = lisp->get_lisp("state");
     if(state == NULL)
       throw std::runtime_error("No state section in savegame");
-    
+
     sq_pushroottable(global_vm);
     sq_pushstring(global_vm, "state", -1);
     if(SQ_FAILED(sq_deleteslot(global_vm, -2, SQFalse)))
       sq_pop(global_vm, 1);
-    
+
     sq_pushstring(global_vm, "state", -1);
     sq_newtable(global_vm);
     load_squirrel_table(global_vm, -1, state);
     if(SQ_FAILED(sq_createslot(global_vm, -3)))
       throw std::runtime_error("Couldn't create state table");
-    sq_pop(global_vm, 1); 
+    sq_pop(global_vm, 1);
   } catch(std::exception& e) {
     log_debug << "Couldn't load savegame: " << e.what() << std::endl;
   }
index 71095b8..f59e5cc 100644 (file)
@@ -43,7 +43,7 @@ public:
 
   void save_state();
   void load_state();
-  
+
   const std::string& get_level_filename(unsigned int i) const;
   unsigned int get_num_levels() const;
 
@@ -63,4 +63,3 @@ public:
 };
 
 #endif
-
index fbc6b0b..b6aa12c 100644 (file)
@@ -36,17 +36,17 @@ LevelTile::LevelTile(const std::string& basedir, const lisp::Lisp* lisp)
 {
   lisp->get("x", pos.x);
   lisp->get("y", pos.y);
-  
+
   std::string spritefile = "images/worldmap/common/leveldot.sprite";
   lisp->get("sprite", spritefile);
   sprite.reset(sprite_manager->create(spritefile));
 
   lisp->get("extro-script", extro_script);
   lisp->get("name", name);
-  
+
   if (!PHYSFS_exists((basedir + name).c_str()))
   {
-    log_warning << "level file '" << name 
+    log_warning << "level file '" << name
       << "' does not exist and will not be added to the worldmap" << std::endl;
     return;
   }
index d8a48e9..be081c9 100644 (file)
@@ -40,7 +40,7 @@ public:
 
   virtual void draw(DrawingContext& context);
   virtual void update(float elapsed_time);
-  
+
   Vector pos;
   std::string name;
   std::string title;
@@ -70,4 +70,3 @@ private:
 }
 
 #endif
-
index ea2bd20..a8e5616 100644 (file)
@@ -35,7 +35,7 @@ SpecialTile::SpecialTile(const lisp::Lisp* lisp)
   lisp->get("x", pos.x);
   lisp->get("y", pos.y);
   lisp->get("invisible-tile", invisible);
-  
+
   if(!invisible) {
     std::string spritefile = "";
     lisp->get("sprite", spritefile);
@@ -83,4 +83,3 @@ SpecialTile::update(float )
 }
 
 }
-
index a7948e3..f32b7b0 100644 (file)
@@ -41,7 +41,7 @@ public:
   virtual void update(float elapsed_time);
 
   Vector pos;
-  
+
   /** Sprite to render instead of guessing what image to draw */
   std::auto_ptr<Sprite> sprite;
 
@@ -65,4 +65,3 @@ public:
 }
 
 #endif
-
index b4db66d..4cffd9c 100644 (file)
@@ -32,7 +32,7 @@ SpriteChange::SpriteChange(const lisp::Lisp* lisp)
   lisp->get("x", pos.x);
   lisp->get("y", pos.y);
   lisp->get("change-on-touch", change_on_touch);
-  
+
   std::string spritefile = "";
   lisp->get("sprite", spritefile);
   sprite.reset(sprite_manager->create(spritefile));
index b48787d..4754e27 100644 (file)
@@ -53,10 +53,10 @@ public:
   std::string stay_action;
 
   /**
-   * name of a group in which only one SpriteChange will ever have its stay_action displayed. 
-   * Leave empty if you don't care. 
+   * name of a group in which only one SpriteChange will ever have its stay_action displayed.
+   * Leave empty if you don't care.
    */
-  std::string stay_group; 
+  std::string stay_group;
 
   virtual void draw(DrawingContext& context);
   virtual void update(float elapsed_time);
@@ -84,4 +84,3 @@ private:
 }
 
 #endif
-
index 26dbeca..d1a7ffb 100644 (file)
@@ -31,12 +31,12 @@ Teleporter::Teleporter(const lisp::Lisp* lisp)
 {
   lisp->get("x", pos.x);
   lisp->get("y", pos.y);
-  
+
   std::string spritefile = "";
   if (lisp->get("sprite", spritefile)) {
     sprite.reset(sprite_manager->create(spritefile));
   }
-  
+
   lisp->get("worldmap", worldmap);
   lisp->get("spawnpoint", spawnpoint);
   lisp->get("automatic", automatic);
@@ -55,4 +55,3 @@ Teleporter::update(float )
 }
 
 }
-
index 4b3b555..0e5cff3 100644 (file)
@@ -40,7 +40,7 @@ public:
 
   /** Position (in tiles, not pixels) */
   Vector pos;
-  
+
   /** Sprite to render, or 0 for no sprite */
   std::auto_ptr<Sprite> sprite;
 
@@ -61,4 +61,3 @@ public:
 }
 
 #endif
-
index 7f5c50a..2e89f04 100644 (file)
 namespace WorldMapNS
 {
 
-static const float TUXSPEED = 200; 
+static const float TUXSPEED = 200;
 static const float map_message_TIME = 2.8;
 
 Tux::Tux(WorldMap* worldmap_)
   : worldmap(worldmap_)
 {
   sprite.reset(sprite_manager->create("images/worldmap/common/tux.sprite"));
-  
+
   offset = 0;
   moving = false;
   direction = D_NONE;
@@ -98,7 +98,7 @@ Tux::get_pos()
     case D_NONE:
       break;
     }
-  
+
   return Vector(x, y);
 }
 
@@ -117,11 +117,11 @@ Tux::set_direction(Direction dir)
   input_direction = dir;
 }
 
-void 
-Tux::tryStartWalking() 
+void
+Tux::tryStartWalking()
 {
   if (moving)
-    return;  
+    return;
   if (input_direction == D_NONE)
     return;
 
@@ -143,7 +143,7 @@ Tux::tryStartWalking()
   }
 }
 
-bool 
+bool
 Tux::canWalk(const Tile* tile, Direction dir)
 {
   return ((tile->getData() & Tile::WORLDMAP_NORTH && dir == D_NORTH) ||
@@ -152,7 +152,7 @@ Tux::canWalk(const Tile* tile, Direction dir)
          (tile->getData() & Tile::WORLDMAP_WEST && dir == D_WEST));
 }
 
-void 
+void
 Tux::tryContinueWalking(float elapsed_time)
 {
   if (!moving)
@@ -176,7 +176,7 @@ Tux::tryContinueWalking(float elapsed_time)
   // if this is a special_tile with passive_message, display it
   SpecialTile* special_tile = worldmap->at_special_tile();
   if(special_tile)
-  {  
+  {
     // direction and the apply_action_ are opposites, since they "see"
     // directions in a different way
     if((direction == D_NORTH && special_tile->apply_action_south) ||
@@ -217,8 +217,8 @@ Tux::tryContinueWalking(float elapsed_time)
 
   // if user wants to change direction, try changing, else guess the direction in which to walk next
   const Tile* tile = worldmap->at(tile_pos);
-  if (direction != input_direction) { 
-    if(canWalk(tile, input_direction)) {  
+  if (direction != input_direction) {
+    if(canWalk(tile, input_direction)) {
       direction = input_direction;
       back_direction = reverse_dir(direction);
     }
@@ -248,7 +248,7 @@ Tux::tryContinueWalking(float elapsed_time)
   // Walk automatically to the next tile
   if(direction == D_NONE)
     return;
-  
+
   Vector next_tile;
   if (!worldmap->path_ok(direction, tile_pos, &next_tile)) {
     log_warning << "Tilemap data is buggy" << std::endl;
@@ -286,7 +286,7 @@ Tux::updateInputDirection()
 void
 Tux::update(float elapsed_time)
 {
-  updateInputDirection(); 
+  updateInputDirection();
   if (moving)
     tryContinueWalking(elapsed_time);
   else
index 6519785..67ec76d 100644 (file)
@@ -55,10 +55,10 @@ private:
   void tryStartWalking(); /**< try starting to walk in input_direction */
   void tryContinueWalking(float elapsed_time); /**< try to continue walking in current direction */
 
-public: 
+public:
   Tux(WorldMap* worldmap_);
   ~Tux();
-  
+
   void setup(); /**< called prior to first update */
   void draw(DrawingContext& context);
   void update(float elapsed_time);
@@ -67,11 +67,10 @@ public:
 
   bool is_moving() const { return moving; }
   Vector get_pos();
-  Vector get_tile_pos() const { return tile_pos; } 
-  void  set_tile_pos(Vector p) { tile_pos = p; } 
+  Vector get_tile_pos() const { return tile_pos; }
+  void  set_tile_pos(Vector p) { tile_pos = p; }
 };
 
 }
 
 #endif
-
index b34e881..0d21134 100644 (file)
@@ -132,10 +132,10 @@ WorldMap::WorldMap(const std::string& filename, const std::string& force_spawnpo
   : tux(0), solids(0), force_spawnpoint(force_spawnpoint)
 {
   tile_manager.reset(new TileManager("images/worldmap.strf"));
-  
+
   tux = new Tux(this);
   add_object(tux);
-    
+
   name = "<no title>";
   music = "music/salcon.ogg";
 
@@ -165,7 +165,7 @@ WorldMap::WorldMap(const std::string& filename, const std::string& force_spawnpo
     throw Scripting::SquirrelError(global_vm, "Couldn't get table from stack");
 
   sq_addref(global_vm, &worldmap_table);
-  sq_pop(global_vm, 1);              
+  sq_pop(global_vm, 1);
 }
 
 WorldMap::~WorldMap()
@@ -180,7 +180,7 @@ WorldMap::~WorldMap()
   sq_release(global_vm, &worldmap_table);
 
   sq_collectgarbage(global_vm);
-  
+
   if(current_ == this)
     current_ = NULL;
 
@@ -247,11 +247,11 @@ WorldMap::load(const std::string& filename)
       throw std::runtime_error("file isn't a supertux-level file.");
 
     lisp->get("name", name);
-    
+
     const lisp::Lisp* sector = lisp->get_lisp("sector");
     if(!sector)
       throw std::runtime_error("No sector sepcified in worldmap file.");
-    
+
     lisp::ListIterator iter(sector);
     while(iter.next()) {
       if(iter.item() == "tilemap") {
@@ -290,7 +290,7 @@ WorldMap::load(const std::string& filename)
     if(solids == 0)
       throw std::runtime_error("No solid tilemap specified");
 
-    move_to_spawnpoint("main"); 
+    move_to_spawnpoint("main");
 
   } catch(std::exception& e) {
     std::stringstream msg;
@@ -313,7 +313,7 @@ WorldMap::get_level_title(LevelTile& level)
     const lisp::Lisp* level_lisp = root->get_lisp("supertux-level");
     if(!level_lisp)
       return;
-    
+
     level_lisp->get("name", level.title);
   } catch(std::exception& e) {
     log_warning << "Problem when reading leveltitle: " << e.what() << std::endl;
@@ -425,7 +425,7 @@ WorldMap::finished_level(Level* gamelevel)
     // Try to detect the next direction to which we should walk
     // FIXME: Mostly a hack
     Direction dir = D_NONE;
-  
+
     const Tile* tile = at(tux->get_tile_pos());
 
     // first, test for crossroads
@@ -471,7 +471,7 @@ WorldMap::update(float delta)
     if(menu == worldmap_menu.get()) {
       switch (worldmap_menu->check())
       {
-        case MNID_RETURNWORLDMAP: // Return to game  
+        case MNID_RETURNWORLDMAP: // Return to game
           Menu::set_current(0);
           break;
         case MNID_QUITWORLDMAP: // Quit Worldmap
@@ -524,7 +524,7 @@ WorldMap::update(float delta)
     enter_level = true;
   if(main_controller->pressed(Controller::PAUSE_MENU))
     on_escape_press();
+
   // check for teleporters
   Teleporter* teleporter = at_teleporter(tux->get_tile_pos());
   if (teleporter && (teleporter->automatic || (enter_level && (!tux->is_moving())))) {
@@ -591,7 +591,7 @@ WorldMap::at_special_tile()
       i != special_tiles.end(); ++i) {
     SpecialTile* special_tile = *i;
     if (special_tile->pos == tux->get_tile_pos())
-      return special_tile; 
+      return special_tile;
   }
 
   return NULL;
@@ -626,13 +626,13 @@ WorldMap::draw(DrawingContext& context)
 {
   context.push_transform();
   context.set_translation(camera_offset);
-  
+
   for(GameObjects::iterator i = game_objects.begin();
       i != game_objects.end(); ++i) {
     GameObject* object = *i;
     object->draw(context);
   }
-  
+
   draw_status(context);
   context.pop_transform();
 }
@@ -642,13 +642,13 @@ WorldMap::draw_status(DrawingContext& context)
 {
   context.push_transform();
   context.set_translation(Vector(0, 0));
+
   player_status->draw(context);
 
   if (!tux->is_moving()) {
     for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) {
       LevelTile* level = *i;
-      
+
       if (level->pos == tux->get_tile_pos()) {
         if(level->title == "")
           get_level_title(*level);
@@ -657,7 +657,7 @@ WorldMap::draw_status(DrawingContext& context)
             Vector(SCREEN_WIDTH/2,
               SCREEN_HEIGHT - white_text->get_height() - 30),
             CENTER_ALLIGN, LAYER_FOREGROUND1);
-        
+
         // if level is solved, draw level picture behind stats
         /*
         if (level->solved) {
@@ -670,7 +670,7 @@ WorldMap::draw_status(DrawingContext& context)
           }
         }
         */
-        
+
         level->statistics.draw_worldmap_info(context);
         break;
       }
@@ -679,11 +679,11 @@ WorldMap::draw_status(DrawingContext& context)
     for(SpecialTiles::iterator i = special_tiles.begin();
         i != special_tiles.end(); ++i) {
       SpecialTile* special_tile = *i;
-      
+
       if (special_tile->pos == tux->get_tile_pos()) {
         /* Display an in-map message in the map, if any as been selected */
         if(!special_tile->map_message.empty() && !special_tile->passive_message)
-          context.draw_text(gold_text, special_tile->map_message, 
+          context.draw_text(gold_text, special_tile->map_message,
               Vector(SCREEN_WIDTH/2,
                 SCREEN_HEIGHT - white_text->get_height() - 60),
               CENTER_ALLIGN, LAYER_FOREGROUND1);
@@ -699,10 +699,10 @@ WorldMap::draw_status(DrawingContext& context)
     }
 
   }
-  
+
   /* Display a passive message in the map, if needed */
   if(passive_message_timer.started())
-    context.draw_text(gold_text, passive_message, 
+    context.draw_text(gold_text, passive_message,
             Vector(SCREEN_WIDTH/2, SCREEN_HEIGHT - white_text->get_height() - 60),
             CENTER_ALLIGN, LAYER_FOREGROUND1);
 
@@ -728,7 +728,7 @@ WorldMap::setup()
 
   // register worldmap_table as worldmap in scripting
   using namespace Scripting;
-  
+
   sq_pushroottable(global_vm);
   sq_pushstring(global_vm, "worldmap", -1);
   sq_pushobject(global_vm, worldmap_table);
@@ -797,7 +797,7 @@ static float read_float(HSQUIRRELVM vm, const char* name)
     msg << "Couldn't get float value for '" << name << "' from table";
     throw Scripting::SquirrelError(vm, msg.str());
   }
-  
+
   float result;
   if(SQ_FAILED(sq_getfloat(vm, -1, &result))) {
     std::ostringstream msg;
@@ -817,7 +817,7 @@ static std::string read_string(HSQUIRRELVM vm, const char* name)
     msg << "Couldn't get string value for '" << name << "' from table";
     throw Scripting::SquirrelError(vm, msg.str());
   }
-  
+
   const char* result;
   if(SQ_FAILED(sq_getstring(vm, -1, &result))) {
     std::ostringstream msg;
@@ -836,8 +836,8 @@ static bool read_bool(HSQUIRRELVM vm, const char* name)
     std::ostringstream msg;
     msg << "Couldn't get bool value for '" << name << "' from table";
     throw Scripting::SquirrelError(vm, msg.str());
-  } 
-  
+  }
+
   SQBool result;
   if(SQ_FAILED(sq_getbool(vm, -1, &result))) {
     std::ostringstream msg;
@@ -853,7 +853,7 @@ void
 WorldMap::save_state()
 {
   using namespace Scripting;
-  
+
   HSQUIRRELVM vm = global_vm;
   int oldtop = sq_gettop(vm);
 
@@ -876,7 +876,7 @@ WorldMap::save_state()
       if(SQ_FAILED(sq_get(vm, -2)))
         throw Scripting::SquirrelError(vm, "Couldn't create.get state.worlds");
     }
-    
+
     sq_pushstring(vm, map_filename.c_str(), map_filename.length());
     if(SQ_FAILED(sq_deleteslot(vm, -2, SQFalse)))
       sq_pop(vm, 1);
@@ -888,32 +888,32 @@ WorldMap::save_state()
     // store tux
     sq_pushstring(vm, "tux", -1);
     sq_newtable(vm);
-    
+
     store_float(vm, "x", tux->get_tile_pos().x);
     store_float(vm, "y", tux->get_tile_pos().y);
     store_string(vm, "back", direction_to_string(tux->back_direction));
 
     sq_createslot(vm, -3);
-    
+
     // levels...
     sq_pushstring(vm, "levels", -1);
     sq_newtable(vm);
 
     for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) {
       LevelTile* level = *i;
-      
+
       if (level->solved) {
         sq_pushstring(vm, level->name.c_str(), -1);
         sq_newtable(vm);
 
-        store_bool(vm, "solved", true);            
+        store_bool(vm, "solved", true);
         // TODO write statistics
         // i->statistics.write(writer);
 
         sq_createslot(vm, -3);
       }
     }
-    
+
     sq_createslot(vm, -3);
 
     // push world into worlds table
@@ -929,10 +929,10 @@ void
 WorldMap::load_state()
 {
   using namespace Scripting;
-  
+
   HSQUIRRELVM vm = global_vm;
   int oldtop = sq_gettop(vm);
+
   try {
     // get state table
     sq_pushroottable(vm);
@@ -999,7 +999,7 @@ WorldMap::solved_level_count()
   size_t count = 0;
   for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) {
     LevelTile* level = *i;
-    
+
     if(level->solved)
       count++;
   }
@@ -1040,5 +1040,5 @@ WorldMap::run_script(std::istream& in, const std::string& sourcename)
 
   return vm;
 }
-   
+
 } // namespace WorldMapNS
index ea84705..9263307 100644 (file)
@@ -86,9 +86,9 @@ private:
   typedef std::vector<GameObject*> GameObjects;
   GameObjects game_objects;
   TileMap* solids;
-  
+
   std::auto_ptr<TileManager> tile_manager;
-  
+
 public:
   /** Variables to deal with the passive map messages */
   Timer passive_message_timer;
@@ -112,7 +112,7 @@ private:
 
   HSQOBJECT worldmap_table;
   typedef std::vector<HSQOBJECT> ScriptList;
-  ScriptList scripts;   
+  ScriptList scripts;
 
   std::string force_spawnpoint; /**< if set, spawnpoint will be forced to this value */
 
@@ -168,7 +168,7 @@ public:
   { return name; }
 
   /**
-   * runs a script in the context of the worldmap (and keeps a reference to 
+   * runs a script in the context of the worldmap (and keeps a reference to
    * the script (so the script gets destroyed when the worldmap is destroyed)
    */
   HSQUIRRELVM run_script(std::istream& in, const std::string& sourcename);
@@ -189,7 +189,7 @@ private:
   void draw_status(DrawingContext& context);
   void calculate_total_stats();
 
-  void load(const std::string& filename);  
+  void load(const std::string& filename);
   void on_escape_press();
 
 };
index 821dedb..d7d8d34 100644 (file)
@@ -11,7 +11,7 @@ void
 DocuCreator::create_docu(Namespace* ns)
 {
     std::string fromfile = original_file != "" ? original_file : inputfile;
-    
+
     writer.openTag("documentation");
     writer.openTag("namespace");
     writer.writeAttribute("name", ns->name);
@@ -42,7 +42,7 @@ DocuCreator::create_class_docu(Class* _class)
         writer.writeTag("documentation");
         writer.write(_class->docu_comment);
     }
-    
+
     for(std::vector<ClassMember*>::iterator i = _class->members.begin();
             i != _class->members.end(); ++i) {
         ClassMember* member = *i;
@@ -63,7 +63,7 @@ void
 DocuCreator::create_function_docu(Class* _class, Function* function)
 {
     writer.openTag("function");
-    
+
     writer.writeAttribute("return_type",
             get_type(function->return_type));
     writer.writeAttribute("name", function->name);
@@ -72,10 +72,10 @@ DocuCreator::create_function_docu(Class* _class, Function* function)
         writer.writeTag("documentation");
         writer.write(function->docu_comment);
     }
-  
+
     for(std::vector<Parameter>::iterator p = function->parameters.begin();
             p != function->parameters.end(); ++p) {
-        if(p == function->parameters.begin() 
+        if(p == function->parameters.begin()
                 && p->type.atomic_type == HSQUIRRELVMType::instance())
             continue;
 
@@ -104,10 +104,9 @@ DocuCreator::get_type(const Type& type)
         return "bool";
     } else if(type.atomic_type == StringType::instance()) {
         return "string";
-    } 
-    
+    }
+
     std::ostringstream msg;
     msg << "Type '" << type.atomic_type->name << "' not supported yet.";
     throw std::runtime_error(msg.str());
 }
-
index fafe124..64318fd 100644 (file)
@@ -40,7 +40,7 @@ WrapperCreator::create_wrapper(Namespace* ns)
     for(std::vector<AtomicType*>::iterator i = ns->types.begin();
             i != ns->types.end(); ++i) {
         AtomicType* type = *i;
-        Class* _class = dynamic_cast<Class*> (type);                 
+        Class* _class = dynamic_cast<Class*> (type);
         if(_class == 0)
             continue;
 
@@ -53,7 +53,7 @@ WrapperCreator::create_wrapper(Namespace* ns)
            << "\n"
            << "#endif\n"
            << "\n";
-    
+
     // cpp header
     out << "/**\n"
         << " * WARNING: This file is automatically generated from:\n"
@@ -92,13 +92,13 @@ WrapperCreator::create_wrapper(Namespace* ns)
     out << "\n";
 
     for(std::vector<AtomicType*>::iterator i = ns->types.begin();
-            i != ns->types.end(); ++i) {                             
+            i != ns->types.end(); ++i) {
         AtomicType* type = *i;
         Class* _class = dynamic_cast<Class*> (type);
         if(_class != 0)
             create_squirrel_instance(_class);
     }
-    
+
     out << "void register_" << modulename << "_wrapper(HSQUIRRELVM v)\n"
         << "{\n"
         << ind << "using namespace Wrapper;\n"
@@ -119,13 +119,13 @@ WrapperCreator::create_register_function_code(Function* function, Class* _class)
 {
     if(function->type == Function::DESTRUCTOR)
         return;
-    
+
     out << ind << "sq_pushstring(v, \"" << function->name << "\", -1);\n";
-    out << ind << "sq_newclosure(v, &" 
-        << (_class != 0 ? _class->name + "_" : "") << function->name 
+    out << ind << "sq_newclosure(v, &"
+        << (_class != 0 ? _class->name + "_" : "") << function->name
         << "_wrapper, 0);\n";
     create_register_slot_code("function", function->name);
-    out << "\n";                                                              
+    out << "\n";
 }
 
 void
@@ -144,7 +144,7 @@ WrapperCreator::create_register_classes_code(Namespace* ns)
     for(std::vector<AtomicType*>::iterator i = ns->types.begin();
             i != ns->types.end(); ++i) {
         AtomicType* type = *i;
-        Class* _class = dynamic_cast<Class*> (type);                 
+        Class* _class = dynamic_cast<Class*> (type);
         if(_class == 0)
             continue;
         if(_class->super_classes.size() > 0)
@@ -158,9 +158,9 @@ void
 WrapperCreator::create_register_class_code(Class* _class)
 {
     out << ind << "// Register class " << _class->name << "\n";
-    out << ind << "sq_pushstring(v, \"" 
-        << _class->name << "\", -1);\n";    
-    
+    out << ind << "sq_pushstring(v, \""
+        << _class->name << "\", -1);\n";
+
     if(_class->super_classes.size() > 0) {
         if(_class->super_classes.size() > 1) {
             std::ostringstream msg;
@@ -168,7 +168,7 @@ WrapperCreator::create_register_class_code(Class* _class)
                 << _class->name << "')";
             throw std::runtime_error(msg.str());
         }
-        
+
         out << ind << "sq_pushstring(v, \""
             << _class->super_classes[0]->name << "\", -1);\n";
         out << ind << "sq_get(v, -3);\n";
@@ -177,7 +177,7 @@ WrapperCreator::create_register_class_code(Class* _class)
         << (_class->super_classes.size() > 0 ? "SQTrue" : "SQFalse")
         << ") < 0) {\n";
     out << ind << ind << "std::ostringstream msg;\n";
-    out << ind << ind << "msg << \"Couldn't create new class '" 
+    out << ind << ind << "msg << \"Couldn't create new class '"
         << _class->name << "'\";\n";
     out << ind << ind << "throw SquirrelError(v, msg.str());\n";
     out << ind << "}\n";
@@ -199,7 +199,7 @@ WrapperCreator::create_register_class_code(Class* _class)
 
     create_register_slot_code("class", _class->name);
     out << "\n";
-    
+
     for(std::vector<Class*>::iterator i = _class->sub_classes.begin();
             i != _class->sub_classes.end(); ++i) {
         Class* _class = *i;
@@ -266,12 +266,12 @@ WrapperCreator::create_function_wrapper(Class* _class, Function* function)
     out << function->name << "_wrapper(HSQUIRRELVM vm)\n"
         << "{\n";
     // avoid warning...
-    if(_class == 0 && function->parameters.empty() 
+    if(_class == 0 && function->parameters.empty()
             && function->return_type.is_void()
             && function->type != Function::CONSTRUCTOR) {
         out << ind << "(void) vm;\n";
     }
-    
+
     // retrieve pointer to class instance
     if(_class != 0 && function->type != Function::CONSTRUCTOR) {
         out << ind << "SQUserPointer data;\n";
@@ -303,7 +303,7 @@ WrapperCreator::create_function_wrapper(Class* _class, Function* function)
         out << "\n";
         return;
     }
-    
+
     // declare and retrieve arguments
     int i = 0;
     int arg_offset = 2;
@@ -319,7 +319,7 @@ WrapperCreator::create_function_wrapper(Class* _class, Function* function)
         }
         ++i;
     }
-    
+
     // call function
     out << ind << "\n";
     out << ind << "try {\n";
@@ -365,7 +365,7 @@ WrapperCreator::create_function_wrapper(Class* _class, Function* function)
         out << ind << ind << "sq_throwerror(vm, _SC(\"Couldn't setup instance of '" << _class->name << "' class\"));\n";
         out << ind << ind << "return SQ_ERROR;\n";
         out << ind << "}\n";
-        out << ind << "sq_setreleasehook(vm, 1, " 
+        out << ind << "sq_setreleasehook(vm, 1, "
             << _class->name << "_release_hook);\n";
     }
     out << ind << "\n";
@@ -394,7 +394,7 @@ WrapperCreator::create_function_wrapper(Class* _class, Function* function)
     out << ind << ind << "return SQ_ERROR;\n";
     out << ind << "}\n";
     out << ind << "\n";
-    
+
     out << "}\n";
     out << "\n";
 }
@@ -453,7 +453,7 @@ WrapperCreator::push_to_stack(const Type& type, const std::string& var)
     } else if(type.atomic_type == &BasicType::BOOL) {
         out << "sq_pushbool(vm, " << var << ");\n";
     } else if(type.atomic_type == StringType::instance()) {
-        out << "sq_pushstring(vm, " << var << ".c_str(), " 
+        out << "sq_pushstring(vm, " << var << ".c_str(), "
             << var << ".size());\n";
     } else {
         std::ostringstream msg;
@@ -485,7 +485,7 @@ void
 WrapperCreator::create_squirrel_instance(Class* _class)
 {
     out << "void create_squirrel_instance(HSQUIRRELVM v, "
-        << ns_prefix << _class->name 
+        << ns_prefix << _class->name
         << "* object, bool setup_releasehook)\n"
         << "{\n"
         << ind << "using namespace Wrapper;\n"
@@ -523,12 +523,11 @@ WrapperCreator::create_class_release_hook(Class* _class)
 {
     out << "static SQInteger " << _class->name << "_release_hook(SQUserPointer ptr, SQInteger )\n"
         << "{\n"
-        << ind << ns_prefix << _class->name 
-        << "* _this = reinterpret_cast<" << ns_prefix << _class->name 
+        << ind << ns_prefix << _class->name
+        << "* _this = reinterpret_cast<" << ns_prefix << _class->name
         << "*> (ptr);\n"
         << ind << "delete _this;\n"
         << ind << "return 0;\n"
         << "}\n"
         << "\n";
 }
-
index ec98429..a2e5395 100644 (file)
@@ -22,7 +22,7 @@ public:
 
 private:
     std::string ns_prefix;
-    
+
     void create_register_functions_code(Namespace* ns);
     void create_register_function_code(Function* function, Class* _class);
     void create_register_classes_code(Namespace* ns);
@@ -31,7 +31,7 @@ private:
     void create_register_constants_code(Namespace* ns);
     void create_register_slot_code(const std::string& what,
                                    const std::string& name);
-    
+
     void create_function_list(Namespace* ns);
     void create_const_lists(Namespace* ns);
     void create_class_const_lists(Class* _class);
@@ -44,4 +44,3 @@ private:
 };
 
 #endif
-
index 9f6f65d..13e6a8c 100644 (file)
@@ -27,4 +27,3 @@ extern std::string modulename;
 extern std::string selected_namespace;
 
 #endif
-
index 6461803..46c5fa0 100644 (file)
@@ -85,7 +85,7 @@ int main(int argc, char** argv)
         usage();
         return 1;
     }
-    
+
     try {
         input = new std::ifstream(inputfile.c_str());
         if(!input->good()) {
@@ -100,24 +100,24 @@ int main(int argc, char** argv)
         unit->namespaces.push_back(std_namespace);
         unit->types.push_back(new HSQUIRRELVMType());
         unit->types.push_back(new SQIntegerType());
-       
+
         yyparse();
 
         Namespace* ns = unit;
         if(selected_namespace != "") {
             ns = ns->findNamespace(selected_namespace);
-        }                                                      
+        }
 
         if(outputcpp != "") {
             std::ofstream cppout(outputcpp.c_str());
             if(!cppout.good()) {
-                std::cerr << "Couldn't open file '" 
+                std::cerr << "Couldn't open file '"
                           << outputcpp << "' for writing.\n";
                 return 1;
             }
             std::ofstream hppout(outputhpp.c_str());
             if(!hppout.good()) {
-                std::cerr << "Couldn't open file '" << outputhpp 
+                std::cerr << "Couldn't open file '" << outputhpp
                           << "' for writing.\n";
                 return 1;
             }
@@ -129,7 +129,7 @@ int main(int argc, char** argv)
         if(output_doc != "") {
             std::ofstream dout(output_doc.c_str());
             if(!dout.good()) {
-                std::cerr << "Couldn't open file '" 
+                std::cerr << "Couldn't open file '"
                     << output_doc << "' for writing.\n";
                 return 1;
             }
@@ -143,4 +143,3 @@ int main(int argc, char** argv)
 
     return 0;
 }
-
index 19ed320..2c398c9 100644 (file)
@@ -40,14 +40,14 @@ public:
 
 private:
     BasicType(const std::string& name)
-    { 
+    {
         this->name = name;
-    }                                     
+    }
 };
 
 class Type {
 public:
-    Type() 
+    Type()
         : atomic_type(0), _unsigned(false), _const(false), _static(false),
         pointer(0), ref(0)
     { }
@@ -55,7 +55,7 @@ public:
     void write_c_type(std::ostream& out)
     {
         if(_static)
-            out << "static ";        
+            out << "static ";
         if(_const)
             out << "const ";
         atomic_type->write_c(out);
@@ -97,7 +97,7 @@ public:
         assert(_instance == this);
         _instance = NULL;
     }
-    
+
     static SQIntegerType* instance()
     {
         return _instance;
@@ -153,7 +153,7 @@ public:
     }
 
 private:
-    static StringType* _instance;   
+    static StringType* _instance;
 };
 
 class Parameter {
@@ -182,7 +182,7 @@ public:
       suspend = false;
       custom = false;
     }
-  
+
     enum FuncType {
         FUNCTION,
         CONSTRUCTOR,
@@ -205,7 +205,7 @@ public:
     {
         has_const_value = false;
     }
-    
+
     Type* type;
     std::string docu_comment;
     std::string name;
@@ -225,7 +225,7 @@ public:
                 i != members.end(); ++i)
             delete *i;
     }
-    
+
     std::vector<ClassMember*> members;
     std::vector<Class*> super_classes;
     std::vector<Class*> sub_classes;
@@ -294,7 +294,7 @@ public:
 
         return ret;
     }
-                                                                             
+
     std::vector<Function*> functions;
     std::vector<Field*> fields;
     std::vector<AtomicType*> types;
@@ -309,4 +309,3 @@ public:
 };
 
 #endif
-
index b44635f..459c220 100644 (file)
@@ -45,7 +45,7 @@ void XmlWriter::closeTag(const char* name)
         throw std::runtime_error(msg.str());
     }
     sections.pop_back();
-    
+
     indent--;
     newLine();
     // XXX: We should check for consistency here
@@ -75,4 +75,3 @@ void XmlWriter::closeTag()
     if (closetag != "")
        out << closetag << "\n";
 }
-
index 97e4344..ad243f3 100644 (file)
@@ -26,7 +26,7 @@ class XmlWriter {
 public:
     XmlWriter(std::ostream& out);
     ~XmlWriter();
-   
+
     /** Start a xml tag which contains subtags */
     void openTag(const char* name);
     /** Closes an xml tag with subtags */
@@ -34,7 +34,7 @@ public:
 
     void writeTag(const char* name);
 
-    template <class T> 
+    template <class T>
       void comment(const T& outp)
       {   // This routine writes just about anything as an XML comment.
        newLine();
@@ -67,7 +67,7 @@ public:
 private:
     void newLine();
     void closeTag();
-    
+
     std::ostream& out;
     int indent;
     std::string closetag;
@@ -76,4 +76,3 @@ private:
 };
 
 #endif
-