├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── COMPILE ├── COPYRIGHT ├── HISTORY ├── Makefile ├── README ├── appveyor.yml ├── doc ├── Makefile ├── make.bat └── source │ ├── _static │ ├── nut.ico │ └── simple_nut.png │ ├── conf.py │ ├── index.rst │ ├── nut.ico │ ├── reference │ ├── api │ │ ├── bytecode_serialization.rst │ │ ├── calls.rst │ │ ├── compiler.rst │ │ ├── debug_interface.rst │ │ ├── garbage_collector.rst │ │ ├── object_creation_and_handling.rst │ │ ├── object_manipulation.rst │ │ ├── raw_object_handling.rst │ │ ├── stack_operations.rst │ │ └── virtual_machine.rst │ ├── api_reference.rst │ ├── embedding │ │ ├── build_configuration.rst │ │ ├── calling_a_function.rst │ │ ├── compiling_a_script.rst │ │ ├── creating_a_c_function.rst │ │ ├── debug_interface.rst │ │ ├── error_conventions.rst │ │ ├── memory_management.rst │ │ ├── references_from_c.rst │ │ ├── runtime_error_handling.rst │ │ ├── tables_and_arrays_manipulation.rst │ │ ├── the_registry_table.rst │ │ ├── the_stack.rst │ │ ├── userdata_and_userpointers.rst │ │ └── vm_initialization.rst │ ├── embedding_squirrel.rst │ ├── index.rst │ ├── introduction.rst │ ├── language.rst │ └── language │ │ ├── arrays.rst │ │ ├── builtin_functions.rst │ │ ├── classes.rst │ │ ├── constants_and_enumerations.rst │ │ ├── datatypes.rst │ │ ├── delegation.rst │ │ ├── execution_context.rst │ │ ├── expressions.rst │ │ ├── functions.rst │ │ ├── generators.rst │ │ ├── lexical_structure.rst │ │ ├── metamethods.rst │ │ ├── statements.rst │ │ ├── tables.rst │ │ ├── threads.rst │ │ └── weak_references.rst │ ├── simple_nut.png │ └── stdlib │ ├── index.rst │ ├── introduction.rst │ ├── stdauxlib.rst │ ├── stdbloblib.rst │ ├── stdiolib.rst │ ├── stdmathlib.rst │ ├── stdstringlib.rst │ └── stdsystemlib.rst ├── etc ├── minimal.c └── test.nut ├── include ├── sqconfig.h ├── sqstdaux.h ├── sqstdblob.h ├── sqstdio.h ├── sqstdmath.h ├── sqstdstring.h ├── sqstdsystem.h └── squirrel.h ├── samples ├── ackermann.nut ├── array.nut ├── class.nut ├── classattributes.nut ├── coroutines.nut ├── delegation.nut ├── fibonacci.nut ├── flow.nut ├── generators.nut ├── hello.nut ├── list.nut ├── loops.nut ├── matrix.nut ├── metamethods.nut ├── methcall.nut ├── regex.nut └── tailstate.nut ├── sq ├── CMakeLists.txt ├── Makefile ├── sq.c └── sq.dsp ├── sqstdlib ├── CMakeLists.txt ├── Makefile ├── sqstdaux.cpp ├── sqstdblob.cpp ├── sqstdblobimpl.h ├── sqstdio.cpp ├── sqstdlib.dsp ├── sqstdmath.cpp ├── sqstdrex.cpp ├── sqstdstream.cpp ├── sqstdstream.h ├── sqstdstring.cpp └── sqstdsystem.cpp ├── squirrel-config.cmake.in ├── squirrel.dsw ├── squirrel.pc.in └── squirrel ├── CMakeLists.txt ├── Makefile ├── sqapi.cpp ├── sqarray.h ├── sqbaselib.cpp ├── sqclass.cpp ├── sqclass.h ├── sqclosure.h ├── sqcompiler.cpp ├── sqcompiler.h ├── sqdebug.cpp ├── sqfuncproto.h ├── sqfuncstate.cpp ├── sqfuncstate.h ├── sqlexer.cpp ├── sqlexer.h ├── sqmem.cpp ├── sqobject.cpp ├── sqobject.h ├── sqopcodes.h ├── sqpcheader.h ├── sqstate.cpp ├── sqstate.h ├── sqstring.h ├── sqtable.cpp ├── sqtable.h ├── squirrel.dsp ├── squserdata.h ├── squtils.h ├── sqvm.cpp └── sqvm.h /.gitignore: -------------------------------------------------------------------------------- 1 | # Folders created at compilation 2 | bin/ 3 | lib/ 4 | 5 | # Folders created at documentation generation 6 | doc/build/ 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | compiler: 3 | - gcc 4 | - clang 5 | 6 | # Travis VMs are 64-bit but we compile both for 32 and 64 bit. To enable the 7 | # 32-bit builds to work, we need gcc-multilib. 8 | addons: 9 | apt: 10 | packages: 11 | - gcc-multilib 12 | - g++-multilib 13 | 14 | # Enable container-based builds. 15 | sudo: false 16 | 17 | script: mkdir build && cd build && cmake .. && make -j2 18 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | project(squirrel 3 | VERSION 3.2 4 | DESCRIPTION "The Squirrel programming language" 5 | HOMEPAGE_URL "http://squirrel-lang.org/" 6 | LANGUAGES C CXX 7 | ) 8 | 9 | option(DISABLE_STATIC "Avoid building/installing static libraries.") 10 | option(LONG_OUTPUT_NAMES "Use longer names for binaries and libraries: squirrel3 (not sq).") 11 | 12 | if (NOT CMAKE_BUILD_TYPE) 13 | set(CMAKE_BUILD_TYPE "Release") 14 | endif () 15 | 16 | include(GNUInstallDirs) 17 | 18 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}") 19 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}") 20 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}") 21 | set(CMAKE_CXX_STANDARD 11) 22 | 23 | if(CMAKE_COMPILER_IS_GNUCXX) 24 | add_compile_options( 25 | "$<$:-fno-rtti;-fno-exceptions>" 26 | -fno-strict-aliasing 27 | -Wall 28 | -Wextra 29 | -pedantic 30 | -Wcast-qual 31 | "$<$:-O3>" 32 | "$<$:-O3;-g>" 33 | "$<$:-Os>" 34 | "$<$:-pg;-pie;-gstabs;-g3;-Og>" 35 | ) 36 | elseif(MSVC) 37 | set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) 38 | add_definitions(-D_CRT_SECURE_NO_WARNINGS) 39 | endif() 40 | 41 | # Need to be defined here to be visible to squirrel.pc.in 42 | if(LONG_OUTPUT_NAMES) 43 | set(LIBSQUIRREL_NAME squirrel3) 44 | set(SQSTDLIB_NAME sqstdlib3) 45 | else() 46 | set(LIBSQUIRREL_NAME squirrel) 47 | set(SQSTDLIB_NAME sqstdlib) 48 | endif() 49 | 50 | add_subdirectory(squirrel) 51 | add_subdirectory(sqstdlib) 52 | if(NOT SQ_DISABLE_INTERPRETER) 53 | add_subdirectory(sq) 54 | endif() 55 | 56 | if(CMAKE_SIZEOF_VOID_P EQUAL 8) 57 | set(tgts) 58 | if(NOT DISABLE_DYNAMIC) 59 | list(APPEND tgts squirrel sqstdlib) 60 | if(NOT SQ_DISABLE_INTERPRETER) 61 | list(APPEND tgts sq) 62 | endif() 63 | endif() 64 | if(NOT DISABLE_STATIC) 65 | list(APPEND tgts squirrel_static sqstdlib_static) 66 | if(NOT SQ_DISABLE_INTERPRETER) 67 | list(APPEND tgts sq_static) 68 | endif() 69 | endif() 70 | foreach(t ${tgts}) 71 | target_compile_definitions(${t} PUBLIC -D_SQ64) 72 | endforeach() 73 | endif() 74 | 75 | if(NOT DISABLE_DYNAMIC) 76 | set_target_properties(squirrel sqstdlib PROPERTIES SOVERSION 0 VERSION 0.0.0) 77 | endif() 78 | 79 | if(NOT SQ_DISABLE_INSTALLER AND NOT SQ_DISABLE_HEADER_INSTALLER) 80 | install(FILES 81 | include/sqconfig.h 82 | include/squirrel.h 83 | DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} 84 | COMPONENT Development 85 | ) 86 | install(FILES 87 | include/sqstdaux.h 88 | include/sqstdblob.h 89 | include/sqstdio.h 90 | include/sqstdmath.h 91 | include/sqstdstring.h 92 | include/sqstdsystem.h 93 | DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} 94 | COMPONENT Development 95 | ) 96 | endif() 97 | 98 | include(CMakePackageConfigHelpers) 99 | 100 | write_basic_package_version_file( 101 | "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/squirrel/squirrel-config-version.cmake" 102 | VERSION "${squirrel_VERSION}" 103 | COMPATIBILITY AnyNewerVersion 104 | ) 105 | 106 | configure_package_config_file( 107 | "${CMAKE_CURRENT_SOURCE_DIR}/squirrel-config.cmake.in" 108 | "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/squirrel/squirrel-config.cmake" 109 | INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/squirrel" 110 | ) 111 | 112 | configure_file( 113 | "${CMAKE_CURRENT_SOURCE_DIR}/squirrel.pc.in" 114 | ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc 115 | @ONLY 116 | ) 117 | 118 | if(NOT SQ_DISABLE_INSTALLER AND NOT SQ_DISABLE_CMAKE_INSTALLER) 119 | export(EXPORT squirrel 120 | NAMESPACE squirrel:: 121 | FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/squirrel/squirrel-targets.cmake" 122 | ) 123 | 124 | install(FILES 125 | "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/squirrel/squirrel-config-version.cmake" 126 | "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/squirrel/squirrel-config.cmake" 127 | DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/squirrel" 128 | COMPONENT Development 129 | ) 130 | 131 | # pc(5) only allows static variant to have extra flags, not an entirely new 132 | # set of flags. While it's uncommon, a way to do it would be to generate a 133 | # ${PROJECT_NAME}_static.pc file. 134 | if(NOT DISABLE_DYNAMIC) 135 | install( 136 | FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc 137 | DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig 138 | COMPONENT Development 139 | ) 140 | endif() 141 | 142 | install(EXPORT squirrel 143 | NAMESPACE squirrel:: 144 | DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/squirrel" 145 | FILE "squirrel-targets.cmake" 146 | COMPONENT Development 147 | ) 148 | endif() 149 | -------------------------------------------------------------------------------- /COMPILE: -------------------------------------------------------------------------------- 1 | Squirrel 3.2 stable 2 | -------------------------------------------------------- 3 | What is in this distribution? 4 | 5 | squirrel 6 | static library implementing the compiler and interpreter of the language 7 | 8 | sqstdlib 9 | the standard utility libraries 10 | 11 | sq 12 | stand alone interpreter 13 | 14 | doc 15 | The manual 16 | 17 | etc 18 | a minimalistic embedding sample 19 | 20 | samples 21 | samples programs 22 | 23 | 24 | HOW TO COMPILE 25 | --------------------------------------------------------- 26 | CMAKE USERS 27 | ......................................................... 28 | If you want to build the shared libraries under Windows using Visual 29 | Studio, you will have to use CMake version 3.4 or newer. If not, an 30 | earlier version will suffice. For a traditional out-of-source build 31 | under Linux, type something like 32 | 33 | $ mkdir build # Create temporary build directory 34 | $ cd build 35 | $ cmake .. # CMake will determine all the necessary information, 36 | # including the platform (32- vs. 64-bit) 37 | $ make 38 | $ make install 39 | $ cd ..; rm -r build 40 | 41 | The default installation directory will be /usr/local on Unix platforms, 42 | and C:/Program Files/squirrel on Windows. The binaries will go into bin/ 43 | and the libraries into lib/. You can change this behavior by calling CMake like 44 | this: 45 | 46 | $ cmake .. -DCMAKE_INSTALL_PREFIX=/some/path/on/your/system 47 | 48 | With the CMAKE_INSTALL_BINDIR and CMAKE_INSTALL_LIBDIR options, the directories 49 | the binaries & libraries will go in (relative to CMAKE_INSTALL_PREFIX) 50 | can be specified. For instance, 51 | 52 | $ cmake .. -DCMAKE_INSTALL_LIBDIR=lib64 53 | 54 | will install the libraries into a 'lib64' subdirectory in the top 55 | source directory. The public header files will be installed into the directory 56 | the value of CMAKE_INSTALL_INCLUDEDIR points to. If you want only the 57 | binaries and no headers, just set -DSQ_DISABLE_HEADER_INSTALLER=ON, and no 58 | header files will be installed. 59 | 60 | Under Windows, it is probably easiest to use the CMake GUI interface, 61 | although invoking CMake from the command line as explained above 62 | should work as well. 63 | 64 | GCC USERS 65 | ......................................................... 66 | There is a very simple makefile that compiles all libraries and exes 67 | from the root of the project run 'make' 68 | 69 | for 32 bits systems 70 | 71 | $ make 72 | 73 | for 64 bits systems 74 | 75 | $ make sq64 76 | 77 | VISUAL C++ USERS 78 | ......................................................... 79 | Open squirrel.dsw from the root project directory and build(dho!) 80 | 81 | DOCUMENTATION GENERATION 82 | ......................................................... 83 | To be able to compile the documentation, make sure that you have Python 84 | installed and the packages sphinx and sphinx_rtd_theme. Browse into doc/ 85 | and use either the Makefile for GCC-based platforms or make.bat for 86 | Windows platforms. 87 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2003-2022 Alberto Demichelis 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | ----------------------------------------------------- 21 | END OF COPYRIGHT 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | SQUIRREL=. 3 | MAKE=make 4 | 5 | sq32: folders 6 | cd squirrel; $(MAKE) 7 | cd sqstdlib; $(MAKE) 8 | cd sq; $(MAKE) 9 | 10 | sqprof: folders 11 | cd squirrel; $(MAKE) sqprof 12 | cd sqstdlib; $(MAKE) sqprof 13 | cd sq; $(MAKE) sqprof 14 | 15 | sq64: folders 16 | cd squirrel; $(MAKE) sq64 17 | cd sqstdlib; $(MAKE) sq64 18 | cd sq; $(MAKE) sq64 19 | 20 | folders: 21 | mkdir -p lib 22 | mkdir -p bin 23 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | The programming language SQUIRREL 3.2 stable 2 | 3 | -------------------------------------------------- 4 | This project has successfully been compiled and run on 5 | * Windows (x86 and amd64) 6 | * Linux (x86, amd64 and ARM) 7 | * Illumos (x86 and amd64) 8 | * FreeBSD (x86 and ARM) 9 | 10 | The following compilers have been confirmed to be working: 11 | MS Visual C++ 6.0 (all on x86 and amd64) 12 | 7.0 | 13 | 7.1 v 14 | 8.0 15 | 9.0 16 | 10.0 17 | 12.0 --- 18 | MinGW gcc 3.2 (mingw special 20020817-1) 19 | Cygnus gcc 3.2 20 | Linux gcc 3.2.3 21 | 4.0.0 (x86 and amd64) 22 | 5.3.1 (amd64) 23 | Illumos gcc 4.0.0 (x86 and amd64) 24 | ARM Linux gcc 4.6.3 (Raspberry Pi Model B) 25 | 26 | 27 | Feedback and suggestions are appreciated 28 | project page - http://www.squirrel-lang.org 29 | community forums - http://forum.squirrel-lang.org 30 | wiki - http://wiki.squirrel-lang.org 31 | author - alberto@demichelis.net 32 | 33 | END OF README 34 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 0.0.{build} 2 | 3 | platform: 4 | - x86 5 | - x64 6 | 7 | configuration: 8 | - Debug 9 | - Release 10 | 11 | clone_folder: c:\sq 12 | 13 | before_build: 14 | - mkdir build 15 | - cd build 16 | - call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %platform% 17 | - echo %platform% 18 | - if %platform%==X64 (cmake .. -G "Visual Studio 14 2015 Win64") 19 | - if %platform%==x86 (cmake .. -G "Visual Studio 14 2015") 20 | 21 | build_script: 22 | - cmake --build . --config %configuration% -- /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" 23 | 24 | artifacts: 25 | - path: build\*\%configuration%\*.exe 26 | - path: build\*\%configuration%\*.dll 27 | 28 | test: off 29 | -------------------------------------------------------------------------------- /doc/source/_static/nut.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/albertodemichelis/squirrel/f77074bdd6152d230609146a3d424c6f49e3770f/doc/source/_static/nut.ico -------------------------------------------------------------------------------- /doc/source/_static/simple_nut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/albertodemichelis/squirrel/f77074bdd6152d230609146a3d424c6f49e3770f/doc/source/_static/simple_nut.png -------------------------------------------------------------------------------- /doc/source/index.rst: -------------------------------------------------------------------------------- 1 | .. Squirrel documentation master file, created by 2 | sphinx-quickstart on Sun Jan 31 00:26:52 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Squirrel's documentation 7 | ========================================= 8 | 9 | Contents: 10 | 11 | .. toctree:: 12 | :maxdepth: 1 13 | 14 | reference/index.rst 15 | stdlib/index.rst 16 | 17 | 18 | Indices and tables 19 | ================== 20 | 21 | * :ref:`genindex` 22 | * :ref:`search` 23 | 24 | 25 | -------------------------------------------------------------------------------- /doc/source/nut.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/albertodemichelis/squirrel/f77074bdd6152d230609146a3d424c6f49e3770f/doc/source/nut.ico -------------------------------------------------------------------------------- /doc/source/reference/api/bytecode_serialization.rst: -------------------------------------------------------------------------------- 1 | .. _api_ref_bytecode_serialization: 2 | 3 | ====================== 4 | Bytecode serialization 5 | ====================== 6 | 7 | .. _sq_readclosure: 8 | 9 | .. c:function:: SQRESULT sq_readclosure(HSQUIRRELVM v, SQREADFUNC readf, SQUserPointer up) 10 | 11 | :param HSQUIRRELVM v: the target VM 12 | :param SQREADFUNC readf: pointer to a read function that will be invoked by the vm during the serialization. 13 | :param SQUserPointer up: pointer that will be passed to each call to the read function 14 | :returns: a SQRESULT 15 | 16 | serialize (read) a closure and pushes it on top of the stack, the source is user defined through a read callback. 17 | 18 | 19 | 20 | 21 | 22 | .. _sq_writeclosure: 23 | 24 | .. c:function:: SQRESULT sq_writeclosure(HSQUIRRELVM v, SQWRITEFUNC writef, SQUserPointer up) 25 | 26 | :param HSQUIRRELVM v: the target VM 27 | :param SQWRITEFUNC writef: pointer to a write function that will be invoked by the vm during the serialization. 28 | :param SQUserPointer up: pointer that will be passed to each call to the write function 29 | :returns: a SQRESULT 30 | :remarks: closures with free variables cannot be serialized 31 | 32 | serializes(writes) the closure on top of the stack, the destination is user defined through a write callback. 33 | -------------------------------------------------------------------------------- /doc/source/reference/api/calls.rst: -------------------------------------------------------------------------------- 1 | .. _api_ref_calls: 2 | 3 | ===== 4 | Calls 5 | ===== 6 | 7 | .. _sq_call: 8 | 9 | .. c:function:: SQRESULT sq_call(HSQUIRRELVM v, SQInteger params, SQBool retval, SQBool raiseerror) 10 | 11 | :param HSQUIRRELVM v: the target VM 12 | :param SQInteger params: number of parameters of the function 13 | :param SQBool retval: if true the function will push the return value in the stack 14 | :param SQBool raiseerror: if true, if a runtime error occurs during the execution of the call, the vm will invoke the error handler. 15 | :returns: a SQRESULT 16 | 17 | calls a closure or a native closure. The function pops all the parameters and leave the closure in the stack; if retval is true the return value of the closure is pushed. If the execution of the function is suspended through sq_suspendvm(), the closure and the arguments will not be automatically popped from the stack. 18 | 19 | When using to create an instance, push a dummy parameter to be filled with the newly-created instance for the constructor's 'this' parameter. 20 | 21 | 22 | 23 | .. _sq_getcallee: 24 | 25 | .. c:function:: SQRESULT sq_getcallee(HSQUIRRELVM v) 26 | 27 | :param HSQUIRRELVM v: the target VM 28 | :returns: a SQRESULT 29 | 30 | push in the stack the currently running closure. 31 | 32 | 33 | 34 | 35 | 36 | .. _sq_getlasterror: 37 | 38 | .. c:function:: SQRESULT sq_getlasterror(HSQUIRRELVM v) 39 | 40 | :param HSQUIRRELVM v: the target VM 41 | :returns: a SQRESULT 42 | :remarks: the pushed error descriptor can be any valid squirrel type. 43 | 44 | pushes the last error in the stack. 45 | 46 | 47 | 48 | 49 | 50 | .. _sq_getlocal: 51 | 52 | .. c:function:: const SQChar * sq_getlocal(HSQUIRRELVM v, SQUnsignedInteger level, SQUnsignedInteger nseq) 53 | 54 | :param HSQUIRRELVM v: the target VM 55 | :param SQUnsignedInteger level: the function index in the calls stack, 0 is the current function 56 | :param SQUnsignedInteger nseq: the index of the local variable in the stack frame (0 is 'this') 57 | :returns: the name of the local variable if a variable exists at the given level/seq otherwise NULL. 58 | 59 | Returns the name of a local variable given stackframe and sequence in the stack and pushes is current value. Free variables are treated as local variables, by sq_getlocal(), and will be returned as they would be at the base of the stack, just before the real local variables. 60 | 61 | 62 | 63 | 64 | 65 | .. _sq_reseterror: 66 | 67 | .. c:function:: void sq_reseterror(HSQUIRRELVM v) 68 | 69 | :param HSQUIRRELVM v: the target VM 70 | 71 | reset the last error in the virtual machine to null 72 | 73 | 74 | 75 | 76 | 77 | .. _sq_resume: 78 | 79 | .. c:function:: SQRESULT sq_resume(HSQUIRRELVM v, SQBool retval, SQBool raiseerror) 80 | 81 | :param HSQUIRRELVM v: the target VM 82 | :param SQBool retval: if true the function will push the return value in the stack 83 | :param SQBool raiseerror: if true, if a runtime error occurs during the execution of the call, the vm will invoke the error handler. 84 | :returns: a SQRESULT 85 | :remarks: if retval != 0 the return value of the generator is pushed. 86 | 87 | resumes the generator at the top position of the stack. 88 | 89 | 90 | .. _sq_tailcall: 91 | 92 | .. c:function:: SQRESULT sq_tailcall(HSQUIRRELVM v, SQInteger nparams) 93 | 94 | :param HSQUIRRELVM v: the target VM 95 | :param SQInteger params: number of parameters of the function 96 | 97 | Calls a closure and removes the caller function from the call stack. 98 | This function must be invoke from a native closure and 99 | he return value of sq_tailcall must be returned by the caller function(see example). 100 | 101 | *.eg* 102 | 103 | :: 104 | 105 | SQInteger tailcall_something_example(HSQUIRRELVM v) 106 | { 107 | //push closure and parameters here 108 | ... 109 | return sq_tailcall(v,2); 110 | } 111 | 112 | .. _sq_throwerror: 113 | 114 | .. c:function:: SQRESULT sq_throwerror(HSQUIRRELVM v, const SQChar * err) 115 | 116 | :param HSQUIRRELVM v: the target VM 117 | :param SQChar * err: the description of the error that has to be thrown 118 | :returns: the value that has to be returned by a native closure in order to throw an exception in the virtual machine. 119 | 120 | sets the last error in the virtual machine and returns the value that has to be returned by a native closure in order to trigger an exception in the virtual machine. 121 | 122 | 123 | .. _sq_throwobject: 124 | 125 | .. c:function:: SQRESULT sq_throwobject(HSQUIRRELVM v) 126 | 127 | :param HSQUIRRELVM v: the target VM 128 | :returns: the value that has to be returned by a native closure in order to throw an exception in the virtual machine. 129 | 130 | pops a value from the stack sets it as the last error in the virtual machine. Returns the value that has to be returned by a native closure in order to trigger an exception in the virtual machine (aka SQ_ERROR). 131 | -------------------------------------------------------------------------------- /doc/source/reference/api/compiler.rst: -------------------------------------------------------------------------------- 1 | .. _api_ref_compiler: 2 | 3 | ======== 4 | Compiler 5 | ======== 6 | 7 | .. _sq_compile: 8 | 9 | .. c:function:: SQRESULT sq_compile(HSQUIRRELVM v, HSQLEXREADFUNC read, SQUserPointer p, const SQChar * sourcename, SQBool raiseerror) 10 | 11 | :param HSQUIRRELVM v: the target VM 12 | :param HSQLEXREADFUNC read: a pointer to a read function that will feed the compiler with the program. 13 | :param SQUserPointer p: a user defined pointer that will be passed by the compiler to the read function at each invocation. 14 | :param SQChar * sourcename: the symbolic name of the program (used only for more meaningful runtime errors) 15 | :param SQBool raiseerror: if this value is true the compiler error handler will be called in case of an error 16 | :returns: a SQRESULT. If the sq_compile fails nothing is pushed in the stack. 17 | :remarks: in case of an error the function will call the function set by sq_setcompilererrorhandler(). 18 | 19 | compiles a squirrel program; if it succeeds, push the compiled script as function in the stack. 20 | 21 | 22 | 23 | 24 | 25 | .. _sq_compilebuffer: 26 | 27 | .. c:function:: SQRESULT sq_compilebuffer(HSQUIRRELVM v, const SQChar* s, SQInteger size, const SQChar * sourcename, SQBool raiseerror) 28 | 29 | :param HSQUIRRELVM v: the target VM 30 | :param SQChar * s: a pointer to the buffer that has to be compiled. 31 | :param SQInteger size: size in characters of the buffer passed in the parameter 's'. 32 | :param SQChar * sourcename: the symbolic name of the program (used only for more meaningful runtime errors) 33 | :param SQBool raiseerror: if this value true the compiler error handler will be called in case of an error 34 | :returns: a SQRESULT. If the sq_compilebuffer fails nothing is pushed in the stack. 35 | :remarks: in case of an error the function will call the function set by sq_setcompilererrorhandler(). 36 | 37 | compiles a squirrel program from a memory buffer; if it succeeds, push the compiled script as function in the stack. 38 | 39 | 40 | 41 | 42 | 43 | .. _sq_enabledebuginfo: 44 | 45 | .. c:function:: void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable) 46 | 47 | :param HSQUIRRELVM v: the target VM 48 | :param SQBool enable: if true enables the debug info generation, if == 0 disables it. 49 | :remarks: The function affects all threads as well. 50 | 51 | enable/disable the debug line information generation at compile time. 52 | 53 | 54 | 55 | 56 | 57 | .. _sq_notifyallexceptions: 58 | 59 | .. c:function:: void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable) 60 | 61 | :param HSQUIRRELVM v: the target VM 62 | :param SQBool enable: if true enables the error callback notification of handled exceptions. 63 | :remarks: By default the VM will invoke the error callback only if an exception is not handled (no try/catch traps are present in the call stack). If notifyallexceptions is enabled, the VM will call the error callback for any exception even if between try/catch blocks. This feature is useful for implementing debuggers. 64 | 65 | enable/disable the error callback notification of handled exceptions. 66 | 67 | 68 | 69 | 70 | 71 | .. _sq_setcompilererrorhandler: 72 | 73 | .. c:function:: void sq_setcompilererrorhandler(HSQUIRRELVM v, SQCOMPILERERROR f) 74 | 75 | :param HSQUIRRELVM v: the target VM 76 | :param SQCOMPILERERROR f: A pointer to the error handler function 77 | :remarks: if the parameter f is NULL no function will be called when a compiler error occurs. The compiler error handler is shared between friend VMs. 78 | 79 | sets the compiler error handler function 80 | -------------------------------------------------------------------------------- /doc/source/reference/api/debug_interface.rst: -------------------------------------------------------------------------------- 1 | .. _api_ref_debug_interface: 2 | 3 | =============== 4 | Debug interface 5 | =============== 6 | 7 | .. _sq_getfunctioninfo: 8 | 9 | .. c:function:: SQRESULT sq_getfunctioninfo(HSQUIRRELVM v, SQInteger level, SQFunctionInfo * fi) 10 | 11 | :param HSQUIRRELVM v: the target VM 12 | :param SQInteger level: calls stack level 13 | :param SQFunctionInfo * fi: pointer to the SQFunctionInfo structure that will store the closure informations 14 | :returns: a SQRESULT. 15 | :remarks: the member 'funcid' of the returned SQFunctionInfo structure is a unique identifier of the function; this can be useful to identify a specific piece of squirrel code in an application like for instance a profiler. this method will fail if the closure in the stack is a native C closure. 16 | 17 | 18 | 19 | *.eg* 20 | 21 | :: 22 | 23 | 24 | typedef struct tagSQFunctionInfo { 25 | SQUserPointer funcid; //unique idetifier for a function (all it's closures will share the same funcid) 26 | const SQChar *name; //function name 27 | const SQChar *source; //function source file name 28 | }SQFunctionInfo; 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | .. _sq_setdebughook: 37 | 38 | .. c:function:: void sq_setdebughook(HSQUIRRELVM v) 39 | 40 | :param HSQUIRRELVM v: the target VM 41 | :remarks: In order to receive a 'per line' callback, is necessary to compile the scripts with the line informations. Without line informations activated, only the 'call/return' callbacks will be invoked. 42 | 43 | pops a closure from the stack an sets it as debug hook. When a debug hook is set it overrides any previously set native or non native hooks. if the hook is null the debug hook will be disabled. 44 | 45 | 46 | 47 | 48 | 49 | .. _sq_setnativedebughook: 50 | 51 | .. c:function:: void sq_setnativedebughook(HSQUIRRELVM v, SQDEBUGHOOK hook) 52 | 53 | :param HSQUIRRELVM v: the target VM 54 | :param SQDEBUGHOOK hook: the native hook function 55 | :remarks: In order to receive a 'per line' callback, is necessary to compile the scripts with the line informations. Without line informations activated, only the 'call/return' callbacks will be invoked. 56 | 57 | sets the native debug hook. When a native hook is set it overrides any previously set native or non native hooks. if the hook is NULL the debug hook will be disabled. 58 | 59 | 60 | 61 | 62 | 63 | .. _sq_stackinfos: 64 | 65 | .. c:function:: SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos * si) 66 | 67 | :param HSQUIRRELVM v: the target VM 68 | :param SQInteger level: calls stack level 69 | :param SQStackInfos * si: pointer to the SQStackInfos structure that will store the stack informations 70 | :returns: a SQRESULT. 71 | 72 | retrieve the calls stack informations of a ceratain level in the calls stack. 73 | -------------------------------------------------------------------------------- /doc/source/reference/api/garbage_collector.rst: -------------------------------------------------------------------------------- 1 | .. _api_ref_garbage_collector: 2 | 3 | ================= 4 | Garbage Collector 5 | ================= 6 | 7 | .. _sq_collectgarbage: 8 | 9 | .. c:function:: SQInteger sq_collectgarbage(HSQUIRRELVM v) 10 | 11 | :param HSQUIRRELVM v: the target VM 12 | :remarks: this api only works with garbage collector builds (NO_GARBAGE_COLLECTOR is not defined) 13 | 14 | runs the garbage collector and returns the number of reference cycles found (and deleted) 15 | 16 | 17 | 18 | 19 | 20 | .. _sq_resurrectunreachable: 21 | 22 | .. c:function:: SQRESULT sq_resurrectunreachable(HSQUIRRELVM v) 23 | 24 | :param HSQUIRRELVM v: the target VM 25 | :remarks: this api only works with garbage collector builds (NO_GARBAGE_COLLECTOR is not defined) 26 | 27 | runs the garbage collector and pushes an array in the stack containing all unreachable object found. If no unreachable object is found, null is pushed instead. This function is meant to help debug reference cycles. 28 | -------------------------------------------------------------------------------- /doc/source/reference/api/raw_object_handling.rst: -------------------------------------------------------------------------------- 1 | .. _api_ref_raw_object_handling: 2 | 3 | =================== 4 | Raw object handling 5 | =================== 6 | 7 | .. _sq_addref: 8 | 9 | .. c:function:: void sq_addref(HSQUIRRELVM v, HSQOBJECT * po) 10 | 11 | :param HSQUIRRELVM v: the target VM 12 | :param HSQOBJECT * po: pointer to an object handler 13 | 14 | adds a reference to an object handler. 15 | 16 | 17 | 18 | 19 | 20 | .. _sq_getobjtypetag: 21 | 22 | .. c:function:: SQRESULT sq_getobjtypetag(HSQOBJECT * o, SQUserPointer * typetag) 23 | 24 | :param HSQOBJECT * o: pointer to an object handler 25 | :param SQUserPointer * typetag: a pointer to the variable that will store the tag 26 | :returns: a SQRESULT 27 | :remarks: the function works also with instances. if the target object is an instance, the typetag of it's base class is fetched. 28 | 29 | gets the typetag of a raw object reference(userdata or class). 30 | 31 | 32 | 33 | 34 | 35 | .. _sq_getrefcount: 36 | 37 | .. c:function:: SQUnsignedInteger sq_getrefcount(HSQUIRRELVM v, HSQOBJECT * po) 38 | 39 | :param HSQUIRRELVM v: the target VM 40 | :param HSQOBJECT * po: object handler 41 | 42 | returns the number of references of a given object. 43 | 44 | 45 | 46 | 47 | 48 | .. _sq_getstackobj: 49 | 50 | .. c:function:: SQRESULT sq_getstackobj(HSQUIRRELVM v, SQInteger idx, HSQOBJECT * po) 51 | 52 | :param HSQUIRRELVM v: the target VM 53 | :param SQInteger idx: index of the target object in the stack 54 | :param HSQOBJECT * po: pointer to an object handler 55 | :returns: a SQRESULT 56 | 57 | gets an object from the stack and stores it in a object handler. 58 | 59 | 60 | 61 | 62 | 63 | .. _sq_objtobool: 64 | 65 | .. c:function:: SQBool sq_objtobool(HSQOBJECT * po) 66 | 67 | :param HSQOBJECT * po: pointer to an object handler 68 | :remarks: If the object is not a bool will always return false. 69 | 70 | return the bool value of a raw object reference. 71 | 72 | 73 | 74 | 75 | 76 | .. _sq_objtofloat: 77 | 78 | .. c:function:: SQFloat sq_objtofloat(HSQOBJECT * po) 79 | 80 | :param HSQOBJECT * po: pointer to an object handler 81 | :remarks: If the object is an integer will convert it to float. If the object is not a number will always return 0. 82 | 83 | return the float value of a raw object reference. 84 | 85 | 86 | 87 | 88 | 89 | .. _sq_objtointeger: 90 | 91 | .. c:function:: SQInteger sq_objtointeger(HSQOBJECT * po) 92 | 93 | :param HSQOBJECT * po: pointer to an object handler 94 | :remarks: If the object is a float will convert it to integer. If the object is not a number will always return 0. 95 | 96 | return the integer value of a raw object reference. 97 | 98 | 99 | 100 | 101 | 102 | .. _sq_objtostring: 103 | 104 | .. c:function:: const SQChar* sq_objtostring(HSQOBJECT * po) 105 | 106 | :param HSQOBJECT * po: pointer to an object handler 107 | :remarks: If the object doesn't reference a string it returns NULL. 108 | 109 | return the string value of a raw object reference. 110 | 111 | 112 | 113 | 114 | 115 | .. _sq_objtouserpointer: 116 | 117 | .. c:function:: SQUserPointer sq_objtouserpointer(HSQOBJECT * po) 118 | 119 | :param HSQOBJECT * po: pointer to an object handler 120 | :remarks: If the object doesn't reference a userpointer it returns NULL. 121 | 122 | return the userpointer value of a raw object reference. 123 | 124 | 125 | 126 | 127 | 128 | .. _sq_pushobject: 129 | 130 | .. c:function:: void sq_pushobject(HSQUIRRELVM v, HSQOBJECT obj) 131 | 132 | :param HSQUIRRELVM v: the target VM 133 | :param HSQOBJECT obj: object handler 134 | 135 | push an object referenced by an object handler into the stack. 136 | 137 | 138 | 139 | 140 | 141 | .. _sq_release: 142 | 143 | .. c:function:: SQBool sq_release(HSQUIRRELVM v, HSQOBJECT * po) 144 | 145 | :param HSQUIRRELVM v: the target VM 146 | :param HSQOBJECT * po: pointer to an object handler 147 | :returns: SQTrue if the object handler released has lost all is references(the ones added with sq_addref). SQFalse otherwise. 148 | :remarks: the function will reset the object handler to null when it loses all references. 149 | 150 | remove a reference from an object handler. 151 | 152 | 153 | 154 | 155 | 156 | .. _sq_resetobject: 157 | 158 | .. c:function:: void sq_resetobject(HSQOBJECT * po) 159 | 160 | :param HSQOBJECT * po: pointer to an object handler 161 | :remarks: Every object handler has to be initialized with this function. 162 | 163 | resets(initialize) an object handler. 164 | -------------------------------------------------------------------------------- /doc/source/reference/api/stack_operations.rst: -------------------------------------------------------------------------------- 1 | .. _api_ref_stack_operations: 2 | 3 | ================ 4 | Stack Operations 5 | ================ 6 | 7 | .. _sq_cmp: 8 | 9 | .. c:function:: SQInteger sq_cmp(HSQUIRRELVM v) 10 | 11 | :param HSQUIRRELVM v: the target VM 12 | :returns: > 0 if obj1>obj2 13 | :returns: == 0 if obj1==obj2 14 | :returns: < 0 if obj1 0. :: 11 | 12 | sq_pushroottable(v); 13 | sq_pushstring(v,"foo",-1); 14 | sq_get(v,-2); //get the function from the root table 15 | sq_pushroottable(v); //'this' (function environment object) 16 | sq_pushinteger(v,1); 17 | sq_pushfloat(v,2.0); 18 | sq_pushstring(v,"three",-1); 19 | sq_call(v,4,SQFalse,SQFalse); 20 | sq_pop(v,2); //pops the roottable and the function 21 | 22 | this is equivalent to the following Squirrel code:: 23 | 24 | foo(1,2.0,"three"); 25 | 26 | If a runtime error occurs (or a exception is thrown) during the squirrel code execution 27 | the sq_call will fail. 28 | -------------------------------------------------------------------------------- /doc/source/reference/embedding/compiling_a_script.rst: -------------------------------------------------------------------------------- 1 | .. embedding_compiling_a_script: 2 | 3 | ================== 4 | Compiling a script 5 | ================== 6 | 7 | You can compile a Squirrel script with the function *sq_compile*.:: 8 | 9 | typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer userdata); 10 | 11 | SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p, 12 | const SQChar *sourcename,SQBool raiseerror); 13 | 14 | In order to compile a script is necessary for the host application to implement a reader 15 | function (SQLEXREADFUNC); this function is used to feed the compiler with the script 16 | data. 17 | The function is called every time the compiler needs a character; It has to return a 18 | character code if succeed or 0 if the source is finished. 19 | 20 | If sq_compile succeeds, the compiled script will be pushed as Squirrel function in the 21 | stack. 22 | 23 | .. :note:: 24 | In order to execute the script, the function generated by *sq_compile()* has 25 | to be called through *sq_call()* 26 | 27 | Here an example of a 'read' function that read from a file: :: 28 | 29 | SQInteger file_lexfeedASCII(SQUserPointer file) 30 | { 31 | int ret; 32 | char c; 33 | if( ( ret=fread(&c,sizeof(c),1,(FILE *)file )>0) ) 34 | return c; 35 | return 0; 36 | } 37 | 38 | int compile_file(HSQUIRRELVM v,const char *filename) 39 | { 40 | FILE *f=fopen(filename,"rb"); 41 | if(f) 42 | { 43 | sq_compile(v,file_lexfeedASCII,f,filename,1); 44 | fclose(f); 45 | return 1; 46 | } 47 | return 0; 48 | } 49 | 50 | When the compiler fails for a syntax error it will try to call the 'compiler error handler'; 51 | this function must be declared as follow: :: 52 | 53 | typedef void (*SQCOMPILERERROR)(HSQUIRRELVM /*v*/,const SQChar * /*desc*/,const SQChar * /*source*/, 54 | SQInteger /*line*/,SQInteger /*column*/); 55 | 56 | and can be set with the following API call:: 57 | 58 | void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f); 59 | -------------------------------------------------------------------------------- /doc/source/reference/embedding/creating_a_c_function.rst: -------------------------------------------------------------------------------- 1 | .. _embedding_creating_a_c_function: 2 | 3 | =================== 4 | Create a C function 5 | =================== 6 | 7 | A native C function must have the following prototype: :: 8 | 9 | typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM); 10 | 11 | The parameters is an handle to the calling VM and the return value is an integer 12 | respecting the following rules: 13 | 14 | * 1 if the function returns a value 15 | * 0 if the function does not return a value 16 | * SQ_ERROR runtime error is thrown 17 | 18 | In order to obtain a new callable squirrel function from a C function pointer, is necessary 19 | to call sq_newclosure() passing the C function to it; the new Squirrel function will be 20 | pushed in the stack. 21 | 22 | When the function is called, the stackbase is the first parameter of the function and the 23 | top is the last. In order to return a value the function has to push it in the stack and 24 | return 1. 25 | 26 | Function parameters are in the stack from position 1 ('this') to *n*. 27 | *sq_gettop()* can be used to determinate the number of parameters. 28 | 29 | If the function has free variables, those will be in the stack after the explicit parameters 30 | an can be handled as normal parameters. Note also that the value returned by *sq_gettop()* will be 31 | affected by free variables. *sq_gettop()* will return the number of parameters plus 32 | number of free variables. 33 | 34 | Here an example, the following function print the value of each argument and return the 35 | number of arguments. :: 36 | 37 | SQInteger print_args(HSQUIRRELVM v) 38 | { 39 | SQInteger nargs = sq_gettop(v); //number of arguments 40 | for(SQInteger n=1;n<=nargs;n++) 41 | { 42 | printf("arg %d is ",n); 43 | switch(sq_gettype(v,n)) 44 | { 45 | case OT_NULL: 46 | printf("null"); 47 | break; 48 | case OT_INTEGER: 49 | printf("integer"); 50 | break; 51 | case OT_FLOAT: 52 | printf("float"); 53 | break; 54 | case OT_STRING: 55 | printf("string"); 56 | break; 57 | case OT_TABLE: 58 | printf("table"); 59 | break; 60 | case OT_ARRAY: 61 | printf("array"); 62 | break; 63 | case OT_USERDATA: 64 | printf("userdata"); 65 | break; 66 | case OT_CLOSURE: 67 | printf("closure(function)"); 68 | break; 69 | case OT_NATIVECLOSURE: 70 | printf("native closure(C function)"); 71 | break; 72 | case OT_GENERATOR: 73 | printf("generator"); 74 | break; 75 | case OT_USERPOINTER: 76 | printf("userpointer"); 77 | break; 78 | case OT_CLASS: 79 | printf("class"); 80 | break; 81 | case OT_INSTANCE: 82 | printf("instance"); 83 | break; 84 | case OT_WEAKREF: 85 | printf("weak reference"); 86 | break; 87 | default: 88 | return sq_throwerror(v,"invalid param"); //throws an exception 89 | } 90 | } 91 | printf("\n"); 92 | sq_pushinteger(v,nargs); //push the number of arguments as return value 93 | return 1; //1 because 1 value is returned 94 | } 95 | 96 | Here an example of how to register a function:: 97 | 98 | SQInteger register_global_func(HSQUIRRELVM v,SQFUNCTION f,const char *fname) 99 | { 100 | sq_pushroottable(v); 101 | sq_pushstring(v,fname,-1); 102 | sq_newclosure(v,f,0); //create a new function 103 | sq_newslot(v,-3,SQFalse); 104 | sq_pop(v,1); //pops the root table 105 | return 0; 106 | } 107 | -------------------------------------------------------------------------------- /doc/source/reference/embedding/debug_interface.rst: -------------------------------------------------------------------------------- 1 | .. _embedding_debug_interface: 2 | 3 | =============== 4 | Debug Interface 5 | =============== 6 | 7 | The squirrel VM exposes a very simple debug interface that allows to easily built a full 8 | featured debugger. 9 | Through the functions sq_setdebughook and sq_setnativedebughook is possible in fact to set a callback function that 10 | will be called every time the VM executes an new line of a script or if a function get 11 | called/returns. The callback will pass as argument the current line the current source and the 12 | current function name (if any).:: 13 | 14 | SQUIRREL_API void sq_setdebughook(HSQUIRRELVM v); 15 | 16 | or :: 17 | 18 | SQUIRREL_API void sq_setnativedebughook(HSQUIRRELVM v,SQDEBUGHOOK hook); 19 | 20 | The following code shows how a debug hook could look like(obviously is possible to 21 | implement this function in C as well). :: 22 | 23 | function debughook(event_type,sourcefile,line,funcname) 24 | { 25 | local fname=funcname?funcname:"unknown"; 26 | local srcfile=sourcefile?sourcefile:"unknown" 27 | switch (event_type) { 28 | case 'l': //called every line(that contains some code) 29 | ::print("LINE line [" + line + "] func [" + fname + "]"); 30 | ::print("file [" + srcfile + "]\n"); 31 | break; 32 | case 'c': //called when a function has been called 33 | ::print("LINE line [" + line + "] func [" + fname + "]"); 34 | ::print("file [" + srcfile + "]\n"); 35 | break; 36 | case 'r': //called when a function returns 37 | ::print("LINE line [" + line + "] func [" + fname + "]"); 38 | ::print("file [" + srcfile + "]\n"); 39 | break; 40 | } 41 | } 42 | 43 | The parameter *event_type* can be 'l' ,'c' or 'r' ; a hook with a 'l' event is called for each line that 44 | gets executed, 'c' every time a function gets called and 'r' every time a function returns. 45 | 46 | A full-featured debugger always allows displaying local variables and calls stack. 47 | The call stack information are retrieved through sq_getstackinfos():: 48 | 49 | SQInteger sq_stackinfos(HSQUIRRELVM v,SQInteger level,SQStackInfos *si); 50 | 51 | While the local variables info through sq_getlocal():: 52 | 53 | SQInteger sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger nseq); 54 | 55 | In order to receive line callbacks the scripts have to be compiled with debug infos enabled 56 | this is done through sq_enabledebuginfo(); :: 57 | 58 | void sq_enabledebuginfo(HSQUIRRELVM v, SQInteger debuginfo); 59 | -------------------------------------------------------------------------------- /doc/source/reference/embedding/error_conventions.rst: -------------------------------------------------------------------------------- 1 | .. _embedding_error_convetions: 2 | 3 | 4 | ======================== 5 | Error Conventions 6 | ======================== 7 | 8 | .. index:: 9 | single: Error Conventions 10 | 11 | Most of the functions in the API return a SQRESULT value; SQRESULT indicates if a 12 | function completed successfully or not. 13 | The macros SQ_SUCCEEDED() and SQ_FAILED() are used to test the result of a function.:: 14 | 15 | if(SQ_FAILED(sq_getstring(v,-1,&s))) 16 | printf("getstring failed"); 17 | -------------------------------------------------------------------------------- /doc/source/reference/embedding/memory_management.rst: -------------------------------------------------------------------------------- 1 | .. _embedding_memory_management: 2 | 3 | ======================== 4 | Memory Management 5 | ======================== 6 | 7 | .. index:: single: Memory Management 8 | 9 | Squirrel uses reference counting (RC) as primary system for memory management; 10 | however, the virtual machine (VM) has an auxiliary 11 | mark and sweep garbage collector that can be invoked on demand. 12 | 13 | There are 2 possible compile time options: 14 | 15 | * The default configuration consists in RC plus a mark and sweep garbage collector. 16 | The host program can call the function sq_collectgarbage() and perform a garbage collection cycle 17 | during the program execution. The garbage collector isn't invoked by the VM and has to 18 | be explicitly called by the host program. 19 | 20 | * The second a situation consists in RC only(define NO_GARBAGE_COLLECTOR); in this case is impossible for 21 | the VM to detect reference cycles, so is the programmer that has to solve them explicitly in order to 22 | avoid memory leaks. 23 | 24 | The only advantage introduced by the second option is that saves 2 additional 25 | pointers that have to be stored for each object in the default configuration with 26 | garbage collector(8 bytes for 32 bits systems). 27 | The types involved are: tables, arrays, functions, threads, userdata and generators; all other 28 | types are untouched. These options do not affect execution speed. 29 | -------------------------------------------------------------------------------- /doc/source/reference/embedding/references_from_c.rst: -------------------------------------------------------------------------------- 1 | .. embedding_references_from_c: 2 | 3 | ======================================================== 4 | Mantaining references to Squirrel values from the C API 5 | ======================================================== 6 | 7 | Squirrel allows to reference values through the C API; the function sq_getstackobj() gets 8 | a handle to a squirrel object(any type). The object handle can be used to control the lifetime 9 | of an object by adding or removing references to it( see sq_addref() and sq_release()). 10 | The object can be also re-pushed in the VM stack using sq_pushobject().:: 11 | 12 | HSQOBJECT obj; 13 | 14 | sq_resetobject(&obj); //initialize the handle 15 | sq_getstackobj(v,-2,&obj); //retrieve an object handle from the pos -2 16 | sq_addref(v,&obj); //adds a reference to the object 17 | 18 | ... //do stuff 19 | 20 | sq_pushobject(v,obj); //push the object in the stack 21 | sq_release(v,&obj); //relese the object 22 | -------------------------------------------------------------------------------- /doc/source/reference/embedding/runtime_error_handling.rst: -------------------------------------------------------------------------------- 1 | .. _embedding_runtime_error_handling: 2 | 3 | ====================== 4 | Runtime error handling 5 | ====================== 6 | 7 | When an exception is not handled by Squirrel code with a try/catch statement, a runtime 8 | error is raised and the execution of the current program is interrupted. It is possible to 9 | set a call back function to intercept the runtime error from the host program; this is 10 | useful to show meaningful errors to the script writer and for implementing visual 11 | debuggers. 12 | The following API call pops a Squirrel function from the stack and sets it as error handler.:: 13 | 14 | SQUIRREL_API void sq_seterrorhandler(HSQUIRRELVM v); 15 | 16 | The error handler is called with 2 parameters, an environment object (this) and a object. 17 | The object can be any squirrel type. 18 | -------------------------------------------------------------------------------- /doc/source/reference/embedding/tables_and_arrays_manipulation.rst: -------------------------------------------------------------------------------- 1 | .. _embedding_tables_and_arrays_manipulation: 2 | 3 | ============================== 4 | Tables and arrays manipulation 5 | ============================== 6 | 7 | A new table is created calling sq_newtable, this function pushes a new table in the stack.:: 8 | 9 | void sq_newtable(HSQUIRRELVM v); 10 | 11 | To create a new slot:: 12 | 13 | SQRESULT sq_newslot(HSQUIRRELVM v,SQInteger idx,SQBool bstatic); 14 | 15 | To set or get the table delegate:: 16 | 17 | SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx); 18 | SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx); 19 | 20 | 21 | A new array is created calling sq_newarray, the function pushes a new array in the 22 | stack; if the parameters size is bigger than 0 the elements are initialized to null.:: 23 | 24 | void sq_newarray (HSQUIRRELVM v,SQInteger size); 25 | 26 | To append a value to the back of the array:: 27 | 28 | SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx); 29 | 30 | To remove a value from the back of the array:: 31 | 32 | SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQInteger pushval); 33 | 34 | To resize the array:: 35 | 36 | SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize); 37 | 38 | To retrieve the size of a table or an array you must use sq_getsize():: 39 | 40 | SQInteger sq_getsize(HSQUIRRELVM v,SQInteger idx); 41 | 42 | To set a value in an array or table:: 43 | 44 | SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx); 45 | 46 | To get a value from an array or table:: 47 | 48 | SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx); 49 | 50 | To get or set a value from a table without employing delegation:: 51 | 52 | SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx); 53 | SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx); 54 | 55 | To iterate a table or an array:: 56 | 57 | SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx); 58 | 59 | Here an example of how to perform an iteration: :: 60 | 61 | //push your table/array here 62 | sq_pushnull(v) //null iterator 63 | while(SQ_SUCCEEDED(sq_next(v,-2))) 64 | { 65 | //here -1 is the value and -2 is the key 66 | 67 | sq_pop(v,2); //pops key and val before the nex iteration 68 | } 69 | 70 | sq_pop(v,1); //pops the null iterator 71 | -------------------------------------------------------------------------------- /doc/source/reference/embedding/the_registry_table.rst: -------------------------------------------------------------------------------- 1 | .. _embedding_the_registry_table: 2 | 3 | ================== 4 | The registry table 5 | ================== 6 | 7 | The registry table is an hidden table shared between vm and all his thread(friend vms). 8 | This table is accessible only through the C API and is meant to be an utility structure 9 | for native C library implementation. 10 | For instance the sqstdlib(squirrel standard library)uses it to store configuration and shared objects 11 | delegates. 12 | The registry is accessible through the API call *sq_pushregistrytable()*.:: 13 | 14 | void sq_pushregistrytable(HSQUIRRELVM v); 15 | -------------------------------------------------------------------------------- /doc/source/reference/embedding/the_stack.rst: -------------------------------------------------------------------------------- 1 | .. _embedding_the_stack: 2 | 3 | 4 | ========== 5 | The Stack 6 | ========== 7 | 8 | Squirrel exchanges values with the virtual machine through a stack. This mechanism has 9 | been inherited from the language Lua. 10 | For instance to call a Squirrel function from C it is necessary to push the function and the 11 | arguments in the stack and then invoke the function; also when Squirrel calls a C 12 | function the parameters will be in the stack as well. 13 | 14 | ------------- 15 | Stack indexes 16 | ------------- 17 | 18 | Many API functions can arbitrarily refer to any element in the stack through an index. 19 | The stack indexes follow those conventions: 20 | 21 | * 1 is the stack base 22 | * Negative indexes are considered an offset from top of the stack. For instance -1 isthe top of the stack. 23 | * 0 is an invalid index 24 | 25 | Here an example (let's pretend that this table is the VM stack) 26 | 27 | +------------+--------------------+--------------------+ 28 | | **STACK** | **positive index** | **negative index** | 29 | +============+====================+====================+ 30 | | "test" | 4 | -1(top) | 31 | +------------+--------------------+--------------------+ 32 | | 1 | 3 | -2 | 33 | +------------+--------------------+--------------------+ 34 | | 0.5 | 2 | -3 | 35 | +------------+--------------------+--------------------+ 36 | | "foo" | 1(base) | -4 | 37 | +------------+--------------------+--------------------+ 38 | 39 | In this case, the function *sq_gettop* would return 4; 40 | 41 | ------------------ 42 | Stack manipulation 43 | ------------------ 44 | 45 | The API offers several functions to push and retrieve data from the Squirrel stack. 46 | 47 | To push a value that is already present in the stack in the top position:: 48 | 49 | void sq_push(HSQUIRRELVM v,SQInteger idx); 50 | 51 | To pop an arbitrary number of elements:: 52 | 53 | void sq_pop(HSQUIRRELVM v,SQInteger nelemstopop); 54 | 55 | To remove an element from the stack:: 56 | 57 | void sq_remove(HSQUIRRELVM v,SQInteger idx); 58 | 59 | To retrieve the top index (and size) of the current 60 | virtual stack you must call *sq_gettop* :: 61 | 62 | SQInteger sq_gettop(HSQUIRRELVM v); 63 | 64 | To force the stack to a certain size you can call *sq_settop* :: 65 | 66 | void sq_settop(HSQUIRRELVM v,SQInteger newtop); 67 | 68 | If the newtop is bigger than the previous one, the new positions in the stack will be 69 | filled with null values. 70 | 71 | The following function pushes a C value into the stack:: 72 | 73 | void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len); 74 | void sq_pushfloat(HSQUIRRELVM v,SQFloat f); 75 | void sq_pushinteger(HSQUIRRELVM v,SQInteger n); 76 | void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p); 77 | void sq_pushbool(HSQUIRRELVM v,SQBool b); 78 | 79 | this function pushes a null into the stack:: 80 | 81 | void sq_pushnull(HSQUIRRELVM v); 82 | 83 | returns the type of the value in a arbitrary position in the stack:: 84 | 85 | SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx); 86 | 87 | the result can be one of the following values: :: 88 | 89 | OT_NULL,OT_INTEGER,OT_FLOAT,OT_STRING,OT_TABLE,OT_ARRAY,OT_USERDATA, 90 | OT_CLOSURE,OT_NATIVECLOSURE,OT_GENERATOR,OT_USERPOINTER,OT_BOOL,OT_INSTANCE,OT_CLASS,OT_WEAKREF 91 | 92 | The following functions convert a squirrel value in the stack to a C value:: 93 | 94 | SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c); 95 | SQRESULT sq_getstringandsize(HSQUIRRELVM v,SQInteger idx,const SQChar **c,SQInteger size); 96 | SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i); 97 | SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f); 98 | SQRESULT sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p); 99 | SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag); 100 | SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *p); 101 | 102 | The function sq_cmp compares 2 values from the stack and returns their relation (like strcmp() in ANSI C).:: 103 | 104 | SQInteger sq_cmp(HSQUIRRELVM v); 105 | -------------------------------------------------------------------------------- /doc/source/reference/embedding/userdata_and_userpointers.rst: -------------------------------------------------------------------------------- 1 | .. _embedding_userdata_and_userpointers: 2 | 3 | ========================= 4 | Userdata and UserPointers 5 | ========================= 6 | 7 | Squirrel allows the host application put arbitrary data chunks into a Squirrel value, this is 8 | possible through the data type userdata.:: 9 | 10 | SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size); 11 | 12 | When the function *sq_newuserdata* is called, Squirrel allocates a new userdata with the 13 | specified size, returns a pointer to his payload buffer and push the object in the stack; at 14 | this point the application can do whatever it want with this memory chunk, the VM will 15 | automatically take cake of the memory deallocation like for every other built-in type. 16 | A userdata can be passed to a function or stored in a table slot. By default Squirrel 17 | cannot manipulate directly userdata; however is possible to assign a delegate to it and 18 | define a behavior like it would be a table. 19 | Because the application would want to do something with the data stored in a userdata 20 | object when it get deleted, is possible to assign a callback that will be called by the VM 21 | just before deleting a certain userdata. 22 | This is done through the API call *sq_setreleasehook*.:: 23 | 24 | typedef SQInteger (*SQRELEASEHOOK)(SQUserPointer,SQInteger size); 25 | 26 | void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook); 27 | 28 | Another kind of userdata is the userpointer; this type is not a memory chunk like the 29 | normal userdata, but just a 'void*' pointer. It cannot have a delegate and is passed by 30 | value, so pushing a userpointer doesn't cause any memory allocation.:: 31 | 32 | void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p); 33 | 34 | -------------------------------------------------------------------------------- /doc/source/reference/embedding/vm_initialization.rst: -------------------------------------------------------------------------------- 1 | .. _embedding_vm_initialization: 2 | 3 | ============================== 4 | Virtual Machine Initialization 5 | ============================== 6 | 7 | The first thing that a host application has to do, is create a virtual machine. 8 | The host application can create any number of virtual machines through the function 9 | *sq_open()*. 10 | Every single VM that was created using *sq_open()* has to be released with the function *sq_close()* when it is no 11 | longer needed.:: 12 | 13 | int main(int argc, char* argv[]) 14 | { 15 | HSQUIRRELVM v; 16 | v = sq_open(1024); //creates a VM with initial stack size 1024 17 | 18 | //do some stuff with squirrel here 19 | 20 | sq_close(v); 21 | } 22 | -------------------------------------------------------------------------------- /doc/source/reference/embedding_squirrel.rst: -------------------------------------------------------------------------------- 1 | .. _embedding_squirrel: 2 | 3 | *************************** 4 | Embedding Squirrel 5 | *************************** 6 | 7 | *This section describes how to embed Squirrel in a host application, 8 | C language knowledge is required to understand this part of the manual.* 9 | 10 | Because of his nature of extension language, Squirrel's compiler and virtual machine 11 | are implemented as C library. The library exposes a set of functions to compile scripts, 12 | call functions, manipulate data and extend the virtual machine. 13 | All declarations needed for embedding the language in an application are in the header file 'squirrel.h'. 14 | 15 | .. toctree:: 16 | embedding/memory_management.rst 17 | embedding/build_configuration.rst 18 | embedding/error_conventions.rst 19 | embedding/vm_initialization.rst 20 | embedding/the_stack.rst 21 | embedding/runtime_error_handling.rst 22 | embedding/compiling_a_script.rst 23 | embedding/calling_a_function.rst 24 | embedding/creating_a_c_function.rst 25 | embedding/tables_and_arrays_manipulation.rst 26 | embedding/userdata_and_userpointers.rst 27 | embedding/the_registry_table.rst 28 | embedding/references_from_c.rst 29 | embedding/debug_interface.rst 30 | -------------------------------------------------------------------------------- /doc/source/reference/index.rst: -------------------------------------------------------------------------------- 1 | .. _reference: 2 | 3 | ################################# 4 | Squirrel 3.2 Reference Manual 5 | ################################# 6 | 7 | Copyright (c) 2003-2022 Alberto Demichelis 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in 17 | all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | THE SOFTWARE. 26 | 27 | .. toctree:: 28 | :maxdepth: 3 29 | :numbered: 30 | 31 | introduction.rst 32 | language.rst 33 | embedding_squirrel.rst 34 | api_reference.rst 35 | -------------------------------------------------------------------------------- /doc/source/reference/introduction.rst: -------------------------------------------------------------------------------- 1 | .. _introduction: 2 | 3 | ************ 4 | Introduction 5 | ************ 6 | 7 | .. index:: 8 | single: introduction 9 | 10 | Squirrel is a high-level, imperative-OO programming language, designed to be a powerful 11 | scripting tool that fits within the size, memory bandwidth, and real-time requirements of 12 | applications like games. 13 | Squirrel offers a wide range of features like dynamic typing, delegation, higher 14 | order functions, generators, tail recursion, exception handling, automatic memory 15 | management while fitting both compiler and virtual machine into about 6k lines of C++ 16 | code. 17 | -------------------------------------------------------------------------------- /doc/source/reference/language.rst: -------------------------------------------------------------------------------- 1 | .. _thelanguage: 2 | 3 | *************************** 4 | The language 5 | *************************** 6 | 7 | .. toctree:: 8 | language/lexical_structure.rst 9 | language/datatypes.rst 10 | language/execution_context.rst 11 | language/statements.rst 12 | language/expressions.rst 13 | language/tables.rst 14 | language/arrays.rst 15 | language/functions.rst 16 | language/classes.rst 17 | language/generators.rst 18 | language/constants_and_enumerations.rst 19 | language/threads.rst 20 | language/weak_references.rst 21 | language/delegation.rst 22 | language/metamethods.rst 23 | language/builtin_functions.rst 24 | -------------------------------------------------------------------------------- /doc/source/reference/language/arrays.rst: -------------------------------------------------------------------------------- 1 | .. _arrays: 2 | 3 | 4 | ================= 5 | Arrays 6 | ================= 7 | 8 | .. index:: 9 | single: Arrays 10 | 11 | An array is a sequence of values indexed by a integer number from 0 to the size of the 12 | array minus 1. Arrays elements can be obtained through their index.:: 13 | 14 | local a=["I'm a string", 123] 15 | print(typeof a[0]) //prints "string" 16 | print(typeof a[1]) //prints "integer" 17 | 18 | Resizing, insertion, deletion of arrays and arrays elements is done through a set of 19 | standard functions (see :ref:`built-in functions `). 20 | -------------------------------------------------------------------------------- /doc/source/reference/language/constants_and_enumerations.rst: -------------------------------------------------------------------------------- 1 | .. _constants_and_enumerations: 2 | 3 | 4 | ======================== 5 | Constants & Enumerations 6 | ======================== 7 | 8 | .. index:: 9 | single: Constants & Enumerations 10 | 11 | 12 | 13 | Squirrel allows to bind constant values to an identifier that will be evaluated compile-time. 14 | This is achieved though constants and Enumerations. 15 | 16 | --------------- 17 | Constants 18 | --------------- 19 | 20 | .. index:: 21 | single: Constants 22 | 23 | Constants bind a specific value to an identifier. Constants are similar to 24 | global values, except that they are evaluated compile time and their value cannot be changed. 25 | 26 | constants values can only be integers, floats or string literals. No expression are allowed. 27 | are declared with the following syntax.:: 28 | 29 | const foobar = 100; 30 | const floatbar = 1.2; 31 | const stringbar = "I'm a constant string"; 32 | 33 | constants are always globally scoped, from the moment they are declared, any following code 34 | can reference them. 35 | Constants will shadow any global slot with the same name( the global slot will remain visible by using the ``::`` syntax).:: 36 | 37 | local x = foobar * 2; 38 | 39 | --------------- 40 | Enumerations 41 | --------------- 42 | 43 | .. index:: 44 | single: Enumerations 45 | 46 | As Constants, Enumerations bind a specific value to a name. Enumerations are also evaluated at compile time 47 | and their value cannot be changed. 48 | 49 | An enum declaration introduces a new enumeration into the program. 50 | Enumeration values can only be integers, floats or string literals. No expression are allowed.:: 51 | 52 | enum Stuff { 53 | first, //this will be 0 54 | second, //this will be 1 55 | third //this will be 2 56 | } 57 | 58 | or:: 59 | 60 | enum Stuff { 61 | first = 10 62 | second = "string" 63 | third = 1.2 64 | } 65 | 66 | An enum value is accessed in a manner that's similar to accessing a static class member. 67 | The name of the member must be qualified with the name of the enumeration, for example ``Stuff.second`` 68 | Enumerations will shadow any global slot with the same name( the global slot will remain visible by using the ``::`` syntax).:: 69 | 70 | local x = Stuff.first * 2; 71 | 72 | -------------------- 73 | Implementation notes 74 | -------------------- 75 | 76 | Enumerations and Constants are a compile-time feature. Only integers, string and floats can be declared as const/enum; 77 | No expressions are allowed(because they would have to be evaluated compile time). 78 | When a const or an enum is declared, it is added compile time to the ``consttable``. This table is stored in the VM shared state 79 | and is shared by the VM and all its threads. 80 | The ``consttable`` is a regular squirrel table; In the same way as the ``roottable`` 81 | it can be modified runtime. 82 | You can access the ``consttable`` through the built-in function ``getconsttable()`` 83 | and also change it through the built-in function ``setconsttable()`` 84 | 85 | here some example: :: 86 | 87 | //creates a constant 88 | getconsttable()["something"] <- 10" 89 | //creates an enumeration 90 | getconsttable()["somethingelse"] <- { a = "10", c = "20", d = "200"}; 91 | //deletes the constant 92 | delete getconsttable()["something"] 93 | //deletes the enumeration 94 | delete getconsttable()["somethingelse"] 95 | 96 | This system allows to procedurally declare constants and enumerations, it is also possible to assign any squirrel type 97 | to a constant/enumeration(function,classes etc...). However this will make serialization of a code chunk impossible. 98 | -------------------------------------------------------------------------------- /doc/source/reference/language/datatypes.rst: -------------------------------------------------------------------------------- 1 | .. _datatypes_and_values: 2 | 3 | ===================== 4 | Values and Data types 5 | ===================== 6 | 7 | While Squirrel is a dynamically typed language and variables do not 8 | have a type, different operations may interpret the variable as 9 | containing a type. Squirrel's basic types are integer, float, string, 10 | null, table, array, function, generator, class, instance, bool, thread 11 | and userdata. 12 | 13 | .. _userdata-index: 14 | 15 | -------- 16 | Integer 17 | -------- 18 | 19 | An Integer represents a 32 bit (or better) signed number.:: 20 | 21 | local a = 123 //decimal 22 | local b = 0x0012 //hexadecimal 23 | local c = 075 //octal 24 | local d = 'w' //char code 25 | 26 | -------- 27 | Float 28 | -------- 29 | 30 | A float represents a 32 bit (or better) floating point number.:: 31 | 32 | local a=1.0 33 | local b=0.234 34 | 35 | -------- 36 | String 37 | -------- 38 | 39 | Strings are an immutable sequence of characters. In order to modify a 40 | string is it necessary create a new one. 41 | 42 | Squirrel's strings are similar to strings in C or C++. They are 43 | delimited by quotation marks(``"``) and can contain escape 44 | sequences (``\t``, ``\a``, ``\b``, ``\n``, ``\r``, ``\v``, ``\f``, 45 | ``\\``, ``\"``, ``\'``, ``\0``, ``\x``, ``\u`` and 46 | ``\U``). 47 | 48 | Verbatim string literals do not interpret escape sequences. They begin 49 | with ``@"`` and end with the matching quote. Verbatim string literals 50 | also can extend over a line break. If they do, they include any white 51 | space characters between the quotes: :: 52 | 53 | local a = "I'm a wonderful string\n" 54 | // has a newline at the end of the string 55 | local x = @"I'm a verbatim string\n" 56 | // the \n is literal, similar to "\\n" in a regular string. 57 | 58 | However, a doubled quotation mark within a verbatim string is replaced 59 | by a single quotation mark: :: 60 | 61 | local multiline = @" 62 | this is a multiline string 63 | it will ""embed"" all the new line 64 | characters 65 | " 66 | 67 | -------- 68 | Null 69 | -------- 70 | 71 | The null value is a primitive value that represents the null, empty, or non-existent 72 | reference. The type Null has exactly one value, called null.:: 73 | 74 | local a = null 75 | 76 | -------- 77 | Bool 78 | -------- 79 | 80 | Bool is a double-valued (Boolean) data type. Its literals are ``true`` 81 | and ``false``. A bool value expresses the validity of a condition 82 | (tells whether the condition is true or false).:: 83 | 84 | local a = true; 85 | 86 | -------- 87 | Table 88 | -------- 89 | 90 | Tables are associative containers implemented as a set of key/value pairs 91 | called slots.:: 92 | 93 | local t={} 94 | local test= 95 | { 96 | a=10 97 | b=function(a) { return a+1; } 98 | } 99 | 100 | -------- 101 | Array 102 | -------- 103 | 104 | Arrays are simple sequence of objects. Their size is dynamic and their index always starts from 0.:: 105 | 106 | local a = ["I'm","an","array"] 107 | local b = [null] 108 | b[0] = a[2]; 109 | 110 | -------- 111 | Function 112 | -------- 113 | 114 | Functions are similar to those in other C-like languages with a few key differences (see below). 115 | 116 | -------- 117 | Class 118 | -------- 119 | 120 | Classes are associative containers implemented as sets of key/value 121 | pairs. Classes are created through a 'class expression' or a 'class 122 | statement'. class members can be inherited from another class object 123 | at creation time. After creation, members can be added until an 124 | instance of the class is created. 125 | 126 | -------------- 127 | Class Instance 128 | -------------- 129 | 130 | Class instances are created by calling a *class object*. Instances, as 131 | tables, are implemented as sets of key/value pairs. Instance members 132 | cannot be dynamically added or removed; however the value of the 133 | members can be changed. 134 | 135 | --------- 136 | Generator 137 | --------- 138 | 139 | Generators are functions that can be suspended with the statement 140 | 'yield' and resumed later (see :ref:`Generators `). 141 | 142 | --------- 143 | Userdata 144 | --------- 145 | 146 | Userdata objects are blobs of memory or pointers defined by the host 147 | application but stored within Squirrel variables (See :ref:`Userdata 148 | and UserPointers `). 149 | 150 | --------- 151 | Thread 152 | --------- 153 | 154 | Threads are objects representing a cooperative thread of execution, 155 | also known as coroutines. 156 | 157 | -------------- 158 | Weak Reference 159 | -------------- 160 | 161 | Weak References are objects that point to another (non-scalar) object but do not own a strong reference to it. 162 | (See :ref:`Weak References `). 163 | -------------------------------------------------------------------------------- /doc/source/reference/language/delegation.rst: -------------------------------------------------------------------------------- 1 | .. _delegation: 2 | 3 | 4 | ======================== 5 | Delegation 6 | ======================== 7 | 8 | .. index:: 9 | single: Delegation 10 | 11 | Squirrel supports implicit delegation. Every table or userdata can have a parent table 12 | (delegate). A parent table is a normal table that allows the definition of special behaviors 13 | for his child. 14 | When a table (or userdata) is indexed with a key that doesn't correspond to one of its 15 | slots, the interpreter automatically delegates the get (or set) operation to its parent.:: 16 | 17 | Entity <- { 18 | } 19 | 20 | function Entity::DoStuff() 21 | { 22 | ::print(_name); 23 | } 24 | 25 | local newentity = { 26 | _name="I'm the new entity" 27 | } 28 | newentity.setdelegate(Entity) 29 | 30 | newentity.DoStuff(); //prints "I'm the new entity" 31 | 32 | The delegate of a table can be retreived through built-in method ``table.getdelegate()``.:: 33 | 34 | local thedelegate = newentity.getdelegate(); 35 | 36 | -------------------------------------------------------------------------------- /doc/source/reference/language/execution_context.rst: -------------------------------------------------------------------------------- 1 | .. _executioncontext: 2 | 3 | ======================= 4 | Execution Context 5 | ======================= 6 | 7 | .. index:: 8 | single: execution context 9 | 10 | The execution context is the union of the function stack frame and the function 11 | environment object(this) and the function root(root table). 12 | The stack frame is the portion of stack where the local variables declared in its body are 13 | stored. 14 | The environment object is an implicit parameter that is automatically passed by the 15 | function caller (see see :ref:`functions `). 16 | The root table is a table associated to the function during its creation. 17 | The root table value of a function is the root table of the VM at the function creation. 18 | The root table of function can also be changed after creation with closure.setroot(). 19 | During the execution, the body of a function can only transparently refer to his execution 20 | context. 21 | This mean that a single identifier can refer to a local variable, to an environment object slot 22 | or to the slot of the closure root table; 23 | The environment object can be explicitly accessed by the keyword ``this``. 24 | The closure root table can be explicitly accessed through the operator ``::`` (see :ref:`Variables `). 25 | 26 | .. _variables: 27 | 28 | ----------------- 29 | Variables 30 | ----------------- 31 | 32 | There are two types of variables in Squirrel, local variables and tables/arrays slots. 33 | Because global variables(variables stored in the root of a closure) are stored in a table, they are table slots. 34 | 35 | A single identifier refers to a local variable or a slot in the environment object.:: 36 | 37 | derefexp := id; 38 | 39 | :: 40 | 41 | _table["foo"] 42 | _array[10] 43 | 44 | with tables we can also use the '.' syntax:: 45 | 46 | derefexp := exp '.' id 47 | 48 | :: 49 | 50 | _table.foo 51 | 52 | Squirrel first checks if an identifier is a local variable (function arguments are local 53 | variables) if not looks up the environment object (this) and finally looks up 54 | to the closure root. 55 | 56 | For instance::: 57 | 58 | function testy(arg) 59 | { 60 | local a=10; 61 | print(a); 62 | return arg; 63 | } 64 | 65 | in this case 'foo' will be equivalent to 'this.foo' or this["foo"]. 66 | 67 | Global variables are stored in a table called the root table. Usually in the global scope the 68 | environment object is the root table, but to explicitly access the closure root of the function from 69 | another scope, the slot name must be prefixed with ``'::'`` (``::foo``). 70 | 71 | For instance::: 72 | 73 | function testy(arg) 74 | { 75 | local a=10; 76 | return arg+::foo; 77 | } 78 | 79 | accesses the variable 'foo' in the closure root table. 80 | 81 | Since Squirrel 3.1 each function has a weak reference to a specific root table, this can differ from the current VM root table.:: 82 | 83 | function test() { 84 | foo = 10; 85 | } 86 | 87 | is equivalent to write:: 88 | 89 | function test() { 90 | if("foo" in this) { 91 | this.foo = 10; 92 | }else { 93 | ::foo = 10; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /doc/source/reference/language/generators.rst: -------------------------------------------------------------------------------- 1 | .. _generators: 2 | 3 | 4 | ================= 5 | Generators 6 | ================= 7 | 8 | .. index:: 9 | single: Generators 10 | 11 | A function that contains a ``yield`` statement is called *'generator function'* . 12 | When a generator function is called, it does not execute the function body, instead it 13 | returns a new suspended generator. 14 | The returned generator can be resumed through the resume statement while it is alive. 15 | The yield keyword, suspends the execution of a generator and optionally returns the 16 | result of an expression to the function that resumed the generator. 17 | The generator dies when it returns, this can happen through an explicit return 18 | statement or by exiting the function body; If an unhandled exception (or runtime error) 19 | occurs while a generator is running, the generator will automatically die. A dead 20 | generator cannot be resumed anymore.:: 21 | 22 | function geny(n) 23 | { 24 | for(local i=1;i<=n;i+=1) 25 | yield i; 26 | return null; 27 | } 28 | 29 | local gtor=geny(10); 30 | local x; 31 | while(x=resume gtor) print(x+"\n"); 32 | 33 | the output of this program will be:: 34 | 35 | 1 36 | 2 37 | 3 38 | 4 39 | 5 40 | 6 41 | 7 42 | 8 43 | 9 44 | 10 45 | 46 | generators can also be iterated using the foreach statement. When a generator is evaluated 47 | by ``foreach``, the generator will be resumed for each iteration until it returns. The value 48 | returned by the ``return`` statement will be ignored. 49 | 50 | .. note:: A suspended generator will hold a strong reference to all the values stored in it's local variables except the ``this`` 51 | object that is only a weak reference. A running generator hold a strong reference also to the ``this`` object. 52 | -------------------------------------------------------------------------------- /doc/source/reference/language/metamethods.rst: -------------------------------------------------------------------------------- 1 | .. _metamethods: 2 | 3 | ----------- 4 | Metamethods 5 | ----------- 6 | 7 | Metamethods are a mechanism that allows the customization of certain aspects of the 8 | language semantics. Those methods are normal functions placed in a table 9 | parent(delegate) or class declaration; It is possible to change many aspects of a table/class instance behavior by just defining 10 | a metamethod. Class objects (not instances) support only 2 metamethods ``_newmember, _inherited`` . 11 | 12 | For example when we use relational operators other than '==' on 2 tables, the VM will 13 | check if the table has a method in his parent called '_cmp'; if so it will call it to determine 14 | the relation between the tables.:: 15 | 16 | local comparable={ 17 | _cmp = function (other) 18 | { 19 | if(nameother.name)return 1; 21 | return 0; 22 | } 23 | } 24 | 25 | local a={ name="Alberto" }.setdelegate(comparable); 26 | local b={ name="Wouter" }.setdelegate(comparable); 27 | 28 | if(a>b) 29 | print("a>b") 30 | else 31 | print("b<=a"); 32 | 33 | for classes the previous code become: :: 34 | 35 | class Comparable { 36 | constructor(n) 37 | { 38 | name = n; 39 | } 40 | function _cmp(other) 41 | { 42 | if(nameother.name) return 1; 44 | return 0; 45 | } 46 | name = null; 47 | } 48 | 49 | local a = Comparable("Alberto"); 50 | local b = Comparable("Wouter"); 51 | 52 | if(a>b) 53 | print("a>b") 54 | else 55 | print("b<=a"); 56 | 57 | ^^^^^ 58 | _set 59 | ^^^^^ 60 | 61 | :: 62 | 63 | _set(idx,val) 64 | 65 | invoked when the index idx is not present in the object or in its delegate chain. 66 | ``_set`` must 'throw null' to notify that a key wasn't found but the there were not runtime errors (clean failure). 67 | This allows the program to differentiate between a runtime error and a 'index not found'. 68 | 69 | ^^^^^ 70 | _get 71 | ^^^^^ 72 | 73 | :: 74 | 75 | _get(idx) 76 | 77 | invoked when the index idx is not present in the object or in its delegate chain. 78 | _get must 'throw null' to notify that a key wasn't found but the there were not runtime errors (clean failure). 79 | This allows the program to differentiate between a runtime error and a 'index not found'. 80 | 81 | ^^^^^^^^^ 82 | _newslot 83 | ^^^^^^^^^ 84 | 85 | :: 86 | 87 | _newslot(key,value) 88 | 89 | invoked when a script tries to add a new slot in a table. 90 | 91 | if the slot already exists in the target table the method will not be invoked also if the 92 | "new slot" operator is used. 93 | 94 | ^^^^^^^^^ 95 | _delslot 96 | ^^^^^^^^^ 97 | 98 | :: 99 | 100 | _delslot(key) 101 | 102 | invoked when a script deletes a slot from a table. 103 | if the method is invoked squirrel will not try to delete the slot himself 104 | 105 | ^^^^^^^^ 106 | _add 107 | ^^^^^^^^ 108 | 109 | :: 110 | 111 | _add(other) 112 | 113 | the + operator 114 | 115 | returns this + other 116 | 117 | ^^^^^^^^^^^^^^^^^^^^^^^^ 118 | _sub 119 | ^^^^^^^^^^^^^^^^^^^^^^^^ 120 | 121 | :: 122 | 123 | _sub(other) 124 | 125 | the - operator (like _add) 126 | 127 | ^^^^^^^^^^^^^^^^^^^^^^^^ 128 | _mul 129 | ^^^^^^^^^^^^^^^^^^^^^^^^ 130 | 131 | :: 132 | 133 | _mul(other) 134 | 135 | the ``*`` operator (like _add) 136 | 137 | ^^^^^^^^^^^^^^^^^^^^^^^^ 138 | _div 139 | ^^^^^^^^^^^^^^^^^^^^^^^^ 140 | 141 | :: 142 | 143 | _div(other) 144 | 145 | the ``/`` operator (like _add) 146 | 147 | ^^^^^^^^^^^^^^^^^^^^^^^^ 148 | _modulo 149 | ^^^^^^^^^^^^^^^^^^^^^^^^ 150 | 151 | :: 152 | 153 | _modulo(other) 154 | 155 | the ``%`` operator (like _add) 156 | 157 | ^^^^^^^^^ 158 | _unm 159 | ^^^^^^^^^ 160 | 161 | :: 162 | 163 | _unm() 164 | 165 | the unary minus operator 166 | 167 | ^^^^^^^^^^^^^^^^^^^^^^^^ 168 | _typeof 169 | ^^^^^^^^^^^^^^^^^^^^^^^^ 170 | 171 | :: 172 | 173 | _typeof() 174 | 175 | invoked by the typeof operator on tables, userdata, and class instances. 176 | 177 | Returns the type of ``this`` as string 178 | 179 | ^^^^^^^^^^^^^^^^^^^^^^^^ 180 | _cmp 181 | ^^^^^^^^^^^^^^^^^^^^^^^^ 182 | 183 | :: 184 | 185 | _cmp(other) 186 | 187 | invoked to emulate the ``< > <= >=`` and ``<=>`` operators 188 | 189 | returns an integer as follow: 190 | 191 | +-----------+----------------------------+ 192 | | returns | relationship | 193 | +===========+============================+ 194 | | > 0 | if ``this`` > ``other`` | 195 | +-----------+----------------------------+ 196 | | 0 | if ``this`` == ``other`` | 197 | +-----------+----------------------------+ 198 | | < 0 | if ``this`` < ``other`` | 199 | +-----------+----------------------------+ 200 | 201 | ^^^^^^^^^^^^^^^^^^^^^^^^ 202 | _call 203 | ^^^^^^^^^^^^^^^^^^^^^^^^ 204 | 205 | :: 206 | 207 | _call(other) 208 | 209 | invoked when a table, userdata, or class instance is called 210 | 211 | ^^^^^^^^^^^^^^^^^^^^^^^^ 212 | _cloned 213 | ^^^^^^^^^^^^^^^^^^^^^^^^ 214 | 215 | :: 216 | 217 | _cloned(original) 218 | 219 | invoked when a table or class instance is cloned(in the cloned table) 220 | 221 | ^^^^^^^^^^^^^^^^^^^^^^^^ 222 | _nexti 223 | ^^^^^^^^^^^^^^^^^^^^^^^^ 224 | 225 | :: 226 | 227 | _nexti(previdx) 228 | 229 | invoked when a userdata or class instance is iterated by a foreach loop. 230 | 231 | If previdx==null it means that it is the first iteration. 232 | The function has to return the index of the 'next' value. 233 | 234 | ^^^^^^^^^^^^^^^^^^^^^^^^ 235 | _tostring 236 | ^^^^^^^^^^^^^^^^^^^^^^^^ 237 | 238 | :: 239 | 240 | _tostring() 241 | 242 | Invoked when during string concatenation or when the ``print`` function prints a table, instance, or userdata. 243 | The method is also invoked by the sq_tostring() API. 244 | 245 | Must return a string representation of the object. 246 | 247 | ^^^^^^^^^^^^^^^^^^^^^^^^ 248 | _inherited 249 | ^^^^^^^^^^^^^^^^^^^^^^^^ 250 | 251 | :: 252 | 253 | _inherited(attributes) 254 | 255 | invoked when a class object inherits from the class implementing ``_inherited``. 256 | The ``this`` contains the new class. 257 | 258 | Return value is ignored. 259 | 260 | ^^^^^^^^^^^^^^^^^^^^^^^^ 261 | _newmember 262 | ^^^^^^^^^^^^^^^^^^^^^^^^ 263 | 264 | :: 265 | 266 | _newmember(index,value,attributes,isstatic) 267 | 268 | invoked for each member declared in a class body (at declaration time). 269 | 270 | If the function is implemented, members will not be added to the class. 271 | -------------------------------------------------------------------------------- /doc/source/reference/language/tables.rst: -------------------------------------------------------------------------------- 1 | .. _tables: 2 | 3 | 4 | ================= 5 | Tables 6 | ================= 7 | 8 | .. index:: 9 | single: Tables 10 | 11 | Tables are associative containers implemented as pairs of key/value (called slot); values 12 | can be any possible type and keys any type except 'null'. 13 | Tables are squirrel's skeleton, delegation and many other features are all implemented 14 | through this type; even the environment, where "global" variables are stored, is a table 15 | (known as root table). 16 | 17 | ------------------ 18 | Construction 19 | ------------------ 20 | 21 | Tables are created through the table constructor (see :ref:`Table constructor `) 22 | 23 | ------------------ 24 | Slot creation 25 | ------------------ 26 | 27 | .. index:: 28 | single: Slot Creation(table) 29 | 30 | Adding a new slot in a existing table is done through the "new slot" operator ``<-``; this 31 | operator behaves like a normal assignment except that if the slot does not exists it will 32 | be created.:: 33 | 34 | local a = {} 35 | 36 | The following line will cause an exception because the slot named 'newslot' does not exist 37 | in the table 'a':: 38 | 39 | a.newslot = 1234 40 | 41 | this will succeed: :: 42 | 43 | a.newslot <- 1234; 44 | 45 | or:: 46 | 47 | a[1] <- "I'm the value of the new slot"; 48 | 49 | ----------------- 50 | Slot deletion 51 | ----------------- 52 | 53 | .. index:: 54 | single: Slot Deletion(table) 55 | 56 | 57 | :: 58 | 59 | exp:= delete derefexp 60 | 61 | Deletion of a slot is done through the keyword delete; the result of this expression will be 62 | the value of the deleted slot.:: 63 | 64 | a <- { 65 | test1=1234 66 | deleteme="now" 67 | } 68 | 69 | delete a.test1 70 | print(delete a.deleteme); //this will print the string "now" 71 | 72 | -------------------------------------------------------------------------------- /doc/source/reference/language/threads.rst: -------------------------------------------------------------------------------- 1 | .. _threads: 2 | 3 | 4 | ======================== 5 | Threads 6 | ======================== 7 | 8 | .. index:: 9 | single: Threads 10 | 11 | Squirrel supports cooperative threads(also known as coroutines). 12 | A cooperative thread is a subroutine that can suspended in mid-execution and provide a value to the 13 | caller without returning program flow, then its execution can be resumed later from the same 14 | point where it was suspended. 15 | At first look a Squirrel thread can be confused with a generator, in fact their behaviour is quite similar. 16 | However while a generator runs in the caller stack and can suspend only the local routine stack a thread 17 | has its own execution stack, global table and error handler; This allows a thread to suspend nested calls and 18 | have it's own error policies. 19 | 20 | ------------------ 21 | Using threads 22 | ------------------ 23 | 24 | .. index:: 25 | single: Using Threads 26 | 27 | Threads are created through the built-in function 'newthread(func)'; this function 28 | gets as parameter a squirrel function and bind it to the new thread objects (will be the thread body). 29 | The returned thread object is initially in 'idle' state. the thread can be started with the function 30 | 'threadobj.call()'; the parameters passed to 'call' are passed to the thread function. 31 | 32 | A thread can be be suspended calling the function suspend(), when this happens the function 33 | that wokeup(or started) the thread returns (If a parameter is passed to suspend() it will 34 | be the return value of the wakeup function , if no parameter is passed the return value will be null). 35 | A suspended thread can be resumed calling the function 'threadobj.wakeup', when this happens 36 | the function that suspended the thread will return(if a parameter is passed to wakeup it will 37 | be the return value of the suspend function, if no parameter is passed the return value will be null). 38 | 39 | A thread terminates when its main function returns or when an unhandled exception occurs during its execution.:: 40 | 41 | function coroutine_test(a,b) 42 | { 43 | ::print(a+" "+b+"\n"); 44 | local ret = ::suspend("suspend 1"); 45 | ::print("the coroutine says "+ret+"\n"); 46 | ret = ::suspend("suspend 2"); 47 | ::print("the coroutine says "+ret+"\n"); 48 | ret = ::suspend("suspend 3"); 49 | ::print("the coroutine says "+ret+"\n"); 50 | return "I'm done" 51 | } 52 | 53 | local coro = ::newthread(coroutine_test); 54 | 55 | local susparam = coro.call("test","coroutine"); //starts the coroutine 56 | 57 | local i = 1; 58 | do 59 | { 60 | ::print("suspend passed ("+susparam+")\n") 61 | susparam = coro.wakeup("ciao "+i); 62 | ++i; 63 | }while(coro.getstatus()=="suspended") 64 | 65 | ::print("return passed ("+susparam+")\n") 66 | 67 | the result of this program will be:: 68 | 69 | test coroutine 70 | suspend passed (suspend 1) 71 | the coroutine says ciao 1 72 | suspend passed (suspend 2) 73 | the coroutine says ciao 2 74 | suspend passed (suspend 3) 75 | the coroutine says ciao 3 76 | return passed (I'm done). 77 | 78 | 79 | the following is an interesting example of how threads and tail recursion 80 | can be combined.:: 81 | 82 | function state1() 83 | { 84 | ::suspend("state1"); 85 | return state2(); //tail call 86 | } 87 | 88 | function state2() 89 | { 90 | ::suspend("state2"); 91 | return state3(); //tail call 92 | } 93 | 94 | function state3() 95 | { 96 | ::suspend("state3"); 97 | return state1(); //tail call 98 | } 99 | 100 | local statethread = ::newthread(state1) 101 | 102 | ::print(statethread.call()+"\n"); 103 | 104 | for(local i = 0; i < 10000; i++) 105 | ::print(statethread.wakeup()+"\n"); 106 | 107 | -------------------------------------------------------------------------------- /doc/source/reference/language/weak_references.rst: -------------------------------------------------------------------------------- 1 | .. _weak_references: 2 | 3 | 4 | ======================== 5 | Weak References 6 | ======================== 7 | 8 | .. index:: 9 | single: Weak References 10 | 11 | 12 | The weak references allows the programmers to create references to objects without 13 | influencing the lifetime of the object itself. 14 | In squirrel Weak references are first-class objects created through the built-in method obj.weakref(). 15 | All types except null implement the weakref() method; however in bools, integers, and floats the method 16 | simply returns the object itself(this because this types are always passed by value). 17 | When a weak references is assigned to a container (table slot,array,class or 18 | instance) is treated differently than other objects; When a container slot that hold a weak 19 | reference is fetched, it always returns the value pointed by the weak reference instead of the weak 20 | reference object. This allow the programmer to ignore the fact that the value handled is weak. 21 | When the object pointed by weak reference is destroyed, the weak reference is automatically set to null.:: 22 | 23 | local t = {} 24 | local a = ["first","second","third"] 25 | //creates a weakref to the array and assigns it to a table slot 26 | t.thearray <- a.weakref(); 27 | 28 | The table slot 'thearray' contains a weak reference to an array. 29 | The following line prints "first", because tables(and all other containers) always return 30 | the object pointed by a weak ref:: 31 | 32 | print(t.thearray[0]); 33 | 34 | the only strong reference to the array is owned by the local variable 'a', so 35 | because the following line assigns a integer to 'a' the array is destroyed.:: 36 | 37 | a = 123; 38 | 39 | When an object pointed by a weak ref is destroyed the weak ref is automatically set to null, 40 | so the following line will print "null".:: 41 | 42 | ::print(typeof(t.thearray)) 43 | 44 | ----------------------------------- 45 | Handling weak references explicitly 46 | ----------------------------------- 47 | 48 | If a weak reference is assigned to a local variable, then is treated as any other value.:: 49 | 50 | local t = {} 51 | local weakobj = t.weakref(); 52 | 53 | the following line prints "weakref".:: 54 | 55 | ::print(typeof(weakobj)) 56 | 57 | the object pointed by the weakref can be obtained through the built-in method weakref.ref(). 58 | 59 | The following line prints "table".:: 60 | 61 | ::print(typeof(weakobj.ref())) 62 | -------------------------------------------------------------------------------- /doc/source/simple_nut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/albertodemichelis/squirrel/f77074bdd6152d230609146a3d424c6f49e3770f/doc/source/simple_nut.png -------------------------------------------------------------------------------- /doc/source/stdlib/index.rst: -------------------------------------------------------------------------------- 1 | .. _stdlib: 2 | 3 | ################################# 4 | Squirrel Standard Library 3.2 5 | ################################# 6 | 7 | Copyright (c) 2003-2022 Alberto Demichelis 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in 17 | all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | THE SOFTWARE. 26 | 27 | 28 | .. toctree:: 29 | :maxdepth: 1 30 | :numbered: 31 | 32 | introduction.rst 33 | stdiolib.rst 34 | stdbloblib.rst 35 | stdmathlib.rst 36 | stdsystemlib.rst 37 | stdstringlib.rst 38 | stdauxlib.rst 39 | 40 | -------------------------------------------------------------------------------- /doc/source/stdlib/introduction.rst: -------------------------------------------------------------------------------- 1 | .. _stdlib_introduction: 2 | 3 | ============ 4 | Introduction 5 | ============ 6 | 7 | The squirrel standard libraries consist in a set of modules implemented in C++. 8 | While are not essential for the language, they provide a set of useful services that are 9 | commonly used by a wide range of applications(file I/O, regular expressions, etc...), 10 | plus they offer a foundation for developing additional libraries. 11 | 12 | All libraries are implemented through the squirrel API and the ANSI C runtime library. 13 | The modules are organized in the following way: 14 | 15 | * I/O : input and output 16 | * blob : binary buffers manipilation 17 | * math : basic mathematical routines 18 | * system : system access function 19 | * string : string formatting and manipulation 20 | * aux : auxiliary functions 21 | 22 | The libraries can be registered independently,except for the IO library that depends from the bloblib. 23 | -------------------------------------------------------------------------------- /doc/source/stdlib/stdauxlib.rst: -------------------------------------------------------------------------------- 1 | .. _stdlib_stdauxlib: 2 | 3 | =============== 4 | The Aux library 5 | =============== 6 | 7 | The aux library implements default handlers for compiler and runtime errors and a stack dumping. 8 | 9 | +++++++++++ 10 | C API 11 | +++++++++++ 12 | 13 | .. _sqstd_seterrorhandlers: 14 | 15 | .. c:function:: void sqstd_seterrorhandlers(HSQUIRRELVM v) 16 | 17 | :param HSQUIRRELVM v: the target VM 18 | 19 | initialize compiler and runtime error handlers, the handlers 20 | use the print function set through(:ref:`sq_setprintfunc `) to output 21 | the error. 22 | 23 | .. _sqstd_printcallstack: 24 | 25 | .. c:function:: void sqstd_printcallstack(HSQUIRRELVM v) 26 | 27 | :param HSQUIRRELVM v: the target VM 28 | 29 | prints the call stack and stack contents. the function 30 | uses the print function set through(:ref:`sq_setprintfunc `) to output 31 | the stack dump. 32 | -------------------------------------------------------------------------------- /doc/source/stdlib/stdmathlib.rst: -------------------------------------------------------------------------------- 1 | .. _stdlib_stdmathlib: 2 | 3 | ================ 4 | The Math library 5 | ================ 6 | 7 | the math lib provides basic mathematic routines. The library mimics the 8 | C runtime library implementation. 9 | 10 | ------------ 11 | Squirrel API 12 | ------------ 13 | 14 | +++++++++++++++ 15 | Global Symbols 16 | +++++++++++++++ 17 | 18 | .. js:function:: abs(x) 19 | 20 | returns the absolute value of `x` as an integer 21 | 22 | .. js:function:: acos(x) 23 | 24 | returns the arccosine of `x` 25 | 26 | .. js:function:: asin(x) 27 | 28 | returns the arcsine of `x` 29 | 30 | .. js:function:: atan(x) 31 | 32 | returns the arctangent of `x` 33 | 34 | .. js:function:: atan2(x,y) 35 | 36 | returns the arctangent of `x/y` 37 | 38 | .. js:function:: ceil(x) 39 | 40 | returns a float value representing the smallest integer that is greater than or equal to `x` 41 | 42 | .. js:function:: cos(x) 43 | 44 | returns the cosine of `x` 45 | 46 | .. js:function:: exp(x) 47 | 48 | returns the exponential value of the float parameter `x` 49 | 50 | .. js:function:: fabs(x) 51 | 52 | returns the absolute value of `x` as a float 53 | 54 | .. js:function:: floor(x) 55 | 56 | returns a float value representing the largest integer that is less than or equal to `x` 57 | 58 | .. js:function:: log(x) 59 | 60 | returns the natural logarithm of `x` 61 | 62 | .. js:function:: log10(x) 63 | 64 | returns the logarithm base-10 of `x` 65 | 66 | .. js:function:: pow(x,y) 67 | 68 | returns `x` raised to the power of `y` 69 | 70 | .. js:function:: rand() 71 | 72 | returns a pseudorandom integer in the range 0 to `RAND_MAX` 73 | 74 | .. js:function:: sin(x) 75 | 76 | rreturns the sine of `x` 77 | 78 | .. js:function:: sqrt(x) 79 | 80 | returns the square root of `x` 81 | 82 | .. js:function:: srand(seed) 83 | 84 | sets the starting point for generating a series of pseudorandom integers 85 | 86 | .. js:function:: tan(x) 87 | 88 | returns the tangent of `x` 89 | 90 | .. js:data:: RAND_MAX 91 | 92 | the maximum value that can be returned by the `rand()` function 93 | 94 | .. js:data:: PI 95 | 96 | The numeric constant pi (3.141592) is the ratio of the circumference of a circle to its diameter 97 | 98 | ------------ 99 | C API 100 | ------------ 101 | 102 | .. _sqstd_register_mathlib: 103 | 104 | .. c:function:: SQRESULT sqstd_register_mathlib(HSQUIRRELVM v) 105 | 106 | :param HSQUIRRELVM v: the target VM 107 | :returns: an SQRESULT 108 | :remarks: The function aspects a table on top of the stack where to register the global library functions. 109 | 110 | initializes and register the math library in the given VM. 111 | 112 | -------------------------------------------------------------------------------- /doc/source/stdlib/stdsystemlib.rst: -------------------------------------------------------------------------------- 1 | .. _stdlib_stdsystemlib: 2 | 3 | ================== 4 | The System library 5 | ================== 6 | 7 | The system library exposes operating system facilities like environment variables, 8 | date time manipulation etc.. 9 | 10 | -------------- 11 | Squirrel API 12 | -------------- 13 | 14 | ++++++++++++++ 15 | Global Symbols 16 | ++++++++++++++ 17 | 18 | .. js:function:: clock() 19 | 20 | returns a float representing the number of seconds elapsed since the start of the process 21 | 22 | .. js:function:: date([time [, format]]) 23 | 24 | returns a table containing a date/time split into the slots: 25 | 26 | +-------------+----------------------------------------+ 27 | | sec | Seconds after minute (0 - 59). | 28 | +-------------+----------------------------------------+ 29 | | min | Minutes after hour (0 - 59). | 30 | +-------------+----------------------------------------+ 31 | | hour | Hours since midnight (0 - 23). | 32 | +-------------+----------------------------------------+ 33 | | day | Day of month (1 - 31). | 34 | +-------------+----------------------------------------+ 35 | | month | Month (0 - 11; January = 0). | 36 | +-------------+----------------------------------------+ 37 | | year | Year (current year). | 38 | +-------------+----------------------------------------+ 39 | | wday | Day of week (0 - 6; Sunday = 0). | 40 | +-------------+----------------------------------------+ 41 | | yday | Day of year (0 - 365; January 1 = 0). | 42 | +-------------+----------------------------------------+ 43 | 44 | if `time` is omitted the current time is used. 45 | 46 | if `format` can be 'l' local time or 'u' UTC time, if omitted is defaulted as 'l'(local time). 47 | 48 | .. js:function:: getenv(varaname) 49 | 50 | Returns a string containing the value of the environment variable `varname` 51 | 52 | .. js:function:: remove(path) 53 | 54 | deletes the file specified by `path` 55 | 56 | .. js:function:: rename(oldname, newname) 57 | 58 | renames the file or directory specified by `oldname` to the name given by `newname` 59 | 60 | .. js:function:: system(cmd) 61 | 62 | xecutes the string `cmd` through the os command interpreter. 63 | 64 | .. js:function:: time() 65 | 66 | returns the number of seconds elapsed since midnight 00:00:00, January 1, 1970. 67 | 68 | the result of this function can be formatted through the function `date()` 69 | 70 | -------------- 71 | C API 72 | -------------- 73 | 74 | .. _sqstd_register_systemlib: 75 | 76 | .. c:function:: SQRESULT sqstd_register_systemlib(HSQUIRRELVM v) 77 | 78 | :param HSQUIRRELVM v: the target VM 79 | :returns: an SQRESULT 80 | :remarks: The function aspects a table on top of the stack where to register the global library functions. 81 | 82 | initialize and register the system library in the given VM. 83 | -------------------------------------------------------------------------------- /etc/minimal.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #ifdef _MSC_VER 9 | #pragma comment (lib ,"squirrel.lib") 10 | #pragma comment (lib ,"sqstdlib.lib") 11 | #endif 12 | 13 | #ifdef SQUNICODE 14 | 15 | #define scvprintf vfwprintf 16 | #else 17 | 18 | #define scvprintf vfprintf 19 | #endif 20 | 21 | void printfunc(HSQUIRRELVM v,const SQChar *s,...) 22 | { 23 | va_list vl; 24 | va_start(vl, s); 25 | scvprintf(stdout, s, vl); 26 | va_end(vl); 27 | } 28 | 29 | void errorfunc(HSQUIRRELVM v,const SQChar *s,...) 30 | { 31 | va_list vl; 32 | va_start(vl, s); 33 | scvprintf(stderr, s, vl); 34 | va_end(vl); 35 | } 36 | 37 | void call_foo(HSQUIRRELVM v, int n,float f,const SQChar *s) 38 | { 39 | SQInteger top = sq_gettop(v); //saves the stack size before the call 40 | sq_pushroottable(v); //pushes the global table 41 | sq_pushstring(v,_SC("foo"),-1); 42 | if(SQ_SUCCEEDED(sq_get(v,-2))) { //gets the field 'foo' from the global table 43 | sq_pushroottable(v); //push the 'this' (in this case is the global table) 44 | sq_pushinteger(v,n); 45 | sq_pushfloat(v,f); 46 | sq_pushstring(v,s,-1); 47 | sq_call(v,4,SQFalse,SQTrue); //calls the function 48 | } 49 | sq_settop(v,top); //restores the original stack size 50 | } 51 | 52 | int main(int argc, char* argv[]) 53 | { 54 | HSQUIRRELVM v; 55 | v = sq_open(1024); // creates a VM with initial stack size 1024 56 | 57 | //REGISTRATION OF STDLIB 58 | //sq_pushroottable(v); //push the root table where the std function will be registered 59 | //sqstd_register_iolib(v); //registers a library 60 | // ... call here other stdlibs string,math etc... 61 | //sq_pop(v,1); //pops the root table 62 | //END REGISTRATION OF STDLIB 63 | 64 | sqstd_seterrorhandlers(v); //registers the default error handlers 65 | 66 | sq_setprintfunc(v, printfunc,errorfunc); //sets the print function 67 | 68 | sq_pushroottable(v); //push the root table(were the globals of the script will be stored) 69 | if(SQ_SUCCEEDED(sqstd_dofile(v, _SC("test.nut"), SQFalse, SQTrue))) // also prints syntax errors if any 70 | { 71 | call_foo(v,1,2.5,_SC("teststring")); 72 | } 73 | 74 | sq_pop(v,1); //pops the root table 75 | sq_close(v); 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /etc/test.nut: -------------------------------------------------------------------------------- 1 | function foo(i, f, s) 2 | { 3 | print("Called foo(), i="+i+", f="+f+", s='"+s+"'\n"); 4 | } 5 | -------------------------------------------------------------------------------- /include/sqconfig.h: -------------------------------------------------------------------------------- 1 | 2 | #ifdef _SQ64 3 | 4 | #ifdef _MSC_VER 5 | typedef __int64 SQInteger; 6 | typedef unsigned __int64 SQUnsignedInteger; 7 | typedef unsigned __int64 SQHash; /*should be the same size of a pointer*/ 8 | #else 9 | typedef long long SQInteger; 10 | typedef unsigned long long SQUnsignedInteger; 11 | typedef unsigned long long SQHash; /*should be the same size of a pointer*/ 12 | #endif 13 | typedef int SQInt32; 14 | typedef unsigned int SQUnsignedInteger32; 15 | #else 16 | typedef int SQInteger; 17 | typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/ 18 | typedef unsigned int SQUnsignedInteger32; /*must be 32 bits(also on 64bits processors)*/ 19 | typedef unsigned int SQUnsignedInteger; 20 | typedef unsigned int SQHash; /*should be the same size of a pointer*/ 21 | #endif 22 | 23 | 24 | #ifdef SQUSEDOUBLE 25 | typedef double SQFloat; 26 | #else 27 | typedef float SQFloat; 28 | #endif 29 | 30 | #if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64) 31 | #ifdef _MSC_VER 32 | typedef __int64 SQRawObjectVal; //must be 64bits 33 | #else 34 | typedef long long SQRawObjectVal; //must be 64bits 35 | #endif 36 | #define SQ_OBJECT_RAWINIT() { _unVal.raw = 0; } 37 | #else 38 | typedef SQUnsignedInteger SQRawObjectVal; //is 32 bits on 32 bits builds and 64 bits otherwise 39 | #define SQ_OBJECT_RAWINIT() 40 | #endif 41 | 42 | #ifndef SQ_ALIGNMENT // SQ_ALIGNMENT shall be less than or equal to SQ_MALLOC alignments, and its value shall be power of 2. 43 | #if defined(SQUSEDOUBLE) || defined(_SQ64) 44 | #define SQ_ALIGNMENT 8 45 | #else 46 | #define SQ_ALIGNMENT 4 47 | #endif 48 | #endif 49 | 50 | typedef void* SQUserPointer; 51 | typedef SQUnsignedInteger SQBool; 52 | typedef SQInteger SQRESULT; 53 | 54 | #ifdef SQUNICODE 55 | #include 56 | #include 57 | 58 | 59 | typedef wchar_t SQChar; 60 | 61 | 62 | #define scstrcmp wcscmp 63 | #ifdef _WIN32 64 | #define scsprintf _snwprintf 65 | #else 66 | #define scsprintf swprintf 67 | #endif 68 | #define scstrlen wcslen 69 | #define scstrtod wcstod 70 | #ifdef _SQ64 71 | #define scstrtol wcstoll 72 | #else 73 | #define scstrtol wcstol 74 | #endif 75 | #define scstrtoul wcstoul 76 | #define scvsprintf vswprintf 77 | #define scstrstr wcsstr 78 | #define scprintf wprintf 79 | 80 | #ifdef _WIN32 81 | #define WCHAR_SIZE 2 82 | #define WCHAR_SHIFT_MUL 1 83 | #define MAX_CHAR 0xFFFF 84 | #else 85 | #define WCHAR_SIZE 4 86 | #define WCHAR_SHIFT_MUL 2 87 | #define MAX_CHAR 0xFFFFFFFF 88 | #endif 89 | 90 | #define _SC(a) L##a 91 | 92 | 93 | #define scisspace iswspace 94 | #define scisdigit iswdigit 95 | #define scisprint iswprint 96 | #define scisxdigit iswxdigit 97 | #define scisalpha iswalpha 98 | #define sciscntrl iswcntrl 99 | #define scisalnum iswalnum 100 | 101 | 102 | #define sq_rsl(l) ((l)<= 0; i-=1) { 25 | y[i] = y[i]+ x[i]; 26 | } 27 | } 28 | print(y[0].tostring()+" "+y[n-1]); 29 | 30 | -------------------------------------------------------------------------------- /samples/class.nut: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////////// 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | class BaseVector { 4 | constructor(...) 5 | { 6 | if(vargv.len() >= 3) { 7 | x = vargv[0]; 8 | y = vargv[1]; 9 | z = vargv[2]; 10 | } 11 | } 12 | 13 | 14 | x = 0; 15 | y = 0; 16 | z = 0; 17 | } 18 | 19 | class Vector3 extends BaseVector { 20 | function _add(other) 21 | { 22 | if(other instanceof this.getclass()) 23 | return ::Vector3(x+other.x,y+other.y,z+other.z); 24 | else 25 | throw "wrong parameter"; 26 | } 27 | function Print() 28 | { 29 | ::print(x+","+y+","+z+"\n"); 30 | } 31 | } 32 | 33 | local v0 = Vector3(1,2,3) 34 | local v1 = Vector3(11,12,13) 35 | local v2 = v0 + v1; 36 | v2.Print(); 37 | 38 | FakeNamespace <- { 39 | Utils = {} 40 | } 41 | 42 | class FakeNamespace.Utils.SuperClass { 43 | constructor() 44 | { 45 | ::print("FakeNamespace.Utils.SuperClass") 46 | } 47 | } 48 | 49 | local testy = FakeNamespace.Utils.SuperClass(); 50 | -------------------------------------------------------------------------------- /samples/classattributes.nut: -------------------------------------------------------------------------------- 1 | class Foo { 2 | //constructor 3 | constructor(a) 4 | { 5 | testy = ["stuff",1,2,3]; 6 | } 7 | //attributes of PrintTesty 8 | 9 | function PrintTesty() 10 | { 11 | foreach(i,val in testy) 12 | { 13 | ::print("idx = "+i+" = "+val+" \n"); 14 | } 15 | } 16 | //attributes of testy 17 | 18 | testy = null; 19 | 20 | } 21 | 22 | foreach(member,val in Foo) 23 | { 24 | ::print(member+"\n"); 25 | local attr; 26 | if((attr = Foo.getattributes(member)) != null) { 27 | foreach(i,v in attr) 28 | { 29 | ::print("\t"+i+" = "+(typeof v)+"\n"); 30 | } 31 | } 32 | else { 33 | ::print("\t\n") 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /samples/coroutines.nut: -------------------------------------------------------------------------------- 1 | function coroutine_test(a,b) 2 | { 3 | ::print(a+" "+b+"\n"); 4 | local ret = ::suspend("suspend 1"); 5 | ::print("the coroutine says "+ret+"\n"); 6 | ret = ::suspend("suspend 2"); 7 | ::print("the coroutine says "+ret+"\n"); 8 | ret = ::suspend("suspend 3"); 9 | ::print("the coroutine says "+ret+"\n"); 10 | return "I'm done" 11 | } 12 | 13 | local coro = ::newthread(coroutine_test); 14 | 15 | local susparam = coro.call("test","coroutine"); //starts the coroutine 16 | 17 | local i = 1; 18 | do 19 | { 20 | ::print("suspend passed ["+susparam+"]\n") 21 | susparam = coro.wakeup("ciao "+i); 22 | ++i; 23 | }while(coro.getstatus()=="suspended") 24 | 25 | ::print("return passed ["+susparam+"]\n") 26 | -------------------------------------------------------------------------------- /samples/delegation.nut: -------------------------------------------------------------------------------- 1 | 2 | PEntity <- { 3 | name="noname" 4 | pos={x=0,y=0,z=0} 5 | type="entity" 6 | //methamethod 7 | _typeof=function() 8 | { 9 | return type; 10 | } 11 | } 12 | 13 | function PEntity::PrintPos() 14 | { 15 | ::print("x="+pos.x+" y="+pos.y+" z="+pos.z+"\n"); 16 | } 17 | 18 | function PEntity::new(name,pos) 19 | { 20 | local newentity=clone ::PEntity; 21 | if(name) 22 | newentity.name=name; 23 | if(pos) 24 | newentity.pos=pos; 25 | return newentity; 26 | } 27 | 28 | PPlayer <- { 29 | model="warrior.mdl" 30 | weapon="fist" 31 | health=100 32 | armor=0 33 | //overrides the parent type 34 | type="player" 35 | } 36 | 37 | function PPlayer::new(name,pos) 38 | { 39 | local p = clone ::PPlayer; 40 | local newplayer = ::PEntity.new(name,pos); 41 | newplayer.setdelegate(p); 42 | return newplayer; 43 | } 44 | 45 | local player=PPlayer.new("godzilla",{x=10,y=20,z=30}); 46 | 47 | ::print("PLAYER NAME"+player.name+"\n"); 48 | ::print("ENTITY TYPE"+typeof player+"\n"); 49 | 50 | player.PrintPos(); 51 | 52 | player.pos.x=123; 53 | 54 | player.PrintPos(); 55 | -------------------------------------------------------------------------------- /samples/fibonacci.nut: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Original Javascript version by David Hedbor(http://www.bagley.org/~doug/shootout/) 4 | * 5 | */ 6 | 7 | function fib(n) 8 | { 9 | if (n < 2) return 1 10 | return fib(n-2) + fib(n-1) 11 | } 12 | 13 | local n = vargv.len()!=0?vargv[0].tointeger():1 14 | 15 | print(fib(n)+"\n") 16 | -------------------------------------------------------------------------------- /samples/flow.nut: -------------------------------------------------------------------------------- 1 | function min(x,y) 2 | return xy?x:y; 6 | 7 | if(min(100,200)>max(50,20)) 8 | print("I'm useless statement just to show up the if/else\n"); 9 | else 10 | print("squirrel!!\n"); 11 | 12 | print("\n") 13 | 14 | function typy(obj) 15 | { 16 | switch(typeof obj) 17 | { 18 | case "integer": 19 | case "float": 20 | return "is a number"; 21 | case "table": 22 | case "array": 23 | return "is a container"; 24 | default: 25 | return "is other stuff" 26 | } 27 | } 28 | 29 | local a=1,b={},c=function(a,b){return a+b;} 30 | 31 | print("a "+typy(a)+"\n"); 32 | print("b "+typy(b)+"\n"); 33 | print("c "+typy(c)+"\n"); 34 | -------------------------------------------------------------------------------- /samples/generators.nut: -------------------------------------------------------------------------------- 1 | /* 2 | *Random number function from The Great Computer Language shootout 3 | *converted to a generator func 4 | */ 5 | 6 | function gen_random(max) { 7 | local last=42 8 | local IM = 139968; 9 | local IA = 3877; 10 | local IC = 29573; 11 | for(;;){ //loops forever 12 | yield (max * (last = (last * IA + IC) % IM) / IM); 13 | } 14 | } 15 | 16 | local randtor=gen_random(100); 17 | 18 | print("RAND NUMBERS \n") 19 | 20 | for(local i=0;i<10;i+=1) 21 | print(">"+resume randtor+"\n"); 22 | 23 | print("FIBONACCI \n") 24 | function fiboz(n) 25 | { 26 | local prev=0; 27 | local curr=1; 28 | yield 1; 29 | 30 | for(local i=0;i"+val+"\n"); 42 | } 43 | -------------------------------------------------------------------------------- /samples/hello.nut: -------------------------------------------------------------------------------- 1 | print("Hello World!") 2 | -------------------------------------------------------------------------------- /samples/list.nut: -------------------------------------------------------------------------------- 1 | /*translation of the list test from The Great Computer Language Shootout 2 | */ 3 | 4 | function compare_arr(a1,a2) 5 | { 6 | foreach(i,val in a1) 7 | if(val!=a2[i])return null; 8 | return 1; 9 | } 10 | 11 | function test() 12 | { 13 | local size=10000 14 | local l1=[]; l1.resize(size); 15 | for(local i=0;i0) 21 | l3.append(l2.pop()); 22 | while(l3.len()>0) 23 | l2.append(l3.pop()); 24 | l1.reverse(); 25 | 26 | if(compare_arr(l1,l2)) 27 | return l1.len(); 28 | return null; 29 | } 30 | 31 | local n = vargv.len()!=0?vargv[0].tointeger():1 32 | for(local i=0;i\n"); 114 | else 115 | print("\n"); 116 | -------------------------------------------------------------------------------- /samples/methcall.nut: -------------------------------------------------------------------------------- 1 | /*translation of the methcall test from The Great Computer Language Shootout 2 | */ 3 | 4 | class Toggle { 5 | bool=null 6 | } 7 | 8 | function Toggle::constructor(startstate) { 9 | bool = startstate 10 | } 11 | 12 | function Toggle::value() { 13 | return bool; 14 | } 15 | 16 | function Toggle::activate() { 17 | bool = !bool; 18 | return this; 19 | } 20 | 21 | class NthToggle extends Toggle { 22 | count_max=null 23 | count=0 24 | } 25 | 26 | function NthToggle::constructor(start_state,max_counter) 27 | { 28 | base.constructor(start_state); 29 | count_max = max_counter 30 | } 31 | 32 | function NthToggle::activate () 33 | { 34 | ++count; 35 | if (count >= count_max ) { 36 | base.activate(); 37 | count = 0; 38 | } 39 | return this; 40 | } 41 | 42 | 43 | function main() { 44 | local n = vargv.len()!=0?vargv[0].tointeger():1 45 | 46 | 47 | 48 | local val = 1; 49 | local toggle = Toggle(val); 50 | local i = n; 51 | while(i--) { 52 | val = toggle.activate().value(); 53 | 54 | } 55 | print(toggle.value() ? "true\n" : "false\n"); 56 | 57 | val = 1; 58 | local ntoggle = NthToggle(val, 3); 59 | i = n; 60 | while(i--) { 61 | val = ntoggle.activate().value(); 62 | } 63 | print(ntoggle.value() ? "true\n" : "false\n"); 64 | 65 | } 66 | local start=clock(); 67 | main(); 68 | print("TIME="+(clock()-start)+"\n"); 69 | -------------------------------------------------------------------------------- /samples/regex.nut: -------------------------------------------------------------------------------- 1 | local ex = regexp("[a-zA-Z]+"); 2 | local string = "123 Test; strlen(str);"; 3 | local res = ex.search(string); 4 | print(string.slice(res.begin,res.end)); //prints "Test" 5 | print("\n"); 6 | ex = regexp(@"\m()"); 7 | string = "123 Test; doSomething(str, getTemp(), (a+(b/c)));"; 8 | res = ex.search(string); 9 | print(string.slice(res.begin,res.end)); //prints "(...)" 10 | print("\n"); 11 | -------------------------------------------------------------------------------- /samples/tailstate.nut: -------------------------------------------------------------------------------- 1 | function state1() 2 | { 3 | ::suspend("state1"); 4 | return state2(); 5 | } 6 | 7 | function state2() 8 | { 9 | ::suspend("state2"); 10 | return state3(); 11 | } 12 | 13 | function state3() 14 | { 15 | ::suspend("state3"); 16 | return state1(); 17 | } 18 | 19 | local statethread = ::newthread(state1) 20 | 21 | ::print(statethread.call()+"\n"); 22 | 23 | for(local i = 0; i < 10000; i++) 24 | ::print(statethread.wakeup()+"\n"); 25 | -------------------------------------------------------------------------------- /sq/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_C_STANDARD 99) 2 | if(NOT DISABLE_DYNAMIC) 3 | add_executable(sq sq.c) 4 | add_executable(squirrel::interpreter ALIAS sq) 5 | set_target_properties(sq PROPERTIES EXPORT_NAME interpreter) 6 | target_link_libraries(sq squirrel sqstdlib) 7 | if(NOT SQ_DISABLE_INSTALLER) 8 | install(TARGETS sq EXPORT squirrel RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime) 9 | endif() 10 | target_include_directories(sq PUBLIC 11 | "$" 12 | "$" 13 | ) 14 | endif() 15 | 16 | if(NOT DISABLE_STATIC) 17 | add_executable(sq_static sq.c) 18 | add_executable(squirrel::interpreter_static ALIAS sq_static) 19 | set_target_properties(sq_static PROPERTIES EXPORT_NAME interpreter_static) 20 | target_link_libraries(sq_static squirrel_static sqstdlib_static) 21 | if(NOT SQ_DISABLE_INSTALLER) 22 | install(TARGETS sq_static EXPORT squirrel RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime) 23 | endif() 24 | target_include_directories(sq_static PUBLIC 25 | "$" 26 | "$" 27 | ) 28 | endif() 29 | 30 | if(LONG_OUTPUT_NAMES) 31 | if(NOT DISABLE_DYNAMIC) 32 | set_target_properties(sq PROPERTIES OUTPUT_NAME squirrel3) 33 | endif() 34 | 35 | if(NOT DISABLE_STATIC) 36 | set_target_properties(sq_static PROPERTIES OUTPUT_NAME squirrel3_static) 37 | endif() 38 | endif() 39 | -------------------------------------------------------------------------------- /sq/Makefile: -------------------------------------------------------------------------------- 1 | SQUIRREL= .. 2 | 3 | 4 | OUT= $(SQUIRREL)/bin/sq 5 | INCZ= -I$(SQUIRREL)/include -I. -I$(SQUIRREL)/sqlibs 6 | LIBZ= -L$(SQUIRREL)/lib 7 | LIB= -lsquirrel -lsqstdlib 8 | 9 | OBJS= sq.o 10 | 11 | SRCS= sq.c 12 | 13 | 14 | sq32: 15 | g++ -O2 -fno-exceptions -fno-rtti -o $(OUT) $(SRCS) $(INCZ) $(LIBZ) $(LIB) 16 | 17 | sqprof: 18 | g++ -O2 -pg -fno-exceptions -fno-rtti -pie -gstabs -g3 -o $(OUT) $(SRCS) $(INCZ) $(LIBZ) $(LIB) 19 | 20 | sq64: 21 | g++ -O2 -m64 -fno-exceptions -fno-rtti -D_SQ64 -o $(OUT) $(SRCS) $(INCZ) $(LIBZ) $(LIB) 22 | -------------------------------------------------------------------------------- /sq/sq.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="sq" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=sq - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "sq.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "sq.mak" CFG="sq - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "sq - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "sq - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_LocalPath ".." 27 | CPP=cl.exe 28 | RSC=rc.exe 29 | 30 | !IF "$(CFG)" == "sq - Win32 Release" 31 | 32 | # PROP BASE Use_MFC 0 33 | # PROP BASE Use_Debug_Libraries 0 34 | # PROP BASE Output_Dir "Release" 35 | # PROP BASE Intermediate_Dir "Release" 36 | # PROP BASE Target_Dir "" 37 | # PROP Use_MFC 0 38 | # PROP Use_Debug_Libraries 0 39 | # PROP Output_Dir "Release" 40 | # PROP Intermediate_Dir "Release" 41 | # PROP Ignore_Export_Lib 0 42 | # PROP Target_Dir "" 43 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 44 | # ADD CPP /nologo /W3 /GX /O2 /I "..\include" /I "..\sqstdlib" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 45 | # ADD BASE RSC /l 0x410 /d "NDEBUG" 46 | # ADD RSC /l 0x410 /d "NDEBUG" 47 | BSC32=bscmake.exe 48 | # ADD BASE BSC32 /nologo 49 | # ADD BSC32 /nologo 50 | LINK32=link.exe 51 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 52 | # ADD LINK32 squirrel.lib sqstdlib.lib /nologo /subsystem:console /machine:I386 /out:"../bin/sq.exe" /libpath:"../lib" 53 | 54 | !ELSEIF "$(CFG)" == "sq - Win32 Debug" 55 | 56 | # PROP BASE Use_MFC 0 57 | # PROP BASE Use_Debug_Libraries 1 58 | # PROP BASE Output_Dir "Debug" 59 | # PROP BASE Intermediate_Dir "Debug" 60 | # PROP BASE Target_Dir "" 61 | # PROP Use_MFC 0 62 | # PROP Use_Debug_Libraries 1 63 | # PROP Output_Dir "Debug" 64 | # PROP Intermediate_Dir "Debug" 65 | # PROP Ignore_Export_Lib 0 66 | # PROP Target_Dir "" 67 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 68 | # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\include" /I "..\sqstdlib" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 69 | # ADD BASE RSC /l 0x410 /d "_DEBUG" 70 | # ADD RSC /l 0x410 /d "_DEBUG" 71 | BSC32=bscmake.exe 72 | # ADD BASE BSC32 /nologo 73 | # ADD BSC32 /nologo 74 | LINK32=link.exe 75 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 76 | # ADD LINK32 squirrel.lib sqstdlib.lib /nologo /subsystem:console /debug /machine:I386 /out:"../bin/sq.exe" /pdbtype:sept /libpath:"../lib" 77 | 78 | !ENDIF 79 | 80 | # Begin Target 81 | 82 | # Name "sq - Win32 Release" 83 | # Name "sq - Win32 Debug" 84 | # Begin Group "Source Files" 85 | 86 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 87 | # Begin Source File 88 | 89 | SOURCE=.\sq.c 90 | # End Source File 91 | # End Group 92 | # Begin Group "Header Files" 93 | 94 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 95 | # End Group 96 | # Begin Group "Resource Files" 97 | 98 | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" 99 | # End Group 100 | # End Target 101 | # End Project 102 | -------------------------------------------------------------------------------- /sqstdlib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SQSTDLIB_SRC sqstdaux.cpp 2 | sqstdblob.cpp 3 | sqstdio.cpp 4 | sqstdmath.cpp 5 | sqstdrex.cpp 6 | sqstdstream.cpp 7 | sqstdstring.cpp 8 | sqstdsystem.cpp) 9 | 10 | if(NOT DISABLE_DYNAMIC) 11 | add_library(sqstdlib SHARED ${SQSTDLIB_SRC}) 12 | add_library(squirrel::sqstdlib ALIAS sqstdlib) 13 | set_property(TARGET sqstdlib PROPERTY EXPORT_NAME sqstdlib) 14 | set_property(TARGET sqstdlib PROPERTY OUTPUT_NAME ${SQSTDLIB_NAME}) 15 | target_link_libraries(sqstdlib squirrel) 16 | if(NOT SQ_DISABLE_INSTALLER) 17 | install(TARGETS sqstdlib EXPORT squirrel 18 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Libraries 19 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Libraries NAMELINK_SKIP 20 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Libraries 21 | ) 22 | install(TARGETS sqstdlib EXPORT squirrel 23 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Development NAMELINK_ONLY 24 | ) 25 | endif() 26 | target_include_directories(sqstdlib PUBLIC 27 | "$" 28 | "$" 29 | ) 30 | endif() 31 | 32 | if(NOT DISABLE_STATIC) 33 | add_library(sqstdlib_static STATIC ${SQSTDLIB_SRC}) 34 | add_library(squirrel::sqstdlib_static ALIAS sqstdlib_static) 35 | set_property(TARGET sqstdlib_static PROPERTY EXPORT_NAME sqstdlib_static) 36 | if(NOT SQ_DISABLE_INSTALLER) 37 | install(TARGETS sqstdlib_static EXPORT squirrel ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Development) 38 | endif() 39 | target_include_directories(sqstdlib_static PUBLIC 40 | "$" 41 | "$" 42 | ) 43 | endif() 44 | 45 | if(LONG_OUTPUT_NAMES) 46 | if(NOT DISABLE_STATIC) 47 | set_target_properties(sqstdlib_static PROPERTIES OUTPUT_NAME sqstdlib3_static) 48 | endif() 49 | endif() 50 | -------------------------------------------------------------------------------- /sqstdlib/Makefile: -------------------------------------------------------------------------------- 1 | SQUIRREL= .. 2 | 3 | 4 | CC?= gcc 5 | OUT?= $(SQUIRREL)/lib/libsqstdlib.a 6 | INCZ?= -I$(SQUIRREL)/include -I. -Iinclude 7 | DEFS= $(CC_EXTRA_FLAGS) 8 | LIB= 9 | 10 | OBJS= \ 11 | sqstdblob.o \ 12 | sqstdio.o \ 13 | sqstdstream.o \ 14 | sqstdmath.o \ 15 | sqstdsystem.o \ 16 | sqstdstring.o \ 17 | sqstdaux.o \ 18 | sqstdrex.o 19 | 20 | SRCS= \ 21 | sqstdblob.cpp \ 22 | sqstdio.cpp \ 23 | sqstdstream.cpp \ 24 | sqstdmath.cpp \ 25 | sqstdsystem.cpp \ 26 | sqstdstring.cpp \ 27 | sqstdaux.cpp \ 28 | sqstdrex.cpp 29 | 30 | 31 | sq32: 32 | $(CC) -O2 -fno-exceptions -fno-rtti -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS) 33 | ar rc $(OUT) *.o 34 | rm *.o 35 | 36 | sqprof: 37 | $(CC) -O2 -pg -fno-exceptions -fno-rtti -pie -gstabs -g3 -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS) 38 | ar rc $(OUT) *.o 39 | rm *.o 40 | 41 | sq64: 42 | $(CC) -O2 -m64 -fno-exceptions -D_SQ64 -fno-rtti -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS) 43 | ar rc $(OUT) *.o 44 | rm *.o 45 | -------------------------------------------------------------------------------- /sqstdlib/sqstdaux.cpp: -------------------------------------------------------------------------------- 1 | /* see copyright notice in squirrel.h */ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | void sqstd_printcallstack(HSQUIRRELVM v) 9 | { 10 | SQPRINTFUNCTION pf = sq_geterrorfunc(v); 11 | if(pf) { 12 | SQStackInfos si; 13 | SQInteger i; 14 | SQFloat f; 15 | const SQChar *s; 16 | SQInteger level=1; //1 is to skip this function that is level 0 17 | const SQChar *name=0; 18 | SQInteger seq=0; 19 | pf(v,_SC("\nCALLSTACK\n")); 20 | while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si))) 21 | { 22 | const SQChar *fn=_SC("unknown"); 23 | const SQChar *src=_SC("unknown"); 24 | if(si.funcname)fn=si.funcname; 25 | if(si.source)src=si.source; 26 | pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line); 27 | level++; 28 | } 29 | level=0; 30 | pf(v,_SC("\nLOCALS\n")); 31 | 32 | for(level=0;level<10;level++){ 33 | seq=0; 34 | while((name = sq_getlocal(v,level,seq))) 35 | { 36 | seq++; 37 | switch(sq_gettype(v,-1)) 38 | { 39 | case OT_NULL: 40 | pf(v,_SC("[%s] NULL\n"),name); 41 | break; 42 | case OT_INTEGER: 43 | sq_getinteger(v,-1,&i); 44 | pf(v,_SC("[%s] %d\n"),name,i); 45 | break; 46 | case OT_FLOAT: 47 | sq_getfloat(v,-1,&f); 48 | pf(v,_SC("[%s] %.14g\n"),name,f); 49 | break; 50 | case OT_USERPOINTER: 51 | pf(v,_SC("[%s] USERPOINTER\n"),name); 52 | break; 53 | case OT_STRING: 54 | sq_getstring(v,-1,&s); 55 | pf(v,_SC("[%s] \"%s\"\n"),name,s); 56 | break; 57 | case OT_TABLE: 58 | pf(v,_SC("[%s] TABLE\n"),name); 59 | break; 60 | case OT_ARRAY: 61 | pf(v,_SC("[%s] ARRAY\n"),name); 62 | break; 63 | case OT_CLOSURE: 64 | pf(v,_SC("[%s] CLOSURE\n"),name); 65 | break; 66 | case OT_NATIVECLOSURE: 67 | pf(v,_SC("[%s] NATIVECLOSURE\n"),name); 68 | break; 69 | case OT_GENERATOR: 70 | pf(v,_SC("[%s] GENERATOR\n"),name); 71 | break; 72 | case OT_USERDATA: 73 | pf(v,_SC("[%s] USERDATA\n"),name); 74 | break; 75 | case OT_THREAD: 76 | pf(v,_SC("[%s] THREAD\n"),name); 77 | break; 78 | case OT_CLASS: 79 | pf(v,_SC("[%s] CLASS\n"),name); 80 | break; 81 | case OT_INSTANCE: 82 | pf(v,_SC("[%s] INSTANCE\n"),name); 83 | break; 84 | case OT_WEAKREF: 85 | pf(v,_SC("[%s] WEAKREF\n"),name); 86 | break; 87 | case OT_BOOL:{ 88 | SQBool bval; 89 | sq_getbool(v,-1,&bval); 90 | pf(v,_SC("[%s] %s\n"),name,bval == SQTrue ? _SC("true"):_SC("false")); 91 | } 92 | break; 93 | default: assert(0); break; 94 | } 95 | sq_pop(v,1); 96 | } 97 | } 98 | } 99 | } 100 | 101 | static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v) 102 | { 103 | SQPRINTFUNCTION pf = sq_geterrorfunc(v); 104 | if(pf) { 105 | const SQChar *sErr = 0; 106 | if(sq_gettop(v)>=1) { 107 | if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) { 108 | pf(v,_SC("\nAN ERROR HAS OCCURRED [%s]\n"),sErr); 109 | } 110 | else{ 111 | pf(v,_SC("\nAN ERROR HAS OCCURRED [unknown]\n")); 112 | } 113 | sqstd_printcallstack(v); 114 | } 115 | } 116 | return 0; 117 | } 118 | 119 | void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column) 120 | { 121 | SQPRINTFUNCTION pf = sq_geterrorfunc(v); 122 | if(pf) { 123 | pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr); 124 | } 125 | } 126 | 127 | void sqstd_seterrorhandlers(HSQUIRRELVM v) 128 | { 129 | sq_setcompilererrorhandler(v,_sqstd_compiler_error); 130 | sq_newclosure(v,_sqstd_aux_printerror,0); 131 | sq_seterrorhandler(v); 132 | } 133 | 134 | SQRESULT sqstd_throwerrorf(HSQUIRRELVM v,const SQChar *err,...) 135 | { 136 | SQInteger n=256; 137 | va_list args; 138 | begin: 139 | va_start(args,err); 140 | SQChar *b=sq_getscratchpad(v,n); 141 | SQInteger r=scvsprintf(b,n,err,args); 142 | va_end(args); 143 | if (r>=n) { 144 | n=r+1;//required+null 145 | goto begin; 146 | } else if (r<0) { 147 | return sq_throwerror(v,_SC("@failed to generate formatted error message")); 148 | } else { 149 | return sq_throwerror(v,b); 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /sqstdlib/sqstdblobimpl.h: -------------------------------------------------------------------------------- 1 | /* see copyright notice in squirrel.h */ 2 | #ifndef _SQSTD_BLOBIMPL_H_ 3 | #define _SQSTD_BLOBIMPL_H_ 4 | 5 | struct SQBlob : public SQStream 6 | { 7 | SQBlob(SQInteger size) { 8 | _size = size; 9 | _allocated = size; 10 | _buf = (unsigned char *)sq_malloc(size); 11 | memset(_buf, 0, _size); 12 | _ptr = 0; 13 | _owns = true; 14 | } 15 | virtual ~SQBlob() { 16 | sq_free(_buf, _allocated); 17 | } 18 | SQInteger Write(void *buffer, SQInteger size) { 19 | if(!CanAdvance(size)) { 20 | GrowBufOf(_ptr + size - _size); 21 | } 22 | memcpy(&_buf[_ptr], buffer, size); 23 | _ptr += size; 24 | return size; 25 | } 26 | SQInteger Read(void *buffer,SQInteger size) { 27 | SQInteger n = size; 28 | if(!CanAdvance(size)) { 29 | if((_size - _ptr) > 0) 30 | n = _size - _ptr; 31 | else return 0; 32 | } 33 | memcpy(buffer, &_buf[_ptr], n); 34 | _ptr += n; 35 | return n; 36 | } 37 | bool Resize(SQInteger n) { 38 | if(!_owns) return false; 39 | if(n != _allocated) { 40 | unsigned char *newbuf = (unsigned char *)sq_malloc(n); 41 | memset(newbuf,0,n); 42 | if(_size > n) 43 | memcpy(newbuf,_buf,n); 44 | else 45 | memcpy(newbuf,_buf,_size); 46 | sq_free(_buf,_allocated); 47 | _buf=newbuf; 48 | _allocated = n; 49 | if(_size > _allocated) 50 | _size = _allocated; 51 | if(_ptr > _allocated) 52 | _ptr = _allocated; 53 | } 54 | return true; 55 | } 56 | bool GrowBufOf(SQInteger n) 57 | { 58 | bool ret = true; 59 | if(_size + n > _allocated) { 60 | if(_size + n > _size * 2) 61 | ret = Resize(_size + n); 62 | else 63 | ret = Resize(_size * 2); 64 | } 65 | _size = _size + n; 66 | return ret; 67 | } 68 | bool CanAdvance(SQInteger n) { 69 | if(_ptr+n>_size)return false; 70 | return true; 71 | } 72 | SQInteger Seek(SQInteger offset, SQInteger origin) { 73 | switch(origin) { 74 | case SQ_SEEK_SET: 75 | if(offset > _size || offset < 0) return -1; 76 | _ptr = offset; 77 | break; 78 | case SQ_SEEK_CUR: 79 | if(_ptr + offset > _size || _ptr + offset < 0) return -1; 80 | _ptr += offset; 81 | break; 82 | case SQ_SEEK_END: 83 | if(_size + offset > _size || _size + offset < 0) return -1; 84 | _ptr = _size + offset; 85 | break; 86 | default: return -1; 87 | } 88 | return 0; 89 | } 90 | bool IsValid() { 91 | return _size == 0 || _buf?true:false; 92 | } 93 | bool EOS() { 94 | return _ptr == _size; 95 | } 96 | SQInteger Flush() { return 0; } 97 | SQInteger Tell() { return _ptr; } 98 | SQInteger Len() { return _size; } 99 | SQUserPointer GetBuf(){ return _buf; } 100 | private: 101 | SQInteger _size; 102 | SQInteger _allocated; 103 | SQInteger _ptr; 104 | unsigned char *_buf; 105 | bool _owns; 106 | }; 107 | 108 | #endif //_SQSTD_BLOBIMPL_H_ 109 | -------------------------------------------------------------------------------- /sqstdlib/sqstdlib.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="sqstdlib" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Static Library" 0x0104 6 | 7 | CFG=sqstdlib - Win32 Release 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "sqstdlib.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "sqstdlib.mak" CFG="sqstdlib - Win32 Release" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "sqstdlib - Win32 Release" (based on "Win32 (x86) Static Library") 21 | !MESSAGE "sqstdlib - Win32 Debug" (based on "Win32 (x86) Static Library") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_LocalPath ".." 27 | CPP=cl.exe 28 | RSC=rc.exe 29 | 30 | !IF "$(CFG)" == "sqstdlib - Win32 Release" 31 | 32 | # PROP BASE Use_MFC 0 33 | # PROP BASE Use_Debug_Libraries 0 34 | # PROP BASE Output_Dir "Release" 35 | # PROP BASE Intermediate_Dir "Release" 36 | # PROP BASE Target_Dir "" 37 | # PROP Use_MFC 0 38 | # PROP Use_Debug_Libraries 0 39 | # PROP Output_Dir "Release" 40 | # PROP Intermediate_Dir "Release" 41 | # PROP Target_Dir "" 42 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c 43 | # ADD CPP /nologo /W3 /GX /O2 /I "..\include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c 44 | # ADD BASE RSC /l 0x410 /d "NDEBUG" 45 | # ADD RSC /l 0x410 /d "NDEBUG" 46 | BSC32=bscmake.exe 47 | # ADD BASE BSC32 /nologo 48 | # ADD BSC32 /nologo 49 | LIB32=link.exe -lib 50 | # ADD BASE LIB32 /nologo 51 | # ADD LIB32 /nologo /out:"..\lib\sqstdlib.lib" 52 | 53 | !ELSEIF "$(CFG)" == "sqstdlib - Win32 Debug" 54 | 55 | # PROP BASE Use_MFC 0 56 | # PROP BASE Use_Debug_Libraries 1 57 | # PROP BASE Output_Dir "Debug" 58 | # PROP BASE Intermediate_Dir "Debug" 59 | # PROP BASE Target_Dir "" 60 | # PROP Use_MFC 0 61 | # PROP Use_Debug_Libraries 1 62 | # PROP Output_Dir "Debug" 63 | # PROP Intermediate_Dir "Debug" 64 | # PROP Target_Dir "" 65 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c 66 | # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c 67 | # ADD BASE RSC /l 0x410 /d "_DEBUG" 68 | # ADD RSC /l 0x410 /d "_DEBUG" 69 | BSC32=bscmake.exe 70 | # ADD BASE BSC32 /nologo 71 | # ADD BSC32 /nologo 72 | LIB32=link.exe -lib 73 | # ADD BASE LIB32 /nologo 74 | # ADD LIB32 /nologo /out:"..\lib\sqstdlib.lib" 75 | 76 | !ENDIF 77 | 78 | # Begin Target 79 | 80 | # Name "sqstdlib - Win32 Release" 81 | # Name "sqstdlib - Win32 Debug" 82 | # Begin Group "Source Files" 83 | 84 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 85 | # Begin Source File 86 | 87 | SOURCE=.\sqstdblob.cpp 88 | # End Source File 89 | # Begin Source File 90 | 91 | SOURCE=.\sqstdio.cpp 92 | # End Source File 93 | # Begin Source File 94 | 95 | SOURCE=.\sqstdmath.cpp 96 | # End Source File 97 | # Begin Source File 98 | 99 | SOURCE=.\sqstdrex.cpp 100 | # End Source File 101 | # Begin Source File 102 | 103 | SOURCE=.\sqstdstream.cpp 104 | # End Source File 105 | # Begin Source File 106 | 107 | SOURCE=.\sqstdstring.cpp 108 | # End Source File 109 | # Begin Source File 110 | 111 | SOURCE=.\sqstdaux.cpp 112 | # End Source File 113 | # Begin Source File 114 | 115 | SOURCE=.\sqstdsystem.cpp 116 | # End Source File 117 | # End Group 118 | # Begin Group "Header Files" 119 | 120 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 121 | # Begin Source File 122 | 123 | SOURCE=.\sqstdblobimpl.h 124 | # End Source File 125 | # Begin Source File 126 | 127 | SOURCE=.\sqstdstream.h 128 | # End Source File 129 | # End Group 130 | # End Target 131 | # End Project 132 | -------------------------------------------------------------------------------- /sqstdlib/sqstdmath.cpp: -------------------------------------------------------------------------------- 1 | /* see copyright notice in squirrel.h */ 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \ 8 | SQFloat f; \ 9 | sq_getfloat(v,2,&f); \ 10 | sq_pushfloat(v,(SQFloat)_funcname(f)); \ 11 | return 1; \ 12 | } 13 | 14 | #define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \ 15 | SQFloat p1,p2; \ 16 | sq_getfloat(v,2,&p1); \ 17 | sq_getfloat(v,3,&p2); \ 18 | sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \ 19 | return 1; \ 20 | } 21 | 22 | static SQInteger math_srand(HSQUIRRELVM v) 23 | { 24 | SQInteger i; 25 | if(SQ_FAILED(sq_getinteger(v,2,&i))) 26 | return sq_throwerror(v,_SC("invalid param")); 27 | srand((unsigned int)i); 28 | return 0; 29 | } 30 | 31 | static SQInteger math_rand(HSQUIRRELVM v) 32 | { 33 | sq_pushinteger(v,rand()); 34 | return 1; 35 | } 36 | 37 | static SQInteger math_abs(HSQUIRRELVM v) 38 | { 39 | SQInteger n; 40 | sq_getinteger(v,2,&n); 41 | sq_pushinteger(v,(SQInteger)abs((int)n)); 42 | return 1; 43 | } 44 | 45 | SINGLE_ARG_FUNC(sqrt) 46 | SINGLE_ARG_FUNC(fabs) 47 | SINGLE_ARG_FUNC(sin) 48 | SINGLE_ARG_FUNC(cos) 49 | SINGLE_ARG_FUNC(asin) 50 | SINGLE_ARG_FUNC(acos) 51 | SINGLE_ARG_FUNC(log) 52 | SINGLE_ARG_FUNC(log10) 53 | SINGLE_ARG_FUNC(tan) 54 | SINGLE_ARG_FUNC(atan) 55 | TWO_ARGS_FUNC(atan2) 56 | TWO_ARGS_FUNC(pow) 57 | SINGLE_ARG_FUNC(floor) 58 | SINGLE_ARG_FUNC(ceil) 59 | SINGLE_ARG_FUNC(exp) 60 | 61 | #define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck} 62 | static const SQRegFunction mathlib_funcs[] = { 63 | _DECL_FUNC(sqrt,2,_SC(".n")), 64 | _DECL_FUNC(sin,2,_SC(".n")), 65 | _DECL_FUNC(cos,2,_SC(".n")), 66 | _DECL_FUNC(asin,2,_SC(".n")), 67 | _DECL_FUNC(acos,2,_SC(".n")), 68 | _DECL_FUNC(log,2,_SC(".n")), 69 | _DECL_FUNC(log10,2,_SC(".n")), 70 | _DECL_FUNC(tan,2,_SC(".n")), 71 | _DECL_FUNC(atan,2,_SC(".n")), 72 | _DECL_FUNC(atan2,3,_SC(".nn")), 73 | _DECL_FUNC(pow,3,_SC(".nn")), 74 | _DECL_FUNC(floor,2,_SC(".n")), 75 | _DECL_FUNC(ceil,2,_SC(".n")), 76 | _DECL_FUNC(exp,2,_SC(".n")), 77 | _DECL_FUNC(srand,2,_SC(".n")), 78 | _DECL_FUNC(rand,1,NULL), 79 | _DECL_FUNC(fabs,2,_SC(".n")), 80 | _DECL_FUNC(abs,2,_SC(".n")), 81 | {NULL,(SQFUNCTION)0,0,NULL} 82 | }; 83 | #undef _DECL_FUNC 84 | 85 | #ifndef M_PI 86 | #define M_PI (3.14159265358979323846) 87 | #endif 88 | 89 | SQRESULT sqstd_register_mathlib(HSQUIRRELVM v) 90 | { 91 | SQInteger i=0; 92 | while(mathlib_funcs[i].name!=0) { 93 | sq_pushstring(v,mathlib_funcs[i].name,-1); 94 | sq_newclosure(v,mathlib_funcs[i].f,0); 95 | sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask); 96 | sq_setnativeclosurename(v,-1,mathlib_funcs[i].name); 97 | sq_newslot(v,-3,SQFalse); 98 | i++; 99 | } 100 | sq_pushstring(v,_SC("RAND_MAX"),-1); 101 | sq_pushinteger(v,RAND_MAX); 102 | sq_newslot(v,-3,SQFalse); 103 | sq_pushstring(v,_SC("PI"),-1); 104 | sq_pushfloat(v,(SQFloat)M_PI); 105 | sq_newslot(v,-3,SQFalse); 106 | return SQ_OK; 107 | } 108 | -------------------------------------------------------------------------------- /sqstdlib/sqstdstream.h: -------------------------------------------------------------------------------- 1 | /* see copyright notice in squirrel.h */ 2 | #ifndef _SQSTD_STREAM_H_ 3 | #define _SQSTD_STREAM_H_ 4 | 5 | SQInteger _stream_readblob(HSQUIRRELVM v); 6 | SQInteger _stream_readline(HSQUIRRELVM v); 7 | SQInteger _stream_readn(HSQUIRRELVM v); 8 | SQInteger _stream_writeblob(HSQUIRRELVM v); 9 | SQInteger _stream_writen(HSQUIRRELVM v); 10 | SQInteger _stream_seek(HSQUIRRELVM v); 11 | SQInteger _stream_tell(HSQUIRRELVM v); 12 | SQInteger _stream_len(HSQUIRRELVM v); 13 | SQInteger _stream_eos(HSQUIRRELVM v); 14 | SQInteger _stream_flush(HSQUIRRELVM v); 15 | 16 | #define _DECL_STREAM_FUNC(name,nparams,typecheck) {_SC(#name),_stream_##name,nparams,typecheck} 17 | SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,const SQRegFunction *methods,const SQRegFunction *globals); 18 | #endif /*_SQSTD_STREAM_H_*/ 19 | -------------------------------------------------------------------------------- /sqstdlib/sqstdsystem.cpp: -------------------------------------------------------------------------------- 1 | /* see copyright notice in squirrel.h */ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #if defined(__APPLE__) && !defined(IOS) 9 | #include 10 | #if TARGET_OS_IPHONE 11 | #define IOS 12 | #endif 13 | #endif 14 | 15 | #ifdef SQUNICODE 16 | #include 17 | #define scgetenv _wgetenv 18 | #define scsystem _wsystem 19 | #define scasctime _wasctime 20 | #define scremove _wremove 21 | #define screname _wrename 22 | #else 23 | #define scgetenv getenv 24 | #define scsystem system 25 | #define scasctime asctime 26 | #define scremove remove 27 | #define screname rename 28 | #endif 29 | #ifdef IOS 30 | #include 31 | extern char **environ; 32 | #endif 33 | 34 | static SQInteger _system_getenv(HSQUIRRELVM v) 35 | { 36 | const SQChar *s; 37 | if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){ 38 | sq_pushstring(v,scgetenv(s),-1); 39 | return 1; 40 | } 41 | return 0; 42 | } 43 | 44 | static SQInteger _system_system(HSQUIRRELVM v) 45 | { 46 | const SQChar *s; 47 | if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){ 48 | #ifdef IOS 49 | pid_t pid; 50 | posix_spawn(&pid, s, NULL, NULL, NULL, environ); 51 | sq_pushinteger(v, 0); 52 | #else 53 | sq_pushinteger(v,scsystem(s)); 54 | #endif 55 | return 1; 56 | } 57 | return sq_throwerror(v,_SC("wrong param")); 58 | } 59 | 60 | static SQInteger _system_clock(HSQUIRRELVM v) 61 | { 62 | sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC); 63 | return 1; 64 | } 65 | 66 | static SQInteger _system_time(HSQUIRRELVM v) 67 | { 68 | SQInteger t = (SQInteger)time(NULL); 69 | sq_pushinteger(v,t); 70 | return 1; 71 | } 72 | 73 | static SQInteger _system_remove(HSQUIRRELVM v) 74 | { 75 | const SQChar *s; 76 | sq_getstring(v,2,&s); 77 | if(scremove(s)==-1) 78 | return sq_throwerror(v,_SC("remove() failed")); 79 | return 0; 80 | } 81 | 82 | static SQInteger _system_rename(HSQUIRRELVM v) 83 | { 84 | const SQChar *oldn,*newn; 85 | sq_getstring(v,2,&oldn); 86 | sq_getstring(v,3,&newn); 87 | if(screname(oldn,newn)==-1) 88 | return sq_throwerror(v,_SC("rename() failed")); 89 | return 0; 90 | } 91 | 92 | static void _set_integer_slot(HSQUIRRELVM v,const SQChar *name,SQInteger val) 93 | { 94 | sq_pushstring(v,name,-1); 95 | sq_pushinteger(v,val); 96 | sq_rawset(v,-3); 97 | } 98 | 99 | static SQInteger _system_date(HSQUIRRELVM v) 100 | { 101 | time_t t; 102 | SQInteger it; 103 | SQInteger format = 'l'; 104 | if(sq_gettop(v) > 1) { 105 | sq_getinteger(v,2,&it); 106 | t = it; 107 | if(sq_gettop(v) > 2) { 108 | sq_getinteger(v,3,(SQInteger*)&format); 109 | } 110 | } 111 | else { 112 | time(&t); 113 | } 114 | tm *date; 115 | if(format == 'u') 116 | date = gmtime(&t); 117 | else 118 | date = localtime(&t); 119 | if(!date) 120 | return sq_throwerror(v,_SC("crt api failure")); 121 | sq_newtable(v); 122 | _set_integer_slot(v, _SC("sec"), date->tm_sec); 123 | _set_integer_slot(v, _SC("min"), date->tm_min); 124 | _set_integer_slot(v, _SC("hour"), date->tm_hour); 125 | _set_integer_slot(v, _SC("day"), date->tm_mday); 126 | _set_integer_slot(v, _SC("month"), date->tm_mon); 127 | _set_integer_slot(v, _SC("year"), date->tm_year+1900); 128 | _set_integer_slot(v, _SC("wday"), date->tm_wday); 129 | _set_integer_slot(v, _SC("yday"), date->tm_yday); 130 | return 1; 131 | } 132 | 133 | 134 | 135 | #define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask} 136 | static const SQRegFunction systemlib_funcs[]={ 137 | _DECL_FUNC(getenv,2,_SC(".s")), 138 | _DECL_FUNC(system,2,_SC(".s")), 139 | _DECL_FUNC(clock,0,NULL), 140 | _DECL_FUNC(time,1,NULL), 141 | _DECL_FUNC(date,-1,_SC(".nn")), 142 | _DECL_FUNC(remove,2,_SC(".s")), 143 | _DECL_FUNC(rename,3,_SC(".ss")), 144 | {NULL,(SQFUNCTION)0,0,NULL} 145 | }; 146 | #undef _DECL_FUNC 147 | 148 | SQInteger sqstd_register_systemlib(HSQUIRRELVM v) 149 | { 150 | SQInteger i=0; 151 | while(systemlib_funcs[i].name!=0) 152 | { 153 | sq_pushstring(v,systemlib_funcs[i].name,-1); 154 | sq_newclosure(v,systemlib_funcs[i].f,0); 155 | sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask); 156 | sq_setnativeclosurename(v,-1,systemlib_funcs[i].name); 157 | sq_newslot(v,-3,SQFalse); 158 | i++; 159 | } 160 | return 1; 161 | } 162 | -------------------------------------------------------------------------------- /squirrel-config.cmake.in: -------------------------------------------------------------------------------- 1 | @PACKAGE_INIT@ 2 | 3 | include("${CMAKE_CURRENT_LIST_DIR}/squirrel-config-version.cmake") 4 | include("${CMAKE_CURRENT_LIST_DIR}/squirrel-targets.cmake") 5 | -------------------------------------------------------------------------------- /squirrel.dsw: -------------------------------------------------------------------------------- 1 | Microsoft Developer Studio Workspace File, Format Version 6.00 2 | # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! 3 | 4 | ############################################################################### 5 | 6 | Project: "sq"=.\sq\sq.dsp - Package Owner=<4> 7 | 8 | Package=<5> 9 | {{{ 10 | begin source code control 11 | . 12 | end source code control 13 | }}} 14 | 15 | Package=<4> 16 | {{{ 17 | Begin Project Dependency 18 | Project_Dep_Name sqlibs 19 | End Project Dependency 20 | Begin Project Dependency 21 | Project_Dep_Name squirrel 22 | End Project Dependency 23 | Begin Project Dependency 24 | Project_Dep_Name sqstdlib 25 | End Project Dependency 26 | }}} 27 | 28 | ############################################################################### 29 | 30 | Project: "sqstdlib"=.\sqstdlib\sqstdlib.dsp - Package Owner=<4> 31 | 32 | Package=<5> 33 | {{{ 34 | begin source code control 35 | "$/squirrel", HAAAAAAA 36 | . 37 | end source code control 38 | }}} 39 | 40 | Package=<4> 41 | {{{ 42 | }}} 43 | 44 | ############################################################################### 45 | 46 | Project: "squirrel"=.\squirrel\squirrel.dsp - Package Owner=<4> 47 | 48 | Package=<5> 49 | {{{ 50 | begin source code control 51 | "$/squirrel", HAAAAAAA 52 | . 53 | end source code control 54 | }}} 55 | 56 | Package=<4> 57 | {{{ 58 | }}} 59 | 60 | ############################################################################### 61 | 62 | Global: 63 | 64 | Package=<5> 65 | {{{ 66 | begin source code control 67 | "$/squirrel", HAAAAAAA 68 | . 69 | end source code control 70 | }}} 71 | 72 | Package=<3> 73 | {{{ 74 | }}} 75 | 76 | ############################################################################### 77 | 78 | -------------------------------------------------------------------------------- /squirrel.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | libdir=@CMAKE_INSTALL_FULL_LIBDIR@ 3 | includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ 4 | 5 | Name: @PROJECT_NAME@ 6 | Version: @PROJECT_VERSION@ 7 | Description: @PROJECT_DESCRIPTION@ 8 | URL: @PROJECT_HOMEPAGE_URL@ 9 | Requires: 10 | Provides: squirrel3 = @PROJECT_VERSION@ 11 | Libs: -L${libdir} -l@LIBSQUIRREL_NAME@ -l@SQSTDLIB_NAME@ 12 | Cflags: -I${includedir} 13 | -------------------------------------------------------------------------------- /squirrel/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SQUIRREL_SRC sqapi.cpp 2 | sqbaselib.cpp 3 | sqclass.cpp 4 | sqcompiler.cpp 5 | sqdebug.cpp 6 | sqfuncstate.cpp 7 | sqlexer.cpp 8 | sqmem.cpp 9 | sqobject.cpp 10 | sqstate.cpp 11 | sqtable.cpp 12 | sqvm.cpp) 13 | 14 | if(NOT DISABLE_DYNAMIC) 15 | add_library(squirrel SHARED ${SQUIRREL_SRC}) 16 | add_library(squirrel::squirrel ALIAS squirrel) 17 | set_property(TARGET squirrel PROPERTY EXPORT_NAME squirrel) 18 | set_property(TARGET squirrel PROPERTY OUTPUT_NAME ${LIBSQUIRREL_NAME}) 19 | if(NOT SQ_DISABLE_INSTALLER) 20 | install(TARGETS squirrel EXPORT squirrel 21 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Libraries 22 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Libraries NAMELINK_SKIP 23 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Libraries 24 | ) 25 | install(TARGETS squirrel EXPORT squirrel 26 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Development NAMELINK_ONLY 27 | ) 28 | endif() 29 | target_include_directories(squirrel PUBLIC 30 | "$" 31 | "$" 32 | ) 33 | endif() 34 | 35 | if(NOT DISABLE_STATIC) 36 | add_library(squirrel_static STATIC ${SQUIRREL_SRC}) 37 | add_library(squirrel::squirrel_static ALIAS squirrel_static) 38 | set_property(TARGET squirrel_static PROPERTY EXPORT_NAME squirrel_static) 39 | if(NOT SQ_DISABLE_INSTALLER) 40 | install(TARGETS squirrel_static EXPORT squirrel ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Development) 41 | endif() 42 | target_include_directories(squirrel_static PUBLIC 43 | "$" 44 | "$" 45 | ) 46 | endif() 47 | 48 | if(LONG_OUTPUT_NAMES) 49 | if(NOT DISABLE_STATIC) 50 | set_target_properties(squirrel_static PROPERTIES OUTPUT_NAME squirrel3_static) 51 | endif() 52 | endif() 53 | -------------------------------------------------------------------------------- /squirrel/Makefile: -------------------------------------------------------------------------------- 1 | SQUIRREL= .. 2 | 3 | 4 | CC?= gcc 5 | OUT?= $(SQUIRREL)/lib/libsquirrel.a 6 | INCZ?= -I$(SQUIRREL)/include -I. -Iinclude 7 | DEFS= $(CC_EXTRA_FLAGS) 8 | LIB= 9 | 10 | OBJS= \ 11 | sqapi.o \ 12 | sqbaselib.o \ 13 | sqfuncstate.o \ 14 | sqdebug.o \ 15 | sqlexer.o \ 16 | sqobject.o \ 17 | sqcompiler.o \ 18 | sqstate.o \ 19 | sqtable.o \ 20 | sqmem.o \ 21 | sqvm.o \ 22 | sqclass.o 23 | 24 | SRCS= \ 25 | sqapi.cpp \ 26 | sqbaselib.cpp \ 27 | sqfuncstate.cpp \ 28 | sqdebug.cpp \ 29 | sqlexer.cpp \ 30 | sqobject.cpp \ 31 | sqcompiler.cpp \ 32 | sqstate.cpp \ 33 | sqtable.cpp \ 34 | sqmem.cpp \ 35 | sqvm.cpp \ 36 | sqclass.cpp 37 | 38 | 39 | 40 | sq32: 41 | $(CC) -O2 -fno-exceptions -fno-rtti -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS) 42 | ar rc $(OUT) *.o 43 | rm *.o 44 | 45 | sqprof: 46 | $(CC) -O2 -pg -fno-exceptions -fno-rtti -pie -gstabs -g3 -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS) 47 | ar rc $(OUT) *.o 48 | rm *.o 49 | 50 | sq64: 51 | $(CC) -O2 -m64 -D_SQ64 -fno-exceptions -fno-rtti -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS) 52 | ar rc $(OUT) *.o 53 | rm *.o 54 | -------------------------------------------------------------------------------- /squirrel/sqarray.h: -------------------------------------------------------------------------------- 1 | /* see copyright notice in squirrel.h */ 2 | #ifndef _SQARRAY_H_ 3 | #define _SQARRAY_H_ 4 | 5 | struct SQArray : public CHAINABLE_OBJ 6 | { 7 | private: 8 | SQArray(SQSharedState *ss,SQInteger nsize){_values.resize(nsize); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);} 9 | ~SQArray() 10 | { 11 | REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); 12 | } 13 | public: 14 | static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){ 15 | SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray)); 16 | new (newarray) SQArray(ss,nInitialSize); 17 | return newarray; 18 | } 19 | #ifndef NO_GARBAGE_COLLECTOR 20 | void Mark(SQCollectable **chain); 21 | SQObjectType GetType() {return OT_ARRAY;} 22 | #endif 23 | void Finalize(){ 24 | _values.resize(0); 25 | } 26 | bool Get(const SQInteger nidx,SQObjectPtr &val) 27 | { 28 | if(nidx>=0 && nidx<(SQInteger)_values.size()){ 29 | SQObjectPtr &o = _values[nidx]; 30 | val = _realval(o); 31 | return true; 32 | } 33 | else return false; 34 | } 35 | bool Set(const SQInteger nidx,const SQObjectPtr &val) 36 | { 37 | if(nidx>=0 && nidx<(SQInteger)_values.size()){ 38 | _values[nidx]=val; 39 | return true; 40 | } 41 | else return false; 42 | } 43 | SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval) 44 | { 45 | SQUnsignedInteger idx=TranslateIndex(refpos); 46 | while(idx<_values.size()){ 47 | //first found 48 | outkey=(SQInteger)idx; 49 | SQObjectPtr &o = _values[idx]; 50 | outval = _realval(o); 51 | //return idx for the next iteration 52 | return ++idx; 53 | } 54 | //nothing to iterate anymore 55 | return -1; 56 | } 57 | SQArray *Clone(){SQArray *anew=Create(_opt_ss(this),0); anew->_values.copy(_values); return anew; } 58 | SQInteger Size() const {return _values.size();} 59 | void Resize(SQInteger size) 60 | { 61 | SQObjectPtr _null; 62 | Resize(size,_null); 63 | } 64 | void Resize(SQInteger size,SQObjectPtr &fill) { _values.resize(size,fill); ShrinkIfNeeded(); } 65 | void Reserve(SQInteger size) { _values.reserve(size); } 66 | void Append(const SQObject &o){_values.push_back(o);} 67 | void Extend(const SQArray *a); 68 | SQObjectPtr &Top(){return _values.top();} 69 | void Pop(){_values.pop_back(); ShrinkIfNeeded(); } 70 | bool Insert(SQInteger idx,const SQObject &val){ 71 | if(idx < 0 || idx > (SQInteger)_values.size()) 72 | return false; 73 | _values.insert(idx,val); 74 | return true; 75 | } 76 | void ShrinkIfNeeded() { 77 | if(_values.size() <= _values.capacity()>>2) //shrink the array 78 | _values.shrinktofit(); 79 | } 80 | bool Remove(SQInteger idx){ 81 | if(idx < 0 || idx >= (SQInteger)_values.size()) 82 | return false; 83 | _values.remove(idx); 84 | ShrinkIfNeeded(); 85 | return true; 86 | } 87 | void Release() 88 | { 89 | sq_delete(this,SQArray); 90 | } 91 | 92 | SQObjectPtrVec _values; 93 | }; 94 | #endif //_SQARRAY_H_ 95 | -------------------------------------------------------------------------------- /squirrel/sqclass.h: -------------------------------------------------------------------------------- 1 | /* see copyright notice in squirrel.h */ 2 | #ifndef _SQCLASS_H_ 3 | #define _SQCLASS_H_ 4 | 5 | struct SQInstance; 6 | 7 | struct SQClassMember { 8 | SQObjectPtr val; 9 | SQObjectPtr attrs; 10 | void Null() { 11 | val.Null(); 12 | attrs.Null(); 13 | } 14 | }; 15 | 16 | typedef sqvector SQClassMemberVec; 17 | 18 | #define MEMBER_TYPE_METHOD 0x01000000 19 | #define MEMBER_TYPE_FIELD 0x02000000 20 | #define MEMBER_MAX_COUNT 0x00FFFFFF 21 | 22 | #define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD) 23 | #define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD) 24 | #define _make_method_idx(i) ((SQInteger)(MEMBER_TYPE_METHOD|i)) 25 | #define _make_field_idx(i) ((SQInteger)(MEMBER_TYPE_FIELD|i)) 26 | #define _member_type(o) (_integer(o)&0xFF000000) 27 | #define _member_idx(o) (_integer(o)&0x00FFFFFF) 28 | 29 | struct SQClass : public CHAINABLE_OBJ 30 | { 31 | SQClass(SQSharedState *ss,SQClass *base); 32 | public: 33 | static SQClass* Create(SQSharedState *ss,SQClass *base) { 34 | SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass)); 35 | new (newclass) SQClass(ss, base); 36 | return newclass; 37 | } 38 | ~SQClass(); 39 | bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic); 40 | bool Get(const SQObjectPtr &key,SQObjectPtr &val) { 41 | if(_members->Get(key,val)) { 42 | if(_isfield(val)) { 43 | SQObjectPtr &o = _defaultvalues[_member_idx(val)].val; 44 | val = _realval(o); 45 | } 46 | else { 47 | val = _methods[_member_idx(val)].val; 48 | } 49 | return true; 50 | } 51 | return false; 52 | } 53 | bool GetConstructor(SQObjectPtr &ctor) 54 | { 55 | if(_constructoridx != -1) { 56 | ctor = _methods[_constructoridx].val; 57 | return true; 58 | } 59 | return false; 60 | } 61 | bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val); 62 | bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval); 63 | void Lock() { _locked = true; if(_base) _base->Lock(); } 64 | void Release() { 65 | if (_hook) { _hook(_typetag,0);} 66 | sq_delete(this, SQClass); 67 | } 68 | void Finalize(); 69 | #ifndef NO_GARBAGE_COLLECTOR 70 | void Mark(SQCollectable ** ); 71 | SQObjectType GetType() {return OT_CLASS;} 72 | #endif 73 | SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); 74 | SQInstance *CreateInstance(); 75 | SQTable *_members; 76 | SQClass *_base; 77 | SQClassMemberVec _defaultvalues; 78 | SQClassMemberVec _methods; 79 | SQObjectPtr _metamethods[MT_LAST]; 80 | SQObjectPtr _attributes; 81 | SQUserPointer _typetag; 82 | SQRELEASEHOOK _hook; 83 | bool _locked; 84 | SQInteger _constructoridx; 85 | SQInteger _udsize; 86 | }; 87 | 88 | #define calcinstancesize(_theclass_) \ 89 | (_theclass_->_udsize + sq_aligning(sizeof(SQInstance) + (sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0)))) 90 | 91 | struct SQInstance : public SQDelegable 92 | { 93 | void Init(SQSharedState *ss); 94 | SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize); 95 | SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize); 96 | public: 97 | static SQInstance* Create(SQSharedState *ss,SQClass *theclass) { 98 | 99 | SQInteger size = calcinstancesize(theclass); 100 | SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); 101 | new (newinst) SQInstance(ss, theclass,size); 102 | if(theclass->_udsize) { 103 | newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize); 104 | } 105 | return newinst; 106 | } 107 | SQInstance *Clone(SQSharedState *ss) 108 | { 109 | SQInteger size = calcinstancesize(_class); 110 | SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); 111 | new (newinst) SQInstance(ss, this,size); 112 | if(_class->_udsize) { 113 | newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize); 114 | } 115 | return newinst; 116 | } 117 | ~SQInstance(); 118 | bool Get(const SQObjectPtr &key,SQObjectPtr &val) { 119 | if(_class->_members->Get(key,val)) { 120 | if(_isfield(val)) { 121 | SQObjectPtr &o = _values[_member_idx(val)]; 122 | val = _realval(o); 123 | } 124 | else { 125 | val = _class->_methods[_member_idx(val)].val; 126 | } 127 | return true; 128 | } 129 | return false; 130 | } 131 | bool Set(const SQObjectPtr &key,const SQObjectPtr &val) { 132 | SQObjectPtr idx; 133 | if(_class->_members->Get(key,idx) && _isfield(idx)) { 134 | _values[_member_idx(idx)] = val; 135 | return true; 136 | } 137 | return false; 138 | } 139 | void Release() { 140 | _uiRef++; 141 | if (_hook) { _hook(_userpointer,0);} 142 | _uiRef--; 143 | if(_uiRef > 0) return; 144 | SQInteger size = _memsize; 145 | this->~SQInstance(); 146 | SQ_FREE(this, size); 147 | } 148 | void Finalize(); 149 | #ifndef NO_GARBAGE_COLLECTOR 150 | void Mark(SQCollectable ** ); 151 | SQObjectType GetType() {return OT_INSTANCE;} 152 | #endif 153 | bool InstanceOf(SQClass *trg); 154 | bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res); 155 | 156 | SQClass *_class; 157 | SQUserPointer _userpointer; 158 | SQRELEASEHOOK _hook; 159 | SQInteger _memsize; 160 | SQObjectPtr _values[1]; 161 | }; 162 | 163 | #endif //_SQCLASS_H_ 164 | -------------------------------------------------------------------------------- /squirrel/sqcompiler.h: -------------------------------------------------------------------------------- 1 | /* see copyright notice in squirrel.h */ 2 | #ifndef _SQCOMPILER_H_ 3 | #define _SQCOMPILER_H_ 4 | 5 | struct SQVM; 6 | 7 | #define TK_IDENTIFIER 258 8 | #define TK_STRING_LITERAL 259 9 | #define TK_INTEGER 260 10 | #define TK_FLOAT 261 11 | #define TK_BASE 262 12 | #define TK_DELETE 263 13 | #define TK_EQ 264 14 | #define TK_NE 265 15 | #define TK_LE 266 16 | #define TK_GE 267 17 | #define TK_SWITCH 268 18 | #define TK_ARROW 269 19 | #define TK_AND 270 20 | #define TK_OR 271 21 | #define TK_IF 272 22 | #define TK_ELSE 273 23 | #define TK_WHILE 274 24 | #define TK_BREAK 275 25 | #define TK_FOR 276 26 | #define TK_DO 277 27 | #define TK_NULL 278 28 | #define TK_FOREACH 279 29 | #define TK_IN 280 30 | #define TK_NEWSLOT 281 31 | #define TK_MODULO 282 32 | #define TK_LOCAL 283 33 | #define TK_CLONE 284 34 | #define TK_FUNCTION 285 35 | #define TK_RETURN 286 36 | #define TK_TYPEOF 287 37 | #define TK_UMINUS 288 38 | #define TK_PLUSEQ 289 39 | #define TK_MINUSEQ 290 40 | #define TK_CONTINUE 291 41 | #define TK_YIELD 292 42 | #define TK_TRY 293 43 | #define TK_CATCH 294 44 | #define TK_THROW 295 45 | #define TK_SHIFTL 296 46 | #define TK_SHIFTR 297 47 | #define TK_RESUME 298 48 | #define TK_DOUBLE_COLON 299 49 | #define TK_CASE 300 50 | #define TK_DEFAULT 301 51 | #define TK_THIS 302 52 | #define TK_PLUSPLUS 303 53 | #define TK_MINUSMINUS 304 54 | #define TK_3WAYSCMP 305 55 | #define TK_USHIFTR 306 56 | #define TK_CLASS 307 57 | #define TK_EXTENDS 308 58 | #define TK_CONSTRUCTOR 310 59 | #define TK_INSTANCEOF 311 60 | #define TK_VARPARAMS 312 61 | #define TK___LINE__ 313 62 | #define TK___FILE__ 314 63 | #define TK_TRUE 315 64 | #define TK_FALSE 316 65 | #define TK_MULEQ 317 66 | #define TK_DIVEQ 318 67 | #define TK_MODEQ 319 68 | #define TK_ATTR_OPEN 320 69 | #define TK_ATTR_CLOSE 321 70 | #define TK_STATIC 322 71 | #define TK_ENUM 323 72 | #define TK_CONST 324 73 | #define TK_RAWCALL 325 74 | 75 | 76 | 77 | typedef void(*CompilerErrorFunc)(void *ud, const SQChar *s); 78 | bool Compile(SQVM *vm, SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo); 79 | #endif //_SQCOMPILER_H_ 80 | -------------------------------------------------------------------------------- /squirrel/sqdebug.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | see copyright notice in squirrel.h 3 | */ 4 | #include "sqpcheader.h" 5 | #include 6 | #include "sqvm.h" 7 | #include "sqfuncproto.h" 8 | #include "sqclosure.h" 9 | #include "sqstring.h" 10 | 11 | SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger level,SQFunctionInfo *fi) 12 | { 13 | SQInteger cssize = v->_callsstacksize; 14 | if (cssize > level) { 15 | SQVM::CallInfo &ci = v->_callsstack[cssize-level-1]; 16 | if(sq_isclosure(ci._closure)) { 17 | SQClosure *c = _closure(ci._closure); 18 | SQFunctionProto *proto = c->_function; 19 | fi->funcid = proto; 20 | fi->name = sq_type(proto->_name) == OT_STRING?_stringval(proto->_name):_SC("unknown"); 21 | fi->source = sq_type(proto->_sourcename) == OT_STRING?_stringval(proto->_sourcename):_SC("unknown"); 22 | fi->line = proto->_lineinfos[0]._line; 23 | return SQ_OK; 24 | } 25 | } 26 | return sq_throwerror(v,_SC("the object is not a closure")); 27 | } 28 | 29 | SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si) 30 | { 31 | SQInteger cssize = v->_callsstacksize; 32 | if (cssize > level) { 33 | memset(si, 0, sizeof(SQStackInfos)); 34 | SQVM::CallInfo &ci = v->_callsstack[cssize-level-1]; 35 | switch (sq_type(ci._closure)) { 36 | case OT_CLOSURE:{ 37 | SQFunctionProto *func = _closure(ci._closure)->_function; 38 | if (sq_type(func->_name) == OT_STRING) 39 | si->funcname = _stringval(func->_name); 40 | if (sq_type(func->_sourcename) == OT_STRING) 41 | si->source = _stringval(func->_sourcename); 42 | si->line = func->GetLine(ci._ip); 43 | } 44 | break; 45 | case OT_NATIVECLOSURE: 46 | si->source = _SC("NATIVE"); 47 | si->funcname = _SC("unknown"); 48 | if(sq_type(_nativeclosure(ci._closure)->_name) == OT_STRING) 49 | si->funcname = _stringval(_nativeclosure(ci._closure)->_name); 50 | si->line = -1; 51 | break; 52 | default: break; //shutup compiler 53 | } 54 | return SQ_OK; 55 | } 56 | return SQ_ERROR; 57 | } 58 | 59 | void SQVM::Raise_Error(const SQChar *s, ...) 60 | { 61 | va_list vl; 62 | va_start(vl, s); 63 | SQInteger buffersize = (SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2); 64 | scvsprintf(_sp(sq_rsl(buffersize)),buffersize, s, vl); 65 | va_end(vl); 66 | _lasterror = SQString::Create(_ss(this),_spval,-1); 67 | } 68 | 69 | void SQVM::Raise_Error(const SQObjectPtr &desc) 70 | { 71 | _lasterror = desc; 72 | } 73 | 74 | SQString *SQVM::PrintObjVal(const SQObjectPtr &o) 75 | { 76 | switch(sq_type(o)) { 77 | case OT_STRING: return _string(o); 78 | case OT_INTEGER: 79 | scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)),sq_rsl(NUMBER_MAX_CHAR), _PRINT_INT_FMT, _integer(o)); 80 | return SQString::Create(_ss(this), _spval); 81 | break; 82 | case OT_FLOAT: 83 | scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)), sq_rsl(NUMBER_MAX_CHAR), _SC("%.14g"), _float(o)); 84 | return SQString::Create(_ss(this), _spval); 85 | break; 86 | default: 87 | return SQString::Create(_ss(this), GetTypeName(o)); 88 | } 89 | } 90 | 91 | void SQVM::Raise_IdxError(const SQObjectPtr &o) 92 | { 93 | SQObjectPtr oval = PrintObjVal(o); 94 | Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval)); 95 | } 96 | 97 | void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2) 98 | { 99 | SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2); 100 | Raise_Error(_SC("comparison between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2)); 101 | } 102 | 103 | 104 | void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type) 105 | { 106 | SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1); 107 | SQInteger found = 0; 108 | for(SQInteger i=0; i<16; i++) 109 | { 110 | SQInteger mask = ((SQInteger)1) << i; 111 | if(typemask & (mask)) { 112 | if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes); 113 | found ++; 114 | StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes); 115 | } 116 | } 117 | Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes)); 118 | } 119 | -------------------------------------------------------------------------------- /squirrel/sqfuncproto.h: -------------------------------------------------------------------------------- 1 | /* see copyright notice in squirrel.h */ 2 | #ifndef _SQFUNCTION_H_ 3 | #define _SQFUNCTION_H_ 4 | 5 | #include "sqopcodes.h" 6 | 7 | enum SQOuterType { 8 | otLOCAL = 0, 9 | otOUTER = 1 10 | }; 11 | 12 | struct SQOuterVar 13 | { 14 | 15 | SQOuterVar(){} 16 | SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t) 17 | { 18 | _name = name; 19 | _src=src; 20 | _type=t; 21 | } 22 | SQOuterVar(const SQOuterVar &ov) 23 | { 24 | _type=ov._type; 25 | _src=ov._src; 26 | _name=ov._name; 27 | } 28 | SQOuterType _type; 29 | SQObjectPtr _name; 30 | SQObjectPtr _src; 31 | }; 32 | 33 | struct SQLocalVarInfo 34 | { 35 | SQLocalVarInfo():_start_op(0),_end_op(0),_pos(0){} 36 | SQLocalVarInfo(const SQLocalVarInfo &lvi) 37 | { 38 | _name=lvi._name; 39 | _start_op=lvi._start_op; 40 | _end_op=lvi._end_op; 41 | _pos=lvi._pos; 42 | } 43 | SQObjectPtr _name; 44 | SQUnsignedInteger _start_op; 45 | SQUnsignedInteger _end_op; 46 | SQUnsignedInteger _pos; 47 | }; 48 | 49 | struct SQLineInfo { SQInteger _line;SQInteger _op; }; 50 | 51 | typedef sqvector SQOuterVarVec; 52 | typedef sqvector SQLocalVarInfoVec; 53 | typedef sqvector SQLineInfoVec; 54 | 55 | #define _FUNC_SIZE(ni,nl,nparams,nfuncs,nouters,nlineinf,localinf,defparams) (sizeof(SQFunctionProto) \ 56 | +((ni-1)*sizeof(SQInstruction))+(nl*sizeof(SQObjectPtr)) \ 57 | +(nparams*sizeof(SQObjectPtr))+(nfuncs*sizeof(SQObjectPtr)) \ 58 | +(nouters*sizeof(SQOuterVar))+(nlineinf*sizeof(SQLineInfo)) \ 59 | +(localinf*sizeof(SQLocalVarInfo))+(defparams*sizeof(SQInteger))) 60 | 61 | 62 | struct SQFunctionProto : public CHAINABLE_OBJ 63 | { 64 | private: 65 | SQFunctionProto(SQSharedState *ss); 66 | ~SQFunctionProto(); 67 | 68 | public: 69 | static SQFunctionProto *Create(SQSharedState *ss,SQInteger ninstructions, 70 | SQInteger nliterals,SQInteger nparameters, 71 | SQInteger nfunctions,SQInteger noutervalues, 72 | SQInteger nlineinfos,SQInteger nlocalvarinfos,SQInteger ndefaultparams) 73 | { 74 | SQFunctionProto *f; 75 | //I compact the whole class and members in a single memory allocation 76 | f = (SQFunctionProto *)sq_vm_malloc(_FUNC_SIZE(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams)); 77 | new (f) SQFunctionProto(ss); 78 | f->_ninstructions = ninstructions; 79 | f->_literals = (SQObjectPtr*)&f->_instructions[ninstructions]; 80 | f->_nliterals = nliterals; 81 | f->_parameters = (SQObjectPtr*)&f->_literals[nliterals]; 82 | f->_nparameters = nparameters; 83 | f->_functions = (SQObjectPtr*)&f->_parameters[nparameters]; 84 | f->_nfunctions = nfunctions; 85 | f->_outervalues = (SQOuterVar*)&f->_functions[nfunctions]; 86 | f->_noutervalues = noutervalues; 87 | f->_lineinfos = (SQLineInfo *)&f->_outervalues[noutervalues]; 88 | f->_nlineinfos = nlineinfos; 89 | f->_localvarinfos = (SQLocalVarInfo *)&f->_lineinfos[nlineinfos]; 90 | f->_nlocalvarinfos = nlocalvarinfos; 91 | f->_defaultparams = (SQInteger *)&f->_localvarinfos[nlocalvarinfos]; 92 | f->_ndefaultparams = ndefaultparams; 93 | 94 | _CONSTRUCT_VECTOR(SQObjectPtr,f->_nliterals,f->_literals); 95 | _CONSTRUCT_VECTOR(SQObjectPtr,f->_nparameters,f->_parameters); 96 | _CONSTRUCT_VECTOR(SQObjectPtr,f->_nfunctions,f->_functions); 97 | _CONSTRUCT_VECTOR(SQOuterVar,f->_noutervalues,f->_outervalues); 98 | //_CONSTRUCT_VECTOR(SQLineInfo,f->_nlineinfos,f->_lineinfos); //not required are 2 integers 99 | _CONSTRUCT_VECTOR(SQLocalVarInfo,f->_nlocalvarinfos,f->_localvarinfos); 100 | return f; 101 | } 102 | void Release(){ 103 | _DESTRUCT_VECTOR(SQObjectPtr,_nliterals,_literals); 104 | _DESTRUCT_VECTOR(SQObjectPtr,_nparameters,_parameters); 105 | _DESTRUCT_VECTOR(SQObjectPtr,_nfunctions,_functions); 106 | _DESTRUCT_VECTOR(SQOuterVar,_noutervalues,_outervalues); 107 | //_DESTRUCT_VECTOR(SQLineInfo,_nlineinfos,_lineinfos); //not required are 2 integers 108 | _DESTRUCT_VECTOR(SQLocalVarInfo,_nlocalvarinfos,_localvarinfos); 109 | SQInteger size = _FUNC_SIZE(_ninstructions,_nliterals,_nparameters,_nfunctions,_noutervalues,_nlineinfos,_nlocalvarinfos,_ndefaultparams); 110 | this->~SQFunctionProto(); 111 | sq_vm_free(this,size); 112 | } 113 | 114 | const SQChar* GetLocal(SQVM *v,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop); 115 | SQInteger GetLine(SQInstruction *curr); 116 | bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write); 117 | static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret); 118 | #ifndef NO_GARBAGE_COLLECTOR 119 | void Mark(SQCollectable **chain); 120 | void Finalize(){ _NULL_SQOBJECT_VECTOR(_literals,_nliterals); } 121 | SQObjectType GetType() {return OT_FUNCPROTO;} 122 | #endif 123 | SQObjectPtr _sourcename; 124 | SQObjectPtr _name; 125 | SQInteger _stacksize; 126 | bool _bgenerator; 127 | SQInteger _varparams; 128 | 129 | SQInteger _nlocalvarinfos; 130 | SQLocalVarInfo *_localvarinfos; 131 | 132 | SQInteger _nlineinfos; 133 | SQLineInfo *_lineinfos; 134 | 135 | SQInteger _nliterals; 136 | SQObjectPtr *_literals; 137 | 138 | SQInteger _nparameters; 139 | SQObjectPtr *_parameters; 140 | 141 | SQInteger _nfunctions; 142 | SQObjectPtr *_functions; 143 | 144 | SQInteger _noutervalues; 145 | SQOuterVar *_outervalues; 146 | 147 | SQInteger _ndefaultparams; 148 | SQInteger *_defaultparams; 149 | 150 | SQInteger _ninstructions; 151 | SQInstruction _instructions[1]; 152 | }; 153 | 154 | #endif //_SQFUNCTION_H_ 155 | -------------------------------------------------------------------------------- /squirrel/sqfuncstate.h: -------------------------------------------------------------------------------- 1 | /* see copyright notice in squirrel.h */ 2 | #ifndef _SQFUNCSTATE_H_ 3 | #define _SQFUNCSTATE_H_ 4 | /////////////////////////////////// 5 | #include "squtils.h" 6 | 7 | struct SQFuncState 8 | { 9 | SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed); 10 | ~SQFuncState(); 11 | #ifdef _DEBUG_DUMP 12 | void Dump(SQFunctionProto *func); 13 | #endif 14 | void Error(const SQChar *err); 15 | SQFuncState *PushChildState(SQSharedState *ss); 16 | void PopChildState(); 17 | void AddInstruction(SQOpcode _op,SQInteger arg0=0,SQInteger arg1=0,SQInteger arg2=0,SQInteger arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);AddInstruction(i);} 18 | void AddInstruction(SQInstruction &i); 19 | void SetInstructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2=0,SQInteger arg3=0); 20 | void SetInstructionParam(SQInteger pos,SQInteger arg,SQInteger val); 21 | SQInstruction &GetInstruction(SQInteger pos){return _instructions[pos];} 22 | void PopInstructions(SQInteger size){for(SQInteger i=0;i _childstates; 82 | SQInteger GetConstant(const SQObject &cons); 83 | private: 84 | CompilerErrorFunc _errfunc; 85 | void *_errtarget; 86 | SQSharedState *_ss; 87 | }; 88 | 89 | 90 | #endif //_SQFUNCSTATE_H_ 91 | 92 | -------------------------------------------------------------------------------- /squirrel/sqlexer.h: -------------------------------------------------------------------------------- 1 | /* see copyright notice in squirrel.h */ 2 | #ifndef _SQLEXER_H_ 3 | #define _SQLEXER_H_ 4 | 5 | #ifdef SQUNICODE 6 | typedef SQChar LexChar; 7 | #else 8 | typedef unsigned char LexChar; 9 | #endif 10 | 11 | struct SQLexer 12 | { 13 | SQLexer(); 14 | ~SQLexer(); 15 | void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed); 16 | void Error(const SQChar *err); 17 | SQInteger Lex(); 18 | const SQChar *Tok2Str(SQInteger tok); 19 | private: 20 | SQInteger GetIDType(const SQChar *s,SQInteger len); 21 | SQInteger ReadString(SQInteger ndelim,bool verbatim); 22 | SQInteger ReadNumber(); 23 | void LexBlockComment(); 24 | void LexLineComment(); 25 | SQInteger ReadID(); 26 | void Next(); 27 | #ifdef SQUNICODE 28 | #if WCHAR_SIZE == 2 29 | SQInteger AddUTF16(SQUnsignedInteger ch); 30 | #endif 31 | #else 32 | SQInteger AddUTF8(SQUnsignedInteger ch); 33 | #endif 34 | SQInteger ProcessStringHexEscape(SQChar *dest, SQInteger maxdigits); 35 | SQInteger _curtoken; 36 | SQTable *_keywords; 37 | SQBool _reached_eof; 38 | public: 39 | SQInteger _prevtoken; 40 | SQInteger _currentline; 41 | SQInteger _lasttokenline; 42 | SQInteger _currentcolumn; 43 | const SQChar *_svalue; 44 | SQInteger _nvalue; 45 | SQFloat _fvalue; 46 | SQLEXREADFUNC _readf; 47 | SQUserPointer _up; 48 | LexChar _currdata; 49 | SQSharedState *_sharedstate; 50 | sqvector _longstr; 51 | CompilerErrorFunc _errfunc; 52 | void *_errtarget; 53 | }; 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /squirrel/sqmem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | see copyright notice in squirrel.h 3 | */ 4 | #include "sqpcheader.h" 5 | #ifndef SQ_EXCLUDE_DEFAULT_MEMFUNCTIONS 6 | void *sq_vm_malloc(SQUnsignedInteger size){ return malloc(size); } 7 | 8 | void *sq_vm_realloc(void *p, SQUnsignedInteger SQ_UNUSED_ARG(oldsize), SQUnsignedInteger size){ return realloc(p, size); } 9 | 10 | void sq_vm_free(void *p, SQUnsignedInteger SQ_UNUSED_ARG(size)){ free(p); } 11 | #endif 12 | -------------------------------------------------------------------------------- /squirrel/sqopcodes.h: -------------------------------------------------------------------------------- 1 | /* see copyright notice in squirrel.h */ 2 | #ifndef _SQOPCODES_H_ 3 | #define _SQOPCODES_H_ 4 | 5 | #define MAX_FUNC_STACKSIZE 0xFF 6 | #define MAX_LITERALS ((SQInteger)0x7FFFFFFF) 7 | 8 | enum BitWiseOP { 9 | BW_AND = 0, 10 | BW_OR = 2, 11 | BW_XOR = 3, 12 | BW_SHIFTL = 4, 13 | BW_SHIFTR = 5, 14 | BW_USHIFTR = 6 15 | }; 16 | 17 | enum CmpOP { 18 | CMP_G = 0, 19 | CMP_GE = 2, 20 | CMP_L = 3, 21 | CMP_LE = 4, 22 | CMP_3W = 5 23 | }; 24 | 25 | enum NewObjectType { 26 | NOT_TABLE = 0, 27 | NOT_ARRAY = 1, 28 | NOT_CLASS = 2 29 | }; 30 | 31 | enum AppendArrayType { 32 | AAT_STACK = 0, 33 | AAT_LITERAL = 1, 34 | AAT_INT = 2, 35 | AAT_FLOAT = 3, 36 | AAT_BOOL = 4 37 | }; 38 | 39 | enum SQOpcode 40 | { 41 | _OP_LINE= 0x00, 42 | _OP_LOAD= 0x01, 43 | _OP_LOADINT= 0x02, 44 | _OP_LOADFLOAT= 0x03, 45 | _OP_DLOAD= 0x04, 46 | _OP_TAILCALL= 0x05, 47 | _OP_CALL= 0x06, 48 | _OP_PREPCALL= 0x07, 49 | _OP_PREPCALLK= 0x08, 50 | _OP_GETK= 0x09, 51 | _OP_MOVE= 0x0A, 52 | _OP_NEWSLOT= 0x0B, 53 | _OP_DELETE= 0x0C, 54 | _OP_SET= 0x0D, 55 | _OP_GET= 0x0E, 56 | _OP_EQ= 0x0F, 57 | _OP_NE= 0x10, 58 | _OP_ADD= 0x11, 59 | _OP_SUB= 0x12, 60 | _OP_MUL= 0x13, 61 | _OP_DIV= 0x14, 62 | _OP_MOD= 0x15, 63 | _OP_BITW= 0x16, 64 | _OP_RETURN= 0x17, 65 | _OP_LOADNULLS= 0x18, 66 | _OP_LOADROOT= 0x19, 67 | _OP_LOADBOOL= 0x1A, 68 | _OP_DMOVE= 0x1B, 69 | _OP_JMP= 0x1C, 70 | //_OP_JNZ= 0x1D, 71 | _OP_JCMP= 0x1D, 72 | _OP_JZ= 0x1E, 73 | _OP_SETOUTER= 0x1F, 74 | _OP_GETOUTER= 0x20, 75 | _OP_NEWOBJ= 0x21, 76 | _OP_APPENDARRAY= 0x22, 77 | _OP_COMPARITH= 0x23, 78 | _OP_INC= 0x24, 79 | _OP_INCL= 0x25, 80 | _OP_PINC= 0x26, 81 | _OP_PINCL= 0x27, 82 | _OP_CMP= 0x28, 83 | _OP_EXISTS= 0x29, 84 | _OP_INSTANCEOF= 0x2A, 85 | _OP_AND= 0x2B, 86 | _OP_OR= 0x2C, 87 | _OP_NEG= 0x2D, 88 | _OP_NOT= 0x2E, 89 | _OP_BWNOT= 0x2F, 90 | _OP_CLOSURE= 0x30, 91 | _OP_YIELD= 0x31, 92 | _OP_RESUME= 0x32, 93 | _OP_FOREACH= 0x33, 94 | _OP_POSTFOREACH= 0x34, 95 | _OP_CLONE= 0x35, 96 | _OP_TYPEOF= 0x36, 97 | _OP_PUSHTRAP= 0x37, 98 | _OP_POPTRAP= 0x38, 99 | _OP_THROW= 0x39, 100 | _OP_NEWSLOTA= 0x3A, 101 | _OP_GETBASE= 0x3B, 102 | _OP_CLOSE= 0x3C 103 | }; 104 | 105 | struct SQInstructionDesc { 106 | const SQChar *name; 107 | }; 108 | 109 | struct SQInstruction 110 | { 111 | SQInstruction(){}; 112 | SQInstruction(SQOpcode _op,SQInteger a0=0,SQInteger a1=0,SQInteger a2=0,SQInteger a3=0) 113 | { op = (unsigned char)_op; 114 | _arg0 = (unsigned char)a0;_arg1 = (SQInt32)a1; 115 | _arg2 = (unsigned char)a2;_arg3 = (unsigned char)a3; 116 | } 117 | 118 | 119 | SQInt32 _arg1; 120 | unsigned char op; 121 | unsigned char _arg0; 122 | unsigned char _arg2; 123 | unsigned char _arg3; 124 | }; 125 | 126 | #include "squtils.h" 127 | typedef sqvector SQInstructionVec; 128 | 129 | #define NEW_SLOT_ATTRIBUTES_FLAG 0x01 130 | #define NEW_SLOT_STATIC_FLAG 0x02 131 | 132 | #endif // _SQOPCODES_H_ 133 | -------------------------------------------------------------------------------- /squirrel/sqpcheader.h: -------------------------------------------------------------------------------- 1 | /* see copyright notice in squirrel.h */ 2 | #ifndef _SQPCHEADER_H_ 3 | #define _SQPCHEADER_H_ 4 | 5 | #if defined(_MSC_VER) && defined(_DEBUG) 6 | #include 7 | #endif 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | //squirrel stuff 16 | #include 17 | #include "sqobject.h" 18 | #include "sqstate.h" 19 | 20 | #endif //_SQPCHEADER_H_ 21 | -------------------------------------------------------------------------------- /squirrel/sqstate.h: -------------------------------------------------------------------------------- 1 | /* see copyright notice in squirrel.h */ 2 | #ifndef _SQSTATE_H_ 3 | #define _SQSTATE_H_ 4 | 5 | #include "squtils.h" 6 | #include "sqobject.h" 7 | struct SQString; 8 | struct SQTable; 9 | //max number of character for a printed number 10 | #define NUMBER_MAX_CHAR 50 11 | 12 | struct SQStringTable 13 | { 14 | SQStringTable(SQSharedState*ss); 15 | ~SQStringTable(); 16 | SQString *Add(const SQChar *,SQInteger len); 17 | SQString* Concat(const SQChar* a, SQInteger alen, const SQChar* b, SQInteger blen); 18 | void Remove(SQString *); 19 | private: 20 | void Resize(SQInteger size); 21 | void AllocNodes(SQInteger size); 22 | SQString **_strings; 23 | SQUnsignedInteger _numofslots; 24 | SQUnsignedInteger _slotused; 25 | SQSharedState *_sharedstate; 26 | }; 27 | 28 | struct RefTable { 29 | struct RefNode { 30 | SQObjectPtr obj; 31 | SQUnsignedInteger refs; 32 | struct RefNode *next; 33 | }; 34 | RefTable(); 35 | ~RefTable(); 36 | void AddRef(SQObject &obj); 37 | SQBool Release(SQObject &obj); 38 | SQUnsignedInteger GetRefCount(SQObject &obj); 39 | #ifndef NO_GARBAGE_COLLECTOR 40 | void Mark(SQCollectable **chain); 41 | #endif 42 | void Finalize(); 43 | private: 44 | RefNode *Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add); 45 | RefNode *Add(SQHash mainpos,SQObject &obj); 46 | void Resize(SQUnsignedInteger size); 47 | void AllocNodes(SQUnsignedInteger size); 48 | SQUnsignedInteger _numofslots; 49 | SQUnsignedInteger _slotused; 50 | RefNode *_nodes; 51 | RefNode *_freelist; 52 | RefNode **_buckets; 53 | }; 54 | 55 | #define ADD_STRING(ss,str,len) ss->_stringtable->Add(str,len) 56 | #define REMOVE_STRING(ss,bstr) ss->_stringtable->Remove(bstr) 57 | 58 | struct SQObjectPtr; 59 | 60 | struct SQSharedState 61 | { 62 | SQSharedState(); 63 | ~SQSharedState(); 64 | void Init(); 65 | public: 66 | SQChar* GetScratchPad(SQInteger size); 67 | SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name); 68 | #ifndef NO_GARBAGE_COLLECTOR 69 | SQInteger CollectGarbage(SQVM *vm); 70 | void RunMark(SQVM *vm,SQCollectable **tchain); 71 | SQInteger ResurrectUnreachable(SQVM *vm); 72 | static void MarkObject(SQObjectPtr &o,SQCollectable **chain); 73 | #endif 74 | SQObjectPtrVec *_metamethods; 75 | SQObjectPtr _metamethodsmap; 76 | SQObjectPtrVec *_systemstrings; 77 | SQObjectPtrVec *_types; 78 | SQStringTable *_stringtable; 79 | RefTable _refs_table; 80 | SQObjectPtr _registry; 81 | SQObjectPtr _consts; 82 | SQObjectPtr _constructoridx; 83 | #ifndef NO_GARBAGE_COLLECTOR 84 | SQCollectable *_gc_chain; 85 | #endif 86 | SQObjectPtr _root_vm; 87 | SQObjectPtr _table_default_delegate; 88 | static const SQRegFunction _table_default_delegate_funcz[]; 89 | SQObjectPtr _array_default_delegate; 90 | static const SQRegFunction _array_default_delegate_funcz[]; 91 | SQObjectPtr _string_default_delegate; 92 | static const SQRegFunction _string_default_delegate_funcz[]; 93 | SQObjectPtr _number_default_delegate; 94 | static const SQRegFunction _number_default_delegate_funcz[]; 95 | SQObjectPtr _generator_default_delegate; 96 | static const SQRegFunction _generator_default_delegate_funcz[]; 97 | SQObjectPtr _closure_default_delegate; 98 | static const SQRegFunction _closure_default_delegate_funcz[]; 99 | SQObjectPtr _thread_default_delegate; 100 | static const SQRegFunction _thread_default_delegate_funcz[]; 101 | SQObjectPtr _class_default_delegate; 102 | static const SQRegFunction _class_default_delegate_funcz[]; 103 | SQObjectPtr _instance_default_delegate; 104 | static const SQRegFunction _instance_default_delegate_funcz[]; 105 | SQObjectPtr _weakref_default_delegate; 106 | static const SQRegFunction _weakref_default_delegate_funcz[]; 107 | 108 | SQCOMPILERERROR _compilererrorhandler; 109 | SQPRINTFUNCTION _printfunc; 110 | SQPRINTFUNCTION _errorfunc; 111 | bool _debuginfo; 112 | bool _notifyallexceptions; 113 | SQUserPointer _foreignptr; 114 | SQRELEASEHOOK _releasehook; 115 | private: 116 | SQChar *_scratchpad; 117 | SQInteger _scratchpadsize; 118 | }; 119 | 120 | #define _sp(s) (_sharedstate->GetScratchPad(s)) 121 | #define _spval (_sharedstate->GetScratchPad(-1)) 122 | 123 | #define _table_ddel _table(_sharedstate->_table_default_delegate) 124 | #define _array_ddel _table(_sharedstate->_array_default_delegate) 125 | #define _string_ddel _table(_sharedstate->_string_default_delegate) 126 | #define _number_ddel _table(_sharedstate->_number_default_delegate) 127 | #define _generator_ddel _table(_sharedstate->_generator_default_delegate) 128 | #define _closure_ddel _table(_sharedstate->_closure_default_delegate) 129 | #define _thread_ddel _table(_sharedstate->_thread_default_delegate) 130 | #define _class_ddel _table(_sharedstate->_class_default_delegate) 131 | #define _instance_ddel _table(_sharedstate->_instance_default_delegate) 132 | #define _weakref_ddel _table(_sharedstate->_weakref_default_delegate) 133 | 134 | bool CompileTypemask(SQIntVec &res,const SQChar *typemask); 135 | 136 | 137 | #endif //_SQSTATE_H_ 138 | -------------------------------------------------------------------------------- /squirrel/sqstring.h: -------------------------------------------------------------------------------- 1 | /* see copyright notice in squirrel.h */ 2 | #ifndef _SQSTRING_H_ 3 | #define _SQSTRING_H_ 4 | 5 | inline SQHash _hashstr (const SQChar *s, size_t l) 6 | { 7 | SQHash h = (SQHash)l; /* seed */ 8 | size_t step = (l >> 5) + 1; /* if string is too long, don't hash all its chars */ 9 | size_t l1; 10 | for (l1 = l; l1 >= step; l1 -= step) 11 | h = h ^ ((h << 5) + (h >> 2) + ((unsigned short)s[l1 - 1])); 12 | return h; 13 | } 14 | 15 | inline SQHash _hashstr2(const SQChar* as, size_t al, const SQChar* bs, size_t bl) 16 | { 17 | size_t l = al + bl; 18 | SQHash h = (SQHash)l; /* seed */ 19 | SQInteger step = (SQInteger)((l >> 5) + 1); /* if string is too long, don't hash all its chars */ 20 | SQInteger l1 = (SQInteger)l; 21 | for (; l1 >= step; l1 -= step) { 22 | SQInteger idx = l1 - 1 - al; 23 | if (idx < 0) { 24 | break; 25 | } 26 | h = h ^ ((h << 5) + (h >> 2) + ((unsigned short)bs[idx])); 27 | } 28 | for (; l1 >= step; l1 -= step) { 29 | SQInteger idx = l1 - 1; 30 | h = h ^ ((h << 5) + (h >> 2) + ((unsigned short)as[idx])); 31 | } 32 | return h; 33 | } 34 | 35 | struct SQString : public SQRefCounted 36 | { 37 | SQString(){} 38 | ~SQString(){} 39 | public: 40 | static SQString *Create(SQSharedState *ss, const SQChar *, SQInteger len = -1 ); 41 | static SQString* Concat(SQSharedState* ss, const SQChar* a, SQInteger alen, const SQChar* b, SQInteger blen); 42 | SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); 43 | void Release(); 44 | SQSharedState *_sharedstate; 45 | SQString *_next; //chain for the string table 46 | SQInteger _len; 47 | SQHash _hash; 48 | SQChar _val[1]; 49 | }; 50 | 51 | 52 | 53 | #endif //_SQSTRING_H_ 54 | -------------------------------------------------------------------------------- /squirrel/sqtable.h: -------------------------------------------------------------------------------- 1 | /* see copyright notice in squirrel.h */ 2 | #ifndef _SQTABLE_H_ 3 | #define _SQTABLE_H_ 4 | /* 5 | * The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.) 6 | * http://www.lua.org/copyright.html#4 7 | * http://www.lua.org/source/4.0.1/src_ltable.c.html 8 | */ 9 | 10 | #include "sqstring.h" 11 | 12 | 13 | #define hashptr(p) ((SQHash)(((SQInteger)p) >> 3)) 14 | 15 | inline SQHash HashObj(const SQObject &key) 16 | { 17 | switch(sq_type(key)) { 18 | case OT_STRING: return _string(key)->_hash; 19 | case OT_FLOAT: return (SQHash)((SQInteger)_float(key)); 20 | case OT_BOOL: case OT_INTEGER: return (SQHash)((SQInteger)_integer(key)); 21 | default: return hashptr(key._unVal.pRefCounted); 22 | } 23 | } 24 | 25 | struct SQTable : public SQDelegable 26 | { 27 | private: 28 | struct _HashNode 29 | { 30 | _HashNode() { next = NULL; } 31 | SQObjectPtr val; 32 | SQObjectPtr key; 33 | _HashNode *next; 34 | }; 35 | _HashNode *_firstfree; 36 | _HashNode *_nodes; 37 | SQInteger _numofnodes; 38 | SQInteger _usednodes; 39 | 40 | /////////////////////////// 41 | void AllocNodes(SQInteger nSize); 42 | void Rehash(bool force); 43 | SQTable(SQSharedState *ss, SQInteger nInitialSize); 44 | void _ClearNodes(); 45 | public: 46 | static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize) 47 | { 48 | SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable)); 49 | new (newtable) SQTable(ss, nInitialSize); 50 | newtable->_delegate = NULL; 51 | return newtable; 52 | } 53 | void Finalize(); 54 | SQTable *Clone(); 55 | ~SQTable() 56 | { 57 | SetDelegate(NULL); 58 | REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); 59 | for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode(); 60 | SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode)); 61 | } 62 | #ifndef NO_GARBAGE_COLLECTOR 63 | void Mark(SQCollectable **chain); 64 | SQObjectType GetType() {return OT_TABLE;} 65 | #endif 66 | inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash) 67 | { 68 | _HashNode *n = &_nodes[hash]; 69 | do{ 70 | if(_rawval(n->key) == _rawval(key) && sq_type(n->key) == sq_type(key)){ 71 | return n; 72 | } 73 | }while((n = n->next)); 74 | return NULL; 75 | } 76 | //for compiler use 77 | inline bool GetStr(const SQChar* key,SQInteger keylen,SQObjectPtr &val) 78 | { 79 | SQHash hash = _hashstr(key,keylen); 80 | _HashNode *n = &_nodes[hash & (_numofnodes - 1)]; 81 | _HashNode *res = NULL; 82 | do{ 83 | if(sq_type(n->key) == OT_STRING && (scstrcmp(_stringval(n->key),key) == 0)){ 84 | res = n; 85 | break; 86 | } 87 | }while((n = n->next)); 88 | if (res) { 89 | val = _realval(res->val); 90 | return true; 91 | } 92 | return false; 93 | } 94 | bool Get(const SQObjectPtr &key,SQObjectPtr &val); 95 | void Remove(const SQObjectPtr &key); 96 | bool Set(const SQObjectPtr &key, const SQObjectPtr &val); 97 | //returns true if a new slot has been created false if it was already present 98 | bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val); 99 | SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval); 100 | 101 | SQInteger CountUsed(){ return _usednodes;} 102 | void Clear(); 103 | void Release() 104 | { 105 | sq_delete(this, SQTable); 106 | } 107 | 108 | }; 109 | 110 | #endif //_SQTABLE_H_ 111 | -------------------------------------------------------------------------------- /squirrel/squserdata.h: -------------------------------------------------------------------------------- 1 | /* see copyright notice in squirrel.h */ 2 | #ifndef _SQUSERDATA_H_ 3 | #define _SQUSERDATA_H_ 4 | 5 | struct SQUserData : SQDelegable 6 | { 7 | SQUserData(SQSharedState *ss){ _delegate = 0; _hook = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); } 8 | ~SQUserData() 9 | { 10 | REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this); 11 | SetDelegate(NULL); 12 | } 13 | static SQUserData* Create(SQSharedState *ss, SQInteger size) 14 | { 15 | SQUserData* ud = (SQUserData*)SQ_MALLOC(sq_aligning(sizeof(SQUserData))+size); 16 | new (ud) SQUserData(ss); 17 | ud->_size = size; 18 | ud->_typetag = 0; 19 | return ud; 20 | } 21 | #ifndef NO_GARBAGE_COLLECTOR 22 | void Mark(SQCollectable **chain); 23 | void Finalize(){SetDelegate(NULL);} 24 | SQObjectType GetType(){ return OT_USERDATA;} 25 | #endif 26 | void Release() { 27 | if (_hook) _hook((SQUserPointer)sq_aligning(this + 1),_size); 28 | SQInteger tsize = _size; 29 | this->~SQUserData(); 30 | SQ_FREE(this, sq_aligning(sizeof(SQUserData)) + tsize); 31 | } 32 | 33 | 34 | SQInteger _size; 35 | SQRELEASEHOOK _hook; 36 | SQUserPointer _typetag; 37 | //SQChar _val[1]; 38 | }; 39 | 40 | #endif //_SQUSERDATA_H_ 41 | -------------------------------------------------------------------------------- /squirrel/squtils.h: -------------------------------------------------------------------------------- 1 | /* see copyright notice in squirrel.h */ 2 | #ifndef _SQUTILS_H_ 3 | #define _SQUTILS_H_ 4 | 5 | void *sq_vm_malloc(SQUnsignedInteger size); 6 | void *sq_vm_realloc(void *p,SQUnsignedInteger oldsize,SQUnsignedInteger size); 7 | void sq_vm_free(void *p,SQUnsignedInteger size); 8 | 9 | #define sq_new(__ptr,__type) {__ptr=(__type *)sq_vm_malloc(sizeof(__type));new (__ptr) __type;} 10 | #define sq_delete(__ptr,__type) {__ptr->~__type();sq_vm_free(__ptr,sizeof(__type));} 11 | #define SQ_MALLOC(__size) sq_vm_malloc((__size)); 12 | #define SQ_FREE(__ptr,__size) sq_vm_free((__ptr),(__size)); 13 | #define SQ_REALLOC(__ptr,__oldsize,__size) sq_vm_realloc((__ptr),(__oldsize),(__size)); 14 | 15 | #define sq_aligning(v) (((size_t)(v) + (SQ_ALIGNMENT-1)) & (~(SQ_ALIGNMENT-1))) 16 | #define sq_max(a, b) ((a) > (b) ? (a) : (b)) 17 | 18 | //sqvector mini vector class, supports objects by value 19 | template class sqvector 20 | { 21 | public: 22 | sqvector() 23 | { 24 | _vals = NULL; 25 | _size = 0; 26 | _allocated = 0; 27 | } 28 | sqvector(const sqvector& v) 29 | { 30 | copy(v); 31 | } 32 | void copy(const sqvector& v) 33 | { 34 | if(_size) { 35 | resize(0); //destroys all previous stuff 36 | } 37 | //resize(v._size); 38 | if(v._size > _allocated) { 39 | _realloc(v._size); 40 | } 41 | for(SQUnsignedInteger i = 0; i < v._size; i++) { 42 | new ((void *)&_vals[i]) T(v._vals[i]); 43 | } 44 | _size = v._size; 45 | } 46 | ~sqvector() 47 | { 48 | if(_allocated) { 49 | for(SQUnsignedInteger i = 0; i < _size; i++) 50 | _vals[i].~T(); 51 | SQ_FREE(_vals, (_allocated * sizeof(T))); 52 | } 53 | } 54 | void reserve(SQUnsignedInteger newsize) { _realloc(newsize); } 55 | void resize(SQUnsignedInteger newsize, const T& fill = T()) 56 | { 57 | if(newsize > _allocated) 58 | _realloc(newsize); 59 | if(newsize > _size) { 60 | while(_size < newsize) { 61 | new ((void *)&_vals[_size]) T(fill); 62 | _size++; 63 | } 64 | } 65 | else{ 66 | for(SQUnsignedInteger i = newsize; i < _size; i++) { 67 | _vals[i].~T(); 68 | } 69 | _size = newsize; 70 | } 71 | } 72 | void shrinktofit() { if(_size > 4) { _realloc(_size); } } 73 | T& top() const { return _vals[_size - 1]; } 74 | inline SQUnsignedInteger size() const { return _size; } 75 | bool empty() const { return (_size <= 0); } 76 | inline T &push_back(const T& val = T()) 77 | { 78 | if(_allocated <= _size) 79 | _realloc(_size * 2); 80 | return *(new ((void *)&_vals[_size++]) T(val)); 81 | } 82 | inline void pop_back() 83 | { 84 | _size--; _vals[_size].~T(); 85 | } 86 | void insert(SQUnsignedInteger idx, const T& val) 87 | { 88 | resize(_size + 1); 89 | for(SQUnsignedInteger i = _size - 1; i > idx; i--) { 90 | _vals[i] = _vals[i - 1]; 91 | } 92 | _vals[idx] = val; 93 | } 94 | void remove(SQUnsignedInteger idx) 95 | { 96 | _vals[idx].~T(); 97 | if(idx < (_size - 1)) { 98 | memmove((void*)&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1)); 99 | } 100 | _size--; 101 | } 102 | SQUnsignedInteger capacity() { return _allocated; } 103 | inline T &back() const { return _vals[_size - 1]; } 104 | inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; } 105 | T* _vals; 106 | private: 107 | void _realloc(SQUnsignedInteger newsize) 108 | { 109 | newsize = (newsize > 0)?newsize:4; 110 | _vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T)); 111 | _allocated = newsize; 112 | } 113 | SQUnsignedInteger _size; 114 | SQUnsignedInteger _allocated; 115 | }; 116 | 117 | #endif //_SQUTILS_H_ 118 | --------------------------------------------------------------------------------