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 |
|
---|