1
0

It's a Squirrel!!

In SquirrelBindings.h use #define USE_SQUIRREL 1 to enable squirrel

git-svn-id: http://mc-server.googlecode.com/svn/trunk@76 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
faketruth 2011-11-08 01:25:01 +00:00
parent 0c3eda9b17
commit 8285a11a26
107 changed files with 23980 additions and 67 deletions

View File

@ -0,0 +1,26 @@
class SquirrelChatLog extends cPlugin__Squirrel
{
constructor()
{
base.constructor();
}
function Initialize()
{
::print("SquirrelChatLog initialize()");
this.SetName("SquirrelChatLog");
local PluginManager = cRoot.Get().GetPluginManager();
PluginManager.AddHook( this, PluginManager.E_PLUGIN_CHAT );
return true;
}
function OnChat( Message, Player )
{
::print(Player.GetName() + ": " + Message);
}
}
Plugin <- SquirrelChatLog();
cRoot.Get().GetPluginManager().AddPlugin( Plugin );

View File

@ -55,6 +55,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\jsoncpp-src-0.5.0\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>

View File

@ -17,10 +17,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WebServer", "WebServer.vcxp
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JsonCpp", "JsonCpp.vcxproj", "{ADBF25B9-7192-4E54-B35E-8EC47CA5EF86}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Converter", "Converter.vcxproj", "{9AB1FB82-2148-40E4-919F-3B184B4593C8}"
ProjectSection(ProjectDependencies) = postProject
{F6F43A78-816D-4C37-A07B-68BED529273A} = {F6F43A78-816D-4C37-A07B-68BED529273A}
EndProjectSection
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "squirrel_3_0_1_stable", "squirrel_3_0_1_stable.vcxproj", "{4571CE2D-9E18-452F-90D6-94AE8E2406F4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -76,12 +73,12 @@ Global
{ADBF25B9-7192-4E54-B35E-8EC47CA5EF86}.Release|Win32.ActiveCfg = Release|Win32
{ADBF25B9-7192-4E54-B35E-8EC47CA5EF86}.Release|Win32.Build.0 = Release|Win32
{ADBF25B9-7192-4E54-B35E-8EC47CA5EF86}.Release|x64.ActiveCfg = Release|Win32
{9AB1FB82-2148-40E4-919F-3B184B4593C8}.Debug|Win32.ActiveCfg = Debug|Win32
{9AB1FB82-2148-40E4-919F-3B184B4593C8}.Debug|Win32.Build.0 = Debug|Win32
{9AB1FB82-2148-40E4-919F-3B184B4593C8}.Debug|x64.ActiveCfg = Debug|Win32
{9AB1FB82-2148-40E4-919F-3B184B4593C8}.Release|Win32.ActiveCfg = Release|Win32
{9AB1FB82-2148-40E4-919F-3B184B4593C8}.Release|Win32.Build.0 = Release|Win32
{9AB1FB82-2148-40E4-919F-3B184B4593C8}.Release|x64.ActiveCfg = Release|Win32
{4571CE2D-9E18-452F-90D6-94AE8E2406F4}.Debug|Win32.ActiveCfg = Debug|Win32
{4571CE2D-9E18-452F-90D6-94AE8E2406F4}.Debug|Win32.Build.0 = Debug|Win32
{4571CE2D-9E18-452F-90D6-94AE8E2406F4}.Debug|x64.ActiveCfg = Debug|Win32
{4571CE2D-9E18-452F-90D6-94AE8E2406F4}.Release|Win32.ActiveCfg = Release|Win32
{4571CE2D-9E18-452F-90D6-94AE8E2406F4}.Release|Win32.Build.0 = Release|Win32
{4571CE2D-9E18-452F-90D6-94AE8E2406F4}.Release|x64.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -78,7 +78,7 @@
<ClCompile>
<AdditionalOptions>/ZI /D_DEBUG %(AdditionalOptions)</AdditionalOptions>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\tolua++-1.0.93\include;..\lua-5.1.4\src;..\zlib-1.2.5;..\mysql-connector\include;..\source\;..\pdcurs34\;..\jsoncpp-src-0.5.0\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\tolua++-1.0.93\include;..\lua-5.1.4\src;..\zlib-1.2.5;..\mysql-connector\include;..\source\;..\pdcurs34\;..\jsoncpp-src-0.5.0\include;..\squirrel_3_0_1_stable\include;..\squirrel_3_0_1_stable;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<ExceptionHandling>Sync</ExceptionHandling>
@ -94,7 +94,7 @@
</ClCompile>
<Link>
<AdditionalOptions>/IGNORE:4078 %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>winmm.lib;ws2_32.lib;Psapi.lib;ZLib.lib;tolua++-1.0.93.lib;lua-5.1.4.lib;WebServer.lib;JsonCpp.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>winmm.lib;ws2_32.lib;Psapi.lib;ZLib.lib;tolua++-1.0.93.lib;lua-5.1.4.lib;WebServer.lib;JsonCpp.lib;squirrel_3_0_1_stable.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../$(ProjectName)_debug.exe</OutputFile>
<AdditionalLibraryDirectories>VLD;./Debug/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
@ -145,10 +145,7 @@
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>false</WholeProgramOptimization>
<AdditionalIncludeDirectories>..\tolua++-1.0.93\include;..\lua-5.1.4\src;..\zlib-1.2.5;..\mysql-connector\include;..\source\;..\pdcurs34\;..\jsoncpp-src-0.5.0\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>Sync</ExceptionHandling>
<AdditionalIncludeDirectories>..\tolua++-1.0.93\include;..\lua-5.1.4\src;..\zlib-1.2.5;..\mysql-connector\include;..\source\;..\pdcurs34\;..\jsoncpp-src-0.5.0\include;..\squirrel_3_0_1_stable\include;..\squirrel_3_0_1_stable;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
@ -161,10 +158,11 @@
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>
</DebugInformationFormat>
<WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<AdditionalOptions>/IGNORE:4078 %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>winmm.lib;ws2_32.lib;Psapi.lib;ZLib.lib;tolua++-1.0.93.lib;lua-5.1.4.lib;WebServer.lib;JsonCpp.lib;libCMT.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>winmm.lib;ws2_32.lib;Psapi.lib;ZLib.lib;tolua++-1.0.93.lib;lua-5.1.4.lib;WebServer.lib;JsonCpp.lib;squirrel_3_0_1_stable.lib;LIBCMT.LIB;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../$(ProjectName).exe</OutputFile>
<AdditionalLibraryDirectories>./Release/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreSpecificDefaultLibraries>LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
@ -350,6 +348,7 @@
<ClCompile Include="..\source\packets\cPacket_WindowClick.cpp" />
<ClCompile Include="..\source\packets\cPacket_WindowClose.cpp" />
<ClCompile Include="..\source\packets\cPacket_WindowOpen.cpp" />
<ClCompile Include="..\source\SquirrelBindings.cpp" />
<ClCompile Include="..\source\Vector3d.cpp" />
<ClCompile Include="..\source\Vector3f.cpp" />
<ClCompile Include="..\source\Vector3i.cpp" />
@ -498,6 +497,7 @@
<ClInclude Include="..\source\packets\cPacket_WindowClick.h" />
<ClInclude Include="..\source\packets\cPacket_WindowClose.h" />
<ClInclude Include="..\source\packets\cPacket_WindowOpen.h" />
<ClInclude Include="..\source\SquirrelBindings.h" />
<ClInclude Include="..\source\Vector3d.h" />
<ClInclude Include="..\source\Vector3f.h" />
<ClInclude Include="..\source\Vector3i.h" />

View File

@ -385,6 +385,9 @@
<Filter Include="cLavaSimulator">
<UniqueIdentifier>{b0401fd9-4021-4ab7-bf61-c8de112b4196}</UniqueIdentifier>
</Filter>
<Filter Include="LuaBindings\SquirrelBindings">
<UniqueIdentifier>{a71ee043-df55-4d42-a9aa-1643b40e1c22}</UniqueIdentifier>
</Filter>
<Filter Include="Packets\cPacket_Explosion">
<UniqueIdentifier>{0a6d025d-4fb8-4557-a348-004b819ea477}</UniqueIdentifier>
</Filter>
@ -781,6 +784,10 @@
<ClCompile Include="..\source\cLavaSimulator.cpp">
<Filter>cLavaSimulator</Filter>
</ClCompile>
<ClCompile Include="..\source\SquirrelBindings.cpp">
<Filter>LuaBindings\SquirrelBindings</Filter>
</ClCompile>
</ItemGroup>
<ClCompile Include="..\source\packets\cPacket_Explosion.cpp">
<Filter>Packets\cPacket_Explosion</Filter>
</ClCompile>
@ -1212,6 +1219,9 @@
<ClInclude Include="..\source\cLavaSimulator.h">
<Filter>cLavaSimulator</Filter>
</ClInclude>
<ClInclude Include="..\source\SquirrelBindings.h">
<Filter>LuaBindings\SquirrelBindings</Filter>
</ClInclude>
<ClInclude Include="..\source\packets\cPacket_Explosion.h">
<Filter>Packets\cPacket_Explosion</Filter>
</ClInclude>

View File

@ -98,6 +98,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>

View File

@ -71,7 +71,6 @@
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Lib />
</ItemDefinitionGroup>
@ -94,7 +93,7 @@
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Lib>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>

View File

@ -69,9 +69,9 @@
<Optimization>Disabled</Optimization>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Lib />
</ItemDefinitionGroup>
@ -95,6 +95,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Lib>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>

View File

@ -98,6 +98,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Lib>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>

View File

@ -10,6 +10,7 @@ World=world_sexy
Plugin=Core
Plugin=Fire
Plugin=MagicCarpet
Squirrel=SquirrelChatLog
[HelpPlugin]
ShowPluginNames=1

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 11/01/11 22:50:07.
** Generated automatically by tolua++-1.0.92 on 11/08/11 02:11:35.
*/
#ifndef __cplusplus
@ -6006,7 +6006,7 @@ static int tolua_AllToLua_cPluginManager_GetPlugin00(lua_State* tolua_S)
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) ||
!tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
!tolua_isstring(tolua_S,2,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,3,&tolua_err)
)
goto tolua_lerror;
@ -6014,7 +6014,7 @@ static int tolua_AllToLua_cPluginManager_GetPlugin00(lua_State* tolua_S)
#endif
{
cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0);
std::string a_Plugin = ((std::string) tolua_tocppstring(tolua_S,2,0));
const char* a_Plugin = ((const char*) tolua_tostring(tolua_S,2,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPlugin'", NULL);
#endif
@ -6545,7 +6545,7 @@ static int tolua_AllToLua_cPlugin_OnChat00(lua_State* tolua_S)
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
!tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
!tolua_isstring(tolua_S,2,0,&tolua_err) ||
!tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,4,&tolua_err)
)
@ -6554,7 +6554,7 @@ static int tolua_AllToLua_cPlugin_OnChat00(lua_State* tolua_S)
#endif
{
cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
std::string a_Chat = ((std::string) tolua_tocppstring(tolua_S,2,0));
const char* a_Chat = ((const char*) tolua_tostring(tolua_S,2,0));
cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnChat'", NULL);
@ -6797,8 +6797,8 @@ static int tolua_AllToLua_cPlugin_GetName00(lua_State* tolua_S)
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetName'", NULL);
#endif
{
std::string tolua_ret = (std::string) self->GetName();
tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
const char* tolua_ret = (const char*) self->GetName();
tolua_pushstring(tolua_S,(const char*)tolua_ret);
}
}
return 1;
@ -6818,7 +6818,7 @@ static int tolua_AllToLua_cPlugin_SetName00(lua_State* tolua_S)
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
!tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
!tolua_isstring(tolua_S,2,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,3,&tolua_err)
)
goto tolua_lerror;
@ -6826,7 +6826,7 @@ static int tolua_AllToLua_cPlugin_SetName00(lua_State* tolua_S)
#endif
{
cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
std::string a_Name = ((std::string) tolua_tocppstring(tolua_S,2,0));
const char* a_Name = ((const char*) tolua_tostring(tolua_S,2,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetName'", NULL);
#endif
@ -7120,9 +7120,9 @@ public:
return ( bool ) cPlugin:: OnBlockDig(a_PacketData,a_Player,a_PickupItem);
};
};
bool OnChat( std::string a_Chat, cPlayer* a_Player) {
bool OnChat( const char* a_Chat, cPlayer* a_Player) {
if (push_method("OnChat", tolua_AllToLua_cPlugin_OnChat00)) {
tolua_pushcppstring(lua_state, (const char*)a_Chat);
tolua_pushstring(lua_state, (const char*)a_Chat);
tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer");
ToluaBase::dbcall(lua_state, 3, 1);
bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
@ -7210,7 +7210,7 @@ public:
bool cPlugin__OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem) {
return ( bool )cPlugin::OnBlockDig(a_PacketData,a_Player,a_PickupItem);
};
bool cPlugin__OnChat( std::string a_Chat, cPlayer* a_Player) {
bool cPlugin__OnChat( const char* a_Chat, cPlayer* a_Player) {
return ( bool )cPlugin::OnChat(a_Chat,a_Player);
};
bool cPlugin__OnLogin( cPacket_Login* a_PacketData) {
@ -7485,7 +7485,7 @@ static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnChat00(lua_State* tolua_S)
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
!tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
!tolua_isstring(tolua_S,2,0,&tolua_err) ||
!tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,4,&tolua_err)
)
@ -7494,7 +7494,7 @@ static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnChat00(lua_State* tolua_S)
#endif
{
Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
std::string a_Chat = ((std::string) tolua_tocppstring(tolua_S,2,0));
const char* a_Chat = ((const char*) tolua_tostring(tolua_S,2,0));
cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnChat'", NULL);
@ -15097,7 +15097,22 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_BLOCK_LEAVES",E_BLOCK_LEAVES);
tolua_constant(tolua_S,"E_BLOCK_SPONGE",E_BLOCK_SPONGE);
tolua_constant(tolua_S,"E_BLOCK_GLASS",E_BLOCK_GLASS);
tolua_constant(tolua_S,"E_BLOCK_LAPIS_ORE",E_BLOCK_LAPIS_ORE);
tolua_constant(tolua_S,"E_BLOCK_LAPIS_BLOCK",E_BLOCK_LAPIS_BLOCK);
tolua_constant(tolua_S,"E_BLOCK_DISPENSER",E_BLOCK_DISPENSER);
tolua_constant(tolua_S,"E_BLOCK_SANDSTONE",E_BLOCK_SANDSTONE);
tolua_constant(tolua_S,"E_BLOCK_NOTE_BLOCK",E_BLOCK_NOTE_BLOCK);
tolua_constant(tolua_S,"E_BLOCK_BED",E_BLOCK_BED);
tolua_constant(tolua_S,"E_BLOCK_POWERED_RAIL",E_BLOCK_POWERED_RAIL);
tolua_constant(tolua_S,"E_BLOCK_DETECTOR_RAIL",E_BLOCK_DETECTOR_RAIL);
tolua_constant(tolua_S,"E_BLOCK_STICKY_PISTON",E_BLOCK_STICKY_PISTON);
tolua_constant(tolua_S,"E_BLOCK_COBWEB",E_BLOCK_COBWEB);
tolua_constant(tolua_S,"E_BLOCK_TALL_GRASS",E_BLOCK_TALL_GRASS);
tolua_constant(tolua_S,"E_BLOCK_DEAD_BUSH",E_BLOCK_DEAD_BUSH);
tolua_constant(tolua_S,"E_BLOCK_PISTON",E_BLOCK_PISTON);
tolua_constant(tolua_S,"E_BLOCK_PISTON_EXTENSION",E_BLOCK_PISTON_EXTENSION);
tolua_constant(tolua_S,"E_BLOCK_WHITE_CLOTH",E_BLOCK_WHITE_CLOTH);
tolua_constant(tolua_S,"E_BLOCK_PISTON_MOVED_BLOCK",E_BLOCK_PISTON_MOVED_BLOCK);
tolua_constant(tolua_S,"E_BLOCK_YELLOW_FLOWER",E_BLOCK_YELLOW_FLOWER);
tolua_constant(tolua_S,"E_BLOCK_RED_ROSE",E_BLOCK_RED_ROSE);
tolua_constant(tolua_S,"E_BLOCK_BROWN_MUSHROOM",E_BLOCK_BROWN_MUSHROOM);
@ -15136,14 +15151,18 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_BLOCK_WOODEN_PRESSURE_PLATE",E_BLOCK_WOODEN_PRESSURE_PLATE);
tolua_constant(tolua_S,"E_BLOCK_REDSTONE_ORE",E_BLOCK_REDSTONE_ORE);
tolua_constant(tolua_S,"E_BLOCK_REDSTONE_ORE_GLOWING",E_BLOCK_REDSTONE_ORE_GLOWING);
tolua_constant(tolua_S,"E_BLOCK_REDSTONE_TORCH_ON",E_BLOCK_REDSTONE_TORCH_ON);
tolua_constant(tolua_S,"E_BLOCK_REDSTONE_TORCH_OFF",E_BLOCK_REDSTONE_TORCH_OFF);
tolua_constant(tolua_S,"E_BLOCK_REDSTONE_TORCH_ON",E_BLOCK_REDSTONE_TORCH_ON);
tolua_constant(tolua_S,"E_BLOCK_STONE_BUTTON",E_BLOCK_STONE_BUTTON);
tolua_constant(tolua_S,"E_BLOCK_SNOW",E_BLOCK_SNOW);
tolua_constant(tolua_S,"E_BLOCK_ICE",E_BLOCK_ICE);
tolua_constant(tolua_S,"E_BLOCK_SNOW_BLOCK",E_BLOCK_SNOW_BLOCK);
tolua_constant(tolua_S,"E_BLOCK_CACTUS",E_BLOCK_CACTUS);
tolua_constant(tolua_S,"E_BLOCK_CLAY",E_BLOCK_CLAY);
tolua_constant(tolua_S,"E_BLOCK_REEDS",E_BLOCK_REEDS);
tolua_constant(tolua_S,"E_BLOCK_JUKEBOX",E_BLOCK_JUKEBOX);
tolua_constant(tolua_S,"E_BLOCK_FENCE",E_BLOCK_FENCE);
tolua_constant(tolua_S,"E_BLOCK_PUMPKIN",E_BLOCK_PUMPKIN);
tolua_constant(tolua_S,"E_BLOCK_BLOODSTONE",E_BLOCK_BLOODSTONE);
tolua_constant(tolua_S,"E_BLOCK_SOULSAND",E_BLOCK_SOULSAND);
tolua_constant(tolua_S,"E_BLOCK_GLOWSTONE",E_BLOCK_GLOWSTONE);
@ -15154,6 +15173,32 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_BLOCK_REDSTONE_REPEATER_ON",E_BLOCK_REDSTONE_REPEATER_ON);
tolua_constant(tolua_S,"E_BLOCK_LOCKED_CHEST",E_BLOCK_LOCKED_CHEST);
tolua_constant(tolua_S,"E_BLOCK_TRAPDOOR",E_BLOCK_TRAPDOOR);
tolua_constant(tolua_S,"E_BLOCK_SILVERFISH_EGG",E_BLOCK_SILVERFISH_EGG);
tolua_constant(tolua_S,"E_BLOCK_STONE_BRICKS",E_BLOCK_STONE_BRICKS);
tolua_constant(tolua_S,"E_BLOCK_HUGE_BROWN_MUSHROOM",E_BLOCK_HUGE_BROWN_MUSHROOM);
tolua_constant(tolua_S,"E_BLOCK_HUGE_RED_MUSHROOM",E_BLOCK_HUGE_RED_MUSHROOM);
tolua_constant(tolua_S,"E_BLOCK_IRON_BAR",E_BLOCK_IRON_BAR);
tolua_constant(tolua_S,"E_BLOCK_GLASS_PLANE",E_BLOCK_GLASS_PLANE);
tolua_constant(tolua_S,"E_BLOCK_MELON",E_BLOCK_MELON);
tolua_constant(tolua_S,"E_BLOCK_PUMPKIN_STEM",E_BLOCK_PUMPKIN_STEM);
tolua_constant(tolua_S,"E_BLOCK_MELON_STEM",E_BLOCK_MELON_STEM);
tolua_constant(tolua_S,"E_BLOCK_VINES",E_BLOCK_VINES);
tolua_constant(tolua_S,"E_BLOCK_FENCE_GATE",E_BLOCK_FENCE_GATE);
tolua_constant(tolua_S,"E_BLOCK_BRICK_STAIRS",E_BLOCK_BRICK_STAIRS);
tolua_constant(tolua_S,"E_BLOCK_STONE_BRICK_STAIRS",E_BLOCK_STONE_BRICK_STAIRS);
tolua_constant(tolua_S,"E_BLOCK_MYCELIUM",E_BLOCK_MYCELIUM);
tolua_constant(tolua_S,"E_BLOCK_LILY_PAD",E_BLOCK_LILY_PAD);
tolua_constant(tolua_S,"E_BLOCK_NETHER_BRICK",E_BLOCK_NETHER_BRICK);
tolua_constant(tolua_S,"E_BLOCK_NETHER_BRICK_FENCE",E_BLOCK_NETHER_BRICK_FENCE);
tolua_constant(tolua_S,"E_BLOCK_NETHER_BRICK_STAIRS",E_BLOCK_NETHER_BRICK_STAIRS);
tolua_constant(tolua_S,"E_BLOCK_NETHER_WART",E_BLOCK_NETHER_WART);
tolua_constant(tolua_S,"E_BLOCK_ENCHANTMENT_TABLE",E_BLOCK_ENCHANTMENT_TABLE);
tolua_constant(tolua_S,"E_BLOCK_BREWING_STAND",E_BLOCK_BREWING_STAND);
tolua_constant(tolua_S,"E_BLOCK_CAULDRON",E_BLOCK_CAULDRON);
tolua_constant(tolua_S,"E_BLOCK_END_PORTAL",E_BLOCK_END_PORTAL);
tolua_constant(tolua_S,"E_BLOCK_END_PORTAL_FRAME",E_BLOCK_END_PORTAL_FRAME);
tolua_constant(tolua_S,"E_BLOCK_END_STONE",E_BLOCK_END_STONE);
tolua_constant(tolua_S,"E_BLOCK_",E_BLOCK_);
tolua_constant(tolua_S,"E_ITEM_EMPTY",E_ITEM_EMPTY);
tolua_constant(tolua_S,"E_ITEM_STONE",E_ITEM_STONE);
tolua_constant(tolua_S,"E_ITEM_GRASS",E_ITEM_GRASS);
@ -15173,9 +15218,104 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_ITEM_COAL_ORE",E_ITEM_COAL_ORE);
tolua_constant(tolua_S,"E_ITEM_LOG",E_ITEM_LOG);
tolua_constant(tolua_S,"E_ITEM_LEAVES",E_ITEM_LEAVES);
tolua_constant(tolua_S,"E_ITEM_SPONGE",E_ITEM_SPONGE);
tolua_constant(tolua_S,"E_ITEM_GLASS",E_ITEM_GLASS);
tolua_constant(tolua_S,"E_ITEM_LAPIS_ORE",E_ITEM_LAPIS_ORE);
tolua_constant(tolua_S,"E_ITEM_LAPIS_BLOCK",E_ITEM_LAPIS_BLOCK);
tolua_constant(tolua_S,"E_ITEM_DISPENSER",E_ITEM_DISPENSER);
tolua_constant(tolua_S,"E_ITEM_SANDSTONE",E_ITEM_SANDSTONE);
tolua_constant(tolua_S,"E_ITEM_NOTE_ITEM",E_ITEM_NOTE_ITEM);
tolua_constant(tolua_S,"E_ITEM_POWERED_RAIL",E_ITEM_POWERED_RAIL);
tolua_constant(tolua_S,"E_ITEM_DETECTOR_RAIL",E_ITEM_DETECTOR_RAIL);
tolua_constant(tolua_S,"E_ITEM_STICKY_PISTON",E_ITEM_STICKY_PISTON);
tolua_constant(tolua_S,"E_ITEM_COBWEB",E_ITEM_COBWEB);
tolua_constant(tolua_S,"E_ITEM_TALL_GRASS",E_ITEM_TALL_GRASS);
tolua_constant(tolua_S,"E_ITEM_DEAD_BRUSH",E_ITEM_DEAD_BRUSH);
tolua_constant(tolua_S,"E_ITEM_PISTON",E_ITEM_PISTON);
tolua_constant(tolua_S,"E_ITEM_PISTON_EXTENSION",E_ITEM_PISTON_EXTENSION);
tolua_constant(tolua_S,"E_ITEM_WHITE_CLOTH",E_ITEM_WHITE_CLOTH);
tolua_constant(tolua_S,"E_ITEM_PISTON_MOVED_BLOCK",E_ITEM_PISTON_MOVED_BLOCK);
tolua_constant(tolua_S,"E_ITEM_YELLOW_FLOWER",E_ITEM_YELLOW_FLOWER);
tolua_constant(tolua_S,"E_ITEM_RED_ROSE",E_ITEM_RED_ROSE);
tolua_constant(tolua_S,"E_ITEM_BROWN_MUSHROOM",E_ITEM_BROWN_MUSHROOM);
tolua_constant(tolua_S,"E_ITEM_RED_MUSHROOM",E_ITEM_RED_MUSHROOM);
tolua_constant(tolua_S,"E_ITEM_GOLD_BLOCK",E_ITEM_GOLD_BLOCK);
tolua_constant(tolua_S,"E_ITEM_IRON_BLOCK",E_ITEM_IRON_BLOCK);
tolua_constant(tolua_S,"E_ITEM_DOUBLE_STEP",E_ITEM_DOUBLE_STEP);
tolua_constant(tolua_S,"E_ITEM_STEP",E_ITEM_STEP);
tolua_constant(tolua_S,"E_ITEM_BRICK",E_ITEM_BRICK);
tolua_constant(tolua_S,"E_ITEM_TNT",E_ITEM_TNT);
tolua_constant(tolua_S,"E_ITEM_BOOKCASE",E_ITEM_BOOKCASE);
tolua_constant(tolua_S,"E_ITEM_MOSSY_COBBLESTONE",E_ITEM_MOSSY_COBBLESTONE);
tolua_constant(tolua_S,"E_ITEM_OBSIDIAN",E_ITEM_OBSIDIAN);
tolua_constant(tolua_S,"E_ITEM_TORCH",E_ITEM_TORCH);
tolua_constant(tolua_S,"E_ITEM_FIRE",E_ITEM_FIRE);
tolua_constant(tolua_S,"E_ITEM_MOB_SPAWNER",E_ITEM_MOB_SPAWNER);
tolua_constant(tolua_S,"E_ITEM_WOODEN_STAIRS",E_ITEM_WOODEN_STAIRS);
tolua_constant(tolua_S,"E_ITEM_CHEST",E_ITEM_CHEST);
tolua_constant(tolua_S,"E_ITEM_REDSTONE_WIRE",E_ITEM_REDSTONE_WIRE);
tolua_constant(tolua_S,"E_ITEM_DIAMOND_ORE",E_ITEM_DIAMOND_ORE);
tolua_constant(tolua_S,"E_ITEM_DIAMOND_BLOCK",E_ITEM_DIAMOND_BLOCK);
tolua_constant(tolua_S,"E_ITEM_WORKBENCH",E_ITEM_WORKBENCH);
tolua_constant(tolua_S,"E_ITEM_CROPS",E_ITEM_CROPS);
tolua_constant(tolua_S,"E_ITEM_SOIL",E_ITEM_SOIL);
tolua_constant(tolua_S,"E_ITEM_FURNACE",E_ITEM_FURNACE);
tolua_constant(tolua_S,"E_ITEM_BURNING_FURNACE",E_ITEM_BURNING_FURNACE);
tolua_constant(tolua_S,"E_ITEM_SIGN_POST",E_ITEM_SIGN_POST);
tolua_constant(tolua_S,"E_ITEM_LADDER",E_ITEM_LADDER);
tolua_constant(tolua_S,"E_ITEM_MINECART_TRACKS",E_ITEM_MINECART_TRACKS);
tolua_constant(tolua_S,"E_ITEM_COBBLESTONE_STAIRS",E_ITEM_COBBLESTONE_STAIRS);
tolua_constant(tolua_S,"E_ITEM_WALLSIGN",E_ITEM_WALLSIGN);
tolua_constant(tolua_S,"E_ITEM_LEVER",E_ITEM_LEVER);
tolua_constant(tolua_S,"E_ITEM_STONE_PRESSURE_PLATE",E_ITEM_STONE_PRESSURE_PLATE);
tolua_constant(tolua_S,"E_ITEM_WOODEN_PRESSURE_PLATE",E_ITEM_WOODEN_PRESSURE_PLATE);
tolua_constant(tolua_S,"E_ITEM_REDSTONE_ORE",E_ITEM_REDSTONE_ORE);
tolua_constant(tolua_S,"E_ITEM_REDSTONE_ORE_GLOWING",E_ITEM_REDSTONE_ORE_GLOWING);
tolua_constant(tolua_S,"E_ITEM_REDSTONE_TORCH_ON",E_ITEM_REDSTONE_TORCH_ON);
tolua_constant(tolua_S,"E_ITEM_REDSTONE_TORCH_OFF",E_ITEM_REDSTONE_TORCH_OFF);
tolua_constant(tolua_S,"E_ITEM_STONE_BUTTON",E_ITEM_STONE_BUTTON);
tolua_constant(tolua_S,"E_ITEM_SNOW",E_ITEM_SNOW);
tolua_constant(tolua_S,"E_ITEM_ICE",E_ITEM_ICE);
tolua_constant(tolua_S,"E_ITEM_SNOW_BLOCK",E_ITEM_SNOW_BLOCK);
tolua_constant(tolua_S,"E_ITEM_CACTUS",E_ITEM_CACTUS);
tolua_constant(tolua_S,"E_ITEM_REEDS",E_ITEM_REEDS);
tolua_constant(tolua_S,"E_ITEM_JUKEBOX",E_ITEM_JUKEBOX);
tolua_constant(tolua_S,"E_ITEM_FENCE",E_ITEM_FENCE);
tolua_constant(tolua_S,"E_ITEM_PUMPKIN",E_ITEM_PUMPKIN);
tolua_constant(tolua_S,"E_ITEM_BLOODSTONE",E_ITEM_BLOODSTONE);
tolua_constant(tolua_S,"E_ITEM_SOULSAND",E_ITEM_SOULSAND);
tolua_constant(tolua_S,"E_ITEM_GLOWSTONE",E_ITEM_GLOWSTONE);
tolua_constant(tolua_S,"E_ITEM_PORT",E_ITEM_PORT);
tolua_constant(tolua_S,"E_ITEM_JACK_O_LANTERN",E_ITEM_JACK_O_LANTERN);
tolua_constant(tolua_S,"E_ITEM_REDSTONE_REPEATER_OFF",E_ITEM_REDSTONE_REPEATER_OFF);
tolua_constant(tolua_S,"E_ITEM_REDSTONE_REPEATER_ON",E_ITEM_REDSTONE_REPEATER_ON);
tolua_constant(tolua_S,"E_ITEM_LOCKED_CHEST",E_ITEM_LOCKED_CHEST);
tolua_constant(tolua_S,"E_ITEM_TRAPDOOR",E_ITEM_TRAPDOOR);
tolua_constant(tolua_S,"E_ITEM_SILVERFISH_EGG",E_ITEM_SILVERFISH_EGG);
tolua_constant(tolua_S,"E_ITEM_STONE_BRICKS",E_ITEM_STONE_BRICKS);
tolua_constant(tolua_S,"E_ITEM_HUGE_BROWN_MUSHROOM",E_ITEM_HUGE_BROWN_MUSHROOM);
tolua_constant(tolua_S,"E_ITEM_HUGE_RED_MUSHROOM",E_ITEM_HUGE_RED_MUSHROOM);
tolua_constant(tolua_S,"E_ITEM_IRON_BAR",E_ITEM_IRON_BAR);
tolua_constant(tolua_S,"E_ITEM_GLASS_PLANE",E_ITEM_GLASS_PLANE);
tolua_constant(tolua_S,"E_ITEM_MELON",E_ITEM_MELON);
tolua_constant(tolua_S,"E_ITEM_PUMPKIN_STEM",E_ITEM_PUMPKIN_STEM);
tolua_constant(tolua_S,"E_ITEM_MELON_STEM",E_ITEM_MELON_STEM);
tolua_constant(tolua_S,"E_ITEM_VINES",E_ITEM_VINES);
tolua_constant(tolua_S,"E_ITEM_FENCE_GATE",E_ITEM_FENCE_GATE);
tolua_constant(tolua_S,"E_ITEM_BRICK_STAIRS",E_ITEM_BRICK_STAIRS);
tolua_constant(tolua_S,"E_ITEM_STONE_BRICK_STAIRS",E_ITEM_STONE_BRICK_STAIRS);
tolua_constant(tolua_S,"E_ITEM_MYCELIUM",E_ITEM_MYCELIUM);
tolua_constant(tolua_S,"E_ITEM_LILY_PAD",E_ITEM_LILY_PAD);
tolua_constant(tolua_S,"E_ITEM_NETHER_BRICK",E_ITEM_NETHER_BRICK);
tolua_constant(tolua_S,"E_ITEM_NETHER_BRICK_FENCE",E_ITEM_NETHER_BRICK_FENCE);
tolua_constant(tolua_S,"E_ITEM_NETHER_BRICK_STAIRS",E_ITEM_NETHER_BRICK_STAIRS);
tolua_constant(tolua_S,"E_ITEM_ENCHANTMENT_TABLE",E_ITEM_ENCHANTMENT_TABLE);
tolua_constant(tolua_S,"E_ITEM_END_PORTAL",E_ITEM_END_PORTAL);
tolua_constant(tolua_S,"E_ITEM_END_PORTAL_FRAME",E_ITEM_END_PORTAL_FRAME);
tolua_constant(tolua_S,"E_ITEM_END_STONE",E_ITEM_END_STONE);
tolua_constant(tolua_S,"E_ITEM_IRON_SHOVEL",E_ITEM_IRON_SHOVEL);
tolua_constant(tolua_S,"E_ITEM_IRON_PICKAXE",E_ITEM_IRON_PICKAXE);
tolua_constant(tolua_S,"E_ITEM_IRON_AXE",E_ITEM_IRON_AXE);
tolua_constant(tolua_S,"E_ITEM_FLINT_AND_STEEL",E_ITEM_FLINT_AND_STEEL);
tolua_constant(tolua_S,"E_ITEM_APPLE",E_ITEM_APPLE);
tolua_constant(tolua_S,"E_ITEM_BOW",E_ITEM_BOW);
@ -15184,6 +15324,21 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_ITEM_DIAMOND",E_ITEM_DIAMOND);
tolua_constant(tolua_S,"E_ITEM_IRON",E_ITEM_IRON);
tolua_constant(tolua_S,"E_ITEM_GOLD",E_ITEM_GOLD);
tolua_constant(tolua_S,"E_ITEM_IRON_SWORD",E_ITEM_IRON_SWORD);
tolua_constant(tolua_S,"E_ITEM_WOODEN_SWORD",E_ITEM_WOODEN_SWORD);
tolua_constant(tolua_S,"E_ITEM_WOODEN_SHOVEL",E_ITEM_WOODEN_SHOVEL);
tolua_constant(tolua_S,"E_ITEM_WOODEN_PICKAXE",E_ITEM_WOODEN_PICKAXE);
tolua_constant(tolua_S,"E_ITEM_WOODEN_AXE",E_ITEM_WOODEN_AXE);
tolua_constant(tolua_S,"E_ITEM_STONE_SWORD",E_ITEM_STONE_SWORD);
tolua_constant(tolua_S,"E_ITEM_STONE_SHOVEL",E_ITEM_STONE_SHOVEL);
tolua_constant(tolua_S,"E_ITEM_STONE_PICKAXE",E_ITEM_STONE_PICKAXE);
tolua_constant(tolua_S,"E_ITEM_STONE_AXE",E_ITEM_STONE_AXE);
tolua_constant(tolua_S,"E_ITEM_DIAMOND_SWORD",E_ITEM_DIAMOND_SWORD);
tolua_constant(tolua_S,"E_ITEM_DIAMOND_SHOVEL",E_ITEM_DIAMOND_SHOVEL);
tolua_constant(tolua_S,"E_ITEM_DIAMOND_PICKAXE",E_ITEM_DIAMOND_PICKAXE);
tolua_constant(tolua_S,"E_ITEM_DIAMOND_AXE",E_ITEM_DIAMOND_AXE);
tolua_constant(tolua_S,"E_ITEM_STICK",E_ITEM_STICK);
tolua_constant(tolua_S,"E_ITEM_BOWL",E_ITEM_BOWL);
tolua_constant(tolua_S,"E_ITEM_MUSHROOM_SOUP",E_ITEM_MUSHROOM_SOUP);
tolua_constant(tolua_S,"E_ITEM_GOLD_SWORD",E_ITEM_GOLD_SWORD);
tolua_constant(tolua_S,"E_ITEM_GOLD_SHOVEL",E_ITEM_GOLD_SHOVEL);
@ -15191,12 +15346,61 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_ITEM_GOLD_AXE",E_ITEM_GOLD_AXE);
tolua_constant(tolua_S,"E_ITEM_STRING",E_ITEM_STRING);
tolua_constant(tolua_S,"E_ITEM_FEATHER",E_ITEM_FEATHER);
tolua_constant(tolua_S,"E_ITEM_GUNPOWDER",E_ITEM_GUNPOWDER);
tolua_constant(tolua_S,"E_ITEM_WOODEN_HOE",E_ITEM_WOODEN_HOE);
tolua_constant(tolua_S,"E_ITEM_STONE_HOE",E_ITEM_STONE_HOE);
tolua_constant(tolua_S,"E_ITEM_IRON_HOE",E_ITEM_IRON_HOE);
tolua_constant(tolua_S,"E_ITEM_DIAMOND_HOE",E_ITEM_DIAMOND_HOE);
tolua_constant(tolua_S,"E_ITEM_GOLD_HOE",E_ITEM_GOLD_HOE);
tolua_constant(tolua_S,"E_ITEM_SEEDS",E_ITEM_SEEDS);
tolua_constant(tolua_S,"E_ITEM_WHEAT",E_ITEM_WHEAT);
tolua_constant(tolua_S,"E_ITEM_BREAD",E_ITEM_BREAD);
tolua_constant(tolua_S,"E_ITEM_LEATHER_CAP",E_ITEM_LEATHER_CAP);
tolua_constant(tolua_S,"E_ITEM_LEATHER_TUNIC",E_ITEM_LEATHER_TUNIC);
tolua_constant(tolua_S,"E_ITEM_LEATHER_PANTS",E_ITEM_LEATHER_PANTS);
tolua_constant(tolua_S,"E_ITEM_LEATHER_BOOTS",E_ITEM_LEATHER_BOOTS);
tolua_constant(tolua_S,"E_ITEM_CHAIN_HELMET",E_ITEM_CHAIN_HELMET);
tolua_constant(tolua_S,"E_ITEM_CHAIN_CHESTPLATE",E_ITEM_CHAIN_CHESTPLATE);
tolua_constant(tolua_S,"E_ITEM_CHAIN_LEGGINGS",E_ITEM_CHAIN_LEGGINGS);
tolua_constant(tolua_S,"E_ITEM_CHAIN_BOOTS",E_ITEM_CHAIN_BOOTS);
tolua_constant(tolua_S,"E_ITEM_IRON_HELMET",E_ITEM_IRON_HELMET);
tolua_constant(tolua_S,"E_ITEM_IRON_CHESTPLATE",E_ITEM_IRON_CHESTPLATE);
tolua_constant(tolua_S,"E_ITEM_IRON_LEGGINGS",E_ITEM_IRON_LEGGINGS);
tolua_constant(tolua_S,"E_ITEM_IRON_BOOTS",E_ITEM_IRON_BOOTS);
tolua_constant(tolua_S,"E_ITEM_DIAMOND_HELMET",E_ITEM_DIAMOND_HELMET);
tolua_constant(tolua_S,"E_ITEM_DIAMOND_CHESTPLATE",E_ITEM_DIAMOND_CHESTPLATE);
tolua_constant(tolua_S,"E_ITEM_DIAMOND_LEGGINGS",E_ITEM_DIAMOND_LEGGINGS);
tolua_constant(tolua_S,"E_ITEM_DIAMOND_BOOTS",E_ITEM_DIAMOND_BOOTS);
tolua_constant(tolua_S,"E_ITEM_GOLD_HELMET",E_ITEM_GOLD_HELMET);
tolua_constant(tolua_S,"E_ITEM_GOLD_CHESTPLATE",E_ITEM_GOLD_CHESTPLATE);
tolua_constant(tolua_S,"E_ITEM_GOLD_LEGGINGS",E_ITEM_GOLD_LEGGINGS);
tolua_constant(tolua_S,"E_ITEM_GOLD_BOOTS",E_ITEM_GOLD_BOOTS);
tolua_constant(tolua_S,"E_ITEM_FLINT",E_ITEM_FLINT);
tolua_constant(tolua_S,"E_ITEM_RAW_MEAT",E_ITEM_RAW_MEAT);
tolua_constant(tolua_S,"E_ITEM_COOKED_MEAT",E_ITEM_COOKED_MEAT);
tolua_constant(tolua_S,"E_ITEM_PAINTINGS",E_ITEM_PAINTINGS);
tolua_constant(tolua_S,"E_ITEM_GOLDEN_APPLE",E_ITEM_GOLDEN_APPLE);
tolua_constant(tolua_S,"E_ITEM_SIGN",E_ITEM_SIGN);
tolua_constant(tolua_S,"E_ITEM_WOODEN_DOOR",E_ITEM_WOODEN_DOOR);
tolua_constant(tolua_S,"E_ITEM_BUCKET",E_ITEM_BUCKET);
tolua_constant(tolua_S,"E_ITEM_WATER_BUCKET",E_ITEM_WATER_BUCKET);
tolua_constant(tolua_S,"E_ITEM_LAVA_BUCKET",E_ITEM_LAVA_BUCKET);
tolua_constant(tolua_S,"E_ITEM_MINECART",E_ITEM_MINECART);
tolua_constant(tolua_S,"E_ITEM_SADDLE",E_ITEM_SADDLE);
tolua_constant(tolua_S,"E_ITEM_IRON_DOOR",E_ITEM_IRON_DOOR);
tolua_constant(tolua_S,"E_ITEM_REDSTONE_DUST",E_ITEM_REDSTONE_DUST);
tolua_constant(tolua_S,"E_ITEM_SNOWBALL",E_ITEM_SNOWBALL);
tolua_constant(tolua_S,"E_ITEM_BOAT",E_ITEM_BOAT);
tolua_constant(tolua_S,"E_ITEM_LEATHER",E_ITEM_LEATHER);
tolua_constant(tolua_S,"E_ITEM_MILK",E_ITEM_MILK);
tolua_constant(tolua_S,"E_ITEM_CLAY_BRICK",E_ITEM_CLAY_BRICK);
tolua_constant(tolua_S,"E_ITEM_CLAY",E_ITEM_CLAY);
tolua_constant(tolua_S,"E_ITEM_SUGAR_CANE",E_ITEM_SUGAR_CANE);
tolua_constant(tolua_S,"E_ITEM_PAPER",E_ITEM_PAPER);
tolua_constant(tolua_S,"E_ITEM_BOOK",E_ITEM_BOOK);
tolua_constant(tolua_S,"E_ITEM_SLIMEBALL",E_ITEM_SLIMEBALL);
tolua_constant(tolua_S,"E_ITEM_CHEST_MINECART",E_ITEM_CHEST_MINECART);
tolua_constant(tolua_S,"E_ITEM_FURNACE_MINECART",E_ITEM_FURNACE_MINECART);
tolua_constant(tolua_S,"E_ITEM_EGG",E_ITEM_EGG);
tolua_constant(tolua_S,"E_ITEM_COMPASS",E_ITEM_COMPASS);
tolua_constant(tolua_S,"E_ITEM_FISHING_ROD",E_ITEM_FISHING_ROD);
@ -15204,7 +15408,49 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_ITEM_GLOWSTONE_DUST",E_ITEM_GLOWSTONE_DUST);
tolua_constant(tolua_S,"E_ITEM_RAW_FISH",E_ITEM_RAW_FISH);
tolua_constant(tolua_S,"E_ITEM_COOKED_FISH",E_ITEM_COOKED_FISH);
tolua_constant(tolua_S,"E_ITEM_DYE",E_ITEM_DYE);
tolua_constant(tolua_S,"E_ITEM_BONE",E_ITEM_BONE);
tolua_constant(tolua_S,"E_ITEM_SUGAR",E_ITEM_SUGAR);
tolua_constant(tolua_S,"E_ITEM_CAKE",E_ITEM_CAKE);
tolua_constant(tolua_S,"E_ITEM_BED",E_ITEM_BED);
tolua_constant(tolua_S,"E_ITEM_REDSTONE_REPEATER",E_ITEM_REDSTONE_REPEATER);
tolua_constant(tolua_S,"E_ITEM_COOKIE",E_ITEM_COOKIE);
tolua_constant(tolua_S,"E_ITEM_MAP",E_ITEM_MAP);
tolua_constant(tolua_S,"E_ITEM_SHEARS",E_ITEM_SHEARS);
tolua_constant(tolua_S,"E_ITEM_MELON_SLICE",E_ITEM_MELON_SLICE);
tolua_constant(tolua_S,"E_ITEM_PUMPKIN_SEEDS",E_ITEM_PUMPKIN_SEEDS);
tolua_constant(tolua_S,"E_ITEM_MELON_SEEDS",E_ITEM_MELON_SEEDS);
tolua_constant(tolua_S,"E_ITEM_RAW_BEEF",E_ITEM_RAW_BEEF);
tolua_constant(tolua_S,"E_ITEM_STEAK",E_ITEM_STEAK);
tolua_constant(tolua_S,"E_ITEM_RAW_CHICKEN",E_ITEM_RAW_CHICKEN);
tolua_constant(tolua_S,"E_ITEM_COOKED_CHICKEN",E_ITEM_COOKED_CHICKEN);
tolua_constant(tolua_S,"E_ITEM_ROTTEN_FLESH",E_ITEM_ROTTEN_FLESH);
tolua_constant(tolua_S,"E_ITEM_ENDER_PEARL",E_ITEM_ENDER_PEARL);
tolua_constant(tolua_S,"E_ITEM_BLAZE_ROD",E_ITEM_BLAZE_ROD);
tolua_constant(tolua_S,"E_ITEM_GHAST_TEAR",E_ITEM_GHAST_TEAR);
tolua_constant(tolua_S,"E_ITEM_GOLD_NUGGET",E_ITEM_GOLD_NUGGET);
tolua_constant(tolua_S,"E_ITEM_NETHER_WART",E_ITEM_NETHER_WART);
tolua_constant(tolua_S,"E_ITEM_POTIONS",E_ITEM_POTIONS);
tolua_constant(tolua_S,"E_ITEM_GLASS_BOTTLE",E_ITEM_GLASS_BOTTLE);
tolua_constant(tolua_S,"E_ITEM_SPIDER_EYE",E_ITEM_SPIDER_EYE);
tolua_constant(tolua_S,"E_ITEM_FERMENTED_SPIDER_EYE",E_ITEM_FERMENTED_SPIDER_EYE);
tolua_constant(tolua_S,"E_ITEM_BLAZE_POWDER",E_ITEM_BLAZE_POWDER);
tolua_constant(tolua_S,"E_ITEM_MAGMA_CREAM",E_ITEM_MAGMA_CREAM);
tolua_constant(tolua_S,"E_ITEM_BREWING_STAND",E_ITEM_BREWING_STAND);
tolua_constant(tolua_S,"E_ITEM_CAULDRON",E_ITEM_CAULDRON);
tolua_constant(tolua_S,"E_ITEM_EYE_OF_ENDER",E_ITEM_EYE_OF_ENDER);
tolua_constant(tolua_S,"E_ITEM_GLISTERING_MELON",E_ITEM_GLISTERING_MELON);
tolua_constant(tolua_S,"E_ITEM_13_DISC",E_ITEM_13_DISC);
tolua_constant(tolua_S,"E_ITEM_CAT_DISC",E_ITEM_CAT_DISC);
tolua_constant(tolua_S,"E_ITEM_BLOCKS_DISC",E_ITEM_BLOCKS_DISC);
tolua_constant(tolua_S,"E_ITEM_CHIRP_DISC",E_ITEM_CHIRP_DISC);
tolua_constant(tolua_S,"E_ITEM_FAR_DISC",E_ITEM_FAR_DISC);
tolua_constant(tolua_S,"E_ITEM_MALL_DISC",E_ITEM_MALL_DISC);
tolua_constant(tolua_S,"E_ITEM_MELLOHI_DISC",E_ITEM_MELLOHI_DISC);
tolua_constant(tolua_S,"E_ITEM_STAL_DISC",E_ITEM_STAL_DISC);
tolua_constant(tolua_S,"E_ITEM_STRAD_DISC",E_ITEM_STRAD_DISC);
tolua_constant(tolua_S,"E_ITEM_WARD_DISC",E_ITEM_WARD_DISC);
tolua_constant(tolua_S,"E_ITEM_11_DISC",E_ITEM_11_DISC);
tolua_constant(tolua_S,"E_KEEP_ALIVE",E_KEEP_ALIVE);
tolua_constant(tolua_S,"E_LOGIN",E_LOGIN);
tolua_constant(tolua_S,"E_HANDSHAKE",E_HANDSHAKE);
@ -15241,6 +15487,11 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_MAP_CHUNK",E_MAP_CHUNK);
tolua_constant(tolua_S,"E_MULTI_BLOCK",E_MULTI_BLOCK);
tolua_constant(tolua_S,"E_BLOCK_CHANGE",E_BLOCK_CHANGE);
tolua_constant(tolua_S,"E_BLOCK_ACTION",E_BLOCK_ACTION);
tolua_constant(tolua_S,"E_EXPLOSION",E_EXPLOSION);
tolua_constant(tolua_S,"E_SOUND_EFFECT",E_SOUND_EFFECT);
tolua_constant(tolua_S,"E_NEW_INVALID_STATE",E_NEW_INVALID_STATE);
tolua_constant(tolua_S,"E_THUNDERBOLT",E_THUNDERBOLT);
tolua_constant(tolua_S,"E_WINDOW_OPEN",E_WINDOW_OPEN);
tolua_constant(tolua_S,"E_WINDOW_CLOSE",E_WINDOW_CLOSE);
tolua_constant(tolua_S,"E_WINDOW_CLICK",E_WINDOW_CLICK);

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 11/01/11 22:50:07.
** Generated automatically by tolua++-1.0.92 on 11/08/11 02:11:36.
*/
/* Exported function */

136
source/SquirrelBindings.cpp Normal file
View File

@ -0,0 +1,136 @@
#include "SquirrelBindings.h"
#if USE_SQUIRREL
#pragma warning(disable:4100) // Getting A LOT of these warnings from SqPlus
#pragma warning(disable:4127)
#include "cMCLogger.h"
#include <sqplus/sqplus.h>
#include <sqplus/SquirrelObject.h>
#include <../squirrel/sqstate.h>
#include <../squirrel/sqvm.h>
#include <stdarg.h>
#include "cPlugin.h"
#include "cPluginManager.h"
#include "cRoot.h"
#include "cPlayer.h"
bool SquirrelBindings::IsBound = false;
bool IsTopClosure( HSQUIRRELVM v )
{
return ( v->_stack[0]._type == OT_CLOSURE );
}
class __Squirrel_Base_Class // All inheritable classes should extend this class, as it allows virtual functions to call Squirrel
{
public:
template<typename T>
static int ConstructAndDestruct(HSQUIRRELVM v, T* a_Instance, SQRELEASEHOOK a_ReleaseHook )
{
LOG("ConstructAndDestruct()");
StackHandler sa(v);
HSQOBJECT ho = sa.GetObjectHandle(1); // OT_INSTANCE
SquirrelObject instance(ho);
SqPlus::PopulateAncestry(v, instance, a_Instance);
a_Instance->vm = v;
a_Instance->obj = instance;
sq_setinstanceup(v, 1, a_Instance);
sq_setreleasehook(v, 1, a_ReleaseHook);
return TRUE;
}
HSQUIRRELVM vm;
SquirrelObject obj;
};
class cPlugin__Squirrel : public cPlugin, public __Squirrel_Base_Class
{
public:
cPlugin__Squirrel() { SetLanguage( cPlugin::E_SQUIRREL ); }
bool Initialize() // This is a pure virtual function, so it NEEDS an implementation on the script side or it would be an illegal instance
{
SqPlus::SquirrelFunction<bool> InitFunc(obj, "Initialize");
if( !InitFunc.func.IsNull() )
return InitFunc();
LOGWARN("cPlugin__Squirrel::Initialize() Pure virtual function called!"); // Spam some errorz to make it clear this function needs to be implemented
return false;
}
static int constructor(HSQUIRRELVM v) { return ConstructAndDestruct( v, new cPlugin__Squirrel, SqPlus::ReleaseClassPtr<cPlugin__Squirrel>::release ); }
virtual bool OnChat( const char* a_Chat, cPlayer* a_Player )
{
if( !IsTopClosure(vm) ) // Avoid recursion (TODO: FIXME: THIS NEEDS MORE RESEARCH!)
{ //Called from C++
return SqPlus::SquirrelFunction<bool>(obj, "OnChat")(a_Chat, a_Player);
}
else // Called from Squirrel
{
return cPlugin::OnChat(a_Chat, a_Player);
}
}
};
static void printFunc(HSQUIRRELVM v,const SQChar * s,...)
{
(void)v;
va_list vl;
va_start(vl,s);
cMCLogger::GetInstance()->Log( s, vl );
va_end(vl);
}
DECLARE_INSTANCE_TYPE( cRoot );
DECLARE_INSTANCE_TYPE( cPluginManager );
DECLARE_ENUM_TYPE( cPluginManager::PluginHook );
DECLARE_INSTANCE_TYPE( cPlugin );
DECLARE_INSTANCE_TYPE( cPlugin__Squirrel );
DECLARE_INSTANCE_TYPE( cEntity );
DECLARE_INSTANCE_TYPE( cPawn );
DECLARE_INSTANCE_TYPE( cPlayer );
void SquirrelBindings::Bind( HSQUIRRELVM a_SquirrelVM )
{
IsBound = true;
sq_setprintfunc(a_SquirrelVM, printFunc, printFunc);
SqPlus::SQClassDefNoConstructor<cEntity>("cEntity");
SqPlus::SQClassDefNoConstructor<cPawn, cEntity>("cPawn", "cEntity");
SqPlus::SQClassDefNoConstructor<cPlayer, cPawn>("cPlayer", "cPawn"). // All NoConstructor because they need a custom one
func(&cPlayer::GetName, "GetName");
SqPlus::SQClassDefNoConstructor<cPlugin>("cPlugin").
func(&cPlugin::SetName, "SetName").
func(&cPlugin::GetName, "GetName").
func(&cPlugin::GetVersion, "GetVersion").
func(&cPlugin::OnChat, "OnChat");
SqPlus::SQClassDef<cPlugin__Squirrel, cPlugin>("cPlugin__Squirrel", "cPlugin").
staticFunc(&cPlugin__Squirrel::constructor, "constructor");
SqPlus::SQClassDefNoConstructor<cRoot>("cRoot").
staticFunc(&cRoot::Get, "Get").
func(static_cast<cPluginManager* (__thiscall cRoot::*)(void)>(&cRoot::GetPluginManager), "GetPluginManager");
SqPlus::SQClassDefNoConstructor<cPluginManager>("cPluginManager").
overloadFunc<bool (cPluginManager::*)(cPlugin*)>(&cPluginManager::AddPlugin, "AddPlugin").
func(&cPluginManager::GetPlugin, "GetPlugin").
func(&cPluginManager::AddHook, "AddHook").
enumInt( cPluginManager::E_PLUGIN_CHAT, "E_PLUGIN_CHAT");
}
#endif

15
source/SquirrelBindings.h Normal file
View File

@ -0,0 +1,15 @@
#pragma once
#define USE_SQUIRREL 0
#if USE_SQUIRREL
struct SQVM;
class SquirrelBindings
{
public:
static void Bind( SQVM* a_SquirrelVM );
static bool IsBound;
};
#endif

View File

@ -69,6 +69,7 @@
#ifndef _WIN32
#define sprintf_s(dst, size, format, ...) sprintf(dst, format, __VA_ARGS__ )
#include <stdlib.h> // rand()
#endif
#define AddPistonDir( x, y, z, dir, amount ) switch(dir) { case 0: (y)-=(amount); break; case 1: (y)+=(amount); break;\

View File

@ -5,6 +5,7 @@
cPlugin::cPlugin()
: m_Version( 0 )
, m_Language( E_CPP )
{
}
@ -44,7 +45,7 @@ bool cPlugin::OnDisconnect( std::string a_Reason, cPlayer* a_Player )
return false;
}
bool cPlugin::OnChat( std::string a_Chat, cPlayer* a_Player )
bool cPlugin::OnChat( const char* a_Chat, cPlayer* a_Player )
{
(void)a_Chat;
(void)a_Player;

View File

@ -41,7 +41,7 @@ public:
virtual bool OnDisconnect( std::string a_Reason, cPlayer* a_Player );
virtual bool OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player );
virtual bool OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem ) { (void)a_PacketData; (void)a_Player; (void)a_PickupItem; return false; }
virtual bool OnChat( std::string a_Chat, cPlayer* a_Player );
virtual bool OnChat( const char* a_Chat, cPlayer* a_Player );
virtual bool OnLogin( cPacket_Login* a_PacketData );
virtual void OnPlayerSpawn( cPlayer* a_Player );
virtual bool OnPlayerJoin( cPlayer* a_Player );
@ -50,8 +50,8 @@ public:
virtual bool OnKilled( cPawn* a_Killed, cEntity* a_Killer ) { (void)a_Killed; (void)a_Killer; return false; }
// Accessors
std::string GetName() const { return m_Name; }
void SetName( std::string a_Name ) { m_Name = a_Name; }
const char* GetName() const { return m_Name.c_str(); }
void SetName( const char* a_Name ) { m_Name = a_Name; }
int GetVersion() const { return m_Version; }
void SetVersion( int a_Version ) { m_Version = a_Version; }
@ -69,7 +69,19 @@ public:
void BindCommand( FuncCommandHandler* a_Function, std::string & a_Command ); // >> EXPORTED IN MANUALBINDINGS <<
const std::vector< CommandStruct > & GetCommands() const { return m_Commands; } // >> EXPORTED IN MANUALBINDINGS <<
/* This should not be exposed to scripting languages */
enum PluginLanguage
{
E_CPP,
E_LUA,
E_SQUIRREL,
};
PluginLanguage GetLanguage() { return m_Language; }
void SetLanguage( PluginLanguage a_Language ) { m_Language = a_Language; }
private:
PluginLanguage m_Language;
std::vector< CommandStruct > m_Commands;
std::string m_Name;
int m_Version;

View File

@ -6,10 +6,16 @@
#include "cItem.h"
#include "cRoot.h"
#include "cLuaCommandBinder.h"
#include "../iniFile/iniFile.h"
#include <string> //strcmp
#include <stdarg.h>
#include "../iniFile/iniFile.h"
#include "SquirrelBindings.h"
#if USE_SQUIRREL
#pragma warning(disable:4100;disable:4127;disable:4510;disable:4610;disable:4244;disable:4512) // Getting A LOT of these warnings from SqPlus
#include <sqplus/sqplus.h>
#pragma warning(default:4100;default:4127;default:4510;default:4610;default:4244;default:4512)
#endif
extern std::vector<std::string> StringSplit(std::string str, std::string delim);
@ -39,6 +45,7 @@ cPluginManager::cPluginManager()
cPluginManager::~cPluginManager()
{
UnloadPluginsNow();
delete m_LuaCommandBinder;
delete m_pState;
}
@ -54,6 +61,16 @@ void cPluginManager::ReloadPluginsNow()
m_bReloadPlugins = false;
UnloadPluginsNow();
#if USE_SQUIRREL
if( !SquirrelBindings::IsBound ) // Can only do this once apparently, or we're making ambiguous calls in the script
{
SquirrelVM::Init();
SquirrelBindings::Bind( SquirrelVM::GetVMPtr() );
}
#endif
cIniFile IniFile("settings.ini");
if( IniFile.ReadFile() )
{
@ -64,10 +81,10 @@ void cPluginManager::ReloadPluginsNow()
for(unsigned int i = 0; i < NumPlugins; i++)
{
std::string ValueName = IniFile.GetValueName(KeyNum, i );
if( ValueName.compare("Plugin") == 0 )
{ // It's a plugin
if( ValueName.compare("Plugin") == 0 ) // It's a Lua plugin
{
std::string PluginFile = IniFile.GetValue(KeyNum, i );
if( PluginFile.compare("") != 0 )
if( !PluginFile.empty() )
{
// allow for comma separated plugin list
// degrades and works fine for the plugin
@ -82,6 +99,32 @@ void cPluginManager::ReloadPluginsNow()
}
}
}
#if USE_SQUIRREL
else if( ValueName.compare("Squirrel") == 0 ) // Squirrel plugin
{
std::string PluginFile = IniFile.GetValue(KeyNum, i );
if( !PluginFile.empty() )
{
LOGINFO("Loading Squirrel plugin: %s", PluginFile.c_str() );
try
{
SquirrelObject SquirrelScript = SquirrelVM::CompileScript( (std::string("Plugins/") + PluginFile + ".nut").c_str() );
try
{
SquirrelVM::RunScript( SquirrelScript );
}
catch (SquirrelError & e)
{
LOGERROR("Error: %s, %s\n", e.desc, "SquirrelVM::RunScript");
}
}
catch (SquirrelError & e)
{
LOGERROR("Error: %s, %s\n", e.desc, "SquirrelVM::CompileScript");
}
}
}
#endif
}
}
@ -98,6 +141,8 @@ void cPluginManager::ReloadPluginsNow()
{
LOG("WARNING: Can't find settings.ini, so can't load any plugins.");
}
LOG("--Done loading plugins--");
}
@ -291,11 +336,11 @@ bool cPluginManager::CallHook( PluginHook a_Hook, unsigned int a_NumArgs, ... )
return false;
}
cPlugin* cPluginManager::GetPlugin( std::string a_Plugin )
cPlugin* cPluginManager::GetPlugin( const char* a_Plugin )
{
for( PluginList::iterator itr = m_pState->Plugins.begin(); itr != m_pState->Plugins.end(); ++itr )
{
if( (*itr)->GetName().compare( a_Plugin ) == 0 )
if( std::string( (*itr)->GetName() ).compare( a_Plugin ) == 0 )
{
return *itr;
}
@ -328,6 +373,25 @@ void cPluginManager::UnloadPluginsNow()
{
RemovePlugin( *m_pState->Plugins.begin(), true );
}
//SquirrelVM::Shutdown(); // This breaks shit
}
void cPluginManager::RemoveHooks( cPlugin* a_Plugin )
{
m_pState->Hooks[ E_PLUGIN_TICK ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_CHAT ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_COLLECT_ITEM ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_BLOCK_DIG ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_BLOCK_PLACE ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_DISCONNECT ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_HANDSHAKE ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_LOGIN ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_PLAYER_SPAWN ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_PLAYER_JOIN ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_PLAYER_MOVE ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_TAKE_DAMAGE ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_KILLED ].remove( a_Plugin );
}
void cPluginManager::RemovePlugin( cPlugin* a_Plugin, bool a_bDelete /* = false */ )
@ -336,8 +400,10 @@ void cPluginManager::RemovePlugin( cPlugin* a_Plugin, bool a_bDelete /* = false
{
m_LuaCommandBinder->RemoveBindingsForPlugin( a_Plugin );
m_pState->Plugins.remove( a_Plugin );
RemoveHooks( a_Plugin );
a_Plugin->OnDisable();
delete a_Plugin;
if( a_Plugin->GetLanguage() != cPlugin::E_SQUIRREL ) // Squirrel needs to clean it up himself!
delete a_Plugin;
}
else
{
@ -356,11 +422,14 @@ bool cPluginManager::AddPlugin( cPlugin* a_Plugin )
m_pState->Plugins.push_back( a_Plugin );
return true;
}
RemoveHooks( a_Plugin ); // Undo any damage the Initialize() might have done
return false;
}
bool cPluginManager::AddPlugin( lua_State* a_LuaState, cPlugin* a_Plugin )
{
a_Plugin->SetLanguage( cPlugin::E_LUA );
cPlugin_Lua* LuaPlugin = GetLuaPlugin( a_LuaState );
if( LuaPlugin && a_Plugin->Initialize() )
{
@ -391,8 +460,8 @@ void cPluginManager::RemoveLuaPlugin( std::string a_FileName )
if( (*itr)->GetFileName() == a_FileName )
{
cPlugin_Lua* Plugin = *itr;
delete Plugin;
m_pState->LuaPlugins.remove( Plugin );
delete Plugin;
return;
}
}

View File

@ -34,7 +34,7 @@ public: //tolua_export
static cPluginManager * GetPluginManager(); //tolua_export
typedef std::list< cPlugin* > PluginList;
cPlugin* GetPlugin( std::string a_Plugin ); //tolua_export
cPlugin* GetPlugin( const char* a_Plugin ); //tolua_export
const PluginList & GetAllPlugins(); // >> EXPORTED IN MANUALBINDINGS <<
void ReloadPlugins(); //tolua_export
@ -47,6 +47,7 @@ public: //tolua_export
bool CallHook( PluginHook a_Hook, unsigned int a_NumArgs, ... );
void RemoveHooks( cPlugin* a_Plugin );
void RemovePlugin( cPlugin* a_Plugin, bool a_bDelete = false ); //tolua_export
void RemoveLuaPlugin( std::string a_FileName ); //tolua_export
cPlugin_Lua* GetLuaPlugin( lua_State* a_State ); //tolua_export

View File

@ -109,7 +109,7 @@ void cWebAdmin::Request_Handler(webserver::http_request* r)
const cPluginManager::PluginList & List = PM->GetAllPlugins();
for( cPluginManager::PluginList::const_iterator itr = List.begin(); itr != List.end(); ++itr )
{
Content += (*itr)->GetName() + "<br>";
Content += std::string( (*itr)->GetName() ) + "<br>";
}
Content += "</p>";
Content += "<h4>Players:</h4><p>";

View File

@ -9,6 +9,13 @@
#include <csignal> //std::signal
#include <stdlib.h> //exit()
#include "SquirrelBindings.h"
#if USE_SQUIRREL
#pragma warning(disable:4100;disable:4127;disable:4510;disable:4610;disable:4244;disable:4512) // Getting A LOT of these warnings from SqPlus
#include <sqplus/sqplus.h>
#pragma warning(default:4100;default:4127;default:4510;default:4610;default:4244;default:4512)
#endif
void ShowCrashReport(int)
{
std::signal(SIGSEGV, SIG_DFL);
@ -43,6 +50,11 @@ int main( int argc, char **argv )
{
LOGERROR("Unknown exception!");
}
#if USE_SQUIRREL
SquirrelVM::Shutdown();
#endif
#ifdef _DEBUG
_CrtDumpMemoryLeaks();
#endif

View File

@ -0,0 +1,41 @@
Squirrel 3.0 stable
--------------------------------------------------------
What is in this distribution?
squirrel
static library implementing the compiler and interpreter of the language
sqstdlib
the standard utility libraries
sq
stand alone interpreter
doc
The manual
etc
a minimalistic embedding sample
samples
samples programs
HOW TO COMPILE
---------------------------------------------------------
GCC USERS
.........................................................
There is a very simple makefile that compiles all libraries and exes
from the root of the project run 'make'
for 32 bits systems
$ make
for 64 bits systems
$ make sq64
VISUAL C++ USERS
.........................................................
Open squirrel.dsw from the root project directory and build(dho!)

View File

@ -0,0 +1,21 @@
Copyright (c) 2003-2011 Alberto Demichelis
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------
END OF COPYRIGHT

View File

@ -0,0 +1,422 @@
***version 3.0.1 stable***
-added # as alternative symbol for "line comment"(mostly useful for shell scripts)
-added sq_throwobject() to throw an arbitrary object from the C API
-added alignement flag for userdata types, SQ_ALIGNMENT (thx Shigemasa)
-added rawset() and rawget() to class and instance default delegate
-changed bytecode format now ensures matching integer size and float size
-now inherited classes also inherit userdatasize
-added SQUIRREL_VERSION_NUMBER in squirrel.h and _versionnumber_ global symbol
-fixed sq_getmemberhandle
-fixed sq_getrefcount
-refactored some sqstdio code
-refactored some clone code
-refactored some stuff in the string lib
-added -s and -fno-exceptions in GCC makefile(better performance when using GCC)
***2011-03-13 ***
***version 3.0 stable***
-added sq_getcallee()
-sq_getfreevariable() also works for native closures
-minior optimizations
-removed several warning when compiling with GCC 4.x
-fixed some errors in the documentation
-fixed bug when using SQUSEDOUBLE and 32bits intengers
-fixed bug when invoking generators with closure.call() (thx huntercool)
***2010-12-19 ***
***version 3.0 release candidate 1(RC 1)***
-improved metamethods error handling
-added parameter 'isstatic' to _newmember metamethod(thx G.Meyer)
-added sq_getrefcount() to return number of refences from C++(thx G.Meyer)
***2010-11-07 ***
***version 3.0 beta 3***
-license changed to "MIT license"
-added sq_resurrectunreachable() and resurrectunreachable()
-added callee() built in function, returns the current running closure
-added thread.getstackinfos()
-added sq_objtouserpointer()
-added sq_newtableex()
-various refactoring and optimizations
-fixed several 64bits issues regarding integer to string conversions
-fixed some bugs when SQUSEDOUBLE is used in 32bits systems
***2010-08-18 ***
***version 3.0 beta 2.1***
-fixed bug in class constructor
-fixed bug in compound arith
***2010-08-12 ***
***version 3.0 beta 2***
-class methods can be added or replaced after the class as been instantiated
-JSON compliant table syntax, this is currently an experimental feature (thx atai)
-sq_getsize() now returns userdatasize for classes and instances
-now setroottable() and setconsttable() return the previous value of the respective table
-fixed bug in compound arith operators when used on a free variable (thx ellon)
-fixed some x64 minor bugs
-fixed minor bug in the compiler
-refactored some VM internals
-documented sq_getmemberhandle, sq_getbyhandle, sq_setbyhandle to set and get value from classes
***2009-11-15 ***
***version 3.0 beta 1***
-various refactoring and optimizations
-fixed bug in free variables (thx mokehehe)
-fixed bug in functions with default parameters (thx ara & Yexo)
-fixed bug in exception handling
-improved error propagation in _set and _get metamethods ( and 'throw null' for clean failure)
-added sq_getmemberhandle, sq_getbyhandle, sq_setbyhandle to set and get value from classes
***2009-06-30 ***
***version 3.0 alpha 2***
-added real free variables(thx Paul Ruizendaal)
-added refactored function call implementation and compiler(thx Paul Ruizendaal)
-added sq_getfunctioninfo
-added compile time flag SQUSEDOUBLE to use double precision floats
-added global slot _floatsize_ int the base lib to recognize single precision and double precision builds
-sq_wakeupvm can now resume the vm with an exception
-added sqstd_format
-now blobs can be cloned
-generators can now be instantiated by calling sq_call() or closure.call()
-fixed debughook bug
-fixed cooroutine error propagation
***2008-07-23 ***
***version 3.0 alpha 1***
-first branch from 2.x source tree
-added 'base' keyword
-removed 'delegate' keyword
-now compiled scripts are vararg functions
-added setdelegate() and getdelegate() table builtin methods
-added <=> 3 ways compare operator
-added lambda expression @(a,b) a + b
-added local function statement
-added array built-in map(),reduce(),apply(),filter() and find()
-generators hold only a weak reference of the enviroment object
-removed 'vargv' and 'vargc' keywords
-now var args are passed as an array called vargv(as a paramter)
-removed 'parent' keyword
-added class getbase() built in method
-instanceof doesn't throw an exception if the left expression is not a class
-lexical scoping for free variables(free variables are no longer in the second parameter list)
-sq_setprintfunc accept error func
-sq_geterrorfunc()
-added sq_arrayremove() and sq_arrayinsert()
-error() built in function(works like print but prints using the errorfunc)
-added native debug hook
***2008-02-17 ***
***version 2.2 stable***
-added _newslot metamethod in classes
-added enums added constants
-added sq_pushconsttable, sq_setconsttable
-added default param
-added octal literals(thx Dinosaur)
-fixed debug hook, 'calls' and 'returns' are properly notified in the same number.
-fixed a coroutine bug
***2007-07-29 ***
***version 2.1.2 stable***
-new behaviour for generators iteration using foreach
now when a generator is iterated by foreach the value returned by a 'return val' statement
will terminate the iteration but will not be returned as foreach iteration
-added sq_setclassudsize()
-added sq_clear()
-added table.clear(), array.clear()
-fixed sq_cmp() (thx jyuill)
-fixed minor bugs
***2006-08-21 ***
***version 2.1.1 stable***
-vm refactoring
-optimized internal function memory layout
-new global symbol _version_ (is the version string)
-code size optimization for float literals(on 32bits float builts)
-now the raw ref API(sq_addref etc...) is fully reentrant.
-fixed a bug in sq_getdelegate() now pushes null if the object doesn't have a delegate(thx MatzeB)
-improved C reference performances in NO_GARBAGE_COLLECTOR builds
-sq_getlocal() now enumerates also outer values.
-fixed regexp library for GCC users.
***2006-03-19 ***
***version 2.1 stable***
-added static class fields, new keyword static
-added 64bits architecture support
-added global slot _intsize_ int the base lib to recognize 32bits and 64bits builds
-added functions with fixed environment, closure.bindenv() built-in function
-all types except userdata and null implement the tostring() method
-string concatenation now invokes metamethod _tostring
-new metamethods for class objects _newmember and _inherited
-sq_call() sq_resume() sq_wakeupvm() have a new signature
-new C referencing implementation(scales more with the amount of references)
-refactored hash table
-new api functions sq_newslot(),sq_tobool(),sq_getbase(), sq_instanceof(), sq_bindenv()
-the api func sq_createslot was deprecated but still supported in form of C macro on top of sq_newslot
-sq_setreleasehook() now also works for classes
-stream.readstr() and stream.writestr() have been deprecated(this affects file and blob)
-fixed squirrel.h undeclared api calls
-fixed few minor bugs
-SQChar is now defined as wchar_t
-removed warning when building with -Wall -pedantic for GCC users
-added new std io function writeclosuretofile()
-added new std string functions strip(),rstrip(),lstrip() and split()
-regular expressions operators (+,*) now have more POSIX greedyness behaviour
-class constructors are now invoked as normal functions
***2005-10-02 ***
***version 2.0.5 stable***
-fixed some 64bits incompatibilities (thx sarge)
-fixed minor bug in the stdlib format() function (thx Rick)
-fixed a bug in dofile() that was preventing to compile empty files
-added new API sq_poptop() & sq_getfreevariable()
-some performance improvements
***2005-08-14 ***
***version 2.0.4 stable***
-weak references and related API calls
-added sq_objtobool()
-class instances memory policies improved(1 mem allocation for the whole instance)
-typetags are now declared as SQUserPointer instead of unsigned int
-first pass for 64bits compatibility
-fixed minor bug in the stdio stream
-fixed a bug in format()
-fixed bug in string.tointeger() and string.tofloat()
***2005-06-24 ***
***version 2.0.3 stable***
-dofile() and loadfile() in the iolib now can decode ASCII, UTF8 files UCS2 big-endian and little-endian
-sq_setparamscheck() : now typemesk can check for null
-added string escape sequence \xhhhh
-fixed some C++ standard incompatibilities
***2005-05-15 ***
***version 2.0.2 stable***
-performances improvements (expecially for GCC users)
-removed all dependencies from C++ exception handling
-various bugfixes
***2005-04-12 ***
***version 2.0.1 stable***
-various bugfixes
-sq_setparamscheck() now allows spaces in the typemask
***2005-04-03 ***
***version 2.0 stable***
-added API sq_gettypetag()
-added built-in function to the bool type(tointeger, tostring etc...)
***2005-02-27 ***
***version 2.0 release candidate 1(RC 1)***
-added API sq_reseterror()
-modified sq_release()
-now class instances can be cloned
-various bufixes
***2005-01-26 ***
***version 2.0 beta 1***
-added bool type
-class properties can be redefined in a derived class
-added ops *= /= and %=
-new syntax for class attributes declaration </ and /> instead of ( and )
-increased the max number of literals per function from 65535 to 16777215
-now free variables have proper lexical scoping
-added API sq_createinstance(), sq_pushbool(), sq_getbool()
-added built-in function type()
-added built-in function obj.rawin(key) in table,class and instance
-sq_rawget() and sq_rawset() now work also on classes and instances
-the VM no longer uses C++ exception handling (more suitable for embedded devices)
-various bufixes
***2004-12-21 ***
***version 2.0 alpha 2***
-globals scoping changed, now if :: is omitted the VM automatically falls back on the root table
-various bufixes
-added class level attributes
***2004-12-12 ***
***version 2.0 alpha 1***
-codebase branch from version 1.x
-added classes
-added functions with variable number of parameters(vargc & vargv and the ...)
-0 and 0.0 are now considered 'false' by all conditional statements(if,while,for,?,do-while)
-added new api functions sq_newclass() sq_setinstanceup() sq_getinstanceup() sq_getattributes() sq_setattributes()
-modified api sq_settypetag()
***2004-11-01 ***
***version 1.0 stable***
-fixed some minor bug
-improved operator 'delete' performances
-added scientific notation for float numbers( eg. 2.e16 or 2.e-2)
***2004-08-30 ***
***version 1.0 release candidate 2(RC 2)***
-fixed bug in the vm(thx Pierre Renaux)
-fixed bug in the optimizer(thx Pierre Renaux)
-fixed some bug in the documentation(thx JD)
-added new api functions for raw object handling
-removed nested multiline comments
-reduced memory footprint in C references
***2004-08-23 ***
***version 1.0 release candidate 1(RC 1)***
-fixed division by zero
-the 'in' operator and obj.rawget() do not query the default delegate anymore
-added function sq_getprintfunc()
-added new standard library 'auxlib'(implements default error handlers)
***2004-07-12 ***
***version 1.0 beta 4***
-fixed a bug in the integer.tochar() built-in method
-fixed unary minus operator
-fixed bug in dofile()
-fixed inconsistency between != and == operators(on float/integer comparison)
-added javascript style unsigned right shift operator '>>>'
-added array(size) constructor built-in function
-array.resize(size,[fill]) built-in function accepts an optional 'fill' value
-improved debug API, added sq_getclosureinfo() and sq_setnativeclosurename()
***2004-05-23 ***
***version 1.0 beta 3***
-minor vm bug fixes
-string allocation is now faster
-tables and array memory usage is now less conservative(they shrink)
-added regular expression routines in the standard library
-The 'c' expression now accepts only 1 character(thx irbrian)
-multiline strings <[ ]> have been substituted with C# style verbatim strings (eg. @"string")
-added new keyword 'parent' for accessing the delegate of tables and unserdata
-The metamethod '_clone' has been renamed '_cloned'
-the _delslot metamethod's behaviour and prototype have been changed
-new default function in the integer and float object 'tochar()'
-the built-in function chcode2string has been removed
-the default method [table].getdelegate() has been removed
-new api sq_rawdeleteslot()
-new table built-in method rawdelete(key)
-the dynamic mudule loading has been removed from the standard distribution
-some optimizations in the VM
***2004-04-21 ***
***version 1.0 beta 2***
-minor compiler/parser bug fixes
-sq_newclosure has a different prototype, the "paramscheck" of paramter has been moved to the new function sq_setparamscheck()
-sq_setparamscheck allows to add automatic parameters type checking in native closures
-sq_compile() lost the lineinfo parameter
-new api sq_enabledebuginfo() globally sets compiler's debug info generation
-added consistency check on bytecode serialization
-fixed += operator, now works on strings like +
-added global slot in the base lib _charsize_ to recognize unicode builds from ascii builds runtime
-added registry table
-new api call sq_pushregistrytable()
-added type tag to the userdata type sq_settypetag()
-sq_getuserdata now queries the userdata typetag
-the built in function collect_garbage() as been renamed collectgarbage() for consistency reasons
-new standard libraries(sqlibs are now obsolete)
***2004-02-20 ***
***version 1.0 beta 1***
-fixed a bug in the compiler (thanks Martin Kofler)
-fixed bug in the switch case statement
-fixed the _unm metamethod
-fixed minor bugs in the API
-fixed automatic stack resizing
-first beta version
first pass code clean up in the VM and base lib
first pass code coverege test has been done on VM and built-in lib
-new VM creation API sq_open() sq_close() (sq_newvm and sq_releasevm are now obsolete)
-new api allows to specifiy a "print" function to output text(sq_printfunc)
-added some small optimizations
-new cooperative multi-threading capabilities in the base library(coroutines), VMs are now a built in type("thread")
-new built in functions have been added for manipulating the new "thread" type
-friend virtual machines share the same root table, error handler and debug hook by default
-new compile time options
***2004-01-19 ***
***version 0.9 alpha***
-fixed a garbage collection bug
-fixed some API bugs(thanks to Joshua Jensen)
-fixed tail calls (in the version 0.8 the tail call optimization was erroneously disabled)
-new function parameters semantic, now passing a wrong number of parameters generates an exception
-native closures have now a built in parameter number checking
-sq_rawget and sq_rawset now work also on arrays
-sq_getsize now woks also on userdata
-the userdata release hook prototype is changed(now passes the size of the userdata)
-the lexer reader function now returns an integer instead of a char that allows better error checking on the input(thx Joshua Jensen)
-faster compiler
-try/catch blocks do not cause any runtime memory allocation anymore
***2003-12-06 ***
***version 0.8 alpha***
-fixed a bug that was preventing to have callable userdata throught the metamethod _call
-fixed a garbage collection bug
-fixed == operator now can compare correctly different types
-new built in method getstackinfos(level)
-improved line informations precision for the debug hook
-new api call sq_compilebuffer()
-new built-in api function compilestring()
-new syntactic sugar for function declarations inside tables
-the debug API has been finalized
***2003-11-17 ***
***version 0.7 alpha***
-fixed critical bug SQInteger the tail call system
-fixed bug in the continue statement code generation
-fixed func call param issue(thanks to Rewoonenco Andrew)
-added _delslot metamethod(thanks to Rewoonenco Andrew)
-new multiline string expression ( delimited by <[ and ]> )
-normal strings ("") do not allow embedded new line anymore
-reduced vm memory footprint(C refs are shared between friend VMs)
-new api method sq_deleteslot()
-new debug hook event 'r' is triggered when a function returns
***2003-11-04 ***
***version 0.6 alpha***
-fixed switch statement(was executing the default case after a break)
-sq_call() doesn't pop the closure (just the params)
-the vm execution can be suspended from the C API anytime (micro-threads)
-new api calls sq_suspendvm() sq_wakeupvm() sq_getvmstate() and sq_reservestack()
***2003-10-13 ***
***version 0.5 alpha***
-fixed some minor bug
-tested with non ASCII identifiers in unicode mode(I've tried chinese chars)
-added built-in function string.find()
-the built-in function array.sort() optionally accepts a cmp(a,b) function
-the debug hook function now has a new prototype debug_hook(event_type,sourcefile,line,functionname)
-fixed some debug info imprecision
***2003-10-01 ***
***version 0.4 alpha***
-faster VM
-sq_call will pop arguments and closure also in case of failure
-fixed a bug in sq_remove
-now the VM detects delegation cycles(and throws an exception)
-new operators ++ and --
-new operator ',' comma operator
-fixed some expression precedence issue
-fixed bug in sq_arraypop
***2003-09-15 ***
***version 0.3 alpha***
-fixed a bug in array::insert()
-optional Unicode core(define SQUNICODE or _UNICODE on Win32)
-sq_compiler uses a new reader function SQLEXREADFUNC
-the debug hook passes 'l' instead of 'line' for line callbacks
and 'c' instead of 'call' for call callbacks
-new array.extend() bulit-in function
-new API sq_clone()
***2003-09-10 ***
***version 0.2 pre-alpha***
-new completely reentrant VM (sq_open and sq_close are now obsolete)
-sq_newvm() has a new prototype
-allocators are now global and linked in the VM
-_newslot meta method added
-rawset creates a slot if doesn't exists
-the compiler error callback pass the vm handle(thanks Pierre Renaux)
-sq_setforeignptr() sq_getforeingptr() are now public
-sq_resume() now is possible to resume generators from C
-sq_getlasterror() retrieve the last thrown error
-improved docs
***2003-09-06 ***
***version 0.1 pre-alpha***
first release

View File

@ -0,0 +1,18 @@
SQUIRREL=.
MAKE=make
sq32:
cd squirrel; $(MAKE)
cd sqstdlib; $(MAKE)
cd sq; $(MAKE)
sqprof:
cd squirrel; $(MAKE) sqprof
cd sqstdlib; $(MAKE) sqprof
cd sq; $(MAKE) sqprof
sq64:
cd squirrel; $(MAKE) sq64
cd sqstdlib; $(MAKE) sq64
cd sq; $(MAKE) sq64

View File

@ -0,0 +1,23 @@
The programming language SQUIRREL 3.0 stable
--------------------------------------------------
The project has been compiled and run on Windows(x86 and x64) and
Linux(x86 and x64) and Solaris(x86 and x64).
Has been tested with the following compilers:
MS Visual C++ 6.0,7.0,7.1,8.0,9.0,10.0 (32 and 64bits)
MinGW gcc 3.2 (mingw special 20020817-1)
Cygnus gcc 3.2
Linux gcc 3.2.3
Linux gcc 4.0.0 (x86 & 64bits)
Solaris gcc 4.0.0 (x86 & 64bits)
Feedback and suggestions are appreciated
project page - http://www.squirrel-lang.org
community forums - http://forum.squirrel-lang.org
wiki - http://wiki.squirrel-lang.org
author - alberto@demichelis.net
END OF README

View File

@ -0,0 +1,16 @@
/* see copyright notice in squirrel.h */
#ifndef _SQSTD_AUXLIB_H_
#define _SQSTD_AUXLIB_H_
#ifdef __cplusplus
extern "C" {
#endif
SQUIRREL_API void sqstd_seterrorhandlers(HSQUIRRELVM v);
SQUIRREL_API void sqstd_printcallstack(HSQUIRRELVM v);
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /* _SQSTD_AUXLIB_H_ */

View File

@ -0,0 +1,20 @@
/* see copyright notice in squirrel.h */
#ifndef _SQSTDBLOB_H_
#define _SQSTDBLOB_H_
#ifdef __cplusplus
extern "C" {
#endif
SQUIRREL_API SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size);
SQUIRREL_API SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr);
SQUIRREL_API SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sqstd_register_bloblib(HSQUIRRELVM v);
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*_SQSTDBLOB_H_*/

View File

@ -0,0 +1,53 @@
/* see copyright notice in squirrel.h */
#ifndef _SQSTDIO_H_
#define _SQSTDIO_H_
#ifdef __cplusplus
#define SQSTD_STREAM_TYPE_TAG 0x80000000
struct SQStream {
virtual SQInteger Read(void *buffer, SQInteger size) = 0;
virtual SQInteger Write(void *buffer, SQInteger size) = 0;
virtual SQInteger Flush() = 0;
virtual SQInteger Tell() = 0;
virtual SQInteger Len() = 0;
virtual SQInteger Seek(SQInteger offset, SQInteger origin) = 0;
virtual bool IsValid() = 0;
virtual bool EOS() = 0;
};
extern "C" {
#endif
#define SQ_SEEK_CUR 0
#define SQ_SEEK_END 1
#define SQ_SEEK_SET 2
typedef void* SQFILE;
SQUIRREL_API SQFILE sqstd_fopen(const SQChar *,const SQChar *);
SQUIRREL_API SQInteger sqstd_fread(SQUserPointer, SQInteger, SQInteger, SQFILE);
SQUIRREL_API SQInteger sqstd_fwrite(const SQUserPointer, SQInteger, SQInteger, SQFILE);
SQUIRREL_API SQInteger sqstd_fseek(SQFILE , SQInteger , SQInteger);
SQUIRREL_API SQInteger sqstd_ftell(SQFILE);
SQUIRREL_API SQInteger sqstd_fflush(SQFILE);
SQUIRREL_API SQInteger sqstd_fclose(SQFILE);
SQUIRREL_API SQInteger sqstd_feof(SQFILE);
SQUIRREL_API SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own);
SQUIRREL_API SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file);
//compiler helpers
SQUIRREL_API SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror);
SQUIRREL_API SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror);
SQUIRREL_API SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename);
SQUIRREL_API SQRESULT sqstd_register_iolib(HSQUIRRELVM v);
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*_SQSTDIO_H_*/

View File

@ -0,0 +1,15 @@
/* see copyright notice in squirrel.h */
#ifndef _SQSTD_MATH_H_
#define _SQSTD_MATH_H_
#ifdef __cplusplus
extern "C" {
#endif
SQUIRREL_API SQRESULT sqstd_register_mathlib(HSQUIRRELVM v);
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*_SQSTD_MATH_H_*/

View File

@ -0,0 +1,33 @@
/* see copyright notice in squirrel.h */
#ifndef _SQSTD_STRING_H_
#define _SQSTD_STRING_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned int SQRexBool;
typedef struct SQRex SQRex;
typedef struct {
const SQChar *begin;
SQInteger len;
} SQRexMatch;
SQUIRREL_API SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error);
SQUIRREL_API void sqstd_rex_free(SQRex *exp);
SQUIRREL_API SQBool sqstd_rex_match(SQRex* exp,const SQChar* text);
SQUIRREL_API SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end);
SQUIRREL_API SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end);
SQUIRREL_API SQInteger sqstd_rex_getsubexpcount(SQRex* exp);
SQUIRREL_API SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp);
SQUIRREL_API SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output);
SQUIRREL_API SQRESULT sqstd_register_stringlib(HSQUIRRELVM v);
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*_SQSTD_STRING_H_*/

View File

@ -0,0 +1,15 @@
/* see copyright notice in squirrel.h */
#ifndef _SQSTD_SYSTEMLIB_H_
#define _SQSTD_SYSTEMLIB_H_
#ifdef __cplusplus
extern "C" {
#endif
SQUIRREL_API SQInteger sqstd_register_systemlib(HSQUIRRELVM v);
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /* _SQSTD_SYSTEMLIB_H_ */

View File

@ -0,0 +1,500 @@
/*
Copyright (c) 2003-2011 Alberto Demichelis
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef _SQUIRREL_H_
#define _SQUIRREL_H_
#ifdef __cplusplus
extern "C" {
#endif
#ifndef SQUIRREL_API
#define SQUIRREL_API extern
#endif
#if (defined(_WIN64) || defined(_LP64))
#ifndef _SQ64
#define _SQ64
#endif
#endif
#ifdef _SQ64
#ifdef _MSC_VER
typedef __int64 SQInteger;
typedef unsigned __int64 SQUnsignedInteger;
typedef unsigned __int64 SQHash; /*should be the same size of a pointer*/
#else
typedef long long SQInteger;
typedef unsigned long long SQUnsignedInteger;
typedef unsigned long long SQHash; /*should be the same size of a pointer*/
#endif
typedef int SQInt32;
typedef unsigned int SQUnsignedInteger32;
#else
typedef int SQInteger;
typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/
typedef unsigned int SQUnsignedInteger32; /*must be 32 bits(also on 64bits processors)*/
typedef unsigned int SQUnsignedInteger;
typedef unsigned int SQHash; /*should be the same size of a pointer*/
#endif
#ifdef SQUSEDOUBLE
typedef double SQFloat;
#else
typedef float SQFloat;
#endif
#if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64)
#ifdef _MSC_VER
typedef __int64 SQRawObjectVal; //must be 64bits
#else
typedef long long SQRawObjectVal; //must be 64bits
#endif
#define SQ_OBJECT_RAWINIT() { _unVal.raw = 0; }
#else
typedef SQUnsignedInteger SQRawObjectVal; //is 32 bits on 32 bits builds and 64 bits otherwise
#define SQ_OBJECT_RAWINIT()
#endif
#ifndef SQ_ALIGNMENT // SQ_ALIGNMENT shall be less than or equal to SQ_MALLOC alignments, and its value shall be power of 2.
#if defined(SQUSEDOUBLE) || defined(_SQ64)
#define SQ_ALIGNMENT 8
#else
#define SQ_ALIGNMENT 4
#endif
#endif
typedef void* SQUserPointer;
typedef SQUnsignedInteger SQBool;
typedef SQInteger SQRESULT;
#define SQTrue (1)
#define SQFalse (0)
struct SQVM;
struct SQTable;
struct SQArray;
struct SQString;
struct SQClosure;
struct SQGenerator;
struct SQNativeClosure;
struct SQUserData;
struct SQFunctionProto;
struct SQRefCounted;
struct SQClass;
struct SQInstance;
struct SQDelegable;
struct SQOuter;
#ifdef _UNICODE
#define SQUNICODE
#endif
#ifdef SQUNICODE
#if (defined(_MSC_VER) && _MSC_VER >= 1400) // 1400 = VS8
#if !defined(_NATIVE_WCHAR_T_DEFINED) //this is if the compiler considers wchar_t as native type
#define wchar_t unsigned short
#endif
#else
typedef unsigned short wchar_t;
#endif
typedef wchar_t SQChar;
#define _SC(a) L##a
#define scstrcmp wcscmp
#define scsprintf swprintf
#define scstrlen wcslen
#define scstrtod wcstod
#ifdef _SQ64
#define scstrtol _wcstoi64
#else
#define scstrtol wcstol
#endif
#define scatoi _wtoi
#define scstrtoul wcstoul
#define scvsprintf vswprintf
#define scstrstr wcsstr
#define scisspace iswspace
#define scisdigit iswdigit
#define scisxdigit iswxdigit
#define scisalpha iswalpha
#define sciscntrl iswcntrl
#define scisalnum iswalnum
#define scprintf wprintf
#define MAX_CHAR 0xFFFF
#else
typedef char SQChar;
#define _SC(a) a
#define scstrcmp strcmp
#define scsprintf sprintf
#define scstrlen strlen
#define scstrtod strtod
#ifdef _SQ64
#ifdef _MSC_VER
#define scstrtol _strtoi64
#else
#define scstrtol strtoll
#endif
#else
#define scstrtol strtol
#endif
#define scatoi atoi
#define scstrtoul strtoul
#define scvsprintf vsprintf
#define scstrstr strstr
#define scisspace isspace
#define scisdigit isdigit
#define scisxdigit isxdigit
#define sciscntrl iscntrl
#define scisalpha isalpha
#define scisalnum isalnum
#define scprintf printf
#define MAX_CHAR 0xFF
#endif
#ifdef _SQ64
#define _PRINT_INT_PREC _SC("ll")
#define _PRINT_INT_FMT _SC("%lld")
#else
#define _PRINT_INT_FMT _SC("%d")
#endif
#define SQUIRREL_VERSION _SC("Squirrel 3.0.1 stable")
#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2011 Alberto Demichelis")
#define SQUIRREL_AUTHOR _SC("Alberto Demichelis")
#define SQUIRREL_VERSION_NUMBER 301
#define SQ_VMSTATE_IDLE 0
#define SQ_VMSTATE_RUNNING 1
#define SQ_VMSTATE_SUSPENDED 2
#define SQUIRREL_EOB 0
#define SQ_BYTECODE_STREAM_TAG 0xFAFA
#define SQOBJECT_REF_COUNTED 0x08000000
#define SQOBJECT_NUMERIC 0x04000000
#define SQOBJECT_DELEGABLE 0x02000000
#define SQOBJECT_CANBEFALSE 0x01000000
#define SQ_MATCHTYPEMASKSTRING (-99999)
#define _RT_MASK 0x00FFFFFF
#define _RAW_TYPE(type) (type&_RT_MASK)
#define _RT_NULL 0x00000001
#define _RT_INTEGER 0x00000002
#define _RT_FLOAT 0x00000004
#define _RT_BOOL 0x00000008
#define _RT_STRING 0x00000010
#define _RT_TABLE 0x00000020
#define _RT_ARRAY 0x00000040
#define _RT_USERDATA 0x00000080
#define _RT_CLOSURE 0x00000100
#define _RT_NATIVECLOSURE 0x00000200
#define _RT_GENERATOR 0x00000400
#define _RT_USERPOINTER 0x00000800
#define _RT_THREAD 0x00001000
#define _RT_FUNCPROTO 0x00002000
#define _RT_CLASS 0x00004000
#define _RT_INSTANCE 0x00008000
#define _RT_WEAKREF 0x00010000
#define _RT_OUTER 0x00020000
typedef enum tagSQObjectType{
OT_NULL = (_RT_NULL|SQOBJECT_CANBEFALSE),
OT_INTEGER = (_RT_INTEGER|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
OT_FLOAT = (_RT_FLOAT|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
OT_BOOL = (_RT_BOOL|SQOBJECT_CANBEFALSE),
OT_STRING = (_RT_STRING|SQOBJECT_REF_COUNTED),
OT_TABLE = (_RT_TABLE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
OT_ARRAY = (_RT_ARRAY|SQOBJECT_REF_COUNTED),
OT_USERDATA = (_RT_USERDATA|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
OT_CLOSURE = (_RT_CLOSURE|SQOBJECT_REF_COUNTED),
OT_NATIVECLOSURE = (_RT_NATIVECLOSURE|SQOBJECT_REF_COUNTED),
OT_GENERATOR = (_RT_GENERATOR|SQOBJECT_REF_COUNTED),
OT_USERPOINTER = _RT_USERPOINTER,
OT_THREAD = (_RT_THREAD|SQOBJECT_REF_COUNTED) ,
OT_FUNCPROTO = (_RT_FUNCPROTO|SQOBJECT_REF_COUNTED), //internal usage only
OT_CLASS = (_RT_CLASS|SQOBJECT_REF_COUNTED),
OT_INSTANCE = (_RT_INSTANCE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
OT_WEAKREF = (_RT_WEAKREF|SQOBJECT_REF_COUNTED),
OT_OUTER = (_RT_OUTER|SQOBJECT_REF_COUNTED) //internal usage only
}SQObjectType;
#define ISREFCOUNTED(t) (t&SQOBJECT_REF_COUNTED)
typedef union tagSQObjectValue
{
struct SQTable *pTable;
struct SQArray *pArray;
struct SQClosure *pClosure;
struct SQOuter *pOuter;
struct SQGenerator *pGenerator;
struct SQNativeClosure *pNativeClosure;
struct SQString *pString;
struct SQUserData *pUserData;
SQInteger nInteger;
SQFloat fFloat;
SQUserPointer pUserPointer;
struct SQFunctionProto *pFunctionProto;
struct SQRefCounted *pRefCounted;
struct SQDelegable *pDelegable;
struct SQVM *pThread;
struct SQClass *pClass;
struct SQInstance *pInstance;
struct SQWeakRef *pWeakRef;
SQRawObjectVal raw;
}SQObjectValue;
typedef struct tagSQObject
{
SQObjectType _type;
SQObjectValue _unVal;
}SQObject;
typedef struct tagSQMemberHandle{
SQBool _static;
SQInteger _index;
}SQMemberHandle;
typedef struct tagSQStackInfos{
const SQChar* funcname;
const SQChar* source;
SQInteger line;
}SQStackInfos;
typedef struct SQVM* HSQUIRRELVM;
typedef SQObject HSQOBJECT;
typedef SQMemberHandle HSQMEMBERHANDLE;
typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM);
typedef SQInteger (*SQRELEASEHOOK)(SQUserPointer,SQInteger size);
typedef void (*SQCOMPILERERROR)(HSQUIRRELVM,const SQChar * /*desc*/,const SQChar * /*source*/,SQInteger /*line*/,SQInteger /*column*/);
typedef void (*SQPRINTFUNCTION)(HSQUIRRELVM,const SQChar * ,...);
typedef void (*SQDEBUGHOOK)(HSQUIRRELVM /*v*/, SQInteger /*type*/, const SQChar * /*sourcename*/, SQInteger /*line*/, const SQChar * /*funcname*/);
typedef SQInteger (*SQWRITEFUNC)(SQUserPointer,SQUserPointer,SQInteger);
typedef SQInteger (*SQREADFUNC)(SQUserPointer,SQUserPointer,SQInteger);
typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer);
typedef struct tagSQRegFunction{
const SQChar *name;
SQFUNCTION f;
SQInteger nparamscheck;
const SQChar *typemask;
}SQRegFunction;
typedef struct tagSQFunctionInfo {
SQUserPointer funcid;
const SQChar *name;
const SQChar *source;
}SQFunctionInfo;
/*vm*/
SQUIRREL_API HSQUIRRELVM sq_open(SQInteger initialstacksize);
SQUIRREL_API HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize);
SQUIRREL_API void sq_seterrorhandler(HSQUIRRELVM v);
SQUIRREL_API void sq_close(HSQUIRRELVM v);
SQUIRREL_API void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p);
SQUIRREL_API SQUserPointer sq_getforeignptr(HSQUIRRELVM v);
SQUIRREL_API void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc,SQPRINTFUNCTION errfunc);
SQUIRREL_API SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v);
SQUIRREL_API SQPRINTFUNCTION sq_geterrorfunc(HSQUIRRELVM v);
SQUIRREL_API SQRESULT sq_suspendvm(HSQUIRRELVM v);
SQUIRREL_API SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool resumedret,SQBool retval,SQBool raiseerror,SQBool throwerror);
SQUIRREL_API SQInteger sq_getvmstate(HSQUIRRELVM v);
/*compiler*/
SQUIRREL_API SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror);
SQUIRREL_API SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror);
SQUIRREL_API void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable);
SQUIRREL_API void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable);
SQUIRREL_API void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f);
/*stack operations*/
SQUIRREL_API void sq_push(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API void sq_pop(HSQUIRRELVM v,SQInteger nelemstopop);
SQUIRREL_API void sq_poptop(HSQUIRRELVM v);
SQUIRREL_API void sq_remove(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQInteger sq_gettop(HSQUIRRELVM v);
SQUIRREL_API void sq_settop(HSQUIRRELVM v,SQInteger newtop);
SQUIRREL_API SQRESULT sq_reservestack(HSQUIRRELVM v,SQInteger nsize);
SQUIRREL_API SQInteger sq_cmp(HSQUIRRELVM v);
SQUIRREL_API void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx);
/*object creation handling*/
SQUIRREL_API SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size);
SQUIRREL_API void sq_newtable(HSQUIRRELVM v);
SQUIRREL_API void sq_newtableex(HSQUIRRELVM v,SQInteger initialcapacity);
SQUIRREL_API void sq_newarray(HSQUIRRELVM v,SQInteger size);
SQUIRREL_API void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars);
SQUIRREL_API SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask);
SQUIRREL_API SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len);
SQUIRREL_API void sq_pushfloat(HSQUIRRELVM v,SQFloat f);
SQUIRREL_API void sq_pushinteger(HSQUIRRELVM v,SQInteger n);
SQUIRREL_API void sq_pushbool(HSQUIRRELVM v,SQBool b);
SQUIRREL_API void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p);
SQUIRREL_API void sq_pushnull(HSQUIRRELVM v);
SQUIRREL_API SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQInteger sq_getsize(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQBool sq_instanceof(HSQUIRRELVM v);
SQUIRREL_API SQRESULT sq_tostring(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b);
SQUIRREL_API SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c);
SQUIRREL_API SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i);
SQUIRREL_API SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f);
SQUIRREL_API SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b);
SQUIRREL_API SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread);
SQUIRREL_API SQRESULT sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p);
SQUIRREL_API SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag);
SQUIRREL_API SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag);
SQUIRREL_API SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag);
SQUIRREL_API void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook);
SQUIRREL_API SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize);
SQUIRREL_API SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger idx,SQFunctionInfo *fi);
SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars);
SQUIRREL_API SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name);
SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p);
SQUIRREL_API SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag);
SQUIRREL_API SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize);
SQUIRREL_API SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase);
SQUIRREL_API SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API void sq_weakref(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t);
SQUIRREL_API SQRESULT sq_getmemberhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle);
SQUIRREL_API SQRESULT sq_getbyhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle);
SQUIRREL_API SQRESULT sq_setbyhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle);
/*object manipulation*/
SQUIRREL_API void sq_pushroottable(HSQUIRRELVM v);
SQUIRREL_API void sq_pushregistrytable(HSQUIRRELVM v);
SQUIRREL_API void sq_pushconsttable(HSQUIRRELVM v);
SQUIRREL_API SQRESULT sq_setroottable(HSQUIRRELVM v);
SQUIRREL_API SQRESULT sq_setconsttable(HSQUIRRELVM v);
SQUIRREL_API SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic);
SQUIRREL_API SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
SQUIRREL_API SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
SQUIRREL_API SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
SQUIRREL_API SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize);
SQUIRREL_API SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx);
SQUIRREL_API SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos);
SQUIRREL_API SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval);
SQUIRREL_API SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx);
/*calls*/
SQUIRREL_API SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror);
SQUIRREL_API SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror);
SQUIRREL_API const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx);
SQUIRREL_API SQRESULT sq_getcallee(HSQUIRRELVM v);
SQUIRREL_API const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval);
SQUIRREL_API SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err);
SQUIRREL_API SQRESULT sq_throwobject(HSQUIRRELVM v);
SQUIRREL_API void sq_reseterror(HSQUIRRELVM v);
SQUIRREL_API void sq_getlasterror(HSQUIRRELVM v);
/*raw object handling*/
SQUIRREL_API SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po);
SQUIRREL_API void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj);
SQUIRREL_API void sq_addref(HSQUIRRELVM v,HSQOBJECT *po);
SQUIRREL_API SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po);
SQUIRREL_API SQUnsignedInteger sq_getrefcount(HSQUIRRELVM v,HSQOBJECT *po);
SQUIRREL_API void sq_resetobject(HSQOBJECT *po);
SQUIRREL_API const SQChar *sq_objtostring(const HSQOBJECT *o);
SQUIRREL_API SQBool sq_objtobool(const HSQOBJECT *o);
SQUIRREL_API SQInteger sq_objtointeger(const HSQOBJECT *o);
SQUIRREL_API SQFloat sq_objtofloat(const HSQOBJECT *o);
SQUIRREL_API SQUserPointer sq_objtouserpointer(const HSQOBJECT *o);
SQUIRREL_API SQRESULT sq_getobjtypetag(const HSQOBJECT *o,SQUserPointer * typetag);
/*GC*/
SQUIRREL_API SQInteger sq_collectgarbage(HSQUIRRELVM v);
SQUIRREL_API SQRESULT sq_resurrectunreachable(HSQUIRRELVM v);
/*serialization*/
SQUIRREL_API SQRESULT sq_writeclosure(HSQUIRRELVM vm,SQWRITEFUNC writef,SQUserPointer up);
SQUIRREL_API SQRESULT sq_readclosure(HSQUIRRELVM vm,SQREADFUNC readf,SQUserPointer up);
/*mem allocation*/
SQUIRREL_API void *sq_malloc(SQUnsignedInteger size);
SQUIRREL_API void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize);
SQUIRREL_API void sq_free(void *p,SQUnsignedInteger size);
/*debug*/
SQUIRREL_API SQRESULT sq_stackinfos(HSQUIRRELVM v,SQInteger level,SQStackInfos *si);
SQUIRREL_API void sq_setdebughook(HSQUIRRELVM v);
SQUIRREL_API void sq_setnativedebughook(HSQUIRRELVM v,SQDEBUGHOOK hook);
/*UTILITY MACRO*/
#define sq_isnumeric(o) ((o)._type&SQOBJECT_NUMERIC)
#define sq_istable(o) ((o)._type==OT_TABLE)
#define sq_isarray(o) ((o)._type==OT_ARRAY)
#define sq_isfunction(o) ((o)._type==OT_FUNCPROTO)
#define sq_isclosure(o) ((o)._type==OT_CLOSURE)
#define sq_isgenerator(o) ((o)._type==OT_GENERATOR)
#define sq_isnativeclosure(o) ((o)._type==OT_NATIVECLOSURE)
#define sq_isstring(o) ((o)._type==OT_STRING)
#define sq_isinteger(o) ((o)._type==OT_INTEGER)
#define sq_isfloat(o) ((o)._type==OT_FLOAT)
#define sq_isuserpointer(o) ((o)._type==OT_USERPOINTER)
#define sq_isuserdata(o) ((o)._type==OT_USERDATA)
#define sq_isthread(o) ((o)._type==OT_THREAD)
#define sq_isnull(o) ((o)._type==OT_NULL)
#define sq_isclass(o) ((o)._type==OT_CLASS)
#define sq_isinstance(o) ((o)._type==OT_INSTANCE)
#define sq_isbool(o) ((o)._type==OT_BOOL)
#define sq_isweakref(o) ((o)._type==OT_WEAKREF)
#define sq_type(o) ((o)._type)
/* deprecated */
#define sq_createslot(v,n) sq_newslot(v,n,SQFalse)
#define SQ_OK (0)
#define SQ_ERROR (-1)
#define SQ_FAILED(res) (res<0)
#define SQ_SUCCEEDED(res) (res>=0)
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*_SQUIRREL_H_*/

View File

@ -0,0 +1,18 @@
SQUIRREL= ..
OUT= $(SQUIRREL)/lib/libsqplus.a
INCDIRS= -I$(SQUIRREL)/include -I. -Iinclude
ALLSRCS = $(wildcard *.cpp)
WIN32SRCS = $(wildcard *Win32*)
SRCS = $(filter-out $(WIN32SRCS),$(ALLSRCS))
sqplus:
# g++ -fno-rtti -c $(SRCS) $(INCDIRS)
g++ -O3 -fno-rtti -Os -c $(SRCS) $(INCDIRS)
ar rc $(OUT) *.o
rm *.o
#g++ -O3 -fno-rtti -Os -c $(SRCS) $(INCDIRS)
#g++ -ggdb -fno-rtti -c $(SRCS) $(INCDIRS)

View File

@ -0,0 +1,382 @@
#include "sqplus.h"
#include <stdio.h>
#ifdef SQPLUS_SMARTPOINTER_OPT
#define SQPLUS_SMARTPOINTER_CPP_DECLARATION
#include "SqPlusSmartPointer.h"
#endif
namespace SqPlus {
static int getVarInfo(StackHandler & sa,VarRefPtr & vr) {
HSQOBJECT htable = sa.GetObjectHandle(1);
SquirrelObject table(htable);
const SQChar * el = sa.GetString(2);
ScriptStringVar256 varNameTag;
getVarNameTag(varNameTag,sizeof(varNameTag),el);
SQUserPointer data=0;
if (!table.RawGetUserData(varNameTag,&data)) {
return sa.ThrowError(_SC("getVarInfo: Could not retrieve UserData")); // Results in variable not being found error.
}
vr = (VarRefPtr)data;
return SQ_OK;
} // getVarInfo
static int getInstanceVarInfo(StackHandler & sa,VarRefPtr & vr,SQUserPointer & data) {
HSQOBJECT ho = sa.GetObjectHandle(1);
SquirrelObject instance(ho);
const SQChar * el = sa.GetString(2);
ScriptStringVar256 varNameTag;
getVarNameTag(varNameTag,sizeof(varNameTag),el);
SQUserPointer ivrData=0;
if (!instance.RawGetUserData(varNameTag,&ivrData)) {
return sa.ThrowError(_SC("getInstanceVarInfo: Could not retrieve UserData")); // Results in variable not being found error.
}
vr = (VarRefPtr)ivrData;
char * up;
if (!(vr->m_access & (VAR_ACCESS_STATIC|VAR_ACCESS_CONSTANT))) {
SQUserPointer typetag;
instance.GetTypeTag(&typetag);
#if defined(SQ_USE_CLASS_INHERITANCE)
if (typetag != vr->instanceType) {
SquirrelObject typeTable = instance.GetValue(SQ_CLASS_OBJECT_TABLE_NAME);
up = (char *)typeTable.GetUserPointer(INT((size_t)vr->instanceType)); // <TODO> 64-bit compatible version.
if (!up) {
throw SquirrelError(_SC("Invalid Instance Type"));
}
} else {
up = (char *)instance.GetInstanceUP(0);
} // if
#elif defined(SQ_USE_CLASS_INHERITANCE_SIMPLE)
ClassTypeBase *ctb = (ClassTypeBase*)vr->instanceType;
up = (char *)instance.GetInstanceUP(0);
// Walk base classes until type tag match, adjust for inheritence offset
while(ctb && typetag!=ctb) {
up = (char*)up - ctb->m_offset;
ctb = ctb->m_pbase;
}
if (!ctb) {
throw SquirrelError(_SC("Invalid Instance Type"));
}
#else
up = (char *)instance.GetInstanceUP(0);
#endif
#ifdef SQPLUS_SMARTPOINTER_OPT
#define SQPLUS_SMARTPOINTER_INSTANCE_VARINFO
#include "SqPlusSmartPointer.h"
#endif
up += (size_t)vr->offsetOrAddrOrConst; // Offset
} else {
up = (char *)vr->offsetOrAddrOrConst; // Address
} // if
data = up;
return SQ_OK;
} // getInstanceVarInfo
// If not static/global, message can (and will) disappear before arriving at catch (G++)
static ScriptStringVar256 g_msg_throw;
static int setVar(StackHandler & sa,VarRef * vr,void * data) {
if (vr->m_access & (VAR_ACCESS_READ_ONLY|VAR_ACCESS_CONSTANT)) {
const SQChar * el = sa.GetString(2);
SCSNPRINTF(g_msg_throw.s,sizeof(g_msg_throw),_SC("setVar(): Cannot write to constant: %s"),el);
throw SquirrelError(g_msg_throw.s);
} // if
switch (vr->m_type) {
case TypeInfo<INT>::TypeID: {
INT * val = (INT *)data; // Address
if (val) {
INT v = sa.GetInt(3);
// Support for different int sizes
switch( vr->m_size ) {
case 1: v = (*(char*)val = (char)v); break;
case 2: v = (*(short*)val = (short)v); break;
#ifdef _SQ64
case 4: v = (*(int*)val = (int)v); break;
#endif
default: *val = v;
}
return sa.Return(v);
} // if
break;
} // case
case TypeInfo<unsigned>::TypeID: {
unsigned * val = (unsigned *)data; // Address
if (val) {
*val = sa.GetInt(3);
return sa.Return(static_cast<INT>(*val));
} // if
break;
} // case
case TypeInfo<FLOAT>::TypeID: {
FLOAT * val = (FLOAT *)data; // Address
if (val) {
*val = sa.GetFloat(3);
return sa.Return(*val);
} // if
break;
} // case
case TypeInfo<bool>::TypeID: {
bool * val = (bool *)data; // Address
if (val) {
*val = sa.GetBool(3) ? true : false;
return sa.Return(*val);
} // if
break;
} // case
case VAR_TYPE_INSTANCE: {
HSQUIRRELVM v = sa.GetVMPtr();
SQUserPointer src = sa.GetInstanceUp(3,(SQUserPointer)vr->varType); // Effectively performs: ClassType<>::type() == ClassType<>().
if (!src) {
throw SquirrelError(_SC("INSTANCE type assignment mismatch"));
}
vr->varType->vgetCopyFunc()(data,src);
return 0;
}
case TypeInfo<SQUserPointer>::TypeID: {
const SQChar * el = sa.GetString(2);
SCSNPRINTF(g_msg_throw.s,sizeof(g_msg_throw),_SC("setVar(): Cannot write to an SQUserPointer: %s"),el);
throw SquirrelError(g_msg_throw.s);
} // case
case TypeInfo<ScriptStringVarBase>::TypeID: {
ScriptStringVarBase * val = (ScriptStringVarBase *)data; // Address
if (val) {
const SQChar * strVal = sa.GetString(3);
if (strVal) {
*val = strVal;
return sa.Return(val->s);
} // if
} // if
break;
} // case
#if defined(SQPLUS_SUPPORT_STD_STRING) && !defined(SQUNICODE)
case TypeInfo<std::string>::TypeID: {
std::string *val = (std::string*)data; // Address
if (val) {
const SQChar *strVal = sa.GetString(3);
if (strVal) {
*val = strVal;
return sa.Return(val->c_str());
} // if
} // if
break;
} // case
#endif
} // switch
return SQ_ERROR;
} // setVar
static int getVar(StackHandler & sa,VarRef * vr,void * data) {
switch (vr->m_type) {
case TypeInfo<INT>::TypeID: {
if (!(vr->m_access & VAR_ACCESS_CONSTANT)) {
if (data) {
INT v;
// Support for different int sizes
switch( vr->m_size ){
case 1: v = *(char*)data; break;
case 2: v = *(short*)data; break;
#ifdef _SQ64
case 4: v = *(int*)data; break;
#endif
default: v = *(INT*)data;
}
return sa.Return(v);
} // if
} else {
INT * val = (INT *)&data; // Constant value
return sa.Return(*val);
} // if
break;
} // case
case TypeInfo<unsigned>::TypeID: {
if (!(vr->m_access & VAR_ACCESS_CONSTANT)) {
unsigned * val = (unsigned *)data; // Address
if (val){
return sa.Return(static_cast<INT>(*val));
}
} else {
unsigned * val = (unsigned *)&data; // Constant value
return sa.Return(static_cast<INT>(*val));
} // if
break;
} // case
case TypeInfo<FLOAT>::TypeID: {
if (!(vr->m_access & VAR_ACCESS_CONSTANT)) {
FLOAT * val = (FLOAT *)data; // Address
if (val) {
return sa.Return(*val);
} // if
} else {
FLOAT * val = (FLOAT *)&data; // Constant value
return sa.Return(*val);
} // if
break;
} // case
case TypeInfo<bool>::TypeID: {
if (!(vr->m_access & VAR_ACCESS_CONSTANT)) {
bool * val = (bool *)data; // Address
if (val) {
return sa.Return(*val);
} // if
} else {
bool * val = (bool *)&data; // Constant value
return sa.Return(*val);
} // if
break;
} // case
case VAR_TYPE_INSTANCE:
if (!CreateNativeClassInstance(sa.GetVMPtr(),vr->varType->GetTypeName(),data,0)) { // data = address. Allocates memory.
SCSNPRINTF(g_msg_throw.s,sizeof(g_msg_throw),_SC("getVar(): Could not create instance: %s"),vr->varType->GetTypeName());
throw SquirrelError(g_msg_throw.s);
} // if
return 1;
case TypeInfo<SQUserPointer>::TypeID:
return sa.Return(data); // The address of member variable, not the variable itself.
case TypeInfo<ScriptStringVarBase>::TypeID: {
if (!(vr->m_access & VAR_ACCESS_CONSTANT)) {
ScriptStringVarBase * val = (ScriptStringVarBase *)data; // Address
if (val) {
return sa.Return(val->s);
} // if
} else {
throw SquirrelError(_SC("getVar(): Invalid type+access: 'ScriptStringVarBase' with VAR_ACCESS_CONSTANT (use VAR_ACCESS_READ_ONLY instead)"));
}
break;
} // case
case TypeInfo<const SQChar *>::TypeID: {
if (!(vr->m_access & VAR_ACCESS_CONSTANT)) {
if( vr->m_access==VAR_ACCESS_READ_WRITE )
throw SquirrelError(_SC("getVar(): Invalid type+access: 'const SQChar *' without VAR_ACCESS_CONSTANT"));
// It is OK to read from a SQChar* if requested
return sa.Return(*(const SQChar **)data); // Address
} else {
return sa.Return((const SQChar *)data); // Address
}
break;
} // case
#ifdef SQPLUS_SUPPORT_STD_STRING
case TypeInfo<std::string>::TypeID: {
if (!(vr->m_access & VAR_ACCESS_CONSTANT)) {
std::string *val = (std::string *)data; // Address
if (val) {
return sa.Return(val->c_str());
}
} else {
throw SquirrelError(_SC("getVar(): Invalid type+access: 'std::string' with VAR_ACCESS_CONSTANT (use VAR_ACCESS_READ_ONLY instead)"));
}
break;
} // case
#endif
} // switch
return SQ_ERROR;
} // getVar
// === Global Vars ===
int setVarFunc(HSQUIRRELVM v) {
SquirrelVM::Init(v); // For handling multi-VM setting right
StackHandler sa(v);
if (sa.GetType(1) == OT_TABLE) {
VarRefPtr vr;
int res = getVarInfo(sa,vr);
if (res != SQ_OK) return res;
return setVar(sa,vr,vr->offsetOrAddrOrConst);
} // if
return SQ_ERROR;
} // setVarFunc
int getVarFunc(HSQUIRRELVM v) {
SquirrelVM::Init(v); // For handling multi-VM setting right
StackHandler sa(v);
if (sa.GetType(1) == OT_TABLE) {
VarRefPtr vr;
int res = getVarInfo(sa,vr);
if (res != SQ_OK) return res;
return getVar(sa,vr,vr->offsetOrAddrOrConst);
} // if
return SQ_ERROR;
} // getVarFunc
// === Instance Vars ===
int setInstanceVarFunc(HSQUIRRELVM v) {
SquirrelVM::Init(v); // For handling multi-VM setting right
StackHandler sa(v);
if (sa.GetType(1) == OT_INSTANCE) {
VarRefPtr vr;
void * data;
int res = getInstanceVarInfo(sa,vr,data);
if (res != SQ_OK) return res;
return setVar(sa,vr,data);
} // if
return SQ_ERROR;
} // setInstanceVarFunc
int getInstanceVarFunc(HSQUIRRELVM v) {
SquirrelVM::Init(v); // For handling multi-VM setting right
StackHandler sa(v);
if (sa.GetType(1) == OT_INSTANCE) {
VarRefPtr vr;
void * data;
int res = getInstanceVarInfo(sa,vr,data);
if (res != SQ_OK) return res;
return getVar(sa,vr,data);
} // if
return SQ_ERROR;
} // getInstanceVarFunc
// === Classes ===
BOOL CreateClass(HSQUIRRELVM v,SquirrelObject & newClass,SQUserPointer classType,const SQChar * name,const SQChar * baseName) {
int n = 0;
int oldtop = sq_gettop(v);
sq_pushroottable(v);
sq_pushstring(v,name,-1);
if (baseName) {
sq_pushstring(v,baseName,-1);
if (SQ_FAILED(sq_get(v,-3))) { // Make sure the base exists if specified by baseName.
sq_settop(v,oldtop);
return FALSE;
} // if
} // if
if (SQ_FAILED(sq_newclass(v,baseName ? 1 : 0))) { // Will inherit from base class on stack from sq_get() above.
sq_settop(v,oldtop);
return FALSE;
} // if
newClass.AttachToStackObject(-1);
sq_settypetag(v,-1,classType);
sq_createslot(v,-3);
sq_pop(v,1);
return TRUE;
} // CreateClass
SquirrelObject RegisterClassType(HSQUIRRELVM v,const SQChar * scriptClassName,SQUserPointer classType,SQFUNCTION constructor) {
SquirrelVM::Init(v); // For handling multi-VM setting right
int top = sq_gettop(v);
SquirrelObject newClass;
if (CreateClass(v,newClass,classType,scriptClassName)) {
SquirrelVM::CreateFunction(newClass,constructor,_SC("constructor"));
} // if
sq_settop(v,top);
return newClass;
} // RegisterClassType
///////////////////////////////////////////////////////////////////////////
// GCC sometimes has problems with finding inline functions at link time
// (that also have a template definition). To solve the problem,
// non-inlines goes here.
#ifdef GCC_INLINE_WORKAROUND
# include "SqPlusFunctionCallImpl.h"
#endif // GCC_INLINE_WORKAROUND
///////////////////////////////////////////////////////////////////////////
} // namespace SqPlus

View File

@ -0,0 +1,337 @@
// This file is included multiple times, with varying options - No header guard.
// Include this file to generate Call templates with or without these options:
// - SQPLUS_APPLY_CONST - const qualifier after functions signature (const func / member func)
// - SQPLUS_APPLY_CDECL - qualifier before class name (MSVC specific calling convention)
#undef CONST_QUAL
#undef CALL_QUAL
#ifdef SQPLUS_APPLY_CONST
#define CONST_QUAL const
#else
#define CONST_QUAL
#endif
#ifdef SQPLUS_APPLY_CDECL
#define CALL_QUAL __cdecl
#else
#define CALL_QUAL
#endif
#ifdef SQPLUS_CALL_MFUNC_RET0
// Include this file again, with __cdecl also (Visual C++ specific)
#if defined(SQPLUS_ENABLE_CDECL_MEMBER_FUNCTIONS) && !defined(SQPLUS_APPLY_CDECL)
#define SQPLUS_APPLY_CDECL
#include "SqPlusCallTemplates.h"
#undef CALL_QUAL
#define CALL_QUAL
#endif
template <typename Callee>
static int Call(Callee & callee,RT (CALL_QUAL Callee::*func)() CONST_QUAL,HSQUIRRELVM v,int /*index*/) {
RT ret = (callee.*func)();
Push(v,ret);
return 1;
}
template <typename Callee,typename P1>
static int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1) CONST_QUAL,HSQUIRRELVM v,int index) {
sq_argassert(1,index + 0);
RT ret = (callee.*func)(
Get(TypeWrapper<P1>(),v,index + 0)
);
Push(v,ret);
return 1;
}
template<typename Callee,typename P1,typename P2>
static int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2) CONST_QUAL,HSQUIRRELVM v,int index) {
sq_argassert(1,index + 0);
sq_argassert(2,index + 1);
RT ret = (callee.*func)(
Get(TypeWrapper<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1)
);
Push(v,ret);
return 1;
}
template<typename Callee,typename P1,typename P2,typename P3>
static int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3) CONST_QUAL,HSQUIRRELVM v,int index) {
sq_argassert(1,index + 0);
sq_argassert(2,index + 1);
sq_argassert(3,index + 2);
RT ret = (callee.*func)(
Get(TypeWrapper<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1),
Get(TypeWrapper<P3>(),v,index + 2)
);
Push(v,ret);
return 1;
}
template<typename Callee,typename P1,typename P2,typename P3,typename P4>
static int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4) CONST_QUAL,HSQUIRRELVM v,int index) {
sq_argassert(1,index + 0);
sq_argassert(2,index + 1);
sq_argassert(3,index + 2);
sq_argassert(4,index + 3);
RT ret = (callee.*func)(
Get(TypeWrapper<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1),
Get(TypeWrapper<P3>(),v,index + 2),
Get(TypeWrapper<P4>(),v,index + 3)
);
Push(v,ret);
return 1;
}
template<typename Callee,typename P1,typename P2,typename P3,typename P4,typename P5>
static int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5) CONST_QUAL,HSQUIRRELVM v,int index) {
sq_argassert(1,index + 0);
sq_argassert(2,index + 1);
sq_argassert(3,index + 2);
sq_argassert(4,index + 3);
sq_argassert(5,index + 4);
RT ret = (callee.*func)(
Get(TypeWrapper<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1),
Get(TypeWrapper<P3>(),v,index + 2),
Get(TypeWrapper<P4>(),v,index + 3),
Get(TypeWrapper<P5>(),v,index + 4)
);
Push(v,ret);
return 1;
}
template<typename Callee,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6>
static int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5,P6) CONST_QUAL,HSQUIRRELVM v,int index) {
sq_argassert(1,index + 0);
sq_argassert(2,index + 1);
sq_argassert(3,index + 2);
sq_argassert(4,index + 3);
sq_argassert(5,index + 4);
sq_argassert(6,index + 5);
RT ret = (callee.*func)(
Get(TypeWrapper<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1),
Get(TypeWrapper<P3>(),v,index + 2),
Get(TypeWrapper<P4>(),v,index + 3),
Get(TypeWrapper<P5>(),v,index + 4),
Get(TypeWrapper<P6>(),v,index + 5)
);
Push(v,ret);
return 1;
}
template<typename Callee,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6,typename P7>
static int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5,P6,P7) CONST_QUAL,HSQUIRRELVM v,int index) {
sq_argassert(1,index + 0);
sq_argassert(2,index + 1);
sq_argassert(3,index + 2);
sq_argassert(4,index + 3);
sq_argassert(5,index + 4);
sq_argassert(6,index + 5);
sq_argassert(7,index + 6);
RT ret = (callee.*func)(
Get(TypeWrapper<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1),
Get(TypeWrapper<P3>(),v,index + 2),
Get(TypeWrapper<P4>(),v,index + 3),
Get(TypeWrapper<P5>(),v,index + 4),
Get(TypeWrapper<P6>(),v,index + 5),
Get(TypeWrapper<P7>(),v,index + 6)
);
Push(v,ret);
return 1;
}
#undef SQPLUS_CALL_MFUNC_RET0
#endif // SQPLUS_CALL_MFUNC_RET0
#ifdef SQPLUS_CALL_MFUNC_NORET
// Include this very same thing with __cdecl also
#if defined(SQPLUS_ENABLE_CDECL_MEMBER_FUNCTIONS) && !defined(SQPLUS_APPLY_CDECL)
#define SQPLUS_APPLY_CDECL
#include "SqPlusCallTemplates.h"
#undef CALL_QUAL
#define CALL_QUAL
#endif
// === Member function calls ===
template<typename Callee>
static int Call(Callee & callee,void (CALL_QUAL Callee::*func)() CONST_QUAL, HSQUIRRELVM,int /*index*/) {
(callee.*func)();
return 0;
}
template<typename Callee,typename P1>
static int Call(Callee & callee,void (CALL_QUAL Callee::*func)(P1) CONST_QUAL, HSQUIRRELVM v,int index) {
sq_argassert(1,index + 0);
(callee.*func)(
Get(TypeWrapper<P1>(),v,index + 0)
);
return 0;
}
template<typename Callee,typename P1,typename P2>
static int Call(Callee & callee,void (CALL_QUAL Callee::*func)(P1,P2) CONST_QUAL, HSQUIRRELVM v,int index) {
sq_argassert(1,index + 0);
sq_argassert(2,index + 1);
(callee.*func)(
Get(TypeWrapper<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1)
);
return 0;
}
template<typename Callee,typename P1,typename P2,typename P3>
static int Call(Callee & callee,void (CALL_QUAL Callee::*func)(P1,P2,P3) CONST_QUAL, HSQUIRRELVM v,int index) {
sq_argassert(1,index + 0);
sq_argassert(2,index + 1);
sq_argassert(3,index + 2);
(callee.*func)(
Get(TypeWrapper<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1),
Get(TypeWrapper<P3>(),v,index + 2)
);
return 0;
}
template<typename Callee,typename P1,typename P2,typename P3,typename P4>
static int Call(Callee & callee,void (CALL_QUAL Callee::*func)(P1,P2,P3,P4) CONST_QUAL, HSQUIRRELVM v,int index) {
sq_argassert(1,index + 0);
sq_argassert(2,index + 1);
sq_argassert(3,index + 2);
sq_argassert(4,index + 3);
(callee.*func)(
Get(TypeWrapper<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1),
Get(TypeWrapper<P3>(),v,index + 2),
Get(TypeWrapper<P4>(),v,index + 3)
);
return 0;
}
template<typename Callee,typename P1,typename P2,typename P3,typename P4,typename P5>
static int Call(Callee & callee,void (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5) CONST_QUAL, HSQUIRRELVM v,int index) {
sq_argassert(1,index + 0);
sq_argassert(2,index + 1);
sq_argassert(3,index + 2);
sq_argassert(4,index + 3);
sq_argassert(5,index + 4);
(callee.*func)(
Get(TypeWrapper<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1),
Get(TypeWrapper<P3>(),v,index + 2),
Get(TypeWrapper<P4>(),v,index + 3),
Get(TypeWrapper<P5>(),v,index + 4)
);
return 0;
}
template<typename Callee,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6>
static int Call(Callee & callee,void (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5,P6) CONST_QUAL, HSQUIRRELVM v,int index) {
sq_argassert(1,index + 0);
sq_argassert(2,index + 1);
sq_argassert(3,index + 2);
sq_argassert(4,index + 3);
sq_argassert(5,index + 4);
sq_argassert(6,index + 5);
(callee.*func)(
Get(TypeWrapper<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1),
Get(TypeWrapper<P3>(),v,index + 2),
Get(TypeWrapper<P4>(),v,index + 3),
Get(TypeWrapper<P5>(),v,index + 4),
Get(TypeWrapper<P6>(),v,index + 5)
);
return 0;
}
template<typename Callee,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6,typename P7>
static int Call(Callee & callee,void (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5,P6,P7) CONST_QUAL, HSQUIRRELVM v,int index) {
sq_argassert(1,index + 0);
sq_argassert(2,index + 1);
sq_argassert(3,index + 2);
sq_argassert(4,index + 3);
sq_argassert(5,index + 4);
sq_argassert(6,index + 5);
sq_argassert(7,index + 6);
(callee.*func)(
Get(TypeWrapper<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1),
Get(TypeWrapper<P3>(),v,index + 2),
Get(TypeWrapper<P4>(),v,index + 3),
Get(TypeWrapper<P5>(),v,index + 4),
Get(TypeWrapper<P6>(),v,index + 5),
Get(TypeWrapper<P7>(),v,index + 6)
);
return 0;
}
#undef SQPLUS_CALL_MFUNC_NORET
#endif // SQPLUS_CALL_MFUNC_NORET
#ifdef SQPLUS_CALL_MFUNC_RET1
// Include this very same thing with __cdecl also
#if defined(SQPLUS_ENABLE_CDECL_MEMBER_FUNCTIONS) && !defined(SQPLUS_APPLY_CDECL)
#define SQPLUS_APPLY_CDECL
#include "SqPlusCallTemplates.h"
#undef CALL_QUAL
#define CALL_QUAL
#endif
template<typename Callee,typename RT>
int Call(Callee & callee, RT (CALL_QUAL Callee::*func)() CONST_QUAL, HSQUIRRELVM v,int index) {
return ReturnSpecialization<RT>::Call(callee,func,v,index);
}
template<typename Callee,typename RT,typename P1>
int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1) CONST_QUAL, HSQUIRRELVM v,int index) {
return ReturnSpecialization<RT>::Call(callee,func,v,index);
}
template<typename Callee,typename RT,typename P1,typename P2>
int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2) CONST_QUAL, HSQUIRRELVM v,int index) {
return ReturnSpecialization<RT>::Call(callee,func,v,index);
}
template<typename Callee,typename RT,typename P1,typename P2,typename P3>
int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3) CONST_QUAL, HSQUIRRELVM v,int index) {
return ReturnSpecialization<RT>::Call(callee,func,v,index);
}
template<typename Callee,typename RT,typename P1,typename P2,typename P3,typename P4>
int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4) CONST_QUAL, HSQUIRRELVM v,int index) {
return ReturnSpecialization<RT>::Call(callee,func,v,index);
}
template<typename Callee,typename RT,typename P1,typename P2,typename P3,typename P4,typename P5>
int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5) CONST_QUAL, HSQUIRRELVM v,int index) {
return ReturnSpecialization<RT>::Call(callee,func,v,index);
}
template<typename Callee,typename RT,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6>
int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5,P6) CONST_QUAL, HSQUIRRELVM v,int index) {
return ReturnSpecialization<RT>::Call(callee,func,v,index);
}
template<typename Callee,typename RT,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6,typename P7>
int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5,P6,P7) CONST_QUAL, HSQUIRRELVM v,int index) {
return ReturnSpecialization<RT>::Call(callee,func,v,index);
}
#undef SQPLUS_CALL_MFUNC_RET1
#endif // SQPLUS_CALL_MFUNC_RET1
// We will be reusing these symbols later
#undef SQPLUS_APPLY_CDECL
#undef SQPLUS_APPLY_CONST

View File

@ -0,0 +1,74 @@
// SqPlusConst.h
// SqPlus constant type and constant member function support created by Simon Michelmore.
// Modular integration 11/14/05 jcs.
#ifdef SQPLUS_DECLARE_INSTANCE_TYPE_CONST
#undef SQPLUS_DECLARE_INSTANCE_TYPE_CONST
// Kamaitati's NULL_INSTANCE support. 5/28/06 jcs
#ifdef SQPLUS_SUPPORT_NULL_INSTANCES
#define DECLARE_INSTANCE_TYPE_NAME_CONST_BASE(TYPE,NAME) \
inline bool Match(TypeWrapper<const TYPE &>,HSQUIRRELVM v,int idx) { return GetInstance<TYPE,false>(v,idx) != NULL; } \
inline const TYPE & Get(TypeWrapper<const TYPE &>,HSQUIRRELVM v,int idx) { return *GetInstance<TYPE,true>(v,idx); }
// Ordinary case
#define DECLARE_INSTANCE_TYPE_NAME_CONST(TYPE,NAME) \
DECLARE_INSTANCE_TYPE_NAME_(TYPE,NAME) \
namespace SqPlus { \
DECLARE_INSTANCE_TYPE_NAME_CONST_BASE(TYPE,NAME) \
template<> inline void Push(HSQUIRRELVM v,const TYPE * value) { \
if (!value) sq_pushnull(v); \
else if (!CreateNativeClassInstance(v,GetTypeName(*value),(TYPE*)value,0)) \
throw SquirrelError(_SC("Push(): could not create INSTANCE (check registration name)")); } \
template<> inline void Push(HSQUIRRELVM v,const TYPE & value) { if (!CreateCopyInstance(v,GetTypeName(value),value)) throw SquirrelError(_SC("Push(): could not create INSTANCE copy (check registration name)")); } \
} // nameSpace SqPlus
// Case for custom Push implementation (covariant return type)
#define DECLARE_INSTANCE_TYPE_NAME_CONST_CUSTOM(TYPE,NAME) \
DECLARE_INSTANCE_TYPE_NAME_CUSTOM_(TYPE,NAME) \
namespace SqPlus { \
DECLARE_INSTANCE_TYPE_NAME_CONST_BASE(TYPE,NAME) \
template<> void Push(HSQUIRRELVM v,const TYPE * value); \
template<> void Push(HSQUIRRELVM v,const TYPE & value); \
} // nameSpace SqPlus
#else
#define DECLARE_INSTANCE_TYPE_NAME_CONST(TYPE,NAME) \
DECLARE_INSTANCE_TYPE_NAME_(TYPE,NAME) \
namespace SqPlus { \
template<> inline void Push(HSQUIRRELVM v,const TYPE * value) { if (!CreateNativeClassInstance(v,GetTypeName(*value),(TYPE*)value,0)) throw SquirrelError(_SC("Push(): could not create INSTANCE (check registration name)")); } \
template<> inline void Push(HSQUIRRELVM v,const TYPE & value) { if (!CreateCopyInstance(v,GetTypeName(value),value)) throw SquirrelError(_SC("Push(): could not create INSTANCE copy (check registration name)")); } \
template<> inline bool Match(TypeWrapper<const TYPE &>,HSQUIRRELVM v,int idx) { return GetInstance<TYPE,false>(v,idx) != NULL; } \
template<> inline const TYPE & Get(TypeWrapper<const TYPE &>,HSQUIRRELVM v,int idx) { return *GetInstance<TYPE,true>(v,idx); } \
} // nameSpace SqPlus
#endif
#define DECLARE_INSTANCE_TYPE(TYPE) DECLARE_INSTANCE_TYPE_NAME_CONST(TYPE,TYPE)
#define DECLARE_INSTANCE_TYPE_NAME(TYPE,NAME) DECLARE_INSTANCE_TYPE_NAME_CONST(TYPE,NAME)
#define DECLARE_INSTANCE_TYPE_CUSTOM(TYPE) DECLARE_INSTANCE_TYPE_NAME_CONST_CUSTOM(TYPE,TYPE)
#define DECLARE_INSTANCE_TYPE_NAME_CUSTOM(TYPE,NAME) DECLARE_INSTANCE_TYPE_NAME_CONST_CUSTOM(TYPE,NAME)
#endif
#define SQPLUS_APPLY_CONST
#include "SqPlusCallTemplates.h"
#ifdef SQ_REG_CONST_STATIC_VAR
#undef SQ_REG_CONST_STATIC_VAR
template<typename VarType>
SQClassDefBase & staticVar(const VarType * pvar,const SQChar * name,VarAccessType access=VAR_ACCESS_READ_ONLY) {
struct CV {
const VarType * var;
} cv; // Cast Variable helper.
cv.var = pvar;
RegisterInstanceVariable(newClass,ClassType<TClassType>::type(),*(VarType **)&cv,name,VarAccessType(access|VAR_ACCESS_STATIC));
return *this;
} // staticVar
#endif
// SqPlusConst.h

View File

@ -0,0 +1,114 @@
#ifndef _SQPLUS_FUNCTION_CALL_IMPL_H_
#define _SQPLUS_FUNCTION_CALL_IMPL_H_
#ifdef GCC_INLINE_WORKAROUND
# define SQINLINE
#else
# define SQINLINE inline
#endif
SQINLINE void Push(HSQUIRRELVM v,char value) { sq_pushinteger(v,value); }
SQINLINE void Push(HSQUIRRELVM v,unsigned char value) { sq_pushinteger(v,value); }
SQINLINE void Push(HSQUIRRELVM v,short value) { sq_pushinteger(v,value); }
SQINLINE void Push(HSQUIRRELVM v,unsigned short value) { sq_pushinteger(v,value); }
SQINLINE void Push(HSQUIRRELVM v,int value) { sq_pushinteger(v,value); }
SQINLINE void Push(HSQUIRRELVM v,unsigned int value) { sq_pushinteger(v,value); }
SQINLINE void Push(HSQUIRRELVM v,long value) { sq_pushinteger(v,value); }
SQINLINE void Push(HSQUIRRELVM v,unsigned long value) { sq_pushinteger(v,value); }
SQINLINE void Push(HSQUIRRELVM v,double value) { sq_pushfloat(v,(FLOAT)value); }
SQINLINE void Push(HSQUIRRELVM v,float value) { sq_pushfloat(v,(FLOAT)value); }
SQINLINE void Push(HSQUIRRELVM v,const SQChar * value) { sq_pushstring(v,value,-1); }
SQINLINE void Push(HSQUIRRELVM v,SQChar * value) { sq_pushstring(v,value,-1); }
SQINLINE void Push(HSQUIRRELVM v,const SquirrelNull &) { sq_pushnull(v); }
SQINLINE void Push(HSQUIRRELVM v,SQFUNCTION value) { sq_pushuserpointer(v,(void*)value); }
SQINLINE void Push(HSQUIRRELVM v,SQAnythingPtr value) { sq_pushuserpointer(v,(void*)value); } // Cast to SQAnythingPtr instead of void * if USE_ARGUMENT_DEPENDANT_OVERLOADS can't be used by your compiler.
SQINLINE void Push(HSQUIRRELVM v,SquirrelObject & so) { sq_pushobject(v,so.GetObjectHandle()); }
#ifdef USE_ARGUMENT_DEPENDANT_OVERLOADS
#ifdef _MSC_VER
#pragma warning (disable:4675) // Disable warning: "resolved overload was found by argument-dependent lookup" when class/struct pointers are used as function arguments.
#endif
// === BEGIN Argument Dependent Overloads ===
SQINLINE void Push(HSQUIRRELVM v,bool value) { sq_pushbool(v,value); } // Pass bool as int if USE_ARGUMENT_DEPENDANT_OVERLOADS can't be used by your compiler.
SQINLINE void Push(HSQUIRRELVM v,const void * value) { sq_pushuserpointer(v,(void*)value); } // Pass SQAnythingPtr instead of void * " "
SQINLINE void Push(HSQUIRRELVM v,const SQUserPointer & value) { sq_pushuserpointer(v,(void*)value); }
// === END Argument Dependent Overloads ===
#endif
#define SQPLUS_CHECK_GET(res) if (!SQ_SUCCEEDED(res)) throw SquirrelError(_SC("sq_get*() failed (type error)"))
//SQINLINE bool Match(TypeWrapper<bool>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_BOOL; }
SQINLINE bool Match(TypeWrapper<bool>,HSQUIRRELVM v,int idx) { return true; } // All types can be cast to bool
SQINLINE bool Match(TypeWrapper<char>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; }
SQINLINE bool Match(TypeWrapper<unsigned char>,HSQUIRRELVM v, int idx) { return sq_gettype(v,idx) == OT_INTEGER; }
SQINLINE bool Match(TypeWrapper<short>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; }
SQINLINE bool Match(TypeWrapper<unsigned short>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; }
SQINLINE bool Match(TypeWrapper<int>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; }
SQINLINE bool Match(TypeWrapper<unsigned int>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; }
SQINLINE bool Match(TypeWrapper<long>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; }
SQINLINE bool Match(TypeWrapper<unsigned long>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; }
SQINLINE bool Match(TypeWrapper<float>,HSQUIRRELVM v,int idx) { int type = sq_gettype(v,idx); return type == OT_FLOAT; }
SQINLINE bool Match(TypeWrapper<double>,HSQUIRRELVM v,int idx) { int type = sq_gettype(v,idx); return type == OT_FLOAT; }
SQINLINE bool Match(TypeWrapper<const SQChar *>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_STRING; }
SQINLINE bool Match(TypeWrapper<SQChar *>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_STRING; }
SQINLINE bool Match(TypeWrapper<HSQUIRRELVM>,HSQUIRRELVM v,int idx) { return true; } // See Get() for HSQUIRRELVM below (v is always present).
SQINLINE bool Match(TypeWrapper<void*>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_USERPOINTER; }
SQINLINE bool Match(TypeWrapper<SquirrelObject>,HSQUIRRELVM v,int idx) { return true; } // See sq_getstackobj(): always returns true.
SQINLINE void Get(TypeWrapper<void>,HSQUIRRELVM v,int) {}
//SQINLINE bool Get(TypeWrapper<bool>,HSQUIRRELVM v,int idx) { SQBool b; SQPLUS_CHECK_GET(sq_getbool(v,idx,&b)); return b != 0; }
SQINLINE char Get(TypeWrapper<char>,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast<char>(i); }
SQINLINE unsigned char Get(TypeWrapper<unsigned char>,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast<unsigned char>(i); }
SQINLINE short Get(TypeWrapper<short>,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast<short>(i); }
SQINLINE unsigned short Get(TypeWrapper<unsigned short>,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast<unsigned short>(i); }
SQINLINE int Get(TypeWrapper<int>,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return i; }
SQINLINE unsigned int Get(TypeWrapper<unsigned int>,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast<unsigned int>(i); }
SQINLINE long Get(TypeWrapper<long>,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast<long>(i); }
SQINLINE unsigned long Get(TypeWrapper<unsigned long>,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast<unsigned long>(i); }
SQINLINE float Get(TypeWrapper<float>,HSQUIRRELVM v,int idx) { FLOAT f; SQPLUS_CHECK_GET(sq_getfloat(v,idx,&f)); return f; }
SQINLINE double Get(TypeWrapper<double>,HSQUIRRELVM v,int idx) { FLOAT f; SQPLUS_CHECK_GET(sq_getfloat(v,idx,&f)); return static_cast<double>(f); }
SQINLINE const SQChar * Get(TypeWrapper<const SQChar *>,HSQUIRRELVM v,int idx) { const SQChar * s; SQPLUS_CHECK_GET(sq_getstring(v,idx,&s)); return s; }
SQINLINE SquirrelNull Get(TypeWrapper<SquirrelNull>,HSQUIRRELVM v,int idx) { (void)v, (void)idx; return SquirrelNull(); }
SQINLINE void * Get(TypeWrapper<void *>,HSQUIRRELVM v,int idx) { SQUserPointer p; SQPLUS_CHECK_GET(sq_getuserpointer(v,idx,&p)); return p; }
SQINLINE HSQUIRRELVM Get(TypeWrapper<HSQUIRRELVM>,HSQUIRRELVM v,int /*idx*/) { sq_poptop(v); return v; } // sq_poptop(v): remove UserData from stack so GetParamCount() matches normal behavior.
SQINLINE SquirrelObject Get(TypeWrapper<SquirrelObject>,HSQUIRRELVM v,int idx) { HSQOBJECT o; SQPLUS_CHECK_GET(sq_getstackobj(v,idx,&o)); return SquirrelObject(o); }
SQINLINE bool Get(TypeWrapper<bool>,HSQUIRRELVM v,int idx){
switch( sq_gettype(v,idx) ){
case OT_NULL:{ return false; }
case OT_BOOL:{ SQBool b; SQPLUS_CHECK_GET(sq_getbool(v,idx,&b)); return b != 0; }
case OT_INTEGER:{ INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return i != 0; }
case OT_FLOAT:{ FLOAT f; SQPLUS_CHECK_GET(sq_getfloat(v,idx,&f)); return f != (FLOAT)0.0; }
default: return true; } }
#ifdef SQPLUS_AUTOCONVERT_OTHER_CHAR
SQINLINE void Push(HSQUIRRELVM v, const SQOtherChar *value){ SQDefCharBuf cb(value); sq_pushstring(v,(const SQChar*)cb,-1); }
SQINLINE void Push(HSQUIRRELVM v, SQOtherChar *value){ SQDefCharBuf cb(value); sq_pushstring(v,(const SQChar*)cb,-1); }
SQINLINE bool Match(TypeWrapper<const SQOtherChar *>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_STRING; }
SQINLINE bool Match(TypeWrapper<SQOtherChar *>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_STRING; }
/*SQINLINE SQOtherChar* Get(TypeWrapper<const SQOtherChar *>,HSQUIRRELVM v,int idx) {
const SQChar *s; SQPLUS_CHECK_GET(sq_getstring(v,idx,&s));
static SQOthCharBuf ocb[SQPLUS_AUTOCONVERT_MAX_INSTANCES]; static int st_buf_cnt;
return ocb[st_buf_cnt++%SQPLUS_AUTOCONVERT_MAX_INSTANCES].Set(s); }*/
SQINLINE SQOthCharBuf Get(TypeWrapper<const SQOtherChar *>,HSQUIRRELVM v,int idx) { const SQChar * s; SQPLUS_CHECK_GET(sq_getstring(v,idx,&s)); return SQOthCharBuf(s); }
#endif // SQPLUS_AUTOCONVERT_OTHER_CHAR
#if defined(SQPLUS_SUPPORT_STD_STRING) && !defined(SQUNICODE)
SQINLINE void Push(HSQUIRRELVM v,const std::string& value) { sq_pushstring(v,value.c_str(),-1); }
SQINLINE bool Match(TypeWrapper<const std::string&>, HSQUIRRELVM v, int idx) { return sq_gettype(v,idx) == OT_STRING; }
SQINLINE std::string Get(TypeWrapper<const std::string&>,HSQUIRRELVM v,int idx) { const SQChar * s; SQPLUS_CHECK_GET(sq_getstring(v,idx,&s)); return std::string(s); }
#endif // defined(SQPLUS_SUPPORT_STD_STRING) && !defined(SQUNICODE)
// Added jflanglois suggestion, 8/20/06. jcs
#ifdef SQPLUS_SUPPORT_SQ_STD_STRING
typedef std::basic_string<SQChar> sq_std_string;
SQINLINE void Push(HSQUIRRELVM v,const sq_std_string & value) { sq_pushstring(v,value.c_str(),-1); }
SQINLINE bool Match(TypeWrapper<const sq_std_string &>, HSQUIRRELVM v, int idx) { return sq_gettype(v,idx) == OT_STRING; }
SQINLINE sq_std_string Get(TypeWrapper<const sq_std_string &>,HSQUIRRELVM v,int idx) { const SQChar * s; SQPLUS_CHECK_GET(sq_getstring(v,idx,&s)); return sq_std_string(s); }
#endif
// Specialization to support void return type.
SQINLINE void GetRet(TypeWrapper<void>,HSQUIRRELVM v,int idx) { sq_pop(v,2); }
#endif // _SQPLUS_FUNCTION_CALL_IMPL_H_

View File

@ -0,0 +1,61 @@
#include "sqplus.h"
#include "SqPlusOCharBuf.h"
#include <wchar.h>
// Conversion functions, between char* string and wchar_t* strings.
int ol_strlen(const wchar_t* pwc){ return (int)wcslen(pwc); }
int ol_buflen(const wchar_t* pwc){ return (int)wcslen(pwc); }
int ol_charlen(const wchar_t* pwc){ return 1; }
//int ol_charlen(const wchar_t pwc){ return 1; }
int ol_char(const wchar_t* pwc){ return (int)*pwc; }
bool ol_writechar(wchar_t*& pwc, int ch){ *pwc=(wchar_t)ch; pwc++; return true; }
int ol_buflen(const char* pc){ return (int)strlen(pc); }
#if SQPLUS_USE_LATIN1==1
// Convert to 8-bit LATIN1 char set. The only thing to do is convert chars out of range to '?'
int ol_strlen(const char* pc){ return (int)strlen(pc); }
int ol_charlen(const char* pc){ return 1; }
//int ol_charlen(int pc){ return 1; }
int ol_char(const char* pc){ return (int)*(unsigned char*)pc; }
bool ol_writechar(char*& pc, int ch){ *pc=(char)(ch>255?'?':ch); pc++; return true; }
#else
#include "SqPlusUtf8.h"
// Convert to 8-Bit UTF8 encoding. Some more work here.
int ol_strlen(const char* pc){ return sqplus_utf8_strlen(pc); }
int ol_charlen(const char* pc){ return sqplus_utf8_len_first(pc); }
//int ol_charlen(int ch){ char buf[8]; return sqplus_wchar_to_utf8(buf,ch,8); }
int ol_char(const char* pc){ int chr=-1; sqplus_utf8_to_wchar(&chr,pc); return chr; }
bool ol_writechar(char*& pc, int ch) {
int l=sqplus_wchar_to_utf8(pc,ch,8);
if(l>0){
pc += l;
return true;
}
else return false;
}
#endif
#ifdef SQUNICODE
// SQChar is wchar_t, convert to/from to either Latin1 or UTF8
SQDefCharBuf CH2SQ( const char* ps ){
return SQDefCharBuf(ps);
}
SQOthCharBuf SQ2CH( const wchar_t* pws ){
return SQOthCharBuf(pws);
}
#else
// SQChar is char, convert to/from wchar_t
SQDefCharBuf WC2SQ( const wchar_t* pws ){
return SQDefCharBuf(pws);
}
SQOthCharBuf SQ2WC( const char* ps ){
return SQOthCharBuf(ps);
}
#endif

View File

@ -0,0 +1,193 @@
#ifndef SQPLUS_OCHARBUF_H
#define SQPLUS_OCHARBUF_H
// Conversion routines between different character encodings, to be used in
// Push/Get/Match handlers of SqPlus. It enables using both of char* and
// wchar_t* as function arguments.
//
// When converting from wchar_t to char, the choice is between using a Latin1
// or a UTF8 representation in 8-bit mode. This is probably most useful if
// Squirrel is compiled in ANSI mode and the app uses some wchar_t strings
// (UNICODE mode on Win32).
//
// A char is either
// - A Latin1 character (first code page, coincides with Unicode points 0..255)
// - Part of an UTF8 character
//
// Note: SQUTF8 requires Squirrel sources that have been patched for UTF8 strings
// internally (when converting function arguments).
#ifndef SQUTF8
// Default to Latin1 conversion
//#undef SQPLUS_USE_LATIN1
#ifndef SQPLUS_USE_LATIN1
#define SQPLUS_USE_LATIN1 1
#endif
#else
// Using Squirrel with internal UTF8 string encoding
//#undef SQPLUS_USE_LATIN1
#ifndef SQPLUS_USE_LATIN1
#define SQPLUS_USE_LATIN1 0
#endif
#endif
// The various ol_... functions sets up for a conversion scheme
// that can be used in both wchar_t => char and char => wchar_t.
int ol_strlen(const wchar_t* pwc);
int ol_buflen(const wchar_t* pwc);
int ol_charlen(const wchar_t* pwc);
int ol_char(const wchar_t* pwc);
bool ol_writechar(wchar_t*& pwc, int ch);
int ol_strlen(const char* pc);
int ol_buflen(const char* pc);
int ol_charlen(const char* pc);
int ol_char(const char* pc);
bool ol_writechar(char*& pc, int ch);
#ifdef SQUNICODE
// SQChar is wchar_t, convert to/from either Latin1 or UTF8
typedef char SQOtherChar;
#else
// SQChar is char, convert to/from wchar_t
typedef wchar_t SQOtherChar;
#endif
// Buffer to hold a string and release it in destructor.
// SQT is input character type
// SQOT is the opposite type of SQChar
// If 'try_borrow' is set, it will not allocate a new buffer when no
// conversion is done, it will just keep the input pointer (beware).
template<class SQT, class SQOT, bool use_latin1>
struct SQCharBufImpl {
// Allocate a buffer from string of same type
SQCharBufImpl(const SQT *poc=NULL, bool try_borrow=true ) : m_poc(0), m_own(false) {
Init( poc, try_borrow );
}
// This does conversion from other char type
SQCharBufImpl(const SQOT *ps, bool try_borrow=false ) : m_poc(0), m_own(false) {
Init( ps ); // Cannot borrow pointer when doing conversion
}
void Init( const SQT *poc, bool try_borrow ){
m_own = !try_borrow;
if( try_borrow ){
m_poc = (SQT*)poc;
}
else {
int sl = poc ? ol_buflen(poc) : 0;
if( poc ){
m_poc = poc ? new SQT[sl+1] : NULL;
if( m_poc ) memcpy( m_poc, poc, (sl+1)*sizeof(SQT) );
}
else
m_poc = NULL;
}
}
void Init( const SQOT *ps ){
m_own = true;
if( ps ){
int sl = ps ? ol_strlen(ps) : 0; // Length of string in characters (not bytes)
int scl = 0; // Length of converted string in char/wchar_t count
// How much storage needed?
if( !use_latin1 && sizeof(SQT)<sizeof(SQOT) ){
// Converting wchar_t => UTF8
const SQOT *ps1 = ps; // It is wchar_t* here
SQT tmp_buf[8];
SQT *ptmp;
while( *ps1 ){
ptmp = tmp_buf;
if( ol_writechar(ptmp,*ps1++) )
scl += ol_charlen(tmp_buf);
else
scl++;
}
}
else scl = sl; // Converting to wchar_t or Latin1, keep length
m_poc = new SQT[scl+1];
if( !m_poc ) return;
// Convert
SQT *poc = m_poc;
while( *ps ){
ol_writechar( poc, ol_char(ps) );
ps += ol_charlen(ps);
}
*poc = 0; // Terminating zero
}
else
m_poc = NULL;
}
~SQCharBufImpl(){ Release(); }
void Release( ){
if(m_poc && m_own )
delete [] m_poc;
m_poc = NULL;
}
SQT* Set( const SQOT *ps ){
Release( );
Init( ps );
return m_poc;
}
operator SQT*() const { return m_poc; }
SQCharBufImpl<SQT,SQOT,use_latin1>& operator = (const SQT *ps){
Release();
Init( ps, false );
return *this;
}
SQCharBufImpl<SQT,SQOT,use_latin1>& operator = (const SQOT *ps){
Release();
Init( ps );
return *this;
}
// Move string from other here - Note: Empties the input argument (other)
SQCharBufImpl<SQT,SQOT,use_latin1>& operator = (const SQCharBufImpl<SQT,SQOT,use_latin1>& other){
Release();
m_poc = other.m_poc;
m_own = other.m_own;
SQT **psqt = (SQT**)&other.m_poc;
*psqt = NULL;
return *this;
}
protected:
SQT *m_poc;
bool m_own;
};
typedef SQCharBufImpl<SQOtherChar, SQChar, bool(SQPLUS_USE_LATIN1)> SQOthCharBuf;
typedef SQCharBufImpl<SQChar, SQOtherChar, bool(SQPLUS_USE_LATIN1)> SQDefCharBuf;
typedef SQCharBufImpl<wchar_t, char, bool(SQPLUS_USE_LATIN1)> SQWCharBuf;
typedef SQCharBufImpl<char, wchar_t, bool(SQPLUS_USE_LATIN1)> SQACharBuf;
#ifdef SQUNICODE
// SQChar is wchar_t, convert to/from to either Latin1 or UTF8
#define WC2SQ(s) s
#define SQ2WC(s) s
SQDefCharBuf CH2SQ( const char* ps );
SQOthCharBuf SQ2CH( const wchar_t* pws );
#else
// SQChar is char, convert to/from wchar_t
SQDefCharBuf WC2SQ( const wchar_t* pws );
SQOthCharBuf SQ2WC( const char* pws );
#define CH2SQ(s) s
#define SQ2CH(s) s
#endif
#endif // SQPLUS_CHARBUF_H

View File

@ -0,0 +1,819 @@
// SqPlusOverload.h
// SqPlus function overloading support created by Katsuaki Kawachi.
//
// Const member function fixed Tegan
// from http://squirrel-lang.org/forums/thread/2160.aspx
#ifdef SQPLUS_OVERLOAD_RELEASE_HOOK
#undef SQPLUS_OVERLOAD_RELEASE_HOOK
// These end up int ClassType<T> now
static inline int destruct(SQUserPointer up, SQInteger size) {
if (up) {
static_cast<T*>(up)->~T();
sq_free(up, size);
}
return 0;
}
static inline SQRELEASEHOOK &release(void) {
static SQRELEASEHOOK hook = ClassType<T>::destruct;
return hook;
}
void releaseHook(SQRELEASEHOOK releaseHook) {
release() = releaseHook;
//return *this;
}
static inline SQRELEASEHOOK &getReleaseHook(void) {
return release();
}
#endif // SQPLUS_OVERLOAD_RELEASE_HOOK
#ifdef SQPLUS_OVERLOAD_DECLARATION
#undef SQPLUS_OVERLOAD_DECLARATION
template<typename Func> struct Arg;
#endif // SQPLUS_OVERLOAD_DECLARATION
#ifdef SQPLUS_OVERLOAD_IMPLEMENTATION
#undef SQPLUS_OVERLOAD_IMPLEMENTATION
private:
class SQFuncHolder {
private:
template<typename T>
class FlexArray {
protected:
SquirrelObject array;
public:
FlexArray(int size = 0) {
this->resize(size);
}
int size(void) const {
return array.Len();
}
void resize(int newSize) {
if (this->size() == 0) {
array = SquirrelVM::CreateArray(newSize);
} else {
array.ArrayResize(newSize);
}
}
void push_back(const T &t) {
this->set(this->size(), t);
}
void set(int index, const T &t) {
get(index) = t;
}
T &get(int index) {
if (index >= array.Len()) {
resize(index + 1);
}
SQUserPointer up = array.GetUserPointer(index);
if (!up) {
up = sq_newuserdata(SquirrelVM::GetVMPtr(), sizeof(T));
new(static_cast<T*>(up)) T;
array.SetUserPointer(index, up);
}
return *static_cast<T*>(up);
}
};
/*
storage of wrapped C++ functions
*/
typedef SQInteger(*WrappedFunction)(HSQUIRRELVM, bool, int);
typedef FlexArray<WrappedFunction> SQWrappedFuncArray;
typedef FlexArray<SQWrappedFuncArray> SQWrappedFuncArray2 ;
typedef FlexArray<SQWrappedFuncArray2> SQWrappedFuncArray3 ;
struct MemberHolder {
static SQWrappedFuncArray &funcs(int functionIndex,
int paramCount) {
static SQWrappedFuncArray3 funcs;
return funcs.get(paramCount).get(functionIndex);
}
};
struct StaticHolder {
static SQWrappedFuncArray &funcs(int functionIndex,
int paramCount) {
static SQWrappedFuncArray3 funcs;
return funcs.get(paramCount).get(functionIndex);
}
};
struct ConstructorHolder {
static SQWrappedFuncArray &funcs(int paramCount) {
static SQWrappedFuncArray2 funcs;
return funcs.get(paramCount);
}
};
/*
wrapper for C++ functions
*/
template<typename Mfunc> struct MemberDispatcher {
static inline FlexArray<Mfunc> &mfunc(void) {
static FlexArray<Mfunc> mfunc;
return mfunc;
}
static inline SQInteger
dispatch(HSQUIRRELVM v, bool execute, int functionIndex) {
return execute ?
Call(*GetInstance<TClassType, true>(v, 1),
mfunc().get(functionIndex), v, 2) :
Arg<Mfunc>::argTypeDistance(v);
}
};
template<typename Sfunc> struct StaticDispatcher {
static inline FlexArray<Sfunc> &sfunc(void) {
static FlexArray<Sfunc> sfunc;
return sfunc;
}
static inline SQInteger
dispatch(HSQUIRRELVM v, bool execute, int functionIndex) {
return execute ?
Call(sfunc().get(functionIndex), v, 2) :
Arg<Sfunc>::argTypeDistance(v);
}
};
template<typename Cfunc> struct Constructor {
static inline Cfunc &cfunc(void) {
static Cfunc cfunc = 0;
return cfunc;
}
static inline SQInteger
construct(HSQUIRRELVM v, bool execute, int) {
return execute ?
Call(cfunc(), v, 2) :
Arg<Cfunc>::argTypeDistance(v);
}
};
// search and call an overloaded function on runtime
static inline SQInteger
call(SQWrappedFuncArray &funcs, HSQUIRRELVM v, int functionIndex = 0) {
bool ambiguous = false;
int imin = -1;
int dmin = INT_MAX;
for (int i = 0, size = funcs.size(); i < size; ++i) {
// FIXME: to be refactored
const int d = (**funcs.get(i))(v, false, functionIndex);
if (d == 0) { // complete match
imin = i;
ambiguous = false;
goto SQPLUS_OVERLOAD_CALL_IMMEDIATE_EXECUTION;
} else if (0 < d && d < dmin) {
dmin = d;
imin = i;
ambiguous = false;
} else if (d == dmin) {
ambiguous = true;
}
}
if (ambiguous) {
return sq_throwerror(
v, _SC("Call of overloaded function is ambiguous")
);
} else if (imin == -1) {
return sq_throwerror(
v, _SC("No match for given arguments")
);
}
SQPLUS_OVERLOAD_CALL_IMMEDIATE_EXECUTION:
// FIXME: to be refactored
return (**funcs.get(imin))(v, true, functionIndex);
}
public:
template<typename Mfunc> static inline void
addMemberFunc(int functionIndex, Mfunc mfunc) {
MemberHolder::funcs(functionIndex, Arg<Mfunc>::num()).push_back(
&MemberDispatcher<Mfunc>::dispatch
);
MemberDispatcher<Mfunc>::mfunc().set(functionIndex, mfunc);
}
template<typename Sfunc> static inline void
addStaticFunc(int functionIndex, Sfunc sfunc) {
StaticHolder::funcs(functionIndex, Arg<Sfunc>::num()).push_back(
&StaticDispatcher<Sfunc>::dispatch
);
StaticDispatcher<Sfunc>::sfunc().set(functionIndex, sfunc);
}
template<typename Cfunc> static inline void
addConstructor(Cfunc cfunc) {
ConstructorHolder::funcs(Arg<Cfunc>::num()).push_back(
&Constructor<Cfunc>::construct
);
Constructor<Cfunc>::cfunc() = cfunc;
}
static inline SQInteger
memberCall(int paramCount, HSQUIRRELVM v, int functionIndex) {
return call(MemberHolder::funcs(functionIndex, paramCount),
v, functionIndex);
}
static inline SQInteger
staticCall(int paramCount, HSQUIRRELVM v, int functionIndex) {
return call(StaticHolder::funcs(functionIndex, paramCount),
v, functionIndex);
}
static inline SQInteger
constructorCall(int paramCount, HSQUIRRELVM v, int) {
return call(ConstructorHolder::funcs(paramCount), v);
}
}; // class SQFuncHolder
struct FunctionNameEnumerator {
SquirrelObject names;
FunctionNameEnumerator(void) : names(SquirrelVM::CreateTable()) {}
int index(const SQChar *n) {
int i;
SquirrelObject v = names.GetValue(n);
if (v.IsNull()) {
i = names.Len();
names.SetValue(n, i);
} else {
i = v.ToInteger();
}
return i;
}
};
FunctionNameEnumerator overloadedMemberNames;
FunctionNameEnumerator overloadedStaticMemberNames;
static SquirrelObject &
functionIndexHolders(HSQUIRRELVM v) {
static SquirrelObject indexHolders;
if (indexHolders.IsNull()) {
sq_newtable(v);
indexHolders.AttachToStackObject(-1);
sq_pop(v, 1);
}
return indexHolders;
}
template<int N>
static SquirrelObject &
indexHolder(HSQUIRRELVM v) {
static SquirrelObject holder;
if (holder.IsNull()) {
sq_pushobject(v, functionIndexHolders(v).GetObjectHandle());
sq_pushinteger(v, N);
if (SQ_OK == sq_rawget(v, -2)) {
holder.AttachToStackObject(-1);
sq_pop(v, 3);
} else {
sq_pushinteger(v, N);
sq_newtable(v);
holder.AttachToStackObject(-1);
sq_rawset(v, -3);
sq_pop(v, 1);
}
}
return holder;
}
template<typename Func>
class SQOverloader {
private:
static inline SQInteger switcher(HSQUIRRELVM v,
int(*caller)(int, HSQUIRRELVM, int),
int fidx) {
return (*caller)(StackHandler(v).GetParamCount() - 1,
v,
fidx);
}
static inline SQInteger memberSwitcher(HSQUIRRELVM v) {
SQInteger fidx;
sq_pushobject(v, indexHolder<0>(v).GetObjectHandle());
sq_push(v, 0); // native closure
sq_rawget(v, -2);
sq_getinteger(v, -1, &fidx);
sq_pop(v, 2);
return switcher(v, SQFuncHolder::memberCall, fidx);
}
static inline SQInteger staticSwitcher(HSQUIRRELVM v) {
SQInteger fidx;
sq_pushobject(v, indexHolder<1>(v).GetObjectHandle());
sq_push(v, 0); // native closure
sq_rawget(v, -2);
sq_getinteger(v, -1, &fidx);
sq_pop(v, 2);
return switcher(v, SQFuncHolder::staticCall, fidx);
}
static inline SQInteger constructorSwitcher(HSQUIRRELVM v) {
return switcher(v, SQFuncHolder::constructorCall, 0);
}
public:
static inline void addMemberFunc(SQClassDefBase<TClassType,TClassBase> *def,
Func mfunc,
const SQChar *name) {
const int fidx = def->overloadedMemberNames.index(name);
SQFuncHolder::addMemberFunc(fidx, mfunc);
def->staticFuncVarArgs(memberSwitcher, name);
HSQUIRRELVM v = def->v;
// get closure
sq_pushobject(v, def->newClass.GetObjectHandle());
sq_pushstring(v, name, -1);
sq_rawget(v, -2);
// holder[closure] = fidx
sq_pushobject(v, indexHolder<0>(v).GetObjectHandle());
sq_push(v, -2);
sq_pushinteger(v, fidx);
sq_rawset(v, -3);
//
sq_pop(v, 3);
}
static inline void addOperatorFunc(SQClassDefBase<TClassType,TClassBase> *def,
Func ofunc,
const SQChar *name) {
if (Arg<Func>::num() != 1) {
//assert(false &&
// "Cannot add this function as operator (argc != 1)");
abort();
}
SQChar proxy[256];
scsprintf(proxy, _SC("overloaded%s"), name);
addMemberFunc(def, ofunc, proxy);
SQChar script[512];
scsprintf(script, _SC("%s.%s<-function(o){return %s.%s(o);}"),
def->name, name, def->name, proxy);
SquirrelVM::RunScript(SquirrelVM::CompileBuffer(script));
}
static inline void addStaticFunc(SQClassDefBase<TClassType,TClassBase> *def,
Func sfunc,
const SQChar *name) {
const int fidx = def->overloadedStaticMemberNames.index(name);
SQFuncHolder::addStaticFunc(fidx, sfunc);
def->staticFuncVarArgs(staticSwitcher, name);
HSQUIRRELVM v = def->v;
// get closure
sq_pushobject(v, def->newClass.GetObjectHandle());
sq_pushstring(v, name, -1);
sq_rawget(v, -2);
// holder[closure] = fidx
sq_pushobject(v, indexHolder<1>(v).GetObjectHandle());
sq_push(v, -2);
sq_pushinteger(v, fidx);
sq_rawset(v, -3);
//
sq_pop(v, 3);
}
template<typename Cfunc>
static inline void addConstructor(SQClassDefBase<TClassType,TClassBase> *def,
Cfunc cfunc) {
SQFuncHolder::addConstructor(cfunc);
def->staticFuncVarArgs(constructorSwitcher, _SC("constructor"));
}
static inline void addGlobalFunc(SQClassDefBase<TClassType,TClassBase> *def,
Func gfunc,
const SQChar *name) {
const int fidx = def->overloadedStaticMemberNames.index(name);
SQFuncHolder::addStaticFunc(fidx, gfunc);
SquirrelVM::CreateFunctionGlobal(staticSwitcher, name, _SC("*"));
HSQUIRRELVM v = def->v;
// get closure
sq_pushroottable(v);
sq_pushstring(v, name, -1);
sq_rawget(v, -2);
// holder[closure] = fidx
sq_pushobject(v, indexHolder<1>(v).GetObjectHandle());
sq_push(v, -2);
sq_pushinteger(v, fidx);
sq_rawset(v, -3);
//
sq_pop(v, 3);
}
};
public:
template<typename Mfunc>
SQClassDefBase<TClassType,TClassBase> &overloadFunc(Mfunc mfunc, const SQChar *n) {
SQOverloader<Mfunc>::addMemberFunc(this, mfunc, n);
return *this;
}
template<typename Ofunc>
SQClassDefBase<TClassType,TClassBase> &overloadOperator(Ofunc ofunc, const SQChar *n){
SQOverloader<Ofunc>::addOperatorFunc(this, ofunc, n);
return *this;
}
template<typename Sfunc>
SQClassDefBase<TClassType,TClassBase> &overloadStaticFunc(Sfunc sfunc,
const SQChar *n) {
SQOverloader<Sfunc>::addStaticFunc(this, sfunc, n);
return *this;
}
template<typename Cmetafunc>
SQClassDefBase<TClassType,TClassBase> &overloadConstructor(void) {
SQOverloader<Cmetafunc>::addConstructor(this, &Arg<Cmetafunc>::create);
return *this;
}
template<typename Cfunc>
SQClassDefBase<TClassType,TClassBase> &overloadConstructor(Cfunc cfunc) {
SQOverloader<Cfunc>::addConstructor(this, cfunc);
return *this;
}
template<typename Gfunc>
SQClassDefBase<TClassType,TClassBase> &overloadGlobalFunc(Gfunc gfunc,
const SQChar *n) {
SQOverloader<Gfunc>::addGlobalFunc(this, gfunc, n);
return *this;
}
#endif // SQPLUS_OVERLOAD_IMPLEMENTATION
#ifdef SQPLUS_OVERLOAD_FUNCTIONS
#undef SQPLUS_OVERLOAD_FUNCTIONS
struct GlobalFuncOverloader {};
static inline SQClassDefBase<GlobalFuncOverloader,SQNoBaseClass> &globalFuncOverloader(void)
{
static SQClassDefBase<GlobalFuncOverloader,SQNoBaseClass> fo(_SC("GlobalFuncOverloader"));
return fo;
}
template<typename Gfunc> void
OverloadGlobal(Gfunc gfunc, const SQChar *n)
{
globalFuncOverloader().overloadGlobalFunc(gfunc, n);
}
template<typename TYPE> struct CheckInstance {
template<typename T> struct unref {typedef T type;};
template<typename T> struct unref<T&> {typedef T type;};
template<typename T> struct unref<T*> {typedef T type;};
template<typename T> struct unref<const T&> {typedef T type;};
template<typename T> struct unref<const T*> {typedef T type;};
/*
d = -1 : not in hierarchy
d = 0 : same
d > 0 : similar (o is d-th subclass of TYPE)
*/
static inline int distance(HSQUIRRELVM v, int index) {
HSQOBJECT o;
sq_resetobject(&o);
sq_getstackobj(v, index, &o);
const int top = sq_gettop(v);
sq_pushroottable(v);
// Check plain object type
int d = -1;
if (Match(TypeWrapper<TYPE>(), v, index)) {
d = 0;
// Check instance type hierarchy
if (sq_type(o) == OT_INSTANCE) {
SQUserPointer dsttype =
ClassType<typename unref<TYPE>::type>::type();
SQUserPointer argtype;
for (sq_getclass(v, index);
sq_gettypetag(v, -1, &argtype) == SQ_OK;
sq_getbase(v, -1)) {
if (argtype == dsttype) {
goto SQPLUS_OVERLOAD_DISTANCE_IMMEDIATE_RETURN;
}
++d;
}
d = -1; // no matching type found
}
}
SQPLUS_OVERLOAD_DISTANCE_IMMEDIATE_RETURN:
sq_settop(v, top);
return d;
}
};
template<typename T, typename R>
struct Arg<R(T::*)(void)> {
static inline int num(void) {return 0;}
static inline int argTypeDistance(HSQUIRRELVM) {
return 0;
}
};
template<typename T, typename R, typename A1>
struct Arg<R(T::*)(A1)> {
static inline int num(void) {return 1;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2>
struct Arg<R(T::*)(A1, A2)> {
static inline int num(void) {return 2;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2, typename A3>
struct Arg<R(T::*)(A1, A2, A3)> {
static inline int num(void) {return 3;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2, A3)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2, typename A3, typename A4>
struct Arg<R(T::*)(A1, A2, A3, A4)> {
static inline int num(void) {return 4;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2, A3, A4)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2, typename A3, typename A4, typename A5>
struct Arg<R(T::*)(A1, A2, A3, A4, A5)> {
static inline int num(void) {return 5;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2, A3, A4, A5)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
struct Arg<R(T::*)(A1, A2, A3, A4, A5, A6)> {
static inline int num(void) {return 6;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2, A3, A4, A5, A6)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
struct Arg<R(T::*)(A1, A2, A3, A4, A5, A6, A7)> {
static inline int num(void) {return 7;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2, A3, A4, A5, A6, A7)>::argTypeDistance(v);
}
};
#ifdef SQPLUS_CONST_OPT
template<typename T, typename R>
struct Arg<R(T::*)(void) const> {
static inline int num(void) {return 0;}
static inline int argTypeDistance(HSQUIRRELVM) {
return 0;
}
};
template<typename T, typename R, typename A1>
struct Arg<R(T::*)(A1) const> {
static inline int num(void) {return 1;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2>
struct Arg<R(T::*)(A1, A2) const> {
static inline int num(void) {return 2;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2, typename A3>
struct Arg<R(T::*)(A1, A2, A3) const> {
static inline int num(void) {return 3;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2, A3)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2, typename A3, typename A4>
struct Arg<R(T::*)(A1, A2, A3, A4) const> {
static inline int num(void) {return 4;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2, A3, A4)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2, typename A3, typename A4, typename A5>
struct Arg<R(T::*)(A1, A2, A3, A4, A5) const> {
static inline int num(void) {return 5;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2, A3, A4, A5)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
struct Arg<R(T::*)(A1, A2, A3, A4, A5, A6) const> {
static inline int num(void) {return 6;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2, A3, A4, A5, A6)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
struct Arg<R(T::*)(A1, A2, A3, A4, A5, A6, A7) const> {
static inline int num(void) {return 7;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2, A3, A4, A5, A6, A7)>::argTypeDistance(v);
}
};
#endif
static inline int classAllocationError(HSQUIRRELVM v) {
return sq_throwerror(v, _SC("Failed to allocate memory"));
}
template<typename R>
struct Arg<R(*)(void)> {
static inline int num(void) {return 0;}
static inline int argTypeDistance(HSQUIRRELVM) {return 0;}
static inline int create(void) {
HSQUIRRELVM v = SquirrelVM::GetVMPtr();
R *r = static_cast<R*>(sq_malloc(sizeof(R)));
return r ?
PostConstruct<R>(v, new(r) R,
ClassType<R>::getReleaseHook()) :
classAllocationError(v);
}
};
template<typename R, typename A1>
struct Arg<R(*)(A1)> {
static inline int num(void) {return 1;}
static inline int argTypeDistance(HSQUIRRELVM v) {
int s, r;
r = 0;
s = CheckInstance<A1>::distance(v, 2); if (s < 0) {return -1;} r += s;
return r;
}
static inline int create(A1 a1) {
HSQUIRRELVM v = SquirrelVM::GetVMPtr();
R *r = static_cast<R*>(sq_malloc(sizeof(R)));
return r ?
PostConstruct<R>(v, new(r) R(a1),
ClassType<R>::getReleaseHook()) :
classAllocationError(v);
}
};
template<typename R, typename A1, typename A2>
struct Arg<R(*)(A1, A2)> {
static inline int num(void) {return 2;}
static inline int argTypeDistance(HSQUIRRELVM v) {
int s, r;
r = 0;
s = CheckInstance<A1>::distance(v, 2); if (s < 0) {return -1;} r += s;
s = CheckInstance<A2>::distance(v, 3); if (s < 0) {return -1;} r += s;
return r;
}
static inline int create(A1 a1, A2 a2) {
HSQUIRRELVM v = SquirrelVM::GetVMPtr();
R *r = static_cast<R*>(sq_malloc(sizeof(R)));
return r ?
PostConstruct<R>(v, new(r) R(a1, a2),
ClassType<R>::getReleaseHook()) :
classAllocationError(v);
}
};
template<typename R, typename A1, typename A2, typename A3>
struct Arg<R(*)(A1, A2, A3)> {
static inline int num(void) {return 3;}
static inline int argTypeDistance(HSQUIRRELVM v) {
int s, r;
r = 0;
s = CheckInstance<A1>::distance(v, 2); if (s < 0) {return -1;} r += s;
s = CheckInstance<A2>::distance(v, 3); if (s < 0) {return -1;} r += s;
s = CheckInstance<A3>::distance(v, 4); if (s < 0) {return -1;} r += s;
return r;
}
static inline int create(A1 a1, A2 a2, A3 a3) {
HSQUIRRELVM v = SquirrelVM::GetVMPtr();
R *r = static_cast<R*>(sq_malloc(sizeof(R)));
return r ?
PostConstruct<R>(v, new(r) R(a1, a2, a3),
ClassType<R>::getReleaseHook()) :
classAllocationError(v);
}
};
template<typename R, typename A1, typename A2, typename A3, typename A4>
struct Arg<R(*)(A1, A2, A3, A4)> {
static inline int num(void) {return 4;}
static inline int argTypeDistance(HSQUIRRELVM v) {
int s, r;
r = 0;
s = CheckInstance<A1>::distance(v, 2); if (s < 0) {return -1;} r += s;
s = CheckInstance<A2>::distance(v, 3); if (s < 0) {return -1;} r += s;
s = CheckInstance<A3>::distance(v, 4); if (s < 0) {return -1;} r += s;
s = CheckInstance<A4>::distance(v, 5); if (s < 0) {return -1;} r += s;
return r;
}
static inline int create(A1 a1, A2 a2, A3 a3, A4 a4) {
HSQUIRRELVM v = SquirrelVM::GetVMPtr();
R *r = static_cast<R*>(sq_malloc(sizeof(R)));
return r ?
PostConstruct<R>(v, new(r) R(a1, a2, a3, a4),
ClassType<R>::getReleaseHook()) :
classAllocationError(v);
}
};
template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5>
struct Arg<R(*)(A1, A2, A3, A4, A5)> {
static inline int num(void) {return 5;}
static inline int argTypeDistance(HSQUIRRELVM v) {
int s, r;
r = 0;
s = CheckInstance<A1>::distance(v, 2); if (s < 0) {return -1;} r += s;
s = CheckInstance<A2>::distance(v, 3); if (s < 0) {return -1;} r += s;
s = CheckInstance<A3>::distance(v, 4); if (s < 0) {return -1;} r += s;
s = CheckInstance<A4>::distance(v, 5); if (s < 0) {return -1;} r += s;
s = CheckInstance<A5>::distance(v, 6); if (s < 0) {return -1;} r += s;
return r;
}
static inline int create(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
HSQUIRRELVM v = SquirrelVM::GetVMPtr();
R *r = static_cast<R*>(sq_malloc(sizeof(R)));
return r ?
PostConstruct<R>(v, new(r) R(a1, a2, a3, a4, a5),
ClassType<R>::getReleaseHook()) :
classAllocationError(v);
}
};
template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
struct Arg<R(*)(A1, A2, A3, A4, A5, A6)> {
static inline int num(void) {return 6;}
static inline int argTypeDistance(HSQUIRRELVM v) {
int s, r;
r = 0;
s = CheckInstance<A1>::distance(v, 2); if (s < 0) {return -1;} r += s;
s = CheckInstance<A2>::distance(v, 3); if (s < 0) {return -1;} r += s;
s = CheckInstance<A3>::distance(v, 4); if (s < 0) {return -1;} r += s;
s = CheckInstance<A4>::distance(v, 5); if (s < 0) {return -1;} r += s;
s = CheckInstance<A5>::distance(v, 6); if (s < 0) {return -1;} r += s;
s = CheckInstance<A6>::distance(v, 7); if (s < 0) {return -1;} r += s;
return r;
}
static inline int create(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
HSQUIRRELVM v = SquirrelVM::GetVMPtr();
R *r = static_cast<R*>(sq_malloc(sizeof(R)));
return r ?
PostConstruct<R>(v, new(r) R(a1, a2, a3, a4, a5, a6),
ClassType<R>::getReleaseHook()) :
classAllocationError(v);
}
};
template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
struct Arg<R(*)(A1, A2, A3, A4, A5, A6, A7)> {
static inline int num(void) {return 7;}
static inline int argTypeDistance(HSQUIRRELVM v) {
int s, r;
r = 0;
s = CheckInstance<A1>::distance(v, 2); if (s < 0) {return -1;} r += s;
s = CheckInstance<A2>::distance(v, 3); if (s < 0) {return -1;} r += s;
s = CheckInstance<A3>::distance(v, 4); if (s < 0) {return -1;} r += s;
s = CheckInstance<A4>::distance(v, 5); if (s < 0) {return -1;} r += s;
s = CheckInstance<A5>::distance(v, 6); if (s < 0) {return -1;} r += s;
s = CheckInstance<A6>::distance(v, 7); if (s < 0) {return -1;} r += s;
s = CheckInstance<A7>::distance(v, 8); if (s < 0) {return -1;} r += s;
return r;
}
static inline int create(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
HSQUIRRELVM v = SquirrelVM::GetVMPtr();
R *r = static_cast<R*>(sq_malloc(sizeof(R)));
return r ?
PostConstruct<R>(v, new(r) R(a1, a2, a3, a4, a5, a6, a7),
ClassType<R>::getReleaseHook()) :
classAllocationError(v);
}
};
#endif // SQPLUS_OVERLOAD_FUNCTIONS
// SqPlusOverload.h
// Local Variables:
// mode: c++
// End:

View File

@ -0,0 +1,129 @@
#ifndef SQPLUSSETUP_H
#define SQPLUSSETUP_H
// Setup file for SqPlus.
// Comment / uncomment / define options below.
// Inheritance in Squirrel allows one class to inherit a base class's
// functions and variables.
//
// Variables are merged: if Derived has a var name 'val' and Base has
// a var of the same name, the resulting var 'val' will take Derived's
// initialization value.
//
// Functions are not merged, and can be called via Squirrel scoping rules.
//
// Define SQ_USE_CLASS_INHERITANCE to enable class inheritance support
// (requires slightly more memory and adds some CPU overhead).
//
// Can also be useful for debugging, as class type information is
// checked before dispatching instance function calls and before
// accessing instance member variables.
#define SQ_USE_CLASS_INHERITANCE
// This is a new C++ template based inheritence scheme that uses no
// additional memory per instance. To support offset between "this"
// pointer in base and derived class, use a second class in:
// SQClassDef< MyClass, MyBaseClass >.
// NOTE: For new code SQ_USE_CLASS_INHERITANCE_SIMPLE is more
// efficient than above method.
//#define SQ_USE_CLASS_INHERITANCE_SIMPLE
// === Instance type info support ===
#define SQ_SUPPORT_INSTANCE_TYPE_INFO
// === Constant argument and constant member function support ===
// Define SQPLUS_CONST_OPT before including SqPlus.h for constant
// argument + constant member function support.
#define SQPLUS_CONST_OPT
// === Uncomment to support smart pointer ===
// Define SQPLUS_SMARTPOINTER_OPT before including SqPlus.h for
// smartpointer member function + variable support
//#define SQPLUS_SMARTPOINTER_OPT
// === Function overloading support ===
#define SQPLUS_OVERLOAD_OPT
// === Uncomment to support std::string ===
// Requires that Squirrel is compiled with SQChar == char
//#define SQPLUS_SUPPORT_STD_STRING
// === Uncomment to support typedef std::basic_string<SQChar> sq_std_string ===
#define SQPLUS_SUPPORT_SQ_STD_STRING
// === Uncomment to support NULL INSTANCE arguments ===
#define SQPLUS_SUPPORT_NULL_INSTANCES
// === Uncomment to disable copying of class instances ===
// If classes being exposed have private or protected constructors
// one cannot do assign (=) in template functions.
//#define SQPLUS_DISABLE_COPY_INSTANCES
// === Auto generating typemasks for registered functions ===
// This is useful when using Squirrel interactively
//#define SQPLUS_ENABLE_AUTO_TYPEMASK
// === Uncomment to generate a typeof function for each class ===
// This is mostly for displaying function help from inside a Squirrel prompt
//#define SQPLUS_ENABLE_TYPEOF
// === Uncomment to skip sq_argassert() ===
//#define SQ_SKIP_ARG_ASSERT
// === GCC Inline template fix ===
// Can solve problems when linking if GCC has problems with inline functions
//#define GCC_INLINE_WORKAROUND
// === MSVC cdecl member functions ===
// Enable binding member functions with __cdecl calling convention under MSVC.
// Mostly useful when linking with binaries from other compilers.
#ifdef _MSC_VER
//#define SQPLUS_ENABLE_CDECL_MEMBER_FUNCTIONS
#endif
// === Generic Push/Pop/Match handlers ===
// This enables using a 'fallback' set of Push/Get/Match that operates
// on class level (not on template level). This opens for handling all
// members of a certain class hierarchy using the same function
// GenPush/GenGet/GenMatch overrides (provided the hierarchy has some
// run-time type mechanism to use). They are used whenever an exact
// template match is not found.
//#define SQPLUS_USE_GENERIC_HANDLERS
// === Sandbox VM ===
// This enables giving one VM the role of 'sandbox' VM where scripts
// of unknown origin may execute and not have access to any SqPlus
// registered functions. All normal VMs have full access to script
// functions, but the one given in SetSandboxVm() can only use std
// Squirrel functions.
//#define SQPLUS_USE_SANDBOX_VM
#if defined(SQPLUS_SUPPORT_STD_STRING) || defined(SQPLUS_SUPPORT_SQ_STD_STRING)
# include <string>
#endif
// === Conversion of arguments from opposite char type ( char <=> wchar_t ) ===
// Converts strings to opposite encoding in Push/Get handlers (UTF8 / Latin1)
#define SQPLUS_AUTOCONVERT_OTHER_CHAR
// === Whether 8 bit chars are treated as Latin1(1) or UTF8(0) ===
// (leave undefined for undefined for automatic handling)
#define SQPLUS_USE_LATIN1 1
// === Include system library bindings when creating VM:s in SquirrelVM::Init() ===
// Define to bind to system lib when VM:s are created automatically in
// SquirrelVM::Init()
//#define SQPLUS_SQUIRRELVM_WITH_SYSTEMLIB
#endif // SQPLUSSETUP_H

View File

@ -0,0 +1,141 @@
// SqPlusSmartPointer.h
// SqPlus smart pointer member function support created by James Whitworth.
// Modular integration 07/11/07 James Whitworth.
// you must define the function:
// unsigned char* getSmartPointerPointee(unsigned char*) {
// return &(MySmartPointer->pointee);
// }
// somewhere in your program so it can correctly lookup member variables on the class pointed to
// by your smart pointer.
#ifdef SQPLUS_SMARTPOINTER_ACCESSTYPE
#undef SQPLUS_SMARTPOINTER_ACCESSTYPE
enum VarAccessType {VAR_ACCESS_READ_WRITE=0,VAR_ACCESS_READ_ONLY=1<<0,VAR_ACCESS_CONSTANT=1<<1,VAR_ACCESS_STATIC=1<<2,VAR_ACCESS_SMARTPOINTER=1<<3};
#endif // #ifdef SQPLUS_SMARTPOINTER_ACCESSTYPE
#ifdef SQPLUS_SMARTPOINTER_REGISTER_VARIABLE
#undef SQPLUS_SMARTPOINTER_REGISTER_VARIABLE
// classType is the type of the member variable's containing class.
template<typename T>
void
RegisterSmartInstanceVariable(SquirrelObject & so,
ClassTypeBase *classType,
T *var,
const SQChar *scriptVarName,
VarAccessType access = VAR_ACCESS_READ_WRITE)
{
VarRef *pvr = createVarRef(so,scriptVarName);
// var must be passed in as &obj->var, where obj = 0
// (the address is the offset), or as static/global address.
void *offsetOrAddrOrConst = static_cast<void*>(var);
*pvr = VarRef(offsetOrAddrOrConst,
TypeInfo<T>(),
classType,
ClassType<T>::type(),
sizeof(*var),
access);
pvr->m_access |= VAR_ACCESS_SMARTPOINTER;
createInstanceSetGetHandlers(so);
}
#endif // #ifdef SQPLUS_SMARTPOINTER_REGISTER_VARIABLE
#ifdef SQPLUS_SMARTPOINTER_DISPATCH
#undef SQPLUS_SMARTPOINTER_DISPATCH
template<typename Callee,typename Pointee,typename Func>
class DirectCallSmartInstanceMemberFunction {
public:
static inline int Dispatch(HSQUIRRELVM v) {
DirectCallInstanceFuncPicker<Callee, Func> p(v);
if (!p.instance || !p.func) {
sq_throwerror(v, _SC("Invalid Instance Type"));
}
Pointee *pointeeInstance = static_cast<Pointee*>(p.instance->get());
return
!pointeeInstance ? sq_throwerror(v, _SC("SmartPointer Pointee NULL")) :
Call(*pointeeInstance, *(p.func), v, 2);
}
};
#endif // #ifdef SQPLUS_SMARTPOINTER_DISPATCH
#ifdef SQPLUS_SMARTPOINTER_DIRECT_CLOSURE
#undef SQPLUS_SMARTPOINTER_DIRECT_CLOSURE
template<typename Callee,typename Pointee,typename Func>
inline void sq_pushdirectsmartinstanceclosure(HSQUIRRELVM v,const Callee & callee,const Pointee & pointee,Func func,SQUnsignedInteger nupvalues) {
unsigned char * up = (unsigned char *)sq_newuserdata(v,sizeof(func)); // Also pushed on stack.
memcpy(up,&func,sizeof(func));
sq_newclosure(v,DirectCallSmartInstanceMemberFunction<Callee,Pointee,Func>::Dispatch,nupvalues+1);
} // sq_pushdirectinstanceclosure
#endif // #ifdef SQPLUS_SMARTPOINTER_DIRECT_CLOSURE
#ifdef SQPLUS_SMARTPOINTER_REGISTER_INSTANCE
#undef SQPLUS_SMARTPOINTER_REGISTER_INSTANCE
template<typename Callee, typename Pointee, typename Func>
inline void RegisterSmartInstance(HSQUIRRELVM v,HSQOBJECT hclass,Callee & callee,Pointee & pointee,Func func,const SQChar * name) {
sq_pushobject(v,hclass);
sq_pushstring(v,name,-1);
sq_pushdirectsmartinstanceclosure(v,callee,pointee,func,0);
sq_createslot(v,-3);
sq_poptop(v); // Remove hclass.
} // RegisterInstance
#endif // #ifdef SQPLUS_SMARTPOINTER_REGISTER_INSTANCE
#ifdef SQPLUS_SMARTPOINTER_CLASS_DEF_FUNC
#undef SQPLUS_SMARTPOINTER_CLASS_DEF_FUNC
// Register a smartpointer member function.
template<typename Pointee, typename Func>
SQClassDefBase & smartFunc(Func pfunc,const SQChar * name) {
RegisterSmartInstance(v,newClass.GetObjectHandle(),*(TClassType *)0,*(Pointee *)0,pfunc,name);
return *this;
} // func
#endif // #ifdef SQPLUS_SMARTPOINTER_CLASS_DEF_FUNC
#ifdef SQPLUS_SMARTPOINTER_CLASS_DEF_VAR
#undef SQPLUS_SMARTPOINTER_CLASS_DEF_VAR
// Register a member variable.
template<typename Pointee, typename VarType>
SQClassDefBase & smartVar(VarType Pointee::* pvar,const SQChar * name,VarAccessType access=VAR_ACCESS_READ_WRITE) {
struct CV {
VarType Pointee::* var;
} cv; // Cast Variable helper.
cv.var = pvar;
RegisterSmartInstanceVariable(newClass,ClassType<TClassType>::type(),*(VarType **)&cv,name,access);
return *this;
} // var
// Register a member variable as a UserPointer (read only).
template<typename Pointee, typename VarType>
SQClassDefBase & smartVarAsUserPointer(VarType Pointee::* pvar,const SQChar * name) {
struct CV {
VarType Pointee::* var;
} cv; // Cast Variable helper.
cv.var = pvar;
RegisterSmartInstanceVariable(newClass,ClassType<TClassType>::type(),*(SQAnything **)&cv,name,VAR_ACCESS_READ_ONLY);
return *this;
} // varAsUserPointer
#endif // #ifdef SQPLUS_SMARTPOINTER_CLASS_DEF_VAR
#ifdef SQPLUS_SMARTPOINTER_CPP_DECLARATION
#undef SQPLUS_SMARTPOINTER_CPP_DECLARATION
extern unsigned char* getSmartPointerPointee(unsigned char*);
#endif
#ifdef SQPLUS_SMARTPOINTER_INSTANCE_VARINFO
#undef SQPLUS_SMARTPOINTER_INSTANCE_VARINFO
if(vr->m_access & VAR_ACCESS_SMARTPOINTER) {
up = reinterpret_cast<char*>(
getSmartPointerPointee(reinterpret_cast<unsigned char*>(up))
);
}
#endif // #ifdef SQPLUS_SMARTPOINTER_CPP_DECLARATION
// SqPlusSmartPointer.h

View File

@ -0,0 +1,169 @@
// File to automatically generate a typemask for a function
// Will generate type masks that accepts Instance pointer or null
#ifndef SQPLUS_ACCEPT_NULL_INSTANCE
#define SQPLUS_ACCEPT_NULL_INSTANCE
#endif
// Macros to reduce typing: (P1), (P1,P2), (P1,P2,P3), ...
#define P_0
#define P_1 P1
#define P_2 P_1,P2
#define P_3 P_2,P3
#define P_4 P_3,P4
#define P_5 P_4,P5
#define P_6 P_5,P6
#define P_7 P_6,P7
// Macros to reduce typing: (typename P1), (typename P1,typename P2), ...
#define PTN_0
#define PTN_1 typename P1
#define PTN_2 PTN_1,typename P2
#define PTN_3 PTN_2,typename P3
#define PTN_4 PTN_3,typename P4
#define PTN_5 PTN_4,typename P5
#define PTN_6 PTN_5,typename P6
#define PTN_7 PTN_6,typename P7
// Include a comma first in list: ,typename P1,typename P2
#define PTNC_0
#define PTNC_1 ,PTN_1
#define PTNC_2 ,PTN_2
#define PTNC_3 ,PTN_3
#define PTNC_4 ,PTN_4
#define PTNC_5 ,PTN_5
#define PTNC_6 ,PTN_6
#define PTNC_7 ,PTN_7
#ifdef SQUNICODE
#define scstrcpy wcscpy
#else
#define scstrcpy strcpy
#endif
inline const SQChar* strappchar(SQChar *buf, SQChar *in, SQChar ch){
int l=scstrlen(in);
scstrcpy(buf,in);
buf[l] = ch;
#ifdef SQPLUS_ACCEPT_NULL_INSTANCE
if( ch=='x' ){
buf[++l] = '|'; // Also accept NULL pointers
buf[++l] = 'o';
}
#endif
buf[l+1] = 0;
return buf;
}
template<class T>
struct sqTypeMask { };
// Return type not included in type mask, delegate to void case
// Base case, no arguments
template<typename RT>
struct sqTypeMask<RT(*)()> {
static const SQChar *Get(){
static SQChar buf[64];
//buf[0] = _SC('t');
//buf[1] = 0;
//strcpy(buf,"t|x"); // Accept both instance and table, we don't use param anyway
buf[0] = _SC('.'); // Accept anything (not used)
buf[1] = 0;
return buf;
}
};
// Recursive case, peel of one arg at each level
#define DECLARE_RT_SQTYPEMASK(N,M) \
template<typename RT PTNC_##N> \
struct sqTypeMask<RT(*)(P_##N)> { \
static const SQChar *Get(){ \
static SQChar buf[10]; \
return strappchar(buf, (SQChar*)sqTypeMask<RT(*)(P_##M)>::Get(), \
(SQChar)TypeInfo<P##N>::TypeMask); \
} \
};
DECLARE_RT_SQTYPEMASK(1,0)
DECLARE_RT_SQTYPEMASK(2,1)
DECLARE_RT_SQTYPEMASK(3,2)
DECLARE_RT_SQTYPEMASK(4,3)
DECLARE_RT_SQTYPEMASK(5,4)
DECLARE_RT_SQTYPEMASK(6,5)
DECLARE_RT_SQTYPEMASK(7,6)
// Difference to above is that 1st param is instance instead of table
#define DECLARE_RT_MEMBER_SQTYPEMASK(N,QUAL) \
template<typename Callee, typename RT PTNC_##N> \
struct sqTypeMask<RT(Callee::*)(P_##N) QUAL> { \
static const SQChar *Get(){ \
SQChar *buf = (SQChar*)sqTypeMask<RT(*)(P_##N)>::Get(); \
buf[0] = _SC('x'); \
return buf; \
} \
};
// buf[1] = 0; \
DECLARE_RT_MEMBER_SQTYPEMASK(0,)
DECLARE_RT_MEMBER_SQTYPEMASK(1,)
DECLARE_RT_MEMBER_SQTYPEMASK(2,)
DECLARE_RT_MEMBER_SQTYPEMASK(3,)
DECLARE_RT_MEMBER_SQTYPEMASK(4,)
DECLARE_RT_MEMBER_SQTYPEMASK(5,)
DECLARE_RT_MEMBER_SQTYPEMASK(6,)
DECLARE_RT_MEMBER_SQTYPEMASK(7,)
DECLARE_RT_MEMBER_SQTYPEMASK(0,const)
DECLARE_RT_MEMBER_SQTYPEMASK(1,const)
DECLARE_RT_MEMBER_SQTYPEMASK(2,const)
DECLARE_RT_MEMBER_SQTYPEMASK(3,const)
DECLARE_RT_MEMBER_SQTYPEMASK(4,const)
DECLARE_RT_MEMBER_SQTYPEMASK(5,const)
DECLARE_RT_MEMBER_SQTYPEMASK(6,const)
DECLARE_RT_MEMBER_SQTYPEMASK(7,const)
#ifdef _MSC_VER
// Difference to above is we're using __cdecl calling convention here
// Only makes sense for MSVC where member functions can have different
// calling conventions (__cdecl or __thiscall)
#define DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(N,QUAL) \
template<typename Callee, typename RT PTNC_##N> \
struct sqTypeMask<RT(__cdecl Callee::*)(P_##N) QUAL> { \
static const SQChar *Get(){ \
SQChar *buf = (SQChar*)sqTypeMask<RT(*)(P_##N)>::Get(); \
buf[0] = _SC('x'); \
return buf; \
} \
};
// buf[1] = 0; \
DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(0,)
DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(1,)
DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(2,)
DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(3,)
DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(4,)
DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(5,)
DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(6,)
DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(7,)
DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(0,const)
DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(1,const)
DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(2,const)
DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(3,const)
DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(4,const)
DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(5,const)
DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(6,const)
DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(7,const)
#endif // _MSC_VER

View File

@ -0,0 +1,133 @@
///////////////////////////////////////////////////////////////////////
// Simple conversion routines, to, from UTF8 and full Unicode character
// (using int).
//
// Only when needed
#if !defined(SQPLUS_USE_LATIN1) || SQPLUS_USE_LATIN1==0
static char g_utf8_length[256];
static int g_did_init_length;
void sqplus_init_utf8_lengths() {
// Fill in lengths in array above
for( int lb=0; lb<256; lb++ ){
int l = -1;
if( !(lb&0x80) ) l=1;
else if( (lb&0xE0)==0xC0 ) l=2;
else if( (lb&0xF0)==0xE0 ) l=3;
else if( (lb&0xF8)==0xF0 ) l=4;
else if( (lb&0xFC)==0xF8 ) l=5;
else if( (lb&0xFE)==0xFC ) l=6;
g_utf8_length[lb] = l;
}
g_did_init_length = 1;
}
// Length of a UTF8 encoded Unicode character
int sqplus_utf8_len(int lead_byte){
if( !(lead_byte&0x80) ) return 1; // Special case, make faster
if( !g_did_init_length )
sqplus_init_utf8_lengths();
return g_utf8_length[(unsigned char)lead_byte];
}
int sqplus_utf8_len_first(const char* pc){
int lb = *(unsigned char*)pc;
if( !(lb&0x80) ) return 1; // Special case, make faster
if( !g_did_init_length )
sqplus_init_utf8_lengths();
int l = g_utf8_length[(unsigned char)lb];
if( l>0 ) return l;
// Invalid UTF8 lead byte. Look for next valid character.
const char *pc1 = pc+1;
while( ((*pc1)&0xC0)==0x80 )
pc1++;
return int(pc1 - pc);
}
// Length of a UTF8 encoded Unicode string (number of Unicode characters)
int sqplus_utf8_strlen(const char *str) {
if( !str ) return 0;
int l, tl=0;
while( *str ){
l = sqplus_utf8_len_first(str);
str += l;
tl++;
}
return tl;
}
// Convert one UTF8 encoded character to Unicode point
int sqplus_utf8_to_wchar(int *result, const char *string){
int res=-1;
// Assume argument pointers to be OK
unsigned char ch = *string;
int l = sqplus_utf8_len(ch);
if( l<1 ) return -1;
int wc = l>1 ? (ch&(0x7F>>l)) : ch;
while( l>1 ){
wc = (wc<<6) + (*++string & 0x3F);
l--;
}
*result = wc;
return 0;
}
// Convert one Unicode point to UTF8 encoded version.
// Checks if output fits in 1/4/6 bytes buffer.
int sqplus_wchar_to_utf8(char *s, int wc, int size){
if( size<1 ) return -1;
if( (unsigned int)wc>=0x80000000 ) return -2;
// Single byte case
if( wc<0x80 ){
*s = (char)wc;
//*s = (char)wc&0x7F;
return 1;
}
if( size<4 ) return -3;
// Two or more UTF8 bytes
int p = 1; // Index of last UTF8 byte
if( wc>0x7FF ){ // 11 bits
// Three or more UTF8 bytes
p++; // p>=2
if( wc>0xFFFF ){ // 16 bits
// Four or more UTF8 bytes
p++; // p>=3
if( wc>0x1FFFFF ){ // 21 bits
// Five or more UTF8 bytes
if( size<6 ) return -3;
p++; // p>=4 UTF8 bytes
if( wc>0x3FFFFFF ){ // 26 bits
// Six UTF8 bytes
p++; // p>=5
if( (unsigned int)wc>(unsigned int)0x7FFFFFF ){ // 31 bits
// Would need 7 UTF8 bytes. Not supported.
return -10;
}
s[p-4] = 0x80 | ((wc>>24)&0x3F); // Bit 24..29
}
s[p-3] = 0x80 | ((wc>>18)&0x3F); // Bit 18..23
}
s[p-2] = 0x80 | ((wc>>12)&0x3F); // Bit 12..17
}
s[p-1] = 0x80 | ((wc>>6)&0x3F); // Bit 6..11
}
s[p] = 0x80 | (wc&0x3F); // Bit 0..5
s[0] = (0xFC << (5-p)) | (wc>>(p*6));
return p+1;
}
#endif // #if !defined(SQPLUS_USE_LATIN1) || SQPLUS_USE_LATIN1==0

View File

@ -0,0 +1,15 @@
#ifndef SQPLUSUTF8_H
#define SQPLUSUTF8_H
#if defined(SQUTF8) || SQPLUS_USE_LATIN1!=1
// Simple Unicode <-> UTF8 conversion routines
//int sqplus_utf8_len(char lead_byte);
int sqplus_utf8_len_first(const char *str);
int sqplus_utf8_strlen(const char *str);
int sqplus_utf8_to_wchar(int *result, const char *string);
int sqplus_wchar_to_utf8(char *s, int wc, int size);
#endif // defined(SQUTF8) || SQPLUS_USE_LATIN1!=1
#endif // SQPLUSUTF8_H

View File

@ -0,0 +1,161 @@
#include "sqplus.h"
BOOL CreateStaticNamespace(HSQUIRRELVM v,ScriptNamespaceDecl *sn)
{
int n = 0;
sq_pushroottable(v);
sq_pushstring(v,sn->name,-1);
sq_newtable(v);
const ScriptClassMemberDecl *members = sn->members;
const ScriptClassMemberDecl *m = NULL;
while(members[n].name) {
m = &members[n];
sq_pushstring(v,m->name,-1);
sq_newclosure(v,m->func,0);
sq_setparamscheck(v,m->params,m->typemask);
sq_setnativeclosurename(v,-1,m->name);
sq_createslot(v,-3);
n++;
}
const ScriptConstantDecl *consts = sn->constants;
const ScriptConstantDecl *c = NULL;
n = 0;
while(consts[n].name) {
c = &consts[n];
sq_pushstring(v,c->name,-1);
switch(c->type) {
case OT_STRING: sq_pushstring(v,c->val.s,-1);break;
case OT_INTEGER: sq_pushinteger(v,c->val.i);break;
case OT_FLOAT: sq_pushfloat(v,c->val.f);break;
}
sq_createslot(v,-3);
n++;
}
if(sn->delegate) {
const ScriptClassMemberDecl *members = sn->delegate;
const ScriptClassMemberDecl *m = NULL;
sq_newtable(v);
while(members[n].name) {
m = &members[n];
sq_pushstring(v,m->name,-1);
sq_newclosure(v,m->func,0);
sq_setparamscheck(v,m->params,m->typemask);
sq_setnativeclosurename(v,-1,m->name);
sq_createslot(v,-3);
n++;
}
sq_setdelegate(v,-2);
}
sq_createslot(v,-3);
sq_pop(v,1);
return TRUE;
}
BOOL CreateClass(HSQUIRRELVM v,SquirrelClassDecl *cd)
{
int n = 0;
int oldtop = sq_gettop(v);
sq_pushroottable(v);
sq_pushstring(v,cd->name,-1);
if(cd->base) {
sq_pushstring(v,cd->base,-1);
if(SQ_FAILED(sq_get(v,-3))) { // Make sure the base exists if specified by cd->base name.
sq_settop(v,oldtop);
return FALSE;
}
}
if(SQ_FAILED(sq_newclass(v,cd->base?1:0))) { // Will inherit from base class on stack from sq_get() above.
sq_settop(v,oldtop);
return FALSE;
}
// sq_settypetag(v,-1,(unsigned int)cd);
#ifdef _WIN32
#pragma warning(disable : 4311)
#endif
sq_settypetag(v,-1,reinterpret_cast<SQUserPointer>(cd));
const ScriptClassMemberDecl *members = cd->members;
const ScriptClassMemberDecl *m = NULL;
if (members) {
while(members[n].name) {
m = &members[n];
sq_pushstring(v,m->name,-1);
sq_newclosure(v,m->func,0);
sq_setparamscheck(v,m->params,m->typemask);
sq_setnativeclosurename(v,-1,m->name);
sq_createslot(v,-3);
n++;
}
} // if
sq_createslot(v,-3);
sq_pop(v,1);
return TRUE;
}
BOOL CreateNativeClassInstance(HSQUIRRELVM v,
const SQChar *classname,
SQUserPointer ud,
SQRELEASEHOOK hook)
{
// If we don't do this, SquirrelVM keeps an old pointer around and this
// will be used by SquirrelObject. That crashes when using several VMs.
SquirrelVM::Init( v );
int oldtop = sq_gettop(v);
sq_pushroottable(v);
sq_pushstring(v,classname,-1);
if(SQ_FAILED(sq_rawget(v,-2))){ //Get the class (created with sq_newclass()).
sq_settop(v,oldtop);
return FALSE;
}
//sq_pushroottable(v);
if(SQ_FAILED(sq_createinstance(v,-1))) {
sq_settop(v,oldtop);
return FALSE;
}
#ifdef SQ_USE_CLASS_INHERITANCE
HSQOBJECT ho;
sq_getstackobj(v, -1, &ho); // OT_INSTANCE
SquirrelObject instance(ho);
SqPlus::PopulateAncestry(v, instance, ud);
#endif
sq_remove(v,-3); //removes the root table
sq_remove(v,-2); //removes the class
if(SQ_FAILED(sq_setinstanceup(v,-1,ud))) {
sq_settop(v,oldtop);
return FALSE;
}
sq_setreleasehook(v,-1,hook);
return TRUE;
}
// Create native class instance and leave on stack.
BOOL CreateConstructNativeClassInstance(HSQUIRRELVM v,const SQChar * className) {
int oldtop = sq_gettop(v);
sq_pushroottable(v);
sq_pushstring(v,className,-1);
if (SQ_FAILED(sq_rawget(v,-2))) { // Get the class (created with sq_newclass()).
sq_settop(v,oldtop);
return FALSE;
} // if
#if 0
sq_remove(v,-3); // Remove the root table.
sq_push(v,1); // Push the 'this'.
#else // Kamaitati's change. 5/28/06 jcs.
sq_remove(v,-2); // Remove the root table.
sq_pushroottable(v); // Push the 'this'.
#endif
if (SQ_FAILED(sq_call(v,1,SQTrue,SQ_CALL_RAISE_ERROR))) { // Call ClassName(): creates new instance and calls constructor (instead of sq_createinstance() where constructor is not called).
sq_settop(v,oldtop);
return FALSE;
} // if
sq_remove(v,-2); // Remove the class.
// int newtop = sq_gettop(v);
return TRUE;
} // CreateConstructNativeClassInstance

View File

@ -0,0 +1,152 @@
#ifndef SQUIRREL_BINDINGS_UTILS_H
#define SQUIRREL_BINDINGS_UTILS_H
struct ScriptClassMemberDecl {
const SQChar *name;
SQFUNCTION func;
int params;
const SQChar *typemask;
};
struct SquirrelClassDecl {
const SQChar *name;
const SQChar *base;
const ScriptClassMemberDecl *members;
};
struct ScriptConstantDecl {
const SQChar *name;
SQObjectType type;
union value {
value(float v){ f = v; }
value(int v){ i = v; }
value(long int v){ li = v; }
value(const SQChar *v){ s = v; }
float f;
int i;
long int li;
const SQChar *s;
} val;
};
struct ScriptNamespaceDecl {
const SQChar *name;
const ScriptClassMemberDecl *members;
const ScriptConstantDecl *constants;
const ScriptClassMemberDecl *delegate;
};
#define _BEGIN_CLASS(classname) \
int __##classname##__typeof(HSQUIRRELVM v) \
{ \
sq_pushstring(v,_SC(#classname),-1); \
return 1; \
} \
struct ScriptClassMemberDecl __##classname##_members[] = { \
{_SC("_typeof"),__##classname##__typeof,1,NULL},
#define _BEGIN_NAMESPACE(xnamespace) struct ScriptClassMemberDecl __##xnamespace##_members[] = {
#define _BEGIN_NAMESPACE_CONSTANTS(xnamespace) {NULL,NULL,0,NULL}}; \
struct ScriptConstantDecl __##xnamespace##_constants[] = {
#define _BEGIN_DELEGATE(xnamespace) struct ScriptClassMemberDecl __##xnamespace##_delegate[] = {
#define _DELEGATE(xnamespace) __##xnamespace##_delegate
#define _END_DELEGATE(classname) {NULL,NULL,NULL,NULL}};
#define _CONSTANT(name,type,val) {_SC(#name),type,val},
#define _CONSTANT_IMPL(name,type) {_SC(#name),type,name},
#define _MEMBER_FUNCTION(classname,name,nparams,typemask) \
{_SC(#name),__##classname##_##name,nparams,typemask},
#define _END_NAMESPACE(classname,delegate) {NULL,OT_NULL,0}}; \
struct ScriptNamespaceDecl __##classname##_decl = { \
_SC(#classname), __##classname##_members,__##classname##_constants,delegate };
#define _END_CLASS(classname) {NULL,NULL,0,NULL}}; \
struct SquirrelClassDecl __##classname##_decl = { \
_SC(#classname), NULL, __##classname##_members };
#define _END_CLASS_INHERITANCE(classname,base) {NULL,NULL,NULL,NULL}}; \
struct SquirrelClassDecl __##classname##_decl = { \
_SC(#classname), _SC(#base), __##classname##_members };
#define _MEMBER_FUNCTION_IMPL(classname,name) \
int __##classname##_##name(HSQUIRRELVM v)
#define _INIT_STATIC_NAMESPACE(classname) CreateStaticNamespace(SquirrelVM::GetVMPtr(),&__##classname##_decl);
#define _INIT_CLASS(classname)CreateClass(SquirrelVM::GetVMPtr(),&__##classname##_decl);
#define _DECL_STATIC_NAMESPACE(xnamespace) extern struct ScriptNamespaceDecl __##xnamespace##_decl;
#define _DECL_CLASS(classname) extern struct SquirrelClassDecl __##classname##_decl;
#define _CHECK_SELF(cppclass,scriptclass) \
cppclass *self = NULL; \
if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)&__##scriptclass##_decl))) { \
return sq_throwerror(v,_SC("invalid instance type"));\
}
#define _CHECK_INST_PARAM(pname,idx,cppclass,scriptclass) \
cppclass *pname = NULL; \
if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer*)&pname,(SQUserPointer)&__##scriptclass##_decl))) { \
return sq_throwerror(v,_SC("invalid instance type"));\
} \
#define _CHECK_INST_PARAM_BREAK(pname,idx,cppclass,scriptclass) \
cppclass *pname = NULL; \
if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer*)&pname,(SQUserPointer)&__##scriptclass##_decl))) { \
break; \
} \
#define _CLASS_TAG(classname) ((unsigned int)&__##classname##_decl)
#define _DECL_NATIVE_CONSTRUCTION(classname,cppclass) \
BOOL push_##classname(cppclass &quat); \
SquirrelObject new_##classname(cppclass &quat);
#define _IMPL_NATIVE_CONSTRUCTION(classname,cppclass) \
static int classname##_release_hook(SQUserPointer p, int size) \
{ \
if(p) { \
cppclass *pv = (cppclass *)p; \
delete pv; \
} \
return 0; \
} \
BOOL push_##classname(cppclass &quat) \
{ \
cppclass *newquat = new cppclass; \
*newquat = quat; \
if(!CreateNativeClassInstance(SquirrelVM::GetVMPtr(),_SC(#classname),newquat,classname##_release_hook)) { \
delete newquat; \
return FALSE; \
} \
return TRUE; \
} \
SquirrelObject new_##classname(cppclass &quat) \
{ \
SquirrelObject ret; \
if(push_##classname(quat)) { \
ret.AttachToStackObject(-1); \
sq_pop(SquirrelVM::GetVMPtr(),1); \
} \
return ret; \
} \
int construct_##classname(cppclass *p) \
{ \
sq_setinstanceup(SquirrelVM::GetVMPtr(),1,p); \
sq_setreleasehook(SquirrelVM::GetVMPtr(),1,classname##_release_hook); \
return 1; \
}
BOOL CreateStaticClass(HSQUIRRELVM v,SquirrelClassDecl *cd);
BOOL CreateStaticNamespace(HSQUIRRELVM v,ScriptNamespaceDecl *sn);
BOOL CreateClass(HSQUIRRELVM v,SquirrelClassDecl *cd);
BOOL InitScriptClasses(HSQUIRRELVM v);
BOOL CreateNativeClassInstance(HSQUIRRELVM v,const SQChar *classname,SQUserPointer ud,SQRELEASEHOOK hook);
BOOL CreateConstructNativeClassInstance(HSQUIRRELVM v,const SQChar * className);
#endif // SQUIRREL_BINDINGS_UTILS_H

View File

@ -0,0 +1,31 @@
#include "sqplus.h"
//#include "SquirrelObject.h"
//#include "SquirrelVM.h"
#include "SquirrelBindingsUtilsWin32.h"
int refcounted_release_hook(SQUserPointer p, int size)
{
IUnknown *pRC = (IUnknown*)p;
pRC->Release();
return 0;
}
static BOOL __CreateRefCountedInstance(HSQUIRRELVM v,const SQChar *classname,IUnknown *pRC,SQRELEASEHOOK hook)
{
if(!CreateNativeClassInstance(v,classname,pRC,hook)) return FALSE;
return TRUE;
}
int construct_RefCounted(IUnknown *p)
{
sq_setinstanceup(SquirrelVM::GetVMPtr(),1,p);
sq_setreleasehook(SquirrelVM::GetVMPtr(),1,refcounted_release_hook);
return 1;
}
BOOL CreateRefCountedInstance(HSQUIRRELVM v,const SQChar *classname,IUnknown *pRC)
{
return __CreateRefCountedInstance(v,classname,pRC,refcounted_release_hook);
}

View File

@ -0,0 +1,41 @@
#ifndef SQUIRREL_BINDINGS_UTILS_WIN32_H
#define SQUIRREL_BINDINGS_UTILS_WIN32_H
#ifndef _INC_WINDOWS
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
#endif
#ifndef __IUnknown_INTERFACE_DEFINED__
#include <unknwn.h>
#endif
#ifndef SQUIRREL_BINDINGS_UTILS_H
#include "SquirrelBindingsUtils.h"
#endif
#define _DECLARE_REFCOUNTED_NEW(cppclass,classname) \
SquirrelObject new_##classname(cppclass *ptr) { \
if(CreateRefCountedInstance(SquirrelVM::GetVMPtr(),_SC(#classname),ptr)) { \
HSQOBJECT o; \
sq_getstackobj(SquirrelVM::GetVMPtr(),-1,&o); \
SquirrelObject tmp = o; \
sq_pop(SquirrelVM::GetVMPtr(),1); \
return tmp; \
} \
return SquirrelObject() ; \
}
#define _RETURN_REFCOUNTED_INSTANCE(classname,ptr) \
if(!CreateRefCountedInstance(SquirrelVM::GetVMPtr(),_SC(#classname),ptr)) { \
return sa.ThrowError(_SC("cannot create the class instance")); \
} \
return 1;
BOOL CreateRefCountedInstance(HSQUIRRELVM v,const SQChar *classname,IUnknown *pRC);
BOOL CreateRefCountedInstanceChached(HSQUIRRELVM v,const SQChar *classname,IUnknown *pRC);
int refcounted_release_hook(SQUserPointer p, int size);
int construct_RefCounted(IUnknown *p);
#endif // SQUIRREL_BINDINGS_UTILS_WIN32_H

View File

@ -0,0 +1,702 @@
#include "sqplus.h"
SquirrelObject::SquirrelObject(void)
{
sq_resetobject(&_o);
}
SquirrelObject::~SquirrelObject()
{
Reset();
}
SquirrelObject::SquirrelObject(const SquirrelObject &o)
{
_o = o._o;
sq_addref(SquirrelVM::_VM,&_o);
}
SquirrelObject::SquirrelObject(HSQOBJECT o)
{
_o = o;
sq_addref(SquirrelVM::_VM,&_o);
}
void SquirrelObject::Reset(void) {
if(SquirrelVM::_VM)
sq_release(SquirrelVM::_VM,&_o);
else if( _o._type!=OT_NULL && _o._unVal.pRefCounted )
printf( "SquirrelObject::~SquirrelObject - Cannot release\n" );
sq_resetobject(&_o);
} // SquirrelObject::Reset
SquirrelObject SquirrelObject::Clone()
{
SquirrelObject ret;
if(GetType() == OT_TABLE || GetType() == OT_ARRAY)
{
sq_pushobject(SquirrelVM::_VM,_o);
sq_clone(SquirrelVM::_VM,-1);
ret.AttachToStackObject(-1);
sq_pop(SquirrelVM::_VM,2);
}
return ret;
}
SquirrelObject & SquirrelObject::operator =(const SquirrelObject &o)
{
//HSQOBJECT t;
//t = o._o;
//sq_addref(SquirrelVM::_VM,&t);
sq_addref(SquirrelVM::_VM, (HSQOBJECT*)&o._o);
sq_release(SquirrelVM::_VM,&_o);
//_o = t;
_o = o._o;
return *this;
}
SquirrelObject & SquirrelObject::operator =(HSQOBJECT ho)
{
sq_addref(SquirrelVM::_VM,&ho);
sq_release(SquirrelVM::_VM,&_o);
_o = ho;
return *this;
}
SquirrelObject & SquirrelObject::operator =(int n)
{
sq_pushinteger(SquirrelVM::_VM,n);
AttachToStackObject(-1);
sq_pop(SquirrelVM::_VM,1);
return *this;
}
#include <assert.h>
#include "../squirrel/sqstate.h"
#include "../squirrel/sqvm.h"
SquirrelObject & SquirrelObject::operator =(HSQUIRRELVM v)
{
if( v && SquirrelVM::_VM ){
SquirrelVM::_VM->Push(v);
AttachToStackObject(-1);
sq_poptop(SquirrelVM::_VM);
}
else Reset();
return *this;
}
bool SquirrelObject::operator == (const SquirrelObject &o)
{
bool cmp = false;
HSQUIRRELVM v = SquirrelVM::GetVMPtr();
int oldtop = sq_gettop(v);
sq_pushobject(v, GetObjectHandle());
sq_pushobject(v, o.GetObjectHandle());
if(sq_cmp(v) == 0)
cmp = true;
sq_settop(v, oldtop);
return cmp;
}
bool SquirrelObject::CompareUserPointer( const SquirrelObject &o )
{
if( _o._type == o.GetObjectHandle()._type )
if( _o._unVal.pUserPointer == o.GetObjectHandle()._unVal.pUserPointer )
return true;
return false;
}
void SquirrelObject::ArrayAppend(const SquirrelObject &o)
{
if(sq_isarray(_o)) {
sq_pushobject(SquirrelVM::_VM,_o);
sq_pushobject(SquirrelVM::_VM,o._o);
sq_arrayappend(SquirrelVM::_VM,-2);
sq_pop(SquirrelVM::_VM,1);
}
}
void SquirrelObject::AttachToStackObject(int idx)
{
HSQOBJECT t;
sq_getstackobj(SquirrelVM::_VM,idx,&t);
sq_addref(SquirrelVM::_VM,&t);
sq_release(SquirrelVM::_VM,&_o);
_o = t;
}
BOOL SquirrelObject::SetDelegate(SquirrelObject &obj)
{
if(obj.GetType() == OT_TABLE ||
obj.GetType() == OT_NULL) {
switch(_o._type) {
case OT_USERDATA:
case OT_TABLE:
sq_pushobject(SquirrelVM::_VM,_o);
sq_pushobject(SquirrelVM::_VM,obj._o);
if(SQ_SUCCEEDED(sq_setdelegate(SquirrelVM::_VM,-2))) {
sq_pop(SquirrelVM::_VM,1);
return TRUE;
}
sq_pop(SquirrelVM::_VM,1);
break;
}
}
return FALSE;
}
SquirrelObject SquirrelObject::GetDelegate()
{
SquirrelObject ret;
if(_o._type == OT_TABLE || _o._type == OT_USERDATA)
{
int top = sq_gettop(SquirrelVM::_VM);
sq_pushobject(SquirrelVM::_VM,_o);
sq_getdelegate(SquirrelVM::_VM,-1);
ret.AttachToStackObject(-1);
sq_settop(SquirrelVM::_VM,top);
// sq_pop(SquirrelVM::_VM,2);
}
return ret;
}
BOOL SquirrelObject::IsNull() const
{
return sq_isnull(_o);
}
BOOL SquirrelObject::IsNumeric() const
{
return sq_isnumeric(_o);
}
int SquirrelObject::Len() const
{
int ret = 0;
if(sq_isarray(_o) || sq_istable(_o) || sq_isstring(_o)) {
sq_pushobject(SquirrelVM::_VM,_o);
ret = sq_getsize(SquirrelVM::_VM,-1);
sq_pop(SquirrelVM::_VM,1);
}
return ret;
}
#define _SETVALUE_INT_BEGIN \
BOOL ret = FALSE; \
int top = sq_gettop(SquirrelVM::_VM); \
sq_pushobject(SquirrelVM::_VM,_o); \
sq_pushinteger(SquirrelVM::_VM,key);
#define _SETVALUE_INT_END \
if(SQ_SUCCEEDED(sq_rawset(SquirrelVM::_VM,-3))) { \
ret = TRUE; \
} \
sq_settop(SquirrelVM::_VM,top); \
return ret;
BOOL SquirrelObject::SetValue(INT key,const SquirrelObject &val)
{
_SETVALUE_INT_BEGIN
sq_pushobject(SquirrelVM::_VM,val._o);
_SETVALUE_INT_END
}
BOOL SquirrelObject::SetValue(INT key,INT n)
{
_SETVALUE_INT_BEGIN
sq_pushinteger(SquirrelVM::_VM,n);
_SETVALUE_INT_END
}
BOOL SquirrelObject::SetValue(INT key,FLOAT f)
{
_SETVALUE_INT_BEGIN
sq_pushfloat(SquirrelVM::_VM,f);
_SETVALUE_INT_END
}
BOOL SquirrelObject::SetValue(INT key,const SQChar *s)
{
_SETVALUE_INT_BEGIN
sq_pushstring(SquirrelVM::_VM,s,-1);
_SETVALUE_INT_END
}
BOOL SquirrelObject::SetValue(INT key,bool b)
{
_SETVALUE_INT_BEGIN
sq_pushbool(SquirrelVM::_VM,b);
_SETVALUE_INT_END
}
BOOL SquirrelObject::SetValue(const SquirrelObject &key,const SquirrelObject &val)
{
BOOL ret = FALSE;
int top = sq_gettop(SquirrelVM::_VM);
sq_pushobject(SquirrelVM::_VM,_o);
sq_pushobject(SquirrelVM::_VM,key._o);
sq_pushobject(SquirrelVM::_VM,val._o);
if(SQ_SUCCEEDED(sq_rawset(SquirrelVM::_VM,-3))) {
ret = TRUE;
}
sq_settop(SquirrelVM::_VM,top);
return ret;
}
#define _SETVALUE_STR_BEGIN \
BOOL ret = FALSE; \
int top = sq_gettop(SquirrelVM::_VM); \
sq_pushobject(SquirrelVM::_VM,_o); \
sq_pushstring(SquirrelVM::_VM,key,-1);
#define _SETVALUE_STR_END \
if(SQ_SUCCEEDED(sq_rawset(SquirrelVM::_VM,-3))) { \
ret = TRUE; \
} \
sq_settop(SquirrelVM::_VM,top); \
return ret;
BOOL SquirrelObject::SetValue(const SQChar *key,const SquirrelObject &val)
{
_SETVALUE_STR_BEGIN
sq_pushobject(SquirrelVM::_VM,val._o);
_SETVALUE_STR_END
}
BOOL SquirrelObject::SetValue(const SQChar *key,INT n)
{
_SETVALUE_STR_BEGIN
sq_pushinteger(SquirrelVM::_VM,n);
_SETVALUE_STR_END
}
BOOL SquirrelObject::SetValue(const SQChar *key,FLOAT f)
{
_SETVALUE_STR_BEGIN
sq_pushfloat(SquirrelVM::_VM,f);
_SETVALUE_STR_END
}
BOOL SquirrelObject::SetValue(const SQChar *key,const SQChar *s)
{
_SETVALUE_STR_BEGIN
sq_pushstring(SquirrelVM::_VM,s,-1);
_SETVALUE_STR_END
}
BOOL SquirrelObject::SetValue(const SQChar *key,bool b)
{
_SETVALUE_STR_BEGIN
sq_pushbool(SquirrelVM::_VM,b);
_SETVALUE_STR_END
}
// === BEGIN User Pointer, User Data ===
BOOL SquirrelObject::SetUserPointer(const SQChar * key,SQUserPointer up) {
_SETVALUE_STR_BEGIN
sq_pushuserpointer(SquirrelVM::_VM,up);
_SETVALUE_STR_END
} // SquirrelObject::SetUserPointer
SQUserPointer SquirrelObject::GetUserPointer(const SQChar * key) {
SQUserPointer ret = NULL;
if (GetSlot(key)) {
sq_getuserpointer(SquirrelVM::_VM,-1,&ret);
sq_pop(SquirrelVM::_VM,1);
} // if
sq_pop(SquirrelVM::_VM,1);
return ret;
} // SquirrelObject::GetUserPointer
BOOL SquirrelObject::SetUserPointer(INT key,SQUserPointer up) {
_SETVALUE_INT_BEGIN
sq_pushuserpointer(SquirrelVM::_VM,up);
_SETVALUE_INT_END
} // SquirrelObject::SetUserPointer
SQUserPointer SquirrelObject::GetUserPointer(INT key) {
SQUserPointer ret = NULL;
if (GetSlot(key)) {
sq_getuserpointer(SquirrelVM::_VM,-1,&ret);
sq_pop(SquirrelVM::_VM,1);
} // if
sq_pop(SquirrelVM::_VM,1);
return ret;
} // SquirrelObject::GetUserPointer
// === User Data ===
BOOL SquirrelObject::NewUserData(const SQChar * key,INT size,SQUserPointer * typetag) {
_SETVALUE_STR_BEGIN
sq_newuserdata(SquirrelVM::_VM,size);
if (typetag) {
sq_settypetag(SquirrelVM::_VM,-1,typetag);
} // if
_SETVALUE_STR_END
} // SquirrelObject::NewUserData
BOOL SquirrelObject::GetUserData(const SQChar * key,SQUserPointer * data,SQUserPointer * typetag) {
BOOL ret = false;
if (GetSlot(key)) {
sq_getuserdata(SquirrelVM::_VM,-1,data,typetag);
sq_pop(SquirrelVM::_VM,1);
ret = true;
} // if
sq_pop(SquirrelVM::_VM,1);
return ret;
} // SquirrelObject::GetUserData
BOOL SquirrelObject::RawGetUserData(const SQChar * key,SQUserPointer * data,SQUserPointer * typetag) {
BOOL ret = false;
if (RawGetSlot(key)) {
sq_getuserdata(SquirrelVM::_VM,-1,data,typetag);
sq_pop(SquirrelVM::_VM,1);
ret = true;
} // if
sq_pop(SquirrelVM::_VM,1);
return ret;
} // SquirrelObject::RawGetUserData
// === END User Pointer ===
// === BEGIN Arrays ===
BOOL SquirrelObject::ArrayResize(INT newSize) {
// int top = sq_gettop(SquirrelVM::_VM);
sq_pushobject(SquirrelVM::_VM,GetObjectHandle());
BOOL res = sq_arrayresize(SquirrelVM::_VM,-1,newSize) == SQ_OK;
sq_pop(SquirrelVM::_VM,1);
// sq_settop(SquirrelVM::_VM,top);
return res;
} // SquirrelObject::ArrayResize
BOOL SquirrelObject::ArrayExtend(INT amount) {
int newLen = Len()+amount;
return ArrayResize(newLen);
} // SquirrelObject::ArrayExtend
BOOL SquirrelObject::ArrayReverse(void) {
sq_pushobject(SquirrelVM::_VM,GetObjectHandle());
BOOL res = sq_arrayreverse(SquirrelVM::_VM,-1) == SQ_OK;
sq_pop(SquirrelVM::_VM,1);
return res;
} // SquirrelObject::ArrayReverse
SquirrelObject SquirrelObject::ArrayPop(SQBool returnPoppedVal) {
SquirrelObject ret;
int top = sq_gettop(SquirrelVM::_VM);
sq_pushobject(SquirrelVM::_VM,GetObjectHandle());
if (sq_arraypop(SquirrelVM::_VM,-1,returnPoppedVal) == SQ_OK) {
if (returnPoppedVal) {
ret.AttachToStackObject(-1);
} // if
} // if
sq_settop(SquirrelVM::_VM,top);
return ret;
} // SquirrelObject::ArrayPop
// === END Arrays ===
SQObjectType SquirrelObject::GetType()
{
return _o._type;
}
BOOL SquirrelObject::GetSlot(INT key) const
{
sq_pushobject(SquirrelVM::_VM,_o);
sq_pushinteger(SquirrelVM::_VM,key);
if(SQ_SUCCEEDED(sq_get(SquirrelVM::_VM,-2))) {
return TRUE;
}
return FALSE;
}
SquirrelObject SquirrelObject::GetValue(INT key)const
{
SquirrelObject ret;
if(GetSlot(key)) {
ret.AttachToStackObject(-1);
sq_pop(SquirrelVM::_VM,1);
}
sq_pop(SquirrelVM::_VM,1);
return ret;
}
FLOAT SquirrelObject::GetFloat(INT key) const
{
FLOAT ret = 0.0f;
if(GetSlot(key)) {
sq_getfloat(SquirrelVM::_VM,-1,&ret);
sq_pop(SquirrelVM::_VM,1);
}
sq_pop(SquirrelVM::_VM,1);
return ret;
}
INT SquirrelObject::GetInt(INT key) const
{
INT ret = 0;
if(GetSlot(key)) {
sq_getinteger(SquirrelVM::_VM,-1,&ret);
sq_pop(SquirrelVM::_VM,1);
}
sq_pop(SquirrelVM::_VM,1);
return ret;
}
const SQChar *SquirrelObject::GetString(INT key) const
{
const SQChar *ret = NULL;
if(GetSlot(key)) {
sq_getstring(SquirrelVM::_VM,-1,&ret);
sq_pop(SquirrelVM::_VM,1);
}
sq_pop(SquirrelVM::_VM,1);
return ret;
}
bool SquirrelObject::GetBool(INT key) const
{
SQBool ret = FALSE;
if(GetSlot(key)) {
sq_getbool(SquirrelVM::_VM,-1,&ret);
sq_pop(SquirrelVM::_VM,1);
}
sq_pop(SquirrelVM::_VM,1);
return ret?true:false;
}
BOOL SquirrelObject::Exists(const SQChar *key) const
{
if(GetSlot(key)) {
sq_pop(SquirrelVM::_VM,2);
return TRUE;
} else {
sq_pop(SquirrelVM::_VM,1);
return FALSE;
}
}
////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
BOOL SquirrelObject::GetSlot(const SQChar *name) const
{
sq_pushobject(SquirrelVM::_VM,_o);
sq_pushstring(SquirrelVM::_VM,name,-1);
if(SQ_SUCCEEDED(sq_get(SquirrelVM::_VM,-2))) {
return TRUE;
}
return FALSE;
}
BOOL SquirrelObject::RawGetSlot(const SQChar *name) const {
sq_pushobject(SquirrelVM::_VM,_o);
sq_pushstring(SquirrelVM::_VM,name,-1);
if(SQ_SUCCEEDED(sq_rawget(SquirrelVM::_VM,-2))) {
return TRUE;
}
return FALSE;
} // SquirrelObject::RawGetSlot
SquirrelObject SquirrelObject::GetValue(const SQChar *key)const
{
SquirrelObject ret;
if(GetSlot(key)) {
ret.AttachToStackObject(-1);
sq_pop(SquirrelVM::_VM,1);
}
sq_pop(SquirrelVM::_VM,1);
return ret;
}
FLOAT SquirrelObject::GetFloat(const SQChar *key) const
{
FLOAT ret = 0.0f;
if(GetSlot(key)) {
sq_getfloat(SquirrelVM::_VM,-1,&ret);
sq_pop(SquirrelVM::_VM,1);
}
sq_pop(SquirrelVM::_VM,1);
return ret;
}
INT SquirrelObject::GetInt(const SQChar *key) const
{
INT ret = 0;
if(GetSlot(key)) {
sq_getinteger(SquirrelVM::_VM,-1,&ret);
sq_pop(SquirrelVM::_VM,1);
}
sq_pop(SquirrelVM::_VM,1);
return ret;
}
const SQChar *SquirrelObject::GetString(const SQChar *key) const
{
const SQChar *ret = NULL;
if(GetSlot(key)) {
sq_getstring(SquirrelVM::_VM,-1,&ret);
sq_pop(SquirrelVM::_VM,1);
}
sq_pop(SquirrelVM::_VM,1);
return ret;
}
bool SquirrelObject::GetBool(const SQChar *key) const
{
SQBool ret = FALSE;
if(GetSlot(key)) {
sq_getbool(SquirrelVM::_VM,-1,&ret);
sq_pop(SquirrelVM::_VM,1);
}
sq_pop(SquirrelVM::_VM,1);
return ret?true:false;
}
SQUserPointer SquirrelObject::GetInstanceUP(SQUserPointer tag) const
{
SQUserPointer up;
sq_pushobject(SquirrelVM::_VM,_o);
if (SQ_FAILED(sq_getinstanceup(SquirrelVM::_VM,-1,(SQUserPointer*)&up,tag))) {
sq_reseterror(SquirrelVM::_VM);
up = NULL;
} // if
sq_pop(SquirrelVM::_VM,1);
return up;
}
BOOL SquirrelObject::SetInstanceUP(SQUserPointer up)
{
if(!sq_isinstance(_o)) return FALSE;
sq_pushobject(SquirrelVM::_VM,_o);
sq_setinstanceup(SquirrelVM::_VM,-1,up);
sq_pop(SquirrelVM::_VM,1);
return TRUE;
}
SquirrelObject SquirrelObject::GetAttributes(const SQChar *key)
{
SquirrelObject ret;
int top = sq_gettop(SquirrelVM::_VM);
sq_pushobject(SquirrelVM::_VM,_o);
if(key)
sq_pushstring(SquirrelVM::_VM,key,-1);
else
sq_pushnull(SquirrelVM::_VM);
if(SQ_SUCCEEDED(sq_getattributes(SquirrelVM::_VM,-2))) {
ret.AttachToStackObject(-1);
}
sq_settop(SquirrelVM::_VM,top);
return ret;
}
BOOL SquirrelObject::BeginIteration()
{
if(!sq_istable(_o) && !sq_isarray(_o) && !sq_isclass(_o))
return FALSE;
sq_pushobject(SquirrelVM::_VM,_o);
sq_pushnull(SquirrelVM::_VM);
return TRUE;
}
BOOL SquirrelObject::Next(SquirrelObject &key,SquirrelObject &val)
{
if(SQ_SUCCEEDED(sq_next(SquirrelVM::_VM,-2))) {
key.AttachToStackObject(-2);
val.AttachToStackObject(-1);
sq_pop(SquirrelVM::_VM,2);
return TRUE;
}
return FALSE;
}
BOOL SquirrelObject::GetTypeTag(SQUserPointer * typeTag) {
if (SQ_SUCCEEDED(sq_getobjtypetag(&_o,typeTag))) {
return TRUE;
} // if
return FALSE;
} // SquirrelObject::GetTypeTag
const SQChar * SquirrelObject::GetTypeName(const SQChar * key) {
#if 1
// This version will work even if SQ_SUPPORT_INSTANCE_TYPE_INFO is not enabled.
SqPlus::ScriptStringVar256 varNameTag;
SqPlus::getVarNameTag(varNameTag,sizeof(varNameTag),key);
SQUserPointer data=0;
if (!RawGetUserData(varNameTag,&data)) {
return NULL;
} // if
SqPlus::VarRefPtr vr = (SqPlus::VarRefPtr)data;
return vr->varType->GetTypeName();
#else // This version will only work if SQ_SUPPORT_INSTANCE_TYPE_INFO is enabled.
SquirrelObject so = GetValue(key);
if (so.IsNull()) return NULL;
return so.GetTypeName();
#endif
} // SquirrelObject::GetTypeName
const SQChar * SquirrelObject::GetTypeName(INT key) {
SquirrelObject so = GetValue(key);
if (so.IsNull()) return NULL;
return so.GetTypeName();
} // SquirrelObject::GetTypeName
const SQChar * SquirrelObject::GetTypeName(void) {
SQUserPointer typeTag=NULL;
if (SQ_SUCCEEDED(sq_getobjtypetag(&_o,&typeTag))) {
SquirrelObject typeTable = SquirrelVM::GetRootTable().GetValue(SQ_PLUS_TYPE_TABLE);
if (typeTable.IsNull()) {
return NULL; // Not compiled with SQ_SUPPORT_INSTANCE_TYPE_INFO enabled.
} // if
return typeTable.GetString(INT((size_t)typeTag));
} // if
return NULL;
} // SquirrelObject::GetTypeName
SquirrelObject SquirrelObject::GetBase(void)
{
SquirrelObject ret;
sq_pushobject(SquirrelVM::_VM,_o);
sq_getbase(SquirrelVM::_VM,-1);
ret.AttachToStackObject(-1);
sq_pop(SquirrelVM::_VM,2);
return ret;
}
const SQChar* SquirrelObject::ToString()
{
return sq_objtostring(&_o);
}
SQInteger SquirrelObject::ToInteger()
{
return sq_objtointeger(&_o);
}
SQFloat SquirrelObject::ToFloat()
{
return sq_objtofloat(&_o);
}
bool SquirrelObject::ToBool()
{
//<<FIXME>>
return _o._unVal.nInteger?true:false;
}
void SquirrelObject::EndIteration()
{
sq_pop(SquirrelVM::_VM,2);
}

View File

@ -0,0 +1,256 @@
#ifndef _SQUIRREL_OBJECT_H_
#define _SQUIRREL_OBJECT_H_
class SquirrelObject
{
friend class SquirrelVM;
public:
SquirrelObject();
virtual ~SquirrelObject();
SquirrelObject(const SquirrelObject & o);
SquirrelObject(HSQOBJECT o);
#if 1
template <typename _ty>
SquirrelObject(const _ty & val) { sq_resetobject(&_o); Set((_ty &)val); } // Cast away const to avoid compiler SqPlus::Push() match issue.
template <typename _ty>
SquirrelObject(_ty & val) { sq_resetobject(&_o); Set(val); }
template <typename _ty>
SquirrelObject(_ty * val) { sq_resetobject(&_o); SetByValue(val); } // Set() would also be OK here. SetByValue() to save potential compiler overhead.
#endif
SquirrelObject & operator = (HSQOBJECT ho);
SquirrelObject & operator = (const SquirrelObject &o);
SquirrelObject & operator = (int n);
SquirrelObject & operator = (HSQUIRRELVM v);
operator HSQOBJECT& (){ return _o; }
bool operator ==(const SquirrelObject& o);
bool CompareUserPointer(const SquirrelObject& o);
void AttachToStackObject(int idx);
void Reset(void); // Release (any) reference and reset _o.
SquirrelObject Clone();
BOOL SetValue(const SquirrelObject &key,const SquirrelObject &val);
BOOL SetValue(SQInteger key,const SquirrelObject &val);
BOOL SetValue(INT key,bool b); // Compiler treats SQBool as INT.
BOOL SetValue(INT key,INT n);
BOOL SetValue(INT key,FLOAT f);
BOOL SetValue(INT key,const SQChar *s);
BOOL SetValue(const SQChar *key,const SquirrelObject &val);
BOOL SetValue(const SQChar *key,bool b);
BOOL SetValue(const SQChar *key,INT n);
BOOL SetValue(const SQChar *key,FLOAT f);
BOOL SetValue(const SQChar *key,const SQChar *s);
BOOL SetUserPointer(const SQChar * key,SQUserPointer up);
SQUserPointer GetUserPointer(const SQChar * key);
BOOL SetUserPointer(INT key,SQUserPointer up);
SQUserPointer GetUserPointer(INT key);
BOOL NewUserData(const SQChar * key,INT size,SQUserPointer * typetag=0);
BOOL GetUserData(const SQChar * key,SQUserPointer * data,SQUserPointer * typetag=0);
BOOL RawGetUserData(const SQChar * key,SQUserPointer * data,SQUserPointer * typetag=0);
// === BEGIN Arrays ===
BOOL ArrayResize(INT newSize);
BOOL ArrayExtend(INT amount);
BOOL ArrayReverse(void);
SquirrelObject ArrayPop(SQBool returnPoppedVal=SQTrue);
void ArrayAppend(const SquirrelObject &o);
template<typename T>
BOOL ArrayAppend(T item);
// === END Arrays ===
BOOL SetInstanceUP(SQUserPointer up);
BOOL IsNull() const;
int IsNumeric() const;
int Len() const;
BOOL SetDelegate(SquirrelObject &obj);
SquirrelObject GetDelegate();
const SQChar* ToString();
bool ToBool();
SQInteger ToInteger();
SQFloat ToFloat();
SQUserPointer GetInstanceUP(SQUserPointer tag) const;
SquirrelObject GetValue(const SQChar *key) const;
BOOL Exists(const SQChar *key) const;
FLOAT GetFloat(const SQChar *key) const;
INT GetInt(const SQChar *key) const;
const SQChar *GetString(const SQChar *key) const;
bool GetBool(const SQChar *key) const;
SquirrelObject GetValue(INT key) const;
FLOAT GetFloat(INT key) const;
INT GetInt(INT key) const;
const SQChar *GetString(INT key) const;
bool GetBool(INT key) const;
SquirrelObject GetAttributes(const SQChar *key = NULL);
SQObjectType GetType();
HSQOBJECT & GetObjectHandle() const {return *(HSQOBJECT*)&_o;}
BOOL BeginIteration();
BOOL Next(SquirrelObject &key,SquirrelObject &value);
void EndIteration();
BOOL GetTypeTag(SQUserPointer * typeTag);
// === Get the type name of item/object through string key in a table or class. Returns NULL if the type name is not set (not an SqPlus registered type).
const SQChar * GetTypeName(const SQChar * key);
// === Get the type name of item/object through INT key in a table or class. Returns NULL if the type name is not set (not an SqPlus registered type).
const SQChar * GetTypeName(INT key);
// === Get the type name of this object, else return NULL if not an SqPlus registered type.
const SQChar * GetTypeName(void);
// === Return base class of object using sq_getbase() ===
SquirrelObject GetBase();
// === BEGIN code suggestion from the Wiki ===
// Get any bound type from this SquirrelObject. Note that Squirrel's handling of references and pointers still holds here.
template<typename _ty>
_ty Get(void);
// Set any bound type to this SquirrelObject. Note that Squirrel's handling of references and pointers still holds here.
template<typename _ty>
SquirrelObject SetByValue(_ty val); // classes/structs should be passed by ref (below) to avoid an extra copy.
// Set any bound type to this SquirrelObject. Note that Squirrel's handling of references and pointers still holds here.
template<typename _ty>
SquirrelObject &Set(_ty & val);
// === END code suggestion from the Wiki ===
private:
BOOL GetSlot(const SQChar *name) const;
BOOL RawGetSlot(const SQChar *name) const;
BOOL GetSlot(INT key) const;
HSQOBJECT _o;
};
struct StackHandler {
StackHandler(HSQUIRRELVM v) {
_top = sq_gettop(v);
this->v = v;
}
SQFloat GetFloat(int idx) {
SQFloat x = 0.0f;
if(idx > 0 && idx <= _top) {
sq_getfloat(v,idx,&x);
}
return x;
}
SQInteger GetInt(int idx) {
SQInteger x = 0;
if(idx > 0 && idx <= _top) {
sq_getinteger(v,idx,&x);
}
return x;
}
HSQOBJECT GetObjectHandle(int idx) {
HSQOBJECT x;
if(idx > 0 && idx <= _top) {
sq_resetobject(&x);
sq_getstackobj(v,idx,&x);
}
return x;
}
const SQChar *GetString(int idx)
{
const SQChar *x = NULL;
if(idx > 0 && idx <= _top) {
sq_getstring(v,idx,&x);
}
return x;
}
SQUserPointer GetUserPointer(int idx)
{
SQUserPointer x = 0;
if(idx > 0 && idx <= _top) {
sq_getuserpointer(v,idx,&x);
}
return x;
}
SQUserPointer GetInstanceUp(int idx,SQUserPointer tag)
{
SQUserPointer self;
if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer*)&self,tag)))
return NULL;
return self;
}
SQUserPointer GetUserData(int idx,SQUserPointer tag=0)
{
SQUserPointer otag;
SQUserPointer up;
if(idx > 0 && idx <= _top) {
if(SQ_SUCCEEDED(sq_getuserdata(v,idx,&up,&otag))) {
if(tag == otag)
return up;
}
}
return NULL;
}
BOOL GetBool(int idx)
{
SQBool ret;
if(idx > 0 && idx <= _top) {
if(SQ_SUCCEEDED(sq_getbool(v,idx,&ret)))
return ret;
}
return FALSE;
}
int GetType(int idx)
{
if(idx > 0 && idx <= _top) {
return sq_gettype(v,idx);
}
return -1;
}
int GetParamCount() {
return _top;
}
int Return(const SQChar *s)
{
sq_pushstring(v,s,-1);
return 1;
}
int Return(FLOAT f)
{
sq_pushfloat(v,f);
return 1;
}
int Return(INT i)
{
sq_pushinteger(v,i);
return 1;
}
int Return(bool b)
{
sq_pushbool(v,b);
return 1;
}
int Return(SQUserPointer p) {
sq_pushuserpointer(v,p);
return 1;
}
int Return(SquirrelObject &o)
{
sq_pushobject(v,o.GetObjectHandle());
return 1;
}
int Return() { return 0; }
int ThrowError(const SQChar *error) {
return sq_throwerror(v,error);
}
HSQUIRRELVM GetVMPtr() { return v; }
private:
int _top;
HSQUIRRELVM v;
};
#endif //_SQUIRREL_OBJECT_H_

View File

@ -0,0 +1,505 @@
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#define _DEBUG_DUMP
#include "sqplus.h"
#include <sqstdio.h>
#include <sqstdmath.h>
#include <sqstdstring.h>
#include <sqstdaux.h>
#include <sqstdblob.h>
#include <sqstdsystem.h>
HSQUIRRELVM SquirrelVM::_VM;
bool SquirrelVM::_no_vm_ref;
int SquirrelVM::_CallState = -1;
SquirrelObject* SquirrelVM::_root;
HSQUIRRELVM SquirrelVM::_sandboxVM;
SquirrelObject SquirrelVM::_vm;
// Helper struct to keep track of all SQSharedState:s created by SquirrelVM.
#include "../squirrel/sqpcheader.h"
#include "../squirrel/sqvm.h"
struct SQSharedStateNode {
SQSharedStateNode( SQSharedState* ps );
~SQSharedStateNode( );
SQSharedState* m_ps;
SQSharedStateNode* m_nxt;
};
// Linked list of shared states
static SQSharedStateNode* g_sqss_fst;
SQSharedStateNode::SQSharedStateNode( SQSharedState* ps ) : m_ps(ps), m_nxt(g_sqss_fst) {
g_sqss_fst = this;
}
SQSharedStateNode::~SQSharedStateNode() {
if(m_ps) sq_delete(m_ps,SQSharedState);
delete m_nxt;
}
static struct SquirrelVM_ModConstr {
~SquirrelVM_ModConstr(){
// Delete any shared states we created
delete g_sqss_fst;
g_sqss_fst = NULL;
}
} g_squirrelvm_mod_constr;
SquirrelError::SquirrelError()
{
const SQChar *s;
sq_getlasterror(SquirrelVM::_VM);
sq_getstring(SquirrelVM::_VM,-1,&s);
if(s) {
desc = s;
}
else {
desc = _SC("unknown error");
}
}
SquirrelVMSys::~SquirrelVMSys() {
// Must take care to release object with the 'ref' VM
PushRefVM( _vm.GetObjectHandle()._unVal.pThread );
_vm.Reset();
PopRefVM();
}
void SquirrelVMSys::Set( HSQUIRRELVM v ){
// Must take care to release object with the 'ref' VM
PushRefVM( v );
_vm = v;
PopRefVM( );
}
void SquirrelVMSys::Set( const SquirrelObject& ov ){
assert( ov.GetObjectHandle()._type==OT_THREAD );
// Must take care to release object with the 'ref' VM
PushRefVM( ov.GetObjectHandle()._unVal.pThread );
_vm = ov;
PopRefVM( );
}
SquirrelVMSys::operator HSQUIRRELVM () const {
// Avoid const madness
SquirrelObject *pvm = (SquirrelObject*)&_vm;
assert( pvm->GetObjectHandle()._type==OT_THREAD );
return pvm->GetObjectHandle()._unVal.pThread;
}
// When doing a SquirrelObject assignment, a reference using the current
// VM is done.
HSQUIRRELVM g_VM_pushed;
void SquirrelVMSys::PushRefVM( HSQUIRRELVM v ){
assert( !g_VM_pushed );
g_VM_pushed = SquirrelVM::_VM;
SquirrelVM::_VM = v;
}
void SquirrelVMSys::PopRefVM( ){
SquirrelVM::_VM = g_VM_pushed;
g_VM_pushed = NULL;
}
bool SquirrelVM::Init( HSQUIRRELVM v ){
if( v && v==_VM )
return true;
// Do we have a previous state?
Release( );
bool created_new = false;
if( !v ){
// Create a new VM - a root VM with new SharedState.
v = sq_open(1024);
if( !v ) return false;
// Store the associated shared state in a linked list. The state will only
// be destroyed at app shutdown. Often that is fine, but if using many
// VM:s briefly, this allocation is not optimal.
new SQSharedStateNode( _ss(v) );
created_new = true;
sq_setprintfunc(v,SquirrelVM::PrintFunc, SquirrelVM::PrintFunc);
sq_pushroottable(v);
sqstd_register_iolib(v);
sqstd_register_bloblib(v);
sqstd_register_mathlib(v);
sqstd_register_stringlib(v);
#ifdef SQPLUS_SQUIRRELVM_WITH_SYSTEMLIB
sqstd_register_systemlib(v);
#endif
sqstd_seterrorhandlers(v);
//TODO error handler, compiler error handler
sq_pop(v,1);
}
// After this we hold a ref
_no_vm_ref = false;
_VM = v;
_vm = v;
// In the case where Squirrel is ref counted we currently
// hold two references to the VM (since it is created with
// a ref count of 1). In the GC case, it is outside of the
// chain of valid objects, so it is not referenced. Compensate
// in ref counted case.
if( created_new )
DropVMRefIfRefCounted( v );
return true;
}
bool SquirrelVM::InitNoRef( HSQUIRRELVM v ){
if( v && v==_VM )
return true;
// Do we have a previous state?
Release( );
// Set pointer to this VM, without referencing it
_no_vm_ref = true;
_VM = v;
return true;
}
/*
void SquirrelVM::Init( HSQUIRRELVM v )
{
if( v && v==_VM ) {
return;
}
// Do we have a previous state?
Release();
if( !v ){
// Create a new VM and own it
_VM = sq_open(1024);
sq_setprintfunc(_VM,SquirrelVM::PrintFunc);
sq_pushroottable(_VM);
sqstd_register_iolib(_VM);
sqstd_register_bloblib(_VM);
sqstd_register_mathlib(_VM);
sqstd_register_stringlib(_VM);
sqstd_seterrorhandlers(_VM);
//TODO error handler, compiler error handler
sq_pop(_VM,1);
}
else {
_VM = v;
}
// After this we hold a ref
_vm = _VM;
}
*/
void SquirrelVM::Release() {
// Release root table object if we have one
if( _root ){
delete _root;
_root = NULL;
}
// Release our ref on VM - if we should
if( !_no_vm_ref )
_vm.Reset();
_VM = NULL;
}
void SquirrelVM::DropVMRefIfRefCounted( HSQUIRRELVM v ){
#ifdef NO_GARBAGE_COLLECTOR
if( v ){
SQObject t;
t._unVal.pThread = v;
t._type = OT_THREAD;
sq_release( v, &t );
}
#endif
}
BOOL SquirrelVM::Update()
{
//update remote debugger
return TRUE;
}
void SquirrelVM::PrintFunc(HSQUIRRELVM v,const SQChar* s,...)
{
static SQChar temp[2048];
va_list vl;
va_start(vl, s);
scvsprintf( temp,s, vl);
SCPUTS(temp);
va_end(vl);
}
SquirrelObject SquirrelVM::CompileScript(const SQChar *s)
{
SquirrelObject ret;
if(SQ_SUCCEEDED(sqstd_loadfile(_VM,s,1))) {
ret.AttachToStackObject(-1);
sq_pop(_VM,1);
return ret;
}
throw SquirrelError();
}
SquirrelObject SquirrelVM::CompileBuffer(const SQChar *s,const SQChar * debugInfo)
{
SquirrelObject ret;
if(SQ_SUCCEEDED(sq_compilebuffer(_VM,s,(int)scstrlen(s)*sizeof(SQChar),debugInfo,1))) {
ret.AttachToStackObject(-1);
sq_pop(_VM,1);
return ret;
}
throw SquirrelError();
}
SquirrelObject SquirrelVM::RunScript(const SquirrelObject &o,SquirrelObject *_this)
{
SquirrelObject ret;
sq_pushobject(_VM,o._o);
if(_this) {
sq_pushobject(_VM,_this->_o);
}
else {
sq_pushroottable(_VM);
}
if(SQ_SUCCEEDED(sq_call(_VM,1,SQTrue,SQ_CALL_RAISE_ERROR))) {
ret.AttachToStackObject(-1);
sq_pop(_VM,2);
return ret;
}
sq_pop(_VM,1);
throw SquirrelError();
}
BOOL SquirrelVM::BeginCall(const SquirrelObject &func)
{
if(_CallState != -1)
return FALSE;
_CallState = 1;
sq_pushobject(_VM,func._o);
sq_pushroottable(_VM);
return TRUE;
}
BOOL SquirrelVM::BeginCall(const SquirrelObject &func,SquirrelObject &_this)
{
if(_CallState != -1)
throw SquirrelError(_SC("call already initialized"));
_CallState = 1;
sq_pushobject(_VM,func._o);
sq_pushobject(_VM,_this._o);
return TRUE;
}
#define _CHECK_CALL_STATE \
if(_CallState == -1) \
throw SquirrelError(_SC("call not initialized"));
void SquirrelVM::PushParam(const SquirrelObject &o)
{
_CHECK_CALL_STATE
sq_pushobject(_VM,o._o);
_CallState++;
}
void SquirrelVM::PushParam(const SQChar *s)
{
_CHECK_CALL_STATE
sq_pushstring(_VM,s,-1);
_CallState++;
}
void SquirrelVM::PushParam(SQInteger n)
{
_CHECK_CALL_STATE
sq_pushinteger(_VM,n);
_CallState++;
}
void SquirrelVM::PushParam(SQFloat f)
{
_CHECK_CALL_STATE
sq_pushfloat(_VM,f);
_CallState++;
}
void SquirrelVM::PushParamNull()
{
_CHECK_CALL_STATE
sq_pushnull(_VM);
_CallState++;
}
void SquirrelVM::PushParam(SQUserPointer up)
{
_CHECK_CALL_STATE
sq_pushuserpointer(_VM,up);
_CallState++;
}
SquirrelObject SquirrelVM::EndCall()
{
SquirrelObject ret;
if(_CallState >= 0) {
int oldtop = sq_gettop(_VM);
int nparams = _CallState;
_CallState = -1;
if(SQ_SUCCEEDED(sq_call(_VM,nparams,SQTrue,SQ_CALL_RAISE_ERROR))) {
ret.AttachToStackObject(-1);
sq_pop(_VM,2);
}else {
sq_settop(_VM,oldtop-(nparams+1));
throw SquirrelError();
}
}
return ret;
}
SquirrelObject SquirrelVM::CreateInstance(SquirrelObject &oclass)
{
SquirrelObject ret;
int oldtop = sq_gettop(_VM);
sq_pushobject(_VM,oclass._o);
if(SQ_FAILED(sq_createinstance(_VM,-1))) {
sq_settop(_VM,oldtop);
throw SquirrelError();
}
ret.AttachToStackObject(-1);
sq_pop(_VM,2);
return ret;
}
SquirrelObject SquirrelVM::CreateTable()
{
SquirrelObject ret;
sq_newtable(_VM);
ret.AttachToStackObject(-1);
sq_pop(_VM,1);
return ret;
}
SquirrelObject SquirrelVM::CreateString(const SQChar *s)
{
SquirrelObject ret;
sq_pushstring(_VM,s,-1);
ret.AttachToStackObject(-1);
sq_pop(_VM,1);
return ret;
}
SquirrelObject SquirrelVM::CreateArray(int size)
{
SquirrelObject ret;
sq_newarray(_VM,size);
ret.AttachToStackObject(-1);
sq_pop(_VM,1);
return ret;
}
SquirrelObject SquirrelVM::CreateFunction(SQFUNCTION func)
{
SquirrelObject ret;
sq_newclosure(_VM,func,0);
ret.AttachToStackObject(-1);
sq_pop(_VM,1);
return ret;
}
SquirrelObject SquirrelVM::CreateUserData(int size) {
SquirrelObject ret;
sq_newuserdata(_VM,size);
ret.AttachToStackObject(-1);
sq_pop(_VM,1);
return ret;
}
const SquirrelObject &SquirrelVM::GetRootTable()
{
if( !_root ){
sq_pushroottable(_VM);
_root = new SquirrelObject();
_root->AttachToStackObject(-1);
sq_pop(_VM,1);
}
return *_root;
}
void SquirrelVM::PushRootTable(void) {
sq_pushroottable(_VM);
} // SquirrelVM::PushRootTable
// Creates a function in the table or class currently on the stack.
//void CreateFunction(HSQUIRRELVM v,const SQChar * scriptFuncName,SQFUNCTION func,int numParams=0,const SQChar * typeMask=0) {
SquirrelObject SquirrelVM::CreateFunction(SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask) {
sq_pushstring(_VM,scriptFuncName,-1);
sq_newclosure(_VM,func,0);
SquirrelObject ret;
ret.AttachToStackObject(-1);
SQChar tm[64];
SQChar * ptm = tm;
int numParams = SQ_MATCHTYPEMASKSTRING;
if (typeMask) {
if (typeMask[0] == '*') {
ptm = 0; // Variable args: don't check parameters.
numParams = 0; // Clear SQ_MATCHTYPEMASKSTRING (does not mean match 0 params. See sq_setparamscheck()).
} else {
if (SCSNPRINTF(tm,sizeof(tm),_SC("t|y|x%s"),typeMask) < 0) {
// sq_throwerror(_VM,_SC("CreateFunction: typeMask string too long."));
throw SquirrelError(_SC("CreateFunction: typeMask string too long."));
} // if
} // if
} else { // <TODO> Need to check object type on stack: table, class, instance, etc.
SCSNPRINTF(tm,sizeof(tm),_SC("%s"),_SC("t|y|x")); // table, class, instance.
// tm[0] = 't';
// tm[1] = 0;
} // if
#if 0
sq_setparamscheck(_VM,numParams+1,ptm); // Parameters are table+args (thus, the +1).
#else
if (ptm) {
sq_setparamscheck(_VM,numParams,ptm); // Determine arg count from type string.
} // if
#endif
#ifdef _DEBUG
sq_setnativeclosurename(_VM,-1,scriptFuncName); // For debugging only.
#endif
sq_createslot(_VM,-3); // Create slot in table or class (assigning function to slot at scriptNameFunc).
return ret;
} // SquirrelVM::CreateFunction
SquirrelObject SquirrelVM::CreateFunction(SquirrelObject & so,SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask) {
PushObject(so);
SquirrelObject ret = CreateFunction(func,scriptFuncName,typeMask);
Pop(1);
return ret;
} // SquirrelVM::CreateFunction
// Create a Global function on the root table.
//void CreateFunctionGlobal(HSQUIRRELVM v,const SQChar * scriptFuncName,SQFUNCTION func,int numParams=0,const SQChar * typeMask=0) {
SquirrelObject SquirrelVM::CreateFunctionGlobal(SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask) {
PushRootTable(); // Push root table.
// CreateFunction(scriptFuncName,func,numParams,typeMask);
SquirrelObject ret = CreateFunction(func,scriptFuncName,typeMask);
Pop(1); // Pop root table.
return ret;
} // SquirrelVM::CreateFunctionGlobal

View File

@ -0,0 +1,179 @@
#ifndef _SQUIRREL_VM_H_
#define _SQUIRREL_VM_H_
#include "SquirrelObject.h"
struct SquirrelError {
SquirrelError();
SquirrelError(const SQChar* s):desc(s){}
const SQChar *desc;
};
// This class can hold a reference to a SquirrelVM. It keeps a Squirrel ref
// to the VM to protect it from being deleted while held.
struct SquirrelVMSys {
SquirrelVMSys() { }
~SquirrelVMSys();
void Set( HSQUIRRELVM v );
void Set( const SquirrelObject& ov );
void Reset( ){ _vm.Reset(); }
SquirrelVMSys& operator = (HSQUIRRELVM v){ Set(v); return *this; }
operator HSQUIRRELVM () const;
protected:
void PushRefVM(HSQUIRRELVM v);
void PopRefVM();
SquirrelObject _vm;
friend class SquirrelVM;
};
// Notes on creating / destroying SquirrelVM:s:
//
// VM:s created through sq_open are special since they create a new
// SQSharedState. That shared state is later shared by any new thread
// or friend VM. sq_close can be used for closing VM:s created through
// sq_open (but not for friend VMs).
//
// Using squirrel references in SquirrelVMSys and SquirrelVM, one must
// make sure that these are all reset if one calls sq_close manually.
//
// When there are no more references to a VM, it is destroyed automatically,
// but the shared state is not! For VM:s created by SquirrelVM, it keeps
// a list of shared states it has created and will destroy them all on
// app shutdown.
class SquirrelVM {
friend class SquirrelObject;
friend struct SquirrelError;
friend struct SquirrelVMSys;
public:
// If a VM is passed as arg here, Init will not alter it. Otherwise
// a new VM is created and initialized. A squirrel reference is kept
// while it is the current VM.
static bool Init( HSQUIRRELVM v=NULL );
// Initialize with an externally created VM, without adding a ref
// on it. NOTE: This may not be compatible with Set/GetVMSys as
// we're just working with raw pointers here.
static bool InitNoRef( HSQUIRRELVM v );
static BOOL IsInitialized(){return _VM == NULL?FALSE:TRUE;}
static void Release(); // Release ref on VM and reset VM pointer
static void Shutdown(){ Release(); }
static void AppFinalShutdown(); // Call when finally shutting down app
static BOOL Update(); //debugger and maybe GC later
static SquirrelObject CompileScript(const SQChar *s);
static SquirrelObject CompileBuffer(const SQChar *s,const SQChar * debugInfo=_SC("console_buffer"));
static SquirrelObject RunScript(const SquirrelObject &o,SquirrelObject *_this = NULL);
static void PrintFunc(HSQUIRRELVM v,const SQChar* s,...);
static BOOL BeginCall(const SquirrelObject &func);
static BOOL BeginCall(const SquirrelObject &func,SquirrelObject &_this);
static void PushParam(const SquirrelObject &o);
static void PushParam(const SQChar *s);
static void PushParam(SQInteger n);
static void PushParam(SQFloat f);
static void PushParam(SQUserPointer up);
static void PushParamNull();
static SquirrelObject EndCall();
static SquirrelObject CreateString(const SQChar *s);
static SquirrelObject CreateTable();
static SquirrelObject CreateArray(int size);
static SquirrelObject CreateInstance(SquirrelObject &oclass); // oclass is an existing class. Create an 'instance' (OT_INSTANCE) of oclass.
static SquirrelObject CreateFunction(SQFUNCTION func);
static SquirrelObject CreateUserData(int size);
static const SquirrelObject &GetRootTable();
static HSQUIRRELVM GetVMPtr() { return _VM; }
// The sandbox VM ptr is one which cannot access functions bound with
// SqPlus. It is suitable for running non-trusted scripts that can only
// access basic functionality.
static void SetSandboxVMPtr(HSQUIRRELVM v) {
_sandboxVM = v;
} // SetSandboxVMPtr
static HSQUIRRELVM GetSandboxVMPtr() {
return _sandboxVM;
} // GetSandboxVMPtr
static void GetVMSys(SquirrelVMSys & vmSys) {
vmSys.Set( _vm );
} // GetVMSys
static void SetVMSys(const SquirrelVMSys & vmSys) {
Release();
HSQUIRRELVM v = (HSQUIRRELVM)vmSys;
if( v )
Init( v );
} // SetVMSys
static void PushValue(INT val) {
sq_pushinteger(_VM,val);
} // PushValue
static void PushValue(FLOAT val) {
sq_pushfloat(_VM,val);
} // PushValue
static void PushValue(bool val) { // Compiler treats SQBool as INT.
sq_pushbool(_VM,val);
} // PushValue
static void PushValue(SQChar * val) {
sq_pushstring(_VM,val,-1);
} // PushValue
static void PushValue(SQUserPointer val) {
sq_pushuserpointer(_VM,val);
} // PushValue
static void PushValue(const SQChar * val) {
sq_pushstring(_VM,val,-1);
} // PushValue
static void PushObject(SquirrelObject & so) {
sq_pushobject(_VM,so._o);
} // PushObject
static void Pop(SQInteger nelemstopop) {
sq_pop(_VM,nelemstopop);
} // Pop
static void PushRootTable(void);
// Create/bind a function on the table currently on the stack.
static SquirrelObject CreateFunction(SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask=0);
// Create/bind a function on the table so. typeMask: standard Squirrel types plus: no typemask means no args, "*" means any type of args.
static SquirrelObject CreateFunction(SquirrelObject & so,SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask=0);
// Create/bind a function to the root table. typeMask: standard Squirrel types plus: no typemask means no args, "*" means any type of args.
static SquirrelObject CreateFunctionGlobal(SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask=0);
// This is a helper to correct a difference in referncing new VM:s in
// ref counted versus garbage collected modes. NOTE: Only use after creating
// a VM with: 1 - sq_open() 2 - Creating a ref to the VM (SquirrelObject)
static void DropVMRefIfRefCounted( HSQUIRRELVM v );
private:
static SquirrelObject _vm; // This is a Squirrel reference to the VM
static HSQUIRRELVM _VM; // The raw C++ pointer
static bool _no_vm_ref; // Set if we only keep the raw C++ pointer and no ref
static int _CallState;
static SquirrelObject * _root; // Cached root table if non NULL
static HSQUIRRELVM _sandboxVM; // The sandbox VM (that cannot use bound functions)
};
template<typename T>
inline BOOL SquirrelObject::ArrayAppend(T item) {
sq_pushobject(SquirrelVM::_VM,GetObjectHandle());
SquirrelVM::PushValue(item);
BOOL res = sq_arrayappend(SquirrelVM::_VM,-2) == SQ_OK;
sq_pop(SquirrelVM::_VM,1);
return res;
} // ArrayAppend
#endif //_SQUIRREL_VM_H_

View File

@ -0,0 +1,359 @@
2008-07-13 "SQUIRREL2_1_1_sqplus_snapshot_20080713"
* Released as a snapshot
2008-07-06 kawachi
* Removed testSqPlus2
2008-06-26 arst@users.sf.net
* SquirrelVM.cpp / SqPlusSetup.h
- Added a new define SQPLUS_SQUIRRELVM_WITH_SYSTEMLIB
(Juggernaut, http://squirrel-lang.org/forums/2585/ShowThread.aspx#2585)
- Added a new function:
SQClassDefBase::scriptVar(const SQChar* name, int ival,
SQBool static_var=SQFalse)
It allows for creating either static or ordinary Squirrel class
members from C++ source code. Versions for int/double/const
SQChar*.
- SquirrelObject::GetBase() - retrieve base class.
(Juggernaut, http://squirrel-lang.org/forums/2585/ShowThread.aspx#2585)
2008-06-14 Kazei
* Fixed memory leak in overloadConstructor
(http://squirrel-lang.org/forums/thread/2516.aspx)
2008-05-10 Neimod
* Fixed for typesafe scripting
(http://squirrel-lang.org/forums/thread/2478.aspx)
2008-05-08 arst@users.sf.net
* sqplus.h/.cpp
- SQ_USE_CLASS_INHERITANCE_SIMPLE is a new way of handling class
inheritence in SqPlus, relying on a template scheme (see ClassTypeBase
and ClassType<T>). It doesn't use any memory per instance and should
be a bit faster than previous scheme. SqClassDef has been given
a second template argument to account for this:
struct SQClassDef<MyClass, TheBaseClass> ...
- The name of the class (in SqClassDef) can be filled in by SqPlus now,
if Squirrel class name is same as C++ class name:
SQClasDef<Troll, Creature>("Troll", "Creature").func(...) =>
SQClasDef<Troll, Creature>().func(...)
- Code to handle class types (names, copy funcs, ID tag, ...) has been
collected in ClassTypeBase and ClassType<T>.
- A new macro to specify that classes should not be copied with default
C++ method: DECLARE_NONCOPY_TYPE(ClassThatCannotBeCopied).
- Reworked body of repetetive template functions, Moved to
SqPlusCallTemplates.h. Can be included with different qualifiers
(const, cdecl).
- Support for cdecl member functions (MSVC specific) through:
SQPLUS_ENABLE_CDECL_MEMBER_FUNCTIONS
cdecl functions are compatible across compilers, while thiscall
is not.
- Generic Push/Pop/Match handlers: SQPLUS_USE_GENERIC_HANDLERS
By default, Push/Get/Match handlers are for a single type. This
adds a fallback level, so that `hierarchy wide' handlers can
be used (define for base class and let all derived classes use
just that).
- For functions that return a pointer to a temporarary (such as
returning a SQDefCharBuf, a template mapper class:
Temporary<T>::type
was added. It can hold a temporary value while finishing a
SquirrelFunction call (before returning to C++).
- Suppressing horrible warnings from Visual C++ about sprintf and related
functions (_CRT_SECURE_NO_DEPRECATE).
* SquirrelVM.h/.cpp
- Changed SquirrelVM and SquirrelVMSys to make them hold a reference
on a SQVM so that ownership can be shared in a defined way.
- SquirrelVMSys can be used as before to swap the `active' VM.
Now it holds a ref to a VM so that a VM is closed automatically
when switched out and there are no refs to any longer. (To hold a
VM ref in the application, simply use an instance of SquirrelVMSys).
- NOTE: A VM created through sq_open() comes out with a reference
count of 1. A VM created with sq_newthread() arrives with a ref
count of 0. SquirrelVM will compensate for this.
- Possibility to store a `sandbox VM'. This VM is not allowed to
access functions / classes bound with SqPlus and so can run more
untrusted scripts.
- Hopefully these changes will not break current apps. (Note: creating
and keeping correct refs on SQVM involved some difficulties (with ref-
counting and garbage collected Squirrel). The scheme provided here is
(I hope) a working solution.)
* SquirrelObject.h/.cpp
- Added: operator = (HSQOBJECT)
- From forum: (http://squirrel-lang.org/forums/thread/2506.aspx)
(suggested by auron0)
- Added: operator == (const SquirrelObject& o)
- Added: CompareUserPointer(const SquirrelObject& o)
* SqPlusUTF8.h / .cpp
- New files for converting strings in arguments (UTF8 <-> wchar_t)
- Fix for conversion of UTF8 sequence of length 3+ bytes
2008-02-17 PallavNawani
* BindVariable of std::string
(http://squirrel-lang.org/forums/2370/ShowThread.aspx)
2007-10-14 "SQUIRREL2_1_1_sqplus_snapshot_20071014"
* Fixed const member function overloading by Tegan
(http://squirrel-lang.org/forums/thread/2160.aspx)
* Updates for missing inline in DECLARE_INSTANCE_TYPE_NAME
(http://squirrel-lang.org/forums/thread/2156.aspx)
* Fixed resolution in function overloading
(http://squirrel-lang.org/forums/thread/2179.aspx)
* Added support for operator overloading suggested by Tegan
(http://squirrel-lang.org/forums/thread/2160.aspx)
2007-09-27 "SQUIRREL2_1_1_sqplus_snapshot_20070927"
* Added ats's extensions :
http://squirrel-lang.org/forums/1/2153/ShowThread.aspx
- GCC_INLINE_WORKAROUND (problems with inline functions with gcc)
- Set/get for short/char members
- Get for const SQChar*
- DECLARE_ENUM_TYPE - Allows enums to be used as arguments
- Support for more customized Push handlers
- SQPLUS_DISABLE_COPY_INSTANCES (disabling automatic use of copy
constructors)
- Support for automatically generate TypeMasks (a template
solution) on function registration
2007-08-25 "SQUIRREL2_1_1_sqplus_snapshot_20070825"
* Added m0pey's smart pointer support :
http://squirrel-lang.org/forums/thread/1982.aspx
2007-01-07 "SQUIRREL2_1_1_sqplus_snapshot_20070701"
* Fixed `returning a pointer of a derived class' problem with gcc
(http://squirrel-lang.org/forums/thread/1875.aspx) based on
http://wiki.squirrel-lang.org/default.aspx/SquirrelWiki/SqPlusNativeCreatedInstancesWithCorrectAncestry.html
2007-06/02 "SQUIRREL2_1_1_sqplus_snapshot_20070602"
* Fix by Sebastien Frippiat:
http://squirrel-lang.org/forums/thread/507.aspx
2007-05-27 "SQUIRREL2_1_1_sqplus_snapshot_20070527"
* Added sqplus/SqPlusOverload.h for function overloading. See
testSqPlus2unit/test_FunctionOverloading.cpp.
2007-03-04 "SQUIRREL2_1_1_sqplus_snapshot_20070304"
* Fixed compilation problem on g++-3.4.4 (cygwin):
http://squirrel-lang.org/forums/thread/1753.aspx
2007-02-25 "SQUIRREL2_1_1_sqplus_snapshot_20070225"
* Fix by Kamaitati: http://squirrel-lang.org/forums/thread/1748.aspx
* Modified sqplu.h (SquirrelObject::Set<>()) for gcc
* Added testSqPlus2unit directory for unit testing
2006-10-09- "SQUIRREL2_1_1_sqplus_25"
* Fixed SqPlusConst.h:
http://squirrel-lang.org/forums/thread/1314.aspx, changed
SquirrelObject Get/Set to default to pass-by-reference, where
pass-by-copy requires extra parameter
2006-10-08 "SQUIRREL2_1_1_sqplus_24"
* Added SQClassDefNoConstructor<>:
http://wiki.squirrel-lang.org/default.aspx/SquirrelWiki/SqPlusWithoutAutoDefaultConstructor.html
(allows binding abstract base classes/pure-virtual-interfaces)
* Added "Squirrel Set/Get objects"
http://wiki.squirrel-lang.org/default.aspx/SquirrelWiki/SqPlusGetSetObjects.html
2006-09-30 "SQUIRREL2_1_1_sqplus_23"
* Fixed return type for sq_std_string Get()
2006-08-21 "SQUIRREL2_1_0_sqplus_22"
* Merged in Squirrel 2.1.1 Stable
2006-08-20 "SQUIRREL2_1_0_sqplus_21"
* Changed code order to be compatible with GCC 4.1.x.
* Added jflanglois' suggestion for std::basic_string<SQChar>
2006-06-27 "SQUIRREL2_1_0_sqplus_20"
* Added Katsuaki Kawachi's GetInstance()/Match() changes
(http://www.squirrel-lang.org/forums/962/ShowPost.aspx)
2006-02-06 "SQUIRREL2_1_0_sqplus_19"
* Added VS7.1 make/project files with 71 suffix: can be used
alongside VS8 without directory changes
* Added optional debug string argument to SquirrelVM::CompileBuffer()
2006-05-28 "SQUIRREL2_1_0_sqplus_18"
* Added Kamaitati's changes: bug fix, C++ style inheritance support,
null instance argument support
2006-04-25 "SQUIRREL2_1_0_sqplus_17"
* Changed SquirrelObject::GetInstanceUP() to return NULL and
clear internal error state on invalid instance type request
* Added SquirrelObject::GetTypeName(const "SQChar" * key),
SquirrelObject::GetTypeName("INT" key) and
SquirrelObject::GetTypeName().
* Added SQ_SUPPORT_INSTANCE_TYPE_INFO compile time option
* Added missing template arguments (7 argument case)
* Source changes to support VS7.1 and VS8 compilation (standard and
UNICODE builds)
* Added Code::Blocks project files
2006-03-26 "SQUIRREL2_1_0_sqplus_11"
* Updated make/build files to VS8 (http://msdn.microsoft.com/vstudio/)
* Source changes for VS8 compilation
2006-03-19 "SQUIRREL2_1_0_sqplus_10"
* Updated to Squirrel 2.1
2006-02-27 "SQUIRREL2_0_5_sqplus_9"
* Added Ben's changes to implement DECLARE_INSTANCE_TYPE_NAME
(http://www.squirrel-lang.org/forums/635/ShowPost.aspx)
2005-12-22 "SQUIRREL2_0_5_sqplus_8"
* Added GetVMSys() and SetVMSys() to better support multiple VM's
2005-11-21 "SQUIRREL2_0_5_sqplus_7"
* Added modular support for const member functions. Defining
SQPLUS_CONST_OPT before including sqplus.h enables the added
functionality
* SqPlus tested on Mac OS-X
2005-11-03 "SQUIRREL2_0_5_sqplus_6"
* Fixed inheritance issue: tables added to classes are not newly
created upon instantiation- they must be cloned during
construction (language design)
* Reworked projects build settings to better allow building all
projects types: Debug, Release, Debug - Unicode, Release - Unicode
2005-11-01 "SQUIRREL2_0_5_sqplus_5"
* Added Unicode support
2005-10-23 "SQUIRREL2_0_5_sqplus_4"
* Added gcc support:
- Added simple GNU Makefiles for gcc
- Minor code changes for gcc compilation
- Tested on RH Linux gcc 3.2.3, Cygwin gcc 3.4.4, and gcc on Sony PSP
(http://www.squirrel-lang.org/forums/420/ShowPost.aspx#420)
* Added ClassDef::enumInt() for registering enums as ints
(to replace ClassDef::constant((int)myEnum))
2005-10-14 "SQUIRREL2_0_5_sqplus_3"
* Added support for SquirrelObject as a function argument and return
value. Tables and arrays can be directly accessed without using
the stack. This also makes it possible to return tables, arrays,
classes, and closures for later use at runtime, saving look-up
overhead
* Added GetRet() for SquirrelFunction<> to ensure proper stack
behavior
* Added additional error return info to help with debugging
* Removed unused code

View File

@ -0,0 +1,190 @@
<?xml version="1.0"?>
<!DOCTYPE CodeBlocks_project_file>
<CodeBlocks_project_file>
<FileVersion major="1" minor="1"/>
<Project>
<Option title="sqplus"/>
<Option makefile="Makefile"/>
<Option makefile_is_custom="0"/>
<Option default_target="-1"/>
<Option compiler="0"/>
<Build>
<Target title="Debug">
<Option output="..\lib\libsqplusD.a"/>
<Option working_dir=""/>
<Option object_output="Debug"/>
<Option deps_output=".deps"/>
<Option type="2"/>
<Option compiler="0"/>
<Option createDefFile="1"/>
<Option projectResourceIncludeDirsRelation="2"/>
<Compiler>
<Add option="-DWIN32"/>
<Add option="-D_DEBUG"/>
<Add option="-D_LIB"/>
<Add option="-D_CRT_SECURE_NO_DEPRECATE"/>
<Add option="-W"/>
<Add option="-O0"/>
<Add directory="..\include"/>
</Compiler>
</Target>
<Target title="Release">
<Option output="..\lib\libsqplus.a"/>
<Option working_dir=""/>
<Option object_output="Release"/>
<Option deps_output=".deps"/>
<Option type="2"/>
<Option compiler="0"/>
<Option createDefFile="1"/>
<Option projectResourceIncludeDirsRelation="2"/>
<Compiler>
<Add option="-DWIN32"/>
<Add option="-DNDEBUG"/>
<Add option="-D_LIB"/>
<Add option="-D_CRT_SECURE_NO_DEPRECATE"/>
<Add option="-W"/>
<Add option="-g"/>
<Add directory="..\include"/>
</Compiler>
</Target>
<Target title="Debug - Unicode">
<Option output="..\lib\libsqplusDU.a"/>
<Option working_dir=""/>
<Option object_output="Debug - Unicode"/>
<Option deps_output=".deps"/>
<Option type="2"/>
<Option compiler="0"/>
<Option createDefFile="1"/>
<Option projectResourceIncludeDirsRelation="2"/>
<Compiler>
<Add option="-DWIN32"/>
<Add option="-D_DEBUG"/>
<Add option="-D_LIB"/>
<Add option="-D_CRT_SECURE_NO_DEPRECATE"/>
<Add option="-D_CRT_NON_CONFORMING_SWPRINTFS"/>
<Add option="-W"/>
<Add option="-O0"/>
<Add directory="..\include"/>
</Compiler>
</Target>
<Target title="Release - Unicode">
<Option output="..\lib\libsqplusU.a"/>
<Option working_dir=""/>
<Option object_output="Release - Unicode"/>
<Option deps_output=".deps"/>
<Option type="2"/>
<Option compiler="0"/>
<Option createDefFile="1"/>
<Option projectResourceIncludeDirsRelation="2"/>
<Compiler>
<Add option="-DWIN32"/>
<Add option="-DNDEBUG"/>
<Add option="-D_LIB"/>
<Add option="-D_CRT_SECURE_NO_DEPRECATE"/>
<Add option="-D_CRT_NON_CONFORMING_SWPRINTFS"/>
<Add option="-W"/>
<Add option="-g"/>
<Add directory="..\include"/>
</Compiler>
</Target>
</Build>
<Unit filename="SqPlus.cpp">
<Option compilerVar="CPP"/>
<Option target="Debug"/>
<Option target="Release"/>
<Option target="Debug - Unicode"/>
<Option target="Release - Unicode"/>
</Unit>
<Unit filename="SqPlusConst.h">
<Option compilerVar=""/>
<Option compile="0"/>
<Option link="0"/>
<Option target="Debug"/>
<Option target="Release"/>
<Option target="Debug - Unicode"/>
<Option target="Release - Unicode"/>
</Unit>
<Unit filename="SquirrelBindingsUtils.cpp">
<Option compilerVar="CPP"/>
<Option target="Debug"/>
<Option target="Release"/>
<Option target="Debug - Unicode"/>
<Option target="Release - Unicode"/>
</Unit>
<Unit filename="SquirrelBindingsUtils.h">
<Option compilerVar=""/>
<Option compile="0"/>
<Option link="0"/>
<Option target="Debug"/>
<Option target="Release"/>
<Option target="Debug - Unicode"/>
<Option target="Release - Unicode"/>
</Unit>
<Unit filename="SquirrelBindingsUtilsWin32.cpp">
<Option compilerVar="CPP"/>
<Option target="Debug"/>
<Option target="Release"/>
<Option target="Debug - Unicode"/>
<Option target="Release - Unicode"/>
</Unit>
<Unit filename="SquirrelBindingsUtilsWin32.h">
<Option compilerVar=""/>
<Option compile="0"/>
<Option link="0"/>
<Option target="Debug"/>
<Option target="Release"/>
<Option target="Debug - Unicode"/>
<Option target="Release - Unicode"/>
</Unit>
<Unit filename="SquirrelObject.cpp">
<Option compilerVar="CPP"/>
<Option target="Debug"/>
<Option target="Release"/>
<Option target="Debug - Unicode"/>
<Option target="Release - Unicode"/>
</Unit>
<Unit filename="SquirrelObject.h">
<Option compilerVar=""/>
<Option compile="0"/>
<Option link="0"/>
<Option target="Debug"/>
<Option target="Release"/>
<Option target="Debug - Unicode"/>
<Option target="Release - Unicode"/>
</Unit>
<Unit filename="SquirrelVM.cpp">
<Option compilerVar="CPP"/>
<Option target="Debug"/>
<Option target="Release"/>
<Option target="Debug - Unicode"/>
<Option target="Release - Unicode"/>
</Unit>
<Unit filename="SquirrelVM.h">
<Option compilerVar=""/>
<Option compile="0"/>
<Option link="0"/>
<Option target="Debug"/>
<Option target="Release"/>
<Option target="Debug - Unicode"/>
<Option target="Release - Unicode"/>
</Unit>
<Unit filename="sqplus.h">
<Option compilerVar=""/>
<Option compile="0"/>
<Option link="0"/>
<Option target="Debug"/>
<Option target="Release"/>
<Option target="Debug - Unicode"/>
<Option target="Release - Unicode"/>
</Unit>
<Unit filename="sqplusWin32.h">
<Option compilerVar=""/>
<Option compile="0"/>
<Option link="0"/>
<Option target="Debug"/>
<Option target="Release"/>
<Option target="Debug - Unicode"/>
<Option target="Release - Unicode"/>
</Unit>
</Project>
</CodeBlocks_project_file>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,355 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="sqplus"
ProjectGUID="{F9811314-C694-49A4-BD87-BA2E7F30D358}"
RootNamespace="sqplus"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="../lib/sqplusD.lib"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="../lib/sqplus.lib"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug - Unicode|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="../lib/sqplusDU.lib"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release - Unicode|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="../lib/sqplusU.lib"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\SqPlus.cpp"
>
</File>
<File
RelativePath=".\SqPlusOCharBuf.cpp"
>
</File>
<File
RelativePath=".\SqPlusUtf8.cpp"
>
</File>
<File
RelativePath=".\SquirrelBindingsUtils.cpp"
>
</File>
<File
RelativePath=".\SquirrelBindingsUtilsWin32.cpp"
>
</File>
<File
RelativePath=".\SquirrelObject.cpp"
>
</File>
<File
RelativePath=".\SquirrelVM.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\sqplus.h"
>
</File>
<File
RelativePath=".\SqPlusConst.h"
>
</File>
<File
RelativePath=".\SqPlusOCharBuf.h"
>
</File>
<File
RelativePath=".\SqPlusSetup.h"
>
</File>
<File
RelativePath=".\sqplusWin32.h"
>
</File>
<File
RelativePath=".\SquirrelBindingsUtils.h"
>
</File>
<File
RelativePath=".\SquirrelBindingsUtilsWin32.h"
>
</File>
<File
RelativePath=".\SquirrelObject.h"
>
</File>
<File
RelativePath=".\SquirrelVM.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,159 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug - Unicode|Win32">
<Configuration>Debug - Unicode</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release - Unicode|Win32">
<Configuration>Release - Unicode</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{F9811314-C694-49A4-BD87-BA2E7F30D358}</ProjectGuid>
<RootNamespace>sqplus</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - Unicode|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Unicode|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - Unicode|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Unicode|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug - Unicode|Win32'">$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug - Unicode|Win32'">$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release - Unicode|Win32'">$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release - Unicode|Win32'">$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Lib>
<OutputFile>../lib/sqplusD.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Lib>
<OutputFile>../lib/sqplus.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Unicode|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Lib>
<OutputFile>../lib/sqplusDU.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - Unicode|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Lib>
<OutputFile>../lib/sqplusU.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="SqPlus.cpp" />
<ClCompile Include="SqPlusOCharBuf.cpp" />
<ClCompile Include="SqPlusUtf8.cpp" />
<ClCompile Include="SquirrelBindingsUtils.cpp" />
<ClCompile Include="SquirrelBindingsUtilsWin32.cpp" />
<ClCompile Include="SquirrelObject.cpp" />
<ClCompile Include="SquirrelVM.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="sqplus.h" />
<ClInclude Include="SqPlusConst.h" />
<ClInclude Include="SqPlusOCharBuf.h" />
<ClInclude Include="SqPlusSetup.h" />
<ClInclude Include="sqplusWin32.h" />
<ClInclude Include="SquirrelBindingsUtils.h" />
<ClInclude Include="SquirrelBindingsUtilsWin32.h" />
<ClInclude Include="SquirrelObject.h" />
<ClInclude Include="SquirrelVM.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="SqPlus.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SqPlusOCharBuf.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SqPlusUtf8.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SquirrelBindingsUtils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SquirrelBindingsUtilsWin32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SquirrelObject.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SquirrelVM.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="sqplus.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SqPlusConst.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SqPlusOCharBuf.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SqPlusSetup.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="sqplusWin32.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SquirrelBindingsUtils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SquirrelBindingsUtilsWin32.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SquirrelObject.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SquirrelVM.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>

View File

@ -0,0 +1,235 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="sqplus"
ProjectGUID="{F9811314-C694-49A4-BD87-BA2E7F30D358}"
RootNamespace="sqplus"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="../lib/sqplusD.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="../lib/sqplus.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Debug - Unicode|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="../lib/sqplusDU.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release - Unicode|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="../lib/sqplusU.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath=".\SqPlus.cpp">
</File>
<File
RelativePath=".\SqPlusOCharBuf.cpp">
</File>
<File
RelativePath=".\SqPlusUtf8.cpp">
</File>
<File
RelativePath=".\SquirrelBindingsUtils.cpp">
</File>
<File
RelativePath=".\SquirrelBindingsUtilsWin32.cpp">
</File>
<File
RelativePath=".\SquirrelObject.cpp">
</File>
<File
RelativePath=".\SquirrelVM.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath=".\sqplus.h">
</File>
<File
RelativePath=".\SqPlusConst.h">
</File>
<File
RelativePath=".\sqplusWin32.h">
</File>
<File
RelativePath=".\SquirrelBindingsUtils.h">
</File>
<File
RelativePath=".\SquirrelBindingsUtilsWin32.h">
</File>
<File
RelativePath=".\SquirrelObject.h">
</File>
<File
RelativePath=".\SquirrelVM.h">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,7 @@
#ifndef _SQ_PLUS_WIN32_H_
#define _SQ_PLUS_WIN32_H_
#include "sqplus.h"
#include "SquirrelBindingsUtilsWin32.h"
#endif //_SQ_PLUS_WIN32_H_

View File

@ -0,0 +1,41 @@
SQUIRREL= ..
OUT= $(SQUIRREL)/lib/libsqstdlib.a
INCZ= -I$(SQUIRREL)/include -I. -Iinclude
OBJS= \
sqstdblob.o \
sqstdio.o \
sqstdstream.o \
sqstdmath.o \
sqstdsystem.o \
sqstdstring.o \
sqstdaux.o \
sqstdrex.o
SRCS= \
sqstdblob.cpp \
sqstdio.cpp \
sqstdstream.cpp \
sqstdmath.cpp \
sqstdsystem.cpp \
sqstdstring.cpp \
sqstdaux.cpp \
sqstdrex.cpp
sq32:
gcc -O2 -fno-exceptions -fno-rtti -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ)
ar rc $(OUT) *.o
rm *.o
sqprof:
gcc -O2 -pg -fno-exceptions -fno-rtti -pie -gstabs -g3 -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ)
ar rc $(OUT) *.o
rm *.o
sq64:
gcc -O2 -m64 -fno-exceptions -D_SQ64 -fno-rtti -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ)
ar rc $(OUT) *.o
rm *.o

View File

@ -0,0 +1,129 @@
/* see copyright notice in squirrel.h */
#include <squirrel.h>
#include <sqstdaux.h>
#include <assert.h>
void sqstd_printcallstack(HSQUIRRELVM v)
{
SQPRINTFUNCTION pf = sq_geterrorfunc(v);
if(pf) {
SQStackInfos si;
SQInteger i;
SQFloat f;
const SQChar *s;
SQInteger level=1; //1 is to skip this function that is level 0
const SQChar *name=0;
SQInteger seq=0;
pf(v,_SC("\nCALLSTACK\n"));
while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si)))
{
const SQChar *fn=_SC("unknown");
const SQChar *src=_SC("unknown");
if(si.funcname)fn=si.funcname;
if(si.source)src=si.source;
pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line);
level++;
}
level=0;
pf(v,_SC("\nLOCALS\n"));
for(level=0;level<10;level++){
seq=0;
while((name = sq_getlocal(v,level,seq)))
{
seq++;
switch(sq_gettype(v,-1))
{
case OT_NULL:
pf(v,_SC("[%s] NULL\n"),name);
break;
case OT_INTEGER:
sq_getinteger(v,-1,&i);
pf(v,_SC("[%s] %d\n"),name,i);
break;
case OT_FLOAT:
sq_getfloat(v,-1,&f);
pf(v,_SC("[%s] %.14g\n"),name,f);
break;
case OT_USERPOINTER:
pf(v,_SC("[%s] USERPOINTER\n"),name);
break;
case OT_STRING:
sq_getstring(v,-1,&s);
pf(v,_SC("[%s] \"%s\"\n"),name,s);
break;
case OT_TABLE:
pf(v,_SC("[%s] TABLE\n"),name);
break;
case OT_ARRAY:
pf(v,_SC("[%s] ARRAY\n"),name);
break;
case OT_CLOSURE:
pf(v,_SC("[%s] CLOSURE\n"),name);
break;
case OT_NATIVECLOSURE:
pf(v,_SC("[%s] NATIVECLOSURE\n"),name);
break;
case OT_GENERATOR:
pf(v,_SC("[%s] GENERATOR\n"),name);
break;
case OT_USERDATA:
pf(v,_SC("[%s] USERDATA\n"),name);
break;
case OT_THREAD:
pf(v,_SC("[%s] THREAD\n"),name);
break;
case OT_CLASS:
pf(v,_SC("[%s] CLASS\n"),name);
break;
case OT_INSTANCE:
pf(v,_SC("[%s] INSTANCE\n"),name);
break;
case OT_WEAKREF:
pf(v,_SC("[%s] WEAKREF\n"),name);
break;
case OT_BOOL:{
sq_getinteger(v,-1,&i);
pf(v,_SC("[%s] %s\n"),name,i?_SC("true"):_SC("false"));
}
break;
default: assert(0); break;
}
sq_pop(v,1);
}
}
}
}
static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v)
{
SQPRINTFUNCTION pf = sq_geterrorfunc(v);
if(pf) {
const SQChar *sErr = 0;
if(sq_gettop(v)>=1) {
if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) {
pf(v,_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr);
}
else{
pf(v,_SC("\nAN ERROR HAS OCCURED [unknown]\n"));
}
sqstd_printcallstack(v);
}
}
return 0;
}
void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column)
{
SQPRINTFUNCTION pf = sq_geterrorfunc(v);
if(pf) {
pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr);
}
}
void sqstd_seterrorhandlers(HSQUIRRELVM v)
{
sq_setcompilererrorhandler(v,_sqstd_compiler_error);
sq_newclosure(v,_sqstd_aux_printerror,0);
sq_seterrorhandler(v);
}

View File

@ -0,0 +1,275 @@
/* see copyright notice in squirrel.h */
#include <new>
#include <squirrel.h>
#include <sqstdio.h>
#include <string.h>
#include <sqstdblob.h>
#include "sqstdstream.h"
#include "sqstdblobimpl.h"
#define SQSTD_BLOB_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000002)
//Blob
#define SETUP_BLOB(v) \
SQBlob *self = NULL; \
{ if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) \
return SQ_ERROR; }
static SQInteger _blob_resize(HSQUIRRELVM v)
{
SETUP_BLOB(v);
SQInteger size;
sq_getinteger(v,2,&size);
if(!self->Resize(size))
return sq_throwerror(v,_SC("resize failed"));
return 0;
}
static void __swap_dword(unsigned int *n)
{
*n=(unsigned int)(((*n&0xFF000000)>>24) |
((*n&0x00FF0000)>>8) |
((*n&0x0000FF00)<<8) |
((*n&0x000000FF)<<24));
}
static void __swap_word(unsigned short *n)
{
*n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00);
}
static SQInteger _blob_swap4(HSQUIRRELVM v)
{
SETUP_BLOB(v);
SQInteger num=(self->Len()-(self->Len()%4))>>2;
unsigned int *t=(unsigned int *)self->GetBuf();
for(SQInteger i = 0; i < num; i++) {
__swap_dword(&t[i]);
}
return 0;
}
static SQInteger _blob_swap2(HSQUIRRELVM v)
{
SETUP_BLOB(v);
SQInteger num=(self->Len()-(self->Len()%2))>>1;
unsigned short *t = (unsigned short *)self->GetBuf();
for(SQInteger i = 0; i < num; i++) {
__swap_word(&t[i]);
}
return 0;
}
static SQInteger _blob__set(HSQUIRRELVM v)
{
SETUP_BLOB(v);
SQInteger idx,val;
sq_getinteger(v,2,&idx);
sq_getinteger(v,3,&val);
if(idx < 0 || idx >= self->Len())
return sq_throwerror(v,_SC("index out of range"));
((unsigned char *)self->GetBuf())[idx] = (unsigned char) val;
sq_push(v,3);
return 1;
}
static SQInteger _blob__get(HSQUIRRELVM v)
{
SETUP_BLOB(v);
SQInteger idx;
sq_getinteger(v,2,&idx);
if(idx < 0 || idx >= self->Len())
return sq_throwerror(v,_SC("index out of range"));
sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]);
return 1;
}
static SQInteger _blob__nexti(HSQUIRRELVM v)
{
SETUP_BLOB(v);
if(sq_gettype(v,2) == OT_NULL) {
sq_pushinteger(v, 0);
return 1;
}
SQInteger idx;
if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) {
if(idx+1 < self->Len()) {
sq_pushinteger(v, idx+1);
return 1;
}
sq_pushnull(v);
return 1;
}
return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type"));
}
static SQInteger _blob__typeof(HSQUIRRELVM v)
{
sq_pushstring(v,_SC("blob"),-1);
return 1;
}
static SQInteger _blob_releasehook(SQUserPointer p, SQInteger size)
{
SQBlob *self = (SQBlob*)p;
self->~SQBlob();
sq_free(self,sizeof(SQBlob));
return 1;
}
static SQInteger _blob_constructor(HSQUIRRELVM v)
{
SQInteger nparam = sq_gettop(v);
SQInteger size = 0;
if(nparam == 2) {
sq_getinteger(v, 2, &size);
}
if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size"));
//SQBlob *b = new SQBlob(size);
SQBlob *b = new (sq_malloc(sizeof(SQBlob)))SQBlob(size);
if(SQ_FAILED(sq_setinstanceup(v,1,b))) {
b->~SQBlob();
sq_free(b,sizeof(SQBlob));
return sq_throwerror(v, _SC("cannot create blob"));
}
sq_setreleasehook(v,1,_blob_releasehook);
return 0;
}
static SQInteger _blob__cloned(HSQUIRRELVM v)
{
SQBlob *other = NULL;
{
if(SQ_FAILED(sq_getinstanceup(v,2,(SQUserPointer*)&other,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
return SQ_ERROR;
}
//SQBlob *thisone = new SQBlob(other->Len());
SQBlob *thisone = new (sq_malloc(sizeof(SQBlob)))SQBlob(other->Len());
memcpy(thisone->GetBuf(),other->GetBuf(),thisone->Len());
if(SQ_FAILED(sq_setinstanceup(v,1,thisone))) {
thisone->~SQBlob();
sq_free(thisone,sizeof(SQBlob));
return sq_throwerror(v, _SC("cannot clone blob"));
}
sq_setreleasehook(v,1,_blob_releasehook);
return 0;
}
#define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck}
static SQRegFunction _blob_methods[] = {
_DECL_BLOB_FUNC(constructor,-1,_SC("xn")),
_DECL_BLOB_FUNC(resize,2,_SC("xn")),
_DECL_BLOB_FUNC(swap2,1,_SC("x")),
_DECL_BLOB_FUNC(swap4,1,_SC("x")),
_DECL_BLOB_FUNC(_set,3,_SC("xnn")),
_DECL_BLOB_FUNC(_get,2,_SC("xn")),
_DECL_BLOB_FUNC(_typeof,1,_SC("x")),
_DECL_BLOB_FUNC(_nexti,2,_SC("x")),
_DECL_BLOB_FUNC(_cloned,2,_SC("xx")),
{0,0,0,0}
};
//GLOBAL FUNCTIONS
static SQInteger _g_blob_casti2f(HSQUIRRELVM v)
{
SQInteger i;
sq_getinteger(v,2,&i);
sq_pushfloat(v,*((SQFloat *)&i));
return 1;
}
static SQInteger _g_blob_castf2i(HSQUIRRELVM v)
{
SQFloat f;
sq_getfloat(v,2,&f);
sq_pushinteger(v,*((SQInteger *)&f));
return 1;
}
static SQInteger _g_blob_swap2(HSQUIRRELVM v)
{
SQInteger i;
sq_getinteger(v,2,&i);
short s=(short)i;
sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF));
return 1;
}
static SQInteger _g_blob_swap4(HSQUIRRELVM v)
{
SQInteger i;
sq_getinteger(v,2,&i);
unsigned int t4 = (unsigned int)i;
__swap_dword(&t4);
sq_pushinteger(v,(SQInteger)t4);
return 1;
}
static SQInteger _g_blob_swapfloat(HSQUIRRELVM v)
{
SQFloat f;
sq_getfloat(v,2,&f);
__swap_dword((unsigned int *)&f);
sq_pushfloat(v,f);
return 1;
}
#define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck}
static SQRegFunction bloblib_funcs[]={
_DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")),
_DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")),
_DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")),
_DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")),
_DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")),
{0,0}
};
SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr)
{
SQBlob *blob;
if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
return -1;
*ptr = blob->GetBuf();
return SQ_OK;
}
SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx)
{
SQBlob *blob;
if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
return -1;
return blob->Len();
}
SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size)
{
SQInteger top = sq_gettop(v);
sq_pushregistrytable(v);
sq_pushstring(v,_SC("std_blob"),-1);
if(SQ_SUCCEEDED(sq_get(v,-2))) {
sq_remove(v,-2); //removes the registry
sq_push(v,1); // push the this
sq_pushinteger(v,size); //size
SQBlob *blob = NULL;
if(SQ_SUCCEEDED(sq_call(v,2,SQTrue,SQFalse))
&& SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) {
sq_remove(v,-2);
return blob->GetBuf();
}
}
sq_settop(v,top);
return NULL;
}
SQRESULT sqstd_register_bloblib(HSQUIRRELVM v)
{
return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs);
}

View File

@ -0,0 +1,108 @@
/* see copyright notice in squirrel.h */
#ifndef _SQSTD_BLOBIMPL_H_
#define _SQSTD_BLOBIMPL_H_
struct SQBlob : public SQStream
{
SQBlob(SQInteger size) {
_size = size;
_allocated = size;
_buf = (unsigned char *)sq_malloc(size);
memset(_buf, 0, _size);
_ptr = 0;
_owns = true;
}
virtual ~SQBlob() {
sq_free(_buf, _allocated);
}
SQInteger Write(void *buffer, SQInteger size) {
if(!CanAdvance(size)) {
GrowBufOf(_ptr + size - _size);
}
memcpy(&_buf[_ptr], buffer, size);
_ptr += size;
return size;
}
SQInteger Read(void *buffer,SQInteger size) {
SQInteger n = size;
if(!CanAdvance(size)) {
if((_size - _ptr) > 0)
n = _size - _ptr;
else return 0;
}
memcpy(buffer, &_buf[_ptr], n);
_ptr += n;
return n;
}
bool Resize(SQInteger n) {
if(!_owns) return false;
if(n != _allocated) {
unsigned char *newbuf = (unsigned char *)sq_malloc(n);
memset(newbuf,0,n);
if(_size > n)
memcpy(newbuf,_buf,n);
else
memcpy(newbuf,_buf,_size);
sq_free(_buf,_allocated);
_buf=newbuf;
_allocated = n;
if(_size > _allocated)
_size = _allocated;
if(_ptr > _allocated)
_ptr = _allocated;
}
return true;
}
bool GrowBufOf(SQInteger n)
{
bool ret = true;
if(_size + n > _allocated) {
if(_size + n > _size * 2)
ret = Resize(_size + n);
else
ret = Resize(_size * 2);
}
_size = _size + n;
return ret;
}
bool CanAdvance(SQInteger n) {
if(_ptr+n>_size)return false;
return true;
}
SQInteger Seek(SQInteger offset, SQInteger origin) {
switch(origin) {
case SQ_SEEK_SET:
if(offset > _size || offset < 0) return -1;
_ptr = offset;
break;
case SQ_SEEK_CUR:
if(_ptr + offset > _size || _ptr + offset < 0) return -1;
_ptr += offset;
break;
case SQ_SEEK_END:
if(_size + offset > _size || _size + offset < 0) return -1;
_ptr = _size + offset;
break;
default: return -1;
}
return 0;
}
bool IsValid() {
return _buf?true:false;
}
bool EOS() {
return _ptr == _size;
}
SQInteger Flush() { return 0; }
SQInteger Tell() { return _ptr; }
SQInteger Len() { return _size; }
SQUserPointer GetBuf(){ return _buf; }
private:
SQInteger _size;
SQInteger _allocated;
SQInteger _ptr;
unsigned char *_buf;
bool _owns;
};
#endif //_SQSTD_BLOBIMPL_H_

View File

@ -0,0 +1,419 @@
/* see copyright notice in squirrel.h */
#include <new>
#include <stdio.h>
#include <squirrel.h>
#include <sqstdio.h>
#include "sqstdstream.h"
#define SQSTD_FILE_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000001)
//basic API
SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode)
{
#ifndef SQUNICODE
return (SQFILE)fopen(filename,mode);
#else
return (SQFILE)_wfopen(filename,mode);
#endif
}
SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file)
{
return (SQInteger)fread(buffer,size,count,(FILE *)file);
}
SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file)
{
return (SQInteger)fwrite(buffer,size,count,(FILE *)file);
}
SQInteger sqstd_fseek(SQFILE file, SQInteger offset, SQInteger origin)
{
SQInteger realorigin;
switch(origin) {
case SQ_SEEK_CUR: realorigin = SEEK_CUR; break;
case SQ_SEEK_END: realorigin = SEEK_END; break;
case SQ_SEEK_SET: realorigin = SEEK_SET; break;
default: return -1; //failed
}
return fseek((FILE *)file,(long)offset,(int)realorigin);
}
SQInteger sqstd_ftell(SQFILE file)
{
return ftell((FILE *)file);
}
SQInteger sqstd_fflush(SQFILE file)
{
return fflush((FILE *)file);
}
SQInteger sqstd_fclose(SQFILE file)
{
return fclose((FILE *)file);
}
SQInteger sqstd_feof(SQFILE file)
{
return feof((FILE *)file);
}
//File
struct SQFile : public SQStream {
SQFile() { _handle = NULL; _owns = false;}
SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;}
virtual ~SQFile() { Close(); }
bool Open(const SQChar *filename ,const SQChar *mode) {
Close();
if( (_handle = sqstd_fopen(filename,mode)) ) {
_owns = true;
return true;
}
return false;
}
void Close() {
if(_handle && _owns) {
sqstd_fclose(_handle);
_handle = NULL;
_owns = false;
}
}
SQInteger Read(void *buffer,SQInteger size) {
return sqstd_fread(buffer,1,size,_handle);
}
SQInteger Write(void *buffer,SQInteger size) {
return sqstd_fwrite(buffer,1,size,_handle);
}
SQInteger Flush() {
return sqstd_fflush(_handle);
}
SQInteger Tell() {
return sqstd_ftell(_handle);
}
SQInteger Len() {
SQInteger prevpos=Tell();
Seek(0,SQ_SEEK_END);
SQInteger size=Tell();
Seek(prevpos,SQ_SEEK_SET);
return size;
}
SQInteger Seek(SQInteger offset, SQInteger origin) {
return sqstd_fseek(_handle,offset,origin);
}
bool IsValid() { return _handle?true:false; }
bool EOS() { return Tell()==Len()?true:false;}
SQFILE GetHandle() {return _handle;}
private:
SQFILE _handle;
bool _owns;
};
static SQInteger _file__typeof(HSQUIRRELVM v)
{
sq_pushstring(v,_SC("file"),-1);
return 1;
}
static SQInteger _file_releasehook(SQUserPointer p, SQInteger size)
{
SQFile *self = (SQFile*)p;
self->~SQFile();
sq_free(self,sizeof(SQFile));
return 1;
}
static SQInteger _file_constructor(HSQUIRRELVM v)
{
const SQChar *filename,*mode;
bool owns = true;
SQFile *f;
SQFILE newf;
if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) {
sq_getstring(v, 2, &filename);
sq_getstring(v, 3, &mode);
newf = sqstd_fopen(filename, mode);
if(!newf) return sq_throwerror(v, _SC("cannot open file"));
} else if(sq_gettype(v,2) == OT_USERPOINTER) {
owns = !(sq_gettype(v,3) == OT_NULL);
sq_getuserpointer(v,2,&newf);
} else {
return sq_throwerror(v,_SC("wrong parameter"));
}
f = new (sq_malloc(sizeof(SQFile)))SQFile(newf,owns);
if(SQ_FAILED(sq_setinstanceup(v,1,f))) {
f->~SQFile();
sq_free(f,sizeof(SQFile));
return sq_throwerror(v, _SC("cannot create blob with negative size"));
}
sq_setreleasehook(v,1,_file_releasehook);
return 0;
}
//bindings
#define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck}
static SQRegFunction _file_methods[] = {
_DECL_FILE_FUNC(constructor,3,_SC("x")),
_DECL_FILE_FUNC(_typeof,1,_SC("x")),
{0,0,0,0},
};
SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own)
{
SQInteger top = sq_gettop(v);
sq_pushregistrytable(v);
sq_pushstring(v,_SC("std_file"),-1);
if(SQ_SUCCEEDED(sq_get(v,-2))) {
sq_remove(v,-2); //removes the registry
sq_pushroottable(v); // push the this
sq_pushuserpointer(v,file); //file
if(own){
sq_pushinteger(v,1); //true
}
else{
sq_pushnull(v); //false
}
if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) {
sq_remove(v,-2);
return SQ_OK;
}
}
sq_settop(v,top);
return SQ_OK;
}
SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file)
{
SQFile *fileobj = NULL;
if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG))) {
*file = fileobj->GetHandle();
return SQ_OK;
}
return sq_throwerror(v,_SC("not a file"));
}
static SQInteger _io_file_lexfeed_PLAIN(SQUserPointer file)
{
SQInteger ret;
char c;
if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )
return c;
return 0;
}
#ifdef SQUNICODE
static SQInteger _io_file_lexfeed_UTF8(SQUserPointer file)
{
#define READ() \
if(sqstd_fread(&inchar,sizeof(inchar),1,(FILE *)file) != 1) \
return 0;
static const SQInteger utf8_lengths[16] =
{
1,1,1,1,1,1,1,1, /* 0000 to 0111 : 1 byte (plain ASCII) */
0,0,0,0, /* 1000 to 1011 : not valid */
2,2, /* 1100, 1101 : 2 bytes */
3, /* 1110 : 3 bytes */
4 /* 1111 :4 bytes */
};
static unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07};
unsigned char inchar;
SQInteger c = 0;
READ();
c = inchar;
//
if(c >= 0x80) {
SQInteger tmp;
SQInteger codelen = utf8_lengths[c>>4];
if(codelen == 0)
return 0;
//"invalid UTF-8 stream";
tmp = c&byte_masks[codelen];
for(SQInteger n = 0; n < codelen-1; n++) {
tmp<<=6;
READ();
tmp |= inchar & 0x3F;
}
c = tmp;
}
return c;
}
#endif
static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer file)
{
SQInteger ret;
wchar_t c;
if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )
return (SQChar)c;
return 0;
}
static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer file)
{
SQInteger ret;
unsigned short c;
if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) {
c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00);
return (SQChar)c;
}
return 0;
}
SQInteger file_read(SQUserPointer file,SQUserPointer buf,SQInteger size)
{
SQInteger ret;
if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret;
return -1;
}
SQInteger file_write(SQUserPointer file,SQUserPointer p,SQInteger size)
{
return sqstd_fwrite(p,1,size,(SQFILE)file);
}
SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror)
{
SQFILE file = sqstd_fopen(filename,_SC("rb"));
SQInteger ret;
unsigned short us;
unsigned char uc;
SQLEXREADFUNC func = _io_file_lexfeed_PLAIN;
if(file){
ret = sqstd_fread(&us,1,2,file);
if(ret != 2) {
//probably an empty file
us = 0;
}
if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE
sqstd_fseek(file,0,SQ_SEEK_SET);
if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) {
sqstd_fclose(file);
return SQ_OK;
}
}
else { //SCRIPT
switch(us)
{
//gotta swap the next 2 lines on BIG endian machines
case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian;
case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian;
case 0xBBEF:
if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) {
sqstd_fclose(file);
return sq_throwerror(v,_SC("io error"));
}
if(uc != 0xBF) {
sqstd_fclose(file);
return sq_throwerror(v,_SC("Unrecognozed ecoding"));
}
#ifdef SQUNICODE
func = _io_file_lexfeed_UTF8;
#else
func = _io_file_lexfeed_PLAIN;
#endif
break;//UTF-8 ;
default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii
}
if(SQ_SUCCEEDED(sq_compile(v,func,file,filename,printerror))){
sqstd_fclose(file);
return SQ_OK;
}
}
sqstd_fclose(file);
return SQ_ERROR;
}
return sq_throwerror(v,_SC("cannot open the file"));
}
SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror)
{
if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) {
sq_push(v,-2);
if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) {
sq_remove(v,retval?-2:-1); //removes the closure
return 1;
}
sq_pop(v,1); //removes the closure
}
return SQ_ERROR;
}
SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename)
{
SQFILE file = sqstd_fopen(filename,_SC("wb+"));
if(!file) return sq_throwerror(v,_SC("cannot open the file"));
if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) {
sqstd_fclose(file);
return SQ_OK;
}
sqstd_fclose(file);
return SQ_ERROR; //forward the error
}
SQInteger _g_io_loadfile(HSQUIRRELVM v)
{
const SQChar *filename;
SQBool printerror = SQFalse;
sq_getstring(v,2,&filename);
if(sq_gettop(v) >= 3) {
sq_getbool(v,3,&printerror);
}
if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror)))
return 1;
return SQ_ERROR; //propagates the error
}
SQInteger _g_io_writeclosuretofile(HSQUIRRELVM v)
{
const SQChar *filename;
sq_getstring(v,2,&filename);
if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,filename)))
return 1;
return SQ_ERROR; //propagates the error
}
SQInteger _g_io_dofile(HSQUIRRELVM v)
{
const SQChar *filename;
SQBool printerror = SQFalse;
sq_getstring(v,2,&filename);
if(sq_gettop(v) >= 3) {
sq_getbool(v,3,&printerror);
}
sq_push(v,1); //repush the this
if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror)))
return 1;
return SQ_ERROR; //propagates the error
}
#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck}
static SQRegFunction iolib_funcs[]={
_DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")),
_DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")),
_DECL_GLOBALIO_FUNC(writeclosuretofile,3,_SC(".sc")),
{0,0}
};
SQRESULT sqstd_register_iolib(HSQUIRRELVM v)
{
SQInteger top = sq_gettop(v);
//create delegate
declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs);
sq_pushstring(v,_SC("stdout"),-1);
sqstd_createfile(v,stdout,SQFalse);
sq_newslot(v,-3,SQFalse);
sq_pushstring(v,_SC("stdin"),-1);
sqstd_createfile(v,stdin,SQFalse);
sq_newslot(v,-3,SQFalse);
sq_pushstring(v,_SC("stderr"),-1);
sqstd_createfile(v,stderr,SQFalse);
sq_newslot(v,-3,SQFalse);
sq_settop(v,top);
return SQ_OK;
}

View File

@ -0,0 +1,131 @@
# 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.cpp
# 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

View File

@ -0,0 +1,107 @@
/* see copyright notice in squirrel.h */
#include <squirrel.h>
#include <math.h>
#include <stdlib.h>
#include <sqstdmath.h>
#define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \
SQFloat f; \
sq_getfloat(v,2,&f); \
sq_pushfloat(v,(SQFloat)_funcname(f)); \
return 1; \
}
#define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \
SQFloat p1,p2; \
sq_getfloat(v,2,&p1); \
sq_getfloat(v,3,&p2); \
sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \
return 1; \
}
static SQInteger math_srand(HSQUIRRELVM v)
{
SQInteger i;
if(SQ_FAILED(sq_getinteger(v,2,&i)))
return sq_throwerror(v,_SC("invalid param"));
srand((unsigned int)i);
return 0;
}
static SQInteger math_rand(HSQUIRRELVM v)
{
sq_pushinteger(v,rand());
return 1;
}
static SQInteger math_abs(HSQUIRRELVM v)
{
SQInteger n;
sq_getinteger(v,2,&n);
sq_pushinteger(v,(SQInteger)abs((int)n));
return 1;
}
SINGLE_ARG_FUNC(sqrt)
SINGLE_ARG_FUNC(fabs)
SINGLE_ARG_FUNC(sin)
SINGLE_ARG_FUNC(cos)
SINGLE_ARG_FUNC(asin)
SINGLE_ARG_FUNC(acos)
SINGLE_ARG_FUNC(log)
SINGLE_ARG_FUNC(log10)
SINGLE_ARG_FUNC(tan)
SINGLE_ARG_FUNC(atan)
TWO_ARGS_FUNC(atan2)
TWO_ARGS_FUNC(pow)
SINGLE_ARG_FUNC(floor)
SINGLE_ARG_FUNC(ceil)
SINGLE_ARG_FUNC(exp)
#define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck}
static SQRegFunction mathlib_funcs[] = {
_DECL_FUNC(sqrt,2,_SC(".n")),
_DECL_FUNC(sin,2,_SC(".n")),
_DECL_FUNC(cos,2,_SC(".n")),
_DECL_FUNC(asin,2,_SC(".n")),
_DECL_FUNC(acos,2,_SC(".n")),
_DECL_FUNC(log,2,_SC(".n")),
_DECL_FUNC(log10,2,_SC(".n")),
_DECL_FUNC(tan,2,_SC(".n")),
_DECL_FUNC(atan,2,_SC(".n")),
_DECL_FUNC(atan2,3,_SC(".nn")),
_DECL_FUNC(pow,3,_SC(".nn")),
_DECL_FUNC(floor,2,_SC(".n")),
_DECL_FUNC(ceil,2,_SC(".n")),
_DECL_FUNC(exp,2,_SC(".n")),
_DECL_FUNC(srand,2,_SC(".n")),
_DECL_FUNC(rand,1,NULL),
_DECL_FUNC(fabs,2,_SC(".n")),
_DECL_FUNC(abs,2,_SC(".n")),
{0,0},
};
#undef _DECL_FUNC
#ifndef M_PI
#define M_PI (3.14159265358979323846)
#endif
SQRESULT sqstd_register_mathlib(HSQUIRRELVM v)
{
SQInteger i=0;
while(mathlib_funcs[i].name!=0) {
sq_pushstring(v,mathlib_funcs[i].name,-1);
sq_newclosure(v,mathlib_funcs[i].f,0);
sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask);
sq_setnativeclosurename(v,-1,mathlib_funcs[i].name);
sq_newslot(v,-3,SQFalse);
i++;
}
sq_pushstring(v,_SC("RAND_MAX"),-1);
sq_pushinteger(v,RAND_MAX);
sq_newslot(v,-3,SQFalse);
sq_pushstring(v,_SC("PI"),-1);
sq_pushfloat(v,(SQFloat)M_PI);
sq_newslot(v,-3,SQFalse);
return SQ_OK;
}

View File

@ -0,0 +1,638 @@
/* see copyright notice in squirrel.h */
#include <squirrel.h>
#include <string.h>
#include <ctype.h>
#include <setjmp.h>
#include <sqstdstring.h>
#ifdef _UINCODE
#define scisprint iswprint
#else
#define scisprint isprint
#endif
#ifdef _DEBUG
#include <stdio.h>
static const SQChar *g_nnames[] =
{
_SC("NONE"),_SC("OP_GREEDY"), _SC("OP_OR"),
_SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"), _SC("OP_CLASS"),
_SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"),
_SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB")
};
#endif
#define OP_GREEDY (MAX_CHAR+1) // * + ? {n}
#define OP_OR (MAX_CHAR+2)
#define OP_EXPR (MAX_CHAR+3) //parentesis ()
#define OP_NOCAPEXPR (MAX_CHAR+4) //parentesis (?:)
#define OP_DOT (MAX_CHAR+5)
#define OP_CLASS (MAX_CHAR+6)
#define OP_CCLASS (MAX_CHAR+7)
#define OP_NCLASS (MAX_CHAR+8) //negates class the [^
#define OP_RANGE (MAX_CHAR+9)
#define OP_CHAR (MAX_CHAR+10)
#define OP_EOL (MAX_CHAR+11)
#define OP_BOL (MAX_CHAR+12)
#define OP_WB (MAX_CHAR+13)
#define SQREX_SYMBOL_ANY_CHAR ('.')
#define SQREX_SYMBOL_GREEDY_ONE_OR_MORE ('+')
#define SQREX_SYMBOL_GREEDY_ZERO_OR_MORE ('*')
#define SQREX_SYMBOL_GREEDY_ZERO_OR_ONE ('?')
#define SQREX_SYMBOL_BRANCH ('|')
#define SQREX_SYMBOL_END_OF_STRING ('$')
#define SQREX_SYMBOL_BEGINNING_OF_STRING ('^')
#define SQREX_SYMBOL_ESCAPE_CHAR ('\\')
typedef int SQRexNodeType;
typedef struct tagSQRexNode{
SQRexNodeType type;
SQInteger left;
SQInteger right;
SQInteger next;
}SQRexNode;
struct SQRex{
const SQChar *_eol;
const SQChar *_bol;
const SQChar *_p;
SQInteger _first;
SQInteger _op;
SQRexNode *_nodes;
SQInteger _nallocated;
SQInteger _nsize;
SQInteger _nsubexpr;
SQRexMatch *_matches;
SQInteger _currsubexp;
void *_jmpbuf;
const SQChar **_error;
};
static SQInteger sqstd_rex_list(SQRex *exp);
static SQInteger sqstd_rex_newnode(SQRex *exp, SQRexNodeType type)
{
SQRexNode n;
n.type = type;
n.next = n.right = n.left = -1;
if(type == OP_EXPR)
n.right = exp->_nsubexpr++;
if(exp->_nallocated < (exp->_nsize + 1)) {
SQInteger oldsize = exp->_nallocated;
exp->_nallocated *= 2;
exp->_nodes = (SQRexNode *)sq_realloc(exp->_nodes, oldsize * sizeof(SQRexNode) ,exp->_nallocated * sizeof(SQRexNode));
}
exp->_nodes[exp->_nsize++] = n;
SQInteger newid = exp->_nsize - 1;
return (SQInteger)newid;
}
static void sqstd_rex_error(SQRex *exp,const SQChar *error)
{
if(exp->_error) *exp->_error = error;
longjmp(*((jmp_buf*)exp->_jmpbuf),-1);
}
static void sqstd_rex_expect(SQRex *exp, SQInteger n){
if((*exp->_p) != n)
sqstd_rex_error(exp, _SC("expected paren"));
exp->_p++;
}
static SQChar sqstd_rex_escapechar(SQRex *exp)
{
if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR){
exp->_p++;
switch(*exp->_p) {
case 'v': exp->_p++; return '\v';
case 'n': exp->_p++; return '\n';
case 't': exp->_p++; return '\t';
case 'r': exp->_p++; return '\r';
case 'f': exp->_p++; return '\f';
default: return (*exp->_p++);
}
} else if(!scisprint(*exp->_p)) sqstd_rex_error(exp,_SC("letter expected"));
return (*exp->_p++);
}
static SQInteger sqstd_rex_charclass(SQRex *exp,SQInteger classid)
{
SQInteger n = sqstd_rex_newnode(exp,OP_CCLASS);
exp->_nodes[n].left = classid;
return n;
}
static SQInteger sqstd_rex_charnode(SQRex *exp,SQBool isclass)
{
SQChar t;
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':
{
t = *exp->_p; exp->_p++;
return sqstd_rex_charclass(exp,t);
}
case 'b':
case 'B':
if(!isclass) {
SQInteger node = sqstd_rex_newnode(exp,OP_WB);
exp->_nodes[node].left = *exp->_p;
exp->_p++;
return node;
} //else default
default:
t = *exp->_p; exp->_p++;
return sqstd_rex_newnode(exp,t);
}
}
else if(!scisprint(*exp->_p)) {
sqstd_rex_error(exp,_SC("letter expected"));
}
t = *exp->_p; exp->_p++;
return sqstd_rex_newnode(exp,t);
}
static SQInteger sqstd_rex_class(SQRex *exp)
{
SQInteger ret = -1;
SQInteger first = -1,chain;
if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING){
ret = sqstd_rex_newnode(exp,OP_NCLASS);
exp->_p++;
}else ret = sqstd_rex_newnode(exp,OP_CLASS);
if(*exp->_p == ']') sqstd_rex_error(exp,_SC("empty class"));
chain = ret;
while(*exp->_p != ']' && exp->_p != exp->_eol) {
if(*exp->_p == '-' && first != -1){
SQInteger r;
if(*exp->_p++ == ']') sqstd_rex_error(exp,_SC("unfinished range"));
r = sqstd_rex_newnode(exp,OP_RANGE);
if(exp->_nodes[first].type>*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;
SQInteger t = sqstd_rex_escapechar(exp);
exp->_nodes[r].right = t;
exp->_nodes[chain].next = r;
chain = r;
first = -1;
}
else{
if(first!=-1){
SQInteger c = first;
exp->_nodes[chain].next = c;
chain = c;
first = sqstd_rex_charnode(exp,SQTrue);
}
else{
first = sqstd_rex_charnode(exp,SQTrue);
}
}
}
if(first!=-1){
SQInteger c = first;
exp->_nodes[chain].next = c;
chain = c;
first = -1;
}
/* hack? */
exp->_nodes[ret].left = exp->_nodes[ret].next;
exp->_nodes[ret].next = -1;
return ret;
}
static SQInteger sqstd_rex_parsenumber(SQRex *exp)
{
SQInteger ret = *exp->_p-'0';
SQInteger positions = 10;
exp->_p++;
while(isdigit(*exp->_p)) {
ret = ret*10+(*exp->_p++-'0');
if(positions==1000000000) sqstd_rex_error(exp,_SC("overflow in numeric constant"));
positions *= 10;
};
return ret;
}
static SQInteger sqstd_rex_element(SQRex *exp)
{
SQInteger ret = -1;
switch(*exp->_p)
{
case '(': {
SQInteger expr;
exp->_p++;
if(*exp->_p =='?') {
exp->_p++;
sqstd_rex_expect(exp,':');
expr = sqstd_rex_newnode(exp,OP_NOCAPEXPR);
}
else
expr = sqstd_rex_newnode(exp,OP_EXPR);
SQInteger newn = sqstd_rex_list(exp);
exp->_nodes[expr].left = newn;
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;
}
SQInteger op;
SQBool isgreedy = SQFalse;
unsigned short p0 = 0, p1 = 0;
switch(*exp->_p){
case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break;
case SQREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break;
case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; isgreedy = SQTrue; break;
case '{':
exp->_p++;
if(!isdigit(*exp->_p)) sqstd_rex_error(exp,_SC("number expected"));
p0 = (unsigned short)sqstd_rex_parsenumber(exp);
/*******************************/
switch(*exp->_p) {
case '}':
p1 = p0; exp->_p++;
break;
case ',':
exp->_p++;
p1 = 0xFFFF;
if(isdigit(*exp->_p)){
p1 = (unsigned short)sqstd_rex_parsenumber(exp);
}
sqstd_rex_expect(exp,'}');
break;
default:
sqstd_rex_error(exp,_SC(", or } expected"));
}
/*******************************/
isgreedy = SQTrue;
break;
}
if(isgreedy) {
SQInteger nnode = sqstd_rex_newnode(exp,OP_GREEDY);
op = OP_GREEDY;
exp->_nodes[nnode].left = ret;
exp->_nodes[nnode].right = ((p0)<<16)|p1;
ret = nnode;
}
if((*exp->_p != SQREX_SYMBOL_BRANCH) && (*exp->_p != ')') && (*exp->_p != SQREX_SYMBOL_GREEDY_ZERO_OR_MORE) && (*exp->_p != SQREX_SYMBOL_GREEDY_ONE_OR_MORE) && (*exp->_p != '\0')) {
SQInteger nnode = sqstd_rex_element(exp);
exp->_nodes[ret].next = nnode;
}
return ret;
}
static SQInteger sqstd_rex_list(SQRex *exp)
{
SQInteger ret=-1,e;
if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING) {
exp->_p++;
ret = sqstd_rex_newnode(exp,OP_BOL);
}
e = sqstd_rex_element(exp);
if(ret != -1) {
exp->_nodes[ret].next = e;
}
else ret = e;
if(*exp->_p == SQREX_SYMBOL_BRANCH) {
SQInteger temp,tright;
exp->_p++;
temp = sqstd_rex_newnode(exp,OP_OR);
exp->_nodes[temp].left = ret;
tright = sqstd_rex_list(exp);
exp->_nodes[temp].right = tright;
ret = temp;
}
return ret;
}
static SQBool sqstd_rex_matchcclass(SQInteger cclass,SQChar c)
{
switch(cclass) {
case 'a': return isalpha(c)?SQTrue:SQFalse;
case 'A': return !isalpha(c)?SQTrue:SQFalse;
case 'w': return (isalnum(c) || c == '_')?SQTrue:SQFalse;
case 'W': return (!isalnum(c) && c != '_')?SQTrue:SQFalse;
case 's': return isspace(c)?SQTrue:SQFalse;
case 'S': return !isspace(c)?SQTrue:SQFalse;
case 'd': return isdigit(c)?SQTrue:SQFalse;
case 'D': return !isdigit(c)?SQTrue:SQFalse;
case 'x': return isxdigit(c)?SQTrue:SQFalse;
case 'X': return !isxdigit(c)?SQTrue:SQFalse;
case 'c': return iscntrl(c)?SQTrue:SQFalse;
case 'C': return !iscntrl(c)?SQTrue:SQFalse;
case 'p': return ispunct(c)?SQTrue:SQFalse;
case 'P': return !ispunct(c)?SQTrue:SQFalse;
case 'l': return islower(c)?SQTrue:SQFalse;
case 'u': return isupper(c)?SQTrue:SQFalse;
}
return SQFalse; /*cannot happen*/
}
static SQBool sqstd_rex_matchclass(SQRex* exp,SQRexNode *node,SQChar c)
{
do {
switch(node->type) {
case OP_RANGE:
if(c >= node->left && c <= node->right) return SQTrue;
break;
case OP_CCLASS:
if(sqstd_rex_matchcclass(node->left,c)) return SQTrue;
break;
default:
if(c == node->type)return SQTrue;
}
} while((node->next != -1) && (node = &exp->_nodes[node->next]));
return SQFalse;
}
static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar *str,SQRexNode *next)
{
SQRexNodeType type = node->type;
switch(type) {
case OP_GREEDY: {
//SQRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL;
SQRexNode *greedystop = NULL;
SQInteger p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0;
const SQChar *s=str, *good = str;
if(node->next != -1) {
greedystop = &exp->_nodes[node->next];
}
else {
greedystop = next;
}
while((nmaches == 0xFFFF || nmaches < p1)) {
const SQChar *stop;
if(!(s = sqstd_rex_matchnode(exp,&exp->_nodes[node->left],s,greedystop)))
break;
nmaches++;
good=s;
if(greedystop) {
//checks that 0 matches satisfy the expression(if so skips)
//if not would always stop(for instance if is a '?')
if(greedystop->type != OP_GREEDY ||
(greedystop->type == OP_GREEDY && ((greedystop->right >> 16)&0x0000FFFF) != 0))
{
SQRexNode *gnext = NULL;
if(greedystop->next != -1) {
gnext = &exp->_nodes[greedystop->next];
}else if(next && next->next != -1){
gnext = &exp->_nodes[next->next];
}
stop = sqstd_rex_matchnode(exp,greedystop,s,gnext);
if(stop) {
//if satisfied stop it
if(p0 == p1 && p0 == nmaches) break;
else if(nmaches >= p0 && p1 == 0xFFFF) break;
else if(nmaches >= p0 && nmaches <= p1) break;
}
}
}
if(s >= exp->_eol)
break;
}
if(p0 == p1 && p0 == nmaches) return good;
else if(nmaches >= p0 && p1 == 0xFFFF) return good;
else if(nmaches >= p0 && nmaches <= p1) return good;
return NULL;
}
case OP_OR: {
const SQChar *asd = str;
SQRexNode *temp=&exp->_nodes[node->left];
while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) {
if(temp->next != -1)
temp = &exp->_nodes[temp->next];
else
return asd;
}
asd = str;
temp = &exp->_nodes[node->right];
while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) {
if(temp->next != -1)
temp = &exp->_nodes[temp->next];
else
return asd;
}
return NULL;
break;
}
case OP_EXPR:
case OP_NOCAPEXPR:{
SQRexNode *n = &exp->_nodes[node->left];
const SQChar *cur = str;
SQInteger capture = -1;
if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) {
capture = exp->_currsubexp;
exp->_matches[capture].begin = cur;
exp->_currsubexp++;
}
int tempcap = exp->_currsubexp;
do {
SQRexNode *subnext = NULL;
if(n->next != -1) {
subnext = &exp->_nodes[n->next];
}else {
subnext = next;
}
if(!(cur = sqstd_rex_matchnode(exp,n,cur,subnext))) {
if(capture != -1){
exp->_matches[capture].begin = 0;
exp->_matches[capture].len = 0;
}
return NULL;
}
} while((n->next != -1) && (n = &exp->_nodes[n->next]));
exp->_currsubexp = tempcap;
if(capture != -1)
exp->_matches[capture].len = cur - exp->_matches[capture].begin;
return cur;
}
case OP_WB:
if((str == exp->_bol && !isspace(*str))
|| (str == exp->_eol && !isspace(*(str-1)))
|| (!isspace(*str) && isspace(*(str+1)))
|| (isspace(*str) && !isspace(*(str+1))) ) {
return (node->left == 'b')?str:NULL;
}
return (node->left == 'b')?NULL:str;
case OP_BOL:
if(str == exp->_bol) return str;
return NULL;
case OP_EOL:
if(str == exp->_eol) return str;
return NULL;
case OP_DOT:{
*str++;
}
return str;
case OP_NCLASS:
case OP_CLASS:
if(sqstd_rex_matchclass(exp,&exp->_nodes[node->left],*str)?(type == OP_CLASS?SQTrue:SQFalse):(type == OP_NCLASS?SQTrue:SQFalse)) {
*str++;
return str;
}
return NULL;
case OP_CCLASS:
if(sqstd_rex_matchcclass(node->left,*str)) {
*str++;
return str;
}
return NULL;
default: /* char */
if(*str != node->type) return NULL;
*str++;
return str;
}
return NULL;
}
/* public api */
SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error)
{
SQRex *exp = (SQRex *)sq_malloc(sizeof(SQRex));
exp->_eol = exp->_bol = NULL;
exp->_p = pattern;
exp->_nallocated = (SQInteger)scstrlen(pattern) * sizeof(SQChar);
exp->_nodes = (SQRexNode *)sq_malloc(exp->_nallocated * sizeof(SQRexNode));
exp->_nsize = 0;
exp->_matches = 0;
exp->_nsubexpr = 0;
exp->_first = sqstd_rex_newnode(exp,OP_EXPR);
exp->_error = error;
exp->_jmpbuf = sq_malloc(sizeof(jmp_buf));
if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) {
SQInteger res = sqstd_rex_list(exp);
exp->_nodes[exp->_first].left = res;
if(*exp->_p!='\0')
sqstd_rex_error(exp,_SC("unexpected character"));
#ifdef _DEBUG
{
SQInteger nsize,i;
SQRexNode *t;
nsize = exp->_nsize;
t = &exp->_nodes[0];
scprintf(_SC("\n"));
for(i = 0;i < nsize; i++) {
if(exp->_nodes[i].type>MAX_CHAR)
scprintf(_SC("[%02d] %10s "),i,g_nnames[exp->_nodes[i].type-MAX_CHAR]);
else
scprintf(_SC("[%02d] %10c "),i,exp->_nodes[i].type);
scprintf(_SC("left %02d right %02d next %02d\n"),exp->_nodes[i].left,exp->_nodes[i].right,exp->_nodes[i].next);
}
scprintf(_SC("\n"));
}
#endif
exp->_matches = (SQRexMatch *) sq_malloc(exp->_nsubexpr * sizeof(SQRexMatch));
memset(exp->_matches,0,exp->_nsubexpr * sizeof(SQRexMatch));
}
else{
sqstd_rex_free(exp);
return NULL;
}
return exp;
}
void sqstd_rex_free(SQRex *exp)
{
if(exp) {
if(exp->_nodes) sq_free(exp->_nodes,exp->_nallocated * sizeof(SQRexNode));
if(exp->_jmpbuf) sq_free(exp->_jmpbuf,sizeof(jmp_buf));
if(exp->_matches) sq_free(exp->_matches,exp->_nsubexpr * sizeof(SQRexMatch));
sq_free(exp,sizeof(SQRex));
}
}
SQBool sqstd_rex_match(SQRex* exp,const SQChar* text)
{
const SQChar* res = NULL;
exp->_bol = text;
exp->_eol = text + scstrlen(text);
exp->_currsubexp = 0;
res = sqstd_rex_matchnode(exp,exp->_nodes,text,NULL);
if(res == NULL || res != exp->_eol)
return SQFalse;
return SQTrue;
}
SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end)
{
const SQChar *cur = NULL;
SQInteger node = exp->_first;
if(text_begin >= text_end) return SQFalse;
exp->_bol = text_begin;
exp->_eol = text_end;
do {
cur = text_begin;
while(node != -1) {
exp->_currsubexp = 0;
cur = sqstd_rex_matchnode(exp,&exp->_nodes[node],cur,NULL);
if(!cur)
break;
node = exp->_nodes[node].next;
}
*text_begin++;
} while(cur == NULL && text_begin != text_end);
if(cur == NULL)
return SQFalse;
--text_begin;
if(out_begin) *out_begin = text_begin;
if(out_end) *out_end = cur;
return SQTrue;
}
SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end)
{
return sqstd_rex_searchrange(exp,text,text + scstrlen(text),out_begin,out_end);
}
SQInteger sqstd_rex_getsubexpcount(SQRex* exp)
{
return exp->_nsubexpr;
}
SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp)
{
if( n<0 || n >= exp->_nsubexpr) return SQFalse;
*subexp = exp->_matches[n];
return SQTrue;
}

View File

@ -0,0 +1,336 @@
/* see copyright notice in squirrel.h */
#include <new>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <squirrel.h>
#include <sqstdio.h>
#include <sqstdblob.h>
#include "sqstdstream.h"
#include "sqstdblobimpl.h"
#define SETUP_STREAM(v) \
SQStream *self = NULL; \
if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_STREAM_TYPE_TAG))) \
return sq_throwerror(v,_SC("invalid type tag")); \
if(!self->IsValid()) \
return sq_throwerror(v,_SC("the stream is invalid"));
SQInteger _stream_readblob(HSQUIRRELVM v)
{
SETUP_STREAM(v);
SQUserPointer data,blobp;
SQInteger size,res;
sq_getinteger(v,2,&size);
if(size > self->Len()) {
size = self->Len();
}
data = sq_getscratchpad(v,size);
res = self->Read(data,size);
if(res <= 0)
return sq_throwerror(v,_SC("no data left to read"));
blobp = sqstd_createblob(v,res);
memcpy(blobp,data,res);
return 1;
}
#define SAFE_READN(ptr,len) { \
if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \
}
SQInteger _stream_readn(HSQUIRRELVM v)
{
SETUP_STREAM(v);
SQInteger format;
sq_getinteger(v, 2, &format);
switch(format) {
case 'l': {
SQInteger i;
SAFE_READN(&i, sizeof(i));
sq_pushinteger(v, i);
}
break;
case 'i': {
SQInt32 i;
SAFE_READN(&i, sizeof(i));
sq_pushinteger(v, i);
}
break;
case 's': {
short s;
SAFE_READN(&s, sizeof(short));
sq_pushinteger(v, s);
}
break;
case 'w': {
unsigned short w;
SAFE_READN(&w, sizeof(unsigned short));
sq_pushinteger(v, w);
}
break;
case 'c': {
char c;
SAFE_READN(&c, sizeof(char));
sq_pushinteger(v, c);
}
break;
case 'b': {
unsigned char c;
SAFE_READN(&c, sizeof(unsigned char));
sq_pushinteger(v, c);
}
break;
case 'f': {
float f;
SAFE_READN(&f, sizeof(float));
sq_pushfloat(v, f);
}
break;
case 'd': {
double d;
SAFE_READN(&d, sizeof(double));
sq_pushfloat(v, (SQFloat)d);
}
break;
default:
return sq_throwerror(v, _SC("invalid format"));
}
return 1;
}
SQInteger _stream_writeblob(HSQUIRRELVM v)
{
SQUserPointer data;
SQInteger size;
SETUP_STREAM(v);
if(SQ_FAILED(sqstd_getblob(v,2,&data)))
return sq_throwerror(v,_SC("invalid parameter"));
size = sqstd_getblobsize(v,2);
if(self->Write(data,size) != size)
return sq_throwerror(v,_SC("io error"));
sq_pushinteger(v,size);
return 1;
}
SQInteger _stream_writen(HSQUIRRELVM v)
{
SETUP_STREAM(v);
SQInteger format, ti;
SQFloat tf;
sq_getinteger(v, 3, &format);
switch(format) {
case 'l': {
SQInteger i;
sq_getinteger(v, 2, &ti);
i = ti;
self->Write(&i, sizeof(SQInteger));
}
break;
case 'i': {
SQInt32 i;
sq_getinteger(v, 2, &ti);
i = (SQInt32)ti;
self->Write(&i, sizeof(SQInt32));
}
break;
case 's': {
short s;
sq_getinteger(v, 2, &ti);
s = (short)ti;
self->Write(&s, sizeof(short));
}
break;
case 'w': {
unsigned short w;
sq_getinteger(v, 2, &ti);
w = (unsigned short)ti;
self->Write(&w, sizeof(unsigned short));
}
break;
case 'c': {
char c;
sq_getinteger(v, 2, &ti);
c = (char)ti;
self->Write(&c, sizeof(char));
}
break;
case 'b': {
unsigned char b;
sq_getinteger(v, 2, &ti);
b = (unsigned char)ti;
self->Write(&b, sizeof(unsigned char));
}
break;
case 'f': {
float f;
sq_getfloat(v, 2, &tf);
f = (float)tf;
self->Write(&f, sizeof(float));
}
break;
case 'd': {
double d;
sq_getfloat(v, 2, &tf);
d = tf;
self->Write(&d, sizeof(double));
}
break;
default:
return sq_throwerror(v, _SC("invalid format"));
}
return 0;
}
SQInteger _stream_seek(HSQUIRRELVM v)
{
SETUP_STREAM(v);
SQInteger offset, origin = SQ_SEEK_SET;
sq_getinteger(v, 2, &offset);
if(sq_gettop(v) > 2) {
SQInteger t;
sq_getinteger(v, 3, &t);
switch(t) {
case 'b': origin = SQ_SEEK_SET; break;
case 'c': origin = SQ_SEEK_CUR; break;
case 'e': origin = SQ_SEEK_END; break;
default: return sq_throwerror(v,_SC("invalid origin"));
}
}
sq_pushinteger(v, self->Seek(offset, origin));
return 1;
}
SQInteger _stream_tell(HSQUIRRELVM v)
{
SETUP_STREAM(v);
sq_pushinteger(v, self->Tell());
return 1;
}
SQInteger _stream_len(HSQUIRRELVM v)
{
SETUP_STREAM(v);
sq_pushinteger(v, self->Len());
return 1;
}
SQInteger _stream_flush(HSQUIRRELVM v)
{
SETUP_STREAM(v);
if(!self->Flush())
sq_pushinteger(v, 1);
else
sq_pushnull(v);
return 1;
}
SQInteger _stream_eos(HSQUIRRELVM v)
{
SETUP_STREAM(v);
if(self->EOS())
sq_pushinteger(v, 1);
else
sq_pushnull(v);
return 1;
}
SQInteger _stream__cloned(HSQUIRRELVM v)
{
return sq_throwerror(v,_SC("this object cannot be cloned"));
}
static SQRegFunction _stream_methods[] = {
_DECL_STREAM_FUNC(readblob,2,_SC("xn")),
_DECL_STREAM_FUNC(readn,2,_SC("xn")),
_DECL_STREAM_FUNC(writeblob,-2,_SC("xx")),
_DECL_STREAM_FUNC(writen,3,_SC("xnn")),
_DECL_STREAM_FUNC(seek,-2,_SC("xnn")),
_DECL_STREAM_FUNC(tell,1,_SC("x")),
_DECL_STREAM_FUNC(len,1,_SC("x")),
_DECL_STREAM_FUNC(eos,1,_SC("x")),
_DECL_STREAM_FUNC(flush,1,_SC("x")),
_DECL_STREAM_FUNC(_cloned,0,NULL),
{0,0}
};
void init_streamclass(HSQUIRRELVM v)
{
sq_pushregistrytable(v);
sq_pushstring(v,_SC("std_stream"),-1);
if(SQ_FAILED(sq_get(v,-2))) {
sq_pushstring(v,_SC("std_stream"),-1);
sq_newclass(v,SQFalse);
sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG);
SQInteger i = 0;
while(_stream_methods[i].name != 0) {
SQRegFunction &f = _stream_methods[i];
sq_pushstring(v,f.name,-1);
sq_newclosure(v,f.f,0);
sq_setparamscheck(v,f.nparamscheck,f.typemask);
sq_newslot(v,-3,SQFalse);
i++;
}
sq_newslot(v,-3,SQFalse);
sq_pushroottable(v);
sq_pushstring(v,_SC("stream"),-1);
sq_pushstring(v,_SC("std_stream"),-1);
sq_get(v,-4);
sq_newslot(v,-3,SQFalse);
sq_pop(v,1);
}
else {
sq_pop(v,1); //result
}
sq_pop(v,1);
}
SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals)
{
if(sq_gettype(v,-1) != OT_TABLE)
return sq_throwerror(v,_SC("table expected"));
SQInteger top = sq_gettop(v);
//create delegate
init_streamclass(v);
sq_pushregistrytable(v);
sq_pushstring(v,reg_name,-1);
sq_pushstring(v,_SC("std_stream"),-1);
if(SQ_SUCCEEDED(sq_get(v,-3))) {
sq_newclass(v,SQTrue);
sq_settypetag(v,-1,typetag);
SQInteger i = 0;
while(methods[i].name != 0) {
SQRegFunction &f = methods[i];
sq_pushstring(v,f.name,-1);
sq_newclosure(v,f.f,0);
sq_setparamscheck(v,f.nparamscheck,f.typemask);
sq_setnativeclosurename(v,-1,f.name);
sq_newslot(v,-3,SQFalse);
i++;
}
sq_newslot(v,-3,SQFalse);
sq_pop(v,1);
i = 0;
while(globals[i].name!=0)
{
SQRegFunction &f = globals[i];
sq_pushstring(v,f.name,-1);
sq_newclosure(v,f.f,0);
sq_setparamscheck(v,f.nparamscheck,f.typemask);
sq_setnativeclosurename(v,-1,f.name);
sq_newslot(v,-3,SQFalse);
i++;
}
//register the class in the target table
sq_pushstring(v,name,-1);
sq_pushregistrytable(v);
sq_pushstring(v,reg_name,-1);
sq_get(v,-2);
sq_remove(v,-2);
sq_newslot(v,-3,SQFalse);
sq_settop(v,top);
return SQ_OK;
}
sq_settop(v,top);
return SQ_ERROR;
}

View File

@ -0,0 +1,18 @@
/* see copyright notice in squirrel.h */
#ifndef _SQSTD_STREAM_H_
#define _SQSTD_STREAM_H_
SQInteger _stream_readblob(HSQUIRRELVM v);
SQInteger _stream_readline(HSQUIRRELVM v);
SQInteger _stream_readn(HSQUIRRELVM v);
SQInteger _stream_writeblob(HSQUIRRELVM v);
SQInteger _stream_writen(HSQUIRRELVM v);
SQInteger _stream_seek(HSQUIRRELVM v);
SQInteger _stream_tell(HSQUIRRELVM v);
SQInteger _stream_len(HSQUIRRELVM v);
SQInteger _stream_eos(HSQUIRRELVM v);
SQInteger _stream_flush(HSQUIRRELVM v);
#define _DECL_STREAM_FUNC(name,nparams,typecheck) {_SC(#name),_stream_##name,nparams,typecheck}
SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals);
#endif /*_SQSTD_STREAM_H_*/

View File

@ -0,0 +1,378 @@
/* see copyright notice in squirrel.h */
#include <squirrel.h>
#include <sqstdstring.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
#ifdef SQUNICODE
#define scstrchr wcschr
#define scsnprintf wsnprintf
#define scatoi _wtoi
#define scstrtok wcstok
#else
#define scstrchr strchr
#define scsnprintf snprintf
#define scatoi atoi
#define scstrtok strtok
#endif
#define MAX_FORMAT_LEN 20
#define MAX_WFORMAT_LEN 3
#define ADDITIONAL_FORMAT_SPACE (100*sizeof(SQChar))
static SQInteger validate_format(HSQUIRRELVM v, SQChar *fmt, const SQChar *src, SQInteger n,SQInteger &width)
{
SQChar swidth[MAX_WFORMAT_LEN];
SQInteger wc = 0;
SQInteger start = n;
fmt[0] = '%';
while (scstrchr(_SC("-+ #0"), src[n])) n++;
while (scisdigit(src[n])) {
swidth[wc] = src[n];
n++;
wc++;
if(wc>=MAX_WFORMAT_LEN)
return sq_throwerror(v,_SC("width format too long"));
}
swidth[wc] = '\0';
if(wc > 0) {
width = scatoi(swidth);
}
else
width = 0;
if (src[n] == '.') {
n++;
wc = 0;
while (scisdigit(src[n])) {
swidth[wc] = src[n];
n++;
wc++;
if(wc>=MAX_WFORMAT_LEN)
return sq_throwerror(v,_SC("precision format too long"));
}
swidth[wc] = '\0';
if(wc > 0) {
width += scatoi(swidth);
}
}
if (n-start > MAX_FORMAT_LEN )
return sq_throwerror(v,_SC("format too long"));
memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(SQChar));
fmt[(n-start)+2] = '\0';
return n;
}
SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output)
{
const SQChar *format;
SQChar *dest;
SQChar fmt[MAX_FORMAT_LEN];
sq_getstring(v,nformatstringidx,&format);
SQInteger allocated = (sq_getsize(v,nformatstringidx)+2)*sizeof(SQChar);
dest = sq_getscratchpad(v,allocated);
SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0;
while(format[n] != '\0') {
if(format[n] != '%') {
assert(i < allocated);
dest[i++] = format[n];
n++;
}
else if(format[n+1] == '%') { //handles %%
dest[i++] = '%';
n += 2;
}
else {
n++;
if( nparam > sq_gettop(v) )
return sq_throwerror(v,_SC("not enough paramters for the given format string"));
n = validate_format(v,fmt,format,n,w);
if(n < 0) return -1;
SQInteger addlen = 0;
SQInteger valtype = 0;
const SQChar *ts;
SQInteger ti;
SQFloat tf;
switch(format[n]) {
case 's':
if(SQ_FAILED(sq_getstring(v,nparam,&ts)))
return sq_throwerror(v,_SC("string expected for the specified format"));
addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar));
valtype = 's';
break;
case 'i': case 'd': case 'o': case 'u': case 'x': case 'X':
#ifdef _SQ64
{
size_t flen = scstrlen(fmt);
SQInteger fpos = flen - 1;
SQChar f = fmt[fpos];
SQChar *prec = (SQChar *)_PRINT_INT_PREC;
while(*prec != _SC('\0')) {
fmt[fpos++] = *prec++;
}
fmt[fpos++] = f;
fmt[fpos++] = _SC('\0');
}
#endif
case 'c':
if(SQ_FAILED(sq_getinteger(v,nparam,&ti)))
return sq_throwerror(v,_SC("integer expected for the specified format"));
addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
valtype = 'i';
break;
case 'f': case 'g': case 'G': case 'e': case 'E':
if(SQ_FAILED(sq_getfloat(v,nparam,&tf)))
return sq_throwerror(v,_SC("float expected for the specified format"));
addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
valtype = 'f';
break;
default:
return sq_throwerror(v,_SC("invalid format"));
}
n++;
allocated += addlen + sizeof(SQChar);
dest = sq_getscratchpad(v,allocated);
switch(valtype) {
case 's': i += scsprintf(&dest[i],fmt,ts); break;
case 'i': i += scsprintf(&dest[i],fmt,ti); break;
case 'f': i += scsprintf(&dest[i],fmt,tf); break;
};
nparam ++;
}
}
*outlen = i;
dest[i] = '\0';
*output = dest;
return SQ_OK;
}
static SQInteger _string_format(HSQUIRRELVM v)
{
SQChar *dest = NULL;
SQInteger length = 0;
if(SQ_FAILED(sqstd_format(v,2,&length,&dest)))
return -1;
sq_pushstring(v,dest,length);
return 1;
}
static void __strip_l(const SQChar *str,const SQChar **start)
{
const SQChar *t = str;
while(((*t) != '\0') && scisspace(*t)){ t++; }
*start = t;
}
static void __strip_r(const SQChar *str,SQInteger len,const SQChar **end)
{
if(len == 0) {
*end = str;
return;
}
const SQChar *t = &str[len-1];
while(t != str && scisspace(*t)) { t--; }
*end = t+1;
}
static SQInteger _string_strip(HSQUIRRELVM v)
{
const SQChar *str,*start,*end;
sq_getstring(v,2,&str);
SQInteger len = sq_getsize(v,2);
__strip_l(str,&start);
__strip_r(str,len,&end);
sq_pushstring(v,start,end - start);
return 1;
}
static SQInteger _string_lstrip(HSQUIRRELVM v)
{
const SQChar *str,*start;
sq_getstring(v,2,&str);
__strip_l(str,&start);
sq_pushstring(v,start,-1);
return 1;
}
static SQInteger _string_rstrip(HSQUIRRELVM v)
{
const SQChar *str,*end;
sq_getstring(v,2,&str);
SQInteger len = sq_getsize(v,2);
__strip_r(str,len,&end);
sq_pushstring(v,str,end - str);
return 1;
}
static SQInteger _string_split(HSQUIRRELVM v)
{
const SQChar *str,*seps;
SQChar *stemp,*tok;
sq_getstring(v,2,&str);
sq_getstring(v,3,&seps);
if(sq_getsize(v,3) == 0) return sq_throwerror(v,_SC("empty separators string"));
SQInteger memsize = (sq_getsize(v,2)+1)*sizeof(SQChar);
stemp = sq_getscratchpad(v,memsize);
memcpy(stemp,str,memsize);
tok = scstrtok(stemp,seps);
sq_newarray(v,0);
while( tok != NULL ) {
sq_pushstring(v,tok,-1);
sq_arrayappend(v,-2);
tok = scstrtok( NULL, seps );
}
return 1;
}
#define SETUP_REX(v) \
SQRex *self = NULL; \
sq_getinstanceup(v,1,(SQUserPointer *)&self,0);
static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger size)
{
SQRex *self = ((SQRex *)p);
sqstd_rex_free(self);
return 1;
}
static SQInteger _regexp_match(HSQUIRRELVM v)
{
SETUP_REX(v);
const SQChar *str;
sq_getstring(v,2,&str);
if(sqstd_rex_match(self,str) == SQTrue)
{
sq_pushbool(v,SQTrue);
return 1;
}
sq_pushbool(v,SQFalse);
return 1;
}
static void _addrexmatch(HSQUIRRELVM v,const SQChar *str,const SQChar *begin,const SQChar *end)
{
sq_newtable(v);
sq_pushstring(v,_SC("begin"),-1);
sq_pushinteger(v,begin - str);
sq_rawset(v,-3);
sq_pushstring(v,_SC("end"),-1);
sq_pushinteger(v,end - str);
sq_rawset(v,-3);
}
static SQInteger _regexp_search(HSQUIRRELVM v)
{
SETUP_REX(v);
const SQChar *str,*begin,*end;
SQInteger start = 0;
sq_getstring(v,2,&str);
if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
_addrexmatch(v,str,begin,end);
return 1;
}
return 0;
}
static SQInteger _regexp_capture(HSQUIRRELVM v)
{
SETUP_REX(v);
const SQChar *str,*begin,*end;
SQInteger start = 0;
sq_getstring(v,2,&str);
if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
SQInteger n = sqstd_rex_getsubexpcount(self);
SQRexMatch match;
sq_newarray(v,0);
for(SQInteger i = 0;i < n; i++) {
sqstd_rex_getsubexp(self,i,&match);
if(match.len > 0)
_addrexmatch(v,str,match.begin,match.begin+match.len);
else
_addrexmatch(v,str,str,str); //empty match
sq_arrayappend(v,-2);
}
return 1;
}
return 0;
}
static SQInteger _regexp_subexpcount(HSQUIRRELVM v)
{
SETUP_REX(v);
sq_pushinteger(v,sqstd_rex_getsubexpcount(self));
return 1;
}
static SQInteger _regexp_constructor(HSQUIRRELVM v)
{
const SQChar *error,*pattern;
sq_getstring(v,2,&pattern);
SQRex *rex = sqstd_rex_compile(pattern,&error);
if(!rex) return sq_throwerror(v,error);
sq_setinstanceup(v,1,rex);
sq_setreleasehook(v,1,_rexobj_releasehook);
return 0;
}
static SQInteger _regexp__typeof(HSQUIRRELVM v)
{
sq_pushstring(v,_SC("regexp"),-1);
return 1;
}
#define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask}
static SQRegFunction rexobj_funcs[]={
_DECL_REX_FUNC(constructor,2,_SC(".s")),
_DECL_REX_FUNC(search,-2,_SC("xsn")),
_DECL_REX_FUNC(match,2,_SC("xs")),
_DECL_REX_FUNC(capture,-2,_SC("xsn")),
_DECL_REX_FUNC(subexpcount,1,_SC("x")),
_DECL_REX_FUNC(_typeof,1,_SC("x")),
{0,0}
};
#undef _DECL_REX_FUNC
#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask}
static SQRegFunction stringlib_funcs[]={
_DECL_FUNC(format,-2,_SC(".s")),
_DECL_FUNC(strip,2,_SC(".s")),
_DECL_FUNC(lstrip,2,_SC(".s")),
_DECL_FUNC(rstrip,2,_SC(".s")),
_DECL_FUNC(split,3,_SC(".ss")),
{0,0}
};
#undef _DECL_FUNC
SQInteger sqstd_register_stringlib(HSQUIRRELVM v)
{
sq_pushstring(v,_SC("regexp"),-1);
sq_newclass(v,SQFalse);
SQInteger i = 0;
while(rexobj_funcs[i].name != 0) {
SQRegFunction &f = rexobj_funcs[i];
sq_pushstring(v,f.name,-1);
sq_newclosure(v,f.f,0);
sq_setparamscheck(v,f.nparamscheck,f.typemask);
sq_setnativeclosurename(v,-1,f.name);
sq_newslot(v,-3,SQFalse);
i++;
}
sq_newslot(v,-3,SQFalse);
i = 0;
while(stringlib_funcs[i].name!=0)
{
sq_pushstring(v,stringlib_funcs[i].name,-1);
sq_newclosure(v,stringlib_funcs[i].f,0);
sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask);
sq_setnativeclosurename(v,-1,stringlib_funcs[i].name);
sq_newslot(v,-3,SQFalse);
i++;
}
return 1;
}

View File

@ -0,0 +1,147 @@
/* see copyright notice in squirrel.h */
#include <squirrel.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <sqstdsystem.h>
#ifdef SQUNICODE
#include <wchar.h>
#define scgetenv _wgetenv
#define scsystem _wsystem
#define scasctime _wasctime
#define scremove _wremove
#define screname _wrename
#else
#define scgetenv getenv
#define scsystem system
#define scasctime asctime
#define scremove remove
#define screname rename
#endif
static SQInteger _system_getenv(HSQUIRRELVM v)
{
const SQChar *s;
if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
sq_pushstring(v,scgetenv(s),-1);
return 1;
}
return 0;
}
static SQInteger _system_system(HSQUIRRELVM v)
{
const SQChar *s;
if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
sq_pushinteger(v,scsystem(s));
return 1;
}
return sq_throwerror(v,_SC("wrong param"));
}
static SQInteger _system_clock(HSQUIRRELVM v)
{
sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC);
return 1;
}
static SQInteger _system_time(HSQUIRRELVM v)
{
time_t t;
time(&t);
sq_pushinteger(v,*((SQInteger *)&t));
return 1;
}
static SQInteger _system_remove(HSQUIRRELVM v)
{
const SQChar *s;
sq_getstring(v,2,&s);
if(scremove(s)==-1)
return sq_throwerror(v,_SC("remove() failed"));
return 0;
}
static SQInteger _system_rename(HSQUIRRELVM v)
{
const SQChar *oldn,*newn;
sq_getstring(v,2,&oldn);
sq_getstring(v,3,&newn);
if(screname(oldn,newn)==-1)
return sq_throwerror(v,_SC("rename() failed"));
return 0;
}
static void _set_integer_slot(HSQUIRRELVM v,const SQChar *name,SQInteger val)
{
sq_pushstring(v,name,-1);
sq_pushinteger(v,val);
sq_rawset(v,-3);
}
static SQInteger _system_date(HSQUIRRELVM v)
{
time_t t;
SQInteger it;
SQInteger format = 'l';
if(sq_gettop(v) > 1) {
sq_getinteger(v,2,&it);
t = it;
if(sq_gettop(v) > 2) {
sq_getinteger(v,3,(SQInteger*)&format);
}
}
else {
time(&t);
}
tm *date;
if(format == 'u')
date = gmtime(&t);
else
date = localtime(&t);
if(!date)
return sq_throwerror(v,_SC("crt api failure"));
sq_newtable(v);
_set_integer_slot(v, _SC("sec"), date->tm_sec);
_set_integer_slot(v, _SC("min"), date->tm_min);
_set_integer_slot(v, _SC("hour"), date->tm_hour);
_set_integer_slot(v, _SC("day"), date->tm_mday);
_set_integer_slot(v, _SC("month"), date->tm_mon);
_set_integer_slot(v, _SC("year"), date->tm_year+1900);
_set_integer_slot(v, _SC("wday"), date->tm_wday);
_set_integer_slot(v, _SC("yday"), date->tm_yday);
return 1;
}
#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask}
static SQRegFunction systemlib_funcs[]={
_DECL_FUNC(getenv,2,_SC(".s")),
_DECL_FUNC(system,2,_SC(".s")),
_DECL_FUNC(clock,0,NULL),
_DECL_FUNC(time,1,NULL),
_DECL_FUNC(date,-1,_SC(".nn")),
_DECL_FUNC(remove,2,_SC(".s")),
_DECL_FUNC(rename,3,_SC(".ss")),
{0,0}
};
#undef _DECL_FUNC
SQInteger sqstd_register_systemlib(HSQUIRRELVM v)
{
SQInteger i=0;
while(systemlib_funcs[i].name!=0)
{
sq_pushstring(v,systemlib_funcs[i].name,-1);
sq_newclosure(v,systemlib_funcs[i].f,0);
sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask);
sq_setnativeclosurename(v,-1,systemlib_funcs[i].name);
sq_newslot(v,-3,SQFalse);
i++;
}
return 1;
}

View File

@ -0,0 +1,77 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "sq"=.\sq\sq.dsp - Package Owner=<4>
Package=<5>
{{{
begin source code control
.
end source code control
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name sqlibs
End Project Dependency
Begin Project Dependency
Project_Dep_Name squirrel
End Project Dependency
Begin Project Dependency
Project_Dep_Name sqstdlib
End Project Dependency
}}}
###############################################################################
Project: "sqstdlib"=.\sqstdlib\sqstdlib.dsp - Package Owner=<4>
Package=<5>
{{{
begin source code control
"$/squirrel", HAAAAAAA
.
end source code control
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "squirrel"=.\squirrel\squirrel.dsp - Package Owner=<4>
Package=<5>
{{{
begin source code control
"$/squirrel", HAAAAAAA
.
end source code control
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
begin source code control
"$/squirrel", HAAAAAAA
.
end source code control
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@ -0,0 +1,52 @@
SQUIRREL= ..
OUT= $(SQUIRREL)/lib/libsquirrel.a
INCZ= -I$(SQUIRREL)/include -I. -Iinclude
DEFS=
LIB=
OBJS= \
sqapi.o \
sqbaselib.o \
sqfuncstate.o \
sqdebug.o \
sqlexer.o \
sqobject.o \
sqcompiler.o \
sqstate.o \
sqtable.o \
sqmem.o \
sqvm.o \
sqclass.o
SRCS= \
sqapi.cpp \
sqbaselib.cpp \
sqfuncstate.cpp \
sqdebug.cpp \
sqlexer.cpp \
sqobject.cpp \
sqcompiler.cpp \
sqstate.cpp \
sqtable.cpp \
sqmem.cpp \
sqvm.cpp \
sqclass.cpp
sq32:
gcc -O2 -fno-exceptions -fno-rtti -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS)
ar rc $(OUT) *.o
rm *.o
sqprof:
gcc -O2 -pg -fno-exceptions -fno-rtti -pie -gstabs -g3 -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS)
ar rc $(OUT) *.o
rm *.o
sq64:
gcc -O2 -m64 -D_SQ64 -fno-exceptions -fno-rtti -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS)
ar rc $(OUT) *.o
rm *.o

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,94 @@
/* see copyright notice in squirrel.h */
#ifndef _SQARRAY_H_
#define _SQARRAY_H_
struct SQArray : public CHAINABLE_OBJ
{
private:
SQArray(SQSharedState *ss,SQInteger nsize){_values.resize(nsize); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
~SQArray()
{
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
}
public:
static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){
SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray));
new (newarray) SQArray(ss,nInitialSize);
return newarray;
}
#ifndef NO_GARBAGE_COLLECTOR
void Mark(SQCollectable **chain);
SQObjectType GetType() {return OT_ARRAY;}
#endif
void Finalize(){
_values.resize(0);
}
bool Get(const SQInteger nidx,SQObjectPtr &val)
{
if(nidx>=0 && nidx<(SQInteger)_values.size()){
SQObjectPtr &o = _values[nidx];
val = _realval(o);
return true;
}
else return false;
}
bool Set(const SQInteger nidx,const SQObjectPtr &val)
{
if(nidx>=0 && nidx<(SQInteger)_values.size()){
_values[nidx]=val;
return true;
}
else return false;
}
SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval)
{
SQUnsignedInteger idx=TranslateIndex(refpos);
while(idx<_values.size()){
//first found
outkey=(SQInteger)idx;
SQObjectPtr &o = _values[idx];
outval = _realval(o);
//return idx for the next iteration
return ++idx;
}
//nothing to iterate anymore
return -1;
}
SQArray *Clone(){SQArray *anew=Create(_opt_ss(this),0); anew->_values.copy(_values); return anew; }
SQInteger Size() const {return _values.size();}
void Resize(SQInteger size)
{
SQObjectPtr _null;
Resize(size,_null);
}
void Resize(SQInteger size,SQObjectPtr &fill) { _values.resize(size,fill); ShrinkIfNeeded(); }
void Reserve(SQInteger size) { _values.reserve(size); }
void Append(const SQObject &o){_values.push_back(o);}
void Extend(const SQArray *a);
SQObjectPtr &Top(){return _values.top();}
void Pop(){_values.pop_back(); ShrinkIfNeeded(); }
bool Insert(SQInteger idx,const SQObject &val){
if(idx < 0 || idx > (SQInteger)_values.size())
return false;
_values.insert(idx,val);
return true;
}
void ShrinkIfNeeded() {
if(_values.size() <= _values.capacity()>>2) //shrink the array
_values.shrinktofit();
}
bool Remove(SQInteger idx){
if(idx < 0 || idx >= (SQInteger)_values.size())
return false;
_values.remove(idx);
ShrinkIfNeeded();
return true;
}
void Release()
{
sq_delete(this,SQArray);
}
SQObjectPtrVec _values;
};
#endif //_SQARRAY_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,213 @@
/*
see copyright notice in squirrel.h
*/
#include "sqpcheader.h"
#include "sqvm.h"
#include "sqtable.h"
#include "sqclass.h"
#include "sqfuncproto.h"
#include "sqclosure.h"
SQClass::SQClass(SQSharedState *ss,SQClass *base)
{
_base = base;
_typetag = 0;
_hook = NULL;
_udsize = 0;
_locked = false;
_constructoridx = -1;
if(_base) {
_constructoridx = _base->_constructoridx;
_udsize = _base->_udsize;
_defaultvalues.copy(base->_defaultvalues);
_methods.copy(base->_methods);
_COPY_VECTOR(_metamethods,base->_metamethods,MT_LAST);
__ObjAddRef(_base);
}
_members = base?base->_members->Clone() : SQTable::Create(ss,0);
__ObjAddRef(_members);
INIT_CHAIN();
ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
}
void SQClass::Finalize() {
_attributes.Null();
_defaultvalues.resize(0);
_methods.resize(0);
_NULL_SQOBJECT_VECTOR(_metamethods,MT_LAST);
__ObjRelease(_members);
if(_base) {
__ObjRelease(_base);
}
}
SQClass::~SQClass()
{
REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
Finalize();
}
bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic)
{
SQObjectPtr temp;
bool belongs_to_static_table = type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE || bstatic;
if(_locked && !belongs_to_static_table)
return false; //the class already has an instance so cannot be modified
if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value
{
_defaultvalues[_member_idx(temp)].val = val;
return true;
}
if(belongs_to_static_table) {
SQInteger mmidx;
if((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) &&
(mmidx = ss->GetMetaMethodIdxByName(key)) != -1) {
_metamethods[mmidx] = val;
}
else {
SQObjectPtr theval = val;
if(_base && type(val) == OT_CLOSURE) {
theval = _closure(val)->Clone();
_closure(theval)->_base = _base;
__ObjAddRef(_base); //ref for the closure
}
if(type(temp) == OT_NULL) {
bool isconstructor;
SQVM::IsEqual(ss->_constructoridx, key, isconstructor);
if(isconstructor) {
_constructoridx = (SQInteger)_methods.size();
}
SQClassMember m;
m.val = theval;
_members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size())));
_methods.push_back(m);
}
else {
_methods[_member_idx(temp)].val = theval;
}
}
return true;
}
SQClassMember m;
m.val = val;
_members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size())));
_defaultvalues.push_back(m);
return true;
}
SQInstance *SQClass::CreateInstance()
{
if(!_locked) Lock();
return SQInstance::Create(_opt_ss(this),this);
}
SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
{
SQObjectPtr oval;
SQInteger idx = _members->Next(false,refpos,outkey,oval);
if(idx != -1) {
if(_ismethod(oval)) {
outval = _methods[_member_idx(oval)].val;
}
else {
SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val;
outval = _realval(o);
}
}
return idx;
}
bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val)
{
SQObjectPtr idx;
if(_members->Get(key,idx)) {
if(_isfield(idx))
_defaultvalues[_member_idx(idx)].attrs = val;
else
_methods[_member_idx(idx)].attrs = val;
return true;
}
return false;
}
bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval)
{
SQObjectPtr idx;
if(_members->Get(key,idx)) {
outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs);
return true;
}
return false;
}
///////////////////////////////////////////////////////////////////////
void SQInstance::Init(SQSharedState *ss)
{
_userpointer = NULL;
_hook = NULL;
__ObjAddRef(_class);
_delegate = _class->_members;
INIT_CHAIN();
ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
}
SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize)
{
_memsize = memsize;
_class = c;
SQUnsignedInteger nvalues = _class->_defaultvalues.size();
for(SQUnsignedInteger n = 0; n < nvalues; n++) {
new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val);
}
Init(ss);
}
SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize)
{
_memsize = memsize;
_class = i->_class;
SQUnsignedInteger nvalues = _class->_defaultvalues.size();
for(SQUnsignedInteger n = 0; n < nvalues; n++) {
new (&_values[n]) SQObjectPtr(i->_values[n]);
}
Init(ss);
}
void SQInstance::Finalize()
{
SQUnsignedInteger nvalues = _class->_defaultvalues.size();
__ObjRelease(_class);
_NULL_SQOBJECT_VECTOR(_values,nvalues);
//for(SQUnsignedInteger i = 0; i < nvalues; i++) {
// _values[i].Null();
// }
}
SQInstance::~SQInstance()
{
REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
if(_class){ Finalize(); } //if _class is null it was already finalized by the GC
}
bool SQInstance::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res)
{
if(type(_class->_metamethods[mm]) != OT_NULL) {
res = _class->_metamethods[mm];
return true;
}
return false;
}
bool SQInstance::InstanceOf(SQClass *trg)
{
SQClass *parent = _class;
while(parent != NULL) {
if(parent == trg)
return true;
parent = parent->_base;
}
return false;
}

View File

@ -0,0 +1,158 @@
/* see copyright notice in squirrel.h */
#ifndef _SQCLASS_H_
#define _SQCLASS_H_
struct SQInstance;
struct SQClassMember {
SQObjectPtr val;
SQObjectPtr attrs;
};
typedef sqvector<SQClassMember> SQClassMemberVec;
#define MEMBER_TYPE_METHOD 0x01000000
#define MEMBER_TYPE_FIELD 0x02000000
#define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD)
#define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD)
#define _make_method_idx(i) ((SQInteger)(MEMBER_TYPE_METHOD|i))
#define _make_field_idx(i) ((SQInteger)(MEMBER_TYPE_FIELD|i))
#define _member_type(o) (_integer(o)&0xFF000000)
#define _member_idx(o) (_integer(o)&0x00FFFFFF)
struct SQClass : public CHAINABLE_OBJ
{
SQClass(SQSharedState *ss,SQClass *base);
public:
static SQClass* Create(SQSharedState *ss,SQClass *base) {
SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass));
new (newclass) SQClass(ss, base);
return newclass;
}
~SQClass();
bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic);
bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
if(_members->Get(key,val)) {
if(_isfield(val)) {
SQObjectPtr &o = _defaultvalues[_member_idx(val)].val;
val = _realval(o);
}
else {
val = _methods[_member_idx(val)].val;
}
return true;
}
return false;
}
bool GetConstructor(SQObjectPtr &ctor)
{
if(_constructoridx != -1) {
ctor = _methods[_constructoridx].val;
return true;
}
return false;
}
bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val);
bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval);
void Lock() { _locked = true; if(_base) _base->Lock(); }
void Release() {
if (_hook) { _hook(_typetag,0);}
sq_delete(this, SQClass);
}
void Finalize();
#ifndef NO_GARBAGE_COLLECTOR
void Mark(SQCollectable ** );
SQObjectType GetType() {return OT_CLASS;}
#endif
SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
SQInstance *CreateInstance();
SQTable *_members;
SQClass *_base;
SQClassMemberVec _defaultvalues;
SQClassMemberVec _methods;
SQObjectPtr _metamethods[MT_LAST];
SQObjectPtr _attributes;
SQUserPointer _typetag;
SQRELEASEHOOK _hook;
bool _locked;
SQInteger _constructoridx;
SQInteger _udsize;
};
#define calcinstancesize(_theclass_) \
(_theclass_->_udsize + sq_aligning(sizeof(SQInstance) + (sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0))))
struct SQInstance : public SQDelegable
{
void Init(SQSharedState *ss);
SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize);
SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize);
public:
static SQInstance* Create(SQSharedState *ss,SQClass *theclass) {
SQInteger size = calcinstancesize(theclass);
SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
new (newinst) SQInstance(ss, theclass,size);
if(theclass->_udsize) {
newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize);
}
return newinst;
}
SQInstance *Clone(SQSharedState *ss)
{
SQInteger size = calcinstancesize(_class);
SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
new (newinst) SQInstance(ss, this,size);
if(_class->_udsize) {
newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize);
}
return newinst;
}
~SQInstance();
bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
if(_class->_members->Get(key,val)) {
if(_isfield(val)) {
SQObjectPtr &o = _values[_member_idx(val)];
val = _realval(o);
}
else {
val = _class->_methods[_member_idx(val)].val;
}
return true;
}
return false;
}
bool Set(const SQObjectPtr &key,const SQObjectPtr &val) {
SQObjectPtr idx;
if(_class->_members->Get(key,idx) && _isfield(idx)) {
_values[_member_idx(idx)] = val;
return true;
}
return false;
}
void Release() {
_uiRef++;
if (_hook) { _hook(_userpointer,0);}
_uiRef--;
if(_uiRef > 0) return;
SQInteger size = _memsize;
this->~SQInstance();
SQ_FREE(this, size);
}
void Finalize();
#ifndef NO_GARBAGE_COLLECTOR
void Mark(SQCollectable ** );
SQObjectType GetType() {return OT_INSTANCE;}
#endif
bool InstanceOf(SQClass *trg);
bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
SQClass *_class;
SQUserPointer _userpointer;
SQRELEASEHOOK _hook;
SQInteger _memsize;
SQObjectPtr _values[1];
};
#endif //_SQCLASS_H_

View File

@ -0,0 +1,193 @@
/* see copyright notice in squirrel.h */
#ifndef _SQCLOSURE_H_
#define _SQCLOSURE_H_
#define _CALC_CLOSURE_SIZE(func) (sizeof(SQClosure) + (func->_noutervalues*sizeof(SQObjectPtr)) + (func->_ndefaultparams*sizeof(SQObjectPtr)))
struct SQFunctionProto;
struct SQClass;
struct SQClosure : public CHAINABLE_OBJ
{
private:
SQClosure(SQSharedState *ss,SQFunctionProto *func){_function = func; __ObjAddRef(_function); _base = NULL; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;}
public:
static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func){
SQInteger size = _CALC_CLOSURE_SIZE(func);
SQClosure *nc=(SQClosure*)SQ_MALLOC(size);
new (nc) SQClosure(ss,func);
nc->_outervalues = (SQObjectPtr *)(nc + 1);
nc->_defaultparams = &nc->_outervalues[func->_noutervalues];
_CONSTRUCT_VECTOR(SQObjectPtr,func->_noutervalues,nc->_outervalues);
_CONSTRUCT_VECTOR(SQObjectPtr,func->_ndefaultparams,nc->_defaultparams);
return nc;
}
void Release(){
SQFunctionProto *f = _function;
SQInteger size = _CALC_CLOSURE_SIZE(f);
_DESTRUCT_VECTOR(SQObjectPtr,f->_noutervalues,_outervalues);
_DESTRUCT_VECTOR(SQObjectPtr,f->_ndefaultparams,_defaultparams);
__ObjRelease(_function);
this->~SQClosure();
sq_vm_free(this,size);
}
SQClosure *Clone()
{
SQFunctionProto *f = _function;
SQClosure * ret = SQClosure::Create(_opt_ss(this),f);
ret->_env = _env;
if(ret->_env) __ObjAddRef(ret->_env);
_COPY_VECTOR(ret->_outervalues,_outervalues,f->_noutervalues);
_COPY_VECTOR(ret->_defaultparams,_defaultparams,f->_ndefaultparams);
return ret;
}
~SQClosure();
bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
#ifndef NO_GARBAGE_COLLECTOR
void Mark(SQCollectable **chain);
void Finalize(){
SQFunctionProto *f = _function;
_NULL_SQOBJECT_VECTOR(_outervalues,f->_noutervalues);
_NULL_SQOBJECT_VECTOR(_defaultparams,f->_ndefaultparams);
}
SQObjectType GetType() {return OT_CLOSURE;}
#endif
SQWeakRef *_env;
SQClass *_base;
SQFunctionProto *_function;
SQObjectPtr *_outervalues;
SQObjectPtr *_defaultparams;
};
//////////////////////////////////////////////
struct SQOuter : public CHAINABLE_OBJ
{
private:
SQOuter(SQSharedState *ss, SQObjectPtr *outer){_valptr = outer; _next = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); }
public:
static SQOuter *Create(SQSharedState *ss, SQObjectPtr *outer)
{
SQOuter *nc = (SQOuter*)SQ_MALLOC(sizeof(SQOuter));
new (nc) SQOuter(ss, outer);
return nc;
}
~SQOuter() { REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); }
void Release()
{
this->~SQOuter();
sq_vm_free(this,sizeof(SQOuter));
}
#ifndef NO_GARBAGE_COLLECTOR
void Mark(SQCollectable **chain);
void Finalize() { _value.Null(); }
SQObjectType GetType() {return OT_OUTER;}
#endif
SQObjectPtr *_valptr; /* pointer to value on stack, or _value below */
SQInteger _idx; /* idx in stack array, for relocation */
SQObjectPtr _value; /* value of outer after stack frame is closed */
SQOuter *_next; /* pointer to next outer when frame is open */
};
//////////////////////////////////////////////
struct SQGenerator : public CHAINABLE_OBJ
{
enum SQGeneratorState{eRunning,eSuspended,eDead};
private:
SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=NULL;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
public:
static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){
SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));
new (nc) SQGenerator(ss,closure);
return nc;
}
~SQGenerator()
{
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
}
void Kill(){
_state=eDead;
_stack.resize(0);
_closure.Null();}
void Release(){
sq_delete(this,SQGenerator);
}
bool Yield(SQVM *v,SQInteger target);
bool Resume(SQVM *v,SQObjectPtr &dest);
#ifndef NO_GARBAGE_COLLECTOR
void Mark(SQCollectable **chain);
void Finalize(){_stack.resize(0);_closure.Null();}
SQObjectType GetType() {return OT_GENERATOR;}
#endif
SQObjectPtr _closure;
SQObjectPtrVec _stack;
SQVM::CallInfo _ci;
ExceptionsTraps _etraps;
SQGeneratorState _state;
};
#define _CALC_NATVIVECLOSURE_SIZE(noutervalues) (sizeof(SQNativeClosure) + (noutervalues*sizeof(SQObjectPtr)))
struct SQNativeClosure : public CHAINABLE_OBJ
{
private:
SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); _env = NULL;}
public:
static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func,SQInteger nouters)
{
SQInteger size = _CALC_NATVIVECLOSURE_SIZE(nouters);
SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(size);
new (nc) SQNativeClosure(ss,func);
nc->_outervalues = (SQObjectPtr *)(nc + 1);
nc->_noutervalues = nouters;
_CONSTRUCT_VECTOR(SQObjectPtr,nc->_noutervalues,nc->_outervalues);
return nc;
}
SQNativeClosure *Clone()
{
SQNativeClosure * ret = SQNativeClosure::Create(_opt_ss(this),_function,_noutervalues);
ret->_env = _env;
if(ret->_env) __ObjAddRef(ret->_env);
ret->_name = _name;
_COPY_VECTOR(ret->_outervalues,_outervalues,_noutervalues);
ret->_typecheck.copy(_typecheck);
ret->_nparamscheck = _nparamscheck;
return ret;
}
~SQNativeClosure()
{
__ObjRelease(_env);
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
}
void Release(){
SQInteger size = _CALC_NATVIVECLOSURE_SIZE(_noutervalues);
_DESTRUCT_VECTOR(SQObjectPtr,_noutervalues,_outervalues);
this->~SQNativeClosure();
sq_free(this,size);
}
#ifndef NO_GARBAGE_COLLECTOR
void Mark(SQCollectable **chain);
void Finalize() { _NULL_SQOBJECT_VECTOR(_outervalues,_noutervalues); }
SQObjectType GetType() {return OT_NATIVECLOSURE;}
#endif
SQInteger _nparamscheck;
SQIntVec _typecheck;
SQObjectPtr *_outervalues;
SQUnsignedInteger _noutervalues;
SQWeakRef *_env;
SQFUNCTION _function;
SQObjectPtr _name;
};
#endif //_SQCLOSURE_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,77 @@
/* see copyright notice in squirrel.h */
#ifndef _SQCOMPILER_H_
#define _SQCOMPILER_H_
struct SQVM;
#define TK_IDENTIFIER 258
#define TK_STRING_LITERAL 259
#define TK_INTEGER 260
#define TK_FLOAT 261
#define TK_BASE 262
#define TK_DELETE 263
#define TK_EQ 264
#define TK_NE 265
#define TK_LE 266
#define TK_GE 267
#define TK_SWITCH 268
#define TK_ARROW 269
#define TK_AND 270
#define TK_OR 271
#define TK_IF 272
#define TK_ELSE 273
#define TK_WHILE 274
#define TK_BREAK 275
#define TK_FOR 276
#define TK_DO 277
#define TK_NULL 278
#define TK_FOREACH 279
#define TK_IN 280
#define TK_NEWSLOT 281
#define TK_MODULO 282
#define TK_LOCAL 283
#define TK_CLONE 284
#define TK_FUNCTION 285
#define TK_RETURN 286
#define TK_TYPEOF 287
#define TK_UMINUS 288
#define TK_PLUSEQ 289
#define TK_MINUSEQ 290
#define TK_CONTINUE 291
#define TK_YIELD 292
#define TK_TRY 293
#define TK_CATCH 294
#define TK_THROW 295
#define TK_SHIFTL 296
#define TK_SHIFTR 297
#define TK_RESUME 298
#define TK_DOUBLE_COLON 299
#define TK_CASE 300
#define TK_DEFAULT 301
#define TK_THIS 302
#define TK_PLUSPLUS 303
#define TK_MINUSMINUS 304
#define TK_3WAYSCMP 305
#define TK_USHIFTR 306
#define TK_CLASS 307
#define TK_EXTENDS 308
#define TK_CONSTRUCTOR 310
#define TK_INSTANCEOF 311
#define TK_VARPARAMS 312
//#define TK_VARGC 313
//#define TK_VARGV 314
#define TK_TRUE 315
#define TK_FALSE 316
#define TK_MULEQ 317
#define TK_DIVEQ 318
#define TK_MODEQ 319
#define TK_ATTR_OPEN 320
#define TK_ATTR_CLOSE 321
#define TK_STATIC 322
#define TK_ENUM 323
#define TK_CONST 324
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_

View File

@ -0,0 +1,116 @@
/*
see copyright notice in squirrel.h
*/
#include "sqpcheader.h"
#include <stdarg.h>
#include "sqvm.h"
#include "sqfuncproto.h"
#include "sqclosure.h"
#include "sqstring.h"
SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger level,SQFunctionInfo *fi)
{
SQInteger cssize = v->_callsstacksize;
if (cssize > level) {
SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];
if(sq_isclosure(ci._closure)) {
SQClosure *c = _closure(ci._closure);
SQFunctionProto *proto = c->_function;
fi->funcid = proto;
fi->name = type(proto->_name) == OT_STRING?_stringval(proto->_name):_SC("unknown");
fi->source = type(proto->_name) == OT_STRING?_stringval(proto->_sourcename):_SC("unknown");
return SQ_OK;
}
}
return sq_throwerror(v,_SC("the object is not a closure"));
}
SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si)
{
SQInteger cssize = v->_callsstacksize;
if (cssize > level) {
memset(si, 0, sizeof(SQStackInfos));
SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];
switch (type(ci._closure)) {
case OT_CLOSURE:{
SQFunctionProto *func = _closure(ci._closure)->_function;
if (type(func->_name) == OT_STRING)
si->funcname = _stringval(func->_name);
if (type(func->_sourcename) == OT_STRING)
si->source = _stringval(func->_sourcename);
si->line = func->GetLine(ci._ip);
}
break;
case OT_NATIVECLOSURE:
si->source = _SC("NATIVE");
si->funcname = _SC("unknown");
if(type(_nativeclosure(ci._closure)->_name) == OT_STRING)
si->funcname = _stringval(_nativeclosure(ci._closure)->_name);
si->line = -1;
break;
default: break; //shutup compiler
}
return SQ_OK;
}
return SQ_ERROR;
}
void SQVM::Raise_Error(const SQChar *s, ...)
{
va_list vl;
va_start(vl, s);
scvsprintf(_sp(rsl((SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2))), s, vl);
va_end(vl);
_lasterror = SQString::Create(_ss(this),_spval,-1);
}
void SQVM::Raise_Error(const SQObjectPtr &desc)
{
_lasterror = desc;
}
SQString *SQVM::PrintObjVal(const SQObjectPtr &o)
{
switch(type(o)) {
case OT_STRING: return _string(o);
case OT_INTEGER:
scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _PRINT_INT_FMT, _integer(o));
return SQString::Create(_ss(this), _spval);
break;
case OT_FLOAT:
scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%.14g"), _float(o));
return SQString::Create(_ss(this), _spval);
break;
default:
return SQString::Create(_ss(this), GetTypeName(o));
}
}
void SQVM::Raise_IdxError(const SQObjectPtr &o)
{
SQObjectPtr oval = PrintObjVal(o);
Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval));
}
void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2)
{
SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2);
Raise_Error(_SC("comparsion between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2));
}
void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type)
{
SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1);
SQInteger found = 0;
for(SQInteger i=0; i<16; i++)
{
SQInteger mask = 0x00000001 << i;
if(typemask & (mask)) {
if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes);
found ++;
StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes);
}
}
Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes));
}

View File

@ -0,0 +1,154 @@
/* see copyright notice in squirrel.h */
#ifndef _SQFUNCTION_H_
#define _SQFUNCTION_H_
#include "sqopcodes.h"
enum SQOuterType {
otLOCAL = 0,
otOUTER = 1
};
struct SQOuterVar
{
SQOuterVar(){}
SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t)
{
_name = name;
_src=src;
_type=t;
}
SQOuterVar(const SQOuterVar &ov)
{
_type=ov._type;
_src=ov._src;
_name=ov._name;
}
SQOuterType _type;
SQObjectPtr _name;
SQObjectPtr _src;
};
struct SQLocalVarInfo
{
SQLocalVarInfo():_start_op(0),_end_op(0),_pos(0){}
SQLocalVarInfo(const SQLocalVarInfo &lvi)
{
_name=lvi._name;
_start_op=lvi._start_op;
_end_op=lvi._end_op;
_pos=lvi._pos;
}
SQObjectPtr _name;
SQUnsignedInteger _start_op;
SQUnsignedInteger _end_op;
SQUnsignedInteger _pos;
};
struct SQLineInfo { SQInteger _line;SQInteger _op; };
typedef sqvector<SQOuterVar> SQOuterVarVec;
typedef sqvector<SQLocalVarInfo> SQLocalVarInfoVec;
typedef sqvector<SQLineInfo> SQLineInfoVec;
#define _FUNC_SIZE(ni,nl,nparams,nfuncs,nouters,nlineinf,localinf,defparams) (sizeof(SQFunctionProto) \
+((ni-1)*sizeof(SQInstruction))+(nl*sizeof(SQObjectPtr)) \
+(nparams*sizeof(SQObjectPtr))+(nfuncs*sizeof(SQObjectPtr)) \
+(nouters*sizeof(SQOuterVar))+(nlineinf*sizeof(SQLineInfo)) \
+(localinf*sizeof(SQLocalVarInfo))+(defparams*sizeof(SQInteger)))
struct SQFunctionProto : public CHAINABLE_OBJ
{
private:
SQFunctionProto(SQSharedState *ss);
~SQFunctionProto();
public:
static SQFunctionProto *Create(SQSharedState *ss,SQInteger ninstructions,
SQInteger nliterals,SQInteger nparameters,
SQInteger nfunctions,SQInteger noutervalues,
SQInteger nlineinfos,SQInteger nlocalvarinfos,SQInteger ndefaultparams)
{
SQFunctionProto *f;
//I compact the whole class and members in a single memory allocation
f = (SQFunctionProto *)sq_vm_malloc(_FUNC_SIZE(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams));
new (f) SQFunctionProto(ss);
f->_ninstructions = ninstructions;
f->_literals = (SQObjectPtr*)&f->_instructions[ninstructions];
f->_nliterals = nliterals;
f->_parameters = (SQObjectPtr*)&f->_literals[nliterals];
f->_nparameters = nparameters;
f->_functions = (SQObjectPtr*)&f->_parameters[nparameters];
f->_nfunctions = nfunctions;
f->_outervalues = (SQOuterVar*)&f->_functions[nfunctions];
f->_noutervalues = noutervalues;
f->_lineinfos = (SQLineInfo *)&f->_outervalues[noutervalues];
f->_nlineinfos = nlineinfos;
f->_localvarinfos = (SQLocalVarInfo *)&f->_lineinfos[nlineinfos];
f->_nlocalvarinfos = nlocalvarinfos;
f->_defaultparams = (SQInteger *)&f->_localvarinfos[nlocalvarinfos];
f->_ndefaultparams = ndefaultparams;
_CONSTRUCT_VECTOR(SQObjectPtr,f->_nliterals,f->_literals);
_CONSTRUCT_VECTOR(SQObjectPtr,f->_nparameters,f->_parameters);
_CONSTRUCT_VECTOR(SQObjectPtr,f->_nfunctions,f->_functions);
_CONSTRUCT_VECTOR(SQOuterVar,f->_noutervalues,f->_outervalues);
//_CONSTRUCT_VECTOR(SQLineInfo,f->_nlineinfos,f->_lineinfos); //not required are 2 integers
_CONSTRUCT_VECTOR(SQLocalVarInfo,f->_nlocalvarinfos,f->_localvarinfos);
return f;
}
void Release(){
_DESTRUCT_VECTOR(SQObjectPtr,_nliterals,_literals);
_DESTRUCT_VECTOR(SQObjectPtr,_nparameters,_parameters);
_DESTRUCT_VECTOR(SQObjectPtr,_nfunctions,_functions);
_DESTRUCT_VECTOR(SQOuterVar,_noutervalues,_outervalues);
//_DESTRUCT_VECTOR(SQLineInfo,_nlineinfos,_lineinfos); //not required are 2 integers
_DESTRUCT_VECTOR(SQLocalVarInfo,_nlocalvarinfos,_localvarinfos);
SQInteger size = _FUNC_SIZE(_ninstructions,_nliterals,_nparameters,_nfunctions,_noutervalues,_nlineinfos,_nlocalvarinfos,_ndefaultparams);
this->~SQFunctionProto();
sq_vm_free(this,size);
}
const SQChar* GetLocal(SQVM *v,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop);
SQInteger GetLine(SQInstruction *curr);
bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
#ifndef NO_GARBAGE_COLLECTOR
void Mark(SQCollectable **chain);
void Finalize(){ _NULL_SQOBJECT_VECTOR(_literals,_nliterals); }
SQObjectType GetType() {return OT_FUNCPROTO;}
#endif
SQObjectPtr _sourcename;
SQObjectPtr _name;
SQInteger _stacksize;
bool _bgenerator;
SQInteger _varparams;
SQInteger _nlocalvarinfos;
SQLocalVarInfo *_localvarinfos;
SQInteger _nlineinfos;
SQLineInfo *_lineinfos;
SQInteger _nliterals;
SQObjectPtr *_literals;
SQInteger _nparameters;
SQObjectPtr *_parameters;
SQInteger _nfunctions;
SQObjectPtr *_functions;
SQInteger _noutervalues;
SQOuterVar *_outervalues;
SQInteger _ndefaultparams;
SQInteger *_defaultparams;
SQInteger _ninstructions;
SQInstruction _instructions[1];
};
#endif //_SQFUNCTION_H_

View File

@ -0,0 +1,652 @@
/*
see copyright notice in squirrel.h
*/
#include "sqpcheader.h"
#ifndef NO_COMPILER
#include "sqcompiler.h"
#include "sqstring.h"
#include "sqfuncproto.h"
#include "sqtable.h"
#include "sqopcodes.h"
#include "sqfuncstate.h"
#ifdef _DEBUG_DUMP
SQInstructionDesc g_InstrDesc[]={
{_SC("_OP_LINE")},
{_SC("_OP_LOAD")},
{_SC("_OP_LOADINT")},
{_SC("_OP_LOADFLOAT")},
{_SC("_OP_DLOAD")},
{_SC("_OP_TAILCALL")},
{_SC("_OP_CALL")},
{_SC("_OP_PREPCALL")},
{_SC("_OP_PREPCALLK")},
{_SC("_OP_GETK")},
{_SC("_OP_MOVE")},
{_SC("_OP_NEWSLOT")},
{_SC("_OP_DELETE")},
{_SC("_OP_SET")},
{_SC("_OP_GET")},
{_SC("_OP_EQ")},
{_SC("_OP_NE")},
{_SC("_OP_ADD")},
{_SC("_OP_SUB")},
{_SC("_OP_MUL")},
{_SC("_OP_DIV")},
{_SC("_OP_MOD")},
{_SC("_OP_BITW")},
{_SC("_OP_RETURN")},
{_SC("_OP_LOADNULLS")},
{_SC("_OP_LOADROOT")},
{_SC("_OP_LOADBOOL")},
{_SC("_OP_DMOVE")},
{_SC("_OP_JMP")},
{_SC("_OP_JCMP")},
{_SC("_OP_JZ")},
{_SC("_OP_SETOUTER")},
{_SC("_OP_GETOUTER")},
{_SC("_OP_NEWOBJ")},
{_SC("_OP_APPENDARRAY")},
{_SC("_OP_COMPARITH")},
{_SC("_OP_INC")},
{_SC("_OP_INCL")},
{_SC("_OP_PINC")},
{_SC("_OP_PINCL")},
{_SC("_OP_CMP")},
{_SC("_OP_EXISTS")},
{_SC("_OP_INSTANCEOF")},
{_SC("_OP_AND")},
{_SC("_OP_OR")},
{_SC("_OP_NEG")},
{_SC("_OP_NOT")},
{_SC("_OP_BWNOT")},
{_SC("_OP_CLOSURE")},
{_SC("_OP_YIELD")},
{_SC("_OP_RESUME")},
{_SC("_OP_FOREACH")},
{_SC("_OP_POSTFOREACH")},
{_SC("_OP_CLONE")},
{_SC("_OP_TYPEOF")},
{_SC("_OP_PUSHTRAP")},
{_SC("_OP_POPTRAP")},
{_SC("_OP_THROW")},
{_SC("_OP_NEWSLOTA")},
{_SC("_OP_GETBASE")},
{_SC("_OP_CLOSE")},
{_SC("_OP_JCMP")}
};
#endif
void DumpLiteral(SQObjectPtr &o)
{
switch(type(o)){
case OT_STRING: scprintf(_SC("\"%s\""),_stringval(o));break;
case OT_FLOAT: scprintf(_SC("{%f}"),_float(o));break;
case OT_INTEGER: scprintf(_SC("{") _PRINT_INT_FMT _SC("}"),_integer(o));break;
case OT_BOOL: scprintf(_SC("%s"),_integer(o)?_SC("true"):_SC("false"));break;
default: scprintf(_SC("(%s %p)"),GetTypeName(o),(void*)_rawval(o));break; break; //shut up compiler
}
}
SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed)
{
_nliterals = 0;
_literals = SQTable::Create(ss,0);
_strings = SQTable::Create(ss,0);
_sharedstate = ss;
_lastline = 0;
_optimization = true;
_parent = parent;
_stacksize = 0;
_traps = 0;
_returnexp = 0;
_varparams = false;
_errfunc = efunc;
_errtarget = ed;
_bgenerator = false;
_outers = 0;
_ss = ss;
}
void SQFuncState::Error(const SQChar *err)
{
_errfunc(_errtarget,err);
}
#ifdef _DEBUG_DUMP
void SQFuncState::Dump(SQFunctionProto *func)
{
SQUnsignedInteger n=0,i;
SQInteger si;
scprintf(_SC("SQInstruction sizeof %d\n"),sizeof(SQInstruction));
scprintf(_SC("SQObject sizeof %d\n"),sizeof(SQObject));
scprintf(_SC("--------------------------------------------------------------------\n"));
scprintf(_SC("*****FUNCTION [%s]\n"),type(func->_name)==OT_STRING?_stringval(func->_name):_SC("unknown"));
scprintf(_SC("-----LITERALS\n"));
SQObjectPtr refidx,key,val;
SQInteger idx;
SQObjectPtrVec templiterals;
templiterals.resize(_nliterals);
while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) {
refidx=idx;
templiterals[_integer(val)]=key;
}
for(i=0;i<templiterals.size();i++){
scprintf(_SC("[%d] "),n);
DumpLiteral(templiterals[i]);
scprintf(_SC("\n"));
n++;
}
scprintf(_SC("-----PARAMS\n"));
if(_varparams)
scprintf(_SC("<<VARPARAMS>>\n"));
n=0;
for(i=0;i<_parameters.size();i++){
scprintf(_SC("[%d] "),n);
DumpLiteral(_parameters[i]);
scprintf(_SC("\n"));
n++;
}
scprintf(_SC("-----LOCALS\n"));
for(si=0;si<func->_nlocalvarinfos;si++){
SQLocalVarInfo lvi=func->_localvarinfos[si];
scprintf(_SC("[%d] %s \t%d %d\n"),lvi._pos,_stringval(lvi._name),lvi._start_op,lvi._end_op);
n++;
}
scprintf(_SC("-----LINE INFO\n"));
for(i=0;i<_lineinfos.size();i++){
SQLineInfo li=_lineinfos[i];
scprintf(_SC("op [%d] line [%d] \n"),li._op,li._line);
n++;
}
scprintf(_SC("-----dump\n"));
n=0;
for(i=0;i<_instructions.size();i++){
SQInstruction &inst=_instructions[i];
if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){
SQInteger lidx = inst._arg1;
scprintf(_SC("[%03d] %15s %d "),n,g_InstrDesc[inst.op].name,inst._arg0);
if(lidx >= 0xFFFFFFFF)
scprintf(_SC("null"));
else {
SQInteger refidx;
SQObjectPtr val,key,refo;
while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) {
refo = refidx;
}
DumpLiteral(key);
}
if(inst.op != _OP_DLOAD) {
scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3);
}
else {
scprintf(_SC(" %d "),inst._arg2);
lidx = inst._arg3;
if(lidx >= 0xFFFFFFFF)
scprintf(_SC("null"));
else {
SQInteger refidx;
SQObjectPtr val,key,refo;
while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) {
refo = refidx;
}
DumpLiteral(key);
scprintf(_SC("\n"));
}
}
}
else if(inst.op==_OP_LOADFLOAT) {
scprintf(_SC("[%03d] %15s %d %f %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,*((SQFloat*)&inst._arg1),inst._arg2,inst._arg3);
}
/* else if(inst.op==_OP_ARITH){
scprintf(_SC("[%03d] %15s %d %d %d %c\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
}*/
else {
scprintf(_SC("[%03d] %15s %d %d %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
}
n++;
}
scprintf(_SC("-----\n"));
scprintf(_SC("stack size[%d]\n"),func->_stacksize);
scprintf(_SC("--------------------------------------------------------------------\n\n"));
}
#endif
SQInteger SQFuncState::GetNumericConstant(const SQInteger cons)
{
return GetConstant(SQObjectPtr(cons));
}
SQInteger SQFuncState::GetNumericConstant(const SQFloat cons)
{
return GetConstant(SQObjectPtr(cons));
}
SQInteger SQFuncState::GetConstant(const SQObject &cons)
{
SQObjectPtr val;
if(!_table(_literals)->Get(cons,val))
{
val = _nliterals;
_table(_literals)->NewSlot(cons,val);
_nliterals++;
if(_nliterals > MAX_LITERALS) {
val.Null();
Error(_SC("internal compiler error: too many literals"));
}
}
return _integer(val);
}
void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3)
{
_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&arg0);
_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&arg1);
_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&arg2);
_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&arg3);
}
void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val)
{
switch(arg){
case 0:_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&val);break;
case 1:case 4:_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&val);break;
case 2:_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&val);break;
case 3:_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&val);break;
};
}
SQInteger SQFuncState::AllocStackPos()
{
SQInteger npos=_vlocals.size();
_vlocals.push_back(SQLocalVarInfo());
if(_vlocals.size()>((SQUnsignedInteger)_stacksize)) {
if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC("internal compiler error: too many locals"));
_stacksize=_vlocals.size();
}
return npos;
}
SQInteger SQFuncState::PushTarget(SQInteger n)
{
if(n!=-1){
_targetstack.push_back(n);
return n;
}
n=AllocStackPos();
_targetstack.push_back(n);
return n;
}
SQInteger SQFuncState::GetUpTarget(SQInteger n){
return _targetstack[((_targetstack.size()-1)-n)];
}
SQInteger SQFuncState::TopTarget(){
return _targetstack.back();
}
SQInteger SQFuncState::PopTarget()
{
SQInteger npos=_targetstack.back();
SQLocalVarInfo &t=_vlocals[_targetstack.back()];
if(type(t._name)==OT_NULL){
_vlocals.pop_back();
}
_targetstack.pop_back();
return npos;
}
SQInteger SQFuncState::GetStackSize()
{
return _vlocals.size();
}
SQInteger SQFuncState::CountOuters(SQInteger stacksize)
{
SQInteger outers = 0;
SQInteger k = _vlocals.size() - 1;
while(k >= stacksize) {
SQLocalVarInfo &lvi = _vlocals[k];
k--;
if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer
outers++;
}
}
return outers;
}
void SQFuncState::SetStackSize(SQInteger n)
{
SQInteger size=_vlocals.size();
while(size>n){
size--;
SQLocalVarInfo lvi = _vlocals.back();
if(type(lvi._name)!=OT_NULL){
if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer
_outers--;
}
lvi._end_op = GetCurrentPos();
_localvarinfos.push_back(lvi);
}
_vlocals.pop_back();
}
}
bool SQFuncState::IsConstant(const SQObject &name,SQObject &e)
{
SQObjectPtr val;
if(_table(_sharedstate->_consts)->Get(name,val)) {
e = val;
return true;
}
return false;
}
bool SQFuncState::IsLocal(SQUnsignedInteger stkpos)
{
if(stkpos>=_vlocals.size())return false;
else if(type(_vlocals[stkpos]._name)!=OT_NULL)return true;
return false;
}
SQInteger SQFuncState::PushLocalVariable(const SQObject &name)
{
SQInteger pos=_vlocals.size();
SQLocalVarInfo lvi;
lvi._name=name;
lvi._start_op=GetCurrentPos()+1;
lvi._pos=_vlocals.size();
_vlocals.push_back(lvi);
if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size();
return pos;
}
SQInteger SQFuncState::GetLocalVariable(const SQObject &name)
{
SQInteger locals=_vlocals.size();
while(locals>=1){
SQLocalVarInfo &lvi = _vlocals[locals-1];
if(type(lvi._name)==OT_STRING && _string(lvi._name)==_string(name)){
return locals-1;
}
locals--;
}
return -1;
}
void SQFuncState::MarkLocalAsOuter(SQInteger pos)
{
SQLocalVarInfo &lvi = _vlocals[pos];
lvi._end_op = UINT_MINUS_ONE;
_outers++;
}
SQInteger SQFuncState::GetOuterVariable(const SQObject &name)
{
SQInteger outers = _outervalues.size();
for(SQInteger i = 0; i<outers; i++) {
if(_string(_outervalues[i]._name) == _string(name))
return i;
}
SQInteger pos=-1;
if(_parent) {
pos = _parent->GetLocalVariable(name);
if(pos == -1) {
pos = _parent->GetOuterVariable(name);
if(pos != -1) {
_outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otOUTER)); //local
return _outervalues.size() - 1;
}
}
else {
_parent->MarkLocalAsOuter(pos);
_outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otLOCAL)); //local
return _outervalues.size() - 1;
}
}
return -1;
}
void SQFuncState::AddParameter(const SQObject &name)
{
PushLocalVariable(name);
_parameters.push_back(name);
}
void SQFuncState::AddLineInfos(SQInteger line,bool lineop,bool force)
{
if(_lastline!=line || force){
SQLineInfo li;
li._line=line;li._op=(GetCurrentPos()+1);
if(lineop)AddInstruction(_OP_LINE,0,line);
if(_lastline!=line) {
_lineinfos.push_back(li);
}
_lastline=line;
}
}
void SQFuncState::DiscardTarget()
{
SQInteger discardedtarget = PopTarget();
SQInteger size = _instructions.size();
if(size > 0 && _optimization){
SQInstruction &pi = _instructions[size-1];//previous instruction
switch(pi.op) {
case _OP_SET:case _OP_NEWSLOT:case _OP_SETOUTER:case _OP_CALL:
if(pi._arg0 == discardedtarget) {
pi._arg0 = 0xFF;
}
}
}
}
void SQFuncState::AddInstruction(SQInstruction &i)
{
SQInteger size = _instructions.size();
if(size > 0 && _optimization){ //simple optimizer
SQInstruction &pi = _instructions[size-1];//previous instruction
switch(i.op) {
case _OP_JZ:
if( pi.op == _OP_CMP && pi._arg1 < 0xFF) {
pi.op = _OP_JCMP;
pi._arg0 = (unsigned char)pi._arg1;
pi._arg1 = i._arg1;
return;
}
case _OP_SET:
case _OP_NEWSLOT:
if(i._arg0 == i._arg3) {
i._arg0 = 0xFF;
}
break;
case _OP_SETOUTER:
if(i._arg0 == i._arg2) {
i._arg0 = 0xFF;
}
break;
case _OP_RETURN:
if( _parent && i._arg0 != MAX_FUNC_STACKSIZE && pi.op == _OP_CALL && _returnexp < size-1) {
pi.op = _OP_TAILCALL;
} else if(pi.op == _OP_CLOSE){
pi = i;
return;
}
break;
case _OP_GET:
if( pi.op == _OP_LOAD && pi._arg0 == i._arg2 && (!IsLocal(pi._arg0))){
pi._arg1 = pi._arg1;
pi._arg2 = (unsigned char)i._arg1;
pi.op = _OP_GETK;
pi._arg0 = i._arg0;
return;
}
break;
case _OP_PREPCALL:
if( pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){
pi.op = _OP_PREPCALLK;
pi._arg0 = i._arg0;
pi._arg1 = pi._arg1;
pi._arg2 = i._arg2;
pi._arg3 = i._arg3;
return;
}
break;
case _OP_APPENDARRAY: {
SQInteger aat = -1;
switch(pi.op) {
case _OP_LOAD: aat = AAT_LITERAL; break;
case _OP_LOADINT: aat = AAT_INT; break;
case _OP_LOADBOOL: aat = AAT_BOOL; break;
case _OP_LOADFLOAT: aat = AAT_FLOAT; break;
default: break;
}
if(aat != -1 && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){
pi.op = _OP_APPENDARRAY;
pi._arg0 = i._arg0;
pi._arg1 = pi._arg1;
pi._arg2 = (unsigned char)aat;
pi._arg3 = MAX_FUNC_STACKSIZE;
return;
}
}
break;
case _OP_MOVE:
switch(pi.op) {
case _OP_GET: case _OP_ADD: case _OP_SUB: case _OP_MUL: case _OP_DIV: case _OP_MOD: case _OP_BITW:
case _OP_LOADINT: case _OP_LOADFLOAT: case _OP_LOADBOOL: case _OP_LOAD:
if(pi._arg0 == i._arg1)
{
pi._arg0 = i._arg0;
_optimization = false;
//_result_elimination = false;
return;
}
}
if(pi.op == _OP_MOVE)
{
pi.op = _OP_DMOVE;
pi._arg2 = i._arg0;
pi._arg3 = (unsigned char)i._arg1;
return;
}
break;
case _OP_LOAD:
if(pi.op == _OP_LOAD && i._arg1 < 256) {
pi.op = _OP_DLOAD;
pi._arg2 = i._arg0;
pi._arg3 = (unsigned char)i._arg1;
return;
}
break;
case _OP_EQ:case _OP_NE:
if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0) ))
{
pi.op = i.op;
pi._arg0 = i._arg0;
pi._arg1 = pi._arg1;
pi._arg2 = i._arg2;
pi._arg3 = MAX_FUNC_STACKSIZE;
return;
}
break;
case _OP_LOADNULLS:
if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) {
pi._arg1 = pi._arg1 + 1;
pi.op = _OP_LOADNULLS;
return;
}
break;
case _OP_LINE:
if(pi.op == _OP_LINE) {
_instructions.pop_back();
_lineinfos.pop_back();
}
break;
}
}
_optimization = true;
_instructions.push_back(i);
}
SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len)
{
SQObjectPtr ns(SQString::Create(_sharedstate,s,len));
_table(_strings)->NewSlot(ns,(SQInteger)1);
return ns;
}
SQObject SQFuncState::CreateTable()
{
SQObjectPtr nt(SQTable::Create(_sharedstate,0));
_table(_strings)->NewSlot(nt,(SQInteger)1);
return nt;
}
SQFunctionProto *SQFuncState::BuildProto()
{
SQFunctionProto *f=SQFunctionProto::Create(_ss,_instructions.size(),
_nliterals,_parameters.size(),_functions.size(),_outervalues.size(),
_lineinfos.size(),_localvarinfos.size(),_defaultparams.size());
SQObjectPtr refidx,key,val;
SQInteger idx;
f->_stacksize = _stacksize;
f->_sourcename = _sourcename;
f->_bgenerator = _bgenerator;
f->_name = _name;
while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) {
f->_literals[_integer(val)]=key;
refidx=idx;
}
for(SQUnsignedInteger nf = 0; nf < _functions.size(); nf++) f->_functions[nf] = _functions[nf];
for(SQUnsignedInteger np = 0; np < _parameters.size(); np++) f->_parameters[np] = _parameters[np];
for(SQUnsignedInteger no = 0; no < _outervalues.size(); no++) f->_outervalues[no] = _outervalues[no];
for(SQUnsignedInteger nl = 0; nl < _localvarinfos.size(); nl++) f->_localvarinfos[nl] = _localvarinfos[nl];
for(SQUnsignedInteger ni = 0; ni < _lineinfos.size(); ni++) f->_lineinfos[ni] = _lineinfos[ni];
for(SQUnsignedInteger nd = 0; nd < _defaultparams.size(); nd++) f->_defaultparams[nd] = _defaultparams[nd];
memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(SQInstruction));
f->_varparams = _varparams;
return f;
}
SQFuncState *SQFuncState::PushChildState(SQSharedState *ss)
{
SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState));
new (child) SQFuncState(ss,this,_errfunc,_errtarget);
_childstates.push_back(child);
return child;
}
void SQFuncState::PopChildState()
{
SQFuncState *child = _childstates.back();
sq_delete(child,SQFuncState);
_childstates.pop_back();
}
SQFuncState::~SQFuncState()
{
while(_childstates.size() > 0)
{
PopChildState();
}
}
#endif

View File

@ -0,0 +1,91 @@
/* see copyright notice in squirrel.h */
#ifndef _SQFUNCSTATE_H_
#define _SQFUNCSTATE_H_
///////////////////////////////////
#include "squtils.h"
struct SQFuncState
{
SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed);
~SQFuncState();
#ifdef _DEBUG_DUMP
void Dump(SQFunctionProto *func);
#endif
void Error(const SQChar *err);
SQFuncState *PushChildState(SQSharedState *ss);
void PopChildState();
void AddInstruction(SQOpcode _op,SQInteger arg0=0,SQInteger arg1=0,SQInteger arg2=0,SQInteger arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);AddInstruction(i);}
void AddInstruction(SQInstruction &i);
void SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2=0,SQInteger arg3=0);
void SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val);
SQInstruction &GetInstruction(SQInteger pos){return _instructions[pos];}
void PopInstructions(SQInteger size){for(SQInteger i=0;i<size;i++)_instructions.pop_back();}
void SetStackSize(SQInteger n);
SQInteger CountOuters(SQInteger stacksize);
void SnoozeOpt(){_optimization=false;}
void AddDefaultParam(SQInteger trg) { _defaultparams.push_back(trg); }
SQInteger GetDefaultParamCount() { return _defaultparams.size(); }
SQInteger GetCurrentPos(){return _instructions.size()-1;}
SQInteger GetNumericConstant(const SQInteger cons);
SQInteger GetNumericConstant(const SQFloat cons);
SQInteger PushLocalVariable(const SQObject &name);
void AddParameter(const SQObject &name);
//void AddOuterValue(const SQObject &name);
SQInteger GetLocalVariable(const SQObject &name);
void MarkLocalAsOuter(SQInteger pos);
SQInteger GetOuterVariable(const SQObject &name);
SQInteger GenerateCode();
SQInteger GetStackSize();
SQInteger CalcStackFrameSize();
void AddLineInfos(SQInteger line,bool lineop,bool force=false);
SQFunctionProto *BuildProto();
SQInteger AllocStackPos();
SQInteger PushTarget(SQInteger n=-1);
SQInteger PopTarget();
SQInteger TopTarget();
SQInteger GetUpTarget(SQInteger n);
void DiscardTarget();
bool IsLocal(SQUnsignedInteger stkpos);
SQObject CreateString(const SQChar *s,SQInteger len = -1);
SQObject CreateTable();
bool IsConstant(const SQObject &name,SQObject &e);
SQInteger _returnexp;
SQLocalVarInfoVec _vlocals;
SQIntVec _targetstack;
SQInteger _stacksize;
bool _varparams;
bool _bgenerator;
SQIntVec _unresolvedbreaks;
SQIntVec _unresolvedcontinues;
SQObjectPtrVec _functions;
SQObjectPtrVec _parameters;
SQOuterVarVec _outervalues;
SQInstructionVec _instructions;
SQLocalVarInfoVec _localvarinfos;
SQObjectPtr _literals;
SQObjectPtr _strings;
SQObjectPtr _name;
SQObjectPtr _sourcename;
SQInteger _nliterals;
SQLineInfoVec _lineinfos;
SQFuncState *_parent;
SQIntVec _scope_blocks;
SQIntVec _breaktargets;
SQIntVec _continuetargets;
SQIntVec _defaultparams;
SQInteger _lastline;
SQInteger _traps; //contains number of nested exception traps
SQInteger _outers;
bool _optimization;
SQSharedState *_sharedstate;
sqvector<SQFuncState*> _childstates;
SQInteger GetConstant(const SQObject &cons);
private:
CompilerErrorFunc _errfunc;
void *_errtarget;
SQSharedState *_ss;
};
#endif //_SQFUNCSTATE_H_

View File

@ -0,0 +1,489 @@
/*
see copyright notice in squirrel.h
*/
#include "sqpcheader.h"
#include <ctype.h>
#include <stdlib.h>
#include "sqtable.h"
#include "sqstring.h"
#include "sqcompiler.h"
#include "sqlexer.h"
#define CUR_CHAR (_currdata)
#define RETURN_TOKEN(t) { _prevtoken = _curtoken; _curtoken = t; return t;}
#define IS_EOB() (CUR_CHAR <= SQUIRREL_EOB)
#define NEXT() {Next();_currentcolumn++;}
#define INIT_TEMP_STRING() { _longstr.resize(0);}
#define APPEND_CHAR(c) { _longstr.push_back(c);}
#define TERMINATE_BUFFER() {_longstr.push_back(_SC('\0'));}
#define ADD_KEYWORD(key,id) _keywords->NewSlot( SQString::Create(ss, _SC(#key)) ,SQInteger(id))
SQLexer::SQLexer(){}
SQLexer::~SQLexer()
{
_keywords->Release();
}
void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed)
{
_errfunc = efunc;
_errtarget = ed;
_sharedstate = ss;
_keywords = SQTable::Create(ss, 26);
ADD_KEYWORD(while, TK_WHILE);
ADD_KEYWORD(do, TK_DO);
ADD_KEYWORD(if, TK_IF);
ADD_KEYWORD(else, TK_ELSE);
ADD_KEYWORD(break, TK_BREAK);
ADD_KEYWORD(continue, TK_CONTINUE);
ADD_KEYWORD(return, TK_RETURN);
ADD_KEYWORD(null, TK_NULL);
ADD_KEYWORD(function, TK_FUNCTION);
ADD_KEYWORD(local, TK_LOCAL);
ADD_KEYWORD(for, TK_FOR);
ADD_KEYWORD(foreach, TK_FOREACH);
ADD_KEYWORD(in, TK_IN);
ADD_KEYWORD(typeof, TK_TYPEOF);
ADD_KEYWORD(base, TK_BASE);
ADD_KEYWORD(delete, TK_DELETE);
ADD_KEYWORD(try, TK_TRY);
ADD_KEYWORD(catch, TK_CATCH);
ADD_KEYWORD(throw, TK_THROW);
ADD_KEYWORD(clone, TK_CLONE);
ADD_KEYWORD(yield, TK_YIELD);
ADD_KEYWORD(resume, TK_RESUME);
ADD_KEYWORD(switch, TK_SWITCH);
ADD_KEYWORD(case, TK_CASE);
ADD_KEYWORD(default, TK_DEFAULT);
ADD_KEYWORD(this, TK_THIS);
ADD_KEYWORD(class,TK_CLASS);
ADD_KEYWORD(extends,TK_EXTENDS);
ADD_KEYWORD(constructor,TK_CONSTRUCTOR);
ADD_KEYWORD(instanceof,TK_INSTANCEOF);
ADD_KEYWORD(true,TK_TRUE);
ADD_KEYWORD(false,TK_FALSE);
ADD_KEYWORD(static,TK_STATIC);
ADD_KEYWORD(enum,TK_ENUM);
ADD_KEYWORD(const,TK_CONST);
_readf = rg;
_up = up;
_lasttokenline = _currentline = 1;
_currentcolumn = 0;
_prevtoken = -1;
_reached_eof = SQFalse;
Next();
}
void SQLexer::Error(const SQChar *err)
{
_errfunc(_errtarget,err);
}
void SQLexer::Next()
{
SQInteger t = _readf(_up);
if(t > MAX_CHAR) Error(_SC("Invalid character"));
if(t != 0) {
_currdata = (LexChar)t;
return;
}
_currdata = SQUIRREL_EOB;
_reached_eof = SQTrue;
}
const SQChar *SQLexer::Tok2Str(SQInteger tok)
{
SQObjectPtr itr, key, val;
SQInteger nitr;
while((nitr = _keywords->Next(false,itr, key, val)) != -1) {
itr = (SQInteger)nitr;
if(((SQInteger)_integer(val)) == tok)
return _stringval(key);
}
return NULL;
}
void SQLexer::LexBlockComment()
{
bool done = false;
while(!done) {
switch(CUR_CHAR) {
case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue;
case _SC('\n'): _currentline++; NEXT(); continue;
case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment"));
default: NEXT();
}
}
}
void SQLexer::LexLineComment()
{
do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB()));
}
SQInteger SQLexer::Lex()
{
_lasttokenline = _currentline;
while(CUR_CHAR != SQUIRREL_EOB) {
switch(CUR_CHAR){
case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue;
case _SC('\n'):
_currentline++;
_prevtoken=_curtoken;
_curtoken=_SC('\n');
NEXT();
_currentcolumn=1;
continue;
case _SC('#'): LexLineComment(); continue;
case _SC('/'):
NEXT();
switch(CUR_CHAR){
case _SC('*'):
NEXT();
LexBlockComment();
continue;
case _SC('/'):
LexLineComment();
continue;
case _SC('='):
NEXT();
RETURN_TOKEN(TK_DIVEQ);
continue;
case _SC('>'):
NEXT();
RETURN_TOKEN(TK_ATTR_CLOSE);
continue;
default:
RETURN_TOKEN('/');
}
case _SC('='):
NEXT();
if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') }
else { NEXT(); RETURN_TOKEN(TK_EQ); }
case _SC('<'):
NEXT();
switch(CUR_CHAR) {
case _SC('='):
NEXT();
if(CUR_CHAR == _SC('>')) {
NEXT();
RETURN_TOKEN(TK_3WAYSCMP);
}
RETURN_TOKEN(TK_LE)
break;
case _SC('-'): NEXT(); RETURN_TOKEN(TK_NEWSLOT); break;
case _SC('<'): NEXT(); RETURN_TOKEN(TK_SHIFTL); break;
case _SC('/'): NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); break;
}
RETURN_TOKEN('<');
case _SC('>'):
NEXT();
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);}
else if(CUR_CHAR == _SC('>')){
NEXT();
if(CUR_CHAR == _SC('>')){
NEXT();
RETURN_TOKEN(TK_USHIFTR);
}
RETURN_TOKEN(TK_SHIFTR);
}
else { RETURN_TOKEN('>') }
case _SC('!'):
NEXT();
if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')}
else { NEXT(); RETURN_TOKEN(TK_NE); }
case _SC('@'): {
SQInteger stype;
NEXT();
if(CUR_CHAR != _SC('"')) {
RETURN_TOKEN('@');
}
if((stype=ReadString('"',true))!=-1) {
RETURN_TOKEN(stype);
}
Error(_SC("error parsing the string"));
}
case _SC('"'):
case _SC('\''): {
SQInteger stype;
if((stype=ReadString(CUR_CHAR,false))!=-1){
RETURN_TOKEN(stype);
}
Error(_SC("error parsing the string"));
}
case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'):
case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'):
{SQInteger ret = CUR_CHAR;
NEXT(); RETURN_TOKEN(ret); }
case _SC('.'):
NEXT();
if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') }
NEXT();
if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); }
NEXT();
RETURN_TOKEN(TK_VARPARAMS);
case _SC('&'):
NEXT();
if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') }
else { NEXT(); RETURN_TOKEN(TK_AND); }
case _SC('|'):
NEXT();
if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') }
else { NEXT(); RETURN_TOKEN(TK_OR); }
case _SC(':'):
NEXT();
if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') }
else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); }
case _SC('*'):
NEXT();
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);}
else RETURN_TOKEN('*');
case _SC('%'):
NEXT();
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);}
else RETURN_TOKEN('%');
case _SC('-'):
NEXT();
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);}
else if (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);}
else RETURN_TOKEN('-');
case _SC('+'):
NEXT();
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);}
else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);}
else RETURN_TOKEN('+');
case SQUIRREL_EOB:
return 0;
default:{
if (scisdigit(CUR_CHAR)) {
SQInteger ret = ReadNumber();
RETURN_TOKEN(ret);
}
else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) {
SQInteger t = ReadID();
RETURN_TOKEN(t);
}
else {
SQInteger c = CUR_CHAR;
if (sciscntrl((int)c)) Error(_SC("unexpected character(control)"));
NEXT();
RETURN_TOKEN(c);
}
RETURN_TOKEN(0);
}
}
}
return 0;
}
SQInteger SQLexer::GetIDType(SQChar *s)
{
SQObjectPtr t;
if(_keywords->Get(SQString::Create(_sharedstate, s), t)) {
return SQInteger(_integer(t));
}
return TK_IDENTIFIER;
}
SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
{
INIT_TEMP_STRING();
NEXT();
if(IS_EOB()) return -1;
for(;;) {
while(CUR_CHAR != ndelim) {
switch(CUR_CHAR) {
case SQUIRREL_EOB:
Error(_SC("unfinished string"));
return -1;
case _SC('\n'):
if(!verbatim) Error(_SC("newline in a constant"));
APPEND_CHAR(CUR_CHAR); NEXT();
_currentline++;
break;
case _SC('\\'):
if(verbatim) {
APPEND_CHAR('\\'); NEXT();
}
else {
NEXT();
switch(CUR_CHAR) {
case _SC('x'): NEXT(); {
if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected"));
const SQInteger maxdigits = 4;
SQChar temp[maxdigits+1];
SQInteger n = 0;
while(isxdigit(CUR_CHAR) && n < maxdigits) {
temp[n] = CUR_CHAR;
n++;
NEXT();
}
temp[n] = 0;
SQChar *sTemp;
APPEND_CHAR((SQChar)scstrtoul(temp,&sTemp,16));
}
break;
case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break;
case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break;
case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break;
case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break;
case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break;
case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break;
case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break;
case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break;
case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break;
case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break;
case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break;
default:
Error(_SC("unrecognised escaper char"));
break;
}
}
break;
default:
APPEND_CHAR(CUR_CHAR);
NEXT();
}
}
NEXT();
if(verbatim && CUR_CHAR == '"') { //double quotation
APPEND_CHAR(CUR_CHAR);
NEXT();
}
else {
break;
}
}
TERMINATE_BUFFER();
SQInteger len = _longstr.size()-1;
if(ndelim == _SC('\'')) {
if(len == 0) Error(_SC("empty constant"));
if(len > 1) Error(_SC("constant too long"));
_nvalue = _longstr[0];
return TK_INTEGER;
}
_svalue = &_longstr[0];
return TK_STRING_LITERAL;
}
void LexHexadecimal(const SQChar *s,SQUnsignedInteger *res)
{
*res = 0;
while(*s != 0)
{
if(scisdigit(*s)) *res = (*res)*16+((*s++)-'0');
else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-'A'+10);
else { assert(0); }
}
}
void LexInteger(const SQChar *s,SQUnsignedInteger *res)
{
*res = 0;
while(*s != 0)
{
*res = (*res)*10+((*s++)-'0');
}
}
SQInteger scisodigit(SQInteger c) { return c >= _SC('0') && c <= _SC('7'); }
void LexOctal(const SQChar *s,SQUnsignedInteger *res)
{
*res = 0;
while(*s != 0)
{
if(scisodigit(*s)) *res = (*res)*8+((*s++)-'0');
else { assert(0); }
}
}
SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; }
#define MAX_HEX_DIGITS (sizeof(SQInteger)*2)
SQInteger SQLexer::ReadNumber()
{
#define TINT 1
#define TFLOAT 2
#define THEX 3
#define TSCIENTIFIC 4
#define TOCTAL 5
SQInteger type = TINT, firstchar = CUR_CHAR;
SQChar *sTemp;
INIT_TEMP_STRING();
NEXT();
if(firstchar == _SC('0') && (toupper(CUR_CHAR) == _SC('X') || scisodigit(CUR_CHAR)) ) {
if(scisodigit(CUR_CHAR)) {
type = TOCTAL;
while(scisodigit(CUR_CHAR)) {
APPEND_CHAR(CUR_CHAR);
NEXT();
}
if(scisdigit(CUR_CHAR)) Error(_SC("invalid octal number"));
}
else {
NEXT();
type = THEX;
while(isxdigit(CUR_CHAR)) {
APPEND_CHAR(CUR_CHAR);
NEXT();
}
if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number"));
}
}
else {
APPEND_CHAR((int)firstchar);
while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) {
if(CUR_CHAR == _SC('.')) type = TFLOAT;
if(isexponent(CUR_CHAR)) {
if(type != TFLOAT) Error(_SC("invalid numeric format"));
type = TSCIENTIFIC;
APPEND_CHAR(CUR_CHAR);
NEXT();
if(CUR_CHAR == '+' || CUR_CHAR == '-'){
APPEND_CHAR(CUR_CHAR);
NEXT();
}
if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected"));
}
APPEND_CHAR(CUR_CHAR);
NEXT();
}
}
TERMINATE_BUFFER();
switch(type) {
case TSCIENTIFIC:
case TFLOAT:
_fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp);
return TK_FLOAT;
case TINT:
LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
return TK_INTEGER;
case THEX:
LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
return TK_INTEGER;
case TOCTAL:
LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
return TK_INTEGER;
}
return 0;
}
SQInteger SQLexer::ReadID()
{
SQInteger res;
INIT_TEMP_STRING();
do {
APPEND_CHAR(CUR_CHAR);
NEXT();
} while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_'));
TERMINATE_BUFFER();
res = GetIDType(&_longstr[0]);
if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) {
_svalue = &_longstr[0];
}
return res;
}

View File

@ -0,0 +1,47 @@
/* see copyright notice in squirrel.h */
#ifndef _SQLEXER_H_
#define _SQLEXER_H_
#ifdef SQUNICODE
typedef SQChar LexChar;
#else
typedef unsigned char LexChar;
#endif
struct SQLexer
{
SQLexer();
~SQLexer();
void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed);
void Error(const SQChar *err);
SQInteger Lex();
const SQChar *Tok2Str(SQInteger tok);
private:
SQInteger GetIDType(SQChar *s);
SQInteger ReadString(SQInteger ndelim,bool verbatim);
SQInteger ReadNumber();
void LexBlockComment();
void LexLineComment();
SQInteger ReadID();
void Next();
SQInteger _curtoken;
SQTable *_keywords;
SQBool _reached_eof;
public:
SQInteger _prevtoken;
SQInteger _currentline;
SQInteger _lasttokenline;
SQInteger _currentcolumn;
const SQChar *_svalue;
SQInteger _nvalue;
SQFloat _fvalue;
SQLEXREADFUNC _readf;
SQUserPointer _up;
LexChar _currdata;
SQSharedState *_sharedstate;
sqvector<SQChar> _longstr;
CompilerErrorFunc _errfunc;
void *_errtarget;
};
#endif

View File

@ -0,0 +1,9 @@
/*
see copyright notice in squirrel.h
*/
#include "sqpcheader.h"
void *sq_vm_malloc(SQUnsignedInteger size){ return malloc(size); }
void *sq_vm_realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger size){ return realloc(p, size); }
void sq_vm_free(void *p, SQUnsignedInteger size){ free(p); }

View File

@ -0,0 +1,655 @@
/*
see copyright notice in squirrel.h
*/
#include "sqpcheader.h"
#include "sqvm.h"
#include "sqstring.h"
#include "sqarray.h"
#include "sqtable.h"
#include "squserdata.h"
#include "sqfuncproto.h"
#include "sqclass.h"
#include "sqclosure.h"
const SQChar *IdType2Name(SQObjectType type)
{
switch(_RAW_TYPE(type))
{
case _RT_NULL:return _SC("null");
case _RT_INTEGER:return _SC("integer");
case _RT_FLOAT:return _SC("float");
case _RT_BOOL:return _SC("bool");
case _RT_STRING:return _SC("string");
case _RT_TABLE:return _SC("table");
case _RT_ARRAY:return _SC("array");
case _RT_GENERATOR:return _SC("generator");
case _RT_CLOSURE:
case _RT_NATIVECLOSURE:
return _SC("function");
case _RT_USERDATA:
case _RT_USERPOINTER:
return _SC("userdata");
case _RT_THREAD: return _SC("thread");
case _RT_FUNCPROTO: return _SC("function");
case _RT_CLASS: return _SC("class");
case _RT_INSTANCE: return _SC("instance");
case _RT_WEAKREF: return _SC("weakref");
case _RT_OUTER: return _SC("outer");
default:
return NULL;
}
}
const SQChar *GetTypeName(const SQObjectPtr &obj1)
{
return IdType2Name(type(obj1));
}
SQString *SQString::Create(SQSharedState *ss,const SQChar *s,SQInteger len)
{
SQString *str=ADD_STRING(ss,s,len);
return str;
}
void SQString::Release()
{
REMOVE_STRING(_sharedstate,this);
}
SQInteger SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
{
SQInteger idx = (SQInteger)TranslateIndex(refpos);
while(idx < _len){
outkey = (SQInteger)idx;
outval = SQInteger(_val[idx]);
//return idx for the next iteration
return ++idx;
}
//nothing to iterate anymore
return -1;
}
SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx)
{
switch(type(idx)){
case OT_NULL:
return 0;
case OT_INTEGER:
return (SQUnsignedInteger)_integer(idx);
default: assert(0); break;
}
return 0;
}
SQWeakRef *SQRefCounted::GetWeakRef(SQObjectType type)
{
if(!_weakref) {
sq_new(_weakref,SQWeakRef);
_weakref->_obj._type = type;
_weakref->_obj._unVal.pRefCounted = this;
}
return _weakref;
}
SQRefCounted::~SQRefCounted()
{
if(_weakref) {
_weakref->_obj._type = OT_NULL;
_weakref->_obj._unVal.pRefCounted = NULL;
}
}
void SQWeakRef::Release() {
if(ISREFCOUNTED(_obj._type)) {
_obj._unVal.pRefCounted->_weakref = NULL;
}
sq_delete(this,SQWeakRef);
}
bool SQDelegable::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) {
if(_delegate) {
return _delegate->Get((*_ss(v)->_metamethods)[mm],res);
}
return false;
}
bool SQDelegable::SetDelegate(SQTable *mt)
{
SQTable *temp = mt;
if(temp == this) return false;
while (temp) {
if (temp->_delegate == this) return false; //cycle detected
temp = temp->_delegate;
}
if (mt) __ObjAddRef(mt);
__ObjRelease(_delegate);
_delegate = mt;
return true;
}
bool SQGenerator::Yield(SQVM *v,SQInteger target)
{
if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator")); return false;}
if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; }
SQInteger size = v->_top-v->_stackbase;
_stack.resize(size);
SQObject _this = v->_stack[v->_stackbase];
_stack._vals[0] = ISREFCOUNTED(type(_this)) ? SQObjectPtr(_refcounted(_this)->GetWeakRef(type(_this))) : _this;
for(SQInteger n =1; n<target; n++) {
_stack._vals[n] = v->_stack[v->_stackbase+n];
}
for(SQInteger j =0; j < size; j++)
{
v->_stack[v->_stackbase+j].Null();
}
_ci = *v->ci;
_ci._generator=NULL;
for(SQInteger i=0;i<_ci._etraps;i++) {
_etraps.push_back(v->_etraps.top());
v->_etraps.pop_back();
}
_state=eSuspended;
return true;
}
bool SQGenerator::Resume(SQVM *v,SQObjectPtr &dest)
{
if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; }
if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; }
SQInteger size = _stack.size();
SQInteger target = &dest - &(v->_stack._vals[v->_stackbase]);
assert(target>=0 && target<=255);
if(!v->EnterFrame(v->_top, v->_top + size, false))
return false;
v->ci->_generator = this;
v->ci->_target = (SQInt32)target;
v->ci->_closure = _ci._closure;
v->ci->_ip = _ci._ip;
v->ci->_literals = _ci._literals;
v->ci->_ncalls = _ci._ncalls;
v->ci->_etraps = _ci._etraps;
v->ci->_root = _ci._root;
for(SQInteger i=0;i<_ci._etraps;i++) {
v->_etraps.push_back(_etraps.top());
_etraps.pop_back();
}
SQObject _this = _stack._vals[0];
v->_stack[v->_stackbase] = type(_this) == OT_WEAKREF ? _weakref(_this)->_obj : _this;
for(SQInteger n = 1; n<size; n++) {
v->_stack[v->_stackbase+n] = _stack._vals[n];
_stack._vals[n].Null();
}
_state=eRunning;
if (v->_debughook)
v->CallDebugHook(_SC('c'));
return true;
}
void SQArray::Extend(const SQArray *a){
SQInteger xlen;
if((xlen=a->Size()))
for(SQInteger i=0;i<xlen;i++)
Append(a->_values[i]);
}
const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop)
{
SQUnsignedInteger nvars=_nlocalvarinfos;
const SQChar *res=NULL;
if(nvars>=nseq){
for(SQUnsignedInteger i=0;i<nvars;i++){
if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop)
{
if(nseq==0){
vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]);
res=_stringval(_localvarinfos[i]._name);
break;
}
nseq--;
}
}
}
return res;
}
SQInteger SQFunctionProto::GetLine(SQInstruction *curr)
{
SQInteger op = (SQInteger)(curr-_instructions);
SQInteger line=_lineinfos[0]._line;
SQInteger low = 0;
SQInteger high = _nlineinfos - 1;
SQInteger mid = 0;
while(low <= high)
{
mid = low + ((high - low) >> 1);
SQInteger curop = _lineinfos[mid]._op;
if(curop > op)
{
high = mid - 1;
}
else if(curop < op) {
if(mid < (_nlineinfos - 1)
&& _lineinfos[mid + 1]._op >= op) {
break;
}
low = mid + 1;
}
else { //equal
break;
}
}
line = _lineinfos[mid]._line;
return line;
}
SQClosure::~SQClosure()
{
__ObjRelease(_env);
__ObjRelease(_base);
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
}
#define _CHECK_IO(exp) { if(!exp)return false; }
bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size)
{
if(write(up,dest,size) != size) {
v->Raise_Error(_SC("io error (write function failure)"));
return false;
}
return true;
}
bool SafeRead(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,SQInteger size)
{
if(size && read(up,dest,size) != size) {
v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated"));
return false;
}
return true;
}
bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUnsignedInteger32 tag)
{
return SafeWrite(v,write,up,&tag,sizeof(tag));
}
bool CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUnsignedInteger32 tag)
{
SQUnsignedInteger32 t;
_CHECK_IO(SafeRead(v,read,up,&t,sizeof(t)));
if(t != tag){
v->Raise_Error(_SC("invalid or corrupted closure stream"));
return false;
}
return true;
}
bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o)
{
SQUnsignedInteger32 _type = (SQUnsignedInteger32)type(o);
_CHECK_IO(SafeWrite(v,write,up,&_type,sizeof(_type)));
switch(type(o)){
case OT_STRING:
_CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger)));
_CHECK_IO(SafeWrite(v,write,up,_stringval(o),rsl(_string(o)->_len)));
break;
case OT_INTEGER:
_CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break;
case OT_FLOAT:
_CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(SQFloat)));break;
case OT_NULL:
break;
default:
v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o));
return false;
}
return true;
}
bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o)
{
SQUnsignedInteger32 _type;
_CHECK_IO(SafeRead(v,read,up,&_type,sizeof(_type)));
SQObjectType t = (SQObjectType)_type;
switch(t){
case OT_STRING:{
SQInteger len;
_CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger)));
_CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(rsl(len)),rsl(len)));
o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len);
}
break;
case OT_INTEGER:{
SQInteger i;
_CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break;
}
case OT_FLOAT:{
SQFloat f;
_CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break;
}
case OT_NULL:
o.Null();
break;
default:
v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t));
return false;
}
return true;
}
bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
{
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD));
_CHECK_IO(WriteTag(v,write,up,sizeof(SQChar)));
_CHECK_IO(WriteTag(v,write,up,sizeof(SQInteger)));
_CHECK_IO(WriteTag(v,write,up,sizeof(SQFloat)));
_CHECK_IO(_function->Save(v,up,write));
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL));
return true;
}
bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret)
{
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD));
_CHECK_IO(CheckTag(v,read,up,sizeof(SQChar)));
_CHECK_IO(CheckTag(v,read,up,sizeof(SQInteger)));
_CHECK_IO(CheckTag(v,read,up,sizeof(SQFloat)));
SQObjectPtr func;
_CHECK_IO(SQFunctionProto::Load(v,up,read,func));
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL));
ret = SQClosure::Create(_ss(v),_funcproto(func));
return true;
}
SQFunctionProto::SQFunctionProto(SQSharedState *ss)
{
_stacksize=0;
_bgenerator=false;
INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);
}
SQFunctionProto::~SQFunctionProto()
{
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
}
bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
{
SQInteger i,nliterals = _nliterals,nparameters = _nparameters;
SQInteger noutervalues = _noutervalues,nlocalvarinfos = _nlocalvarinfos;
SQInteger nlineinfos=_nlineinfos,ninstructions = _ninstructions,nfunctions=_nfunctions;
SQInteger ndefaultparams = _ndefaultparams;
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
_CHECK_IO(WriteObject(v,up,write,_sourcename));
_CHECK_IO(WriteObject(v,up,write,_name));
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
_CHECK_IO(SafeWrite(v,write,up,&nliterals,sizeof(nliterals)));
_CHECK_IO(SafeWrite(v,write,up,&nparameters,sizeof(nparameters)));
_CHECK_IO(SafeWrite(v,write,up,&noutervalues,sizeof(noutervalues)));
_CHECK_IO(SafeWrite(v,write,up,&nlocalvarinfos,sizeof(nlocalvarinfos)));
_CHECK_IO(SafeWrite(v,write,up,&nlineinfos,sizeof(nlineinfos)));
_CHECK_IO(SafeWrite(v,write,up,&ndefaultparams,sizeof(ndefaultparams)));
_CHECK_IO(SafeWrite(v,write,up,&ninstructions,sizeof(ninstructions)));
_CHECK_IO(SafeWrite(v,write,up,&nfunctions,sizeof(nfunctions)));
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
for(i=0;i<nliterals;i++){
_CHECK_IO(WriteObject(v,up,write,_literals[i]));
}
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
for(i=0;i<nparameters;i++){
_CHECK_IO(WriteObject(v,up,write,_parameters[i]));
}
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
for(i=0;i<noutervalues;i++){
_CHECK_IO(SafeWrite(v,write,up,&_outervalues[i]._type,sizeof(SQUnsignedInteger)));
_CHECK_IO(WriteObject(v,up,write,_outervalues[i]._src));
_CHECK_IO(WriteObject(v,up,write,_outervalues[i]._name));
}
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
for(i=0;i<nlocalvarinfos;i++){
SQLocalVarInfo &lvi=_localvarinfos[i];
_CHECK_IO(WriteObject(v,up,write,lvi._name));
_CHECK_IO(SafeWrite(v,write,up,&lvi._pos,sizeof(SQUnsignedInteger)));
_CHECK_IO(SafeWrite(v,write,up,&lvi._start_op,sizeof(SQUnsignedInteger)));
_CHECK_IO(SafeWrite(v,write,up,&lvi._end_op,sizeof(SQUnsignedInteger)));
}
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
_CHECK_IO(SafeWrite(v,write,up,_lineinfos,sizeof(SQLineInfo)*nlineinfos));
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
_CHECK_IO(SafeWrite(v,write,up,_defaultparams,sizeof(SQInteger)*ndefaultparams));
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
_CHECK_IO(SafeWrite(v,write,up,_instructions,sizeof(SQInstruction)*ninstructions));
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
for(i=0;i<nfunctions;i++){
_CHECK_IO(_funcproto(_functions[i])->Save(v,up,write));
}
_CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize)));
_CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator)));
_CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams)));
return true;
}
bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret)
{
SQInteger i, nliterals,nparameters;
SQInteger noutervalues ,nlocalvarinfos ;
SQInteger nlineinfos,ninstructions ,nfunctions,ndefaultparams ;
SQObjectPtr sourcename, name;
SQObjectPtr o;
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
_CHECK_IO(ReadObject(v, up, read, sourcename));
_CHECK_IO(ReadObject(v, up, read, name));
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
_CHECK_IO(SafeRead(v,read,up, &nliterals, sizeof(nliterals)));
_CHECK_IO(SafeRead(v,read,up, &nparameters, sizeof(nparameters)));
_CHECK_IO(SafeRead(v,read,up, &noutervalues, sizeof(noutervalues)));
_CHECK_IO(SafeRead(v,read,up, &nlocalvarinfos, sizeof(nlocalvarinfos)));
_CHECK_IO(SafeRead(v,read,up, &nlineinfos, sizeof(nlineinfos)));
_CHECK_IO(SafeRead(v,read,up, &ndefaultparams, sizeof(ndefaultparams)));
_CHECK_IO(SafeRead(v,read,up, &ninstructions, sizeof(ninstructions)));
_CHECK_IO(SafeRead(v,read,up, &nfunctions, sizeof(nfunctions)));
SQFunctionProto *f = SQFunctionProto::Create(_opt_ss(v),ninstructions,nliterals,nparameters,
nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams);
SQObjectPtr proto = f; //gets a ref in case of failure
f->_sourcename = sourcename;
f->_name = name;
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
for(i = 0;i < nliterals; i++){
_CHECK_IO(ReadObject(v, up, read, o));
f->_literals[i] = o;
}
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
for(i = 0; i < nparameters; i++){
_CHECK_IO(ReadObject(v, up, read, o));
f->_parameters[i] = o;
}
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
for(i = 0; i < noutervalues; i++){
SQUnsignedInteger type;
SQObjectPtr name;
_CHECK_IO(SafeRead(v,read,up, &type, sizeof(SQUnsignedInteger)));
_CHECK_IO(ReadObject(v, up, read, o));
_CHECK_IO(ReadObject(v, up, read, name));
f->_outervalues[i] = SQOuterVar(name,o, (SQOuterType)type);
}
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
for(i = 0; i < nlocalvarinfos; i++){
SQLocalVarInfo lvi;
_CHECK_IO(ReadObject(v, up, read, lvi._name));
_CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(SQUnsignedInteger)));
_CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(SQUnsignedInteger)));
_CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(SQUnsignedInteger)));
f->_localvarinfos[i] = lvi;
}
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
_CHECK_IO(SafeRead(v,read,up, f->_lineinfos, sizeof(SQLineInfo)*nlineinfos));
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
_CHECK_IO(SafeRead(v,read,up, f->_defaultparams, sizeof(SQInteger)*ndefaultparams));
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
_CHECK_IO(SafeRead(v,read,up, f->_instructions, sizeof(SQInstruction)*ninstructions));
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
for(i = 0; i < nfunctions; i++){
_CHECK_IO(_funcproto(o)->Load(v, up, read, o));
f->_functions[i] = o;
}
_CHECK_IO(SafeRead(v,read,up, &f->_stacksize, sizeof(f->_stacksize)));
_CHECK_IO(SafeRead(v,read,up, &f->_bgenerator, sizeof(f->_bgenerator)));
_CHECK_IO(SafeRead(v,read,up, &f->_varparams, sizeof(f->_varparams)));
ret = f;
return true;
}
#ifndef NO_GARBAGE_COLLECTOR
#define START_MARK() if(!(_uiRef&MARK_FLAG)){ \
_uiRef|=MARK_FLAG;
#define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \
AddToChain(chain, this); }
void SQVM::Mark(SQCollectable **chain)
{
START_MARK()
SQSharedState::MarkObject(_lasterror,chain);
SQSharedState::MarkObject(_errorhandler,chain);
SQSharedState::MarkObject(_debughook_closure,chain);
SQSharedState::MarkObject(_roottable, chain);
SQSharedState::MarkObject(temp_reg, chain);
for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);
for(SQInteger k = 0; k < _callsstacksize; k++) SQSharedState::MarkObject(_callsstack[k]._closure, chain);
END_MARK()
}
void SQArray::Mark(SQCollectable **chain)
{
START_MARK()
SQInteger len = _values.size();
for(SQInteger i = 0;i < len; i++) SQSharedState::MarkObject(_values[i], chain);
END_MARK()
}
void SQTable::Mark(SQCollectable **chain)
{
START_MARK()
if(_delegate) _delegate->Mark(chain);
SQInteger len = _numofnodes;
for(SQInteger i = 0; i < len; i++){
SQSharedState::MarkObject(_nodes[i].key, chain);
SQSharedState::MarkObject(_nodes[i].val, chain);
}
END_MARK()
}
void SQClass::Mark(SQCollectable **chain)
{
START_MARK()
_members->Mark(chain);
if(_base) _base->Mark(chain);
SQSharedState::MarkObject(_attributes, chain);
for(SQUnsignedInteger i =0; i< _defaultvalues.size(); i++) {
SQSharedState::MarkObject(_defaultvalues[i].val, chain);
SQSharedState::MarkObject(_defaultvalues[i].attrs, chain);
}
for(SQUnsignedInteger j =0; j< _methods.size(); j++) {
SQSharedState::MarkObject(_methods[j].val, chain);
SQSharedState::MarkObject(_methods[j].attrs, chain);
}
for(SQUnsignedInteger k =0; k< MT_LAST; k++) {
SQSharedState::MarkObject(_metamethods[k], chain);
}
END_MARK()
}
void SQInstance::Mark(SQCollectable **chain)
{
START_MARK()
_class->Mark(chain);
SQUnsignedInteger nvalues = _class->_defaultvalues.size();
for(SQUnsignedInteger i =0; i< nvalues; i++) {
SQSharedState::MarkObject(_values[i], chain);
}
END_MARK()
}
void SQGenerator::Mark(SQCollectable **chain)
{
START_MARK()
for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);
SQSharedState::MarkObject(_closure, chain);
END_MARK()
}
void SQFunctionProto::Mark(SQCollectable **chain)
{
START_MARK()
for(SQInteger i = 0; i < _nliterals; i++) SQSharedState::MarkObject(_literals[i], chain);
for(SQInteger k = 0; k < _nfunctions; k++) SQSharedState::MarkObject(_functions[k], chain);
END_MARK()
}
void SQClosure::Mark(SQCollectable **chain)
{
START_MARK()
if(_base) _base->Mark(chain);
SQFunctionProto *fp = _function;
fp->Mark(chain);
for(SQInteger i = 0; i < fp->_noutervalues; i++) SQSharedState::MarkObject(_outervalues[i], chain);
for(SQInteger k = 0; k < fp->_ndefaultparams; k++) SQSharedState::MarkObject(_defaultparams[k], chain);
END_MARK()
}
void SQNativeClosure::Mark(SQCollectable **chain)
{
START_MARK()
for(SQUnsignedInteger i = 0; i < _noutervalues; i++) SQSharedState::MarkObject(_outervalues[i], chain);
END_MARK()
}
void SQOuter::Mark(SQCollectable **chain)
{
START_MARK()
/* If the valptr points to a closed value, that value is alive */
if(_valptr == &_value) {
SQSharedState::MarkObject(_value, chain);
}
END_MARK()
}
void SQUserData::Mark(SQCollectable **chain){
START_MARK()
if(_delegate) _delegate->Mark(chain);
END_MARK()
}
void SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; }
#endif

View File

@ -0,0 +1,354 @@
/* see copyright notice in squirrel.h */
#ifndef _SQOBJECT_H_
#define _SQOBJECT_H_
#include "squtils.h"
#ifdef _SQ64
#define UINT_MINUS_ONE (0xFFFFFFFFFFFFFFFF)
#else
#define UINT_MINUS_ONE (0xFFFFFFFF)
#endif
#define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R'))
#define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T'))
#define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L'))
struct SQSharedState;
enum SQMetaMethod{
MT_ADD=0,
MT_SUB=1,
MT_MUL=2,
MT_DIV=3,
MT_UNM=4,
MT_MODULO=5,
MT_SET=6,
MT_GET=7,
MT_TYPEOF=8,
MT_NEXTI=9,
MT_CMP=10,
MT_CALL=11,
MT_CLONED=12,
MT_NEWSLOT=13,
MT_DELSLOT=14,
MT_TOSTRING=15,
MT_NEWMEMBER=16,
MT_INHERITED=17,
MT_LAST = 18
};
#define MM_ADD _SC("_add")
#define MM_SUB _SC("_sub")
#define MM_MUL _SC("_mul")
#define MM_DIV _SC("_div")
#define MM_UNM _SC("_unm")
#define MM_MODULO _SC("_modulo")
#define MM_SET _SC("_set")
#define MM_GET _SC("_get")
#define MM_TYPEOF _SC("_typeof")
#define MM_NEXTI _SC("_nexti")
#define MM_CMP _SC("_cmp")
#define MM_CALL _SC("_call")
#define MM_CLONED _SC("_cloned")
#define MM_NEWSLOT _SC("_newslot")
#define MM_DELSLOT _SC("_delslot")
#define MM_TOSTRING _SC("_tostring")
#define MM_NEWMEMBER _SC("_newmember")
#define MM_INHERITED _SC("_inherited")
#define _CONSTRUCT_VECTOR(type,size,ptr) { \
for(SQInteger n = 0; n < ((SQInteger)size); n++) { \
new (&ptr[n]) type(); \
} \
}
#define _DESTRUCT_VECTOR(type,size,ptr) { \
for(SQInteger nl = 0; nl < ((SQInteger)size); nl++) { \
ptr[nl].~type(); \
} \
}
#define _COPY_VECTOR(dest,src,size) { \
for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \
dest[_n_] = src[_n_]; \
} \
}
#define _NULL_SQOBJECT_VECTOR(vec,size) { \
for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \
vec[_n_].Null(); \
} \
}
#define MINPOWER2 4
struct SQRefCounted
{
SQUnsignedInteger _uiRef;
struct SQWeakRef *_weakref;
SQRefCounted() { _uiRef = 0; _weakref = NULL; }
virtual ~SQRefCounted();
SQWeakRef *GetWeakRef(SQObjectType type);
virtual void Release()=0;
};
struct SQWeakRef : SQRefCounted
{
void Release();
SQObject _obj;
};
#define _realval(o) (type((o)) != OT_WEAKREF?(SQObject)o:_weakref(o)->_obj)
struct SQObjectPtr;
#define __AddRef(type,unval) if(ISREFCOUNTED(type)) \
{ \
unval.pRefCounted->_uiRef++; \
}
#define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)==0)) \
{ \
unval.pRefCounted->Release(); \
}
#define __ObjRelease(obj) { \
if((obj)) { \
(obj)->_uiRef--; \
if((obj)->_uiRef == 0) \
(obj)->Release(); \
(obj) = NULL; \
} \
}
#define __ObjAddRef(obj) { \
(obj)->_uiRef++; \
}
#define type(obj) ((obj)._type)
#define is_delegable(t) (type(t)&SQOBJECT_DELEGABLE)
#define raw_type(obj) _RAW_TYPE((obj)._type)
#define _integer(obj) ((obj)._unVal.nInteger)
#define _float(obj) ((obj)._unVal.fFloat)
#define _string(obj) ((obj)._unVal.pString)
#define _table(obj) ((obj)._unVal.pTable)
#define _array(obj) ((obj)._unVal.pArray)
#define _closure(obj) ((obj)._unVal.pClosure)
#define _generator(obj) ((obj)._unVal.pGenerator)
#define _nativeclosure(obj) ((obj)._unVal.pNativeClosure)
#define _userdata(obj) ((obj)._unVal.pUserData)
#define _userpointer(obj) ((obj)._unVal.pUserPointer)
#define _thread(obj) ((obj)._unVal.pThread)
#define _funcproto(obj) ((obj)._unVal.pFunctionProto)
#define _class(obj) ((obj)._unVal.pClass)
#define _instance(obj) ((obj)._unVal.pInstance)
#define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable)
#define _weakref(obj) ((obj)._unVal.pWeakRef)
#define _outer(obj) ((obj)._unVal.pOuter)
#define _refcounted(obj) ((obj)._unVal.pRefCounted)
#define _rawval(obj) ((obj)._unVal.raw)
#define _stringval(obj) (obj)._unVal.pString->_val
#define _userdataval(obj) ((SQUserPointer)sq_aligning((obj)._unVal.pUserData + 1))
#define tofloat(num) ((type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num))
#define tointeger(num) ((type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num))
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
#if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64)
#define SQ_REFOBJECT_INIT() SQ_OBJECT_RAWINIT()
#else
#define SQ_REFOBJECT_INIT()
#endif
#define _REF_TYPE_DECL(type,_class,sym) \
SQObjectPtr(_class * x) \
{ \
SQ_OBJECT_RAWINIT() \
_type=type; \
_unVal.sym = x; \
assert(_unVal.pTable); \
_unVal.pRefCounted->_uiRef++; \
} \
inline SQObjectPtr& operator=(_class *x) \
{ \
SQObjectType tOldType; \
SQObjectValue unOldVal; \
tOldType=_type; \
unOldVal=_unVal; \
_type = type; \
SQ_REFOBJECT_INIT() \
_unVal.sym = x; \
_unVal.pRefCounted->_uiRef++; \
__Release(tOldType,unOldVal); \
return *this; \
}
#define _SCALAR_TYPE_DECL(type,_class,sym) \
SQObjectPtr(_class x) \
{ \
SQ_OBJECT_RAWINIT() \
_type=type; \
_unVal.sym = x; \
} \
inline SQObjectPtr& operator=(_class x) \
{ \
__Release(_type,_unVal); \
_type = type; \
SQ_OBJECT_RAWINIT() \
_unVal.sym = x; \
return *this; \
}
struct SQObjectPtr : public SQObject
{
SQObjectPtr()
{
SQ_OBJECT_RAWINIT()
_type=OT_NULL;
_unVal.pUserPointer=NULL;
}
SQObjectPtr(const SQObjectPtr &o)
{
//SQ_OBJECT_RAWINIT()
_type=o._type;
_unVal=o._unVal;
__AddRef(_type,_unVal);
}
SQObjectPtr(const SQObject &o)
{
//SQ_OBJECT_RAWINIT()
_type=o._type;
_unVal=o._unVal;
__AddRef(_type,_unVal);
}
_REF_TYPE_DECL(OT_TABLE,SQTable,pTable)
_REF_TYPE_DECL(OT_CLASS,SQClass,pClass)
_REF_TYPE_DECL(OT_INSTANCE,SQInstance,pInstance)
_REF_TYPE_DECL(OT_ARRAY,SQArray,pArray)
_REF_TYPE_DECL(OT_CLOSURE,SQClosure,pClosure)
_REF_TYPE_DECL(OT_NATIVECLOSURE,SQNativeClosure,pNativeClosure)
_REF_TYPE_DECL(OT_OUTER,SQOuter,pOuter)
_REF_TYPE_DECL(OT_GENERATOR,SQGenerator,pGenerator)
_REF_TYPE_DECL(OT_STRING,SQString,pString)
_REF_TYPE_DECL(OT_USERDATA,SQUserData,pUserData)
_REF_TYPE_DECL(OT_WEAKREF,SQWeakRef,pWeakRef)
_REF_TYPE_DECL(OT_THREAD,SQVM,pThread)
_REF_TYPE_DECL(OT_FUNCPROTO,SQFunctionProto,pFunctionProto)
_SCALAR_TYPE_DECL(OT_INTEGER,SQInteger,nInteger)
_SCALAR_TYPE_DECL(OT_FLOAT,SQFloat,fFloat)
_SCALAR_TYPE_DECL(OT_USERPOINTER,SQUserPointer,pUserPointer)
SQObjectPtr(bool bBool)
{
SQ_OBJECT_RAWINIT()
_type = OT_BOOL;
_unVal.nInteger = bBool?1:0;
}
inline SQObjectPtr& operator=(bool b)
{
__Release(_type,_unVal);
SQ_OBJECT_RAWINIT()
_type = OT_BOOL;
_unVal.nInteger = b?1:0;
return *this;
}
~SQObjectPtr()
{
__Release(_type,_unVal);
}
inline SQObjectPtr& operator=(const SQObjectPtr& obj)
{
SQObjectType tOldType;
SQObjectValue unOldVal;
tOldType=_type;
unOldVal=_unVal;
_unVal = obj._unVal;
_type = obj._type;
__AddRef(_type,_unVal);
__Release(tOldType,unOldVal);
return *this;
}
inline SQObjectPtr& operator=(const SQObject& obj)
{
SQObjectType tOldType;
SQObjectValue unOldVal;
tOldType=_type;
unOldVal=_unVal;
_unVal = obj._unVal;
_type = obj._type;
__AddRef(_type,_unVal);
__Release(tOldType,unOldVal);
return *this;
}
inline void Null()
{
__Release(_type ,_unVal);
_type = OT_NULL;
_unVal.raw = NULL;
}
private:
SQObjectPtr(const SQChar *){} //safety
};
inline void _Swap(SQObject &a,SQObject &b)
{
SQObjectType tOldType = a._type;
SQObjectValue unOldVal = a._unVal;
a._type = b._type;
a._unVal = b._unVal;
b._type = tOldType;
b._unVal = unOldVal;
}
/////////////////////////////////////////////////////////////////////////////////////
#ifndef NO_GARBAGE_COLLECTOR
#define MARK_FLAG 0x80000000
struct SQCollectable : public SQRefCounted {
SQCollectable *_next;
SQCollectable *_prev;
SQSharedState *_sharedstate;
virtual SQObjectType GetType()=0;
virtual void Release()=0;
virtual void Mark(SQCollectable **chain)=0;
void UnMark();
virtual void Finalize()=0;
static void AddToChain(SQCollectable **chain,SQCollectable *c);
static void RemoveFromChain(SQCollectable **chain,SQCollectable *c);
};
#define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj)
#define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);}
#define CHAINABLE_OBJ SQCollectable
#define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;}
#else
#define ADD_TO_CHAIN(chain,obj) ((void)0)
#define REMOVE_FROM_CHAIN(chain,obj) ((void)0)
#define CHAINABLE_OBJ SQRefCounted
#define INIT_CHAIN() ((void)0)
#endif
struct SQDelegable : public CHAINABLE_OBJ {
bool SetDelegate(SQTable *m);
virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
SQTable *_delegate;
};
SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx);
typedef sqvector<SQObjectPtr> SQObjectPtrVec;
typedef sqvector<SQInteger> SQIntVec;
const SQChar *GetTypeName(const SQObjectPtr &obj1);
const SQChar *IdType2Name(SQObjectType type);
#endif //_SQOBJECT_H_

View File

@ -0,0 +1,132 @@
/* see copyright notice in squirrel.h */
#ifndef _SQOPCODES_H_
#define _SQOPCODES_H_
#define MAX_FUNC_STACKSIZE 0xFF
#define MAX_LITERALS ((SQInteger)0x7FFFFFFF)
enum BitWiseOP {
BW_AND = 0,
BW_OR = 2,
BW_XOR = 3,
BW_SHIFTL = 4,
BW_SHIFTR = 5,
BW_USHIFTR = 6
};
enum CmpOP {
CMP_G = 0,
CMP_GE = 2,
CMP_L = 3,
CMP_LE = 4,
CMP_3W = 5
};
enum NewObjectType {
NOT_TABLE = 0,
NOT_ARRAY = 1,
NOT_CLASS = 2
};
enum AppendArrayType {
AAT_STACK = 0,
AAT_LITERAL = 1,
AAT_INT = 2,
AAT_FLOAT = 3,
AAT_BOOL = 4
};
enum SQOpcode
{
_OP_LINE= 0x00,
_OP_LOAD= 0x01,
_OP_LOADINT= 0x02,
_OP_LOADFLOAT= 0x03,
_OP_DLOAD= 0x04,
_OP_TAILCALL= 0x05,
_OP_CALL= 0x06,
_OP_PREPCALL= 0x07,
_OP_PREPCALLK= 0x08,
_OP_GETK= 0x09,
_OP_MOVE= 0x0A,
_OP_NEWSLOT= 0x0B,
_OP_DELETE= 0x0C,
_OP_SET= 0x0D,
_OP_GET= 0x0E,
_OP_EQ= 0x0F,
_OP_NE= 0x10,
_OP_ADD= 0x11,
_OP_SUB= 0x12,
_OP_MUL= 0x13,
_OP_DIV= 0x14,
_OP_MOD= 0x15,
_OP_BITW= 0x16,
_OP_RETURN= 0x17,
_OP_LOADNULLS= 0x18,
_OP_LOADROOT= 0x19,
_OP_LOADBOOL= 0x1A,
_OP_DMOVE= 0x1B,
_OP_JMP= 0x1C,
//_OP_JNZ= 0x1D,
_OP_JCMP= 0x1D,
_OP_JZ= 0x1E,
_OP_SETOUTER= 0x1F,
_OP_GETOUTER= 0x20,
_OP_NEWOBJ= 0x21,
_OP_APPENDARRAY= 0x22,
_OP_COMPARITH= 0x23,
_OP_INC= 0x24,
_OP_INCL= 0x25,
_OP_PINC= 0x26,
_OP_PINCL= 0x27,
_OP_CMP= 0x28,
_OP_EXISTS= 0x29,
_OP_INSTANCEOF= 0x2A,
_OP_AND= 0x2B,
_OP_OR= 0x2C,
_OP_NEG= 0x2D,
_OP_NOT= 0x2E,
_OP_BWNOT= 0x2F,
_OP_CLOSURE= 0x30,
_OP_YIELD= 0x31,
_OP_RESUME= 0x32,
_OP_FOREACH= 0x33,
_OP_POSTFOREACH= 0x34,
_OP_CLONE= 0x35,
_OP_TYPEOF= 0x36,
_OP_PUSHTRAP= 0x37,
_OP_POPTRAP= 0x38,
_OP_THROW= 0x39,
_OP_NEWSLOTA= 0x3A,
_OP_GETBASE= 0x3B,
_OP_CLOSE= 0x3C,
};
struct SQInstructionDesc {
const SQChar *name;
};
struct SQInstruction
{
SQInstruction(){};
SQInstruction(SQOpcode _op,SQInteger a0=0,SQInteger a1=0,SQInteger a2=0,SQInteger a3=0)
{ op = _op;
_arg0 = (unsigned char)a0;_arg1 = (SQInt32)a1;
_arg2 = (unsigned char)a2;_arg3 = (unsigned char)a3;
}
SQInt32 _arg1;
unsigned char op;
unsigned char _arg0;
unsigned char _arg2;
unsigned char _arg3;
};
#include "squtils.h"
typedef sqvector<SQInstruction> SQInstructionVec;
#define NEW_SLOT_ATTRIBUTES_FLAG 0x01
#define NEW_SLOT_STATIC_FLAG 0x02
#endif // _SQOPCODES_H_

View File

@ -0,0 +1,19 @@
/* see copyright notice in squirrel.h */
#ifndef _SQPCHEADER_H_
#define _SQPCHEADER_H_
#if defined(_MSC_VER) && defined(_DEBUG)
#include <crtdbg.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <new>
//squirrel stuff
#include <squirrel.h>
#include "sqobject.h"
#include "sqstate.h"
#endif //_SQPCHEADER_H_

View File

@ -0,0 +1,648 @@
/*
see copyright notice in squirrel.h
*/
#include "sqpcheader.h"
#include "sqopcodes.h"
#include "sqvm.h"
#include "sqfuncproto.h"
#include "sqclosure.h"
#include "sqstring.h"
#include "sqtable.h"
#include "sqarray.h"
#include "squserdata.h"
#include "sqclass.h"
//SQObjectPtr _null_;
//SQObjectPtr _true_(true);
//SQObjectPtr _false_(false);
//SQObjectPtr _one_((SQInteger)1);
//SQObjectPtr _minusone_((SQInteger)-1);
SQSharedState::SQSharedState()
{
_compilererrorhandler = NULL;
_printfunc = NULL;
_errorfunc = NULL;
_debuginfo = false;
_notifyallexceptions = false;
}
#define newsysstring(s) { \
_systemstrings->push_back(SQString::Create(this,s)); \
}
#define newmetamethod(s) { \
_metamethods->push_back(SQString::Create(this,s)); \
_table(_metamethodsmap)->NewSlot(_metamethods->back(),(SQInteger)(_metamethods->size()-1)); \
}
bool CompileTypemask(SQIntVec &res,const SQChar *typemask)
{
SQInteger i = 0;
SQInteger mask = 0;
while(typemask[i] != 0) {
switch(typemask[i]){
case 'o': mask |= _RT_NULL; break;
case 'i': mask |= _RT_INTEGER; break;
case 'f': mask |= _RT_FLOAT; break;
case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break;
case 's': mask |= _RT_STRING; break;
case 't': mask |= _RT_TABLE; break;
case 'a': mask |= _RT_ARRAY; break;
case 'u': mask |= _RT_USERDATA; break;
case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break;
case 'b': mask |= _RT_BOOL; break;
case 'g': mask |= _RT_GENERATOR; break;
case 'p': mask |= _RT_USERPOINTER; break;
case 'v': mask |= _RT_THREAD; break;
case 'x': mask |= _RT_INSTANCE; break;
case 'y': mask |= _RT_CLASS; break;
case 'r': mask |= _RT_WEAKREF; break;
case '.': mask = -1; res.push_back(mask); i++; mask = 0; continue;
case ' ': i++; continue; //ignores spaces
default:
return false;
}
i++;
if(typemask[i] == '|') {
i++;
if(typemask[i] == 0)
return false;
continue;
}
res.push_back(mask);
mask = 0;
}
return true;
}
SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz)
{
SQInteger i=0;
SQTable *t=SQTable::Create(ss,0);
while(funcz[i].name!=0){
SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f,0);
nc->_nparamscheck = funcz[i].nparamscheck;
nc->_name = SQString::Create(ss,funcz[i].name);
if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask))
return NULL;
t->NewSlot(SQString::Create(ss,funcz[i].name),nc);
i++;
}
return t;
}
void SQSharedState::Init()
{
_scratchpad=NULL;
_scratchpadsize=0;
#ifndef NO_GARBAGE_COLLECTOR
_gc_chain=NULL;
#endif
_stringtable = (SQStringTable*)SQ_MALLOC(sizeof(SQStringTable));
new (_stringtable) SQStringTable(this);
sq_new(_metamethods,SQObjectPtrVec);
sq_new(_systemstrings,SQObjectPtrVec);
sq_new(_types,SQObjectPtrVec);
_metamethodsmap = SQTable::Create(this,MT_LAST-1);
//adding type strings to avoid memory trashing
//types names
newsysstring(_SC("null"));
newsysstring(_SC("table"));
newsysstring(_SC("array"));
newsysstring(_SC("closure"));
newsysstring(_SC("string"));
newsysstring(_SC("userdata"));
newsysstring(_SC("integer"));
newsysstring(_SC("float"));
newsysstring(_SC("userpointer"));
newsysstring(_SC("function"));
newsysstring(_SC("generator"));
newsysstring(_SC("thread"));
newsysstring(_SC("class"));
newsysstring(_SC("instance"));
newsysstring(_SC("bool"));
//meta methods
newmetamethod(MM_ADD);
newmetamethod(MM_SUB);
newmetamethod(MM_MUL);
newmetamethod(MM_DIV);
newmetamethod(MM_UNM);
newmetamethod(MM_MODULO);
newmetamethod(MM_SET);
newmetamethod(MM_GET);
newmetamethod(MM_TYPEOF);
newmetamethod(MM_NEXTI);
newmetamethod(MM_CMP);
newmetamethod(MM_CALL);
newmetamethod(MM_CLONED);
newmetamethod(MM_NEWSLOT);
newmetamethod(MM_DELSLOT);
newmetamethod(MM_TOSTRING);
newmetamethod(MM_NEWMEMBER);
newmetamethod(MM_INHERITED);
_constructoridx = SQString::Create(this,_SC("constructor"));
_registry = SQTable::Create(this,0);
_consts = SQTable::Create(this,0);
_table_default_delegate = CreateDefaultDelegate(this,_table_default_delegate_funcz);
_array_default_delegate = CreateDefaultDelegate(this,_array_default_delegate_funcz);
_string_default_delegate = CreateDefaultDelegate(this,_string_default_delegate_funcz);
_number_default_delegate = CreateDefaultDelegate(this,_number_default_delegate_funcz);
_closure_default_delegate = CreateDefaultDelegate(this,_closure_default_delegate_funcz);
_generator_default_delegate = CreateDefaultDelegate(this,_generator_default_delegate_funcz);
_thread_default_delegate = CreateDefaultDelegate(this,_thread_default_delegate_funcz);
_class_default_delegate = CreateDefaultDelegate(this,_class_default_delegate_funcz);
_instance_default_delegate = CreateDefaultDelegate(this,_instance_default_delegate_funcz);
_weakref_default_delegate = CreateDefaultDelegate(this,_weakref_default_delegate_funcz);
}
SQSharedState::~SQSharedState()
{
_constructoridx.Null();
_table(_registry)->Finalize();
_table(_consts)->Finalize();
_table(_metamethodsmap)->Finalize();
_registry.Null();
_consts.Null();
_metamethodsmap.Null();
while(!_systemstrings->empty()) {
_systemstrings->back().Null();
_systemstrings->pop_back();
}
_thread(_root_vm)->Finalize();
_root_vm.Null();
_table_default_delegate.Null();
_array_default_delegate.Null();
_string_default_delegate.Null();
_number_default_delegate.Null();
_closure_default_delegate.Null();
_generator_default_delegate.Null();
_thread_default_delegate.Null();
_class_default_delegate.Null();
_instance_default_delegate.Null();
_weakref_default_delegate.Null();
_refs_table.Finalize();
#ifndef NO_GARBAGE_COLLECTOR
SQCollectable *t = _gc_chain;
SQCollectable *nx = NULL;
while(t) {
t->_uiRef++;
t->Finalize();
nx = t->_next;
if(--t->_uiRef == 0)
t->Release();
t=nx;
}
assert(_gc_chain==NULL); //just to proove a theory
while(_gc_chain){
_gc_chain->_uiRef++;
_gc_chain->Release();
}
#endif
sq_delete(_types,SQObjectPtrVec);
sq_delete(_systemstrings,SQObjectPtrVec);
sq_delete(_metamethods,SQObjectPtrVec);
sq_delete(_stringtable,SQStringTable);
if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize);
}
SQInteger SQSharedState::GetMetaMethodIdxByName(const SQObjectPtr &name)
{
if(type(name) != OT_STRING)
return -1;
SQObjectPtr ret;
if(_table(_metamethodsmap)->Get(name,ret)) {
return _integer(ret);
}
return -1;
}
#ifndef NO_GARBAGE_COLLECTOR
void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain)
{
switch(type(o)){
case OT_TABLE:_table(o)->Mark(chain);break;
case OT_ARRAY:_array(o)->Mark(chain);break;
case OT_USERDATA:_userdata(o)->Mark(chain);break;
case OT_CLOSURE:_closure(o)->Mark(chain);break;
case OT_NATIVECLOSURE:_nativeclosure(o)->Mark(chain);break;
case OT_GENERATOR:_generator(o)->Mark(chain);break;
case OT_THREAD:_thread(o)->Mark(chain);break;
case OT_CLASS:_class(o)->Mark(chain);break;
case OT_INSTANCE:_instance(o)->Mark(chain);break;
case OT_OUTER:_outer(o)->Mark(chain);break;
case OT_FUNCPROTO:_funcproto(o)->Mark(chain);break;
default: break; //shutup compiler
}
}
void SQSharedState::RunMark(SQVM *vm,SQCollectable **tchain)
{
SQVM *vms = _thread(_root_vm);
vms->Mark(tchain);
_refs_table.Mark(tchain);
MarkObject(_registry,tchain);
MarkObject(_consts,tchain);
MarkObject(_metamethodsmap,tchain);
MarkObject(_table_default_delegate,tchain);
MarkObject(_array_default_delegate,tchain);
MarkObject(_string_default_delegate,tchain);
MarkObject(_number_default_delegate,tchain);
MarkObject(_generator_default_delegate,tchain);
MarkObject(_thread_default_delegate,tchain);
MarkObject(_closure_default_delegate,tchain);
MarkObject(_class_default_delegate,tchain);
MarkObject(_instance_default_delegate,tchain);
MarkObject(_weakref_default_delegate,tchain);
}
SQInteger SQSharedState::ResurrectUnreachable(SQVM *vm)
{
SQInteger n=0;
SQCollectable *tchain=NULL;
RunMark(vm,&tchain);
SQCollectable *resurrected = _gc_chain;
SQCollectable *t = resurrected;
//SQCollectable *nx = NULL;
_gc_chain = tchain;
SQArray *ret = NULL;
if(resurrected) {
ret = SQArray::Create(this,0);
SQCollectable *rlast = NULL;
while(t) {
rlast = t;
SQObjectType type = t->GetType();
if(type != OT_FUNCPROTO && type != OT_OUTER) {
SQObject sqo;
sqo._type = type;
sqo._unVal.pRefCounted = t;
ret->Append(sqo);
}
t = t->_next;
n++;
}
assert(rlast->_next == NULL);
rlast->_next = _gc_chain;
if(_gc_chain)
{
_gc_chain->_prev = rlast;
}
_gc_chain = resurrected;
}
t = _gc_chain;
while(t) {
t->UnMark();
t = t->_next;
}
if(ret) {
SQObjectPtr temp = ret;
vm->Push(temp);
}
else {
vm->PushNull();
}
return n;
}
SQInteger SQSharedState::CollectGarbage(SQVM *vm)
{
SQInteger n=0;
SQCollectable *tchain=NULL;
RunMark(vm,&tchain);
SQCollectable *t = _gc_chain;
SQCollectable *nx = NULL;
while(t) {
t->_uiRef++;
t->Finalize();
nx = t->_next;
if(--t->_uiRef == 0)
t->Release();
t = nx;
n++;
}
t = tchain;
while(t) {
t->UnMark();
t = t->_next;
}
_gc_chain = tchain;
return n;
}
#endif
#ifndef NO_GARBAGE_COLLECTOR
void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c)
{
c->_prev = NULL;
c->_next = *chain;
if(*chain) (*chain)->_prev = c;
*chain = c;
}
void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c)
{
if(c->_prev) c->_prev->_next = c->_next;
else *chain = c->_next;
if(c->_next)
c->_next->_prev = c->_prev;
c->_next = NULL;
c->_prev = NULL;
}
#endif
SQChar* SQSharedState::GetScratchPad(SQInteger size)
{
SQInteger newsize;
if(size>0) {
if(_scratchpadsize < size) {
newsize = size + (size>>1);
_scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
_scratchpadsize = newsize;
}else if(_scratchpadsize >= (size<<5)) {
newsize = _scratchpadsize >> 1;
_scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
_scratchpadsize = newsize;
}
}
return _scratchpad;
}
RefTable::RefTable()
{
AllocNodes(4);
}
void RefTable::Finalize()
{
RefNode *nodes = _nodes;
for(SQUnsignedInteger n = 0; n < _numofslots; n++) {
nodes->obj.Null();
nodes++;
}
}
RefTable::~RefTable()
{
SQ_FREE(_buckets,(_numofslots * sizeof(RefNode *)) + (_numofslots * sizeof(RefNode)));
}
#ifndef NO_GARBAGE_COLLECTOR
void RefTable::Mark(SQCollectable **chain)
{
RefNode *nodes = (RefNode *)_nodes;
for(SQUnsignedInteger n = 0; n < _numofslots; n++) {
if(type(nodes->obj) != OT_NULL) {
SQSharedState::MarkObject(nodes->obj,chain);
}
nodes++;
}
}
#endif
void RefTable::AddRef(SQObject &obj)
{
SQHash mainpos;
RefNode *prev;
RefNode *ref = Get(obj,mainpos,&prev,true);
ref->refs++;
}
SQUnsignedInteger RefTable::GetRefCount(SQObject &obj)
{
SQHash mainpos;
RefNode *prev;
RefNode *ref = Get(obj,mainpos,&prev,true);
return ref->refs;
}
SQBool RefTable::Release(SQObject &obj)
{
SQHash mainpos;
RefNode *prev;
RefNode *ref = Get(obj,mainpos,&prev,false);
if(ref) {
if(--ref->refs == 0) {
SQObjectPtr o = ref->obj;
if(prev) {
prev->next = ref->next;
}
else {
_buckets[mainpos] = ref->next;
}
ref->next = _freelist;
_freelist = ref;
_slotused--;
ref->obj.Null();
//<<FIXME>>test for shrink?
return SQTrue;
}
}
else {
assert(0);
}
return SQFalse;
}
void RefTable::Resize(SQUnsignedInteger size)
{
RefNode **oldbucks = _buckets;
RefNode *t = _nodes;
SQUnsignedInteger oldnumofslots = _numofslots;
AllocNodes(size);
//rehash
SQUnsignedInteger nfound = 0;
for(SQUnsignedInteger n = 0; n < oldnumofslots; n++) {
if(type(t->obj) != OT_NULL) {
//add back;
assert(t->refs != 0);
RefNode *nn = Add(::HashObj(t->obj)&(_numofslots-1),t->obj);
nn->refs = t->refs;
t->obj.Null();
nfound++;
}
t++;
}
assert(nfound == oldnumofslots);
SQ_FREE(oldbucks,(oldnumofslots * sizeof(RefNode *)) + (oldnumofslots * sizeof(RefNode)));
}
RefTable::RefNode *RefTable::Add(SQHash mainpos,SQObject &obj)
{
RefNode *t = _buckets[mainpos];
RefNode *newnode = _freelist;
newnode->obj = obj;
_buckets[mainpos] = newnode;
_freelist = _freelist->next;
newnode->next = t;
assert(newnode->refs == 0);
_slotused++;
return newnode;
}
RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add)
{
RefNode *ref;
mainpos = ::HashObj(obj)&(_numofslots-1);
*prev = NULL;
for (ref = _buckets[mainpos]; ref; ) {
if(_rawval(ref->obj) == _rawval(obj) && type(ref->obj) == type(obj))
break;
*prev = ref;
ref = ref->next;
}
if(ref == NULL && add) {
if(_numofslots == _slotused) {
assert(_freelist == 0);
Resize(_numofslots*2);
mainpos = ::HashObj(obj)&(_numofslots-1);
}
ref = Add(mainpos,obj);
}
return ref;
}
void RefTable::AllocNodes(SQUnsignedInteger size)
{
RefNode **bucks;
RefNode *nodes;
bucks = (RefNode **)SQ_MALLOC((size * sizeof(RefNode *)) + (size * sizeof(RefNode)));
nodes = (RefNode *)&bucks[size];
RefNode *temp = nodes;
SQUnsignedInteger n;
for(n = 0; n < size - 1; n++) {
bucks[n] = NULL;
temp->refs = 0;
new (&temp->obj) SQObjectPtr;
temp->next = temp+1;
temp++;
}
bucks[n] = NULL;
temp->refs = 0;
new (&temp->obj) SQObjectPtr;
temp->next = NULL;
_freelist = nodes;
_nodes = nodes;
_buckets = bucks;
_slotused = 0;
_numofslots = size;
}
//////////////////////////////////////////////////////////////////////////
//SQStringTable
/*
* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)
* http://www.lua.org/copyright.html#4
* http://www.lua.org/source/4.0.1/src_lstring.c.html
*/
SQStringTable::SQStringTable(SQSharedState *ss)
{
_sharedstate = ss;
AllocNodes(4);
_slotused = 0;
}
SQStringTable::~SQStringTable()
{
SQ_FREE(_strings,sizeof(SQString*)*_numofslots);
_strings = NULL;
}
void SQStringTable::AllocNodes(SQInteger size)
{
_numofslots = size;
_strings = (SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots);
memset(_strings,0,sizeof(SQString*)*_numofslots);
}
SQString *SQStringTable::Add(const SQChar *news,SQInteger len)
{
if(len<0)
len = (SQInteger)scstrlen(news);
SQHash h = ::_hashstr(news,len)&(_numofslots-1);
SQString *s;
for (s = _strings[h]; s; s = s->_next){
if(s->_len == len && (!memcmp(news,s->_val,rsl(len))))
return s; //found
}
SQString *t=(SQString *)SQ_MALLOC(rsl(len)+sizeof(SQString));
new (t) SQString;
t->_sharedstate = _sharedstate;
memcpy(t->_val,news,rsl(len));
t->_val[len] = _SC('\0');
t->_len = len;
t->_hash = ::_hashstr(news,len);
t->_next = _strings[h];
_strings[h] = t;
_slotused++;
if (_slotused > _numofslots) /* too crowded? */
Resize(_numofslots*2);
return t;
}
void SQStringTable::Resize(SQInteger size)
{
SQInteger oldsize=_numofslots;
SQString **oldtable=_strings;
AllocNodes(size);
for (SQInteger i=0; i<oldsize; i++){
SQString *p = oldtable[i];
while(p){
SQString *next = p->_next;
SQHash h = p->_hash&(_numofslots-1);
p->_next = _strings[h];
_strings[h] = p;
p = next;
}
}
SQ_FREE(oldtable,oldsize*sizeof(SQString*));
}
void SQStringTable::Remove(SQString *bs)
{
SQString *s;
SQString *prev=NULL;
SQHash h = bs->_hash&(_numofslots - 1);
for (s = _strings[h]; s; ){
if(s == bs){
if(prev)
prev->_next = s->_next;
else
_strings[h] = s->_next;
_slotused--;
SQInteger slen = s->_len;
s->~SQString();
SQ_FREE(s,sizeof(SQString) + rsl(slen));
return;
}
prev = s;
s = s->_next;
}
assert(0);//if this fail something is wrong
}

View File

@ -0,0 +1,144 @@
/* see copyright notice in squirrel.h */
#ifndef _SQSTATE_H_
#define _SQSTATE_H_
#include "squtils.h"
#include "sqobject.h"
struct SQString;
struct SQTable;
//max number of character for a printed number
#define NUMBER_MAX_CHAR 50
struct SQStringTable
{
SQStringTable(SQSharedState*ss);
~SQStringTable();
SQString *Add(const SQChar *,SQInteger len);
void Remove(SQString *);
private:
void Resize(SQInteger size);
void AllocNodes(SQInteger size);
SQString **_strings;
SQUnsignedInteger _numofslots;
SQUnsignedInteger _slotused;
SQSharedState *_sharedstate;
};
struct RefTable {
struct RefNode {
SQObjectPtr obj;
SQUnsignedInteger refs;
struct RefNode *next;
};
RefTable();
~RefTable();
void AddRef(SQObject &obj);
SQBool Release(SQObject &obj);
SQUnsignedInteger GetRefCount(SQObject &obj);
#ifndef NO_GARBAGE_COLLECTOR
void Mark(SQCollectable **chain);
#endif
void Finalize();
private:
RefNode *Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add);
RefNode *Add(SQHash mainpos,SQObject &obj);
void Resize(SQUnsignedInteger size);
void AllocNodes(SQUnsignedInteger size);
SQUnsignedInteger _numofslots;
SQUnsignedInteger _slotused;
RefNode *_nodes;
RefNode *_freelist;
RefNode **_buckets;
};
#define ADD_STRING(ss,str,len) ss->_stringtable->Add(str,len)
#define REMOVE_STRING(ss,bstr) ss->_stringtable->Remove(bstr)
struct SQObjectPtr;
struct SQSharedState
{
SQSharedState();
~SQSharedState();
void Init();
public:
SQChar* GetScratchPad(SQInteger size);
SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name);
#ifndef NO_GARBAGE_COLLECTOR
SQInteger CollectGarbage(SQVM *vm);
void RunMark(SQVM *vm,SQCollectable **tchain);
SQInteger ResurrectUnreachable(SQVM *vm);
static void MarkObject(SQObjectPtr &o,SQCollectable **chain);
#endif
SQObjectPtrVec *_metamethods;
SQObjectPtr _metamethodsmap;
SQObjectPtrVec *_systemstrings;
SQObjectPtrVec *_types;
SQStringTable *_stringtable;
RefTable _refs_table;
SQObjectPtr _registry;
SQObjectPtr _consts;
SQObjectPtr _constructoridx;
#ifndef NO_GARBAGE_COLLECTOR
SQCollectable *_gc_chain;
#endif
SQObjectPtr _root_vm;
SQObjectPtr _table_default_delegate;
static SQRegFunction _table_default_delegate_funcz[];
SQObjectPtr _array_default_delegate;
static SQRegFunction _array_default_delegate_funcz[];
SQObjectPtr _string_default_delegate;
static SQRegFunction _string_default_delegate_funcz[];
SQObjectPtr _number_default_delegate;
static SQRegFunction _number_default_delegate_funcz[];
SQObjectPtr _generator_default_delegate;
static SQRegFunction _generator_default_delegate_funcz[];
SQObjectPtr _closure_default_delegate;
static SQRegFunction _closure_default_delegate_funcz[];
SQObjectPtr _thread_default_delegate;
static SQRegFunction _thread_default_delegate_funcz[];
SQObjectPtr _class_default_delegate;
static SQRegFunction _class_default_delegate_funcz[];
SQObjectPtr _instance_default_delegate;
static SQRegFunction _instance_default_delegate_funcz[];
SQObjectPtr _weakref_default_delegate;
static SQRegFunction _weakref_default_delegate_funcz[];
SQCOMPILERERROR _compilererrorhandler;
SQPRINTFUNCTION _printfunc;
SQPRINTFUNCTION _errorfunc;
bool _debuginfo;
bool _notifyallexceptions;
private:
SQChar *_scratchpad;
SQInteger _scratchpadsize;
};
#define _sp(s) (_sharedstate->GetScratchPad(s))
#define _spval (_sharedstate->GetScratchPad(-1))
#define _table_ddel _table(_sharedstate->_table_default_delegate)
#define _array_ddel _table(_sharedstate->_array_default_delegate)
#define _string_ddel _table(_sharedstate->_string_default_delegate)
#define _number_ddel _table(_sharedstate->_number_default_delegate)
#define _generator_ddel _table(_sharedstate->_generator_default_delegate)
#define _closure_ddel _table(_sharedstate->_closure_default_delegate)
#define _thread_ddel _table(_sharedstate->_thread_default_delegate)
#define _class_ddel _table(_sharedstate->_class_default_delegate)
#define _instance_ddel _table(_sharedstate->_instance_default_delegate)
#define _weakref_ddel _table(_sharedstate->_weakref_default_delegate)
#ifdef SQUNICODE //rsl REAL STRING LEN
#define rsl(l) ((l)<<1)
#else
#define rsl(l) (l)
#endif
//extern SQObjectPtr _null_;
bool CompileTypemask(SQIntVec &res,const SQChar *typemask);
void *sq_vm_malloc(SQUnsignedInteger size);
void *sq_vm_realloc(void *p,SQUnsignedInteger oldsize,SQUnsignedInteger size);
void sq_vm_free(void *p,SQUnsignedInteger size);
#endif //_SQSTATE_H_

View File

@ -0,0 +1,31 @@
/* see copyright notice in squirrel.h */
#ifndef _SQSTRING_H_
#define _SQSTRING_H_
inline SQHash _hashstr (const SQChar *s, size_t l)
{
SQHash h = (SQHash)l; /* seed */
size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */
for (; l>=step; l-=step)
h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++));
return h;
}
struct SQString : public SQRefCounted
{
SQString(){}
~SQString(){}
public:
static SQString *Create(SQSharedState *ss, const SQChar *, SQInteger len = -1 );
SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
void Release();
SQSharedState *_sharedstate;
SQString *_next; //chain for the string table
SQInteger _len;
SQHash _hash;
SQChar _val[1];
};
#endif //_SQSTRING_H_

View File

@ -0,0 +1,220 @@
/*
see copyright notice in squirrel.h
*/
#include "sqpcheader.h"
#include "sqvm.h"
#include "sqtable.h"
#include "sqfuncproto.h"
#include "sqclosure.h"
SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize)
{
SQInteger pow2size=MINPOWER2;
while(nInitialSize>pow2size)pow2size=pow2size<<1;
AllocNodes(pow2size);
_usednodes = 0;
_delegate = NULL;
INIT_CHAIN();
ADD_TO_CHAIN(&_sharedstate->_gc_chain,this);
}
void SQTable::Remove(const SQObjectPtr &key)
{
_HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
if (n) {
n->val.Null();
n->key.Null();
_usednodes--;
Rehash(false);
}
}
void SQTable::AllocNodes(SQInteger nSize)
{
_HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize);
for(SQInteger i=0;i<nSize;i++){
_HashNode &n = nodes[i];
new (&n) _HashNode;
n.next=NULL;
}
_numofnodes=nSize;
_nodes=nodes;
_firstfree=&_nodes[_numofnodes-1];
}
void SQTable::Rehash(bool force)
{
SQInteger oldsize=_numofnodes;
//prevent problems with the integer division
if(oldsize<4)oldsize=4;
_HashNode *nold=_nodes;
SQInteger nelems=CountUsed();
if (nelems >= oldsize-oldsize/4) /* using more than 3/4? */
AllocNodes(oldsize*2);
else if (nelems <= oldsize/4 && /* less than 1/4? */
oldsize > MINPOWER2)
AllocNodes(oldsize/2);
else if(force)
AllocNodes(oldsize);
else
return;
_usednodes = 0;
for (SQInteger i=0; i<oldsize; i++) {
_HashNode *old = nold+i;
if (type(old->key) != OT_NULL)
NewSlot(old->key,old->val);
}
for(SQInteger k=0;k<oldsize;k++)
nold[k].~_HashNode();
SQ_FREE(nold,oldsize*sizeof(_HashNode));
}
SQTable *SQTable::Clone()
{
SQTable *nt=Create(_opt_ss(this),_numofnodes);
#ifdef _FAST_CLONE
_HashNode *basesrc = _nodes;
_HashNode *basedst = nt->_nodes;
_HashNode *src = _nodes;
_HashNode *dst = nt->_nodes;
SQInteger n = 0;
for(n = 0; n < _numofnodes; n++) {
dst->key = src->key;
dst->val = src->val;
if(src->next) {
assert(src->next > basesrc);
dst->next = basedst + (src->next - basesrc);
assert(dst != dst->next);
}
dst++;
src++;
}
assert(_firstfree > basesrc);
assert(_firstfree != NULL);
nt->_firstfree = basedst + (_firstfree - basesrc);
#else
SQInteger ridx=0;
SQObjectPtr key,val;
while((ridx=Next(true,ridx,key,val))!=-1){
nt->NewSlot(key,val);
}
#endif
nt->SetDelegate(_delegate);
return nt;
}
bool SQTable::Get(const SQObjectPtr &key,SQObjectPtr &val)
{
if(type(key) == OT_NULL)
return false;
_HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
if (n) {
val = _realval(n->val);
return true;
}
return false;
}
bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
{
assert(type(key) != OT_NULL);
SQHash h = HashObj(key) & (_numofnodes - 1);
_HashNode *n = _Get(key, h);
if (n) {
n->val = val;
return false;
}
_HashNode *mp = &_nodes[h];
n = mp;
//key not found I'll insert it
//main pos is not free
if(type(mp->key) != OT_NULL) {
n = _firstfree; /* get a free place */
SQHash mph = HashObj(mp->key) & (_numofnodes - 1);
_HashNode *othern; /* main position of colliding node */
if (mp > n && (othern = &_nodes[mph]) != mp){
/* yes; move colliding node into free position */
while (othern->next != mp){
assert(othern->next != NULL);
othern = othern->next; /* find previous */
}
othern->next = n; /* redo the chain with `n' in place of `mp' */
n->key = mp->key;
n->val = mp->val;/* copy colliding node into free pos. (mp->next also goes) */
n->next = mp->next;
mp->key.Null();
mp->val.Null();
mp->next = NULL; /* now `mp' is free */
}
else{
/* new node will go into free position */
n->next = mp->next; /* chain new position */
mp->next = n;
mp = n;
}
}
mp->key = key;
for (;;) { /* correct `firstfree' */
if (type(_firstfree->key) == OT_NULL && _firstfree->next == NULL) {
mp->val = val;
_usednodes++;
return true; /* OK; table still has a free place */
}
else if (_firstfree == _nodes) break; /* cannot decrement from here */
else (_firstfree)--;
}
Rehash(true);
return NewSlot(key, val);
}
SQInteger SQTable::Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
{
SQInteger idx = (SQInteger)TranslateIndex(refpos);
while (idx < _numofnodes) {
if(type(_nodes[idx].key) != OT_NULL) {
//first found
_HashNode &n = _nodes[idx];
outkey = n.key;
outval = getweakrefs?(SQObject)n.val:_realval(n.val);
//return idx for the next iteration
return ++idx;
}
++idx;
}
//nothing to iterate anymore
return -1;
}
bool SQTable::Set(const SQObjectPtr &key, const SQObjectPtr &val)
{
_HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
if (n) {
n->val = val;
return true;
}
return false;
}
void SQTable::_ClearNodes()
{
for(SQInteger i = 0;i < _numofnodes; i++) { _HashNode &n = _nodes[i]; n.key.Null(); n.val.Null(); }
}
void SQTable::Finalize()
{
_ClearNodes();
SetDelegate(NULL);
}
void SQTable::Clear()
{
_ClearNodes();
_usednodes = 0;
Rehash(true);
}

Some files were not shown because too many files have changed in this diff Show More