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