[906] | 1 | /*
|
---|
| 2 | * TinyJS
|
---|
| 3 | *
|
---|
| 4 | * A single-file Javascript-alike engine
|
---|
| 5 | *
|
---|
| 6 | * Authored By Gordon Williams <gw@pur3.co.uk>
|
---|
| 7 | *
|
---|
| 8 | * Copyright (C) 2009 Pur3 Ltd
|
---|
| 9 | *
|
---|
| 10 |
|
---|
| 11 | * 42TinyJS
|
---|
| 12 | *
|
---|
| 13 | * A fork of TinyJS with the goal to makes a more JavaScript/ECMA compliant engine
|
---|
| 14 | *
|
---|
| 15 | * Authored / Changed By Armin Diedering <armin@diedering.de>
|
---|
| 16 | *
|
---|
| 17 | * Copyright (C) 2010-2013 ardisoft
|
---|
| 18 | *
|
---|
| 19 | *
|
---|
| 20 | * Permission is hereby granted, free of charge, to any person obtaining a copy of
|
---|
| 21 | * this software and associated documentation files (the "Software"), to deal in
|
---|
| 22 | * the Software without restriction, including without limitation the rights to
|
---|
| 23 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
---|
| 24 | * of the Software, and to permit persons to whom the Software is furnished to do
|
---|
| 25 | * so, subject to the following conditions:
|
---|
| 26 |
|
---|
| 27 | * The above copyright notice and this permission notice shall be included in all
|
---|
| 28 | * copies or substantial portions of the Software.
|
---|
| 29 |
|
---|
| 30 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
---|
| 31 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
---|
| 32 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
---|
| 33 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
---|
| 34 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
---|
| 35 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
---|
| 36 | * SOFTWARE.
|
---|
| 37 | */
|
---|
| 38 |
|
---|
| 39 | #ifndef TINYJS_H
|
---|
| 40 | #define TINYJS_H
|
---|
| 41 |
|
---|
| 42 | #include <string>
|
---|
| 43 | #include <vector>
|
---|
| 44 | #include <map>
|
---|
| 45 | #include <set>
|
---|
| 46 | #include <stdint.h>
|
---|
| 47 | #include <cassert>
|
---|
| 48 | #include <limits>
|
---|
| 49 |
|
---|
| 50 | #include "config.h"
|
---|
| 51 |
|
---|
| 52 | #if __cplusplus >= 201103L
|
---|
| 53 | # define MEMBER_DELETE =delete
|
---|
| 54 | #else
|
---|
| 55 | # define MEMBER_DELETE
|
---|
| 56 | #endif
|
---|
| 57 |
|
---|
| 58 | #ifdef NO_POOL_ALLOCATOR
|
---|
| 59 | template<typename T, int num_objects=64>
|
---|
| 60 | class fixed_size_object {};
|
---|
| 61 | #else
|
---|
| 62 | # include "pool_allocator.h"
|
---|
| 63 | #endif
|
---|
| 64 |
|
---|
| 65 | #ifdef _MSC_VER
|
---|
| 66 | # if defined(_DEBUG) && defined(_DEBUG_NEW)
|
---|
| 67 | # define _AFXDLL
|
---|
| 68 | # include <afx.h> // MFC-Kern- und -Standardkomponenten
|
---|
| 69 | # define new DEBUG_NEW
|
---|
| 70 | # endif
|
---|
| 71 | # define DEPRECATED(_Text) __declspec(deprecated(_Text))
|
---|
| 72 | #elif defined(__GNUC__)
|
---|
| 73 | # define DEPRECATED(_Text) __attribute__ ((deprecated))
|
---|
| 74 | #else
|
---|
| 75 | # define DEPRECATED(_Text)
|
---|
| 76 | #endif
|
---|
| 77 |
|
---|
| 78 | #ifndef ASSERT
|
---|
| 79 | # define ASSERT(X) assert(X)
|
---|
| 80 | #endif
|
---|
| 81 |
|
---|
| 82 | #undef TRACE
|
---|
| 83 | #ifndef TRACE
|
---|
| 84 | #define TRACE printf
|
---|
| 85 | #endif // TRACE
|
---|
| 86 |
|
---|
| 87 | enum LEX_TYPES {
|
---|
| 88 | LEX_EOF = 0,
|
---|
| 89 | #define LEX_RELATIONS_1_BEGIN LEX_EQUAL
|
---|
| 90 | LEX_EQUAL = 256,
|
---|
| 91 | LEX_TYPEEQUAL,
|
---|
| 92 | LEX_NEQUAL,
|
---|
| 93 | LEX_NTYPEEQUAL,
|
---|
| 94 | #define LEX_RELATIONS_1_END LEX_NTYPEEQUAL
|
---|
| 95 | LEX_LEQUAL,
|
---|
| 96 | LEX_GEQUAL,
|
---|
| 97 | #define LEX_SHIFTS_BEGIN LEX_LSHIFT
|
---|
| 98 | LEX_LSHIFT,
|
---|
| 99 | LEX_RSHIFT,
|
---|
| 100 | LEX_RSHIFTU, // unsigned
|
---|
| 101 | #define LEX_SHIFTS_END LEX_RSHIFTU
|
---|
| 102 | LEX_PLUSPLUS,
|
---|
| 103 | LEX_MINUSMINUS,
|
---|
| 104 | LEX_ANDAND,
|
---|
| 105 | LEX_OROR,
|
---|
| 106 | LEX_INT,
|
---|
| 107 |
|
---|
| 108 | #define LEX_ASSIGNMENTS_BEGIN LEX_PLUSEQUAL
|
---|
| 109 | LEX_PLUSEQUAL,
|
---|
| 110 | LEX_MINUSEQUAL,
|
---|
| 111 | LEX_ASTERISKEQUAL,
|
---|
| 112 | LEX_SLASHEQUAL,
|
---|
| 113 | LEX_PERCENTEQUAL,
|
---|
| 114 | LEX_LSHIFTEQUAL,
|
---|
| 115 | LEX_RSHIFTEQUAL,
|
---|
| 116 | LEX_RSHIFTUEQUAL, // unsigned
|
---|
| 117 | LEX_ANDEQUAL,
|
---|
| 118 | LEX_OREQUAL,
|
---|
| 119 | LEX_XOREQUAL,
|
---|
| 120 | #define LEX_ASSIGNMENTS_END LEX_XOREQUAL
|
---|
| 121 |
|
---|
| 122 | #define LEX_TOKEN_NONSIMPLE_1_BEGIN LEX_TOKEN_STRING_BEGIN
|
---|
| 123 | #define LEX_TOKEN_STRING_BEGIN LEX_ID
|
---|
| 124 | LEX_ID,
|
---|
| 125 | LEX_STR,
|
---|
| 126 | LEX_REGEXP,
|
---|
| 127 | LEX_T_LABEL,
|
---|
| 128 | LEX_T_DUMMY_LABEL,
|
---|
| 129 | #define LEX_TOKEN_STRING_END LEX_T_DUMMY_LABEL
|
---|
| 130 |
|
---|
| 131 | LEX_FLOAT,
|
---|
| 132 | #define LEX_TOKEN_NONSIMPLE_1_END LEX_FLOAT
|
---|
| 133 |
|
---|
| 134 | // reserved words
|
---|
| 135 | LEX_R_IF,
|
---|
| 136 | LEX_R_ELSE,
|
---|
| 137 | LEX_R_DO,
|
---|
| 138 | LEX_R_WHILE,
|
---|
| 139 | LEX_R_FOR,
|
---|
| 140 | LEX_R_IN,
|
---|
| 141 | LEX_T_OF,
|
---|
| 142 | LEX_R_BREAK,
|
---|
| 143 | LEX_R_CONTINUE,
|
---|
| 144 | LEX_R_RETURN,
|
---|
| 145 | LEX_R_VAR,
|
---|
| 146 | LEX_R_LET,
|
---|
| 147 | LEX_R_CONST,
|
---|
| 148 | LEX_R_WITH,
|
---|
| 149 | LEX_R_TRUE,
|
---|
| 150 | LEX_R_FALSE,
|
---|
| 151 | LEX_R_NULL,
|
---|
| 152 | LEX_R_NEW,
|
---|
| 153 | LEX_R_TRY,
|
---|
| 154 | LEX_R_CATCH,
|
---|
| 155 | LEX_R_FINALLY,
|
---|
| 156 | LEX_R_THROW,
|
---|
| 157 | LEX_R_TYPEOF,
|
---|
| 158 | LEX_R_VOID,
|
---|
| 159 | LEX_R_DELETE,
|
---|
| 160 | LEX_R_INSTANCEOF,
|
---|
| 161 | LEX_R_SWITCH,
|
---|
| 162 | LEX_R_CASE,
|
---|
| 163 | LEX_R_DEFAULT,
|
---|
| 164 |
|
---|
| 165 | // special token
|
---|
| 166 | // LEX_T_FILE,
|
---|
| 167 | #define LEX_TOKEN_NONSIMPLE_2_BEGIN LEX_TOKEN_FOR_BEGIN
|
---|
| 168 | #define LEX_TOKEN_FOR_BEGIN LEX_T_LOOP
|
---|
| 169 | LEX_T_LOOP,
|
---|
| 170 | LEX_T_FOR_IN,
|
---|
| 171 | #define LEX_TOKEN_FOR_END LEX_T_FOR_IN
|
---|
| 172 | #define LEX_TOKEN_FUNCTION_BEGIN LEX_R_FUNCTION
|
---|
| 173 | LEX_R_FUNCTION,
|
---|
| 174 | LEX_T_FUNCTION_PLACEHOLDER,
|
---|
| 175 | LEX_T_FUNCTION_OPERATOR,
|
---|
| 176 | LEX_T_GET,
|
---|
| 177 | LEX_T_SET,
|
---|
| 178 | #define LEX_TOKEN_FUNCTION_END LEX_T_SET
|
---|
| 179 | LEX_T_TRY,
|
---|
| 180 | LEX_T_OBJECT_LITERAL,
|
---|
| 181 | LEX_T_DESTRUCTURING_VAR,
|
---|
| 182 | LEX_T_FORWARD,
|
---|
| 183 | #define LEX_TOKEN_NONSIMPLE_2_END LEX_T_FORWARD
|
---|
| 184 |
|
---|
| 185 | LEX_T_EXCEPTION_VAR,
|
---|
| 186 | LEX_T_SKIP,
|
---|
| 187 | };
|
---|
| 188 | #define LEX_TOKEN_DATA_STRING(tk) ((LEX_TOKEN_STRING_BEGIN<= tk && tk <= LEX_TOKEN_STRING_END))
|
---|
| 189 | #define LEX_TOKEN_DATA_FLOAT(tk) (tk==LEX_FLOAT)
|
---|
| 190 | #define LEX_TOKEN_DATA_LOOP(tk) (LEX_TOKEN_FOR_BEGIN <= tk && tk <= LEX_TOKEN_FOR_END)
|
---|
| 191 | #define LEX_TOKEN_DATA_FUNCTION(tk) (LEX_TOKEN_FUNCTION_BEGIN <= tk && tk <= LEX_TOKEN_FUNCTION_END)
|
---|
| 192 | #define LEX_TOKEN_DATA_TRY(tk) (tk == LEX_T_TRY)
|
---|
| 193 | #define LEX_TOKEN_DATA_OBJECT_LITERAL(tk) (tk==LEX_T_OBJECT_LITERAL)
|
---|
| 194 | #define LEX_TOKEN_DATA_DESTRUCTURING_VAR(tk) (tk==LEX_T_DESTRUCTURING_VAR)
|
---|
| 195 | #define LEX_TOKEN_DATA_FORWARDER(tk) (tk==LEX_T_FORWARD)
|
---|
| 196 |
|
---|
| 197 | #define LEX_TOKEN_DATA_SIMPLE(tk) (!((LEX_TOKEN_NONSIMPLE_1_BEGIN <= tk && tk <= LEX_TOKEN_NONSIMPLE_1_END) || (LEX_TOKEN_NONSIMPLE_2_BEGIN <= tk && tk <= LEX_TOKEN_NONSIMPLE_2_END)))
|
---|
| 198 |
|
---|
| 199 | enum SCRIPTVARLINK_FLAGS {
|
---|
| 200 | SCRIPTVARLINK_WRITABLE = 1<<0,
|
---|
| 201 | SCRIPTVARLINK_CONFIGURABLE = 1<<1,
|
---|
| 202 | SCRIPTVARLINK_ENUMERABLE = 1<<2,
|
---|
| 203 | SCRIPTVARLINK_DEFAULT = SCRIPTVARLINK_WRITABLE | SCRIPTVARLINK_CONFIGURABLE | SCRIPTVARLINK_ENUMERABLE,
|
---|
| 204 | SCRIPTVARLINK_VARDEFAULT = SCRIPTVARLINK_WRITABLE | SCRIPTVARLINK_ENUMERABLE,
|
---|
| 205 | SCRIPTVARLINK_CONSTDEFAULT = SCRIPTVARLINK_ENUMERABLE,
|
---|
| 206 | SCRIPTVARLINK_BUILDINDEFAULT = SCRIPTVARLINK_WRITABLE | SCRIPTVARLINK_CONFIGURABLE,
|
---|
| 207 | SCRIPTVARLINK_READONLY = SCRIPTVARLINK_CONFIGURABLE,
|
---|
| 208 | SCRIPTVARLINK_READONLY_ENUM = SCRIPTVARLINK_CONFIGURABLE | SCRIPTVARLINK_ENUMERABLE,
|
---|
| 209 | SCRIPTVARLINK_CONSTANT = 0,
|
---|
| 210 | };
|
---|
| 211 |
|
---|
| 212 | enum ERROR_TYPES {
|
---|
| 213 | Error = 0,
|
---|
| 214 | EvalError,
|
---|
| 215 | RangeError,
|
---|
| 216 | ReferenceError,
|
---|
| 217 | SyntaxError,
|
---|
| 218 | TypeError
|
---|
| 219 | };
|
---|
| 220 | #define ERROR_MAX TypeError
|
---|
| 221 | #define ERROR_COUNT (ERROR_MAX+1)
|
---|
| 222 | extern const char *ERROR_NAME[];
|
---|
| 223 |
|
---|
| 224 |
|
---|
| 225 | #define TINYJS_RETURN_VAR "return"
|
---|
| 226 | #define TINYJS_LOKALE_VAR "__locale__"
|
---|
| 227 | #define TINYJS_ANONYMOUS_VAR "__anonymous__"
|
---|
| 228 | #define TINYJS_ARGUMENTS_VAR "arguments"
|
---|
| 229 | #define TINYJS___PROTO___VAR "__proto__"
|
---|
| 230 | #define TINYJS_PROTOTYPE_CLASS "prototype"
|
---|
| 231 | #define TINYJS_FUNCTION_CLOSURE_VAR "__function_closure__"
|
---|
| 232 | #define TINYJS_SCOPE_PARENT_VAR "__scope_parent__"
|
---|
| 233 | #define TINYJS_SCOPE_WITH_VAR "__scope_with__"
|
---|
| 234 | #define TINYJS_ACCESSOR_GET_VAR "__accessor_get__"
|
---|
| 235 | #define TINYJS_ACCESSOR_SET_VAR "__accessor_set__"
|
---|
| 236 | #define TINYJS_TEMP_NAME ""
|
---|
| 237 | #define TINYJS_BLANK_DATA ""
|
---|
| 238 |
|
---|
| 239 | typedef std::vector<std::string> STRING_VECTOR_t;
|
---|
| 240 | typedef STRING_VECTOR_t::iterator STRING_VECTOR_it;
|
---|
| 241 |
|
---|
| 242 | typedef std::set<std::string> STRING_SET_t;
|
---|
| 243 | typedef STRING_SET_t::iterator STRING_SET_it;
|
---|
| 244 |
|
---|
| 245 | /// convert the given string into a quoted string suitable for javascript
|
---|
| 246 | std::string getJSString(const std::string &str);
|
---|
| 247 | /// convert the given int into a string
|
---|
| 248 | std::string int2string(int32_t intData);
|
---|
| 249 | std::string int2string(uint32_t intData);
|
---|
| 250 | /// convert the given double into a string
|
---|
| 251 | std::string float2string(const double &floatData);
|
---|
| 252 |
|
---|
| 253 |
|
---|
| 254 | //////////////////////////////////////////////////////////////////////////
|
---|
| 255 | /// CScriptException
|
---|
| 256 | //////////////////////////////////////////////////////////////////////////
|
---|
| 257 |
|
---|
| 258 | class CScriptException {
|
---|
| 259 | public:
|
---|
| 260 | ERROR_TYPES errorType;
|
---|
| 261 | std::string message;
|
---|
| 262 | std::string fileName;
|
---|
| 263 | int lineNumber;
|
---|
| 264 | int column;
|
---|
| 265 | CScriptException(const std::string &Message, const std::string &File, int Line=-1, int Column=-1) :
|
---|
| 266 | errorType(Error), message(Message), fileName(File), lineNumber(Line), column(Column){}
|
---|
| 267 | CScriptException(ERROR_TYPES ErrorType, const std::string &Message, const std::string &File, int Line=-1, int Column=-1) :
|
---|
| 268 | errorType(ErrorType), message(Message), fileName(File), lineNumber(Line), column(Column){}
|
---|
| 269 | CScriptException(const std::string &Message, const char *File="", int Line=-1, int Column=-1) :
|
---|
| 270 | errorType(Error), message(Message), fileName(File), lineNumber(Line), column(Column){}
|
---|
| 271 | CScriptException(ERROR_TYPES ErrorType, const std::string &Message, const char *File="", int Line=-1, int Column=-1) :
|
---|
| 272 | errorType(ErrorType), message(Message), fileName(File), lineNumber(Line), column(Column){}
|
---|
| 273 | std::string toString();
|
---|
| 274 | };
|
---|
| 275 |
|
---|
| 276 |
|
---|
| 277 | //////////////////////////////////////////////////////////////////////////
|
---|
| 278 | /// CScriptLex
|
---|
| 279 | //////////////////////////////////////////////////////////////////////////
|
---|
| 280 |
|
---|
| 281 | class CScriptLex
|
---|
| 282 | {
|
---|
| 283 | public:
|
---|
| 284 | CScriptLex(const char *Code, const std::string &File="", int Line=0, int Column=0);
|
---|
| 285 | struct POS;
|
---|
| 286 | int tk; ///< The type of the token that we have
|
---|
| 287 | int last_tk; ///< The type of the last token that we have
|
---|
| 288 | std::string tkStr; ///< Data contained in the token we have here
|
---|
| 289 |
|
---|
| 290 | void check(int expected_tk, int alternate_tk=-1); ///< Lexical check wotsit
|
---|
| 291 | void match(int expected_tk, int alternate_tk=-1); ///< Lexical match wotsit
|
---|
| 292 | void reset(const POS &toPos); ///< Reset this lex so we can start again
|
---|
| 293 |
|
---|
| 294 | std::string currentFile;
|
---|
| 295 | struct POS {
|
---|
| 296 | const char *tokenStart;
|
---|
| 297 | int currentLine;
|
---|
| 298 | const char *currentLineStart;
|
---|
| 299 | } pos;
|
---|
| 300 | int currentLine() { return pos.currentLine; }
|
---|
| 301 | int currentColumn() { return pos.tokenStart-pos.currentLineStart; }
|
---|
| 302 | bool lineBreakBeforeToken;
|
---|
| 303 | private:
|
---|
| 304 | const char *data;
|
---|
| 305 | const char *dataPos;
|
---|
| 306 | char currCh, nextCh;
|
---|
| 307 |
|
---|
| 308 | void getNextCh();
|
---|
| 309 | void getNextToken(); ///< Get the text token from our text string
|
---|
| 310 | };
|
---|
| 311 |
|
---|
| 312 |
|
---|
| 313 | //////////////////////////////////////////////////////////////////////////
|
---|
| 314 | /// CScriptTokenData
|
---|
| 315 | //////////////////////////////////////////////////////////////////////////
|
---|
| 316 |
|
---|
| 317 | class CScriptToken;
|
---|
| 318 | typedef std::vector<CScriptToken> TOKEN_VECT;
|
---|
| 319 | typedef std::vector<CScriptToken>::iterator TOKEN_VECT_it;
|
---|
| 320 | typedef std::vector<CScriptToken>::const_iterator TOKEN_VECT_cit;
|
---|
| 321 | class CScriptTokenData
|
---|
| 322 | {
|
---|
| 323 | protected:
|
---|
| 324 | CScriptTokenData() : refs(0){}
|
---|
| 325 | virtual ~CScriptTokenData() {}
|
---|
| 326 | private:
|
---|
| 327 | // CScriptTokenData(const CScriptTokenData &noCopy);
|
---|
| 328 | // CScriptTokenData &operator=(const CScriptTokenData &noCopy);
|
---|
| 329 | public:
|
---|
| 330 | void ref() { refs++; }
|
---|
| 331 | void unref() { if(--refs == 0) delete this; }
|
---|
| 332 | private:
|
---|
| 333 | int refs;
|
---|
| 334 | };
|
---|
| 335 | template<typename C>
|
---|
| 336 | class CScriptTokenDataPtr {
|
---|
| 337 | public:
|
---|
| 338 | CScriptTokenDataPtr() : ptr(0) {}
|
---|
| 339 | CScriptTokenDataPtr(const CScriptTokenDataPtr &Copy) : ptr(0) { *this=Copy; }
|
---|
| 340 | CScriptTokenDataPtr &operator=(const CScriptTokenDataPtr &Copy) {
|
---|
| 341 | if(ptr != Copy.ptr) {
|
---|
| 342 | if(ptr) ptr->unref();
|
---|
| 343 | if((ptr = Copy.ptr)) ptr->ref();
|
---|
| 344 | }
|
---|
| 345 | return *this;
|
---|
| 346 | }
|
---|
| 347 | CScriptTokenDataPtr(C &Init) { (ptr=&Init)->ref(); }
|
---|
| 348 | ~CScriptTokenDataPtr() { if(ptr) ptr->unref(); }
|
---|
| 349 | C *operator->() { return ptr; }
|
---|
| 350 | C &operator*() { return *ptr; }
|
---|
| 351 | operator bool() { return ptr!=0; }
|
---|
| 352 | bool operator==(const CScriptTokenDataPtr& rhs) { return ptr==rhs.ptr; }
|
---|
| 353 | private:
|
---|
| 354 | C *ptr;
|
---|
| 355 | };
|
---|
| 356 |
|
---|
| 357 | class CScriptTokenDataString : public fixed_size_object<CScriptTokenDataString>, public CScriptTokenData {
|
---|
| 358 | public:
|
---|
| 359 | CScriptTokenDataString(const std::string &String) : tokenStr(String) {}
|
---|
| 360 | std::string tokenStr;
|
---|
| 361 | private:
|
---|
| 362 | };
|
---|
| 363 |
|
---|
| 364 | class CScriptTokenDataFnc : public fixed_size_object<CScriptTokenDataFnc>, public CScriptTokenData {
|
---|
| 365 | public:
|
---|
| 366 | std::string file;
|
---|
| 367 | int line;
|
---|
| 368 | std::string name;
|
---|
| 369 | TOKEN_VECT arguments;
|
---|
| 370 | TOKEN_VECT body;
|
---|
| 371 | std::string getArgumentsString();
|
---|
| 372 | };
|
---|
| 373 |
|
---|
| 374 | class CScriptTokenDataForwards : public fixed_size_object<CScriptTokenDataForwards>, public CScriptTokenData {
|
---|
| 375 | public:
|
---|
| 376 | CScriptTokenDataForwards() {}
|
---|
| 377 | enum {
|
---|
| 378 | LETS = 0,
|
---|
| 379 | VARS,
|
---|
| 380 | CONSTS,
|
---|
| 381 | END
|
---|
| 382 | };
|
---|
| 383 | STRING_SET_t varNames[END];
|
---|
| 384 | STRING_SET_t vars_in_letscope;
|
---|
| 385 | class compare_fnc_token_by_name {
|
---|
| 386 | public:
|
---|
| 387 | bool operator()(const CScriptToken& lhs, const CScriptToken& rhs) const;
|
---|
| 388 | };
|
---|
| 389 | typedef std::set<CScriptToken, compare_fnc_token_by_name> FNC_SET_t;
|
---|
| 390 | typedef FNC_SET_t::iterator FNC_SET_it;
|
---|
| 391 | FNC_SET_t functions;
|
---|
| 392 | bool checkRedefinition(const std::string &Str, bool checkVars);
|
---|
| 393 | void addVars( STRING_VECTOR_t &Vars );
|
---|
| 394 | void addConsts( STRING_VECTOR_t &Vars );
|
---|
| 395 | std::string addVarsInLetscope(STRING_VECTOR_t &Vars);
|
---|
| 396 | std::string addLets(STRING_VECTOR_t &Lets);
|
---|
| 397 | bool empty() { return varNames[LETS].empty() && varNames[VARS].empty() && varNames[CONSTS].empty() && functions.empty(); }
|
---|
| 398 | private:
|
---|
| 399 | };
|
---|
| 400 | class CScriptTokenDataForwardsPtr {
|
---|
| 401 | public:
|
---|
| 402 | CScriptTokenDataForwardsPtr() : ptr(0) {}
|
---|
| 403 | CScriptTokenDataForwardsPtr(const CScriptTokenDataForwardsPtr &Copy) : ptr(0) { *this=Copy; }
|
---|
| 404 | CScriptTokenDataForwardsPtr &operator=(const CScriptTokenDataForwardsPtr &Copy) {
|
---|
| 405 | if(ptr != Copy.ptr) {
|
---|
| 406 | if(ptr) ptr->unref();
|
---|
| 407 | if((ptr = Copy.ptr)) ptr->ref();
|
---|
| 408 | }
|
---|
| 409 | return *this;
|
---|
| 410 | }
|
---|
| 411 | CScriptTokenDataForwardsPtr(CScriptTokenDataForwards &Init) { (ptr=&Init)->ref(); }
|
---|
| 412 | ~CScriptTokenDataForwardsPtr() { if(ptr) ptr->unref(); }
|
---|
| 413 | CScriptTokenDataForwards *operator->() { return ptr; }
|
---|
| 414 | operator bool() { return ptr!=0; }
|
---|
| 415 | bool operator==(const CScriptTokenDataForwardsPtr& rhs) { return ptr==rhs.ptr; }
|
---|
| 416 | private:
|
---|
| 417 | CScriptTokenDataForwards *ptr;
|
---|
| 418 | };
|
---|
| 419 | typedef std::vector<CScriptTokenDataForwardsPtr> FORWARDER_VECTOR_t;
|
---|
| 420 |
|
---|
| 421 | class CScriptTokenDataLoop : public fixed_size_object<CScriptTokenDataLoop>, public CScriptTokenData {
|
---|
| 422 | public:
|
---|
| 423 | CScriptTokenDataLoop() { type=FOR; }
|
---|
| 424 | enum {FOR_EACH=0, FOR_IN, FOR_OF, FOR, WHILE, DO} type; // do not change the order
|
---|
| 425 | STRING_VECTOR_t labels;
|
---|
| 426 | TOKEN_VECT init;
|
---|
| 427 | TOKEN_VECT condition;
|
---|
| 428 | TOKEN_VECT iter;
|
---|
| 429 | TOKEN_VECT body;
|
---|
| 430 | std::string getParsableString(const std::string &IndentString="", const std::string &Indent="");
|
---|
| 431 | };
|
---|
| 432 |
|
---|
| 433 | typedef std::pair<std::string, std::string> DESTRUCTURING_VAR_t;
|
---|
| 434 | typedef std::vector<DESTRUCTURING_VAR_t> DESTRUCTURING_VARS_t;
|
---|
| 435 | typedef DESTRUCTURING_VARS_t::iterator DESTRUCTURING_VARS_it;
|
---|
| 436 | typedef DESTRUCTURING_VARS_t::const_iterator DESTRUCTURING_VARS_cit;
|
---|
| 437 | class CScriptTokenDataDestructuringVar : public fixed_size_object<CScriptTokenDataDestructuringVar>, public CScriptTokenData {
|
---|
| 438 | public:
|
---|
| 439 | DESTRUCTURING_VARS_t vars;
|
---|
| 440 | void getVarNames(STRING_VECTOR_t Name);
|
---|
| 441 | std::string getParsableString();
|
---|
| 442 | private:
|
---|
| 443 | };
|
---|
| 444 |
|
---|
| 445 | class CScriptTokenDataObjectLiteral : public fixed_size_object<CScriptTokenDataObjectLiteral>, public CScriptTokenData {
|
---|
| 446 | public:
|
---|
| 447 | enum {ARRAY, OBJECT} type;
|
---|
| 448 | int flags;
|
---|
| 449 | struct ELEMENT {
|
---|
| 450 | std::string id;
|
---|
| 451 | TOKEN_VECT value;
|
---|
| 452 | };
|
---|
| 453 | bool destructuring;
|
---|
| 454 | bool structuring;
|
---|
| 455 | std::vector<ELEMENT> elements;
|
---|
| 456 | void setMode(bool Destructuring);
|
---|
| 457 | std::string getParsableString();
|
---|
| 458 | private:
|
---|
| 459 | };
|
---|
| 460 |
|
---|
| 461 | class CScriptTokenDataTry : public fixed_size_object<CScriptTokenDataTry>, public CScriptTokenData {
|
---|
| 462 | public:
|
---|
| 463 | TOKEN_VECT tryBlock;
|
---|
| 464 | struct CatchBlock {
|
---|
| 465 | CScriptTokenDataPtr<CScriptTokenDataDestructuringVar> indentifiers;
|
---|
| 466 | TOKEN_VECT condition;
|
---|
| 467 | TOKEN_VECT block;
|
---|
| 468 | };
|
---|
| 469 | std::vector<CatchBlock> catchBlocks;
|
---|
| 470 | typedef std::vector<CatchBlock>::iterator CatchBlock_it;
|
---|
| 471 | TOKEN_VECT finallyBlock;
|
---|
| 472 | std::string getParsableString(const std::string &IndentString="", const std::string &Indent="");
|
---|
| 473 | };
|
---|
| 474 |
|
---|
| 475 |
|
---|
| 476 | //////////////////////////////////////////////////////////////////////////
|
---|
| 477 | /// CScriptToken
|
---|
| 478 | //////////////////////////////////////////////////////////////////////////
|
---|
| 479 |
|
---|
| 480 | class CScriptTokenizer;
|
---|
| 481 | /*
|
---|
| 482 | a Token needs 8 Byte
|
---|
| 483 | 2 Bytes for the Row-Position of the Token
|
---|
| 484 | 2 Bytes for the Token self
|
---|
| 485 | and
|
---|
| 486 | 4 Bytes for special Datas in an union
|
---|
| 487 | e.g. an int for interger-literals
|
---|
| 488 | or pointer for double-literals,
|
---|
| 489 | for string-literals or for functions
|
---|
| 490 | */
|
---|
| 491 | class CScriptToken : public fixed_size_object<CScriptToken>
|
---|
| 492 | {
|
---|
| 493 | public:
|
---|
| 494 | CScriptToken() : line(0), column(0), token(0), intData(0) {}
|
---|
| 495 | CScriptToken(CScriptLex *l, int Match=-1, int Alternate=-1);
|
---|
| 496 | CScriptToken(uint16_t Tk, int IntData=0);
|
---|
| 497 | CScriptToken(uint16_t Tk, const std::string &TkStr);
|
---|
| 498 | CScriptToken(const CScriptToken &Copy) : token(0) { *this = Copy; }
|
---|
| 499 | CScriptToken &operator =(const CScriptToken &Copy);
|
---|
| 500 | ~CScriptToken() { clear(); }
|
---|
| 501 |
|
---|
| 502 | int &Int() { ASSERT(LEX_TOKEN_DATA_SIMPLE(token)); return intData; }
|
---|
| 503 | std::string &String() { ASSERT(LEX_TOKEN_DATA_STRING(token)); return dynamic_cast<CScriptTokenDataString*>(tokenData)->tokenStr; }
|
---|
| 504 | double &Float() { ASSERT(LEX_TOKEN_DATA_FLOAT(token)); return *floatData; }
|
---|
| 505 | CScriptTokenDataFnc &Fnc() { ASSERT(LEX_TOKEN_DATA_FUNCTION(token)); return *dynamic_cast<CScriptTokenDataFnc*>(tokenData); }
|
---|
| 506 | const CScriptTokenDataFnc &Fnc() const { ASSERT(LEX_TOKEN_DATA_FUNCTION(token)); return *dynamic_cast<CScriptTokenDataFnc*>(tokenData); }
|
---|
| 507 | CScriptTokenDataObjectLiteral &Object() { ASSERT(LEX_TOKEN_DATA_OBJECT_LITERAL(token)); return *dynamic_cast<CScriptTokenDataObjectLiteral*>(tokenData); }
|
---|
| 508 | CScriptTokenDataDestructuringVar &DestructuringVar() { ASSERT(LEX_TOKEN_DATA_DESTRUCTURING_VAR(token)); return *dynamic_cast<CScriptTokenDataDestructuringVar*>(tokenData); }
|
---|
| 509 | CScriptTokenDataLoop &Loop() { ASSERT(LEX_TOKEN_DATA_LOOP(token)); return *dynamic_cast<CScriptTokenDataLoop*>(tokenData); }
|
---|
| 510 | CScriptTokenDataTry &Try() { ASSERT(LEX_TOKEN_DATA_TRY(token)); return *dynamic_cast<CScriptTokenDataTry*>(tokenData); }
|
---|
| 511 | CScriptTokenDataForwards &Forwarder() { ASSERT(LEX_TOKEN_DATA_FORWARDER(token)); return *dynamic_cast<CScriptTokenDataForwards*>(tokenData); }
|
---|
| 512 | #ifdef _DEBUG
|
---|
| 513 | std::string token_str;
|
---|
| 514 | #endif
|
---|
| 515 | uint16_t line;
|
---|
| 516 | uint16_t column;
|
---|
| 517 | uint16_t token;
|
---|
| 518 |
|
---|
| 519 | static std::string getParsableString(TOKEN_VECT &Tokens, const std::string &IndentString="", const std::string &Indent="");
|
---|
| 520 | static std::string getParsableString(TOKEN_VECT_it Begin, TOKEN_VECT_it End, const std::string &IndentString="", const std::string &Indent="");
|
---|
| 521 | static std::string getTokenStr( int token, bool *need_space=0 );
|
---|
| 522 | static const char *isReservedWord(int Token);
|
---|
| 523 | static int isReservedWord(const std::string &Str);
|
---|
| 524 | private:
|
---|
| 525 |
|
---|
| 526 | void clear();
|
---|
| 527 | union {
|
---|
| 528 | int intData;
|
---|
| 529 | double *floatData;
|
---|
| 530 | CScriptTokenData *tokenData;
|
---|
| 531 | };
|
---|
| 532 | };
|
---|
| 533 |
|
---|
| 534 |
|
---|
| 535 | //////////////////////////////////////////////////////////////////////////
|
---|
| 536 | /// CScriptTokenizer - converts the code in a vector with tokens
|
---|
| 537 | //////////////////////////////////////////////////////////////////////////
|
---|
| 538 |
|
---|
| 539 | class CScriptTokenizer
|
---|
| 540 | {
|
---|
| 541 | public:
|
---|
| 542 | struct ScriptTokenPosition {
|
---|
| 543 | ScriptTokenPosition(TOKEN_VECT *Tokens) : tokens(Tokens), pos(tokens->begin())/*, currentLine(0)*//*, currentColumn(0)*/ {}
|
---|
| 544 | bool operator ==(const ScriptTokenPosition &eq) { return pos == eq.pos; }
|
---|
| 545 | ScriptTokenPosition &operator =(const ScriptTokenPosition ©) {
|
---|
| 546 | tokens=copy.tokens; pos=copy.pos;
|
---|
| 547 | // currentLine=copy.currentLine;
|
---|
| 548 | return *this;
|
---|
| 549 | }
|
---|
| 550 | TOKEN_VECT *tokens;
|
---|
| 551 | TOKEN_VECT_it pos;
|
---|
| 552 | int currentLine() { return pos->line; }
|
---|
| 553 | int currentColumn() { return pos->column; }
|
---|
| 554 | };
|
---|
| 555 | struct ScriptTokenState {
|
---|
| 556 | TOKEN_VECT Tokens;
|
---|
| 557 | FORWARDER_VECTOR_t Forwarders;
|
---|
| 558 | std::vector<int> Marks;
|
---|
| 559 | STRING_VECTOR_t Labels;
|
---|
| 560 | STRING_VECTOR_t LoopLabels;
|
---|
| 561 | bool LeftHand;
|
---|
| 562 | void pushLeftHandState() { States.push_back(LeftHand); }
|
---|
| 563 | void popLeftHandeState() { LeftHand = States.back(); States.pop_back(); }
|
---|
| 564 | std::vector<bool> States;
|
---|
| 565 | };
|
---|
| 566 | CScriptTokenizer();
|
---|
| 567 | CScriptTokenizer(CScriptLex &Lexer);
|
---|
| 568 | CScriptTokenizer(const char *Code, const std::string &File="", int Line=0, int Column=0);
|
---|
| 569 | void tokenizeCode(CScriptLex &Lexer);
|
---|
| 570 |
|
---|
| 571 | CScriptToken &getToken() { return *(tokenScopeStack.back().pos); }
|
---|
| 572 | void getNextToken();
|
---|
| 573 | bool check(int ExpectedToken, int AlternateToken=-1);
|
---|
| 574 | void match(int ExpectedToken, int AlternateToken=-1);
|
---|
| 575 | void pushTokenScope(TOKEN_VECT &Tokens);
|
---|
| 576 | ScriptTokenPosition &getPos() { return tokenScopeStack.back(); }
|
---|
| 577 | void setPos(ScriptTokenPosition &TokenPos);
|
---|
| 578 | ScriptTokenPosition &getPrevPos() { return prevPos; }
|
---|
| 579 | void skip(int Tokens);
|
---|
| 580 | int tk; // current Token
|
---|
| 581 | std::string currentFile;
|
---|
| 582 | int currentLine() { return getPos().currentLine();}
|
---|
| 583 | int currentColumn() { return getPos().currentColumn();}
|
---|
| 584 | const std::string &tkStr() { static std::string empty; return LEX_TOKEN_DATA_STRING(getToken().token)?getToken().String():empty; }
|
---|
| 585 | private:
|
---|
| 586 | void tokenizeTry(ScriptTokenState &State, int Flags);
|
---|
| 587 | void tokenizeSwitch(ScriptTokenState &State, int Flags);
|
---|
| 588 | void tokenizeWith(ScriptTokenState &State, int Flags);
|
---|
| 589 | void tokenizeWhileAndDo(ScriptTokenState &State, int Flags);
|
---|
| 590 | void tokenizeIf(ScriptTokenState &State, int Flags);
|
---|
| 591 | void tokenizeFor(ScriptTokenState &State, int Flags);
|
---|
| 592 | CScriptToken tokenizeVarIdentifier(STRING_VECTOR_t *VarNames=0, bool *NeedAssignment=0);
|
---|
| 593 | void tokenizeFunction(ScriptTokenState &State, int Flags, bool noLetDef=false);
|
---|
| 594 | void tokenizeLet(ScriptTokenState &State, int Flags, bool noLetDef=false);
|
---|
| 595 | void tokenizeVarNoConst(ScriptTokenState &State, int Flags);
|
---|
| 596 | void tokenizeVarAndConst(ScriptTokenState &State, int Flags);
|
---|
| 597 | void _tokenizeLiteralObject(ScriptTokenState &State, int Flags);
|
---|
| 598 | void _tokenizeLiteralArray(ScriptTokenState &State, int Flags);
|
---|
| 599 |
|
---|
| 600 | void tokenizeLiteral(ScriptTokenState &State, int Flags);
|
---|
| 601 | void tokenizeMember(ScriptTokenState &State, int Flags);
|
---|
| 602 | void tokenizeFunctionCall(ScriptTokenState &State, int Flags);
|
---|
| 603 | void tokenizeSubExpression(ScriptTokenState &State, int Flags);
|
---|
| 604 | void tokenizeLogic(ScriptTokenState &State, int Flags, int op= LEX_OROR, int op_n=LEX_ANDAND);
|
---|
| 605 | void tokenizeCondition(ScriptTokenState &State, int Flags);
|
---|
| 606 | void tokenizeAssignment(ScriptTokenState &State, int Flags);
|
---|
| 607 | void tokenizeExpression(ScriptTokenState &State, int Flags);
|
---|
| 608 | void tokenizeBlock(ScriptTokenState &State, int Flags);
|
---|
| 609 | void tokenizeStatementNoLet(ScriptTokenState &State, int Flags);
|
---|
| 610 | void tokenizeStatement(ScriptTokenState &State, int Flags);
|
---|
| 611 |
|
---|
| 612 | int pushToken(TOKEN_VECT &Tokens, int Match=-1, int Alternate=-1);
|
---|
| 613 | int pushToken(TOKEN_VECT &Tokens, const CScriptToken &Token);
|
---|
| 614 | void pushForwarder(ScriptTokenState &State, bool noMarks=false);
|
---|
| 615 | void removeEmptyForwarder(ScriptTokenState &State);
|
---|
| 616 | void pushForwarder(TOKEN_VECT &Tokens, FORWARDER_VECTOR_t &Forwarders, std::vector<int> &Marks);
|
---|
| 617 | void removeEmptyForwarder(TOKEN_VECT &Tokens, FORWARDER_VECTOR_t &Forwarders, std::vector<int> &Marks);
|
---|
| 618 | void throwTokenNotExpected();
|
---|
| 619 | CScriptLex *l;
|
---|
| 620 | TOKEN_VECT tokens;
|
---|
| 621 | ScriptTokenPosition prevPos;
|
---|
| 622 | std::vector<ScriptTokenPosition> tokenScopeStack;
|
---|
| 623 | };
|
---|
| 624 |
|
---|
| 625 |
|
---|
| 626 | //////////////////////////////////////////////////////////////////////////
|
---|
| 627 | /// forward-declaration
|
---|
| 628 | //////////////////////////////////////////////////////////////////////////
|
---|
| 629 |
|
---|
| 630 | class CNumber;
|
---|
| 631 | class CScriptVar;
|
---|
| 632 | class CScriptVarPtr;
|
---|
| 633 | template<typename C> class CScriptVarPointer;
|
---|
| 634 | class CScriptVarLink;
|
---|
| 635 | class CScriptVarLinkPtr;
|
---|
| 636 | class CScriptVarLinkWorkPtr;
|
---|
| 637 |
|
---|
| 638 | class CScriptVarPrimitive;
|
---|
| 639 | typedef CScriptVarPointer<CScriptVarPrimitive> CScriptVarPrimitivePtr;
|
---|
| 640 |
|
---|
| 641 | class CScriptVarScopeFnc;
|
---|
| 642 | typedef CScriptVarPointer<CScriptVarScopeFnc> CFunctionsScopePtr;
|
---|
| 643 | typedef void (*JSCallback)(const CFunctionsScopePtr &var, void *userdata);
|
---|
| 644 |
|
---|
| 645 | class CTinyJS;
|
---|
| 646 | class CScriptResult;
|
---|
| 647 |
|
---|
| 648 | //////////////////////////////////////////////////////////////////////////
|
---|
| 649 | /// CScriptVar
|
---|
| 650 | //////////////////////////////////////////////////////////////////////////
|
---|
| 651 |
|
---|
| 652 | typedef std::vector<class CScriptVarLinkPtr> SCRIPTVAR_CHILDS_t;
|
---|
| 653 | typedef SCRIPTVAR_CHILDS_t::iterator SCRIPTVAR_CHILDS_it;
|
---|
| 654 | typedef SCRIPTVAR_CHILDS_t::const_iterator SCRIPTVAR_CHILDS_cit;
|
---|
| 655 |
|
---|
| 656 | class CScriptVar : public fixed_size_object<CScriptVar> {
|
---|
| 657 | protected:
|
---|
| 658 | CScriptVar(CTinyJS *Context, const CScriptVarPtr &Prototype); ///< Create
|
---|
| 659 | CScriptVar(const CScriptVar &Copy); ///< Copy protected -> use clone for public
|
---|
| 660 | private:
|
---|
| 661 | CScriptVar & operator=(const CScriptVar &Copy) MEMBER_DELETE; ///< private -> no assignment-Copy
|
---|
| 662 | public:
|
---|
| 663 | virtual ~CScriptVar();
|
---|
| 664 | virtual CScriptVarPtr clone()=0;
|
---|
| 665 |
|
---|
| 666 | /// Type
|
---|
| 667 | virtual bool isObject(); ///< is an Object
|
---|
| 668 | virtual bool isArray(); ///< is an Array
|
---|
| 669 | virtual bool isError(); ///< is an ErrorObject
|
---|
| 670 | virtual bool isRegExp(); ///< is a RegExpObject
|
---|
| 671 | virtual bool isAccessor(); ///< is an Accessor
|
---|
| 672 | virtual bool isNull(); ///< is Null
|
---|
| 673 | virtual bool isUndefined();///< is Undefined
|
---|
| 674 | virtual bool isNaN(); ///< is NaN
|
---|
| 675 | virtual bool isString(); ///< is String
|
---|
| 676 | virtual bool isInt(); ///< is Integer
|
---|
| 677 | virtual bool isBool(); ///< is Bool
|
---|
| 678 | virtual int isInfinity(); ///< is Infinity ///< +1==POSITIVE_INFINITY, -1==NEGATIVE_INFINITY, 0==is not an InfinityVar
|
---|
| 679 | virtual bool isDouble(); ///< is Double
|
---|
| 680 |
|
---|
| 681 | virtual bool isRealNumber(); ///< is isInt | isDouble
|
---|
| 682 | virtual bool isNumber(); ///< is isNaN | isInt | isDouble | isInfinity
|
---|
| 683 | virtual bool isPrimitive();///< isNull | isUndefined | isNaN | isString | isInt | isDouble | isInfinity
|
---|
| 684 |
|
---|
| 685 | virtual bool isFunction(); ///< is CScriptVarFunction / CScriptVarFunctionNativeCallback / CScriptVarFunctionNativeClass
|
---|
| 686 | virtual bool isNative(); ///< is CScriptVarFunctionNativeCallback / CScriptVarFunctionNativeClass
|
---|
| 687 | virtual bool isBounded(); ///< is CScriptVarFunctionBounded
|
---|
| 688 |
|
---|
| 689 | virtual bool isIterator();
|
---|
| 690 |
|
---|
| 691 | bool isBasic() { return Childs.empty(); } ///< Is this *not* an array/object/etc
|
---|
| 692 |
|
---|
| 693 |
|
---|
| 694 | //////////////////////////////////////////////////////////////////////////
|
---|
| 695 | /// Value
|
---|
| 696 | //////////////////////////////////////////////////////////////////////////
|
---|
| 697 |
|
---|
| 698 | virtual CScriptVarPrimitivePtr getRawPrimitive()=0; ///< is Var==Primitive -> return this isObject return Value
|
---|
| 699 | CScriptVarPrimitivePtr toPrimitive(); ///< by default call getDefaultValue_hintNumber by a Date-object calls getDefaultValue_hintString
|
---|
| 700 | virtual CScriptVarPrimitivePtr toPrimitive(CScriptResult &execute); ///< if the var an ObjectType gets the valueOf; if valueOf of an ObjectType gets toString / otherwise gets the Var itself
|
---|
| 701 | CScriptVarPrimitivePtr toPrimitive_hintString(int32_t radix=0); ///< if the var an ObjectType gets the valueOf; if valueOf of an ObjectType gets toString / otherwise gets the Var itself
|
---|
| 702 | CScriptVarPrimitivePtr toPrimitive_hintString(CScriptResult &execute, int32_t radix=0); ///< if the var an ObjectType gets the valueOf; if valueOf of an ObjectType gets toString / otherwise gets the Var itself
|
---|
| 703 | CScriptVarPrimitivePtr toPrimitive_hintNumber(); ///< if the var an ObjectType gets the valueOf; if valueOf of an ObjectType gets toString / otherwise gets the Var itself
|
---|
| 704 | CScriptVarPrimitivePtr toPrimitive_hintNumber(CScriptResult &execute); ///< if the var an ObjectType gets the valueOf; if valueOf of an ObjectType gets toString / otherwise gets the Var itself
|
---|
| 705 |
|
---|
| 706 | CScriptVarPtr callJS_toString(CScriptResult &execute, int radix=0);
|
---|
| 707 | virtual CScriptVarPtr toString_CallBack(CScriptResult &execute, int radix=0);
|
---|
| 708 | CScriptVarPtr callJS_valueOf(CScriptResult &execute);
|
---|
| 709 | virtual CScriptVarPtr valueOf_CallBack();
|
---|
| 710 |
|
---|
| 711 | CNumber toNumber();
|
---|
| 712 | CNumber toNumber(CScriptResult &execute);
|
---|
| 713 | virtual bool toBoolean();
|
---|
| 714 | std::string toString(int32_t radix=0); ///< shortcut for this->toPrimitive_hintString()->toCString();
|
---|
| 715 | std::string toString(CScriptResult &execute, int32_t radix=0); ///< shortcut for this->toPrimitive_hintString(execute)->toCString();
|
---|
| 716 | #define WARN_DEPRECATED
|
---|
| 717 | #ifdef WARN_DEPRECATED
|
---|
| 718 | int DEPRECATED("getInt() is deprecated use toNumber().toInt32 instead") getInt();
|
---|
| 719 | bool DEPRECATED("getBool() is deprecated use toBoolean() instead") getBool();
|
---|
| 720 | double DEPRECATED("getDouble() is deprecated use toNumber().toDouble() instead") getDouble();
|
---|
| 721 | std::string DEPRECATED("getString() is deprecated use toString() instead") getString();
|
---|
| 722 | #else
|
---|
| 723 | int getInt();
|
---|
| 724 | bool getBool();
|
---|
| 725 | double getDouble();
|
---|
| 726 | std::string getString();
|
---|
| 727 | #endif
|
---|
| 728 | virtual CScriptTokenDataFnc *getFunctionData(); ///< { return 0; }
|
---|
| 729 |
|
---|
| 730 | virtual CScriptVarPtr toObject()=0;
|
---|
| 731 |
|
---|
| 732 | CScriptVarPtr toIterator(int Mode=3);
|
---|
| 733 | CScriptVarPtr toIterator(CScriptResult &execute, int Mode=3);
|
---|
| 734 |
|
---|
| 735 |
|
---|
| 736 | // virtual std::string getParsableString(const std::string &indentString, const std::string &indent, bool &hasRecursion); ///< get Data as a parsable javascript string
|
---|
| 737 | #define getParsableStringRecursionsCheck() do{ \
|
---|
| 738 | if(uniqueID && uniqueID==temporaryID) { hasRecursion=true; return "recursion"; } \
|
---|
| 739 | temporaryID = uniqueID; \
|
---|
| 740 | } while(0)
|
---|
| 741 | virtual std::string getParsableString(const std::string &indentString, const std::string &indent, uint32_t uniqueID, bool &hasRecursion); ///< get Data as a parsable javascript string
|
---|
| 742 | virtual std::string getVarType()=0;
|
---|
| 743 |
|
---|
| 744 | #ifdef WARN_DEPRECATED
|
---|
| 745 | CScriptVarPtr DEPRECATED("getNumericVar() is deprecated use toNumber() instead") getNumericVar(); ///< returns an Integer, a Double, an Infinity or a NaN
|
---|
| 746 | #else
|
---|
| 747 | CScriptVarPtr getNumericVar(); ///< returns an Integer, a Double, an Infinity or a NaN
|
---|
| 748 | #endif
|
---|
| 749 |
|
---|
| 750 | //////////////////////////////////////////////////////////////////////////
|
---|
| 751 | /// Childs
|
---|
| 752 | //////////////////////////////////////////////////////////////////////////
|
---|
| 753 |
|
---|
| 754 |
|
---|
| 755 | CScriptVarPtr getOwnPropertyDescriptor(const std::string &Name);
|
---|
| 756 | const char *defineProperty(const std::string &Name, CScriptVarPtr Attributes);
|
---|
| 757 |
|
---|
| 758 | /// flags
|
---|
| 759 | void setExtensible(bool On=true) { extensible=On; }
|
---|
| 760 | void preventExtensions() { extensible=false; }
|
---|
| 761 | bool isExtensible() const { return extensible; }
|
---|
| 762 | void seal();
|
---|
| 763 | bool isSealed() const;
|
---|
| 764 | void freeze();
|
---|
| 765 | bool isFrozen() const;
|
---|
| 766 |
|
---|
| 767 | /// find
|
---|
| 768 | CScriptVarLinkPtr findChild(const std::string &childName); ///< Tries to find a child with the given name, may return 0
|
---|
| 769 | CScriptVarLinkWorkPtr findChildWithStringChars(const std::string &childName);
|
---|
| 770 | CScriptVarLinkPtr findChildInPrototypeChain(const std::string &childName);
|
---|
| 771 | CScriptVarLinkWorkPtr findChildWithPrototypeChain(const std::string &childName);
|
---|
| 772 | CScriptVarLinkPtr findChildByPath(const std::string &path); ///< Tries to find a child with the given path (separated by dots)
|
---|
| 773 | CScriptVarLinkPtr findChildOrCreate(const std::string &childName/*, int varFlags=SCRIPTVAR_UNDEFINED*/); ///< Tries to find a child with the given name, or will create it with the given flags
|
---|
| 774 | CScriptVarLinkPtr findChildOrCreateByPath(const std::string &path); ///< Tries to find a child with the given path (separated by dots)
|
---|
| 775 | void keys(STRING_SET_t &Keys, bool OnlyEnumerable=true, uint32_t ID=0);
|
---|
| 776 | /// add & remove
|
---|
| 777 | CScriptVarLinkPtr addChild(const std::string &childName, const CScriptVarPtr &child, int linkFlags = SCRIPTVARLINK_DEFAULT);
|
---|
| 778 | CScriptVarLinkPtr DEPRECATED("addChildNoDup is deprecated use addChildOrReplace instead!") addChildNoDup(const std::string &childName, const CScriptVarPtr &child, int linkFlags = SCRIPTVARLINK_DEFAULT);
|
---|
| 779 | CScriptVarLinkPtr addChildOrReplace(const std::string &childName, const CScriptVarPtr &child, int linkFlags = SCRIPTVARLINK_DEFAULT); ///< add a child overwriting any with the same name
|
---|
| 780 | bool removeLink(CScriptVarLinkPtr &link); ///< Remove a specific link (this is faster than finding via a child)
|
---|
| 781 | void removeAllChildren();
|
---|
| 782 |
|
---|
| 783 | /// ARRAY
|
---|
| 784 | CScriptVarPtr getArrayIndex(uint32_t idx); ///< The the value at an array index
|
---|
| 785 | void setArrayIndex(uint32_t idx, const CScriptVarPtr &value); ///< Set the value at an array index
|
---|
| 786 | uint32_t getArrayLength(); ///< If this is an array, return the number of items in it (else 0)
|
---|
| 787 |
|
---|
| 788 | //////////////////////////////////////////////////////////////////////////
|
---|
| 789 | int getChildren() { return Childs.size(); } ///< Get the number of children
|
---|
| 790 | CTinyJS *getContext() { return context; }
|
---|
| 791 | CScriptVarPtr mathsOp(const CScriptVarPtr &b, int op); ///< do a maths op with another script variable
|
---|
| 792 |
|
---|
| 793 | void trace(const std::string &name = ""); ///< Dump out the contents of this using trace
|
---|
| 794 | void trace(std::string &indentStr, uint32_t uniqueID, const std::string &name = ""); ///< Dump out the contents of this using trace
|
---|
| 795 | std::string getFlagsAsString(); ///< For debugging - just dump a string version of the flags
|
---|
| 796 | // void getJSON(std::ostringstream &destination, const std::string linePrefix=""); ///< Write out all the JS code needed to recreate this script variable to the stream (as JSON)
|
---|
| 797 |
|
---|
| 798 | SCRIPTVAR_CHILDS_t Childs;
|
---|
| 799 |
|
---|
| 800 | /// For memory management/garbage collection
|
---|
| 801 | private:
|
---|
| 802 | CScriptVar *ref(); ///< Add reference to this variable
|
---|
| 803 | void unref(); ///< Remove a reference, and delete this variable if required
|
---|
| 804 | public:
|
---|
| 805 | int getRefs(); ///< Get the number of references to this script variable
|
---|
| 806 | template<class T>
|
---|
| 807 | operator T *(){ T *ret = dynamic_cast<T*>(this); ASSERT(ret!=0); return ret; }
|
---|
| 808 | template<class T>
|
---|
| 809 | T *get(){ T *ret = dynamic_cast<T*>(this); ASSERT(ret!=0); return ret; }
|
---|
| 810 |
|
---|
| 811 | //CScriptVarPtr newScriptVar(const CNumber &t); // { return ::newScriptVar(context, t); }
|
---|
| 812 | template<typename T> CScriptVarPtr newScriptVar(T t); // { return ::newScriptVar(context, t); }
|
---|
| 813 | template<typename T1, typename T2> CScriptVarPtr newScriptVar(T1 t1, T2 t2); // { return ::newScriptVar(context, t); }
|
---|
| 814 | template<typename T> const CScriptVarPtr &constScriptVar(T t); // { return ::newScriptVar(context, t); }
|
---|
| 815 | void setTemporaryID(uint32_t ID) { temporaryID = ID; }
|
---|
| 816 | virtual void setTemporaryID_recursive(uint32_t ID);
|
---|
| 817 | uint32_t getTempraryID() { return temporaryID; }
|
---|
| 818 | protected:
|
---|
| 819 | bool extensible;
|
---|
| 820 | CTinyJS *context;
|
---|
| 821 | int refs; ///< The number of references held to this - used for garbage collection
|
---|
| 822 | CScriptVar *prev;
|
---|
| 823 | public:
|
---|
| 824 | CScriptVar *next;
|
---|
| 825 | uint32_t temporaryID;
|
---|
| 826 |
|
---|
| 827 | friend class CScriptVarPtr;
|
---|
| 828 | };
|
---|
| 829 |
|
---|
| 830 |
|
---|
| 831 | //////////////////////////////////////////////////////////////////////////
|
---|
| 832 | /// CScriptVarPtr
|
---|
| 833 | //////////////////////////////////////////////////////////////////////////
|
---|
| 834 |
|
---|
| 835 | class CScriptVarPtr {
|
---|
| 836 | public:
|
---|
| 837 | // construct
|
---|
| 838 | CScriptVarPtr() : var(0) {} ///< 0-Pointer
|
---|
| 839 | CScriptVarPtr(CScriptVar *Var) : var(Var) { if(var) var->ref(); } // creates a new CScriptVar (from new);
|
---|
| 840 |
|
---|
| 841 | // copy
|
---|
| 842 | CScriptVarPtr(const CScriptVarPtr &Copy) : var(Copy.var) { if(var) var->ref(); }
|
---|
| 843 | CScriptVarPtr& operator=(const CScriptVarPtr &Copy) {
|
---|
| 844 | if(var != Copy.var) {
|
---|
| 845 | if(var) var->unref();
|
---|
| 846 | var = Copy.var; if(var) var->ref();
|
---|
| 847 | }
|
---|
| 848 | return *this;
|
---|
| 849 | }
|
---|
| 850 | // deconstruct
|
---|
| 851 | ~CScriptVarPtr() { if(var) var->unref(); }
|
---|
| 852 |
|
---|
| 853 | // if
|
---|
| 854 | operator bool() const { return var!=0; }
|
---|
| 855 |
|
---|
| 856 | bool operator ==(const CScriptVarPtr &Other) const { return var == Other.var; }
|
---|
| 857 | bool operator !=(const CScriptVarPtr &Other) const { return var != Other.var; }
|
---|
| 858 |
|
---|
| 859 | // access
|
---|
| 860 | CScriptVar * operator ->() const { return var; }
|
---|
| 861 | CScriptVar *getVar() const { return var; }
|
---|
| 862 |
|
---|
| 863 | void clear() { if(var) var->unref(); var=0; }
|
---|
| 864 | protected:
|
---|
| 865 | CScriptVar *var;
|
---|
| 866 | };
|
---|
| 867 |
|
---|
| 868 | //////////////////////////////////////////////////////////////////////////
|
---|
| 869 | /// CScriptVarPointer - template
|
---|
| 870 | //////////////////////////////////////////////////////////////////////////
|
---|
| 871 |
|
---|
| 872 | template<typename C>
|
---|
| 873 | class CScriptVarPointer : public CScriptVarPtr {
|
---|
| 874 | public:
|
---|
| 875 | CScriptVarPointer() {}
|
---|
| 876 | CScriptVarPointer(CScriptVar *Var) : CScriptVarPtr(dynamic_cast<C*>(Var)) {}
|
---|
| 877 | CScriptVarPointer(const CScriptVarPtr &Copy) : CScriptVarPtr(dynamic_cast<C*>(Copy.getVar())) {}
|
---|
| 878 | CScriptVarPointer<C> &operator=(const CScriptVarPtr &Copy) { CScriptVarPtr::operator=(dynamic_cast<C*>(Copy.getVar())); return *this; }
|
---|
| 879 | C * operator ->() const { C *Var = dynamic_cast<C*>(var); ASSERT(var && Var); return Var; }
|
---|
| 880 | };
|
---|
| 881 |
|
---|
| 882 |
|
---|
| 883 | //////////////////////////////////////////////////////////////////////////
|
---|
| 884 | /// CScriptVarLink
|
---|
| 885 | //////////////////////////////////////////////////////////////////////////
|
---|
| 886 | class CScriptVarLink : public fixed_size_object<CScriptVarLink>
|
---|
| 887 | {
|
---|
| 888 | private: // prevent gloabal creating
|
---|
| 889 | CScriptVarLink(const CScriptVarPtr &var, const std::string &name = TINYJS_TEMP_NAME, int flags = SCRIPTVARLINK_DEFAULT);
|
---|
| 890 | private: // prevent Copy
|
---|
| 891 | CScriptVarLink(const CScriptVarLink &link) MEMBER_DELETE; ///< Copy constructor
|
---|
| 892 | public:
|
---|
| 893 | ~CScriptVarLink();
|
---|
| 894 |
|
---|
| 895 | const std::string &getName() const { return name; }
|
---|
| 896 |
|
---|
| 897 | int getFlags() { return flags; }
|
---|
| 898 | const CScriptVarPtr &getVarPtr() const { return var; }
|
---|
| 899 | const CScriptVarPtr &setVarPtr(const CScriptVarPtr &Var) { return var = Var; } ///< simple Replace the Variable pointed to
|
---|
| 900 |
|
---|
| 901 |
|
---|
| 902 | bool isOwned() const { return owner!=0; }
|
---|
| 903 |
|
---|
| 904 | bool isWritable() const { return (flags & SCRIPTVARLINK_WRITABLE) != 0; }
|
---|
| 905 | void setWritable(bool On) { On ? (flags |= SCRIPTVARLINK_WRITABLE) : (flags &= ~SCRIPTVARLINK_WRITABLE); }
|
---|
| 906 | bool isConfigurable() const { return (flags & SCRIPTVARLINK_CONFIGURABLE) != 0; }
|
---|
| 907 | void setConfigurable(bool On) { On ? (flags |= SCRIPTVARLINK_CONFIGURABLE) : (flags &= ~SCRIPTVARLINK_CONFIGURABLE); }
|
---|
| 908 | bool isEnumerable() const { return (flags & SCRIPTVARLINK_ENUMERABLE) != 0; }
|
---|
| 909 | void setEnumerable(bool On) { On ? (flags |= SCRIPTVARLINK_ENUMERABLE) : (flags &= ~SCRIPTVARLINK_ENUMERABLE); }
|
---|
| 910 |
|
---|
| 911 | CScriptVar *getOwner() { return owner; };
|
---|
| 912 | void setOwner(CScriptVar *Owner) { owner = Owner; }
|
---|
| 913 |
|
---|
| 914 | /// forward to ScriptVar
|
---|
| 915 |
|
---|
| 916 | CScriptVarPrimitivePtr toPrimitive() { ///< by default call getDefaultValue_hintNumber by a Date-object calls getDefaultValue_hintString
|
---|
| 917 | return var->toPrimitive(); }
|
---|
| 918 | CScriptVarPrimitivePtr toPrimitive(CScriptResult &execute) { ///< if the var an ObjectType gets the valueOf; if valueOf of an ObjectType gets toString / otherwise gets the Var itself
|
---|
| 919 | return var->toPrimitive(execute); }
|
---|
| 920 | CScriptVarPrimitivePtr toPrimitive_hintString(int32_t radix=0) { ///< if the var an ObjectType gets the valueOf; if valueOf of an ObjectType gets toString / otherwise gets the Var itself
|
---|
| 921 | return var->toPrimitive_hintString(radix); }
|
---|
| 922 | CScriptVarPrimitivePtr toPrimitive_hintString(CScriptResult &execute, int32_t radix=0) { ///< if the var an ObjectType gets the valueOf; if valueOf of an ObjectType gets toString / otherwise gets the Var itself
|
---|
| 923 | return var->toPrimitive_hintString(execute, radix); }
|
---|
| 924 | CScriptVarPrimitivePtr toPrimitive_hintNumber() { ///< if the var an ObjectType gets the valueOf; if valueOf of an ObjectType gets toString / otherwise gets the Var itself
|
---|
| 925 | return var->toPrimitive_hintNumber(); }
|
---|
| 926 | CScriptVarPrimitivePtr toPrimitive_hintNumber(CScriptResult &execute) { ///< if the var an ObjectType gets the valueOf; if valueOf of an ObjectType gets toString / otherwise gets the Var itself
|
---|
| 927 | return var->toPrimitive_hintNumber(execute); }
|
---|
| 928 |
|
---|
| 929 | CNumber toNumber(); // { return var->toNumber(); }
|
---|
| 930 | CNumber toNumber(CScriptResult &execute); // { return var->toNumber(execute); }
|
---|
| 931 | bool toBoolean() { return var->toBoolean(); }
|
---|
| 932 | std::string toString(int32_t radix=0) { ///< shortcut for this->toPrimitive_hintString()->toCString();
|
---|
| 933 | return var->toString(radix); }
|
---|
| 934 | std::string toString(CScriptResult &execute, int32_t radix=0) { ///< shortcut for this->toPrimitive_hintString(execute)->toCString();
|
---|
| 935 | return var->toString(execute, radix); }
|
---|
| 936 | CScriptVarPtr toObject() { return var->toObject(); };
|
---|
| 937 |
|
---|
| 938 | private:
|
---|
| 939 | std::string name;
|
---|
| 940 | CScriptVar *owner; // pointer to the owner CScriptVar
|
---|
| 941 | uint32_t flags;
|
---|
| 942 | CScriptVarPtr var;
|
---|
| 943 | #ifdef _DEBUG
|
---|
| 944 | char dummy[24];
|
---|
| 945 | #endif
|
---|
| 946 | CScriptVarLink *ref();
|
---|
| 947 | void unref();
|
---|
| 948 | private:
|
---|
| 949 | int refs;
|
---|
| 950 | friend class CScriptVarLinkPtr;
|
---|
| 951 | };
|
---|
| 952 |
|
---|
| 953 |
|
---|
| 954 | //////////////////////////////////////////////////////////////////////////
|
---|
| 955 | /// CScriptVarLinkPtr
|
---|
| 956 | //////////////////////////////////////////////////////////////////////////
|
---|
| 957 |
|
---|
| 958 | class CScriptVarLinkPtr {
|
---|
| 959 | public:
|
---|
| 960 | // construct
|
---|
| 961 | CScriptVarLinkPtr() : link(0) {} ///< 0-Pointer
|
---|
| 962 | CScriptVarLinkPtr(const CScriptVarPtr &var, const std::string &name = TINYJS_TEMP_NAME, int flags = SCRIPTVARLINK_DEFAULT) { link=(new CScriptVarLink(var, name, flags))->ref(); }
|
---|
| 963 | CScriptVarLinkPtr(CScriptVarLink *Link) : link(Link) { if(link) link->ref(); } // creates a new CScriptVarLink (from new);
|
---|
| 964 |
|
---|
| 965 | // reconstruct
|
---|
| 966 | CScriptVarLinkPtr &operator()(const CScriptVarPtr &var, const std::string &name = TINYJS_TEMP_NAME, int flags = SCRIPTVARLINK_DEFAULT);
|
---|
| 967 | CScriptVarLinkPtr &operator=(const CScriptVarPtr &var) { return operator()(var); }
|
---|
| 968 | // deconstruct
|
---|
| 969 | ~CScriptVarLinkPtr() { if(link) link->unref(); }
|
---|
| 970 |
|
---|
| 971 | // copy
|
---|
| 972 | CScriptVarLinkPtr(const CScriptVarLinkPtr &Copy) : link(Copy.link) { if(link) link->ref(); }
|
---|
| 973 | CScriptVarLinkPtr &operator=(const CScriptVarLinkPtr &Copy) {
|
---|
| 974 | if(link != Copy.link) {
|
---|
| 975 | if(link) link->unref();
|
---|
| 976 | link = Copy.link; if(link) link->ref();
|
---|
| 977 | }
|
---|
| 978 | return *this;
|
---|
| 979 | }
|
---|
| 980 |
|
---|
| 981 | // getter & setter
|
---|
| 982 | CScriptVarLinkWorkPtr getter();
|
---|
| 983 | CScriptVarLinkWorkPtr getter(CScriptResult &execute);
|
---|
| 984 | CScriptVarLinkWorkPtr setter(const CScriptVarPtr &Var);
|
---|
| 985 | CScriptVarLinkWorkPtr setter(CScriptResult &execute, const CScriptVarPtr &Var);
|
---|
| 986 |
|
---|
| 987 | // if
|
---|
| 988 | operator bool() const { return link!=0; }
|
---|
| 989 |
|
---|
| 990 | // for sorting in child-list
|
---|
| 991 | bool operator <(const std::string &rhs) const;
|
---|
| 992 | bool operator ==(const CScriptVarLinkPtr &rhs) const { return link==rhs.link; }
|
---|
| 993 | // access to CScriptVarLink
|
---|
| 994 | CScriptVarLink *operator ->() const { return link; }
|
---|
| 995 |
|
---|
| 996 | operator const CScriptVarPtr &() const { static CScriptVarPtr NullPtr; return link?link->getVarPtr():NullPtr; }
|
---|
| 997 |
|
---|
| 998 | void clear() { if(link) link->unref(); link=0; }
|
---|
| 999 | protected:
|
---|
| 1000 | CScriptVarLink *link;
|
---|
| 1001 | };
|
---|
| 1002 |
|
---|
| 1003 |
|
---|
| 1004 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1005 | /// CScriptVarLinkWorkPtr
|
---|
| 1006 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1007 |
|
---|
| 1008 | class CScriptVarLinkWorkPtr : public CScriptVarLinkPtr {
|
---|
| 1009 | public:
|
---|
| 1010 | // construct
|
---|
| 1011 | CScriptVarLinkWorkPtr() {}
|
---|
| 1012 | CScriptVarLinkWorkPtr(const CScriptVarPtr &var, const std::string &name = TINYJS_TEMP_NAME, int flags = SCRIPTVARLINK_DEFAULT) : CScriptVarLinkPtr(var, name, flags) {}
|
---|
| 1013 | CScriptVarLinkWorkPtr(CScriptVarLink *Link) : CScriptVarLinkPtr(Link) { if(link) referencedOwner = link->getOwner(); } // creates a new CScriptVarLink (from new);
|
---|
| 1014 | CScriptVarLinkWorkPtr(const CScriptVarLinkPtr &Copy) : CScriptVarLinkPtr(Copy) { if(link) referencedOwner = link->getOwner(); }
|
---|
| 1015 |
|
---|
| 1016 | // reconstruct
|
---|
| 1017 | CScriptVarLinkWorkPtr &operator()(const CScriptVarPtr &var, const std::string &name = TINYJS_TEMP_NAME, int flags = SCRIPTVARLINK_DEFAULT) {CScriptVarLinkPtr::operator()(var, name, flags); referencedOwner.clear(); return *this; }
|
---|
| 1018 |
|
---|
| 1019 | // copy
|
---|
| 1020 | CScriptVarLinkWorkPtr(const CScriptVarLinkWorkPtr &Copy) : CScriptVarLinkPtr(Copy), referencedOwner(Copy.referencedOwner) {}
|
---|
| 1021 | CScriptVarLinkWorkPtr &operator=(const CScriptVarLinkWorkPtr &Copy) { CScriptVarLinkPtr::operator=(Copy); referencedOwner = Copy.referencedOwner; return *this; }
|
---|
| 1022 |
|
---|
| 1023 | // getter & setter
|
---|
| 1024 | CScriptVarLinkWorkPtr getter();
|
---|
| 1025 | CScriptVarLinkWorkPtr getter(CScriptResult &execute);
|
---|
| 1026 | CScriptVarLinkWorkPtr setter(const CScriptVarPtr &Var);
|
---|
| 1027 | CScriptVarLinkWorkPtr setter(CScriptResult &execute, const CScriptVarPtr &Var);
|
---|
| 1028 |
|
---|
| 1029 |
|
---|
| 1030 | void swap(CScriptVarLinkWorkPtr &Link) {
|
---|
| 1031 | CScriptVarPtr _referencedOwner = referencedOwner; referencedOwner = Link.referencedOwner; Link.referencedOwner = _referencedOwner;
|
---|
| 1032 | CScriptVarLink *_link=link; link=Link.link; Link.link=_link;
|
---|
| 1033 | }
|
---|
| 1034 |
|
---|
| 1035 | void clear() { CScriptVarLinkPtr::clear(); referencedOwner.clear(); }
|
---|
| 1036 | void setReferencedOwner(const CScriptVarPtr &Owner) { referencedOwner = Owner; }
|
---|
| 1037 | const CScriptVarPtr &getReferencedOwner() const { return referencedOwner; }
|
---|
| 1038 | bool hasReferencedOwner() const { return referencedOwner; }
|
---|
| 1039 | private:
|
---|
| 1040 | CScriptVarPtr referencedOwner;
|
---|
| 1041 | };
|
---|
| 1042 |
|
---|
| 1043 |
|
---|
| 1044 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1045 | #define define_dummy_t(t1) struct t1##_t{}; extern t1##_t t1
|
---|
| 1046 | #define declare_dummy_t(t1) t1##_t t1
|
---|
| 1047 | #define define_newScriptVar_Fnc(t1, ...) CScriptVarPtr newScriptVar(__VA_ARGS__)
|
---|
| 1048 | #define define_newScriptVar_NamedFnc(t1, ...) CScriptVarPtr newScriptVar##t1(__VA_ARGS__)
|
---|
| 1049 | #define define_ScriptVarPtr_Type(t1) class CScriptVar##t1; typedef CScriptVarPointer<CScriptVar##t1> CScriptVar##t1##Ptr
|
---|
| 1050 |
|
---|
| 1051 | #define define_DEPRECATED_newScriptVar_Fnc(t1, ...) CScriptVarPtr DEPRECATED("newScriptVar("#__VA_ARGS__") is deprecated use constScriptVar("#__VA_ARGS__") instead") newScriptVar(__VA_ARGS__)
|
---|
| 1052 |
|
---|
| 1053 |
|
---|
| 1054 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1055 | /// CScriptVarPrimitive
|
---|
| 1056 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1057 |
|
---|
| 1058 | define_ScriptVarPtr_Type(Primitive);
|
---|
| 1059 | class CScriptVarPrimitive : public CScriptVar {
|
---|
| 1060 | protected:
|
---|
| 1061 | CScriptVarPrimitive(CTinyJS *Context, const CScriptVarPtr &Prototype) : CScriptVar(Context, Prototype) { setExtensible(false); }
|
---|
| 1062 | CScriptVarPrimitive(const CScriptVarPrimitive &Copy) : CScriptVar(Copy) { } ///< Copy protected -> use clone for public
|
---|
| 1063 | public:
|
---|
| 1064 | virtual ~CScriptVarPrimitive();
|
---|
| 1065 |
|
---|
| 1066 | virtual bool isPrimitive(); ///< return true;
|
---|
| 1067 |
|
---|
| 1068 | virtual CScriptVarPrimitivePtr getRawPrimitive();
|
---|
| 1069 | virtual bool toBoolean(); /// false by default
|
---|
| 1070 | virtual CNumber toNumber_Callback()=0;
|
---|
| 1071 | virtual std::string toCString(int radix=0)=0;
|
---|
| 1072 |
|
---|
| 1073 | virtual CScriptVarPtr toObject();
|
---|
| 1074 | virtual CScriptVarPtr toString_CallBack(CScriptResult &execute, int radix=0);
|
---|
| 1075 | protected:
|
---|
| 1076 | };
|
---|
| 1077 |
|
---|
| 1078 |
|
---|
| 1079 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1080 | /// CScriptVarUndefined
|
---|
| 1081 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1082 |
|
---|
| 1083 | define_dummy_t(Undefined);
|
---|
| 1084 | define_ScriptVarPtr_Type(Undefined);
|
---|
| 1085 | class CScriptVarUndefined : public CScriptVarPrimitive {
|
---|
| 1086 | protected:
|
---|
| 1087 | CScriptVarUndefined(CTinyJS *Context);
|
---|
| 1088 | CScriptVarUndefined(const CScriptVarUndefined &Copy) : CScriptVarPrimitive(Copy) {} ///< Copy protected -> use clone for public
|
---|
| 1089 | public:
|
---|
| 1090 | virtual ~CScriptVarUndefined();
|
---|
| 1091 | virtual CScriptVarPtr clone();
|
---|
| 1092 |
|
---|
| 1093 | virtual bool isUndefined(); // { return true; }
|
---|
| 1094 |
|
---|
| 1095 | virtual CNumber toNumber_Callback(); // { return NaN; }
|
---|
| 1096 | virtual std::string toCString(int radix=0);// { return "undefined"; }
|
---|
| 1097 |
|
---|
| 1098 | virtual std::string getVarType(); // { return "undefined"; }
|
---|
| 1099 | friend define_DEPRECATED_newScriptVar_Fnc(Undefined, CTinyJS *, Undefined_t);
|
---|
| 1100 | friend define_newScriptVar_NamedFnc(Undefined, CTinyJS *Context);
|
---|
| 1101 | };
|
---|
| 1102 | inline define_DEPRECATED_newScriptVar_Fnc(Undefined, CTinyJS *Context, Undefined_t) { return new CScriptVarUndefined(Context); }
|
---|
| 1103 | inline define_newScriptVar_NamedFnc(Undefined, CTinyJS *Context) { return new CScriptVarUndefined(Context); }
|
---|
| 1104 |
|
---|
| 1105 |
|
---|
| 1106 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1107 | /// CScriptVarNull
|
---|
| 1108 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1109 |
|
---|
| 1110 | define_dummy_t(Null);
|
---|
| 1111 | define_ScriptVarPtr_Type(Null);
|
---|
| 1112 | class CScriptVarNull : public CScriptVarPrimitive {
|
---|
| 1113 | protected:
|
---|
| 1114 | CScriptVarNull(CTinyJS *Context);
|
---|
| 1115 | CScriptVarNull(const CScriptVarNull &Copy) : CScriptVarPrimitive(Copy) {} ///< Copy protected -> use clone for public
|
---|
| 1116 | public:
|
---|
| 1117 | virtual ~CScriptVarNull();
|
---|
| 1118 | virtual CScriptVarPtr clone();
|
---|
| 1119 |
|
---|
| 1120 | virtual bool isNull(); // { return true; }
|
---|
| 1121 |
|
---|
| 1122 | virtual CNumber toNumber_Callback(); // { return 0; }
|
---|
| 1123 | virtual std::string toCString(int radix=0);// { return "null"; }
|
---|
| 1124 |
|
---|
| 1125 | virtual std::string getVarType(); // { return "null"; }
|
---|
| 1126 |
|
---|
| 1127 | friend define_DEPRECATED_newScriptVar_Fnc(Null, CTinyJS *Context, Null_t);
|
---|
| 1128 | friend define_newScriptVar_NamedFnc(Null, CTinyJS *Context);
|
---|
| 1129 | };
|
---|
| 1130 | inline define_DEPRECATED_newScriptVar_Fnc(Null, CTinyJS *Context, Null_t) { return new CScriptVarNull(Context); }
|
---|
| 1131 | inline define_newScriptVar_NamedFnc(Null, CTinyJS *Context) { return new CScriptVarNull(Context); }
|
---|
| 1132 |
|
---|
| 1133 |
|
---|
| 1134 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1135 | /// CScriptVarString
|
---|
| 1136 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1137 |
|
---|
| 1138 | define_ScriptVarPtr_Type(String);
|
---|
| 1139 | class CScriptVarString : public CScriptVarPrimitive {
|
---|
| 1140 | protected:
|
---|
| 1141 | CScriptVarString(CTinyJS *Context, const std::string &Data);
|
---|
| 1142 | CScriptVarString(const CScriptVarString &Copy) : CScriptVarPrimitive(Copy), data(Copy.data) {} ///< Copy protected -> use clone for public
|
---|
| 1143 | public:
|
---|
| 1144 | virtual ~CScriptVarString();
|
---|
| 1145 | virtual CScriptVarPtr clone();
|
---|
| 1146 | virtual bool isString(); // { return true; }
|
---|
| 1147 |
|
---|
| 1148 | virtual bool toBoolean();
|
---|
| 1149 | virtual CNumber toNumber_Callback();
|
---|
| 1150 | virtual std::string toCString(int radix=0);
|
---|
| 1151 |
|
---|
| 1152 | virtual std::string getParsableString(const std::string &indentString, const std::string &indent, uint32_t uniqueID, bool &hasRecursion); // { return getJSString(data); }
|
---|
| 1153 | virtual std::string getVarType(); // { return "string"; }
|
---|
| 1154 |
|
---|
| 1155 | virtual CScriptVarPtr toObject();
|
---|
| 1156 | virtual CScriptVarPtr toString_CallBack(CScriptResult &execute, int radix=0);
|
---|
| 1157 |
|
---|
| 1158 | uint32_t stringLength() { return data.size(); }
|
---|
| 1159 | int getChar(uint32_t Idx);
|
---|
| 1160 | protected:
|
---|
| 1161 | std::string data;
|
---|
| 1162 | private:
|
---|
| 1163 | friend define_newScriptVar_Fnc(String, CTinyJS *Context, const std::string &);
|
---|
| 1164 | friend define_newScriptVar_Fnc(String, CTinyJS *Context, const char *);
|
---|
| 1165 | friend define_newScriptVar_Fnc(String, CTinyJS *Context, char *);
|
---|
| 1166 | };
|
---|
| 1167 | inline define_newScriptVar_Fnc(String, CTinyJS *Context, const std::string &Obj) { return new CScriptVarString(Context, Obj); }
|
---|
| 1168 | inline define_newScriptVar_Fnc(String, CTinyJS *Context, const char *Obj) { return new CScriptVarString(Context, Obj); }
|
---|
| 1169 | inline define_newScriptVar_Fnc(String, CTinyJS *Context, char *Obj) { return new CScriptVarString(Context, Obj); }
|
---|
| 1170 |
|
---|
| 1171 |
|
---|
| 1172 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1173 | /// CNumber
|
---|
| 1174 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1175 | define_dummy_t(NegativeZero);
|
---|
| 1176 | define_dummy_t(NaN);
|
---|
| 1177 | class Infinity{public:Infinity(int Sig=1):sig(Sig){} int Sig(){return sig;} private:int sig; } ;
|
---|
| 1178 | extern Infinity InfinityPositive;
|
---|
| 1179 | extern Infinity InfinityNegative;
|
---|
| 1180 |
|
---|
| 1181 | class CNumber {
|
---|
| 1182 | private:
|
---|
| 1183 | enum NType {
|
---|
| 1184 | tnNULL, tInt32, tDouble, tNaN, tInfinity
|
---|
| 1185 | };
|
---|
| 1186 | CNumber(NType Type, int32_t InfinitySign=0) : type(Type) { Int32 = InfinitySign; }
|
---|
| 1187 | public:
|
---|
| 1188 |
|
---|
| 1189 | CNumber(const CNumber &Copy) { *this=Copy; }
|
---|
| 1190 |
|
---|
| 1191 | CNumber(int32_t Value=0) : type(tInt32) { Int32=Value; }
|
---|
| 1192 | #if 1
|
---|
| 1193 | template<typename T>CNumber(T Value) { *this = Value; }
|
---|
| 1194 | #else
|
---|
| 1195 | CNumber(negativeZero_t Value) { *this = Value; }
|
---|
| 1196 | CNumber(NaN_t Value) { *this = Value; }
|
---|
| 1197 | CNumber(Infinity Value) { *this = Value; }
|
---|
| 1198 | CNumber(uint32_t Value) { *this = Value; }
|
---|
| 1199 | CNumber(double Value) { *this = Value; }
|
---|
| 1200 | CNumber(unsigned char Value) { *this = Value; }
|
---|
| 1201 | CNumber(const char *Value) { *this = Value; }
|
---|
| 1202 | CNumber(const std::string &Value) { *this = Value; }
|
---|
| 1203 | #endif
|
---|
| 1204 | CNumber &operator=(NegativeZero_t) { type=tnNULL; Int32=0; return *this; }
|
---|
| 1205 | CNumber &operator=(NaN_t) { type=tNaN; Int32=0; return *this; }
|
---|
| 1206 | CNumber &operator=(Infinity v) { type=tInfinity; Int32=v.Sig(); return *this; }
|
---|
| 1207 | CNumber &operator=(int32_t Value) { type=tInt32; Int32=Value; return *this; }
|
---|
| 1208 | CNumber &operator=(uint32_t Value) {
|
---|
| 1209 | if(Value<=(uint32_t)std::numeric_limits<int32_t>::max())
|
---|
| 1210 | type=tInt32, Int32=int32_t(Value);
|
---|
| 1211 | else
|
---|
| 1212 | type=tDouble, Double=Value;
|
---|
| 1213 | return *this;
|
---|
| 1214 | }
|
---|
| 1215 | CNumber &operator=(double Value);
|
---|
| 1216 | CNumber &operator=(unsigned char Value) { type=tInt32; Int32=Value; return *this; }
|
---|
| 1217 | CNumber &operator=(const char *Value);
|
---|
| 1218 | CNumber &operator=(const std::string &Value) { return operator=(Value.c_str());}
|
---|
| 1219 |
|
---|
| 1220 | int32_t parseInt(const char *str, int32_t radix=0, const char **endptr=0);
|
---|
| 1221 | void parseInt(const std::string &str, int32_t radix=0) { parseInt(str.c_str(), radix); }
|
---|
| 1222 | void parseFloat(const char *str, const char **endptr=0);
|
---|
| 1223 | void parseFloat(const std::string &str) { parseFloat(str.c_str()); }
|
---|
| 1224 |
|
---|
| 1225 | CNumber add(const CNumber &Value) const;
|
---|
| 1226 | CNumber operator-() const;
|
---|
| 1227 | CNumber operator~() const { if(type==tNaN) return *this; else return ~toInt32(); }
|
---|
| 1228 | bool operator!() const { return isZero(); }
|
---|
| 1229 | CNumber multi(const CNumber &Value) const;
|
---|
| 1230 | CNumber div(const CNumber &Value) const;
|
---|
| 1231 | CNumber modulo(const CNumber &Value) const;
|
---|
| 1232 |
|
---|
| 1233 | CNumber round() const;
|
---|
| 1234 | CNumber floor() const;
|
---|
| 1235 | CNumber ceil() const;
|
---|
| 1236 | CNumber abs() const;
|
---|
| 1237 |
|
---|
| 1238 | CNumber shift(const CNumber &Value, bool right) const;
|
---|
| 1239 | CNumber ushift(const CNumber &Value, bool right=true) const;
|
---|
| 1240 |
|
---|
| 1241 | CNumber binary(const CNumber &Value, char Mode) const;
|
---|
| 1242 |
|
---|
| 1243 |
|
---|
| 1244 | int less(const CNumber &Value) const;
|
---|
| 1245 | bool equal(const CNumber &Value) const;
|
---|
| 1246 |
|
---|
| 1247 |
|
---|
| 1248 | bool isInt32() const { return type == tInt32; }
|
---|
| 1249 | bool isDouble() const { return type == tDouble; }
|
---|
| 1250 |
|
---|
| 1251 | bool isNaN() const { return type == tNaN; }
|
---|
| 1252 | int isInfinity() const { return type == tInfinity ? Int32 : 0; }
|
---|
| 1253 | bool isFinite() const { return type == tInt32 || type == tDouble || type == tnNULL; }
|
---|
| 1254 | bool isNegativeZero() const { return type==tnNULL; }
|
---|
| 1255 | bool isZero() const; ///< is 0, -0
|
---|
| 1256 | bool isInteger() const;
|
---|
| 1257 | int sign() const;
|
---|
| 1258 |
|
---|
| 1259 | int32_t toInt32() const { return cast<int32_t>(); }
|
---|
| 1260 | uint32_t toUInt32() const { return cast<uint32_t>(); }
|
---|
| 1261 | double toDouble() const;
|
---|
| 1262 | bool toBoolean() const { return !isZero() && type!=tNaN; }
|
---|
| 1263 | std::string toString(uint32_t Radix=10) const;
|
---|
| 1264 | private:
|
---|
| 1265 | template<typename T> T cast() const {
|
---|
| 1266 | switch(type) {
|
---|
| 1267 | case tInt32:
|
---|
| 1268 | return T(Int32);
|
---|
| 1269 | case tDouble:
|
---|
| 1270 | return T(Double);
|
---|
| 1271 | default:
|
---|
| 1272 | return T(0);
|
---|
| 1273 | }
|
---|
| 1274 | }
|
---|
| 1275 | NType type;
|
---|
| 1276 | union {
|
---|
| 1277 | int32_t Int32;
|
---|
| 1278 | double Double;
|
---|
| 1279 | };
|
---|
| 1280 | };
|
---|
| 1281 | inline CNumber operator+(const CNumber &lhs, const CNumber &rhs) { return lhs.add(rhs); }
|
---|
| 1282 | inline CNumber &operator+=(CNumber &lhs, const CNumber &rhs) { return lhs=lhs.add(rhs); }
|
---|
| 1283 | inline CNumber operator-(const CNumber &lhs, const CNumber &rhs) { return lhs.add(-rhs); }
|
---|
| 1284 | inline CNumber &operator-=(CNumber &lhs, const CNumber &rhs) { return lhs=lhs.add(-rhs); }
|
---|
| 1285 | inline CNumber operator*(const CNumber &lhs, const CNumber &rhs) { return lhs.multi(rhs); }
|
---|
| 1286 | inline CNumber &operator*=(CNumber &lhs, const CNumber &rhs) { return lhs=lhs.multi(rhs); }
|
---|
| 1287 | inline CNumber operator/(const CNumber &lhs, const CNumber &rhs) { return lhs.div(rhs); }
|
---|
| 1288 | inline CNumber &operator/=(CNumber &lhs, const CNumber &rhs) { return lhs=lhs.div(rhs); }
|
---|
| 1289 | inline CNumber operator%(const CNumber &lhs, const CNumber &rhs) { return lhs.modulo(rhs); }
|
---|
| 1290 | inline CNumber &operator%=(CNumber &lhs, const CNumber &rhs) { return lhs=lhs.modulo(rhs); }
|
---|
| 1291 | inline CNumber operator>>(const CNumber &lhs, const CNumber &rhs) { return lhs.shift(rhs, true); }
|
---|
| 1292 | inline CNumber &operator>>=(CNumber &lhs, const CNumber &rhs) { return lhs=lhs.shift(rhs, true); }
|
---|
| 1293 | inline CNumber operator<<(const CNumber &lhs, const CNumber &rhs) { return lhs.shift(rhs, false); }
|
---|
| 1294 | inline CNumber &operator<<=(CNumber &lhs, const CNumber &rhs) { return lhs=lhs.shift(rhs, false); }
|
---|
| 1295 |
|
---|
| 1296 | inline bool operator==(const CNumber &lhs, const CNumber &rhs) { return lhs.equal(rhs); }
|
---|
| 1297 | inline bool operator!=(const CNumber &lhs, const CNumber &rhs) { return !lhs.equal(rhs); }
|
---|
| 1298 | inline bool operator<(const CNumber &lhs, const CNumber &rhs) { return lhs.less(rhs)>0; }
|
---|
| 1299 | inline bool operator<=(const CNumber &lhs, const CNumber &rhs) { return rhs.less(lhs)<0; }
|
---|
| 1300 | inline bool operator>(const CNumber &lhs, const CNumber &rhs) { return rhs.less(lhs)>0; }
|
---|
| 1301 | inline bool operator>=(const CNumber &lhs, const CNumber &rhs) { return lhs.less(rhs)<0; }
|
---|
| 1302 |
|
---|
| 1303 | inline CNumber round(const CNumber &lhs) { return lhs.round(); }
|
---|
| 1304 | inline CNumber floor(const CNumber &lhs) { return lhs.floor(); }
|
---|
| 1305 | inline CNumber ceil(const CNumber &lhs) { return lhs.ceil(); }
|
---|
| 1306 | inline CNumber abs(const CNumber &lhs) { return lhs.abs(); }
|
---|
| 1307 |
|
---|
| 1308 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1309 | /// CScriptVarNumber
|
---|
| 1310 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1311 |
|
---|
| 1312 | define_ScriptVarPtr_Type(Number);
|
---|
| 1313 | class CScriptVarNumber : public CScriptVarPrimitive {
|
---|
| 1314 | protected:
|
---|
| 1315 | CScriptVarNumber(CTinyJS *Context, const CNumber &Data);
|
---|
| 1316 | CScriptVarNumber(const CScriptVarNumber &Copy) : CScriptVarPrimitive(Copy), data(Copy.data) {} ///< Copy protected -> use clone for public
|
---|
| 1317 | public:
|
---|
| 1318 | virtual ~CScriptVarNumber();
|
---|
| 1319 | virtual CScriptVarPtr clone();
|
---|
| 1320 | virtual bool isNumber(); // { return true; }
|
---|
| 1321 | virtual bool isInt(); // { return true; }
|
---|
| 1322 | virtual bool isDouble(); // { return true; }
|
---|
| 1323 | virtual bool isRealNumber(); // { return true; }
|
---|
| 1324 | virtual int isInfinity(); // { return data; }
|
---|
| 1325 | virtual bool isNaN();// { return true; }
|
---|
| 1326 |
|
---|
| 1327 | virtual bool toBoolean();
|
---|
| 1328 | virtual CNumber toNumber_Callback();
|
---|
| 1329 | virtual std::string toCString(int radix=0);
|
---|
| 1330 |
|
---|
| 1331 | virtual std::string getVarType(); // { return "number"; }
|
---|
| 1332 |
|
---|
| 1333 | virtual CScriptVarPtr toObject();
|
---|
| 1334 | private:
|
---|
| 1335 | CNumber data;
|
---|
| 1336 | friend define_newScriptVar_Fnc(Number, CTinyJS *Context, const CNumber &);
|
---|
| 1337 | friend define_newScriptVar_NamedFnc(Number, CTinyJS *Context, const CNumber &);
|
---|
| 1338 | };
|
---|
| 1339 | define_newScriptVar_Fnc(Number, CTinyJS *Context, const CNumber &Obj);
|
---|
| 1340 | inline define_newScriptVar_NamedFnc(Number, CTinyJS *Context, const CNumber &Obj) { return new CScriptVarNumber(Context, Obj); }
|
---|
| 1341 | inline define_newScriptVar_Fnc(Number, CTinyJS *Context, unsigned int Obj) { return newScriptVarNumber(Context, CNumber(Obj)); }
|
---|
| 1342 | inline define_newScriptVar_Fnc(Number, CTinyJS *Context, int Obj) { return newScriptVarNumber(Context, CNumber(Obj)); }
|
---|
| 1343 | inline define_newScriptVar_Fnc(Number, CTinyJS *Context, double Obj) { return newScriptVarNumber(Context, CNumber(Obj)); }
|
---|
| 1344 | inline define_DEPRECATED_newScriptVar_Fnc(NaN, CTinyJS *Context, NaN_t) { return newScriptVarNumber(Context, CNumber(NaN)); }
|
---|
| 1345 | inline define_DEPRECATED_newScriptVar_Fnc(Infinity, CTinyJS *Context, Infinity Obj) { return newScriptVarNumber(Context, CNumber(Obj)); }
|
---|
| 1346 |
|
---|
| 1347 |
|
---|
| 1348 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1349 | /// CScriptVarBool
|
---|
| 1350 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1351 |
|
---|
| 1352 | define_ScriptVarPtr_Type(Bool);
|
---|
| 1353 | class CScriptVarBool : public CScriptVarPrimitive {
|
---|
| 1354 | protected:
|
---|
| 1355 | CScriptVarBool(CTinyJS *Context, bool Data);
|
---|
| 1356 | CScriptVarBool(const CScriptVarBool &Copy) : CScriptVarPrimitive(Copy), data(Copy.data) {} ///< Copy protected -> use clone for public
|
---|
| 1357 | public:
|
---|
| 1358 | virtual ~CScriptVarBool();
|
---|
| 1359 | virtual CScriptVarPtr clone();
|
---|
| 1360 | virtual bool isBool(); // { return true; }
|
---|
| 1361 |
|
---|
| 1362 | virtual bool toBoolean();
|
---|
| 1363 | virtual CNumber toNumber_Callback();
|
---|
| 1364 | virtual std::string toCString(int radix=0);
|
---|
| 1365 |
|
---|
| 1366 | virtual std::string getVarType(); // { return "boolean"; }
|
---|
| 1367 |
|
---|
| 1368 | virtual CScriptVarPtr toObject();
|
---|
| 1369 | protected:
|
---|
| 1370 | bool data;
|
---|
| 1371 |
|
---|
| 1372 | friend define_DEPRECATED_newScriptVar_Fnc(Bool, CTinyJS *, bool);
|
---|
| 1373 | friend define_newScriptVar_NamedFnc(Bool, CTinyJS *Context, bool);
|
---|
| 1374 | };
|
---|
| 1375 | inline define_DEPRECATED_newScriptVar_Fnc(Bool, CTinyJS *Context, bool Obj) { return new CScriptVarBool(Context, Obj); }
|
---|
| 1376 | inline define_newScriptVar_NamedFnc(Bool, CTinyJS *Context, bool Obj) { return new CScriptVarBool(Context, Obj); }
|
---|
| 1377 |
|
---|
| 1378 |
|
---|
| 1379 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1380 | /// CScriptVarObject
|
---|
| 1381 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1382 |
|
---|
| 1383 | define_dummy_t(StopIteration);
|
---|
| 1384 | define_dummy_t(Object);
|
---|
| 1385 | define_ScriptVarPtr_Type(Object);
|
---|
| 1386 |
|
---|
| 1387 | class CScriptVarObject : public CScriptVar {
|
---|
| 1388 | protected:
|
---|
| 1389 | CScriptVarObject(CTinyJS *Context);
|
---|
| 1390 | CScriptVarObject(CTinyJS *Context, const CScriptVarPtr &Prototype) : CScriptVar(Context, Prototype) {}
|
---|
| 1391 | CScriptVarObject(CTinyJS *Context, const CScriptVarPrimitivePtr &Value, const CScriptVarPtr &Prototype) : CScriptVar(Context, Prototype), value(Value) {}
|
---|
| 1392 | CScriptVarObject(const CScriptVarObject &Copy) : CScriptVar(Copy) {} ///< Copy protected -> use clone for public
|
---|
| 1393 | public:
|
---|
| 1394 | virtual ~CScriptVarObject();
|
---|
| 1395 | virtual CScriptVarPtr clone();
|
---|
| 1396 |
|
---|
| 1397 | virtual CScriptVarPrimitivePtr getRawPrimitive();
|
---|
| 1398 | virtual bool isObject(); // { return true; }
|
---|
| 1399 |
|
---|
| 1400 | virtual std::string getParsableString(const std::string &indentString, const std::string &indent, uint32_t uniqueID, bool &hasRecursion);
|
---|
| 1401 | virtual std::string getVarType(); ///< always "object"
|
---|
| 1402 | virtual CScriptVarPtr toObject();
|
---|
| 1403 |
|
---|
| 1404 | virtual CScriptVarPtr valueOf_CallBack();
|
---|
| 1405 | virtual CScriptVarPtr toString_CallBack(CScriptResult &execute, int radix=0);
|
---|
| 1406 | virtual void setTemporaryID_recursive(uint32_t ID);
|
---|
| 1407 | protected:
|
---|
| 1408 | private:
|
---|
| 1409 | CScriptVarPrimitivePtr value;
|
---|
| 1410 | friend define_newScriptVar_Fnc(Object, CTinyJS *Context, Object_t);
|
---|
| 1411 | friend define_newScriptVar_Fnc(Object, CTinyJS *Context, Object_t, const CScriptVarPtr &);
|
---|
| 1412 | friend define_newScriptVar_Fnc(Object, CTinyJS *Context, const CScriptVarPtr &);
|
---|
| 1413 | friend define_newScriptVar_Fnc(Object, CTinyJS *Context, const CScriptVarPrimitivePtr &, const CScriptVarPtr &);
|
---|
| 1414 | };
|
---|
| 1415 | inline define_newScriptVar_Fnc(Object, CTinyJS *Context, Object_t) { return new CScriptVarObject(Context); }
|
---|
| 1416 | inline define_newScriptVar_Fnc(Object, CTinyJS *Context, Object_t, const CScriptVarPtr &Prototype) { return new CScriptVarObject(Context, Prototype); }
|
---|
| 1417 | inline define_newScriptVar_Fnc(Object, CTinyJS *Context, const CScriptVarPtr &Prototype) { return new CScriptVarObject(Context, Prototype); }
|
---|
| 1418 | inline define_newScriptVar_Fnc(Object, CTinyJS *Context, const CScriptVarPrimitivePtr &Value, const CScriptVarPtr &Prototype) { return new CScriptVarObject(Context, Value, Prototype); }
|
---|
| 1419 |
|
---|
| 1420 |
|
---|
| 1421 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1422 | /// CScriptVarError
|
---|
| 1423 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1424 |
|
---|
| 1425 | define_ScriptVarPtr_Type(Error);
|
---|
| 1426 |
|
---|
| 1427 | class CScriptVarError : public CScriptVarObject {
|
---|
| 1428 | protected:
|
---|
| 1429 | CScriptVarError(CTinyJS *Context, ERROR_TYPES type, const char *message, const char *file, int line, int column);// : CScriptVarObject(Context), value(Value) {}
|
---|
| 1430 | CScriptVarError(const CScriptVarError &Copy) : CScriptVarObject(Copy) {} ///< Copy protected -> use clone for public
|
---|
| 1431 | public:
|
---|
| 1432 | virtual ~CScriptVarError();
|
---|
| 1433 | virtual CScriptVarPtr clone();
|
---|
| 1434 | virtual bool isError(); // { return true; }
|
---|
| 1435 |
|
---|
| 1436 | // virtual std::string getParsableString(const std::string &indentString, const std::string &indent); ///< get Data as a parsable javascript string
|
---|
| 1437 |
|
---|
| 1438 | virtual CScriptVarPtr toString_CallBack(CScriptResult &execute, int radix=0);
|
---|
| 1439 | CScriptException *toCScriptException();
|
---|
| 1440 | private:
|
---|
| 1441 | friend define_newScriptVar_NamedFnc(Error, CTinyJS *Context, ERROR_TYPES type, const char *message, const char *file, int line, int column);
|
---|
| 1442 | friend define_newScriptVar_NamedFnc(Error, CTinyJS *Context, const CScriptException &Exception);
|
---|
| 1443 | };
|
---|
| 1444 | inline define_newScriptVar_NamedFnc(Error, CTinyJS *Context, ERROR_TYPES type, const char *message=0, const char *file=0, int line=-1, int column=-1) { return new CScriptVarError(Context, type, message, file, line, column); }
|
---|
| 1445 | inline define_newScriptVar_NamedFnc(Error, CTinyJS *Context, const CScriptException &Exception) { return new CScriptVarError(Context, Exception.errorType, Exception.message.c_str(), Exception.fileName.c_str(), Exception.lineNumber, Exception.column); }
|
---|
| 1446 |
|
---|
| 1447 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1448 | /// CScriptVarArray
|
---|
| 1449 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1450 |
|
---|
| 1451 | define_dummy_t(Array);
|
---|
| 1452 | define_ScriptVarPtr_Type(Array);
|
---|
| 1453 | class CScriptVarArray : public CScriptVarObject {
|
---|
| 1454 | protected:
|
---|
| 1455 | CScriptVarArray(CTinyJS *Context);
|
---|
| 1456 | CScriptVarArray(const CScriptVarArray &Copy) : CScriptVarObject(Copy) {} ///< Copy protected -> use clone for public
|
---|
| 1457 | public:
|
---|
| 1458 | virtual ~CScriptVarArray();
|
---|
| 1459 | virtual CScriptVarPtr clone();
|
---|
| 1460 | virtual bool isArray(); // { return true; }
|
---|
| 1461 |
|
---|
| 1462 | virtual std::string getParsableString(const std::string &indentString, const std::string &indent, uint32_t uniqueID, bool &hasRecursion);
|
---|
| 1463 |
|
---|
| 1464 | virtual CScriptVarPtr toString_CallBack(CScriptResult &execute, int radix=0);
|
---|
| 1465 |
|
---|
| 1466 | friend define_newScriptVar_Fnc(Array, CTinyJS *Context, Array_t);
|
---|
| 1467 | private:
|
---|
| 1468 | void native_Length(const CFunctionsScopePtr &c, void *data);
|
---|
| 1469 | };
|
---|
| 1470 | inline define_newScriptVar_Fnc(Array, CTinyJS *Context, Array_t) { return new CScriptVarArray(Context); }
|
---|
| 1471 |
|
---|
| 1472 |
|
---|
| 1473 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1474 | /// CScriptVarRegExp
|
---|
| 1475 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1476 | #ifndef NO_REGEXP
|
---|
| 1477 |
|
---|
| 1478 | define_ScriptVarPtr_Type(RegExp);
|
---|
| 1479 | class CScriptVarRegExp : public CScriptVarObject {
|
---|
| 1480 | protected:
|
---|
| 1481 | CScriptVarRegExp(CTinyJS *Context, const std::string &Source, const std::string &Flags);
|
---|
| 1482 | CScriptVarRegExp(const CScriptVarRegExp &Copy) : CScriptVarObject(Copy), regexp(Copy.regexp), flags(Copy.flags) {} ///< Copy protected -> use clone for public
|
---|
| 1483 | public:
|
---|
| 1484 | virtual ~CScriptVarRegExp();
|
---|
| 1485 | virtual CScriptVarPtr clone();
|
---|
| 1486 | virtual bool isRegExp(); // { return true; }
|
---|
| 1487 | virtual CScriptVarPtr toString_CallBack(CScriptResult &execute, int radix=0);
|
---|
| 1488 |
|
---|
| 1489 | CScriptVarPtr exec(const std::string &Input, bool Test=false);
|
---|
| 1490 |
|
---|
| 1491 | bool Global() { return flags.find('g')!=std::string::npos; }
|
---|
| 1492 | bool IgnoreCase() { return flags.find('i')!=std::string::npos; }
|
---|
| 1493 | bool Multiline() { return true; /* currently always true -- flags.find('m')!=std::string::npos;*/ }
|
---|
| 1494 | bool Sticky() { return flags.find('y')!=std::string::npos; }
|
---|
| 1495 | const std::string &Regexp() { return regexp; }
|
---|
| 1496 | unsigned int LastIndex();
|
---|
| 1497 | void LastIndex(unsigned int Idx);
|
---|
| 1498 |
|
---|
| 1499 | static const char *ErrorStr(int Error);
|
---|
| 1500 | protected:
|
---|
| 1501 | std::string regexp;
|
---|
| 1502 | std::string flags;
|
---|
| 1503 | private:
|
---|
| 1504 | void native_Global(const CFunctionsScopePtr &c, void *data);
|
---|
| 1505 | void native_IgnoreCase(const CFunctionsScopePtr &c, void *data);
|
---|
| 1506 | void native_Multiline(const CFunctionsScopePtr &c, void *data);
|
---|
| 1507 | void native_Sticky(const CFunctionsScopePtr &c, void *data);
|
---|
| 1508 | void native_Source(const CFunctionsScopePtr &c, void *data);
|
---|
| 1509 |
|
---|
| 1510 | friend define_newScriptVar_Fnc(RegExp, CTinyJS *Context, const std::string &, const std::string &);
|
---|
| 1511 |
|
---|
| 1512 | };
|
---|
| 1513 | inline define_newScriptVar_Fnc(RegExp, CTinyJS *Context, const std::string &Obj, const std::string &Flags) { return new CScriptVarRegExp(Context, Obj, Flags); }
|
---|
| 1514 |
|
---|
| 1515 | #endif /* NO_REGEXP */
|
---|
| 1516 |
|
---|
| 1517 |
|
---|
| 1518 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1519 | /// CScriptVarDefaultIterator
|
---|
| 1520 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1521 |
|
---|
| 1522 | define_dummy_t(DefaultIterator);
|
---|
| 1523 | define_ScriptVarPtr_Type(DefaultIterator);
|
---|
| 1524 |
|
---|
| 1525 | class CScriptVarDefaultIterator : public CScriptVarObject {
|
---|
| 1526 | protected:
|
---|
| 1527 | CScriptVarDefaultIterator(CTinyJS *Context, const CScriptVarPtr &Object, int Mode);
|
---|
| 1528 | CScriptVarDefaultIterator(const CScriptVarDefaultIterator &Copy)
|
---|
| 1529 | :
|
---|
| 1530 | CScriptVarObject(Copy), mode(Copy.mode), object(Copy.object),
|
---|
| 1531 | keys(Copy.keys), pos(keys.begin()){} ///< Copy protected -> use clone for public
|
---|
| 1532 | public:
|
---|
| 1533 | virtual ~CScriptVarDefaultIterator();
|
---|
| 1534 | virtual CScriptVarPtr clone();
|
---|
| 1535 | virtual bool isIterator();
|
---|
| 1536 |
|
---|
| 1537 | void native_next(const CFunctionsScopePtr &c, void *data);
|
---|
| 1538 | private:
|
---|
| 1539 | int mode;
|
---|
| 1540 | CScriptVarPtr object;
|
---|
| 1541 | STRING_SET_t keys;
|
---|
| 1542 | STRING_SET_it pos;
|
---|
| 1543 | friend define_newScriptVar_NamedFnc(DefaultIterator, CTinyJS *, const CScriptVarPtr &, int);
|
---|
| 1544 |
|
---|
| 1545 | };
|
---|
| 1546 | inline define_newScriptVar_NamedFnc(DefaultIterator, CTinyJS *Context, const CScriptVarPtr &Object, int Mode) { return new CScriptVarDefaultIterator(Context, Object, Mode); }
|
---|
| 1547 |
|
---|
| 1548 |
|
---|
| 1549 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1550 | /// CScriptVarFunction
|
---|
| 1551 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1552 |
|
---|
| 1553 | define_ScriptVarPtr_Type(Function);
|
---|
| 1554 | class CScriptVarFunction : public CScriptVarObject {
|
---|
| 1555 | protected:
|
---|
| 1556 | CScriptVarFunction(CTinyJS *Context, CScriptTokenDataFnc *Data);
|
---|
| 1557 | CScriptVarFunction(const CScriptVarFunction &Copy) : CScriptVarObject(Copy), data(Copy.data) { data->ref(); } ///< Copy protected -> use clone for public
|
---|
| 1558 | public:
|
---|
| 1559 | virtual ~CScriptVarFunction();
|
---|
| 1560 | virtual CScriptVarPtr clone();
|
---|
| 1561 | virtual bool isObject(); // { return true; }
|
---|
| 1562 | virtual bool isFunction(); // { return true; }
|
---|
| 1563 | virtual bool isPrimitive(); // { return false; }
|
---|
| 1564 |
|
---|
| 1565 | virtual std::string getVarType(); // { return "function"; }
|
---|
| 1566 | virtual std::string getParsableString(const std::string &indentString, const std::string &indent, uint32_t uniqueID, bool &hasRecursion);
|
---|
| 1567 | virtual CScriptVarPtr toString_CallBack(CScriptResult &execute, int radix=0);
|
---|
| 1568 | virtual CScriptTokenDataFnc *getFunctionData();
|
---|
| 1569 | void setFunctionData(CScriptTokenDataFnc *Data);
|
---|
| 1570 | private:
|
---|
| 1571 | CScriptTokenDataFnc *data;
|
---|
| 1572 |
|
---|
| 1573 | friend define_newScriptVar_Fnc(Function, CTinyJS *Context, CScriptTokenDataFnc *);
|
---|
| 1574 | };
|
---|
| 1575 | inline define_newScriptVar_Fnc(Function, CTinyJS *Context, CScriptTokenDataFnc *Obj) { return new CScriptVarFunction(Context, Obj); }
|
---|
| 1576 |
|
---|
| 1577 |
|
---|
| 1578 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1579 | /// CScriptVarFunctionBounded
|
---|
| 1580 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1581 |
|
---|
| 1582 | define_ScriptVarPtr_Type(FunctionBounded);
|
---|
| 1583 | class CScriptVarFunctionBounded : public CScriptVarFunction {
|
---|
| 1584 | protected:
|
---|
| 1585 | CScriptVarFunctionBounded(CScriptVarFunctionPtr BoundedFunction, CScriptVarPtr BoundedThis, const std::vector<CScriptVarPtr> &BoundedArguments);
|
---|
| 1586 | CScriptVarFunctionBounded(const CScriptVarFunctionBounded &Copy) : CScriptVarFunction(Copy), boundedThis(Copy.boundedThis), boundedArguments(Copy.boundedArguments) { } ///< Copy protected -> use clone for public
|
---|
| 1587 | public:
|
---|
| 1588 | virtual ~CScriptVarFunctionBounded();
|
---|
| 1589 | virtual CScriptVarPtr clone();
|
---|
| 1590 | virtual bool isBounded(); ///< is CScriptVarFunctionBounded
|
---|
| 1591 | virtual void setTemporaryID_recursive(uint32_t ID);
|
---|
| 1592 | CScriptVarPtr callFunction(CScriptResult &execute, std::vector<CScriptVarPtr> &Arguments, const CScriptVarPtr &This, CScriptVarPtr *newThis=0);
|
---|
| 1593 | protected:
|
---|
| 1594 | private:
|
---|
| 1595 | CScriptVarFunctionPtr boundedFunction;
|
---|
| 1596 | CScriptVarPtr boundedThis;
|
---|
| 1597 | std::vector<CScriptVarPtr> boundedArguments;
|
---|
| 1598 |
|
---|
| 1599 | friend define_newScriptVar_NamedFnc(FunctionBounded, CScriptVarFunctionPtr BoundedFunction, CScriptVarPtr BoundedThis, const std::vector<CScriptVarPtr> &BoundedArguments);
|
---|
| 1600 | };
|
---|
| 1601 | inline define_newScriptVar_NamedFnc(FunctionBounded, CScriptVarFunctionPtr BoundedFunction, CScriptVarPtr BoundedThis, const std::vector<CScriptVarPtr> &BoundedArguments) { return new CScriptVarFunctionBounded(BoundedFunction, BoundedThis, BoundedArguments); }
|
---|
| 1602 |
|
---|
| 1603 |
|
---|
| 1604 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1605 | /// CScriptVarFunctionNative
|
---|
| 1606 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1607 |
|
---|
| 1608 | define_ScriptVarPtr_Type(FunctionNative);
|
---|
| 1609 | class CScriptVarFunctionNative : public CScriptVarFunction {
|
---|
| 1610 | protected:
|
---|
| 1611 | CScriptVarFunctionNative(CTinyJS *Context, void *Userdata) : CScriptVarFunction(Context, new CScriptTokenDataFnc), jsUserData(Userdata) { }
|
---|
| 1612 | CScriptVarFunctionNative(const CScriptVarFunctionNative &Copy) : CScriptVarFunction(Copy), jsUserData(Copy.jsUserData) { } ///< Copy protected -> use clone for public
|
---|
| 1613 | public:
|
---|
| 1614 | virtual ~CScriptVarFunctionNative();
|
---|
| 1615 | virtual CScriptVarPtr clone()=0;
|
---|
| 1616 | virtual bool isNative(); // { return true; }
|
---|
| 1617 |
|
---|
| 1618 | virtual void callFunction(const CFunctionsScopePtr &c)=0;// { jsCallback(c, jsCallbackUserData); }
|
---|
| 1619 | protected:
|
---|
| 1620 | void *jsUserData; ///< user data passed as second argument to native functions
|
---|
| 1621 | };
|
---|
| 1622 |
|
---|
| 1623 |
|
---|
| 1624 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1625 | /// CScriptVarFunctionNativeCallback
|
---|
| 1626 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1627 |
|
---|
| 1628 | define_ScriptVarPtr_Type(FunctionNativeCallback);
|
---|
| 1629 | class CScriptVarFunctionNativeCallback : public CScriptVarFunctionNative {
|
---|
| 1630 | protected:
|
---|
| 1631 | CScriptVarFunctionNativeCallback(CTinyJS *Context, JSCallback Callback, void *Userdata) : CScriptVarFunctionNative(Context, Userdata), jsCallback(Callback) { }
|
---|
| 1632 | CScriptVarFunctionNativeCallback(const CScriptVarFunctionNativeCallback &Copy) : CScriptVarFunctionNative(Copy), jsCallback(Copy.jsCallback) { } ///< Copy protected -> use clone for public
|
---|
| 1633 | public:
|
---|
| 1634 | virtual ~CScriptVarFunctionNativeCallback();
|
---|
| 1635 | virtual CScriptVarPtr clone();
|
---|
| 1636 | virtual void callFunction(const CFunctionsScopePtr &c);
|
---|
| 1637 | private:
|
---|
| 1638 | JSCallback jsCallback; ///< Callback for native functions
|
---|
| 1639 | friend define_newScriptVar_Fnc(FunctionNativeCallback, CTinyJS *Context, JSCallback Callback, void*);
|
---|
| 1640 | };
|
---|
| 1641 | inline define_newScriptVar_Fnc(FunctionNativeCallback, CTinyJS *Context, JSCallback Callback, void *Userdata) { return new CScriptVarFunctionNativeCallback(Context, Callback, Userdata); }
|
---|
| 1642 |
|
---|
| 1643 |
|
---|
| 1644 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1645 | /// CScriptVarFunctionNativeClass
|
---|
| 1646 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1647 |
|
---|
| 1648 | template<class native>
|
---|
| 1649 | class CScriptVarFunctionNativeClass : public CScriptVarFunctionNative {
|
---|
| 1650 | protected:
|
---|
| 1651 | CScriptVarFunctionNativeClass(CTinyJS *Context, native *ClassPtr, void (native::*ClassFnc)(const CFunctionsScopePtr &, void *), void *Userdata) : CScriptVarFunctionNative(Context, Userdata), classPtr(ClassPtr), classFnc(ClassFnc) { }
|
---|
| 1652 | CScriptVarFunctionNativeClass(const CScriptVarFunctionNativeClass &Copy) : CScriptVarFunctionNative(Copy), classPtr(Copy.classPtr), classFnc(Copy.classFnc) { } ///< Copy protected -> use clone for public
|
---|
| 1653 | public:
|
---|
| 1654 | virtual CScriptVarPtr clone() { return new CScriptVarFunctionNativeClass(*this); }
|
---|
| 1655 |
|
---|
| 1656 | virtual void callFunction(const CFunctionsScopePtr &c) { (classPtr->*classFnc)(c, jsUserData); }
|
---|
| 1657 | private:
|
---|
| 1658 | native *classPtr;
|
---|
| 1659 | void (native::*classFnc)(const CFunctionsScopePtr &c, void *userdata);
|
---|
| 1660 | template<typename native2>
|
---|
| 1661 | friend define_newScriptVar_Fnc(FunctionNativeCallback, CTinyJS*, native2 *, void (native2::*)(const CFunctionsScopePtr &, void *), void *);
|
---|
| 1662 | };
|
---|
| 1663 | template<typename native>
|
---|
| 1664 | define_newScriptVar_Fnc(FunctionNativeCallback, CTinyJS *Context, native *ClassPtr, void (native::*ClassFnc)(const CFunctionsScopePtr &, void *), void *Userdata) { return new CScriptVarFunctionNativeClass<native>(Context, ClassPtr, ClassFnc, Userdata); }
|
---|
| 1665 |
|
---|
| 1666 |
|
---|
| 1667 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1668 | /// CScriptVarAccessor
|
---|
| 1669 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1670 |
|
---|
| 1671 | define_dummy_t(Accessor);
|
---|
| 1672 | define_ScriptVarPtr_Type(Accessor);
|
---|
| 1673 |
|
---|
| 1674 | class CScriptVarAccessor : public CScriptVarObject {
|
---|
| 1675 | protected:
|
---|
| 1676 | CScriptVarAccessor(CTinyJS *Context);
|
---|
| 1677 | CScriptVarAccessor(CTinyJS *Context, JSCallback getter, void *getterdata, JSCallback setter, void *setterdata);
|
---|
| 1678 | template<class C> CScriptVarAccessor(CTinyJS *Context, C *class_ptr, void(C::*getterFnc)(const CFunctionsScopePtr &, void *), void *getterData, void(C::*setterFnc)(const CFunctionsScopePtr &, void *), void *setterData) : CScriptVarObject(Context) {
|
---|
| 1679 | if(getterFnc)
|
---|
| 1680 | addChild(TINYJS_ACCESSOR_GET_VAR, ::newScriptVar(Context, class_ptr, getterFnc, getterData), 0);
|
---|
| 1681 | if(setterFnc)
|
---|
| 1682 | addChild(TINYJS_ACCESSOR_SET_VAR, ::newScriptVar(Context, class_ptr, setterFnc, setterData), 0);
|
---|
| 1683 | }
|
---|
| 1684 | CScriptVarAccessor(CTinyJS *Context, const CScriptVarFunctionPtr &getter, const CScriptVarFunctionPtr &setter);
|
---|
| 1685 |
|
---|
| 1686 | CScriptVarAccessor(const CScriptVarAccessor &Copy) : CScriptVarObject(Copy) {} ///< Copy protected -> use clone for public
|
---|
| 1687 | public:
|
---|
| 1688 | virtual ~CScriptVarAccessor();
|
---|
| 1689 | virtual CScriptVarPtr clone();
|
---|
| 1690 | virtual bool isAccessor(); // { return true; }
|
---|
| 1691 | virtual bool isPrimitive(); // { return false; }
|
---|
| 1692 |
|
---|
| 1693 | virtual std::string getParsableString(const std::string &indentString, const std::string &indent, uint32_t uniqueID, bool &hasRecursion);
|
---|
| 1694 | virtual std::string getVarType(); // { return "object"; }
|
---|
| 1695 |
|
---|
| 1696 | CScriptVarPtr getValue();
|
---|
| 1697 |
|
---|
| 1698 | friend define_newScriptVar_Fnc(Accessor, CTinyJS *Context, Accessor_t);
|
---|
| 1699 | friend define_newScriptVar_NamedFnc(Accessor, CTinyJS *Context, JSCallback getter, void *getterdata, JSCallback setter, void *setterdata);
|
---|
| 1700 | template<class C> friend define_newScriptVar_NamedFnc(Accessor, CTinyJS *Context, C *class_ptr, void(C::*getterFnc)(const CFunctionsScopePtr &, void *), void *getterData, void(C::*setterFnc)(const CFunctionsScopePtr &, void *), void *setterData);
|
---|
| 1701 | friend define_newScriptVar_NamedFnc(Accessor, CTinyJS *Context, const CScriptVarFunctionPtr &, const CScriptVarFunctionPtr &);
|
---|
| 1702 | };
|
---|
| 1703 | inline define_newScriptVar_Fnc(Accessor, CTinyJS *Context, Accessor_t) { return new CScriptVarAccessor(Context); }
|
---|
| 1704 | inline define_newScriptVar_NamedFnc(Accessor, CTinyJS *Context, JSCallback getter, void *getterdata, JSCallback setter, void *setterdata) { return new CScriptVarAccessor(Context, getter, getterdata, setter, setterdata); }
|
---|
| 1705 | template<class C> define_newScriptVar_NamedFnc(Accessor, CTinyJS *Context, C *class_ptr, void(C::*getterFnc)(const CFunctionsScopePtr &, void *), void *getterData, void(C::*setterFnc)(const CFunctionsScopePtr &, void *), void *setterData) { return new CScriptVarAccessor(Context, class_ptr, getterFnc, getterData, setterFnc, setterData); }
|
---|
| 1706 | inline define_newScriptVar_NamedFnc(Accessor, CTinyJS *Context, const CScriptVarFunctionPtr &getter, const CScriptVarFunctionPtr &setter) { return new CScriptVarAccessor(Context, getter, setter); }
|
---|
| 1707 |
|
---|
| 1708 |
|
---|
| 1709 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1710 | /// CScriptVarDestructuring
|
---|
| 1711 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1712 |
|
---|
| 1713 | class CScriptVarDestructuring : public CScriptVarObject {
|
---|
| 1714 | protected: // only derived classes or friends can be created
|
---|
| 1715 | CScriptVarDestructuring(CTinyJS *Context) // constructor for rootScope
|
---|
| 1716 | : CScriptVarObject(Context) {}
|
---|
| 1717 | virtual CScriptVarPtr clone();
|
---|
| 1718 | public:
|
---|
| 1719 | virtual ~CScriptVarDestructuring();
|
---|
| 1720 | };
|
---|
| 1721 |
|
---|
| 1722 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1723 | /// CScriptVarScope
|
---|
| 1724 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1725 |
|
---|
| 1726 | define_dummy_t(Scope);
|
---|
| 1727 | define_ScriptVarPtr_Type(Scope);
|
---|
| 1728 | class CScriptVarScope : public CScriptVarObject {
|
---|
| 1729 | protected: // only derived classes or friends can be created
|
---|
| 1730 | CScriptVarScope(CTinyJS *Context) // constructor for rootScope
|
---|
| 1731 | : CScriptVarObject(Context) {}
|
---|
| 1732 | virtual CScriptVarPtr clone();
|
---|
| 1733 | virtual bool isObject(); // { return false; }
|
---|
| 1734 | public:
|
---|
| 1735 | virtual ~CScriptVarScope();
|
---|
| 1736 | virtual CScriptVarPtr scopeVar(); ///< to create var like: var a = ...
|
---|
| 1737 | virtual CScriptVarPtr scopeLet(); ///< to create var like: let a = ...
|
---|
| 1738 | virtual CScriptVarLinkWorkPtr findInScopes(const std::string &childName);
|
---|
| 1739 | virtual CScriptVarScopePtr getParent();
|
---|
| 1740 | friend define_newScriptVar_Fnc(Scope, CTinyJS *Context, Scope_t);
|
---|
| 1741 | };
|
---|
| 1742 | inline define_newScriptVar_Fnc(Scope, CTinyJS *Context, Scope_t) { return new CScriptVarScope(Context); }
|
---|
| 1743 |
|
---|
| 1744 |
|
---|
| 1745 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1746 | /// CScriptVarScopeFnc
|
---|
| 1747 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1748 |
|
---|
| 1749 | define_dummy_t(ScopeFnc);
|
---|
| 1750 | define_ScriptVarPtr_Type(ScopeFnc);
|
---|
| 1751 | class CScriptVarScopeFnc : public CScriptVarScope {
|
---|
| 1752 | protected: // only derived classes or friends can be created
|
---|
| 1753 | CScriptVarScopeFnc(CTinyJS *Context, const CScriptVarScopePtr &Closure) // constructor for FncScope
|
---|
| 1754 | : CScriptVarScope(Context), closure(Closure ? addChild(TINYJS_FUNCTION_CLOSURE_VAR, Closure, 0) : CScriptVarLinkPtr()) {}
|
---|
| 1755 | public:
|
---|
| 1756 | virtual ~CScriptVarScopeFnc();
|
---|
| 1757 | virtual CScriptVarLinkWorkPtr findInScopes(const std::string &childName);
|
---|
| 1758 |
|
---|
| 1759 | void setReturnVar(const CScriptVarPtr &var); ///< Set the result value. Use this when setting complex return data as it avoids a deepCopy()
|
---|
| 1760 |
|
---|
| 1761 | #define DEPRECATED_getParameter DEPRECATED("getParameter is deprecated use getArgument instead")
|
---|
| 1762 | DEPRECATED_getParameter CScriptVarPtr getParameter(const std::string &name);
|
---|
| 1763 | DEPRECATED_getParameter CScriptVarPtr getParameter(int Idx);
|
---|
| 1764 | CScriptVarPtr getArgument(const std::string &name); ///< If this is a function, get the parameter with the given name (for use by native functions)
|
---|
| 1765 | CScriptVarPtr getArgument(int Idx); ///< If this is a function, get the parameter with the given index (for use by native functions)
|
---|
| 1766 | DEPRECATED("getParameterLength is deprecated use getArgumentsLength instead") int getParameterLength(); ///< If this is a function, get the count of parameters
|
---|
| 1767 | int getArgumentsLength(); ///< If this is a function, get the count of parameters
|
---|
| 1768 |
|
---|
| 1769 | void throwError(ERROR_TYPES ErrorType, const std::string &message);
|
---|
| 1770 |
|
---|
| 1771 | protected:
|
---|
| 1772 | CScriptVarLinkPtr closure;
|
---|
| 1773 | friend define_newScriptVar_Fnc(ScopeFnc, CTinyJS *Context, ScopeFnc_t, const CScriptVarScopePtr &Closure);
|
---|
| 1774 | };
|
---|
| 1775 | inline define_newScriptVar_Fnc(ScopeFnc, CTinyJS *Context, ScopeFnc_t, const CScriptVarScopePtr &Closure) { return new CScriptVarScopeFnc(Context, Closure); }
|
---|
| 1776 |
|
---|
| 1777 |
|
---|
| 1778 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1779 | /// CScriptVarScopeLet
|
---|
| 1780 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1781 |
|
---|
| 1782 | define_dummy_t(ScopeLet);
|
---|
| 1783 | define_ScriptVarPtr_Type(ScopeLet);
|
---|
| 1784 | class CScriptVarScopeLet : public CScriptVarScope {
|
---|
| 1785 | protected: // only derived classes or friends can be created
|
---|
| 1786 | CScriptVarScopeLet(const CScriptVarScopePtr &Parent); // constructor for LetScope
|
---|
| 1787 | // : CScriptVarScope(Parent->getContext()), parent( context->getRoot() != Parent ? addChild(TINYJS_SCOPE_PARENT_VAR, Parent, 0) : 0) {}
|
---|
| 1788 | public:
|
---|
| 1789 | virtual ~CScriptVarScopeLet();
|
---|
| 1790 | virtual CScriptVarLinkWorkPtr findInScopes(const std::string &childName);
|
---|
| 1791 | virtual CScriptVarPtr scopeVar(); ///< to create var like: var a = ...
|
---|
| 1792 | virtual CScriptVarScopePtr getParent();
|
---|
| 1793 | void setletExpressionInitMode(bool Mode) { letExpressionInitMode = Mode; }
|
---|
| 1794 | protected:
|
---|
| 1795 | CScriptVarLinkPtr parent;
|
---|
| 1796 | bool letExpressionInitMode;
|
---|
| 1797 | friend define_newScriptVar_Fnc(ScopeLet, CTinyJS *Context, ScopeLet_t, const CScriptVarScopePtr &Parent);
|
---|
| 1798 | };
|
---|
| 1799 | inline define_newScriptVar_Fnc(ScopeLet, CTinyJS *, ScopeLet_t, const CScriptVarScopePtr &Parent) { return new CScriptVarScopeLet(Parent); }
|
---|
| 1800 |
|
---|
| 1801 |
|
---|
| 1802 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1803 | /// CScriptVarScopeWith
|
---|
| 1804 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1805 |
|
---|
| 1806 | define_dummy_t(ScopeWith);
|
---|
| 1807 | define_ScriptVarPtr_Type(ScopeWith);
|
---|
| 1808 | class CScriptVarScopeWith : public CScriptVarScopeLet {
|
---|
| 1809 | protected:
|
---|
| 1810 | CScriptVarScopeWith(const CScriptVarScopePtr &Parent, const CScriptVarPtr &With)
|
---|
| 1811 | : CScriptVarScopeLet(Parent), with(addChild(TINYJS_SCOPE_WITH_VAR, With, 0)) {}
|
---|
| 1812 |
|
---|
| 1813 | public:
|
---|
| 1814 | virtual ~CScriptVarScopeWith();
|
---|
| 1815 | virtual CScriptVarPtr scopeLet(); ///< to create var like: let a = ...
|
---|
| 1816 | virtual CScriptVarLinkWorkPtr findInScopes(const std::string &childName);
|
---|
| 1817 | private:
|
---|
| 1818 | CScriptVarLinkPtr with;
|
---|
| 1819 | friend define_newScriptVar_Fnc(ScopeWith, CTinyJS *Context, ScopeWith_t, const CScriptVarScopePtr &Parent, const CScriptVarPtr &With);
|
---|
| 1820 | };
|
---|
| 1821 | inline define_newScriptVar_Fnc(ScopeWith, CTinyJS *, ScopeWith_t, const CScriptVarScopePtr &Parent, const CScriptVarPtr &With) { return new CScriptVarScopeWith(Parent, With); }
|
---|
| 1822 |
|
---|
| 1823 |
|
---|
| 1824 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1825 | template<typename T>
|
---|
| 1826 | inline CScriptVarPtr CScriptVar::newScriptVar(T t) { return ::newScriptVar(context, t); }
|
---|
| 1827 | template<typename T1, typename T2>
|
---|
| 1828 | inline CScriptVarPtr CScriptVar::newScriptVar(T1 t1, T2 t2) { return ::newScriptVar(context, t1, t2); }
|
---|
| 1829 | //inline CScriptVarPtr newScriptVar(const CNumber &t) { return ::newScriptVar(context, t); }
|
---|
| 1830 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1831 |
|
---|
| 1832 |
|
---|
| 1833 | class CScriptResult {
|
---|
| 1834 | public:
|
---|
| 1835 | enum TYPE {
|
---|
| 1836 | Normal,
|
---|
| 1837 | Break,
|
---|
| 1838 | Continue,
|
---|
| 1839 | Return,
|
---|
| 1840 | Throw,
|
---|
| 1841 | noExecute
|
---|
| 1842 | };
|
---|
| 1843 | CScriptResult() : type(Normal) {}
|
---|
| 1844 | CScriptResult(TYPE Type) : type(Type) {}
|
---|
| 1845 | // ~RESULT() { if(type==Throw) throw value; }
|
---|
| 1846 | bool isNormal() { return type==Normal; }
|
---|
| 1847 | bool isBreak() { return type==Break; }
|
---|
| 1848 | bool isContinue() { return type==Continue; }
|
---|
| 1849 | bool isBreakContinue() { return type==Break || type==Continue; }
|
---|
| 1850 | bool isReturn() { return type==Return; }
|
---|
| 1851 | bool isReturnNormal() { return type==Return || type==Normal; }
|
---|
| 1852 | bool isThrow() { return type==Throw; }
|
---|
| 1853 |
|
---|
| 1854 | operator bool() const { return type==Normal; }
|
---|
| 1855 | void set(TYPE Type, bool Clear=true) { type=Type; if(Clear) value.clear(), target.clear(); }
|
---|
| 1856 | void set(TYPE Type, const CScriptVarPtr &Value) { type=Type; value=Value; }
|
---|
| 1857 | void set(TYPE Type, const std::string &Target) { type=Type; target=Target; }
|
---|
| 1858 |
|
---|
| 1859 | void cThrow() { if(type==Throw) throw value; }
|
---|
| 1860 |
|
---|
| 1861 | CScriptResult &operator()(const CScriptResult &rhs) { if(type!=Normal) *this=rhs; return *this; }
|
---|
| 1862 |
|
---|
| 1863 | enum TYPE type;
|
---|
| 1864 | CScriptVarPtr value;
|
---|
| 1865 | std::string target;
|
---|
| 1866 | };
|
---|
| 1867 |
|
---|
| 1868 |
|
---|
| 1869 |
|
---|
| 1870 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1871 | /// CTinyJS
|
---|
| 1872 | //////////////////////////////////////////////////////////////////////////
|
---|
| 1873 |
|
---|
| 1874 | class CTinyJS {
|
---|
| 1875 | public:
|
---|
| 1876 | CTinyJS();
|
---|
| 1877 | ~CTinyJS();
|
---|
| 1878 |
|
---|
| 1879 | void execute(CScriptTokenizer &Tokenizer);
|
---|
| 1880 | void execute(const char *Code, const std::string &File="", int Line=0, int Column=0);
|
---|
| 1881 | void execute(const std::string &Code, const std::string &File="", int Line=0, int Column=0);
|
---|
| 1882 | /** Evaluate the given code and return a link to a javascript object,
|
---|
| 1883 | * useful for (dangerous) JSON parsing. If nothing to return, will return
|
---|
| 1884 | * 'undefined' variable type. CScriptVarLink is returned as this will
|
---|
| 1885 | * automatically unref the result as it goes out of scope. If you want to
|
---|
| 1886 | * keep it, you must use ref() and unref() */
|
---|
| 1887 | CScriptVarLinkPtr evaluateComplex(CScriptTokenizer &Tokenizer);
|
---|
| 1888 | /** Evaluate the given code and return a link to a javascript object,
|
---|
| 1889 | * useful for (dangerous) JSON parsing. If nothing to return, will return
|
---|
| 1890 | * 'undefined' variable type. CScriptVarLink is returned as this will
|
---|
| 1891 | * automatically unref the result as it goes out of scope. If you want to
|
---|
| 1892 | * keep it, you must use ref() and unref() */
|
---|
| 1893 | CScriptVarLinkPtr evaluateComplex(const char *code, const std::string &File="", int Line=0, int Column=0);
|
---|
| 1894 | /** Evaluate the given code and return a link to a javascript object,
|
---|
| 1895 | * useful for (dangerous) JSON parsing. If nothing to return, will return
|
---|
| 1896 | * 'undefined' variable type. CScriptVarLink is returned as this will
|
---|
| 1897 | * automatically unref the result as it goes out of scope. If you want to
|
---|
| 1898 | * keep it, you must use ref() and unref() */
|
---|
| 1899 | CScriptVarLinkPtr evaluateComplex(const std::string &code, const std::string &File="", int Line=0, int Column=0);
|
---|
| 1900 | /** Evaluate the given code and return a string. If nothing to return, will return
|
---|
| 1901 | * 'undefined' */
|
---|
| 1902 | std::string evaluate(CScriptTokenizer &Tokenizer);
|
---|
| 1903 | /** Evaluate the given code and return a string. If nothing to return, will return
|
---|
| 1904 | * 'undefined' */
|
---|
| 1905 | std::string evaluate(const char *code, const std::string &File="", int Line=0, int Column=0);
|
---|
| 1906 | /** Evaluate the given code and return a string. If nothing to return, will return
|
---|
| 1907 | * 'undefined' */
|
---|
| 1908 | std::string evaluate(const std::string &code, const std::string &File="", int Line=0, int Column=0);
|
---|
| 1909 |
|
---|
| 1910 | /// add a native function to be called from TinyJS
|
---|
| 1911 | /** example:
|
---|
| 1912 | \code
|
---|
| 1913 | void scRandInt(const CFunctionsScopePtr &c, void *userdata) { ... }
|
---|
| 1914 | tinyJS->addNative("function randInt(min, max)", scRandInt, 0);
|
---|
| 1915 | \endcode
|
---|
| 1916 |
|
---|
| 1917 | or
|
---|
| 1918 |
|
---|
| 1919 | \code
|
---|
| 1920 | void scSubstring(const CFunctionsScopePtr &c, void *userdata) { ... }
|
---|
| 1921 | tinyJS->addNative("function String.substring(lo, hi)", scSubstring, 0);
|
---|
| 1922 | \endcode
|
---|
| 1923 | or
|
---|
| 1924 |
|
---|
| 1925 | \code
|
---|
| 1926 | class Class
|
---|
| 1927 | {
|
---|
| 1928 | public:
|
---|
| 1929 | void scSubstring(const CFunctionsScopePtr &c, void *userdata) { ... }
|
---|
| 1930 | };
|
---|
| 1931 | Class Instanz;
|
---|
| 1932 | tinyJS->addNative("function String.substring(lo, hi)", &Instanz, &Class::*scSubstring, 0);
|
---|
| 1933 | \endcode
|
---|
| 1934 | */
|
---|
| 1935 |
|
---|
| 1936 | CScriptVarFunctionNativePtr addNative(const std::string &funcDesc, JSCallback ptr, void *userdata=0, int LinkFlags=SCRIPTVARLINK_BUILDINDEFAULT);
|
---|
| 1937 | template<class C>
|
---|
| 1938 | CScriptVarFunctionNativePtr addNative(const std::string &funcDesc, C *class_ptr, void(C::*class_fnc)(const CFunctionsScopePtr &, void *), void *userdata=0, int LinkFlags=SCRIPTVARLINK_BUILDINDEFAULT)
|
---|
| 1939 | {
|
---|
| 1940 | return addNative(funcDesc, ::newScriptVar<C>(this, class_ptr, class_fnc, userdata), LinkFlags);
|
---|
| 1941 | }
|
---|
| 1942 |
|
---|
| 1943 | /// Send all variables to stdout
|
---|
| 1944 | void trace();
|
---|
| 1945 |
|
---|
| 1946 | const CScriptVarScopePtr &getRoot() { return root; }; /// gets the root of symbol table
|
---|
| 1947 | // CScriptVar *root; /// root of symbol table
|
---|
| 1948 |
|
---|
| 1949 | /// newVars & constVars
|
---|
| 1950 | //CScriptVarPtr newScriptVar(const CNumber &t) { return ::newScriptVar(this, t); }
|
---|
| 1951 | template<typename T> CScriptVarPtr newScriptVar(T t) { return ::newScriptVar(this, t); }
|
---|
| 1952 | template<typename T1, typename T2> CScriptVarPtr newScriptVar(T1 t1, T2 t2) { return ::newScriptVar(this, t1, t2); }
|
---|
| 1953 | const CScriptVarPtr &constScriptVar(Undefined_t) { return constUndefined; }
|
---|
| 1954 | const CScriptVarPtr &constScriptVar(Null_t) { return constNull; }
|
---|
| 1955 | const CScriptVarPtr &constScriptVar(NaN_t) { return constNaN; }
|
---|
| 1956 | const CScriptVarPtr &constScriptVar(Infinity t) { return t.Sig()<0 ? constInfinityNegative : constInfinityPositive; }
|
---|
| 1957 | const CScriptVarPtr &constScriptVar(bool Val) { return Val?constTrue:constFalse; }
|
---|
| 1958 | const CScriptVarPtr &constScriptVar(NegativeZero_t) { return constNegativZero; }
|
---|
| 1959 | const CScriptVarPtr &constScriptVar(StopIteration_t) { return constStopIteration; }
|
---|
| 1960 |
|
---|
| 1961 | private:
|
---|
| 1962 | CScriptTokenizer *t; /// current tokenizer
|
---|
| 1963 | bool haveTry;
|
---|
| 1964 | std::vector<CScriptVarScopePtr>scopes;
|
---|
| 1965 | CScriptVarScopePtr root;
|
---|
| 1966 | const CScriptVarScopePtr &scope() { return scopes.back(); }
|
---|
| 1967 |
|
---|
| 1968 | class CScopeControl { // helper-class to manage scopes
|
---|
| 1969 | private:
|
---|
| 1970 | CScopeControl(const CScopeControl& Copy) MEMBER_DELETE; // no copy
|
---|
| 1971 | CScopeControl& operator =(const CScopeControl& Copy) MEMBER_DELETE;
|
---|
| 1972 | public:
|
---|
| 1973 | CScopeControl(CTinyJS *Context) : context(Context), count(0) {}
|
---|
| 1974 | ~CScopeControl() { while(count--) {CScriptVarScopePtr parent = context->scopes.back()->getParent(); if(parent) context->scopes.back() = parent; else context->scopes.pop_back() ;} }
|
---|
| 1975 | void addFncScope(const CScriptVarScopePtr &Scope) { context->scopes.push_back(Scope); count++; }
|
---|
| 1976 | CScriptVarScopeLetPtr addLetScope() { count++; return context->scopes.back() = ::newScriptVar(context, ScopeLet, context->scopes.back()); }
|
---|
| 1977 | void addWithScope(const CScriptVarPtr &With) { context->scopes.back() = ::newScriptVar(context, ScopeWith, context->scopes.back(), With); count++; }
|
---|
| 1978 | private:
|
---|
| 1979 | CTinyJS *context;
|
---|
| 1980 | int count;
|
---|
| 1981 | };
|
---|
| 1982 | friend class CScopeControl;
|
---|
| 1983 | public:
|
---|
| 1984 | CScriptVarPtr objectPrototype; /// Built in object class
|
---|
| 1985 | CScriptVarPtr objectPrototype_valueOf; /// Built in object class
|
---|
| 1986 | CScriptVarPtr objectPrototype_toString; /// Built in object class
|
---|
| 1987 | CScriptVarPtr arrayPrototype; /// Built in array class
|
---|
| 1988 | CScriptVarPtr stringPrototype; /// Built in string class
|
---|
| 1989 | CScriptVarPtr regexpPrototype; /// Built in string class
|
---|
| 1990 | CScriptVarPtr numberPrototype; /// Built in number class
|
---|
| 1991 | CScriptVarPtr booleanPrototype; /// Built in boolean class
|
---|
| 1992 | CScriptVarPtr iteratorPrototype; /// Built in boolean class
|
---|
| 1993 | CScriptVarPtr functionPrototype; /// Built in function class
|
---|
| 1994 | const CScriptVarPtr &getErrorPrototype(ERROR_TYPES Type) { return errorPrototypes[Type]; }
|
---|
| 1995 | private:
|
---|
| 1996 | CScriptVarPtr errorPrototypes[ERROR_COUNT]; /// Built in error class
|
---|
| 1997 | CScriptVarPtr constUndefined;
|
---|
| 1998 | CScriptVarPtr constNull;
|
---|
| 1999 | CScriptVarPtr constNaN;
|
---|
| 2000 | CScriptVarPtr constInfinityPositive;
|
---|
| 2001 | CScriptVarPtr constInfinityNegative;
|
---|
| 2002 | CScriptVarPtr constNegativZero;
|
---|
| 2003 | CScriptVarPtr constTrue;
|
---|
| 2004 | CScriptVarPtr constFalse;
|
---|
| 2005 | CScriptVarPtr constStopIteration;
|
---|
| 2006 |
|
---|
| 2007 | std::vector<CScriptVarPtr *> pseudo_refered;
|
---|
| 2008 |
|
---|
| 2009 | void CheckRightHandVar(CScriptResult &execute, CScriptVarLinkWorkPtr &link)
|
---|
| 2010 | {
|
---|
| 2011 | if(execute && link && !link->isOwned() && !link.hasReferencedOwner() && !link->getName().empty())
|
---|
| 2012 | throwError(execute, ReferenceError, link->getName() + " is not defined", t->getPrevPos());
|
---|
| 2013 | }
|
---|
| 2014 |
|
---|
| 2015 | void CheckRightHandVar(CScriptResult &execute, CScriptVarLinkWorkPtr &link, CScriptTokenizer::ScriptTokenPosition &Pos)
|
---|
| 2016 | {
|
---|
| 2017 | if(execute && link && !link->isOwned() && !link.hasReferencedOwner() && !link->getName().empty())
|
---|
| 2018 | throwError(execute, ReferenceError, link->getName() + " is not defined", Pos);
|
---|
| 2019 | }
|
---|
| 2020 |
|
---|
| 2021 | public:
|
---|
| 2022 | // function call
|
---|
| 2023 | CScriptVarPtr callFunction(const CScriptVarFunctionPtr &Function, std::vector<CScriptVarPtr> &Arguments, const CScriptVarPtr &This, CScriptVarPtr *newThis=0);
|
---|
| 2024 | CScriptVarPtr callFunction(CScriptResult &execute, const CScriptVarFunctionPtr &Function, std::vector<CScriptVarPtr> &Arguments, const CScriptVarPtr &This, CScriptVarPtr *newThis=0);
|
---|
| 2025 |
|
---|
| 2026 | // parsing - in order of precedence
|
---|
| 2027 | CScriptVarPtr mathsOp(CScriptResult &execute, const CScriptVarPtr &a, const CScriptVarPtr &b, int op);
|
---|
| 2028 | private:
|
---|
| 2029 | void assign_destructuring_var(const CScriptVarPtr &Scope, const CScriptTokenDataDestructuringVar &Objc, const CScriptVarPtr &Val, CScriptResult &execute);
|
---|
| 2030 | void execute_var_init(bool hideLetScope, CScriptResult &execute);
|
---|
| 2031 | void execute_destructuring(CScriptTokenDataObjectLiteral &Objc, const CScriptVarPtr &Val, CScriptResult &execute);
|
---|
| 2032 | CScriptVarLinkWorkPtr execute_literals(CScriptResult &execute);
|
---|
| 2033 | CScriptVarLinkWorkPtr execute_member(CScriptVarLinkWorkPtr &parent, CScriptResult &execute);
|
---|
| 2034 | CScriptVarLinkWorkPtr execute_function_call(CScriptResult &execute);
|
---|
| 2035 | bool execute_unary_rhs(CScriptResult &execute, CScriptVarLinkWorkPtr& a);
|
---|
| 2036 | CScriptVarLinkWorkPtr execute_unary(CScriptResult &execute);
|
---|
| 2037 | CScriptVarLinkWorkPtr execute_term(CScriptResult &execute);
|
---|
| 2038 | CScriptVarLinkWorkPtr execute_expression(CScriptResult &execute);
|
---|
| 2039 | CScriptVarLinkWorkPtr execute_binary_shift(CScriptResult &execute);
|
---|
| 2040 | CScriptVarLinkWorkPtr execute_relation(CScriptResult &execute, int set=LEX_EQUAL, int set_n='<');
|
---|
| 2041 | CScriptVarLinkWorkPtr execute_binary_logic(CScriptResult &execute, int op='|', int op_n1='^', int op_n2='&');
|
---|
| 2042 | CScriptVarLinkWorkPtr execute_logic(CScriptResult &execute, int op=LEX_OROR, int op_n=LEX_ANDAND);
|
---|
| 2043 | CScriptVarLinkWorkPtr execute_condition(CScriptResult &execute);
|
---|
| 2044 | CScriptVarLinkPtr execute_assignment(CScriptVarLinkWorkPtr Lhs, CScriptResult &execute);
|
---|
| 2045 | CScriptVarLinkPtr execute_assignment(CScriptResult &execute);
|
---|
| 2046 | CScriptVarLinkPtr execute_base(CScriptResult &execute);
|
---|
| 2047 | void execute_block(CScriptResult &execute);
|
---|
| 2048 | void execute_statement(CScriptResult &execute);
|
---|
| 2049 | // parsing utility functions
|
---|
| 2050 | CScriptVarLinkWorkPtr parseFunctionDefinition(const CScriptToken &FncToken);
|
---|
| 2051 | CScriptVarLinkWorkPtr parseFunctionsBodyFromString(const std::string &ArgumentList, const std::string &FncBody);
|
---|
| 2052 | public:
|
---|
| 2053 | CScriptVarLinkPtr findInScopes(const std::string &childName); ///< Finds a child, looking recursively up the scopes
|
---|
| 2054 | private:
|
---|
| 2055 | //////////////////////////////////////////////////////////////////////////
|
---|
| 2056 | /// addNative-helper
|
---|
| 2057 | CScriptVarFunctionNativePtr addNative(const std::string &funcDesc, CScriptVarFunctionNativePtr Var, int LinkFlags);
|
---|
| 2058 |
|
---|
| 2059 | //////////////////////////////////////////////////////////////////////////
|
---|
| 2060 | /// throws an Error & Exception
|
---|
| 2061 | public:
|
---|
| 2062 | void throwError(CScriptResult &execute, ERROR_TYPES ErrorType, const std::string &message);
|
---|
| 2063 | void throwException(ERROR_TYPES ErrorType, const std::string &message);
|
---|
| 2064 | void throwError(CScriptResult &execute, ERROR_TYPES ErrorType, const std::string &message, CScriptTokenizer::ScriptTokenPosition &Pos);
|
---|
| 2065 | void throwException(ERROR_TYPES ErrorType, const std::string &message, CScriptTokenizer::ScriptTokenPosition &Pos);
|
---|
| 2066 | private:
|
---|
| 2067 | //////////////////////////////////////////////////////////////////////////
|
---|
| 2068 | /// native Object-Constructors & prototype-functions
|
---|
| 2069 |
|
---|
| 2070 | void native_Object(const CFunctionsScopePtr &c, void *data);
|
---|
| 2071 | void native_Object_getPrototypeOf(const CFunctionsScopePtr &c, void *data);
|
---|
| 2072 | /* Userdate for set-/isObjectState
|
---|
| 2073 | * 0 - preventExtensions / isExtensible
|
---|
| 2074 | * 1 - seal / isSealed
|
---|
| 2075 | * 2 - freeze / isFrozen
|
---|
| 2076 | */
|
---|
| 2077 | void native_Object_setObjectSecure(const CFunctionsScopePtr &c, void *data);
|
---|
| 2078 | void native_Object_isSecureObject(const CFunctionsScopePtr &c, void *data);
|
---|
| 2079 | void native_Object_keys(const CFunctionsScopePtr &c, void *data);
|
---|
| 2080 | void native_Object_getOwnPropertyDescriptor(const CFunctionsScopePtr &c, void *data);
|
---|
| 2081 | void native_Object_defineProperty(const CFunctionsScopePtr &c, void *data);
|
---|
| 2082 | void native_Object_defineProperties(const CFunctionsScopePtr &c, void *data);
|
---|
| 2083 |
|
---|
| 2084 | void native_Object_prototype_hasOwnProperty(const CFunctionsScopePtr &c, void *data);
|
---|
| 2085 | void native_Object_prototype_valueOf(const CFunctionsScopePtr &c, void *data);
|
---|
| 2086 | void native_Object_prototype_toString(const CFunctionsScopePtr &c, void *data);
|
---|
| 2087 |
|
---|
| 2088 | void native_Array(const CFunctionsScopePtr &c, void *data);
|
---|
| 2089 |
|
---|
| 2090 | void native_String(const CFunctionsScopePtr &c, void *data);
|
---|
| 2091 |
|
---|
| 2092 | void native_RegExp(const CFunctionsScopePtr &c, void *data);
|
---|
| 2093 |
|
---|
| 2094 | void native_Number(const CFunctionsScopePtr &c, void *data);
|
---|
| 2095 |
|
---|
| 2096 | void native_Boolean(const CFunctionsScopePtr &c, void *data);
|
---|
| 2097 |
|
---|
| 2098 | void native_Iterator(const CFunctionsScopePtr &c, void *data);
|
---|
| 2099 |
|
---|
| 2100 | void native_Function(const CFunctionsScopePtr &c, void *data);
|
---|
| 2101 | void native_Function_prototype_call(const CFunctionsScopePtr &c, void *data);
|
---|
| 2102 | void native_Function_prototype_apply(const CFunctionsScopePtr &c, void *data);
|
---|
| 2103 | void native_Function_prototype_bind(const CFunctionsScopePtr &c, void *data);
|
---|
| 2104 |
|
---|
| 2105 | void native_Error(const CFunctionsScopePtr &c, void *data);
|
---|
| 2106 | void native_EvalError(const CFunctionsScopePtr &c, void *data);
|
---|
| 2107 | void native_RangeError(const CFunctionsScopePtr &c, void *data);
|
---|
| 2108 | void native_ReferenceError(const CFunctionsScopePtr &c, void *data);
|
---|
| 2109 | void native_SyntaxError(const CFunctionsScopePtr &c, void *data);
|
---|
| 2110 | void native_TypeError(const CFunctionsScopePtr &c, void *data);
|
---|
| 2111 |
|
---|
| 2112 |
|
---|
| 2113 | //////////////////////////////////////////////////////////////////////////
|
---|
| 2114 | /// global function
|
---|
| 2115 |
|
---|
| 2116 | void native_eval(const CFunctionsScopePtr &c, void *data);
|
---|
| 2117 | void native_isNAN(const CFunctionsScopePtr &c, void *data);
|
---|
| 2118 | void native_isFinite(const CFunctionsScopePtr &c, void *data);
|
---|
| 2119 | void native_parseInt(const CFunctionsScopePtr &c, void *data);
|
---|
| 2120 | void native_parseFloat(const CFunctionsScopePtr &c, void *data);
|
---|
| 2121 |
|
---|
| 2122 |
|
---|
| 2123 |
|
---|
| 2124 | void native_JSON_parse(const CFunctionsScopePtr &c, void *data);
|
---|
| 2125 |
|
---|
| 2126 |
|
---|
| 2127 | uint32_t uniqueID;
|
---|
| 2128 | public:
|
---|
| 2129 | uint32_t getUniqueID() { return ++uniqueID; }
|
---|
| 2130 | CScriptVar *first;
|
---|
| 2131 | void setTemporaryID_recursive(uint32_t ID);
|
---|
| 2132 | void ClearUnreferedVars(const CScriptVarPtr &extra=CScriptVarPtr());
|
---|
| 2133 | };
|
---|
| 2134 |
|
---|
| 2135 |
|
---|
| 2136 | //////////////////////////////////////////////////////////////////////////
|
---|
| 2137 | template<typename T>
|
---|
| 2138 | inline const CScriptVarPtr &CScriptVar::constScriptVar(T t) { return context->constScriptVar(t); }
|
---|
| 2139 | //////////////////////////////////////////////////////////////////////////
|
---|
| 2140 | inline CNumber CScriptVarLink::toNumber() { return var->toNumber(); }
|
---|
| 2141 | inline CNumber CScriptVarLink::toNumber(CScriptResult &execute) { return var->toNumber(execute); }
|
---|
| 2142 |
|
---|
| 2143 | #endif
|
---|
| 2144 |
|
---|
| 2145 |
|
---|