[906] | 1 | /*
|
---|
| 2 | * TinyJS
|
---|
| 3 | *
|
---|
| 4 | * A single-file Javascript-alike engine
|
---|
| 5 | *
|
---|
| 6 | * Authored By Gordon Williams <gw@pur3.co.uk>
|
---|
| 7 | *
|
---|
| 8 | * Copyright (C) 2009 Pur3 Ltd
|
---|
| 9 | *
|
---|
| 10 |
|
---|
| 11 | * 42TinyJS
|
---|
| 12 | *
|
---|
| 13 | * A fork of TinyJS with the goal to makes a more JavaScript/ECMA compliant engine
|
---|
| 14 | *
|
---|
| 15 | * Authored / Changed By Armin Diedering <armin@diedering.de>
|
---|
| 16 | *
|
---|
| 17 | * Copyright (C) 2010-2013 ardisoft
|
---|
| 18 | *
|
---|
| 19 | *
|
---|
| 20 | * Permission is hereby granted, free of charge, to any person obtaining a copy of
|
---|
| 21 | * this software and associated documentation files (the "Software"), to deal in
|
---|
| 22 | * the Software without restriction, including without limitation the rights to
|
---|
| 23 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
---|
| 24 | * of the Software, and to permit persons to whom the Software is furnished to do
|
---|
| 25 | * so, subject to the following conditions:
|
---|
| 26 |
|
---|
| 27 | * The above copyright notice and this permission notice shall be included in all
|
---|
| 28 | * copies or substantial portions of the Software.
|
---|
| 29 |
|
---|
| 30 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
---|
| 31 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
---|
| 32 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
---|
| 33 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
---|
| 34 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
---|
| 35 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
---|
| 36 | * SOFTWARE.
|
---|
| 37 | */
|
---|
| 38 |
|
---|
| 39 |
|
---|
| 40 | #include <math.h>
|
---|
| 41 | #include <cstdlib>
|
---|
| 42 | #include <sstream>
|
---|
| 43 | #include <time.h>
|
---|
| 44 | #include "TinyJS.h"
|
---|
| 45 |
|
---|
| 46 | using namespace std;
|
---|
| 47 | // ----------------------------------------------- Actual Functions
|
---|
| 48 |
|
---|
| 49 | static void scTrace(const CFunctionsScopePtr &c, void * userdata) {
|
---|
| 50 | CTinyJS *js = (CTinyJS*)userdata;
|
---|
| 51 | if(c->getArgumentsLength())
|
---|
| 52 | c->getArgument(0)->trace();
|
---|
| 53 | else
|
---|
| 54 | js->getRoot()->trace("root");
|
---|
| 55 | }
|
---|
| 56 |
|
---|
| 57 | static void scObjectDump(const CFunctionsScopePtr &c, void *) {
|
---|
| 58 | c->getArgument("this")->trace("> ");
|
---|
| 59 | }
|
---|
| 60 |
|
---|
| 61 | static void scObjectClone(const CFunctionsScopePtr &c, void *) {
|
---|
| 62 | CScriptVarPtr obj = c->getArgument("this");
|
---|
| 63 | c->setReturnVar(obj->clone());
|
---|
| 64 | }
|
---|
| 65 |
|
---|
| 66 | static void scIntegerValueOf(const CFunctionsScopePtr &c, void *) {
|
---|
| 67 | string str = c->getArgument("str")->toString();
|
---|
| 68 |
|
---|
| 69 | int val = 0;
|
---|
| 70 | if (str.length()==1)
|
---|
| 71 | val = str.operator[](0);
|
---|
| 72 | c->setReturnVar(c->newScriptVar(val));
|
---|
| 73 | }
|
---|
| 74 |
|
---|
| 75 | static void scJSONStringify(const CFunctionsScopePtr &c, void *) {
|
---|
| 76 | uint32_t UniqueID = c->getContext()->getUniqueID();
|
---|
| 77 | bool hasRecursion=false;
|
---|
| 78 | c->setReturnVar(c->newScriptVar(c->getArgument("obj")->getParsableString("", " ", UniqueID, hasRecursion)));
|
---|
| 79 | if(hasRecursion) c->throwError(TypeError, "cyclic object value");
|
---|
| 80 | }
|
---|
| 81 |
|
---|
| 82 | static void scArrayContains(const CFunctionsScopePtr &c, void *data) {
|
---|
| 83 | CScriptVarPtr obj = c->getArgument("obj");
|
---|
| 84 | CScriptVarPtr arr = c->getArgument("this");
|
---|
| 85 |
|
---|
| 86 | int l = arr->getArrayLength();
|
---|
| 87 | CScriptVarPtr equal = c->constScriptVar(Undefined);
|
---|
| 88 | for (int i=0;i<l;i++) {
|
---|
| 89 | equal = obj->mathsOp(arr->getArrayIndex(i), LEX_EQUAL);
|
---|
| 90 | if(equal->toBoolean()) {
|
---|
| 91 | c->setReturnVar(c->constScriptVar(true));
|
---|
| 92 | return;
|
---|
| 93 | }
|
---|
| 94 | }
|
---|
| 95 | c->setReturnVar(c->constScriptVar(false));
|
---|
| 96 | }
|
---|
| 97 |
|
---|
| 98 | static void scArrayRemove(const CFunctionsScopePtr &c, void *data) {
|
---|
| 99 | CScriptVarPtr obj = c->getArgument("obj");
|
---|
| 100 | CScriptVarPtr arr = c->getArgument("this");
|
---|
| 101 | int i;
|
---|
| 102 | vector<int> removedIndices;
|
---|
| 103 |
|
---|
| 104 | int l = arr->getArrayLength();
|
---|
| 105 | CScriptVarPtr equal = c->constScriptVar(Undefined);
|
---|
| 106 | for (i=0;i<l;i++) {
|
---|
| 107 | equal = obj->mathsOp(arr->getArrayIndex(i), LEX_EQUAL);
|
---|
| 108 | if(equal->toBoolean()) {
|
---|
| 109 | removedIndices.push_back(i);
|
---|
| 110 | }
|
---|
| 111 | }
|
---|
| 112 | if(removedIndices.size()) {
|
---|
| 113 | vector<int>::iterator remove_it = removedIndices.begin();
|
---|
| 114 | int next_remove = *remove_it;
|
---|
| 115 | int next_insert = *remove_it++;
|
---|
| 116 | for (i=next_remove;i<l;i++) {
|
---|
| 117 |
|
---|
| 118 | CScriptVarLinkPtr link = arr->findChild(int2string(i));
|
---|
| 119 | if(i == next_remove) {
|
---|
| 120 | if(link) arr->removeLink(link);
|
---|
| 121 | if(remove_it != removedIndices.end())
|
---|
| 122 | next_remove = *remove_it++;
|
---|
| 123 | } else {
|
---|
| 124 | if(link) {
|
---|
| 125 | arr->setArrayIndex(next_insert++, link);
|
---|
| 126 | arr->removeLink(link);
|
---|
| 127 | }
|
---|
| 128 | }
|
---|
| 129 | }
|
---|
| 130 | }
|
---|
| 131 | }
|
---|
| 132 |
|
---|
| 133 | static void scArrayJoin(const CFunctionsScopePtr &c, void *data) {
|
---|
| 134 | string sep = c->getArgument("separator")->toString();
|
---|
| 135 | CScriptVarPtr arr = c->getArgument("this");
|
---|
| 136 |
|
---|
| 137 | ostringstream sstr;
|
---|
| 138 | int l = arr->getArrayLength();
|
---|
| 139 | for (int i=0;i<l;i++) {
|
---|
| 140 | if (i>0) sstr << sep;
|
---|
| 141 | sstr << arr->getArrayIndex(i)->toString();
|
---|
| 142 | }
|
---|
| 143 |
|
---|
| 144 | c->setReturnVar(c->newScriptVar(sstr.str()));
|
---|
| 145 | }
|
---|
| 146 |
|
---|
| 147 | // ----------------------------------------------- Register Functions
|
---|
| 148 | void registerFunctions(CTinyJS *tinyJS) {
|
---|
| 149 | }
|
---|
| 150 | extern "C" void _registerFunctions(CTinyJS *tinyJS) {
|
---|
| 151 | tinyJS->addNative("function trace()", scTrace, tinyJS, SCRIPTVARLINK_BUILDINDEFAULT);
|
---|
| 152 | tinyJS->addNative("function Object.prototype.dump()", scObjectDump, 0, SCRIPTVARLINK_BUILDINDEFAULT);
|
---|
| 153 | tinyJS->addNative("function Object.prototype.clone()", scObjectClone, 0, SCRIPTVARLINK_BUILDINDEFAULT);
|
---|
| 154 |
|
---|
| 155 | tinyJS->addNative("function Integer.valueOf(str)", scIntegerValueOf, 0, SCRIPTVARLINK_BUILDINDEFAULT); // value of a single character
|
---|
| 156 | tinyJS->addNative("function JSON.stringify(obj, replacer)", scJSONStringify, 0, SCRIPTVARLINK_BUILDINDEFAULT); // convert to JSON. replacer is ignored at the moment
|
---|
| 157 | tinyJS->addNative("function Array.prototype.contains(obj)", scArrayContains, 0, SCRIPTVARLINK_BUILDINDEFAULT);
|
---|
| 158 | tinyJS->addNative("function Array.prototype.remove(obj)", scArrayRemove, 0, SCRIPTVARLINK_BUILDINDEFAULT);
|
---|
| 159 | tinyJS->addNative("function Array.prototype.join(separator)", scArrayJoin, 0, SCRIPTVARLINK_BUILDINDEFAULT);
|
---|
| 160 | }
|
---|
| 161 |
|
---|