Compare commits
188 Commits
v3.1
...
rework_new
Author | SHA1 | Date | |
---|---|---|---|
a8ed39d3b4 | |||
af0dae2fa5 | |||
e62f3074cb | |||
ac1bd10654 | |||
2704e12018 | |||
48c38c1797 | |||
fa37b1fedb | |||
74d6af9ac4 | |||
22c303a587 | |||
b6c6a38844 | |||
fa206b5e49 | |||
51b24cad24 | |||
d76c59feb2 | |||
d1509119e9 | |||
0f8fe6003f | |||
be1fc5ae60 | |||
36a162e89d | |||
25e0b49c20 | |||
985ddbb7f2 | |||
e23132b712 | |||
a374a839ce | |||
d80ea723cb | |||
056190e60b | |||
440bc87551 | |||
04cdeeac1a | |||
7a589d9a98 | |||
0f930d76f7 | |||
096051c269 | |||
966b5fdad6 | |||
05107dc711 | |||
ab2fc34e1c | |||
c6875d59bf | |||
ad27afec61 | |||
ff85991e11 | |||
aa49dbd05d | |||
45e2df01f0 | |||
394cc68950 | |||
f882c9fedc | |||
1b59eb8c8e | |||
d92da4207d | |||
2fb1234972 | |||
5377f4b891 | |||
5e372fdbfa | |||
68295a1431 | |||
db219fa8e6 | |||
bec51d5c0a | |||
73000df2bb | |||
7e62732281 | |||
92ffade769 | |||
d7cdc92133 | |||
21c05fee09 | |||
5dc4c42958 | |||
![]() |
02b773b4ae | ||
![]() |
f4665e155e | ||
![]() |
dda695e95f | ||
![]() |
4a8ed6a67a | ||
![]() |
453a966890 | ||
![]() |
0be2bebef0 | ||
![]() |
c10a777285 | ||
![]() |
938655a90b | ||
![]() |
497c8f9d47 | ||
![]() |
ee38035634 | ||
![]() |
249a26e829 | ||
![]() |
7d589eb444 | ||
![]() |
b00cd02629 | ||
![]() |
5460758eb0 | ||
![]() |
3835c65eab | ||
![]() |
ab7243ca59 | ||
![]() |
b89da87b10 | ||
![]() |
effd225a84 | ||
![]() |
d2de0ef10d | ||
![]() |
3c2de4bd59 | ||
![]() |
5c737b040a | ||
![]() |
7fe2a71c13 | ||
![]() |
2fa5378a1a | ||
![]() |
26a655a503 | ||
![]() |
74cca2d7d3 | ||
![]() |
a7df1b46a4 | ||
![]() |
31738a5b37 | ||
![]() |
a0857ae0b8 | ||
![]() |
7e72756c52 | ||
![]() |
a3a78eec20 | ||
![]() |
57ca6c191e | ||
![]() |
40e994bc88 | ||
![]() |
3c8d024bdb | ||
![]() |
2186a3fe21 | ||
![]() |
5dcf698a91 | ||
![]() |
304be42986 | ||
![]() |
00b4d3abd1 | ||
![]() |
9dd92a7d49 | ||
![]() |
4df9f90385 | ||
![]() |
8471ad1aea | ||
![]() |
a0e46fce11 | ||
![]() |
14cbc7b2dc | ||
![]() |
c62aacd250 | ||
![]() |
d159befb13 | ||
![]() |
0bf296d46a | ||
![]() |
5743cd5c91 | ||
![]() |
76c67169ed | ||
![]() |
aa4afc5b14 | ||
![]() |
5b3bfb21fb | ||
![]() |
6186e02a23 | ||
![]() |
bdcb7cc12b | ||
![]() |
d130dc5471 | ||
![]() |
be35cf850b | ||
![]() |
05dbbc1820 | ||
![]() |
795af921cc | ||
![]() |
fae1cabb51 | ||
![]() |
cfd4df6988 | ||
![]() |
c7a0707137 | ||
![]() |
701a0e4ae5 | ||
![]() |
eeba56c81b | ||
![]() |
48842f0979 | ||
![]() |
f3bb11ef99 | ||
![]() |
36c308bf57 | ||
![]() |
bd43d374dc | ||
![]() |
3019ac3c2c | ||
![]() |
5e4bcebc6f | ||
![]() |
17124aa789 | ||
![]() |
2ad9683f54 | ||
![]() |
d1d28aacc9 | ||
![]() |
15e2c23eea | ||
![]() |
7629853586 | ||
![]() |
e618271e11 | ||
![]() |
d81f7e1c9d | ||
![]() |
7aadf19f34 | ||
![]() |
f7cf119db7 | ||
![]() |
a96a2f3d78 | ||
![]() |
90cd4bc238 | ||
![]() |
ba338b145c | ||
![]() |
87deb68c46 | ||
![]() |
457f3b25bc | ||
![]() |
98b5cc434d | ||
![]() |
7290b1fffe | ||
![]() |
26ef4c4f5e | ||
![]() |
2d509d385b | ||
![]() |
3b217e7e42 | ||
![]() |
3c4098da84 | ||
![]() |
997c7aefd2 | ||
![]() |
2e346b54ac | ||
![]() |
09c4e7a8c1 | ||
![]() |
4f20c881ab | ||
![]() |
f441f7f99d | ||
![]() |
8ca802658c | ||
![]() |
9004743fc4 | ||
![]() |
0961039dd7 | ||
![]() |
7c0550b8ad | ||
![]() |
e0f0e180a3 | ||
![]() |
656c6a0d68 | ||
![]() |
16ab1fd6c0 | ||
![]() |
2aef08d0a5 | ||
![]() |
f87cd114d7 | ||
![]() |
7bb5dd4982 | ||
![]() |
5b50a56e56 | ||
![]() |
8242f5ac06 | ||
![]() |
692d4958e8 | ||
![]() |
70afceec42 | ||
![]() |
301db648da | ||
![]() |
b589ea521d | ||
![]() |
35ab252494 | ||
![]() |
160184d2dd | ||
![]() |
b9fc931752 | ||
![]() |
72135d9a7f | ||
![]() |
7305257b95 | ||
![]() |
e347779446 | ||
![]() |
4125aa515d | ||
![]() |
ed23d140df | ||
![]() |
8fb371b3fc | ||
![]() |
78b44c851b | ||
![]() |
b35c9e827c | ||
![]() |
f8f229fa00 | ||
![]() |
175139968a | ||
![]() |
c44d568a8b | ||
![]() |
a70a135192 | ||
![]() |
4fddb87839 | ||
![]() |
4305796277 | ||
![]() |
953d9e9771 | ||
![]() |
2f6419f19b | ||
![]() |
9218082df1 | ||
![]() |
d02fa17be2 | ||
![]() |
98bb79893e | ||
![]() |
7233a7c7de | ||
![]() |
9f4407d8ef | ||
![]() |
d9d0ebb4c0 | ||
![]() |
558a4f4f3b | ||
![]() |
d2e93dcba6 | ||
![]() |
6db0aa2095 | ||
![]() |
14ac45d285 |
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.pyc
|
17
.travis.yml
Normal file
17
.travis.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
language: cpp
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
# Travis VMs are 64-bit but we compile both for 32 and 64 bit. To enable the
|
||||
# 32-bit builds to work, we need gcc-multilib.
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gcc-multilib
|
||||
- g++-multilib
|
||||
|
||||
# Enable container-based builds.
|
||||
sudo: false
|
||||
|
||||
script: mkdir build && cd build && cmake .. && make -j2
|
@@ -1,68 +0,0 @@
|
||||
if(MSVC)
|
||||
cmake_minimum_required(VERSION 3.4)
|
||||
else()
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
endif()
|
||||
|
||||
set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}" CACHE PATH "")
|
||||
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "")
|
||||
|
||||
project(squirrel C CXX)
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}/include)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(SQ_FLAGS -fno-exceptions -fno-strict-aliasing -Wall -Wextra -pedantic -Wcast-qual)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
set(SQ_FLAGS ${SQ_FLAGS} -O3)
|
||||
elseif(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
|
||||
set(SQ_FLAGS ${SQ_FLAGS} -O3 -g)
|
||||
elseif(CMAKE_BUILD_TYPE STREQUAL "MinSizeRel")
|
||||
set(SQ_FLAGS ${SQ_FLAGS} -Os)
|
||||
elseif(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(SQ_FLAGS ${SQ_FLAGS} -pg -pie -gstabs -g3 -Og)
|
||||
endif()
|
||||
|
||||
if(CMAKE_VERSION VERSION_GREATER 3)
|
||||
add_compile_options(${SQ_FLAGS})
|
||||
else()
|
||||
add_definitions(${SQ_FLAGS})
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -std=c++0x")
|
||||
elseif(MSVC)
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
add_definitions(-D_SQ64)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED INSTALL_BIN_DIR)
|
||||
set(INSTALL_BIN_DIR bin)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED INSTALL_LIB_DIR)
|
||||
set(INSTALL_LIB_DIR lib)
|
||||
endif()
|
||||
|
||||
add_subdirectory(squirrel)
|
||||
add_subdirectory(sqstdlib)
|
||||
add_subdirectory(sq)
|
||||
|
||||
if(NOT WIN32)
|
||||
set_target_properties(squirrel sqstdlib PROPERTIES SOVERSION 0 VERSION 0.0.0)
|
||||
endif()
|
||||
|
||||
if(DEFINED INSTALL_INC_DIR)
|
||||
set(SQ_PUB_HEADERS include/sqconfig.h
|
||||
include/sqstdaux.h
|
||||
include/sqstdblob.h
|
||||
include/sqstdio.h
|
||||
include/sqstdmath.h
|
||||
include/sqstdstring.h
|
||||
include/sqstdsystem.h
|
||||
include/squirrel.h)
|
||||
install(FILES ${SQ_PUB_HEADERS} DESTINATION ${INSTALL_INC_DIR})
|
||||
endif()
|
7
COMPILE
7
COMPILE
@@ -77,3 +77,10 @@ for 64 bits systems
|
||||
VISUAL C++ USERS
|
||||
.........................................................
|
||||
Open squirrel.dsw from the root project directory and build(dho!)
|
||||
|
||||
DOCUMENTATION GENERATION
|
||||
.........................................................
|
||||
To be able to compile the documentation, make sure that you have Python
|
||||
installed and the packages sphinx and sphinx_rtd_theme. Browse into doc/
|
||||
and use either the Makefile for GCC-based platforms or make.bat for
|
||||
Windows platforms.
|
||||
|
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2003-2016 Alberto Demichelis
|
||||
Copyright (c) 2003-2017 Alberto Demichelis
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
514
HISTORY
514
HISTORY
@@ -1,514 +0,0 @@
|
||||
***version 3.1 stable***
|
||||
-added slice range for tolower and toupper
|
||||
-added startswith() and endswith() in string lib
|
||||
-added SQ_EXCLUDE_DEFAULT_MEMFUNCTIONS to exclude default mem fuction from compilation
|
||||
-added sq_getreleasehook
|
||||
-added thread.wakeupthrow()
|
||||
-added sq_pushthread
|
||||
-added \u and \U escape sequence for UTF8,UTF16 or UCS4 characters
|
||||
-added CMake scripts(thx Fabian Wolff)
|
||||
-the escape character \x is based on sizeof(SQChar)
|
||||
-fixed several warnings(thx Markus Oberhumer)
|
||||
-fixed optimizer bug in compound arith oprators(+=,-= etc...)
|
||||
-fixed sq_getrefvmcount() (thx Gerrit)
|
||||
-fixed sq_getrefcount() when no references were added with sq_addref() (thx Gerrit)
|
||||
-fixed bug in string.tointeger() (thx Domingo)
|
||||
-fixed weakref comparison in 32bit builds using doubles(thx Domingo)
|
||||
-fixed compiler bug(thx Peter)
|
||||
-fixed some error in the documentation(thx Alexander)
|
||||
-fixed some error reporting in compiler(thx Alexander)
|
||||
-fixed incorrect optional semicolon after "if block"(thx Alexander)
|
||||
-fixed crash bug in compiler related to compound arith operators(+=,-= etc...) (thx Jeff1)
|
||||
|
||||
***2015-01-10 ***
|
||||
***version 3.1 RC 1***
|
||||
-added new header sqconfig.h for all optional type declarations(unicode, 64bits etc..)
|
||||
-added sq_setsharedforeignptr sq_getsharedforeignptr
|
||||
-added sq_setsharedreleasehook sq_getsharedreleasehook
|
||||
-added escape() in sqstd string library
|
||||
-added __LINE__ and __FILE__ (thx mingodad)
|
||||
-widechar support on gcc builds
|
||||
-now boolean can be used in constants
|
||||
-reduced dependencies on C runtime library
|
||||
-newthread and sq_newthread() no longer reinitialize the root table on friend VMs(thx Lucas Cardellini)
|
||||
-exceptions in the _inherited metamethod are propagated(thx Lucas Cardellini)
|
||||
-'in' operator performance improvement(thx unagipai and mingodad)
|
||||
-fixes crash in compiler when trying to write 'base'
|
||||
-fixed bug in switch statement when using locals as case values (thx mingodad)
|
||||
-fixed bug in print()(thx Lucas Cardellini)
|
||||
|
||||
***2013-08-30 ***
|
||||
***version 3.1 beta 1***
|
||||
-added new scoping rule(root attached to closures)
|
||||
-added closure.setroot() closure.getroot()
|
||||
-added sq_setclosureroot() and sq_getclosureroot()
|
||||
-added sq_setvmreleasehook() and sq_getvmreleasehook()
|
||||
-added documentaion for sq_getbase()
|
||||
-now string.tointeger() accepts an optional parameter 'base'
|
||||
-now format accepts zeroes in the format string (thx mingodad)
|
||||
-fixed bug in sqstd_createfile() (thx mingodad)
|
||||
-minor buxfixes
|
||||
|
||||
***2012-11-10 ***
|
||||
***version 3.0.4 stable***
|
||||
-sq_deleteslot slot now pops the key in case of failure
|
||||
-fixed bug when _get metamethod throws null
|
||||
-fixed a bug in rstrip
|
||||
-added some error handling
|
||||
-minor bugfixes
|
||||
|
||||
***2012-06-19 ***
|
||||
***version 3.1.0 alpha 1***
|
||||
-changed in and instanceof operator precendence
|
||||
-root object in closures
|
||||
-added closure.setroot closure.getroot
|
||||
-added sq_setclosureroot and sq_getclosureroot
|
||||
|
||||
***version 3.0.3 stable***
|
||||
-improved error messages for _cmp(when a non integer value is returned) (thx Yexo)
|
||||
-added class.newmember() built in method (thx Nam)
|
||||
-added class.rawnewmember() built in method (thx Nam)
|
||||
-added sq_rawnewmember() (thx Nam)
|
||||
-added sq_getversion()
|
||||
-added sq_typeof()
|
||||
-added sq_getclosurename()
|
||||
-added file.close() in stdlib
|
||||
-documented closure.getinfos() built-in method
|
||||
-fixed string iteration doesn't return negative numbers for characters > 127
|
||||
-fixed bug in tofloat() when converting a string with scientific notation without a decimal point (thx wr2)
|
||||
-fixed potential infinite loop in array.sort() when the _cmp function is inconsistent (thx Yexo)
|
||||
-fixed obscure bug in the compiler(thx yishin)
|
||||
-fixed some minor bug
|
||||
|
||||
***2011-11-28 ***
|
||||
***version 3.0.2 stable***
|
||||
-added sq_gethash API
|
||||
-now array.sort() is implemented with heapsort
|
||||
-now floats in scientific notation also accept numbers with no '.' (eg. 1e+6 or 1e6)
|
||||
-fixed some warning
|
||||
-fixed some documentation
|
||||
-fixed bug in GC
|
||||
|
||||
***2011-09-08 ***
|
||||
***version 3.0.1 stable***
|
||||
-added # as alternative symbol for "line comment"(mostly useful for shell scripts)
|
||||
-added sq_throwobject() to throw an arbitrary object from the C API
|
||||
-added alignement flag for userdata types, SQ_ALIGNMENT (thx Shigemasa)
|
||||
-added rawset() and rawget() to class and instance default delegate
|
||||
-changed bytecode format now ensures matching integer size and float size
|
||||
-now inherited classes also inherit userdatasize
|
||||
-added SQUIRREL_VERSION_NUMBER in squirrel.h and _versionnumber_ global symbol
|
||||
-fixed sq_getmemberhandle
|
||||
-fixed sq_getrefcount
|
||||
-refactored some sqstdio code
|
||||
-refactored some clone code
|
||||
-refactored some stuff in the string lib
|
||||
-added -s and -fno-exceptions in GCC makefile(better performance when using GCC)
|
||||
|
||||
***2011-03-13 ***
|
||||
***version 3.0 stable***
|
||||
-added sq_getcallee()
|
||||
-sq_getfreevariable() also works for native closures
|
||||
-minior optimizations
|
||||
-removed several warning when compiling with GCC 4.x
|
||||
-fixed some errors in the documentation
|
||||
-fixed bug when using SQUSEDOUBLE and 32bits intengers
|
||||
-fixed bug when invoking generators with closure.call() (thx huntercool)
|
||||
|
||||
***2010-12-19 ***
|
||||
***version 3.0 release candidate 1(RC 1)***
|
||||
-improved metamethods error handling
|
||||
-added parameter 'isstatic' to _newmember metamethod(thx G.Meyer)
|
||||
-added sq_getrefcount() to return number of refences from C++(thx G.Meyer)
|
||||
|
||||
***2010-11-07 ***
|
||||
***version 3.0 beta 3***
|
||||
-license changed to "MIT license"
|
||||
-added sq_resurrectunreachable() and resurrectunreachable()
|
||||
-added callee() built in function, returns the current running closure
|
||||
-added thread.getstackinfos()
|
||||
-added sq_objtouserpointer()
|
||||
-added sq_newtableex()
|
||||
-various refactoring and optimizations
|
||||
-fixed several 64bits issues regarding integer to string conversions
|
||||
-fixed some bugs when SQUSEDOUBLE is used in 32bits systems
|
||||
|
||||
***2010-08-18 ***
|
||||
***version 3.0 beta 2.1***
|
||||
-fixed bug in class constructor
|
||||
-fixed bug in compound arith
|
||||
|
||||
***2010-08-12 ***
|
||||
***version 3.0 beta 2***
|
||||
-class methods can be added or replaced after the class as been instantiated
|
||||
-JSON compliant table syntax, this is currently an experimental feature (thx atai)
|
||||
-sq_getsize() now returns userdatasize for classes and instances
|
||||
-now setroottable() and setconsttable() return the previous value of the respective table
|
||||
-fixed bug in compound arith operators when used on a free variable (thx ellon)
|
||||
-fixed some x64 minor bugs
|
||||
-fixed minor bug in the compiler
|
||||
-refactored some VM internals
|
||||
-documented sq_getmemberhandle, sq_getbyhandle, sq_setbyhandle to set and get value from classes
|
||||
|
||||
***2009-11-15 ***
|
||||
***version 3.0 beta 1***
|
||||
-various refactoring and optimizations
|
||||
-fixed bug in free variables (thx mokehehe)
|
||||
-fixed bug in functions with default parameters (thx ara & Yexo)
|
||||
-fixed bug in exception handling
|
||||
-improved error propagation in _set and _get metamethods ( and 'throw null' for clean failure)
|
||||
-added sq_getmemberhandle, sq_getbyhandle, sq_setbyhandle to set and get value from classes
|
||||
|
||||
***2009-06-30 ***
|
||||
***version 3.0 alpha 2***
|
||||
-added real free variables(thx Paul Ruizendaal)
|
||||
-added refactored function call implementation and compiler(thx Paul Ruizendaal)
|
||||
-added sq_getfunctioninfo
|
||||
-added compile time flag SQUSEDOUBLE to use double precision floats
|
||||
-added global slot _floatsize_ int the base lib to recognize single precision and double precision builds
|
||||
-sq_wakeupvm can now resume the vm with an exception
|
||||
-added sqstd_format
|
||||
-now blobs can be cloned
|
||||
-generators can now be instantiated by calling sq_call() or closure.call()
|
||||
-fixed debughook bug
|
||||
-fixed cooroutine error propagation
|
||||
|
||||
***2008-07-23 ***
|
||||
***version 3.0 alpha 1***
|
||||
-first branch from 2.x source tree
|
||||
-added 'base' keyword
|
||||
-removed 'delegate' keyword
|
||||
-now compiled scripts are vararg functions
|
||||
-added setdelegate() and getdelegate() table builtin methods
|
||||
-added <=> 3 ways compare operator
|
||||
-added lambda expression @(a,b) a + b
|
||||
-added local function statement
|
||||
-added array built-in map(),reduce(),apply(),filter() and find()
|
||||
-generators hold only a weak reference of the enviroment object
|
||||
-removed 'vargv' and 'vargc' keywords
|
||||
-now var args are passed as an array called vargv(as a paramter)
|
||||
-removed 'parent' keyword
|
||||
-added class getbase() built in method
|
||||
-instanceof doesn't throw an exception if the left expression is not a class
|
||||
-lexical scoping for free variables(free variables are no longer in the second parameter list)
|
||||
-sq_setprintfunc accept error func
|
||||
-sq_geterrorfunc()
|
||||
-added sq_arrayremove() and sq_arrayinsert()
|
||||
-error() built in function(works like print but prints using the errorfunc)
|
||||
-added native debug hook
|
||||
|
||||
***2008-02-17 ***
|
||||
***version 2.2 stable***
|
||||
-added _newslot metamethod in classes
|
||||
-added enums added constants
|
||||
-added sq_pushconsttable, sq_setconsttable
|
||||
-added default param
|
||||
-added octal literals(thx Dinosaur)
|
||||
-fixed debug hook, 'calls' and 'returns' are properly notified in the same number.
|
||||
-fixed a coroutine bug
|
||||
|
||||
***2007-07-29 ***
|
||||
***version 2.1.2 stable***
|
||||
-new behaviour for generators iteration using foreach
|
||||
now when a generator is iterated by foreach the value returned by a 'return val' statement
|
||||
will terminate the iteration but will not be returned as foreach iteration
|
||||
-added sq_setclassudsize()
|
||||
-added sq_clear()
|
||||
-added table.clear(), array.clear()
|
||||
-fixed sq_cmp() (thx jyuill)
|
||||
-fixed minor bugs
|
||||
|
||||
***2006-08-21 ***
|
||||
***version 2.1.1 stable***
|
||||
-vm refactoring
|
||||
-optimized internal function memory layout
|
||||
-new global symbol _version_ (is the version string)
|
||||
-code size optimization for float literals(on 32bits float builts)
|
||||
-now the raw ref API(sq_addref etc...) is fully reentrant.
|
||||
-fixed a bug in sq_getdelegate() now pushes null if the object doesn't have a delegate(thx MatzeB)
|
||||
-improved C reference performances in NO_GARBAGE_COLLECTOR builds
|
||||
-sq_getlocal() now enumerates also outer values.
|
||||
-fixed regexp library for GCC users.
|
||||
|
||||
***2006-03-19 ***
|
||||
***version 2.1 stable***
|
||||
-added static class fields, new keyword static
|
||||
-added 64bits architecture support
|
||||
-added global slot _intsize_ int the base lib to recognize 32bits and 64bits builds
|
||||
-added functions with fixed environment, closure.bindenv() built-in function
|
||||
-all types except userdata and null implement the tostring() method
|
||||
-string concatenation now invokes metamethod _tostring
|
||||
-new metamethods for class objects _newmember and _inherited
|
||||
-sq_call() sq_resume() sq_wakeupvm() have a new signature
|
||||
-new C referencing implementation(scales more with the amount of references)
|
||||
-refactored hash table
|
||||
-new api functions sq_newslot(),sq_tobool(),sq_getbase(), sq_instanceof(), sq_bindenv()
|
||||
-the api func sq_createslot was deprecated but still supported in form of C macro on top of sq_newslot
|
||||
-sq_setreleasehook() now also works for classes
|
||||
-stream.readstr() and stream.writestr() have been deprecated(this affects file and blob)
|
||||
-fixed squirrel.h undeclared api calls
|
||||
-fixed few minor bugs
|
||||
-SQChar is now defined as wchar_t
|
||||
-removed warning when building with -Wall -pedantic for GCC users
|
||||
-added new std io function writeclosuretofile()
|
||||
-added new std string functions strip(),rstrip(),lstrip() and split()
|
||||
-regular expressions operators (+,*) now have more POSIX greedyness behaviour
|
||||
-class constructors are now invoked as normal functions
|
||||
|
||||
***2005-10-02 ***
|
||||
***version 2.0.5 stable***
|
||||
-fixed some 64bits incompatibilities (thx sarge)
|
||||
-fixed minor bug in the stdlib format() function (thx Rick)
|
||||
-fixed a bug in dofile() that was preventing to compile empty files
|
||||
-added new API sq_poptop() & sq_getfreevariable()
|
||||
-some performance improvements
|
||||
|
||||
***2005-08-14 ***
|
||||
***version 2.0.4 stable***
|
||||
-weak references and related API calls
|
||||
-added sq_objtobool()
|
||||
-class instances memory policies improved(1 mem allocation for the whole instance)
|
||||
-typetags are now declared as SQUserPointer instead of unsigned int
|
||||
-first pass for 64bits compatibility
|
||||
-fixed minor bug in the stdio stream
|
||||
-fixed a bug in format()
|
||||
-fixed bug in string.tointeger() and string.tofloat()
|
||||
|
||||
***2005-06-24 ***
|
||||
***version 2.0.3 stable***
|
||||
-dofile() and loadfile() in the iolib now can decode ASCII, UTF8 files UCS2 big-endian and little-endian
|
||||
-sq_setparamscheck() : now typemesk can check for null
|
||||
-added string escape sequence \xhhhh
|
||||
-fixed some C++ standard incompatibilities
|
||||
|
||||
***2005-05-15 ***
|
||||
***version 2.0.2 stable***
|
||||
-performances improvements (expecially for GCC users)
|
||||
-removed all dependencies from C++ exception handling
|
||||
-various bugfixes
|
||||
|
||||
***2005-04-12 ***
|
||||
***version 2.0.1 stable***
|
||||
-various bugfixes
|
||||
-sq_setparamscheck() now allows spaces in the typemask
|
||||
|
||||
***2005-04-03 ***
|
||||
***version 2.0 stable***
|
||||
-added API sq_gettypetag()
|
||||
-added built-in function to the bool type(tointeger, tostring etc...)
|
||||
|
||||
***2005-02-27 ***
|
||||
***version 2.0 release candidate 1(RC 1)***
|
||||
-added API sq_reseterror()
|
||||
-modified sq_release()
|
||||
-now class instances can be cloned
|
||||
-various bufixes
|
||||
|
||||
***2005-01-26 ***
|
||||
***version 2.0 beta 1***
|
||||
-added bool type
|
||||
-class properties can be redefined in a derived class
|
||||
-added ops *= /= and %=
|
||||
-new syntax for class attributes declaration </ and /> instead of ( and )
|
||||
-increased the max number of literals per function from 65535 to 16777215
|
||||
-now free variables have proper lexical scoping
|
||||
-added API sq_createinstance(), sq_pushbool(), sq_getbool()
|
||||
-added built-in function type()
|
||||
-added built-in function obj.rawin(key) in table,class and instance
|
||||
-sq_rawget() and sq_rawset() now work also on classes and instances
|
||||
-the VM no longer uses C++ exception handling (more suitable for embedded devices)
|
||||
-various bufixes
|
||||
|
||||
***2004-12-21 ***
|
||||
***version 2.0 alpha 2***
|
||||
-globals scoping changed, now if :: is omitted the VM automatically falls back on the root table
|
||||
-various bufixes
|
||||
-added class level attributes
|
||||
|
||||
***2004-12-12 ***
|
||||
***version 2.0 alpha 1***
|
||||
-codebase branch from version 1.x
|
||||
-added classes
|
||||
-added functions with variable number of parameters(vargc & vargv and the ...)
|
||||
-0 and 0.0 are now considered 'false' by all conditional statements(if,while,for,?,do-while)
|
||||
-added new api functions sq_newclass() sq_setinstanceup() sq_getinstanceup() sq_getattributes() sq_setattributes()
|
||||
-modified api sq_settypetag()
|
||||
|
||||
***2004-11-01 ***
|
||||
***version 1.0 stable***
|
||||
-fixed some minor bug
|
||||
-improved operator 'delete' performances
|
||||
-added scientific notation for float numbers( eg. 2.e16 or 2.e-2)
|
||||
|
||||
***2004-08-30 ***
|
||||
***version 1.0 release candidate 2(RC 2)***
|
||||
-fixed bug in the vm(thx Pierre Renaux)
|
||||
-fixed bug in the optimizer(thx Pierre Renaux)
|
||||
-fixed some bug in the documentation(thx JD)
|
||||
-added new api functions for raw object handling
|
||||
-removed nested multiline comments
|
||||
-reduced memory footprint in C references
|
||||
|
||||
***2004-08-23 ***
|
||||
***version 1.0 release candidate 1(RC 1)***
|
||||
-fixed division by zero
|
||||
-the 'in' operator and obj.rawget() do not query the default delegate anymore
|
||||
-added function sq_getprintfunc()
|
||||
-added new standard library 'auxlib'(implements default error handlers)
|
||||
|
||||
***2004-07-12 ***
|
||||
***version 1.0 beta 4***
|
||||
-fixed a bug in the integer.tochar() built-in method
|
||||
-fixed unary minus operator
|
||||
-fixed bug in dofile()
|
||||
-fixed inconsistency between != and == operators(on float/integer comparison)
|
||||
-added javascript style unsigned right shift operator '>>>'
|
||||
-added array(size) constructor built-in function
|
||||
-array.resize(size,[fill]) built-in function accepts an optional 'fill' value
|
||||
-improved debug API, added sq_getclosureinfo() and sq_setnativeclosurename()
|
||||
|
||||
***2004-05-23 ***
|
||||
***version 1.0 beta 3***
|
||||
-minor vm bug fixes
|
||||
-string allocation is now faster
|
||||
-tables and array memory usage is now less conservative(they shrink)
|
||||
-added regular expression routines in the standard library
|
||||
-The 'c' expression now accepts only 1 character(thx irbrian)
|
||||
-multiline strings <[ ]> have been substituted with C# style verbatim strings (eg. @"string")
|
||||
-added new keyword 'parent' for accessing the delegate of tables and unserdata
|
||||
-The metamethod '_clone' has been renamed '_cloned'
|
||||
-the _delslot metamethod's behaviour and prototype have been changed
|
||||
-new default function in the integer and float object 'tochar()'
|
||||
-the built-in function chcode2string has been removed
|
||||
-the default method [table].getdelegate() has been removed
|
||||
-new api sq_rawdeleteslot()
|
||||
-new table built-in method rawdelete(key)
|
||||
-the dynamic mudule loading has been removed from the standard distribution
|
||||
-some optimizations in the VM
|
||||
|
||||
***2004-04-21 ***
|
||||
***version 1.0 beta 2***
|
||||
-minor compiler/parser bug fixes
|
||||
-sq_newclosure has a different prototype, the "paramscheck" of paramter has been moved to the new function sq_setparamscheck()
|
||||
-sq_setparamscheck allows to add automatic parameters type checking in native closures
|
||||
-sq_compile() lost the lineinfo parameter
|
||||
-new api sq_enabledebuginfo() globally sets compiler's debug info generation
|
||||
-added consistency check on bytecode serialization
|
||||
-fixed += operator, now works on strings like +
|
||||
-added global slot in the base lib _charsize_ to recognize unicode builds from ascii builds runtime
|
||||
-added registry table
|
||||
-new api call sq_pushregistrytable()
|
||||
-added type tag to the userdata type sq_settypetag()
|
||||
-sq_getuserdata now queries the userdata typetag
|
||||
-the built in function collect_garbage() as been renamed collectgarbage() for consistency reasons
|
||||
-new standard libraries(sqlibs are now obsolete)
|
||||
|
||||
***2004-02-20 ***
|
||||
***version 1.0 beta 1***
|
||||
-fixed a bug in the compiler (thanks Martin Kofler)
|
||||
-fixed bug in the switch case statement
|
||||
-fixed the _unm metamethod
|
||||
-fixed minor bugs in the API
|
||||
-fixed automatic stack resizing
|
||||
-first beta version
|
||||
first pass code clean up in the VM and base lib
|
||||
first pass code coverege test has been done on VM and built-in lib
|
||||
-new VM creation API sq_open() sq_close() (sq_newvm and sq_releasevm are now obsolete)
|
||||
-new api allows to specifiy a "print" function to output text(sq_printfunc)
|
||||
-added some small optimizations
|
||||
-new cooperative multi-threading capabilities in the base library(coroutines), VMs are now a built in type("thread")
|
||||
-new built in functions have been added for manipulating the new "thread" type
|
||||
-friend virtual machines share the same root table, error handler and debug hook by default
|
||||
-new compile time options
|
||||
|
||||
***2004-01-19 ***
|
||||
***version 0.9 alpha***
|
||||
-fixed a garbage collection bug
|
||||
-fixed some API bugs(thanks to Joshua Jensen)
|
||||
-fixed tail calls (in the version 0.8 the tail call optimization was erroneously disabled)
|
||||
-new function parameters semantic, now passing a wrong number of parameters generates an exception
|
||||
-native closures have now a built in parameter number checking
|
||||
-sq_rawget and sq_rawset now work also on arrays
|
||||
-sq_getsize now woks also on userdata
|
||||
-the userdata release hook prototype is changed(now passes the size of the userdata)
|
||||
-the lexer reader function now returns an integer instead of a char that allows better error checking on the input(thx Joshua Jensen)
|
||||
-faster compiler
|
||||
-try/catch blocks do not cause any runtime memory allocation anymore
|
||||
|
||||
***2003-12-06 ***
|
||||
***version 0.8 alpha***
|
||||
-fixed a bug that was preventing to have callable userdata throught the metamethod _call
|
||||
-fixed a garbage collection bug
|
||||
-fixed == operator now can compare correctly different types
|
||||
-new built in method getstackinfos(level)
|
||||
-improved line informations precision for the debug hook
|
||||
-new api call sq_compilebuffer()
|
||||
-new built-in api function compilestring()
|
||||
-new syntactic sugar for function declarations inside tables
|
||||
-the debug API has been finalized
|
||||
|
||||
***2003-11-17 ***
|
||||
***version 0.7 alpha***
|
||||
-fixed critical bug SQInteger the tail call system
|
||||
-fixed bug in the continue statement code generation
|
||||
-fixed func call param issue(thanks to Rewoonenco Andrew)
|
||||
-added _delslot metamethod(thanks to Rewoonenco Andrew)
|
||||
-new multiline string expression ( delimited by <[ and ]> )
|
||||
-normal strings ("") do not allow embedded new line anymore
|
||||
-reduced vm memory footprint(C refs are shared between friend VMs)
|
||||
-new api method sq_deleteslot()
|
||||
-new debug hook event 'r' is triggered when a function returns
|
||||
|
||||
***2003-11-04 ***
|
||||
***version 0.6 alpha***
|
||||
-fixed switch statement(was executing the default case after a break)
|
||||
-sq_call() doesn't pop the closure (just the params)
|
||||
-the vm execution can be suspended from the C API anytime (micro-threads)
|
||||
-new api calls sq_suspendvm() sq_wakeupvm() sq_getvmstate() and sq_reservestack()
|
||||
|
||||
***2003-10-13 ***
|
||||
***version 0.5 alpha***
|
||||
-fixed some minor bug
|
||||
-tested with non ASCII identifiers in unicode mode(I've tried chinese chars)
|
||||
-added built-in function string.find()
|
||||
-the built-in function array.sort() optionally accepts a cmp(a,b) function
|
||||
-the debug hook function now has a new prototype debug_hook(event_type,sourcefile,line,functionname)
|
||||
-fixed some debug info imprecision
|
||||
|
||||
***2003-10-01 ***
|
||||
***version 0.4 alpha***
|
||||
-faster VM
|
||||
-sq_call will pop arguments and closure also in case of failure
|
||||
-fixed a bug in sq_remove
|
||||
-now the VM detects delegation cycles(and throws an exception)
|
||||
-new operators ++ and --
|
||||
-new operator ',' comma operator
|
||||
-fixed some expression precedence issue
|
||||
-fixed bug in sq_arraypop
|
||||
|
||||
***2003-09-15 ***
|
||||
***version 0.3 alpha***
|
||||
-fixed a bug in array::insert()
|
||||
-optional Unicode core(define SQUNICODE or _UNICODE on Win32)
|
||||
-sq_compiler uses a new reader function SQLEXREADFUNC
|
||||
-the debug hook passes 'l' instead of 'line' for line callbacks
|
||||
and 'c' instead of 'call' for call callbacks
|
||||
-new array.extend() bulit-in function
|
||||
-new API sq_clone()
|
||||
|
||||
***2003-09-10 ***
|
||||
***version 0.2 pre-alpha***
|
||||
-new completely reentrant VM (sq_open and sq_close are now obsolete)
|
||||
-sq_newvm() has a new prototype
|
||||
-allocators are now global and linked in the VM
|
||||
-_newslot meta method added
|
||||
-rawset creates a slot if doesn't exists
|
||||
-the compiler error callback pass the vm handle(thanks Pierre Renaux)
|
||||
-sq_setforeignptr() sq_getforeingptr() are now public
|
||||
-sq_resume() now is possible to resume generators from C
|
||||
-sq_getlasterror() retrieve the last thrown error
|
||||
-improved docs
|
||||
|
||||
***2003-09-06 ***
|
||||
***version 0.1 pre-alpha***
|
||||
first release
|
22
Makefile
22
Makefile
@@ -1,22 +0,0 @@
|
||||
|
||||
SQUIRREL=.
|
||||
MAKE=make
|
||||
|
||||
sq32: folders
|
||||
cd squirrel; $(MAKE)
|
||||
cd sqstdlib; $(MAKE)
|
||||
cd sq; $(MAKE)
|
||||
|
||||
sqprof: folders
|
||||
cd squirrel; $(MAKE) sqprof
|
||||
cd sqstdlib; $(MAKE) sqprof
|
||||
cd sq; $(MAKE) sqprof
|
||||
|
||||
sq64: folders
|
||||
cd squirrel; $(MAKE) sq64
|
||||
cd sqstdlib; $(MAKE) sq64
|
||||
cd sq; $(MAKE) sq64
|
||||
|
||||
folders:
|
||||
mkdir -p lib
|
||||
mkdir -p bin
|
2
README
2
README
@@ -12,7 +12,7 @@ The following compilers have been confirmed to be working:
|
||||
7.1 v
|
||||
8.0
|
||||
9.0
|
||||
10.0
|
||||
10.0
|
||||
12.0 ---
|
||||
MinGW gcc 3.2 (mingw special 20020817-1)
|
||||
Cygnus gcc 3.2
|
||||
|
329
cmdLine/rabbit.cpp
Normal file
329
cmdLine/rabbit.cpp
Normal file
@@ -0,0 +1,329 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#if defined(_MSC_VER) && defined(_DEBUG)
|
||||
#include <crtdbg.h>
|
||||
#include <conio.h>
|
||||
#endif
|
||||
#include <rabbit/rabbit.hpp>
|
||||
#include <rabbit-std/sqstdblob.hpp>
|
||||
#include <rabbit-std/sqstdsystem.hpp>
|
||||
#include <rabbit-std/sqstdio.hpp>
|
||||
#include <rabbit-std/sqstdmath.hpp>
|
||||
#include <rabbit-std/sqstdstring.hpp>
|
||||
#include <rabbit-std/sqstdaux.hpp>
|
||||
|
||||
void PrintVersionInfos();
|
||||
|
||||
#if defined(_MSC_VER) && defined(_DEBUG)
|
||||
int MemAllocHook(int allocType,
|
||||
void *userData,
|
||||
size_t size,
|
||||
int blockType,
|
||||
long requestNumber,
|
||||
const unsigned char *filename,
|
||||
int lineNumber) {
|
||||
//if(requestNumber==769)_asm int 3;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int64_t quit(rabbit::VirtualMachine* v)
|
||||
{
|
||||
int *done;
|
||||
sq_getuserpointer(v,-1,(rabbit::UserPointer*)&done);
|
||||
*done=1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void printfunc(rabbit::VirtualMachine* SQ_UNUSED_ARG(v),const char *s,...)
|
||||
{
|
||||
va_list vl;
|
||||
va_start(vl, s);
|
||||
vfprintf(stdout, s, vl);
|
||||
va_end(vl);
|
||||
}
|
||||
|
||||
void errorfunc(rabbit::VirtualMachine* SQ_UNUSED_ARG(v),const char *s,...)
|
||||
{
|
||||
va_list vl;
|
||||
va_start(vl, s);
|
||||
vfprintf(stderr, s, vl);
|
||||
va_end(vl);
|
||||
}
|
||||
|
||||
void PrintVersionInfos()
|
||||
{
|
||||
fprintf(stdout,"%s %s (%d bits)\n",RABBIT_VERSION,RABBIT_COPYRIGHT,((int)(sizeof(int64_t)*8)));
|
||||
}
|
||||
|
||||
void PrintUsage()
|
||||
{
|
||||
fprintf(stderr,"usage: sq <options> <scriptpath [args]>.\n"
|
||||
"Available options are:\n"
|
||||
" -c compiles the file to bytecode(default output 'out.karrot')\n"
|
||||
" -o specifies output file for the -c option\n"
|
||||
" -c compiles only\n"
|
||||
" -d generates debug infos\n"
|
||||
" -v displays version infos\n"
|
||||
" -h prints help\n");
|
||||
}
|
||||
|
||||
#define _INTERACTIVE 0
|
||||
#define _DONE 2
|
||||
#define _ERROR 3
|
||||
//<<FIXME>> this func is a mess
|
||||
int getargs(rabbit::VirtualMachine* v,int argc, char* argv[],int64_t *retval)
|
||||
{
|
||||
int i;
|
||||
int compiles_only = 0;
|
||||
char * output = NULL;
|
||||
*retval = 0;
|
||||
if(argc>1)
|
||||
{
|
||||
int arg=1,exitloop=0;
|
||||
|
||||
while(arg < argc && !exitloop)
|
||||
{
|
||||
|
||||
if(argv[arg][0]=='-')
|
||||
{
|
||||
switch(argv[arg][1])
|
||||
{
|
||||
case 'd':
|
||||
sq_enabledebuginfo(v,1);
|
||||
break;
|
||||
case 'c':
|
||||
compiles_only = 1;
|
||||
break;
|
||||
case 'o':
|
||||
if(arg < argc) {
|
||||
arg++;
|
||||
output = argv[arg];
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
PrintVersionInfos();
|
||||
return _DONE;
|
||||
|
||||
case 'h':
|
||||
PrintVersionInfos();
|
||||
PrintUsage();
|
||||
return _DONE;
|
||||
default:
|
||||
PrintVersionInfos();
|
||||
printf("unknown prameter '-%c'\n",argv[arg][1]);
|
||||
PrintUsage();
|
||||
*retval = -1;
|
||||
return _ERROR;
|
||||
}
|
||||
}else break;
|
||||
arg++;
|
||||
}
|
||||
|
||||
// src file
|
||||
|
||||
if(arg<argc) {
|
||||
const char *filename=NULL;
|
||||
filename=argv[arg];
|
||||
|
||||
arg++;
|
||||
|
||||
//sq_pushstring(v,"ARGS",-1);
|
||||
//sq_newarray(v,0);
|
||||
|
||||
//sq_createslot(v,-3);
|
||||
//sq_pop(v,1);
|
||||
if(compiles_only) {
|
||||
if(SQ_SUCCEEDED(rabbit::std::loadfile(v,filename,SQTrue))){
|
||||
const char *outfile = "out.karrot";
|
||||
if(output) {
|
||||
outfile = output;
|
||||
}
|
||||
if(SQ_SUCCEEDED(rabbit::std::writeclosuretofile(v,outfile)))
|
||||
return _DONE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//if(SQ_SUCCEEDED(rabbit::std::dofile(v,filename,SQFalse,SQTrue))) {
|
||||
//return _DONE;
|
||||
//}
|
||||
if(SQ_SUCCEEDED(rabbit::std::loadfile(v,filename,SQTrue))) {
|
||||
int callargs = 1;
|
||||
sq_pushroottable(v);
|
||||
for(i=arg;i<argc;i++)
|
||||
{
|
||||
const char *a;
|
||||
a=argv[i];
|
||||
sq_pushstring(v,a,-1);
|
||||
callargs++;
|
||||
//sq_arrayappend(v,-2);
|
||||
}
|
||||
if(SQ_SUCCEEDED(sq_call(v,callargs,SQTrue,SQTrue))) {
|
||||
rabbit::ObjectType type = sq_gettype(v,-1);
|
||||
if(type == rabbit::OT_INTEGER) {
|
||||
*retval = type;
|
||||
sq_getinteger(v,-1,retval);
|
||||
}
|
||||
return _DONE;
|
||||
}
|
||||
else{
|
||||
return _ERROR;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
//if this point is reached an error occurred
|
||||
{
|
||||
const char *err;
|
||||
sq_getlasterror(v);
|
||||
if(SQ_SUCCEEDED(sq_getstring(v,-1,&err))) {
|
||||
printf("error [%s]\n",err);
|
||||
*retval = -2;
|
||||
return _ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return _INTERACTIVE;
|
||||
}
|
||||
|
||||
void Interactive(rabbit::VirtualMachine* v)
|
||||
{
|
||||
|
||||
#define MAXINPUT 1024
|
||||
char buffer[MAXINPUT];
|
||||
int64_t blocks =0;
|
||||
int64_t string=0;
|
||||
int64_t retval=0;
|
||||
int64_t done=0;
|
||||
PrintVersionInfos();
|
||||
|
||||
sq_pushroottable(v);
|
||||
sq_pushstring(v,"quit",-1);
|
||||
sq_pushuserpointer(v,&done);
|
||||
sq_newclosure(v,quit,1);
|
||||
sq_setparamscheck(v,1,NULL);
|
||||
sq_newslot(v,-3,SQFalse);
|
||||
sq_pop(v,1);
|
||||
|
||||
while (!done)
|
||||
{
|
||||
int64_t i = 0;
|
||||
printf("\nrabbit> ");
|
||||
for(;;) {
|
||||
int c;
|
||||
if(done)return;
|
||||
c = getchar();
|
||||
if (c == '\n') {
|
||||
if (i>0 && buffer[i-1] == '\\')
|
||||
{
|
||||
buffer[i-1] = '\n';
|
||||
}
|
||||
else if(blocks==0)break;
|
||||
buffer[i++] = '\n';
|
||||
}
|
||||
else if (c=='}') {blocks--; buffer[i++] = (char)c;}
|
||||
else if(c=='{' && !string){
|
||||
blocks++;
|
||||
buffer[i++] = (char)c;
|
||||
}
|
||||
else if(c=='"' || c=='\''){
|
||||
string=!string;
|
||||
buffer[i++] = (char)c;
|
||||
}
|
||||
else if (i >= MAXINPUT-1) {
|
||||
fprintf(stderr, "rabbit: input line too long\n");
|
||||
break;
|
||||
}
|
||||
else{
|
||||
buffer[i++] = (char)c;
|
||||
}
|
||||
}
|
||||
buffer[i] = '\0';
|
||||
|
||||
if(buffer[0]=='='){
|
||||
snprintf(sq_getscratchpad(v,MAXINPUT),(size_t)MAXINPUT,"return (%s)",&buffer[1]);
|
||||
memcpy(buffer,sq_getscratchpad(v,-1),(strlen(sq_getscratchpad(v,-1))+1)*sizeof(char));
|
||||
retval=1;
|
||||
}
|
||||
i=strlen(buffer);
|
||||
if(i>0){
|
||||
int64_t oldtop=sq_gettop(v);
|
||||
if(SQ_SUCCEEDED(sq_compilebuffer(v,buffer,i,"interactive console",SQTrue))){
|
||||
sq_pushroottable(v);
|
||||
if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue)) && retval){
|
||||
printf("\n");
|
||||
sq_pushroottable(v);
|
||||
sq_pushstring(v,"print",-1);
|
||||
sq_get(v,-2);
|
||||
sq_pushroottable(v);
|
||||
sq_push(v,-4);
|
||||
sq_call(v,2,SQFalse,SQTrue);
|
||||
retval=0;
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
sq_settop(v,oldtop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
rabbit::VirtualMachine* v;
|
||||
int64_t retval = 0;
|
||||
#if defined(_MSC_VER) && defined(_DEBUG)
|
||||
_CrtsetAllocHook(MemAllocHook);
|
||||
#endif
|
||||
|
||||
v=rabbit::sq_open(1024);
|
||||
sq_setprintfunc(v,printfunc,errorfunc);
|
||||
|
||||
sq_pushroottable(v);
|
||||
|
||||
rabbit::std::register_bloblib(v);
|
||||
rabbit::std::register_iolib(v);
|
||||
rabbit::std::register_systemlib(v);
|
||||
rabbit::std::register_mathlib(v);
|
||||
rabbit::std::register_stringlib(v);
|
||||
|
||||
//aux library
|
||||
//sets error handlers
|
||||
rabbit::std::seterrorhandlers(v);
|
||||
|
||||
//gets arguments
|
||||
switch(getargs(v,argc,argv,&retval))
|
||||
{
|
||||
case _INTERACTIVE:
|
||||
Interactive(v);
|
||||
break;
|
||||
case _DONE:
|
||||
case _ERROR:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
sq_close(v);
|
||||
|
||||
#if defined(_MSC_VER) && defined(_DEBUG)
|
||||
_getch();
|
||||
_CrtMemdumpAllObjectsSince( NULL );
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
216
doc/Makefile
216
doc/Makefile
@@ -1,216 +0,0 @@
|
||||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = build
|
||||
|
||||
# User-friendly check for sphinx-build
|
||||
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
|
||||
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
|
||||
endif
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
|
||||
# the i18n builder cannot share the environment and doctrees with the others
|
||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " singlehtml to make a single large HTML file"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " applehelp to make an Apple Help Book"
|
||||
@echo " devhelp to make HTML files and a Devhelp project"
|
||||
@echo " epub to make an epub"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
|
||||
@echo " text to make text files"
|
||||
@echo " man to make manual pages"
|
||||
@echo " texinfo to make Texinfo files"
|
||||
@echo " info to make Texinfo files and run them through makeinfo"
|
||||
@echo " gettext to make PO message catalogs"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " xml to make Docutils-native XML files"
|
||||
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
@echo " coverage to run coverage check of the documentation (if enabled)"
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf $(BUILDDIR)/*
|
||||
|
||||
.PHONY: html
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
.PHONY: dirhtml
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
.PHONY: singlehtml
|
||||
singlehtml:
|
||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||
|
||||
.PHONY: pickle
|
||||
pickle:
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
.PHONY: json
|
||||
json:
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
.PHONY: htmlhelp
|
||||
htmlhelp:
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
.PHONY: qthelp
|
||||
qthelp:
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/testy_sphinxy.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/testy_sphinxy.qhc"
|
||||
|
||||
.PHONY: applehelp
|
||||
applehelp:
|
||||
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
|
||||
@echo
|
||||
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
|
||||
@echo "N.B. You won't be able to view it unless you put it in" \
|
||||
"~/Library/Documentation/Help or install it in your application" \
|
||||
"bundle."
|
||||
|
||||
.PHONY: devhelp
|
||||
devhelp:
|
||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||
@echo
|
||||
@echo "Build finished."
|
||||
@echo "To view the help file:"
|
||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/testy_sphinxy"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/testy_sphinxy"
|
||||
@echo "# devhelp"
|
||||
|
||||
.PHONY: epub
|
||||
epub:
|
||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
.PHONY: latex
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
.PHONY: latexpdf
|
||||
latexpdf:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
.PHONY: latexpdfja
|
||||
latexpdfja:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through platex and dvipdfmx..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
.PHONY: text
|
||||
text:
|
||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||
@echo
|
||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||
|
||||
.PHONY: man
|
||||
man:
|
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||
@echo
|
||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||
|
||||
.PHONY: texinfo
|
||||
texinfo:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo
|
||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
||||
@echo "Run \`make' in that directory to run these through makeinfo" \
|
||||
"(use \`make info' here to do that automatically)."
|
||||
|
||||
.PHONY: info
|
||||
info:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo "Running Texinfo files through makeinfo..."
|
||||
make -C $(BUILDDIR)/texinfo info
|
||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
||||
|
||||
.PHONY: gettext
|
||||
gettext:
|
||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
||||
@echo
|
||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
||||
|
||||
.PHONY: changes
|
||||
changes:
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
.PHONY: linkcheck
|
||||
linkcheck:
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
.PHONY: doctest
|
||||
doctest:
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
||||
|
||||
.PHONY: coverage
|
||||
coverage:
|
||||
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
|
||||
@echo "Testing of coverage in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/coverage/python.txt."
|
||||
|
||||
.PHONY: xml
|
||||
xml:
|
||||
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
|
||||
@echo
|
||||
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
|
||||
|
||||
.PHONY: pseudoxml
|
||||
pseudoxml:
|
||||
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
|
||||
@echo
|
||||
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
|
526
doc/make.bat
526
doc/make.bat
@@ -1,263 +1,263 @@
|
||||
@ECHO OFF
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set BUILDDIR=build
|
||||
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
|
||||
set I18NSPHINXOPTS=%SPHINXOPTS% source
|
||||
if NOT "%PAPER%" == "" (
|
||||
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
|
||||
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
if "%1" == "help" (
|
||||
:help
|
||||
echo.Please use `make ^<target^>` where ^<target^> is one of
|
||||
echo. html to make standalone HTML files
|
||||
echo. dirhtml to make HTML files named index.html in directories
|
||||
echo. singlehtml to make a single large HTML file
|
||||
echo. pickle to make pickle files
|
||||
echo. json to make JSON files
|
||||
echo. htmlhelp to make HTML files and a HTML help project
|
||||
echo. qthelp to make HTML files and a qthelp project
|
||||
echo. devhelp to make HTML files and a Devhelp project
|
||||
echo. epub to make an epub
|
||||
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
||||
echo. text to make text files
|
||||
echo. man to make manual pages
|
||||
echo. texinfo to make Texinfo files
|
||||
echo. gettext to make PO message catalogs
|
||||
echo. changes to make an overview over all changed/added/deprecated items
|
||||
echo. xml to make Docutils-native XML files
|
||||
echo. pseudoxml to make pseudoxml-XML files for display purposes
|
||||
echo. linkcheck to check all external links for integrity
|
||||
echo. doctest to run all doctests embedded in the documentation if enabled
|
||||
echo. coverage to run coverage check of the documentation if enabled
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "clean" (
|
||||
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
|
||||
del /q /s %BUILDDIR%\*
|
||||
goto end
|
||||
)
|
||||
|
||||
|
||||
REM Check if sphinx-build is available and fallback to Python version if any
|
||||
%SPHINXBUILD% 1>NUL 2>NUL
|
||||
if errorlevel 9009 goto sphinx_python
|
||||
goto sphinx_ok
|
||||
|
||||
:sphinx_python
|
||||
|
||||
set SPHINXBUILD=python -m sphinx.__init__
|
||||
%SPHINXBUILD% 2> nul
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.http://sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
:sphinx_ok
|
||||
|
||||
|
||||
if "%1" == "html" (
|
||||
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "dirhtml" (
|
||||
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "singlehtml" (
|
||||
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pickle" (
|
||||
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the pickle files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "json" (
|
||||
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the JSON files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "htmlhelp" (
|
||||
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run HTML Help Workshop with the ^
|
||||
.hhp project file in %BUILDDIR%/htmlhelp.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "qthelp" (
|
||||
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run "qcollectiongenerator" with the ^
|
||||
.qhcp project file in %BUILDDIR%/qthelp, like this:
|
||||
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\testy_sphinxy.qhcp
|
||||
echo.To view the help file:
|
||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\testy_sphinxy.ghc
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "devhelp" (
|
||||
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "epub" (
|
||||
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The epub file is in %BUILDDIR%/epub.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latex" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latexpdf" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
cd %BUILDDIR%/latex
|
||||
make all-pdf
|
||||
cd %~dp0
|
||||
echo.
|
||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latexpdfja" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
cd %BUILDDIR%/latex
|
||||
make all-pdf-ja
|
||||
cd %~dp0
|
||||
echo.
|
||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "text" (
|
||||
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The text files are in %BUILDDIR%/text.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "man" (
|
||||
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The manual pages are in %BUILDDIR%/man.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "texinfo" (
|
||||
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "gettext" (
|
||||
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "changes" (
|
||||
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.The overview file is in %BUILDDIR%/changes.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "linkcheck" (
|
||||
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Link check complete; look for any errors in the above output ^
|
||||
or in %BUILDDIR%/linkcheck/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "doctest" (
|
||||
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Testing of doctests in the sources finished, look at the ^
|
||||
results in %BUILDDIR%/doctest/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "coverage" (
|
||||
%SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Testing of coverage in the sources finished, look at the ^
|
||||
results in %BUILDDIR%/coverage/python.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "xml" (
|
||||
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The XML files are in %BUILDDIR%/xml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pseudoxml" (
|
||||
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
|
||||
goto end
|
||||
)
|
||||
|
||||
:end
|
||||
@ECHO OFF
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set BUILDDIR=build
|
||||
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
|
||||
set I18NSPHINXOPTS=%SPHINXOPTS% source
|
||||
if NOT "%PAPER%" == "" (
|
||||
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
|
||||
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
if "%1" == "help" (
|
||||
:help
|
||||
echo.Please use `make ^<target^>` where ^<target^> is one of
|
||||
echo. html to make standalone HTML files
|
||||
echo. dirhtml to make HTML files named index.html in directories
|
||||
echo. singlehtml to make a single large HTML file
|
||||
echo. pickle to make pickle files
|
||||
echo. json to make JSON files
|
||||
echo. htmlhelp to make HTML files and a HTML help project
|
||||
echo. qthelp to make HTML files and a qthelp project
|
||||
echo. devhelp to make HTML files and a Devhelp project
|
||||
echo. epub to make an epub
|
||||
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
||||
echo. text to make text files
|
||||
echo. man to make manual pages
|
||||
echo. texinfo to make Texinfo files
|
||||
echo. gettext to make PO message catalogs
|
||||
echo. changes to make an overview over all changed/added/deprecated items
|
||||
echo. xml to make Docutils-native XML files
|
||||
echo. pseudoxml to make pseudoxml-XML files for display purposes
|
||||
echo. linkcheck to check all external links for integrity
|
||||
echo. doctest to run all doctests embedded in the documentation if enabled
|
||||
echo. coverage to run coverage check of the documentation if enabled
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "clean" (
|
||||
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
|
||||
del /q /s %BUILDDIR%\*
|
||||
goto end
|
||||
)
|
||||
|
||||
|
||||
REM Check if sphinx-build is available and fallback to Python version if any
|
||||
%SPHINXBUILD% 1>NUL 2>NUL
|
||||
if errorlevel 9009 goto sphinx_python
|
||||
goto sphinx_ok
|
||||
|
||||
:sphinx_python
|
||||
|
||||
set SPHINXBUILD=python -m sphinx.__init__
|
||||
%SPHINXBUILD% 2> nul
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.http://sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
:sphinx_ok
|
||||
|
||||
|
||||
if "%1" == "html" (
|
||||
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "dirhtml" (
|
||||
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "singlehtml" (
|
||||
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pickle" (
|
||||
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the pickle files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "json" (
|
||||
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the JSON files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "htmlhelp" (
|
||||
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run HTML Help Workshop with the ^
|
||||
.hhp project file in %BUILDDIR%/htmlhelp.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "qthelp" (
|
||||
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run "qcollectiongenerator" with the ^
|
||||
.qhcp project file in %BUILDDIR%/qthelp, like this:
|
||||
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\testy_sphinxy.qhcp
|
||||
echo.To view the help file:
|
||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\testy_sphinxy.ghc
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "devhelp" (
|
||||
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "epub" (
|
||||
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The epub file is in %BUILDDIR%/epub.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latex" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latexpdf" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
cd %BUILDDIR%/latex
|
||||
make all-pdf
|
||||
cd %~dp0
|
||||
echo.
|
||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latexpdfja" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
cd %BUILDDIR%/latex
|
||||
make all-pdf-ja
|
||||
cd %~dp0
|
||||
echo.
|
||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "text" (
|
||||
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The text files are in %BUILDDIR%/text.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "man" (
|
||||
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The manual pages are in %BUILDDIR%/man.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "texinfo" (
|
||||
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "gettext" (
|
||||
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "changes" (
|
||||
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.The overview file is in %BUILDDIR%/changes.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "linkcheck" (
|
||||
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Link check complete; look for any errors in the above output ^
|
||||
or in %BUILDDIR%/linkcheck/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "doctest" (
|
||||
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Testing of doctests in the sources finished, look at the ^
|
||||
results in %BUILDDIR%/doctest/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "coverage" (
|
||||
%SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Testing of coverage in the sources finished, look at the ^
|
||||
results in %BUILDDIR%/coverage/python.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "xml" (
|
||||
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The XML files are in %BUILDDIR%/xml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pseudoxml" (
|
||||
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
|
||||
goto end
|
||||
)
|
||||
|
||||
:end
|
||||
|
@@ -26,14 +26,14 @@ import time
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.pngmath',
|
||||
'sphinx.ext.pngmath',
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
# add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix(es) of source filenames.
|
||||
@@ -117,7 +117,7 @@ html_theme = 'sphinx_rtd_theme'
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
# add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
@@ -136,12 +136,12 @@ html_logo = 'simple_nut.png'
|
||||
# pixels large.
|
||||
html_favicon = 'nut.ico'
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
# add any extra paths that contain custom files (such as robots.txt or
|
||||
# .htaccess) here, relative to this directory. These files are copied
|
||||
# directly to the root of the documentation.
|
||||
#html_extra_path = []
|
||||
@@ -157,7 +157,7 @@ html_static_path = ['_static']
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
@@ -173,7 +173,7 @@ html_static_path = ['_static']
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
# If true, "created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
@@ -213,7 +213,7 @@ latex_elements = {
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
# additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
|
||||
# Latex figure (float) alignment
|
||||
@@ -225,10 +225,10 @@ latex_elements = {
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
_stdauthor = r'Alberto Demichelis'
|
||||
latex_documents = [
|
||||
('reference/index', 'reference.tex',
|
||||
'Squirrel Reference Manual', _stdauthor, 'manual'),
|
||||
('stdlib/index', 'stdlib.tex',
|
||||
'Squirrel Standard Library', _stdauthor, 'manual'),
|
||||
('reference/index', 'reference.tex',
|
||||
'Squirrel Reference Manual', _stdauthor, 'manual'),
|
||||
('stdlib/index', 'stdlib.tex',
|
||||
'Squirrel Standard Library', _stdauthor, 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
@@ -257,8 +257,8 @@ latex_documents = [
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
(master_doc, 'Squirrel', u'Squirrel Documentation',
|
||||
[author], 1)
|
||||
(master_doc, 'Squirrel', u'Squirrel Documentation',
|
||||
[author], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
@@ -271,9 +271,9 @@ man_pages = [
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'Squirrel', u'Squirrel Documentation',
|
||||
author, 'Squirrel', 'The Programming Language.',
|
||||
'Miscellaneous'),
|
||||
(master_doc, 'Squirrel', u'Squirrel Documentation',
|
||||
author, 'Squirrel', 'The Programming Language.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
@@ -285,5 +285,5 @@ texinfo_documents = [
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
||||
|
||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||
# If true, do not generate a @detailmenu in the "top" node's menu.
|
||||
#texinfo_no_detailmenu = False
|
||||
|
@@ -29,4 +29,4 @@ serialize (read) a closure and pushes it on top of the stack, the source is user
|
||||
:returns: a SQRESULT
|
||||
:remarks: closures with free variables cannot be serialized
|
||||
|
||||
serializes(writes) the closure on top of the stack, the desination is user defined through a write callback.
|
||||
serializes(writes) the closure on top of the stack, the destination is user defined through a write callback.
|
||||
|
@@ -13,11 +13,10 @@ Calls
|
||||
:param SQBool retval: if true the function will push the return value in the stack
|
||||
:param SQBool raiseerror: if true, if a runtime error occurs during the execution of the call, the vm will invoke the error handler.
|
||||
:returns: a SQRESULT
|
||||
:remarks: 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.
|
||||
|
||||
calls a closure or a native closure.
|
||||
|
||||
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.
|
||||
|
||||
When using to create an instance, push a dummy parameter to be filled with the newly-created instance for the constructor's 'this' parameter.
|
||||
|
||||
|
||||
|
||||
@@ -88,9 +87,28 @@ reset the last error in the virtual machine to null
|
||||
resumes the generator at the top position of the stack.
|
||||
|
||||
|
||||
.. _sq_tailcall:
|
||||
|
||||
.. c:function:: SQRESULT sq_tailcall(HSQUIRRELVM v, SQInteger nparams)
|
||||
|
||||
:param HSQUIRRELVM v: the target VM
|
||||
:param SQInteger params: number of parameters of the function
|
||||
|
||||
Calls a closure and removes the caller function from the call stack.
|
||||
This function must be invoke from a native closure and
|
||||
he return value of sq_tailcall must be returned by the caller function(see example).
|
||||
|
||||
*.eg*
|
||||
|
||||
::
|
||||
|
||||
SQInteger tailcall_something_example(HSQUIRRELVM v)
|
||||
{
|
||||
//push closure and parameters here
|
||||
...
|
||||
return sq_tailcall(v,2);
|
||||
}
|
||||
|
||||
.. _sq_throwerror:
|
||||
|
||||
.. c:function:: SQRESULT sq_throwerror(HSQUIRRELVM v, const SQChar * err)
|
||||
@@ -102,9 +120,6 @@ resumes the generator at the top position of the stack.
|
||||
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.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.. _sq_throwobject:
|
||||
|
||||
.. c:function:: SQRESULT sq_throwobject(HSQUIRRELVM v)
|
||||
|
@@ -76,4 +76,4 @@ enable/disable the error callback notification of handled exceptions.
|
||||
:param SQCOMPILERERROR f: A pointer to the error handler function
|
||||
: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.
|
||||
|
||||
sets the compiler error handler function
|
||||
sets the compiler error handler function
|
||||
|
@@ -69,4 +69,4 @@ sets the native debug hook. When a native hook is set it overrides any previousl
|
||||
:param SQStackInfos * si: pointer to the SQStackInfos structure that will store the stack informations
|
||||
:returns: a SQRESULT.
|
||||
|
||||
retrieve the calls stack informations of a ceratain level in the calls stack.
|
||||
retrieve the calls stack informations of a ceratain level in the calls stack.
|
||||
|
@@ -9,9 +9,9 @@ Garbage Collector
|
||||
.. c:function:: SQInteger sq_collectgarbage(HSQUIRRELVM v)
|
||||
|
||||
:param HSQUIRRELVM v: the target VM
|
||||
:remarks: this api only works with gabage collector builds (NO_GARBAGE_COLLECTOR is not defined)
|
||||
:remarks: this api only works with garbage collector builds (NO_GARBAGE_COLLECTOR is not defined)
|
||||
|
||||
runs the garbage collector and returns the number of reference cycles found(and deleted)
|
||||
runs the garbage collector and returns the number of reference cycles found (and deleted)
|
||||
|
||||
|
||||
|
||||
@@ -22,6 +22,6 @@ runs the garbage collector and returns the number of reference cycles found(and
|
||||
.. c:function:: SQRESULT sq_resurrectunreachable(HSQUIRRELVM v)
|
||||
|
||||
:param HSQUIRRELVM v: the target VM
|
||||
:remarks: this api only works with gabage collector builds (NO_GARBAGE_COLLECTOR is not defined)
|
||||
:remarks: this api only works with garbage collector builds (NO_GARBAGE_COLLECTOR is not defined)
|
||||
|
||||
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 debugging reference cycles.
|
||||
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.
|
||||
|
@@ -13,7 +13,7 @@ Object creation and handling
|
||||
:returns: a SQRESULT
|
||||
:remarks: the cloned closure holds the environment object as weak reference
|
||||
|
||||
pops an object from the stack(must be a table,instance or class) clones the closure at position idx in the stack and sets the popped object as environment of the cloned closure. Then pushes the new cloned closure on top of the stack.
|
||||
pops an object from the stack (must be a table, instance, or class); clones the closure at position idx in the stack and sets the popped object as environment of the cloned closure. Then pushes the new cloned closure on top of the stack.
|
||||
|
||||
|
||||
|
||||
@@ -54,8 +54,8 @@ gets the value of the bool at the idx position in the stack.
|
||||
.. c:function:: SQRESULT sq_getbyhandle(HSQUIRRELVM v, SQInteger idx, HSQMEMBERHANDLE* handle)
|
||||
|
||||
:param HSQUIRRELVM v: the target VM
|
||||
:param SQInteger idx: an index in the stack pointing to the class
|
||||
:param HSQMEMBERHANDLE* handle: a pointer the member handle
|
||||
:param SQInteger idx: an index in the stack pointing to the class or instance
|
||||
:param HSQMEMBERHANDLE* handle: a pointer to the member handle
|
||||
:returns: a SQRESULT
|
||||
|
||||
pushes the value of a class or instance member using a member handle (see sq_getmemberhandle)
|
||||
@@ -88,7 +88,7 @@ retrieves number of parameters and number of freevariables from a squirrel closu
|
||||
:param SQInteger idx: index of the target closure
|
||||
:returns: an SQRESULT
|
||||
|
||||
pushes the name of the closure at poistion idx in the stack. Note that the name can be a string or null if the closure is anonymous or a native closure with no name assigned to it.
|
||||
pushes the name of the closure at position idx in the stack. Note that the name can be a string or null if the closure is anonymous or a native closure with no name assigned to it.
|
||||
|
||||
|
||||
|
||||
@@ -177,9 +177,9 @@ gets the value of the integer at the idx position in the stack.
|
||||
:param SQInteger idx: an index in the stack pointing to the class
|
||||
:param HSQMEMBERHANDLE* handle: a pointer to the variable that will store the handle
|
||||
:returns: a SQRESULT
|
||||
:remarks: This method works only with classes and instances. A handle retrieved through a class can be later used to set or get values from one of the class instances and vice-versa. Handles retrieved from base classes are still valid in derived classes and respect inheritance rules.
|
||||
:remarks: This method works only with classes. A handle retrieved through a class can be later used to set or get values from one of the class instances. Handles retrieved from base classes are still valid in derived classes and respect inheritance rules.
|
||||
|
||||
pops a value from the stack and uses it as index to fetch the handle of a class member. The handle can be later used to set or get the member value using sq_getbyhandle(),sq_setbyhandle().
|
||||
pops a value from the stack and uses it as index to fetch the handle of a class member. The handle can be later used to set or get the member value using sq_getbyhandle(), sq_setbyhandle().
|
||||
|
||||
|
||||
|
||||
@@ -220,9 +220,9 @@ returns a pointer to a memory buffer that is at least as big as minsize.
|
||||
:param HSQUIRRELVM v: the target VM
|
||||
:param SQInteger idx: an index in the stack
|
||||
:returns: the size of the value at the position idx in the stack
|
||||
:remarks: this function only works with strings,arrays,tables,classes,instances and userdata if the value is not a valid type types the function will return -1.
|
||||
:remarks: this function only works with strings, arrays, tables, classes, instances, and userdata if the value is not a valid type, the function will return -1.
|
||||
|
||||
returns the size of a value at the idx position in the stack, if the value is a class or a class instance the size returned is the size of the userdata buffer(see sq_setclassudsize).
|
||||
returns the size of a value at the idx position in the stack. If the value is a class or a class instance the size returned is the size of the userdata buffer (see sq_setclassudsize).
|
||||
|
||||
|
||||
|
||||
@@ -243,6 +243,21 @@ gets a pointer to the string at the idx position in the stack.
|
||||
|
||||
|
||||
|
||||
.. _sq_getstringandsize:
|
||||
|
||||
.. c:function:: SQRESULT sq_getstringandsize(HSQUIRRELVM v, SQInteger idx, const SQChar ** c, SQInteger* size)
|
||||
|
||||
:param HSQUIRRELVM v: the target VM
|
||||
:param SQInteger idx: an index in the stack
|
||||
:param const SQChar ** c: a pointer to the pointer that will point to the string
|
||||
:param SQInteger * size: a pointer to a SQInteger which will receive the size of the string
|
||||
:returns: a SQRESULT
|
||||
|
||||
gets a pointer to the string at the idx position in the stack; additionally retrieves its size.
|
||||
|
||||
|
||||
|
||||
|
||||
.. _sq_getthread:
|
||||
|
||||
.. c:function:: SQRESULT sq_getthread(HSQUIRRELVM v, SQInteger idx, HSQUIRRELVM* v)
|
||||
@@ -252,7 +267,7 @@ gets a pointer to the string at the idx position in the stack.
|
||||
:param HSQUIRRELVM* v: A pointer to the variable that will store the thread pointer
|
||||
:returns: a SQRESULT
|
||||
|
||||
gets a a pointer to the thread the idx position in the stack.
|
||||
gets a pointer to the thread the idx position in the stack.
|
||||
|
||||
|
||||
|
||||
@@ -282,7 +297,7 @@ returns the type of the value at the position idx in the stack
|
||||
:returns: a SQRESULT
|
||||
:remarks: the function works also with instances. if the taget object is an instance, the typetag of it's base class is fetched.
|
||||
|
||||
gets the typetag of the object(userdata or class) at position idx in the stack.
|
||||
gets the typetag of the object (userdata or class) at position idx in the stack.
|
||||
|
||||
|
||||
|
||||
@@ -340,7 +355,7 @@ creates a new array and pushes it in the stack
|
||||
:param SQBool hasbase: if the parameter is true the function expects a base class on top of the stack.
|
||||
:returns: a SQRESULT
|
||||
|
||||
creates a new class object. If the parameter 'hasbase' is different than 0, the function pops a class from the stack and inherits the new created class from it.
|
||||
creates a new class object. If the parameter 'hasbase' is different than 0, the function pops a class from the stack and inherits the new created class from it. The new class is pushed in the stack.
|
||||
|
||||
|
||||
|
||||
@@ -379,7 +394,7 @@ creates a new table and pushes it in the stack
|
||||
:param HSQUIRRELVM v: the target VM
|
||||
:param SQInteger initialcapacity: number of key/value pairs to preallocate
|
||||
|
||||
creates a new table and pushes it in the stack. This function allows to specify the initial capacity of the table to prevent unnecessary rehashing when the number of slots required is known at creation-time.
|
||||
creates a new table and pushes it in the stack. This function allows you to specify the initial capacity of the table to prevent unnecessary rehashing when the number of slots required is known at creation-time.
|
||||
|
||||
|
||||
|
||||
@@ -431,7 +446,7 @@ pushes a float into the stack
|
||||
:param HSQUIRRELVM v: the target VM
|
||||
:param SQInteger n: the integer that has to be pushed
|
||||
|
||||
pushes a integer into the stack
|
||||
pushes an integer into the stack
|
||||
|
||||
|
||||
|
||||
@@ -455,7 +470,7 @@ pushes a null value into the stack
|
||||
|
||||
:param HSQUIRRELVM v: the target VM
|
||||
:param const SQChar * s: pointer to the string that has to be pushed
|
||||
:param SQInteger len: lenght of the string pointed by s
|
||||
:param SQInteger len: length of the string pointed by s
|
||||
:remarks: if the parameter len is less than 0 the VM will calculate the length using strlen(s)
|
||||
|
||||
pushes a string in the stack
|
||||
@@ -501,7 +516,7 @@ pops a value from the stack and sets it to a class or instance member using a me
|
||||
:param SQInteger udsize: size in bytes reserved for user data
|
||||
:returns: a SQRESULT
|
||||
|
||||
Sets the user data size of a class. If a class 'user data size' is greater than 0. When an instance of the class is created additional space will is reserved at the end of the memory chunk where the instance is stored. The userpointer of the instance will also be automatically set to this memory area. This allows to minimize allocations in applications that have to carry data along with the class instance.
|
||||
Sets the user data size of a class. If a class 'user data size' is greater than 0. When an instance of the class is created additional space will be reserved at the end of the memory chunk where the instance is stored. The userpointer of the instance will also be automatically set to this memory area. This allows you to minimize allocations in applications that have to carry data along with the class instance.
|
||||
|
||||
|
||||
|
||||
@@ -515,7 +530,7 @@ Sets the user data size of a class. If a class 'user data size' is greater than
|
||||
:param SQInteger idx: index of the target closure
|
||||
:returns: an SQRESULT
|
||||
|
||||
pops a table from the stack and sets it as root of the closre at position idx in the stack
|
||||
pops a table from the stack and sets it as root of the closure at position idx in the stack
|
||||
|
||||
|
||||
|
||||
@@ -545,7 +560,7 @@ sets the userpointer of the class instance at position idx in the stack.
|
||||
:param const SQChar * name: the name that has to be set
|
||||
:returns: an SQRESULT
|
||||
|
||||
sets the name of the native closure at the position idx in the stack. the name of a native closure is purely for debug pourposes. The name is retieved trough the function sq_stackinfos() while the closure is in the call stack.
|
||||
sets the name of the native closure at the position idx in the stack. The name of a native closure is purely for debug purposes. The name is retrieved trough the function sq_stackinfos() while the closure is in the call stack.
|
||||
|
||||
|
||||
|
||||
@@ -556,11 +571,11 @@ sets the name of the native closure at the position idx in the stack. the name o
|
||||
.. c:function:: SQRESULT sq_setparamscheck(HSQUIRRELVM v, SQInteger nparamscheck, const SQChar * typemask)
|
||||
|
||||
:param HSQUIRRELVM v: the target VM
|
||||
:param SQInteger nparamscheck: defines the parameters number check policy(0 disable the param checking). if nparamscheck is greater than 0 the VM ensures that the number of parameters is exactly the number specified in nparamscheck(eg. if nparamscheck == 3 the function can only be called with 3 parameters). if nparamscheck is less than 0 the VM ensures that the closure is called with at least the absolute value of the number specified in nparamcheck(eg. nparamscheck == -3 will check that the function is called with at least 3 parameters). the hidden paramater 'this' is included in this number free variables aren't. If SQ_MATCHTYPEMASKSTRING is passed instead of the number of parameters, the function will automatically extrapolate the number of parameters to check from the typemask(eg. if the typemask is ".sn" is like passing 3).
|
||||
:param const SQChar * typemask: defines a mask to validate the parametes types passed to the function. if the parameter is NULL no typechecking is applyed(default).
|
||||
:remarks: The typemask consists in a zero teminated string that represent the expected parameter type. The types are expressed as follows: 'o' null, 'i' integer, 'f' float, 'n' integer or float, 's' string, 't' table, 'a' array, 'u' userdata, 'c' closure and nativeclosure, 'g' generator, 'p' userpointer, 'v' thread, 'x' instance(class instance), 'y' class, 'b' bool. and '.' any type. The symbol '|' can be used as 'or' to accept multiple types on the same parameter. There isn't any limit on the number of 'or' that can be used. Spaces are ignored so can be inserted between types to increase readbility. For instance to check a function that espect a table as 'this' a string as first parameter and a number or a userpointer as second parameter, the string would be "tsn|p" (table,string,number or userpointer). If the parameters mask is contains less parameters than 'nparamscheck' the remaining parameters will not be typechecked.
|
||||
:param SQInteger nparamscheck: defines the parameters number check policy (0 disables the param checking). If nparamscheck is greater than 0, the VM ensures that the number of parameters is exactly the number specified in nparamscheck (eg. if nparamscheck == 3 the function can only be called with 3 parameters). If nparamscheck is less than 0 the VM ensures that the closure is called with at least the absolute value of the number specified in nparamcheck (eg. nparamscheck == -3 will check that the function is called with at least 3 parameters). The hidden parameter 'this' is included in this number; free variables aren't. If SQ_MATCHTYPEMASKSTRING is passed instead of the number of parameters, the function will automatically infer the number of parameters to check from the typemask (eg. if the typemask is ".sn", it is like passing 3).
|
||||
:param const SQChar * typemask: defines a mask to validate the parametes types passed to the function. If the parameter is NULL, no typechecking is applied (default).
|
||||
:remarks: The typemask consists in a zero terminated string that represent the expected parameter type. The types are expressed as follows: 'o' null, 'i' integer, 'f' float, 'n' integer or float, 's' string, 't' table, 'a' array, 'u' userdata, 'c' closure and nativeclosure, 'g' generator, 'p' userpointer, 'v' thread, 'x' instance(class instance), 'y' class, 'b' bool. and '.' any type. The symbol '|' can be used as 'or' to accept multiple types on the same parameter. There isn't any limit on the number of 'or' that can be used. Spaces are ignored so can be inserted between types to increase readability. For instance to check a function that expect a table as 'this' a string as first parameter and a number or a userpointer as second parameter, the string would be "tsn|p" (table,string,number or userpointer). If the parameters mask is contains fewer parameters than 'nparamscheck', the remaining parameters will not be typechecked.
|
||||
|
||||
Sets the parameters validation scheme for the native closure at the top position in the stack. Allows to validate the number of paramters accepted by the function and optionally their types. If the function call do not comply with the parameter schema set by sq_setparamscheck, an exception is thrown.
|
||||
Sets the parameter validation scheme for the native closure at the top position in the stack. Allows you to validate the number of parameters accepted by the function and optionally their types. If the function call does not comply with the parameter schema set by sq_setparamscheck, an exception is thrown.
|
||||
|
||||
*.eg*
|
||||
|
||||
@@ -572,7 +587,7 @@ Sets the parameters validation scheme for the native closure at the top position
|
||||
SQUserPointer p;
|
||||
const SQChar *s;
|
||||
SQInteger i;
|
||||
//no type checking, if the call comply to the mask
|
||||
//no type checking, if the call complies with the mask
|
||||
//surely the functions will succeed.
|
||||
sq_getuserdata(v,1,&p,NULL);
|
||||
sq_getstring(v,2,&s);
|
||||
@@ -603,7 +618,7 @@ Sets the parameters validation scheme for the native closure at the top position
|
||||
:param SQRELEASEHOOK hook: a function pointer to the hook(see sample below)
|
||||
:remarks: the function hook is called by the VM before the userdata memory is deleted.
|
||||
|
||||
sets the release hook of the userdata, class instance or class at position idx in the stack.
|
||||
sets the release hook of the userdata, class instance, or class at position idx in the stack.
|
||||
|
||||
*.eg*
|
||||
|
||||
@@ -632,7 +647,7 @@ sets the release hook of the userdata, class instance or class at position idx i
|
||||
:param SQUserPointer typetag: an arbitrary SQUserPointer
|
||||
:returns: a SQRESULT
|
||||
|
||||
sets the typetag of the object(userdata or class) at position idx in the stack.
|
||||
sets the typetag of the object (userdata or class) at position idx in the stack.
|
||||
|
||||
|
||||
|
||||
@@ -645,7 +660,7 @@ sets the typetag of the object(userdata or class) at position idx in the stack.
|
||||
:param HSQUIRRELVM v: the target VM
|
||||
:param SQInteger idx: an index in the stack
|
||||
:param SQBool * b: A pointer to the bool that will store the value
|
||||
:remarks: if the object is not a bool the function converts the value too bool according to squirrel's rules. For instance the number 1 will result in true, and the number 0 in false.
|
||||
:remarks: if the object is not a bool the function converts the value to bool according to squirrel's rules. For instance the number 1 will result in true, and the number 0 in false.
|
||||
|
||||
gets the value at position idx in the stack as bool.
|
||||
|
||||
@@ -674,7 +689,7 @@ converts the object at position idx in the stack to string and pushes the result
|
||||
:param SQInteger idx: an index in the stack
|
||||
:returns: a SQRESULT
|
||||
|
||||
pushes the type name of the value at the position idx in the stack, it also invokes the _typeof metamethod for tables and class instances that implement it; in that case the pushed object could be something other than a string (is up to the _typeof implementation).
|
||||
pushes the type name of the value at the position idx in the stack. It also invokes the _typeof metamethod for tables and class instances that implement it; in that case the pushed object could be something other than a string (is up to the _typeof implementation).
|
||||
|
||||
|
||||
|
||||
|
@@ -25,7 +25,7 @@ pops a value from the stack and pushes it in the back of the array at the positi
|
||||
|
||||
:param HSQUIRRELVM v: the target VM
|
||||
:param SQInteger idx: index of the target array in the stack
|
||||
:param SQInteger destpos: the postion in the array where the item has to be inserted
|
||||
:param SQInteger destpos: the position in the array where the item has to be inserted
|
||||
:returns: a SQRESULT
|
||||
:remarks: Only works on arrays.
|
||||
|
||||
@@ -74,7 +74,7 @@ removes an item from an array
|
||||
:param SQInteger idx: index of the target array in the stack
|
||||
:param SQInteger newsize: requested size of the array
|
||||
:returns: a SQRESULT
|
||||
:remarks: Only works on arrays.if newsize if greater than the current size the new array slots will be filled with nulls.
|
||||
:remarks: Only works on arrays. If newsize if greater than the current size the new array slots will be filled with nulls.
|
||||
|
||||
resizes the array at the position idx in the stack.
|
||||
|
||||
@@ -91,7 +91,7 @@ resizes the array at the position idx in the stack.
|
||||
:returns: a SQRESULT
|
||||
:remarks: Only works on arrays.
|
||||
|
||||
reverse an array in place.
|
||||
reverses an array in place.
|
||||
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ reverse an array in place.
|
||||
:returns: a SQRESULT
|
||||
:remarks: Only works on tables and arrays.
|
||||
|
||||
clears all the element of the table/array at position idx in the stack.
|
||||
clears all the elements of the table/array at position idx in the stack.
|
||||
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ clears all the element of the table/array at position idx in the stack.
|
||||
:param SQInteger idx: index of the target object in the stack
|
||||
:returns: a SQRESULT
|
||||
|
||||
Clones the table, array or class instance at the position idx, clones it and pushes the new object in the stack.
|
||||
pushes a clone of the table, array, or class instance at the position idx.
|
||||
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ Clones the table, array or class instance at the position idx, clones it and pus
|
||||
:returns: a SQRESULT
|
||||
:remarks: invoke the _newslot metamethod in the table delegate. it only works on tables. [this function is deperecated since version 2.0.5 use sq_newslot() instead]
|
||||
|
||||
pops a key and a value from the stack and performs a set operation on the table or class that is at position idx in the stack, if the slot does not exits it will be created.
|
||||
pops a key and a value from the stack and performs a set operation on the table or class that is at position idx in the stack; if the slot does not exist, it will be created.
|
||||
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ pops a key and a value from the stack and performs a set operation on the table
|
||||
:returns: a SQRESULT
|
||||
:remarks: invoke the _delslot metamethod in the table delegate. it only works on tables.
|
||||
|
||||
pops a key from the stack and delete the slot indexed by it from the table at position idx in the stack, if the slot does not exits nothing happens.
|
||||
pops a key from the stack and delete the slot indexed by it from the table at position idx in the stack; if the slot does not exist, nothing happens.
|
||||
|
||||
|
||||
|
||||
@@ -164,9 +164,9 @@ pops a key from the stack and delete the slot indexed by it from the table at po
|
||||
:param HSQUIRRELVM v: the target VM
|
||||
:param SQInteger idx: index of the target object in the stack
|
||||
:returns: a SQRESULT
|
||||
:remarks: this call will invokes the delegation system like a normal dereference it only works on tables, arrays and userdata. if the function fails nothing will be pushed in the stack.
|
||||
:remarks: this call will invokes the delegation system like a normal dereference it only works on tables, arrays, classes, instances and userdata; if the function fails, nothing will be pushed in the stack.
|
||||
|
||||
pops a key from the stack and performs a get operation on the object at the position idx in the stack, and pushes the result in the stack.
|
||||
pops a key from the stack and performs a get operation on the object at the position idx in the stack; and pushes the result in the stack.
|
||||
|
||||
|
||||
|
||||
@@ -180,7 +180,7 @@ pops a key from the stack and performs a get operation on the object at the posi
|
||||
:param SQInteger idx: index of the target class in the stack
|
||||
:returns: a SQRESULT
|
||||
|
||||
Gets the attribute of a class mameber. The function pops a key from the stack and pushes the attribute of the class member indexed by they key from class at position idx in the stack. If key is null the function gets the class level attribute.
|
||||
Gets the attribute of a class member. The function pops a key from the stack and pushes the attribute of the class member indexed by they key from a class at position idx in the stack. If key is null the function gets the class level attribute.
|
||||
|
||||
|
||||
|
||||
@@ -267,7 +267,7 @@ pushes the object pointed by the weak reference at position idx in the stack.
|
||||
:returns: SQTrue if the instance at position -2 in the stack is an instance of the class object at position -1 in the stack.
|
||||
:remarks: The function doesn't pop any object from the stack.
|
||||
|
||||
Determintes if an object is an instance of a certain class. Expects an istance and a class in the stack.
|
||||
Determines if an object is an instance of a certain class. Expects an instance and a class in the stack.
|
||||
|
||||
|
||||
|
||||
@@ -283,7 +283,7 @@ Determintes if an object is an instance of a certain class. Expects an istance a
|
||||
:returns: a SQRESULT
|
||||
:remarks: Invokes the _newmember metamethod in the class. it only works on classes.
|
||||
|
||||
pops a key, a value and an object(that will be set as attribute of the member) from the stack and performs a new slot operation on the class that is at position idx in the stack, if the slot does not exits it will be created.
|
||||
pops a key, a value and an object (which will be set as attribute of the member) from the stack and performs a new slot operation on the class that is at position idx in the stack; if the slot does not exist, it will be created.
|
||||
|
||||
|
||||
|
||||
@@ -299,7 +299,7 @@ pops a key, a value and an object(that will be set as attribute of the member) f
|
||||
:returns: a SQRESULT
|
||||
:remarks: Invokes the _newslot metamethod in the table delegate. it only works on tables and classes.
|
||||
|
||||
pops a key and a value from the stack and performs a set operation on the table or class that is at position idx in the stack, if the slot does not exits it will be created.
|
||||
pops a key and a value from the stack and performs a set operation on the table or class that is at position idx in the stack, if the slot does not exist it will be created.
|
||||
|
||||
|
||||
|
||||
@@ -313,7 +313,7 @@ pops a key and a value from the stack and performs a set operation on the table
|
||||
:param SQInteger idx: index of the target object in the stack
|
||||
:returns: a SQRESULT
|
||||
|
||||
Pushes in the stack the next key and value of an array, table or class slot. To start the iteration this function expects a null value on top of the stack; at every call the function will substitute the null value with an iterator and push key and value of the container slot. Every iteration the application has to pop the previous key and value but leave the iterator(that is used as reference point for the next iteration). The function will fail when all slots have been iterated(see Tables and arrays manipulation).
|
||||
Pushes in the stack the next key and value of an array, table, or class slot. To start the iteration this function expects a null value on top of the stack; at every call the function will substitute the null value with an iterator and push key and value of the container slot. Every iteration the application has to pop the previous key and value but leave the iterator(that is used as reference point for the next iteration). The function will fail when all slots have been iterated(see Tables and arrays manipulation).
|
||||
|
||||
|
||||
|
||||
@@ -328,7 +328,7 @@ Pushes in the stack the next key and value of an array, table or class slot. To
|
||||
:param SQBool pushval: if this param is true the function will push the value of the deleted slot.
|
||||
:returns: a SQRESULT
|
||||
|
||||
Deletes a slot from a table without employing the _delslot metamethod. pops a key from the stack and delete the slot indexed by it from the table at position idx in the stack, if the slot does not exits nothing happens.
|
||||
Deletes a slot from a table without employing the _delslot metamethod. Pops a key from the stack and delete the slot indexed by it from the table at position idx in the stack; if the slot does not exist nothing happens.
|
||||
|
||||
|
||||
|
||||
@@ -359,7 +359,7 @@ pops a key from the stack and performs a get operation on the object at position
|
||||
:returns: a SQRESULT
|
||||
:remarks: it only works on classes.
|
||||
|
||||
pops a key, a value and an object(that will be set as attribute of the member) from the stack and performs a new slot operation on the class that is at position idx in the stack, if the slot does not exits it will be created.
|
||||
pops a key, a value and an object(that will be set as attribute of the member) from the stack and performs a new slot operation on the class that is at position idx in the stack; if the slot does not exist it will be created.
|
||||
|
||||
|
||||
|
||||
@@ -403,7 +403,7 @@ pops a key and a value from the stack and performs a set operation on the object
|
||||
:param SQInteger idx: index of the target class in the stack.
|
||||
:returns: a SQRESULT
|
||||
|
||||
Sets the attribute of a class mameber. The function pops a key and a value from the stack and sets the attribute (indexed by they key) on the class at position idx in the stack. If key is null the function sets the class level attribute. If the function succeed, the old attribute value is pushed in the stack.
|
||||
Sets the attribute of a class member. The function pops a key and a value from the stack and sets the attribute (indexed by the key) on the class at position idx in the stack. If key is null the function sets the class level attribute. If the function succeed, the old attribute value is pushed in the stack.
|
||||
|
||||
|
||||
|
||||
@@ -416,9 +416,9 @@ Sets the attribute of a class mameber. The function pops a key and a value from
|
||||
:param HSQUIRRELVM v: the target VM
|
||||
:param SQInteger idx: index of the target object in the stack
|
||||
:returns: a SQRESULT
|
||||
:remarks: to remove the delgate from an object is necessary to use null as delegate instead of a table.
|
||||
:remarks: to remove the delegate from an object, set a null value.
|
||||
|
||||
pops a table from the stack and sets it as delegate of the object at the position idx in the stack.
|
||||
pops a table from the stack and sets it as the delegate of the object at the position idx in the stack.
|
||||
|
||||
|
||||
|
||||
@@ -433,7 +433,7 @@ pops a table from the stack and sets it as delegate of the object at the positio
|
||||
:param SQInteger nval: 0 based index of the free variable(relative to the closure).
|
||||
:returns: a SQRESULT
|
||||
|
||||
pops a value from the stack and sets it as free variable of the closure at the position idx in the stack.
|
||||
pops a value from the stack and sets it as a free variable of the closure at the position idx in the stack.
|
||||
|
||||
|
||||
|
||||
@@ -446,6 +446,6 @@ pops a value from the stack and sets it as free variable of the closure at the p
|
||||
:param HSQUIRRELVM v: the target VM
|
||||
:param SQInteger idx: index to the target object in the stack
|
||||
:returns: a SQRESULT
|
||||
:remarks: if the object at idx position is an integer,float,bool or null the object itself is pushed instead of a weak ref.
|
||||
:remarks: if the object at idx position is one of (integer, float, bool, null), the object itself is pushed instead of a weak ref.
|
||||
|
||||
pushes a weak reference to the object at position idx in the stack.
|
||||
pushes a weak reference to the object at position idx in the stack.
|
||||
|
@@ -24,7 +24,7 @@ adds a reference to an object handler.
|
||||
:param HSQOBJECT* o: pointer to an object handler
|
||||
:param SQUserPointer* typetag: a pointer to the variable that will store the tag
|
||||
:returns: a SQRESULT
|
||||
:remarks: the function works also with instances. if the taget object is an instance, the typetag of it's base class is fetched.
|
||||
:remarks: the function works also with instances. if the target object is an instance, the typetag of it's base class is fetched.
|
||||
|
||||
gets the typetag of a raw object reference(userdata or class).
|
||||
|
||||
@@ -145,7 +145,7 @@ push an object referenced by an object handler into the stack.
|
||||
:param HSQUIRRELVM v: the target VM
|
||||
:param HSQOBJECT* po: pointer to an object handler
|
||||
:returns: SQTrue if the object handler released has lost all is references(the ones added with sq_addref). SQFalse otherwise.
|
||||
:remarks: the function will reset the object handler to null when it losts all references.
|
||||
:remarks: the function will reset the object handler to null when it loses all references.
|
||||
|
||||
remove a reference from an object handler.
|
||||
|
||||
|
@@ -13,7 +13,7 @@ Stack Operations
|
||||
:returns: == 0 if obj1==obj2
|
||||
:returns: < 0 if obj1<obj2
|
||||
|
||||
compares 2 object from the stack and compares them.
|
||||
compares 2 object from the top of the stack. obj2 should be pushed before obj1.
|
||||
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ removes an element from an arbitrary position in the stack
|
||||
:param SQInteger nsize: required stack size
|
||||
:returns: a SQRESULT
|
||||
|
||||
ensure that the stack space left is at least of a specified size.If the stack is smaller it will automatically grow. if there's a memtamethod currently running the function will fail and the stack will not be resized, this situatuation has to be considered a "stack overflow".
|
||||
ensure that the stack space left is at least of a specified size.If the stack is smaller it will automatically grow. If there's a metamethod currently running the function will fail and the stack will not be resized, this situation has to be considered a "stack overflow".
|
||||
|
||||
|
||||
|
||||
@@ -104,4 +104,4 @@ ensure that the stack space left is at least of a specified size.If the stack is
|
||||
:param HSQUIRRELVM v: the target VM
|
||||
:param SQInteger v: the new top index
|
||||
|
||||
resize the stack, if new top is bigger then the current top the function will push nulls.
|
||||
resize the stack. If new top is bigger then the current top the function will push nulls.
|
||||
|
@@ -63,7 +63,7 @@ returns the current print function of the given Virtual machine. (see sq_setprin
|
||||
:param HSQUIRRELVM v: the target VM
|
||||
:returns: the current VMs shared foreign pointer
|
||||
|
||||
Returns the shared foreign pointer of a group of friend VMs .
|
||||
Returns the shared foreign pointer of a group of friend VMs
|
||||
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ Returns the shared foreign pointer of a group of friend VMs .
|
||||
:param HSQUIRRELVM v: the target VM
|
||||
:returns: the current VMs release hook.
|
||||
|
||||
Returns the shared release hook of a group of friend VMs .
|
||||
Returns the shared release hook of a group of friend VMs
|
||||
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ Returns the shared release hook of a group of friend VMs .
|
||||
|
||||
:returns: version number of the vm(as in SQUIRREL_VERSION_NUMBER).
|
||||
|
||||
returns the version number of the vm.
|
||||
returns the version number of the vm
|
||||
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ returns the version number of the vm.
|
||||
:param HSQUIRRELVM v: the target VM
|
||||
:returns: the current VMs release hook.
|
||||
|
||||
Returns the release hook of a VM instance.
|
||||
Returns the release hook of a VM instance
|
||||
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ returns the execution state of a virtual machine
|
||||
:param HSQUIRRELVM src: the source VM
|
||||
:param SQInteger idx: the index in the source stack of the value that has to be moved
|
||||
|
||||
pushes the object at the position 'idx' of the source vm stack in the destination vm stack.
|
||||
pushes the object at the position 'idx' of the source vm stack in the destination vm stack
|
||||
|
||||
|
||||
|
||||
@@ -297,7 +297,7 @@ Sets the release hook of a certain VM group. The release hook is invoked when th
|
||||
:param HSQUIRRELVM v: the target VM
|
||||
:param SQRELESEHOOK hook: The hook that has to be set
|
||||
|
||||
Sets the release hook of a certain VM instance. The release hook is invoked when the vm is destroyed. The userpointer passed to the function is the vm foreignpointer(see sq_setforeignpointer())
|
||||
Sets the release hook of a certain VM instance. The release hook is invoked when the vm is destroyed. The userpointer passed to the function is the vm foreignpointer (see sq_setforeignpointer())
|
||||
|
||||
|
||||
|
||||
@@ -338,4 +338,4 @@ Suspends the execution of the specified vm.
|
||||
:param SQBool throwerror: if true, the vm will thow an exception as soon as is resumed. the exception payload must be set beforehand invoking sq_thowerror().
|
||||
:returns: an HRESULT.
|
||||
|
||||
Wake up the execution a previously suspended virtual machine.
|
||||
wake up the execution a previously suspended virtual machine
|
||||
|
@@ -13,19 +13,19 @@ Unicode
|
||||
.. index:: single: Unicode
|
||||
|
||||
By default Squirrel strings are plain 8-bits ASCII characters; however if the symbol
|
||||
'SQUNICODE' is defined the VM, compiler and API will use 16-bits characters (UCS2).
|
||||
'SQUNICODE' is defined the VM, compiler and API will use 16-bit characters (UCS2).
|
||||
|
||||
.. _squirrel_64bits:
|
||||
|
||||
---------------------------------
|
||||
Squirrel on 64 bits architectures
|
||||
---------------------------------
|
||||
--------------------------------
|
||||
Squirrel on 64-bit architectures
|
||||
--------------------------------
|
||||
|
||||
.. index::
|
||||
single: Squirrel on 64 bits architectures
|
||||
single: Squirrel on 64-bit architectures
|
||||
single: 64 bits
|
||||
|
||||
Squirrel can be compiled on 64 bits architectures by defining '_SQ64' in the C++
|
||||
Squirrel can be compiled on 64-bit architectures by defining '_SQ64' in the C++
|
||||
preprocessor. This flag should be defined in any project that includes 'squirrel.h'.
|
||||
|
||||
.. _userdata_alignment:
|
||||
@@ -37,13 +37,13 @@ Userdata Alignment
|
||||
.. index:: single: Userdata Alignment
|
||||
|
||||
Both class instances and userdatas can have a buffer associated to them.
|
||||
Squirrel specifies the alignment(in bytes) through the peroprocessor defining 'SQ_ALIGNMENT'.
|
||||
By default SQ_ALIGNMENT is defined as 4 for 32 bits builds and 8 for 64bits builds and builds that use 64bits floats.
|
||||
Squirrel specifies the alignment(in bytes) through the preprocessor defining 'SQ_ALIGNMENT'.
|
||||
By default SQ_ALIGNMENT is defined as 4 for 32-bit builds and 8 for 64-bit builds and builds that use 64-bit floats.
|
||||
It is possible to override the value of SQ_ALIGNMENT respecting the following rules.
|
||||
SQ_ALIGNMENT shall be less than or equal to SQ_MALLOC alignments, and it shall be power of 2.
|
||||
|
||||
.. note:: This only applies for userdata allocated by the VM, specified via sq_setclassudsize() or belonging to a userdata object.
|
||||
userpointers specified by the user are not affected by alignemnt rules.
|
||||
userpointers specified by the user are not affected by alignment rules.
|
||||
|
||||
.. _standalone_vm:
|
||||
|
||||
@@ -53,7 +53,7 @@ Stand-alone VM without compiler
|
||||
|
||||
.. index:: single: Stand-alone VM without compiler
|
||||
|
||||
Squirrel's VM can be compiled without it's compiler by defining 'NO_COMPILER' in the C++ preprocessor.
|
||||
Squirrel's VM can be compiled without its compiler by defining 'NO_COMPILER' in the C++ preprocessor.
|
||||
When 'NO_COMPILER' is defined all function related to the compiler (eg. sq_compile) will fail. Other functions
|
||||
that conditionally load precompiled bytecode or compile a file (eg. sqstd_dofile) will only work with
|
||||
precompiled bytecode.
|
||||
|
@@ -16,7 +16,7 @@ parameter is > 0. ::
|
||||
sq_pushinteger(v,1);
|
||||
sq_pushfloat(v,2.0);
|
||||
sq_pushstring(v,"three",-1);
|
||||
sq_call(v,4,SQFalse);
|
||||
sq_call(v,4,SQFalse,SQFalse);
|
||||
sq_pop(v,2); //pops the roottable and the function
|
||||
|
||||
this is equivalent to the following Squirrel code::
|
||||
|
@@ -8,7 +8,7 @@ You can compile a Squirrel script with the function *sq_compile*.::
|
||||
|
||||
typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer userdata);
|
||||
|
||||
SQRESULT sq_compile(HSQUIRRELVM v,SQREADFUNC read,SQUserPointer p,
|
||||
SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,
|
||||
const SQChar *sourcename,SQBool raiseerror);
|
||||
|
||||
In order to compile a script is necessary for the host application to implement a reader
|
||||
|
@@ -23,7 +23,7 @@ When the function is called, the stackbase is the first parameter of the functio
|
||||
top is the last. In order to return a value the function has to push it in the stack and
|
||||
return 1.
|
||||
|
||||
Function parameters are in the stack from postion 1 ('this') to *n*.
|
||||
Function parameters are in the stack from position 1 ('this') to *n*.
|
||||
*sq_gettop()* can be used to determinate the number of parameters.
|
||||
|
||||
If the function has free variables, those will be in the stack after the explicit parameters
|
||||
@@ -99,7 +99,8 @@ Here an example of how to register a function::
|
||||
{
|
||||
sq_pushroottable(v);
|
||||
sq_pushstring(v,fname,-1);
|
||||
sq_newclosure(v,f,0,0); //create a new function
|
||||
sq_newclosure(v,f,0); //create a new function
|
||||
sq_newslot(v,-3,SQFalse);
|
||||
sq_pop(v,1); //pops the root table
|
||||
return 0;
|
||||
}
|
||||
|
@@ -11,11 +11,11 @@ The object can be also re-pushed in the VM stack using sq_pushobject().::
|
||||
|
||||
HSQOBJECT obj;
|
||||
|
||||
sq_resetobject(v,&obj) //initialize the handle
|
||||
sq_resetobject(&obj); //initialize the handle
|
||||
sq_getstackobj(v,-2,&obj); //retrieve an object handle from the pos -2
|
||||
sq_addref(v,&obj); //adds a reference to the object
|
||||
|
||||
... //do stuff
|
||||
|
||||
sq_pushobject(v,&obj); //push the object in the stack
|
||||
sq_pushobject(v,obj); //push the object in the stack
|
||||
sq_release(v,&obj); //relese the object
|
||||
|
@@ -47,7 +47,7 @@ To get a value from an array or table::
|
||||
|
||||
SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx);
|
||||
|
||||
To get or set a value from a table without employ delegation::
|
||||
To get or set a value from a table without employing delegation::
|
||||
|
||||
SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx);
|
||||
SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx);
|
||||
|
@@ -5,7 +5,7 @@ The registry table
|
||||
==================
|
||||
|
||||
The registry table is an hidden table shared between vm and all his thread(friend vms).
|
||||
This table is accessible only through the C API and is ment to be an utility structure
|
||||
This table is accessible only through the C API and is meant to be an utility structure
|
||||
for native C library implementation.
|
||||
For instance the sqstdlib(squirrel standard library)uses it to store configuration and shared objects
|
||||
delegates.
|
||||
|
@@ -65,7 +65,7 @@ To force the stack to a certain size you can call *sq_settop* ::
|
||||
|
||||
void sq_settop(HSQUIRRELVM v,SQInteger newtop);
|
||||
|
||||
If the newtop is bigger than the previous one, the new posistions in the stack will be
|
||||
If the newtop is bigger than the previous one, the new positions in the stack will be
|
||||
filled with null values.
|
||||
|
||||
The following function pushes a C value into the stack::
|
||||
@@ -92,6 +92,7 @@ the result can be one of the following values: ::
|
||||
The following functions convert a squirrel value in the stack to a C value::
|
||||
|
||||
SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c);
|
||||
SQRESULT sq_getstringandsize(HSQUIRRELVM v,SQInteger idx,const SQChar **c,SQInteger size);
|
||||
SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i);
|
||||
SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f);
|
||||
SQRESULT sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p);
|
||||
|
@@ -26,4 +26,4 @@ All declarations needed for embedding the language in an application are in the
|
||||
embedding/userdata_and_userpointers.rst
|
||||
embedding/the_registry_table.rst
|
||||
embedding/references_from_c.rst
|
||||
embedding/debug_interface.rst
|
||||
embedding/debug_interface.rst
|
||||
|
@@ -4,7 +4,7 @@
|
||||
Squirrel 3.1 Reference Manual
|
||||
#################################
|
||||
|
||||
Copyrigth (c) 2003-2016 Alberto Demichelis
|
||||
Copyright (c) 2003-2016 Alberto Demichelis
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -31,4 +31,4 @@ THE SOFTWARE.
|
||||
introduction.rst
|
||||
language.rst
|
||||
embedding_squirrel.rst
|
||||
api_reference.rst
|
||||
api_reference.rst
|
||||
|
@@ -7,10 +7,10 @@ Introduction
|
||||
.. index::
|
||||
single: introduction
|
||||
|
||||
Squirrel is a high level imperative-OO programming language, designed to be a powerful
|
||||
scripting tool that fits in the size, memory bandwidth, and real-time requirements of
|
||||
Squirrel is a high-level, imperative-OO programming language, designed to be a powerful
|
||||
scripting tool that fits within the size, memory bandwidth, and real-time requirements of
|
||||
applications like games.
|
||||
Although Squirrel offers a wide range of features like dynamic typing, delegation, higher
|
||||
Squirrel offers a wide range of features like dynamic typing, delegation, higher
|
||||
order functions, generators, tail recursion, exception handling, automatic memory
|
||||
management, both compiler and virtual machine fit together in about 6k lines of C++
|
||||
code.
|
||||
management while fitting both compiler and virtual machine into about 6k lines of C++
|
||||
code.
|
||||
|
@@ -20,4 +20,4 @@
|
||||
language/weak_references.rst
|
||||
language/delegation.rst
|
||||
language/metamethods.rst
|
||||
language/builtin_functions.rst
|
||||
language/builtin_functions.rst
|
||||
|
@@ -16,8 +16,7 @@ Global Symbols
|
||||
|
||||
.. js:function:: array(size,[fill])
|
||||
|
||||
create and returns array of a specified size.if the optional parameter fill is specified its
|
||||
value will be used to fill the new array's slots. If the fill paramter is omitted null is used instead.
|
||||
creates and returns array of a specified size. If the optional parameter fill is specified its value will be used to fill the new array's slots. If the fill parameter is omitted, null is used instead.
|
||||
|
||||
.. js:function:: seterrorhandler(func)
|
||||
|
||||
@@ -36,7 +35,7 @@ sets the debug hook
|
||||
|
||||
.. js:function:: enabledebuginfo(enable)
|
||||
|
||||
enable/disable the debug line information generation at compile time. enable != null enables . enable == null disables.
|
||||
enable/disable the debug line information generation at compile time. enable != null enables. enable == null disables.
|
||||
|
||||
.. js:function:: getroottable()
|
||||
|
||||
@@ -52,15 +51,15 @@ returns the const table of the VM.
|
||||
|
||||
.. js:function:: setconsttable(table)
|
||||
|
||||
sets the const table of the VM. And returns the previous const table.
|
||||
sets the const table of the VM; returns the previous const table.
|
||||
|
||||
.. js:function:: assert(exp)
|
||||
.. js:function:: assert(exp, [message])
|
||||
|
||||
throws an exception if exp is null
|
||||
throws an exception if exp is null or false. Throws "assertion failed" string by default, or message if specified.
|
||||
|
||||
.. js:function:: print(x)
|
||||
|
||||
prints x in the standard output
|
||||
prints x to the standard output
|
||||
|
||||
.. js:function:: error(x)
|
||||
|
||||
@@ -76,15 +75,15 @@ compiles a string containing a squirrel script into a function and returns it::
|
||||
|
||||
.. js:function:: collectgarbage()
|
||||
|
||||
runs the garbage collector and returns the number of reference cycles found(and deleted) This function only works on garbage collector builds.
|
||||
Runs the garbage collector and returns the number of reference cycles found (and deleted). This function only works on garbage collector builds.
|
||||
|
||||
.. js:function:: resurrectunreachable()
|
||||
|
||||
runs the garbage collector and returns an array containing all unreachable object found. If no unreachable object is found, null is returned instead. This function is meant to help debugging reference cycles. This function only works on garbage collector builds.
|
||||
Runs the garbage collector and returns an array containing all unreachable object found. If no unreachable object is found, null is returned instead. This function is meant to help debugging reference cycles. This function only works on garbage collector builds.
|
||||
|
||||
.. js:function:: type(obj)
|
||||
|
||||
return the 'raw' type of an object without invoking the metatmethod '_typeof'.
|
||||
return the 'raw' type of an object without invoking the metamethod '_typeof'.
|
||||
|
||||
.. js:function:: getstackinfos(level)
|
||||
|
||||
@@ -105,7 +104,7 @@ returns the stack informations of a given call stack level. returns a table form
|
||||
}
|
||||
}
|
||||
|
||||
level = 0 is the current function, level = 1 is the caller and so on. If the stack level doesn't exist the function returns null.
|
||||
level = 0 is getstackinfos() itself! level = 1 is the current function, level = 2 is the caller of the current function, and so on. If the stack level doesn't exist the function returns null.
|
||||
|
||||
.. js:function:: newthread(threadfunc)
|
||||
|
||||
@@ -113,7 +112,7 @@ creates a new cooperative thread object(coroutine) and returns it
|
||||
|
||||
.. js:data:: _versionnumber_
|
||||
|
||||
integer values describing the version of VM and compiler. eg. for Squirrel 3.0.1 this value will be 301
|
||||
integer values describing the version of VM and compiler. e.g. for Squirrel 3.0.1 this value will be 301
|
||||
|
||||
.. js:data:: _version_
|
||||
|
||||
@@ -121,15 +120,15 @@ string values describing the version of VM and compiler.
|
||||
|
||||
.. js:data:: _charsize_
|
||||
|
||||
size in bytes of the internal VM rapresentation for characters(1 for ASCII builds 2 for UNICODE builds).
|
||||
size in bytes of the internal VM representation for characters(1 for ASCII builds 2 for UNICODE builds).
|
||||
|
||||
.. js:data:: _intsize_
|
||||
|
||||
size in bytes of the internal VM rapresentation for integers(4 for 32bits builds 8 for 64bits builds).
|
||||
size in bytes of the internal VM representation for integers(4 for 32bits builds 8 for 64bits builds).
|
||||
|
||||
.. js:data:: _floatsize_
|
||||
|
||||
size in bytes of the internal VM rapresentation for floats(4 for single precision builds 8 for double precision builds).
|
||||
size in bytes of the internal VM representation for floats(4 for single precision builds 8 for double precision builds).
|
||||
|
||||
-----------------
|
||||
Default delegates
|
||||
@@ -153,17 +152,17 @@ converts the number to string and returns it
|
||||
|
||||
.. js:function:: integer.tointeger()
|
||||
|
||||
returns the value of the integer(dummy function)
|
||||
dummy function; returns the value of the integer.
|
||||
|
||||
|
||||
.. js:function:: integer.tochar()
|
||||
|
||||
returns a string containing a single character rapresented by the integer.
|
||||
returns a string containing a single character represented by the integer.
|
||||
|
||||
|
||||
.. js:function:: integer.weakref()
|
||||
|
||||
dummy function, returns the integer itself.
|
||||
dummy function; returns the integer itself.
|
||||
|
||||
^^^^^
|
||||
Float
|
||||
@@ -186,12 +185,12 @@ converts the number to string and returns it
|
||||
|
||||
.. js:function:: float.tochar()
|
||||
|
||||
returns a string containing a single character rapresented by the integer part of the float.
|
||||
returns a string containing a single character represented by the integer part of the float.
|
||||
|
||||
|
||||
.. js:function:: float.weakref()
|
||||
|
||||
dummy function, returns the float itself.
|
||||
dummy function; returns the float itself.
|
||||
|
||||
^^^^
|
||||
Bool
|
||||
@@ -209,12 +208,12 @@ returns 1 for true 0 for false
|
||||
|
||||
.. js:function:: bool.tostring()
|
||||
|
||||
returns "true" for true "false" for false
|
||||
returns "true" for true and "false" for false
|
||||
|
||||
|
||||
.. js:function:: bool.weakref()
|
||||
|
||||
dummy function, returns the bool itself.
|
||||
dummy function; returns the bool itself.
|
||||
|
||||
^^^^^^
|
||||
String
|
||||
@@ -227,7 +226,7 @@ returns the string length
|
||||
|
||||
.. js:function:: string.tointeger([base])
|
||||
|
||||
converts the string to integer and returns it.An optional parameter base can be specified, if a base is not specified it defaults to base 10
|
||||
Converts the string to integer and returns it. An optional parameter base can be specified--if a base is not specified, it defaults to base 10.
|
||||
|
||||
|
||||
.. js:function:: string.tofloat()
|
||||
@@ -237,7 +236,7 @@ converts the string to float and returns it
|
||||
|
||||
.. js:function:: string.tostring()
|
||||
|
||||
returns the string(dummy function)
|
||||
returns the string (really, a dummy function)
|
||||
|
||||
|
||||
.. js:function:: string.slice(start,[end])
|
||||
@@ -247,7 +246,7 @@ returns a section of the string as new string. Copies from start to the end (not
|
||||
|
||||
.. js:function:: string.find(substr,[startidx])
|
||||
|
||||
search a sub string(substr) starting from the index startidx and returns the index of its first occurrence. If startidx is omitted the search operation starts from the beginning of the string. The function returns null if substr is not found.
|
||||
Searches a sub string (substr) starting from the index startidx and returns the index of its first occurrence. If startidx is omitted the search operation starts from the beginning of the string. The function returns null if substr is not found.
|
||||
|
||||
|
||||
.. js:function:: string.tolower()
|
||||
@@ -280,17 +279,17 @@ tries to get a value from the slot 'key' without employing delegation
|
||||
|
||||
.. js:function:: table.rawset(key,val)
|
||||
|
||||
sets the slot 'key' with the value 'val' without employing delegation. If the slot does not exists , it will be created.
|
||||
Sets the slot 'key' with the value 'val' without employing delegation. If the slot does not exists, it will be created. Returns table itself.
|
||||
|
||||
|
||||
.. js:function:: table.rawdelete()
|
||||
|
||||
deletes the slot key without emplying delegetion and retunrs his value. if the slo does not exists returns always null.
|
||||
Deletes the slot key without employing delegation and returns its value. If the slot does not exists, returns null.
|
||||
|
||||
|
||||
.. js:function:: table.rawin(key)
|
||||
|
||||
returns true if the slot 'key' exists. the function has the same eddect as the operator 'in' but does not employ delegation.
|
||||
returns true if the slot 'key' exists. the function has the same effect as the operator 'in' but does not employ delegation.
|
||||
|
||||
|
||||
.. js:function:: table.weakref()
|
||||
@@ -300,23 +299,28 @@ returns a weak reference to the object.
|
||||
|
||||
.. js:function:: table.tostring()
|
||||
|
||||
tries to invoke the _tostring metamethod, if failed. returns "(table : pointer)".
|
||||
Tries to invoke the _tostring metamethod. If that fails, it returns "(table : pointer)".
|
||||
|
||||
|
||||
.. js:function:: table.clear()
|
||||
|
||||
removes all the slot from the table
|
||||
removes all the slots from the table. Returns table itself.
|
||||
|
||||
|
||||
.. js:function:: table.setdelegate(table)
|
||||
|
||||
sets the delegate of the table, to remove a delegate 'null' must be passed to the function. The function returns the table itself (eg. a.setdelegate(b) in this case 'a' is the return value).
|
||||
Sets the delegate of the table. To remove a delegate, 'null' must be passed to the function. The function returns the table itself (e.g. a.setdelegate(b) -- in this case 'a' is the return value).
|
||||
|
||||
|
||||
.. js:function:: table.getdelegate()
|
||||
|
||||
returns the table's delegate or null if no delegate was set.
|
||||
|
||||
|
||||
.. js:function:: table.filter(func(key,val))
|
||||
|
||||
Creates a new table with all values that pass the test implemented by the provided function. In detail, it creates a new table, invokes the specified function for each key-value pair in the original table; if the function returns 'true', then the value is added to the newly created table at the same key.
|
||||
|
||||
^^^^^^
|
||||
Array
|
||||
^^^^^^
|
||||
@@ -328,17 +332,17 @@ returns the length of the array
|
||||
|
||||
.. js:function:: array.append(val)
|
||||
|
||||
appends the value 'val' at the end of the array
|
||||
appends the value 'val' at the end of the array. Returns array itself.
|
||||
|
||||
|
||||
.. js:function:: array.push(val)
|
||||
|
||||
appends the value 'val' at the end of the array
|
||||
appends the value 'val' at the end of the array. Returns array itself.
|
||||
|
||||
|
||||
.. js:function:: array.extend(array)
|
||||
|
||||
Extends the array by appending all the items in the given array.
|
||||
Extends the array by appending all the items in the given array. Returns array itself.
|
||||
|
||||
|
||||
.. js:function:: array.pop()
|
||||
@@ -353,22 +357,22 @@ returns the value of the array with the higher index
|
||||
|
||||
.. js:function:: array.insert(idx,val)
|
||||
|
||||
inserst the value 'val' at the position 'idx' in the array
|
||||
inserts the value 'val' at the position 'idx' in the array. Returns array itself.
|
||||
|
||||
|
||||
.. js:function:: array.remove(idx)
|
||||
|
||||
removes the value at the position 'idx' in the array
|
||||
removes the value at the position 'idx' in the array and returns its value.
|
||||
|
||||
|
||||
.. js:function:: array.resize(size,[fill])
|
||||
|
||||
resizes the array, if the optional parameter fill is specified its value will be used to fill the new array's slots(if the size specified is bigger than the previous size) . If the fill paramter is omitted null is used instead.
|
||||
Resizes the array. If the optional parameter 'fill' is specified, its value will be used to fill the new array's slots when the size specified is bigger than the previous size. If the fill parameter is omitted, null is used instead. Returns array itself.
|
||||
|
||||
|
||||
.. js:function:: array.sort([compare_func])
|
||||
|
||||
sorts the array. a custom compare function can be optionally passed.The function prototype as to be the following.::
|
||||
Sorts the array in-place. A custom compare function can be optionally passed. The function prototype as to be the following.::
|
||||
|
||||
function custom_compare(a,b)
|
||||
{
|
||||
@@ -381,16 +385,16 @@ a more compact version of a custom compare can be written using a lambda express
|
||||
|
||||
arr.sort(@(a,b) a <=> b);
|
||||
|
||||
|
||||
Returns array itself.
|
||||
|
||||
.. js:function:: array.reverse()
|
||||
|
||||
reverse the elements of the array in place
|
||||
reverse the elements of the array in place. Returns array itself.
|
||||
|
||||
|
||||
.. js:function:: array.slice(start,[end])
|
||||
|
||||
returns a section of the array as new array. Copies from start to the end (not included). If start is negative the index is calculated as length + start, if end is negative the index is calculated as length + end. If end is omitted end is equal to the array length.
|
||||
Returns a section of the array as new array. Copies from start to the end (not included). If start is negative the index is calculated as length + start, if end is negative the index is calculated as length + end. If end is omitted end is equal to the array length.
|
||||
|
||||
|
||||
.. js:function:: array.weakref()
|
||||
@@ -410,7 +414,7 @@ removes all the items from the array
|
||||
|
||||
.. js:function:: array.map(func(a))
|
||||
|
||||
creates a new array of the same size. for each element in the original array invokes the function 'func' and assigns the return value of the function to the corresponding element of the newly created array.
|
||||
Creates a new array of the same size. For each element in the original array invokes the function 'func' and assigns the return value of the function to the corresponding element of the newly created array.
|
||||
|
||||
|
||||
.. js:function:: array.apply(func(a))
|
||||
@@ -420,7 +424,7 @@ for each element in the array invokes the function 'func' and replace the origin
|
||||
|
||||
.. js:function:: array.reduce(func(prevval,curval))
|
||||
|
||||
Reduces an array to a single value. For each element in the array invokes the function 'func' passing the initial value (or value from the previous callback call) and the value of the current element. the return value of the function is then used as 'prevval' for the next element. Given an array of length 0, returns null. Given an array of length 1, returns the first element. Given an array with 2 or more elements calls the function with the first two elements as the parameters, gets that result, then calls the function with that result and the third element, gets that result, calls the function with that result and the fourth parameter and so on until all element have been processed. Finally returns the return value of the last invocation of func.
|
||||
Reduces an array to a single value. For each element in the array invokes the function 'func' passing the initial value (or value from the previous callback call) and the value of the current element. the return value of the function is then used as 'prevval' for the next element. Given an array of length 0, returns null. Given an array of length 1, returns the first element. Given an array with 2 or more elements calls the function with the first two elements as the parameters, gets that result, then calls the function with that result and the third element, gets that result, calls the function with that result and the fourth parameter and so on until all element have been processed. Finally, returns the return value of the last invocation of func.
|
||||
|
||||
|
||||
.. js:function:: array.filter(func(index,val))
|
||||
@@ -436,52 +440,52 @@ Performs a linear search for the value in the array. Returns the index of the va
|
||||
Function
|
||||
^^^^^^^^
|
||||
|
||||
.. js:function:: array.call(_this,args...)
|
||||
.. js:function:: function.call(_this,args...)
|
||||
|
||||
calls the function with the specified environment object('this') and parameters
|
||||
|
||||
|
||||
.. js:function:: array.pcall(_this,args...)
|
||||
.. js:function:: function.pcall(_this,args...)
|
||||
|
||||
calls the function with the specified environment object('this') and parameters, this function will not invoke the error callback in case of failure(pcall stays for 'protected call')
|
||||
|
||||
|
||||
.. js:function:: array.acall(array_args)
|
||||
.. js:function:: function.acall(array_args)
|
||||
|
||||
calls the function with the specified environment object('this') and parameters. The function accepts an array containing the parameters that will be passed to the called function.Where array_args has to contain the required 'this' object at the [0] position.
|
||||
|
||||
|
||||
.. js:function:: array.pacall(array_args)
|
||||
.. js:function:: function.pacall(array_args)
|
||||
|
||||
calls the function with the specified environment object('this') and parameters. The function accepts an array containing the parameters that will be passed to the called function.Where array_args has to contain the required 'this' object at the [0] position. This function will not invoke the error callback in case of failure(pacall stays for 'protected array call')
|
||||
|
||||
|
||||
.. js:function:: array.weakref()
|
||||
.. js:function:: function.weakref()
|
||||
|
||||
returns a weak reference to the object.
|
||||
|
||||
|
||||
.. js:function:: array.tostring()
|
||||
.. js:function:: function.tostring()
|
||||
|
||||
returns the string "(closure : pointer)".
|
||||
|
||||
|
||||
.. js:function:: array.setroot(table)
|
||||
.. js:function:: function.setroot(table)
|
||||
|
||||
sets the root table of a closure
|
||||
|
||||
|
||||
.. js:function:: array.getroot()
|
||||
.. js:function:: function.getroot()
|
||||
|
||||
returns the root table of the closure
|
||||
|
||||
|
||||
.. js:function:: array.bindenv(env)
|
||||
.. js:function:: function.bindenv(env)
|
||||
|
||||
clones the function(aka closure) and bind the enviroment object to it(table,class or instance). the this parameter of the newly create function will always be set to env. Note that the created function holds a weak reference to its environment object so cannot be used to control its lifetime.
|
||||
clones the function(aka closure) and bind the environment object to it(table,class or instance). the this parameter of the newly create function will always be set to env. Note that the created function holds a weak reference to its environment object so cannot be used to control its lifetime.
|
||||
|
||||
|
||||
.. js:function:: array.getinfos()
|
||||
.. js:function:: function.getinfos()
|
||||
|
||||
returns a table containing informations about the function, like parameters, name and source name; ::
|
||||
|
||||
@@ -511,7 +515,7 @@ Class
|
||||
|
||||
.. js:function:: class.instance()
|
||||
|
||||
returns a new instance of the class. this function does not invoke the instance constructor. The constructor must be explicitly called( eg. class_inst.constructor(class_inst) ).
|
||||
returns a new instance of the class. this function does not invoke the instance constructor. The constructor must be explicitly called (eg. class_inst.constructor(class_inst) ).
|
||||
|
||||
|
||||
.. js:function:: class.getattributes(membername)
|
||||
@@ -526,7 +530,7 @@ sets the attribute of the specified member and returns the previous attribute va
|
||||
|
||||
.. js:function:: class.rawin(key)
|
||||
|
||||
returns true if the slot 'key' exists. the function has the same eddect as the operator 'in' but does not employ delegation.
|
||||
returns true if the slot 'key' exists. the function has the same effect as the operator 'in' but does not employ delegation.
|
||||
|
||||
|
||||
.. js:function:: class.weakref()
|
||||
@@ -546,7 +550,7 @@ tries to get a value from the slot 'key' without employing delegation
|
||||
|
||||
.. js:function:: class.rawset(key,val)
|
||||
|
||||
sets the slot 'key' with the value 'val' without employing delegation. If the slot does not exists , it will be created.
|
||||
sets the slot 'key' with the value 'val' without employing delegation. If the slot does not exists, it will be created.
|
||||
|
||||
|
||||
.. js:function:: class.newmember(key,val,[attrs],[bstatic])
|
||||
@@ -556,7 +560,7 @@ sets/adds the slot 'key' with the value 'val' and attributes 'attrs' and if pres
|
||||
|
||||
.. js:function:: class.rawnewmember(key,val,[attrs],[bstatic])
|
||||
|
||||
sets/adds the slot 'key' with the value 'val' and attributes 'attrs'.If bstatic is true the slot will be added as static. If the slot does not exists , it will be created. It doesn't invoke any metamethod.
|
||||
sets/adds the slot 'key' with the value 'val' and attributes 'attrs'. If bstatic is true the slot will be added as static. If the slot does not exist, it will be created. It doesn't invoke any metamethod.
|
||||
|
||||
^^^^^^^^^^^^^^
|
||||
Class Instance
|
||||
@@ -571,7 +575,7 @@ returns the class that created the instance.
|
||||
|
||||
:param key: ze key
|
||||
|
||||
returns true if the slot 'key' exists. the function has the same eddect as the operator 'in' but does not employ delegation.
|
||||
returns true if the slot 'key' exists. the function has the same effect as the operator 'in' but does not employ delegation.
|
||||
|
||||
|
||||
.. js:function:: instance.weakref()
|
||||
@@ -581,7 +585,7 @@ returns a weak reference to the object.
|
||||
|
||||
.. js:function:: instance.tostring()
|
||||
|
||||
tries to invoke the _tostring metamethod, if failed. returns "(insatnce : pointer)".
|
||||
tries to invoke the _tostring metamethod, if failed. returns "(instance : pointer)".
|
||||
|
||||
|
||||
.. js:function:: instance.rawget(key)
|
||||
@@ -591,7 +595,7 @@ tries to get a value from the slot 'key' without employing delegation
|
||||
|
||||
.. js:function:: instance.rawset(key,val)
|
||||
|
||||
sets the slot 'key' with the value 'val' without employing delegation. If the slot does not exists , it will be created.
|
||||
sets the slot 'key' with the value 'val' without employing delegation. If the slot does not exists, it will be created.
|
||||
|
||||
^^^^^^^^^^^^^^
|
||||
Generator
|
||||
@@ -656,7 +660,7 @@ Weak Reference
|
||||
|
||||
.. js:function:: weakreference.ref()
|
||||
|
||||
returns the object that the weak reference is pointing at, null if the object that was point at was destroyed.
|
||||
returns the object that the weak reference is pointing at; null if the object that was point at was destroyed.
|
||||
|
||||
|
||||
.. js:function:: weakreference.weakref()
|
||||
|
@@ -46,7 +46,7 @@ For instance: ::
|
||||
|
||||
}
|
||||
|
||||
the previous code examples is a syntactic sugar for: ::
|
||||
the previous code example is a syntactic sugar for: ::
|
||||
|
||||
Foo <- class {
|
||||
//constructor
|
||||
@@ -67,7 +67,7 @@ the previous code examples is a syntactic sugar for: ::
|
||||
|
||||
}
|
||||
|
||||
in order to emulate namespaces, is also possible to declare something like this::
|
||||
in order to emulate namespaces, it is also possible to declare something like this::
|
||||
|
||||
//just 2 regular nested tables
|
||||
FakeNamespace <- {
|
||||
@@ -214,7 +214,7 @@ class declaration. The values are copied verbatim, *no cloning is performed* eve
|
||||
|
||||
.. note:: FOR C# and Java programmers:
|
||||
|
||||
Squirrel doesn't clone member's default values nor executes the member declaration for each instace(as C# or java).
|
||||
Squirrel doesn't clone member's default values nor executes the member declaration for each instance(as C# or java).
|
||||
|
||||
So consider this example: ::
|
||||
|
||||
@@ -226,8 +226,8 @@ class declaration. The values are copied verbatim, *no cloning is performed* eve
|
||||
local a = Foo();
|
||||
local b = Foo();
|
||||
|
||||
In the snippet above both instances will refer to the same array and same table.To archieve what a C# or Java programmer would
|
||||
exepect, the following approach should be taken. ::
|
||||
In the snippet above both instances will refer to the same array and same table.To achieve what a C# or Java programmer would
|
||||
expect, the following approach should be taken. ::
|
||||
|
||||
class Foo {
|
||||
myarray = null
|
||||
@@ -327,7 +327,7 @@ Here an example: ::
|
||||
}
|
||||
}
|
||||
|
||||
Same rule apply to the constructor. The constructor is a regular function (apart from being automatically invoked on contruction).::
|
||||
Same rule apply to the constructor. The constructor is a regular function (apart from being automatically invoked on construction).::
|
||||
|
||||
class BaseClass {
|
||||
constructor()
|
||||
|
@@ -2,16 +2,16 @@
|
||||
|
||||
|
||||
========================
|
||||
Constants & Enumarations
|
||||
Constants & Enumerations
|
||||
========================
|
||||
|
||||
.. index::
|
||||
single: Constants & Enumarations
|
||||
single: Constants & Enumerations
|
||||
|
||||
|
||||
|
||||
Squirrel allows to bind constant values to an identifier that will be evaluated compile-time.
|
||||
This is archieved though constants and enumarations.
|
||||
This is achieved though constants and Enumerations.
|
||||
|
||||
---------------
|
||||
Constants
|
||||
@@ -20,7 +20,7 @@ Constants
|
||||
.. index::
|
||||
single: Constants
|
||||
|
||||
Constants bind a specific value to an indentifier. Constants are similar to
|
||||
Constants bind a specific value to an identifier. Constants are similar to
|
||||
global values, except that they are evaluated compile time and their value cannot be changed.
|
||||
|
||||
constants values can only be integers, floats or string literals. No expression are allowed.
|
||||
@@ -28,7 +28,7 @@ are declared with the following syntax.::
|
||||
|
||||
const foobar = 100;
|
||||
const floatbar = 1.2;
|
||||
const stringbar = "I'm a contant string";
|
||||
const stringbar = "I'm a constant string";
|
||||
|
||||
constants are always globally scoped, from the moment they are declared, any following code
|
||||
can reference them.
|
||||
@@ -37,17 +37,17 @@ Constants will shadow any global slot with the same name( the global slot will r
|
||||
local x = foobar * 2;
|
||||
|
||||
---------------
|
||||
Enumrations
|
||||
Enumerations
|
||||
---------------
|
||||
|
||||
.. index::
|
||||
single: Enumrations
|
||||
single: Enumerations
|
||||
|
||||
As Constants, Enumerations bind a specific value to a name. Enumerations are also evaluated compile time
|
||||
As Constants, Enumerations bind a specific value to a name. Enumerations are also evaluated at compile time
|
||||
and their value cannot be changed.
|
||||
|
||||
An enum declaration introduces a new enumeration into the program.
|
||||
Enumerations values can only be integers, floats or string literals. No expression are allowed.::
|
||||
Enumeration values can only be integers, floats or string literals. No expression are allowed.::
|
||||
|
||||
enum Stuff {
|
||||
first, //this will be 0
|
||||
@@ -73,7 +73,7 @@ Enumerations will shadow any global slot with the same name( the global slot wil
|
||||
Implementation notes
|
||||
--------------------
|
||||
|
||||
Enumerations and Contants are a compile-time feature. Only integers, string and floats can be declared as const/enum;
|
||||
Enumerations and Constants are a compile-time feature. Only integers, string and floats can be declared as const/enum;
|
||||
No expressions are allowed(because they would have to be evaluated compile time).
|
||||
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
|
||||
and is shared by the VM and all its threads.
|
||||
|
@@ -4,10 +4,11 @@
|
||||
Values and Data types
|
||||
=====================
|
||||
|
||||
Squirrel is a dynamically typed language so variables do not have a type, although they
|
||||
refer to a value that does have a type.
|
||||
Squirrel basic types are integer, float, string, null, table, array, function, generator,
|
||||
class, instance, bool, thread and userdata.
|
||||
While Squirrel is a dynamically typed language and variables do not
|
||||
have a type, different operations may interpret the variable as
|
||||
containing a type. Squirrel's basic types are integer, float, string,
|
||||
null, table, array, function, generator, class, instance, bool, thread
|
||||
and userdata.
|
||||
|
||||
.. _userdata-index:
|
||||
|
||||
@@ -15,7 +16,7 @@ class, instance, bool, thread and userdata.
|
||||
Integer
|
||||
--------
|
||||
|
||||
An Integer represents a 32 bits (or better) signed number.::
|
||||
An Integer represents a 32 bit (or better) signed number.::
|
||||
|
||||
local a = 123 //decimal
|
||||
local b = 0x0012 //hexadecimal
|
||||
@@ -26,7 +27,7 @@ An Integer represents a 32 bits (or better) signed number.::
|
||||
Float
|
||||
--------
|
||||
|
||||
A float represents a 32 bits (or better) floating point number.::
|
||||
A float represents a 32 bit (or better) floating point number.::
|
||||
|
||||
local a=1.0
|
||||
local b=0.234
|
||||
@@ -35,24 +36,27 @@ A float represents a 32 bits (or better) floating point number.::
|
||||
String
|
||||
--------
|
||||
|
||||
Strings are an immutable sequence of characters to modify a string is necessary create a new one.
|
||||
Strings are an immutable sequence of characters. In order to modify a
|
||||
string is it necessary create a new one.
|
||||
|
||||
Squirrel's strings, behave like C or C++, are delimited by quotation marks(``"``) and can contain
|
||||
escape sequences(``\t``, ``\a``, ``\b``, ``\n``, ``\r``, ``\v``, ``\f``, ``\\``, ``\"``, ``\'``, ``\0``,
|
||||
``\x<hh>``, ``\u<hhhh>`` and ``\U<hhhhhhhh>``).
|
||||
Squirrel's strings are similar to strings in C or C++. They are
|
||||
delimited by quotation marks(``"``) and can contain escape
|
||||
sequences (``\t``, ``\a``, ``\b``, ``\n``, ``\r``, ``\v``, ``\f``,
|
||||
``\\``, ``\"``, ``\'``, ``\0``, ``\x<hh>``, ``\u<hhhh>`` and
|
||||
``\U<hhhhhhhh>``).
|
||||
|
||||
Verbatim string literals begin with ``@"`` and end with the matching quote.
|
||||
Verbatim string literals also can extend over a line break. If they do, they
|
||||
include any white space characters between the quotes: ::
|
||||
Verbatim string literals do not interpret escape sequences. They begin
|
||||
with ``@"`` and end with the matching quote. Verbatim string literals
|
||||
also can extend over a line break. If they do, they include any white
|
||||
space characters between the quotes: ::
|
||||
|
||||
local a = "I'm a wonderful string\n"
|
||||
// has a newline at the end of the string
|
||||
local x = @"I'm a verbatim string\n"
|
||||
// the \n is copied in the string same as \\n in a regular string "I'm a verbatim string\n"
|
||||
// the \n is literal, similar to "\\n" in a regular string.
|
||||
|
||||
The only exception to the "no escape sequence" rule for verbatim
|
||||
string literals is that you can put a double quotation mark inside a
|
||||
verbatim string by doubling it: ::
|
||||
However, a doubled quotation mark within a verbatim string is replaced
|
||||
by a single quotation mark: ::
|
||||
|
||||
local multiline = @"
|
||||
this is a multiline string
|
||||
@@ -73,7 +77,7 @@ reference. The type Null has exactly one value, called null.::
|
||||
Bool
|
||||
--------
|
||||
|
||||
the bool data type can have only two. They are the literals ``true``
|
||||
Bool is a double-valued (Boolean) data type. Its literals are ``true``
|
||||
and ``false``. A bool value expresses the validity of a condition
|
||||
(tells whether the condition is true or false).::
|
||||
|
||||
@@ -83,7 +87,8 @@ and ``false``. A bool value expresses the validity of a condition
|
||||
Table
|
||||
--------
|
||||
|
||||
Tables are associative containers implemented as pairs of key/value (called a slot).::
|
||||
Tables are associative containers implemented as a set of key/value pairs
|
||||
called slots.::
|
||||
|
||||
local t={}
|
||||
local test=
|
||||
@@ -96,7 +101,7 @@ Tables are associative containers implemented as pairs of key/value (called a sl
|
||||
Array
|
||||
--------
|
||||
|
||||
Arrays are simple sequence of objects, their size is dynamic and their index starts always from 0.::
|
||||
Arrays are simple sequence of objects. Their size is dynamic and their index always starts from 0.::
|
||||
|
||||
local a = ["I'm","an","array"]
|
||||
local b = [null]
|
||||
@@ -106,53 +111,52 @@ Arrays are simple sequence of objects, their size is dynamic and their index sta
|
||||
Function
|
||||
--------
|
||||
|
||||
Functions are similar to those in other C-like languages and to most programming
|
||||
languages in general, however there are a few key differences (see below).
|
||||
Functions are similar to those in other C-like languages with a few key differences (see below).
|
||||
|
||||
--------
|
||||
Class
|
||||
--------
|
||||
|
||||
Classes are associative containers implemented as pairs of key/value. Classes are created through
|
||||
a 'class expression' or a 'class statement'. class members can be inherited from another class object
|
||||
at creation time. After creation members can be added until a instance of the class is created.
|
||||
Classes are associative containers implemented as sets of key/value
|
||||
pairs. Classes are created through a 'class expression' or a 'class
|
||||
statement'. class members can be inherited from another class object
|
||||
at creation time. After creation, members can be added until an
|
||||
instance of the class is created.
|
||||
|
||||
--------------
|
||||
Class Instance
|
||||
--------------
|
||||
|
||||
Class instances are created by calling a *class object*. Instances, as tables, are
|
||||
implemented as pair of key/value. Instances members cannot be dyncamically added or removed however
|
||||
the value of the members can be changed.
|
||||
|
||||
|
||||
Class instances are created by calling a *class object*. Instances, as
|
||||
tables, are implemented as sets of key/value pairs. Instance members
|
||||
cannot be dynamically added or removed; however the value of the
|
||||
members can be changed.
|
||||
|
||||
---------
|
||||
Generator
|
||||
---------
|
||||
|
||||
Generators are functions that can be suspended with the statement 'yield' and resumed
|
||||
later (see :ref:`Generators <generators>`).
|
||||
Generators are functions that can be suspended with the statement
|
||||
'yield' and resumed later (see :ref:`Generators <generators>`).
|
||||
|
||||
---------
|
||||
Userdata
|
||||
---------
|
||||
|
||||
Userdata objects are blobs of memory(or pointers) defined by the host application but
|
||||
stored into Squirrel variables (See :ref:`Userdata and UserPointers <embedding_userdata_and_userpointers>`).
|
||||
|
||||
Userdata objects are blobs of memory or pointers defined by the host
|
||||
application but stored within Squirrel variables (See :ref:`Userdata
|
||||
and UserPointers <embedding_userdata_and_userpointers>`).
|
||||
|
||||
---------
|
||||
Thread
|
||||
---------
|
||||
|
||||
Threads are objects that represents a cooperative thread of execution, also known as coroutines.
|
||||
Threads are objects representing a cooperative thread of execution,
|
||||
also known as coroutines.
|
||||
|
||||
--------------
|
||||
Weak Reference
|
||||
--------------
|
||||
|
||||
Weak References are objects that point to another(non scalar) object but do not own a strong reference to it.
|
||||
Weak References are objects that point to another (non-scalar) object but do not own a strong reference to it.
|
||||
(See :ref:`Weak References <weak_references>`).
|
||||
|
||||
|
||||
|
@@ -50,7 +50,7 @@ with tables we can also use the '.' syntax::
|
||||
_table.foo
|
||||
|
||||
Squirrel first checks if an identifier is a local variable (function arguments are local
|
||||
variables) if not looks up the environment object (this) and finally looksup
|
||||
variables) if not looks up the environment object (this) and finally looks up
|
||||
to the closure root.
|
||||
|
||||
For instance:::
|
||||
|
@@ -221,10 +221,10 @@ Bitwise Operators
|
||||
exp:= 'exp' op 'exp'
|
||||
exp := '~' exp
|
||||
|
||||
Squirrel supports the standard c-like bit wise operators ``&, |, ^, ~, <<, >>`` plus the unsigned
|
||||
right shift operator ``<<<``. The unsigned right shift works exactly like the normal right shift operator(``<<``)
|
||||
Squirrel supports the standard C-like bitwise operators ``&, |, ^, ~, <<, >>`` plus the unsigned
|
||||
right shift operator ``>>>``. The unsigned right shift works exactly like the normal right shift operator(``>>``)
|
||||
except for treating the left operand as an unsigned integer, so is not affected by the sign. Those operators
|
||||
only work on integers values, passing of any other operand type to these operators will
|
||||
only work on integer values; passing of any other operand type to these operators will
|
||||
cause an exception.
|
||||
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -243,7 +243,7 @@ Operators precedence
|
||||
+---------------------------------------+-----------+
|
||||
| ``<<, >>, >>>`` | |
|
||||
+---------------------------------------+-----------+
|
||||
| ``<, <=, >, >=`` | |
|
||||
| ``<, <=, >, >=, instanceof`` | |
|
||||
+---------------------------------------+-----------+
|
||||
| ``==, !=, <=>`` | |
|
||||
+---------------------------------------+-----------+
|
||||
@@ -253,9 +253,9 @@ Operators precedence
|
||||
+---------------------------------------+-----------+
|
||||
| ``&&, in`` | |
|
||||
+---------------------------------------+-----------+
|
||||
| ``+=, =, -=`` | ... |
|
||||
| ``+=, =, -=, /=, *=, %=`` | ... |
|
||||
+---------------------------------------+-----------+
|
||||
| ``,(comma operator)`` | lowest |
|
||||
| ``, (comma operator)`` | lowest |
|
||||
+---------------------------------------+-----------+
|
||||
|
||||
.. _table_contructor:
|
||||
@@ -293,7 +293,7 @@ A new slot with exp1 as key and exp2 as value is created::
|
||||
[1]="I'm the value"
|
||||
}
|
||||
|
||||
both syntaxes can be mixed::
|
||||
Both syntaxes can be mixed::
|
||||
|
||||
local table=
|
||||
{
|
||||
@@ -369,6 +369,6 @@ Creates a new array.::
|
||||
|
||||
a <- [] //creates an empty array
|
||||
|
||||
arrays can be initialized with values during the construction::
|
||||
Arrays can be initialized with values during the construction::
|
||||
|
||||
a <- [1,"string!",[],{}] //creates an array with 4 elements
|
||||
a <- [1,"string!",[],{}] //creates an array with 4 elements
|
||||
|
@@ -140,19 +140,31 @@ Function calls
|
||||
The expression is evaluated in this order: derefexp after the explist (arguments) and at
|
||||
the end the call.
|
||||
|
||||
Every function call in Squirrel passes the environment object *this* as hidden parameter
|
||||
to the called function. The 'this' parameter is the object where the function was indexed
|
||||
from.
|
||||
A function call in Squirrel passes the current environment object *this* as a hidden parameter.
|
||||
But when the function was immediately indexed from an object, *this* shall be the object
|
||||
which was indexed, instead.
|
||||
|
||||
If we call a function with this syntax::
|
||||
If we call a function with the syntax::
|
||||
|
||||
table.foo(a)
|
||||
mytable.foo(x,y)
|
||||
|
||||
the environment object passed to foo will be 'table'::
|
||||
the environment object passed to 'foo' as *this* will be 'mytable' (since 'foo' was immediately indexed from 'mytable')
|
||||
|
||||
foo(x,y) // equivalent to this.foo(x,y)
|
||||
Whereas with the syntax::
|
||||
|
||||
The environment object will be *this* (the same of the caller function).
|
||||
foo(x,y) // implicitly equivalent to this.foo(x,y)
|
||||
|
||||
the environment object will be the current *this* (that is, propagated from the caller's *this*).
|
||||
|
||||
It may help to remember the rules in the following way:
|
||||
|
||||
foo(x,y) ---> this.foo(x,y)
|
||||
table.foo(x,y) ---> call foo with (table,x,y)
|
||||
|
||||
It may also help to consider why it works this way: it's designed to assist with object-oriented style.
|
||||
When calling 'foo(x,y)' it's assumed you're calling another member of the object (or of the file) and
|
||||
so should operate on the same object.
|
||||
When calling 'mytable.foo(x,y)' it's written plainly that you're calling a member of a different object.
|
||||
|
||||
---------------------------------------------
|
||||
Binding an environment to a function
|
||||
@@ -184,7 +196,7 @@ Lambda Expressions
|
||||
|
||||
exp := '@' '(' paramlist ')' exp
|
||||
|
||||
Lambda expressions are a synctactic sugar to quickly define a function that consists of a single expression.
|
||||
Lambda expressions are a syntactic sugar to quickly define a function that consists of a single expression.
|
||||
This feature comes handy when functional programming patterns are applied, like map/reduce or passing a compare method to
|
||||
array.sort().
|
||||
|
||||
|
@@ -13,11 +13,11 @@ Identifiers
|
||||
|
||||
.. index:: single: identifiers
|
||||
|
||||
Identifiers start with a alphabetic character or '_' followed by any number of alphabetic
|
||||
characters, '_' or digits ([0-9]). Squirrel is a case sensitive language, this means that the
|
||||
lowercase and uppercase representation of the same alphabetic character are considered
|
||||
different characters. For instance "foo", "Foo" and "fOo" will be treated as 3 distinct
|
||||
identifiers.
|
||||
Identifiers start with an alphabetic character or the symbol '_' followed by any number
|
||||
of alphabetic characters, '_' or digits ([0-9]). Squirrel is a case sensitive language
|
||||
meaning that the lowercase and uppercase representation of the same alphabetic
|
||||
character are considered different characters. For instance, "foo", "Foo" and "fOo" are
|
||||
treated as 3 distinct identifiers.
|
||||
|
||||
-----------
|
||||
Keywords
|
||||
@@ -25,7 +25,7 @@ Keywords
|
||||
|
||||
.. index:: single: keywords
|
||||
|
||||
The following words are reserved words by the language and cannot be used as identifiers:
|
||||
The following words are reserved and cannot be used as identifiers:
|
||||
|
||||
+------------+------------+-----------+------------+------------+-------------+
|
||||
| base | break | case | catch | class | clone |
|
||||
@@ -69,7 +69,7 @@ Other tokens
|
||||
single: delimiters
|
||||
single: other tokens
|
||||
|
||||
Other used tokens are:
|
||||
Other significant tokens are:
|
||||
|
||||
+----------+----------+----------+----------+----------+----------+
|
||||
| ``{`` | ``}`` | ``[`` | ``]`` | ``.`` | ``:`` |
|
||||
@@ -86,7 +86,7 @@ Literals
|
||||
single: string literals
|
||||
single: numeric literals
|
||||
|
||||
Squirrel accepts integer numbers, floating point numbers and strings literals.
|
||||
Squirrel accepts integer numbers, floating point numbers and string literals.
|
||||
|
||||
+-------------------------------+------------------------------------------+
|
||||
| ``34`` | Integer number(base 10) |
|
||||
@@ -131,7 +131,7 @@ A comment is text that the compiler ignores but that is useful for programmers.
|
||||
Comments are normally used to embed annotations in the code. The compiler
|
||||
treats them as white space.
|
||||
|
||||
The ``/*`` (slash, asterisk) characters, followed by any
|
||||
A comment can be ``/*`` (slash, asterisk) characters, followed by any
|
||||
sequence of characters (including new lines),
|
||||
followed by the ``*/`` characters. This syntax is the same as ANSI C.::
|
||||
|
||||
@@ -141,9 +141,9 @@ followed by the ``*/`` characters. This syntax is the same as ANSI C.::
|
||||
this lines will be ignored by the compiler
|
||||
*/
|
||||
|
||||
The ``//`` (two slashes) characters, followed by any sequence of characters.
|
||||
A new line not immediately preceded by a backslash terminates this form of comment.
|
||||
It is commonly called a *"single-line comment."*::
|
||||
A comment can also be ``//`` (two slashes) characters, followed by any sequence of
|
||||
characters. A new line not immediately preceded by a backslash terminates this form of
|
||||
comment. It is commonly called a *"single-line comment."*::
|
||||
|
||||
//this is a single line comment. this line will be ignored by the compiler
|
||||
|
||||
@@ -152,5 +152,3 @@ The character ``#`` is an alternative syntax for single line comment.::
|
||||
# this is also a single line comment.
|
||||
|
||||
This to facilitate the use of squirrel in UNIX-style shell scripts.
|
||||
|
||||
|
||||
|
@@ -6,11 +6,11 @@ Metamethods
|
||||
|
||||
Metamethods are a mechanism that allows the customization of certain aspects of the
|
||||
language semantics. Those methods are normal functions placed in a table
|
||||
parent(delegate) or class declaration; Is possible to change many aspect of a table/class instance behavior by just defining
|
||||
a metamethod. Class objects(not instances) supports only 2 metamethods ``_newmember, _inherited`` .
|
||||
parent(delegate) or class declaration; It is possible to change many aspects of a table/class instance behavior by just defining
|
||||
a metamethod. Class objects (not instances) support only 2 metamethods ``_newmember, _inherited`` .
|
||||
|
||||
For example when we use relational operators other than '==' on 2 tables, the VM will
|
||||
check if the table has a method in his parent called '_cmp' if so it will call it to determine
|
||||
check if the table has a method in his parent called '_cmp'; if so it will call it to determine
|
||||
the relation between the tables.::
|
||||
|
||||
local comparable={
|
||||
@@ -63,8 +63,8 @@ _set
|
||||
_set(idx,val)
|
||||
|
||||
invoked when the index idx is not present in the object or in its delegate chain.
|
||||
``_set`` must 'throw null' to notify that a key wasn't found but the there were not runtime errors(clean failure).
|
||||
This allows the program to defferentieate between a runtime error and a 'index not found'.
|
||||
``_set`` must 'throw null' to notify that a key wasn't found but the there were not runtime errors (clean failure).
|
||||
This allows the program to differentiate between a runtime error and a 'index not found'.
|
||||
|
||||
^^^^^
|
||||
_get
|
||||
@@ -72,11 +72,11 @@ _get
|
||||
|
||||
::
|
||||
|
||||
_get(idx,val)
|
||||
_get(idx)
|
||||
|
||||
invoked when the index idx is not present in the object or in its delegate chain.
|
||||
_get must 'throw null' to notify that a key wasn't found but the there were not runtime errors(clean failure).
|
||||
This allows the program to defferentieate between a runtime error and a 'index not found'.
|
||||
_get must 'throw null' to notify that a key wasn't found but the there were not runtime errors (clean failure).
|
||||
This allows the program to differentiate between a runtime error and a 'index not found'.
|
||||
|
||||
^^^^^^^^^
|
||||
_newslot
|
||||
@@ -165,16 +165,16 @@ _unm
|
||||
the unary minus operator
|
||||
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
_tyoeof
|
||||
_typeof
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
::
|
||||
|
||||
_tyoeof()
|
||||
_typeof()
|
||||
|
||||
invoked by the typeof operator on tables ,userdata and class instances
|
||||
invoked by the typeof operator on tables, userdata, and class instances.
|
||||
|
||||
returns the type of ``this`` as string
|
||||
Returns the type of ``this`` as string
|
||||
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
_cmp
|
||||
@@ -206,7 +206,7 @@ _call
|
||||
|
||||
_call(other)
|
||||
|
||||
invoked when a table, userdata or class instance is called
|
||||
invoked when a table, userdata, or class instance is called
|
||||
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
_cloned
|
||||
@@ -226,9 +226,9 @@ _nexti
|
||||
|
||||
_nexti(previdx)
|
||||
|
||||
invoked when a userdata or class instance is iterated by a foreach loop
|
||||
invoked when a userdata or class instance is iterated by a foreach loop.
|
||||
|
||||
if previdx==null it means that it is the first iteration.
|
||||
If previdx==null it means that it is the first iteration.
|
||||
The function has to return the index of the 'next' value.
|
||||
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -237,12 +237,12 @@ _tostring
|
||||
|
||||
::
|
||||
|
||||
_tostring(previdx)
|
||||
_tostring()
|
||||
|
||||
invoked when during string conacatenation or when the ``print`` function prints a table, instance or userdata.
|
||||
The method is also invoked by the sq_tostring() api
|
||||
Invoked when during string concatenation or when the ``print`` function prints a table, instance, or userdata.
|
||||
The method is also invoked by the sq_tostring() API.
|
||||
|
||||
must return a string representation of the object.
|
||||
Must return a string representation of the object.
|
||||
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
_inherited
|
||||
@@ -252,10 +252,10 @@ _inherited
|
||||
|
||||
_inherited(attributes)
|
||||
|
||||
invoked when a class object inherits from the class implementing ``_inherited``
|
||||
the ``this`` contains the new class.
|
||||
invoked when a class object inherits from the class implementing ``_inherited``.
|
||||
The ``this`` contains the new class.
|
||||
|
||||
return value is ignored.
|
||||
Return value is ignored.
|
||||
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
_newmember
|
||||
@@ -265,6 +265,6 @@ _newmember
|
||||
|
||||
_newmember(index,value,attributes,isstatic)
|
||||
|
||||
invoked for each member declared in a class body(at declaration time).
|
||||
invoked for each member declared in a class body (at declaration time).
|
||||
|
||||
if the function is implemented, members will not be added to the class.
|
||||
If the function is implemented, members will not be added to the class.
|
||||
|
@@ -52,7 +52,7 @@ true and false
|
||||
single: true
|
||||
single: false
|
||||
|
||||
Squirrel has a boolean type(bool) however like C++ it considers null, 0(integer) and 0.0(float)
|
||||
Squirrel has a boolean type (bool) however like C++ it considers null, 0(integer) and 0.0(float)
|
||||
as *false*, any other value is considered *true*.
|
||||
|
||||
^^^^^^^^^^^^^^^^^
|
||||
@@ -326,7 +326,7 @@ try/catch
|
||||
stat:= 'try' stat 'catch' '(' id ')' stat
|
||||
|
||||
The try statement encloses a block of code in which an exceptional condition can occur,
|
||||
such as a runtime error or a throw statement. The catch clause provides the exceptionhandling
|
||||
such as a runtime error or a throw statement. The catch clause provides the exception-handling
|
||||
code. When a catch clause catches an exception, its id is bound to that
|
||||
exception.
|
||||
|
||||
|
@@ -18,7 +18,7 @@ through this type; even the environment, where "global" variables are stored, is
|
||||
Construction
|
||||
------------------
|
||||
|
||||
Tables are created through the table constructor (see :ref:`Table constructor <table_contructor>`)
|
||||
Tables are created through the table constructor (see :ref:`Table constructor <table_constructor>`)
|
||||
|
||||
------------------
|
||||
Slot creation
|
||||
|
@@ -22,17 +22,17 @@ Using threads
|
||||
------------------
|
||||
|
||||
.. index::
|
||||
single: Usign Threads
|
||||
single: Using Threads
|
||||
|
||||
Threads are created through the built-in function 'newthread(func)'; this function
|
||||
gets as parameter a squirrel function and bind it to the new thread objecs(will be the thread body).
|
||||
gets as parameter a squirrel function and bind it to the new thread objects (will be the thread body).
|
||||
The returned thread object is initially in 'idle' state. the thread can be started with the function
|
||||
'threadobj.call()'; the parameters passed to 'call' are passed to the thread function.
|
||||
|
||||
A thread can be be suspended calling the function suspend(), when this happens the function
|
||||
that wokeup(or started) the thread returns (If a parametrer is passed to suspend() it will
|
||||
that wokeup(or started) the thread returns (If a parameter is passed to suspend() it will
|
||||
be the return value of the wakeup function , if no parameter is passed the return value will be null).
|
||||
A suspended thread can be resumed calling the funtion 'threadobj.wakeup', when this happens
|
||||
A suspended thread can be resumed calling the function 'threadobj.wakeup', when this happens
|
||||
the function that suspended the thread will return(if a parameter is passed to wakeup it will
|
||||
be the return value of the suspend function, if no parameter is passed the return value will be null).
|
||||
|
||||
|
@@ -12,7 +12,7 @@ Weak References
|
||||
The weak references allows the programmers to create references to objects without
|
||||
influencing the lifetime of the object itself.
|
||||
In squirrel Weak references are first-class objects created through the built-in method obj.weakref().
|
||||
All types except null implement the weakref() method; however in bools,integers and float the method
|
||||
All types except null implement the weakref() method; however in bools, integers, and floats the method
|
||||
simply returns the object itself(this because this types are always passed by value).
|
||||
When a weak references is assigned to a container (table slot,array,class or
|
||||
instance) is treated differently than other objects; When a container slot that hold a weak
|
||||
|
@@ -4,7 +4,7 @@
|
||||
Squirrel Standard Library 3.1
|
||||
#################################
|
||||
|
||||
Copyrigth (c) 2003-2016 Alberto Demichelis
|
||||
Copyright (c) 2003-2016 Alberto Demichelis
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@@ -28,4 +28,4 @@ C API
|
||||
|
||||
prints the call stack and stack contents. the function
|
||||
uses the print function set through(:ref:`sq_setprintfunc <sq_setprintfunc>`) to output
|
||||
the stack dump.
|
||||
the stack dump.
|
||||
|
@@ -4,7 +4,7 @@
|
||||
The Blob library
|
||||
==================
|
||||
The blob library implements binary data manipulations routines. The library is
|
||||
based on `blob objects` that rapresent a buffer of arbitrary
|
||||
based on `blob objects` that represent a buffer of arbitrary
|
||||
binary data.
|
||||
|
||||
---------------
|
||||
@@ -60,26 +60,26 @@ A blob can also be accessed byte by byte through the `[]` operator.
|
||||
|
||||
.. js:function:: blob.len()
|
||||
|
||||
returns the lenght of the stream
|
||||
returns the length of the stream
|
||||
|
||||
.. js:function:: blob.readblob(size)
|
||||
|
||||
:param int size: number of bytes to read
|
||||
|
||||
read n bytes from the stream and retuns them as blob
|
||||
read n bytes from the stream and returns them as blob
|
||||
|
||||
.. js:function:: blob.readn(type)
|
||||
|
||||
:param int type: type of the number to read
|
||||
|
||||
reads a number from the stream according to the type pameter.
|
||||
reads a number from the stream according to the type parameter.
|
||||
|
||||
`type` can have the following values:
|
||||
|
||||
+--------------+--------------------------------------------------------------------------------+----------------------+
|
||||
| parameter | return description | return type |
|
||||
+==============+================================================================================+======================+
|
||||
| 'l' | processor dependent, 32bits on 32bits processors, 64bits on 64bits prcessors | integer |
|
||||
| 'l' | processor dependent, 32bits on 32bits processors, 64bits on 64bits processors | integer |
|
||||
+--------------+--------------------------------------------------------------------------------+----------------------+
|
||||
| 'i' | 32bits number | integer |
|
||||
+--------------+--------------------------------------------------------------------------------+----------------------+
|
||||
@@ -98,7 +98,7 @@ A blob can also be accessed byte by byte through the `[]` operator.
|
||||
|
||||
.. js:function:: blob.resize(size)
|
||||
|
||||
:param int size: the new size of the blobl in bytes
|
||||
:param int size: the new size of the blob in bytes
|
||||
|
||||
resizes the blob to the specified `size`
|
||||
|
||||
@@ -142,7 +142,7 @@ A blob can also be accessed byte by byte through the `[]` operator.
|
||||
:param number n: the value to be written
|
||||
:param int type: type of the number to write
|
||||
|
||||
writes a number in the stream formatted according to the `type` pameter
|
||||
writes a number in the stream formatted according to the `type` parameter
|
||||
|
||||
`type` can have the following values:
|
||||
|
||||
@@ -210,4 +210,4 @@ C API
|
||||
:param SQInteger size: the size of the blob payload that has to be created
|
||||
:returns: a pointer to the newly created blob payload
|
||||
|
||||
creates a blob with the given payload size and pushes it in the stack.
|
||||
creates a blob with the given payload size and pushes it in the stack.
|
||||
|
@@ -21,20 +21,20 @@ Global Symbols
|
||||
returns the value returned by the script or null if no value is returned.
|
||||
if the optional parameter 'raiseerror' is true, the compiler error handler is invoked
|
||||
in case of a syntax error. If raiseerror is omitted or set to false, the compiler
|
||||
error handler is not ivoked.
|
||||
When squirrel is compiled in unicode mode the function can handle different character ecodings,
|
||||
error handler is not invoked.
|
||||
When squirrel is compiled in Unicode mode the function can handle different character encodings,
|
||||
UTF8 with and without prefix and UCS-2 prefixed(both big endian an little endian).
|
||||
If the source stream is not prefixed UTF8 ecoding is used as default.
|
||||
If the source stream is not prefixed UTF8 encoding is used as default.
|
||||
|
||||
.. js:function:: loadfile(path, [raiseerror])
|
||||
|
||||
compiles a squirrel script or loads a precompiled one an returns it as as function.
|
||||
if the optional parameter 'raiseerror' is true, the compiler error handler is invoked
|
||||
in case of a syntax error. If raiseerror is omitted or set to false, the compiler
|
||||
error handler is not ivoked.
|
||||
When squirrel is compiled in unicode mode the function can handle different character ecodings,
|
||||
error handler is not invoked.
|
||||
When squirrel is compiled in Unicode mode the function can handle different character encodings,
|
||||
UTF8 with and without prefix and UCS-2 prefixed(both big endian an little endian).
|
||||
If the source stream is not prefixed UTF8 ecoding is used as default.
|
||||
If the source stream is not prefixed UTF8 encoding is used as default.
|
||||
|
||||
.. js:function:: writeclosuretofile(destpath, closure)
|
||||
|
||||
@@ -63,7 +63,7 @@ The file class
|
||||
|
||||
.. js:class:: file(path, patten)
|
||||
|
||||
It's contructor imitates the behaviour of the C runtime function fopen for eg. ::
|
||||
It's constructor imitates the behaviour of the C runtime function fopen for eg. ::
|
||||
|
||||
local myfile = file("test.xxx","wb+");
|
||||
|
||||
@@ -79,30 +79,30 @@ The file class
|
||||
|
||||
.. js:function:: file.flush()
|
||||
|
||||
flushes the stream.return a value != null if succeded, otherwise returns null
|
||||
flushes the stream.return a value != null if succeeded, otherwise returns null
|
||||
|
||||
.. js:function:: file.len()
|
||||
|
||||
returns the lenght of the stream
|
||||
returns the length of the stream
|
||||
|
||||
.. js:function:: file.readblob(size)
|
||||
|
||||
:param int size: number of bytes to read
|
||||
|
||||
read n bytes from the stream and retuns them as blob
|
||||
read n bytes from the stream and returns them as blob
|
||||
|
||||
.. js:function:: file.readn(type)
|
||||
|
||||
:param int type: type of the number to read
|
||||
|
||||
reads a number from the stream according to the type pameter.
|
||||
reads a number from the stream according to the type parameter.
|
||||
|
||||
`type` can have the following values:
|
||||
|
||||
+--------------+--------------------------------------------------------------------------------+----------------------+
|
||||
| parameter | return description | return type |
|
||||
+==============+================================================================================+======================+
|
||||
| 'l' | processor dependent, 32bits on 32bits processors, 64bits on 64bits prcessors | integer |
|
||||
| 'l' | processor dependent, 32bits on 32bits processors, 64bits on 64bits processors | integer |
|
||||
+--------------+--------------------------------------------------------------------------------+----------------------+
|
||||
| 'i' | 32bits number | integer |
|
||||
+--------------+--------------------------------------------------------------------------------+----------------------+
|
||||
@@ -121,7 +121,7 @@ The file class
|
||||
|
||||
.. js:function:: file.resize(size)
|
||||
|
||||
:param int size: the new size of the blobl in bytes
|
||||
:param int size: the new size of the blob in bytes
|
||||
|
||||
resizes the blob to the specified `size`
|
||||
|
||||
@@ -157,7 +157,7 @@ The file class
|
||||
:param number n: the value to be written
|
||||
:param int type: type of the number to write
|
||||
|
||||
writes a number in the stream formatted according to the `type` pameter
|
||||
writes a number in the stream formatted according to the `type` pamraeter
|
||||
|
||||
`type` can have the following values:
|
||||
|
||||
@@ -230,9 +230,9 @@ Script loading and serialization
|
||||
:returns: an SQRESULT
|
||||
|
||||
Compiles a squirrel script or loads a precompiled one an pushes it as closure in the stack.
|
||||
When squirrel is compiled in unicode mode the function can handle different character ecodings,
|
||||
When squirrel is compiled in Unicode mode the function can handle different character encodings,
|
||||
UTF8 with and without prefix and UCS-2 prefixed(both big endian an little endian).
|
||||
If the source stream is not prefixed UTF8 ecoding is used as default.
|
||||
If the source stream is not prefixed UTF8 encoding is used as default.
|
||||
|
||||
.. c:function:: SQRESULT sqstd_dofile(HSQUIRRELVM v, const SQChar* filename, SQBool retval, SQBool printerror)
|
||||
|
||||
@@ -241,13 +241,13 @@ Script loading and serialization
|
||||
:param SQBool retval: if true the function will push the return value of the executed script in the stack.
|
||||
:param SQBool printerror: if true the compiler error handler will be called if a error occurs
|
||||
:returns: an SQRESULT
|
||||
:remarks: the function aspects a table on top of the stack that will be used as 'this' for the execution of the script. The 'this' parameter is left untouched in the stack.
|
||||
:remarks: the function expects a table on top of the stack that will be used as 'this' for the execution of the script. The 'this' parameter is left untouched in the stack.
|
||||
|
||||
Compiles a squirrel script or loads a precompiled one and executes it.
|
||||
Optionally pushes the return value of the executed script in the stack.
|
||||
When squirrel is compiled in unicode mode the function can handle different character ecodings,
|
||||
When squirrel is compiled in unicode mode the function can handle different character encodings,
|
||||
UTF8 with and without prefix and UCS-2 prefixed(both big endian an little endian).
|
||||
If the source stream is not prefixed UTF8 ecoding is used as default. ::
|
||||
If the source stream is not prefixed, UTF8 encoding is used as default. ::
|
||||
|
||||
sq_pushroottable(v); //push the root table(were the globals of the script will are stored)
|
||||
sqstd_dofile(v, _SC("test.nut"), SQFalse, SQTrue);// also prints syntax errors if any
|
||||
@@ -259,6 +259,6 @@ Script loading and serialization
|
||||
:returns: an SQRESULT
|
||||
|
||||
serializes the closure at the top position in the stack as bytecode in
|
||||
the file specified by the paremeter filename. If a file with the
|
||||
the file specified by the parameter filename. If a file with the
|
||||
same name already exists, it will be overwritten.
|
||||
|
||||
|
@@ -17,8 +17,8 @@ Global Symbols
|
||||
.. js:function:: endswith(str, cmp)
|
||||
|
||||
returns `true` if the end of the string `str` matches a the string `cmp` otherwise returns `false`
|
||||
|
||||
.. js:function:: ecape(str)
|
||||
|
||||
.. js:function:: escape(str)
|
||||
|
||||
Returns a string with backslashes before characters that need to be escaped(`\",\a,\b,\t,\n,\v,\f,\r,\\,\",\',\0,\xnn`).
|
||||
|
||||
@@ -28,10 +28,18 @@ Global Symbols
|
||||
The format string follows the same rules as the `printf` family of
|
||||
standard C functions( the "*" is not supported). ::
|
||||
|
||||
eg.
|
||||
e.g.
|
||||
sq> print(format("%s %d 0x%02X\n","this is a test :",123,10));
|
||||
this is a test : 123 0x0A
|
||||
|
||||
.. js:function:: printf(formatstr, ...)
|
||||
|
||||
Just like calling `print(format(formatstr` as in the example above, but is more convenient AND more efficient. ::
|
||||
|
||||
e.g.
|
||||
sq> printf("%s %d 0x%02X\n","this is a test :",123,10);
|
||||
this is a test : 123 0x0A
|
||||
|
||||
.. js:function:: lstrip(str)
|
||||
|
||||
Strips white-space-only characters that might appear at the beginning of the given string
|
||||
@@ -42,7 +50,7 @@ Global Symbols
|
||||
Strips white-space-only characters that might appear at the end of the given string
|
||||
and returns the new stripped string.
|
||||
|
||||
.. js:function:: split(str, separtators)
|
||||
.. js:function:: split(str, separators)
|
||||
|
||||
returns an array of strings split at each point where a separator character occurs in `str`.
|
||||
The separator is not returned as part of any array element.
|
||||
@@ -57,8 +65,8 @@ Global Symbols
|
||||
|
||||
.. js:function:: startswith(str, cmp)
|
||||
|
||||
returns `true` if the beginning of the string `str` matches a the string `cmp` otherwise returns `false`
|
||||
|
||||
returns `true` if the beginning of the string `str` matches the string `cmp`; otherwise returns `false`
|
||||
|
||||
.. js:function:: strip(str)
|
||||
|
||||
Strips white-space-only characters that might appear at the beginning or end of the given string and returns the new stripped string.
|
||||
@@ -69,8 +77,8 @@ The regexp class
|
||||
|
||||
.. js:class:: regexp(pattern)
|
||||
|
||||
The regexp object rapresent a precompiled regular experssion pattern. The object is created
|
||||
trough `regexp(patern)`.
|
||||
The regexp object represents a precompiled regular expression pattern. The object is created
|
||||
through `regexp(pattern)`.
|
||||
|
||||
|
||||
+---------------------+--------------------------------------+
|
||||
@@ -140,19 +148,19 @@ The regexp class
|
||||
+---------------------+--------------------------------------+
|
||||
| `\\d` | digits |
|
||||
+---------------------+--------------------------------------+
|
||||
| `\\D` | non nondigits |
|
||||
| `\\D` | non digits |
|
||||
+---------------------+--------------------------------------+
|
||||
| `\\x` | exadecimal digits |
|
||||
| `\\x` | hexadecimal digits |
|
||||
+---------------------+--------------------------------------+
|
||||
| `\\X` | non exadecimal digits |
|
||||
| `\\X` | non hexadecimal digits |
|
||||
+---------------------+--------------------------------------+
|
||||
| `\\c` | control characters |
|
||||
+---------------------+--------------------------------------+
|
||||
| `\\C` | non control characters |
|
||||
+---------------------+--------------------------------------+
|
||||
| `\\p` | punctation |
|
||||
| `\\p` | punctuation |
|
||||
+---------------------+--------------------------------------+
|
||||
| `\\P` | non punctation |
|
||||
| `\\P` | non punctuation |
|
||||
+---------------------+--------------------------------------+
|
||||
| `\\b` | word boundary |
|
||||
+---------------------+--------------------------------------+
|
||||
@@ -162,13 +170,13 @@ The regexp class
|
||||
|
||||
.. js:function:: regexp.capture(str [, start])
|
||||
|
||||
returns an array of tables containing two indexs("begin" and "end")of
|
||||
returns an array of tables containing two indexes ("begin" and "end") of
|
||||
the first match of the regular expression in the string `str`.
|
||||
An array entry is created for each captured sub expressions. If no match occurs returns null.
|
||||
The search starts from the index `start`
|
||||
of the string, if `start` is omitted the search starts from the beginning of the string.
|
||||
of the string; if `start` is omitted the search starts from the beginning of the string.
|
||||
|
||||
the first element of the returned array(index 0) always contains the complete match.
|
||||
The first element of the returned array(index 0) always contains the complete match.
|
||||
|
||||
::
|
||||
|
||||
@@ -195,9 +203,9 @@ The regexp class
|
||||
|
||||
.. js:function:: regexp.search(str [, start])
|
||||
|
||||
returns a table containing two indexs("begin" and "end") of the first match of the regular expression in
|
||||
returns a table containing two indexes ("begin" and "end") of the first match of the regular expression in
|
||||
the string `str`, otherwise if no match occurs returns null. The search starts from the index `start`
|
||||
of the string, if `start` is omitted the search starts from the beginning of the string.
|
||||
of the string; if `start` is omitted the search starts from the beginning of the string.
|
||||
|
||||
::
|
||||
|
||||
@@ -275,7 +283,7 @@ Regular Expessions
|
||||
:param SQChar** out_end: a pointer to a string pointer that will be set with the end of the match
|
||||
:returns: SQTrue if successful otherwise SQFalse
|
||||
|
||||
searches the first match of the expressin in the string specified in the parameter text.
|
||||
searches the first match of the expression in the string specified in the parameter text.
|
||||
if the match is found returns SQTrue and the sets out_begin to the beginning of the
|
||||
match and out_end at the end of the match; otherwise returns SQFalse.
|
||||
|
||||
@@ -288,9 +296,9 @@ Regular Expessions
|
||||
:param SQChar** out_end: a pointer to a string pointer that will be set with the end of the match
|
||||
:returns: SQTrue if successful otherwise SQFalse
|
||||
|
||||
searches the first match of the expressin in the string delimited
|
||||
searches the first match of the expression in the string delimited
|
||||
by the parameter text_begin and text_end.
|
||||
if the match is found returns SQTrue and the sets out_begin to the beginning of the
|
||||
if the match is found returns SQTrue and sets out_begin to the beginning of the
|
||||
match and out_end at the end of the match; otherwise returns SQFalse.
|
||||
|
||||
.. c:function:: SQInteger sqstd_rex_getsubexpcount(SQRex * exp)
|
||||
@@ -305,7 +313,7 @@ Regular Expessions
|
||||
:param SQRex* exp: a compiled expression
|
||||
:param SQInteger n: the index of the submatch(0 is the complete match)
|
||||
:param SQRexMatch* a: pointer to structure that will store the result
|
||||
:returns: the function returns SQTrue if n is valid index otherwise SQFalse.
|
||||
:returns: the function returns SQTrue if n is a valid index; otherwise SQFalse.
|
||||
|
||||
retrieve the begin and and pointer to the length of the sub expression indexed
|
||||
by n. The result is passed trhough the struct SQRexMatch.
|
||||
by n. The result is passed through the struct SQRexMatch.
|
||||
|
@@ -21,7 +21,7 @@ Global Symbols
|
||||
|
||||
.. js:function:: date([time [, format]])
|
||||
|
||||
returns a table containing a date/time splitted in the slots:
|
||||
returns a table containing a date/time split into the slots:
|
||||
|
||||
+-------------+----------------------------------------+
|
||||
| sec | Seconds after minute (0 - 59). |
|
||||
@@ -79,4 +79,4 @@ C API
|
||||
:returns: an SQRESULT
|
||||
:remarks: The function aspects a table on top of the stack where to register the global library functions.
|
||||
|
||||
initialize and register the system library in the given VM.
|
||||
initialize and register the system library in the given VM.
|
||||
|
@@ -1,78 +0,0 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <squirrel.h>
|
||||
#include <sqstdio.h>
|
||||
#include <sqstdaux.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment (lib ,"squirrel.lib")
|
||||
#pragma comment (lib ,"sqstdlib.lib")
|
||||
#endif
|
||||
|
||||
#ifdef SQUNICODE
|
||||
|
||||
#define scvprintf vfwprintf
|
||||
#else
|
||||
|
||||
#define scvprintf vfprintf
|
||||
#endif
|
||||
|
||||
void printfunc(HSQUIRRELVM v,const SQChar *s,...)
|
||||
{
|
||||
va_list vl;
|
||||
va_start(vl, s);
|
||||
scvprintf(stdout, s, vl);
|
||||
va_end(vl);
|
||||
}
|
||||
|
||||
void errorfunc(HSQUIRRELVM v,const SQChar *s,...)
|
||||
{
|
||||
va_list vl;
|
||||
va_start(vl, s);
|
||||
scvprintf(stderr, s, vl);
|
||||
va_end(vl);
|
||||
}
|
||||
|
||||
void call_foo(HSQUIRRELVM v, int n,float f,const SQChar *s)
|
||||
{
|
||||
SQInteger top = sq_gettop(v); //saves the stack size before the call
|
||||
sq_pushroottable(v); //pushes the global table
|
||||
sq_pushstring(v,_SC("foo"),-1);
|
||||
if(SQ_SUCCEEDED(sq_get(v,-2))) { //gets the field 'foo' from the global table
|
||||
sq_pushroottable(v); //push the 'this' (in this case is the global table)
|
||||
sq_pushinteger(v,n);
|
||||
sq_pushfloat(v,f);
|
||||
sq_pushstring(v,s,-1);
|
||||
sq_call(v,4,SQFalse,SQTrue); //calls the function
|
||||
}
|
||||
sq_settop(v,top); //restores the original stack size
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
HSQUIRRELVM v;
|
||||
v = sq_open(1024); // creates a VM with initial stack size 1024
|
||||
|
||||
//REGISTRATION OF STDLIB
|
||||
//sq_pushroottable(v); //push the root table where the std function will be registered
|
||||
//sqstd_register_iolib(v); //registers a library
|
||||
// ... call here other stdlibs string,math etc...
|
||||
//sq_pop(v,1); //pops the root table
|
||||
//END REGISTRATION OF STDLIB
|
||||
|
||||
sqstd_seterrorhandlers(v); //registers the default error handlers
|
||||
|
||||
sq_setprintfunc(v, printfunc,errorfunc); //sets the print function
|
||||
|
||||
sq_pushroottable(v); //push the root table(were the globals of the script will be stored)
|
||||
if(SQ_SUCCEEDED(sqstd_dofile(v, _SC("test.nut"), SQFalse, SQTrue))) // also prints syntax errors if any
|
||||
{
|
||||
call_foo(v,1,2.5,_SC("teststring"));
|
||||
}
|
||||
|
||||
sq_pop(v,1); //pops the root table
|
||||
sq_close(v);
|
||||
|
||||
return 0;
|
||||
}
|
65
etc/minimal.cpp
Normal file
65
etc/minimal.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <squirrel.h>
|
||||
#include <sqstdio.h>
|
||||
#include <sqstdaux.h>
|
||||
|
||||
void printfunc(HSQUIRRELVM v,const char *s,...)
|
||||
{
|
||||
va_list vl;
|
||||
va_start(vl, s);
|
||||
vfprintf(stdout, s, vl);
|
||||
va_end(vl);
|
||||
}
|
||||
|
||||
void errorfunc(HSQUIRRELVM v,const char *s,...)
|
||||
{
|
||||
va_list vl;
|
||||
va_start(vl, s);
|
||||
vfprintf(stderr, s, vl);
|
||||
va_end(vl);
|
||||
}
|
||||
|
||||
void call_foo(HSQUIRRELVM v, int n,float f,const char *s)
|
||||
{
|
||||
int64_t top = sq_gettop(v); //saves the stack size before the call
|
||||
sq_pushroottable(v); //pushes the global table
|
||||
sq_pushstring(v,"foo",-1);
|
||||
if(SQ_SUCCEEDED(sq_get(v,-2))) { //gets the field 'foo' from the global table
|
||||
sq_pushroottable(v); //push the 'this' (in this case is the global table)
|
||||
sq_pushinteger(v,n);
|
||||
sq_pushfloat(v,f);
|
||||
sq_pushstring(v,s,-1);
|
||||
sq_call(v,4,SQFalse,SQTrue); //calls the function
|
||||
}
|
||||
sq_settop(v,top); //restores the original stack size
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
HSQUIRRELVM v;
|
||||
v = sq_open(1024); // creates a VM with initial stack size 1024
|
||||
|
||||
//REGISTRATION OF STDLIB
|
||||
//sq_pushroottable(v); //push the root table where the std function will be registered
|
||||
//rabbit::std::register_iolib(v); //registers a library
|
||||
// ... call here other stdlibs string,math etc...
|
||||
//sq_pop(v,1); //pops the root table
|
||||
//END REGISTRATION OF STDLIB
|
||||
|
||||
rabbit::std::seterrorhandlers(v); //registers the default error handlers
|
||||
|
||||
sq_setprintfunc(v, printfunc,errorfunc); //sets the print function
|
||||
|
||||
sq_pushroottable(v); //push the root table(were the globals of the script will be stored)
|
||||
if(SQ_SUCCEEDED(rabbit::std::dofile(v, "test.nut", SQFalse, SQTrue))) // also prints syntax errors if any
|
||||
{
|
||||
call_foo(v,1,2.5,"teststring");
|
||||
}
|
||||
|
||||
sq_pop(v,1); //pops the root table
|
||||
sq_close(v);
|
||||
|
||||
return 0;
|
||||
}
|
@@ -1,146 +0,0 @@
|
||||
|
||||
#ifdef _SQ64
|
||||
|
||||
#ifdef _MSC_VER
|
||||
typedef __int64 SQInteger;
|
||||
typedef unsigned __int64 SQUnsignedInteger;
|
||||
typedef unsigned __int64 SQHash; /*should be the same size of a pointer*/
|
||||
#else
|
||||
typedef long long SQInteger;
|
||||
typedef unsigned long long SQUnsignedInteger;
|
||||
typedef unsigned long long SQHash; /*should be the same size of a pointer*/
|
||||
#endif
|
||||
typedef int SQInt32;
|
||||
typedef unsigned int SQUnsignedInteger32;
|
||||
#else
|
||||
typedef int SQInteger;
|
||||
typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/
|
||||
typedef unsigned int SQUnsignedInteger32; /*must be 32 bits(also on 64bits processors)*/
|
||||
typedef unsigned int SQUnsignedInteger;
|
||||
typedef unsigned int SQHash; /*should be the same size of a pointer*/
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef SQUSEDOUBLE
|
||||
typedef double SQFloat;
|
||||
#else
|
||||
typedef float SQFloat;
|
||||
#endif
|
||||
|
||||
#if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64)
|
||||
#ifdef _MSC_VER
|
||||
typedef __int64 SQRawObjectVal; //must be 64bits
|
||||
#else
|
||||
typedef long long SQRawObjectVal; //must be 64bits
|
||||
#endif
|
||||
#define SQ_OBJECT_RAWINIT() { _unVal.raw = 0; }
|
||||
#else
|
||||
typedef SQUnsignedInteger SQRawObjectVal; //is 32 bits on 32 bits builds and 64 bits otherwise
|
||||
#define SQ_OBJECT_RAWINIT()
|
||||
#endif
|
||||
|
||||
#ifndef SQ_ALIGNMENT // SQ_ALIGNMENT shall be less than or equal to SQ_MALLOC alignments, and its value shall be power of 2.
|
||||
#if defined(SQUSEDOUBLE) || defined(_SQ64)
|
||||
#define SQ_ALIGNMENT 8
|
||||
#else
|
||||
#define SQ_ALIGNMENT 4
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef void* SQUserPointer;
|
||||
typedef SQUnsignedInteger SQBool;
|
||||
typedef SQInteger SQRESULT;
|
||||
|
||||
#ifdef SQUNICODE
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
|
||||
|
||||
typedef wchar_t SQChar;
|
||||
|
||||
|
||||
#define scstrcmp wcscmp
|
||||
#ifdef _WIN32
|
||||
#define scsprintf _snwprintf
|
||||
#else
|
||||
#define scsprintf swprintf
|
||||
#endif
|
||||
#define scstrlen wcslen
|
||||
#define scstrtod wcstod
|
||||
#ifdef _SQ64
|
||||
#define scstrtol wcstoll
|
||||
#else
|
||||
#define scstrtol wcstol
|
||||
#endif
|
||||
#define scstrtoul wcstoul
|
||||
#define scvsprintf vswprintf
|
||||
#define scstrstr wcsstr
|
||||
#define scprintf wprintf
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WCHAR_SIZE 2
|
||||
#define WCHAR_SHIFT_MUL 1
|
||||
#define MAX_CHAR 0xFFFF
|
||||
#else
|
||||
#define WCHAR_SIZE 4
|
||||
#define WCHAR_SHIFT_MUL 2
|
||||
#define MAX_CHAR 0xFFFFFFFF
|
||||
#endif
|
||||
|
||||
#define _SC(a) L##a
|
||||
|
||||
|
||||
#define scisspace iswspace
|
||||
#define scisdigit iswdigit
|
||||
#define scisprint iswprint
|
||||
#define scisxdigit iswxdigit
|
||||
#define scisalpha iswalpha
|
||||
#define sciscntrl iswcntrl
|
||||
#define scisalnum iswalnum
|
||||
|
||||
|
||||
#define sq_rsl(l) ((l)<<WCHAR_SHIFT_MUL)
|
||||
|
||||
#else
|
||||
typedef char SQChar;
|
||||
#define _SC(a) a
|
||||
#define scstrcmp strcmp
|
||||
#ifdef _MSC_VER
|
||||
#define scsprintf _snprintf
|
||||
#else
|
||||
#define scsprintf snprintf
|
||||
#endif
|
||||
#define scstrlen strlen
|
||||
#define scstrtod strtod
|
||||
#ifdef _SQ64
|
||||
#ifdef _MSC_VER
|
||||
#define scstrtol _strtoi64
|
||||
#else
|
||||
#define scstrtol strtoll
|
||||
#endif
|
||||
#else
|
||||
#define scstrtol strtol
|
||||
#endif
|
||||
#define scstrtoul strtoul
|
||||
#define scvsprintf vsnprintf
|
||||
#define scstrstr strstr
|
||||
#define scisspace isspace
|
||||
#define scisdigit isdigit
|
||||
#define scisprint isprint
|
||||
#define scisxdigit isxdigit
|
||||
#define sciscntrl iscntrl
|
||||
#define scisalpha isalpha
|
||||
#define scisalnum isalnum
|
||||
#define scprintf printf
|
||||
#define MAX_CHAR 0xFF
|
||||
|
||||
#define sq_rsl(l) (l)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _SQ64
|
||||
#define _PRINT_INT_PREC _SC("ll")
|
||||
#define _PRINT_INT_FMT _SC("%lld")
|
||||
#else
|
||||
#define _PRINT_INT_FMT _SC("%d")
|
||||
#endif
|
@@ -1,16 +0,0 @@
|
||||
/* see copyright notice in squirrel.h */
|
||||
#ifndef _SQSTD_AUXLIB_H_
|
||||
#define _SQSTD_AUXLIB_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
SQUIRREL_API void sqstd_seterrorhandlers(HSQUIRRELVM v);
|
||||
SQUIRREL_API void sqstd_printcallstack(HSQUIRRELVM v);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /* _SQSTD_AUXLIB_H_ */
|
@@ -1,20 +0,0 @@
|
||||
/* see copyright notice in squirrel.h */
|
||||
#ifndef _SQSTDBLOB_H_
|
||||
#define _SQSTDBLOB_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
SQUIRREL_API SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size);
|
||||
SQUIRREL_API SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr);
|
||||
SQUIRREL_API SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx);
|
||||
|
||||
SQUIRREL_API SQRESULT sqstd_register_bloblib(HSQUIRRELVM v);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*_SQSTDBLOB_H_*/
|
||||
|
@@ -1,53 +0,0 @@
|
||||
/* see copyright notice in squirrel.h */
|
||||
#ifndef _SQSTDIO_H_
|
||||
#define _SQSTDIO_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#define SQSTD_STREAM_TYPE_TAG 0x80000000
|
||||
|
||||
struct SQStream {
|
||||
virtual SQInteger Read(void *buffer, SQInteger size) = 0;
|
||||
virtual SQInteger Write(void *buffer, SQInteger size) = 0;
|
||||
virtual SQInteger Flush() = 0;
|
||||
virtual SQInteger Tell() = 0;
|
||||
virtual SQInteger Len() = 0;
|
||||
virtual SQInteger Seek(SQInteger offset, SQInteger origin) = 0;
|
||||
virtual bool IsValid() = 0;
|
||||
virtual bool EOS() = 0;
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SQ_SEEK_CUR 0
|
||||
#define SQ_SEEK_END 1
|
||||
#define SQ_SEEK_SET 2
|
||||
|
||||
typedef void* SQFILE;
|
||||
|
||||
SQUIRREL_API SQFILE sqstd_fopen(const SQChar *,const SQChar *);
|
||||
SQUIRREL_API SQInteger sqstd_fread(SQUserPointer, SQInteger, SQInteger, SQFILE);
|
||||
SQUIRREL_API SQInteger sqstd_fwrite(const SQUserPointer, SQInteger, SQInteger, SQFILE);
|
||||
SQUIRREL_API SQInteger sqstd_fseek(SQFILE , SQInteger , SQInteger);
|
||||
SQUIRREL_API SQInteger sqstd_ftell(SQFILE);
|
||||
SQUIRREL_API SQInteger sqstd_fflush(SQFILE);
|
||||
SQUIRREL_API SQInteger sqstd_fclose(SQFILE);
|
||||
SQUIRREL_API SQInteger sqstd_feof(SQFILE);
|
||||
|
||||
SQUIRREL_API SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own);
|
||||
SQUIRREL_API SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file);
|
||||
|
||||
//compiler helpers
|
||||
SQUIRREL_API SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror);
|
||||
SQUIRREL_API SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror);
|
||||
SQUIRREL_API SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename);
|
||||
|
||||
SQUIRREL_API SQRESULT sqstd_register_iolib(HSQUIRRELVM v);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*_SQSTDIO_H_*/
|
||||
|
@@ -1,15 +0,0 @@
|
||||
/* see copyright notice in squirrel.h */
|
||||
#ifndef _SQSTD_MATH_H_
|
||||
#define _SQSTD_MATH_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
SQUIRREL_API SQRESULT sqstd_register_mathlib(HSQUIRRELVM v);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*_SQSTD_MATH_H_*/
|
@@ -1,33 +0,0 @@
|
||||
/* see copyright notice in squirrel.h */
|
||||
#ifndef _SQSTD_STRING_H_
|
||||
#define _SQSTD_STRING_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef unsigned int SQRexBool;
|
||||
typedef struct SQRex SQRex;
|
||||
|
||||
typedef struct {
|
||||
const SQChar *begin;
|
||||
SQInteger len;
|
||||
} SQRexMatch;
|
||||
|
||||
SQUIRREL_API SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error);
|
||||
SQUIRREL_API void sqstd_rex_free(SQRex *exp);
|
||||
SQUIRREL_API SQBool sqstd_rex_match(SQRex* exp,const SQChar* text);
|
||||
SQUIRREL_API SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end);
|
||||
SQUIRREL_API SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end);
|
||||
SQUIRREL_API SQInteger sqstd_rex_getsubexpcount(SQRex* exp);
|
||||
SQUIRREL_API SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp);
|
||||
|
||||
SQUIRREL_API SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output);
|
||||
|
||||
SQUIRREL_API SQRESULT sqstd_register_stringlib(HSQUIRRELVM v);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*_SQSTD_STRING_H_*/
|
@@ -1,15 +0,0 @@
|
||||
/* see copyright notice in squirrel.h */
|
||||
#ifndef _SQSTD_SYSTEMLIB_H_
|
||||
#define _SQSTD_SYSTEMLIB_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
SQUIRREL_API SQInteger sqstd_register_systemlib(HSQUIRRELVM v);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /* _SQSTD_SYSTEMLIB_H_ */
|
@@ -1,405 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2003-2016 Alberto Demichelis
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#ifndef _SQUIRREL_H_
|
||||
#define _SQUIRREL_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef SQUIRREL_API
|
||||
#define SQUIRREL_API extern
|
||||
#endif
|
||||
|
||||
#if (defined(_WIN64) || defined(_LP64))
|
||||
#ifndef _SQ64
|
||||
#define _SQ64
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#define SQTrue (1)
|
||||
#define SQFalse (0)
|
||||
|
||||
struct SQVM;
|
||||
struct SQTable;
|
||||
struct SQArray;
|
||||
struct SQString;
|
||||
struct SQClosure;
|
||||
struct SQGenerator;
|
||||
struct SQNativeClosure;
|
||||
struct SQUserData;
|
||||
struct SQFunctionProto;
|
||||
struct SQRefCounted;
|
||||
struct SQClass;
|
||||
struct SQInstance;
|
||||
struct SQDelegable;
|
||||
struct SQOuter;
|
||||
|
||||
#ifdef _UNICODE
|
||||
#define SQUNICODE
|
||||
#endif
|
||||
|
||||
#include "sqconfig.h"
|
||||
|
||||
#define SQUIRREL_VERSION _SC("Squirrel 3.1 stable")
|
||||
#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2016 Alberto Demichelis")
|
||||
#define SQUIRREL_AUTHOR _SC("Alberto Demichelis")
|
||||
#define SQUIRREL_VERSION_NUMBER 310
|
||||
|
||||
#define SQ_VMSTATE_IDLE 0
|
||||
#define SQ_VMSTATE_RUNNING 1
|
||||
#define SQ_VMSTATE_SUSPENDED 2
|
||||
|
||||
#define SQUIRREL_EOB 0
|
||||
#define SQ_BYTECODE_STREAM_TAG 0xFAFA
|
||||
|
||||
#define SQOBJECT_REF_COUNTED 0x08000000
|
||||
#define SQOBJECT_NUMERIC 0x04000000
|
||||
#define SQOBJECT_DELEGABLE 0x02000000
|
||||
#define SQOBJECT_CANBEFALSE 0x01000000
|
||||
|
||||
#define SQ_MATCHTYPEMASKSTRING (-99999)
|
||||
|
||||
#define _RT_MASK 0x00FFFFFF
|
||||
#define _RAW_TYPE(type) (type&_RT_MASK)
|
||||
|
||||
#define _RT_NULL 0x00000001
|
||||
#define _RT_INTEGER 0x00000002
|
||||
#define _RT_FLOAT 0x00000004
|
||||
#define _RT_BOOL 0x00000008
|
||||
#define _RT_STRING 0x00000010
|
||||
#define _RT_TABLE 0x00000020
|
||||
#define _RT_ARRAY 0x00000040
|
||||
#define _RT_USERDATA 0x00000080
|
||||
#define _RT_CLOSURE 0x00000100
|
||||
#define _RT_NATIVECLOSURE 0x00000200
|
||||
#define _RT_GENERATOR 0x00000400
|
||||
#define _RT_USERPOINTER 0x00000800
|
||||
#define _RT_THREAD 0x00001000
|
||||
#define _RT_FUNCPROTO 0x00002000
|
||||
#define _RT_CLASS 0x00004000
|
||||
#define _RT_INSTANCE 0x00008000
|
||||
#define _RT_WEAKREF 0x00010000
|
||||
#define _RT_OUTER 0x00020000
|
||||
|
||||
typedef enum tagSQObjectType{
|
||||
OT_NULL = (_RT_NULL|SQOBJECT_CANBEFALSE),
|
||||
OT_INTEGER = (_RT_INTEGER|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
|
||||
OT_FLOAT = (_RT_FLOAT|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
|
||||
OT_BOOL = (_RT_BOOL|SQOBJECT_CANBEFALSE),
|
||||
OT_STRING = (_RT_STRING|SQOBJECT_REF_COUNTED),
|
||||
OT_TABLE = (_RT_TABLE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
|
||||
OT_ARRAY = (_RT_ARRAY|SQOBJECT_REF_COUNTED),
|
||||
OT_USERDATA = (_RT_USERDATA|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
|
||||
OT_CLOSURE = (_RT_CLOSURE|SQOBJECT_REF_COUNTED),
|
||||
OT_NATIVECLOSURE = (_RT_NATIVECLOSURE|SQOBJECT_REF_COUNTED),
|
||||
OT_GENERATOR = (_RT_GENERATOR|SQOBJECT_REF_COUNTED),
|
||||
OT_USERPOINTER = _RT_USERPOINTER,
|
||||
OT_THREAD = (_RT_THREAD|SQOBJECT_REF_COUNTED) ,
|
||||
OT_FUNCPROTO = (_RT_FUNCPROTO|SQOBJECT_REF_COUNTED), //internal usage only
|
||||
OT_CLASS = (_RT_CLASS|SQOBJECT_REF_COUNTED),
|
||||
OT_INSTANCE = (_RT_INSTANCE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
|
||||
OT_WEAKREF = (_RT_WEAKREF|SQOBJECT_REF_COUNTED),
|
||||
OT_OUTER = (_RT_OUTER|SQOBJECT_REF_COUNTED) //internal usage only
|
||||
}SQObjectType;
|
||||
|
||||
#define ISREFCOUNTED(t) (t&SQOBJECT_REF_COUNTED)
|
||||
|
||||
|
||||
typedef union tagSQObjectValue
|
||||
{
|
||||
struct SQTable *pTable;
|
||||
struct SQArray *pArray;
|
||||
struct SQClosure *pClosure;
|
||||
struct SQOuter *pOuter;
|
||||
struct SQGenerator *pGenerator;
|
||||
struct SQNativeClosure *pNativeClosure;
|
||||
struct SQString *pString;
|
||||
struct SQUserData *pUserData;
|
||||
SQInteger nInteger;
|
||||
SQFloat fFloat;
|
||||
SQUserPointer pUserPointer;
|
||||
struct SQFunctionProto *pFunctionProto;
|
||||
struct SQRefCounted *pRefCounted;
|
||||
struct SQDelegable *pDelegable;
|
||||
struct SQVM *pThread;
|
||||
struct SQClass *pClass;
|
||||
struct SQInstance *pInstance;
|
||||
struct SQWeakRef *pWeakRef;
|
||||
SQRawObjectVal raw;
|
||||
}SQObjectValue;
|
||||
|
||||
|
||||
typedef struct tagSQObject
|
||||
{
|
||||
SQObjectType _type;
|
||||
SQObjectValue _unVal;
|
||||
}SQObject;
|
||||
|
||||
typedef struct tagSQMemberHandle{
|
||||
SQBool _static;
|
||||
SQInteger _index;
|
||||
}SQMemberHandle;
|
||||
|
||||
typedef struct tagSQStackInfos{
|
||||
const SQChar* funcname;
|
||||
const SQChar* source;
|
||||
SQInteger line;
|
||||
}SQStackInfos;
|
||||
|
||||
typedef struct SQVM* HSQUIRRELVM;
|
||||
typedef SQObject HSQOBJECT;
|
||||
typedef SQMemberHandle HSQMEMBERHANDLE;
|
||||
typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM);
|
||||
typedef SQInteger (*SQRELEASEHOOK)(SQUserPointer,SQInteger size);
|
||||
typedef void (*SQCOMPILERERROR)(HSQUIRRELVM,const SQChar * /*desc*/,const SQChar * /*source*/,SQInteger /*line*/,SQInteger /*column*/);
|
||||
typedef void (*SQPRINTFUNCTION)(HSQUIRRELVM,const SQChar * ,...);
|
||||
typedef void (*SQDEBUGHOOK)(HSQUIRRELVM /*v*/, SQInteger /*type*/, const SQChar * /*sourcename*/, SQInteger /*line*/, const SQChar * /*funcname*/);
|
||||
typedef SQInteger (*SQWRITEFUNC)(SQUserPointer,SQUserPointer,SQInteger);
|
||||
typedef SQInteger (*SQREADFUNC)(SQUserPointer,SQUserPointer,SQInteger);
|
||||
|
||||
typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer);
|
||||
|
||||
typedef struct tagSQRegFunction{
|
||||
const SQChar *name;
|
||||
SQFUNCTION f;
|
||||
SQInteger nparamscheck;
|
||||
const SQChar *typemask;
|
||||
}SQRegFunction;
|
||||
|
||||
typedef struct tagSQFunctionInfo {
|
||||
SQUserPointer funcid;
|
||||
const SQChar *name;
|
||||
const SQChar *source;
|
||||
SQInteger line;
|
||||
}SQFunctionInfo;
|
||||
|
||||
/*vm*/
|
||||
SQUIRREL_API HSQUIRRELVM sq_open(SQInteger initialstacksize);
|
||||
SQUIRREL_API HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize);
|
||||
SQUIRREL_API void sq_seterrorhandler(HSQUIRRELVM v);
|
||||
SQUIRREL_API void sq_close(HSQUIRRELVM v);
|
||||
SQUIRREL_API void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p);
|
||||
SQUIRREL_API SQUserPointer sq_getforeignptr(HSQUIRRELVM v);
|
||||
SQUIRREL_API void sq_setsharedforeignptr(HSQUIRRELVM v,SQUserPointer p);
|
||||
SQUIRREL_API SQUserPointer sq_getsharedforeignptr(HSQUIRRELVM v);
|
||||
SQUIRREL_API void sq_setvmreleasehook(HSQUIRRELVM v,SQRELEASEHOOK hook);
|
||||
SQUIRREL_API SQRELEASEHOOK sq_getvmreleasehook(HSQUIRRELVM v);
|
||||
SQUIRREL_API void sq_setsharedreleasehook(HSQUIRRELVM v,SQRELEASEHOOK hook);
|
||||
SQUIRREL_API SQRELEASEHOOK sq_getsharedreleasehook(HSQUIRRELVM v);
|
||||
SQUIRREL_API void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc,SQPRINTFUNCTION errfunc);
|
||||
SQUIRREL_API SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v);
|
||||
SQUIRREL_API SQPRINTFUNCTION sq_geterrorfunc(HSQUIRRELVM v);
|
||||
SQUIRREL_API SQRESULT sq_suspendvm(HSQUIRRELVM v);
|
||||
SQUIRREL_API SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool resumedret,SQBool retval,SQBool raiseerror,SQBool throwerror);
|
||||
SQUIRREL_API SQInteger sq_getvmstate(HSQUIRRELVM v);
|
||||
SQUIRREL_API SQInteger sq_getversion();
|
||||
|
||||
/*compiler*/
|
||||
SQUIRREL_API SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror);
|
||||
SQUIRREL_API SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror);
|
||||
SQUIRREL_API void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable);
|
||||
SQUIRREL_API void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable);
|
||||
SQUIRREL_API void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f);
|
||||
|
||||
/*stack operations*/
|
||||
SQUIRREL_API void sq_push(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API void sq_pop(HSQUIRRELVM v,SQInteger nelemstopop);
|
||||
SQUIRREL_API void sq_poptop(HSQUIRRELVM v);
|
||||
SQUIRREL_API void sq_remove(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQInteger sq_gettop(HSQUIRRELVM v);
|
||||
SQUIRREL_API void sq_settop(HSQUIRRELVM v,SQInteger newtop);
|
||||
SQUIRREL_API SQRESULT sq_reservestack(HSQUIRRELVM v,SQInteger nsize);
|
||||
SQUIRREL_API SQInteger sq_cmp(HSQUIRRELVM v);
|
||||
SQUIRREL_API void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx);
|
||||
|
||||
/*object creation handling*/
|
||||
SQUIRREL_API SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size);
|
||||
SQUIRREL_API void sq_newtable(HSQUIRRELVM v);
|
||||
SQUIRREL_API void sq_newtableex(HSQUIRRELVM v,SQInteger initialcapacity);
|
||||
SQUIRREL_API void sq_newarray(HSQUIRRELVM v,SQInteger size);
|
||||
SQUIRREL_API void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars);
|
||||
SQUIRREL_API SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask);
|
||||
SQUIRREL_API SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQRESULT sq_setclosureroot(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQRESULT sq_getclosureroot(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len);
|
||||
SQUIRREL_API void sq_pushfloat(HSQUIRRELVM v,SQFloat f);
|
||||
SQUIRREL_API void sq_pushinteger(HSQUIRRELVM v,SQInteger n);
|
||||
SQUIRREL_API void sq_pushbool(HSQUIRRELVM v,SQBool b);
|
||||
SQUIRREL_API void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p);
|
||||
SQUIRREL_API void sq_pushnull(HSQUIRRELVM v);
|
||||
SQUIRREL_API void sq_pushthread(HSQUIRRELVM v, HSQUIRRELVM thread);
|
||||
SQUIRREL_API SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQRESULT sq_typeof(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQInteger sq_getsize(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQHash sq_gethash(HSQUIRRELVM v, SQInteger idx);
|
||||
SQUIRREL_API SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQBool sq_instanceof(HSQUIRRELVM v);
|
||||
SQUIRREL_API SQRESULT sq_tostring(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b);
|
||||
SQUIRREL_API SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c);
|
||||
SQUIRREL_API SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i);
|
||||
SQUIRREL_API SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f);
|
||||
SQUIRREL_API SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b);
|
||||
SQUIRREL_API SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread);
|
||||
SQUIRREL_API SQRESULT sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p);
|
||||
SQUIRREL_API SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag);
|
||||
SQUIRREL_API SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag);
|
||||
SQUIRREL_API SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag);
|
||||
SQUIRREL_API void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook);
|
||||
SQUIRREL_API SQRELEASEHOOK sq_getreleasehook(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize);
|
||||
SQUIRREL_API SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger level,SQFunctionInfo *fi);
|
||||
SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars);
|
||||
SQUIRREL_API SQRESULT sq_getclosurename(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name);
|
||||
SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p);
|
||||
SQUIRREL_API SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag);
|
||||
SQUIRREL_API SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize);
|
||||
SQUIRREL_API SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase);
|
||||
SQUIRREL_API SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API void sq_weakref(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t);
|
||||
SQUIRREL_API SQRESULT sq_getmemberhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle);
|
||||
SQUIRREL_API SQRESULT sq_getbyhandle(HSQUIRRELVM v,SQInteger idx,const HSQMEMBERHANDLE *handle);
|
||||
SQUIRREL_API SQRESULT sq_setbyhandle(HSQUIRRELVM v,SQInteger idx,const HSQMEMBERHANDLE *handle);
|
||||
|
||||
/*object manipulation*/
|
||||
SQUIRREL_API void sq_pushroottable(HSQUIRRELVM v);
|
||||
SQUIRREL_API void sq_pushregistrytable(HSQUIRRELVM v);
|
||||
SQUIRREL_API void sq_pushconsttable(HSQUIRRELVM v);
|
||||
SQUIRREL_API SQRESULT sq_setroottable(HSQUIRRELVM v);
|
||||
SQUIRREL_API SQRESULT sq_setconsttable(HSQUIRRELVM v);
|
||||
SQUIRREL_API SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic);
|
||||
SQUIRREL_API SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
|
||||
SQUIRREL_API SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
|
||||
SQUIRREL_API SQRESULT sq_newmember(HSQUIRRELVM v,SQInteger idx,SQBool bstatic);
|
||||
SQUIRREL_API SQRESULT sq_rawnewmember(HSQUIRRELVM v,SQInteger idx,SQBool bstatic);
|
||||
SQUIRREL_API SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
|
||||
SQUIRREL_API SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize);
|
||||
SQUIRREL_API SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx);
|
||||
SQUIRREL_API SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos);
|
||||
SQUIRREL_API SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval);
|
||||
SQUIRREL_API SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx);
|
||||
SQUIRREL_API SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx);
|
||||
|
||||
/*calls*/
|
||||
SQUIRREL_API SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror);
|
||||
SQUIRREL_API SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror);
|
||||
SQUIRREL_API const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx);
|
||||
SQUIRREL_API SQRESULT sq_getcallee(HSQUIRRELVM v);
|
||||
SQUIRREL_API const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval);
|
||||
SQUIRREL_API SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err);
|
||||
SQUIRREL_API SQRESULT sq_throwobject(HSQUIRRELVM v);
|
||||
SQUIRREL_API void sq_reseterror(HSQUIRRELVM v);
|
||||
SQUIRREL_API void sq_getlasterror(HSQUIRRELVM v);
|
||||
|
||||
/*raw object handling*/
|
||||
SQUIRREL_API SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po);
|
||||
SQUIRREL_API void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj);
|
||||
SQUIRREL_API void sq_addref(HSQUIRRELVM v,HSQOBJECT *po);
|
||||
SQUIRREL_API SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po);
|
||||
SQUIRREL_API SQUnsignedInteger sq_getrefcount(HSQUIRRELVM v,HSQOBJECT *po);
|
||||
SQUIRREL_API void sq_resetobject(HSQOBJECT *po);
|
||||
SQUIRREL_API const SQChar *sq_objtostring(const HSQOBJECT *o);
|
||||
SQUIRREL_API SQBool sq_objtobool(const HSQOBJECT *o);
|
||||
SQUIRREL_API SQInteger sq_objtointeger(const HSQOBJECT *o);
|
||||
SQUIRREL_API SQFloat sq_objtofloat(const HSQOBJECT *o);
|
||||
SQUIRREL_API SQUserPointer sq_objtouserpointer(const HSQOBJECT *o);
|
||||
SQUIRREL_API SQRESULT sq_getobjtypetag(const HSQOBJECT *o,SQUserPointer * typetag);
|
||||
SQUIRREL_API SQUnsignedInteger sq_getvmrefcount(HSQUIRRELVM v, const HSQOBJECT *po);
|
||||
|
||||
|
||||
/*GC*/
|
||||
SQUIRREL_API SQInteger sq_collectgarbage(HSQUIRRELVM v);
|
||||
SQUIRREL_API SQRESULT sq_resurrectunreachable(HSQUIRRELVM v);
|
||||
|
||||
/*serialization*/
|
||||
SQUIRREL_API SQRESULT sq_writeclosure(HSQUIRRELVM vm,SQWRITEFUNC writef,SQUserPointer up);
|
||||
SQUIRREL_API SQRESULT sq_readclosure(HSQUIRRELVM vm,SQREADFUNC readf,SQUserPointer up);
|
||||
|
||||
/*mem allocation*/
|
||||
SQUIRREL_API void *sq_malloc(SQUnsignedInteger size);
|
||||
SQUIRREL_API void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize);
|
||||
SQUIRREL_API void sq_free(void *p,SQUnsignedInteger size);
|
||||
|
||||
/*debug*/
|
||||
SQUIRREL_API SQRESULT sq_stackinfos(HSQUIRRELVM v,SQInteger level,SQStackInfos *si);
|
||||
SQUIRREL_API void sq_setdebughook(HSQUIRRELVM v);
|
||||
SQUIRREL_API void sq_setnativedebughook(HSQUIRRELVM v,SQDEBUGHOOK hook);
|
||||
|
||||
/*UTILITY MACRO*/
|
||||
#define sq_isnumeric(o) ((o)._type&SQOBJECT_NUMERIC)
|
||||
#define sq_istable(o) ((o)._type==OT_TABLE)
|
||||
#define sq_isarray(o) ((o)._type==OT_ARRAY)
|
||||
#define sq_isfunction(o) ((o)._type==OT_FUNCPROTO)
|
||||
#define sq_isclosure(o) ((o)._type==OT_CLOSURE)
|
||||
#define sq_isgenerator(o) ((o)._type==OT_GENERATOR)
|
||||
#define sq_isnativeclosure(o) ((o)._type==OT_NATIVECLOSURE)
|
||||
#define sq_isstring(o) ((o)._type==OT_STRING)
|
||||
#define sq_isinteger(o) ((o)._type==OT_INTEGER)
|
||||
#define sq_isfloat(o) ((o)._type==OT_FLOAT)
|
||||
#define sq_isuserpointer(o) ((o)._type==OT_USERPOINTER)
|
||||
#define sq_isuserdata(o) ((o)._type==OT_USERDATA)
|
||||
#define sq_isthread(o) ((o)._type==OT_THREAD)
|
||||
#define sq_isnull(o) ((o)._type==OT_NULL)
|
||||
#define sq_isclass(o) ((o)._type==OT_CLASS)
|
||||
#define sq_isinstance(o) ((o)._type==OT_INSTANCE)
|
||||
#define sq_isbool(o) ((o)._type==OT_BOOL)
|
||||
#define sq_isweakref(o) ((o)._type==OT_WEAKREF)
|
||||
#define sq_type(o) ((o)._type)
|
||||
|
||||
/* deprecated */
|
||||
#define sq_createslot(v,n) sq_newslot(v,n,SQFalse)
|
||||
|
||||
#define SQ_OK (0)
|
||||
#define SQ_ERROR (-1)
|
||||
|
||||
#define SQ_FAILED(res) (res<0)
|
||||
#define SQ_SUCCEEDED(res) (res>=0)
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define SQ_UNUSED_ARG(x) __attribute__((unused)) x
|
||||
#else
|
||||
# define SQ_UNUSED_ARG(x) x
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*_SQUIRREL_H_*/
|
127
lutin_rabbit-core.py
Normal file
127
lutin_rabbit-core.py
Normal file
@@ -0,0 +1,127 @@
|
||||
#!/usr/bin/python
|
||||
import lutin.debug as debug
|
||||
import lutin.tools as tools
|
||||
import os
|
||||
|
||||
|
||||
def get_type():
|
||||
return "LIBRARY"
|
||||
|
||||
def get_desc():
|
||||
return "rabbit script interpreter"
|
||||
|
||||
def get_licence():
|
||||
return "MIT"
|
||||
|
||||
def get_compagny_type():
|
||||
return "org"
|
||||
|
||||
def get_compagny_name():
|
||||
return "rabbit"
|
||||
|
||||
def get_maintainer():
|
||||
return ["Edouard DUPIN <edupin@gmail.com>"]
|
||||
|
||||
def get_version():
|
||||
return [0,1]
|
||||
|
||||
def configure(target, my_module):
|
||||
my_module.add_src_file([
|
||||
'rabbit/Array.cpp',
|
||||
'rabbit/AutoDec.cpp',
|
||||
'rabbit/Class.cpp',
|
||||
'rabbit/ClassMember.cpp',
|
||||
'rabbit/Closure.cpp',
|
||||
'rabbit/Compiler.cpp',
|
||||
'rabbit/Delegable.cpp',
|
||||
'rabbit/ExceptionTrap.cpp',
|
||||
'rabbit/FuncState.cpp',
|
||||
'rabbit/FunctionInfo.cpp',
|
||||
'rabbit/FunctionProto.cpp',
|
||||
'rabbit/Generator.cpp',
|
||||
'rabbit/Hash.cpp',
|
||||
'rabbit/Instance.cpp',
|
||||
'rabbit/Instruction.cpp',
|
||||
'rabbit/Lexer.cpp',
|
||||
'rabbit/LineInfo.cpp',
|
||||
'rabbit/LocalVarInfo.cpp',
|
||||
'rabbit/MemberHandle.cpp',
|
||||
'rabbit/MetaMethod.cpp',
|
||||
'rabbit/NativeClosure.cpp',
|
||||
'rabbit/Object.cpp',
|
||||
'rabbit/ObjectPtr.cpp',
|
||||
'rabbit/ObjectType.cpp',
|
||||
'rabbit/ObjectValue.cpp',
|
||||
'rabbit/Outer.cpp',
|
||||
'rabbit/OuterVar.cpp',
|
||||
'rabbit/RefCounted.cpp',
|
||||
'rabbit/RefTable.cpp',
|
||||
'rabbit/RegFunction.cpp',
|
||||
'rabbit/SharedState.cpp',
|
||||
'rabbit/StackInfos.cpp',
|
||||
'rabbit/String.cpp',
|
||||
'rabbit/StringTable.cpp',
|
||||
'rabbit/Table.cpp',
|
||||
'rabbit/UserData.cpp',
|
||||
'rabbit/VirtualMachine.cpp',
|
||||
'rabbit/WeakRef.cpp',
|
||||
'rabbit/sqapi.cpp',
|
||||
'rabbit/sqbaselib.cpp',
|
||||
'rabbit/sqdebug.cpp',
|
||||
'rabbit/sqmem.cpp',
|
||||
])
|
||||
my_module.compile_version("c++", 2011)
|
||||
my_module.add_depend([
|
||||
'z',
|
||||
'm',
|
||||
'c',
|
||||
'etk-base',
|
||||
])
|
||||
my_module.add_header_file([
|
||||
'rabbit/Array.hpp',
|
||||
'rabbit/AutoDec.hpp',
|
||||
'rabbit/Class.hpp',
|
||||
'rabbit/ClassMember.hpp',
|
||||
'rabbit/Closure.hpp',
|
||||
'rabbit/Compiler.hpp',
|
||||
'rabbit/Delegable.hpp',
|
||||
'rabbit/ExceptionTrap.hpp',
|
||||
'rabbit/FuncState.hpp',
|
||||
'rabbit/FunctionInfo.hpp',
|
||||
'rabbit/FunctionProto.hpp',
|
||||
'rabbit/Generator.hpp',
|
||||
'rabbit/Hash.hpp',
|
||||
'rabbit/Instance.hpp',
|
||||
'rabbit/Instruction.hpp',
|
||||
'rabbit/Lexer.hpp',
|
||||
'rabbit/LineInfo.hpp',
|
||||
'rabbit/LocalVarInfo.hpp',
|
||||
'rabbit/MemberHandle.hpp',
|
||||
'rabbit/MetaMethod.hpp',
|
||||
'rabbit/NativeClosure.hpp',
|
||||
'rabbit/Object.hpp',
|
||||
'rabbit/ObjectPtr.hpp',
|
||||
'rabbit/ObjectType.hpp',
|
||||
'rabbit/ObjectValue.hpp',
|
||||
'rabbit/Outer.hpp',
|
||||
'rabbit/OuterVar.hpp',
|
||||
'rabbit/RefCounted.hpp',
|
||||
'rabbit/RefTable.hpp',
|
||||
'rabbit/RegFunction.hpp',
|
||||
'rabbit/SharedState.hpp',
|
||||
'rabbit/StackInfos.hpp',
|
||||
'rabbit/String.hpp',
|
||||
'rabbit/StringTable.hpp',
|
||||
'rabbit/Table.hpp',
|
||||
'rabbit/UserData.hpp',
|
||||
'rabbit/VirtualMachine.hpp',
|
||||
'rabbit/WeakRef.hpp',
|
||||
'rabbit/rabbit.hpp',
|
||||
'rabbit/sqconfig.hpp',
|
||||
'rabbit/sqopcodes.hpp',
|
||||
'rabbit/squtils.hpp',
|
||||
])
|
||||
|
||||
return True
|
||||
|
||||
|
55
lutin_rabbit-std.py
Normal file
55
lutin_rabbit-std.py
Normal file
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/python
|
||||
import lutin.debug as debug
|
||||
import lutin.tools as tools
|
||||
import os
|
||||
|
||||
|
||||
def get_type():
|
||||
return "LIBRARY"
|
||||
|
||||
def get_desc():
|
||||
return "rabbit script interpreter (std wrapping)"
|
||||
|
||||
def get_licence():
|
||||
return "MIT"
|
||||
|
||||
def get_compagny_type():
|
||||
return "org"
|
||||
|
||||
def get_compagny_name():
|
||||
return "rabbit"
|
||||
|
||||
def get_maintainer():
|
||||
return ["Edouard DUPIN <edupin@gmail.com>"]
|
||||
|
||||
def get_version():
|
||||
return [0,1]
|
||||
|
||||
def configure(target, my_module):
|
||||
my_module.add_src_file([
|
||||
'rabbit-std/sqstdaux.cpp',
|
||||
'rabbit-std/sqstdstream.cpp',
|
||||
'rabbit-std/sqstdrex.cpp',
|
||||
'rabbit-std/sqstdsystem.cpp',
|
||||
'rabbit-std/sqstdio.cpp',
|
||||
'rabbit-std/sqstdblob.cpp',
|
||||
'rabbit-std/sqstdmath.cpp',
|
||||
'rabbit-std/sqstdstring.cpp',
|
||||
])
|
||||
my_module.compile_version("c++", 2011)
|
||||
my_module.add_depend([
|
||||
'rabbit-core'
|
||||
])
|
||||
my_module.add_header_file([
|
||||
'rabbit-std/sqstdstring.hpp',
|
||||
'rabbit-std/sqstdmath.hpp',
|
||||
'rabbit-std/sqstdaux.hpp',
|
||||
'rabbit-std/sqstdsystem.hpp',
|
||||
'rabbit-std/sqstdblobimpl.hpp',
|
||||
'rabbit-std/sqstdstream.hpp',
|
||||
'rabbit-std/sqstdio.hpp',
|
||||
'rabbit-std/sqstdblob.hpp',
|
||||
])
|
||||
return True
|
||||
|
||||
|
40
lutin_rabbit.py
Normal file
40
lutin_rabbit.py
Normal file
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/python
|
||||
import lutin.debug as debug
|
||||
import lutin.tools as tools
|
||||
import os
|
||||
|
||||
|
||||
def get_type():
|
||||
return "BINARY"
|
||||
|
||||
def get_desc():
|
||||
return "rabbit command line interpreter"
|
||||
|
||||
def get_licence():
|
||||
return "MIT"
|
||||
|
||||
def get_compagny_type():
|
||||
return "org"
|
||||
|
||||
def get_compagny_name():
|
||||
return "rabbit"
|
||||
|
||||
def get_maintainer():
|
||||
return ["Edouard DUPIN <edupin@gmail.com>"]
|
||||
|
||||
def get_version():
|
||||
return [0,1]
|
||||
|
||||
def configure(target, my_module):
|
||||
my_module.add_src_file([
|
||||
'cmdLine/rabbit.cpp',
|
||||
])
|
||||
my_module.compile_version("c++", 2011)
|
||||
my_module.add_depend([
|
||||
'rabbit-core',
|
||||
'rabbit-std',
|
||||
'cxx',
|
||||
])
|
||||
return True
|
||||
|
||||
|
142
rabbit-std/sqstdaux.cpp
Normal file
142
rabbit-std/sqstdaux.cpp
Normal file
@@ -0,0 +1,142 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
|
||||
#include <rabbit/rabbit.hpp>
|
||||
#include <rabbit-std/sqstdaux.hpp>
|
||||
#include <assert.h>
|
||||
#include <rabbit/StackInfos.hpp>
|
||||
|
||||
void rabbit::std::printcallstack(rabbit::VirtualMachine* v)
|
||||
{
|
||||
SQPRINTFUNCTION pf = sq_geterrorfunc(v);
|
||||
if(pf) {
|
||||
rabbit::StackInfos si;
|
||||
int64_t i;
|
||||
float_t f;
|
||||
const char *s;
|
||||
int64_t level=1; //1 is to skip this function that is level 0
|
||||
const char *name=0;
|
||||
int64_t seq=0;
|
||||
pf(v,"\nCALLSTACK\n");
|
||||
while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si)))
|
||||
{
|
||||
const char *fn="unknown";
|
||||
const char *src="unknown";
|
||||
if(si.funcname)fn=si.funcname;
|
||||
if(si.source)src=si.source;
|
||||
pf(v,"*FUNCTION [%s()] %s line [%d]\n",fn,src,si.line);
|
||||
level++;
|
||||
}
|
||||
level=0;
|
||||
pf(v,"\nLOCALS\n");
|
||||
|
||||
for(level=0;level<10;level++){
|
||||
seq=0;
|
||||
while((name = sq_getlocal(v,level,seq)))
|
||||
{
|
||||
seq++;
|
||||
switch(sq_gettype(v,-1))
|
||||
{
|
||||
case rabbit::OT_NULL:
|
||||
pf(v,"[%s] NULL\n",name);
|
||||
break;
|
||||
case rabbit::OT_INTEGER:
|
||||
sq_getinteger(v,-1,&i);
|
||||
pf(v,"[%s] %d\n",name,i);
|
||||
break;
|
||||
case rabbit::OT_FLOAT:
|
||||
sq_getfloat(v,-1,&f);
|
||||
pf(v,"[%s] %.14g\n",name,f);
|
||||
break;
|
||||
case rabbit::OT_USERPOINTER:
|
||||
pf(v,"[%s] USERPOINTER\n",name);
|
||||
break;
|
||||
case rabbit::OT_STRING:
|
||||
sq_getstring(v,-1,&s);
|
||||
pf(v,"[%s] \"%s\"\n",name,s);
|
||||
break;
|
||||
case rabbit::OT_TABLE:
|
||||
pf(v,"[%s] TABLE\n",name);
|
||||
break;
|
||||
case rabbit::OT_ARRAY:
|
||||
pf(v,"[%s] ARRAY\n",name);
|
||||
break;
|
||||
case rabbit::OT_CLOSURE:
|
||||
pf(v,"[%s] CLOSURE\n",name);
|
||||
break;
|
||||
case rabbit::OT_NATIVECLOSURE:
|
||||
pf(v,"[%s] NATIVECLOSURE\n",name);
|
||||
break;
|
||||
case rabbit::OT_GENERATOR:
|
||||
pf(v,"[%s] GENERATOR\n",name);
|
||||
break;
|
||||
case rabbit::OT_USERDATA:
|
||||
pf(v,"[%s] USERDATA\n",name);
|
||||
break;
|
||||
case rabbit::OT_THREAD:
|
||||
pf(v,"[%s] THREAD\n",name);
|
||||
break;
|
||||
case rabbit::OT_CLASS:
|
||||
pf(v,"[%s] CLASS\n",name);
|
||||
break;
|
||||
case rabbit::OT_INSTANCE:
|
||||
pf(v,"[%s] INSTANCE\n",name);
|
||||
break;
|
||||
case rabbit::OT_WEAKREF:
|
||||
pf(v,"[%s] WEAKREF\n",name);
|
||||
break;
|
||||
case rabbit::OT_BOOL:
|
||||
{
|
||||
rabbit::Bool bval;
|
||||
sq_getbool(v,-1,&bval);
|
||||
pf(v,"[%s] %s\n",name,bval == SQTrue ? "true":"false");
|
||||
}
|
||||
break;
|
||||
default: assert(0); break;
|
||||
}
|
||||
sq_pop(v,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace rabbit {
|
||||
namespace std {
|
||||
static int64_t aux_printerror(rabbit::VirtualMachine* v) {
|
||||
SQPRINTFUNCTION pf = sq_geterrorfunc(v);
|
||||
if(pf) {
|
||||
const char *sErr = 0;
|
||||
if(sq_gettop(v)>=1) {
|
||||
if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) {
|
||||
pf(v,"\nAN ERROR HAS OCCURRED [%s]\n",sErr);
|
||||
}
|
||||
else{
|
||||
pf(v,"\nAN ERROR HAS OCCURRED [unknown]\n");
|
||||
}
|
||||
rabbit::std::printcallstack(v);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void compiler_error(rabbit::VirtualMachine* v,const char *sErr,const char *sSource,int64_t line,int64_t column) {
|
||||
SQPRINTFUNCTION pf = sq_geterrorfunc(v);
|
||||
if(pf) {
|
||||
pf(v,"%s line = (%d) column = (%d) : error %s\n",sSource,line,column,sErr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rabbit::std::seterrorhandlers(rabbit::VirtualMachine* v)
|
||||
{
|
||||
sq_setcompilererrorhandler(v,rabbit::std::compiler_error);
|
||||
sq_newclosure(v,rabbit::std::aux_printerror,0);
|
||||
sq_seterrorhandler(v);
|
||||
}
|
16
rabbit-std/sqstdaux.hpp
Normal file
16
rabbit-std/sqstdaux.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace rabbit {
|
||||
namespace std {
|
||||
void seterrorhandlers(rabbit::VirtualMachine* v);
|
||||
void printcallstack(rabbit::VirtualMachine* v);
|
||||
}
|
||||
}
|
||||
|
281
rabbit-std/sqstdblob.cpp
Normal file
281
rabbit-std/sqstdblob.cpp
Normal file
@@ -0,0 +1,281 @@
|
||||
/* see copyright notice in rabbit.hpp */
|
||||
#include <new>
|
||||
#include <rabbit/rabbit.hpp>
|
||||
#include <rabbit-std/sqstdio.hpp>
|
||||
#include <string.h>
|
||||
#include <rabbit-std/sqstdblob.hpp>
|
||||
#include <rabbit-std/sqstdstream.hpp>
|
||||
#include <rabbit-std/sqstdblobimpl.hpp>
|
||||
|
||||
#define SQSTD_BLOB_TYPE_TAG ((uint64_t)(SQSTD_STREAM_TYPE_TAG | 0x00000002))
|
||||
|
||||
//Blob
|
||||
|
||||
|
||||
#define SETUP_BLOB(v) \
|
||||
rabbit::std::Blob *self = NULL; \
|
||||
{ if(SQ_FAILED(rabbit::sq_getinstanceup(v,1,(rabbit::UserPointer*)&self,(rabbit::UserPointer)SQSTD_BLOB_TYPE_TAG))) \
|
||||
return rabbit::sq_throwerror(v,"invalid type tag"); } \
|
||||
if(!self || !self->IsValid()) \
|
||||
return rabbit::sq_throwerror(v,"the blob is invalid");
|
||||
|
||||
|
||||
static int64_t _blob_resize(rabbit::VirtualMachine* v)
|
||||
{
|
||||
SETUP_BLOB(v);
|
||||
int64_t size;
|
||||
rabbit::sq_getinteger(v,2,&size);
|
||||
if(!self->resize(size))
|
||||
return rabbit::sq_throwerror(v,"resize failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __swap_dword(unsigned int *n)
|
||||
{
|
||||
*n=(unsigned int)(((*n&0xFF000000)>>24) |
|
||||
((*n&0x00FF0000)>>8) |
|
||||
((*n&0x0000FF00)<<8) |
|
||||
((*n&0x000000FF)<<24));
|
||||
}
|
||||
|
||||
static void __swap_word(unsigned short *n)
|
||||
{
|
||||
*n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00);
|
||||
}
|
||||
|
||||
static int64_t _blob_swap4(rabbit::VirtualMachine* v)
|
||||
{
|
||||
SETUP_BLOB(v);
|
||||
int64_t num=(self->Len()-(self->Len()%4))>>2;
|
||||
unsigned int *t=(unsigned int *)self->getBuf();
|
||||
for(int64_t i = 0; i < num; i++) {
|
||||
__swap_dword(&t[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int64_t _blob_swap2(rabbit::VirtualMachine* v)
|
||||
{
|
||||
SETUP_BLOB(v);
|
||||
int64_t num=(self->Len()-(self->Len()%2))>>1;
|
||||
unsigned short *t = (unsigned short *)self->getBuf();
|
||||
for(int64_t i = 0; i < num; i++) {
|
||||
__swap_word(&t[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int64_t _blob__set(rabbit::VirtualMachine* v)
|
||||
{
|
||||
SETUP_BLOB(v);
|
||||
int64_t idx,val;
|
||||
rabbit::sq_getinteger(v,2,&idx);
|
||||
rabbit::sq_getinteger(v,3,&val);
|
||||
if(idx < 0 || idx >= self->Len())
|
||||
return rabbit::sq_throwerror(v,"index out of range");
|
||||
((unsigned char *)self->getBuf())[idx] = (unsigned char) val;
|
||||
rabbit::sq_push(v,3);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int64_t _blob__get(rabbit::VirtualMachine* v)
|
||||
{
|
||||
SETUP_BLOB(v);
|
||||
int64_t idx;
|
||||
|
||||
if ((rabbit::sq_gettype(v, 2) & SQOBJECT_NUMERIC) == 0)
|
||||
{
|
||||
rabbit::sq_pushnull(v);
|
||||
return rabbit::sq_throwobject(v);
|
||||
}
|
||||
rabbit::sq_getinteger(v,2,&idx);
|
||||
if(idx < 0 || idx >= self->Len())
|
||||
return rabbit::sq_throwerror(v,"index out of range");
|
||||
rabbit::sq_pushinteger(v,((unsigned char *)self->getBuf())[idx]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int64_t _blob__nexti(rabbit::VirtualMachine* v)
|
||||
{
|
||||
SETUP_BLOB(v);
|
||||
if(rabbit::sq_gettype(v,2) == rabbit::OT_NULL) {
|
||||
rabbit::sq_pushinteger(v, 0);
|
||||
return 1;
|
||||
}
|
||||
int64_t idx;
|
||||
if(SQ_SUCCEEDED(rabbit::sq_getinteger(v, 2, &idx))) {
|
||||
if(idx+1 < self->Len()) {
|
||||
rabbit::sq_pushinteger(v, idx+1);
|
||||
return 1;
|
||||
}
|
||||
rabbit::sq_pushnull(v);
|
||||
return 1;
|
||||
}
|
||||
return rabbit::sq_throwerror(v,"internal error (_nexti) wrong argument type");
|
||||
}
|
||||
|
||||
static int64_t _blob__typeof(rabbit::VirtualMachine* v)
|
||||
{
|
||||
rabbit::sq_pushstring(v,"blob",-1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int64_t _blob_releasehook(rabbit::UserPointer p, int64_t SQ_UNUSED_ARG(size))
|
||||
{
|
||||
rabbit::std::Blob *self = (rabbit::std::Blob*)p;
|
||||
self->~Blob();
|
||||
rabbit::sq_free(self,sizeof(rabbit::std::Blob));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int64_t _blob_constructor(rabbit::VirtualMachine* v)
|
||||
{
|
||||
int64_t nparam = rabbit::sq_gettop(v);
|
||||
int64_t size = 0;
|
||||
if(nparam == 2) {
|
||||
rabbit::sq_getinteger(v, 2, &size);
|
||||
}
|
||||
if(size < 0) return rabbit::sq_throwerror(v, "cannot create blob with negative size");
|
||||
//rabbit::std::Blob *b = new rabbit::std::Blob(size);
|
||||
|
||||
rabbit::std::Blob *b = ETK_NEW(rabbit::std::Blob, size);
|
||||
if(SQ_FAILED(rabbit::sq_setinstanceup(v,1,b))) {
|
||||
ETK_FREE(rabbit::std::Blob, b);
|
||||
return rabbit::sq_throwerror(v, "cannot create blob");
|
||||
}
|
||||
rabbit::sq_setreleasehook(v,1,_blob_releasehook);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int64_t _blob__cloned(rabbit::VirtualMachine* v)
|
||||
{
|
||||
rabbit::std::Blob *other = NULL;
|
||||
{
|
||||
if(SQ_FAILED(rabbit::sq_getinstanceup(v,2,(rabbit::UserPointer*)&other,(rabbit::UserPointer)SQSTD_BLOB_TYPE_TAG)))
|
||||
return SQ_ERROR;
|
||||
}
|
||||
//rabbit::std::Blob *thisone = new rabbit::std::Blob(other->Len());
|
||||
rabbit::std::Blob *thisone = ETK_NEW(rabbit::std::Blob, other->Len());
|
||||
memcpy(thisone->getBuf(),other->getBuf(),thisone->Len());
|
||||
if(SQ_FAILED(rabbit::sq_setinstanceup(v,1,thisone))) {
|
||||
ETK_FREE(rabbit::std::Blob, thisone);
|
||||
return rabbit::sq_throwerror(v, "cannot clone blob");
|
||||
}
|
||||
rabbit::sq_setreleasehook(v,1,_blob_releasehook);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define _DECL_BLOB_FUNC(name,nparams,typecheck) {#name,_blob_##name,nparams,typecheck}
|
||||
static const rabbit::RegFunction _blob_methods[] = {
|
||||
_DECL_BLOB_FUNC(constructor,-1,"xn"),
|
||||
_DECL_BLOB_FUNC(resize,2,"xn"),
|
||||
_DECL_BLOB_FUNC(swap2,1,"x"),
|
||||
_DECL_BLOB_FUNC(swap4,1,"x"),
|
||||
_DECL_BLOB_FUNC(_set,3,"xnn"),
|
||||
_DECL_BLOB_FUNC(_get,2,"x."),
|
||||
_DECL_BLOB_FUNC(_typeof,1,"x"),
|
||||
_DECL_BLOB_FUNC(_nexti,2,"x"),
|
||||
_DECL_BLOB_FUNC(_cloned,2,"xx"),
|
||||
{NULL,(SQFUNCTION)0,0,NULL}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//GLOBAL FUNCTIONS
|
||||
|
||||
static int64_t _g_blob_casti2f(rabbit::VirtualMachine* v)
|
||||
{
|
||||
int64_t i;
|
||||
rabbit::sq_getinteger(v,2,&i);
|
||||
rabbit::sq_pushfloat(v,*((const float_t *)&i));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int64_t _g_blob_castf2i(rabbit::VirtualMachine* v)
|
||||
{
|
||||
float_t f;
|
||||
rabbit::sq_getfloat(v,2,&f);
|
||||
rabbit::sq_pushinteger(v,*((const int64_t *)&f));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int64_t _g_blob_swap2(rabbit::VirtualMachine* v)
|
||||
{
|
||||
int64_t i;
|
||||
rabbit::sq_getinteger(v,2,&i);
|
||||
short s=(short)i;
|
||||
rabbit::sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int64_t _g_blob_swap4(rabbit::VirtualMachine* v)
|
||||
{
|
||||
int64_t i;
|
||||
rabbit::sq_getinteger(v,2,&i);
|
||||
unsigned int t4 = (unsigned int)i;
|
||||
__swap_dword(&t4);
|
||||
rabbit::sq_pushinteger(v,(int64_t)t4);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int64_t _g_blob_swapfloat(rabbit::VirtualMachine* v)
|
||||
{
|
||||
float_t f;
|
||||
rabbit::sq_getfloat(v,2,&f);
|
||||
__swap_dword((unsigned int *)&f);
|
||||
rabbit::sq_pushfloat(v,f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {#name,_g_blob_##name,nparams,typecheck}
|
||||
static const rabbit::RegFunction bloblib_funcs[]={
|
||||
_DECL_GLOBALBLOB_FUNC(casti2f,2,".n"),
|
||||
_DECL_GLOBALBLOB_FUNC(castf2i,2,".n"),
|
||||
_DECL_GLOBALBLOB_FUNC(swap2,2,".n"),
|
||||
_DECL_GLOBALBLOB_FUNC(swap4,2,".n"),
|
||||
_DECL_GLOBALBLOB_FUNC(swapfloat,2,".n"),
|
||||
{NULL,(SQFUNCTION)0,0,NULL}
|
||||
};
|
||||
|
||||
rabbit::Result rabbit::std::getblob(rabbit::VirtualMachine* v,int64_t idx,rabbit::UserPointer *ptr)
|
||||
{
|
||||
rabbit::std::Blob *blob;
|
||||
if(SQ_FAILED(rabbit::sq_getinstanceup(v,idx,(rabbit::UserPointer *)&blob,(rabbit::UserPointer)SQSTD_BLOB_TYPE_TAG)))
|
||||
return -1;
|
||||
*ptr = blob->getBuf();
|
||||
return SQ_OK;
|
||||
}
|
||||
|
||||
int64_t rabbit::std::getblobsize(rabbit::VirtualMachine* v,int64_t idx)
|
||||
{
|
||||
rabbit::std::Blob *blob;
|
||||
if(SQ_FAILED(rabbit::sq_getinstanceup(v,idx,(rabbit::UserPointer *)&blob,(rabbit::UserPointer)SQSTD_BLOB_TYPE_TAG)))
|
||||
return -1;
|
||||
return blob->Len();
|
||||
}
|
||||
|
||||
rabbit::UserPointer rabbit::std::createblob(rabbit::VirtualMachine* v, int64_t size)
|
||||
{
|
||||
int64_t top = rabbit::sq_gettop(v);
|
||||
rabbit::sq_pushregistrytable(v);
|
||||
rabbit::sq_pushstring(v,"std_blob",-1);
|
||||
if(SQ_SUCCEEDED(rabbit::sq_get(v,-2))) {
|
||||
rabbit::sq_remove(v,-2); //removes the registry
|
||||
rabbit::sq_push(v,1); // push the this
|
||||
rabbit::sq_pushinteger(v,size); //size
|
||||
rabbit::std::Blob *blob = NULL;
|
||||
if(SQ_SUCCEEDED(rabbit::sq_call(v,2,SQTrue,SQFalse))
|
||||
&& SQ_SUCCEEDED(rabbit::sq_getinstanceup(v,-1,(rabbit::UserPointer *)&blob,(rabbit::UserPointer)SQSTD_BLOB_TYPE_TAG))) {
|
||||
rabbit::sq_remove(v,-2);
|
||||
return blob->getBuf();
|
||||
}
|
||||
}
|
||||
rabbit::sq_settop(v,top);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rabbit::Result rabbit::std::register_bloblib(rabbit::VirtualMachine* v)
|
||||
{
|
||||
return declare_stream(v,"blob",(rabbit::UserPointer)SQSTD_BLOB_TYPE_TAG,"std_blob",_blob_methods,bloblib_funcs);
|
||||
}
|
||||
|
19
rabbit-std/sqstdblob.hpp
Normal file
19
rabbit-std/sqstdblob.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace rabbit {
|
||||
namespace std {
|
||||
rabbit::UserPointer createblob(rabbit::VirtualMachine* v, int64_t size);
|
||||
rabbit::Result getblob(rabbit::VirtualMachine* v,int64_t idx,rabbit::UserPointer *ptr);
|
||||
int64_t getblobsize(rabbit::VirtualMachine* v,int64_t idx);
|
||||
|
||||
rabbit::Result register_bloblib(rabbit::VirtualMachine* v);
|
||||
|
||||
}
|
||||
}
|
116
rabbit-std/sqstdblobimpl.hpp
Normal file
116
rabbit-std/sqstdblobimpl.hpp
Normal file
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace rabbit {
|
||||
namespace std {
|
||||
struct Blob : public SQStream
|
||||
{
|
||||
Blob(int64_t size) {
|
||||
_size = size;
|
||||
_allocated = size;
|
||||
_buf = (unsigned char *)sq_malloc(size);
|
||||
memset(_buf, 0, _size);
|
||||
_ptr = 0;
|
||||
_owns = true;
|
||||
}
|
||||
virtual ~Blob() {
|
||||
sq_free(_buf, _allocated);
|
||||
}
|
||||
int64_t Write(void *buffer, int64_t size) {
|
||||
if(!CanAdvance(size)) {
|
||||
GrowBufOf(_ptr + size - _size);
|
||||
}
|
||||
memcpy(&_buf[_ptr], buffer, size);
|
||||
_ptr += size;
|
||||
return size;
|
||||
}
|
||||
int64_t Read(void *buffer,int64_t size) {
|
||||
int64_t n = size;
|
||||
if(!CanAdvance(size)) {
|
||||
if((_size - _ptr) > 0)
|
||||
n = _size - _ptr;
|
||||
else return 0;
|
||||
}
|
||||
memcpy(buffer, &_buf[_ptr], n);
|
||||
_ptr += n;
|
||||
return n;
|
||||
}
|
||||
bool resize(int64_t n) {
|
||||
if(!_owns) return false;
|
||||
if(n != _allocated) {
|
||||
unsigned char *newbuf = (unsigned char *)sq_malloc(n);
|
||||
memset(newbuf,0,n);
|
||||
if(_size > n)
|
||||
memcpy(newbuf,_buf,n);
|
||||
else
|
||||
memcpy(newbuf,_buf,_size);
|
||||
sq_free(_buf,_allocated);
|
||||
_buf=newbuf;
|
||||
_allocated = n;
|
||||
if(_size > _allocated)
|
||||
_size = _allocated;
|
||||
if(_ptr > _allocated)
|
||||
_ptr = _allocated;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool GrowBufOf(int64_t n)
|
||||
{
|
||||
bool ret = true;
|
||||
if(_size + n > _allocated) {
|
||||
if(_size + n > _size * 2)
|
||||
ret = resize(_size + n);
|
||||
else
|
||||
ret = resize(_size * 2);
|
||||
}
|
||||
_size = _size + n;
|
||||
return ret;
|
||||
}
|
||||
bool CanAdvance(int64_t n) {
|
||||
if(_ptr+n>_size)return false;
|
||||
return true;
|
||||
}
|
||||
int64_t Seek(int64_t offset, int64_t origin) {
|
||||
switch(origin) {
|
||||
case SQ_SEEK_SET:
|
||||
if(offset > _size || offset < 0) return -1;
|
||||
_ptr = offset;
|
||||
break;
|
||||
case SQ_SEEK_CUR:
|
||||
if(_ptr + offset > _size || _ptr + offset < 0) return -1;
|
||||
_ptr += offset;
|
||||
break;
|
||||
case SQ_SEEK_END:
|
||||
if(_size + offset > _size || _size + offset < 0) return -1;
|
||||
_ptr = _size + offset;
|
||||
break;
|
||||
default: return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
bool IsValid() {
|
||||
return _size == 0 || _buf?true:false;
|
||||
}
|
||||
bool EOS() {
|
||||
return _ptr == _size;
|
||||
}
|
||||
int64_t Flush() { return 0; }
|
||||
int64_t Tell() { return _ptr; }
|
||||
int64_t Len() { return _size; }
|
||||
rabbit::UserPointer getBuf(){ return _buf; }
|
||||
private:
|
||||
int64_t _size;
|
||||
int64_t _allocated;
|
||||
int64_t _ptr;
|
||||
unsigned char *_buf;
|
||||
bool _owns;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
450
rabbit-std/sqstdio.cpp
Normal file
450
rabbit-std/sqstdio.cpp
Normal file
@@ -0,0 +1,450 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
|
||||
#include <new>
|
||||
#include <stdio.h>
|
||||
#include <rabbit/rabbit.hpp>
|
||||
#include <rabbit-std/sqstdio.hpp>
|
||||
#include <rabbit-std/sqstdstream.hpp>
|
||||
|
||||
#define SQSTD_FILE_TYPE_TAG ((uint64_t)(SQSTD_STREAM_TYPE_TAG | 0x00000001))
|
||||
//basic API
|
||||
rabbit::std::SQFILE rabbit::std::fopen(const char *filename ,const char *mode)
|
||||
{
|
||||
return (SQFILE)::fopen(filename,mode);
|
||||
}
|
||||
|
||||
int64_t rabbit::std::fread(void* buffer, int64_t size, int64_t count, SQFILE file)
|
||||
{
|
||||
int64_t ret = (int64_t)::fread(buffer,size,count,(FILE *)file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t rabbit::std::fwrite(const rabbit::UserPointer buffer, int64_t size, int64_t count, SQFILE file)
|
||||
{
|
||||
return (int64_t)::fwrite(buffer,size,count,(FILE *)file);
|
||||
}
|
||||
|
||||
int64_t rabbit::std::fseek(SQFILE file, int64_t offset, int64_t origin)
|
||||
{
|
||||
int64_t realorigin;
|
||||
switch(origin) {
|
||||
case SQ_SEEK_CUR: realorigin = SEEK_CUR; break;
|
||||
case SQ_SEEK_END: realorigin = SEEK_END; break;
|
||||
case SQ_SEEK_SET: realorigin = SEEK_SET; break;
|
||||
default: return -1; //failed
|
||||
}
|
||||
return ::fseek((FILE *)file,(long)offset,(int)realorigin);
|
||||
}
|
||||
|
||||
int64_t rabbit::std::ftell(SQFILE file)
|
||||
{
|
||||
return ::ftell((FILE *)file);
|
||||
}
|
||||
|
||||
int64_t rabbit::std::fflush(SQFILE file)
|
||||
{
|
||||
return ::fflush((FILE *)file);
|
||||
}
|
||||
|
||||
int64_t rabbit::std::fclose(SQFILE file)
|
||||
{
|
||||
return ::fclose((FILE *)file);
|
||||
}
|
||||
|
||||
int64_t rabbit::std::feof(SQFILE file)
|
||||
{
|
||||
return ::feof((FILE *)file);
|
||||
}
|
||||
namespace rabbit {
|
||||
|
||||
namespace std {
|
||||
//File
|
||||
struct File : public rabbit::std::SQStream {
|
||||
File() { _handle = NULL; _owns = false;}
|
||||
File(SQFILE file, bool owns) { _handle = file; _owns = owns;}
|
||||
virtual ~File() { close(); }
|
||||
bool Open(const char *filename ,const char *mode) {
|
||||
close();
|
||||
if( (_handle = rabbit::std::fopen(filename,mode)) ) {
|
||||
_owns = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void close() {
|
||||
if(_handle && _owns) {
|
||||
rabbit::std::fclose(_handle);
|
||||
_handle = NULL;
|
||||
_owns = false;
|
||||
}
|
||||
}
|
||||
int64_t Read(void *buffer,int64_t size) {
|
||||
return rabbit::std::fread(buffer,1,size,_handle);
|
||||
}
|
||||
int64_t Write(void *buffer,int64_t size) {
|
||||
return rabbit::std::fwrite(buffer,1,size,_handle);
|
||||
}
|
||||
int64_t Flush() {
|
||||
return rabbit::std::fflush(_handle);
|
||||
}
|
||||
int64_t Tell() {
|
||||
return rabbit::std::ftell(_handle);
|
||||
}
|
||||
int64_t Len() {
|
||||
int64_t prevpos=Tell();
|
||||
Seek(0,SQ_SEEK_END);
|
||||
int64_t size=Tell();
|
||||
Seek(prevpos,SQ_SEEK_SET);
|
||||
return size;
|
||||
}
|
||||
int64_t Seek(int64_t offset, int64_t origin) {
|
||||
return rabbit::std::fseek(_handle,offset,origin);
|
||||
}
|
||||
bool IsValid() { return _handle?true:false; }
|
||||
bool EOS() { return Tell()==Len()?true:false;}
|
||||
SQFILE getHandle() {return _handle;}
|
||||
private:
|
||||
SQFILE _handle;
|
||||
bool _owns;
|
||||
};
|
||||
}
|
||||
}
|
||||
static int64_t _file__typeof(rabbit::VirtualMachine* v)
|
||||
{
|
||||
sq_pushstring(v,"file",-1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int64_t _file_releasehook(rabbit::UserPointer p, int64_t SQ_UNUSED_ARG(size))
|
||||
{
|
||||
rabbit::std::File *self = (rabbit::std::File*)p;
|
||||
self->~File();
|
||||
rabbit::sq_free(self,sizeof(rabbit::std::File));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int64_t _file_constructor(rabbit::VirtualMachine* v)
|
||||
{
|
||||
const char *filename,*mode;
|
||||
bool owns = true;
|
||||
rabbit::std::File *f;
|
||||
rabbit::std::SQFILE newf;
|
||||
if(rabbit::sq_gettype(v,2) == rabbit::OT_STRING && sq_gettype(v,3) == rabbit::OT_STRING) {
|
||||
rabbit::sq_getstring(v, 2, &filename);
|
||||
rabbit::sq_getstring(v, 3, &mode);
|
||||
newf = rabbit::std::fopen(filename, mode);
|
||||
if(!newf) return rabbit::sq_throwerror(v, "cannot open file");
|
||||
} else if(rabbit::sq_gettype(v,2) == rabbit::OT_USERPOINTER) {
|
||||
owns = !(rabbit::sq_gettype(v,3) == rabbit::OT_NULL);
|
||||
rabbit::sq_getuserpointer(v,2,&newf);
|
||||
} else {
|
||||
return rabbit::sq_throwerror(v,"wrong parameter");
|
||||
}
|
||||
|
||||
f = ETK_NEW(rabbit::std::File, newf, owns);
|
||||
if(SQ_FAILED(rabbit::sq_setinstanceup(v, 1, f))) {
|
||||
ETK_DELETE(rabbit::std::File, f);
|
||||
return rabbit::sq_throwerror(v, "cannot create blob with negative size");
|
||||
}
|
||||
rabbit::sq_setreleasehook(v, 1, _file_releasehook);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int64_t _file_close(rabbit::VirtualMachine* v)
|
||||
{
|
||||
rabbit::std::File *self = NULL;
|
||||
if(SQ_SUCCEEDED(rabbit::sq_getinstanceup(v,1,(rabbit::UserPointer*)&self,(rabbit::UserPointer)SQSTD_FILE_TYPE_TAG))
|
||||
&& self != NULL)
|
||||
{
|
||||
self->close();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//bindings
|
||||
#define _DECL_FILE_FUNC(name,nparams,typecheck) {#name,_file_##name,nparams,typecheck}
|
||||
static const rabbit::RegFunction _file_methods[] = {
|
||||
_DECL_FILE_FUNC(constructor,3,"x"),
|
||||
_DECL_FILE_FUNC(_typeof,1,"x"),
|
||||
_DECL_FILE_FUNC(close,1,"x"),
|
||||
{NULL,(SQFUNCTION)0,0,NULL}
|
||||
};
|
||||
|
||||
|
||||
|
||||
rabbit::Result rabbit::std::createfile(rabbit::VirtualMachine* v, SQFILE file,rabbit::Bool own)
|
||||
{
|
||||
int64_t top = sq_gettop(v);
|
||||
sq_pushregistrytable(v);
|
||||
sq_pushstring(v,"std_file",-1);
|
||||
if(SQ_SUCCEEDED(sq_get(v,-2))) {
|
||||
sq_remove(v,-2); //removes the registry
|
||||
sq_pushroottable(v); // push the this
|
||||
sq_pushuserpointer(v,file); //file
|
||||
if(own){
|
||||
sq_pushinteger(v,1); //true
|
||||
}
|
||||
else{
|
||||
sq_pushnull(v); //false
|
||||
}
|
||||
if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) {
|
||||
sq_remove(v,-2);
|
||||
return SQ_OK;
|
||||
}
|
||||
}
|
||||
sq_settop(v,top);
|
||||
return SQ_ERROR;
|
||||
}
|
||||
|
||||
rabbit::Result rabbit::std::getfile(rabbit::VirtualMachine* v, int64_t idx, SQFILE *file)
|
||||
{
|
||||
rabbit::std::File *fileobj = NULL;
|
||||
if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(rabbit::UserPointer*)&fileobj,(rabbit::UserPointer)SQSTD_FILE_TYPE_TAG))) {
|
||||
*file = fileobj->getHandle();
|
||||
return SQ_OK;
|
||||
}
|
||||
return sq_throwerror(v,"not a file");
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define IO_BUFFER_SIZE 2048
|
||||
struct IOBuffer {
|
||||
unsigned char buffer[IO_BUFFER_SIZE];
|
||||
int64_t size;
|
||||
int64_t ptr;
|
||||
rabbit::std::SQFILE file;
|
||||
};
|
||||
|
||||
int64_t _read_byte(IOBuffer *iobuffer)
|
||||
{
|
||||
if(iobuffer->ptr < iobuffer->size) {
|
||||
|
||||
int64_t ret = iobuffer->buffer[iobuffer->ptr];
|
||||
iobuffer->ptr++;
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
if( (iobuffer->size = rabbit::std::fread(iobuffer->buffer,1,IO_BUFFER_SIZE,iobuffer->file )) > 0 )
|
||||
{
|
||||
int64_t ret = iobuffer->buffer[0];
|
||||
iobuffer->ptr = 1;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t _read_two_bytes(IOBuffer *iobuffer)
|
||||
{
|
||||
if(iobuffer->ptr < iobuffer->size) {
|
||||
if(iobuffer->size < 2) return 0;
|
||||
int64_t ret = *((const wchar_t*)&iobuffer->buffer[iobuffer->ptr]);
|
||||
iobuffer->ptr += 2;
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
if( (iobuffer->size = rabbit::std::fread(iobuffer->buffer,1,IO_BUFFER_SIZE,iobuffer->file )) > 0 )
|
||||
{
|
||||
if(iobuffer->size < 2) return 0;
|
||||
int64_t ret = *((const wchar_t*)&iobuffer->buffer[0]);
|
||||
iobuffer->ptr = 2;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int64_t _io_file_lexfeed_PLAIN(rabbit::UserPointer iobuf)
|
||||
{
|
||||
IOBuffer *iobuffer = (IOBuffer *)iobuf;
|
||||
return _read_byte(iobuffer);
|
||||
|
||||
}
|
||||
|
||||
static int64_t _io_file_lexfeed_UCS2_LE(rabbit::UserPointer iobuf)
|
||||
{
|
||||
int64_t ret;
|
||||
IOBuffer *iobuffer = (IOBuffer *)iobuf;
|
||||
if( (ret = _read_two_bytes(iobuffer)) > 0 )
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int64_t _io_file_lexfeed_UCS2_BE(rabbit::UserPointer iobuf)
|
||||
{
|
||||
int64_t c;
|
||||
IOBuffer *iobuffer = (IOBuffer *)iobuf;
|
||||
if( (c = _read_two_bytes(iobuffer)) > 0 ) {
|
||||
c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00);
|
||||
return c;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t file_read(rabbit::UserPointer file,rabbit::UserPointer buf,int64_t size)
|
||||
{
|
||||
int64_t ret;
|
||||
if( ( ret = rabbit::std::fread(buf,1,size,(rabbit::std::SQFILE)file ))!=0 )return ret;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int64_t file_write(rabbit::UserPointer file,rabbit::UserPointer p,int64_t size)
|
||||
{
|
||||
return rabbit::std::fwrite(p,1,size,(rabbit::std::SQFILE)file);
|
||||
}
|
||||
|
||||
rabbit::Result rabbit::std::loadfile(rabbit::VirtualMachine* v,const char *filename,rabbit::Bool printerror)
|
||||
{
|
||||
SQFILE file = rabbit::std::fopen(filename,"rb");
|
||||
|
||||
int64_t ret;
|
||||
unsigned short us;
|
||||
unsigned char uc;
|
||||
SQLEXREADFUNC func = _io_file_lexfeed_PLAIN;
|
||||
if(file){
|
||||
ret = rabbit::std::fread(&us,1,2,file);
|
||||
if(ret != 2) {
|
||||
//probably an empty file
|
||||
us = 0;
|
||||
}
|
||||
if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE
|
||||
rabbit::std::fseek(file,0,SQ_SEEK_SET);
|
||||
if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) {
|
||||
rabbit::std::fclose(file);
|
||||
return SQ_OK;
|
||||
}
|
||||
}
|
||||
else { //SCRIPT
|
||||
|
||||
switch(us)
|
||||
{
|
||||
//gotta swap the next 2 lines on BIG endian machines
|
||||
case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian;
|
||||
case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian;
|
||||
case 0xBBEF:
|
||||
if(rabbit::std::fread(&uc,1,sizeof(uc),file) == 0) {
|
||||
rabbit::std::fclose(file);
|
||||
return sq_throwerror(v,"io error");
|
||||
}
|
||||
if(uc != 0xBF) {
|
||||
rabbit::std::fclose(file);
|
||||
return sq_throwerror(v,"Unrecognized encoding");
|
||||
}
|
||||
func = _io_file_lexfeed_PLAIN;
|
||||
break;//UTF-8 ;
|
||||
default: rabbit::std::fseek(file,0,SQ_SEEK_SET); break; // ascii
|
||||
}
|
||||
IOBuffer buffer;
|
||||
buffer.ptr = 0;
|
||||
buffer.size = 0;
|
||||
buffer.file = file;
|
||||
if(SQ_SUCCEEDED(sq_compile(v,func,&buffer,filename,printerror))){
|
||||
rabbit::std::fclose(file);
|
||||
return SQ_OK;
|
||||
}
|
||||
}
|
||||
rabbit::std::fclose(file);
|
||||
return SQ_ERROR;
|
||||
}
|
||||
return sq_throwerror(v,"cannot open the file");
|
||||
}
|
||||
|
||||
rabbit::Result rabbit::std::dofile(rabbit::VirtualMachine* v,const char *filename,rabbit::Bool retval,rabbit::Bool printerror)
|
||||
{
|
||||
//at least one entry must exist in order for us to push it as the environment
|
||||
if(sq_gettop(v) == 0)
|
||||
return sq_throwerror(v,"environment table expected");
|
||||
|
||||
if(SQ_SUCCEEDED(rabbit::std::loadfile(v,filename,printerror))) {
|
||||
sq_push(v,-2);
|
||||
if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) {
|
||||
sq_remove(v,retval?-2:-1); //removes the closure
|
||||
return 1;
|
||||
}
|
||||
sq_pop(v,1); //removes the closure
|
||||
}
|
||||
return SQ_ERROR;
|
||||
}
|
||||
|
||||
rabbit::Result rabbit::std::writeclosuretofile(rabbit::VirtualMachine* v,const char *filename)
|
||||
{
|
||||
SQFILE file = rabbit::std::fopen(filename,"wb+");
|
||||
if(!file) return sq_throwerror(v,"cannot open the file");
|
||||
if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) {
|
||||
rabbit::std::fclose(file);
|
||||
return SQ_OK;
|
||||
}
|
||||
rabbit::std::fclose(file);
|
||||
return SQ_ERROR; //forward the error
|
||||
}
|
||||
|
||||
int64_t _g_io_loadfile(rabbit::VirtualMachine* v)
|
||||
{
|
||||
const char *filename;
|
||||
rabbit::Bool printerror = SQFalse;
|
||||
sq_getstring(v,2,&filename);
|
||||
if(sq_gettop(v) >= 3) {
|
||||
sq_getbool(v,3,&printerror);
|
||||
}
|
||||
if(SQ_SUCCEEDED(rabbit::std::loadfile(v,filename,printerror)))
|
||||
return 1;
|
||||
return SQ_ERROR; //propagates the error
|
||||
}
|
||||
|
||||
int64_t _g_io_writeclosuretofile(rabbit::VirtualMachine* v)
|
||||
{
|
||||
const char *filename;
|
||||
sq_getstring(v,2,&filename);
|
||||
if(SQ_SUCCEEDED(rabbit::std::writeclosuretofile(v,filename)))
|
||||
return 1;
|
||||
return SQ_ERROR; //propagates the error
|
||||
}
|
||||
|
||||
int64_t _g_io_dofile(rabbit::VirtualMachine* v)
|
||||
{
|
||||
const char *filename;
|
||||
rabbit::Bool printerror = SQFalse;
|
||||
sq_getstring(v,2,&filename);
|
||||
if(sq_gettop(v) >= 3) {
|
||||
sq_getbool(v,3,&printerror);
|
||||
}
|
||||
sq_push(v,1); //repush the this
|
||||
if(SQ_SUCCEEDED(rabbit::std::dofile(v,filename,SQTrue,printerror)))
|
||||
return 1;
|
||||
return SQ_ERROR; //propagates the error
|
||||
}
|
||||
|
||||
#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {#name,_g_io_##name,nparams,typecheck}
|
||||
static const rabbit::RegFunction iolib_funcs[]={
|
||||
_DECL_GLOBALIO_FUNC(loadfile,-2,".sb"),
|
||||
_DECL_GLOBALIO_FUNC(dofile,-2,".sb"),
|
||||
_DECL_GLOBALIO_FUNC(writeclosuretofile,3,".sc"),
|
||||
{NULL,(SQFUNCTION)0,0,NULL}
|
||||
};
|
||||
|
||||
rabbit::Result rabbit::std::register_iolib(rabbit::VirtualMachine* v)
|
||||
{
|
||||
int64_t top = sq_gettop(v);
|
||||
//create delegate
|
||||
declare_stream(v,"file",(rabbit::UserPointer)SQSTD_FILE_TYPE_TAG, "std_file",_file_methods,iolib_funcs);
|
||||
sq_pushstring(v,"stdout",-1);
|
||||
rabbit::std::createfile(v,stdout,SQFalse);
|
||||
sq_newslot(v,-3,SQFalse);
|
||||
sq_pushstring(v,"stdin",-1);
|
||||
rabbit::std::createfile(v,stdin,SQFalse);
|
||||
sq_newslot(v,-3,SQFalse);
|
||||
sq_pushstring(v,"stderr",-1);
|
||||
rabbit::std::createfile(v,stderr,SQFalse);
|
||||
sq_newslot(v,-3,SQFalse);
|
||||
sq_settop(v,top);
|
||||
return SQ_OK;
|
||||
}
|
52
rabbit-std/sqstdio.hpp
Normal file
52
rabbit-std/sqstdio.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace rabbit {
|
||||
namespace std {
|
||||
#define SQSTD_STREAM_TYPE_TAG 0x80000000
|
||||
|
||||
struct SQStream {
|
||||
virtual ~SQStream() {}
|
||||
virtual int64_t Read(void *buffer, int64_t size) = 0;
|
||||
virtual int64_t Write(void *buffer, int64_t size) = 0;
|
||||
virtual int64_t Flush() = 0;
|
||||
virtual int64_t Tell() = 0;
|
||||
virtual int64_t Len() = 0;
|
||||
virtual int64_t Seek(int64_t offset, int64_t origin) = 0;
|
||||
virtual bool IsValid() = 0;
|
||||
virtual bool EOS() = 0;
|
||||
};
|
||||
|
||||
#define SQ_SEEK_CUR 0
|
||||
#define SQ_SEEK_END 1
|
||||
#define SQ_SEEK_SET 2
|
||||
|
||||
using SQFILE = void*;
|
||||
|
||||
SQFILE fopen(const char *,const char *);
|
||||
int64_t fread(rabbit::UserPointer, int64_t, int64_t, SQFILE);
|
||||
int64_t fwrite(const rabbit::UserPointer, int64_t, int64_t, SQFILE);
|
||||
int64_t fseek(SQFILE , int64_t , int64_t);
|
||||
int64_t ftell(SQFILE);
|
||||
int64_t fflush(SQFILE);
|
||||
int64_t fclose(SQFILE);
|
||||
int64_t feof(SQFILE);
|
||||
|
||||
rabbit::Result createfile(rabbit::VirtualMachine* v, SQFILE file,rabbit::Bool own);
|
||||
rabbit::Result getfile(rabbit::VirtualMachine* v, int64_t idx, SQFILE *file);
|
||||
|
||||
//compiler helpers
|
||||
rabbit::Result loadfile(rabbit::VirtualMachine* v,const char *filename,rabbit::Bool printerror);
|
||||
rabbit::Result dofile(rabbit::VirtualMachine* v,const char *filename,rabbit::Bool retval,rabbit::Bool printerror);
|
||||
rabbit::Result writeclosuretofile(rabbit::VirtualMachine* v,const char *filename);
|
||||
|
||||
rabbit::Result register_iolib(rabbit::VirtualMachine* v);
|
||||
|
||||
}
|
||||
}
|
114
rabbit-std/sqstdmath.cpp
Normal file
114
rabbit-std/sqstdmath.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
|
||||
#include <rabbit/rabbit.hpp>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <rabbit-std/sqstdmath.hpp>
|
||||
|
||||
#define SINGLE_ARG_FUNC(_funcname) static int64_t math_##_funcname(rabbit::VirtualMachine* v){ \
|
||||
float_t f; \
|
||||
sq_getfloat(v,2,&f); \
|
||||
sq_pushfloat(v,(float_t)_funcname(f)); \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
#define TWO_ARGS_FUNC(_funcname) static int64_t math_##_funcname(rabbit::VirtualMachine* v){ \
|
||||
float_t p1,p2; \
|
||||
sq_getfloat(v,2,&p1); \
|
||||
sq_getfloat(v,3,&p2); \
|
||||
sq_pushfloat(v,(float_t)_funcname(p1,p2)); \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
static int64_t math_srand(rabbit::VirtualMachine* v)
|
||||
{
|
||||
int64_t i;
|
||||
if(SQ_FAILED(sq_getinteger(v,2,&i)))
|
||||
return sq_throwerror(v,"invalid param");
|
||||
srand((unsigned int)i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int64_t math_rand(rabbit::VirtualMachine* v)
|
||||
{
|
||||
sq_pushinteger(v,rand());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int64_t math_abs(rabbit::VirtualMachine* v)
|
||||
{
|
||||
int64_t n;
|
||||
sq_getinteger(v,2,&n);
|
||||
sq_pushinteger(v,(int64_t)abs((int)n));
|
||||
return 1;
|
||||
}
|
||||
|
||||
SINGLE_ARG_FUNC(sqrt)
|
||||
SINGLE_ARG_FUNC(fabs)
|
||||
SINGLE_ARG_FUNC(sin)
|
||||
SINGLE_ARG_FUNC(cos)
|
||||
SINGLE_ARG_FUNC(asin)
|
||||
SINGLE_ARG_FUNC(acos)
|
||||
SINGLE_ARG_FUNC(log)
|
||||
SINGLE_ARG_FUNC(log10)
|
||||
SINGLE_ARG_FUNC(tan)
|
||||
SINGLE_ARG_FUNC(atan)
|
||||
TWO_ARGS_FUNC(atan2)
|
||||
TWO_ARGS_FUNC(pow)
|
||||
SINGLE_ARG_FUNC(floor)
|
||||
SINGLE_ARG_FUNC(ceil)
|
||||
SINGLE_ARG_FUNC(exp)
|
||||
|
||||
#define _DECL_FUNC(name,nparams,tycheck) {#name,math_##name,nparams,tycheck}
|
||||
static const rabbit::RegFunction mathlib_funcs[] = {
|
||||
_DECL_FUNC(sqrt,2,".n"),
|
||||
_DECL_FUNC(sin,2,".n"),
|
||||
_DECL_FUNC(cos,2,".n"),
|
||||
_DECL_FUNC(asin,2,".n"),
|
||||
_DECL_FUNC(acos,2,".n"),
|
||||
_DECL_FUNC(log,2,".n"),
|
||||
_DECL_FUNC(log10,2,".n"),
|
||||
_DECL_FUNC(tan,2,".n"),
|
||||
_DECL_FUNC(atan,2,".n"),
|
||||
_DECL_FUNC(atan2,3,".nn"),
|
||||
_DECL_FUNC(pow,3,".nn"),
|
||||
_DECL_FUNC(floor,2,".n"),
|
||||
_DECL_FUNC(ceil,2,".n"),
|
||||
_DECL_FUNC(exp,2,".n"),
|
||||
_DECL_FUNC(srand,2,".n"),
|
||||
_DECL_FUNC(rand,1,NULL),
|
||||
_DECL_FUNC(fabs,2,".n"),
|
||||
_DECL_FUNC(abs,2,".n"),
|
||||
{NULL,(SQFUNCTION)0,0,NULL}
|
||||
};
|
||||
#undef _DECL_FUNC
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265358979323846)
|
||||
#endif
|
||||
|
||||
rabbit::Result rabbit::std::register_mathlib(rabbit::VirtualMachine* v)
|
||||
{
|
||||
int64_t i=0;
|
||||
while(mathlib_funcs[i].name!=0) {
|
||||
sq_pushstring(v,mathlib_funcs[i].name,-1);
|
||||
sq_newclosure(v,mathlib_funcs[i].f,0);
|
||||
sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask);
|
||||
sq_setnativeclosurename(v,-1,mathlib_funcs[i].name);
|
||||
sq_newslot(v,-3,SQFalse);
|
||||
i++;
|
||||
}
|
||||
sq_pushstring(v,"RAND_MAX",-1);
|
||||
sq_pushinteger(v,RAND_MAX);
|
||||
sq_newslot(v,-3,SQFalse);
|
||||
sq_pushstring(v,"PI",-1);
|
||||
sq_pushfloat(v,(float_t)M_PI);
|
||||
sq_newslot(v,-3,SQFalse);
|
||||
return SQ_OK;
|
||||
}
|
17
rabbit-std/sqstdmath.hpp
Normal file
17
rabbit-std/sqstdmath.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <rabbit/rabbit.hpp>
|
||||
#include <rabbit/RegFunction.hpp>
|
||||
|
||||
namespace rabbit {
|
||||
namespace std {
|
||||
rabbit::Result register_mathlib(rabbit::VirtualMachine* v);
|
||||
}
|
||||
}
|
687
rabbit-std/sqstdrex.cpp
Normal file
687
rabbit-std/sqstdrex.cpp
Normal file
@@ -0,0 +1,687 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
|
||||
#include <rabbit/rabbit.hpp>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <setjmp.h>
|
||||
#include <rabbit-std/sqstdstring.hpp>
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include <stdio.h>
|
||||
|
||||
static const char *g_nnames[] = {
|
||||
"NONE",
|
||||
"OP_GREEDY",
|
||||
"OP_OR",
|
||||
"OP_EXPR",
|
||||
"OP_NOCAPEXPR",
|
||||
"OP_DOT",
|
||||
"OP_CLASS",
|
||||
"OP_CCLASS",
|
||||
"OP_NCLASS",
|
||||
"OP_RANGE",
|
||||
"OP_CHAR",
|
||||
"OP_EOL",
|
||||
"OP_BOL",
|
||||
"OP_WB",
|
||||
"OP_MB"
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#define OP_GREEDY (UINT8_MAX+1) // * + ? {n}
|
||||
#define OP_OR (UINT8_MAX+2)
|
||||
#define OP_EXPR (UINT8_MAX+3) //parentesis ()
|
||||
#define OP_NOCAPEXPR (UINT8_MAX+4) //parentesis (?:)
|
||||
#define OP_DOT (UINT8_MAX+5)
|
||||
#define OP_CLASS (UINT8_MAX+6)
|
||||
#define OP_CCLASS (UINT8_MAX+7)
|
||||
#define OP_NCLASS (UINT8_MAX+8) //negates class the [^
|
||||
#define OP_RANGE (UINT8_MAX+9)
|
||||
#define OP_CHAR (UINT8_MAX+10)
|
||||
#define OP_EOL (UINT8_MAX+11)
|
||||
#define OP_BOL (UINT8_MAX+12)
|
||||
#define OP_WB (UINT8_MAX+13)
|
||||
#define OP_MB (UINT8_MAX+14) //match balanced
|
||||
|
||||
#define SQREX_SYMBOL_ANY_CHAR ('.')
|
||||
#define SQREX_SYMBOL_GREEDY_ONE_OR_MORE ('+')
|
||||
#define SQREX_SYMBOL_GREEDY_ZERO_OR_MORE ('*')
|
||||
#define SQREX_SYMBOL_GREEDY_ZERO_OR_ONE ('?')
|
||||
#define SQREX_SYMBOL_BRANCH ('|')
|
||||
#define SQREX_SYMBOL_END_OF_STRING ('$')
|
||||
#define SQREX_SYMBOL_BEGINNING_OF_STRING ('^')
|
||||
#define SQREX_SYMBOL_ESCAPE_CHAR ('\\')
|
||||
|
||||
namespace rabbit {
|
||||
|
||||
namespace std {
|
||||
|
||||
typedef int SQRexNodeType;
|
||||
|
||||
typedef struct tagSQRexNode{
|
||||
SQRexNodeType type;
|
||||
int64_t left;
|
||||
int64_t right;
|
||||
int64_t next;
|
||||
}SQRexNode;
|
||||
|
||||
struct SQRex{
|
||||
const char *_eol;
|
||||
const char *_bol;
|
||||
const char *_p;
|
||||
int64_t _first;
|
||||
int64_t _op;
|
||||
SQRexNode *_nodes;
|
||||
int64_t _nallocated;
|
||||
int64_t _nsize;
|
||||
int64_t _nsubexpr;
|
||||
rabbit::std::SQRexMatch *_matches;
|
||||
int64_t _currsubexp;
|
||||
void *_jmpbuf;
|
||||
const char **_error;
|
||||
};
|
||||
|
||||
static int64_t rex_list(SQRex *exp);
|
||||
|
||||
static int64_t rex_newnode(SQRex *exp, SQRexNodeType type)
|
||||
{
|
||||
SQRexNode n;
|
||||
n.type = type;
|
||||
n.next = n.right = n.left = -1;
|
||||
if(type == OP_EXPR)
|
||||
n.right = exp->_nsubexpr++;
|
||||
if(exp->_nallocated < (exp->_nsize + 1)) {
|
||||
int64_t oldsize = exp->_nallocated;
|
||||
exp->_nallocated *= 2;
|
||||
exp->_nodes = (SQRexNode *)sq_realloc(exp->_nodes, oldsize * sizeof(SQRexNode) ,exp->_nallocated * sizeof(SQRexNode));
|
||||
}
|
||||
exp->_nodes[exp->_nsize++] = n;
|
||||
int64_t newid = exp->_nsize - 1;
|
||||
return (int64_t)newid;
|
||||
}
|
||||
|
||||
static void rex_error(SQRex *exp,const char *error)
|
||||
{
|
||||
if(exp->_error) *exp->_error = error;
|
||||
longjmp(*((jmp_buf*)exp->_jmpbuf),-1);
|
||||
}
|
||||
|
||||
static void rex_expect(SQRex *exp, int64_t n){
|
||||
if((*exp->_p) != n)
|
||||
rabbit::std::rex_error(exp, "expected paren");
|
||||
exp->_p++;
|
||||
}
|
||||
|
||||
static char rex_escapechar(SQRex *exp)
|
||||
{
|
||||
if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR){
|
||||
exp->_p++;
|
||||
switch(*exp->_p) {
|
||||
case 'v': exp->_p++; return '\v';
|
||||
case 'n': exp->_p++; return '\n';
|
||||
case 't': exp->_p++; return '\t';
|
||||
case 'r': exp->_p++; return '\r';
|
||||
case 'f': exp->_p++; return '\f';
|
||||
default: return (*exp->_p++);
|
||||
}
|
||||
} else if(!isprint(*exp->_p)) rabbit::std::rex_error(exp,"letter expected");
|
||||
return (*exp->_p++);
|
||||
}
|
||||
|
||||
static int64_t rex_charclass(SQRex *exp,int64_t classid)
|
||||
{
|
||||
int64_t n = rabbit::std::rex_newnode(exp,OP_CCLASS);
|
||||
exp->_nodes[n].left = classid;
|
||||
return n;
|
||||
}
|
||||
|
||||
static int64_t rex_charnode(SQRex *exp,rabbit::Bool isclass)
|
||||
{
|
||||
char t;
|
||||
if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR) {
|
||||
exp->_p++;
|
||||
switch(*exp->_p) {
|
||||
case 'n': exp->_p++; return rabbit::std::rex_newnode(exp,'\n');
|
||||
case 't': exp->_p++; return rabbit::std::rex_newnode(exp,'\t');
|
||||
case 'r': exp->_p++; return rabbit::std::rex_newnode(exp,'\r');
|
||||
case 'f': exp->_p++; return rabbit::std::rex_newnode(exp,'\f');
|
||||
case 'v': exp->_p++; return rabbit::std::rex_newnode(exp,'\v');
|
||||
case 'a': case 'A': case 'w': case 'W': case 's': case 'S':
|
||||
case 'd': case 'D': case 'x': case 'X': case 'c': case 'C':
|
||||
case 'p': case 'P': case 'l': case 'u':
|
||||
{
|
||||
t = *exp->_p; exp->_p++;
|
||||
return rabbit::std::rex_charclass(exp,t);
|
||||
}
|
||||
case 'm':
|
||||
{
|
||||
char cb, ce; //cb = character begin match ce = character end match
|
||||
cb = *++exp->_p; //skip 'm'
|
||||
ce = *++exp->_p;
|
||||
exp->_p++; //points to the next char to be parsed
|
||||
if ((!cb) || (!ce)) rabbit::std::rex_error(exp,"balanced chars expected");
|
||||
if ( cb == ce ) rabbit::std::rex_error(exp,"open/close char can't be the same");
|
||||
int64_t node = rabbit::std::rex_newnode(exp,OP_MB);
|
||||
exp->_nodes[node].left = cb;
|
||||
exp->_nodes[node].right = ce;
|
||||
return node;
|
||||
}
|
||||
case 0:
|
||||
rabbit::std::rex_error(exp,"letter expected for argument of escape sequence");
|
||||
break;
|
||||
case 'b':
|
||||
case 'B':
|
||||
if(!isclass) {
|
||||
int64_t node = rabbit::std::rex_newnode(exp,OP_WB);
|
||||
exp->_nodes[node].left = *exp->_p;
|
||||
exp->_p++;
|
||||
return node;
|
||||
} //else default
|
||||
default:
|
||||
t = *exp->_p; exp->_p++;
|
||||
return rabbit::std::rex_newnode(exp,t);
|
||||
}
|
||||
}
|
||||
else if(!isprint(*exp->_p)) {
|
||||
|
||||
rabbit::std::rex_error(exp,"letter expected");
|
||||
}
|
||||
t = *exp->_p; exp->_p++;
|
||||
return rabbit::std::rex_newnode(exp,t);
|
||||
}
|
||||
static int64_t rex_class(SQRex *exp)
|
||||
{
|
||||
int64_t ret = -1;
|
||||
int64_t first = -1,chain;
|
||||
if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING){
|
||||
ret = rabbit::std::rex_newnode(exp,OP_NCLASS);
|
||||
exp->_p++;
|
||||
}else ret = rabbit::std::rex_newnode(exp,OP_CLASS);
|
||||
|
||||
if(*exp->_p == ']') rabbit::std::rex_error(exp,"empty class");
|
||||
chain = ret;
|
||||
while(*exp->_p != ']' && exp->_p != exp->_eol) {
|
||||
if(*exp->_p == '-' && first != -1){
|
||||
int64_t r;
|
||||
if(*exp->_p++ == ']') rabbit::std::rex_error(exp,"unfinished range");
|
||||
r = rabbit::std::rex_newnode(exp,OP_RANGE);
|
||||
if(exp->_nodes[first].type>*exp->_p) rabbit::std::rex_error(exp,"invalid range");
|
||||
if(exp->_nodes[first].type == OP_CCLASS) rabbit::std::rex_error(exp,"cannot use character classes in ranges");
|
||||
exp->_nodes[r].left = exp->_nodes[first].type;
|
||||
int64_t t = rabbit::std::rex_escapechar(exp);
|
||||
exp->_nodes[r].right = t;
|
||||
exp->_nodes[chain].next = r;
|
||||
chain = r;
|
||||
first = -1;
|
||||
}
|
||||
else{
|
||||
if(first!=-1){
|
||||
int64_t c = first;
|
||||
exp->_nodes[chain].next = c;
|
||||
chain = c;
|
||||
first = rabbit::std::rex_charnode(exp,SQTrue);
|
||||
}
|
||||
else{
|
||||
first = rabbit::std::rex_charnode(exp,SQTrue);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(first!=-1){
|
||||
int64_t c = first;
|
||||
exp->_nodes[chain].next = c;
|
||||
}
|
||||
/* hack? */
|
||||
exp->_nodes[ret].left = exp->_nodes[ret].next;
|
||||
exp->_nodes[ret].next = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int64_t rex_parsenumber(SQRex *exp)
|
||||
{
|
||||
int64_t ret = *exp->_p-'0';
|
||||
int64_t positions = 10;
|
||||
exp->_p++;
|
||||
while(isdigit(*exp->_p)) {
|
||||
ret = ret*10+(*exp->_p++-'0');
|
||||
if(positions==1000000000) rabbit::std::rex_error(exp,"overflow in numeric constant");
|
||||
positions *= 10;
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int64_t rex_element(SQRex *exp)
|
||||
{
|
||||
int64_t ret = -1;
|
||||
switch(*exp->_p)
|
||||
{
|
||||
case '(': {
|
||||
int64_t expr;
|
||||
exp->_p++;
|
||||
|
||||
|
||||
if(*exp->_p =='?') {
|
||||
exp->_p++;
|
||||
rabbit::std::rex_expect(exp,':');
|
||||
expr = rabbit::std::rex_newnode(exp,OP_NOCAPEXPR);
|
||||
}
|
||||
else
|
||||
expr = rabbit::std::rex_newnode(exp,OP_EXPR);
|
||||
int64_t newn = rabbit::std::rex_list(exp);
|
||||
exp->_nodes[expr].left = newn;
|
||||
ret = expr;
|
||||
rabbit::std::rex_expect(exp,')');
|
||||
}
|
||||
break;
|
||||
case '[':
|
||||
exp->_p++;
|
||||
ret = rabbit::std::rex_class(exp);
|
||||
rabbit::std::rex_expect(exp,']');
|
||||
break;
|
||||
case SQREX_SYMBOL_END_OF_STRING: exp->_p++; ret = rabbit::std::rex_newnode(exp,OP_EOL);break;
|
||||
case SQREX_SYMBOL_ANY_CHAR: exp->_p++; ret = rabbit::std::rex_newnode(exp,OP_DOT);break;
|
||||
default:
|
||||
ret = rabbit::std::rex_charnode(exp,SQFalse);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
rabbit::Bool isgreedy = SQFalse;
|
||||
unsigned short p0 = 0, p1 = 0;
|
||||
switch(*exp->_p){
|
||||
case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break;
|
||||
case SQREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break;
|
||||
case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; isgreedy = SQTrue; break;
|
||||
case '{':
|
||||
exp->_p++;
|
||||
if(!isdigit(*exp->_p)) rabbit::std::rex_error(exp,"number expected");
|
||||
p0 = (unsigned short)rabbit::std::rex_parsenumber(exp);
|
||||
/*******************************/
|
||||
switch(*exp->_p) {
|
||||
case '}':
|
||||
p1 = p0; exp->_p++;
|
||||
break;
|
||||
case ',':
|
||||
exp->_p++;
|
||||
p1 = 0xFFFF;
|
||||
if(isdigit(*exp->_p)){
|
||||
p1 = (unsigned short)rabbit::std::rex_parsenumber(exp);
|
||||
}
|
||||
rabbit::std::rex_expect(exp,'}');
|
||||
break;
|
||||
default:
|
||||
rabbit::std::rex_error(exp,", or } expected");
|
||||
}
|
||||
/*******************************/
|
||||
isgreedy = SQTrue;
|
||||
break;
|
||||
|
||||
}
|
||||
if(isgreedy) {
|
||||
int64_t nnode = rabbit::std::rex_newnode(exp,OP_GREEDY);
|
||||
exp->_nodes[nnode].left = ret;
|
||||
exp->_nodes[nnode].right = ((p0)<<16)|p1;
|
||||
ret = nnode;
|
||||
}
|
||||
|
||||
if((*exp->_p != SQREX_SYMBOL_BRANCH) && (*exp->_p != ')') && (*exp->_p != SQREX_SYMBOL_GREEDY_ZERO_OR_MORE) && (*exp->_p != SQREX_SYMBOL_GREEDY_ONE_OR_MORE) && (*exp->_p != '\0')) {
|
||||
int64_t nnode = rabbit::std::rex_element(exp);
|
||||
exp->_nodes[ret].next = nnode;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int64_t rex_list(SQRex *exp)
|
||||
{
|
||||
int64_t ret=-1,e;
|
||||
if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING) {
|
||||
exp->_p++;
|
||||
ret = rabbit::std::rex_newnode(exp,OP_BOL);
|
||||
}
|
||||
e = rabbit::std::rex_element(exp);
|
||||
if(ret != -1) {
|
||||
exp->_nodes[ret].next = e;
|
||||
}
|
||||
else ret = e;
|
||||
|
||||
if(*exp->_p == SQREX_SYMBOL_BRANCH) {
|
||||
int64_t temp,tright;
|
||||
exp->_p++;
|
||||
temp = rabbit::std::rex_newnode(exp,OP_OR);
|
||||
exp->_nodes[temp].left = ret;
|
||||
tright = rabbit::std::rex_list(exp);
|
||||
exp->_nodes[temp].right = tright;
|
||||
ret = temp;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static rabbit::Bool rex_matchcclass(int64_t cclass,char c)
|
||||
{
|
||||
switch(cclass) {
|
||||
case 'a': return isalpha(c)?SQTrue:SQFalse;
|
||||
case 'A': return !isalpha(c)?SQTrue:SQFalse;
|
||||
case 'w': return (isalnum(c) || c == '_')?SQTrue:SQFalse;
|
||||
case 'W': return (!isalnum(c) && c != '_')?SQTrue:SQFalse;
|
||||
case 's': return isspace(c)?SQTrue:SQFalse;
|
||||
case 'S': return !isspace(c)?SQTrue:SQFalse;
|
||||
case 'd': return isdigit(c)?SQTrue:SQFalse;
|
||||
case 'D': return !isdigit(c)?SQTrue:SQFalse;
|
||||
case 'x': return isxdigit(c)?SQTrue:SQFalse;
|
||||
case 'X': return !isxdigit(c)?SQTrue:SQFalse;
|
||||
case 'c': return iscntrl(c)?SQTrue:SQFalse;
|
||||
case 'C': return !iscntrl(c)?SQTrue:SQFalse;
|
||||
case 'p': return ispunct(c)?SQTrue:SQFalse;
|
||||
case 'P': return !ispunct(c)?SQTrue:SQFalse;
|
||||
case 'l': return islower(c)?SQTrue:SQFalse;
|
||||
case 'u': return isupper(c)?SQTrue:SQFalse;
|
||||
}
|
||||
return SQFalse; /*cannot happen*/
|
||||
}
|
||||
|
||||
static rabbit::Bool rex_matchclass(SQRex* exp,SQRexNode *node,char c)
|
||||
{
|
||||
do {
|
||||
switch(node->type) {
|
||||
case OP_RANGE:
|
||||
if(c >= node->left && c <= node->right) return SQTrue;
|
||||
break;
|
||||
case OP_CCLASS:
|
||||
if(rabbit::std::rex_matchcclass(node->left,c)) return SQTrue;
|
||||
break;
|
||||
default:
|
||||
if(c == node->type)return SQTrue;
|
||||
}
|
||||
} while((node->next != -1) && (node = &exp->_nodes[node->next]));
|
||||
return SQFalse;
|
||||
}
|
||||
|
||||
static const char * rex_matchnode(SQRex* exp,SQRexNode *node,const char *str,SQRexNode *next)
|
||||
{
|
||||
|
||||
SQRexNodeType type = node->type;
|
||||
switch(type) {
|
||||
case OP_GREEDY: {
|
||||
//SQRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL;
|
||||
SQRexNode *greedystop = NULL;
|
||||
int64_t p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0;
|
||||
const char *s=str, *good = str;
|
||||
|
||||
if(node->next != -1) {
|
||||
greedystop = &exp->_nodes[node->next];
|
||||
}
|
||||
else {
|
||||
greedystop = next;
|
||||
}
|
||||
|
||||
while((nmaches == 0xFFFF || nmaches < p1)) {
|
||||
|
||||
const char *stop;
|
||||
if(!(s = rabbit::std::rex_matchnode(exp,&exp->_nodes[node->left],s,greedystop)))
|
||||
break;
|
||||
nmaches++;
|
||||
good=s;
|
||||
if(greedystop) {
|
||||
//checks that 0 matches satisfy the expression(if so skips)
|
||||
//if not would always stop(for instance if is a '?')
|
||||
if(greedystop->type != OP_GREEDY ||
|
||||
(greedystop->type == OP_GREEDY && ((greedystop->right >> 16)&0x0000FFFF) != 0))
|
||||
{
|
||||
SQRexNode *gnext = NULL;
|
||||
if(greedystop->next != -1) {
|
||||
gnext = &exp->_nodes[greedystop->next];
|
||||
}else if(next && next->next != -1){
|
||||
gnext = &exp->_nodes[next->next];
|
||||
}
|
||||
stop = rabbit::std::rex_matchnode(exp,greedystop,s,gnext);
|
||||
if(stop) {
|
||||
//if satisfied stop it
|
||||
if(p0 == p1 && p0 == nmaches) break;
|
||||
else if(nmaches >= p0 && p1 == 0xFFFF) break;
|
||||
else if(nmaches >= p0 && nmaches <= p1) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(s >= exp->_eol)
|
||||
break;
|
||||
}
|
||||
if(p0 == p1 && p0 == nmaches) return good;
|
||||
else if(nmaches >= p0 && p1 == 0xFFFF) return good;
|
||||
else if(nmaches >= p0 && nmaches <= p1) return good;
|
||||
return NULL;
|
||||
}
|
||||
case OP_OR: {
|
||||
const char *asd = str;
|
||||
SQRexNode *temp=&exp->_nodes[node->left];
|
||||
while( (asd = rabbit::std::rex_matchnode(exp,temp,asd,NULL)) ) {
|
||||
if(temp->next != -1)
|
||||
temp = &exp->_nodes[temp->next];
|
||||
else
|
||||
return asd;
|
||||
}
|
||||
asd = str;
|
||||
temp = &exp->_nodes[node->right];
|
||||
while( (asd = rabbit::std::rex_matchnode(exp,temp,asd,NULL)) ) {
|
||||
if(temp->next != -1)
|
||||
temp = &exp->_nodes[temp->next];
|
||||
else
|
||||
return asd;
|
||||
}
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
case OP_EXPR:
|
||||
case OP_NOCAPEXPR:{
|
||||
SQRexNode *n = &exp->_nodes[node->left];
|
||||
const char *cur = str;
|
||||
int64_t capture = -1;
|
||||
if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) {
|
||||
capture = exp->_currsubexp;
|
||||
exp->_matches[capture].begin = cur;
|
||||
exp->_currsubexp++;
|
||||
}
|
||||
int64_t tempcap = exp->_currsubexp;
|
||||
do {
|
||||
SQRexNode *subnext = NULL;
|
||||
if(n->next != -1) {
|
||||
subnext = &exp->_nodes[n->next];
|
||||
}else {
|
||||
subnext = next;
|
||||
}
|
||||
if(!(cur = rabbit::std::rex_matchnode(exp,n,cur,subnext))) {
|
||||
if(capture != -1){
|
||||
exp->_matches[capture].begin = 0;
|
||||
exp->_matches[capture].len = 0;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
} while((n->next != -1) && (n = &exp->_nodes[n->next]));
|
||||
|
||||
exp->_currsubexp = tempcap;
|
||||
if(capture != -1)
|
||||
exp->_matches[capture].len = cur - exp->_matches[capture].begin;
|
||||
return cur;
|
||||
}
|
||||
case OP_WB:
|
||||
if((str == exp->_bol && !isspace(*str))
|
||||
|| (str == exp->_eol && !isspace(*(str-1)))
|
||||
|| (!isspace(*str) && isspace(*(str+1)))
|
||||
|| (isspace(*str) && !isspace(*(str+1))) ) {
|
||||
return (node->left == 'b')?str:NULL;
|
||||
}
|
||||
return (node->left == 'b')?NULL:str;
|
||||
case OP_BOL:
|
||||
if(str == exp->_bol) return str;
|
||||
return NULL;
|
||||
case OP_EOL:
|
||||
if(str == exp->_eol) return str;
|
||||
return NULL;
|
||||
case OP_DOT:{
|
||||
if (str == exp->_eol) return NULL;
|
||||
str++;
|
||||
}
|
||||
return str;
|
||||
case OP_NCLASS:
|
||||
case OP_CLASS:
|
||||
if (str == exp->_eol) return NULL;
|
||||
if(rabbit::std::rex_matchclass(exp,&exp->_nodes[node->left],*str)?(type == OP_CLASS?SQTrue:SQFalse):(type == OP_NCLASS?SQTrue:SQFalse)) {
|
||||
str++;
|
||||
return str;
|
||||
}
|
||||
return NULL;
|
||||
case OP_CCLASS:
|
||||
if (str == exp->_eol) return NULL;
|
||||
if(rabbit::std::rex_matchcclass(node->left,*str)) {
|
||||
str++;
|
||||
return str;
|
||||
}
|
||||
return NULL;
|
||||
case OP_MB:
|
||||
{
|
||||
int64_t cb = node->left; //char that opens a balanced expression
|
||||
if(*str != cb) return NULL; // string doesnt start with open char
|
||||
int64_t ce = node->right; //char that closes a balanced expression
|
||||
int64_t cont = 1;
|
||||
const char *streol = exp->_eol;
|
||||
while (++str < streol) {
|
||||
if (*str == ce) {
|
||||
if (--cont == 0) {
|
||||
return ++str;
|
||||
}
|
||||
}
|
||||
else if (*str == cb) cont++;
|
||||
}
|
||||
}
|
||||
return NULL; // string ends out of balance
|
||||
default: /* char */
|
||||
if (str == exp->_eol) return NULL;
|
||||
if(*str != node->type) return NULL;
|
||||
str++;
|
||||
return str;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* public api */
|
||||
rabbit::std::SQRex *rabbit::std::rex_compile(const char *pattern,const char **error)
|
||||
{
|
||||
SQRex * volatile exp = (SQRex *)sq_malloc(sizeof(SQRex)); // "volatile" is needed for setjmp()
|
||||
exp->_eol = exp->_bol = NULL;
|
||||
exp->_p = pattern;
|
||||
exp->_nallocated = (int64_t)strlen(pattern) * sizeof(char);
|
||||
exp->_nodes = (SQRexNode *)sq_malloc(exp->_nallocated * sizeof(SQRexNode));
|
||||
exp->_nsize = 0;
|
||||
exp->_matches = 0;
|
||||
exp->_nsubexpr = 0;
|
||||
exp->_first = rabbit::std::rex_newnode(exp,OP_EXPR);
|
||||
exp->_error = error;
|
||||
exp->_jmpbuf = sq_malloc(sizeof(jmp_buf));
|
||||
if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) {
|
||||
int64_t res = rabbit::std::rex_list(exp);
|
||||
exp->_nodes[exp->_first].left = res;
|
||||
if(*exp->_p!='\0')
|
||||
rabbit::std::rex_error(exp,"unexpected character");
|
||||
#ifdef _DEBUG
|
||||
{
|
||||
int64_t nsize,i;
|
||||
SQRexNode *t;
|
||||
nsize = exp->_nsize;
|
||||
t = &exp->_nodes[0];
|
||||
printf("\n");
|
||||
for(i = 0;i < nsize; i++) {
|
||||
if(exp->_nodes[i].type>UINT8_MAX)
|
||||
printf("[%02d] %10s ", (int32_t)i,g_nnames[exp->_nodes[i].type-UINT8_MAX]);
|
||||
else
|
||||
printf("[%02d] %10c ", (int32_t)i,exp->_nodes[i].type);
|
||||
printf("left %02d right %02d next %02d\n", (int32_t)exp->_nodes[i].left, (int32_t)exp->_nodes[i].right, (int32_t)exp->_nodes[i].next);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
exp->_matches = (SQRexMatch *) sq_malloc(exp->_nsubexpr * sizeof(SQRexMatch));
|
||||
memset(exp->_matches,0,exp->_nsubexpr * sizeof(SQRexMatch));
|
||||
}
|
||||
else{
|
||||
rabbit::std::rex_free(exp);
|
||||
return NULL;
|
||||
}
|
||||
return exp;
|
||||
}
|
||||
|
||||
void rabbit::std::rex_free(SQRex *exp)
|
||||
{
|
||||
if(exp) {
|
||||
if(exp->_nodes) sq_free(exp->_nodes,exp->_nallocated * sizeof(SQRexNode));
|
||||
if(exp->_jmpbuf) sq_free(exp->_jmpbuf,sizeof(jmp_buf));
|
||||
if(exp->_matches) sq_free(exp->_matches,exp->_nsubexpr * sizeof(SQRexMatch));
|
||||
sq_free(exp,sizeof(SQRex));
|
||||
}
|
||||
}
|
||||
|
||||
rabbit::Bool rabbit::std::rex_match(SQRex* exp,const char* text)
|
||||
{
|
||||
const char* res = NULL;
|
||||
exp->_bol = text;
|
||||
exp->_eol = text + strlen(text);
|
||||
exp->_currsubexp = 0;
|
||||
res = rabbit::std::rex_matchnode(exp,exp->_nodes,text,NULL);
|
||||
if(res == NULL || res != exp->_eol)
|
||||
return SQFalse;
|
||||
return SQTrue;
|
||||
}
|
||||
|
||||
rabbit::Bool rabbit::std::rex_searchrange(SQRex* exp,const char* text_begin,const char* text_end,const char** out_begin, const char** out_end)
|
||||
{
|
||||
const char *cur = NULL;
|
||||
int64_t node = exp->_first;
|
||||
if(text_begin >= text_end) return SQFalse;
|
||||
exp->_bol = text_begin;
|
||||
exp->_eol = text_end;
|
||||
do {
|
||||
cur = text_begin;
|
||||
while(node != -1) {
|
||||
exp->_currsubexp = 0;
|
||||
cur = rabbit::std::rex_matchnode(exp,&exp->_nodes[node],cur,NULL);
|
||||
if(!cur)
|
||||
break;
|
||||
node = exp->_nodes[node].next;
|
||||
}
|
||||
text_begin++;
|
||||
} while(cur == NULL && text_begin != text_end);
|
||||
|
||||
if(cur == NULL)
|
||||
return SQFalse;
|
||||
|
||||
--text_begin;
|
||||
|
||||
if(out_begin) *out_begin = text_begin;
|
||||
if(out_end) *out_end = cur;
|
||||
return SQTrue;
|
||||
}
|
||||
|
||||
rabbit::Bool rabbit::std::rex_search(SQRex* exp,const char* text, const char** out_begin, const char** out_end)
|
||||
{
|
||||
return rabbit::std::rex_searchrange(exp,text,text + strlen(text),out_begin,out_end);
|
||||
}
|
||||
|
||||
int64_t rabbit::std::rex_getsubexpcount(SQRex* exp)
|
||||
{
|
||||
return exp->_nsubexpr;
|
||||
}
|
||||
|
||||
rabbit::Bool rabbit::std::rex_getsubexp(SQRex* exp, int64_t n, SQRexMatch *subexp)
|
||||
{
|
||||
if( n<0 || n >= exp->_nsubexpr) return SQFalse;
|
||||
*subexp = exp->_matches[n];
|
||||
return SQTrue;
|
||||
}
|
||||
|
343
rabbit-std/sqstdstream.cpp
Normal file
343
rabbit-std/sqstdstream.cpp
Normal file
@@ -0,0 +1,343 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
|
||||
#include <new>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <rabbit/rabbit.hpp>
|
||||
#include <rabbit-std/sqstdio.hpp>
|
||||
#include <rabbit-std/sqstdblob.hpp>
|
||||
#include <rabbit-std/sqstdstream.hpp>
|
||||
#include <rabbit-std/sqstdblobimpl.hpp>
|
||||
|
||||
#define SETUP_STREAM(v) \
|
||||
rabbit::std::SQStream *self = NULL; \
|
||||
if(SQ_FAILED(sq_getinstanceup(v,1,(rabbit::UserPointer*)&self,(rabbit::UserPointer)((uint64_t)SQSTD_STREAM_TYPE_TAG)))) \
|
||||
return rabbit::sq_throwerror(v,"invalid type tag"); \
|
||||
if(!self || !self->IsValid()) \
|
||||
return rabbit::sq_throwerror(v,"the stream is invalid");
|
||||
|
||||
int64_t _stream_readblob(rabbit::VirtualMachine* v)
|
||||
{
|
||||
SETUP_STREAM(v);
|
||||
rabbit::UserPointer data,blobp;
|
||||
int64_t size,res;
|
||||
sq_getinteger(v,2,&size);
|
||||
if(size > self->Len()) {
|
||||
size = self->Len();
|
||||
}
|
||||
data = sq_getscratchpad(v,size);
|
||||
res = self->Read(data,size);
|
||||
if(res <= 0)
|
||||
return sq_throwerror(v,"no data left to read");
|
||||
blobp = rabbit::std::createblob(v,res);
|
||||
memcpy(blobp,data,res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define SAFE_READN(ptr,len) { \
|
||||
if(self->Read(ptr,len) != len) return sq_throwerror(v,"io error"); \
|
||||
}
|
||||
int64_t _stream_readn(rabbit::VirtualMachine* v)
|
||||
{
|
||||
SETUP_STREAM(v);
|
||||
int64_t format;
|
||||
sq_getinteger(v, 2, &format);
|
||||
switch(format) {
|
||||
case 'l': {
|
||||
int64_t i;
|
||||
SAFE_READN(&i, sizeof(i));
|
||||
sq_pushinteger(v, i);
|
||||
}
|
||||
break;
|
||||
case 'i': {
|
||||
int32_t i;
|
||||
SAFE_READN(&i, sizeof(i));
|
||||
sq_pushinteger(v, i);
|
||||
}
|
||||
break;
|
||||
case 's': {
|
||||
short s;
|
||||
SAFE_READN(&s, sizeof(short));
|
||||
sq_pushinteger(v, s);
|
||||
}
|
||||
break;
|
||||
case 'w': {
|
||||
unsigned short w;
|
||||
SAFE_READN(&w, sizeof(unsigned short));
|
||||
sq_pushinteger(v, w);
|
||||
}
|
||||
break;
|
||||
case 'c': {
|
||||
char c;
|
||||
SAFE_READN(&c, sizeof(char));
|
||||
sq_pushinteger(v, c);
|
||||
}
|
||||
break;
|
||||
case 'b': {
|
||||
unsigned char c;
|
||||
SAFE_READN(&c, sizeof(unsigned char));
|
||||
sq_pushinteger(v, c);
|
||||
}
|
||||
break;
|
||||
case 'f': {
|
||||
float f;
|
||||
SAFE_READN(&f, sizeof(float));
|
||||
sq_pushfloat(v, f);
|
||||
}
|
||||
break;
|
||||
case 'd': {
|
||||
double d;
|
||||
SAFE_READN(&d, sizeof(double));
|
||||
sq_pushfloat(v, (float_t)d);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return sq_throwerror(v, "invalid format");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int64_t _stream_writeblob(rabbit::VirtualMachine* v)
|
||||
{
|
||||
rabbit::UserPointer data;
|
||||
int64_t size;
|
||||
SETUP_STREAM(v);
|
||||
if(SQ_FAILED(rabbit::std::getblob(v,2,&data)))
|
||||
return sq_throwerror(v,"invalid parameter");
|
||||
size = rabbit::std::getblobsize(v,2);
|
||||
if(self->Write(data,size) != size)
|
||||
return sq_throwerror(v,"io error");
|
||||
sq_pushinteger(v,size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int64_t _stream_writen(rabbit::VirtualMachine* v)
|
||||
{
|
||||
SETUP_STREAM(v);
|
||||
int64_t format, ti;
|
||||
float_t tf;
|
||||
sq_getinteger(v, 3, &format);
|
||||
switch(format) {
|
||||
case 'l': {
|
||||
int64_t i;
|
||||
sq_getinteger(v, 2, &ti);
|
||||
i = ti;
|
||||
self->Write(&i, sizeof(int64_t));
|
||||
}
|
||||
break;
|
||||
case 'i': {
|
||||
int32_t i;
|
||||
sq_getinteger(v, 2, &ti);
|
||||
i = (int32_t)ti;
|
||||
self->Write(&i, sizeof(int32_t));
|
||||
}
|
||||
break;
|
||||
case 's': {
|
||||
short s;
|
||||
sq_getinteger(v, 2, &ti);
|
||||
s = (short)ti;
|
||||
self->Write(&s, sizeof(short));
|
||||
}
|
||||
break;
|
||||
case 'w': {
|
||||
unsigned short w;
|
||||
sq_getinteger(v, 2, &ti);
|
||||
w = (unsigned short)ti;
|
||||
self->Write(&w, sizeof(unsigned short));
|
||||
}
|
||||
break;
|
||||
case 'c': {
|
||||
char c;
|
||||
sq_getinteger(v, 2, &ti);
|
||||
c = (char)ti;
|
||||
self->Write(&c, sizeof(char));
|
||||
}
|
||||
break;
|
||||
case 'b': {
|
||||
unsigned char b;
|
||||
sq_getinteger(v, 2, &ti);
|
||||
b = (unsigned char)ti;
|
||||
self->Write(&b, sizeof(unsigned char));
|
||||
}
|
||||
break;
|
||||
case 'f': {
|
||||
float f;
|
||||
sq_getfloat(v, 2, &tf);
|
||||
f = (float)tf;
|
||||
self->Write(&f, sizeof(float));
|
||||
}
|
||||
break;
|
||||
case 'd': {
|
||||
double d;
|
||||
sq_getfloat(v, 2, &tf);
|
||||
d = tf;
|
||||
self->Write(&d, sizeof(double));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return sq_throwerror(v, "invalid format");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t _stream_seek(rabbit::VirtualMachine* v)
|
||||
{
|
||||
SETUP_STREAM(v);
|
||||
int64_t offset, origin = SQ_SEEK_SET;
|
||||
sq_getinteger(v, 2, &offset);
|
||||
if(sq_gettop(v) > 2) {
|
||||
int64_t t;
|
||||
sq_getinteger(v, 3, &t);
|
||||
switch(t) {
|
||||
case 'b': origin = SQ_SEEK_SET; break;
|
||||
case 'c': origin = SQ_SEEK_CUR; break;
|
||||
case 'e': origin = SQ_SEEK_END; break;
|
||||
default: return sq_throwerror(v,"invalid origin");
|
||||
}
|
||||
}
|
||||
sq_pushinteger(v, self->Seek(offset, origin));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int64_t _stream_tell(rabbit::VirtualMachine* v)
|
||||
{
|
||||
SETUP_STREAM(v);
|
||||
sq_pushinteger(v, self->Tell());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int64_t _stream_len(rabbit::VirtualMachine* v)
|
||||
{
|
||||
SETUP_STREAM(v);
|
||||
sq_pushinteger(v, self->Len());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int64_t _stream_flush(rabbit::VirtualMachine* v)
|
||||
{
|
||||
SETUP_STREAM(v);
|
||||
if(!self->Flush())
|
||||
sq_pushinteger(v, 1);
|
||||
else
|
||||
sq_pushnull(v);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int64_t _stream_eos(rabbit::VirtualMachine* v)
|
||||
{
|
||||
SETUP_STREAM(v);
|
||||
if(self->EOS())
|
||||
sq_pushinteger(v, 1);
|
||||
else
|
||||
sq_pushnull(v);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int64_t _stream__cloned(rabbit::VirtualMachine* v)
|
||||
{
|
||||
return sq_throwerror(v,"this object cannot be cloned");
|
||||
}
|
||||
|
||||
static const rabbit::RegFunction _stream_methods[] = {
|
||||
_DECL_STREAM_FUNC(readblob,2,"xn"),
|
||||
_DECL_STREAM_FUNC(readn,2,"xn"),
|
||||
_DECL_STREAM_FUNC(writeblob,-2,"xx"),
|
||||
_DECL_STREAM_FUNC(writen,3,"xnn"),
|
||||
_DECL_STREAM_FUNC(seek,-2,"xnn"),
|
||||
_DECL_STREAM_FUNC(tell,1,"x"),
|
||||
_DECL_STREAM_FUNC(len,1,"x"),
|
||||
_DECL_STREAM_FUNC(eos,1,"x"),
|
||||
_DECL_STREAM_FUNC(flush,1,"x"),
|
||||
_DECL_STREAM_FUNC(_cloned,0,NULL),
|
||||
{NULL,(SQFUNCTION)0,0,NULL}
|
||||
};
|
||||
|
||||
void init_streamclass(rabbit::VirtualMachine* v)
|
||||
{
|
||||
sq_pushregistrytable(v);
|
||||
sq_pushstring(v,"std_stream",-1);
|
||||
if(SQ_FAILED(sq_get(v,-2))) {
|
||||
sq_pushstring(v,"std_stream",-1);
|
||||
sq_newclass(v,SQFalse);
|
||||
sq_settypetag(v,-1,(rabbit::UserPointer)((uint64_t)SQSTD_STREAM_TYPE_TAG));
|
||||
int64_t i = 0;
|
||||
while(_stream_methods[i].name != 0) {
|
||||
const rabbit::RegFunction &f = _stream_methods[i];
|
||||
sq_pushstring(v,f.name,-1);
|
||||
sq_newclosure(v,f.f,0);
|
||||
sq_setparamscheck(v,f.nparamscheck,f.typemask);
|
||||
sq_newslot(v,-3,SQFalse);
|
||||
i++;
|
||||
}
|
||||
sq_newslot(v,-3,SQFalse);
|
||||
sq_pushroottable(v);
|
||||
sq_pushstring(v,"stream",-1);
|
||||
sq_pushstring(v,"std_stream",-1);
|
||||
sq_get(v,-4);
|
||||
sq_newslot(v,-3,SQFalse);
|
||||
sq_pop(v,1);
|
||||
}
|
||||
else {
|
||||
sq_pop(v,1); //result
|
||||
}
|
||||
sq_pop(v,1);
|
||||
}
|
||||
|
||||
rabbit::Result rabbit::std::declare_stream(rabbit::VirtualMachine* v,const char* name,rabbit::UserPointer typetag,const char* reg_name,const rabbit::RegFunction *methods,const rabbit::RegFunction *globals)
|
||||
{
|
||||
if(sq_gettype(v,-1) != rabbit::OT_TABLE)
|
||||
return sq_throwerror(v,"table expected");
|
||||
int64_t top = sq_gettop(v);
|
||||
//create delegate
|
||||
init_streamclass(v);
|
||||
sq_pushregistrytable(v);
|
||||
sq_pushstring(v,reg_name,-1);
|
||||
sq_pushstring(v,"std_stream",-1);
|
||||
if(SQ_SUCCEEDED(sq_get(v,-3))) {
|
||||
sq_newclass(v,SQTrue);
|
||||
sq_settypetag(v,-1,typetag);
|
||||
int64_t i = 0;
|
||||
while(methods[i].name != 0) {
|
||||
const rabbit::RegFunction &f = methods[i];
|
||||
sq_pushstring(v,f.name,-1);
|
||||
sq_newclosure(v,f.f,0);
|
||||
sq_setparamscheck(v,f.nparamscheck,f.typemask);
|
||||
sq_setnativeclosurename(v,-1,f.name);
|
||||
sq_newslot(v,-3,SQFalse);
|
||||
i++;
|
||||
}
|
||||
sq_newslot(v,-3,SQFalse);
|
||||
sq_pop(v,1);
|
||||
|
||||
i = 0;
|
||||
while(globals[i].name!=0)
|
||||
{
|
||||
const rabbit::RegFunction &f = globals[i];
|
||||
sq_pushstring(v,f.name,-1);
|
||||
sq_newclosure(v,f.f,0);
|
||||
sq_setparamscheck(v,f.nparamscheck,f.typemask);
|
||||
sq_setnativeclosurename(v,-1,f.name);
|
||||
sq_newslot(v,-3,SQFalse);
|
||||
i++;
|
||||
}
|
||||
//register the class in the target table
|
||||
sq_pushstring(v,name,-1);
|
||||
sq_pushregistrytable(v);
|
||||
sq_pushstring(v,reg_name,-1);
|
||||
sq_get(v,-2);
|
||||
sq_remove(v,-2);
|
||||
sq_newslot(v,-3,SQFalse);
|
||||
|
||||
sq_settop(v,top);
|
||||
return SQ_OK;
|
||||
}
|
||||
sq_settop(v,top);
|
||||
return SQ_ERROR;
|
||||
}
|
28
rabbit-std/sqstdstream.hpp
Normal file
28
rabbit-std/sqstdstream.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <rabbit/RegFunction.hpp>
|
||||
|
||||
namespace rabbit {
|
||||
namespace std {
|
||||
int64_t _stream_readblob(rabbit::VirtualMachine* v);
|
||||
int64_t _stream_readline(rabbit::VirtualMachine* v);
|
||||
int64_t _stream_readn(rabbit::VirtualMachine* v);
|
||||
int64_t _stream_writeblob(rabbit::VirtualMachine* v);
|
||||
int64_t _stream_writen(rabbit::VirtualMachine* v);
|
||||
int64_t _stream_seek(rabbit::VirtualMachine* v);
|
||||
int64_t _stream_tell(rabbit::VirtualMachine* v);
|
||||
int64_t _stream_len(rabbit::VirtualMachine* v);
|
||||
int64_t _stream_eos(rabbit::VirtualMachine* v);
|
||||
int64_t _stream_flush(rabbit::VirtualMachine* v);
|
||||
|
||||
#define _DECL_STREAM_FUNC(name,nparams,typecheck) {#name,_stream_##name,nparams,typecheck}
|
||||
rabbit::Result declare_stream(rabbit::VirtualMachine* v,const char* name,rabbit::UserPointer typetag,const char* reg_name,const rabbit::RegFunction *methods,const rabbit::RegFunction *globals);
|
||||
}
|
||||
}
|
523
rabbit-std/sqstdstring.cpp
Normal file
523
rabbit-std/sqstdstring.cpp
Normal file
@@ -0,0 +1,523 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
|
||||
#include <rabbit/rabbit.hpp>
|
||||
#include <rabbit-std/sqstdstring.hpp>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define MAX_FORMAT_LEN 20
|
||||
#define MAX_WFORMAT_LEN 3
|
||||
#define ADDITIONAL_FORMAT_SPACE (100*sizeof(char))
|
||||
|
||||
static rabbit::Bool isfmtchr(char ch)
|
||||
{
|
||||
switch(ch) {
|
||||
case '-':
|
||||
case '+':
|
||||
case ' ':
|
||||
case '#':
|
||||
case '0':
|
||||
return SQTrue;
|
||||
}
|
||||
return SQFalse;
|
||||
}
|
||||
|
||||
static int64_t validate_format(rabbit::VirtualMachine* v, char *fmt, const char *src, int64_t n,int64_t &width)
|
||||
{
|
||||
char *dummy;
|
||||
char swidth[MAX_WFORMAT_LEN];
|
||||
int64_t wc = 0;
|
||||
int64_t start = n;
|
||||
fmt[0] = '%';
|
||||
while (isfmtchr(src[n])) n++;
|
||||
while (isdigit(src[n])) {
|
||||
swidth[wc] = src[n];
|
||||
n++;
|
||||
wc++;
|
||||
if(wc>=MAX_WFORMAT_LEN)
|
||||
return sq_throwerror(v,"width format too long");
|
||||
}
|
||||
swidth[wc] = '\0';
|
||||
if(wc > 0) {
|
||||
width = strtol(swidth,&dummy,10);
|
||||
}
|
||||
else
|
||||
width = 0;
|
||||
if (src[n] == '.') {
|
||||
n++;
|
||||
|
||||
wc = 0;
|
||||
while (isdigit(src[n])) {
|
||||
swidth[wc] = src[n];
|
||||
n++;
|
||||
wc++;
|
||||
if(wc>=MAX_WFORMAT_LEN)
|
||||
return sq_throwerror(v,"precision format too long");
|
||||
}
|
||||
swidth[wc] = '\0';
|
||||
if(wc > 0) {
|
||||
width += strtol(swidth,&dummy,10);
|
||||
|
||||
}
|
||||
}
|
||||
if (n-start > MAX_FORMAT_LEN )
|
||||
return sq_throwerror(v,"format too long");
|
||||
memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(char));
|
||||
fmt[(n-start)+2] = '\0';
|
||||
return n;
|
||||
}
|
||||
|
||||
rabbit::Result rabbit::std::format(rabbit::VirtualMachine* v,int64_t nformatstringidx,int64_t *outlen,char **output)
|
||||
{
|
||||
const char *format;
|
||||
char *dest;
|
||||
char fmt[MAX_FORMAT_LEN];
|
||||
const rabbit::Result res = sq_getstring(v,nformatstringidx,&format);
|
||||
if (SQ_FAILED(res)) {
|
||||
return res; // propagate the error
|
||||
}
|
||||
int64_t format_size = sq_getsize(v,nformatstringidx);
|
||||
int64_t allocated = (format_size+2)*sizeof(char);
|
||||
dest = sq_getscratchpad(v,allocated);
|
||||
int64_t n = 0,i = 0, nparam = nformatstringidx+1, w = 0;
|
||||
//while(format[n] != '\0')
|
||||
while(n < format_size)
|
||||
{
|
||||
if(format[n] != '%') {
|
||||
assert(i < allocated);
|
||||
dest[i++] = format[n];
|
||||
n++;
|
||||
}
|
||||
else if(format[n+1] == '%') { //handles %%
|
||||
dest[i++] = '%';
|
||||
n += 2;
|
||||
}
|
||||
else {
|
||||
n++;
|
||||
if( nparam > sq_gettop(v) )
|
||||
return sq_throwerror(v,"not enough parameters for the given format string");
|
||||
n = validate_format(v,fmt,format,n,w);
|
||||
if(n < 0) return -1;
|
||||
int64_t addlen = 0;
|
||||
int64_t valtype = 0;
|
||||
const char *ts = NULL;
|
||||
int64_t ti = 0;
|
||||
float_t tf = 0;
|
||||
switch(format[n]) {
|
||||
case 's':
|
||||
if(SQ_FAILED(sq_getstring(v,nparam,&ts)))
|
||||
return sq_throwerror(v,"string expected for the specified format");
|
||||
addlen = (sq_getsize(v,nparam)*sizeof(char))+((w+1)*sizeof(char));
|
||||
valtype = 's';
|
||||
break;
|
||||
case 'i':
|
||||
case 'd':
|
||||
case 'o':
|
||||
case 'u':
|
||||
case 'x':
|
||||
case 'X':
|
||||
{
|
||||
size_t flen = strlen(fmt);
|
||||
int64_t fpos = flen - 1;
|
||||
char f = fmt[fpos];
|
||||
const char *prec = (const char *)_PRINT_INT_PREC;
|
||||
while(*prec != '\0') {
|
||||
fmt[fpos++] = *prec++;
|
||||
}
|
||||
fmt[fpos++] = f;
|
||||
fmt[fpos++] = '\0';
|
||||
}
|
||||
case 'c':
|
||||
if(SQ_FAILED(sq_getinteger(v,nparam,&ti)))
|
||||
return sq_throwerror(v,"integer expected for the specified format");
|
||||
addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(char));
|
||||
valtype = 'i';
|
||||
break;
|
||||
case 'f': case 'g': case 'G': case 'e': case 'E':
|
||||
if(SQ_FAILED(sq_getfloat(v,nparam,&tf)))
|
||||
return sq_throwerror(v,"float expected for the specified format");
|
||||
addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(char));
|
||||
valtype = 'f';
|
||||
break;
|
||||
default:
|
||||
return sq_throwerror(v,"invalid format");
|
||||
}
|
||||
n++;
|
||||
allocated += addlen + sizeof(char);
|
||||
dest = sq_getscratchpad(v,allocated);
|
||||
switch(valtype) {
|
||||
case 's': i += snprintf(&dest[i],allocated,fmt,ts); break;
|
||||
case 'i': i += snprintf(&dest[i],allocated,fmt,ti); break;
|
||||
case 'f': i += snprintf(&dest[i],allocated,fmt,tf); break;
|
||||
};
|
||||
nparam ++;
|
||||
}
|
||||
}
|
||||
*outlen = i;
|
||||
dest[i] = '\0';
|
||||
*output = dest;
|
||||
return SQ_OK;
|
||||
}
|
||||
|
||||
static int64_t _string_printf(rabbit::VirtualMachine* v)
|
||||
{
|
||||
char *dest = NULL;
|
||||
int64_t length = 0;
|
||||
if(SQ_FAILED(rabbit::std::format(v,2,&length,&dest)))
|
||||
return -1;
|
||||
|
||||
SQPRINTFUNCTION printfunc = sq_getprintfunc(v);
|
||||
if(printfunc) printfunc(v,dest);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int64_t _string_format(rabbit::VirtualMachine* v)
|
||||
{
|
||||
char *dest = NULL;
|
||||
int64_t length = 0;
|
||||
if(SQ_FAILED(rabbit::std::format(v,2,&length,&dest)))
|
||||
return -1;
|
||||
sq_pushstring(v,dest,length);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void __strip_l(const char *str,const char **start)
|
||||
{
|
||||
const char *t = str;
|
||||
while(((*t) != '\0') && isspace(*t)){ t++; }
|
||||
*start = t;
|
||||
}
|
||||
|
||||
static void __strip_r(const char *str,int64_t len,const char **end)
|
||||
{
|
||||
if(len == 0) {
|
||||
*end = str;
|
||||
return;
|
||||
}
|
||||
const char *t = &str[len-1];
|
||||
while(t >= str && isspace(*t)) { t--; }
|
||||
*end = t + 1;
|
||||
}
|
||||
|
||||
static int64_t _string_strip(rabbit::VirtualMachine* v)
|
||||
{
|
||||
const char *str,*start,*end;
|
||||
sq_getstring(v,2,&str);
|
||||
int64_t len = sq_getsize(v,2);
|
||||
__strip_l(str,&start);
|
||||
__strip_r(str,len,&end);
|
||||
sq_pushstring(v,start,end - start);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int64_t _string_lstrip(rabbit::VirtualMachine* v)
|
||||
{
|
||||
const char *str,*start;
|
||||
sq_getstring(v,2,&str);
|
||||
__strip_l(str,&start);
|
||||
sq_pushstring(v,start,-1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int64_t _string_rstrip(rabbit::VirtualMachine* v)
|
||||
{
|
||||
const char *str,*end;
|
||||
sq_getstring(v,2,&str);
|
||||
int64_t len = sq_getsize(v,2);
|
||||
__strip_r(str,len,&end);
|
||||
sq_pushstring(v,str,end - str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int64_t _string_split(rabbit::VirtualMachine* v)
|
||||
{
|
||||
const char *str,*seps;
|
||||
char *stemp;
|
||||
sq_getstring(v,2,&str);
|
||||
sq_getstring(v,3,&seps);
|
||||
int64_t sepsize = sq_getsize(v,3);
|
||||
if(sepsize == 0) return sq_throwerror(v,"empty separators string");
|
||||
int64_t memsize = (sq_getsize(v,2)+1)*sizeof(char);
|
||||
stemp = sq_getscratchpad(v,memsize);
|
||||
memcpy(stemp,str,memsize);
|
||||
char *start = stemp;
|
||||
char *end = stemp;
|
||||
sq_newarray(v,0);
|
||||
while(*end != '\0')
|
||||
{
|
||||
char cur = *end;
|
||||
for(int64_t i = 0; i < sepsize; i++)
|
||||
{
|
||||
if(cur == seps[i])
|
||||
{
|
||||
*end = 0;
|
||||
sq_pushstring(v,start,-1);
|
||||
sq_arrayappend(v,-2);
|
||||
start = end + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
end++;
|
||||
}
|
||||
if(end != start)
|
||||
{
|
||||
sq_pushstring(v,start,-1);
|
||||
sq_arrayappend(v,-2);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int64_t _string_escape(rabbit::VirtualMachine* v)
|
||||
{
|
||||
const char *str;
|
||||
char *dest,*resstr;
|
||||
int64_t size;
|
||||
sq_getstring(v,2,&str);
|
||||
size = sq_getsize(v,2);
|
||||
if(size == 0) {
|
||||
sq_push(v,2);
|
||||
return 1;
|
||||
}
|
||||
const char *escpat = "\\x%02x";
|
||||
const int64_t maxescsize = 4;
|
||||
int64_t destcharsize = (size * maxescsize); //assumes every char could be escaped
|
||||
resstr = dest = (char *)sq_getscratchpad(v,destcharsize * sizeof(char));
|
||||
char c;
|
||||
char escch;
|
||||
int64_t escaped = 0;
|
||||
for(int n = 0; n < size; n++){
|
||||
c = *str++;
|
||||
escch = 0;
|
||||
if(isprint(c) || c == 0) {
|
||||
switch(c) {
|
||||
case '\a': escch = 'a'; break;
|
||||
case '\b': escch = 'b'; break;
|
||||
case '\t': escch = 't'; break;
|
||||
case '\n': escch = 'n'; break;
|
||||
case '\v': escch = 'v'; break;
|
||||
case '\f': escch = 'f'; break;
|
||||
case '\r': escch = 'r'; break;
|
||||
case '\\': escch = '\\'; break;
|
||||
case '\"': escch = '\"'; break;
|
||||
case '\'': escch = '\''; break;
|
||||
case 0: escch = '0'; break;
|
||||
}
|
||||
if(escch) {
|
||||
*dest++ = '\\';
|
||||
*dest++ = escch;
|
||||
escaped++;
|
||||
}
|
||||
else {
|
||||
*dest++ = c;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
dest += snprintf(dest, destcharsize, escpat, c);
|
||||
escaped++;
|
||||
}
|
||||
}
|
||||
|
||||
if(escaped) {
|
||||
sq_pushstring(v,resstr,dest - resstr);
|
||||
}
|
||||
else {
|
||||
sq_push(v,2); //nothing escaped
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int64_t _string_startswith(rabbit::VirtualMachine* v)
|
||||
{
|
||||
const char *str,*cmp;
|
||||
sq_getstring(v,2,&str);
|
||||
sq_getstring(v,3,&cmp);
|
||||
int64_t len = sq_getsize(v,2);
|
||||
int64_t cmplen = sq_getsize(v,3);
|
||||
rabbit::Bool ret = SQFalse;
|
||||
if(cmplen <= len) {
|
||||
ret = memcmp(str,cmp,sq_rsl(cmplen)) == 0 ? SQTrue : SQFalse;
|
||||
}
|
||||
sq_pushbool(v,ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int64_t _string_endswith(rabbit::VirtualMachine* v)
|
||||
{
|
||||
const char *str,*cmp;
|
||||
sq_getstring(v,2,&str);
|
||||
sq_getstring(v,3,&cmp);
|
||||
int64_t len = sq_getsize(v,2);
|
||||
int64_t cmplen = sq_getsize(v,3);
|
||||
rabbit::Bool ret = SQFalse;
|
||||
if(cmplen <= len) {
|
||||
ret = memcmp(&str[len - cmplen],cmp,sq_rsl(cmplen)) == 0 ? SQTrue : SQFalse;
|
||||
}
|
||||
sq_pushbool(v,ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define SETUP_REX(v) \
|
||||
rabbit::std::SQRex *self = NULL; \
|
||||
rabbit::sq_getinstanceup(v,1,(rabbit::UserPointer *)&self,0);
|
||||
|
||||
static int64_t _rexobj_releasehook(rabbit::UserPointer p, int64_t SQ_UNUSED_ARG(size))
|
||||
{
|
||||
rabbit::std::SQRex *self = ((rabbit::std::SQRex *)p);
|
||||
rabbit::std::rex_free(self);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int64_t _regexp_match(rabbit::VirtualMachine* v)
|
||||
{
|
||||
SETUP_REX(v);
|
||||
const char *str;
|
||||
sq_getstring(v,2,&str);
|
||||
if(rabbit::std::rex_match(self,str) == SQTrue)
|
||||
{
|
||||
sq_pushbool(v,SQTrue);
|
||||
return 1;
|
||||
}
|
||||
sq_pushbool(v,SQFalse);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void _addrexmatch(rabbit::VirtualMachine* v,const char *str,const char *begin,const char *end)
|
||||
{
|
||||
sq_newtable(v);
|
||||
sq_pushstring(v,"begin",-1);
|
||||
sq_pushinteger(v,begin - str);
|
||||
sq_rawset(v,-3);
|
||||
sq_pushstring(v,"end",-1);
|
||||
sq_pushinteger(v,end - str);
|
||||
sq_rawset(v,-3);
|
||||
}
|
||||
|
||||
static int64_t _regexp_search(rabbit::VirtualMachine* v)
|
||||
{
|
||||
SETUP_REX(v);
|
||||
const char *str,*begin,*end;
|
||||
int64_t start = 0;
|
||||
sq_getstring(v,2,&str);
|
||||
if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
|
||||
if(rabbit::std::rex_search(self,str+start,&begin,&end) == SQTrue) {
|
||||
_addrexmatch(v,str,begin,end);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int64_t _regexp_capture(rabbit::VirtualMachine* v)
|
||||
{
|
||||
SETUP_REX(v);
|
||||
const char *str,*begin,*end;
|
||||
int64_t start = 0;
|
||||
sq_getstring(v,2,&str);
|
||||
if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
|
||||
if(rabbit::std::rex_search(self,str+start,&begin,&end) == SQTrue) {
|
||||
int64_t n = rabbit::std::rex_getsubexpcount(self);
|
||||
rabbit::std::SQRexMatch match;
|
||||
sq_newarray(v,0);
|
||||
for(int64_t i = 0;i < n; i++) {
|
||||
rabbit::std::rex_getsubexp(self,i,&match);
|
||||
if(match.len > 0)
|
||||
_addrexmatch(v,str,match.begin,match.begin+match.len);
|
||||
else
|
||||
_addrexmatch(v,str,str,str); //empty match
|
||||
sq_arrayappend(v,-2);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int64_t _regexp_subexpcount(rabbit::VirtualMachine* v)
|
||||
{
|
||||
SETUP_REX(v);
|
||||
sq_pushinteger(v,rabbit::std::rex_getsubexpcount(self));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int64_t _regexp_constructor(rabbit::VirtualMachine* v)
|
||||
{
|
||||
const char *error,*pattern;
|
||||
sq_getstring(v,2,&pattern);
|
||||
rabbit::std::SQRex *rex = rabbit::std::rex_compile(pattern,&error);
|
||||
if(!rex) return sq_throwerror(v,error);
|
||||
sq_setinstanceup(v,1,rex);
|
||||
sq_setreleasehook(v,1,_rexobj_releasehook);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int64_t _regexp__typeof(rabbit::VirtualMachine* v)
|
||||
{
|
||||
sq_pushstring(v,"regexp",-1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define _DECL_REX_FUNC(name,nparams,pmask) {#name,_regexp_##name,nparams,pmask}
|
||||
static const rabbit::RegFunction rexobj_funcs[]={
|
||||
_DECL_REX_FUNC(constructor,2,".s"),
|
||||
_DECL_REX_FUNC(search,-2,"xsn"),
|
||||
_DECL_REX_FUNC(match,2,"xs"),
|
||||
_DECL_REX_FUNC(capture,-2,"xsn"),
|
||||
_DECL_REX_FUNC(subexpcount,1,"x"),
|
||||
_DECL_REX_FUNC(_typeof,1,"x"),
|
||||
{NULL,(SQFUNCTION)0,0,NULL}
|
||||
};
|
||||
#undef _DECL_REX_FUNC
|
||||
|
||||
#define _DECL_FUNC(name,nparams,pmask) {#name,_string_##name,nparams,pmask}
|
||||
static const rabbit::RegFunction stringlib_funcs[]={
|
||||
_DECL_FUNC(format,-2,".s"),
|
||||
_DECL_FUNC(printf,-2,".s"),
|
||||
_DECL_FUNC(strip,2,".s"),
|
||||
_DECL_FUNC(lstrip,2,".s"),
|
||||
_DECL_FUNC(rstrip,2,".s"),
|
||||
_DECL_FUNC(split,3,".ss"),
|
||||
_DECL_FUNC(escape,2,".s"),
|
||||
_DECL_FUNC(startswith,3,".ss"),
|
||||
_DECL_FUNC(endswith,3,".ss"),
|
||||
{NULL,(SQFUNCTION)0,0,NULL}
|
||||
};
|
||||
#undef _DECL_FUNC
|
||||
|
||||
|
||||
int64_t rabbit::std::register_stringlib(rabbit::VirtualMachine* v)
|
||||
{
|
||||
sq_pushstring(v,"regexp",-1);
|
||||
sq_newclass(v,SQFalse);
|
||||
int64_t i = 0;
|
||||
while(rexobj_funcs[i].name != 0) {
|
||||
const rabbit::RegFunction &f = rexobj_funcs[i];
|
||||
sq_pushstring(v,f.name,-1);
|
||||
sq_newclosure(v,f.f,0);
|
||||
sq_setparamscheck(v,f.nparamscheck,f.typemask);
|
||||
sq_setnativeclosurename(v,-1,f.name);
|
||||
sq_newslot(v,-3,SQFalse);
|
||||
i++;
|
||||
}
|
||||
sq_newslot(v,-3,SQFalse);
|
||||
|
||||
i = 0;
|
||||
while(stringlib_funcs[i].name!=0)
|
||||
{
|
||||
sq_pushstring(v,stringlib_funcs[i].name,-1);
|
||||
sq_newclosure(v,stringlib_funcs[i].f,0);
|
||||
sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask);
|
||||
sq_setnativeclosurename(v,-1,stringlib_funcs[i].name);
|
||||
sq_newslot(v,-3,SQFalse);
|
||||
i++;
|
||||
}
|
||||
return 1;
|
||||
}
|
35
rabbit-std/sqstdstring.hpp
Normal file
35
rabbit-std/sqstdstring.hpp
Normal file
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <rabbit/RegFunction.hpp>
|
||||
|
||||
namespace rabbit {
|
||||
namespace std {
|
||||
using SQRexBool = unsigned int;
|
||||
using SQRex = struct SQRex;
|
||||
|
||||
typedef struct {
|
||||
const char *begin;
|
||||
int64_t len;
|
||||
} SQRexMatch;
|
||||
|
||||
SQRex *rex_compile(const char *pattern,const char **error);
|
||||
void rex_free(SQRex *exp);
|
||||
rabbit::Bool rex_match(SQRex* exp,const char* text);
|
||||
rabbit::Bool rex_search(SQRex* exp,const char* text, const char** out_begin, const char** out_end);
|
||||
rabbit::Bool rex_searchrange(SQRex* exp,const char* text_begin,const char* text_end,const char** out_begin, const char** out_end);
|
||||
int64_t rex_getsubexpcount(SQRex* exp);
|
||||
rabbit::Bool rex_getsubexp(SQRex* exp, int64_t n, SQRexMatch *subexp);
|
||||
|
||||
rabbit::Result format(rabbit::VirtualMachine* v,int64_t nformatstringidx,int64_t *outlen,char **output);
|
||||
|
||||
rabbit::Result register_stringlib(rabbit::VirtualMachine* v);
|
||||
|
||||
}
|
||||
}
|
140
rabbit-std/sqstdsystem.cpp
Normal file
140
rabbit-std/sqstdsystem.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
|
||||
#include <rabbit/rabbit.hpp>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <rabbit-std/sqstdsystem.hpp>
|
||||
|
||||
#include <rabbit/RegFunction.hpp>
|
||||
|
||||
static int64_t _system_getenv(rabbit::VirtualMachine* v)
|
||||
{
|
||||
const char *s;
|
||||
if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
|
||||
sq_pushstring(v,getenv(s),-1);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int64_t _system_system(rabbit::VirtualMachine* v)
|
||||
{
|
||||
const char *s;
|
||||
if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
|
||||
sq_pushinteger(v,system(s));
|
||||
return 1;
|
||||
}
|
||||
return sq_throwerror(v,"wrong param");
|
||||
}
|
||||
|
||||
|
||||
static int64_t _system_clock(rabbit::VirtualMachine* v)
|
||||
{
|
||||
sq_pushfloat(v,((float_t)clock())/(float_t)CLOCKS_PER_SEC);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int64_t _system_time(rabbit::VirtualMachine* v)
|
||||
{
|
||||
int64_t t = (int64_t)time(NULL);
|
||||
sq_pushinteger(v,t);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int64_t _system_remove(rabbit::VirtualMachine* v)
|
||||
{
|
||||
const char *s;
|
||||
sq_getstring(v,2,&s);
|
||||
if(remove(s)==-1)
|
||||
return sq_throwerror(v,"remove() failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int64_t _system_rename(rabbit::VirtualMachine* v)
|
||||
{
|
||||
const char *oldn,*newn;
|
||||
sq_getstring(v,2,&oldn);
|
||||
sq_getstring(v,3,&newn);
|
||||
if(rename(oldn,newn)==-1)
|
||||
return sq_throwerror(v,"rename() failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _set_integer_slot(rabbit::VirtualMachine* v,const char *name,int64_t val)
|
||||
{
|
||||
sq_pushstring(v,name,-1);
|
||||
sq_pushinteger(v,val);
|
||||
sq_rawset(v,-3);
|
||||
}
|
||||
|
||||
static int64_t _system_date(rabbit::VirtualMachine* v)
|
||||
{
|
||||
time_t t;
|
||||
int64_t it;
|
||||
int64_t format = 'l';
|
||||
if(sq_gettop(v) > 1) {
|
||||
sq_getinteger(v,2,&it);
|
||||
t = it;
|
||||
if(sq_gettop(v) > 2) {
|
||||
sq_getinteger(v,3,(int64_t*)&format);
|
||||
}
|
||||
}
|
||||
else {
|
||||
time(&t);
|
||||
}
|
||||
tm *date;
|
||||
if(format == 'u')
|
||||
date = gmtime(&t);
|
||||
else
|
||||
date = localtime(&t);
|
||||
if(!date)
|
||||
return sq_throwerror(v,"crt api failure");
|
||||
sq_newtable(v);
|
||||
_set_integer_slot(v, "sec", date->tm_sec);
|
||||
_set_integer_slot(v, "min", date->tm_min);
|
||||
_set_integer_slot(v, "hour", date->tm_hour);
|
||||
_set_integer_slot(v, "day", date->tm_mday);
|
||||
_set_integer_slot(v, "month", date->tm_mon);
|
||||
_set_integer_slot(v, "year", date->tm_year+1900);
|
||||
_set_integer_slot(v, "wday", date->tm_wday);
|
||||
_set_integer_slot(v, "yday", date->tm_yday);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define _DECL_FUNC(name,nparams,pmask) {#name,_system_##name,nparams,pmask}
|
||||
static const rabbit::RegFunction systemlib_funcs[]={
|
||||
_DECL_FUNC(getenv,2,".s"),
|
||||
_DECL_FUNC(system,2,".s"),
|
||||
_DECL_FUNC(clock,0,NULL),
|
||||
_DECL_FUNC(time,1,NULL),
|
||||
_DECL_FUNC(date,-1,".nn"),
|
||||
_DECL_FUNC(remove,2,".s"),
|
||||
_DECL_FUNC(rename,3,".ss"),
|
||||
{NULL,(SQFUNCTION)0,0,NULL}
|
||||
};
|
||||
#undef _DECL_FUNC
|
||||
|
||||
int64_t rabbit::std::register_systemlib(rabbit::VirtualMachine* v)
|
||||
{
|
||||
int64_t i=0;
|
||||
while(systemlib_funcs[i].name!=0)
|
||||
{
|
||||
sq_pushstring(v,systemlib_funcs[i].name,-1);
|
||||
sq_newclosure(v,systemlib_funcs[i].f,0);
|
||||
sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask);
|
||||
sq_setnativeclosurename(v,-1,systemlib_funcs[i].name);
|
||||
sq_newslot(v,-3,SQFalse);
|
||||
i++;
|
||||
}
|
||||
return 1;
|
||||
}
|
14
rabbit-std/sqstdsystem.hpp
Normal file
14
rabbit-std/sqstdsystem.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace rabbit {
|
||||
namespace std {
|
||||
int64_t register_systemlib(rabbit::VirtualMachine* v);
|
||||
}
|
||||
}
|
135
rabbit/Array.cpp
Normal file
135
rabbit/Array.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#include <rabbit/Array.hpp>
|
||||
#include <rabbit/squtils.hpp>
|
||||
#include <rabbit/WeakRef.hpp>
|
||||
|
||||
|
||||
|
||||
void rabbit::Array::extend(const rabbit::Array *a){
|
||||
int64_t xlen = a->size();
|
||||
// TODO: check this condition...
|
||||
if(xlen) {
|
||||
for(int64_t iii=0;iii<xlen;++iii) {
|
||||
append((*a)[iii]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rabbit::Array::Array(rabbit::SharedState* _ss, int64_t _nsize) {
|
||||
m_data.resize(_nsize);
|
||||
}
|
||||
rabbit::Array::~Array() {
|
||||
// TODO: Clean DATA ...
|
||||
}
|
||||
// TODO : remove this ETK_ALLOC can do it natively ...
|
||||
rabbit::Array* rabbit::Array::create(rabbit::SharedState* _ss,
|
||||
int64_t _ninitialsize) {
|
||||
Array *newarray = ETK_NEW(Array, _ss, _ninitialsize);
|
||||
return newarray;
|
||||
}
|
||||
void rabbit::Array::finalize() {
|
||||
m_data.resize(0);
|
||||
}
|
||||
bool rabbit::Array::get(const int64_t _nidx, rabbit::ObjectPtr& _val) const {
|
||||
if( _nidx >= 0
|
||||
&& _nidx < (int64_t)m_data.size()){
|
||||
rabbit::ObjectPtr &o = m_data[_nidx];
|
||||
_val = o.getRealObject();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool rabbit::Array::set(const int64_t _nidx,const rabbit::ObjectPtr& _val) const {
|
||||
if(_nidx>=0 && _nidx<(int64_t)m_data.size()){
|
||||
m_data[_nidx] = _val;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
int64_t rabbit::Array::next(const rabbit::ObjectPtr& _refpos,
|
||||
rabbit::ObjectPtr& _outkey,
|
||||
rabbit::ObjectPtr& _outval) {
|
||||
uint64_t idx=translateIndex(_refpos);
|
||||
while(idx<m_data.size()){
|
||||
//first found
|
||||
_outkey=(int64_t)idx;
|
||||
rabbit::ObjectPtr& o = m_data[idx];
|
||||
_outval = o.getRealObject();
|
||||
//return idx for the next iteration
|
||||
return ++idx;
|
||||
}
|
||||
//nothing to iterate anymore
|
||||
return -1;
|
||||
}
|
||||
rabbit::Array* rabbit::Array::clone() const {
|
||||
Array *anew = create(NULL,0);
|
||||
anew->m_data = m_data;
|
||||
return anew;
|
||||
}
|
||||
int64_t rabbit::Array::size() const {
|
||||
return m_data.size();
|
||||
}
|
||||
void rabbit::Array::resize(int64_t _size) {
|
||||
rabbit::ObjectPtr empty;
|
||||
resize(_size, empty);
|
||||
}
|
||||
void rabbit::Array::resize(int64_t _size,
|
||||
rabbit::ObjectPtr& _fill) {
|
||||
m_data.resize(_size, _fill);
|
||||
shrinkIfNeeded();
|
||||
}
|
||||
void rabbit::Array::reserve(int64_t _size) {
|
||||
m_data.reserve(_size);
|
||||
}
|
||||
void rabbit::Array::append(const rabbit::Object& _o) {
|
||||
m_data.pushBack(_o);
|
||||
}
|
||||
|
||||
rabbit::ObjectPtr& rabbit::Array::top(){
|
||||
return m_data.back();
|
||||
}
|
||||
void rabbit::Array::pop() {
|
||||
m_data.popBack();
|
||||
shrinkIfNeeded();
|
||||
}
|
||||
bool rabbit::Array::insert(int64_t _idx,const rabbit::Object& _val) {
|
||||
if( _idx < 0
|
||||
|| _idx > (int64_t)m_data.size()) {
|
||||
return false;
|
||||
}
|
||||
m_data.insert(_idx, _val);
|
||||
return true;
|
||||
}
|
||||
void rabbit::Array::shrinkIfNeeded() {
|
||||
// TODO: Check this. No real need with etk ==> automatic ...
|
||||
/*
|
||||
if(m_data.size() <= m_data.capacity()>>2) {
|
||||
//shrink the array
|
||||
m_data.shrinktofit();
|
||||
}
|
||||
*/
|
||||
}
|
||||
bool rabbit::Array::remove(int64_t _idx) {
|
||||
if( _idx < 0
|
||||
|| _idx >= (int64_t)m_data.size()) {
|
||||
return false;
|
||||
}
|
||||
m_data.remove(_idx);
|
||||
shrinkIfNeeded();
|
||||
return true;
|
||||
}
|
||||
void rabbit::Array::release() {
|
||||
ETK_DELETE(Array, this);
|
||||
}
|
||||
rabbit::ObjectPtr& rabbit::Array::operator[] (const size_t _pos) {
|
||||
return m_data[_pos];
|
||||
}
|
||||
const rabbit::ObjectPtr& rabbit::Array::operator[] (const size_t _pos) const {
|
||||
return m_data[_pos];
|
||||
}
|
52
rabbit/Array.hpp
Normal file
52
rabbit/Array.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <rabbit/RefCounted.hpp>
|
||||
#include <rabbit/ObjectPtr.hpp>
|
||||
#include <etk/Vector.hpp>
|
||||
|
||||
namespace rabbit {
|
||||
class SharedState;
|
||||
class Array : public rabbit::RefCounted {
|
||||
private:
|
||||
Array(rabbit::SharedState* _ss,
|
||||
int64_t _nsize);
|
||||
~Array();
|
||||
public:
|
||||
// TODO : remove this ETK_ALLOC can do it natively ...
|
||||
static Array* create(rabbit::SharedState* _ss,
|
||||
int64_t _ninitialsize);
|
||||
void finalize();
|
||||
bool get(const int64_t _nidx,
|
||||
rabbit::ObjectPtr& _val) const;
|
||||
bool set(const int64_t _nidx,const rabbit::ObjectPtr& _val) const;
|
||||
int64_t next(const rabbit::ObjectPtr& _refpos,
|
||||
rabbit::ObjectPtr& _outkey,
|
||||
rabbit::ObjectPtr& _outval);
|
||||
Array* clone() const;
|
||||
int64_t size() const;
|
||||
void resize(int64_t _size);
|
||||
void resize(int64_t _size,
|
||||
rabbit::ObjectPtr& _fill);
|
||||
void reserve(int64_t _size);
|
||||
void append(const rabbit::Object& _o);
|
||||
void extend(const Array* _a);
|
||||
rabbit::ObjectPtr &top();
|
||||
void pop();
|
||||
bool insert(int64_t _idx,const rabbit::Object& _val);
|
||||
void shrinkIfNeeded();
|
||||
bool remove(int64_t _idx);
|
||||
void release();
|
||||
rabbit::ObjectPtr& operator[] (const size_t _pos);
|
||||
const rabbit::ObjectPtr& operator[] (const size_t _pos) const;
|
||||
private:
|
||||
mutable etk::Vector<rabbit::ObjectPtr> m_data;
|
||||
};
|
||||
}
|
||||
|
18
rabbit/AutoDec.cpp
Normal file
18
rabbit/AutoDec.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
|
||||
#include <rabbit/AutoDec.hpp>
|
||||
|
||||
rabbit::AutoDec::AutoDec(int64_t* _count) {
|
||||
m_countPointer = _count;
|
||||
}
|
||||
|
||||
rabbit::AutoDec::~AutoDec() {
|
||||
(*m_countPointer)--;
|
||||
}
|
||||
|
22
rabbit/AutoDec.hpp
Normal file
22
rabbit/AutoDec.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <rabbit/rabbit.hpp>
|
||||
|
||||
namespace rabbit {
|
||||
class AutoDec {
|
||||
public:
|
||||
AutoDec(int64_t* _count);
|
||||
~AutoDec();
|
||||
private:
|
||||
int64_t* m_countPointer;
|
||||
};
|
||||
}
|
||||
|
185
rabbit/Class.cpp
Normal file
185
rabbit/Class.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#include <rabbit/Class.hpp>
|
||||
#include <rabbit/Instance.hpp>
|
||||
#include <rabbit/Table.hpp>
|
||||
#include <rabbit/SharedState.hpp>
|
||||
#include <rabbit/squtils.hpp>
|
||||
|
||||
#include <rabbit/VirtualMachine.hpp>
|
||||
#include <rabbit/WeakRef.hpp>
|
||||
#include <rabbit/Closure.hpp>
|
||||
|
||||
rabbit::Class::Class(rabbit::SharedState *ss, rabbit::Class *base) {
|
||||
_base = base;
|
||||
_typetag = 0;
|
||||
_hook = NULL;
|
||||
_udsize = 0;
|
||||
_locked = false;
|
||||
_constructoridx = -1;
|
||||
if(_base) {
|
||||
_constructoridx = _base->_constructoridx;
|
||||
_udsize = _base->_udsize;
|
||||
_defaultvalues = base->_defaultvalues;
|
||||
_methods = base->_methods;
|
||||
_COPY_VECTOR(_metamethods,base->_metamethods, rabbit::MT_LAST);
|
||||
__ObjaddRef(_base);
|
||||
}
|
||||
_members = base?base->_members->clone() : rabbit::Table::create(ss,0);
|
||||
__ObjaddRef(_members);
|
||||
}
|
||||
|
||||
void rabbit::Class::finalize() {
|
||||
_attributes.Null();
|
||||
_NULL_SQOBJECT_VECTOR(_defaultvalues,_defaultvalues.size());
|
||||
_methods.resize(0);
|
||||
_NULL_SQOBJECT_VECTOR(_metamethods, rabbit::MT_LAST);
|
||||
__Objrelease(_members);
|
||||
if(_base) {
|
||||
__Objrelease(_base);
|
||||
}
|
||||
}
|
||||
|
||||
rabbit::Class::~Class() {
|
||||
finalize();
|
||||
}
|
||||
|
||||
rabbit::Class* rabbit::Class::create(rabbit::SharedState *ss, Class *base) {
|
||||
rabbit::Class *newclass = ETK_NEW(Class, ss, base);
|
||||
return newclass;
|
||||
}
|
||||
|
||||
bool rabbit::Class::get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val) {
|
||||
if(_members->get(key,val)) {
|
||||
if(_isfield(val)) {
|
||||
rabbit::ObjectPtr &o = _defaultvalues[_member_idx(val)].val;
|
||||
val = o.getRealObject();
|
||||
} else {
|
||||
val = _methods[_member_idx(val)].val;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool rabbit::Class::getConstructor(rabbit::ObjectPtr &ctor) {
|
||||
if(_constructoridx != -1) {
|
||||
ctor = _methods[_constructoridx].val;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void rabbit::Class::lock() {
|
||||
_locked = true;
|
||||
if(_base) {
|
||||
_base->lock();
|
||||
}
|
||||
}
|
||||
|
||||
void rabbit::Class::release() {
|
||||
if (_hook) {
|
||||
_hook(_typetag,0);
|
||||
}
|
||||
ETK_DELETE(Class, this);
|
||||
}
|
||||
|
||||
bool rabbit::Class::newSlot(rabbit::SharedState *ss,const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val,bool bstatic) {
|
||||
rabbit::ObjectPtr temp;
|
||||
bool belongs_to_static_table = val.isClosure() == true
|
||||
|| val.isNativeClosure() == true
|
||||
|| bstatic;
|
||||
if(_locked && !belongs_to_static_table) {
|
||||
//the class already has an instance so cannot be modified
|
||||
return false;
|
||||
}
|
||||
//overrides the default value
|
||||
if(_members->get(key,temp) && _isfield(temp)) {
|
||||
_defaultvalues[_member_idx(temp)].val = val;
|
||||
return true;
|
||||
}
|
||||
if(belongs_to_static_table) {
|
||||
int64_t mmidx;
|
||||
if( ( val.isClosure() == true
|
||||
|| val.isNativeClosure() == true )
|
||||
&& (mmidx = ss->getMetaMethodIdxByName(key)) != -1) {
|
||||
_metamethods[mmidx] = val;
|
||||
} else {
|
||||
rabbit::ObjectPtr theval = val;
|
||||
if(_base && val.isClosure() == true) {
|
||||
theval = const_cast<rabbit::Closure*>(val.toClosure())->clone();
|
||||
theval.toClosure()->_base = _base;
|
||||
__ObjaddRef(_base); //ref for the closure
|
||||
}
|
||||
if(temp.isNull() == true) {
|
||||
bool isconstructor;
|
||||
rabbit::VirtualMachine::isEqual(ss->_constructoridx, key, isconstructor);
|
||||
if(isconstructor) {
|
||||
_constructoridx = (int64_t)_methods.size();
|
||||
}
|
||||
rabbit::ClassMember m;
|
||||
m.val = theval;
|
||||
_members->newSlot(key,rabbit::ObjectPtr(_make_method_idx(_methods.size())));
|
||||
_methods.pushBack(m);
|
||||
} else {
|
||||
_methods[_member_idx(temp)].val = theval;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
rabbit::ClassMember m;
|
||||
m.val = val;
|
||||
_members->newSlot(key,rabbit::ObjectPtr(_make_field_idx(_defaultvalues.size())));
|
||||
_defaultvalues.pushBack(m);
|
||||
return true;
|
||||
}
|
||||
|
||||
rabbit::Instance *rabbit::Class::createInstance() {
|
||||
if(!_locked) {
|
||||
lock();
|
||||
}
|
||||
return rabbit::Instance::create(NULL,this);
|
||||
}
|
||||
|
||||
int64_t rabbit::Class::next(const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey, rabbit::ObjectPtr &outval) {
|
||||
rabbit::ObjectPtr oval;
|
||||
int64_t idx = _members->next(false,refpos,outkey,oval);
|
||||
if(idx != -1) {
|
||||
if(_ismethod(oval)) {
|
||||
outval = _methods[_member_idx(oval)].val;
|
||||
} else {
|
||||
rabbit::ObjectPtr &o = _defaultvalues[_member_idx(oval)].val;
|
||||
outval = o.getRealObject();
|
||||
}
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
bool rabbit::Class::setAttributes(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val) {
|
||||
rabbit::ObjectPtr idx;
|
||||
if(_members->get(key,idx)) {
|
||||
if(_isfield(idx)) {
|
||||
_defaultvalues[_member_idx(idx)].attrs = val;
|
||||
} else {
|
||||
_methods[_member_idx(idx)].attrs = val;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool rabbit::Class::getAttributes(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &outval) {
|
||||
rabbit::ObjectPtr idx;
|
||||
if(_members->get(key,idx)) {
|
||||
outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
51
rabbit/Class.hpp
Normal file
51
rabbit/Class.hpp
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
|
||||
#include <rabbit/VirtualMachine.hpp>
|
||||
|
||||
|
||||
|
||||
#include <rabbit/ClassMember.hpp>
|
||||
|
||||
namespace rabbit {
|
||||
class Class : public rabbit::RefCounted {
|
||||
public:
|
||||
Class(rabbit::SharedState *ss,rabbit::Class *base);
|
||||
public:
|
||||
static Class* create(rabbit::SharedState *ss, Class *base);
|
||||
~Class();
|
||||
bool newSlot(rabbit::SharedState *ss, const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val,bool bstatic);
|
||||
bool get(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &val);
|
||||
bool getConstructor(rabbit::ObjectPtr &ctor);
|
||||
bool setAttributes(const rabbit::ObjectPtr &key,const rabbit::ObjectPtr &val);
|
||||
bool getAttributes(const rabbit::ObjectPtr &key,rabbit::ObjectPtr &outval);
|
||||
void lock();
|
||||
void release();
|
||||
void finalize();
|
||||
int64_t next(const rabbit::ObjectPtr &refpos, rabbit::ObjectPtr &outkey, rabbit::ObjectPtr &outval);
|
||||
rabbit::Instance *createInstance();
|
||||
rabbit::Table *_members;
|
||||
rabbit::Class *_base;
|
||||
etk::Vector<rabbit::ClassMember> _defaultvalues;
|
||||
etk::Vector<rabbit::ClassMember> _methods;
|
||||
rabbit::ObjectPtr _metamethods[rabbit::MT_LAST];
|
||||
rabbit::ObjectPtr _attributes;
|
||||
rabbit::UserPointer _typetag;
|
||||
SQRELEASEHOOK _hook;
|
||||
bool _locked;
|
||||
int64_t _constructoridx;
|
||||
int64_t _udsize;
|
||||
};
|
||||
#define calcinstancesize(_theclass_) \
|
||||
(_theclass_->_udsize + sq_aligning(sizeof(rabbit::Instance) + (sizeof(rabbit::ObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0))))
|
||||
|
||||
};
|
||||
|
9
rabbit/ClassMember.cpp
Normal file
9
rabbit/ClassMember.cpp
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#include <rabbit/ClassMember.hpp>
|
||||
|
37
rabbit/ClassMember.hpp
Normal file
37
rabbit/ClassMember.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <rabbit/sqconfig.hpp>
|
||||
|
||||
#include <rabbit/ObjectPtr.hpp>
|
||||
|
||||
|
||||
|
||||
#define MEMBER_TYPE_METHOD 0x01000000
|
||||
#define MEMBER_TYPE_FIELD 0x02000000
|
||||
|
||||
#define _ismethod(o) (o.toInteger()&MEMBER_TYPE_METHOD)
|
||||
#define _isfield(o) (o.toInteger()&MEMBER_TYPE_FIELD)
|
||||
#define _make_method_idx(i) ((int64_t)(MEMBER_TYPE_METHOD|i))
|
||||
#define _make_field_idx(i) ((int64_t)(MEMBER_TYPE_FIELD|i))
|
||||
#define _member_type(o) (o.toInteger()&0xFF000000)
|
||||
#define _member_idx(o) (o.toInteger()&0x00FFFFFF)
|
||||
|
||||
namespace rabbit {
|
||||
class ClassMember {
|
||||
public:
|
||||
rabbit::ObjectPtr val;
|
||||
rabbit::ObjectPtr attrs;
|
||||
void Null() {
|
||||
val.Null();
|
||||
attrs.Null();
|
||||
}
|
||||
};
|
||||
}
|
195
rabbit/Closure.cpp
Normal file
195
rabbit/Closure.cpp
Normal file
@@ -0,0 +1,195 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#include <rabbit/Closure.hpp>
|
||||
#include <rabbit/VirtualMachine.hpp>
|
||||
#include <rabbit/rabbit.hpp>
|
||||
|
||||
#include <rabbit/ObjectPtr.hpp>
|
||||
#include <rabbit/WeakRef.hpp>
|
||||
#include <rabbit/FunctionProto.hpp>
|
||||
|
||||
#include <rabbit/LocalVarInfo.hpp>
|
||||
#include <rabbit/LineInfo.hpp>
|
||||
#include <rabbit/OuterVar.hpp>
|
||||
#include <rabbit/String.hpp>
|
||||
#include <rabbit/SharedState.hpp>
|
||||
#include <rabbit/Table.hpp>
|
||||
#include <rabbit/Class.hpp>
|
||||
#include <rabbit/RefCounted.hpp>
|
||||
#include <rabbit/squtils.hpp>
|
||||
|
||||
|
||||
|
||||
bool rabbit::SafeWrite(rabbit::VirtualMachine* v,SQWRITEFUNC write,rabbit::UserPointer up,rabbit::UserPointer dest,int64_t size)
|
||||
{
|
||||
if(write(up,dest,size) != size) {
|
||||
v->raise_error("io error (write function failure)");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rabbit::SafeRead(rabbit::VirtualMachine* v,SQWRITEFUNC read,rabbit::UserPointer up,rabbit::UserPointer dest,int64_t size)
|
||||
{
|
||||
if(size && read(up,dest,size) != size) {
|
||||
v->raise_error("io error, read function failure, the origin stream could be corrupted/trucated");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rabbit::WriteTag(rabbit::VirtualMachine* v,SQWRITEFUNC write,rabbit::UserPointer up,uint32_t tag)
|
||||
{
|
||||
return SafeWrite(v,write,up,&tag,sizeof(tag));
|
||||
}
|
||||
|
||||
bool rabbit::CheckTag(rabbit::VirtualMachine* v,SQWRITEFUNC read,rabbit::UserPointer up,uint32_t tag)
|
||||
{
|
||||
uint32_t t;
|
||||
_CHECK_IO(SafeRead(v,read,up,&t,sizeof(t)));
|
||||
if(t != tag){
|
||||
v->raise_error("invalid or corrupted closure stream");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rabbit::WriteObject(rabbit::VirtualMachine* v,rabbit::UserPointer up,SQWRITEFUNC write,rabbit::ObjectPtr &o)
|
||||
{
|
||||
uint32_t _type = (uint32_t)o.getType();
|
||||
_CHECK_IO(SafeWrite(v,write,up,&_type,sizeof(_type)));
|
||||
switch(o.getType()){
|
||||
case rabbit::OT_STRING:
|
||||
_CHECK_IO(SafeWrite(v,write,up,&o.toString()->_len,sizeof(int64_t)));
|
||||
_CHECK_IO(SafeWrite(v,write,up,o.getStringValue(),sq_rsl(o.toString()->_len)));
|
||||
break;
|
||||
case rabbit::OT_BOOL:
|
||||
case rabbit::OT_INTEGER:
|
||||
_CHECK_IO(SafeWrite(v,write,up,&o.toInteger(),sizeof(int64_t)));break;
|
||||
case rabbit::OT_FLOAT:
|
||||
_CHECK_IO(SafeWrite(v,write,up,&o.toFloat(),sizeof(float_t)));break;
|
||||
case rabbit::OT_NULL:
|
||||
break;
|
||||
default:
|
||||
v->raise_error("cannot serialize a %s",getTypeName(o));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rabbit::ReadObject(rabbit::VirtualMachine* v,rabbit::UserPointer up,SQREADFUNC read,rabbit::ObjectPtr &o)
|
||||
{
|
||||
uint32_t _type;
|
||||
_CHECK_IO(SafeRead(v,read,up,&_type,sizeof(_type)));
|
||||
rabbit::ObjectType t = (rabbit::ObjectType)_type;
|
||||
switch(t){
|
||||
case rabbit::OT_STRING:{
|
||||
int64_t len;
|
||||
_CHECK_IO(SafeRead(v,read,up,&len,sizeof(int64_t)));
|
||||
_CHECK_IO(SafeRead(v,read,up,_get_shared_state(v)->getScratchPad(sq_rsl(len)),sq_rsl(len)));
|
||||
o=rabbit::String::create(_get_shared_state(v),_get_shared_state(v)->getScratchPad(-1),len);
|
||||
}
|
||||
break;
|
||||
case rabbit::OT_INTEGER:{
|
||||
int64_t i;
|
||||
_CHECK_IO(SafeRead(v,read,up,&i,sizeof(int64_t))); o = i; break;
|
||||
}
|
||||
case rabbit::OT_BOOL:{
|
||||
int64_t i;
|
||||
_CHECK_IO(SafeRead(v,read,up,&i,sizeof(int64_t))); o._type = rabbit::OT_BOOL; o._unVal.nInteger = i; break;
|
||||
}
|
||||
case rabbit::OT_FLOAT:{
|
||||
float_t f;
|
||||
_CHECK_IO(SafeRead(v,read,up,&f,sizeof(float_t))); o = f; break;
|
||||
}
|
||||
case rabbit::OT_NULL:
|
||||
o.Null();
|
||||
break;
|
||||
default:
|
||||
v->raise_error("cannot serialize a %s",IdType2Name(t));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rabbit::Closure::save(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQWRITEFUNC write)
|
||||
{
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD));
|
||||
_CHECK_IO(WriteTag(v,write,up,sizeof(char)));
|
||||
_CHECK_IO(WriteTag(v,write,up,sizeof(int64_t)));
|
||||
_CHECK_IO(WriteTag(v,write,up,sizeof(float_t)));
|
||||
_CHECK_IO(_function->save(v,up,write));
|
||||
_CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rabbit::Closure::load(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQREADFUNC read,rabbit::ObjectPtr &ret)
|
||||
{
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD));
|
||||
_CHECK_IO(CheckTag(v,read,up,sizeof(char)));
|
||||
_CHECK_IO(CheckTag(v,read,up,sizeof(int64_t)));
|
||||
_CHECK_IO(CheckTag(v,read,up,sizeof(float_t)));
|
||||
rabbit::ObjectPtr func;
|
||||
_CHECK_IO(rabbit::FunctionProto::load(v,up,read,func));
|
||||
_CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL));
|
||||
ret = rabbit::Closure::create(_get_shared_state(v),func.toFunctionProto(),v->_roottable.toTable()->getWeakRef(rabbit::OT_TABLE));
|
||||
//FIXME: load an root for this closure
|
||||
return true;
|
||||
}
|
||||
|
||||
rabbit::Closure::~Closure() {
|
||||
__Objrelease(_root);
|
||||
__Objrelease(_env);
|
||||
__Objrelease(_base);
|
||||
}
|
||||
|
||||
rabbit::Closure::Closure(rabbit::SharedState *ss,rabbit::FunctionProto *func){
|
||||
_function = func;
|
||||
__ObjaddRef(_function); _base = NULL;
|
||||
_env = NULL;
|
||||
_root=NULL;
|
||||
}
|
||||
rabbit::Closure *rabbit::Closure::create(rabbit::SharedState *ss,rabbit::FunctionProto *func,rabbit::WeakRef *root){
|
||||
int64_t size = _CALC_CLOSURE_SIZE(func);
|
||||
rabbit::Closure *nc = ETK_NEW(rabbit::Closure, ss, func);
|
||||
nc->_outervalues = (rabbit::ObjectPtr *)(nc + 1);
|
||||
nc->_defaultparams = &nc->_outervalues[func->_noutervalues];
|
||||
nc->_root = root;
|
||||
__ObjaddRef(nc->_root);
|
||||
_CONSTRUCT_VECTOR(rabbit::ObjectPtr,func->_noutervalues,nc->_outervalues);
|
||||
_CONSTRUCT_VECTOR(rabbit::ObjectPtr,func->_ndefaultparams,nc->_defaultparams);
|
||||
return nc;
|
||||
}
|
||||
|
||||
void rabbit::Closure::release(){
|
||||
rabbit::FunctionProto *f = _function;
|
||||
int64_t size = _CALC_CLOSURE_SIZE(f);
|
||||
_DESTRUCT_VECTOR(ObjectPtr,f->_noutervalues,_outervalues);
|
||||
_DESTRUCT_VECTOR(ObjectPtr,f->_ndefaultparams,_defaultparams);
|
||||
__Objrelease(_function);
|
||||
ETK_FREE(Closure, this);
|
||||
}
|
||||
|
||||
void rabbit::Closure::setRoot(rabbit::WeakRef *r) {
|
||||
__Objrelease(_root);
|
||||
_root = r;
|
||||
__ObjaddRef(_root);
|
||||
}
|
||||
|
||||
rabbit::Closure* rabbit::Closure::clone() {
|
||||
rabbit::FunctionProto *f = _function;
|
||||
rabbit::Closure * ret = rabbit::Closure::create(NULL,f,_root);
|
||||
ret->_env = _env;
|
||||
if(ret->_env) {
|
||||
__ObjaddRef(ret->_env);
|
||||
}
|
||||
_COPY_VECTOR(ret->_outervalues,_outervalues,f->_noutervalues);
|
||||
_COPY_VECTOR(ret->_defaultparams,_defaultparams,f->_ndefaultparams);
|
||||
return ret;
|
||||
}
|
||||
|
56
rabbit/Closure.hpp
Normal file
56
rabbit/Closure.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <rabbit/RefCounted.hpp>
|
||||
#include <rabbit/sqconfig.hpp>
|
||||
#include <rabbit/rabbit.hpp>
|
||||
#include <rabbit/squtils.hpp>
|
||||
|
||||
namespace rabbit {
|
||||
class SharedState;
|
||||
class FunctionProto;
|
||||
class VirtualMachine;
|
||||
class WeakRef;
|
||||
class ObjectPtr;
|
||||
class Class;
|
||||
|
||||
|
||||
#define _CALC_CLOSURE_SIZE(func) (sizeof(rabbit::Closure) + (func->_noutervalues*sizeof(rabbit::ObjectPtr)) + (func->_ndefaultparams*sizeof(rabbit::ObjectPtr)))
|
||||
|
||||
class Closure : public rabbit::RefCounted {
|
||||
private:
|
||||
Closure(rabbit::SharedState *ss,rabbit::FunctionProto *func);
|
||||
public:
|
||||
static Closure *create(rabbit::SharedState *ss,rabbit::FunctionProto *func,rabbit::WeakRef *root);
|
||||
void release();
|
||||
void setRoot(rabbit::WeakRef *r);
|
||||
Closure *clone();
|
||||
~Closure();
|
||||
|
||||
bool save(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQWRITEFUNC write);
|
||||
static bool load(rabbit::VirtualMachine *v,rabbit::UserPointer up,SQREADFUNC read,rabbit::ObjectPtr &ret);
|
||||
rabbit::WeakRef *_env;
|
||||
rabbit::WeakRef *_root;
|
||||
rabbit::Class *_base;
|
||||
rabbit::FunctionProto *_function;
|
||||
rabbit::ObjectPtr *_outervalues;
|
||||
rabbit::ObjectPtr *_defaultparams;
|
||||
};
|
||||
bool SafeWrite(rabbit::VirtualMachine* v,SQWRITEFUNC write,rabbit::UserPointer up,rabbit::UserPointer dest,int64_t size);
|
||||
bool SafeRead(rabbit::VirtualMachine* v,SQWRITEFUNC read,rabbit::UserPointer up,rabbit::UserPointer dest,int64_t size);
|
||||
bool WriteTag(rabbit::VirtualMachine* v,SQWRITEFUNC write,rabbit::UserPointer up,uint32_t tag);
|
||||
bool CheckTag(rabbit::VirtualMachine* v,SQWRITEFUNC read,rabbit::UserPointer up,uint32_t tag);
|
||||
bool WriteObject(rabbit::VirtualMachine* v,rabbit::UserPointer up,SQWRITEFUNC write,rabbit::ObjectPtr &o);
|
||||
bool ReadObject(rabbit::VirtualMachine* v,rabbit::UserPointer up,SQREADFUNC read,rabbit::ObjectPtr &o);
|
||||
|
||||
}
|
||||
#define _CHECK_IO(exp) { if(!exp)return false; }
|
||||
#define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R'))
|
||||
#define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T'))
|
||||
#define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L'))
|
1621
rabbit/Compiler.cpp
Normal file
1621
rabbit/Compiler.cpp
Normal file
File diff suppressed because it is too large
Load Diff
88
rabbit/Compiler.hpp
Normal file
88
rabbit/Compiler.hpp
Normal file
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <rabbit/sqconfig.hpp>
|
||||
#include <rabbit/rabbit.hpp>
|
||||
#include <rabbit/ObjectPtr.hpp>
|
||||
|
||||
namespace rabbit {
|
||||
#define TK_IDENTIFIER 258
|
||||
#define TK_STRING_LITERAL 259
|
||||
#define TK_INTEGER 260
|
||||
#define TK_FLOAT 261
|
||||
#define TK_BASE 262
|
||||
#define TK_DELETE 263
|
||||
#define TK_EQ 264
|
||||
#define TK_NE 265
|
||||
#define TK_LE 266
|
||||
#define TK_GE 267
|
||||
#define TK_SWITCH 268
|
||||
#define TK_ARROW 269
|
||||
#define TK_AND 270
|
||||
#define TK_OR 271
|
||||
#define TK_IF 272
|
||||
#define TK_ELSE 273
|
||||
#define TK_WHILE 274
|
||||
#define TK_BREAK 275
|
||||
#define TK_FOR 276
|
||||
#define TK_DO 277
|
||||
#define TK_NULL 278
|
||||
#define TK_FOREACH 279
|
||||
#define TK_IN 280
|
||||
#define TK_NEWSLOT 281
|
||||
#define TK_MODULO 282
|
||||
#define TK_LOCAL 283
|
||||
#define TK_CLONE 284
|
||||
#define TK_FUNCTION 285
|
||||
#define TK_RETURN 286
|
||||
#define TK_TYPEOF 287
|
||||
#define TK_UMINUS 288
|
||||
#define TK_PLUSEQ 289
|
||||
#define TK_MINUSEQ 290
|
||||
#define TK_CONTINUE 291
|
||||
#define TK_YIELD 292
|
||||
#define TK_TRY 293
|
||||
#define TK_CATCH 294
|
||||
#define TK_THROW 295
|
||||
#define TK_SHIFTL 296
|
||||
#define TK_SHIFTR 297
|
||||
#define TK_RESUME 298
|
||||
#define TK_DOUBLE_COLON 299
|
||||
#define TK_CASE 300
|
||||
#define TK_DEFAULT 301
|
||||
#define TK_THIS 302
|
||||
#define TK_PLUSPLUS 303
|
||||
#define TK_MINUSMINUS 304
|
||||
#define TK_3WAYSCMP 305
|
||||
#define TK_USHIFTR 306
|
||||
#define TK_CLASS 307
|
||||
#define TK_EXTENDS 308
|
||||
#define TK_CONSTRUCTOR 310
|
||||
#define TK_INSTANCEOF 311
|
||||
#define TK_VARPARAMS 312
|
||||
#define TK___LINE__ 313
|
||||
#define TK___FILE__ 314
|
||||
#define TK_TRUE 315
|
||||
#define TK_FALSE 316
|
||||
#define TK_MULEQ 317
|
||||
#define TK_DIVEQ 318
|
||||
#define TK_MODEQ 319
|
||||
#define TK_ATTR_OPEN 320
|
||||
#define TK_ATTR_CLOSE 321
|
||||
#define TK_STATIC 322
|
||||
#define TK_ENUM 323
|
||||
#define TK_CONST 324
|
||||
#define TK_RAWCALL 325
|
||||
|
||||
|
||||
|
||||
typedef void(*compilererrorFunc)(void *ud, const char *s);
|
||||
bool compile(rabbit::VirtualMachine *vm, SQLEXREADFUNC rg, rabbit::UserPointer up, const char *sourcename, rabbit::ObjectPtr &out, bool raiseerror, bool lineinfo);
|
||||
|
||||
}
|
42
rabbit/Delegable.cpp
Normal file
42
rabbit/Delegable.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
|
||||
#include <rabbit/Delegable.hpp>
|
||||
|
||||
#include <rabbit/VirtualMachine.hpp>
|
||||
#include <rabbit/Table.hpp>
|
||||
#include <rabbit/SharedState.hpp>
|
||||
|
||||
|
||||
bool rabbit::Delegable::getMetaMethod(rabbit::VirtualMachine *v,rabbit::MetaMethod mm,rabbit::ObjectPtr &res) const {
|
||||
if(_delegate) {
|
||||
return _delegate->get((*_get_shared_state(v)->_metamethods)[mm],res);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool rabbit::Delegable::setDelegate(rabbit::Table *mt) {
|
||||
rabbit::Table *temp = mt;
|
||||
if(temp == this) {
|
||||
return false;
|
||||
}
|
||||
while (temp) {
|
||||
if (temp->_delegate == this) {
|
||||
//cycle detected
|
||||
return false;
|
||||
}
|
||||
temp = temp->_delegate;
|
||||
}
|
||||
if (mt) {
|
||||
__ObjaddRef(mt);
|
||||
}
|
||||
__Objrelease(_delegate);
|
||||
_delegate = mt;
|
||||
return true;
|
||||
}
|
||||
|
25
rabbit/Delegable.hpp
Normal file
25
rabbit/Delegable.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <rabbit/RefCounted.hpp>
|
||||
#include <rabbit/MetaMethod.hpp>
|
||||
#include <rabbit/ObjectPtr.hpp>
|
||||
|
||||
namespace rabbit {
|
||||
class Table;
|
||||
class VirtualMachine;
|
||||
class Delegable : public rabbit::RefCounted {
|
||||
public:
|
||||
bool setDelegate(rabbit::Table *m);
|
||||
public:
|
||||
virtual bool getMetaMethod(rabbit::VirtualMachine *v, rabbit::MetaMethod mm, rabbit::ObjectPtr& res) const;
|
||||
mutable rabbit::Table *_delegate;
|
||||
};
|
||||
}
|
25
rabbit/ExceptionTrap.cpp
Normal file
25
rabbit/ExceptionTrap.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
|
||||
#include <rabbit/ExceptionTrap.hpp>
|
||||
#include <rabbit/Instruction.hpp>
|
||||
|
||||
|
||||
rabbit::ExceptionTrap::ExceptionTrap(int64_t ss,
|
||||
int64_t stackbase,
|
||||
rabbit::Instruction *ip,
|
||||
int64_t ex_target) {
|
||||
_stacksize = ss;
|
||||
_stackbase = stackbase;
|
||||
_ip = ip;
|
||||
_extarget = ex_target;
|
||||
}
|
||||
|
||||
rabbit::ExceptionTrap::ExceptionTrap(const rabbit::ExceptionTrap &et) {
|
||||
(*this) = et;
|
||||
}
|
29
rabbit/ExceptionTrap.hpp
Normal file
29
rabbit/ExceptionTrap.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <rabbit/sqconfig.hpp>
|
||||
|
||||
namespace rabbit {
|
||||
class Instruction;
|
||||
class ExceptionTrap {
|
||||
public:
|
||||
ExceptionTrap() = default;
|
||||
ExceptionTrap(int64_t ss,
|
||||
int64_t stackbase,
|
||||
rabbit::Instruction *ip,
|
||||
int64_t ex_target);
|
||||
ExceptionTrap(const rabbit::ExceptionTrap &et);
|
||||
|
||||
int64_t _stackbase = 0;
|
||||
int64_t _stacksize = 0;
|
||||
rabbit::Instruction *_ip = nullptr;
|
||||
int64_t _extarget = 0;
|
||||
};
|
||||
}
|
679
rabbit/FuncState.cpp
Normal file
679
rabbit/FuncState.cpp
Normal file
@@ -0,0 +1,679 @@
|
||||
/**
|
||||
* @author Alberto DEMICHELIS
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @copyright 2003-2017, Alberto DEMICHELIS, all right reserved
|
||||
* @license MPL-2 (see license file)
|
||||
*/
|
||||
#include <rabbit/Compiler.hpp>
|
||||
#include <rabbit/FuncState.hpp>
|
||||
|
||||
#ifndef NO_COMPILER
|
||||
#include <rabbit/Compiler.hpp>
|
||||
|
||||
#include <rabbit/FunctionProto.hpp>
|
||||
#include <rabbit/Instruction.hpp>
|
||||
#include <rabbit/String.hpp>
|
||||
#include <rabbit/Class.hpp>
|
||||
#include <rabbit/Table.hpp>
|
||||
#include <rabbit/SharedState.hpp>
|
||||
|
||||
|
||||
|
||||
#include <rabbit/sqopcodes.hpp>
|
||||
#include <rabbit/squtils.hpp>
|
||||
|
||||
#define UINT_MINUS_ONE (0xFFFFFFFFFFFFFFFF)
|
||||
|
||||
|
||||
#ifdef _DEBUG_DUMP
|
||||
rabbit::InstructionDesc g_InstrDesc[]={
|
||||
{"_OP_LINE"},
|
||||
{"_OP_LOAD"},
|
||||
{"_OP_LOADINT"},
|
||||
{"_OP_LOADFLOAT"},
|
||||
{"_OP_DLOAD"},
|
||||
{"_OP_TAILCALL"},
|
||||
{"_OP_CALL"},
|
||||
{"_OP_PREPCALL"},
|
||||
{"_OP_PREPCALLK"},
|
||||
{"_OP_GETK"},
|
||||
{"_OP_MOVE"},
|
||||
{"_OP_NEWSLOT"},
|
||||
{"_OP_DELETE"},
|
||||
{"_OP_SET"},
|
||||
{"_OP_GET"},
|
||||
{"_OP_EQ"},
|
||||
{"_OP_NE"},
|
||||
{"_OP_ADD"},
|
||||
{"_OP_SUB"},
|
||||
{"_OP_MUL"},
|
||||
{"_OP_DIV"},
|
||||
{"_OP_MOD"},
|
||||
{"_OP_BITW"},
|
||||
{"_OP_RETURN"},
|
||||
{"_OP_LOADNULLS"},
|
||||
{"_OP_LOADROOT"},
|
||||
{"_OP_LOADBOOL"},
|
||||
{"_OP_DMOVE"},
|
||||
{"_OP_JMP"},
|
||||
{"_OP_JCMP"},
|
||||
{"_OP_JZ"},
|
||||
{"_OP_SETOUTER"},
|
||||
{"_OP_GETOUTER"},
|
||||
{"_OP_NEWOBJ"},
|
||||
{"_OP_APPENDARRAY"},
|
||||
{"_OP_COMPARITH"},
|
||||
{"_OP_INC"},
|
||||
{"_OP_INCL"},
|
||||
{"_OP_PINC"},
|
||||
{"_OP_PINCL"},
|
||||
{"_OP_CMP"},
|
||||
{"_OP_EXISTS"},
|
||||
{"_OP_INSTANCEOF"},
|
||||
{"_OP_AND"},
|
||||
{"_OP_OR"},
|
||||
{"_OP_NEG"},
|
||||
{"_OP_NOT"},
|
||||
{"_OP_BWNOT"},
|
||||
{"_OP_CLOSURE"},
|
||||
{"_OP_YIELD"},
|
||||
{"_OP_RESUME"},
|
||||
{"_OP_FOREACH"},
|
||||
{"_OP_POSTFOREACH"},
|
||||
{"_OP_CLONE"},
|
||||
{"_OP_TYPEOF"},
|
||||
{"_OP_PUSHTRAP"},
|
||||
{"_OP_POPTRAP"},
|
||||
{"_OP_THROW"},
|
||||
{"_OP_NEWSLOTA"},
|
||||
{"_OP_GETBASE"},
|
||||
{"_OP_CLOSE"},
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
void rabbit::FuncState::addInstruction(SQOpcode _op,int64_t arg0,int64_t arg1,int64_t arg2,int64_t arg3){
|
||||
rabbit::Instruction i(_op,arg0,arg1,arg2,arg3);
|
||||
addInstruction(i);
|
||||
}
|
||||
|
||||
static void dumpLiteral(rabbit::ObjectPtr &o) {
|
||||
switch(o.getType()){
|
||||
case rabbit::OT_STRING:
|
||||
printf("\"%s\"",o.getStringValue());
|
||||
break;
|
||||
case rabbit::OT_FLOAT:
|
||||
printf("{%f}",o.toFloat());
|
||||
break;
|
||||
case rabbit::OT_INTEGER:
|
||||
printf("{" _PRINT_INT_FMT "}",o.toInteger());
|
||||
break;
|
||||
case rabbit::OT_BOOL:
|
||||
printf("%s",o.toInteger()?"true":"false");
|
||||
break;
|
||||
default:
|
||||
printf("(%s %p)",getTypeName(o),(void*)o.toRaw());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rabbit::FuncState::FuncState(rabbit::SharedState *ss,rabbit::FuncState *parent,compilererrorFunc efunc,void *ed)
|
||||
{
|
||||
_nliterals = 0;
|
||||
_literals = rabbit::Table::create(ss,0);
|
||||
_strings = rabbit::Table::create(ss,0);
|
||||
_sharedstate = ss;
|
||||
_lastline = 0;
|
||||
_optimization = true;
|
||||
_parent = parent;
|
||||
_stacksize = 0;
|
||||
_traps = 0;
|
||||
_returnexp = 0;
|
||||
_varparams = false;
|
||||
_errfunc = efunc;
|
||||
_errtarget = ed;
|
||||
_bgenerator = false;
|
||||
_outers = 0;
|
||||
_ss = ss;
|
||||
|
||||
}
|
||||
|
||||
void rabbit::FuncState::error(const char *err)
|
||||
{
|
||||
_errfunc(_errtarget,err);
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_DUMP
|
||||
void rabbit::FuncState::dump(rabbit::FunctionProto *func)
|
||||
{
|
||||
uint64_t n=0,i;
|
||||
int64_t si;
|
||||
printf("rabbit::Instruction sizeof %d\n",(int32_t)sizeof(rabbit::Instruction));
|
||||
printf("rabbit::Object sizeof %d\n", (int32_t)sizeof(rabbit::Object));
|
||||
printf("--------------------------------------------------------------------\n");
|
||||
printf("*****FUNCTION [%s]\n",func->_name.isString() == true?func->_name.getStringValue():"unknown");
|
||||
printf("-----LITERALS\n");
|
||||
rabbit::ObjectPtr refidx,key,val;
|
||||
int64_t idx;
|
||||
etk::Vector<rabbit::ObjectPtr> templiterals;
|
||||
templiterals.resize(_nliterals);
|
||||
while((idx=_literals.toTable()->next(false,refidx,key,val))!=-1) {
|
||||
refidx=idx;
|
||||
templiterals[val.toInteger()]=key;
|
||||
}
|
||||
for(i=0;i<templiterals.size();i++){
|
||||
printf("[%d] ", (int32_t)n);
|
||||
dumpLiteral(templiterals[i]);
|
||||
printf("\n");
|
||||
n++;
|
||||
}
|
||||
printf("-----PARAMS\n");
|
||||
if(_varparams)
|
||||
printf("<<VARPARAMS>>\n");
|
||||
n=0;
|
||||
for(i=0;i<_parameters.size();i++){
|
||||
printf("[%d] ", (int32_t)n);
|
||||
dumpLiteral(_parameters[i]);
|
||||
printf("\n");
|
||||
n++;
|
||||
}
|
||||
printf("-----LOCALS\n");
|
||||
for(si=0;si<func->_nlocalvarinfos;si++){
|
||||
rabbit::LocalVarInfo lvi=func->_localvarinfos[si];
|
||||
printf("[%d] %s \t%d %d\n", (int32_t)lvi._pos,lvi._name.getStringValue(), (int32_t)lvi._start_op, (int32_t)lvi._end_op);
|
||||
n++;
|
||||
}
|
||||
printf("-----LINE INFO\n");
|
||||
for(i=0;i<_lineinfos.size();i++){
|
||||
rabbit::LineInfo li=_lineinfos[i];
|
||||
printf("op [%d] line [%d] \n", (int32_t)li._op, (int32_t)li._line);
|
||||
n++;
|
||||
}
|
||||
printf("-----dump\n");
|
||||
n=0;
|
||||
for(i=0;i<_instructions.size();i++){
|
||||
rabbit::Instruction &inst=_instructions[i];
|
||||
if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){
|
||||
|
||||
int64_t lidx = inst._arg1;
|
||||
printf("[%03d] %15s %d ", (int32_t)n,g_InstrDesc[inst.op].name,inst._arg0);
|
||||
if(lidx >= 0xFFFFFFFF)
|
||||
printf("null");
|
||||
else {
|
||||
int64_t refidx;
|
||||
rabbit::ObjectPtr val,key,refo;
|
||||
while(((refidx=_literals.toTable()->next(false,refo,key,val))!= -1) && (val.toInteger() != lidx)) {
|
||||
refo = refidx;
|
||||
}
|
||||
dumpLiteral(key);
|
||||
}
|
||||
if(inst.op != _OP_DLOAD) {
|
||||
printf(" %d %d \n",inst._arg2,inst._arg3);
|
||||
}
|
||||
else {
|
||||
printf(" %d ",inst._arg2);
|
||||
lidx = inst._arg3;
|
||||
if(lidx >= 0xFFFFFFFF)
|
||||
printf("null");
|
||||
else {
|
||||
int64_t refidx;
|
||||
rabbit::ObjectPtr val,key,refo;
|
||||
while(((refidx=_literals.toTable()->next(false,refo,key,val))!= -1) && (val.toInteger() != lidx)) {
|
||||
refo = refidx;
|
||||
}
|
||||
dumpLiteral(key);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(inst.op==_OP_LOADFLOAT) {
|
||||
printf("[%03d] %15s %d %f %d %d\n", (int32_t)n,g_InstrDesc[inst.op].name,inst._arg0,*((float_t*)&inst._arg1),inst._arg2,inst._arg3);
|
||||
}
|
||||
/* else if(inst.op==_OP_ARITH){
|
||||
printf("[%03d] %15s %d %d %d %c\n",n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
|
||||
}*/
|
||||
else {
|
||||
printf("[%03d] %15s %d %d %d %d\n", (int32_t)n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
|
||||
}
|
||||
n++;
|
||||
}
|
||||
printf("-----\n");
|
||||
printf("stack size[%d]\n", (int32_t)func->_stacksize);
|
||||
printf("--------------------------------------------------------------------\n\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
int64_t rabbit::FuncState::getNumericConstant(const int64_t cons)
|
||||
{
|
||||
return getConstant(rabbit::ObjectPtr(cons));
|
||||
}
|
||||
|
||||
int64_t rabbit::FuncState::getNumericConstant(const float_t cons)
|
||||
{
|
||||
return getConstant(rabbit::ObjectPtr(cons));
|
||||
}
|
||||
|
||||
int64_t rabbit::FuncState::getConstant(const rabbit::Object &cons)
|
||||
{
|
||||
rabbit::ObjectPtr val;
|
||||
if(!_literals.toTable()->get(cons,val))
|
||||
{
|
||||
val = _nliterals;
|
||||
_literals.toTable()->newSlot(cons,val);
|
||||
_nliterals++;
|
||||
if(_nliterals > MAX_LITERALS) {
|
||||
val.Null();
|
||||
error("internal compiler error: too many literals");
|
||||
}
|
||||
}
|
||||
return val.toInteger();
|
||||
}
|
||||
|
||||
void rabbit::FuncState::setIntructionParams(int64_t pos,int64_t arg0,int64_t arg1,int64_t arg2,int64_t arg3)
|
||||
{
|
||||
_instructions[pos]._arg0=(unsigned char)*((uint64_t *)&arg0);
|
||||
_instructions[pos]._arg1=(int32_t)*((uint64_t *)&arg1);
|
||||
_instructions[pos]._arg2=(unsigned char)*((uint64_t *)&arg2);
|
||||
_instructions[pos]._arg3=(unsigned char)*((uint64_t *)&arg3);
|
||||
}
|
||||
|
||||
void rabbit::FuncState::setIntructionParam(int64_t pos,int64_t arg,int64_t val)
|
||||
{
|
||||
switch(arg){
|
||||
case 0:_instructions[pos]._arg0=(unsigned char)*((uint64_t *)&val);break;
|
||||
case 1:case 4:_instructions[pos]._arg1=(int32_t)*((uint64_t *)&val);break;
|
||||
case 2:_instructions[pos]._arg2=(unsigned char)*((uint64_t *)&val);break;
|
||||
case 3:_instructions[pos]._arg3=(unsigned char)*((uint64_t *)&val);break;
|
||||
};
|
||||
}
|
||||
|
||||
int64_t rabbit::FuncState::allocStackPos()
|
||||
{
|
||||
int64_t npos=_vlocals.size();
|
||||
_vlocals.pushBack(rabbit::LocalVarInfo());
|
||||
if(_vlocals.size()>((uint64_t)_stacksize)) {
|
||||
if(_stacksize>MAX_FUNC_STACKSIZE) error("internal compiler error: too many locals");
|
||||
_stacksize=_vlocals.size();
|
||||
}
|
||||
return npos;
|
||||
}
|
||||
|
||||
int64_t rabbit::FuncState::pushTarget(int64_t n)
|
||||
{
|
||||
if(n!=-1){
|
||||
_targetstack.pushBack(n);
|
||||
return n;
|
||||
}
|
||||
n=allocStackPos();
|
||||
_targetstack.pushBack(n);
|
||||
return n;
|
||||
}
|
||||
|
||||
int64_t rabbit::FuncState::getUpTarget(int64_t n){
|
||||
return _targetstack[((_targetstack.size()-1)-n)];
|
||||
}
|
||||
|
||||
int64_t rabbit::FuncState::topTarget(){
|
||||
return _targetstack.back();
|
||||
}
|
||||
int64_t rabbit::FuncState::popTarget()
|
||||
{
|
||||
uint64_t npos=_targetstack.back();
|
||||
assert(npos < _vlocals.size());
|
||||
rabbit::LocalVarInfo &t = _vlocals[npos];
|
||||
if(t._name.isNull()==true){
|
||||
_vlocals.popBack();
|
||||
}
|
||||
_targetstack.popBack();
|
||||
return npos;
|
||||
}
|
||||
|
||||
int64_t rabbit::FuncState::getStacksize()
|
||||
{
|
||||
return _vlocals.size();
|
||||
}
|
||||
|
||||
int64_t rabbit::FuncState::CountOuters(int64_t stacksize)
|
||||
{
|
||||
int64_t outers = 0;
|
||||
int64_t k = _vlocals.size() - 1;
|
||||
while(k >= stacksize) {
|
||||
rabbit::LocalVarInfo &lvi = _vlocals[k];
|
||||
k--;
|
||||
if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer
|
||||
outers++;
|
||||
}
|
||||
}
|
||||
return outers;
|
||||
}
|
||||
|
||||
void rabbit::FuncState::setStacksize(int64_t n)
|
||||
{
|
||||
int64_t size=_vlocals.size();
|
||||
while(size>n){
|
||||
size--;
|
||||
rabbit::LocalVarInfo lvi = _vlocals.back();
|
||||
if(lvi._name.isNull()==false){
|
||||
if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer
|
||||
_outers--;
|
||||
}
|
||||
lvi._end_op = getCurrentPos();
|
||||
_localvarinfos.pushBack(lvi);
|
||||
}
|
||||
_vlocals.popBack();
|
||||
}
|
||||
}
|
||||
|
||||
bool rabbit::FuncState::isConstant(const rabbit::Object &name,rabbit::Object &e)
|
||||
{
|
||||
rabbit::ObjectPtr val;
|
||||
if(_sharedstate->_consts.toTable()->get(name,val)) {
|
||||
e = val;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool rabbit::FuncState::isLocal(uint64_t stkpos)
|
||||
{
|
||||
if(stkpos>=_vlocals.size()) {
|
||||
return false;
|
||||
} else if(_vlocals[stkpos]._name.isNull()==false) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t rabbit::FuncState::pushLocalVariable(const rabbit::Object &name)
|
||||
{
|
||||
int64_t pos=_vlocals.size();
|
||||
rabbit::LocalVarInfo lvi;
|
||||
lvi._name=name;
|
||||
lvi._start_op=getCurrentPos()+1;
|
||||
lvi._pos=_vlocals.size();
|
||||
_vlocals.pushBack(lvi);
|
||||
if(_vlocals.size()>((uint64_t)_stacksize))_stacksize=_vlocals.size();
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int64_t rabbit::FuncState::getLocalVariable(const rabbit::Object &name)
|
||||
{
|
||||
int64_t locals=_vlocals.size();
|
||||
while(locals>=1){
|
||||
rabbit::LocalVarInfo &lvi = _vlocals[locals-1];
|
||||
if( lvi._name.isString() == true
|
||||
&& lvi._name.toString() == name.toString()){
|
||||
return locals-1;
|
||||
}
|
||||
locals--;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void rabbit::FuncState::markLocalAsOuter(int64_t pos)
|
||||
{
|
||||
rabbit::LocalVarInfo &lvi = _vlocals[pos];
|
||||
lvi._end_op = UINT_MINUS_ONE;
|
||||
_outers++;
|
||||
}
|
||||
|
||||
int64_t rabbit::FuncState::getOuterVariable(const rabbit::Object &name)
|
||||
{
|
||||
int64_t outers = _outervalues.size();
|
||||
for(int64_t i = 0; i<outers; i++) {
|
||||
if(_outervalues[i]._name.toString() == name.toString())
|
||||
return i;
|
||||
}
|
||||
int64_t pos=-1;
|
||||
if(_parent) {
|
||||
pos = _parent->getLocalVariable(name);
|
||||
if(pos == -1) {
|
||||
pos = _parent->getOuterVariable(name);
|
||||
if(pos != -1) {
|
||||
_outervalues.pushBack(rabbit::OuterVar(name,rabbit::ObjectPtr(int64_t(pos)),otOUTER)); //local
|
||||
return _outervalues.size() - 1;
|
||||
}
|
||||
} else {
|
||||
_parent->markLocalAsOuter(pos);
|
||||
_outervalues.pushBack(rabbit::OuterVar(name,rabbit::ObjectPtr(int64_t(pos)),otLOCAL)); //local
|
||||
return _outervalues.size() - 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void rabbit::FuncState::addParameter(const rabbit::Object &name)
|
||||
{
|
||||
pushLocalVariable(name);
|
||||
_parameters.pushBack(name);
|
||||
}
|
||||
|
||||
void rabbit::FuncState::addLineInfos(int64_t line,bool lineop,bool force)
|
||||
{
|
||||
if(_lastline!=line || force){
|
||||
rabbit::LineInfo li;
|
||||
li._line=line;li._op=(getCurrentPos()+1);
|
||||
if(lineop)addInstruction(_OP_LINE,0,line);
|
||||
if(_lastline!=line) {
|
||||
_lineinfos.pushBack(li);
|
||||
}
|
||||
_lastline=line;
|
||||
}
|
||||
}
|
||||
|
||||
void rabbit::FuncState::discardTarget()
|
||||
{
|
||||
int64_t discardedtarget = popTarget();
|
||||
int64_t size = _instructions.size();
|
||||
if(size > 0 && _optimization){
|
||||
rabbit::Instruction &pi = _instructions[size-1];//previous instruction
|
||||
switch(pi.op) {
|
||||
case _OP_SET:case _OP_NEWSLOT:case _OP_SETOUTER:case _OP_CALL:
|
||||
if(pi._arg0 == discardedtarget) {
|
||||
pi._arg0 = 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rabbit::FuncState::addInstruction(rabbit::Instruction &i)
|
||||
{
|
||||
int64_t size = _instructions.size();
|
||||
if(size > 0 && _optimization){ //simple optimizer
|
||||
rabbit::Instruction &pi = _instructions[size-1];//previous instruction
|
||||
switch(i.op) {
|
||||
case _OP_JZ:
|
||||
if( pi.op == _OP_CMP && pi._arg1 < 0xFF) {
|
||||
pi.op = _OP_JCMP;
|
||||
pi._arg0 = (unsigned char)pi._arg1;
|
||||
pi._arg1 = i._arg1;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case _OP_SET:
|
||||
case _OP_NEWSLOT:
|
||||
if(i._arg0 == i._arg3) {
|
||||
i._arg0 = 0xFF;
|
||||
}
|
||||
break;
|
||||
case _OP_SETOUTER:
|
||||
if(i._arg0 == i._arg2) {
|
||||
i._arg0 = 0xFF;
|
||||
}
|
||||
break;
|
||||
case _OP_RETURN:
|
||||
if( _parent && i._arg0 != MAX_FUNC_STACKSIZE && pi.op == _OP_CALL && _returnexp < size-1) {
|
||||
pi.op = _OP_TAILCALL;
|
||||
} else if(pi.op == _OP_CLOSE){
|
||||
pi = i;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case _OP_GET:
|
||||
if( pi.op == _OP_LOAD && pi._arg0 == i._arg2 && (!isLocal(pi._arg0))){
|
||||
pi._arg1 = pi._arg1;
|
||||
pi._arg2 = (unsigned char)i._arg1;
|
||||
pi.op = _OP_GETK;
|
||||
pi._arg0 = i._arg0;
|
||||
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case _OP_PREPCALL:
|
||||
if( pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!isLocal(pi._arg0))){
|
||||
pi.op = _OP_PREPCALLK;
|
||||
pi._arg0 = i._arg0;
|
||||
pi._arg1 = pi._arg1;
|
||||
pi._arg2 = i._arg2;
|
||||
pi._arg3 = i._arg3;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case _OP_APPENDARRAY: {
|
||||
int64_t aat = -1;
|
||||
switch(pi.op) {
|
||||
case _OP_LOAD: aat = AAT_LITERAL; break;
|
||||
case _OP_LOADINT: aat = AAT_INT; break;
|
||||
case _OP_LOADBOOL: aat = AAT_BOOL; break;
|
||||
case _OP_LOADFLOAT: aat = AAT_FLOAT; break;
|
||||
default: break;
|
||||
}
|
||||
if(aat != -1 && pi._arg0 == i._arg1 && (!isLocal(pi._arg0))){
|
||||
pi.op = _OP_APPENDARRAY;
|
||||
pi._arg0 = i._arg0;
|
||||
pi._arg1 = pi._arg1;
|
||||
pi._arg2 = (unsigned char)aat;
|
||||
pi._arg3 = MAX_FUNC_STACKSIZE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case _OP_MOVE:
|
||||
switch(pi.op) {
|
||||
case _OP_GET: case _OP_ADD: case _OP_SUB: case _OP_MUL: case _OP_DIV: case _OP_MOD: case _OP_BITW:
|
||||
case _OP_LOADINT: case _OP_LOADFLOAT: case _OP_LOADBOOL: case _OP_LOAD:
|
||||
|
||||
if(pi._arg0 == i._arg1)
|
||||
{
|
||||
pi._arg0 = i._arg0;
|
||||
_optimization = false;
|
||||
//_result_elimination = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(pi.op == _OP_MOVE)
|
||||
{
|
||||
pi.op = _OP_DMOVE;
|
||||
pi._arg2 = i._arg0;
|
||||
pi._arg3 = (unsigned char)i._arg1;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case _OP_LOAD:
|
||||
if(pi.op == _OP_LOAD && i._arg1 < 256) {
|
||||
pi.op = _OP_DLOAD;
|
||||
pi._arg2 = i._arg0;
|
||||
pi._arg3 = (unsigned char)i._arg1;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case _OP_EQ:case _OP_NE:
|
||||
if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!isLocal(pi._arg0) ))
|
||||
{
|
||||
pi.op = i.op;
|
||||
pi._arg0 = i._arg0;
|
||||
pi._arg1 = pi._arg1;
|
||||
pi._arg2 = i._arg2;
|
||||
pi._arg3 = MAX_FUNC_STACKSIZE;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case _OP_LOADNULLS:
|
||||
if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) {
|
||||
|
||||
pi._arg1 = pi._arg1 + 1;
|
||||
pi.op = _OP_LOADNULLS;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case _OP_LINE:
|
||||
if(pi.op == _OP_LINE) {
|
||||
_instructions.popBack();
|
||||
_lineinfos.popBack();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
_optimization = true;
|
||||
_instructions.pushBack(i);
|
||||
}
|
||||
|
||||
rabbit::Object rabbit::FuncState::createString(const char *s,int64_t len)
|
||||
{
|
||||
rabbit::ObjectPtr ns(rabbit::String::create(_sharedstate,s,len));
|
||||
_strings.toTable()->newSlot(ns,(int64_t)1);
|
||||
return ns;
|
||||
}
|
||||
|
||||
rabbit::Object rabbit::FuncState::createTable()
|
||||
{
|
||||
rabbit::ObjectPtr nt(rabbit::Table::create(_sharedstate,0));
|
||||
_strings.toTable()->newSlot(nt,(int64_t)1);
|
||||
return nt;
|
||||
}
|
||||
|
||||
rabbit::FunctionProto* rabbit::FuncState::buildProto() {
|
||||
rabbit::FunctionProto *f=rabbit::FunctionProto::create(_ss,_instructions.size(),
|
||||
_nliterals,_parameters.size(),_functions.size(),_outervalues.size(),
|
||||
_lineinfos.size(),_localvarinfos.size(),_defaultparams.size());
|
||||
|
||||
rabbit::ObjectPtr refidx,key,val;
|
||||
int64_t idx;
|
||||
|
||||
f->_stacksize = _stacksize;
|
||||
f->_sourcename = _sourcename;
|
||||
f->_bgenerator = _bgenerator;
|
||||
f->_name = _name;
|
||||
|
||||
while((idx=_literals.toTable()->next(false,refidx,key,val))!=-1) {
|
||||
f->_literals[val.toInteger()]=key;
|
||||
refidx=idx;
|
||||
}
|
||||
|
||||
for(uint64_t nf = 0; nf < _functions.size(); nf++) f->_functions[nf] = _functions[nf];
|
||||
for(uint64_t np = 0; np < _parameters.size(); np++) f->_parameters[np] = _parameters[np];
|
||||
for(uint64_t no = 0; no < _outervalues.size(); no++) f->_outervalues[no] = _outervalues[no];
|
||||
for(uint64_t nl = 0; nl < _localvarinfos.size(); nl++) f->_localvarinfos[nl] = _localvarinfos[nl];
|
||||
for(uint64_t ni = 0; ni < _lineinfos.size(); ni++) f->_lineinfos[ni] = _lineinfos[ni];
|
||||
for(uint64_t nd = 0; nd < _defaultparams.size(); nd++) f->_defaultparams[nd] = _defaultparams[nd];
|
||||
|
||||
memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(rabbit::Instruction));
|
||||
|
||||
f->_varparams = _varparams;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
rabbit::FuncState *rabbit::FuncState::pushChildState(rabbit::SharedState *ss) {
|
||||
FuncState *child = ETK_NEW(rabbit::FuncState, ss, this, _errfunc, _errtarget);
|
||||
_childstates.pushBack(child);
|
||||
return child;
|
||||
}
|
||||
|
||||
void rabbit::FuncState::popChildState() {
|
||||
FuncState *child = _childstates.back();
|
||||
ETK_DELETE(FuncState, child);
|
||||
_childstates.popBack();
|
||||
}
|
||||
|
||||
rabbit::FuncState::~FuncState() {
|
||||
while(_childstates.size() > 0) {
|
||||
popChildState();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user