diff --git a/Engine/source/CMakeLists.txt b/Engine/source/CMakeLists.txt index 8c7380df59..b690506440 100644 --- a/Engine/source/CMakeLists.txt +++ b/Engine/source/CMakeLists.txt @@ -33,12 +33,12 @@ endif (APPLE) # When on Windows, we need to link against winsock and windows codecs if (WIN32) - set(TORQUE_SOURCE_FILES ${TORQUE_SOURCE_FILES} ${TORQUE_PLATFORM_WIN_SOURCES}) + set(TORQUE_SOURCE_FILES ${TORQUE_SOURCE_FILES} ${TORQUE_PLATFORM_WIN_SOURCES}) endif (WIN32) # Linux requires X11 & freetype if (UNIX AND NOT APPLE) - set(TORQUE_SOURCE_FILES ${TORQUE_SOURCE_FILES} ${TORQUE_PLATFORM_X11_SOURCES}) + set(TORQUE_SOURCE_FILES ${TORQUE_SOURCE_FILES} ${TORQUE_PLATFORM_X11_SOURCES}) find_package(Freetype REQUIRED) set(TORQUE_INCLUDE_DIRECTORIES ${TORQUE_INCLUDE_DIRECTORIES} ${FREETYPE_INCLUDE_DIRS}) endif (UNIX AND NOT APPLE) @@ -50,11 +50,12 @@ torqueAddSourceDirectories("app" "app/net") # Handle console torqueAddSourceDirectories("console") +torqueAddSourceDirectories("console/torquescript") # Handle Platform torqueAddSourceDirectories("platform" "platform/threads" "platform/async" "platform/input" "platform/output") - + torqueAddSourceDirectories("platform/nativeDialogs") # Handle T3D @@ -291,7 +292,7 @@ endforeach() # Prepare Windows RC file if (WIN32) set(APPLICATION_ICON_PATH "${CMAKE_SOURCE_DIR}/Tools/CMake/torque.ico") - + configure_file("${CMAKE_SOURCE_DIR}/Tools/CMake/torque-win.rc.in" "${CMAKE_BINARY_DIR}/temp/torque.rc") set(TORQUE_SOURCE_FILES ${TORQUE_SOURCE_FILES} "${CMAKE_BINARY_DIR}/temp/torque.rc") endif (WIN32) @@ -300,7 +301,7 @@ endif (WIN32) if (APPLE) set(TORQUE_SOURCE_FILES ${TORQUE_SOURCE_FILES} ${TORQUE_PLATFORM_MAC_SOURCES} "${CMAKE_SOURCE_DIR}/Tools/CMake/torque.icns") set_source_files_properties("${CMAKE_SOURCE_DIR}/Tools/CMake/torque.icns" PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") - + set(EXECUTABLE_NAME "${TORQUE_APP_NAME}") configure_file("${CMAKE_SOURCE_DIR}/Tools/CMake/Info.plist.in" "${CMAKE_BINARY_DIR}/temp/Info.plist" COPYONLY) endif (APPLE) @@ -348,25 +349,25 @@ if (APPLE) set(CMAKE_XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../Frameworks") elseif (WIN32) add_executable(${TORQUE_APP_NAME} WIN32 ${TORQUE_SOURCE_FILES}) - + set(TORQUE_CXX_FLAGS_COMMON_DEFAULT "-DUNICODE -D_UNICODE -D_CRT_SECURE_NO_WARNINGS /MP /Ob2 /Oi /Ot /Oy /GT /Zi /W4 /nologo /GF /EHsc /GS- /Gy- /Qpar- /fp:precise /fp:except- /GR /Zc:wchar_t-" ) if( TORQUE_CPU_X32 ) set(TORQUE_CXX_FLAGS_COMMON_DEFAULT "${TORQUE_CXX_FLAGS_COMMON_DEFAULT} /arch:SSE2") endif() set(TORQUE_CXX_FLAGS_COMMON ${TORQUE_CXX_FLAGS_COMMON_DEFAULT} CACHE STRING "") mark_as_advanced(TORQUE_CXX_FLAGS_COMMON) - + set(TORQUE_CXX_FLAGS_EXECUTABLES "/wd4018 /wd4100 /wd4121 /wd4127 /wd4130 /wd4244 /wd4245 /wd4389 /wd4511 /wd4512 /wd4800 /wd4995" CACHE STRING "") mark_as_advanced(TORQUE_CXX_FLAGS_EXECUTABLES) - + set(TORQUE_CXX_FLAGS "${TORQUE_CXX_FLAGS_COMMON_DEFAULT} ${TORQUE_CXX_FLAGS_EXECUTABLES}" CACHE STRING "") mark_as_advanced(TORQUE_CXX_FLAGS) - + # NOTE: On Windows, /Zc:wchar_t- is necessary otherwise you get unicode errors set_target_properties(${TORQUE_APP_NAME} PROPERTIES COMPILE_FLAGS "${TORQUE_CXX_FLAGS}") else() add_executable(${TORQUE_APP_NAME} ${TORQUE_SOURCE_FILES}) - + # NOTE: On Linux, we set the rpath to ./ so that shared objects next to the executable are used set_target_properties(${TORQUE_APP_NAME} PROPERTIES LINK_FLAGS "-Wl,-rpath,./") endif() @@ -423,9 +424,9 @@ if (UNIX) # For eg. OSX some links are not valid targets - for example frameworks provided by OS if (TARGET ${GAME_LINK_LIBRARY}) get_target_property(LINK_LIBRARY_TYPE ${GAME_LINK_LIBRARY} TYPE) - + # Only pay attention to shared libraries and make them output to the app resources - if ("${LINK_LIBRARY_TYPE}" STREQUAL "SHARED_LIBRARY") + if ("${LINK_LIBRARY_TYPE}" STREQUAL "SHARED_LIBRARY") if (APPLE) set_target_properties(${GAME_LINK_LIBRARY} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${TORQUE_APP_GAME_DIRECTORY}/${TORQUE_APP_NAME}.app/Contents/Frameworks") else() @@ -434,4 +435,4 @@ if (UNIX) endif() endif() endforeach() -endif (UNIX) \ No newline at end of file +endif (UNIX) diff --git a/Engine/source/T3D/assets/CubemapAsset.cpp b/Engine/source/T3D/assets/CubemapAsset.cpp index c5d7be7ca0..96912e6e76 100644 --- a/Engine/source/T3D/assets/CubemapAsset.cpp +++ b/Engine/source/T3D/assets/CubemapAsset.cpp @@ -41,6 +41,7 @@ #endif // Debug Profiling. +#include "console/script.h" #include "platform/profiler.h" //----------------------------------------------------------------------------- @@ -140,7 +141,7 @@ void CubemapAsset::initializeAsset() mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath; - if (Torque::FS::IsScriptFile(mScriptPath)) + if (Con::isScriptFile(mScriptPath)) Con::executeFile(mScriptPath, false, false); } @@ -148,7 +149,7 @@ void CubemapAsset::onAssetRefresh() { mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath; - if (Torque::FS::IsScriptFile(mScriptPath)) + if (Con::isScriptFile(mScriptPath)) Con::executeFile(mScriptPath, false, false); } diff --git a/Engine/source/T3D/assets/GUIAsset.cpp b/Engine/source/T3D/assets/GUIAsset.cpp index 8c56059f1f..0537c70f02 100644 --- a/Engine/source/T3D/assets/GUIAsset.cpp +++ b/Engine/source/T3D/assets/GUIAsset.cpp @@ -41,6 +41,7 @@ #endif // Debug Profiling. +#include "console/script.h" #include "platform/profiler.h" //----------------------------------------------------------------------------- @@ -118,12 +119,12 @@ void GUIAsset::initializeAsset() { mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath; - if (Torque::FS::IsScriptFile(mScriptPath)) + if (Con::isScriptFile(mScriptPath)) Con::executeFile(mScriptPath, false, false); mGUIPath = getOwned() ? expandAssetFilePath(mGUIFile) : mGUIPath; - if (Torque::FS::IsScriptFile(mGUIPath)) + if (Con::isScriptFile(mGUIPath)) Con::executeFile(mGUIPath, false, false); } @@ -131,12 +132,12 @@ void GUIAsset::onAssetRefresh() { mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath; - if (Torque::FS::IsScriptFile(mScriptPath)) + if (Con::isScriptFile(mScriptPath)) Con::executeFile(mScriptPath, false, false); mGUIPath = getOwned() ? expandAssetFilePath(mGUIFile) : mGUIPath; - if (Torque::FS::IsScriptFile(mGUIPath)) + if (Con::isScriptFile(mGUIPath)) Con::executeFile(mGUIPath, false, false); } diff --git a/Engine/source/T3D/assets/GameObjectAsset.cpp b/Engine/source/T3D/assets/GameObjectAsset.cpp index 566689f0fe..ac207c039f 100644 --- a/Engine/source/T3D/assets/GameObjectAsset.cpp +++ b/Engine/source/T3D/assets/GameObjectAsset.cpp @@ -41,6 +41,7 @@ #endif // Debug Profiling. +#include "console/script.h" #include "platform/profiler.h" //----------------------------------------------------------------------------- @@ -134,7 +135,7 @@ void GameObjectAsset::initializeAsset() //Ensure we have an expanded filepath mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath; - if (Torque::FS::IsScriptFile(mScriptPath)) + if (Con::isScriptFile(mScriptPath)) Con::executeFile(mScriptPath, false, false); mTAMLPath = getOwned() ? expandAssetFilePath(mTAMLFile) : mTAMLPath; @@ -145,7 +146,7 @@ void GameObjectAsset::onAssetRefresh() //Ensure we have an expanded filepath mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath; - if (Torque::FS::IsScriptFile(mScriptPath)) + if (Con::isScriptFile(mScriptPath)) Con::executeFile(mScriptPath, false, false); mTAMLPath = getOwned() ? expandAssetFilePath(mTAMLFile) : mTAMLPath; diff --git a/Engine/source/T3D/assets/MaterialAsset.cpp b/Engine/source/T3D/assets/MaterialAsset.cpp index ec83976859..5540ce6a9c 100644 --- a/Engine/source/T3D/assets/MaterialAsset.cpp +++ b/Engine/source/T3D/assets/MaterialAsset.cpp @@ -40,6 +40,7 @@ #include "assets/assetPtr.h" #endif +#include "console/script.h" #include "T3D/assets/assetImporter.h" StringTableEntry MaterialAsset::smNoMaterialAssetFallback = NULL; @@ -179,7 +180,7 @@ void MaterialAsset::initializeAsset() { mLoadedState = EmbeddedDefinition; } - else if (Torque::FS::IsScriptFile(mScriptPath)) + else if (Con::isScriptFile(mScriptPath)) { if (!Sim::findObject(mMatDefinitionName)) { @@ -211,7 +212,7 @@ void MaterialAsset::onAssetRefresh() return; } - if (Torque::FS::IsScriptFile(mScriptPath)) + if (Con::isScriptFile(mScriptPath)) { //Since we're refreshing, we can assume that the file we're executing WILL have an existing definition. //But that definition, whatever it is, is the 'correct' one, so we enable the Replace Existing behavior diff --git a/Engine/source/T3D/assets/PostEffectAsset.cpp b/Engine/source/T3D/assets/PostEffectAsset.cpp index 047a901fc0..c3bac07dea 100644 --- a/Engine/source/T3D/assets/PostEffectAsset.cpp +++ b/Engine/source/T3D/assets/PostEffectAsset.cpp @@ -41,6 +41,7 @@ #endif // Debug Profiling. +#include "console/script.h" #include "platform/profiler.h" //----------------------------------------------------------------------------- @@ -137,7 +138,7 @@ void PostEffectAsset::initializeAsset() mHLSLShaderPath = getOwned() ? expandAssetFilePath(mHLSLShaderFile) : mHLSLShaderPath; mGLSLShaderPath = getOwned() ? expandAssetFilePath(mGLSLShaderFile) : mGLSLShaderPath; - if (Torque::FS::IsScriptFile(mScriptPath)) + if (Con::isScriptFile(mScriptPath)) Con::executeFile(mScriptPath, false, false); } @@ -147,7 +148,7 @@ void PostEffectAsset::onAssetRefresh() mHLSLShaderPath = getOwned() ? expandAssetFilePath(mHLSLShaderFile) : mHLSLShaderPath; mGLSLShaderPath = getOwned() ? expandAssetFilePath(mGLSLShaderFile) : mGLSLShaderPath; - if (Torque::FS::IsScriptFile(mScriptPath)) + if (Con::isScriptFile(mScriptPath)) Con::executeFile(mScriptPath, false, false); } diff --git a/Engine/source/T3D/assets/ScriptAsset.cpp b/Engine/source/T3D/assets/ScriptAsset.cpp index 9fe05c329b..be2dbc6069 100644 --- a/Engine/source/T3D/assets/ScriptAsset.cpp +++ b/Engine/source/T3D/assets/ScriptAsset.cpp @@ -40,6 +40,7 @@ #endif // Debug Profiling. +#include "console/script.h" #include "platform/profiler.h" //----------------------------------------------------------------------------- @@ -140,7 +141,7 @@ void ScriptAsset::initializeAsset() mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath; - if (Torque::FS::IsScriptFile(mScriptPath)) + if (Con::isScriptFile(mScriptPath)) { //We're initialized properly, so we'll go ahead and kick along any dependencies we may have as well AssetManager::typeAssetDependsOnHash::Iterator assetDependenciesItr = mpOwningAssetManager->getDependedOnAssets()->find(mpAssetDefinition->mAssetId); @@ -170,7 +171,7 @@ void ScriptAsset::onAssetRefresh() { mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath; - if (Torque::FS::IsScriptFile(mScriptPath)) + if (Con::isScriptFile(mScriptPath)) { //Refresh any dependencies we may have for (U32 i = 0; i < mScriptAssetDependencies.size(); i++) @@ -215,7 +216,7 @@ bool ScriptAsset::execScript() if (handle) return true; - if (Torque::FS::IsScriptFile(mScriptPath)) + if (Con::isScriptFile(mScriptPath)) { return Con::executeFile(mScriptPath, false, false); } diff --git a/Engine/source/T3D/assets/TerrainMaterialAsset.cpp b/Engine/source/T3D/assets/TerrainMaterialAsset.cpp index 97635f1624..18d175f3db 100644 --- a/Engine/source/T3D/assets/TerrainMaterialAsset.cpp +++ b/Engine/source/T3D/assets/TerrainMaterialAsset.cpp @@ -40,6 +40,7 @@ #include "assets/assetPtr.h" #endif +#include "console/script.h" #include "T3D/assets/assetImporter.h" StringTableEntry TerrainMaterialAsset::smNoTerrainMaterialAssetFallback = NULL; @@ -182,7 +183,7 @@ void TerrainMaterialAsset::initializeAsset() { mLoadedState = EmbeddedDefinition; } - else if (Torque::FS::IsScriptFile(mScriptPath)) + else if (Con::isScriptFile(mScriptPath)) { if (!Sim::findObject(mMatDefinitionName)) { @@ -214,7 +215,7 @@ void TerrainMaterialAsset::onAssetRefresh() return; } - if (Torque::FS::IsScriptFile(mScriptPath)) + if (Con::isScriptFile(mScriptPath)) { //Since we're refreshing, we can assume that the file we're executing WILL have an existing definition. //But that definition, whatever it is, is the 'correct' one, so we enable the Replace Existing behavior diff --git a/Engine/source/T3D/prefab.cpp b/Engine/source/T3D/prefab.cpp index 255b44d244..75dc8f5210 100644 --- a/Engine/source/T3D/prefab.cpp +++ b/Engine/source/T3D/prefab.cpp @@ -31,6 +31,7 @@ #include "console/consoleTypes.h" #include "core/volume.h" #include "console/engineAPI.h" +#include "console/script.h" #include "T3D/physics/physicsShape.h" #include "core/util/path.h" @@ -344,7 +345,7 @@ void Prefab::_loadFile( bool addFileNotify ) if ( mFilename == StringTable->EmptyString()) return; - if ( !Torque::FS::IsScriptFile( mFilename ) ) + if ( !Con::isScriptFile( mFilename ) ) { Con::errorf( "Prefab::_loadFile() - file %s was not found.", mFilename ); return; diff --git a/Engine/source/T3D/trigger.cpp b/Engine/source/T3D/trigger.cpp index f3dcd7016c..1fa807ce2c 100644 --- a/Engine/source/T3D/trigger.cpp +++ b/Engine/source/T3D/trigger.cpp @@ -27,6 +27,7 @@ #include "console/consoleTypes.h" #include "console/engineAPI.h" #include "collision/boxConvex.h" +#include "console/script.h" #include "core/stream/bitStream.h" #include "math/mathIO.h" diff --git a/Engine/source/Verve/Core/VDataTable.cpp b/Engine/source/Verve/Core/VDataTable.cpp index 9bb4b92ffb..79f151fcaa 100644 --- a/Engine/source/Verve/Core/VDataTable.cpp +++ b/Engine/source/Verve/Core/VDataTable.cpp @@ -22,6 +22,7 @@ //----------------------------------------------------------------------------- #include "Verve/Core/VDataTable.h" +#include "console/script.h" #include "console/simObject.h" //----------------------------------------------------------------------------- @@ -228,7 +229,7 @@ bool VDataTable::getValue( SimObject *pObject, const String &pFieldName, String case VDataTable::k_TypeExpression : { // Evaluate. - pValue = Con::evaluate( fieldValue, false ).getString(); + pValue = Con::evaluate( fieldValue, false ).value.getString(); } break; diff --git a/Engine/source/Verve/Extension/Script/VScriptEvent.cpp b/Engine/source/Verve/Extension/Script/VScriptEvent.cpp index 6fcdb80462..a44a08f37a 100644 --- a/Engine/source/Verve/Extension/Script/VScriptEvent.cpp +++ b/Engine/source/Verve/Extension/Script/VScriptEvent.cpp @@ -26,6 +26,7 @@ #include "Verve/Extension/Script/VScriptEvent.h" #include "console/consoleTypes.h" +#include "console/script.h" //----------------------------------------------------------------------------- IMPLEMENT_CONOBJECT( VScriptEvent ); diff --git a/Engine/source/afx/afxChoreographer.cpp b/Engine/source/afx/afxChoreographer.cpp index 2997f27ddf..844bcac124 100644 --- a/Engine/source/afx/afxChoreographer.cpp +++ b/Engine/source/afx/afxChoreographer.cpp @@ -26,9 +26,9 @@ #include "afx/arcaneFX.h" #include "console/engineAPI.h" +#include "console/script.h" #include "T3D/gameBase/gameConnection.h" #include "math/mathIO.h" -#include "console/compiler.h" #include "afx/afxConstraint.h" #include "afx/afxChoreographer.h" @@ -108,12 +108,11 @@ bool afxChoreographerData::preload(bool server, String &errorStr) if (!server && client_script_file != ST_NULLSTRING) { - Compiler::gSyntaxError = false; - Con::evaluate(avar("exec(\"%s\");", client_script_file), false, 0); - if (Compiler::gSyntaxError) + Con::EvalResult result = Con::evaluate(avar("exec(\"%s\");", client_script_file), false, 0); + + if (!result.valid) { Con::errorf("afxChoreographerData: failed to exec clientScriptFile \"%s\" -- syntax error", client_script_file); - Compiler::gSyntaxError = false; } } diff --git a/Engine/source/afx/arcaneFX.cpp b/Engine/source/afx/arcaneFX.cpp index 5c7ea34606..4e67124d9b 100644 --- a/Engine/source/afx/arcaneFX.cpp +++ b/Engine/source/afx/arcaneFX.cpp @@ -31,8 +31,9 @@ #include "T3D/gameBase/gameProcess.h" #include "T3D/player.h" #include "math/mathUtils.h" -#include "console/compiler.h" + #include "console/engineAPI.h" +#include "console/script.h" #include "afx/afxChoreographer.h" #include "afx/afxSelectron.h" @@ -672,7 +673,7 @@ DefineEngineFunction(wasSyntaxError, bool, (),, "for detecting syntax errors after reloading a script.\n\n" "@ingroup AFX") { - return Compiler::gSyntaxError; + return Con::getLastEvalResult().valid == false; } //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~// diff --git a/Engine/source/afx/ea/afxEA_PhraseEffect.cpp b/Engine/source/afx/ea/afxEA_PhraseEffect.cpp index 84a75ee7ed..c16f2d468d 100644 --- a/Engine/source/afx/ea/afxEA_PhraseEffect.cpp +++ b/Engine/source/afx/ea/afxEA_PhraseEffect.cpp @@ -26,8 +26,8 @@ #include #include "afx/arcaneFX.h" -#include "console/compiler.h" #include "T3D/player.h" +#include "console/script.h" #include "afx/afxEffectDefs.h" #include "afx/afxPhrase.h" @@ -314,13 +314,10 @@ void afxEA_PhraseEffect::trigger_new_phrase() } b[0] = '\0'; - Compiler::gSyntaxError = false; - //Con::errorf("EVAL [%s]", avar("%s;", buffer)); - Con::evaluate(avar("%s;", buffer), false, 0); - if (Compiler::gSyntaxError) + Con::EvalResult result = Con::evaluate(avar("%s;", buffer), false, 0); + if (!result.valid) { Con::errorf("onTriggerCommand \"%s\" -- syntax error", phrase_fx_data->on_trig_cmd); - Compiler::gSyntaxError = false; } } diff --git a/Engine/source/app/mainLoop.cpp b/Engine/source/app/mainLoop.cpp index 97f25e4f39..5d1e9fcf41 100644 --- a/Engine/source/app/mainLoop.cpp +++ b/Engine/source/app/mainLoop.cpp @@ -61,6 +61,7 @@ // For the TickMs define... fix this for T2D... #include "T3D/gameBase/processList.h" #include "cinterface/cinterface.h" +#include "console/script.h" #ifdef TORQUE_ENABLE_VFS #include "platform/platformVFS.h" diff --git a/Engine/source/app/net/serverQuery.cpp b/Engine/source/app/net/serverQuery.cpp index ef41dab470..1f48cd57cb 100644 --- a/Engine/source/app/net/serverQuery.cpp +++ b/Engine/source/app/net/serverQuery.cpp @@ -107,6 +107,7 @@ #include "sim/netInterface.h" // cafTODO: breaks T2D +#include "console/script.h" #include "T3D/gameBase/gameConnection.h" // This is basically the server query protocol version now: @@ -2020,7 +2021,7 @@ static void handleGameInfoRequest( const NetAddress* address, U32 key, U8 flags out->writeString( Con::getVariable( "pref::Server::Info" ) ); else writeCString( out, Con::getVariable( "pref::Server::Info" ) ); - writeLongCString( out, Con::evaluate( "onServerInfoQuery();" ) ); + writeLongCString( out, Con::executef( "onServerInfoQuery" ) ); BitStream::sendPacketStream(address); } diff --git a/Engine/source/cinterface/c_controlInterface.cpp b/Engine/source/cinterface/c_controlInterface.cpp index 304d3932db..3001a34d1b 100644 --- a/Engine/source/cinterface/c_controlInterface.cpp +++ b/Engine/source/cinterface/c_controlInterface.cpp @@ -23,6 +23,7 @@ #include "c_controlInterface.h" #include "console/consoleInternal.h" +#include "console/engineAPI.h" #include "console/simSet.h" #include "app/mainLoop.h" #include "windowManager/platformWindow.h" @@ -50,7 +51,7 @@ extern "C" { // reset the engine, unloading any current level and returning to the main menu void torque_reset() { - Con::evaluate("disconnect();"); + Con::executef("disconnect"); } // initialize Torque 3D including argument handling @@ -119,7 +120,7 @@ extern "C" { // signal an engine shutdown (as with the quit(); console command) void torque_enginesignalshutdown() { - Con::evaluate("quit();"); + Con::executef("quit"); } // shutdown the engine diff --git a/Engine/source/cinterface/cinterface.cpp b/Engine/source/cinterface/cinterface.cpp index 3cd717c13e..685c573d3b 100644 --- a/Engine/source/cinterface/cinterface.cpp +++ b/Engine/source/cinterface/cinterface.cpp @@ -21,7 +21,6 @@ //----------------------------------------------------------------------------- #include "cinterface.h" -#include "console/compiler.h" #include "windowManager/platformWindow.h" CInterface& CInterface::GetCInterface() diff --git a/Engine/source/console/console.cpp b/Engine/source/console/console.cpp index 5afd26f3aa..84ae03ce31 100644 --- a/Engine/source/console/console.cpp +++ b/Engine/source/console/console.cpp @@ -28,16 +28,16 @@ #include "console/consoleObject.h" #include "console/consoleParser.h" #include "core/stream/fileStream.h" -#include "console/ast.h" #include "core/tAlgorithm.h" #include "console/consoleTypes.h" #include "console/telnetDebugger.h" #include "console/simBase.h" -#include "console/compiler.h" #include "console/stringStack.h" #include "console/ICallMethod.h" #include "console/engineAPI.h" #include + +#include "returnBuffer.h" #include "platform/threads/mutex.h" #include "core/util/journal/journal.h" #include "cinterface/cinterface.h" @@ -72,13 +72,10 @@ char* ConsoleValue::convertToBuffer() const const char* ConsoleValue::getConsoleData() const { - return Con::getData(type, ct->dataPtr, 0, ct->enumTable); + return Con::getData(ct->consoleType, ct->dataPtr, 0, ct->enumTable); } ConsoleDocFragment* ConsoleDocFragment::smFirst; -ExprEvalState gEvalState; -StmtNode *gStatementList; -StmtNode *gAnonFunctionList; U32 gAnonFunctionID = 0; ConsoleConstructor *ConsoleConstructor::mFirst = NULL; bool gWarnUndefinedScriptVariables; @@ -565,7 +562,7 @@ U32 tabComplete(char* inputBuffer, U32 cursorPos, U32 maxResultLength, bool forw // In the global namespace, we can complete on global vars as well as functions. if (inputBuffer[completionBaseStart] == '$') { - newText = gEvalState.globalVars.tabComplete(inputBuffer + completionBaseStart, completionBaseLen, forwardTab); + newText = gGlobalVars.tabComplete(inputBuffer + completionBaseStart, completionBaseLen, forwardTab); } else { @@ -665,9 +662,9 @@ static void _printf(ConsoleLogEntry::Level level, ConsoleLogEntry::Type type, co char buffer[8192] = {}; U32 offset = 0; - if( gEvalState.traceOn && gEvalState.getStackDepth() > 0 ) + if( gTraceOn && !getFrameStack().empty()) { - offset = gEvalState.getStackDepth() * 3; + offset = getFrameStack().size() * 3; for(U32 i = 0; i < offset; i++) buffer[i] = ' '; } @@ -831,41 +828,25 @@ bool getVariableObjectField(const char *name, SimObject **object, const char **f return false; } -Dictionary::Entry *getLocalVariableEntry(const char *name) -{ - name = prependPercent(name); - return gEvalState.getCurrentFrame().lookup(StringTable->insert(name)); -} - Dictionary::Entry *getVariableEntry(const char *name) { name = prependDollar(name); - return gEvalState.globalVars.lookup(StringTable->insert(name)); + return gGlobalVars.lookup(StringTable->insert(name)); } Dictionary::Entry *addVariableEntry(const char *name) { name = prependDollar(name); - return gEvalState.globalVars.add(StringTable->insert(name)); + return gGlobalVars.add(StringTable->insert(name)); } Dictionary::Entry *getAddVariableEntry(const char *name) { name = prependDollar(name); StringTableEntry stName = StringTable->insert(name); - Dictionary::Entry *entry = gEvalState.globalVars.lookup(stName); + Dictionary::Entry *entry = gGlobalVars.lookup(stName); if (!entry) - entry = gEvalState.globalVars.add(stName); - return entry; -} - -Dictionary::Entry *getAddLocalVariableEntry(const char *name) -{ - name = prependPercent(name); - StringTableEntry stName = StringTable->insert(name); - Dictionary::Entry *entry = gEvalState.getCurrentFrame().lookup(stName); - if (!entry) - entry = gEvalState.getCurrentFrame().add(stName); + entry = gGlobalVars.add(stName); return entry; } @@ -881,7 +862,7 @@ void setVariable(const char *name, const char *value) else { name = prependDollar(name); - gEvalState.globalVars.setVariable(StringTable->insert(name), value); + gGlobalVars.setVariable(StringTable->insert(name), value); } } @@ -988,7 +969,7 @@ void stripColorChars(char* line) } } -// +// const char *getObjectTokenField(const char *name) { const char *dot = dStrchr(name, '.'); @@ -1046,7 +1027,7 @@ const char *getLocalVariable(const char *name) { name = prependPercent(name); - return gEvalState.getCurrentFrame().getVariable(StringTable->insert(name)); + return Con::getCurrentStackFrame()->getVariable(StringTable->insert(name)); } bool getBoolVariable(const char *varName, bool def) @@ -1099,7 +1080,7 @@ void addVariable( const char *name, void *dptr, const char* usage ) { - gEvalState.globalVars.addVariable( name, type, dptr, usage ); + gGlobalVars.addVariable( name, type, dptr, usage ); } void addConstant( const char *name, @@ -1107,24 +1088,24 @@ void addConstant( const char *name, const void *dptr, const char* usage ) { - Dictionary::Entry* entry = gEvalState.globalVars.addVariable( name, type, const_cast< void* >( dptr ), usage ); + Dictionary::Entry* entry = gGlobalVars.addVariable( name, type, const_cast< void* >( dptr ), usage ); entry->mIsConstant = true; } bool removeVariable(const char *name) { name = StringTable->lookup(prependDollar(name)); - return name!=0 && gEvalState.globalVars.removeVariable(name); + return name!=0 && gGlobalVars.removeVariable(name); } void addVariableNotify( const char *name, const NotifyDelegate &callback ) { - gEvalState.globalVars.addVariableNotify( name, callback ); + gGlobalVars.addVariableNotify( name, callback ); } void removeVariableNotify( const char *name, const NotifyDelegate &callback ) { - gEvalState.globalVars.removeVariableNotify( name, callback ); + gGlobalVars.removeVariableNotify( name, callback ); } //--------------------------------------------------------------------------- @@ -1206,359 +1187,6 @@ void addCommand( const char *name,BoolCallback cb,const char *usage, S32 minArgs Namespace::global()->addCommand( StringTable->insert(name), cb, usage, minArgs, maxArgs, isToolOnly, header ); } -bool executeFile(const char* fileName, bool noCalls, bool journalScript) -{ - bool journal = false; - - char scriptFilenameBuffer[1024]; - U32 execDepth = 0; - U32 journalDepth = 1; - - execDepth++; - if (journalDepth >= execDepth) - journalDepth = execDepth + 1; - else - journal = true; - - bool ret = false; - - if (journalScript && !journal) - { - journal = true; - journalDepth = execDepth; - } - - // Determine the filename we actually want... - Con::expandScriptFilename(scriptFilenameBuffer, sizeof(scriptFilenameBuffer), fileName); - - // since this function expects a script file reference, if it's a .dso - // lets terminate the string before the dso so it will act like a .tscript - if (dStrEndsWith(scriptFilenameBuffer, ".dso")) - { - scriptFilenameBuffer[dStrlen(scriptFilenameBuffer) - dStrlen(".dso")] = '\0'; - } - - // Figure out where to put DSOs - StringTableEntry dsoPath = Con::getDSOPath(scriptFilenameBuffer); - - const char *ext = dStrrchr(scriptFilenameBuffer, '.'); - - if (!ext) - { - // Try appending the default script extension and see if that succeeds - - if (executeFile(fileName + String("." TORQUE_SCRIPT_EXTENSION), noCalls, journalScript)) - { - return true; - } - - // We need an extension! - Con::errorf(ConsoleLogEntry::Script, "exec: invalid script file name %s.", scriptFilenameBuffer); - execDepth--; - return false; - } - - // Check Editor Extensions - bool isEditorScript = false; - - // If the script file extension is '.ed.tscript' then compile it to a different compiled extension - if (dStricmp(ext, "." TORQUE_SCRIPT_EXTENSION) == 0) - { - const char* ext2 = ext - 3; - if (dStricmp(ext2, ".ed." TORQUE_SCRIPT_EXTENSION) == 0) - isEditorScript = true; - } - else if (dStricmp(ext, ".gui") == 0) - { - const char* ext2 = ext - 3; - if (dStricmp(ext2, ".ed.gui") == 0) - isEditorScript = true; - } - - StringTableEntry scriptFileName = StringTable->insert(scriptFilenameBuffer); - - // Is this a file we should compile? (anything in the prefs path should not be compiled) - StringTableEntry prefsPath = Platform::getPrefsPath(); - bool compiled = dStricmp(ext, ".mis") && !journal && !Con::getBoolVariable("Scripts::ignoreDSOs"); - - // [tom, 12/5/2006] stripBasePath() fucks up if the filename is not in the exe - // path, current directory or prefs path. Thus, getDSOFilename() will also screw - // up and so this allows the scripts to still load but without a DSO. - if (Platform::isFullPath(Platform::stripBasePath(scriptFilenameBuffer))) - compiled = false; - - // [tom, 11/17/2006] It seems to make sense to not compile scripts that are in the - // prefs directory. However, getDSOPath() can handle this situation and will put - // the dso along with the script to avoid name clashes with tools/game dsos. - if ((dsoPath && *dsoPath == 0) || (prefsPath && prefsPath[0] && dStrnicmp(scriptFileName, prefsPath, dStrlen(prefsPath)) == 0)) - compiled = false; - - // If we're in a journaling mode, then we will read the script - // from the journal file. - if (journal && Journal::IsPlaying()) - { - char fileNameBuf[256]; - bool fileRead = false; - U32 fileSize; - - Journal::ReadString(fileNameBuf); - Journal::Read(&fileRead); - - if (!fileRead) - { - Con::errorf(ConsoleLogEntry::Script, "Journal script read (failed) for %s", fileNameBuf); - execDepth--; - return false; - } - Journal::Read(&fileSize); - char *script = new char[fileSize + 1]; - Journal::Read(fileSize, script); - script[fileSize] = 0; - Con::printf("Executing (journal-read) %s.", scriptFileName); - CodeBlock *newCodeBlock = new CodeBlock(); - newCodeBlock->compileExec(scriptFileName, script, noCalls, 0); - delete[] script; - delete newCodeBlock; - - execDepth--; - return true; - } - - // Ok, we let's try to load and compile the script. - Torque::FS::FileNodeRef scriptFile = Torque::FS::GetFileNode(scriptFileName); - Torque::FS::FileNodeRef dsoFile; - - // ResourceObject *rScr = gResourceManager->find(scriptFileName); - // ResourceObject *rCom = NULL; - - char nameBuffer[512]; - char* script = NULL; - U32 version; - - Stream *compiledStream = NULL; - Torque::Time scriptModifiedTime, dsoModifiedTime; - - // Check here for .edso - bool edso = false; - if (dStricmp(ext, ".edso") == 0 && scriptFile != NULL) - { - edso = true; - dsoFile = scriptFile; - scriptFile = NULL; - - dsoModifiedTime = dsoFile->getModifiedTime(); - dStrcpy(nameBuffer, scriptFileName, 512); - } - - // If we're supposed to be compiling this file, check to see if there's a DSO - if (compiled && !edso) - { - const char *filenameOnly = dStrrchr(scriptFileName, '/'); - if (filenameOnly) - ++filenameOnly; - else - filenameOnly = scriptFileName; - - char pathAndFilename[1024]; - Platform::makeFullPathName(filenameOnly, pathAndFilename, sizeof(pathAndFilename), dsoPath); - - if (isEditorScript) - dStrcpyl(nameBuffer, sizeof(nameBuffer), pathAndFilename, ".edso", NULL); - else - dStrcpyl(nameBuffer, sizeof(nameBuffer), pathAndFilename, ".dso", NULL); - - dsoFile = Torque::FS::GetFileNode(nameBuffer); - - if (scriptFile != NULL) - scriptModifiedTime = scriptFile->getModifiedTime(); - - if (dsoFile != NULL) - dsoModifiedTime = dsoFile->getModifiedTime(); - } - - // Let's do a sanity check to complain about DSOs in the future. - // - // MM: This doesn't seem to be working correctly for now so let's just not issue - // the warning until someone knows how to resolve it. - // - //if(compiled && rCom && rScr && Platform::compareFileTimes(comModifyTime, scrModifyTime) < 0) - //{ - //Con::warnf("exec: Warning! Found a DSO from the future! (%s)", nameBuffer); - //} - - // If we had a DSO, let's check to see if we should be reading from it. - //MGT: fixed bug with dsos not getting recompiled correctly - //Note: Using Nathan Martin's version from the forums since its easier to read and understand - if (compiled && dsoFile != NULL && (scriptFile == NULL || (dsoModifiedTime >= scriptModifiedTime))) - { //MGT: end - compiledStream = FileStream::createAndOpen(nameBuffer, Torque::FS::File::Read); - if (compiledStream) - { - // Check the version! - compiledStream->read(&version); - if (version != Con::DSOVersion) - { - Con::warnf("exec: Found an old DSO (%s, ver %d < %d), ignoring.", nameBuffer, version, Con::DSOVersion); - delete compiledStream; - compiledStream = NULL; - } - } - } - - // If we're journalling, let's write some info out. - if (journal && Journal::IsRecording()) - Journal::WriteString(scriptFileName); - - if (scriptFile != NULL && !compiledStream) - { - // If we have source but no compiled version, then we need to compile - // (and journal as we do so, if that's required). - - void *data; - U32 dataSize = 0; - Torque::FS::ReadFile(scriptFileName, data, dataSize, true); - - if (journal && Journal::IsRecording()) - Journal::Write(bool(data != NULL)); - - if (data == NULL) - { - Con::errorf(ConsoleLogEntry::Script, "exec: invalid script file %s.", scriptFileName); - execDepth--; - return false; - } - else - { - if (!dataSize) - { - execDepth--; - return false; - } - - script = (char *)data; - - if (journal && Journal::IsRecording()) - { - Journal::Write(dataSize); - Journal::Write(dataSize, data); - } - } - -#ifndef TORQUE_NO_DSO_GENERATION - if (compiled) - { - // compile this baddie. -#ifdef TORQUE_DEBUG - Con::printf("Compiling %s...", scriptFileName); -#endif - - CodeBlock *code = new CodeBlock(); - code->compile(nameBuffer, scriptFileName, script); - delete code; - code = NULL; - - compiledStream = FileStream::createAndOpen(nameBuffer, Torque::FS::File::Read); - if (compiledStream) - { - compiledStream->read(&version); - } - else - { - // We have to exit out here, as otherwise we get double error reports. - delete[] script; - execDepth--; - return false; - } - } -#endif - } - else - { - if (journal && Journal::IsRecording()) - Journal::Write(bool(false)); - } - - if (compiledStream) - { - // Delete the script object first to limit memory used - // during recursive execs. - delete[] script; - script = 0; - - // We're all compiled, so let's run it. -#ifdef TORQUE_DEBUG - Con::printf("Loading compiled script %s.", scriptFileName); -#endif - CodeBlock *code = new CodeBlock; - code->read(scriptFileName, *compiledStream); - delete compiledStream; - code->exec(0, scriptFileName, NULL, 0, NULL, noCalls, NULL, 0); - delete code; - ret = true; - } - else - if (scriptFile) - { - // No compiled script, let's just try executing it - // directly... this is either a mission file, or maybe - // we're on a readonly volume. -#ifdef TORQUE_DEBUG - Con::printf("Executing %s.", scriptFileName); -#endif - - CodeBlock *newCodeBlock = new CodeBlock(); - StringTableEntry name = StringTable->insert(scriptFileName); - - newCodeBlock->compileExec(name, script, noCalls, 0); - ret = true; - } - else - { - // Don't have anything. - Con::warnf(ConsoleLogEntry::Script, "Missing file: %s!", scriptFileName); - ret = false; - } - - delete[] script; - execDepth--; - return ret; -} - -ConsoleValue evaluate(const char* string, bool echo, const char *fileName) -{ - ConsoleStackFrameSaver stackSaver; - stackSaver.save(); - - if (echo) - { - if (string[0] == '%') - Con::printf("%s", string); - else - Con::printf("%s%s", getVariable( "$Con::Prompt" ), string); - } - - if(fileName) - fileName = StringTable->insert(fileName); - - CodeBlock *newCodeBlock = new CodeBlock(); - return std::move(newCodeBlock->compileExec(fileName, string, false, fileName ? -1 : 0)); -} - -//------------------------------------------------------------------------------ -ConsoleValue evaluatef(const char* string, ...) -{ - ConsoleStackFrameSaver stackSaver; - stackSaver.save(); - - char buffer[4096]; - va_list args; - va_start(args, string); - dVsprintf(buffer, sizeof(buffer), string, args); - va_end(args); - CodeBlock *newCodeBlock = new CodeBlock(); - return newCodeBlock->compileExec(NULL, buffer, false, 0); -} - //------------------------------------------------------------------------------ // Internal execute for global function which does not save the stack @@ -1598,7 +1226,7 @@ ConsoleValue _internalExecute(S32 argc, ConsoleValue argv[]) return std::move(ConsoleValue()); } - return std::move(ent->execute(argc, argv, &gEvalState)); + return std::move(ent->execute(argc, argv, NULL)); } ConsoleValue execute(S32 argc, ConsoleValue argv[]) @@ -1701,10 +1329,7 @@ static ConsoleValue _internalExecute(SimObject *object, S32 argc, ConsoleValue a // Twiddle %this argument argv[1].setInt(ident); - SimObject *save = gEvalState.thisObject; - gEvalState.thisObject = object; - ConsoleValue ret = std::move(ent->execute(argc, argv, &gEvalState)); - gEvalState.thisObject = save; + ConsoleValue ret = std::move(ent->execute(argc, argv, object)); // Twiddle it back argv[1].setString(oldIdent); @@ -1810,6 +1435,84 @@ void setLogMode(S32 newMode) } } +//------------------------------------------------------------------------------ + +ReturnBuffer retBuffer; + +char* getReturnBuffer(U32 bufferSize) +{ + return retBuffer.getBuffer(bufferSize); +} + +char* getReturnBuffer(const char* stringToCopy) +{ + U32 len = dStrlen(stringToCopy) + 1; + char* ret = retBuffer.getBuffer(len); + dMemcpy(ret, stringToCopy, len); + return ret; +} + +char* getReturnBuffer(const String& str) +{ + const U32 size = str.size(); + char* ret = retBuffer.getBuffer(size); + dMemcpy(ret, str.c_str(), size); + return ret; +} + +char* getReturnBuffer(const StringBuilder& str) +{ + char* buffer = Con::getReturnBuffer(str.length() + 1); + str.copy(buffer); + buffer[str.length()] = '\0'; + + return buffer; +} + +char* getArgBuffer(U32 bufferSize) +{ + return STR.getArgBuffer(bufferSize); +} + +char* getFloatArg(F64 arg) +{ + char* ret = STR.getArgBuffer(32); + dSprintf(ret, 32, "%g", arg); + return ret; +} + +char* getIntArg(S32 arg) +{ + char* ret = STR.getArgBuffer(32); + dSprintf(ret, 32, "%d", arg); + return ret; +} + +char* getBoolArg(bool arg) +{ + char* ret = STR.getArgBuffer(32); + dSprintf(ret, 32, "%d", arg); + return ret; +} + +char* getStringArg(const char* arg) +{ + U32 len = dStrlen(arg) + 1; + char* ret = STR.getArgBuffer(len); + dMemcpy(ret, arg, len); + return ret; +} + +char* getStringArg(const String& arg) +{ + const U32 size = arg.size(); + char* ret = STR.getArgBuffer(size); + dMemcpy(ret, arg.c_str(), size); + return ret; +} + +//------------------------------------------------------------------------------ + Namespace *lookupNamespace(const char *ns) { if(!ns) @@ -1911,7 +1614,7 @@ bool isCurrentScriptToolScript() #ifndef TORQUE_TOOLS return false; #else - const StringTableEntry cbFullPath = CodeBlock::getCurrentCodeBlockFullPath(); + const StringTableEntry cbFullPath = getCurrentScriptModulePath(); if(cbFullPath == NULL) return false; const StringTableEntry exePath = Platform::getMainDotCsDir(); @@ -1922,6 +1625,20 @@ bool isCurrentScriptToolScript() //------------------------------------------------------------------------------ +bool isScriptFile(const char* pFilePath) +{ + return (Torque::FS::IsFile(pFilePath) + || Torque::FS::IsFile(pFilePath + String(".dso")) + || Torque::FS::IsFile(pFilePath + String(".mis")) + || Torque::FS::IsFile(pFilePath + String(".mis.dso")) + || Torque::FS::IsFile(pFilePath + String(".gui")) + || Torque::FS::IsFile(pFilePath + String(".gui.dso")) + || Torque::FS::IsFile(pFilePath + String("." TORQUE_SCRIPT_EXTENSION)) + || Torque::FS::IsFile(pFilePath + String("." TORQUE_SCRIPT_EXTENSION) + String(".dso"))); +} + +//------------------------------------------------------------------------------ + StringTableEntry getModNameFromPath(const char *path) { if(path == NULL || *path == 0) @@ -2248,7 +1965,7 @@ bool expandPath(char* pDstPath, U32 size, const char* pSrcPath, const char* pWor if (leadingToken == '.') { // Fetch the code-block file-path. - const StringTableEntry codeblockFullPath = CodeBlock::getCurrentCodeBlockFullPath(); + const StringTableEntry codeblockFullPath = getCurrentScriptModulePath(); // Do we have a code block full path? if (codeblockFullPath == NULL) diff --git a/Engine/source/console/console.h b/Engine/source/console/console.h index 427fb5765c..df921c6949 100644 --- a/Engine/source/console/console.h +++ b/Engine/source/console/console.h @@ -128,6 +128,7 @@ enum ConsoleValueType struct ConsoleValueConsoleType { + S32 consoleType; void* dataPtr; EnumTable* enumTable; }; @@ -340,8 +341,8 @@ class ConsoleValue TORQUE_FORCEINLINE void setConsoleData(S32 consoleType, void* dataPtr, const EnumTable* enumTable) { cleanupData(); - type = ConsoleValueType::cvSTEntry; - ct = new ConsoleValueConsoleType{ dataPtr, const_cast(enumTable) }; + type = ConsoleValueType::cvConsoleValueType; + ct = new ConsoleValueConsoleType{ consoleType, dataPtr, const_cast(enumTable) }; } TORQUE_FORCEINLINE S32 getType() const @@ -364,6 +365,18 @@ class ConsoleValue return type >= ConsoleValueType::cvConsoleValueType; } + TORQUE_FORCEINLINE ConsoleValueConsoleType* getConsoleType() const + { + if(type >= ConsoleValueType::cvConsoleValueType) + { + return ct; + } + else + { + return NULL; + } + } + TORQUE_FORCEINLINE void setFastFloat(F64 flt) { type = ConsoleValueType::cvFloat; @@ -626,6 +639,7 @@ namespace Con StringTableEntry getPathExpandoValue(U32 expandoIndex); bool isCurrentScriptToolScript(); + bool isScriptFile(const char* path); StringTableEntry getModNameFromPath(const char *path); @@ -918,30 +932,6 @@ namespace Con ConsoleValue execute(SimObject *object, S32 argc, const char* argv[], bool thisCallOnly = false); ConsoleValue execute(SimObject *object, S32 argc, ConsoleValue argv[], bool thisCallOnly = false); - /// Executes a script file and compiles it for use in script. - /// - /// @param string File name that is the script to be executed and compiled. - /// @param fileName Path to the file to execute - /// @param noCalls Deprecated - /// @param journalScript Deprecated - /// - /// @return True if the script was successfully executed, false if not. - bool executeFile(const char* fileName, bool noCalls, bool journalScript); - - /// Evaluate an arbitrary chunk of code. - /// - /// @param string Buffer containing code to execute. - /// @param echo Should we echo the string to the console? - /// @param fileName Indicate what file this code is coming from; used in error reporting and such. - /// NOTE: This function restores the console stack on return. - ConsoleValue evaluate(const char* string, bool echo = false, const char *fileName = NULL); - - /// Evaluate an arbitrary line of script. - /// - /// This wraps dVsprintf(), so you can substitute parameters into the code being executed. - /// NOTE: This function restores the console stack on return. - ConsoleValue evaluatef(const char* string, ...); - /// @} /// @name Console Function Implementation Helpers diff --git a/Engine/source/console/consoleDoc.cpp b/Engine/source/console/consoleDoc.cpp index 26097c2f9a..5ecb3854b0 100644 --- a/Engine/source/console/consoleDoc.cpp +++ b/Engine/source/console/consoleDoc.cpp @@ -23,14 +23,12 @@ #include "platform/platform.h" #include "console/console.h" -#include "console/ast.h" #include "core/tAlgorithm.h" #include "core/strings/findMatch.h" #include "console/consoleInternal.h" #include "console/consoleObject.h" #include "core/stream/fileStream.h" -#include "console/compiler.h" #include "core/frameAllocator.h" #include "console/engineAPI.h" @@ -272,7 +270,7 @@ void Namespace::printNamespaceEntries(Namespace * g, bool dumpScript, bool dumpE } else if(ewalk->mFunctionOffset) // If it's a builtin function... { - String args = ewalk->mCode->getFunctionArgs(ewalk->mFunctionOffset); + String args = ewalk->mModule->getFunctionArgs(ewalk->mFunctionName, ewalk->mFunctionOffset); printClassMethod(false, typeNames[ewalk->mType], ewalk->mFunctionName, args, ""); } else diff --git a/Engine/source/console/consoleFunctions.cpp b/Engine/source/console/consoleFunctions.cpp index f191c5d405..d431cca78f 100644 --- a/Engine/source/console/consoleFunctions.cpp +++ b/Engine/source/console/consoleFunctions.cpp @@ -24,18 +24,17 @@ #include "console/console.h" #include "console/consoleInternal.h" #include "console/engineAPI.h" -#include "console/ast.h" #ifndef _CONSOLFUNCTIONS_H_ #include "console/consoleFunctions.h" #endif +#include "script.h" #include "cinterface/cinterface.h" #include "core/strings/findMatch.h" #include "core/strings/stringUnit.h" #include "core/strings/unicode.h" #include "core/stream/fileStream.h" -#include "console/compiler.h" #include "platform/platformInput.h" #include "core/util/journal/journal.h" #include "gfx/gfxEnums.h" @@ -43,6 +42,7 @@ #include "core/color.h" #include "math/mPoint3.h" #include "math/mathTypes.h" +#include "torquescript/runtime.h" // This is a temporary hack to get tools using the library to // link in this module which contains no other references. @@ -2330,63 +2330,7 @@ DefineEngineFunction( compile, bool, ( const char* fileName, bool overrideNoDSO "@see exec\n" "@ingroup Scripting" ) { - Con::expandScriptFilename( scriptFilenameBuffer, sizeof( scriptFilenameBuffer ), fileName ); - - // Figure out where to put DSOs - StringTableEntry dsoPath = Con::getDSOPath(scriptFilenameBuffer); - if(dsoPath && *dsoPath == 0) - return false; - - // If the script file extention is '.ed.tscript' then compile it to a different compiled extention - bool isEditorScript = false; - const char *ext = dStrrchr( scriptFilenameBuffer, '.' ); - if( ext && ( dStricmp( ext, "." TORQUE_SCRIPT_EXTENSION) == 0 ) ) - { - const char* ext2 = ext - 3; - if( dStricmp( ext2, ".ed." TORQUE_SCRIPT_EXTENSION) == 0 ) - isEditorScript = true; - } - else if( ext && ( dStricmp( ext, ".gui" ) == 0 ) ) - { - const char* ext2 = ext - 3; - if( dStricmp( ext2, ".ed.gui" ) == 0 ) - isEditorScript = true; - } - - const char *filenameOnly = dStrrchr(scriptFilenameBuffer, '/'); - if(filenameOnly) - ++filenameOnly; - else - filenameOnly = scriptFilenameBuffer; - - char nameBuffer[512]; - - if( isEditorScript ) - dStrcpyl(nameBuffer, sizeof(nameBuffer), dsoPath, "/", filenameOnly, ".edso", NULL); - else - dStrcpyl(nameBuffer, sizeof(nameBuffer), dsoPath, "/", filenameOnly, ".dso", NULL); - - void *data = NULL; - U32 dataSize = 0; - Torque::FS::ReadFile(scriptFilenameBuffer, data, dataSize, true); - if(data == NULL) - { - Con::errorf(ConsoleLogEntry::Script, "compile: invalid script file %s.", scriptFilenameBuffer); - return false; - } - - const char *script = static_cast(data); - -#ifdef TORQUE_DEBUG - Con::printf("Compiling %s...", scriptFilenameBuffer); -#endif - - CodeBlock *code = new CodeBlock(); - code->compile(nameBuffer, scriptFilenameBuffer, script, overrideNoDSO); - delete code; - delete[] script; - - return true; + return TorqueScript::getRuntime()->compile(fileName, overrideNoDSO); } //----------------------------------------------------------------------------- @@ -2410,12 +2354,12 @@ DefineEngineFunction( exec, bool, ( const char* fileName, bool noCalls, bool jou DefineEngineFunction( eval, const char*, ( const char* consoleString ), , "eval(consoleString)" ) { - ConsoleValue returnValue = Con::evaluate(consoleString, false, NULL); + Con::EvalResult returnValue = Con::evaluate(consoleString, false, NULL); - return Con::getReturnBuffer(returnValue.getString()); + return Con::getReturnBuffer(returnValue.value.getString()); } -DefineEngineFunction( getVariable, const char*, ( const char* varName ), , "(string varName)\n" +DefineEngineFunction( getVariable, const char*, ( const char* varName ), , "(string varName)\n" "@brief Returns the value of the named variable or an empty string if not found.\n\n" "@varName Name of the variable to search for\n" "@return Value contained by varName, \"\" if the variable does not exist\n" @@ -2589,15 +2533,15 @@ DefineEngineFunction( isDefined, bool, ( const char* varName, const char* varVal else if (name[0] == '%') { // Look up a local variable - if( gEvalState.getStackDepth() > 0 ) + if( Con::getFrameStack().size() > 0 ) { - Dictionary::Entry* ent = gEvalState.getCurrentFrame().lookup(name); + Dictionary::Entry* ent = Con::getCurrentStackFrame()->lookup(name); if (ent) return true; else if (!String::isEmpty(varValue)) { - gEvalState.getCurrentFrame().setVariable(name, varValue); + Con::getCurrentStackFrame()->setVariable(name, varValue); } } else @@ -2606,13 +2550,13 @@ DefineEngineFunction( isDefined, bool, ( const char* varName, const char* varVal else if (name[0] == '$') { // Look up a global value - Dictionary::Entry* ent = gEvalState.globalVars.lookup(name); + Dictionary::Entry* ent = Con::gGlobalVars.lookup(name); if (ent) return true; else if (!String::isEmpty(varValue)) { - gEvalState.globalVars.setVariable(name, varValue); + Con::gGlobalVars.setVariable(name, varValue); } } else @@ -2739,7 +2683,7 @@ DefineEngineFunction( export, void, ( const char* pattern, const char* filename, else filename = NULL; - gEvalState.globalVars.exportVariables( pattern, filename, append ); + Con::gGlobalVars.exportVariables( pattern, filename, append ); } //----------------------------------------------------------------------------- @@ -2756,7 +2700,7 @@ DefineEngineFunction( deleteVariables, void, ( const char* pattern ),, "@see strIsMatchExpr\n" "@ingroup Scripting" ) { - gEvalState.globalVars.deleteVariables( pattern ); + Con::gGlobalVars.deleteVariables( pattern ); } //----------------------------------------------------------------------------- @@ -2769,8 +2713,8 @@ DefineEngineFunction( trace, void, ( bool enable ), ( true ), "@param enable New setting for script trace execution, on by default.\n" "@ingroup Debugging" ) { - gEvalState.traceOn = enable; - Con::printf( "Console trace %s", gEvalState.traceOn ? "enabled." : "disabled." ); + Con::gTraceOn = enable; + Con::printf( "Console trace %s", Con::gTraceOn ? "enabled." : "disabled." ); } //----------------------------------------------------------------------------- diff --git a/Engine/source/console/consoleInternal.cpp b/Engine/source/console/consoleInternal.cpp index dda6d27599..65bcf3ae96 100644 --- a/Engine/source/console/consoleInternal.cpp +++ b/Engine/source/console/consoleInternal.cpp @@ -25,13 +25,11 @@ #include "platform/platform.h" #include "console/console.h" -#include "console/ast.h" #include "core/tAlgorithm.h" #include "core/strings/findMatch.h" #include "console/consoleInternal.h" #include "core/stream/fileStream.h" -#include "console/compiler.h" #include "console/engineAPI.h" //#define DEBUG_SPEW @@ -183,13 +181,13 @@ void Dictionary::exportVariables(const char *varString, const char *fileName, bo for (s = sortList.begin(); s != sortList.end(); s++) { - switch ((*s)->type) + switch ((*s)->value.getType()) { - case Entry::TypeInternalInt: - dSprintf(buffer, sizeof(buffer), "%s = %d;%s", (*s)->name, (*s)->ival, cat); + case ConsoleValueType::cvInteger: + dSprintf(buffer, sizeof(buffer), "%s = %d;%s", (*s)->name, (*s)->getIntValue(), cat); break; - case Entry::TypeInternalFloat: - dSprintf(buffer, sizeof(buffer), "%s = %g;%s", (*s)->name, (*s)->fval, cat); + case ConsoleValueType::cvFloat: + dSprintf(buffer, sizeof(buffer), "%s = %g;%s", (*s)->name, (*s)->getFloatValue(), cat); break; default: expandEscape(expandBuffer, (*s)->getStringValue()); @@ -243,7 +241,7 @@ void Dictionary::exportVariables(const char *varString, Vector *names, V if (values) { - switch ((*s)->type) + switch ((*s)->value.getType()) { case ConsoleValueType::cvInteger: case ConsoleValueType::cvFloat: @@ -375,18 +373,16 @@ Dictionary::Dictionary() #pragma warning( disable : 4355 ) ownHashTable(this), // Warning with VC++ but this is safe. #pragma warning( default : 4355 ) - exprState(NULL), scopeName(NULL), scopeNamespace(NULL), - code(NULL), + module(NULL), ip(0) { + setState(NULL); } -void Dictionary::setState(ExprEvalState *state, Dictionary* ref) +void Dictionary::setState(Dictionary* ref) { - exprState = state; - if (ref) { hashTable = ref->hashTable; @@ -439,7 +435,7 @@ void Dictionary::reset() scopeName = NULL; scopeNamespace = NULL; - code = NULL; + module = NULL; ip = 0; } @@ -465,19 +461,11 @@ const char *Dictionary::tabComplete(const char *prevText, S32 baseLen, bool fFor Dictionary::Entry::Entry(StringTableEntry in_name) { name = in_name; - type = TypeInternalString; notify = NULL; nextEntry = NULL; mUsage = NULL; mIsConstant = false; mNext = NULL; - - ival = 0; - fval = 0; - sval = NULL; - bufferLen = 0; - dataPtr = NULL; - enumTable = NULL; } Dictionary::Entry::~Entry() @@ -488,73 +476,11 @@ Dictionary::Entry::~Entry() void Dictionary::Entry::reset() { name = NULL; - if (type <= TypeInternalString && sval != NULL) - dFree(sval); + value.reset(); if (notify) delete notify; } -void Dictionary::Entry::setStringValue(const char* value) -{ - if (mIsConstant) - { - Con::errorf("Cannot assign value to constant '%s'.", name); - return; - } - - if (type <= TypeInternalString) - { - // Let's not remove empty-string-valued global vars from the dict. - // If we remove them, then they won't be exported, and sometimes - // it could be necessary to export such a global. There are very - // few empty-string global vars so there's no performance-related - // need to remove them from the dict. - /* - if(!value[0] && name[0] == '$') - { - gEvalState.globalVars.remove(this); - return; - } - */ - - U32 stringLen = dStrlen(value); - - // If it's longer than 256 bytes, it's certainly not a number. - // - // (This decision may come back to haunt you. Shame on you if it - // does.) - if (stringLen < 256) - { - fval = dAtof(value); - ival = dAtoi(value); - } - else - { - fval = 0.f; - ival = 0; - } - - type = TypeInternalString; - - // may as well pad to the next cache line - U32 newLen = ((stringLen + 1) + 15) & ~15; - - if (sval == NULL) - sval = (char*)dMalloc(newLen); - else if (newLen > bufferLen) - sval = (char*)dRealloc(sval, newLen); - - bufferLen = newLen; - dStrcpy(sval, value, newLen); - } - else - Con::setData(type, dataPtr, 0, 1, &value, enumTable); - - // Fire off the notification if we have one. - if (notify) - notify->trigger(); -} - const char *Dictionary::getVariable(StringTableEntry name, bool *entValid) { Entry *ent = lookup(name); @@ -630,17 +556,12 @@ Dictionary::Entry* Dictionary::addVariable(const char *name, Entry *ent = add(StringTable->insert(name)); - if (ent->type <= Entry::TypeInternalString && ent->sval != NULL) - dFree(ent->sval); - ent->mUsage = usage; - ent->type = type; - ent->dataPtr = dataPtr; // Fetch enum table, if any. ConsoleBaseType* conType = ConsoleBaseType::getType(type); AssertFatal(conType, "Dictionary::addVariable - invalid console type"); - ent->enumTable = conType->getEnumTable(); + ent->value.setConsoleData(type, dataPtr, conType->getEnumTable()); return ent; } @@ -680,158 +601,15 @@ void Dictionary::validate() "Dictionary::validate() - Dictionary not owner of own hashtable!"); } -void ExprEvalState::pushFrame(StringTableEntry frameName, Namespace *ns, S32 registerCount) -{ -#ifdef DEBUG_SPEW - validate(); - - Platform::outputDebugString("[ConsoleInternal] Pushing new frame for '%s' at %i", - frameName, mStackDepth); -#endif - - if (mStackDepth + 1 > stack.size()) - { -#ifdef DEBUG_SPEW - Platform::outputDebugString("[ConsoleInternal] Growing stack by one frame"); -#endif - - stack.push_back(new Dictionary); - } - - Dictionary& newFrame = *(stack[mStackDepth]); - newFrame.setState(this); - - newFrame.scopeName = frameName; - newFrame.scopeNamespace = ns; - - mStackDepth++; - currentVariable = NULL; - - AssertFatal(!newFrame.getCount(), "ExprEvalState::pushFrame - Dictionary not empty!"); - - ConsoleValue* consoleValArray = new ConsoleValue[registerCount](); - localStack.push_back(ConsoleValueFrame(consoleValArray, false)); - currentRegisterArray = &localStack.last(); - - AssertFatal(mStackDepth == localStack.size(), avar("Stack sizes do not match. mStackDepth = %d, localStack = %d", mStackDepth, localStack.size())); - -#ifdef DEBUG_SPEW - validate(); -#endif -} - -void ExprEvalState::popFrame() -{ - AssertFatal(mStackDepth > 0, "ExprEvalState::popFrame - Stack Underflow!"); - -#ifdef DEBUG_SPEW - validate(); - - Platform::outputDebugString("[ConsoleInternal] Popping %sframe at %i", - getCurrentFrame().isOwner() ? "" : "shared ", mStackDepth - 1); -#endif - - mStackDepth--; - stack[mStackDepth]->reset(); - currentVariable = NULL; - - const ConsoleValueFrame& frame = localStack.last(); - localStack.pop_back(); - if (!frame.isReference) - delete[] frame.values; - - currentRegisterArray = localStack.size() ? &localStack.last() : NULL; - - AssertFatal(mStackDepth == localStack.size(), avar("Stack sizes do not match. mStackDepth = %d, localStack = %d", mStackDepth, localStack.size())); - -#ifdef DEBUG_SPEW - validate(); -#endif -} - -void ExprEvalState::pushFrameRef(S32 stackIndex) -{ - AssertFatal(stackIndex >= 0 && stackIndex < mStackDepth, "You must be asking for a valid frame!"); - -#ifdef DEBUG_SPEW - validate(); - - Platform::outputDebugString("[ConsoleInternal] Cloning frame from %i to %i", - stackIndex, mStackDepth); -#endif - - if (mStackDepth + 1 > stack.size()) - { -#ifdef DEBUG_SPEW - Platform::outputDebugString("[ConsoleInternal] Growing stack by one frame"); -#endif - - stack.push_back(new Dictionary); - } - - Dictionary& newFrame = *(stack[mStackDepth]); - newFrame.setState(this, stack[stackIndex]); - - mStackDepth++; - currentVariable = NULL; - - ConsoleValue* values = localStack[stackIndex].values; - localStack.push_back(ConsoleValueFrame(values, true)); - currentRegisterArray = &localStack.last(); - - AssertFatal(mStackDepth == localStack.size(), avar("Stack sizes do not match. mStackDepth = %d, localStack = %d", mStackDepth, localStack.size())); - -#ifdef DEBUG_SPEW - validate(); -#endif -} - -void ExprEvalState::pushDebugFrame(S32 stackIndex) -{ - pushFrameRef(stackIndex); - - Dictionary& newFrame = *(stack[mStackDepth - 1]); - - // debugger needs to know this info... - newFrame.scopeName = stack[stackIndex]->scopeName; - newFrame.scopeNamespace = stack[stackIndex]->scopeNamespace; - newFrame.code = stack[stackIndex]->code; - newFrame.ip = stack[stackIndex]->ip; -} - -ExprEvalState::ExprEvalState() -{ - VECTOR_SET_ASSOCIATION(stack); - globalVars.setState(this); - thisObject = NULL; - traceOn = false; - currentVariable = NULL; - mStackDepth = 0; - stack.reserve(64); - mShouldReset = false; - mResetLocked = false; - copyVariable = NULL; - currentRegisterArray = NULL; -} - -ExprEvalState::~ExprEvalState() +Con::Module* Con::findScriptModuleForFile(const char* fileName) { - // Delete callframes. - - while (!stack.empty()) + for (Con::Module* module : gScriptModules) { - delete stack.last(); - stack.decrement(); + if (module->getName() == fileName) { + return module; + } } -} - -void ExprEvalState::validate() -{ - AssertFatal(mStackDepth <= stack.size(), - "ExprEvalState::validate() - Stack depth pointing beyond last stack frame!"); - - for (U32 i = 0; i < stack.size(); ++i) - stack[i]->validate(); + return NULL; } DefineEngineFunction(backtrace, void, (), , @@ -842,35 +620,37 @@ DefineEngineFunction(backtrace, void, (), , { U32 totalSize = 1; - for (U32 i = 0; i < gEvalState.getStackDepth(); i++) + for (U32 i = 0; i < Con::getFrameStack().size(); i++) { - if (gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage) - totalSize += dStrlen(gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage) + 2; - if (gEvalState.stack[i]->scopeName) - totalSize += dStrlen(gEvalState.stack[i]->scopeName) + 3; - if (gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mName) - totalSize += dStrlen(gEvalState.stack[i]->scopeNamespace->mName) + 2; + const Con::ConsoleFrame* frame = Con::getStackFrame(i); + if (frame->scopeNamespace && frame->scopeNamespace->mEntryList->mPackage) + totalSize += dStrlen(frame->scopeNamespace->mEntryList->mPackage) + 2; + if (frame->scopeName) + totalSize += dStrlen(frame->scopeName) + 3; + if (frame->scopeNamespace && frame->scopeNamespace->mName) + totalSize += dStrlen(frame->scopeNamespace->mName) + 2; } char *buf = Con::getReturnBuffer(totalSize); buf[0] = 0; - for (U32 i = 0; i < gEvalState.getStackDepth(); i++) + for (U32 i = 0; i < Con::getFrameStack().size(); i++) { + const Con::ConsoleFrame* frame = Con::getStackFrame(i); dStrcat(buf, "->", totalSize); - if (gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage) + if (frame->scopeNamespace && frame->scopeNamespace->mEntryList->mPackage) { dStrcat(buf, "[", totalSize); - dStrcat(buf, gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage, totalSize); + dStrcat(buf, frame->scopeNamespace->mEntryList->mPackage, totalSize); dStrcat(buf, "]", totalSize); } - if (gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mName) + if (frame->scopeNamespace && frame->scopeNamespace->mName) { - dStrcat(buf, gEvalState.stack[i]->scopeNamespace->mName, totalSize); + dStrcat(buf, frame->scopeNamespace->mName, totalSize); dStrcat(buf, "::", totalSize); } - if (gEvalState.stack[i]->scopeName) - dStrcat(buf, gEvalState.stack[i]->scopeName, totalSize); + if (frame->scopeName) + dStrcat(buf, frame->scopeName, totalSize); } Con::printf("BackTrace: %s", buf); @@ -878,7 +658,7 @@ DefineEngineFunction(backtrace, void, (), , Namespace::Entry::Entry() { - mCode = NULL; + mModule = NULL; mType = InvalidFunctionType; mUsage = NULL; mHeader = NULL; @@ -896,10 +676,10 @@ Namespace::Entry::Entry() void Namespace::Entry::clear() { - if (mCode) + if (mModule) { - mCode->decRefCount(); - mCode = NULL; + mModule->decRefCount(); + mModule = NULL; } // Clean up usage strings generated for script functions. @@ -1233,15 +1013,15 @@ Namespace::Entry *Namespace::createLocalEntry(StringTableEntry name) return ent; } -void Namespace::addFunction(StringTableEntry name, CodeBlock *cb, U32 functionOffset, const char* usage, U32 lineNumber) +void Namespace::addFunction(StringTableEntry name, Con::Module *cb, U32 functionOffset, const char* usage, U32 lineNumber) { Entry *ent = createLocalEntry(name); trashCache(); ent->mUsage = usage; - ent->mCode = cb; + ent->mModule = cb; ent->mFunctionOffset = functionOffset; - ent->mCode->incRefCount(); + ent->mModule->incRefCount(); ent->mType = Entry::ConsoleFunctionType; ent->mFunctionLineNumber = lineNumber; } @@ -1366,9 +1146,7 @@ void Namespace::markGroup(const char* name, const char* usage) ent->cb.mGroupName = name; } -extern S32 executeBlock(StmtNode *block, ExprEvalState *state); - -ConsoleValue Namespace::Entry::execute(S32 argc, ConsoleValue *argv, ExprEvalState *state) +ConsoleValue Namespace::Entry::execute(S32 argc, ConsoleValue *argv, SimObject *thisObj) { STR.clearFunctionOffset(); @@ -1376,7 +1154,7 @@ ConsoleValue Namespace::Entry::execute(S32 argc, ConsoleValue *argv, ExprEvalSta { if (mFunctionOffset) { - return std::move(mCode->exec(mFunctionOffset, argv[0].getString(), mNamespace, argc, argv, false, mPackage)); + return std::move(mModule->exec(mFunctionOffset, argv[0].getString(), mNamespace, argc, argv, false, mPackage).value); } else { @@ -1406,21 +1184,21 @@ ConsoleValue Namespace::Entry::execute(S32 argc, ConsoleValue *argv, ExprEvalSta { case StringCallbackType: { - const char* str = cb.mStringCallbackFunc(state->thisObject, argc, argv); + const char* str = cb.mStringCallbackFunc(thisObj, argc, argv); result.setString(str); break; } case IntCallbackType: - result.setInt(cb.mIntCallbackFunc(state->thisObject, argc, argv)); + result.setInt(cb.mIntCallbackFunc(thisObj, argc, argv)); break; case FloatCallbackType: - result.setFloat(cb.mFloatCallbackFunc(state->thisObject, argc, argv)); + result.setFloat(cb.mFloatCallbackFunc(thisObj, argc, argv)); break; case VoidCallbackType: - cb.mVoidCallbackFunc(state->thisObject, argc, argv); + cb.mVoidCallbackFunc(thisObj, argc, argv); break; case BoolCallbackType: - result.setBool(cb.mBoolCallbackFunc(state->thisObject, argc, argv)); + result.setBool(cb.mBoolCallbackFunc(thisObj, argc, argv)); break; } @@ -1704,7 +1482,7 @@ String Namespace::Entry::getArgumentsString() const if (sFindArgumentListSubstring(mUsage, argListStart, argListEnd)) str.append(argListStart, argListEnd - argListStart); - else if (mType == ConsoleFunctionType && mCode) + else if (mType == ConsoleFunctionType && mModule) { // This isn't correct but the nonsense console stuff is set up such that all // functions that have no function bodies are keyed to offset 0 to indicate "no code." @@ -1716,7 +1494,7 @@ String Namespace::Entry::getArgumentsString() const if (!mFunctionOffset) return "()"; - String args = mCode->getFunctionArgs(mFunctionOffset); + String args = mModule->getFunctionArgs(mFunctionName, mFunctionOffset); if (args.isEmpty()) return "()"; diff --git a/Engine/source/console/consoleInternal.h b/Engine/source/console/consoleInternal.h index 16b91eb220..6c0c918281 100644 --- a/Engine/source/console/consoleInternal.h +++ b/Engine/source/console/consoleInternal.h @@ -38,12 +38,12 @@ #ifndef _DATACHUNKER_H_ #include "core/dataChunker.h" #endif +#include "module.h" /// @ingroup console_system Console System /// @{ -class ExprEvalState; struct FunctionDecl; class CodeBlock; class AbstractClassRep; @@ -125,7 +125,7 @@ class Namespace ConsoleFunctionHeader* mHeader; /// The compiled script code if this is a script function. - CodeBlock* mCode; + Con::Module* mModule; /// The offset in the compiled script code at which this function begins. U32 mFunctionOffset; @@ -150,7 +150,7 @@ class Namespace void clear(); /// - ConsoleValue execute(S32 argc, ConsoleValue* argv, ExprEvalState* state); + ConsoleValue execute(S32 argc, ConsoleValue* argv, SimObject* thisObj); /// Return a one-line documentation text string for the function. String getBriefDescription(String* outRemainingDocText = NULL) const; @@ -181,7 +181,7 @@ class Namespace Namespace(); ~Namespace(); - void addFunction(StringTableEntry name, CodeBlock* cb, U32 functionOffset, const char* usage = NULL, U32 lineNumber = 0); + void addFunction(StringTableEntry name, Con::Module* cb, U32 functionOffset, const char* usage = NULL, U32 lineNumber = 0); void addCommand(StringTableEntry name, StringCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); void addCommand(StringTableEntry name, IntCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); void addCommand(StringTableEntry name, FloatCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); @@ -286,16 +286,8 @@ class Dictionary { friend class Dictionary; - enum - { - TypeInternalInt = -3, - TypeInternalFloat = -2, - TypeInternalString = -1, - }; - StringTableEntry name; Entry *nextEntry; - S32 type; typedef Signal NotifySignal; @@ -309,58 +301,17 @@ class Dictionary /// Whether this is a constant that cannot be assigned to. bool mIsConstant; - protected: - - // NOTE: This is protected to ensure no one outside - // of this structure is messing with it. - -#pragma warning( push ) -#pragma warning( disable : 4201 ) // warning C4201: nonstandard extension used : nameless struct/union - - // An variable is either a real dynamic type or - // its one exposed from C++ using a data pointer. - // - // We use this nameless union and struct setup - // to optimize the memory usage. - union - { - struct - { - char* sval; - U32 ival; // doubles as strlen when type is TypeInternalString - F32 fval; - U32 bufferLen; - }; - - struct - { - /// The real data pointer. - void* dataPtr; - - /// The enum lookup table for enumerated types. - const EnumTable* enumTable; - }; - }; - -#pragma warning( pop ) // C4201 + ConsoleValue value; public: Entry() { name = NULL; - type = TypeInternalString; notify = NULL; nextEntry = NULL; mUsage = NULL; mIsConstant = false; mNext = NULL; - - ival = 0; - fval = 0; - sval = NULL; - bufferLen = 0; - dataPtr = NULL; - enumTable = NULL; } Entry(StringTableEntry name); @@ -370,32 +321,21 @@ class Dictionary void reset(); + inline ConsoleValue getValue() { return std::move(value); } + inline U32 getIntValue() { - if (type <= TypeInternalString) - return ival; - else - return dAtoi(Con::getData(type, dataPtr, 0, enumTable)); + return value.getInt(); } inline F32 getFloatValue() { - if (type <= TypeInternalString) - return fval; - else - return dAtof(Con::getData(type, dataPtr, 0, enumTable)); + return value.getFloat(); } inline const char *getStringValue() { - if (type == TypeInternalString) - return sval; - if (type == TypeInternalFloat) - return Con::getData(TypeF32, &fval, 0); - else if (type == TypeInternalInt) - return Con::getData(TypeS32, &ival, 0); - else - return Con::getData(type, dataPtr, 0, enumTable); + return value.getString(); } void setIntValue(U32 val) @@ -406,21 +346,15 @@ class Dictionary return; } - if (type <= TypeInternalString) + if (value.isConsoleType()) { - fval = (F32)val; - ival = val; - if (sval != NULL) - { - dFree(sval); - sval = NULL; - } - type = TypeInternalInt; + const char* dptr = Con::getData(TypeS32, &val, 0); + ConsoleValueConsoleType* cvt = value.getConsoleType(); + Con::setData(cvt->consoleType, cvt->dataPtr, 0, 1, &dptr, cvt->enumTable); } else { - const char* dptr = Con::getData(TypeS32, &val, 0); - Con::setData(type, dataPtr, 0, 1, &dptr, enumTable); + value.setInt(val); } // Fire off the notification if we have one. @@ -436,21 +370,15 @@ class Dictionary return; } - if (type <= TypeInternalString) + if (value.isConsoleType()) { - fval = val; - ival = static_cast(val); - if (sval != NULL) - { - dFree(sval); - sval = NULL; - } - type = TypeInternalFloat; + const char* dptr = Con::getData(TypeF32, &val, 0); + ConsoleValueConsoleType* cvt = value.getConsoleType(); + Con::setData(cvt->consoleType, cvt->dataPtr, 0, 1, &dptr, cvt->enumTable); } else { - const char* dptr = Con::getData(TypeF32, &val, 0); - Con::setData(type, dataPtr, 0, 1, &dptr, enumTable); + value.setFloat(val); } // Fire off the notification if we have one. @@ -458,7 +386,29 @@ class Dictionary notify->trigger(); } - void setStringValue(const char* value); + + void setStringValue(const char* val) + { + if (mIsConstant) + { + Con::errorf("Cannot assign value to constant '%s'.", name); + return; + } + + if (value.isConsoleType()) + { + ConsoleValueConsoleType* cvt = value.getConsoleType(); + Con::setData(cvt->consoleType, cvt->dataPtr, 0, 1, &val, cvt->enumTable); + } + else + { + value.setString(val); + } + + // Fire off the notification if we have one. + if (notify) + notify->trigger(); + } }; struct HashTableData @@ -475,11 +425,10 @@ class Dictionary HashTableData* hashTable; HashTableData ownHashTable; - ExprEvalState *exprState; StringTableEntry scopeName; Namespace *scopeNamespace; - CodeBlock *code; + Con::Module *module; U32 ip; Dictionary(); @@ -487,7 +436,7 @@ class Dictionary Entry *lookup(StringTableEntry name); Entry *add(StringTableEntry name); - void setState(ExprEvalState *state, Dictionary* ref = NULL); + void setState(Dictionary* ref = NULL); void remove(Entry *); void reset(); @@ -547,126 +496,35 @@ struct ConsoleValueFrame } }; -class ExprEvalState +namespace Con { -public: - /// @name Expression Evaluation - /// @{ - - /// - SimObject *thisObject; - Dictionary::Entry *currentVariable; - Dictionary::Entry *copyVariable; - bool traceOn; - - U32 mStackDepth; - bool mShouldReset; ///< Designates if the value stack should be reset - bool mResetLocked; ///< mShouldReset will be set at the end - - ExprEvalState(); - ~ExprEvalState(); - - /// @} - - /// @name Stack Management - /// @{ - - /// The stack of callframes. The extra redirection is necessary since Dictionary holds - /// an interior pointer that will become invalid when the object changes address. - Vector< Dictionary* > stack; - - S32 getTopOfStack() { return (S32)mStackDepth; } - - Vector< ConsoleValueFrame > localStack; - ConsoleValueFrame* currentRegisterArray; // contains array at to top of localStack - - /// - Dictionary globalVars; - - void setCurVarName(StringTableEntry name); - void setCurVarNameCreate(StringTableEntry name); - - S32 getIntVariable(); - F64 getFloatVariable(); - const char *getStringVariable(); - void setIntVariable(S32 val); - void setFloatVariable(F64 val); - void setStringVariable(const char *str); - - TORQUE_FORCEINLINE S32 getLocalIntVariable(S32 reg) - { - return currentRegisterArray->values[reg].getInt(); - } - - TORQUE_FORCEINLINE F64 getLocalFloatVariable(S32 reg) - { - return currentRegisterArray->values[reg].getFloat(); - } - - TORQUE_FORCEINLINE const char* getLocalStringVariable(S32 reg) - { - return currentRegisterArray->values[reg].getString(); - } - - TORQUE_FORCEINLINE void setLocalIntVariable(S32 reg, S64 val) - { - currentRegisterArray->values[reg].setInt(val); - } - - TORQUE_FORCEINLINE void setLocalFloatVariable(S32 reg, F64 val) - { - currentRegisterArray->values[reg].setFloat(val); - } - - TORQUE_FORCEINLINE void setLocalStringVariable(S32 reg, const char* val, S32 len) - { - currentRegisterArray->values[reg].setString(val, len); - } - - TORQUE_FORCEINLINE void setLocalStringTableEntryVariable(S32 reg, StringTableEntry val) - { - currentRegisterArray->values[reg].setStringTableEntry(val); - } + /// The current $instantGroup setting. + extern String gInstantGroup; - TORQUE_FORCEINLINE void moveConsoleValue(S32 reg, ConsoleValue val) - { - currentRegisterArray->values[reg] = std::move(val); - } + /// Global variable storage + inline Dictionary gGlobalVars; - void pushFrame(StringTableEntry frameName, Namespace *ns, S32 regCount); - void popFrame(); + typedef Dictionary ConsoleFrame; + typedef Vector ConsoleStack; - /// Puts a reference to an existing stack frame - /// on the top of the stack. - void pushFrameRef(S32 stackIndex); + inline ConsoleStack gFrameStack; - void pushDebugFrame(S32 stackIndex); + inline ConsoleStack getFrameStack() { return gFrameStack; } + inline void pushStackFrame(ConsoleFrame* frame) { gFrameStack.push_back(frame); } + inline ConsoleFrame* popStackFrame() { ConsoleFrame* last = gFrameStack.last(); gFrameStack.pop_back(); return last; } + inline ConsoleFrame* getCurrentStackFrame() { return getFrameStack().empty() ? NULL : gFrameStack.last(); } + inline ConsoleFrame* getStackFrame(S32 idx) { return gFrameStack[idx]; } - U32 getStackDepth() const - { - return mStackDepth; - } + inline Vector gScriptModules; - Dictionary& getCurrentFrame() - { - return *(stack[mStackDepth - 1]); - } + inline Vector getAllScriptModules() { return gScriptModules; } + Con::Module* findScriptModuleForFile(const char* fileName); + // Convenience functions for getting the execution context + inline const char* getCurrentScriptModulePath() { return getCurrentStackFrame() && getCurrentStackFrame()->module ? getCurrentStackFrame()->module->getPath() : NULL; } + inline const char* getCurrentScriptModuleName() { return getCurrentStackFrame() && getCurrentStackFrame()->module ? getCurrentStackFrame()->module->getName() : NULL; } + inline Con::Module* getCurrentScriptModule() { return getCurrentStackFrame() ? getCurrentStackFrame()->module : NULL; } - Dictionary& getFrameAt(S32 depth) - { - return *(stack[depth]); - } - - /// @} - - /// Run integrity checks for debugging. - void validate(); -}; - -namespace Con -{ - /// The current $instantGroup setting. - extern String gInstantGroup; + inline bool gTraceOn; } /// @} diff --git a/Engine/source/console/engineDoc.cpp b/Engine/source/console/engineDoc.cpp index c471fe820b..baffb12e6c 100644 --- a/Engine/source/console/engineDoc.cpp +++ b/Engine/source/console/engineDoc.cpp @@ -26,7 +26,6 @@ #include "console/engineAPI.h" #include "core/stream/fileStream.h" #include "console/consoleInternal.h" -#include "console/compiler.h" #define USE_UNDOCUMENTED_GROUP @@ -113,10 +112,10 @@ static void dumpVariable( Stream& stream, const char* inClass = NULL ) { // Skip variables defined in script. - - if( entry->type <= Dictionary::Entry::TypeInternalString ) + + if( entry->value.getType() <= ConsoleValueType::cvString ) return; - + // Skip internals... don't export them. if ( entry->mUsage && ( dStrstr( entry->mUsage, "@hide" ) || dStrstr( entry->mUsage, "@internal" ) ) ) @@ -146,10 +145,10 @@ static void dumpVariable( Stream& stream, if( nameComponents.size() > 1 && Con::lookupNamespace( nameComponents.first().c_str() + 1 )->mClassRep ) return; } - + // Skip variables for which we can't decipher their type. - ConsoleBaseType* type = ConsoleBaseType::getType( entry->type ); + ConsoleBaseType* type = ConsoleBaseType::getType( entry->value.getConsoleType()->consoleType ); if( !type ) { Con::errorf( "Can't find type for variable '%s'", entry->name ); @@ -204,9 +203,9 @@ static void dumpVariable( Stream& stream, static void dumpVariables( Stream& stream, const char* inClass = NULL ) { - const U32 hashTableSize = gEvalState.globalVars.hashTable->size; + const U32 hashTableSize = Con::gGlobalVars.hashTable->size; for( U32 i = 0; i < hashTableSize; ++ i ) - for( Dictionary::Entry* entry = gEvalState.globalVars.hashTable->data[ i ]; entry != NULL; entry = entry->nextEntry ) + for( Dictionary::Entry* entry = Con::gGlobalVars.hashTable->data[ i ]; entry != NULL; entry = entry->nextEntry ) dumpVariable( stream, entry, inClass ); } diff --git a/Engine/source/console/fileSystemFunctions.cpp b/Engine/source/console/fileSystemFunctions.cpp index f56bc8a85e..5706abc962 100644 --- a/Engine/source/console/fileSystemFunctions.cpp +++ b/Engine/source/console/fileSystemFunctions.cpp @@ -24,9 +24,7 @@ #include "console/console.h" #include "console/consoleInternal.h" #include "console/engineAPI.h" -#include "console/ast.h" #include "core/stream/fileStream.h" -#include "console/compiler.h" #include "platform/platformInput.h" #include "torqueConfig.h" #include "core/frameAllocator.h" @@ -420,7 +418,7 @@ DefineEngineFunction(isScriptFile, bool, (const char* fileName), , "@ingroup FileSystem") { - return Torque::FS::IsScriptFile(fileName); + return Con::isScriptFile(fileName); } DefineEngineFunction( IsDirectory, bool, ( const char* directory ),, diff --git a/Engine/source/console/module.h b/Engine/source/console/module.h new file mode 100644 index 0000000000..4b5b35bb56 --- /dev/null +++ b/Engine/source/console/module.h @@ -0,0 +1,45 @@ +#ifndef _SCRIPT_MODULE_H_ +#define _SCRIPT_MODULE_H_ +#include "runtime.h" +#include "console/console.h" +#include "platform/types.h" + +namespace Con +{ + class Module + { + private: + S32 mRefCount = 0; + public: + Module() = default; + virtual ~Module() = default; + + void incRefCount() { mRefCount++; } + void decRefCount() { mRefCount--; if (!mRefCount) delete this; } + virtual const char* getFunctionArgs(StringTableEntry functionName, U32 functionOffset) = 0; + virtual const char* getPath() = 0; + virtual const char* getName() = 0; + + virtual EvalResult exec(U32 offset, const char* fnName, Namespace* ns, U32 argc, + ConsoleValue* argv, bool noCalls, StringTableEntry packageName, + S32 setFrame = -1) = 0; + virtual void findBreakLine(U32 ip, U32& line, U32& instruction) = 0; + virtual const char *getFileLine(U32 ip) = 0; + + /// Returns the first breakable line or 0 if none was found. + /// @param lineNumber The one based line number. + virtual U32 findFirstBreakLine(U32 lineNumber) = 0; + + /// Set a OP_BREAK instruction on a line. If a break + /// is not possible on that line it returns false. + /// @param lineNumber The one based line number. + virtual bool setBreakpoint(U32 lineNumber) = 0; + + virtual void setAllBreaks() = 0; + virtual void clearAllBreaks() = 0; + virtual void clearBreakpoint(U32 lineNumber) = 0; + virtual Vector getBreakableLines() = 0; + }; +} + +#endif diff --git a/Engine/source/console/propertyParsing.cpp b/Engine/source/console/propertyParsing.cpp index a97a84403c..1cc59565e7 100644 --- a/Engine/source/console/propertyParsing.cpp +++ b/Engine/source/console/propertyParsing.cpp @@ -35,8 +35,6 @@ // Property system includes: #include "console/propertyParsing.h" -extern ExprEvalState gEvalState; - namespace PropertyInfo { //----------------------------------------------------------------------------- diff --git a/Engine/source/console/runtime.h b/Engine/source/console/runtime.h new file mode 100644 index 0000000000..d10df543cf --- /dev/null +++ b/Engine/source/console/runtime.h @@ -0,0 +1,112 @@ +#ifndef _RUNTIME_H_ +#define _RUNTIME_H_ + +#include "console/console.h" + +namespace Con +{ + struct EvalResult + { + bool valid; + ConsoleValue value; + String error; + + public: + EvalResult() {} + + EvalResult(ConsoleValue&& pValue) + { + valid = true; + value = (ConsoleValue&&)pValue; + } + + EvalResult(String errorMessage) + { + valid = false; + error = errorMessage; + } + }; + + struct Error + { + const char* message; + }; + + struct SyntaxError : Error {}; + + class Stack + { + class Frame + { + public: + ConsoleValue* lookup(const char*); + }; + + public: + S32 getDepth(); + Frame getFrame(S32 idx); + }; + + class Runtime + { + private: + Stack mStack; + public: + virtual ~Runtime() = default; + virtual Stack getStack() { return mStack; } + + /// Convert from a relative script path to an absolute script path. + /// + /// This is used in (among other places) the exec() script function, which + /// takes a parameter indicating a script file and executes it. Script paths + /// can be one of: + /// - Absolute: fps/foo/bar.tscript Paths of this sort are passed + /// through. + /// - Mod-relative: ~/foo/bar.tscript Paths of this sort have their + /// replaced with the name of the current mod. + /// - File-relative: ./baz/blip.tscript Paths of this sort are + /// calculated relative to the path of the current scripting file. + /// + /// @note This function determines paths relative to the currently executing + /// CodeBlock. Calling it outside of script execution will result in + /// it directly copying src to filename, since it won't know to what the + /// path is relative! + /// + /// @param filename Pointer to string buffer to fill with absolute path. + /// @param size Size of buffer pointed to by filename. + /// @param src Original, possibly relative script path. + bool expandScriptFilename(char *filename, U32 size, const char *src); + bool expandToolScriptFilename(char *filename, U32 size, const char *src); + bool collapseScriptFilename(char *filename, U32 size, const char *src); + + virtual void expandEscapedCharacters(char* dest, const char* src) = 0; + virtual bool collapseEscapedCharacters(char* buf) = 0; + + /// Evaluate an arbitrary chunk of code. + /// + /// @param string Buffer containing code to execute. + /// @param echo Should we echo the string to the console? + /// @param fileName Indicate what file this code is coming from; used in error reporting and such. + /// NOTE: This function restores the console stack on return. + virtual EvalResult evaluate(const char* string, bool echo = false, const char *fileName = NULL) = 0; + + virtual EvalResult evaluate(const char* string, S32 frame, bool echo = false, const char *fileName = NULL) = 0; + + /// Evaluate an arbitrary line of script. + /// + /// This wraps dVsprintf(), so you can substitute parameters into the code being executed. + /// NOTE: This function restores the console stack on return. + virtual EvalResult evaluatef(const char* string, ...) = 0; + + /// Executes a script file and compiles it for use in script. + /// + /// @param fileName File name that is the script to be executed and compiled. + /// @param noCalls Deprecated + /// @param journalScript Deprecated + /// + /// @return True if the script was successfully executed, false if not. + virtual bool executeFile(const char* fileName, bool noCalls, bool journalScript) = 0; + }; +} + +#endif diff --git a/Engine/source/console/script.h b/Engine/source/console/script.h new file mode 100644 index 0000000000..ded8acca62 --- /dev/null +++ b/Engine/source/console/script.h @@ -0,0 +1,71 @@ +#ifndef _SCRIPT_H_ +#define _SCRIPT_H_ + +#include "runtime.h" +#include "core/stream/stream.h" +#include "module.h" +#include "core/util/tDictionary.h" + +namespace Con +{ + inline EvalResult gLastEvalResult; + inline EvalResult setLastEvalResult(EvalResult pLastEvalResult) + { + gLastEvalResult.valid = pLastEvalResult.valid; + gLastEvalResult.error = pLastEvalResult.error; + gLastEvalResult.value.setString(pLastEvalResult.value.getString()); + return std::move(pLastEvalResult); + } + inline EvalResult getLastEvalResult() { return setLastEvalResult(std::move(gLastEvalResult)); }; + + bool runStream(Stream* byteCode, const char* fileName); + + bool isCurrentScriptToolScript(); + + + Module* getCurrentModule(); + + inline HashMap gRuntimes; + inline Runtime* getRuntime(S32 pRuntimeId = 0) { return gRuntimes[pRuntimeId]; } + inline void registerRuntime(S32 pRuntimeId, Runtime* pRuntime) + { + AssertFatal(gRuntimes[pRuntimeId] == NULL, "A runtime with that ID already exists"); + gRuntimes[pRuntimeId] = pRuntime; + } + + + /// Evaluate an arbitrary chunk of code. + /// + /// @param script Buffer containing code to execute. + /// @param echo Should we echo the string to the console? + /// @param fileName Indicate what file this code is coming from; used in error reporting and such. + /// NOTE: This function restores the console stack on return. + inline EvalResult evaluate(const char* script, bool echo = false, const char *fileName = NULL) { return setLastEvalResult(getRuntime()->evaluate(script, echo, fileName)); }; + + inline EvalResult evaluate(const char* script, S32 frame, bool echo = false, const char *fileName = NULL) { return setLastEvalResult(getRuntime()->evaluate(script, frame, echo, fileName)); }; + + /// Evaluate an arbitrary line of script. + /// + /// This wraps dVsprintf(), so you can substitute parameters into the code being executed. + /// NOTE: This function restores the console stack on return. + inline EvalResult evaluatef(const char* string, ...) + { + va_list args; + va_start(args, string); + EvalResult result = setLastEvalResult(getRuntime()->evaluatef(string, args)); + va_end(args); + return result; + }; + + /// Executes a script file and compiles it for use in script. + /// + /// @param string File name that is the script to be executed and compiled. + /// @param fileName Path to the file to execute + /// @param noCalls Deprecated + /// @param journalScript Deprecated + /// + /// @return True if the script was successfully executed, false if not. + inline bool executeFile(const char* fileName, bool noCalls, bool journalScript) { return getRuntime()->executeFile(fileName, noCalls, journalScript); }; +} + +#endif diff --git a/Engine/source/console/scriptFilename.cpp b/Engine/source/console/scriptFilename.cpp index b0cacf2bcf..f9f819af50 100644 --- a/Engine/source/console/scriptFilename.cpp +++ b/Engine/source/console/scriptFilename.cpp @@ -23,12 +23,12 @@ #include "platform/platform.h" #include "console/scriptFilename.h" +#include "consoleInternal.h" #include "core/frameAllocator.h" #include "core/tSimpleHashTable.h" #include "core/strings/stringFunctions.h" #include "core/stringTable.h" #include "console/engineAPI.h" -#include "console/compiler.h" namespace Con @@ -88,8 +88,8 @@ bool expandToolScriptFilename(char *filename, U32 size, const char *src) // same way the old code did as it is now possible that something could // be expanded if the name or mod is NULL. This was previously not the case. - const StringTableEntry cbMod = CodeBlock::getCurrentCodeBlockModName(); - const StringTableEntry cbFullPath = CodeBlock::getCurrentCodeBlockFullPath(); + const StringTableEntry cbMod = Con::getCurrentScriptModuleName(); + const StringTableEntry cbFullPath = Con::getCurrentScriptModulePath(); char varBuf[1024], modBuf[1024]; const char *ptr = src; @@ -216,7 +216,8 @@ bool expandToolScriptFilename(char *filename, U32 size, const char *src) bool expandOldScriptFilename(char *filename, U32 size, const char *src) { - const StringTableEntry cbName = CodeBlock::getCurrentCodeBlockName(); + const StringTableEntry cbName = Con::getCurrentScriptModuleName(); + if (!cbName) { dStrcpy(filename, src, size); diff --git a/Engine/source/console/simDatablock.cpp b/Engine/source/console/simDatablock.cpp index ae0fd9c63f..d200f5dfb6 100644 --- a/Engine/source/console/simDatablock.cpp +++ b/Engine/source/console/simDatablock.cpp @@ -27,6 +27,7 @@ #include "platform/platform.h" #include "console/simDatablock.h" +#include "script.h" #include "console/console.h" #include "console/consoleInternal.h" #include "console/engineAPI.h" @@ -34,7 +35,6 @@ #include "T3D/gameBase/gameConnection.h" #include "core/stream/bitStream.h" -#include "console/compiler.h" IMPLEMENT_CO_DATABLOCK_V1(SimDataBlock); SimObjectId SimDataBlock::sNextObjectId = DataBlockObjectIdFirst; @@ -252,17 +252,14 @@ void SimDataBlock::performSubstitutions(SimDataBlock* dblock, const SimObject* o b[0] = '\0'; - // perform the statement evaluation - Compiler::gSyntaxError = false; - //Con::errorf("EVAL [%s]", avar("return %s;", buffer)); - const char *result = Con::evaluate(avar("return %s;", buffer), false, 0); - if (Compiler::gSyntaxError) + Con::EvalResult evalResult = Con::evaluate(avar("return %s;", buffer), false, 0); + if (evalResult.valid) { Con::errorf("Field Substitution Failed: field=\"%s\" substitution=\"%s\" -- syntax error", substitutions[i]->mSlot, substitutions[i]->mValue); - Compiler::gSyntaxError = false; return; } + const char* result = evalResult.value; // output a runtime console error when a substitution produces and empty result. if (result == 0 || result[0] == '\0') diff --git a/Engine/source/console/simEvents.cpp b/Engine/source/console/simEvents.cpp index f6a044c11e..c277285808 100644 --- a/Engine/source/console/simEvents.cpp +++ b/Engine/source/console/simEvents.cpp @@ -25,9 +25,6 @@ #include "platform/threads/semaphore.h" #include "console/simEvents.h" -// Stupid globals not declared in a header -extern ExprEvalState gEvalState; - SimConsoleEvent::SimConsoleEvent(S32 argc, ConsoleValue *argv, bool onObject) { mOnObject = onObject; @@ -79,7 +76,7 @@ void SimConsoleEvent::process(SimObject* object) Namespace::Entry* nse = ns->lookup( StringTable->insert( func ) ); if( nse ) // Execute. - nse->execute( mArgc, mArgv, &gEvalState ); + nse->execute( mArgc, mArgv, object ); } } diff --git a/Engine/source/console/simManager.cpp b/Engine/source/console/simManager.cpp index 94b407a25e..d81704d897 100644 --- a/Engine/source/console/simManager.cpp +++ b/Engine/source/console/simManager.cpp @@ -20,6 +20,7 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +#include "script.h" #include "platform/platform.h" #include "platform/threads/mutex.h" #include "console/simBase.h" @@ -36,8 +37,6 @@ #include "platform/profiler.h" #include "math/mMathFn.h" -extern ExprEvalState gEvalState; - //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- @@ -341,9 +340,9 @@ SimObject* findObject(const char* name) if (c == '%') { - if (gEvalState.getStackDepth()) + if (!Con::getFrameStack().empty()) { - Dictionary::Entry* ent = gEvalState.getCurrentFrame().lookup(StringTable->insert(name)); + Dictionary::Entry* ent = Con::getCurrentStackFrame()->lookup(StringTable->insert(name)); if (ent) return Sim::findObject(ent->getIntValue()); diff --git a/Engine/source/console/simObject.cpp b/Engine/source/console/simObject.cpp index 7d7e3f09d7..3e575b9be5 100644 --- a/Engine/source/console/simObject.cpp +++ b/Engine/source/console/simObject.cpp @@ -35,7 +35,6 @@ #include "console/simPersistID.h" #include "console/typeValidators.h" #include "console/arrayObject.h" -#include "console/codeBlock.h" #include "core/frameAllocator.h" #include "core/stream/fileStream.h" #include "core/fileObject.h" @@ -2479,7 +2478,7 @@ static void sEnumCallback( EngineObject* object ) if( !simObject ) return; - Con::evaluatef( "%s( %i );", sEnumCallbackFunction, simObject->getId() ); + Con::executef(sEnumCallbackFunction, simObject->getId()); } DefineEngineFunction( debugEnumInstances, void, ( const char* className, const char* functionName ),, @@ -2645,10 +2644,10 @@ DefineEngineMethod( SimObject, dumpMethods, ArrayObject*, (),, str.append( e->getPrototypeString() ); str.append( '\n' ); - if( e->mCode && e->mCode->fullPath ) - str.append( e->mCode->fullPath ); + if( e->mModule && e->mModule->getPath() ) + str.append( e->mModule->getPath() ); str.append( '\n' ); - if( e->mCode ) + if( e->mModule ) str.append( String::ToString( e->mFunctionLineNumber ) ); str.append( '\n' ); diff --git a/Engine/source/console/simObjectMemento.cpp b/Engine/source/console/simObjectMemento.cpp index 9493494423..20ea8348f5 100644 --- a/Engine/source/console/simObjectMemento.cpp +++ b/Engine/source/console/simObjectMemento.cpp @@ -23,6 +23,7 @@ #include "platform/platform.h" #include "console/simObjectMemento.h" +#include "script.h" #include "console/simObject.h" #include "console/simDatablock.h" #include "core/stream/memStream.h" @@ -95,7 +96,7 @@ SimObject *SimObjectMemento::restore() const // Read the object. - const UTF8* result = Con::evaluate( mState ); + const UTF8* result = Con::evaluate( mState ).value; // Restore the redefine behavior. diff --git a/Engine/source/console/telnetDebugger.cpp b/Engine/source/console/telnetDebugger.cpp index cc810a8a15..02cd419d4e 100644 --- a/Engine/source/console/telnetDebugger.cpp +++ b/Engine/source/console/telnetDebugger.cpp @@ -28,10 +28,9 @@ #include "console/engineAPI.h" #include "core/stringTable.h" #include "console/consoleInternal.h" -#include "console/ast.h" -#include "console/compiler.h" #include "core/util/journal/process.h" #include "core/module.h" +#include "script.h" MODULE_BEGIN( TelnetDebugger ) @@ -169,7 +168,7 @@ TelnetDebugger::TelnetDebugger() // Add the version number in a global so that // scripts can detect the presence of the // "enhanced" debugger features. - Con::evaluatef( "$dbgVersion = %d;", Version ); + Con::setIntVariable("dbgVersion", Version); } TelnetDebugger::Breakpoint **TelnetDebugger::findBreakpoint(StringTableEntry fileName, S32 lineNumber) @@ -380,7 +379,7 @@ void TelnetDebugger::checkDebugRecv() } } -void TelnetDebugger::executionStopped(CodeBlock *code, U32 lineNumber) +void TelnetDebugger::executionStopped(Con::Module *module, U32 lineNumber) { if(mProgramPaused) return; @@ -392,13 +391,13 @@ void TelnetDebugger::executionStopped(CodeBlock *code, U32 lineNumber) return; } - Breakpoint **bp = findBreakpoint(code->name, lineNumber); + Breakpoint **bp = findBreakpoint(module->getName(), lineNumber); if(!bp) return; Breakpoint *brk = *bp; mProgramPaused = true; - Con::evaluatef("$Debug::result = %s;", brk->testExpression); + Con::setVariable("$Debug::result", brk->testExpression); if(Con::getBoolVariable("$Debug::result")) { brk->curCount++; @@ -406,7 +405,7 @@ void TelnetDebugger::executionStopped(CodeBlock *code, U32 lineNumber) { brk->curCount = 0; if(brk->clearOnHit) - removeBreakpoint(code->name, lineNumber); + removeBreakpoint(module->getName(), lineNumber); breakProcess(); } } @@ -418,8 +417,8 @@ void TelnetDebugger::pushStackFrame() if(mState == NotConnected) return; - if(mBreakOnNextStatement && mStackPopBreakIndex > -1 && - gEvalState.getStackDepth() > mStackPopBreakIndex) + if(mBreakOnNextStatement && mStackPopBreakIndex > -1 && + Con::getFrameStack().size() > mStackPopBreakIndex) setBreakOnNextStatement( false ); } @@ -428,7 +427,7 @@ void TelnetDebugger::popStackFrame() if(mState == NotConnected) return; - if(mStackPopBreakIndex > -1 && gEvalState.getStackDepth()-1 <= mStackPopBreakIndex) + if(mStackPopBreakIndex > -1 && Con::getFrameStack().size()-1 <= mStackPopBreakIndex) setBreakOnNextStatement( true ); } @@ -461,14 +460,14 @@ void TelnetDebugger::sendBreak() S32 last = 0; - for(S32 i = (S32) gEvalState.getStackDepth() - 1; i >= last; i--) + for(S32 i = (S32) Con::getFrameStack().size() - 1; i >= last; i--) { - CodeBlock *code = gEvalState.stack[i]->code; + Con::Module *module = Con::getStackFrame(i)->module; const char *file = ""; - if (code && code->name && code->name[0]) - file = code->name; + if (module && module->getName() && module->getName()[0]) + file = module->getName(); - Namespace *ns = gEvalState.stack[i]->scopeNamespace; + Namespace *ns = Con::getStackFrame(i)->scopeNamespace; scope[0] = 0; if ( ns ) { @@ -482,15 +481,15 @@ void TelnetDebugger::sendBreak() } } - const char *function = gEvalState.stack[i]->scopeName; + const char *function = Con::getStackFrame(i)->scopeName; if ((!function) || (!function[0])) function = ""; dStrcat( scope, function, MaxCommandSize ); U32 line=0, inst; - U32 ip = gEvalState.stack[i]->ip; - if (code) - code->findBreakLine(ip, line, inst); + U32 ip = Con::getStackFrame(i)->ip; + if (module) + module->findBreakLine(ip, line, inst); dSprintf(buffer, MaxCommandSize, " %s %d %s", file, line, scope); send(buffer); } @@ -579,7 +578,7 @@ void TelnetDebugger::removeVariableBreakpoint(const char*) send("removeVariableBreakpoint\r\n"); } -void TelnetDebugger::addAllBreakpoints(CodeBlock *code) +void TelnetDebugger::addAllBreakpoints(Con::Module *module) { if(mState == NotConnected) return; @@ -590,14 +589,14 @@ void TelnetDebugger::addAllBreakpoints(CodeBlock *code) { // TODO: This assumes that the OS file names are case // insensitive... Torque needs a dFilenameCmp() function. - if( dStricmp( cur->fileName, code->name ) == 0 ) + if( dStricmp( cur->fileName, module->getName() ) == 0 ) { - cur->code = code; + cur->module = module; // Find the fist breakline starting from and // including the requested breakline. - S32 newLine = code->findFirstBreakLine(cur->lineNumber); - if (newLine <= 0) + S32 newLine = module->findFirstBreakLine(cur->lineNumber); + if (newLine <= 0) { char buffer[MaxCommandSize]; dSprintf(buffer, MaxCommandSize, "BRKCLR %s %d\r\n", cur->fileName, cur->lineNumber); @@ -638,7 +637,7 @@ void TelnetDebugger::addAllBreakpoints(CodeBlock *code) cur->lineNumber = newLine; } - code->setBreakpoint(cur->lineNumber); + module->setBreakpoint(cur->lineNumber); } cur = cur->next; @@ -646,7 +645,7 @@ void TelnetDebugger::addAllBreakpoints(CodeBlock *code) // Enable all breaks if a break next was set. if (mBreakOnNextStatement) - code->setAllBreaks(); + module->setAllBreaks(); } void TelnetDebugger::addBreakpoint(const char *fileName, S32 line, bool clear, S32 passCount, const char *evalString) @@ -668,12 +667,12 @@ void TelnetDebugger::addBreakpoint(const char *fileName, S32 line, bool clear, S { // Note that if the code block is not already // loaded it is handled by addAllBreakpoints. - CodeBlock* code = CodeBlock::find(fileName); - if (code) + Con::Module* module = Con::findScriptModuleForFile(fileName); + if (module) { // Find the fist breakline starting from and // including the requested breakline. - S32 newLine = code->findFirstBreakLine(line); + S32 newLine = module->findFirstBreakLine(line); if (newLine <= 0) { char buffer[MaxCommandSize]; @@ -703,11 +702,11 @@ void TelnetDebugger::addBreakpoint(const char *fileName, S32 line, bool clear, S line = newLine; } - code->setBreakpoint(line); + module->setBreakpoint(line); } Breakpoint *brk = new Breakpoint; - brk->code = code; + brk->module = module; brk->fileName = fileName; brk->lineNumber = line; brk->passCount = passCount; @@ -719,13 +718,13 @@ void TelnetDebugger::addBreakpoint(const char *fileName, S32 line, bool clear, S } } -void TelnetDebugger::removeBreakpointsFromCode(CodeBlock *code) +void TelnetDebugger::removeBreakpointsFromCode(Con::Module *code) { Breakpoint **walk = &mBreakpoints; Breakpoint *cur; while((cur = *walk) != NULL) { - if(cur->code == code) + if(cur->module == code) { dFree(cur->testExpression); *walk = cur->next; @@ -744,8 +743,8 @@ void TelnetDebugger::removeBreakpoint(const char *fileName, S32 line) { Breakpoint *brk = *bp; *bp = brk->next; - if ( brk->code ) - brk->code->clearBreakpoint(brk->lineNumber); + if ( brk->module ) + brk->module->clearBreakpoint(brk->lineNumber); dFree(brk->testExpression); delete brk; } @@ -757,8 +756,8 @@ void TelnetDebugger::removeAllBreakpoints() while(walk) { Breakpoint *temp = walk->next; - if ( walk->code ) - walk->code->clearBreakpoint(walk->lineNumber); + if ( walk->module ) + walk->module->clearBreakpoint(walk->lineNumber); dFree(walk->testExpression); delete walk; walk = temp; @@ -781,23 +780,24 @@ void TelnetDebugger::debugContinue() void TelnetDebugger::setBreakOnNextStatement( bool enabled ) { + Vector modules = Con::getAllScriptModules(); if ( enabled ) { // Apply breaks on all the code blocks. - for(CodeBlock *walk = CodeBlock::getCodeBlockList(); walk; walk = walk->nextFile) - walk->setAllBreaks(); + for(Con::Module** walk = modules.begin(); walk != modules.end(); walk++) + (*walk)->setAllBreaks(); mBreakOnNextStatement = true; } else if ( !enabled ) { // Clear all the breaks on the codeblocks // then go reapply the breakpoints. - for(CodeBlock *walk = CodeBlock::getCodeBlockList(); walk; walk = walk->nextFile) - walk->clearAllBreaks(); + for(Con::Module** walk = modules.begin(); walk != modules.end(); walk++) + (*walk)->clearAllBreaks(); for(Breakpoint *w = mBreakpoints; w; w = w->next) { - if ( w->code ) - w->code->setBreakpoint(w->lineNumber); + if ( w->module ) + w->module->setBreakpoint(w->lineNumber); } mBreakOnNextStatement = false; } @@ -838,7 +838,7 @@ void TelnetDebugger::debugStepOver() return; setBreakOnNextStatement( true ); - mStackPopBreakIndex = gEvalState.getStackDepth(); + mStackPopBreakIndex = Con::getFrameStack().size(); mProgramPaused = false; send("RUNNING\r\n"); } @@ -849,7 +849,7 @@ void TelnetDebugger::debugStepOut() return; setBreakOnNextStatement( false ); - mStackPopBreakIndex = gEvalState.getStackDepth() - 1; + mStackPopBreakIndex = Con::getFrameStack().size() - 1; if ( mStackPopBreakIndex == 0 ) mStackPopBreakIndex = -1; mProgramPaused = false; @@ -858,84 +858,39 @@ void TelnetDebugger::debugStepOut() void TelnetDebugger::evaluateExpression(const char *tag, S32 frame, const char *evalBuffer) { - // Make sure we're passing a valid frame to the eval. - if ( frame > gEvalState.getStackDepth() ) - frame = gEvalState.getStackDepth() - 1; - if ( frame < 0 ) - frame = 0; - - // Local variables use their own memory management and can't be queried by just executing - // TorqueScript, we have to go digging into the interpreter. - S32 evalBufferLen = dStrlen(evalBuffer); - bool isEvaluatingLocalVariable = evalBufferLen > 0 && evalBuffer[0] == '%'; - if (isEvaluatingLocalVariable) - { - // See calculation of current frame in pushing a reference frame for console exec, we need access - // to the proper scope. - //frame = gEvalState.getTopOfStack() - frame - 1; - S32 stackIndex = gEvalState.getTopOfStack() - frame - 1; - - const char* format = "EVALOUT %s %s\r\n"; - - gEvalState.pushDebugFrame(stackIndex); - - Dictionary& stackFrame = gEvalState.getCurrentFrame(); - StringTableEntry functionName = stackFrame.scopeName; - StringTableEntry namespaceName = stackFrame.scopeNamespace->mName; - StringTableEntry varToLookup = StringTable->insert(evalBuffer); - - S32 registerId = stackFrame.code->variableRegisterTable.lookup(namespaceName, functionName, varToLookup); - - if (registerId == -1) - { - // ERROR, can't read the variable! - send("EVALOUT \"\" \"\""); - return; - } - - const char* varResult = gEvalState.getLocalStringVariable(registerId); - - gEvalState.popFrame(); - - S32 len = dStrlen(format) + dStrlen(tag) + dStrlen(varResult); - char* buffer = new char[len]; - dSprintf(buffer, len, format, tag, varResult[0] ? varResult : "\"\""); - - send(buffer); - delete[] buffer; - - return; - } - // Build a buffer just big enough for this eval. const char* format = "return %s;"; - dsize_t len = dStrlen( format ) + dStrlen( evalBuffer ); + S32 len = dStrlen( format ) + dStrlen( evalBuffer ); char* buffer = new char[ len ]; dSprintf( buffer, len, format, evalBuffer ); + Con::EvalResult evalResult = Con::evaluate(buffer, frame); + delete buffer; + + if (!evalResult.valid) + { + // ERROR, can't read the variable! + send("EVALOUT \"\" \"\""); + return; + } - // Execute the eval. - CodeBlock *newCodeBlock = new CodeBlock(); - ConsoleValue result = newCodeBlock->compileExec( NULL, buffer, false, frame ); - delete [] buffer; - - // Create a new buffer that fits the result. format = "EVALOUT %s %s\r\n"; - len = dStrlen( format ) + dStrlen( tag ) + dStrlen( result.getString() ); - buffer = new char[ len ]; - dSprintf( buffer, len, format, tag, result.getString()[0] ? result.getString() : "\"\"" ); - send( buffer ); - delete newCodeBlock; - delete [] buffer; + len = dStrlen(format) + dStrlen(tag) + dStrlen(evalResult.value); + buffer = new char[len]; + dSprintf(buffer, len, format, tag, evalResult.value[0] ? evalResult.value : "\"\""); + + send(buffer); + delete[] buffer; } void TelnetDebugger::dumpFileList() { send("FILELISTOUT "); - for(CodeBlock *walk = CodeBlock::getCodeBlockList(); walk; walk = walk->nextFile) + Vector modules = Con::getAllScriptModules(); + for(Con::Module** walk = modules.begin(); walk != modules.end(); walk++) { - send(walk->name); - if(walk->nextFile) + send((*walk)->getName()); + if((walk + 1) != modules.end()) send(" "); } send("\r\n"); @@ -944,15 +899,15 @@ void TelnetDebugger::dumpFileList() void TelnetDebugger::dumpBreakableList(const char *fileName) { fileName = StringTable->insert(fileName); - CodeBlock *file = CodeBlock::find(fileName); + Con::Module *file = Con::findScriptModuleForFile(fileName); char buffer[MaxCommandSize]; if(file) { - dSprintf(buffer, MaxCommandSize, "BREAKLISTOUT %s %d", fileName, file->breakListSize >> 1); + dSprintf(buffer, MaxCommandSize, "BREAKLISTOUT %s %d", fileName, file->getBreakableLines().size() >> 1); send(buffer); - for(U32 i = 0; i < file->breakListSize; i += 2) + for(U32 i = 0; i < file->getBreakableLines().size(); i += 2) { - dSprintf(buffer, MaxCommandSize, " %d %d", file->breakList[i], file->breakList[i+1]); + dSprintf(buffer, MaxCommandSize, " %d %d", file->getBreakableLines()[i], file->getBreakableLines()[i+1]); send(buffer); } send("\r\n"); @@ -962,14 +917,14 @@ void TelnetDebugger::dumpBreakableList(const char *fileName) } -void TelnetDebugger::clearCodeBlockPointers(CodeBlock *code) +void TelnetDebugger::clearCodeBlockPointers(Con::Module *code) { Breakpoint **walk = &mBreakpoints; Breakpoint *cur; while((cur = *walk) != NULL) { - if(cur->code == code) - cur->code = NULL; + if(cur->module == code) + cur->module = NULL; walk = &cur->next; } diff --git a/Engine/source/console/telnetDebugger.h b/Engine/source/console/telnetDebugger.h index 5ba6b0f10d..627ce5dc13 100644 --- a/Engine/source/console/telnetDebugger.h +++ b/Engine/source/console/telnetDebugger.h @@ -26,8 +26,7 @@ #ifndef _PLATFORM_PLATFORMNET_H_ #include "platform/platformNet.h" #endif - -class CodeBlock; +#include "module.h" /// Telnet debug service implementation. /// @@ -75,7 +74,7 @@ class TelnetDebugger struct Breakpoint { StringTableEntry fileName; - CodeBlock *code; + Con::Module *module; U32 lineNumber; S32 passCount; S32 curCount; @@ -105,7 +104,7 @@ class TelnetDebugger void evaluateExpression(const char *tag, S32 frame, const char *evalBuffer); void dumpFileList(); void dumpBreakableList(const char *fileName); - void removeBreakpointsFromCode(CodeBlock *code); + void removeBreakpointsFromCode(Con::Module *code); void checkDebugRecv(); void processLineBuffer(S32); @@ -121,13 +120,13 @@ class TelnetDebugger void process(); void popStackFrame(); void pushStackFrame(); - void addAllBreakpoints(CodeBlock *code); + void addAllBreakpoints(Con::Module *module); - void clearCodeBlockPointers(CodeBlock *code); + void clearCodeBlockPointers(Con::Module *code); void breakProcess(); - void executionStopped(CodeBlock *code, U32 lineNumber); + void executionStopped(Con::Module *module, U32 lineNumber); void send(const char *s); void setDebugParameters(S32 port, const char *password, bool waitForClient); void processConsoleLine(const char *consoleLine); diff --git a/Engine/source/console/CMDgram.y b/Engine/source/console/torquescript/CMDgram.y similarity index 100% rename from Engine/source/console/CMDgram.y rename to Engine/source/console/torquescript/CMDgram.y diff --git a/Engine/source/console/CMDscan.cpp b/Engine/source/console/torquescript/CMDscan.cpp similarity index 98% rename from Engine/source/console/CMDscan.cpp rename to Engine/source/console/torquescript/CMDscan.cpp index 37a5ee5c3a..f1a844086c 100644 --- a/Engine/source/console/CMDscan.cpp +++ b/Engine/source/console/torquescript/CMDscan.cpp @@ -29,6 +29,10 @@ #include +#include "compiler.h" +#include "runtime.h" +#include "console/script.h" + /* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ #ifdef c_plusplus @@ -551,11 +555,9 @@ char *yytext; #define YYLMAX 4096 #define YY_NO_UNISTD_H -#include #include "platform/platform.h" #include "core/stringTable.h" #include "console/console.h" -#include "console/compiler.h" #include "console/dynamicTypes.h" #include "core/strings/stringFunctions.h" @@ -576,10 +578,7 @@ inline Token< T > MakeToken( T value, U32 lineNumber ) return result; } -#include "console/cmdgram.h" - -// HACK: C++17 and beyond can't use register keyword -#define register +#include "cmdgram.h" using namespace Compiler; @@ -634,7 +633,7 @@ void CMDerror(const char * s, ...); // Reset the parser. void CMDrestart(FILE *in); -#line 638 "CMDscan.cpp" +#line 635 "CMDscan.cpp" /* Macros after this point can all be overridden by user definitions in * section 1. @@ -777,14 +776,14 @@ YY_MALLOC_DECL YY_DECL { - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; -#line 108 "CMDscan.l" +#line 105 "CMDscan.l" ; -#line 788 "CMDscan.cpp" +#line 785 "CMDscan.cpp" if ( yy_init ) { @@ -826,7 +825,7 @@ YY_DECL yy_match: do { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { yy_last_accepting_state = yy_current_state; @@ -869,187 +868,187 @@ YY_DECL case 1: YY_RULE_SETUP -#line 110 "CMDscan.l" +#line 107 "CMDscan.l" { } YY_BREAK case 2: YY_RULE_SETUP -#line 111 "CMDscan.l" +#line 108 "CMDscan.l" { return(Sc_ScanDocBlock()); } YY_BREAK case 3: YY_RULE_SETUP -#line 112 "CMDscan.l" +#line 109 "CMDscan.l" ; YY_BREAK case 4: YY_RULE_SETUP -#line 113 "CMDscan.l" +#line 110 "CMDscan.l" ; YY_BREAK case 5: YY_RULE_SETUP -#line 114 "CMDscan.l" +#line 111 "CMDscan.l" {lineIndex++;} YY_BREAK case 6: YY_RULE_SETUP -#line 115 "CMDscan.l" +#line 112 "CMDscan.l" { return(Sc_ScanString(STRATOM)); } YY_BREAK case 7: YY_RULE_SETUP -#line 116 "CMDscan.l" +#line 113 "CMDscan.l" { return(Sc_ScanString(TAGATOM)); } YY_BREAK case 8: YY_RULE_SETUP -#line 117 "CMDscan.l" +#line 114 "CMDscan.l" { CMDlval.i = MakeToken< int >( opEQ, lineIndex ); return opEQ; } YY_BREAK case 9: YY_RULE_SETUP -#line 118 "CMDscan.l" +#line 115 "CMDscan.l" { CMDlval.i = MakeToken< int >( opNE, lineIndex ); return opNE; } YY_BREAK case 10: YY_RULE_SETUP -#line 119 "CMDscan.l" +#line 116 "CMDscan.l" { CMDlval.i = MakeToken< int >( opGE, lineIndex ); return opGE; } YY_BREAK case 11: YY_RULE_SETUP -#line 120 "CMDscan.l" +#line 117 "CMDscan.l" { CMDlval.i = MakeToken< int >( opLE, lineIndex ); return opLE; } YY_BREAK case 12: YY_RULE_SETUP -#line 121 "CMDscan.l" +#line 118 "CMDscan.l" { CMDlval.i = MakeToken< int >( opAND, lineIndex ); return opAND; } YY_BREAK case 13: YY_RULE_SETUP -#line 122 "CMDscan.l" +#line 119 "CMDscan.l" { CMDlval.i = MakeToken< int >( opOR, lineIndex ); return opOR; } YY_BREAK case 14: YY_RULE_SETUP -#line 123 "CMDscan.l" +#line 120 "CMDscan.l" { CMDlval.i = MakeToken< int >( opCOLONCOLON, lineIndex ); return opCOLONCOLON; } YY_BREAK case 15: YY_RULE_SETUP -#line 124 "CMDscan.l" +#line 121 "CMDscan.l" { CMDlval.i = MakeToken< int >( opMINUSMINUS, lineIndex ); return opMINUSMINUS; } YY_BREAK case 16: YY_RULE_SETUP -#line 125 "CMDscan.l" +#line 122 "CMDscan.l" { CMDlval.i = MakeToken< int >( opPLUSPLUS, lineIndex ); return opPLUSPLUS; } YY_BREAK case 17: YY_RULE_SETUP -#line 126 "CMDscan.l" +#line 123 "CMDscan.l" { CMDlval.i = MakeToken< int >( opSTREQ, lineIndex ); return opSTREQ; } YY_BREAK case 18: YY_RULE_SETUP -#line 127 "CMDscan.l" +#line 124 "CMDscan.l" { CMDlval.i = MakeToken< int >( opSTRNE, lineIndex ); return opSTRNE; } YY_BREAK case 19: YY_RULE_SETUP -#line 128 "CMDscan.l" +#line 125 "CMDscan.l" { CMDlval.i = MakeToken< int >( opSHL, lineIndex ); return opSHL; } YY_BREAK case 20: YY_RULE_SETUP -#line 129 "CMDscan.l" +#line 126 "CMDscan.l" { CMDlval.i = MakeToken< int >( opSHR, lineIndex ); return opSHR; } YY_BREAK case 21: YY_RULE_SETUP -#line 130 "CMDscan.l" +#line 127 "CMDscan.l" { CMDlval.i = MakeToken< int >( opPLASN, lineIndex ); return opPLASN; } YY_BREAK case 22: YY_RULE_SETUP -#line 131 "CMDscan.l" +#line 128 "CMDscan.l" { CMDlval.i = MakeToken< int >( opMIASN, lineIndex ); return opMIASN; } YY_BREAK case 23: YY_RULE_SETUP -#line 132 "CMDscan.l" +#line 129 "CMDscan.l" { CMDlval.i = MakeToken< int >( opMLASN, lineIndex ); return opMLASN; } YY_BREAK case 24: YY_RULE_SETUP -#line 133 "CMDscan.l" +#line 130 "CMDscan.l" { CMDlval.i = MakeToken< int >( opDVASN, lineIndex ); return opDVASN; } YY_BREAK case 25: YY_RULE_SETUP -#line 134 "CMDscan.l" +#line 131 "CMDscan.l" { CMDlval.i = MakeToken< int >( opMODASN, lineIndex ); return opMODASN; } YY_BREAK case 26: YY_RULE_SETUP -#line 135 "CMDscan.l" +#line 132 "CMDscan.l" { CMDlval.i = MakeToken< int >( opANDASN, lineIndex ); return opANDASN; } YY_BREAK case 27: YY_RULE_SETUP -#line 136 "CMDscan.l" +#line 133 "CMDscan.l" { CMDlval.i = MakeToken< int >( opXORASN, lineIndex ); return opXORASN; } YY_BREAK case 28: YY_RULE_SETUP -#line 137 "CMDscan.l" +#line 134 "CMDscan.l" { CMDlval.i = MakeToken< int >( opORASN, lineIndex ); return opORASN; } YY_BREAK case 29: YY_RULE_SETUP -#line 138 "CMDscan.l" +#line 135 "CMDscan.l" { CMDlval.i = MakeToken< int >( opSLASN, lineIndex ); return opSLASN; } YY_BREAK case 30: YY_RULE_SETUP -#line 139 "CMDscan.l" +#line 136 "CMDscan.l" { CMDlval.i = MakeToken< int >( opSRASN, lineIndex ); return opSRASN; } YY_BREAK case 31: YY_RULE_SETUP -#line 140 "CMDscan.l" +#line 137 "CMDscan.l" { CMDlval.i = MakeToken< int >( opINTNAME, lineIndex ); return opINTNAME; } YY_BREAK case 32: YY_RULE_SETUP -#line 141 "CMDscan.l" +#line 138 "CMDscan.l" { CMDlval.i = MakeToken< int >( opINTNAMER, lineIndex ); return opINTNAMER; } YY_BREAK case 33: YY_RULE_SETUP -#line 142 "CMDscan.l" +#line 139 "CMDscan.l" { CMDlval.i = MakeToken< int >( '\n', lineIndex ); return '@'; } YY_BREAK case 34: YY_RULE_SETUP -#line 143 "CMDscan.l" +#line 140 "CMDscan.l" { CMDlval.i = MakeToken< int >( '\t', lineIndex ); return '@'; } YY_BREAK case 35: YY_RULE_SETUP -#line 144 "CMDscan.l" +#line 141 "CMDscan.l" { CMDlval.i = MakeToken< int >( ' ', lineIndex ); return '@'; } YY_BREAK case 36: YY_RULE_SETUP -#line 145 "CMDscan.l" +#line 142 "CMDscan.l" { CMDlval.i = MakeToken< int >( 0, lineIndex ); return '@'; } YY_BREAK case 37: YY_RULE_SETUP -#line 146 "CMDscan.l" +#line 143 "CMDscan.l" { /* this comment stops syntax highlighting from getting messed up when editing the lexer in TextPad */ int c = 0, l; for ( ; ; ) @@ -1075,222 +1074,222 @@ YY_RULE_SETUP } YY_BREAK case 38: -#line 170 "CMDscan.l" +#line 167 "CMDscan.l" case 39: -#line 171 "CMDscan.l" +#line 168 "CMDscan.l" case 40: -#line 172 "CMDscan.l" +#line 169 "CMDscan.l" case 41: -#line 173 "CMDscan.l" +#line 170 "CMDscan.l" case 42: -#line 174 "CMDscan.l" +#line 171 "CMDscan.l" case 43: -#line 175 "CMDscan.l" +#line 172 "CMDscan.l" case 44: -#line 176 "CMDscan.l" +#line 173 "CMDscan.l" case 45: -#line 177 "CMDscan.l" +#line 174 "CMDscan.l" case 46: -#line 178 "CMDscan.l" +#line 175 "CMDscan.l" case 47: -#line 179 "CMDscan.l" +#line 176 "CMDscan.l" case 48: -#line 180 "CMDscan.l" +#line 177 "CMDscan.l" case 49: -#line 181 "CMDscan.l" +#line 178 "CMDscan.l" case 50: -#line 182 "CMDscan.l" +#line 179 "CMDscan.l" case 51: -#line 183 "CMDscan.l" +#line 180 "CMDscan.l" case 52: -#line 184 "CMDscan.l" +#line 181 "CMDscan.l" case 53: -#line 185 "CMDscan.l" +#line 182 "CMDscan.l" case 54: -#line 186 "CMDscan.l" +#line 183 "CMDscan.l" case 55: -#line 187 "CMDscan.l" +#line 184 "CMDscan.l" case 56: -#line 188 "CMDscan.l" +#line 185 "CMDscan.l" case 57: -#line 189 "CMDscan.l" +#line 186 "CMDscan.l" case 58: -#line 190 "CMDscan.l" +#line 187 "CMDscan.l" case 59: -#line 191 "CMDscan.l" +#line 188 "CMDscan.l" case 60: -#line 192 "CMDscan.l" +#line 189 "CMDscan.l" case 61: YY_RULE_SETUP -#line 192 "CMDscan.l" +#line 189 "CMDscan.l" { CMDlval.i = MakeToken< int >( CMDtext[ 0 ], lineIndex ); return CMDtext[ 0 ]; } YY_BREAK case 62: YY_RULE_SETUP -#line 193 "CMDscan.l" +#line 190 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwIN, lineIndex ); return(rwIN); } YY_BREAK case 63: YY_RULE_SETUP -#line 194 "CMDscan.l" +#line 191 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwCASEOR, lineIndex ); return(rwCASEOR); } YY_BREAK case 64: YY_RULE_SETUP -#line 195 "CMDscan.l" +#line 192 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwBREAK, lineIndex ); return(rwBREAK); } YY_BREAK case 65: YY_RULE_SETUP -#line 196 "CMDscan.l" +#line 193 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwRETURN, lineIndex ); return(rwRETURN); } YY_BREAK case 66: YY_RULE_SETUP -#line 197 "CMDscan.l" +#line 194 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwELSE, lineIndex ); return(rwELSE); } YY_BREAK case 67: YY_RULE_SETUP -#line 198 "CMDscan.l" +#line 195 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwASSERT, lineIndex ); return(rwASSERT); } YY_BREAK case 68: YY_RULE_SETUP -#line 199 "CMDscan.l" +#line 196 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwWHILE, lineIndex ); return(rwWHILE); } YY_BREAK case 69: YY_RULE_SETUP -#line 200 "CMDscan.l" +#line 197 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwDO, lineIndex ); return(rwDO); } YY_BREAK case 70: YY_RULE_SETUP -#line 201 "CMDscan.l" +#line 198 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwIF, lineIndex ); return(rwIF); } YY_BREAK case 71: YY_RULE_SETUP -#line 202 "CMDscan.l" +#line 199 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwFOREACHSTR, lineIndex ); return(rwFOREACHSTR); } YY_BREAK case 72: YY_RULE_SETUP -#line 203 "CMDscan.l" +#line 200 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwFOREACH, lineIndex ); return(rwFOREACH); } YY_BREAK case 73: YY_RULE_SETUP -#line 204 "CMDscan.l" +#line 201 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwFOR, lineIndex ); return(rwFOR); } YY_BREAK case 74: YY_RULE_SETUP -#line 205 "CMDscan.l" +#line 202 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwCONTINUE, lineIndex ); return(rwCONTINUE); } YY_BREAK case 75: YY_RULE_SETUP -#line 206 "CMDscan.l" +#line 203 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwDEFINE, lineIndex ); return(rwDEFINE); } YY_BREAK case 76: YY_RULE_SETUP -#line 207 "CMDscan.l" +#line 204 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwDECLARE, lineIndex ); return(rwDECLARE); } YY_BREAK case 77: YY_RULE_SETUP -#line 208 "CMDscan.l" +#line 205 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwDECLARESINGLETON, lineIndex ); return(rwDECLARESINGLETON); } YY_BREAK case 78: YY_RULE_SETUP -#line 209 "CMDscan.l" +#line 206 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwDATABLOCK, lineIndex ); return(rwDATABLOCK); } YY_BREAK case 79: YY_RULE_SETUP -#line 210 "CMDscan.l" +#line 207 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwCASE, lineIndex ); return(rwCASE); } YY_BREAK case 80: YY_RULE_SETUP -#line 211 "CMDscan.l" +#line 208 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwSWITCHSTR, lineIndex ); return(rwSWITCHSTR); } YY_BREAK case 81: YY_RULE_SETUP -#line 212 "CMDscan.l" +#line 209 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwSWITCH, lineIndex ); return(rwSWITCH); } YY_BREAK case 82: YY_RULE_SETUP -#line 213 "CMDscan.l" +#line 210 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwDEFAULT, lineIndex ); return(rwDEFAULT); } YY_BREAK case 83: YY_RULE_SETUP -#line 214 "CMDscan.l" +#line 211 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwPACKAGE, lineIndex ); return(rwPACKAGE); } YY_BREAK case 84: YY_RULE_SETUP -#line 215 "CMDscan.l" +#line 212 "CMDscan.l" { CMDlval.i = MakeToken< int >( rwNAMESPACE, lineIndex ); return(rwNAMESPACE); } YY_BREAK case 85: YY_RULE_SETUP -#line 216 "CMDscan.l" +#line 213 "CMDscan.l" { CMDlval.i = MakeToken< int >( 1, lineIndex ); return INTCONST; } YY_BREAK case 86: YY_RULE_SETUP -#line 217 "CMDscan.l" +#line 214 "CMDscan.l" { CMDlval.i = MakeToken< int >( 0, lineIndex ); return INTCONST; } YY_BREAK case 87: YY_RULE_SETUP -#line 218 "CMDscan.l" +#line 215 "CMDscan.l" { return(Sc_ScanVar()); } YY_BREAK case 88: YY_RULE_SETUP -#line 220 "CMDscan.l" +#line 216 "CMDscan.l" { return Sc_ScanIdent(); } YY_BREAK case 89: YY_RULE_SETUP -#line 221 "CMDscan.l" +#line 217 "CMDscan.l" return(Sc_ScanHex()); YY_BREAK case 90: YY_RULE_SETUP -#line 222 "CMDscan.l" +#line 218 "CMDscan.l" { CMDtext[CMDleng] = 0; CMDlval.i = MakeToken< int >( dAtoi(CMDtext), lineIndex ); return INTCONST; } YY_BREAK case 91: YY_RULE_SETUP -#line 223 "CMDscan.l" +#line 219 "CMDscan.l" return Sc_ScanNum(); YY_BREAK case 92: YY_RULE_SETUP -#line 224 "CMDscan.l" +#line 220 "CMDscan.l" return(ILLEGAL_TOKEN); YY_BREAK case 93: YY_RULE_SETUP -#line 225 "CMDscan.l" +#line 221 "CMDscan.l" return(ILLEGAL_TOKEN); YY_BREAK case 94: YY_RULE_SETUP -#line 226 "CMDscan.l" +#line 222 "CMDscan.l" ECHO; YY_BREAK -#line 1294 "CMDscan.cpp" +#line 1291 "CMDscan.cpp" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -1433,9 +1432,9 @@ case YY_STATE_EOF(INITIAL): static int yy_get_next_buffer() { - register char *dest = yy_current_buffer->yy_ch_buf; - register char *source = yytext_ptr; - register int number_to_move, i; + char *dest = yy_current_buffer->yy_ch_buf; + char *source = yytext_ptr; + int number_to_move, i; int ret_val; if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) @@ -1563,14 +1562,14 @@ static int yy_get_next_buffer() static yy_state_type yy_get_previous_state() { - register yy_state_type yy_current_state; - register char *yy_cp; + yy_state_type yy_current_state; + char *yy_cp; yy_current_state = yy_start; for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { yy_last_accepting_state = yy_current_state; @@ -1602,10 +1601,10 @@ static yy_state_type yy_try_NUL_trans( yy_current_state ) yy_state_type yy_current_state; #endif { - register int yy_is_jam; - register char *yy_cp = yy_c_buf_p; + int yy_is_jam; + char *yy_cp = yy_c_buf_p; - register YY_CHAR yy_c = 1; + YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { yy_last_accepting_state = yy_current_state; @@ -1626,14 +1625,14 @@ yy_state_type yy_current_state; #ifndef YY_NO_UNPUT #ifdef YY_USE_PROTOS -static void yyunput( int c, register char *yy_bp ) +static void yyunput( int c, char *yy_bp ) #else static void yyunput( c, yy_bp ) int c; -register char *yy_bp; +char *yy_bp; #endif { - register char *yy_cp = yy_c_buf_p; + char *yy_cp = yy_c_buf_p; /* undo effects of setting up yytext */ *yy_cp = yy_hold_char; @@ -1641,10 +1640,10 @@ register char *yy_bp; if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ - register int number_to_move = yy_n_chars + 2; - register char *dest = &yy_current_buffer->yy_ch_buf[ + int number_to_move = yy_n_chars + 2; + char *dest = &yy_current_buffer->yy_ch_buf[ yy_current_buffer->yy_buf_size + 2]; - register char *source = + char *source = &yy_current_buffer->yy_ch_buf[number_to_move]; while ( source > yy_current_buffer->yy_ch_buf ) @@ -2098,7 +2097,7 @@ yyconst char *s2; int n; #endif { - register int i; + int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } @@ -2150,7 +2149,7 @@ int main() return 0; } #endif -#line 226 "CMDscan.l" +#line 222 "CMDscan.l" static const char *scanBuffer; @@ -2341,7 +2340,7 @@ static int Sc_ScanDocBlock() static int Sc_ScanString(int ret) { CMDtext[CMDleng - 1] = 0; - if(!collapseEscape(CMDtext+1)) + if(!TorqueScript::getRuntime()->collapseEscapedCharacters(CMDtext+1)) return -1; dsize_t bufferLen = dStrlen( CMDtext ); diff --git a/Engine/source/console/CMDscan.l b/Engine/source/console/torquescript/CMDscan.l similarity index 100% rename from Engine/source/console/CMDscan.l rename to Engine/source/console/torquescript/CMDscan.l diff --git a/Engine/source/console/ast.h b/Engine/source/console/torquescript/ast.h similarity index 98% rename from Engine/source/console/ast.h rename to Engine/source/console/torquescript/ast.h index 9072c43541..d9de3dd029 100644 --- a/Engine/source/console/ast.h +++ b/Engine/source/console/torquescript/ast.h @@ -23,8 +23,9 @@ #ifndef _AST_H_ #define _AST_H_ -class ExprEvalState; -class Namespace; +#include "evalState.h" +#include "platform/types.h" + class SimObject; class SimGroup; class CodeStream; @@ -101,7 +102,7 @@ struct StmtNode #ifndef DEBUG_AST_NODES # define DBG_STMT_TYPE(s) virtual const char* dbgStmtType() const { return "#s"; } #else -# define DBG_STMT_TYPE(s) +# define DBG_STMT_TYPE(s) #endif struct BreakStmtNode : StmtNode @@ -592,7 +593,14 @@ struct FunctionDeclStmtNode : StmtNode DBG_STMT_TYPE(FunctionDeclStmtNode); }; -extern StmtNode* gStatementList; -extern ExprEvalState gEvalState; +namespace Script +{ + inline ExprEvalState gEvalState; + + inline StmtNode *gStatementList; + inline StmtNode *gAnonFunctionList; + inline U32 gAnonFunctionID = 0; +} + #endif diff --git a/Engine/source/console/astAlloc.cpp b/Engine/source/console/torquescript/astAlloc.cpp similarity index 99% rename from Engine/source/console/astAlloc.cpp rename to Engine/source/console/torquescript/astAlloc.cpp index 5728296ad0..9b149b598f 100644 --- a/Engine/source/console/astAlloc.cpp +++ b/Engine/source/console/torquescript/astAlloc.cpp @@ -21,7 +21,7 @@ //----------------------------------------------------------------------------- #include "console/console.h" -#include "console/compiler.h" +#include "compiler.h" #include "console/consoleInternal.h" using namespace Compiler; diff --git a/Engine/source/console/astNodes.cpp b/Engine/source/console/torquescript/astNodes.cpp similarity index 99% rename from Engine/source/console/astNodes.cpp rename to Engine/source/console/torquescript/astNodes.cpp index 73db0693db..8e786cf14d 100644 --- a/Engine/source/console/astNodes.cpp +++ b/Engine/source/console/torquescript/astNodes.cpp @@ -22,15 +22,10 @@ #include "platform/platform.h" #include "console/console.h" -#include "console/telnetDebugger.h" -#include "console/ast.h" -#include "core/tAlgorithm.h" +#include "ast.h" -#include "core/strings/findMatch.h" -#include "console/consoleInternal.h" -#include "core/stream/fileStream.h" -#include "console/compiler.h" +#include "compiler.h" #include "console/simBase.h" @@ -40,7 +35,7 @@ struct Token T value; S32 lineNumber; }; -#include "console/cmdgram.h" +#include "cmdgram.h" namespace Compiler { diff --git a/Engine/source/console/bison.bat b/Engine/source/console/torquescript/bison.bat similarity index 100% rename from Engine/source/console/bison.bat rename to Engine/source/console/torquescript/bison.bat diff --git a/Engine/source/console/bison.simple b/Engine/source/console/torquescript/bison.simple similarity index 100% rename from Engine/source/console/bison.simple rename to Engine/source/console/torquescript/bison.simple diff --git a/Engine/source/console/cmdgram.cpp b/Engine/source/console/torquescript/cmdgram.cpp similarity index 99% rename from Engine/source/console/cmdgram.cpp rename to Engine/source/console/torquescript/cmdgram.cpp index 6207010b42..34c7737d36 100644 --- a/Engine/source/console/cmdgram.cpp +++ b/Engine/source/console/torquescript/cmdgram.cpp @@ -95,7 +95,7 @@ #include #include #include "console/console.h" -#include "console/compiler.h" +#include "compiler.h" #include "console/consoleInternal.h" #include "core/strings/stringFunctions.h" @@ -1581,7 +1581,7 @@ case 2: break;} case 3: #line 169 "cmdgram.y" -{ if(!gStatementList) { gStatementList = yyvsp[0].stmt; } else { gStatementList->append(yyvsp[0].stmt); } ; +{ if(!Script::gStatementList) { Script::gStatementList = yyvsp[0].stmt; } else { Script::gStatementList->append(yyvsp[0].stmt); } ; break;} case 4: #line 174 "cmdgram.y" @@ -2390,5 +2390,3 @@ case 161: goto yynewstate; } #line 617 "cmdgram.y" - - diff --git a/Engine/source/console/cmdgram.h b/Engine/source/console/torquescript/cmdgram.h similarity index 97% rename from Engine/source/console/cmdgram.h rename to Engine/source/console/torquescript/cmdgram.h index 83736a5653..5316b2fda4 100644 --- a/Engine/source/console/cmdgram.h +++ b/Engine/source/console/torquescript/cmdgram.h @@ -1,3 +1,6 @@ +#ifndef _CMDGRAM_H_ +#define _CMDGRAM_H_ + typedef union { Token< char > c; Token< int > i; @@ -90,3 +93,5 @@ typedef union { extern YYSTYPE CMDlval; + +#endif diff --git a/Engine/source/console/codeBlock.cpp b/Engine/source/console/torquescript/codeBlock.cpp similarity index 95% rename from Engine/source/console/codeBlock.cpp rename to Engine/source/console/torquescript/codeBlock.cpp index c403b45159..f7534cc542 100644 --- a/Engine/source/console/codeBlock.cpp +++ b/Engine/source/console/torquescript/codeBlock.cpp @@ -21,10 +21,11 @@ //----------------------------------------------------------------------------- #include "console/console.h" -#include "console/compiler.h" -#include "console/codeBlock.h" +#include "compiler.h" +#include "codeBlock.h" +#include "ast.h" + #include "console/telnetDebugger.h" -#include "console/ast.h" #include "core/strings/unicode.h" #include "core/strings/stringFunctions.h" #include "core/stringTable.h" @@ -34,8 +35,7 @@ using namespace Compiler; bool CodeBlock::smInFunction = false; CodeBlock * CodeBlock::smCodeBlockList = NULL; -CodeBlock * CodeBlock::smCurrentCodeBlock = NULL; -ConsoleParser *CodeBlock::smCurrentParser = NULL; +TorqueScriptParser *CodeBlock::smCurrentParser = NULL; extern FuncVars gEvalFuncVars; extern FuncVars gGlobalScopeFuncVars; @@ -52,8 +52,6 @@ CodeBlock::CodeBlock() globalFloats = NULL; functionFloats = NULL; lineBreakPairs = NULL; - breakList = NULL; - breakListSize = 0; refCount = 0; code = NULL; @@ -68,7 +66,7 @@ CodeBlock::CodeBlock() CodeBlock::~CodeBlock() { // Make sure we aren't lingering in the current code block... - AssertFatal(smCurrentCodeBlock != this, "CodeBlock::~CodeBlock - Caught lingering in smCurrentCodeBlock!"); + AssertFatal(Con::getCurrentScriptModule() != this, "CodeBlock::~CodeBlock - Caught lingering in smCurrentCodeBlock!"); if (name) removeFromCodeList(); @@ -81,35 +79,10 @@ CodeBlock::~CodeBlock() delete[] globalFloats; delete[] functionFloats; delete[] code; - delete[] breakList; } //------------------------------------------------------------------------- -StringTableEntry CodeBlock::getCurrentCodeBlockName() -{ - if (CodeBlock::getCurrentBlock()) - return CodeBlock::getCurrentBlock()->name; - else - return NULL; -} - -StringTableEntry CodeBlock::getCurrentCodeBlockFullPath() -{ - if (CodeBlock::getCurrentBlock()) - return CodeBlock::getCurrentBlock()->fullPath; - else - return NULL; -} - -StringTableEntry CodeBlock::getCurrentCodeBlockModName() -{ - if (CodeBlock::getCurrentBlock()) - return CodeBlock::getCurrentBlock()->modPath; - else - return NULL; -} - CodeBlock *CodeBlock::find(StringTableEntry name) { for (CodeBlock *walk = CodeBlock::getCodeBlockList(); walk; walk = walk->nextFile) @@ -309,8 +282,7 @@ void CodeBlock::calcBreakList() if (seqCount) size++; - breakList = new U32[size+3]; //lineBreakPairs plus pad - breakListSize = size; + breakList.setSize(size+3); //lineBreakPairs plus pad line = -1; seqCount = 0; size = 0; @@ -502,10 +474,10 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con STEtoCode = compileSTEtoCode; - gStatementList = NULL; + Script::gStatementList = NULL; // Set up the parser. - smCurrentParser = getParserForFile(fileName); + smCurrentParser = new TorqueScriptParser(); AssertISV(smCurrentParser, avar("CodeBlock::compile - no parser available for '%s'!", fileName)); // Now do some parsing. @@ -536,9 +508,9 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con CodeStream codeStream; U32 lastIp; - if (gStatementList) + if (Script::gStatementList) { - lastIp = compileBlock(gStatementList, codeStream, 0) + 1; + lastIp = compileBlock(Script::gStatementList, codeStream, 0) + 1; } else { @@ -594,7 +566,7 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con return true; } -ConsoleValue CodeBlock::compileExec(StringTableEntry fileName, const char *inString, bool noCalls, S32 setFrame) +Con::EvalResult CodeBlock::compileExec(StringTableEntry fileName, const char *inString, bool noCalls, S32 setFrame) { AssertFatal(Con::isMainThread(), "Compiling code on a secondary thread"); @@ -634,14 +606,14 @@ ConsoleValue CodeBlock::compileExec(StringTableEntry fileName, const char *inStr if (name) addToCodeList(); - gStatementList = NULL; - + Script::gStatementList = NULL; + // we are an eval compile if we don't have a file name associated (no exec) gIsEvalCompile = fileName == NULL; gFuncVars = gIsEvalCompile ? &gEvalFuncVars : &gGlobalScopeFuncVars; // Set up the parser. - smCurrentParser = getParserForFile(fileName); + smCurrentParser = new TorqueScriptParser(); AssertISV(smCurrentParser, avar("CodeBlock::compile - no parser available for '%s'!", fileName)); // Now do some parsing. @@ -649,10 +621,10 @@ ConsoleValue CodeBlock::compileExec(StringTableEntry fileName, const char *inStr smCurrentParser->restart(NULL); smCurrentParser->parse(); - if (!gStatementList) + if (!Script::gStatementList) { delete this; - return std::move(ConsoleValue()); + return Con::EvalResult(Con::getVariable("$ScriptError")); } resetTables(); @@ -660,7 +632,7 @@ ConsoleValue CodeBlock::compileExec(StringTableEntry fileName, const char *inStr smInFunction = false; CodeStream codeStream; - U32 lastIp = compileBlock(gStatementList, codeStream, 0); + U32 lastIp = compileBlock(Script::gStatementList, codeStream, 0); lineBreakPairCount = codeStream.getNumLineBreaks(); @@ -677,7 +649,7 @@ ConsoleValue CodeBlock::compileExec(StringTableEntry fileName, const char *inStr codeStream.emit(OP_RETURN_VOID); codeStream.emitCodeStream(&codeSize, &code, &lineBreakPairs); - + S32 localRegisterCount = gIsEvalCompile ? gEvalFuncVars.count() : gGlobalScopeFuncVars.count(); consoleAllocReset(); @@ -701,20 +673,6 @@ ConsoleValue CodeBlock::compileExec(StringTableEntry fileName, const char *inStr //------------------------------------------------------------------------- -void CodeBlock::incRefCount() -{ - refCount++; -} - -void CodeBlock::decRefCount() -{ - refCount--; - if (!refCount) - delete this; -} - -//------------------------------------------------------------------------- - String CodeBlock::getFunctionArgs(U32 ip) { StringBuilder str; diff --git a/Engine/source/console/codeBlock.h b/Engine/source/console/torquescript/codeBlock.h similarity index 79% rename from Engine/source/console/codeBlock.h rename to Engine/source/console/torquescript/codeBlock.h index 57370f683d..b9d7dd207d 100644 --- a/Engine/source/console/codeBlock.h +++ b/Engine/source/console/torquescript/codeBlock.h @@ -26,6 +26,9 @@ #include #include +#include "parser.h" +#include "console/runtime.h" + struct CompilerLocalVariableToRegisterMappingTable { struct RemappingTable @@ -42,8 +45,7 @@ struct CompilerLocalVariableToRegisterMappingTable void write(Stream& stream); }; -#include "console/compiler.h" -#include "console/consoleParser.h" +#include "compiler.h" class Stream; class ConsoleValue; @@ -51,33 +53,24 @@ class ConsoleValue; /// Core TorqueScript code management class. /// /// This class represents a block of code, usually mapped directly to a file. -class CodeBlock +class CodeBlock : Con::Module { private: static CodeBlock* smCodeBlockList; - static CodeBlock* smCurrentCodeBlock; public: static bool smInFunction; - static Compiler::ConsoleParser * smCurrentParser; - - static CodeBlock* getCurrentBlock() - { - return smCurrentCodeBlock; - } + static TorqueScriptParser * smCurrentParser; static CodeBlock *getCodeBlockList() { return smCodeBlockList; } - static StringTableEntry getCurrentCodeBlockName(); - static StringTableEntry getCurrentCodeBlockFullPath(); - static StringTableEntry getCurrentCodeBlockModName(); static CodeBlock *find(StringTableEntry); CodeBlock(); - ~CodeBlock(); + ~CodeBlock() override; StringTableEntry name; StringTableEntry fullPath; @@ -100,59 +93,55 @@ class CodeBlock U32 refCount; U32 lineBreakPairCount; U32 *lineBreakPairs; - U32 breakListSize; - U32 *breakList; + Vector breakList; CodeBlock *nextFile; void addToCodeList(); void removeFromCodeList(); void calcBreakList(); - void clearAllBreaks(); - void setAllBreaks(); + void clearAllBreaks() override; + void setAllBreaks() override; void dumpInstructions(U32 startIp = 0, bool upToReturn = false); /// Returns the first breakable line or 0 if none was found. /// @param lineNumber The one based line number. - U32 findFirstBreakLine(U32 lineNumber); + U32 findFirstBreakLine(U32 lineNumber) override; - void clearBreakpoint(U32 lineNumber); + void clearBreakpoint(U32 lineNumber) override; - /// Set a OP_BREAK instruction on a line. If a break + /// Set a OP_BREAK instruction on a line. If a break /// is not possible on that line it returns false. /// @param lineNumber The one based line number. - bool setBreakpoint(U32 lineNumber); + bool setBreakpoint(U32 lineNumber) override; - void findBreakLine(U32 ip, U32 &line, U32 &instruction); - const char *getFileLine(U32 ip); + void findBreakLine(U32 ip, U32 &line, U32 &instruction) override; + const char *getFileLine(U32 ip) override; - /// + /// String getFunctionArgs(U32 offset); bool read(StringTableEntry fileName, Stream &st); bool compile(const char *dsoName, StringTableEntry fileName, const char *script, bool overrideNoDso = false); - void incRefCount(); - void decRefCount(); - /// Compiles and executes a block of script storing the compiled code in this - /// CodeBlock. If there is no filename breakpoints will not be generated and - /// the CodeBlock will not be added to the linked list of loaded CodeBlocks. + /// CodeBlock. If there is no filename breakpoints will not be generated and + /// the CodeBlock will not be added to the linked list of loaded CodeBlocks. /// Note that if the script contains no executable statements the CodeBlock - /// will delete itself on return an empty string. The return string is any + /// will delete itself on return an empty string. The return string is any /// result of the code executed, if any, or an empty string. /// - /// @param fileName The file name, including path and extension, for the + /// @param fileName The file name, including path and extension, for the /// block of code or an empty string. /// @param script The script code to compile and execute. /// @param noCalls Skips calling functions from the script. - /// @param setFrame A zero based index of the stack frame to execute the code + /// @param setFrame A zero based index of the stack frame to execute the code /// with, zero being the top of the stack. If the the index is /// -1 a new frame is created. If the index is out of range the /// top stack frame is used. - ConsoleValue compileExec(StringTableEntry fileName, const char *script, + Con::EvalResult compileExec(StringTableEntry fileName, const char *script, bool noCalls, S32 setFrame = -1); - /// Executes the existing code in the CodeBlock. The return string is any + /// Executes the existing code in the CodeBlock. The return string is any /// result of the code executed, if any, or an empty string. /// /// @param offset The instruction offset to start executing from. @@ -162,14 +151,20 @@ class CodeBlock /// zero to execute code outside of a function. /// @param argv The function parameter list. /// @param noCalls Skips calling functions from the script. - /// @param setFrame A zero based index of the stack frame to execute the code + /// @param setFrame A zero based index of the stack frame to execute the code /// with, zero being the top of the stack. If the the index is /// -1 a new frame is created. If the index is out of range the /// top stack frame is used. /// @param packageName The code package name or null. - ConsoleValue exec(U32 offset, const char *fnName, Namespace *ns, U32 argc, - ConsoleValue *argv, bool noCalls, StringTableEntry packageName, - S32 setFrame = -1); + Con::EvalResult exec(U32 offset, const char* fnName, Namespace* ns, U32 argc, + ConsoleValue* argv, bool noCalls, StringTableEntry packageName, + S32 setFrame = -1) override; + + const char* getFunctionArgs(StringTableEntry functionName, U32 functionOffset) override { return getFunctionArgs(functionOffset); } + const char* getPath() override { return fullPath; } + const char* getName() override { return name; } + Vector getBreakableLines() override { return breakList; } + }; #endif diff --git a/Engine/source/console/compiledEval.cpp b/Engine/source/console/torquescript/compiledEval.cpp similarity index 89% rename from Engine/source/console/compiledEval.cpp rename to Engine/source/console/torquescript/compiledEval.cpp index c081b77d04..bb57b7370c 100644 --- a/Engine/source/console/compiledEval.cpp +++ b/Engine/source/console/torquescript/compiledEval.cpp @@ -23,31 +23,25 @@ //----------------------------------------------------------------------------- #include "platform/platform.h" -#include "console/console.h" -#include "console/ast.h" -#include "core/tAlgorithm.h" +#include "ast.h" +#include "compiler.h" -#include "core/strings/findMatch.h" #include "core/strings/stringUnit.h" #include "console/consoleInternal.h" -#include "core/stream/fileStream.h" -#include "console/compiler.h" #include "console/simBase.h" -#include "console/telnetDebugger.h" #include "sim/netStringTable.h" -#include "console/ICallMethod.h" #include "console/stringStack.h" #include "util/messaging/message.h" #include "core/frameAllocator.h" #include "console/returnBuffer.h" #include "console/consoleValueStack.h" +#include "console/telnetDebugger.h" #ifndef TORQUE_TGB_ONLY #include "materials/materialDefinition.h" -#include "materials/materialManager.h" #endif using namespace Compiler; @@ -116,6 +110,13 @@ U32 _ITER = 0; ///< Stack pointer for iterStack. ConsoleValue stack[MaxStackSize]; S32 _STK = 0; +ReturnBuffer retBuffer; + +char *getReturnBuffer(U32 bufferSize) +{ + return retBuffer.getBuffer(bufferSize); +} + const char* tsconcat(const char* strA, const char* strB, S32& outputLen) { S32 lenA = dStrlen(strA); @@ -150,7 +151,7 @@ namespace Con Namespace * walk; for (walk = ns; walk; walk = walk->mParent) size += dStrlen(walk->mName) + 4; - char *ret = Con::getReturnBuffer(size); + char *ret = getReturnBuffer(size); ret[0] = 0; for (walk = ns; walk; walk = walk->mParent) { @@ -169,9 +170,9 @@ static void getFieldComponent(SimObject* object, StringTableEntry field, const c if (object && field) prevVal = object->getDataField(field, array); else if (currentLocalRegister != -1) - prevVal = gEvalState.getLocalStringVariable(currentLocalRegister); - else if (gEvalState.currentVariable) - prevVal = gEvalState.getStringVariable(); + prevVal = Script::gEvalState.getLocalStringVariable(currentLocalRegister); + else if (Script::gEvalState.currentVariable) + prevVal = Script::gEvalState.getStringVariable(); // Make sure we got a value. if (prevVal && *prevVal) @@ -192,7 +193,7 @@ static void getFieldComponent(SimObject* object, StringTableEntry field, const c StringTable->insert("a") }; - // Translate xyzw and rgba into the indexed component + // Translate xyzw and rgba into the indexed component // of the variable or field. if (subField == xyzw[0] || subField == rgba[0]) dStrcpy(val, StringUnit::getUnit(prevVal, 0, " \t\n"), 128); @@ -225,10 +226,10 @@ static void setFieldComponent(SimObject* object, StringTableEntry field, const c if (object && field) prevVal = object->getDataField(field, array); else if (currentLocalRegister != -1) - prevVal = gEvalState.getLocalStringVariable(currentLocalRegister); + prevVal = Script::gEvalState.getLocalStringVariable(currentLocalRegister); // Set the value on a variable. - else if (gEvalState.currentVariable) - prevVal = gEvalState.getStringVariable(); + else if (Script::gEvalState.currentVariable) + prevVal = Script::gEvalState.getStringVariable(); // Ensure that the variable has a value if (!prevVal) @@ -250,7 +251,7 @@ static void setFieldComponent(SimObject* object, StringTableEntry field, const c StringTable->insert("a") }; - // Insert the value into the specified + // Insert the value into the specified // component of the string. if (subField == xyzw[0] || subField == rgba[0]) dStrcpy(val, StringUnit::setUnit(prevVal, 0, strValue, " \t\n"), 128); @@ -270,9 +271,9 @@ static void setFieldComponent(SimObject* object, StringTableEntry field, const c if (object && field) object->setDataField(field, 0, val); else if (currentLocalRegister != -1) - gEvalState.setLocalStringVariable(currentLocalRegister, val, dStrlen(val)); - else if (gEvalState.currentVariable) - gEvalState.setStringVariable(val); + Script::gEvalState.setLocalStringVariable(currentLocalRegister, val, dStrlen(val)); + else if (Script::gEvalState.currentVariable) + Script::gEvalState.setStringVariable(val); } } @@ -295,83 +296,26 @@ F64 consoleStringToNumber(const char *str, StringTableEntry file, U32 line) return 0; } -//------------------------------------------------------------ - -namespace Con +SimObject* getThisObject(ConsoleValue& simObjectLookupValue) { - ReturnBuffer retBuffer; + SimObject* thisObject = NULL; - char *getReturnBuffer(U32 bufferSize) - { - return retBuffer.getBuffer(bufferSize); - } - - char *getReturnBuffer(const char *stringToCopy) - { - U32 len = dStrlen(stringToCopy) + 1; - char *ret = retBuffer.getBuffer(len); - dMemcpy(ret, stringToCopy, len); - return ret; - } - - char* getReturnBuffer(const String& str) - { - const U32 size = str.size(); - char* ret = retBuffer.getBuffer(size); - dMemcpy(ret, str.c_str(), size); - return ret; - } - - char* getReturnBuffer(const StringBuilder& str) - { - char* buffer = Con::getReturnBuffer(str.length() + 1); - str.copy(buffer); - buffer[str.length()] = '\0'; - - return buffer; - } - - char *getArgBuffer(U32 bufferSize) - { - return STR.getArgBuffer(bufferSize); - } - - char *getFloatArg(F64 arg) - { - char *ret = STR.getArgBuffer(32); - dSprintf(ret, 32, "%g", arg); - return ret; - } - - char *getIntArg(S32 arg) + // Optimization: If we're an integer, we can lookup the value by SimObjectId + if (simObjectLookupValue.getType() == ConsoleValueType::cvInteger) + thisObject = Sim::findObject(static_cast(simObjectLookupValue.getFastInt())); + else { - char *ret = STR.getArgBuffer(32); - dSprintf(ret, 32, "%d", arg); - return ret; - } + SimObject *foundObject = Sim::findObject(simObjectLookupValue.getString()); - char* getBoolArg(bool arg) - { - char *ret = STR.getArgBuffer(32); - dSprintf(ret, 32, "%d", arg); - return ret; - } + // Optimization: If we're not an integer, let's make it so that the fast path exists + // on the first argument of the method call (speeds up future usage of %this, for example) + if (foundObject != NULL) + simObjectLookupValue.setInt(static_cast(foundObject->getId())); - char *getStringArg(const char *arg) - { - U32 len = dStrlen(arg) + 1; - char *ret = STR.getArgBuffer(len); - dMemcpy(ret, arg, len); - return ret; + thisObject = foundObject; } - char* getStringArg(const String& arg) - { - const U32 size = arg.size(); - char* ret = STR.getArgBuffer(size); - dMemcpy(ret, arg.c_str(), size); - return ret; - } + return thisObject; } //------------------------------------------------------------ @@ -379,7 +323,7 @@ namespace Con void ExprEvalState::setCurVarName(StringTableEntry name) { if (name[0] == '$') - currentVariable = globalVars.lookup(name); + currentVariable = Con::gGlobalVars.lookup(name); else if (getStackDepth() > 0) currentVariable = getCurrentFrame().lookup(name); if (!currentVariable && gWarnUndefinedScriptVariables) @@ -389,7 +333,7 @@ void ExprEvalState::setCurVarName(StringTableEntry name) void ExprEvalState::setCurVarNameCreate(StringTableEntry name) { if (name[0] == '$') - currentVariable = globalVars.add(name); + currentVariable = Con::gGlobalVars.add(name); else if (getStackDepth() > 0) currentVariable = getCurrentFrame().add(name); else @@ -605,7 +549,7 @@ TORQUE_FORCEINLINE void doIntOperation() //----------------------------------------------------------------------------- U32 gExecCount = 0; -ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNamespace, U32 argc, ConsoleValue* argv, bool noCalls, StringTableEntry packageName, S32 setFrame) +Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNamespace, U32 argc, ConsoleValue* argv, bool noCalls, StringTableEntry packageName, S32 setFrame) { #ifdef TORQUE_DEBUG U32 stackStart = _STK; @@ -633,7 +577,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa U32 regCount = code[ip + 2 + 7]; thisFunctionName = CodeToSTE(code, ip); S32 wantedArgc = getMin(argc - 1, fnArgc); // argv[0] is func name - if (gEvalState.traceOn) + if (Con::gTraceOn) { traceBuffer[0] = 0; dStrcat(traceBuffer, "Entering ", TRACE_BUFFER_SIZE); @@ -662,13 +606,13 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa dStrcat(traceBuffer, ")", TRACE_BUFFER_SIZE); Con::printf("%s", traceBuffer); } - gEvalState.pushFrame(thisFunctionName, thisNamespace, regCount); + Script::gEvalState.pushFrame(thisFunctionName, thisNamespace, regCount); popFrame = true; for (i = 0; i < wantedArgc; i++) { S32 reg = code[ip + (2 + 6 + 1 + 1) + i]; ConsoleValue& value = argv[i + 1]; - gEvalState.moveConsoleValue(reg, std::move(value)); + Script::gEvalState.moveConsoleValue(reg, std::move(value)); } ip = ip + fnArgc + (2 + 6 + 1 + 1); curFloatTable = functionFloats; @@ -684,7 +628,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa // If requested stack frame isn't available, request a new one // (this prevents assert failures when creating local // variables without a stack frame) - if (gEvalState.getStackDepth() <= setFrame) + if (Script::gEvalState.getStackDepth() <= setFrame) setFrame = -1; // Do we want this code to execute using a new stack frame? @@ -692,8 +636,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa if (setFrame <= 0) { // argc is the local count for eval - gEvalState.pushFrame(NULL, NULL, argc); - popFrame = true; + Script::gEvalState.pushFrame(NULL, NULL, argc); } else { @@ -701,12 +644,16 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa // on to the top of the stack. Any change that occurs to // the locals during this new frame will also occur in the // original frame. - S32 stackIndex = gEvalState.getTopOfStack() - setFrame - 1; - gEvalState.pushFrameRef(stackIndex); - popFrame = true; + S32 stackIndex = Script::gEvalState.getTopOfStack() - setFrame - 1; + Script::gEvalState.pushFrameRef(stackIndex); } + + popFrame = true; } + Script::gEvalState.getCurrentFrame().module = this; + Script::gEvalState.getCurrentFrame().ip = ip; + // Grab the state of the telenet debugger here once // so that the push and pop frames are always balanced. const bool telDebuggerOn = TelDebugger && TelDebugger->isConnected(); @@ -730,7 +677,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa StringTableEntry curField = NULL; SimObject* prevObject = NULL; SimObject* curObject = NULL; - SimObject* saveObject = NULL; + SimObject* thisObject = NULL; Namespace::Entry* nsEntry; Namespace* ns = NULL; const char* curFNDocBlock = NULL; @@ -744,8 +691,6 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa static char curFieldArray[256]; static char prevFieldArray[256]; - CodeBlock* saveCodeBlock = smCurrentCodeBlock; - smCurrentCodeBlock = this; if (this->name) { Con::gCurrentFile = this->name; @@ -1402,7 +1347,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa case OP_INC: reg = code[ip++]; currentRegister = reg; - gEvalState.setLocalFloatVariable(reg, gEvalState.getLocalFloatVariable(reg) + 1.0); + Script::gEvalState.setLocalFloatVariable(reg, Script::gEvalState.getLocalFloatVariable(reg) + 1.0); break; case OP_SETCURVAR: @@ -1420,7 +1365,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa // set a global, we aren't active currentRegister = -1; - gEvalState.setCurVarName(var); + Script::gEvalState.setCurVarName(var); // In order to let docblocks work properly with variables, we have // clear the current docblock when we do an assign. This way it @@ -1442,7 +1387,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa // set a global, we aren't active currentRegister = -1; - gEvalState.setCurVarNameCreate(var); + Script::gEvalState.setCurVarNameCreate(var); // See OP_SETCURVAR for why we do this. curFNDocBlock = NULL; @@ -1461,7 +1406,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa // set a global, we aren't active currentRegister = -1; - gEvalState.setCurVarName(var); + Script::gEvalState.setCurVarName(var); // See OP_SETCURVAR for why we do this. curFNDocBlock = NULL; @@ -1480,7 +1425,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa // set a global, we aren't active currentRegister = -1; - gEvalState.setCurVarNameCreate(var); + Script::gEvalState.setCurVarNameCreate(var); // See OP_SETCURVAR for why we do this. curFNDocBlock = NULL; @@ -1489,32 +1434,32 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa case OP_LOADVAR_UINT: currentRegister = -1; - stack[_STK + 1].setInt(gEvalState.getIntVariable()); + stack[_STK + 1].setInt(Script::gEvalState.getIntVariable()); _STK++; break; case OP_LOADVAR_FLT: currentRegister = -1; - stack[_STK + 1].setFloat(gEvalState.getFloatVariable()); + stack[_STK + 1].setFloat(Script::gEvalState.getFloatVariable()); _STK++; break; case OP_LOADVAR_STR: currentRegister = -1; - stack[_STK + 1].setString(gEvalState.getStringVariable()); + stack[_STK + 1].setString(Script::gEvalState.getStringVariable()); _STK++; break; case OP_SAVEVAR_UINT: - gEvalState.setIntVariable(stack[_STK].getInt()); + Script::gEvalState.setIntVariable(stack[_STK].getInt()); break; case OP_SAVEVAR_FLT: - gEvalState.setFloatVariable(stack[_STK].getFloat()); + Script::gEvalState.setFloatVariable(stack[_STK].getFloat()); break; case OP_SAVEVAR_STR: - gEvalState.setStringVariable(stack[_STK].getString()); + Script::gEvalState.setStringVariable(stack[_STK].getString()); break; case OP_LOAD_LOCAL_VAR_UINT: @@ -1526,7 +1471,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa prevObject = NULL; curObject = NULL; - stack[_STK + 1].setInt(gEvalState.getLocalIntVariable(reg)); + stack[_STK + 1].setInt(Script::gEvalState.getLocalIntVariable(reg)); _STK++; break; @@ -1539,7 +1484,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa prevObject = NULL; curObject = NULL; - stack[_STK + 1].setFloat(gEvalState.getLocalFloatVariable(reg)); + stack[_STK + 1].setFloat(Script::gEvalState.getLocalFloatVariable(reg)); _STK++; break; @@ -1552,7 +1497,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa prevObject = NULL; curObject = NULL; - val = gEvalState.getLocalStringVariable(reg); + val = Script::gEvalState.getLocalStringVariable(reg); stack[_STK + 1].setString(val); _STK++; break; @@ -1566,7 +1511,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa prevObject = NULL; curObject = NULL; - gEvalState.setLocalIntVariable(reg, stack[_STK].getInt()); + Script::gEvalState.setLocalIntVariable(reg, stack[_STK].getInt()); break; case OP_SAVE_LOCAL_VAR_FLT: @@ -1578,7 +1523,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa prevObject = NULL; curObject = NULL; - gEvalState.setLocalFloatVariable(reg, stack[_STK].getFloat()); + Script::gEvalState.setLocalFloatVariable(reg, stack[_STK].getFloat()); break; case OP_SAVE_LOCAL_VAR_STR: @@ -1591,7 +1536,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa prevObject = NULL; curObject = NULL; - gEvalState.setLocalStringVariable(reg, val, (S32)dStrlen(val)); + Script::gEvalState.setLocalStringVariable(reg, val, (S32)dStrlen(val)); break; case OP_SETCUROBJECT: @@ -1820,10 +1765,10 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa U32 callType = code[ip + 4]; //if this is called from inside a function, append the ip and codeptr - if (!gEvalState.stack.empty()) + if (!Script::gEvalState.stack.empty()) { - gEvalState.getCurrentFrame().code = this; - gEvalState.getCurrentFrame().ip = ip - 1; + Script::gEvalState.getCurrentFrame().module = this; + Script::gEvalState.getCurrentFrame().ip = ip - 1; } ip += 5; @@ -1868,25 +1813,10 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa } else if (callType == FuncCallExprNode::MethodCall) { - saveObject = gEvalState.thisObject; + ConsoleValue& simObjectLookupValue = callArgv[1]; + thisObject = getThisObject(simObjectLookupValue); - // Optimization: If we're an integer, we can lookup the value by SimObjectId - const ConsoleValue& simObjectLookupValue = callArgv[1]; - if (simObjectLookupValue.getType() == ConsoleValueType::cvInteger) - gEvalState.thisObject = Sim::findObject(static_cast(simObjectLookupValue.getFastInt())); - else - { - SimObject *foundObject = Sim::findObject(simObjectLookupValue.getString()); - - // Optimization: If we're not an integer, let's make it so that the fast path exists - // on the first argument of the method call (speeds up future usage of %this, for example) - if (foundObject != NULL) - callArgv[1].setInt(static_cast(foundObject->getId())); - - gEvalState.thisObject = foundObject; - } - - if (gEvalState.thisObject == NULL) + if (thisObject == NULL) { Con::warnf( ConsoleLogEntry::General, @@ -1902,7 +1832,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa break; } - ns = gEvalState.thisObject->getNamespace(); + ns = thisObject->getNamespace(); if (ns) nsEntry = ns->lookup(fnName); else @@ -1910,6 +1840,25 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa } else // it's a ParentCall { + ConsoleValue& simObjectLookupValue = callArgv[1]; + thisObject = getThisObject(simObjectLookupValue); + + if (thisObject == NULL) + { + Con::warnf( + ConsoleLogEntry::General, + "%s: Unable to find object: '%s' attempting to call function '%s'", + getFileLine(ip - 6), + simObjectLookupValue.getString(), + fnName + ); + + gCallStack.popFrame(); + stack[_STK + 1].setEmptyString(); + _STK++; + break; + } + if (thisNamespace) { ns = thisNamespace->mParent; @@ -1933,8 +1882,8 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa if (callType == FuncCallExprNode::MethodCall) { Con::warnf(ConsoleLogEntry::General, " Object %s(%d) %s", - gEvalState.thisObject->getName() ? gEvalState.thisObject->getName() : "", - gEvalState.thisObject->getId(), Con::getNamespaceList(ns)); + thisObject->getName() ? thisObject->getName() : "", + thisObject->getId(), Con::getNamespaceList(ns)); } } gCallStack.popFrame(); @@ -1946,7 +1895,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa { if (nsEntry->mFunctionOffset) { - ConsoleValue returnFromFn = nsEntry->mCode->exec(nsEntry->mFunctionOffset, fnName, nsEntry->mNamespace, callArgc, callArgv, false, nsEntry->mPackage); + ConsoleValue returnFromFn = nsEntry->mModule->exec(nsEntry->mFunctionOffset, fnName, nsEntry->mNamespace, callArgc, callArgv, false, nsEntry->mPackage).value; stack[_STK + 1] = std::move(returnFromFn); } else // no body @@ -1972,7 +1921,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa { case Namespace::Entry::StringCallbackType: { - const char* result = nsEntry->cb.mStringCallbackFunc(gEvalState.thisObject, callArgc, callArgv); + const char* result = nsEntry->cb.mStringCallbackFunc(thisObject, callArgc, callArgv); gCallStack.popFrame(); stack[_STK + 1].setString(result); _STK++; @@ -1980,7 +1929,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa } case Namespace::Entry::IntCallbackType: { - S64 result = nsEntry->cb.mIntCallbackFunc(gEvalState.thisObject, callArgc, callArgv); + S64 result = nsEntry->cb.mIntCallbackFunc(thisObject, callArgc, callArgv); gCallStack.popFrame(); if (code[ip] == OP_POP_STK) @@ -1995,7 +1944,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa } case Namespace::Entry::FloatCallbackType: { - F64 result = nsEntry->cb.mFloatCallbackFunc(gEvalState.thisObject, callArgc, callArgv); + F64 result = nsEntry->cb.mFloatCallbackFunc(thisObject, callArgc, callArgv); gCallStack.popFrame(); if (code[ip] == OP_POP_STK) @@ -2010,7 +1959,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa } case Namespace::Entry::VoidCallbackType: { - nsEntry->cb.mVoidCallbackFunc(gEvalState.thisObject, callArgc, callArgv); + nsEntry->cb.mVoidCallbackFunc(thisObject, callArgc, callArgv); gCallStack.popFrame(); if (code[ip] == OP_POP_STK) @@ -2023,7 +1972,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa { Con::warnf(ConsoleLogEntry::General, "%s: Call to %s in %s uses result of void function call.", getFileLine(ip - 4), fnName, functionName); } - + stack[_STK + 1].setEmptyString(); _STK++; @@ -2031,7 +1980,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa } case Namespace::Entry::BoolCallbackType: { - bool result = nsEntry->cb.mBoolCallbackFunc(gEvalState.thisObject, callArgc, callArgv); + bool result = nsEntry->cb.mBoolCallbackFunc(thisObject, callArgc, callArgv); gCallStack.popFrame(); if (code[ip] == OP_POP_STK) @@ -2048,9 +1997,6 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa } } } - - if (callType == FuncCallExprNode::MethodCall) - gEvalState.thisObject = saveObject; break; } @@ -2122,9 +2068,9 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa case OP_BREAK: { //append the ip and codeptr before managing the breakpoint! - AssertFatal(!gEvalState.stack.empty(), "Empty eval stack on break!"); - gEvalState.getCurrentFrame().code = this; - gEvalState.getCurrentFrame().ip = ip - 1; + AssertFatal(!Script::gEvalState.stack.empty(), "Empty eval stack on break!"); + Script::gEvalState.getCurrentFrame().module = this; + Script::gEvalState.getCurrentFrame().ip = ip - 1; U32 breakLine; findBreakLine(ip - 1, breakLine, instruction); @@ -2153,7 +2099,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa if (isGlobal) { StringTableEntry varName = CodeToSTE(code, ip + 1); - iter.mVar.mVariable = gEvalState.globalVars.add(varName); + iter.mVar.mVariable = Con::gGlobalVars.add(varName); } else { @@ -2227,7 +2173,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa if (iter.mIsGlobalVariable) iter.mVar.mVariable->setStringValue(&str[startIndex]); else - gEvalState.setLocalStringVariable(iter.mVar.mRegister, &str[startIndex], endIndex - startIndex); + Script::gEvalState.setLocalStringVariable(iter.mVar.mRegister, &str[startIndex], endIndex - startIndex); const_cast(str)[endIndex] = savedChar; } @@ -2236,7 +2182,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa if (iter.mIsGlobalVariable) iter.mVar.mVariable->setStringValue(""); else - gEvalState.setLocalStringVariable(iter.mVar.mRegister, "", 0); + Script::gEvalState.setLocalStringVariable(iter.mVar.mRegister, "", 0); } // Skip separator. @@ -2261,7 +2207,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa if (iter.mIsGlobalVariable) iter.mVar.mVariable->setIntValue(id); else - gEvalState.setLocalIntVariable(iter.mVar.mRegister, id); + Script::gEvalState.setLocalIntVariable(iter.mVar.mRegister, id); iter.mData.mObj.mIndex = index + 1; } @@ -2296,12 +2242,12 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa if (popFrame) { - gEvalState.popFrame(); + Script::gEvalState.popFrame(); } if (argv) { - if (gEvalState.traceOn) + if (Con::gTraceOn) { traceBuffer[0] = 0; dStrcat(traceBuffer, "Leaving ", TRACE_BUFFER_SIZE); @@ -2332,11 +2278,11 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa globalStrings = NULL; globalFloats = NULL; } - smCurrentCodeBlock = saveCodeBlock; - if (saveCodeBlock && saveCodeBlock->name) + + if (Con::getCurrentScriptModuleName()) { - Con::gCurrentFile = saveCodeBlock->name; - Con::gCurrentRoot = saveCodeBlock->modPath; + Con::gCurrentFile = Con::getCurrentScriptModuleName(); + Con::gCurrentRoot = Con::getModNameFromPath(Con::getCurrentScriptModulePath()); } decRefCount(); @@ -2346,7 +2292,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa AssertFatal(!(_STK < stackStart), "String stack popped too much in script exec"); #endif - return returnValue; + return Con::EvalResult(std::move(returnValue)); } //------------------------------------------------------------ diff --git a/Engine/source/console/compiler.cpp b/Engine/source/console/torquescript/compiler.cpp similarity index 98% rename from Engine/source/console/compiler.cpp rename to Engine/source/console/torquescript/compiler.cpp index f898b89847..34cb8a95ca 100644 --- a/Engine/source/console/compiler.cpp +++ b/Engine/source/console/torquescript/compiler.cpp @@ -22,16 +22,8 @@ #include "platform/platform.h" #include "console/console.h" -#include "console/telnetDebugger.h" - -#include "console/ast.h" -#include "core/tAlgorithm.h" - -#include "core/strings/findMatch.h" -#include "console/consoleInternal.h" -#include "core/stream/fileStream.h" -#include "console/compiler.h" +#include "compiler.h" #include "console/simBase.h" extern FuncVars gEvalFuncVars; @@ -178,15 +170,15 @@ S32 FuncVars::assign(StringTableEntry var, TypeReq currentType, S32 lineNumber, S32 FuncVars::lookup(StringTableEntry var, S32 lineNumber) { std::unordered_map::iterator found = vars.find(var); - + if (found == vars.end()) { const char* str = avar("Script Warning: Variable %s referenced before used when compiling script. File: %s Line: %d", var, CodeBlock::smCurrentParser->getCurrentFile(), lineNumber); scriptErrorHandler(str); - + return assign(var, TypeReqString, lineNumber, false); } - + return found->second.reg; } @@ -198,11 +190,11 @@ TypeReq FuncVars::lookupType(StringTableEntry var, S32 lineNumber) { const char* str = avar("Script Warning: Variable %s referenced before used when compiling script. File: %s Line: %d", var, CodeBlock::smCurrentParser->getCurrentFile(), lineNumber); scriptErrorHandler(str); - + assign(var, TypeReqString, lineNumber, false); return vars.find(var)->second.currentType; } - + return found->second.currentType; } @@ -561,4 +553,3 @@ void CodeStream::reset() mCodeHead = mCode; } } - diff --git a/Engine/source/console/compiler.h b/Engine/source/console/torquescript/compiler.h similarity index 99% rename from Engine/source/console/compiler.h rename to Engine/source/console/torquescript/compiler.h index 6129239398..e1cfbbed90 100644 --- a/Engine/source/console/compiler.h +++ b/Engine/source/console/torquescript/compiler.h @@ -33,12 +33,14 @@ #include #include +class CodeStream; +struct StmtNode; class Stream; class DataChunker; #include "platform/platform.h" -#include "console/ast.h" -#include "console/codeBlock.h" +#include "ast.h" +#include "codeBlock.h" #ifndef _TVECTOR_H_ #include "core/util/tVector.h" @@ -297,13 +299,13 @@ class FuncVars S32 lookup(StringTableEntry var, S32 lineNumber); TypeReq lookupType(StringTableEntry var, S32 lineNumber); - + inline S32 count() { return counter; } std::unordered_map variableNameMap; void clear(); - + private: std::unordered_map vars; S32 counter = 0; diff --git a/Engine/source/console/torquescript/evalState.cpp b/Engine/source/console/torquescript/evalState.cpp new file mode 100644 index 0000000000..5befb5982a --- /dev/null +++ b/Engine/source/console/torquescript/evalState.cpp @@ -0,0 +1,157 @@ + +#include "evalState.h" + +void ExprEvalState::pushFrame(StringTableEntry frameName, Namespace *ns, S32 registerCount) +{ +#ifdef DEBUG_SPEW + validate(); + + Platform::outputDebugString("[ConsoleInternal] Pushing new frame for '%s' at %i", + frameName, mStackDepth); +#endif + + if (mStackDepth + 1 > stack.size()) + { +#ifdef DEBUG_SPEW + Platform::outputDebugString("[ConsoleInternal] Growing stack by one frame"); +#endif + + stack.push_back(new Dictionary); + } + + Dictionary& newFrame = *(stack[mStackDepth]); + newFrame.setState(); + + newFrame.scopeName = frameName; + newFrame.scopeNamespace = ns; + + Con::pushStackFrame(stack[mStackDepth]); + mStackDepth++; + currentVariable = NULL; + + AssertFatal(!newFrame.getCount(), "ExprEvalState::pushFrame - Dictionary not empty!"); + + ConsoleValue* consoleValArray = new ConsoleValue[registerCount](); + localStack.push_back(ConsoleValueFrame(consoleValArray, false)); + currentRegisterArray = &localStack.last(); + + AssertFatal(mStackDepth == localStack.size(), avar("Stack sizes do not match. mStackDepth = %d, localStack = %d", mStackDepth, localStack.size())); + +#ifdef DEBUG_SPEW + validate(); +#endif +} + +void ExprEvalState::popFrame() +{ + AssertFatal(mStackDepth > 0, "ExprEvalState::popFrame - Stack Underflow!"); + +#ifdef DEBUG_SPEW + validate(); + + Platform::outputDebugString("[ConsoleInternal] Popping %sframe at %i", + getCurrentFrame().isOwner() ? "" : "shared ", mStackDepth - 1); +#endif + + Con::popStackFrame(); + mStackDepth--; + stack[mStackDepth]->reset(); + currentVariable = NULL; + + const ConsoleValueFrame& frame = localStack.last(); + localStack.pop_back(); + if (!frame.isReference) + delete[] frame.values; + + currentRegisterArray = localStack.size() ? &localStack.last() : NULL; + + AssertFatal(mStackDepth == localStack.size(), avar("Stack sizes do not match. mStackDepth = %d, localStack = %d", mStackDepth, localStack.size())); + +#ifdef DEBUG_SPEW + validate(); +#endif +} + +void ExprEvalState::pushFrameRef(S32 stackIndex) +{ + AssertFatal(stackIndex >= 0 && stackIndex < mStackDepth, "You must be asking for a valid frame!"); + +#ifdef DEBUG_SPEW + validate(); + + Platform::outputDebugString("[ConsoleInternal] Cloning frame from %i to %i", + stackIndex, mStackDepth); +#endif + + if (mStackDepth + 1 > stack.size()) + { +#ifdef DEBUG_SPEW + Platform::outputDebugString("[ConsoleInternal] Growing stack by one frame"); +#endif + + stack.push_back(new Dictionary); + } + + Dictionary& newFrame = *(stack[mStackDepth]); + newFrame.setState(stack[stackIndex]); + + Con::pushStackFrame(stack[mStackDepth]); + + mStackDepth++; + currentVariable = NULL; + + ConsoleValue* values = localStack[stackIndex].values; + localStack.push_back(ConsoleValueFrame(values, true)); + currentRegisterArray = &localStack.last(); + + AssertFatal(mStackDepth == localStack.size(), avar("Stack sizes do not match. mStackDepth = %d, localStack = %d", mStackDepth, localStack.size())); + +#ifdef DEBUG_SPEW + validate(); +#endif +} + +void ExprEvalState::pushDebugFrame(S32 stackIndex) +{ + pushFrameRef(stackIndex); + + Dictionary& newFrame = *(stack[mStackDepth - 1]); + + // debugger needs to know this info... + newFrame.scopeName = stack[stackIndex]->scopeName; + newFrame.scopeNamespace = stack[stackIndex]->scopeNamespace; + newFrame.module = stack[stackIndex]->module; + newFrame.ip = stack[stackIndex]->ip; +} + +ExprEvalState::ExprEvalState() +{ + VECTOR_SET_ASSOCIATION(stack); + currentVariable = NULL; + mStackDepth = 0; + stack.reserve(64); + mShouldReset = false; + mResetLocked = false; + copyVariable = NULL; + currentRegisterArray = NULL; +} + +ExprEvalState::~ExprEvalState() +{ + // Delete callframes. + + while (!stack.empty()) + { + delete stack.last(); + stack.decrement(); + } +} + +void ExprEvalState::validate() +{ + AssertFatal(mStackDepth <= stack.size(), + "ExprEvalState::validate() - Stack depth pointing beyond last stack frame!"); + + for (U32 i = 0; i < stack.size(); ++i) + stack[i]->validate(); +} diff --git a/Engine/source/console/torquescript/evalState.h b/Engine/source/console/torquescript/evalState.h new file mode 100644 index 0000000000..cd0d34a138 --- /dev/null +++ b/Engine/source/console/torquescript/evalState.h @@ -0,0 +1,119 @@ +#ifndef _EVALSTATE_H +#define _EVALSTATE_H +#include "console/consoleInternal.h" + +class ExprEvalState +{ +public: + /// @name Expression Evaluation + /// @{ + + /// + + Dictionary::Entry *currentVariable; + Dictionary::Entry *copyVariable; + + U32 mStackDepth; + bool mShouldReset; ///< Designates if the value stack should be reset + bool mResetLocked; ///< mShouldReset will be set at the end + + ExprEvalState(); + ~ExprEvalState(); + + /// @} + + /// @name Stack Management + /// @{ + + /// The stack of callframes. The extra redirection is necessary since Dictionary holds + /// an interior pointer that will become invalid when the object changes address. + Vector< Dictionary* > stack; + + S32 getTopOfStack() { return (S32)mStackDepth; } + + Vector< ConsoleValueFrame > localStack; + ConsoleValueFrame* currentRegisterArray; // contains array at to top of localStack + + /// + + void setCurVarName(StringTableEntry name); + void setCurVarNameCreate(StringTableEntry name); + + S32 getIntVariable(); + F64 getFloatVariable(); + const char *getStringVariable(); + void setIntVariable(S32 val); + void setFloatVariable(F64 val); + void setStringVariable(const char *str); + + TORQUE_FORCEINLINE S32 getLocalIntVariable(S32 reg) + { + return currentRegisterArray->values[reg].getInt(); + } + + TORQUE_FORCEINLINE F64 getLocalFloatVariable(S32 reg) + { + return currentRegisterArray->values[reg].getFloat(); + } + + TORQUE_FORCEINLINE const char* getLocalStringVariable(S32 reg) + { + return currentRegisterArray->values[reg].getString(); + } + + TORQUE_FORCEINLINE void setLocalIntVariable(S32 reg, S64 val) + { + currentRegisterArray->values[reg].setInt(val); + } + + TORQUE_FORCEINLINE void setLocalFloatVariable(S32 reg, F64 val) + { + currentRegisterArray->values[reg].setFloat(val); + } + + TORQUE_FORCEINLINE void setLocalStringVariable(S32 reg, const char* val, S32 len) + { + currentRegisterArray->values[reg].setString(val, len); + } + + TORQUE_FORCEINLINE void setLocalStringTableEntryVariable(S32 reg, StringTableEntry val) + { + currentRegisterArray->values[reg].setStringTableEntry(val); + } + + TORQUE_FORCEINLINE void moveConsoleValue(S32 reg, ConsoleValue val) + { + currentRegisterArray->values[reg] = std::move(val); + } + + void pushFrame(StringTableEntry frameName, Namespace *ns, S32 regCount); + void popFrame(); + + /// Puts a reference to an existing stack frame + /// on the top of the stack. + void pushFrameRef(S32 stackIndex); + + void pushDebugFrame(S32 stackIndex); + + U32 getStackDepth() const + { + return mStackDepth; + } + + Dictionary& getCurrentFrame() + { + return *(stack[mStackDepth - 1]); + } + + Dictionary& getFrameAt(S32 depth) + { + return *(stack[depth]); + } + + /// @} + + /// Run integrity checks for debugging. + void validate(); +}; + +#endif diff --git a/Engine/source/console/optimizer.cpp b/Engine/source/console/torquescript/optimizer.cpp similarity index 97% rename from Engine/source/console/optimizer.cpp rename to Engine/source/console/torquescript/optimizer.cpp index 9bfbb09a5e..5ecf88cad6 100644 --- a/Engine/source/console/optimizer.cpp +++ b/Engine/source/console/torquescript/optimizer.cpp @@ -21,8 +21,7 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- -#include "console/console.h" -#include "console/codeBlock.h" +#include "codeBlock.h" static bool isLiteralNumber(ExprNode* node) { @@ -85,7 +84,7 @@ bool IntBinaryExprNode::optimize() S32 val = getIntValue(right); switch (val) { - case 2: + case 2: op = '&'; optimizedNode = IntNode::alloc(dbgLineNumber, 1); return true; diff --git a/Engine/source/console/torquescript/parser.cpp b/Engine/source/console/torquescript/parser.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Engine/source/console/torquescript/parser.h b/Engine/source/console/torquescript/parser.h new file mode 100644 index 0000000000..cda386acad --- /dev/null +++ b/Engine/source/console/torquescript/parser.h @@ -0,0 +1,49 @@ +#ifndef _TORQUESCRIPT_PARSER_H_ +#define _TORQUESCRIPT_PARSER_H_ +#include + +#include "platform/types.h" + +const char* CMDGetCurrentFile(); +S32 CMDGetCurrentLine(); +S32 CMDparse(); +void CMDrestart(FILE* in); +void CMDSetScanBuffer(const char *sb, const char *fn); + +extern void expandEscape(char *dest, const char *src); +extern bool collapseEscape(char *buf); + +class TorqueScriptParser +{ +public: + TorqueScriptParser() = default; + + const char* mExtension; + + //----------------------------------------------------------------------------- + /// \brief Function for GetCurrentFile from the lexer + //----------------------------------------------------------------------------- + const char* getCurrentFile() { return CMDGetCurrentFile(); } + + //----------------------------------------------------------------------------- + /// \brief Function for GetCurrentLine from the lexer + //----------------------------------------------------------------------------- + S32 getCurrentLine() { return CMDGetCurrentLine(); } + + //----------------------------------------------------------------------------- + /// \brief Function for Parse from the lexer + //----------------------------------------------------------------------------- + S32 parse() { return CMDparse(); } + + //----------------------------------------------------------------------------- + /// \brief Function for Restart from the lexer + //----------------------------------------------------------------------------- + void restart(FILE *pInputFile) { CMDrestart(pInputFile); } + + //----------------------------------------------------------------------------- + /// \brief Function for SetScanBuffer from the lexer + //----------------------------------------------------------------------------- + void setScanBuffer(const char* sb, const char* fn) { CMDSetScanBuffer(sb, fn); } +}; + +#endif diff --git a/Engine/source/console/torquescript/runtime.cpp b/Engine/source/console/torquescript/runtime.cpp new file mode 100644 index 0000000000..f0064f1522 --- /dev/null +++ b/Engine/source/console/torquescript/runtime.cpp @@ -0,0 +1,486 @@ +#include "runtime.h" + +#include "codeBlock.h" +#include "console/script.h" +#include "console/runtime.h" +#include "core/volume.h" +#include "core/stream/fileStream.h" +#include "core/util/timeClass.h" + + +namespace TorqueScript +{ + // Buffer for expanding script filenames. + static char scriptFilenameBuffer[1024]; + + TorqueScriptRuntime::TorqueScriptRuntime() + { + Con::registerRuntime(0, this); + } + + TorqueScriptRuntime::~TorqueScriptRuntime() + { + } + + Con::EvalResult TorqueScriptRuntime::evaluate(const char* string, bool echo, const char* fileName) + { + ConsoleStackFrameSaver stackSaver; + stackSaver.save(); + + if (echo) + { + if (string[0] == '%') + Con::printf("%s", string); + else + Con::printf("%s%s", Con::getVariable("$Con::Prompt"), string); + } + + if (fileName) + fileName = StringTable->insert(fileName); + + CodeBlock* newCodeBlock = new CodeBlock(); + return std::move(newCodeBlock->compileExec(fileName, string, false, fileName ? -1 : 0)); + } + + Con::EvalResult TorqueScriptRuntime::evaluate(const char* script, S32 frame, bool echo, const char* fileName) + { + // Make sure we're passing a valid frame to the eval. + if (frame > Script::gEvalState.getStackDepth()) + frame = Script::gEvalState.getStackDepth() - 1; + if (frame < 0) + frame = 0; + + // Local variables use their own memory management and can't be queried by just executing + // TorqueScript, we have to go digging into the interpreter. + S32 evalBufferLen = dStrlen(script); + bool isEvaluatingLocalVariable = evalBufferLen > 0 && script[0] == '%'; + if (isEvaluatingLocalVariable) + { + // See calculation of current frame in pushing a reference frame for console exec, we need access + // to the proper scope. + //frame = gEvalState.getTopOfStack() - frame - 1; + S32 stackIndex = Script::gEvalState.getStackDepth() - frame - 1; + + Script::gEvalState.pushDebugFrame(stackIndex); + + Dictionary& stackFrame = Script::gEvalState.getCurrentFrame(); + StringTableEntry functionName = stackFrame.scopeName; + StringTableEntry namespaceName = stackFrame.scopeNamespace->mName; + StringTableEntry varToLookup = StringTable->insert(script); + + S32 registerId = ((CodeBlock*)stackFrame.module)->variableRegisterTable.lookup(namespaceName, functionName, varToLookup); + + if (registerId == -1) + { + // ERROR, can't read the variable! + return Con::EvalResult("variable not found"); + } + + const char* varResult = Script::gEvalState.getLocalStringVariable(registerId); + + Script::gEvalState.popFrame(); + + ConsoleValue val; + val.setString(varResult); + + return Con::EvalResult("variable not found"); + } + + // Execute the eval. + CodeBlock* newCodeBlock = new CodeBlock(); + Con::EvalResult result = newCodeBlock->compileExec(NULL, script, false, frame); + return result; + } + + //------------------------------------------------------------------------------ + Con::EvalResult TorqueScriptRuntime::evaluatef(const char* string, ...) + { + char buffer[4096]; + va_list args; + va_start(args, string); + dVsprintf(buffer, sizeof(buffer), string, args); + va_end(args); + return evaluate(buffer); + } + + bool TorqueScriptRuntime::executeFile(const char* fileName, bool noCalls, bool journalScript) + { + bool journal = false; + + U32 execDepth = 0; + U32 journalDepth = 1; + + execDepth++; + if (journalDepth >= execDepth) + journalDepth = execDepth + 1; + else + journal = true; + + bool ret = false; + + if (journalScript && !journal) + { + journal = true; + journalDepth = execDepth; + } + + // Determine the filename we actually want... + Con::expandScriptFilename(scriptFilenameBuffer, sizeof(scriptFilenameBuffer), fileName); + + // since this function expects a script file reference, if it's a .dso + // lets terminate the string before the dso so it will act like a .tscript + if (dStrEndsWith(scriptFilenameBuffer, ".dso")) + { + scriptFilenameBuffer[dStrlen(scriptFilenameBuffer) - dStrlen(".dso")] = '\0'; + } + + // Figure out where to put DSOs + StringTableEntry dsoPath = Con::getDSOPath(scriptFilenameBuffer); + + const char* ext = dStrrchr(scriptFilenameBuffer, '.'); + + if (!ext) + { + // Try appending the default script extension and see if that succeeds + + if (executeFile(fileName + String("." TORQUE_SCRIPT_EXTENSION), noCalls, journalScript)) + { + return true; + } + + // We need an extension! + Con::errorf(ConsoleLogEntry::Script, "exec: invalid script file name %s.", scriptFilenameBuffer); + execDepth--; + return false; + } + + // Check Editor Extensions + bool isEditorScript = false; + + // If the script file extension is '.ed.tscript' then compile it to a different compiled extension + if (dStricmp(ext, "." TORQUE_SCRIPT_EXTENSION) == 0) + { + const char* ext2 = ext - 3; + if (dStricmp(ext2, ".ed." TORQUE_SCRIPT_EXTENSION) == 0) + isEditorScript = true; + } + else if (dStricmp(ext, ".gui") == 0) + { + const char* ext2 = ext - 3; + if (dStricmp(ext2, ".ed.gui") == 0) + isEditorScript = true; + } + + StringTableEntry scriptFileName = StringTable->insert(scriptFilenameBuffer); + + // Is this a file we should compile? (anything in the prefs path should not be compiled) + StringTableEntry prefsPath = Platform::getPrefsPath(); + bool compiled = dStricmp(ext, ".mis") && !journal && !Con::getBoolVariable("Scripts::ignoreDSOs"); + + // [tom, 12/5/2006] stripBasePath() fucks up if the filename is not in the exe + // path, current directory or prefs path. Thus, getDSOFilename() will also screw + // up and so this allows the scripts to still load but without a DSO. + if (Platform::isFullPath(Platform::stripBasePath(scriptFilenameBuffer))) + compiled = false; + + // [tom, 11/17/2006] It seems to make sense to not compile scripts that are in the + // prefs directory. However, getDSOPath() can handle this situation and will put + // the dso along with the script to avoid name clashes with tools/game dsos. + if ((dsoPath && *dsoPath == 0) || (prefsPath && prefsPath[0] && dStrnicmp( + scriptFileName, prefsPath, dStrlen(prefsPath)) == 0)) + compiled = false; + + // If we're in a journaling mode, then we will read the script + // from the journal file. + if (journal && Journal::IsPlaying()) + { + char fileNameBuf[256]; + bool fileRead = false; + U32 fileSize; + + Journal::ReadString(fileNameBuf); + Journal::Read(&fileRead); + + if (!fileRead) + { + Con::errorf(ConsoleLogEntry::Script, "Journal script read (failed) for %s", fileNameBuf); + execDepth--; + return false; + } + Journal::Read(&fileSize); + char* script = new char[fileSize + 1]; + Journal::Read(fileSize, script); + script[fileSize] = 0; + Con::printf("Executing (journal-read) %s.", scriptFileName); + + CodeBlock *newCodeBlock = new CodeBlock(); + newCodeBlock->compileExec(scriptFileName, script, noCalls, 0); + delete newCodeBlock; + delete[] script; + + execDepth--; + return true; + } + + // Ok, we let's try to load and compile the script. + Torque::FS::FileNodeRef scriptFile = Torque::FS::GetFileNode(scriptFileName); + Torque::FS::FileNodeRef dsoFile; + + // ResourceObject *rScr = gResourceManager->find(scriptFileName); + // ResourceObject *rCom = NULL; + + char nameBuffer[512]; + char* script = NULL; + U32 version; + + Stream* compiledStream = NULL; + Torque::Time scriptModifiedTime, dsoModifiedTime; + + // Check here for .edso + bool edso = false; + if (dStricmp(ext, ".edso") == 0 && scriptFile != NULL) + { + edso = true; + dsoFile = scriptFile; + scriptFile = NULL; + + dsoModifiedTime = dsoFile->getModifiedTime(); + dStrcpy(nameBuffer, scriptFileName, 512); + } + + // If we're supposed to be compiling this file, check to see if there's a DSO + if (compiled && !edso) + { + const char* filenameOnly = dStrrchr(scriptFileName, '/'); + if (filenameOnly) + ++filenameOnly; + else + filenameOnly = scriptFileName; + + char pathAndFilename[1024]; + Platform::makeFullPathName(filenameOnly, pathAndFilename, sizeof(pathAndFilename), dsoPath); + + if (isEditorScript) + dStrcpyl(nameBuffer, sizeof(nameBuffer), pathAndFilename, ".edso", NULL); + else + dStrcpyl(nameBuffer, sizeof(nameBuffer), pathAndFilename, ".dso", NULL); + + dsoFile = Torque::FS::GetFileNode(nameBuffer); + + if (scriptFile != NULL) + scriptModifiedTime = scriptFile->getModifiedTime(); + + if (dsoFile != NULL) + dsoModifiedTime = dsoFile->getModifiedTime(); + } + + // Let's do a sanity check to complain about DSOs in the future. + // + // MM: This doesn't seem to be working correctly for now so let's just not issue + // the warning until someone knows how to resolve it. + // + //if(compiled && rCom && rScr && Platform::compareFileTimes(comModifyTime, scrModifyTime) < 0) + //{ + //Con::warnf("exec: Warning! Found a DSO from the future! (%s)", nameBuffer); + //} + + // If we had a DSO, let's check to see if we should be reading from it. + //MGT: fixed bug with dsos not getting recompiled correctly + //Note: Using Nathan Martin's version from the forums since its easier to read and understand + if (compiled && dsoFile != NULL && (scriptFile == NULL || (dsoModifiedTime >= scriptModifiedTime))) + { + //MGT: end + compiledStream = FileStream::createAndOpen(nameBuffer, Torque::FS::File::Read); + if (compiledStream) + { + // Check the version! + compiledStream->read(&version); + if (version != Con::DSOVersion) + { + Con::warnf("exec: Found an old DSO (%s, ver %d < %d), ignoring.", nameBuffer, version, Con::DSOVersion); + delete compiledStream; + compiledStream = NULL; + } + } + } + + // If we're journalling, let's write some info out. + if (journal && Journal::IsRecording()) + Journal::WriteString(scriptFileName); + + if (scriptFile != NULL && !compiledStream) + { + // If we have source but no compiled version, then we need to compile + // (and journal as we do so, if that's required). + + void* data; + U32 dataSize = 0; + Torque::FS::ReadFile(scriptFileName, data, dataSize, true); + + if (journal && Journal::IsRecording()) + Journal::Write(bool(data != NULL)); + + if (data == NULL) + { + Con::errorf(ConsoleLogEntry::Script, "exec: invalid script file %s.", scriptFileName); + execDepth--; + return false; + } + else + { + if (!dataSize) + { + execDepth--; + return false; + } + + script = (char*)data; + + if (journal && Journal::IsRecording()) + { + Journal::Write(dataSize); + Journal::Write(dataSize, data); + } + } + +#ifndef TORQUE_NO_DSO_GENERATION + if (compiled) + { + // compile this baddie. +#ifdef TORQUE_DEBUG + Con::printf("Compiling %s...", scriptFileName); +#endif + + CodeBlock *code = new CodeBlock(); + code->compile(nameBuffer, scriptFileName, script); + delete code; + code = NULL; + + compiledStream = FileStream::createAndOpen(nameBuffer, Torque::FS::File::Read); + if (compiledStream) + { + compiledStream->read(&version); + } + else + { + // We have to exit out here, as otherwise we get double error reports. + delete[] script; + execDepth--; + return false; + } + } +#endif + } + else + { + if (journal && Journal::IsRecording()) + Journal::Write(bool(false)); + } + + if (compiledStream) + { + // Delete the script object first to limit memory used + // during recursive execs. + delete[] script; + script = 0; + + // We're all compiled, so let's run it. +#ifdef TORQUE_DEBUG + Con::printf("Loading compiled script %s.", scriptFileName); +#endif + CodeBlock* code = new CodeBlock; + code->read(scriptFileName, *compiledStream); + delete compiledStream; + code->exec(0, scriptFileName, NULL, 0, NULL, noCalls, NULL, 0); + delete code; + ret = true; + } + else if (scriptFile) + { + // No compiled script, let's just try executing it + // directly... this is either a mission file, or maybe + // we're on a readonly volume. +#ifdef TORQUE_DEBUG + Con::printf("Executing %s.", scriptFileName); +#endif + + CodeBlock *newCodeBlock = new CodeBlock(); + StringTableEntry name = StringTable->insert(scriptFileName); + + newCodeBlock->compileExec(name, script, noCalls, 0); + ret = true; + } + else + { + // Don't have anything. + Con::warnf(ConsoleLogEntry::Script, "Missing file: %s!", scriptFileName); + ret = false; + } + + delete[] script; + execDepth--; + return ret; + } + + bool TorqueScriptRuntime::compile(const char* fileName, bool overrideNoDso) + { + Con::expandScriptFilename( scriptFilenameBuffer, sizeof( scriptFilenameBuffer ), fileName ); + + // Figure out where to put DSOs + StringTableEntry dsoPath = Con::getDSOPath(scriptFilenameBuffer); + if(dsoPath && *dsoPath == 0) + return false; + + // If the script file extention is '.ed.tscript' then compile it to a different compiled extention + bool isEditorScript = false; + const char *ext = dStrrchr( scriptFilenameBuffer, '.' ); + if( ext && ( dStricmp( ext, "." TORQUE_SCRIPT_EXTENSION) == 0 ) ) + { + const char* ext2 = ext - 3; + if( dStricmp( ext2, ".ed." TORQUE_SCRIPT_EXTENSION) == 0 ) + isEditorScript = true; + } + else if( ext && ( dStricmp( ext, ".gui" ) == 0 ) ) + { + const char* ext2 = ext - 3; + if( dStricmp( ext2, ".ed.gui" ) == 0 ) + isEditorScript = true; + } + + const char *filenameOnly = dStrrchr(scriptFilenameBuffer, '/'); + if(filenameOnly) + ++filenameOnly; + else + filenameOnly = scriptFilenameBuffer; + + char nameBuffer[512]; + + if( isEditorScript ) + dStrcpyl(nameBuffer, sizeof(nameBuffer), dsoPath, "/", filenameOnly, ".edso", NULL); + else + dStrcpyl(nameBuffer, sizeof(nameBuffer), dsoPath, "/", filenameOnly, ".dso", NULL); + + void *data = NULL; + U32 dataSize = 0; + Torque::FS::ReadFile(scriptFilenameBuffer, data, dataSize, true); + if(data == NULL) + { + Con::errorf(ConsoleLogEntry::Script, "compile: invalid script file %s.", scriptFilenameBuffer); + return false; + } + + const char *script = static_cast(data); + +#ifdef TORQUE_DEBUG + Con::printf("Compiling %s...", scriptFilenameBuffer); +#endif + + CodeBlock *code = new CodeBlock(); + code->compile(nameBuffer, scriptFilenameBuffer, script, overrideNoDso); + delete code; + delete[] script; + + return true; + } + +} diff --git a/Engine/source/console/torquescript/runtime.h b/Engine/source/console/torquescript/runtime.h new file mode 100644 index 0000000000..42bde09f7b --- /dev/null +++ b/Engine/source/console/torquescript/runtime.h @@ -0,0 +1,27 @@ +#ifndef _TORQUESCRIPT_RUNTIME_H_ +#define _TORQUESCRIPT_RUNTIME_H_ +#include "ast.h" +#include "console/runtime.h" + +namespace TorqueScript +{ + class TorqueScriptRuntime : public Con::Runtime + { + public: + TorqueScriptRuntime(); + ~TorqueScriptRuntime() override; + + void expandEscapedCharacters(char* dest, const char* src) override { expandEscape(dest, src); } + bool collapseEscapedCharacters(char* buf) override { return collapseEscape(buf); } + Con::EvalResult evaluate(const char* string, bool echo = false, const char* fileName = NULL) override; + Con::EvalResult evaluate(const char* script, S32 frame, bool echo = false, const char *fileName = NULL) override; + Con::EvalResult evaluatef(const char* string, ...) override; + bool executeFile(const char* fileName, bool noCalls, bool journalScript) override; + bool compile(const char* fileName, bool overrideNoDso); + }; + + inline TorqueScriptRuntime* gRuntime = new TorqueScriptRuntime(); + inline TorqueScriptRuntime* getRuntime() { return gRuntime; } +} + +#endif diff --git a/Engine/source/core/volume.cpp b/Engine/source/core/volume.cpp index d755975367..6d2e4cab7d 100644 --- a/Engine/source/core/volume.cpp +++ b/Engine/source/core/volume.cpp @@ -1234,18 +1234,6 @@ bool IsFile(const Path &path) return sgMountSystem.isFile(path); } -bool IsScriptFile(const char* pFilePath) -{ - return (sgMountSystem.isFile(pFilePath) - || sgMountSystem.isFile(pFilePath + String(".dso")) - || sgMountSystem.isFile(pFilePath + String(".mis")) - || sgMountSystem.isFile(pFilePath + String(".mis.dso")) - || sgMountSystem.isFile(pFilePath + String(".gui")) - || sgMountSystem.isFile(pFilePath + String(".gui.dso")) - || sgMountSystem.isFile(pFilePath + String("." TORQUE_SCRIPT_EXTENSION)) - || sgMountSystem.isFile(pFilePath + String("." TORQUE_SCRIPT_EXTENSION) + String(".dso"))); -} - bool IsDirectory(const Path &path) { return sgMountSystem.isDirectory(path); diff --git a/Engine/source/core/volume.h b/Engine/source/core/volume.h index d6369660ed..86242adf4d 100644 --- a/Engine/source/core/volume.h +++ b/Engine/source/core/volume.h @@ -567,7 +567,6 @@ bool CreatePath(const Path &path); bool IsReadOnly(const Path &path); bool IsDirectory(const Path &path); bool IsFile(const Path &path); -bool IsScriptFile(const char* pFilePath); bool VerifyWriteAccess(const Path &path); /// This returns a unique file path from the components diff --git a/Engine/source/gfx/gfxCardProfile.cpp b/Engine/source/gfx/gfxCardProfile.cpp index 38ad5c1ea6..7b229e6fa7 100644 --- a/Engine/source/gfx/gfxCardProfile.cpp +++ b/Engine/source/gfx/gfxCardProfile.cpp @@ -25,6 +25,7 @@ #include "console/console.h" #include "console/engineAPI.h" +#include "console/script.h" #include "core/volume.h" // NOTE: The script class docs are in diff --git a/Engine/source/gfx/gl/gfxGLDeviceProfiler.cpp b/Engine/source/gfx/gl/gfxGLDeviceProfiler.cpp index d12ddb923f..51c8fdc703 100644 --- a/Engine/source/gfx/gl/gfxGLDeviceProfiler.cpp +++ b/Engine/source/gfx/gl/gfxGLDeviceProfiler.cpp @@ -1,5 +1,6 @@ #include "gui/core/guiCanvas.h" #include "console/engineAPI.h" +#include "console/script.h" #include "gfx/gfxDebugEvent.h" #include "gfx/gl/gfxGLDevice.h" diff --git a/Engine/source/gui/controls/guiConsoleTextCtrl.cpp b/Engine/source/gui/controls/guiConsoleTextCtrl.cpp index 20a80c8e89..81241e32ec 100644 --- a/Engine/source/gui/controls/guiConsoleTextCtrl.cpp +++ b/Engine/source/gui/controls/guiConsoleTextCtrl.cpp @@ -25,6 +25,7 @@ #include "console/consoleTypes.h" #include "console/console.h" +#include "console/script.h" #include "core/color.h" #include "gfx/gfxDrawUtil.h" #include "gui/core/guiDefaultControlRender.h" diff --git a/Engine/source/gui/controls/guiGameListMenuCtrl.cpp b/Engine/source/gui/controls/guiGameListMenuCtrl.cpp index 839a58bede..7b1e207a16 100644 --- a/Engine/source/gui/controls/guiGameListMenuCtrl.cpp +++ b/Engine/source/gui/controls/guiGameListMenuCtrl.cpp @@ -24,6 +24,7 @@ #include "console/consoleTypes.h" #include "console/engineAPI.h" +#include "console/script.h" #include "gfx/gfxDrawUtil.h" #include "gui/containers/guiScrollCtrl.h" #include "sim/actionMap.h" diff --git a/Engine/source/gui/controls/guiGameSettingsCtrl.cpp b/Engine/source/gui/controls/guiGameSettingsCtrl.cpp index 6f80414f08..fff03c24bf 100644 --- a/Engine/source/gui/controls/guiGameSettingsCtrl.cpp +++ b/Engine/source/gui/controls/guiGameSettingsCtrl.cpp @@ -24,6 +24,7 @@ #include "console/consoleTypes.h" #include "console/engineAPI.h" +#include "console/script.h" #include "gfx/gfxDrawUtil.h" #include "gui/containers/guiScrollCtrl.h" #include "core/strings/stringUnit.h" diff --git a/Engine/source/gui/controls/guiListBoxCtrl.cpp b/Engine/source/gui/controls/guiListBoxCtrl.cpp index 8b69b89e8d..66328b2b33 100644 --- a/Engine/source/gui/controls/guiListBoxCtrl.cpp +++ b/Engine/source/gui/controls/guiListBoxCtrl.cpp @@ -22,6 +22,7 @@ #include "gui/controls/guiListBoxCtrl.h" #include "gfx/gfxDrawUtil.h" #include "console/engineAPI.h" +#include "console/script.h" IMPLEMENT_CONOBJECT(GuiListBoxCtrl); @@ -165,7 +166,7 @@ GuiListBoxCtrl::GuiListBoxCtrl() mColorBullet = true; mItemSize = Point2I(10,20); mLastClickItem = NULL; - + mRenderTooltipDelegate.bind( this, &GuiListBoxCtrl::renderTooltip ); } @@ -469,11 +470,11 @@ void GuiListBoxCtrl::getSelectedItems( Vector &Items ) { // Clear our return vector Items.clear(); - + // If there are no selected items, return an empty vector if( mSelectedItems.empty() ) return; - + for( S32 i = 0; i < mItems.size(); i++ ) if( mItems[i]->isSelected ) Items.push_back( i ); @@ -882,8 +883,8 @@ StringTableEntry GuiListBoxCtrl::getItemText( S32 index ) Con::warnf( "GuiListBoxCtrl::getItemText - index out of range!" ); return StringTable->lookup(""); } - - return mItems[ index ]->itemText; + + return mItems[ index ]->itemText; } DefineEngineMethod( GuiListBoxCtrl, getItemObject, const char*, (S32 index),, @@ -917,7 +918,7 @@ SimObject* GuiListBoxCtrl::getItemObject( S32 index ) SimObject *outObj; Sim::findObject( (SimObjectId)(uintptr_t)(mItems[ index ]->itemData), outObj ); - return outObj; + return outObj; } DefineEngineMethod( GuiListBoxCtrl, setItemText, void, (S32 index, const char* newtext),, @@ -974,7 +975,7 @@ DefineEngineMethod( GuiListBoxCtrl, setItemTooltip, void, (S32 index, const char Con::errorf( "GuiListBoxCtrl::setItemTooltip - index '%i' out of range", index ); return; } - + object->mItems[ index ]->itemTooltip = text; } @@ -1104,7 +1105,7 @@ bool GuiListBoxCtrl::renderTooltip( const Point2I &hoverPos, const Point2I& curs S32 hitItemIndex; if( hitTest( hoverPos, hitItemIndex ) ) tipText = mItems[ hitItemIndex ]->itemTooltip; - + return defaultTooltipRender( hoverPos, cursorPos, tipText ); } @@ -1115,7 +1116,7 @@ bool GuiListBoxCtrl::renderTooltip( const Point2I &hoverPos, const Point2I& curs bool GuiListBoxCtrl::hitTest( const Point2I& point, S32& outItem ) { Point2I localPoint = globalToLocalCoord( point ); - + S32 itemHit = ( localPoint.y < 0 ) ? -1 : (S32)mFloor( (F32)localPoint.y / (F32)mItemSize.y ); if ( itemHit >= mItems.size() || itemHit == -1 ) return false; @@ -1123,7 +1124,7 @@ bool GuiListBoxCtrl::hitTest( const Point2I& point, S32& outItem ) LBItem *hitItem = mItems[ itemHit ]; if ( hitItem == NULL ) return false; - + outItem = itemHit; return true; } @@ -1144,7 +1145,7 @@ void GuiListBoxCtrl::onMouseDown( const GuiEvent &event ) S32 itemHit; if( !hitTest( event.mousePoint, itemHit ) ) return; - + LBItem* hitItem = mItems[ itemHit ]; // If we're not a multiple selection listbox, we simply select/unselect an item @@ -1172,7 +1173,7 @@ void GuiListBoxCtrl::onMouseDown( const GuiEvent &event ) return; } - + // Deal with multiple selections if( event.modifier & SI_MULTISELECT) { @@ -1219,7 +1220,7 @@ void GuiListBoxCtrl::onMouseUp( const GuiEvent& event ) // Execute console command execConsoleCallback(); - + Parent::onMouseUp( event ); } @@ -1268,7 +1269,7 @@ U32 GuiListBoxCtrl::getStringElementCount( const char* inString ) // Yes... search = 0; break; - } + } } // Found a seperator? @@ -1300,7 +1301,7 @@ U32 GuiListBoxCtrl::getStringElementCount( const char* inString ) // Yes... search = 0; break; - } + } } // Found Seperator? @@ -1357,7 +1358,7 @@ const char* GuiListBoxCtrl::getStringElement( const char* inString, const U32 in // Yes... search = 0; break; - } + } } // Found a seperator? @@ -1396,7 +1397,7 @@ const char* GuiListBoxCtrl::getStringElement( const char* inString, const U32 in // Yes... search = 0; break; - } + } } // Found Seperator? @@ -1446,19 +1447,19 @@ void GuiListBoxCtrl::_mirror() // Allow script to filter out objects if desired. - Vector workingSet; + Vector workingSet; // If the method is not defined we assume user wants us to add // all objects. bool isObjMirroredDefined = isMethod( "isObjectMirrored" ); - + for ( S32 i = 0; i < mirrorSet->size(); i++ ) { bool addObj = true; - + if ( isObjMirroredDefined ) - addObj = isObjectMirrored_callback(mirrorSet->at(i)->getIdString()); - + addObj = isObjectMirrored_callback(mirrorSet->at(i)->getIdString()); + if ( addObj ) workingSet.push_back( mirrorSet->at(i)->getId() ); } @@ -1481,8 +1482,8 @@ void GuiListBoxCtrl::_mirror() if ( curObj ) { if ( workingSet.contains( curId ) ) - { - mItems[i]->itemText = _makeMirrorItemName( curObj ); + { + mItems[i]->itemText = _makeMirrorItemName( curObj ); keep = true; } } @@ -1492,7 +1493,7 @@ void GuiListBoxCtrl::_mirror() deleteItem( i ); i--; } - } + } // Add items that are in the SimSet but not yet in the list. @@ -1512,7 +1513,7 @@ void GuiListBoxCtrl::_mirror() break; } } - + for ( U32 j = 0; j < mFilteredItems.size(); j++ ) { if ( (SimObjectId)(uintptr_t)(mFilteredItems[j]->itemData) == curId ) @@ -1523,8 +1524,8 @@ void GuiListBoxCtrl::_mirror() } if ( !found ) - { - addItem( _makeMirrorItemName( curObj ), (void*)(uintptr_t)curId ); + { + addItem( _makeMirrorItemName( curObj ), (void*)(uintptr_t)curId ); } } } @@ -1537,12 +1538,12 @@ StringTableEntry GuiListBoxCtrl::_makeMirrorItemName( SimObject *inObj ) { Con::setIntVariable( "$ThisControl", getId() ); Con::setIntVariable( "$ThisObject", inObj->getId() ); - - outName = StringTable->insert( Con::evaluate( mMakeNameCallback ), true ); + + outName = StringTable->insert( Con::evaluate( mMakeNameCallback ).value, true ); } else if ( inObj->getName() ) outName = StringTable->insert( inObj->getName() ); - + if ( !outName || !outName[0] ) outName = StringTable->insert( "(no name)" ); @@ -1582,22 +1583,22 @@ DefineEngineMethod( GuiListBoxCtrl, addFilteredItem, void, (const char* newItem) void GuiListBoxCtrl::addFilteredItem( String item ) { // Delete from selected items list - for ( S32 i = 0; i < mSelectedItems.size(); i++ ) + for ( S32 i = 0; i < mSelectedItems.size(); i++ ) { String itemText = mSelectedItems[i]->itemText; - if ( String::compare( itemText.c_str(), item.c_str() ) == 0 ) + if ( String::compare( itemText.c_str(), item.c_str() ) == 0 ) { mSelectedItems.erase_fast( i ); break; } } - for ( S32 i = 0; i < mItems.size(); i++ ) + for ( S32 i = 0; i < mItems.size(); i++ ) { String itemText = mItems[i]->itemText; if( String::compare( itemText.c_str(), item.c_str() ) == 0 ) - { - mItems[i]->isSelected = false; + { + mItems[i]->isSelected = false; mFilteredItems.push_front( mItems[i] ); mItems.erase( &mItems[i] ); break; @@ -1625,11 +1626,11 @@ DefineEngineMethod( GuiListBoxCtrl, removeFilteredItem, void, ( const char* item void GuiListBoxCtrl::removeFilteredItem( String item ) { - for ( S32 i = 0; i < mFilteredItems.size(); i++ ) + for ( S32 i = 0; i < mFilteredItems.size(); i++ ) { String itemText = mFilteredItems[i]->itemText; if( String::compare( itemText.c_str(), item.c_str() ) == 0 ) - { + { mItems.push_front( mFilteredItems[i] ); mFilteredItems.erase( &mFilteredItems[i] ); break; diff --git a/Engine/source/gui/controls/guiMLTextEditCtrl.cpp b/Engine/source/gui/controls/guiMLTextEditCtrl.cpp index 2877b1150b..75cebfd417 100644 --- a/Engine/source/gui/controls/guiMLTextEditCtrl.cpp +++ b/Engine/source/gui/controls/guiMLTextEditCtrl.cpp @@ -28,6 +28,7 @@ #include "core/stringBuffer.h" #include "gfx/gfxDrawUtil.h" #include "console/engineAPI.h" +#include "console/script.h" IMPLEMENT_CONOBJECT(GuiMLTextEditCtrl); diff --git a/Engine/source/gui/core/guiControl.cpp b/Engine/source/gui/core/guiControl.cpp index f25c191307..37102adf24 100644 --- a/Engine/source/gui/core/guiControl.cpp +++ b/Engine/source/gui/core/guiControl.cpp @@ -32,7 +32,7 @@ #include "console/console.h" #include "console/consoleInternal.h" #include "console/engineAPI.h" -#include "console/codeBlock.h" +#include "console/script.h" #include "gfx/bitmap/gBitmap.h" #include "sim/actionMap.h" #include "gui/core/guiCanvas.h" @@ -2489,7 +2489,7 @@ void GuiControl::getCursor(GuiCursor *&cursor, bool &showCursor, const GuiEvent const char* GuiControl::evaluate( const char* str ) { smThisControl = this; - const char* result = Con::evaluate(str, false); + const char* result = Con::evaluate(str, false).value; smThisControl = NULL; return result; diff --git a/Engine/source/gui/editor/guiEditCtrl.cpp b/Engine/source/gui/editor/guiEditCtrl.cpp index 94edf135b4..c47529da3d 100644 --- a/Engine/source/gui/editor/guiEditCtrl.cpp +++ b/Engine/source/gui/editor/guiEditCtrl.cpp @@ -31,6 +31,7 @@ #include "gui/containers/guiScrollCtrl.h" #include "core/strings/stringUnit.h" #include "console/engineAPI.h" +#include "console/script.h" IMPLEMENT_CONOBJECT( GuiEditCtrl ); diff --git a/Engine/source/gui/editor/inspector/dynamicGroup.cpp b/Engine/source/gui/editor/inspector/dynamicGroup.cpp index 7b003cefe4..2f3de7f8d9 100644 --- a/Engine/source/gui/editor/inspector/dynamicGroup.cpp +++ b/Engine/source/gui/editor/inspector/dynamicGroup.cpp @@ -25,6 +25,7 @@ #include "gui/editor/inspector/dynamicGroup.h" #include "gui/editor/inspector/dynamicField.h" #include "console/engineAPI.h" +#include "console/script.h" IMPLEMENT_CONOBJECT(GuiInspectorDynamicGroup); diff --git a/Engine/source/gui/editor/inspector/field.cpp b/Engine/source/gui/editor/inspector/field.cpp index b5f0827fd8..34fe76c802 100644 --- a/Engine/source/gui/editor/inspector/field.cpp +++ b/Engine/source/gui/editor/inspector/field.cpp @@ -23,6 +23,8 @@ #include "console/engineAPI.h" #include "platform/platform.h" #include "gui/editor/inspector/field.h" + +#include "console/script.h" #include "gui/buttons/guiIconButtonCtrl.h" #include "gui/editor/guiInspector.h" #include "core/util/safeDelete.h" @@ -321,7 +323,7 @@ void GuiInspectorField::setData( const char* data, bool callbacks ) { char buffer[ 2048 ]; expandEscape( buffer, newValue ); - evaluationResult = Con::evaluatef("$f = \"%s\"; return ( %s );", oldValue.c_str(), buffer); + evaluationResult = Con::evaluatef("$f = \"%s\"; return ( %s );", oldValue.c_str(), buffer).value; newValue = evaluationResult.getString(); Con::evaluatef("$f=0;"); } @@ -359,7 +361,7 @@ void GuiInspectorField::setData( const char* data, bool callbacks ) expandEscape( buffer, newComponentExpr ); evaluationResult = Con::evaluatef("$f = \"%s\"; $v = \"%s\"; return ( %s );", - oldComponentVal, oldValue.c_str(), buffer); + oldComponentVal, oldValue.c_str(), buffer).value; Con::evaluatef("$f=0;$v=0;"); if( !isFirst ) diff --git a/Engine/source/gui/editor/inspector/group.cpp b/Engine/source/gui/editor/inspector/group.cpp index a636529331..f931b03fda 100644 --- a/Engine/source/gui/editor/inspector/group.cpp +++ b/Engine/source/gui/editor/inspector/group.cpp @@ -22,6 +22,8 @@ #include "gui/editor/guiInspector.h" #include "gui/editor/inspector/group.h" + +#include "console/script.h" #include "gui/editor/inspector/dynamicField.h" #include "gui/editor/inspector/datablockField.h" #include "gui/buttons/guiIconButtonCtrl.h" diff --git a/Engine/source/gui/editor/inspector/variableGroup.cpp b/Engine/source/gui/editor/inspector/variableGroup.cpp index 5cb9e34ba3..c05d5f2185 100644 --- a/Engine/source/gui/editor/inspector/variableGroup.cpp +++ b/Engine/source/gui/editor/inspector/variableGroup.cpp @@ -25,8 +25,7 @@ #include "gui/editor/guiInspector.h" #include "gui/buttons/guiIconButtonCtrl.h" #include "console/consoleInternal.h" - -extern ExprEvalState gEvalState; +#include "console/script.h" //----------------------------------------------------------------------------- // GuiInspectorVariableGroup @@ -65,7 +64,7 @@ bool GuiInspectorVariableGroup::inspectGroup() { Vector names; - gEvalState.globalVars.exportVariables(mSearchString, &names, NULL); + Con::gGlobalVars.exportVariables(mSearchString, &names, NULL); for (U32 i = 0; i < names.size(); i++) { diff --git a/Engine/source/gui/shiny/guiAudioCtrl.cpp b/Engine/source/gui/shiny/guiAudioCtrl.cpp index 62678f0457..96fe5f0979 100644 --- a/Engine/source/gui/shiny/guiAudioCtrl.cpp +++ b/Engine/source/gui/shiny/guiAudioCtrl.cpp @@ -21,6 +21,7 @@ //----------------------------------------------------------------------------- #include "gui/shiny/guiAudioCtrl.h" #include "console/engineAPI.h" +#include "console/script.h" #include "sfx/sfxSystem.h" #include "sfx/sfxTrack.h" #include "sfx/sfxSource.h" diff --git a/Engine/source/i18n/lang.cpp b/Engine/source/i18n/lang.cpp index e06ad6e4ef..410858b2d4 100644 --- a/Engine/source/i18n/lang.cpp +++ b/Engine/source/i18n/lang.cpp @@ -25,8 +25,6 @@ #include "core/stream/fileStream.h" #include "console/console.h" #include "console/consoleInternal.h" -#include "console/ast.h" -#include "console/compiler.h" #include "core/util/safeDelete.h" #include "console/engineAPI.h" @@ -102,7 +100,7 @@ bool LangFile::load(Stream *s) bool LangFile::save(const UTF8 *filename) { FileStream *fs; - + if(!isLoaded()) return false; @@ -168,7 +166,7 @@ void LangFile::setLangName(const UTF8 *newName) { if(mLangName) delete [] mLangName; - + dsize_t langNameLen = dStrlen(newName) + 1; mLangName = new UTF8 [langNameLen]; dStrcpy(mLangName, newName, langNameLen); @@ -178,7 +176,7 @@ void LangFile::setLangFile(const UTF8 *langFile) { if(mLangFile) delete [] mLangFile; - + dsize_t langFileLen = dStrlen(langFile) + 1; mLangFile = new UTF8 [langFileLen]; dStrcpy(mLangFile, langFile, langFileLen); @@ -211,7 +209,7 @@ IMPLEMENT_CONOBJECT(LangTable); ConsoleDocClass( LangTable, "@brief Provides the code necessary to handle the low level management " "of the string tables for localization\n\n" - + "One LangTable is created for each mod, as well as one for the C++ code. " "LangTable is responsible for obtaining the correct strings from each " "and relaying it to the appropriate controls.\n\n" @@ -260,7 +258,7 @@ S32 LangTable::addLanguage(const UTF8 *filename, const UTF8 *name /* = NULL */) if(Torque::FS::IsFile(filename)) { lang->setLangFile(filename); - + S32 ret = addLanguage(lang); if(ret >= 0) return ret; @@ -287,7 +285,7 @@ const U32 LangTable::getStringLength(const U32 id) const const UTF8 *s = getString(id); if(s) return dStrlen(s); - + return 0; } @@ -299,7 +297,7 @@ void LangTable::setDefaultLanguage(S32 langid) { if(mDefaultLang >= 0) mLangTable[mDefaultLang]->deactivateLanguage(); - + mDefaultLang = langid; } } @@ -329,7 +327,7 @@ void LangTable::setCurrentLanguage(S32 langid) -DefineEngineMethod(LangTable, addLanguage, S32, (String filename, String languageName), ("", ""), +DefineEngineMethod(LangTable, addLanguage, S32, (String filename, String languageName), ("", ""), "(string filename, [string languageName])" "@brief Adds a language to the table\n\n" "@param filename Name and path to the language file\n" @@ -338,12 +336,12 @@ DefineEngineMethod(LangTable, addLanguage, S32, (String filename, String languag ) { UTF8 scriptFilenameBuffer[1024]; - + Con::expandScriptFilename((char*)scriptFilenameBuffer, sizeof(scriptFilenameBuffer), filename); return object->addLanguage(scriptFilenameBuffer, (const UTF8*)languageName); } -DefineEngineMethod(LangTable, getString, const char *, (U32 id), , +DefineEngineMethod(LangTable, getString, const char *, (U32 id), , "(string filename)" "@brief Grabs a string from the specified table\n\n" "If an invalid is passed, the function will attempt to " @@ -359,7 +357,7 @@ DefineEngineMethod(LangTable, getString, const char *, (U32 id), , dStrcpy(ret, str, retLen); return ret; } - + return ""; } @@ -370,7 +368,7 @@ DefineEngineMethod(LangTable, setDefaultLanguage, void, (S32 langId), , "(int la object->setDefaultLanguage(langId); } -DefineEngineMethod(LangTable, setCurrentLanguage, void, (S32 langId), , +DefineEngineMethod(LangTable, setCurrentLanguage, void, (S32 langId), , "(int language)" "@brief Sets the current language table for grabbing text\n\n" "@param language ID of the table\n") @@ -398,7 +396,7 @@ DefineEngineMethod(LangTable, getLangName, const char *, (S32 langId), , "(int l dStrcpy(ret, str, retLen); return ret; } - + return ""; } @@ -420,9 +418,9 @@ UTF8 *sanitiseVarName(const UTF8 *varName, UTF8 *buffer, U32 bufsize) *buffer = 0; return NULL; } - + dStrcpy(buffer, (const UTF8*)"I18N::", bufsize); - + UTF8 *dptr = buffer + 6; const UTF8 *sptr = varName; while(*sptr) @@ -435,27 +433,27 @@ UTF8 *sanitiseVarName(const UTF8 *varName, UTF8 *buffer, U32 bufsize) *dptr++ = '_'; sptr++; } - + if((dptr - buffer) >= (bufsize - 1)) break; } *dptr = 0; - + return buffer; } UTF8 *getCurrentModVarName(UTF8 *buffer, U32 bufsize) { char varName[256]; - StringTableEntry cbName = CodeBlock::getCurrentCodeBlockName(); - + StringTableEntry cbName = Con::getCurrentScriptModuleName(); + const UTF8 *slash = (const UTF8*)dStrchr(cbName, '/'); if (slash == NULL) { Con::errorf("Illegal CodeBlock path detected in sanitiseVarName() (no mod directory): %s", cbName); return NULL; } - + dStrncpy(varName, cbName, slash - (const UTF8*)cbName); varName[slash - (const UTF8*)cbName] = 0; @@ -465,7 +463,7 @@ UTF8 *getCurrentModVarName(UTF8 *buffer, U32 bufsize) const LangTable *getCurrentModLangTable() { UTF8 saneVarName[256]; - + if(getCurrentModVarName(saneVarName, sizeof(saneVarName))) { const LangTable *lt = dynamic_cast(Sim::findObject(Con::getIntVariable((const char*)saneVarName))); @@ -508,7 +506,7 @@ bool compiledFileNeedsUpdate(UTF8* filename) return false; } -DefineEngineFunction(CompileLanguage, void, (const char* inputFile, bool createMap), (false), +DefineEngineFunction(CompileLanguage, void, (const char* inputFile, bool createMap), (false), "@brief Compiles a LSO language file." " if createIndex is true, will also create languageMap." TORQUE_SCRIPT_EXTENSION " with" " the global variables for each string index." diff --git a/Engine/source/postFx/postEffectVis.cpp b/Engine/source/postFx/postEffectVis.cpp index 5d3d351c0a..a3ff66b9cd 100644 --- a/Engine/source/postFx/postEffectVis.cpp +++ b/Engine/source/postFx/postEffectVis.cpp @@ -22,6 +22,8 @@ #include "platform/platform.h" #include "postFx/postEffectVis.h" + +#include "console/script.h" #include "gui/containers/guiWindowCtrl.h" #include "gui/controls/guiBitmapCtrl.h" #include "gui/core/guiCanvas.h" diff --git a/Engine/source/sfx/sfxDescription.cpp b/Engine/source/sfx/sfxDescription.cpp index 09e08be5c8..97a8732881 100644 --- a/Engine/source/sfx/sfxDescription.cpp +++ b/Engine/source/sfx/sfxDescription.cpp @@ -37,6 +37,8 @@ #include "core/module.h" #include "math/mathIO.h" #include "math/mathTypes.h" +#include "console/simBase.h" +#include "console/engineAPI.h" IMPLEMENT_CO_DATABLOCK_V1( SFXDescription ); @@ -455,7 +457,7 @@ bool SFXDescription::onAdd() const char* channelValue = getDataField( sChannel, NULL ); if( channelValue && channelValue[ 0 ] ) { - ConsoleValue result = Con::evaluatef( "return sfxOldChannelToGroup( %s );", channelValue ); + ConsoleValue result = Con::executef("sfxOldChannelToGroup", channelValue); const char* group = result.getString(); if( !Sim::findObject( group, mSourceGroup ) ) Con::errorf( "SFXDescription::onAdd - could not resolve channel '%s' to SFXSource", channelValue ); diff --git a/Engine/source/sim/actionMap.cpp b/Engine/source/sim/actionMap.cpp index 117278affe..19e56315d8 100644 --- a/Engine/source/sim/actionMap.cpp +++ b/Engine/source/sim/actionMap.cpp @@ -28,6 +28,7 @@ #include "core/stream/fileStream.h" #include "math/mMathFn.h" #include "console/engineAPI.h" +#include "console/script.h" #include "math/mQuat.h" #include "math/mAngAxis.h" diff --git a/Engine/source/testing/ScriptTest.cpp b/Engine/source/testing/ScriptTest.cpp index 76eaba746d..4de2b77d29 100644 --- a/Engine/source/testing/ScriptTest.cpp +++ b/Engine/source/testing/ScriptTest.cpp @@ -26,12 +26,13 @@ #include "console/simBase.h" #include "console/engineAPI.h" #include "math/mMath.h" +#include "console/script.h" #include "console/stringStack.h" #include "gui/buttons/guiIconButtonCtrl.h" inline ConsoleValue RunScript(const char* str) { - return std::move(Con::evaluate(str, false, NULL)); + return std::move(Con::evaluate(str, false, NULL).value); } using ::testing::Matcher; diff --git a/Engine/source/testing/consoleTest.cpp b/Engine/source/testing/consoleTest.cpp index 40eb050155..f5ee08cd66 100644 --- a/Engine/source/testing/consoleTest.cpp +++ b/Engine/source/testing/consoleTest.cpp @@ -7,12 +7,10 @@ #include "console/simBase.h" #include "console/engineAPI.h" #include "math/mMath.h" +#include "console/script.h" #include "console/stringStack.h" #include "console/consoleInternal.h" -// Stupid globals not declared in a header -extern ExprEvalState gEvalState; - using ::testing::Matcher; using ::testing::TypedEq; @@ -25,10 +23,10 @@ class ConsoleTest : public ::testing::Test void SetUp() override { - + } - - + + }; TEST_F(ConsoleTest, executef) @@ -176,7 +174,7 @@ TEST_F(ConsoleTest, execute) { Con::evaluate("function testScriptExecuteFunction(%a,%b) {return %a SPC %b;}\nfunction testScriptExecuteFunction(%a,%b,%this) {return %a SPC %b;}\r\n", false, "testExecute"); - U32 startStackPos = gEvalState.getStackDepth(); + U32 startStackPos = Con::getFrameStack().size(); U32 startStringStackPos = STR.mStart; // const char* versions of execute should maintain stack @@ -187,7 +185,7 @@ TEST_F(ConsoleTest, execute) EXPECT_STREQ(returnValue, "1 2") << "execute should return 1 2"; - EXPECT_EQ(gEvalState.getStackDepth(), startStackPos) << + EXPECT_EQ(Con::getFrameStack().size(), startStackPos) << "execute should restore stack"; returnValue = Con::execute(4, argvObject); @@ -195,6 +193,6 @@ TEST_F(ConsoleTest, execute) EXPECT_STREQ(returnValue, "1 2") << "execute should return 1 2"; - EXPECT_EQ(gEvalState.getStackDepth(), startStackPos) << + EXPECT_EQ(Con::getFrameStack().size(), startStackPos) << "execute should restore stack"; } diff --git a/Engine/source/testing/engineAPITest.cpp b/Engine/source/testing/engineAPITest.cpp index 27d8502593..7f2e66d49d 100644 --- a/Engine/source/testing/engineAPITest.cpp +++ b/Engine/source/testing/engineAPITest.cpp @@ -7,6 +7,7 @@ #include "console/simBase.h" #include "console/engineAPI.h" #include "math/mMath.h" +#include "console/script.h" using ::testing::Matcher; using ::testing::TypedEq; diff --git a/Engine/source/testing/runtimeClassRepTest.cpp b/Engine/source/testing/runtimeClassRepTest.cpp index b9250cc5da..cd3ac8e8f3 100644 --- a/Engine/source/testing/runtimeClassRepTest.cpp +++ b/Engine/source/testing/runtimeClassRepTest.cpp @@ -25,6 +25,7 @@ #include "console/simBase.h" #include "console/consoleTypes.h" #include "console/runtimeClassRep.h" +#include "console/script.h" class RuntimeRegisteredSimObject : public SimObject { diff --git a/Engine/source/testing/unitTesting.cpp b/Engine/source/testing/unitTesting.cpp index b69edb1385..90afddf831 100644 --- a/Engine/source/testing/unitTesting.cpp +++ b/Engine/source/testing/unitTesting.cpp @@ -23,7 +23,7 @@ #include "app/mainLoop.h" #include "console/console.h" -#include "console/codeBlock.h" +#include "console/script.h" #include "console/engineAPI.h" #include "console/consoleInternal.h" #include "gfx/gfxInit.h" @@ -32,6 +32,8 @@ #define _CRTDBG_MAP_ALLOC #include #endif + + //----------------------------------------------------------------------------- class TorqueUnitTestListener : public ::testing::EmptyTestEventListener @@ -195,9 +197,9 @@ DefineEngineFunction(addUnitTest, void, (const char* function), , U32 ln = __LINE__; if (entry != NULL) { - file = entry->mCode->name; + file = entry->mModule->getName(); U32 inst; - entry->mCode->findBreakLine(entry->mFunctionOffset, ln, inst); + entry->mModule->findBreakLine(entry->mFunctionOffset, ln, inst); } else { @@ -210,9 +212,9 @@ DefineEngineFunction(addUnitTest, void, (const char* function), , String scriptFileMessage(const char* message) { - Dictionary* frame = &gEvalState.getCurrentFrame(); - CodeBlock* code = frame->code; - const char* scriptLine = code->getFileLine(frame->ip); + Dictionary* frame = Con::getCurrentStackFrame(); + Con::Module* module = frame->module; + const char* scriptLine = module->getFileLine(frame->ip); return String::ToString("at %s: %s", scriptLine, message); } diff --git a/Engine/source/ts/tsShape.cpp b/Engine/source/ts/tsShape.cpp index e6eb2f4fdd..19b873a336 100644 --- a/Engine/source/ts/tsShape.cpp +++ b/Engine/source/ts/tsShape.cpp @@ -29,12 +29,13 @@ #include "console/console.h" #include "ts/tsShapeInstance.h" #include "collision/convex.h" +#include "console/consoleInternal.h" +#include "console/script.h" #include "materials/matInstance.h" #include "materials/materialManager.h" #include "math/mathIO.h" #include "core/util/endian.h" #include "core/stream/fileStream.h" -#include "console/compiler.h" #include "core/fileObject.h" #ifdef TORQUE_COLLADA @@ -2144,7 +2145,7 @@ template<> void *Resource::create(const Torque::Path &path) scriptPath.setExtension(TORQUE_SCRIPT_EXTENSION); // Don't execute the script if we're already doing so! - StringTableEntry currentScript = Platform::stripBasePath(CodeBlock::getCurrentCodeBlockFullPath()); + StringTableEntry currentScript = Platform::stripBasePath(Con::getCurrentScriptModulePath()); if (!scriptPath.getFullPath().equal(currentScript)) { Torque::Path scriptPathDSO(scriptPath); diff --git a/Engine/source/windowManager/sdl/sdlWindow.cpp b/Engine/source/windowManager/sdl/sdlWindow.cpp index c64da01beb..d713d359c8 100644 --- a/Engine/source/windowManager/sdl/sdlWindow.cpp +++ b/Engine/source/windowManager/sdl/sdlWindow.cpp @@ -650,7 +650,7 @@ void PlatformWindowSDL::_processSDLEvent(SDL_Event &evt) _updateMonitorFromMove(evt); // If display device has changed, make sure window params are compatible with the new device. if (oldDisplay != Con::getIntVariable("pref::Video::deviceId", 0)) - Con::evaluate("configureCanvas();"); + Con::executef("configureCanvas"); break; } case SDL_WINDOWEVENT_RESIZED: diff --git a/Engine/source/windowManager/windowInputGenerator.cpp b/Engine/source/windowManager/windowInputGenerator.cpp index f2391d553e..a24eeae9af 100644 --- a/Engine/source/windowManager/windowInputGenerator.cpp +++ b/Engine/source/windowManager/windowInputGenerator.cpp @@ -21,6 +21,8 @@ //----------------------------------------------------------------------------- #include "windowManager/windowInputGenerator.h" + +#include "console/script.h" #include "windowManager/platformWindow.h" #include "sim/actionMap.h" #include "platform/input/IProcessInput.h"