From 8d81d2c5ebe88f4923d53a3e2eb4cc31a24a5777 Mon Sep 17 00:00:00 2001 From: John Doe Date: Sun, 26 Oct 2014 22:43:22 +0100 Subject: [PATCH] good riddance, .svn folder --- .svn/entries | 1 - .svn/format | 1 - ...13342e94d79fb8d4f40a25a40513b6e57076d0.svn-base | 7 - ...6fc7948c5e88442b3d34fa48efaf31e908f1f2.svn-base | 285 --- ...b994438d5e82bac26e515e81375ad80ee8a9e2.svn-base | 294 --- ...579793252f0352d07f6b6bcdb451ea31cb2fda.svn-base | 5 - ...7b58a944c557deff51914925de5a9aef130201.svn-base | 12 - ...458a4884320d893d45f87adc71160b322d527f.svn-base | 8 - ...1eee7a3b6eeabe99dc4c9f4e60a536ab2402cf.svn-base | 3 - ...4b0879bf42d077f3bdde8f6d6b2d066d8fdc2b.svn-base | 5 - ...c7b999b475568a2dfe41afe27d341d5f1c9815.svn-base | 6 - ...9456d5d22d245efd911a61e28f80aabf310219.svn-base | 15 - ...4fc6d237f099fee0da8be99bda08fe754357fc.svn-base | 4 - ...ccd54d8a43c6c91b9225a7dccbdb302971aea8.svn-base | 5 - ...50b704e748ec4e57d37de9ec5a48889a1414c7.svn-base | 5 - ...c5054e4063e20fae767fe147889d24abe36ea7.svn-base | 360 ---- ...be0a6640afdc5794427c8808a7c20ca8d2c306.svn-base | 13 - ...d03cc0ba37bfc0e8507e4dd6b307d29ebd729b.svn-base | 3 - ...d5492625fc746d81349b8a4cbdf4299fd7183b.svn-base | 10 - ...b4ff612674ecf806062137f28793f303e9031a.svn-base | 37 - ...a0f09eaad0b7500c98a5d824bde54e4ab0a9ba.svn-base | 18 - ...53d0e0bdcc36df327e3e92379ae5b0316d73b6.svn-base | 2190 -------------------- ...27ff2548a4483177cf428737c254fdba3be725.svn-base | 4 - ...31b2bdb233bafb1bbf172a9065e3ec04d54cde.svn-base | 9 - ...6063591602b23d43faa8f31867991e7c0f93dc.svn-base | 12 - ...a8ecf7da0b483cf29d7d789e85b541baf747ca.svn-base | 7 - ...a33ad02fc07dcc76b961c8e50e579530a302a5.svn-base | 66 - ...570c264e14d1351cca2be967bbe62329bb7cea.svn-base | 5 - ...9d98f6c6e06d4f51258f9935713a53db5fdcd0.svn-base | 24 - ...f5fc803659cf3a30f476ac30944a82a6b24f9f.svn-base | 15 - ...e3fe9d186a505b3c5f950983fad166713072f8.svn-base | 3 - ...b662a1347b08fb8c9f48b02aab68cc8f0e579c.svn-base | 4 - ...58f831c64d02ff800519f592f3a99890d95dc9.svn-base | 27 - ...8e8c0a950a4bc2d0dd36c00c8d35940fc911fc.svn-base | 11 - ...b674191cf81d0e511d5f588cf081bf0ff80234.svn-base | 247 --- ...1d60923c68b1fb7bf388e77d888992811b8a49.svn-base | 4 - ...8138e16a5cb393ac32ef3c145f1654806e5484.svn-base | 7 - ...8579cf510cd129a78e6c15d2f561ee50bb16b2.svn-base | 32 - ...fe981670c12565a22d7568a529ddb379b686c1.svn-base | 2 - ...19a78fdf3aa9ba320fa71a0bc4f14a9fdbc869.svn-base | 19 - ...56444e00ad417eb12e267261157989b490f88f.svn-base | 15 - ...892a3253526d334c8f8902616d82a97d7714cd.svn-base | 87 - ...8654882f32416660b1b7820f8542fff6dc8be3.svn-base | 4 - ...ae4fad7a0f93b60a9b09c7da656311aa9bdc0c.svn-base | 3 - ...d242c9c78eddce13db7317c337ae0543d5ed68.svn-base | 9 - ...be306b4aef8549a32a315fdc1250b2db5baa2f.svn-base | 6 - ...15958af1a93d3e5d0662599777f720627fe5bf.svn-base | 9 - ...fd9e15d1a164edc3d50fe278060a81e41afc59.svn-base | 7 - ...7632e29aea1ed6c1c6bca07a8f286b569afceb.svn-base | 4 - ...168a36d9cdf7c1f1802dc97304822e3ce9727e.svn-base | 4 - ...e742ca5e4f1854d7f2e66a4d3c6b70b37a47da.svn-base | 9 - ...f32c6f60b7de28742a11815e3c0ab72eec6737.svn-base | 5 - ...62bff63b200d200039badeb16b18a385bab342.svn-base | 80 - ...98f09d4d2e2339f2c32f472e6203f47582a66b.svn-base | 16 - ...cddea4a9d21ce6301d243a8c2b3bd06d39a397.svn-base | 27 - .svn/wc.db | Bin 69632 -> 0 bytes 56 files changed, 4070 deletions(-) delete mode 100644 .svn/entries delete mode 100644 .svn/format delete mode 100644 .svn/pristine/03/0313342e94d79fb8d4f40a25a40513b6e57076d0.svn-base delete mode 100644 .svn/pristine/08/086fc7948c5e88442b3d34fa48efaf31e908f1f2.svn-base delete mode 100644 .svn/pristine/0c/0cb994438d5e82bac26e515e81375ad80ee8a9e2.svn-base delete mode 100644 .svn/pristine/16/16579793252f0352d07f6b6bcdb451ea31cb2fda.svn-base delete mode 100644 .svn/pristine/1b/1b7b58a944c557deff51914925de5a9aef130201.svn-base delete mode 100644 .svn/pristine/1e/1e458a4884320d893d45f87adc71160b322d527f.svn-base delete mode 100644 .svn/pristine/21/211eee7a3b6eeabe99dc4c9f4e60a536ab2402cf.svn-base delete mode 100644 .svn/pristine/30/304b0879bf42d077f3bdde8f6d6b2d066d8fdc2b.svn-base delete mode 100644 .svn/pristine/30/30c7b999b475568a2dfe41afe27d341d5f1c9815.svn-base delete mode 100644 .svn/pristine/31/319456d5d22d245efd911a61e28f80aabf310219.svn-base delete mode 100644 .svn/pristine/34/344fc6d237f099fee0da8be99bda08fe754357fc.svn-base delete mode 100644 .svn/pristine/36/36ccd54d8a43c6c91b9225a7dccbdb302971aea8.svn-base delete mode 100644 .svn/pristine/3c/3c50b704e748ec4e57d37de9ec5a48889a1414c7.svn-base delete mode 100644 .svn/pristine/4d/4dc5054e4063e20fae767fe147889d24abe36ea7.svn-base delete mode 100644 .svn/pristine/5b/5bbe0a6640afdc5794427c8808a7c20ca8d2c306.svn-base delete mode 100644 .svn/pristine/5c/5cd03cc0ba37bfc0e8507e4dd6b307d29ebd729b.svn-base delete mode 100644 .svn/pristine/5c/5cd5492625fc746d81349b8a4cbdf4299fd7183b.svn-base delete mode 100644 .svn/pristine/5d/5db4ff612674ecf806062137f28793f303e9031a.svn-base delete mode 100644 .svn/pristine/5e/5ea0f09eaad0b7500c98a5d824bde54e4ab0a9ba.svn-base delete mode 100644 .svn/pristine/62/6253d0e0bdcc36df327e3e92379ae5b0316d73b6.svn-base delete mode 100644 .svn/pristine/67/6727ff2548a4483177cf428737c254fdba3be725.svn-base delete mode 100644 .svn/pristine/6c/6c31b2bdb233bafb1bbf172a9065e3ec04d54cde.svn-base delete mode 100644 .svn/pristine/6c/6c6063591602b23d43faa8f31867991e7c0f93dc.svn-base delete mode 100644 .svn/pristine/6f/6fa8ecf7da0b483cf29d7d789e85b541baf747ca.svn-base delete mode 100644 .svn/pristine/77/77a33ad02fc07dcc76b961c8e50e579530a302a5.svn-base delete mode 100644 .svn/pristine/78/78570c264e14d1351cca2be967bbe62329bb7cea.svn-base delete mode 100644 .svn/pristine/80/809d98f6c6e06d4f51258f9935713a53db5fdcd0.svn-base delete mode 100644 .svn/pristine/82/82f5fc803659cf3a30f476ac30944a82a6b24f9f.svn-base delete mode 100644 .svn/pristine/8e/8ee3fe9d186a505b3c5f950983fad166713072f8.svn-base delete mode 100644 .svn/pristine/94/94b662a1347b08fb8c9f48b02aab68cc8f0e579c.svn-base delete mode 100644 .svn/pristine/a0/a058f831c64d02ff800519f592f3a99890d95dc9.svn-base delete mode 100644 .svn/pristine/a4/a48e8c0a950a4bc2d0dd36c00c8d35940fc911fc.svn-base delete mode 100644 .svn/pristine/a7/a7b674191cf81d0e511d5f588cf081bf0ff80234.svn-base delete mode 100644 .svn/pristine/b4/b41d60923c68b1fb7bf388e77d888992811b8a49.svn-base delete mode 100644 .svn/pristine/b5/b58138e16a5cb393ac32ef3c145f1654806e5484.svn-base delete mode 100644 .svn/pristine/b6/b68579cf510cd129a78e6c15d2f561ee50bb16b2.svn-base delete mode 100644 .svn/pristine/b7/b7fe981670c12565a22d7568a529ddb379b686c1.svn-base delete mode 100644 .svn/pristine/b8/b819a78fdf3aa9ba320fa71a0bc4f14a9fdbc869.svn-base delete mode 100644 .svn/pristine/bd/bd56444e00ad417eb12e267261157989b490f88f.svn-base delete mode 100644 .svn/pristine/c1/c1892a3253526d334c8f8902616d82a97d7714cd.svn-base delete mode 100644 .svn/pristine/c6/c68654882f32416660b1b7820f8542fff6dc8be3.svn-base delete mode 100644 .svn/pristine/ca/caae4fad7a0f93b60a9b09c7da656311aa9bdc0c.svn-base delete mode 100644 .svn/pristine/cb/cbd242c9c78eddce13db7317c337ae0543d5ed68.svn-base delete mode 100644 .svn/pristine/ce/cebe306b4aef8549a32a315fdc1250b2db5baa2f.svn-base delete mode 100644 .svn/pristine/d7/d715958af1a93d3e5d0662599777f720627fe5bf.svn-base delete mode 100644 .svn/pristine/db/dbfd9e15d1a164edc3d50fe278060a81e41afc59.svn-base delete mode 100644 .svn/pristine/dd/dd7632e29aea1ed6c1c6bca07a8f286b569afceb.svn-base delete mode 100644 .svn/pristine/de/de168a36d9cdf7c1f1802dc97304822e3ce9727e.svn-base delete mode 100644 .svn/pristine/e1/e1e742ca5e4f1854d7f2e66a4d3c6b70b37a47da.svn-base delete mode 100644 .svn/pristine/e7/e7f32c6f60b7de28742a11815e3c0ab72eec6737.svn-base delete mode 100644 .svn/pristine/e9/e962bff63b200d200039badeb16b18a385bab342.svn-base delete mode 100644 .svn/pristine/ea/ea98f09d4d2e2339f2c32f472e6203f47582a66b.svn-base delete mode 100644 .svn/pristine/fc/fccddea4a9d21ce6301d243a8c2b3bd06d39a397.svn-base delete mode 100644 .svn/wc.db diff --git a/.svn/entries b/.svn/entries deleted file mode 100644 index 48082f7..0000000 --- a/.svn/entries +++ /dev/null @@ -1 +0,0 @@ -12 diff --git a/.svn/format b/.svn/format deleted file mode 100644 index 48082f7..0000000 --- a/.svn/format +++ /dev/null @@ -1 +0,0 @@ -12 diff --git a/.svn/pristine/03/0313342e94d79fb8d4f40a25a40513b6e57076d0.svn-base b/.svn/pristine/03/0313342e94d79fb8d4f40a25a40513b6e57076d0.svn-base deleted file mode 100644 index 550bf32..0000000 --- a/.svn/pristine/03/0313342e94d79fb8d4f40a25a40513b6e57076d0.svn-base +++ /dev/null @@ -1,7 +0,0 @@ -// test for array remove -var a = [1,2,4,5,7]; - -a.remove(2); -a.remove(5); - -result = a.length==3 && a[0]==1 && a[1]==4 && a[2]==7; diff --git a/.svn/pristine/08/086fc7948c5e88442b3d34fa48efaf31e908f1f2.svn-base b/.svn/pristine/08/086fc7948c5e88442b3d34fa48efaf31e908f1f2.svn-base deleted file mode 100644 index 1d79882..0000000 --- a/.svn/pristine/08/086fc7948c5e88442b3d34fa48efaf31e908f1f2.svn-base +++ /dev/null @@ -1,285 +0,0 @@ -/* - * TinyJS - * - * A single-file Javascript-alike engine - * - * - Math and Trigonometry functions - * - * Authored By O.Z.L.B. - * - * Copyright (C) 2011 O.Z.L.B. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is furnished to do - * so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include -#include -#include "TinyJS_MathFunctions.h" - -using namespace std; - -#define k_E exp(1.0) -#define k_PI 3.1415926535897932384626433832795 - -#define F_ABS(a) ((a)>=0 ? (a) : (-(a))) -#define F_MIN(a,b) ((a)>(b) ? (b) : (a)) -#define F_MAX(a,b) ((a)>(b) ? (a) : (b)) -#define F_SGN(a) ((a)>0 ? 1 : ((a)<0 ? -1 : 0 )) -#define F_RNG(a,min,max) ((a)<(min) ? min : ((a)>(max) ? max : a )) -#define F_ROUND(a) ((a)>0 ? (int) ((a)+0.5) : (int) ((a)-0.5) ) - -//CScriptVar shortcut macro -#define scIsInt(a) ( c->getParameter(a)->isInt() ) -#define scIsDouble(a) ( c->getParameter(a)->isDouble() ) -#define scGetInt(a) ( c->getParameter(a)->getInt() ) -#define scGetDouble(a) ( c->getParameter(a)->getDouble() ) -#define scReturnInt(a) ( c->getReturnVar()->setInt(a) ) -#define scReturnDouble(a) ( c->getReturnVar()->setDouble(a) ) - -#ifdef _MSC_VER -namespace -{ - double asinh( const double &value ) - { - double returned; - - if(value>0) - returned = log(value + sqrt(value * value + 1)); - else - returned = -log(-value + sqrt(value * value + 1)); - - return(returned); - } - - double acosh( const double &value ) - { - double returned; - - if(value>0) - returned = log(value + sqrt(value * value - 1)); - else - returned = -log(-value + sqrt(value * value - 1)); - - return(returned); - } -} -#endif - -//Math.abs(x) - returns absolute of given value -void scMathAbs(CScriptVar *c, void *userdata) { - if ( scIsInt("a") ) { - scReturnInt( F_ABS( scGetInt("a") ) ); - } else if ( scIsDouble("a") ) { - scReturnDouble( F_ABS( scGetDouble("a") ) ); - } -} - -//Math.round(a) - returns nearest round of given value -void scMathRound(CScriptVar *c, void *userdata) { - if ( scIsInt("a") ) { - scReturnInt( F_ROUND( scGetInt("a") ) ); - } else if ( scIsDouble("a") ) { - scReturnDouble( F_ROUND( scGetDouble("a") ) ); - } -} - -//Math.min(a,b) - returns minimum of two given values -void scMathMin(CScriptVar *c, void *userdata) { - if ( (scIsInt("a")) && (scIsInt("b")) ) { - scReturnInt( F_MIN( scGetInt("a"), scGetInt("b") ) ); - } else { - scReturnDouble( F_MIN( scGetDouble("a"), scGetDouble("b") ) ); - } -} - -//Math.max(a,b) - returns maximum of two given values -void scMathMax(CScriptVar *c, void *userdata) { - if ( (scIsInt("a")) && (scIsInt("b")) ) { - scReturnInt( F_MAX( scGetInt("a"), scGetInt("b") ) ); - } else { - scReturnDouble( F_MAX( scGetDouble("a"), scGetDouble("b") ) ); - } -} - -//Math.range(x,a,b) - returns value limited between two given values -void scMathRange(CScriptVar *c, void *userdata) { - if ( (scIsInt("x")) ) { - scReturnInt( F_RNG( scGetInt("x"), scGetInt("a"), scGetInt("b") ) ); - } else { - scReturnDouble( F_RNG( scGetDouble("x"), scGetDouble("a"), scGetDouble("b") ) ); - } -} - -//Math.sign(a) - returns sign of given value (-1==negative,0=zero,1=positive) -void scMathSign(CScriptVar *c, void *userdata) { - if ( scIsInt("a") ) { - scReturnInt( F_SGN( scGetInt("a") ) ); - } else if ( scIsDouble("a") ) { - scReturnDouble( F_SGN( scGetDouble("a") ) ); - } -} - -//Math.PI() - returns PI value -void scMathPI(CScriptVar *c, void *userdata) { - scReturnDouble(k_PI); -} - -//Math.toDegrees(a) - returns degree value of a given angle in radians -void scMathToDegrees(CScriptVar *c, void *userdata) { - scReturnDouble( (180.0/k_PI)*( scGetDouble("a") ) ); -} - -//Math.toRadians(a) - returns radians value of a given angle in degrees -void scMathToRadians(CScriptVar *c, void *userdata) { - scReturnDouble( (k_PI/180.0)*( scGetDouble("a") ) ); -} - -//Math.sin(a) - returns trig. sine of given angle in radians -void scMathSin(CScriptVar *c, void *userdata) { - scReturnDouble( sin( scGetDouble("a") ) ); -} - -//Math.asin(a) - returns trig. arcsine of given angle in radians -void scMathASin(CScriptVar *c, void *userdata) { - scReturnDouble( asin( scGetDouble("a") ) ); -} - -//Math.cos(a) - returns trig. cosine of given angle in radians -void scMathCos(CScriptVar *c, void *userdata) { - scReturnDouble( cos( scGetDouble("a") ) ); -} - -//Math.acos(a) - returns trig. arccosine of given angle in radians -void scMathACos(CScriptVar *c, void *userdata) { - scReturnDouble( acos( scGetDouble("a") ) ); -} - -//Math.tan(a) - returns trig. tangent of given angle in radians -void scMathTan(CScriptVar *c, void *userdata) { - scReturnDouble( tan( scGetDouble("a") ) ); -} - -//Math.atan(a) - returns trig. arctangent of given angle in radians -void scMathATan(CScriptVar *c, void *userdata) { - scReturnDouble( atan( scGetDouble("a") ) ); -} - -//Math.sinh(a) - returns trig. hyperbolic sine of given angle in radians -void scMathSinh(CScriptVar *c, void *userdata) { - scReturnDouble( sinh( scGetDouble("a") ) ); -} - -//Math.asinh(a) - returns trig. hyperbolic arcsine of given angle in radians -void scMathASinh(CScriptVar *c, void *userdata) { - scReturnDouble( asinh( scGetDouble("a") ) ); -} - -//Math.cosh(a) - returns trig. hyperbolic cosine of given angle in radians -void scMathCosh(CScriptVar *c, void *userdata) { - scReturnDouble( cosh( scGetDouble("a") ) ); -} - -//Math.acosh(a) - returns trig. hyperbolic arccosine of given angle in radians -void scMathACosh(CScriptVar *c, void *userdata) { - scReturnDouble( acosh( scGetDouble("a") ) ); -} - -//Math.tanh(a) - returns trig. hyperbolic tangent of given angle in radians -void scMathTanh(CScriptVar *c, void *userdata) { - scReturnDouble( tanh( scGetDouble("a") ) ); -} - -//Math.atan(a) - returns trig. hyperbolic arctangent of given angle in radians -void scMathATanh(CScriptVar *c, void *userdata) { - scReturnDouble( atan( scGetDouble("a") ) ); -} - -//Math.E() - returns E Neplero value -void scMathE(CScriptVar *c, void *userdata) { - scReturnDouble(k_E); -} - -//Math.log(a) - returns natural logaritm (base E) of given value -void scMathLog(CScriptVar *c, void *userdata) { - scReturnDouble( log( scGetDouble("a") ) ); -} - -//Math.log10(a) - returns logaritm(base 10) of given value -void scMathLog10(CScriptVar *c, void *userdata) { - scReturnDouble( log10( scGetDouble("a") ) ); -} - -//Math.exp(a) - returns e raised to the power of a given number -void scMathExp(CScriptVar *c, void *userdata) { - scReturnDouble( exp( scGetDouble("a") ) ); -} - -//Math.pow(a,b) - returns the result of a number raised to a power (a)^(b) -void scMathPow(CScriptVar *c, void *userdata) { - scReturnDouble( pow( scGetDouble("a"), scGetDouble("b") ) ); -} - -//Math.sqr(a) - returns square of given value -void scMathSqr(CScriptVar *c, void *userdata) { - scReturnDouble( ( scGetDouble("a") * scGetDouble("a") ) ); -} - -//Math.sqrt(a) - returns square root of given value -void scMathSqrt(CScriptVar *c, void *userdata) { - scReturnDouble( sqrtf( scGetDouble("a") ) ); -} - -// ----------------------------------------------- Register Functions -void registerMathFunctions(CTinyJS *tinyJS) { - - // --- Math and Trigonometry functions --- - tinyJS->addNative("function Math.abs(a)", scMathAbs, 0); - tinyJS->addNative("function Math.round(a)", scMathRound, 0); - tinyJS->addNative("function Math.min(a,b)", scMathMin, 0); - tinyJS->addNative("function Math.max(a,b)", scMathMax, 0); - tinyJS->addNative("function Math.range(x,a,b)", scMathRange, 0); - tinyJS->addNative("function Math.sign(a)", scMathSign, 0); - - tinyJS->addNative("function Math.PI()", scMathPI, 0); - tinyJS->addNative("function Math.toDegrees(a)", scMathToDegrees, 0); - tinyJS->addNative("function Math.toRadians(a)", scMathToRadians, 0); - tinyJS->addNative("function Math.sin(a)", scMathSin, 0); - tinyJS->addNative("function Math.asin(a)", scMathASin, 0); - tinyJS->addNative("function Math.cos(a)", scMathCos, 0); - tinyJS->addNative("function Math.acos(a)", scMathACos, 0); - tinyJS->addNative("function Math.tan(a)", scMathTan, 0); - tinyJS->addNative("function Math.atan(a)", scMathATan, 0); - tinyJS->addNative("function Math.sinh(a)", scMathSinh, 0); - tinyJS->addNative("function Math.asinh(a)", scMathASinh, 0); - tinyJS->addNative("function Math.cosh(a)", scMathCosh, 0); - tinyJS->addNative("function Math.acosh(a)", scMathACosh, 0); - tinyJS->addNative("function Math.tanh(a)", scMathTanh, 0); - tinyJS->addNative("function Math.atanh(a)", scMathATanh, 0); - - tinyJS->addNative("function Math.E()", scMathE, 0); - tinyJS->addNative("function Math.log(a)", scMathLog, 0); - tinyJS->addNative("function Math.log10(a)", scMathLog10, 0); - tinyJS->addNative("function Math.exp(a)", scMathExp, 0); - tinyJS->addNative("function Math.pow(a,b)", scMathPow, 0); - - tinyJS->addNative("function Math.sqr(a)", scMathSqr, 0); - tinyJS->addNative("function Math.sqrt(a)", scMathSqrt, 0); - -} diff --git a/.svn/pristine/0c/0cb994438d5e82bac26e515e81375ad80ee8a9e2.svn-base b/.svn/pristine/0c/0cb994438d5e82bac26e515e81375ad80ee8a9e2.svn-base deleted file mode 100644 index d1c7f05..0000000 --- a/.svn/pristine/0c/0cb994438d5e82bac26e515e81375ad80ee8a9e2.svn-base +++ /dev/null @@ -1,294 +0,0 @@ -/* - * TinyJS - * - * A single-file Javascript-alike engine - * - * Authored By Gordon Williams - * - * Copyright (C) 2009 Pur3 Ltd - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is furnished to do - * so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* - * This is a program to run all the tests in the tests folder... - */ - -#include "TinyJS.h" -#include "TinyJS_Functions.h" -#include "TinyJS_MathFunctions.h" -#include -#include -#include -#include -#include - -#ifdef MTRACE - #include -#endif - -//#define INSANE_MEMORY_DEBUG - -#ifdef INSANE_MEMORY_DEBUG -// needs -rdynamic when compiling/linking -#include -#include -#include -#include -using namespace std; - -void **get_stackframe() { - void **trace = (void**)malloc(sizeof(void*)*17); - int trace_size = 0; - - for (int i=0;i<17;i++) trace[i]=(void*)0; - trace_size = backtrace(trace, 16); - return trace; -} - -void print_stackframe(char *header, void **trace) { - char **messages = (char **)NULL; - int trace_size = 0; - - trace_size = 0; - while (trace[trace_size]) trace_size++; - messages = backtrace_symbols(trace, trace_size); - - printf("%s\n", header); - for (int i=0; i malloced; - -static void *my_malloc_hook(size_t size, const void *caller) { - /* Restore all old hooks */ - __malloc_hook = old_malloc_hook; - __free_hook = old_free_hook; - /* Call recursively */ - void *result = malloc (size); - /* we call malloc here, so protect it too. */ - //printf ("malloc (%u) returns %p\n", (unsigned int) size, result); - malloced[result] = get_stackframe(); - - /* Restore our own hooks */ - __malloc_hook = my_malloc_hook; - __free_hook = my_free_hook; - return result; -} - -static void my_free_hook(void *ptr, const void *caller) { - /* Restore all old hooks */ - __malloc_hook = old_malloc_hook; - __free_hook = old_free_hook; - /* Call recursively */ - free (ptr); - /* we call malloc here, so protect it too. */ - //printf ("freed pointer %p\n", ptr); - if (malloced.find(ptr) == malloced.end()) { - /*fprintf(stderr, "INVALID FREE\n"); - void *trace[16]; - int trace_size = 0; - trace_size = backtrace(trace, 16); - backtrace_symbols_fd(trace, trace_size, STDERR_FILENO);*/ - } else - malloced.erase(ptr); - /* Restore our own hooks */ - __malloc_hook = my_malloc_hook; - __free_hook = my_free_hook; -} - -void memtracing_init() { - old_malloc_hook = __malloc_hook; - old_free_hook = __free_hook; - __malloc_hook = my_malloc_hook; - __free_hook = my_free_hook; -} - -long gethash(void **trace) { - unsigned long hash = 0; - while (*trace) { - hash = (hash<<1) ^ (hash>>63) ^ (unsigned long)*trace; - trace++; - } - return hash; -} - -void memtracing_kill() { - /* Restore all old hooks */ - __malloc_hook = old_malloc_hook; - __free_hook = old_free_hook; - - map hashToReal; - map counts; - map::iterator it = malloced.begin(); - while (it!=malloced.end()) { - long hash = gethash(it->second); - hashToReal[hash] = it->second; - - if (counts.find(hash) == counts.end()) - counts[hash] = 1; - else - counts[hash]++; - - it++; - } - - vector > sorting; - map::iterator countit = counts.begin(); - while (countit!=counts.end()) { - sorting.push_back(pair(countit->second, countit->first)); - countit++; - } - - // sort - bool done = false; - while (!done) { - done = true; - for (int i=0;i t = sorting[i]; - sorting[i] = sorting[i+1]; - sorting[i+1] = t; - done = false; - } - } - } - - - for (int i=0;i the size we read */ - if( !file ) { - printf("Unable to open file! '%s'\n", filename); - return false; - } - char *buffer = new char[size+1]; - long actualRead = fread(buffer,1,size,file); - buffer[actualRead]=0; - buffer[size]=0; - fclose(file); - - CTinyJS s; - registerFunctions(&s); - registerMathFunctions(&s); - s.root->addChild("result", new CScriptVar("0",SCRIPTVAR_INTEGER)); - try { - s.execute(buffer); - } catch (CScriptException *e) { - printf("ERROR: %s\n", e->text.c_str()); - } - bool pass = s.root->getParameter("result")->getBool(); - - if (pass) - printf("PASS\n"); - else { - char fn[64]; - sprintf(fn, "%s.fail.js", filename); - FILE *f = fopen(fn, "wt"); - if (f) { - std::ostringstream symbols; - s.root->getJSON(symbols); - fprintf(f, "%s", symbols.str().c_str()); - fclose(f); - } - - printf("FAIL - symbols written to %s\n", fn); - } - - delete[] buffer; - return pass; -} - -int main(int argc, char **argv) -{ -#ifdef MTRACE - mtrace(); -#endif -#ifdef INSANE_MEMORY_DEBUG - memtracing_init(); -#endif - printf("TinyJS test runner\n"); - printf("USAGE:\n"); - printf(" ./run_tests test.js : run just one test\n"); - printf(" ./run_tests : run all tests\n"); - if (argc==2) { - return !run_test(argv[1]); - } - - int test_num = 1; - int count = 0; - int passed = 0; - - while (test_num<1000) { - char fn[32]; - sprintf(fn, "tests/test%03d.js", test_num); - // check if the file exists - if not, assume we're at the end of our tests - FILE *f = fopen(fn,"r"); - if (!f) break; - fclose(f); - - if (run_test(fn)) - passed++; - count++; - test_num++; - } - - printf("Done. %d tests, %d pass, %d fail\n", count, passed, count-passed); -#ifdef INSANE_MEMORY_DEBUG - memtracing_kill(); -#endif - -#ifdef _DEBUG - #ifdef _WIN32 - _CrtDumpMemoryLeaks(); - #endif -#endif -#ifdef MTRACE - muntrace(); -#endif - - return 0; -} diff --git a/.svn/pristine/16/16579793252f0352d07f6b6bcdb451ea31cb2fda.svn-base b/.svn/pristine/16/16579793252f0352d07f6b6bcdb451ea31cb2fda.svn-base deleted file mode 100644 index 55126fa..0000000 --- a/.svn/pristine/16/16579793252f0352d07f6b6bcdb451ea31cb2fda.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -// simple for loop -var a = 0; -var i; -for (i=1;i<10;i++) a = a + i; -result = a==45; diff --git a/.svn/pristine/1b/1b7b58a944c557deff51914925de5a9aef130201.svn-base b/.svn/pristine/1b/1b7b58a944c557deff51914925de5a9aef130201.svn-base deleted file mode 100644 index ad41262..0000000 --- a/.svn/pristine/1b/1b7b58a944c557deff51914925de5a9aef130201.svn-base +++ /dev/null @@ -1,12 +0,0 @@ -// function-closure - -var a = 40; // a global var - -function closure() { - var a = 39; // a local var; - return function() { return a; }; -} - -var b = closure(); // the local var a is now hidden - -result = b()+3 == 42 && a+2 == 42; diff --git a/.svn/pristine/1e/1e458a4884320d893d45f87adc71160b322d527f.svn-base b/.svn/pristine/1e/1e458a4884320d893d45f87adc71160b322d527f.svn-base deleted file mode 100644 index 4a70a37..0000000 --- a/.svn/pristine/1e/1e458a4884320d893d45f87adc71160b322d527f.svn-base +++ /dev/null @@ -1,8 +0,0 @@ -// Number definition from http://en.wikipedia.org/wiki/JavaScript_syntax -a = 345; // an "integer", although there is only one numeric type in JavaScript -b = 34.5; // a floating-point number -c = 3.45e2; // another floating-point, equivalent to 345 -d = 0377; // an octal integer equal to 255 -e = 0xFF; // a hexadecimal integer equal to 255, digits represented by the letters A-F may be upper or lowercase - -result = a==345 && b*10==345 && c==345 && d==255 && e==255; diff --git a/.svn/pristine/21/211eee7a3b6eeabe99dc4c9f4e60a536ab2402cf.svn-base b/.svn/pristine/21/211eee7a3b6eeabe99dc4c9f4e60a536ab2402cf.svn-base deleted file mode 100644 index a49fa29..0000000 --- a/.svn/pristine/21/211eee7a3b6eeabe99dc4c9f4e60a536ab2402cf.svn-base +++ /dev/null @@ -1,3 +0,0 @@ -// test for ternary - -result = (true?3:4)==3 && (false?5:6)==6; diff --git a/.svn/pristine/30/304b0879bf42d077f3bdde8f6d6b2d066d8fdc2b.svn-base b/.svn/pristine/30/304b0879bf42d077f3bdde8f6d6b2d066d8fdc2b.svn-base deleted file mode 100644 index 104f9a7..0000000 --- a/.svn/pristine/30/304b0879bf42d077f3bdde8f6d6b2d066d8fdc2b.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -// test for array contains -var a = [1,2,4,5,7]; -var b = ["bread","cheese","sandwich"]; - -result = a.contains(1) && !a.contains(42) && b.contains("cheese") && !b.contains("eggs"); diff --git a/.svn/pristine/30/30c7b999b475568a2dfe41afe27d341d5f1c9815.svn-base b/.svn/pristine/30/30c7b999b475568a2dfe41afe27d341d5f1c9815.svn-base deleted file mode 100644 index 2c50344..0000000 --- a/.svn/pristine/30/30c7b999b475568a2dfe41afe27d341d5f1c9815.svn-base +++ /dev/null @@ -1,6 +0,0 @@ -// if .. else -var a = 42; -if (a != 42) - result = 0; -else - result = 1; diff --git a/.svn/pristine/31/319456d5d22d245efd911a61e28f80aabf310219.svn-base b/.svn/pristine/31/319456d5d22d245efd911a61e28f80aabf310219.svn-base deleted file mode 100644 index b293396..0000000 --- a/.svn/pristine/31/319456d5d22d245efd911a61e28f80aabf310219.svn-base +++ /dev/null @@ -1,15 +0,0 @@ -// Undefined/null from http://en.wikipedia.org/wiki/JavaScript_syntax -var testUndefined; // variable declared but not defined, set to value of undefined -var testObj = {}; - -result = 1; -if ((""+testUndefined) != "undefined") result = 0; // test variable exists but value not defined, displays undefined -if ((""+testObj.myProp) != "undefined") result = 0; // testObj exists, property does not, displays undefined -if (!(undefined == null)) result = 0; // unenforced type during check, displays true -if (undefined === null) result = 0;// enforce type during check, displays false - - -if (null != undefined) result = 0; // unenforced type during check, displays true -if (null === undefined) result = 0; // enforce type during check, displays false - - diff --git a/.svn/pristine/34/344fc6d237f099fee0da8be99bda08fe754357fc.svn-base b/.svn/pristine/34/344fc6d237f099fee0da8be99bda08fe754357fc.svn-base deleted file mode 100644 index f944064..0000000 --- a/.svn/pristine/34/344fc6d237f099fee0da8be99bda08fe754357fc.svn-base +++ /dev/null @@ -1,4 +0,0 @@ -// simple for loop containing initialisation, using += -var a = 0; -for (var i=1;i<10;i++) a += i; -result = a==45; diff --git a/.svn/pristine/36/36ccd54d8a43c6c91b9225a7dccbdb302971aea8.svn-base b/.svn/pristine/36/36ccd54d8a43c6c91b9225a7dccbdb302971aea8.svn-base deleted file mode 100644 index b0d5525..0000000 --- a/.svn/pristine/36/36ccd54d8a43c6c91b9225a7dccbdb302971aea8.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -// functions in variables -var bob = {}; -bob.add = function(x,y) { return x+y; }; - -result = bob.add(3,6)==9; diff --git a/.svn/pristine/3c/3c50b704e748ec4e57d37de9ec5a48889a1414c7.svn-base b/.svn/pristine/3c/3c50b704e748ec4e57d37de9ec5a48889a1414c7.svn-base deleted file mode 100644 index d94e231..0000000 --- a/.svn/pristine/3c/3c50b704e748ec4e57d37de9ec5a48889a1414c7.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -/* Javascript eval */ - -myfoo = eval("{ foo: 42 }"); - -result = eval("4*10+2")==42 && myfoo.foo==42; diff --git a/.svn/pristine/4d/4dc5054e4063e20fae767fe147889d24abe36ea7.svn-base b/.svn/pristine/4d/4dc5054e4063e20fae767fe147889d24abe36ea7.svn-base deleted file mode 100644 index ec36b51..0000000 --- a/.svn/pristine/4d/4dc5054e4063e20fae767fe147889d24abe36ea7.svn-base +++ /dev/null @@ -1,360 +0,0 @@ -/* - * TinyJS - * - * A single-file Javascript-alike engine - * - * Authored By Gordon Williams - * - * Copyright (C) 2009 Pur3 Ltd - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is furnished to do - * so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef TINYJS_H -#define TINYJS_H - -// If defined, this keeps a note of all calls and where from in memory. This is slower, but good for debugging -#define TINYJS_CALL_STACK - -#ifdef _WIN32 -#ifdef _DEBUG -#define _CRTDBG_MAP_ALLOC -#include -#include -#endif -#endif -#include -#include - -#ifndef TRACE -#define TRACE printf -#endif // TRACE - - -const int TINYJS_LOOP_MAX_ITERATIONS = 8192; - -enum LEX_TYPES { - LEX_EOF = 0, - LEX_ID = 256, - LEX_INT, - LEX_FLOAT, - LEX_STR, - - LEX_EQUAL, - LEX_TYPEEQUAL, - LEX_NEQUAL, - LEX_NTYPEEQUAL, - LEX_LEQUAL, - LEX_LSHIFT, - LEX_LSHIFTEQUAL, - LEX_GEQUAL, - LEX_RSHIFT, - LEX_RSHIFTUNSIGNED, - LEX_RSHIFTEQUAL, - LEX_PLUSEQUAL, - LEX_MINUSEQUAL, - LEX_PLUSPLUS, - LEX_MINUSMINUS, - LEX_ANDEQUAL, - LEX_ANDAND, - LEX_OREQUAL, - LEX_OROR, - LEX_XOREQUAL, - // reserved words -#define LEX_R_LIST_START LEX_R_IF - LEX_R_IF, - LEX_R_ELSE, - LEX_R_DO, - LEX_R_WHILE, - LEX_R_FOR, - LEX_R_BREAK, - LEX_R_CONTINUE, - LEX_R_FUNCTION, - LEX_R_RETURN, - LEX_R_VAR, - LEX_R_TRUE, - LEX_R_FALSE, - LEX_R_NULL, - LEX_R_UNDEFINED, - LEX_R_NEW, - - LEX_R_LIST_END /* always the last entry */ -}; - -enum SCRIPTVAR_FLAGS { - SCRIPTVAR_UNDEFINED = 0, - SCRIPTVAR_FUNCTION = 1, - SCRIPTVAR_OBJECT = 2, - SCRIPTVAR_ARRAY = 4, - SCRIPTVAR_DOUBLE = 8, // floating point double - SCRIPTVAR_INTEGER = 16, // integer number - SCRIPTVAR_STRING = 32, // string - SCRIPTVAR_NULL = 64, // it seems null is its own data type - - SCRIPTVAR_NATIVE = 128, // to specify this is a native function - SCRIPTVAR_NUMERICMASK = SCRIPTVAR_NULL | - SCRIPTVAR_DOUBLE | - SCRIPTVAR_INTEGER, - SCRIPTVAR_VARTYPEMASK = SCRIPTVAR_DOUBLE | - SCRIPTVAR_INTEGER | - SCRIPTVAR_STRING | - SCRIPTVAR_FUNCTION | - SCRIPTVAR_OBJECT | - SCRIPTVAR_ARRAY | - SCRIPTVAR_NULL, - -}; - -#define TINYJS_RETURN_VAR "return" -#define TINYJS_PROTOTYPE_CLASS "prototype" -#define TINYJS_TEMP_NAME "" -#define TINYJS_BLANK_DATA "" - -/// convert the given string into a quoted string suitable for javascript -std::string getJSString(const std::string &str); - -class CScriptException { -public: - std::string text; - CScriptException(const std::string &exceptionText); -}; - -class CScriptLex -{ -public: - CScriptLex(const std::string &input); - CScriptLex(CScriptLex *owner, int startChar, int endChar); - ~CScriptLex(void); - - char currCh, nextCh; - int tk; ///< The type of the token that we have - int tokenStart; ///< Position in the data at the beginning of the token we have here - int tokenEnd; ///< Position in the data at the last character of the token we have here - int tokenLastEnd; ///< Position in the data at the last character of the last token - std::string tkStr; ///< Data contained in the token we have here - - void match(int expected_tk); ///< Lexical match wotsit - static std::string getTokenStr(int token); ///< Get the string representation of the given token - void reset(); ///< Reset this lex so we can start again - - std::string getSubString(int pos); ///< Return a sub-string from the given position up until right now - CScriptLex *getSubLex(int lastPosition); ///< Return a sub-lexer from the given position up until right now - - std::string getPosition(int pos=-1); ///< Return a string representing the position in lines and columns of the character pos given - -protected: - /* When we go into a loop, we use getSubLex to get a lexer for just the sub-part of the - relevant string. This doesn't re-allocate and copy the string, but instead copies - the data pointer and sets dataOwned to false, and dataStart/dataEnd to the relevant things. */ - char *data; ///< Data string to get tokens from - int dataStart, dataEnd; ///< Start and end position in data string - bool dataOwned; ///< Do we own this data string? - - int dataPos; ///< Position in data (we CAN go past the end of the string here) - - void getNextCh(); - void getNextToken(); ///< Get the text token from our text string -}; - -class CScriptVar; - -typedef void (*JSCallback)(CScriptVar *var, void *userdata); - -class CScriptVarLink -{ -public: - std::string name; - CScriptVarLink *nextSibling; - CScriptVarLink *prevSibling; - CScriptVar *var; - bool owned; - - CScriptVarLink(CScriptVar *var, const std::string &name = TINYJS_TEMP_NAME); - CScriptVarLink(const CScriptVarLink &link); ///< Copy constructor - ~CScriptVarLink(); - void replaceWith(CScriptVar *newVar); ///< Replace the Variable pointed to - void replaceWith(CScriptVarLink *newVar); ///< Replace the Variable pointed to (just dereferences) - int getIntName(); ///< Get the name as an integer (for arrays) - void setIntName(int n); ///< Set the name as an integer (for arrays) -}; - -/// Variable class (containing a doubly-linked list of children) -class CScriptVar -{ -public: - CScriptVar(); ///< Create undefined - CScriptVar(const std::string &varData, int varFlags); ///< User defined - CScriptVar(const std::string &str); ///< Create a string - CScriptVar(double varData); - CScriptVar(int val); - ~CScriptVar(void); - - CScriptVar *getReturnVar(); ///< If this is a function, get the result value (for use by native functions) - void setReturnVar(CScriptVar *var); ///< Set the result value. Use this when setting complex return data as it avoids a deepCopy() - CScriptVar *getParameter(const std::string &name); ///< If this is a function, get the parameter with the given name (for use by native functions) - - CScriptVarLink *findChild(const std::string &childName); ///< Tries to find a child with the given name, may return 0 - CScriptVarLink *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 - CScriptVarLink *findChildOrCreateByPath(const std::string &path); ///< Tries to find a child with the given path (separated by dots) - CScriptVarLink *addChild(const std::string &childName, CScriptVar *child=NULL); - CScriptVarLink *addChildNoDup(const std::string &childName, CScriptVar *child=NULL); ///< add a child overwriting any with the same name - void removeChild(CScriptVar *child); - void removeLink(CScriptVarLink *link); ///< Remove a specific link (this is faster than finding via a child) - void removeAllChildren(); - CScriptVar *getArrayIndex(int idx); ///< The the value at an array index - void setArrayIndex(int idx, CScriptVar *value); ///< Set the value at an array index - int getArrayLength(); ///< If this is an array, return the number of items in it (else 0) - int getChildren(); ///< Get the number of children - - int getInt(); - bool getBool() { return getInt() != 0; } - double getDouble(); - const std::string &getString(); - std::string getParsableString(); ///< get Data as a parsable javascript string - void setInt(int num); - void setDouble(double val); - void setString(const std::string &str); - void setUndefined(); - void setArray(); - bool equals(CScriptVar *v); - - bool isInt() { return (flags&SCRIPTVAR_INTEGER)!=0; } - bool isDouble() { return (flags&SCRIPTVAR_DOUBLE)!=0; } - bool isString() { return (flags&SCRIPTVAR_STRING)!=0; } - bool isNumeric() { return (flags&SCRIPTVAR_NUMERICMASK)!=0; } - bool isFunction() { return (flags&SCRIPTVAR_FUNCTION)!=0; } - bool isObject() { return (flags&SCRIPTVAR_OBJECT)!=0; } - bool isArray() { return (flags&SCRIPTVAR_ARRAY)!=0; } - bool isNative() { return (flags&SCRIPTVAR_NATIVE)!=0; } - bool isUndefined() { return (flags & SCRIPTVAR_VARTYPEMASK) == SCRIPTVAR_UNDEFINED; } - bool isNull() { return (flags & SCRIPTVAR_NULL)!=0; } - bool isBasic() { return firstChild==0; } ///< Is this *not* an array/object/etc - - CScriptVar *mathsOp(CScriptVar *b, int op); ///< do a maths op with another script variable - void copyValue(CScriptVar *val); ///< copy the value from the value given - CScriptVar *deepCopy(); ///< deep copy this node and return the result - - void trace(std::string indentStr = "", const std::string &name = ""); ///< Dump out the contents of this using trace - std::string getFlagsAsString(); ///< For debugging - just dump a string version of the flags - 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) - void setCallback(JSCallback callback, void *userdata); ///< Set the callback for native functions - - CScriptVarLink *firstChild; - CScriptVarLink *lastChild; - - /// For memory management/garbage collection - CScriptVar *ref(); ///< Add reference to this variable - void unref(); ///< Remove a reference, and delete this variable if required - int getRefs(); ///< Get the number of references to this script variable -protected: - int refs; ///< The number of references held to this - used for garbage collection - - std::string data; ///< The contents of this variable if it is a string - long intData; ///< The contents of this variable if it is an int - double doubleData; ///< The contents of this variable if it is a double - int flags; ///< the flags determine the type of the variable - int/double/string/etc - JSCallback jsCallback; ///< Callback for native functions - void *jsCallbackUserData; ///< user data passed as second argument to native functions - - void init(); ///< initialisation of data members - - /** Copy the basic data and flags from the variable given, with no - * children. Should be used internally only - by copyValue and deepCopy */ - void copySimpleData(CScriptVar *val); - - friend class CTinyJS; -}; - -class CTinyJS { -public: - CTinyJS(); - ~CTinyJS(); - - void execute(const std::string &code); - /** Evaluate the given code and return a link to a javascript object, - * useful for (dangerous) JSON parsing. If nothing to return, will return - * 'undefined' variable type. CScriptVarLink is returned as this will - * automatically unref the result as it goes out of scope. If you want to - * keep it, you must use ref() and unref() */ - CScriptVarLink evaluateComplex(const std::string &code); - /** Evaluate the given code and return a string. If nothing to return, will return - * 'undefined' */ - std::string evaluate(const std::string &code); - - /// add a native function to be called from TinyJS - /** example: - \code - void scRandInt(CScriptVar *c, void *userdata) { ... } - tinyJS->addNative("function randInt(min, max)", scRandInt, 0); - \endcode - - or - - \code - void scSubstring(CScriptVar *c, void *userdata) { ... } - tinyJS->addNative("function String.substring(lo, hi)", scSubstring, 0); - \endcode - */ - void addNative(const std::string &funcDesc, JSCallback ptr, void *userdata); - - /// Get the given variable specified by a path (var1.var2.etc), or return 0 - CScriptVar *getScriptVariable(const std::string &path); - /// Get the value of the given variable, or return 0 - const std::string *getVariable(const std::string &path); - /// set the value of the given variable, return trur if it exists and gets set - bool setVariable(const std::string &path, const std::string &varData); - - /// Send all variables to stdout - void trace(); - - CScriptVar *root; /// root of symbol table -private: - CScriptLex *l; /// current lexer - std::vector scopes; /// stack of scopes when parsing -#ifdef TINYJS_CALL_STACK - std::vector call_stack; /// Names of places called so we can show when erroring -#endif - - CScriptVar *stringClass; /// Built in string class - CScriptVar *objectClass; /// Built in object class - CScriptVar *arrayClass; /// Built in array class - - // parsing - in order of precedence - CScriptVarLink *functionCall(bool &execute, CScriptVarLink *function, CScriptVar *parent); - CScriptVarLink *factor(bool &execute); - CScriptVarLink *unary(bool &execute); - CScriptVarLink *term(bool &execute); - CScriptVarLink *expression(bool &execute); - CScriptVarLink *shift(bool &execute); - CScriptVarLink *condition(bool &execute); - CScriptVarLink *logic(bool &execute); - CScriptVarLink *ternary(bool &execute); - CScriptVarLink *base(bool &execute); - void block(bool &execute); - void statement(bool &execute); - // parsing utility functions - CScriptVarLink *parseFunctionDefinition(); - void parseFunctionArguments(CScriptVar *funcVar); - - CScriptVarLink *findInScopes(const std::string &childName); ///< Finds a child, looking recursively up the scopes - /// Look up in any parent classes of the given object - CScriptVarLink *findInParentClasses(CScriptVar *object, const std::string &name); -}; - -#endif diff --git a/.svn/pristine/5b/5bbe0a6640afdc5794427c8808a7c20ca8d2c306.svn-base b/.svn/pristine/5b/5bbe0a6640afdc5794427c8808a7c20ca8d2c306.svn-base deleted file mode 100644 index b4179ea..0000000 --- a/.svn/pristine/5b/5bbe0a6640afdc5794427c8808a7c20ca8d2c306.svn-base +++ /dev/null @@ -1,13 +0,0 @@ -function Foo() { - this.__proto__ = Foo.prototype; -} -Foo.prototype = { value : function() { return this.x + this.y; } }; - -var a = { __proto__ : Foo.prototype, x: 1, y: 2 }; -var b = new Foo(); -b.x = 2; -b.y = 3; - -var result1 = a.value(); -var result2 = b.value(); -result = result1==3 && result2==5; diff --git a/.svn/pristine/5c/5cd03cc0ba37bfc0e8507e4dd6b307d29ebd729b.svn-base b/.svn/pristine/5c/5cd03cc0ba37bfc0e8507e4dd6b307d29ebd729b.svn-base deleted file mode 100644 index cebaa85..0000000 --- a/.svn/pristine/5c/5cd03cc0ba37bfc0e8507e4dd6b307d29ebd729b.svn-base +++ /dev/null @@ -1,3 +0,0 @@ -// comparison -var a = 42; -result = a==42; diff --git a/.svn/pristine/5c/5cd5492625fc746d81349b8a4cbdf4299fd7183b.svn-base b/.svn/pristine/5c/5cd5492625fc746d81349b8a4cbdf4299fd7183b.svn-base deleted file mode 100644 index 99ef7ff..0000000 --- a/.svn/pristine/5c/5cd5492625fc746d81349b8a4cbdf4299fd7183b.svn-base +++ /dev/null @@ -1,10 +0,0 @@ -/* Javascript eval */ - -// 42-tiny-js change begin ---> -// in JavaScript eval is not JSON.parse -// use parentheses or JSON.parse instead -//myfoo = eval("{ foo: 42 }"); -myfoo = eval("("+"{ foo: 42 }"+")"); -//<--- 42-tiny-js change end - -result = eval("4*10+2")==42 && myfoo.foo==42; diff --git a/.svn/pristine/5d/5db4ff612674ecf806062137f28793f303e9031a.svn-base b/.svn/pristine/5d/5db4ff612674ecf806062137f28793f303e9031a.svn-base deleted file mode 100644 index ea216c8..0000000 --- a/.svn/pristine/5d/5db4ff612674ecf806062137f28793f303e9031a.svn-base +++ /dev/null @@ -1,37 +0,0 @@ -/* - * TinyJS - * - * A single-file Javascript-alike engine - * - * Authored By Gordon Williams - * - * Copyright (C) 2009 Pur3 Ltd - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is furnished to do - * so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef TINYJS_FUNCTIONS_H -#define TINYJS_FUNCTIONS_H - -#include "TinyJS.h" - -/// Register useful functions with the TinyJS interpreter -extern void registerFunctions(CTinyJS *tinyJS); - -#endif diff --git a/.svn/pristine/5e/5ea0f09eaad0b7500c98a5d824bde54e4ab0a9ba.svn-base b/.svn/pristine/5e/5ea0f09eaad0b7500c98a5d824bde54e4ab0a9ba.svn-base deleted file mode 100644 index 1432de0..0000000 --- a/.svn/pristine/5e/5ea0f09eaad0b7500c98a5d824bde54e4ab0a9ba.svn-base +++ /dev/null @@ -1,18 +0,0 @@ -// references with functions - -var a = 42; -var b = []; -b[0] = 43; - -function foo(myarray) { - myarray[0]++; -} - -function bar(myvalue) { - myvalue++; -} - -foo(b); -bar(a); - -result = a==42 && b[0]==44; diff --git a/.svn/pristine/62/6253d0e0bdcc36df327e3e92379ae5b0316d73b6.svn-base b/.svn/pristine/62/6253d0e0bdcc36df327e3e92379ae5b0316d73b6.svn-base deleted file mode 100644 index 448eefb..0000000 --- a/.svn/pristine/62/6253d0e0bdcc36df327e3e92379ae5b0316d73b6.svn-base +++ /dev/null @@ -1,2190 +0,0 @@ -/* - * TinyJS - * - * A single-file Javascript-alike engine - * - * Authored By Gordon Williams - * - * Copyright (C) 2009 Pur3 Ltd - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is furnished to do - * so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* Version 0.1 : (gw) First published on Google Code - Version 0.11 : Making sure the 'root' variable never changes - 'symbol_base' added for the current base of the sybmbol table - Version 0.12 : Added findChildOrCreate, changed string passing to use references - Fixed broken string encoding in getJSString() - Removed getInitCode and added getJSON instead - Added nil - Added rough JSON parsing - Improved example app - Version 0.13 : Added tokenEnd/tokenLastEnd to lexer to avoid parsing whitespace - Ability to define functions without names - Can now do "var mine = function(a,b) { ... };" - Slightly better 'trace' function - Added findChildOrCreateByPath function - Added simple test suite - Added skipping of blocks when not executing - Version 0.14 : Added parsing of more number types - Added parsing of string defined with ' - Changed nil to null as per spec, added 'undefined' - Now set variables with the correct scope, and treat unknown - as 'undefined' rather than failing - Added proper (I hope) handling of null and undefined - Added === check - Version 0.15 : Fix for possible memory leaks - Version 0.16 : Removal of un-needed findRecursive calls - symbol_base removed and replaced with 'scopes' stack - Added reference counting a proper tree structure - (Allowing pass by reference) - Allowed JSON output to output IDs, not strings - Added get/set for array indices - Changed Callbacks to include user data pointer - Added some support for objects - Added more Java-esque builtin functions - Version 0.17 : Now we don't deepCopy the parent object of the class - Added JSON.stringify and eval() - Nicer JSON indenting - Fixed function output in JSON - Added evaluateComplex - Fixed some reentrancy issues with evaluate/execute - Version 0.18 : Fixed some issues with code being executed when it shouldn't - Version 0.19 : Added array.length - Changed '__parent' to 'prototype' to bring it more in line with javascript - Version 0.20 : Added '%' operator - Version 0.21 : Added array type - String.length() no more - now String.length - Added extra constructors to reduce confusion - Fixed checks against undefined - Version 0.22 : First part of ardi's changes: - sprintf -> sprintf_s - extra tokens parsed - array memory leak fixed - Fixed memory leak in evaluateComplex - Fixed memory leak in FOR loops - Fixed memory leak for unary minus - Version 0.23 : Allowed evaluate[Complex] to take in semi-colon separated - statements and then only return the value from the last one. - Also checks to make sure *everything* was parsed. - Ints + doubles are now stored in binary form (faster + more precise) - Version 0.24 : More useful error for maths ops - Don't dump everything on a match error. - Version 0.25 : Better string escaping - Version 0.26 : Add CScriptVar::equals - Add built-in array functions - Version 0.27 : Added OZLB's TinyJS.setVariable (with some tweaks) - Added OZLB's Maths Functions - Version 0.28 : Ternary operator - Rudimentary call stack on error - Added String Character functions - Added shift operators - Version 0.29 : Added new object via functions - Fixed getString() for double on some platforms - Version 0.30 : Rlyeh Mario's patch for Math Functions on VC++ - Version 0.31 : Add exec() to TinyJS functions - Now print quoted JSON that can be read by PHP/Python parsers - Fixed postfix increment operator - Version 0.32 : Fixed Math.randInt on 32 bit PCs, where it was broken - Version 0.33 : Fixed Memory leak + brokenness on === comparison - - NOTE: - Constructing an array with an initial length 'Array(5)' doesn't work - Recursive loops of data such as a.foo = a; fail to be garbage collected - length variable cannot be set - The postfix increment operator returns the current value, not the previous as it should. - There is no prefix increment operator - Arrays are implemented as a linked list - hence a lookup time is O(n) - - TODO: - Utility va-args style function in TinyJS for executing a function directly - Merge the parsing of expressions/statements so eval("statement") works like we'd expect. - Move 'shift' implementation into mathsOp - - */ - -#include "TinyJS.h" -#include - -#define ASSERT(X) assert(X) -/* Frees the given link IF it isn't owned by anything else */ -#define CLEAN(x) { CScriptVarLink *__v = x; if (__v && !__v->owned) { delete __v; } } -/* Create a LINK to point to VAR and free the old link. - * BUT this is more clever - it tries to keep the old link if it's not owned to save allocations */ -#define CREATE_LINK(LINK, VAR) { if (!LINK || LINK->owned) LINK = new CScriptVarLink(VAR); else LINK->replaceWith(VAR); } - -#include -#include -#include -#include -#include - -using namespace std; - -#ifdef _WIN32 -#ifdef _DEBUG - #ifndef DBG_NEW - #define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ ) - #define new DBG_NEW - #endif -#endif -#endif - -#ifdef __GNUC__ -#define vsprintf_s vsnprintf -#define sprintf_s snprintf -#define _strdup strdup -#endif - -// ----------------------------------------------------------------------------------- Memory Debug - -#define DEBUG_MEMORY 0 - -#if DEBUG_MEMORY - -vector allocatedVars; -vector allocatedLinks; - -void mark_allocated(CScriptVar *v) { - allocatedVars.push_back(v); -} - -void mark_deallocated(CScriptVar *v) { - for (size_t i=0;igetRefs()); - allocatedVars[i]->trace(" "); - } - for (size_t i=0;iname.c_str(), allocatedLinks[i]->var->getRefs()); - allocatedLinks[i]->var->trace(" "); - } - allocatedVars.clear(); - allocatedLinks.clear(); -} -#endif - -// ----------------------------------------------------------------------------------- Utils -bool isWhitespace(char ch) { - return (ch==' ') || (ch=='\t') || (ch=='\n') || (ch=='\r'); -} - -bool isNumeric(char ch) { - return (ch>='0') && (ch<='9'); -} -bool isNumber(const string &str) { - for (size_t i=0;i='0') && (ch<='9')) || - ((ch>='a') && (ch<='f')) || - ((ch>='A') && (ch<='F')); -} -bool isAlpha(char ch) { - return ((ch>='a') && (ch<='z')) || ((ch>='A') && (ch<='Z')) || ch=='_'; -} - -bool isIDString(const char *s) { - if (!isAlpha(*s)) - return false; - while (*s) { - if (!(isAlpha(*s) || isNumeric(*s))) - return false; - s++; - } - return true; -} - -void replace(string &str, char textFrom, const char *textTo) { - int sLen = strlen(textTo); - size_t p = str.find(textFrom); - while (p != string::npos) { - str = str.substr(0, p) + textTo + str.substr(p+1); - p = str.find(textFrom, p+sLen); - } -} - -/// convert the given string into a quoted string suitable for javascript -std::string getJSString(const std::string &str) { - std::string nStr = str; - for (size_t i=0;i127) { - char buffer[5]; - sprintf_s(buffer, 5, "\\x%02X", nCh); - replaceWith = buffer; - } else replace=false; - } - } - - if (replace) { - nStr = nStr.substr(0, i) + replaceWith + nStr.substr(i+1); - i += strlen(replaceWith)-1; - } - } - return "\"" + nStr + "\""; -} - -/** Is the string alphanumeric */ -bool isAlphaNum(const std::string &str) { - if (str.size()==0) return true; - if (!isAlpha(str[0])) return false; - for (size_t i=0;idata; - dataOwned = false; - dataStart = startChar; - dataEnd = endChar; - reset(); -} - -CScriptLex::~CScriptLex(void) -{ - if (dataOwned) - free((void*)data); -} - -void CScriptLex::reset() { - dataPos = dataStart; - tokenStart = 0; - tokenEnd = 0; - tokenLastEnd = 0; - tk = 0; - tkStr = ""; - getNextCh(); - getNextCh(); - getNextToken(); -} - -void CScriptLex::match(int expected_tk) { - if (tk!=expected_tk) { - ostringstream errorString; - errorString << "Got " << getTokenStr(tk) << " expected " << getTokenStr(expected_tk) - << " at " << getPosition(tokenStart); - throw new CScriptException(errorString.str()); - } - getNextToken(); -} - -string CScriptLex::getTokenStr(int token) { - if (token>32 && token<128) { - char buf[4] = "' '"; - buf[1] = (char)token; - return buf; - } - switch (token) { - case LEX_EOF : return "EOF"; - case LEX_ID : return "ID"; - case LEX_INT : return "INT"; - case LEX_FLOAT : return "FLOAT"; - case LEX_STR : return "STRING"; - case LEX_EQUAL : return "=="; - case LEX_TYPEEQUAL : return "==="; - case LEX_NEQUAL : return "!="; - case LEX_NTYPEEQUAL : return "!=="; - case LEX_LEQUAL : return "<="; - case LEX_LSHIFT : return "<<"; - case LEX_LSHIFTEQUAL : return "<<="; - case LEX_GEQUAL : return ">="; - case LEX_RSHIFT : return ">>"; - case LEX_RSHIFTUNSIGNED : return ">>"; - case LEX_RSHIFTEQUAL : return ">>="; - case LEX_PLUSEQUAL : return "+="; - case LEX_MINUSEQUAL : return "-="; - case LEX_PLUSPLUS : return "++"; - case LEX_MINUSMINUS : return "--"; - case LEX_ANDEQUAL : return "&="; - case LEX_ANDAND : return "&&"; - case LEX_OREQUAL : return "|="; - case LEX_OROR : return "||"; - case LEX_XOREQUAL : return "^="; - // reserved words - case LEX_R_IF : return "if"; - case LEX_R_ELSE : return "else"; - case LEX_R_DO : return "do"; - case LEX_R_WHILE : return "while"; - case LEX_R_FOR : return "for"; - case LEX_R_BREAK : return "break"; - case LEX_R_CONTINUE : return "continue"; - case LEX_R_FUNCTION : return "function"; - case LEX_R_RETURN : return "return"; - case LEX_R_VAR : return "var"; - case LEX_R_TRUE : return "true"; - case LEX_R_FALSE : return "false"; - case LEX_R_NULL : return "null"; - case LEX_R_UNDEFINED : return "undefined"; - case LEX_R_NEW : return "new"; - } - - ostringstream msg; - msg << "?[" << token << "]"; - return msg.str(); -} - -void CScriptLex::getNextCh() { - currCh = nextCh; - if (dataPos < dataEnd) - nextCh = data[dataPos]; - else - nextCh = 0; - dataPos++; -} - -void CScriptLex::getNextToken() { - tk = LEX_EOF; - tkStr.clear(); - while (currCh && isWhitespace(currCh)) getNextCh(); - // newline comments - if (currCh=='/' && nextCh=='/') { - while (currCh && currCh!='\n') getNextCh(); - getNextCh(); - getNextToken(); - return; - } - // block comments - if (currCh=='/' && nextCh=='*') { - while (currCh && (currCh!='*' || nextCh!='/')) getNextCh(); - getNextCh(); - getNextCh(); - getNextToken(); - return; - } - // record beginning of this token - tokenStart = dataPos-2; - // tokens - if (isAlpha(currCh)) { // IDs - while (isAlpha(currCh) || isNumeric(currCh)) { - tkStr += currCh; - getNextCh(); - } - tk = LEX_ID; - if (tkStr=="if") tk = LEX_R_IF; - else if (tkStr=="else") tk = LEX_R_ELSE; - else if (tkStr=="do") tk = LEX_R_DO; - else if (tkStr=="while") tk = LEX_R_WHILE; - else if (tkStr=="for") tk = LEX_R_FOR; - else if (tkStr=="break") tk = LEX_R_BREAK; - else if (tkStr=="continue") tk = LEX_R_CONTINUE; - else if (tkStr=="function") tk = LEX_R_FUNCTION; - else if (tkStr=="return") tk = LEX_R_RETURN; - else if (tkStr=="var") tk = LEX_R_VAR; - else if (tkStr=="true") tk = LEX_R_TRUE; - else if (tkStr=="false") tk = LEX_R_FALSE; - else if (tkStr=="null") tk = LEX_R_NULL; - else if (tkStr=="undefined") tk = LEX_R_UNDEFINED; - else if (tkStr=="new") tk = LEX_R_NEW; - } else if (isNumeric(currCh)) { // Numbers - bool isHex = false; - if (currCh=='0') { tkStr += currCh; getNextCh(); } - if (currCh=='x') { - isHex = true; - tkStr += currCh; getNextCh(); - } - tk = LEX_INT; - while (isNumeric(currCh) || (isHex && isHexadecimal(currCh))) { - tkStr += currCh; - getNextCh(); - } - if (!isHex && currCh=='.') { - tk = LEX_FLOAT; - tkStr += '.'; - getNextCh(); - while (isNumeric(currCh)) { - tkStr += currCh; - getNextCh(); - } - } - // do fancy e-style floating point - if (!isHex && (currCh=='e'||currCh=='E')) { - tk = LEX_FLOAT; - tkStr += currCh; getNextCh(); - if (currCh=='-') { tkStr += currCh; getNextCh(); } - while (isNumeric(currCh)) { - tkStr += currCh; getNextCh(); - } - } - } else if (currCh=='"') { - // strings... - getNextCh(); - while (currCh && currCh!='"') { - if (currCh == '\\') { - getNextCh(); - switch (currCh) { - case 'n' : tkStr += '\n'; break; - case '"' : tkStr += '"'; break; - case '\\' : tkStr += '\\'; break; - default: tkStr += currCh; - } - } else { - tkStr += currCh; - } - getNextCh(); - } - getNextCh(); - tk = LEX_STR; - } else if (currCh=='\'') { - // strings again... - getNextCh(); - while (currCh && currCh!='\'') { - if (currCh == '\\') { - getNextCh(); - switch (currCh) { - case 'n' : tkStr += '\n'; break; - case 'a' : tkStr += '\a'; break; - case 'r' : tkStr += '\r'; break; - case 't' : tkStr += '\t'; break; - case '\'' : tkStr += '\''; break; - case '\\' : tkStr += '\\'; break; - case 'x' : { // hex digits - char buf[3] = "??"; - getNextCh(); buf[0] = currCh; - getNextCh(); buf[1] = currCh; - tkStr += (char)strtol(buf,0,16); - } break; - default: if (currCh>='0' && currCh<='7') { - // octal digits - char buf[4] = "???"; - buf[0] = currCh; - getNextCh(); buf[1] = currCh; - getNextCh(); buf[2] = currCh; - tkStr += (char)strtol(buf,0,8); - } else - tkStr += currCh; - } - } else { - tkStr += currCh; - } - getNextCh(); - } - getNextCh(); - tk = LEX_STR; - } else { - // single chars - tk = currCh; - if (currCh) getNextCh(); - if (tk=='=' && currCh=='=') { // == - tk = LEX_EQUAL; - getNextCh(); - if (currCh=='=') { // === - tk = LEX_TYPEEQUAL; - getNextCh(); - } - } else if (tk=='!' && currCh=='=') { // != - tk = LEX_NEQUAL; - getNextCh(); - if (currCh=='=') { // !== - tk = LEX_NTYPEEQUAL; - getNextCh(); - } - } else if (tk=='<' && currCh=='=') { - tk = LEX_LEQUAL; - getNextCh(); - } else if (tk=='<' && currCh=='<') { - tk = LEX_LSHIFT; - getNextCh(); - if (currCh=='=') { // <<= - tk = LEX_LSHIFTEQUAL; - getNextCh(); - } - } else if (tk=='>' && currCh=='=') { - tk = LEX_GEQUAL; - getNextCh(); - } else if (tk=='>' && currCh=='>') { - tk = LEX_RSHIFT; - getNextCh(); - if (currCh=='=') { // >>= - tk = LEX_RSHIFTEQUAL; - getNextCh(); - } else if (currCh=='>') { // >>> - tk = LEX_RSHIFTUNSIGNED; - getNextCh(); - } - } else if (tk=='+' && currCh=='=') { - tk = LEX_PLUSEQUAL; - getNextCh(); - } else if (tk=='-' && currCh=='=') { - tk = LEX_MINUSEQUAL; - getNextCh(); - } else if (tk=='+' && currCh=='+') { - tk = LEX_PLUSPLUS; - getNextCh(); - } else if (tk=='-' && currCh=='-') { - tk = LEX_MINUSMINUS; - getNextCh(); - } else if (tk=='&' && currCh=='=') { - tk = LEX_ANDEQUAL; - getNextCh(); - } else if (tk=='&' && currCh=='&') { - tk = LEX_ANDAND; - getNextCh(); - } else if (tk=='|' && currCh=='=') { - tk = LEX_OREQUAL; - getNextCh(); - } else if (tk=='|' && currCh=='|') { - tk = LEX_OROR; - getNextCh(); - } else if (tk=='^' && currCh=='=') { - tk = LEX_XOREQUAL; - getNextCh(); - } - } - /* This isn't quite right yet */ - tokenLastEnd = tokenEnd; - tokenEnd = dataPos-3; -} - -string CScriptLex::getSubString(int lastPosition) { - int lastCharIdx = tokenLastEnd+1; - if (lastCharIdx < dataEnd) { - /* save a memory alloc by using our data array to create the - substring */ - char old = data[lastCharIdx]; - data[lastCharIdx] = 0; - std::string value = &data[lastPosition]; - data[lastCharIdx] = old; - return value; - } else { - return std::string(&data[lastPosition]); - } -} - - -CScriptLex *CScriptLex::getSubLex(int lastPosition) { - int lastCharIdx = tokenLastEnd+1; - if (lastCharIdx < dataEnd) - return new CScriptLex(this, lastPosition, lastCharIdx); - else - return new CScriptLex(this, lastPosition, dataEnd ); -} - -string CScriptLex::getPosition(int pos) { - if (pos<0) pos=tokenLastEnd; - int line = 1,col = 1; - for (int i=0;iname = name; - this->nextSibling = 0; - this->prevSibling = 0; - this->var = var->ref(); - this->owned = false; -} - -CScriptVarLink::CScriptVarLink(const CScriptVarLink &link) { - // Copy constructor -#if DEBUG_MEMORY - mark_allocated(this); -#endif - this->name = link.name; - this->nextSibling = 0; - this->prevSibling = 0; - this->var = link.var->ref(); - this->owned = false; -} - -CScriptVarLink::~CScriptVarLink() { -#if DEBUG_MEMORY - mark_deallocated(this); -#endif - var->unref(); -} - -void CScriptVarLink::replaceWith(CScriptVar *newVar) { - CScriptVar *oldVar = var; - var = newVar->ref(); - oldVar->unref(); -} - -void CScriptVarLink::replaceWith(CScriptVarLink *newVar) { - if (newVar) - replaceWith(newVar->var); - else - replaceWith(new CScriptVar()); -} - -int CScriptVarLink::getIntName() { - return atoi(name.c_str()); -} -void CScriptVarLink::setIntName(int n) { - char sIdx[64]; - sprintf_s(sIdx, sizeof(sIdx), "%d", n); - name = sIdx; -} - -// ----------------------------------------------------------------------------------- CSCRIPTVAR - -CScriptVar::CScriptVar() { - refs = 0; -#if DEBUG_MEMORY - mark_allocated(this); -#endif - init(); - flags = SCRIPTVAR_UNDEFINED; -} - -CScriptVar::CScriptVar(const string &str) { - refs = 0; -#if DEBUG_MEMORY - mark_allocated(this); -#endif - init(); - flags = SCRIPTVAR_STRING; - data = str; -} - - -CScriptVar::CScriptVar(const string &varData, int varFlags) { - refs = 0; -#if DEBUG_MEMORY - mark_allocated(this); -#endif - init(); - flags = varFlags; - if (varFlags & SCRIPTVAR_INTEGER) { - intData = strtol(varData.c_str(),0,0); - } else if (varFlags & SCRIPTVAR_DOUBLE) { - doubleData = strtod(varData.c_str(),0); - } else - data = varData; -} - -CScriptVar::CScriptVar(double val) { - refs = 0; -#if DEBUG_MEMORY - mark_allocated(this); -#endif - init(); - setDouble(val); -} - -CScriptVar::CScriptVar(int val) { - refs = 0; -#if DEBUG_MEMORY - mark_allocated(this); -#endif - init(); - setInt(val); -} - -CScriptVar::~CScriptVar(void) { -#if DEBUG_MEMORY - mark_deallocated(this); -#endif - removeAllChildren(); -} - -void CScriptVar::init() { - firstChild = 0; - lastChild = 0; - flags = 0; - jsCallback = 0; - jsCallbackUserData = 0; - data = TINYJS_BLANK_DATA; - intData = 0; - doubleData = 0; -} - -CScriptVar *CScriptVar::getReturnVar() { - return getParameter(TINYJS_RETURN_VAR); -} - -void CScriptVar::setReturnVar(CScriptVar *var) { - findChildOrCreate(TINYJS_RETURN_VAR)->replaceWith(var); -} - - -CScriptVar *CScriptVar::getParameter(const std::string &name) { - return findChildOrCreate(name)->var; -} - -CScriptVarLink *CScriptVar::findChild(const string &childName) { - CScriptVarLink *v = firstChild; - while (v) { - if (v->name.compare(childName)==0) - return v; - v = v->nextSibling; - } - return 0; -} - -CScriptVarLink *CScriptVar::findChildOrCreate(const string &childName, int varFlags) { - CScriptVarLink *l = findChild(childName); - if (l) return l; - - return addChild(childName, new CScriptVar(TINYJS_BLANK_DATA, varFlags)); -} - -CScriptVarLink *CScriptVar::findChildOrCreateByPath(const std::string &path) { - size_t p = path.find('.'); - if (p == string::npos) - return findChildOrCreate(path); - - return findChildOrCreate(path.substr(0,p), SCRIPTVAR_OBJECT)->var-> - findChildOrCreateByPath(path.substr(p+1)); -} - -CScriptVarLink *CScriptVar::addChild(const std::string &childName, CScriptVar *child) { - if (isUndefined()) { - flags = SCRIPTVAR_OBJECT; - } - // if no child supplied, create one - if (!child) - child = new CScriptVar(); - - CScriptVarLink *link = new CScriptVarLink(child, childName); - link->owned = true; - if (lastChild) { - lastChild->nextSibling = link; - link->prevSibling = lastChild; - lastChild = link; - } else { - firstChild = link; - lastChild = link; - } - return link; -} - -CScriptVarLink *CScriptVar::addChildNoDup(const std::string &childName, CScriptVar *child) { - // if no child supplied, create one - if (!child) - child = new CScriptVar(); - - CScriptVarLink *v = findChild(childName); - if (v) { - v->replaceWith(child); - } else { - v = addChild(childName, child); - } - - return v; -} - -void CScriptVar::removeChild(CScriptVar *child) { - CScriptVarLink *link = firstChild; - while (link) { - if (link->var == child) - break; - link = link->nextSibling; - } - ASSERT(link); - removeLink(link); -} - -void CScriptVar::removeLink(CScriptVarLink *link) { - if (!link) return; - if (link->nextSibling) - link->nextSibling->prevSibling = link->prevSibling; - if (link->prevSibling) - link->prevSibling->nextSibling = link->nextSibling; - if (lastChild == link) - lastChild = link->prevSibling; - if (firstChild == link) - firstChild = link->nextSibling; - delete link; -} - -void CScriptVar::removeAllChildren() { - CScriptVarLink *c = firstChild; - while (c) { - CScriptVarLink *t = c->nextSibling; - delete c; - c = t; - } - firstChild = 0; - lastChild = 0; -} - -CScriptVar *CScriptVar::getArrayIndex(int idx) { - char sIdx[64]; - sprintf_s(sIdx, sizeof(sIdx), "%d", idx); - CScriptVarLink *link = findChild(sIdx); - if (link) return link->var; - else return new CScriptVar(TINYJS_BLANK_DATA, SCRIPTVAR_NULL); // undefined -} - -void CScriptVar::setArrayIndex(int idx, CScriptVar *value) { - char sIdx[64]; - sprintf_s(sIdx, sizeof(sIdx), "%d", idx); - CScriptVarLink *link = findChild(sIdx); - - if (link) { - if (value->isUndefined()) - removeLink(link); - else - link->replaceWith(value); - } else { - if (!value->isUndefined()) - addChild(sIdx, value); - } -} - -int CScriptVar::getArrayLength() { - int highest = -1; - if (!isArray()) return 0; - - CScriptVarLink *link = firstChild; - while (link) { - if (isNumber(link->name)) { - int val = atoi(link->name.c_str()); - if (val > highest) highest = val; - } - link = link->nextSibling; - } - return highest+1; -} - -int CScriptVar::getChildren() { - int n = 0; - CScriptVarLink *link = firstChild; - while (link) { - n++; - link = link->nextSibling; - } - return n; -} - -int CScriptVar::getInt() { - /* strtol understands about hex and octal */ - if (isInt()) return intData; - if (isNull()) return 0; - if (isUndefined()) return 0; - if (isDouble()) return (int)doubleData; - return 0; -} - -double CScriptVar::getDouble() { - if (isDouble()) return doubleData; - if (isInt()) return intData; - if (isNull()) return 0; - if (isUndefined()) return 0; - return 0; /* or NaN? */ -} - -const string &CScriptVar::getString() { - /* Because we can't return a string that is generated on demand. - * I should really just use char* :) */ - static string s_null = "null"; - static string s_undefined = "undefined"; - if (isInt()) { - char buffer[32]; - sprintf_s(buffer, sizeof(buffer), "%ld", intData); - data = buffer; - return data; - } - if (isDouble()) { - char buffer[32]; - sprintf_s(buffer, sizeof(buffer), "%f", doubleData); - data = buffer; - return data; - } - if (isNull()) return s_null; - if (isUndefined()) return s_undefined; - // are we just a string here? - return data; -} - -void CScriptVar::setInt(int val) { - flags = (flags&~SCRIPTVAR_VARTYPEMASK) | SCRIPTVAR_INTEGER; - intData = val; - doubleData = 0; - data = TINYJS_BLANK_DATA; -} - -void CScriptVar::setDouble(double val) { - flags = (flags&~SCRIPTVAR_VARTYPEMASK) | SCRIPTVAR_DOUBLE; - doubleData = val; - intData = 0; - data = TINYJS_BLANK_DATA; -} - -void CScriptVar::setString(const string &str) { - // name sure it's not still a number or integer - flags = (flags&~SCRIPTVAR_VARTYPEMASK) | SCRIPTVAR_STRING; - data = str; - intData = 0; - doubleData = 0; -} - -void CScriptVar::setUndefined() { - // name sure it's not still a number or integer - flags = (flags&~SCRIPTVAR_VARTYPEMASK) | SCRIPTVAR_UNDEFINED; - data = TINYJS_BLANK_DATA; - intData = 0; - doubleData = 0; - removeAllChildren(); -} - -void CScriptVar::setArray() { - // name sure it's not still a number or integer - flags = (flags&~SCRIPTVAR_VARTYPEMASK) | SCRIPTVAR_ARRAY; - data = TINYJS_BLANK_DATA; - intData = 0; - doubleData = 0; - removeAllChildren(); -} - -bool CScriptVar::equals(CScriptVar *v) { - CScriptVar *resV = mathsOp(v, LEX_EQUAL); - bool res = resV->getBool(); - delete resV; - return res; -} - -CScriptVar *CScriptVar::mathsOp(CScriptVar *b, int op) { - CScriptVar *a = this; - // Type equality check - if (op == LEX_TYPEEQUAL || op == LEX_NTYPEEQUAL) { - // check type first, then call again to check data - bool eql = ((a->flags & SCRIPTVAR_VARTYPEMASK) == - (b->flags & SCRIPTVAR_VARTYPEMASK)); - if (eql) { - CScriptVar *contents = a->mathsOp(b, LEX_EQUAL); - if (!contents->getBool()) eql = false; - if (!contents->refs) delete contents; - } - ; - if (op == LEX_TYPEEQUAL) - return new CScriptVar(eql); - else - return new CScriptVar(!eql); - } - // do maths... - if (a->isUndefined() && b->isUndefined()) { - if (op == LEX_EQUAL) return new CScriptVar(true); - else if (op == LEX_NEQUAL) return new CScriptVar(false); - else return new CScriptVar(); // undefined - } else if ((a->isNumeric() || a->isUndefined()) && - (b->isNumeric() || b->isUndefined())) { - if (!a->isDouble() && !b->isDouble()) { - // use ints - int da = a->getInt(); - int db = b->getInt(); - switch (op) { - case '+': return new CScriptVar(da+db); - case '-': return new CScriptVar(da-db); - case '*': return new CScriptVar(da*db); - case '/': return new CScriptVar(da/db); - case '&': return new CScriptVar(da&db); - case '|': return new CScriptVar(da|db); - case '^': return new CScriptVar(da^db); - case '%': return new CScriptVar(da%db); - case LEX_EQUAL: return new CScriptVar(da==db); - case LEX_NEQUAL: return new CScriptVar(da!=db); - case '<': return new CScriptVar(da': return new CScriptVar(da>db); - case LEX_GEQUAL: return new CScriptVar(da>=db); - default: throw new CScriptException("Operation "+CScriptLex::getTokenStr(op)+" not supported on the Int datatype"); - } - } else { - // use doubles - double da = a->getDouble(); - double db = b->getDouble(); - switch (op) { - case '+': return new CScriptVar(da+db); - case '-': return new CScriptVar(da-db); - case '*': return new CScriptVar(da*db); - case '/': return new CScriptVar(da/db); - case LEX_EQUAL: return new CScriptVar(da==db); - case LEX_NEQUAL: return new CScriptVar(da!=db); - case '<': return new CScriptVar(da': return new CScriptVar(da>db); - case LEX_GEQUAL: return new CScriptVar(da>=db); - default: throw new CScriptException("Operation "+CScriptLex::getTokenStr(op)+" not supported on the Double datatype"); - } - } - } else if (a->isArray()) { - /* Just check pointers */ - switch (op) { - case LEX_EQUAL: return new CScriptVar(a==b); - case LEX_NEQUAL: return new CScriptVar(a!=b); - default: throw new CScriptException("Operation "+CScriptLex::getTokenStr(op)+" not supported on the Array datatype"); - } - } else if (a->isObject()) { - /* Just check pointers */ - switch (op) { - case LEX_EQUAL: return new CScriptVar(a==b); - case LEX_NEQUAL: return new CScriptVar(a!=b); - default: throw new CScriptException("Operation "+CScriptLex::getTokenStr(op)+" not supported on the Object datatype"); - } - } else { - string da = a->getString(); - string db = b->getString(); - // use strings - switch (op) { - case '+': return new CScriptVar(da+db, SCRIPTVAR_STRING); - case LEX_EQUAL: return new CScriptVar(da==db); - case LEX_NEQUAL: return new CScriptVar(da!=db); - case '<': return new CScriptVar(da': return new CScriptVar(da>db); - case LEX_GEQUAL: return new CScriptVar(da>=db); - default: throw new CScriptException("Operation "+CScriptLex::getTokenStr(op)+" not supported on the string datatype"); - } - } - ASSERT(0); - return 0; -} - -void CScriptVar::copySimpleData(CScriptVar *val) { - data = val->data; - intData = val->intData; - doubleData = val->doubleData; - flags = (flags & ~SCRIPTVAR_VARTYPEMASK) | (val->flags & SCRIPTVAR_VARTYPEMASK); -} - -void CScriptVar::copyValue(CScriptVar *val) { - if (val) { - copySimpleData(val); - // remove all current children - removeAllChildren(); - // copy children of 'val' - CScriptVarLink *child = val->firstChild; - while (child) { - CScriptVar *copied; - // don't copy the 'parent' object... - if (child->name != TINYJS_PROTOTYPE_CLASS) - copied = child->var->deepCopy(); - else - copied = child->var; - - addChild(child->name, copied); - - child = child->nextSibling; - } - } else { - setUndefined(); - } -} - -CScriptVar *CScriptVar::deepCopy() { - CScriptVar *newVar = new CScriptVar(); - newVar->copySimpleData(this); - // copy children - CScriptVarLink *child = firstChild; - while (child) { - CScriptVar *copied; - // don't copy the 'parent' object... - if (child->name != TINYJS_PROTOTYPE_CLASS) - copied = child->var->deepCopy(); - else - copied = child->var; - - newVar->addChild(child->name, copied); - child = child->nextSibling; - } - return newVar; -} - -void CScriptVar::trace(string indentStr, const string &name) { - TRACE("%s'%s' = '%s' %s\n", - indentStr.c_str(), - name.c_str(), - getString().c_str(), - getFlagsAsString().c_str()); - string indent = indentStr+" "; - CScriptVarLink *link = firstChild; - while (link) { - link->var->trace(indent, link->name); - link = link->nextSibling; - } -} - -string CScriptVar::getFlagsAsString() { - string flagstr = ""; - if (flags&SCRIPTVAR_FUNCTION) flagstr = flagstr + "FUNCTION "; - if (flags&SCRIPTVAR_OBJECT) flagstr = flagstr + "OBJECT "; - if (flags&SCRIPTVAR_ARRAY) flagstr = flagstr + "ARRAY "; - if (flags&SCRIPTVAR_NATIVE) flagstr = flagstr + "NATIVE "; - if (flags&SCRIPTVAR_DOUBLE) flagstr = flagstr + "DOUBLE "; - if (flags&SCRIPTVAR_INTEGER) flagstr = flagstr + "INTEGER "; - if (flags&SCRIPTVAR_STRING) flagstr = flagstr + "STRING "; - return flagstr; -} - -string CScriptVar::getParsableString() { - // Numbers can just be put in directly - if (isNumeric()) - return getString(); - if (isFunction()) { - ostringstream funcStr; - funcStr << "function ("; - // get list of parameters - CScriptVarLink *link = firstChild; - while (link) { - funcStr << link->name; - if (link->nextSibling) funcStr << ","; - link = link->nextSibling; - } - // add function body - funcStr << ") " << getString(); - return funcStr.str(); - } - // if it is a string then we quote it - if (isString()) - return getJSString(getString()); - if (isNull()) - return "null"; - return "undefined"; -} - -void CScriptVar::getJSON(ostringstream &destination, const string linePrefix) { - if (isObject()) { - string indentedLinePrefix = linePrefix+" "; - // children - handle with bracketed list - destination << "{ \n"; - CScriptVarLink *link = firstChild; - while (link) { - destination << indentedLinePrefix; - destination << getJSString(link->name); - destination << " : "; - link->var->getJSON(destination, indentedLinePrefix); - link = link->nextSibling; - if (link) { - destination << ",\n"; - } - } - destination << "\n" << linePrefix << "}"; - } else if (isArray()) { - string indentedLinePrefix = linePrefix+" "; - destination << "[\n"; - int len = getArrayLength(); - if (len>10000) len=10000; // we don't want to get stuck here! - - for (int i=0;igetJSON(destination, indentedLinePrefix); - if (iref(); - // Add built-in classes - stringClass = (new CScriptVar(TINYJS_BLANK_DATA, SCRIPTVAR_OBJECT))->ref(); - arrayClass = (new CScriptVar(TINYJS_BLANK_DATA, SCRIPTVAR_OBJECT))->ref(); - objectClass = (new CScriptVar(TINYJS_BLANK_DATA, SCRIPTVAR_OBJECT))->ref(); - root->addChild("String", stringClass); - root->addChild("Array", arrayClass); - root->addChild("Object", objectClass); -} - -CTinyJS::~CTinyJS() { - ASSERT(!l); - scopes.clear(); - stringClass->unref(); - arrayClass->unref(); - objectClass->unref(); - root->unref(); - -#if DEBUG_MEMORY - show_allocated(); -#endif -} - -void CTinyJS::trace() { - root->trace(); -} - -void CTinyJS::execute(const string &code) { - CScriptLex *oldLex = l; - vector oldScopes = scopes; - l = new CScriptLex(code); -#ifdef TINYJS_CALL_STACK - call_stack.clear(); -#endif - scopes.clear(); - scopes.push_back(root); - try { - bool execute = true; - while (l->tk) statement(execute); - } catch (CScriptException *e) { - ostringstream msg; - msg << "Error " << e->text; -#ifdef TINYJS_CALL_STACK - for (int i=(int)call_stack.size()-1;i>=0;i--) - msg << "\n" << i << ": " << call_stack.at(i); -#endif - msg << " at " << l->getPosition(); - delete l; - l = oldLex; - - throw new CScriptException(msg.str()); - } - delete l; - l = oldLex; - scopes = oldScopes; -} - -CScriptVarLink CTinyJS::evaluateComplex(const string &code) { - CScriptLex *oldLex = l; - vector oldScopes = scopes; - - l = new CScriptLex(code); -#ifdef TINYJS_CALL_STACK - call_stack.clear(); -#endif - scopes.clear(); - scopes.push_back(root); - CScriptVarLink *v = 0; - try { - bool execute = true; - do { - CLEAN(v); - v = base(execute); - if (l->tk!=LEX_EOF) l->match(';'); - } while (l->tk!=LEX_EOF); - } catch (CScriptException *e) { - ostringstream msg; - msg << "Error " << e->text; -#ifdef TINYJS_CALL_STACK - for (int i=(int)call_stack.size()-1;i>=0;i--) - msg << "\n" << i << ": " << call_stack.at(i); -#endif - msg << " at " << l->getPosition(); - delete l; - l = oldLex; - - throw new CScriptException(msg.str()); - } - delete l; - l = oldLex; - scopes = oldScopes; - - if (v) { - CScriptVarLink r = *v; - CLEAN(v); - return r; - } - // return undefined... - return CScriptVarLink(new CScriptVar()); -} - -string CTinyJS::evaluate(const string &code) { - return evaluateComplex(code).var->getString(); -} - -void CTinyJS::parseFunctionArguments(CScriptVar *funcVar) { - l->match('('); - while (l->tk!=')') { - funcVar->addChildNoDup(l->tkStr); - l->match(LEX_ID); - if (l->tk!=')') l->match(','); - } - l->match(')'); -} - -void CTinyJS::addNative(const string &funcDesc, JSCallback ptr, void *userdata) { - CScriptLex *oldLex = l; - l = new CScriptLex(funcDesc); - - CScriptVar *base = root; - - l->match(LEX_R_FUNCTION); - string funcName = l->tkStr; - l->match(LEX_ID); - /* Check for dots, we might want to do something like function String.substring ... */ - while (l->tk == '.') { - l->match('.'); - CScriptVarLink *link = base->findChild(funcName); - // if it doesn't exist, make an object class - if (!link) link = base->addChild(funcName, new CScriptVar(TINYJS_BLANK_DATA, SCRIPTVAR_OBJECT)); - base = link->var; - funcName = l->tkStr; - l->match(LEX_ID); - } - - CScriptVar *funcVar = new CScriptVar(TINYJS_BLANK_DATA, SCRIPTVAR_FUNCTION | SCRIPTVAR_NATIVE); - funcVar->setCallback(ptr, userdata); - parseFunctionArguments(funcVar); - delete l; - l = oldLex; - - base->addChild(funcName, funcVar); -} - -CScriptVarLink *CTinyJS::parseFunctionDefinition() { - // actually parse a function... - l->match(LEX_R_FUNCTION); - string funcName = TINYJS_TEMP_NAME; - /* we can have functions without names */ - if (l->tk==LEX_ID) { - funcName = l->tkStr; - l->match(LEX_ID); - } - CScriptVarLink *funcVar = new CScriptVarLink(new CScriptVar(TINYJS_BLANK_DATA, SCRIPTVAR_FUNCTION), funcName); - parseFunctionArguments(funcVar->var); - int funcBegin = l->tokenStart; - bool noexecute = false; - block(noexecute); - funcVar->var->data = l->getSubString(funcBegin); - return funcVar; -} - -/** Handle a function call (assumes we've parsed the function name and we're - * on the start bracket). 'parent' is the object that contains this method, - * if there was one (otherwise it's just a normnal function). - */ -CScriptVarLink *CTinyJS::functionCall(bool &execute, CScriptVarLink *function, CScriptVar *parent) { - if (execute) { - if (!function->var->isFunction()) { - string errorMsg = "Expecting '"; - errorMsg = errorMsg + function->name + "' to be a function"; - throw new CScriptException(errorMsg.c_str()); - } - l->match('('); - // create a new symbol table entry for execution of this function - CScriptVar *functionRoot = new CScriptVar(TINYJS_BLANK_DATA, SCRIPTVAR_FUNCTION); - if (parent) - functionRoot->addChildNoDup("this", parent); - // grab in all parameters - CScriptVarLink *v = function->var->firstChild; - while (v) { - CScriptVarLink *value = base(execute); - if (execute) { - if (value->var->isBasic()) { - // pass by value - functionRoot->addChild(v->name, value->var->deepCopy()); - } else { - // pass by reference - functionRoot->addChild(v->name, value->var); - } - } - CLEAN(value); - if (l->tk!=')') l->match(','); - v = v->nextSibling; - } - l->match(')'); - // setup a return variable - CScriptVarLink *returnVar = NULL; - // execute function! - // add the function's execute space to the symbol table so we can recurse - CScriptVarLink *returnVarLink = functionRoot->addChild(TINYJS_RETURN_VAR); - scopes.push_back(functionRoot); -#ifdef TINYJS_CALL_STACK - call_stack.push_back(function->name + " from " + l->getPosition()); -#endif - - if (function->var->isNative()) { - ASSERT(function->var->jsCallback); - function->var->jsCallback(functionRoot, function->var->jsCallbackUserData); - } else { - /* we just want to execute the block, but something could - * have messed up and left us with the wrong ScriptLex, so - * we want to be careful here... */ - CScriptException *exception = 0; - CScriptLex *oldLex = l; - CScriptLex *newLex = new CScriptLex(function->var->getString()); - l = newLex; - try { - block(execute); - // because return will probably have called this, and set execute to false - execute = true; - } catch (CScriptException *e) { - exception = e; - } - delete newLex; - l = oldLex; - - if (exception) - throw exception; - } -#ifdef TINYJS_CALL_STACK - if (!call_stack.empty()) call_stack.pop_back(); -#endif - scopes.pop_back(); - /* get the real return var before we remove it from our function */ - returnVar = new CScriptVarLink(returnVarLink->var); - functionRoot->removeLink(returnVarLink); - delete functionRoot; - if (returnVar) - return returnVar; - else - return new CScriptVarLink(new CScriptVar()); - } else { - // function, but not executing - just parse args and be done - l->match('('); - while (l->tk != ')') { - CScriptVarLink *value = base(execute); - CLEAN(value); - if (l->tk!=')') l->match(','); - } - l->match(')'); - if (l->tk == '{') { // TODO: why is this here? - block(execute); - } - /* function will be a blank scriptvarlink if we're not executing, - * so just return it rather than an alloc/free */ - return function; - } -} - -CScriptVarLink *CTinyJS::factor(bool &execute) { - if (l->tk=='(') { - l->match('('); - CScriptVarLink *a = base(execute); - l->match(')'); - return a; - } - if (l->tk==LEX_R_TRUE) { - l->match(LEX_R_TRUE); - return new CScriptVarLink(new CScriptVar(1)); - } - if (l->tk==LEX_R_FALSE) { - l->match(LEX_R_FALSE); - return new CScriptVarLink(new CScriptVar(0)); - } - if (l->tk==LEX_R_NULL) { - l->match(LEX_R_NULL); - return new CScriptVarLink(new CScriptVar(TINYJS_BLANK_DATA,SCRIPTVAR_NULL)); - } - if (l->tk==LEX_R_UNDEFINED) { - l->match(LEX_R_UNDEFINED); - return new CScriptVarLink(new CScriptVar(TINYJS_BLANK_DATA,SCRIPTVAR_UNDEFINED)); - } - if (l->tk==LEX_ID) { - CScriptVarLink *a = execute ? findInScopes(l->tkStr) : new CScriptVarLink(new CScriptVar()); - //printf("0x%08X for %s at %s\n", (unsigned int)a, l->tkStr.c_str(), l->getPosition().c_str()); - /* The parent if we're executing a method call */ - CScriptVar *parent = 0; - - if (execute && !a) { - /* Variable doesn't exist! JavaScript says we should create it - * (we won't add it here. This is done in the assignment operator)*/ - a = new CScriptVarLink(new CScriptVar(), l->tkStr); - } - l->match(LEX_ID); - while (l->tk=='(' || l->tk=='.' || l->tk=='[') { - if (l->tk=='(') { // ------------------------------------- Function Call - a = functionCall(execute, a, parent); - } else if (l->tk == '.') { // ------------------------------------- Record Access - l->match('.'); - if (execute) { - const string &name = l->tkStr; - CScriptVarLink *child = a->var->findChild(name); - if (!child) child = findInParentClasses(a->var, name); - if (!child) { - /* if we haven't found this defined yet, use the built-in - 'length' properly */ - if (a->var->isArray() && name == "length") { - int l = a->var->getArrayLength(); - child = new CScriptVarLink(new CScriptVar(l)); - } else if (a->var->isString() && name == "length") { - int l = a->var->getString().size(); - child = new CScriptVarLink(new CScriptVar(l)); - } else { - child = a->var->addChild(name); - } - } - parent = a->var; - a = child; - } - l->match(LEX_ID); - } else if (l->tk == '[') { // ------------------------------------- Array Access - l->match('['); - CScriptVarLink *index = base(execute); - l->match(']'); - if (execute) { - CScriptVarLink *child = a->var->findChildOrCreate(index->var->getString()); - parent = a->var; - a = child; - } - CLEAN(index); - } else ASSERT(0); - } - return a; - } - if (l->tk==LEX_INT || l->tk==LEX_FLOAT) { - CScriptVar *a = new CScriptVar(l->tkStr, - ((l->tk==LEX_INT)?SCRIPTVAR_INTEGER:SCRIPTVAR_DOUBLE)); - l->match(l->tk); - return new CScriptVarLink(a); - } - if (l->tk==LEX_STR) { - CScriptVar *a = new CScriptVar(l->tkStr, SCRIPTVAR_STRING); - l->match(LEX_STR); - return new CScriptVarLink(a); - } - if (l->tk=='{') { - CScriptVar *contents = new CScriptVar(TINYJS_BLANK_DATA, SCRIPTVAR_OBJECT); - /* JSON-style object definition */ - l->match('{'); - while (l->tk != '}') { - string id = l->tkStr; - // we only allow strings or IDs on the left hand side of an initialisation - if (l->tk==LEX_STR) l->match(LEX_STR); - else l->match(LEX_ID); - l->match(':'); - if (execute) { - CScriptVarLink *a = base(execute); - contents->addChild(id, a->var); - CLEAN(a); - } - // no need to clean here, as it will definitely be used - if (l->tk != '}') l->match(','); - } - - l->match('}'); - return new CScriptVarLink(contents); - } - if (l->tk=='[') { - CScriptVar *contents = new CScriptVar(TINYJS_BLANK_DATA, SCRIPTVAR_ARRAY); - /* JSON-style array */ - l->match('['); - int idx = 0; - while (l->tk != ']') { - if (execute) { - char idx_str[16]; // big enough for 2^32 - sprintf_s(idx_str, sizeof(idx_str), "%d",idx); - - CScriptVarLink *a = base(execute); - contents->addChild(idx_str, a->var); - CLEAN(a); - } - // no need to clean here, as it will definitely be used - if (l->tk != ']') l->match(','); - idx++; - } - l->match(']'); - return new CScriptVarLink(contents); - } - if (l->tk==LEX_R_FUNCTION) { - CScriptVarLink *funcVar = parseFunctionDefinition(); - if (funcVar->name != TINYJS_TEMP_NAME) - TRACE("Functions not defined at statement-level are not meant to have a name"); - return funcVar; - } - if (l->tk==LEX_R_NEW) { - // new -> create a new object - l->match(LEX_R_NEW); - const string &className = l->tkStr; - if (execute) { - CScriptVarLink *objClassOrFunc = findInScopes(className); - if (!objClassOrFunc) { - TRACE("%s is not a valid class name", className.c_str()); - return new CScriptVarLink(new CScriptVar()); - } - l->match(LEX_ID); - CScriptVar *obj = new CScriptVar(TINYJS_BLANK_DATA, SCRIPTVAR_OBJECT); - CScriptVarLink *objLink = new CScriptVarLink(obj); - if (objClassOrFunc->var->isFunction()) { - CLEAN(functionCall(execute, objClassOrFunc, obj)); - } else { - obj->addChild(TINYJS_PROTOTYPE_CLASS, objClassOrFunc->var); - if (l->tk == '(') { - l->match('('); - l->match(')'); - } - } - return objLink; - } else { - l->match(LEX_ID); - if (l->tk == '(') { - l->match('('); - l->match(')'); - } - } - } - // Nothing we can do here... just hope it's the end... - l->match(LEX_EOF); - return 0; -} - -CScriptVarLink *CTinyJS::unary(bool &execute) { - CScriptVarLink *a; - if (l->tk=='!') { - l->match('!'); // binary not - a = factor(execute); - if (execute) { - CScriptVar zero(0); - CScriptVar *res = a->var->mathsOp(&zero, LEX_EQUAL); - CREATE_LINK(a, res); - } - } else - a = factor(execute); - return a; -} - -CScriptVarLink *CTinyJS::term(bool &execute) { - CScriptVarLink *a = unary(execute); - while (l->tk=='*' || l->tk=='/' || l->tk=='%') { - int op = l->tk; - l->match(l->tk); - CScriptVarLink *b = unary(execute); - if (execute) { - CScriptVar *res = a->var->mathsOp(b->var, op); - CREATE_LINK(a, res); - } - CLEAN(b); - } - return a; -} - -CScriptVarLink *CTinyJS::expression(bool &execute) { - bool negate = false; - if (l->tk=='-') { - l->match('-'); - negate = true; - } - CScriptVarLink *a = term(execute); - if (negate) { - CScriptVar zero(0); - CScriptVar *res = zero.mathsOp(a->var, '-'); - CREATE_LINK(a, res); - } - - while (l->tk=='+' || l->tk=='-' || - l->tk==LEX_PLUSPLUS || l->tk==LEX_MINUSMINUS) { - int op = l->tk; - l->match(l->tk); - if (op==LEX_PLUSPLUS || op==LEX_MINUSMINUS) { - if (execute) { - CScriptVar one(1); - CScriptVar *res = a->var->mathsOp(&one, op==LEX_PLUSPLUS ? '+' : '-'); - CScriptVarLink *oldValue = new CScriptVarLink(a->var); - // in-place add/subtract - a->replaceWith(res); - CLEAN(a); - a = oldValue; - } - } else { - CScriptVarLink *b = term(execute); - if (execute) { - // not in-place, so just replace - CScriptVar *res = a->var->mathsOp(b->var, op); - CREATE_LINK(a, res); - } - CLEAN(b); - } - } - return a; -} - -CScriptVarLink *CTinyJS::shift(bool &execute) { - CScriptVarLink *a = expression(execute); - if (l->tk==LEX_LSHIFT || l->tk==LEX_RSHIFT || l->tk==LEX_RSHIFTUNSIGNED) { - int op = l->tk; - l->match(op); - CScriptVarLink *b = base(execute); - int shift = execute ? b->var->getInt() : 0; - CLEAN(b); - if (execute) { - if (op==LEX_LSHIFT) a->var->setInt(a->var->getInt() << shift); - if (op==LEX_RSHIFT) a->var->setInt(a->var->getInt() >> shift); - if (op==LEX_RSHIFTUNSIGNED) a->var->setInt(((unsigned int)a->var->getInt()) >> shift); - } - } - return a; -} - -CScriptVarLink *CTinyJS::condition(bool &execute) { - CScriptVarLink *a = shift(execute); - CScriptVarLink *b; - while (l->tk==LEX_EQUAL || l->tk==LEX_NEQUAL || - l->tk==LEX_TYPEEQUAL || l->tk==LEX_NTYPEEQUAL || - l->tk==LEX_LEQUAL || l->tk==LEX_GEQUAL || - l->tk=='<' || l->tk=='>') { - int op = l->tk; - l->match(l->tk); - b = shift(execute); - if (execute) { - CScriptVar *res = a->var->mathsOp(b->var, op); - CREATE_LINK(a,res); - } - CLEAN(b); - } - return a; -} - -CScriptVarLink *CTinyJS::logic(bool &execute) { - CScriptVarLink *a = condition(execute); - CScriptVarLink *b; - while (l->tk=='&' || l->tk=='|' || l->tk=='^' || l->tk==LEX_ANDAND || l->tk==LEX_OROR) { - bool noexecute = false; - int op = l->tk; - l->match(l->tk); - bool shortCircuit = false; - bool boolean = false; - // if we have short-circuit ops, then if we know the outcome - // we don't bother to execute the other op. Even if not - // we need to tell mathsOp it's an & or | - if (op==LEX_ANDAND) { - op = '&'; - shortCircuit = !a->var->getBool(); - boolean = true; - } else if (op==LEX_OROR) { - op = '|'; - shortCircuit = a->var->getBool(); - boolean = true; - } - b = condition(shortCircuit ? noexecute : execute); - if (execute && !shortCircuit) { - if (boolean) { - CScriptVar *newa = new CScriptVar(a->var->getBool()); - CScriptVar *newb = new CScriptVar(b->var->getBool()); - CREATE_LINK(a, newa); - CREATE_LINK(b, newb); - } - CScriptVar *res = a->var->mathsOp(b->var, op); - CREATE_LINK(a, res); - } - CLEAN(b); - } - return a; -} - -CScriptVarLink *CTinyJS::ternary(bool &execute) { - CScriptVarLink *lhs = logic(execute); - bool noexec = false; - if (l->tk=='?') { - l->match('?'); - if (!execute) { - CLEAN(lhs); - CLEAN(base(noexec)); - l->match(':'); - CLEAN(base(noexec)); - } else { - bool first = lhs->var->getBool(); - CLEAN(lhs); - if (first) { - lhs = base(execute); - l->match(':'); - CLEAN(base(noexec)); - } else { - CLEAN(base(noexec)); - l->match(':'); - lhs = base(execute); - } - } - } - - return lhs; -} - -CScriptVarLink *CTinyJS::base(bool &execute) { - CScriptVarLink *lhs = ternary(execute); - if (l->tk=='=' || l->tk==LEX_PLUSEQUAL || l->tk==LEX_MINUSEQUAL) { - /* If we're assigning to this and we don't have a parent, - * add it to the symbol table root as per JavaScript. */ - if (execute && !lhs->owned) { - if (lhs->name.length()>0) { - CScriptVarLink *realLhs = root->addChildNoDup(lhs->name, lhs->var); - CLEAN(lhs); - lhs = realLhs; - } else - TRACE("Trying to assign to an un-named type\n"); - } - - int op = l->tk; - l->match(l->tk); - CScriptVarLink *rhs = base(execute); - if (execute) { - if (op=='=') { - lhs->replaceWith(rhs); - } else if (op==LEX_PLUSEQUAL) { - CScriptVar *res = lhs->var->mathsOp(rhs->var, '+'); - lhs->replaceWith(res); - } else if (op==LEX_MINUSEQUAL) { - CScriptVar *res = lhs->var->mathsOp(rhs->var, '-'); - lhs->replaceWith(res); - } else ASSERT(0); - } - CLEAN(rhs); - } - return lhs; -} - -void CTinyJS::block(bool &execute) { - l->match('{'); - if (execute) { - while (l->tk && l->tk!='}') - statement(execute); - l->match('}'); - } else { - // fast skip of blocks - int brackets = 1; - while (l->tk && brackets) { - if (l->tk == '{') brackets++; - if (l->tk == '}') brackets--; - l->match(l->tk); - } - } - -} - -void CTinyJS::statement(bool &execute) { - if (l->tk==LEX_ID || - l->tk==LEX_INT || - l->tk==LEX_FLOAT || - l->tk==LEX_STR || - l->tk=='-') { - /* Execute a simple statement that only contains basic arithmetic... */ - CLEAN(base(execute)); - l->match(';'); - } else if (l->tk=='{') { - /* A block of code */ - block(execute); - } else if (l->tk==';') { - /* Empty statement - to allow things like ;;; */ - l->match(';'); - } else if (l->tk==LEX_R_VAR) { - /* variable creation. TODO - we need a better way of parsing the left - * hand side. Maybe just have a flag called can_create_var that we - * set and then we parse as if we're doing a normal equals.*/ - l->match(LEX_R_VAR); - while (l->tk != ';') { - CScriptVarLink *a = 0; - if (execute) - a = scopes.back()->findChildOrCreate(l->tkStr); - l->match(LEX_ID); - // now do stuff defined with dots - while (l->tk == '.') { - l->match('.'); - if (execute) { - CScriptVarLink *lastA = a; - a = lastA->var->findChildOrCreate(l->tkStr); - } - l->match(LEX_ID); - } - // sort out initialiser - if (l->tk == '=') { - l->match('='); - CScriptVarLink *var = base(execute); - if (execute) - a->replaceWith(var); - CLEAN(var); - } - if (l->tk != ';') - l->match(','); - } - l->match(';'); - } else if (l->tk==LEX_R_IF) { - l->match(LEX_R_IF); - l->match('('); - CScriptVarLink *var = base(execute); - l->match(')'); - bool cond = execute && var->var->getBool(); - CLEAN(var); - bool noexecute = false; // because we need to be abl;e to write to it - statement(cond ? execute : noexecute); - if (l->tk==LEX_R_ELSE) { - l->match(LEX_R_ELSE); - statement(cond ? noexecute : execute); - } - } else if (l->tk==LEX_R_WHILE) { - // We do repetition by pulling out the string representing our statement - // there's definitely some opportunity for optimisation here - l->match(LEX_R_WHILE); - l->match('('); - int whileCondStart = l->tokenStart; - bool noexecute = false; - CScriptVarLink *cond = base(execute); - bool loopCond = execute && cond->var->getBool(); - CLEAN(cond); - CScriptLex *whileCond = l->getSubLex(whileCondStart); - l->match(')'); - int whileBodyStart = l->tokenStart; - statement(loopCond ? execute : noexecute); - CScriptLex *whileBody = l->getSubLex(whileBodyStart); - CScriptLex *oldLex = l; - int loopCount = TINYJS_LOOP_MAX_ITERATIONS; - while (loopCond && loopCount-->0) { - whileCond->reset(); - l = whileCond; - cond = base(execute); - loopCond = execute && cond->var->getBool(); - CLEAN(cond); - if (loopCond) { - whileBody->reset(); - l = whileBody; - statement(execute); - } - } - l = oldLex; - delete whileCond; - delete whileBody; - - if (loopCount<=0) { - root->trace(); - TRACE("WHILE Loop exceeded %d iterations at %s\n", TINYJS_LOOP_MAX_ITERATIONS, l->getPosition().c_str()); - throw new CScriptException("LOOP_ERROR"); - } - } else if (l->tk==LEX_R_FOR) { - l->match(LEX_R_FOR); - l->match('('); - statement(execute); // initialisation - //l->match(';'); - int forCondStart = l->tokenStart; - bool noexecute = false; - CScriptVarLink *cond = base(execute); // condition - bool loopCond = execute && cond->var->getBool(); - CLEAN(cond); - CScriptLex *forCond = l->getSubLex(forCondStart); - l->match(';'); - int forIterStart = l->tokenStart; - CLEAN(base(noexecute)); // iterator - CScriptLex *forIter = l->getSubLex(forIterStart); - l->match(')'); - int forBodyStart = l->tokenStart; - statement(loopCond ? execute : noexecute); - CScriptLex *forBody = l->getSubLex(forBodyStart); - CScriptLex *oldLex = l; - if (loopCond) { - forIter->reset(); - l = forIter; - CLEAN(base(execute)); - } - int loopCount = TINYJS_LOOP_MAX_ITERATIONS; - while (execute && loopCond && loopCount-->0) { - forCond->reset(); - l = forCond; - cond = base(execute); - loopCond = cond->var->getBool(); - CLEAN(cond); - if (execute && loopCond) { - forBody->reset(); - l = forBody; - statement(execute); - } - if (execute && loopCond) { - forIter->reset(); - l = forIter; - CLEAN(base(execute)); - } - } - l = oldLex; - delete forCond; - delete forIter; - delete forBody; - if (loopCount<=0) { - root->trace(); - TRACE("FOR Loop exceeded %d iterations at %s\n", TINYJS_LOOP_MAX_ITERATIONS, l->getPosition().c_str()); - throw new CScriptException("LOOP_ERROR"); - } - } else if (l->tk==LEX_R_RETURN) { - l->match(LEX_R_RETURN); - CScriptVarLink *result = 0; - if (l->tk != ';') - result = base(execute); - if (execute) { - CScriptVarLink *resultVar = scopes.back()->findChild(TINYJS_RETURN_VAR); - if (resultVar) - resultVar->replaceWith(result); - else - TRACE("RETURN statement, but not in a function.\n"); - execute = false; - } - CLEAN(result); - l->match(';'); - } else if (l->tk==LEX_R_FUNCTION) { - CScriptVarLink *funcVar = parseFunctionDefinition(); - if (execute) { - if (funcVar->name == TINYJS_TEMP_NAME) - TRACE("Functions defined at statement-level are meant to have a name\n"); - else - scopes.back()->addChildNoDup(funcVar->name, funcVar->var); - } - CLEAN(funcVar); - } else l->match(LEX_EOF); -} - -/// Get the given variable specified by a path (var1.var2.etc), or return 0 -CScriptVar *CTinyJS::getScriptVariable(const string &path) { - // traverse path - size_t prevIdx = 0; - size_t thisIdx = path.find('.'); - if (thisIdx == string::npos) thisIdx = path.length(); - CScriptVar *var = root; - while (var && prevIdxfindChild(el); - var = varl?varl->var:0; - prevIdx = thisIdx+1; - thisIdx = path.find('.', prevIdx); - if (thisIdx == string::npos) thisIdx = path.length(); - } - return var; -} - -/// Get the value of the given variable, or return 0 -const string *CTinyJS::getVariable(const string &path) { - CScriptVar *var = getScriptVariable(path); - // return result - if (var) - return &var->getString(); - else - return 0; -} - -/// set the value of the given variable, return trur if it exists and gets set -bool CTinyJS::setVariable(const std::string &path, const std::string &varData) { - CScriptVar *var = getScriptVariable(path); - // return result - if (var) { - if (var->isInt()) - var->setInt((int)strtol(varData.c_str(),0,0)); - else if (var->isDouble()) - var->setDouble(strtod(varData.c_str(),0)); - else - var->setString(varData.c_str()); - return true; - } - else - return false; -} - -/// Finds a child, looking recursively up the scopes -CScriptVarLink *CTinyJS::findInScopes(const std::string &childName) { - for (int s=scopes.size()-1;s>=0;s--) { - CScriptVarLink *v = scopes[s]->findChild(childName); - if (v) return v; - } - return NULL; - -} - -/// Look up in any parent classes of the given object -CScriptVarLink *CTinyJS::findInParentClasses(CScriptVar *object, const std::string &name) { - // Look for links to actual parent classes - CScriptVarLink *parentClass = object->findChild(TINYJS_PROTOTYPE_CLASS); - while (parentClass) { - CScriptVarLink *implementation = parentClass->var->findChild(name); - if (implementation) return implementation; - parentClass = parentClass->var->findChild(TINYJS_PROTOTYPE_CLASS); - } - // else fake it for strings and finally objects - if (object->isString()) { - CScriptVarLink *implementation = stringClass->findChild(name); - if (implementation) return implementation; - } - if (object->isArray()) { - CScriptVarLink *implementation = arrayClass->findChild(name); - if (implementation) return implementation; - } - CScriptVarLink *implementation = objectClass->findChild(name); - if (implementation) return implementation; - - return 0; -} diff --git a/.svn/pristine/67/6727ff2548a4483177cf428737c254fdba3be725.svn-base b/.svn/pristine/67/6727ff2548a4483177cf428737c254fdba3be725.svn-base deleted file mode 100644 index 75c2ce3..0000000 --- a/.svn/pristine/67/6727ff2548a4483177cf428737c254fdba3be725.svn-base +++ /dev/null @@ -1,4 +0,0 @@ -// test for array join -var a = [1,2,4,5,7]; - -result = a.join(",")=="1,2,4,5,7"; diff --git a/.svn/pristine/6c/6c31b2bdb233bafb1bbf172a9065e3ec04d54cde.svn-base b/.svn/pristine/6c/6c31b2bdb233bafb1bbf172a9065e3ec04d54cde.svn-base deleted file mode 100644 index fc3f427..0000000 --- a/.svn/pristine/6c/6c31b2bdb233bafb1bbf172a9065e3ec04d54cde.svn-base +++ /dev/null @@ -1,9 +0,0 @@ -/* Javascript eval */ - -mystructure = { a:39, b:3, addStuff : function(c,d) { return c+d; } }; - -mystring = JSON.stringify(mystructure, undefined); - -mynewstructure = eval(mystring); - -result = mynewstructure.addStuff(mynewstructure.a, mynewstructure.b); diff --git a/.svn/pristine/6c/6c6063591602b23d43faa8f31867991e7c0f93dc.svn-base b/.svn/pristine/6c/6c6063591602b23d43faa8f31867991e7c0f93dc.svn-base deleted file mode 100644 index 7fd5d0d..0000000 --- a/.svn/pristine/6c/6c6063591602b23d43faa8f31867991e7c0f93dc.svn-base +++ /dev/null @@ -1,12 +0,0 @@ -var Foo = { - value : function() { return this.x + this.y; } -}; - -var a = { prototype: Foo, x: 1, y: 2 }; -var b = new Foo(); -b.x = 2; -b.y = 3; - -var result1 = a.value(); -var result2 = b.value(); -result = result1==3 && result2==5; diff --git a/.svn/pristine/6f/6fa8ecf7da0b483cf29d7d789e85b541baf747ca.svn-base b/.svn/pristine/6f/6fa8ecf7da0b483cf29d7d789e85b541baf747ca.svn-base deleted file mode 100644 index a2fb08f..0000000 --- a/.svn/pristine/6f/6fa8ecf7da0b483cf29d7d789e85b541baf747ca.svn-base +++ /dev/null @@ -1,7 +0,0 @@ -// if .. else with blocks -var a = 42; -if (a != 42) { - result = 0; -} else { - result = 1; -} diff --git a/.svn/pristine/77/77a33ad02fc07dcc76b961c8e50e579530a302a5.svn-base b/.svn/pristine/77/77a33ad02fc07dcc76b961c8e50e579530a302a5.svn-base deleted file mode 100644 index 66ecae6..0000000 --- a/.svn/pristine/77/77a33ad02fc07dcc76b961c8e50e579530a302a5.svn-base +++ /dev/null @@ -1,66 +0,0 @@ -/* Mandelbrot! */ - -X1 = -2.0; -Y1 = -2.0; -X2 = 2.0; -Y2 = 2.0; -PX = 32; -PY = 32; - - -lines = []; -for (y=0;y>3); -var c = (-1 >>> 16); -result = a==8 && b==2 && c == 0xFFFF; diff --git a/.svn/pristine/80/809d98f6c6e06d4f51258f9935713a53db5fdcd0.svn-base b/.svn/pristine/80/809d98f6c6e06d4f51258f9935713a53db5fdcd0.svn-base deleted file mode 100644 index 0563c08..0000000 --- a/.svn/pristine/80/809d98f6c6e06d4f51258f9935713a53db5fdcd0.svn-base +++ /dev/null @@ -1,24 +0,0 @@ -CC=g++ -CFLAGS=-c -g -Wall -rdynamic -D_DEBUG -LDFLAGS=-g -rdynamic - -SOURCES= \ -TinyJS.cpp \ -TinyJS_Functions.cpp \ -TinyJS_MathFunctions.cpp - -OBJECTS=$(SOURCES:.cpp=.o) - -all: run_tests Script - -run_tests: run_tests.o $(OBJECTS) - $(CC) $(LDFLAGS) run_tests.o $(OBJECTS) -o $@ - -Script: Script.o $(OBJECTS) - $(CC) $(LDFLAGS) Script.o $(OBJECTS) -o $@ - -.cpp.o: - $(CC) $(CFLAGS) $< -o $@ - -clean: - rm -f run_tests Script run_tests.o Script.o $(OBJECTS) diff --git a/.svn/pristine/82/82f5fc803659cf3a30f476ac30944a82a6b24f9f.svn-base b/.svn/pristine/82/82f5fc803659cf3a30f476ac30944a82a6b24f9f.svn-base deleted file mode 100644 index 6b475a5..0000000 --- a/.svn/pristine/82/82f5fc803659cf3a30f476ac30944a82a6b24f9f.svn-base +++ /dev/null @@ -1,15 +0,0 @@ -// with-test - -var a; - -with(Math) a=PI; - -var b = { get_member : function() { return this.member;}, member:41 }; - -with(b) { - let a = get_member(); //<--- a is local for this block - var c = a+1; -} - - -result = a == Math.PI && c == 42; diff --git a/.svn/pristine/8e/8ee3fe9d186a505b3c5f950983fad166713072f8.svn-base b/.svn/pristine/8e/8ee3fe9d186a505b3c5f950983fad166713072f8.svn-base deleted file mode 100644 index 292ad5e..0000000 --- a/.svn/pristine/8e/8ee3fe9d186a505b3c5f950983fad166713072f8.svn-base +++ /dev/null @@ -1,3 +0,0 @@ -// simple function -function add(x,y) { return x+y; } -result = add(3,6)==9; diff --git a/.svn/pristine/94/94b662a1347b08fb8c9f48b02aab68cc8f0e579c.svn-base b/.svn/pristine/94/94b662a1347b08fb8c9f48b02aab68cc8f0e579c.svn-base deleted file mode 100644 index 2a8570e..0000000 --- a/.svn/pristine/94/94b662a1347b08fb8c9f48b02aab68cc8f0e579c.svn-base +++ /dev/null @@ -1,4 +0,0 @@ -// check for undefined-ness -a = undefined; -b = "foo"; -result = a==undefined && b!=undefined; diff --git a/.svn/pristine/a0/a058f831c64d02ff800519f592f3a99890d95dc9.svn-base b/.svn/pristine/a0/a058f831c64d02ff800519f592f3a99890d95dc9.svn-base deleted file mode 100644 index 78d580e..0000000 --- a/.svn/pristine/a0/a058f831c64d02ff800519f592f3a99890d95dc9.svn-base +++ /dev/null @@ -1,27 +0,0 @@ -// generator-test - -function fibonacci(){ - var fn1 = 1; - var fn2 = 1; - while (1){ - var current = fn2; - fn2 = fn1; - fn1 = fn1 + current; - var reset = yield current; - if (reset){ - fn1 = 1; - fn2 = 1; - } - } -} - -var generator = fibonacci(); - -generator.next(); // 1 -generator.next(); // 1 -generator.next(); // 2 -generator.next(); // 3 -generator.next(); // 5 - - -result = generator.next() == 8 && generator.send(true) == 1; diff --git a/.svn/pristine/a4/a48e8c0a950a4bc2d0dd36c00c8d35940fc911fc.svn-base b/.svn/pristine/a4/a48e8c0a950a4bc2d0dd36c00c8d35940fc911fc.svn-base deleted file mode 100644 index ebebe01..0000000 --- a/.svn/pristine/a4/a48e8c0a950a4bc2d0dd36c00c8d35940fc911fc.svn-base +++ /dev/null @@ -1,11 +0,0 @@ -// references for arrays - -var a = []; -a[0] = 10; -a[1] = 22; - -b = a; - -b[0] = 5; - -result = a[0]==5 && a[1]==22 && b[1]==22; diff --git a/.svn/pristine/a7/a7b674191cf81d0e511d5f588cf081bf0ff80234.svn-base b/.svn/pristine/a7/a7b674191cf81d0e511d5f588cf081bf0ff80234.svn-base deleted file mode 100644 index 8a66994..0000000 --- a/.svn/pristine/a7/a7b674191cf81d0e511d5f588cf081bf0ff80234.svn-base +++ /dev/null @@ -1,247 +0,0 @@ -/* - * TinyJS - * - * A single-file Javascript-alike engine - * - * - Useful language functions - * - * Authored By Gordon Williams - * - * Copyright (C) 2009 Pur3 Ltd - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is furnished to do - * so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "TinyJS_Functions.h" -#include -#include -#include - -using namespace std; -// ----------------------------------------------- Actual Functions -void scTrace(CScriptVar *c, void *userdata) { - CTinyJS *js = (CTinyJS*)userdata; - js->root->trace(); -} - -void scObjectDump(CScriptVar *c, void *) { - c->getParameter("this")->trace("> "); -} - -void scObjectClone(CScriptVar *c, void *) { - CScriptVar *obj = c->getParameter("this"); - c->getReturnVar()->copyValue(obj); -} - -void scMathRand(CScriptVar *c, void *) { - c->getReturnVar()->setDouble((double)rand()/RAND_MAX); -} - -void scMathRandInt(CScriptVar *c, void *) { - int min = c->getParameter("min")->getInt(); - int max = c->getParameter("max")->getInt(); - int val = min + (int)(rand()%(1+max-min)); - c->getReturnVar()->setInt(val); -} - -void scCharToInt(CScriptVar *c, void *) { - string str = c->getParameter("ch")->getString();; - int val = 0; - if (str.length()>0) - val = (int)str.c_str()[0]; - c->getReturnVar()->setInt(val); -} - -void scStringIndexOf(CScriptVar *c, void *) { - string str = c->getParameter("this")->getString(); - string search = c->getParameter("search")->getString(); - size_t p = str.find(search); - int val = (p==string::npos) ? -1 : p; - c->getReturnVar()->setInt(val); -} - -void scStringSubstring(CScriptVar *c, void *) { - string str = c->getParameter("this")->getString(); - int lo = c->getParameter("lo")->getInt(); - int hi = c->getParameter("hi")->getInt(); - - int l = hi-lo; - if (l>0 && lo>=0 && lo+l<=(int)str.length()) - c->getReturnVar()->setString(str.substr(lo, l)); - else - c->getReturnVar()->setString(""); -} - -void scStringCharAt(CScriptVar *c, void *) { - string str = c->getParameter("this")->getString(); - int p = c->getParameter("pos")->getInt(); - if (p>=0 && p<(int)str.length()) - c->getReturnVar()->setString(str.substr(p, 1)); - else - c->getReturnVar()->setString(""); -} - -void scStringCharCodeAt(CScriptVar *c, void *) { - string str = c->getParameter("this")->getString(); - int p = c->getParameter("pos")->getInt(); - if (p>=0 && p<(int)str.length()) - c->getReturnVar()->setInt(str.at(p)); - else - c->getReturnVar()->setInt(0); -} - -void scStringSplit(CScriptVar *c, void *) { - string str = c->getParameter("this")->getString(); - string sep = c->getParameter("separator")->getString(); - CScriptVar *result = c->getReturnVar(); - result->setArray(); - int length = 0; - - size_t pos = str.find(sep); - while (pos != string::npos) { - result->setArrayIndex(length++, new CScriptVar(str.substr(0,pos))); - str = str.substr(pos+1); - pos = str.find(sep); - } - - if (str.size()>0) - result->setArrayIndex(length++, new CScriptVar(str)); -} - -void scStringFromCharCode(CScriptVar *c, void *) { - char str[2]; - str[0] = c->getParameter("char")->getInt(); - str[1] = 0; - c->getReturnVar()->setString(str); -} - -void scIntegerParseInt(CScriptVar *c, void *) { - string str = c->getParameter("str")->getString(); - int val = strtol(str.c_str(),0,0); - c->getReturnVar()->setInt(val); -} - -void scIntegerValueOf(CScriptVar *c, void *) { - string str = c->getParameter("str")->getString(); - - int val = 0; - if (str.length()==1) - val = str[0]; - c->getReturnVar()->setInt(val); -} - -void scJSONStringify(CScriptVar *c, void *) { - std::ostringstream result; - c->getParameter("obj")->getJSON(result); - c->getReturnVar()->setString(result.str()); -} - -void scExec(CScriptVar *c, void *data) { - CTinyJS *tinyJS = (CTinyJS *)data; - std::string str = c->getParameter("jsCode")->getString(); - tinyJS->execute(str); -} - -void scEval(CScriptVar *c, void *data) { - CTinyJS *tinyJS = (CTinyJS *)data; - std::string str = c->getParameter("jsCode")->getString(); - c->setReturnVar(tinyJS->evaluateComplex(str).var); -} - -void scArrayContains(CScriptVar *c, void *data) { - CScriptVar *obj = c->getParameter("obj"); - CScriptVarLink *v = c->getParameter("this")->firstChild; - - bool contains = false; - while (v) { - if (v->var->equals(obj)) { - contains = true; - break; - } - v = v->nextSibling; - } - - c->getReturnVar()->setInt(contains); -} - -void scArrayRemove(CScriptVar *c, void *data) { - CScriptVar *obj = c->getParameter("obj"); - vector removedIndices; - CScriptVarLink *v; - // remove - v = c->getParameter("this")->firstChild; - while (v) { - if (v->var->equals(obj)) { - removedIndices.push_back(v->getIntName()); - } - v = v->nextSibling; - } - // renumber - v = c->getParameter("this")->firstChild; - while (v) { - int n = v->getIntName(); - int newn = n; - for (size_t i=0;i=removedIndices[i]) - newn--; - if (newn!=n) - v->setIntName(newn); - v = v->nextSibling; - } -} - -void scArrayJoin(CScriptVar *c, void *data) { - string sep = c->getParameter("separator")->getString(); - CScriptVar *arr = c->getParameter("this"); - - ostringstream sstr; - int l = arr->getArrayLength(); - for (int i=0;i0) sstr << sep; - sstr << arr->getArrayIndex(i)->getString(); - } - - c->getReturnVar()->setString(sstr.str()); -} - -// ----------------------------------------------- Register Functions -void registerFunctions(CTinyJS *tinyJS) { - tinyJS->addNative("function exec(jsCode)", scExec, tinyJS); // execute the given code - tinyJS->addNative("function eval(jsCode)", scEval, tinyJS); // execute the given string (an expression) and return the result - tinyJS->addNative("function trace()", scTrace, tinyJS); - tinyJS->addNative("function Object.dump()", scObjectDump, 0); - tinyJS->addNative("function Object.clone()", scObjectClone, 0); - tinyJS->addNative("function Math.rand()", scMathRand, 0); - tinyJS->addNative("function Math.randInt(min, max)", scMathRandInt, 0); - tinyJS->addNative("function charToInt(ch)", scCharToInt, 0); // convert a character to an int - get its value - tinyJS->addNative("function String.indexOf(search)", scStringIndexOf, 0); // find the position of a string in a string, -1 if not - tinyJS->addNative("function String.substring(lo,hi)", scStringSubstring, 0); - tinyJS->addNative("function String.charAt(pos)", scStringCharAt, 0); - tinyJS->addNative("function String.charCodeAt(pos)", scStringCharCodeAt, 0); - tinyJS->addNative("function String.fromCharCode(char)", scStringFromCharCode, 0); - tinyJS->addNative("function String.split(separator)", scStringSplit, 0); - tinyJS->addNative("function Integer.parseInt(str)", scIntegerParseInt, 0); // string to int - tinyJS->addNative("function Integer.valueOf(str)", scIntegerValueOf, 0); // value of a single character - tinyJS->addNative("function JSON.stringify(obj, replacer)", scJSONStringify, 0); // convert to JSON. replacer is ignored at the moment - // JSON.parse is left out as you can (unsafely!) use eval instead - tinyJS->addNative("function Array.contains(obj)", scArrayContains, 0); - tinyJS->addNative("function Array.remove(obj)", scArrayRemove, 0); - tinyJS->addNative("function Array.join(separator)", scArrayJoin, 0); -} - diff --git a/.svn/pristine/b4/b41d60923c68b1fb7bf388e77d888992811b8a49.svn-base b/.svn/pristine/b4/b41d60923c68b1fb7bf388e77d888992811b8a49.svn-base deleted file mode 100644 index 9a43bc6..0000000 --- a/.svn/pristine/b4/b41d60923c68b1fb7bf388e77d888992811b8a49.svn-base +++ /dev/null @@ -1,4 +0,0 @@ -// simple function scoping test -var a = 7; -function add(x,y) { var a=x+y; return a; } -result = add(3,6)==9 && a==7; diff --git a/.svn/pristine/b5/b58138e16a5cb393ac32ef3c145f1654806e5484.svn-base b/.svn/pristine/b5/b58138e16a5cb393ac32ef3c145f1654806e5484.svn-base deleted file mode 100644 index 4eaf641..0000000 --- a/.svn/pristine/b5/b58138e16a5cb393ac32ef3c145f1654806e5484.svn-base +++ /dev/null @@ -1,7 +0,0 @@ -// recursion -function a(x) { - if (x>1) - return x*a(x-1); - return 1; -} -result = a(5)==1*2*3*4*5; diff --git a/.svn/pristine/b6/b68579cf510cd129a78e6c15d2f561ee50bb16b2.svn-base b/.svn/pristine/b6/b68579cf510cd129a78e6c15d2f561ee50bb16b2.svn-base deleted file mode 100644 index 5d8856a..0000000 --- a/.svn/pristine/b6/b68579cf510cd129a78e6c15d2f561ee50bb16b2.svn-base +++ /dev/null @@ -1,32 +0,0 @@ -// built-in functions - -foo = "foo bar stuff"; -// 42-tiny-js change begin ---> -// in JavaScript this function is called Math.random() -//r = Math.rand(); -r = Math.random(); -//<--- 42-tiny-js change end - -// 42-tiny-js change begin ---> -// in JavaScript parseInt is a methode in the global scope (root-scope) -//parsed = Integer.parseInt("42"); -parsed = parseInt("42"); -//<--- 42-tiny-js change end - -aStr = "ABCD"; -aChar = aStr.charAt(0); - -obj1 = new Object(); -obj1.food = "cake"; -obj1.desert = "pie"; - -obj2 = obj1.clone(); -obj2.food = "kittens"; - -result = foo.length==13 && foo.indexOf("bar")==4 && foo.substring(8,13)=="stuff" && parsed==42 && -// 42-tiny-js change begin ---> -// in 42tiny-js the Integer-Objecte will be removed -// Integer.valueOf can be replaced by String.charCodeAt -// Integer.valueOf(aChar)==65 && obj1.food=="cake" && obj2.desert=="pie"; - aChar.charCodeAt()==65 && obj1.food=="cake" && obj2.desert=="pie"; -//<--- 42-tiny-js change end diff --git a/.svn/pristine/b7/b7fe981670c12565a22d7568a529ddb379b686c1.svn-base b/.svn/pristine/b7/b7fe981670c12565a22d7568a529ddb379b686c1.svn-base deleted file mode 100644 index e0d95dc..0000000 --- a/.svn/pristine/b7/b7fe981670c12565a22d7568a529ddb379b686c1.svn-base +++ /dev/null @@ -1,2 +0,0 @@ -// simply testing we can return the correct value -result = 1; diff --git a/.svn/pristine/b8/b819a78fdf3aa9ba320fa71a0bc4f14a9fdbc869.svn-base b/.svn/pristine/b8/b819a78fdf3aa9ba320fa71a0bc4f14a9fdbc869.svn-base deleted file mode 100644 index 366f1d4..0000000 --- a/.svn/pristine/b8/b819a78fdf3aa9ba320fa71a0bc4f14a9fdbc869.svn-base +++ /dev/null @@ -1,19 +0,0 @@ -// built-in functions - -foo = "foo bar stuff"; -r = Math.rand(); - -parsed = Integer.parseInt("42"); - -aStr = "ABCD"; -aChar = aStr.charAt(0); - -obj1 = new Object(); -obj1.food = "cake"; -obj1.desert = "pie"; - -obj2 = obj1.clone(); -obj2.food = "kittens"; - -result = foo.length==13 && foo.indexOf("bar")==4 && foo.substring(8,13)=="stuff" && parsed==42 && - Integer.valueOf(aChar)==65 && obj1.food=="cake" && obj2.desert=="pie"; diff --git a/.svn/pristine/bd/bd56444e00ad417eb12e267261157989b490f88f.svn-base b/.svn/pristine/bd/bd56444e00ad417eb12e267261157989b490f88f.svn-base deleted file mode 100644 index e2fd636..0000000 --- a/.svn/pristine/bd/bd56444e00ad417eb12e267261157989b490f88f.svn-base +++ /dev/null @@ -1,15 +0,0 @@ -/* Javascript eval */ - -mystructure = { a:39, b:3, addStuff : function(c,d) { return c+d; } }; - -mystring = JSON.stringify(mystructure, undefined); - -// 42-tiny-js change begin ---> -// in JavaScript eval is not JSON.parse -// use parentheses or JSON.parse instead -//mynewstructure = eval(mystring); -mynewstructure = eval("("+mystring+")"); -mynewstructure2 = JSON.parse(mystring); -//<--- 42-tiny-js change end - -result = mynewstructure.addStuff(mynewstructure.a, mynewstructure.b) == 42 && mynewstructure2.addStuff(mynewstructure2.a, mynewstructure2.b) == 42; diff --git a/.svn/pristine/c1/c1892a3253526d334c8f8902616d82a97d7714cd.svn-base b/.svn/pristine/c1/c1892a3253526d334c8f8902616d82a97d7714cd.svn-base deleted file mode 100644 index 5145c12..0000000 --- a/.svn/pristine/c1/c1892a3253526d334c8f8902616d82a97d7714cd.svn-base +++ /dev/null @@ -1,87 +0,0 @@ -/* - * TinyJS - * - * A single-file Javascript-alike engine - * - * Authored By Gordon Williams - * - * Copyright (C) 2009 Pur3 Ltd - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is furnished to do - * so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* - * This is a simple program showing how to use TinyJS - */ - -#include "TinyJS.h" -#include "TinyJS_Functions.h" -#include -#include - - -//const char *code = "var a = 5; if (a==5) a=4; else a=3;"; -//const char *code = "{ var a = 4; var b = 1; while (a>0) { b = b * 2; a = a - 1; } var c = 5; }"; -//const char *code = "{ var b = 1; for (var i=0;i<4;i=i+1) b = b * 2; }"; -const char *code = "function myfunc(x, y) { return x + y; } var a = myfunc(1,2); print(a);"; - -void js_print(CScriptVar *v, void *userdata) { - printf("> %s\n", v->getParameter("text")->getString().c_str()); -} - -void js_dump(CScriptVar *v, void *userdata) { - CTinyJS *js = (CTinyJS*)userdata; - js->root->trace("> "); -} - - -int main(int argc, char **argv) -{ - CTinyJS *js = new CTinyJS(); - /* add the functions from TinyJS_Functions.cpp */ - registerFunctions(js); - /* Add a native function */ - js->addNative("function print(text)", &js_print, 0); - js->addNative("function dump()", &js_dump, js); - /* Execute out bit of code - we could call 'evaluate' here if - we wanted something returned */ - try { - js->execute("var lets_quit = 0; function quit() { lets_quit = 1; }"); - js->execute("print(\"Interactive mode... Type quit(); to exit, or print(...); to print something, or dump() to dump the symbol table!\");"); - } catch (CScriptException *e) { - printf("ERROR: %s\n", e->text.c_str()); - } - - while (js->evaluate("lets_quit") == "0") { - char buffer[2048]; - fgets ( buffer, sizeof(buffer), stdin ); - try { - js->execute(buffer); - } catch (CScriptException *e) { - printf("ERROR: %s\n", e->text.c_str()); - } - } - delete js; -#ifdef _WIN32 -#ifdef _DEBUG - _CrtDumpMemoryLeaks(); -#endif -#endif - return 0; -} diff --git a/.svn/pristine/c6/c68654882f32416660b1b7820f8542fff6dc8be3.svn-base b/.svn/pristine/c6/c68654882f32416660b1b7820f8542fff6dc8be3.svn-base deleted file mode 100644 index 82e89da..0000000 --- a/.svn/pristine/c6/c68654882f32416660b1b7820f8542fff6dc8be3.svn-base +++ /dev/null @@ -1,4 +0,0 @@ -// double function calls -function a(x) { return x+2; } -function b(x) { return a(x)+1; } -result = a(3)==5 && b(3)==6; diff --git a/.svn/pristine/ca/caae4fad7a0f93b60a9b09c7da656311aa9bdc0c.svn-base b/.svn/pristine/ca/caae4fad7a0f93b60a9b09c7da656311aa9bdc0c.svn-base deleted file mode 100644 index 2d6cc19..0000000 --- a/.svn/pristine/ca/caae4fad7a0f93b60a9b09c7da656311aa9bdc0c.svn-base +++ /dev/null @@ -1,3 +0,0 @@ -// test for postincrement working as expected -var foo = 5; -result = (foo++)==5; diff --git a/.svn/pristine/cb/cbd242c9c78eddce13db7317c337ae0543d5ed68.svn-base b/.svn/pristine/cb/cbd242c9c78eddce13db7317c337ae0543d5ed68.svn-base deleted file mode 100644 index cb5489f..0000000 --- a/.svn/pristine/cb/cbd242c9c78eddce13db7317c337ae0543d5ed68.svn-base +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef TINYJS_MATHFUNCTIONS_H -#define TINYJS_MATHFUNCTIONS_H - -#include "TinyJS.h" - -/// Register useful math. functions with the TinyJS interpreter -extern void registerMathFunctions(CTinyJS *tinyJS); - -#endif diff --git a/.svn/pristine/ce/cebe306b4aef8549a32a315fdc1250b2db5baa2f.svn-base b/.svn/pristine/ce/cebe306b4aef8549a32a315fdc1250b2db5baa2f.svn-base deleted file mode 100644 index b40d427..0000000 --- a/.svn/pristine/ce/cebe306b4aef8549a32a315fdc1250b2db5baa2f.svn-base +++ /dev/null @@ -1,6 +0,0 @@ -// mikael.kindborg@mobilesorcery.com - Function symbol is evaluated in bracket-less body of false if-statement -var foo; // a var is only created automated by assignment - -if (foo !== undefined) foo(); - -result = 1; diff --git a/.svn/pristine/d7/d715958af1a93d3e5d0662599777f720627fe5bf.svn-base b/.svn/pristine/d7/d715958af1a93d3e5d0662599777f720627fe5bf.svn-base deleted file mode 100644 index efd3418..0000000 --- a/.svn/pristine/d7/d715958af1a93d3e5d0662599777f720627fe5bf.svn-base +++ /dev/null @@ -1,9 +0,0 @@ -// the 'lf' in the printf caused issues writing doubles on some compilers -var a=5.0/10.0*100.0; -var b=5.0*110.0; -var c=50.0/10.0; -a.dump(); -b.dump(); -c.dump(); -result = a==50 && b==550 && c==5; - diff --git a/.svn/pristine/db/dbfd9e15d1a164edc3d50fe278060a81e41afc59.svn-base b/.svn/pristine/db/dbfd9e15d1a164edc3d50fe278060a81e41afc59.svn-base deleted file mode 100644 index 351fcc2..0000000 --- a/.svn/pristine/db/dbfd9e15d1a164edc3d50fe278060a81e41afc59.svn-base +++ /dev/null @@ -1,7 +0,0 @@ -// Array length test - -myArray = [ 1, 2, 3, 4, 5 ]; -myArray2 = [ 1, 2, 3, 4, 5 ]; -myArray2[8] = 42; - -result = myArray.length == 5 && myArray2.length == 9; diff --git a/.svn/pristine/dd/dd7632e29aea1ed6c1c6bca07a8f286b569afceb.svn-base b/.svn/pristine/dd/dd7632e29aea1ed6c1c6bca07a8f286b569afceb.svn-base deleted file mode 100644 index 2f07c8b..0000000 --- a/.svn/pristine/dd/dd7632e29aea1ed6c1c6bca07a8f286b569afceb.svn-base +++ /dev/null @@ -1,4 +0,0 @@ -// simple if -var a = 42; -if (a < 43) - result = 1; diff --git a/.svn/pristine/de/de168a36d9cdf7c1f1802dc97304822e3ce9727e.svn-base b/.svn/pristine/de/de168a36d9cdf7c1f1802dc97304822e3ce9727e.svn-base deleted file mode 100644 index 08bf42e..0000000 --- a/.svn/pristine/de/de168a36d9cdf7c1f1802dc97304822e3ce9727e.svn-base +++ /dev/null @@ -1,4 +0,0 @@ -// functions in variables using JSON-style initialisation -var bob = { add : function(x,y) { return x+y; } }; - -result = bob.add(3,6)==9; diff --git a/.svn/pristine/e1/e1e742ca5e4f1854d7f2e66a4d3c6b70b37a47da.svn-base b/.svn/pristine/e1/e1e742ca5e4f1854d7f2e66a4d3c6b70b37a47da.svn-base deleted file mode 100644 index 51b892d..0000000 --- a/.svn/pristine/e1/e1e742ca5e4f1854d7f2e66a4d3c6b70b37a47da.svn-base +++ /dev/null @@ -1,9 +0,0 @@ -function Person(name) { - this.name = name; - this.kill = function() { this.name += " is dead"; }; -} - -var a = new Person("Kenny"); -a.kill(); -result = a.name == "Kenny is dead"; - diff --git a/.svn/pristine/e7/e7f32c6f60b7de28742a11815e3c0ab72eec6737.svn-base b/.svn/pristine/e7/e7f32c6f60b7de28742a11815e3c0ab72eec6737.svn-base deleted file mode 100644 index 927ec6e..0000000 --- a/.svn/pristine/e7/e7f32c6f60b7de28742a11815e3c0ab72eec6737.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -// test for string split -var b = "1,4,7"; -var a = b.split(","); - -result = a.length==3 && a[0]==1 && a[1]==4 && a[2]==7; diff --git a/.svn/pristine/e9/e962bff63b200d200039badeb16b18a385bab342.svn-base b/.svn/pristine/e9/e962bff63b200d200039badeb16b18a385bab342.svn-base deleted file mode 100644 index 82c176d..0000000 --- a/.svn/pristine/e9/e962bff63b200d200039badeb16b18a385bab342.svn-base +++ /dev/null @@ -1,80 +0,0 @@ -// switch-case-tests - -//////////////////////////////////////////////////// -// switch-test 1: case with break; -//////////////////////////////////////////////////// -var a1=5; -var b1=6; -var r1=0; - -switch(a1+5){ - case 6: - r1 = 2; - break; - case b1+4: - r1 = 42; - break; - case 7: - r1 = 2; - break; -} - -//////////////////////////////////////////////////// -// switch-test 2: case with out break; -//////////////////////////////////////////////////// -var a2=5; -var b2=6; -var r2=0; - -switch(a2+4){ - case 6: - r2 = 2; - break; - case b2+3: - r2 = 40; - //break; - case 7: - r2 += 2; - break; -} - -//////////////////////////////////////////////////// -// switch-test 3: case with default; -//////////////////////////////////////////////////// -var a3=5; -var b3=6; -var r3=0; - -switch(a3+44){ - case 6: - r3 = 2; - break; - case b3+3: - r3 = 1; - break; - default: - r3 = 42; - break; -} - -//////////////////////////////////////////////////// -// switch-test 4: case default before case; -//////////////////////////////////////////////////// -var a4=5; -var b4=6; -var r4=0; - -switch(a4+44){ - default: - r4 = 42; - break; - case 6: - r4 = 2; - break; - case b4+3: - r4 = 1; - break; -} - - -result = r1 == 42 && r2 == 42 && r3 == 42 && r4 == 42; diff --git a/.svn/pristine/ea/ea98f09d4d2e2339f2c32f472e6203f47582a66b.svn-base b/.svn/pristine/ea/ea98f09d4d2e2339f2c32f472e6203f47582a66b.svn-base deleted file mode 100644 index 5538c54..0000000 --- a/.svn/pristine/ea/ea98f09d4d2e2339f2c32f472e6203f47582a66b.svn-base +++ /dev/null @@ -1,16 +0,0 @@ -// Variable creation and scope from http://en.wikipedia.org/wiki/JavaScript_syntax -x = 0; // A global variable -var y = 'Hello!'; // Another global variable -z = 0; // yet another global variable - -function f(){ - var z = 'foxes'; // A local variable - twenty = 20; // Global because keyword var is not used - return x; // We can use x here because it is global -} -// The value of z is no longer available - - -// testing -blah = f(); -result = blah==0 && z!='foxes' && twenty==20; diff --git a/.svn/pristine/fc/fccddea4a9d21ce6301d243a8c2b3bd06d39a397.svn-base b/.svn/pristine/fc/fccddea4a9d21ce6301d243a8c2b3bd06d39a397.svn-base deleted file mode 100644 index 076b5c8..0000000 --- a/.svn/pristine/fc/fccddea4a9d21ce6301d243a8c2b3bd06d39a397.svn-base +++ /dev/null @@ -1,27 +0,0 @@ -// Test reported by sterowang, Variable attribute defines conflict with function. -/* -What steps will reproduce the problem? -1. function a (){}; -2. b = {}; -3. b.a = {}; -4. a(); - -What is the expected output? What do you see instead? -Function "a" should be called. But the error message "Error Expecting 'a' -to be a function at (line: 1, col: 1)" received. - -What version of the product are you using? On what operating system? -Version 1.6 is used on Cent OS 5.4 - - -Please provide any additional information below. -When using dump() to show symbols, found the function "a" is reassigned to -"{}" by "b.a = {};" call. -*/ - -function a (){}; -b = {}; -b.a = {}; -a(); - -result = 1; diff --git a/.svn/wc.db b/.svn/wc.db deleted file mode 100644 index ce35f7ecd94d5cd4df8982faa2869e1f73605b8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcwPel00001 literal 69632 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 bD1BK-_Y7JTY3xfF#;u$lSq$Um`}6-F))l=? -- 2.11.4.GIT