TinyJS on mbed. TinyJS is very simple JavaScript engine.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TinyJS_Functions.cpp Source File

TinyJS_Functions.cpp

00001 /*
00002  * TinyJS
00003  *
00004  * A single-file Javascript-alike engine
00005  *
00006  * - Useful language functions
00007  *
00008  * Authored By Gordon Williams <gw@pur3.co.uk>
00009  *
00010  * Copyright (C) 2009 Pur3 Ltd
00011  *
00012  * Permission is hereby granted, free of charge, to any person obtaining a copy of
00013  * this software and associated documentation files (the "Software"), to deal in
00014  * the Software without restriction, including without limitation the rights to
00015  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
00016  * of the Software, and to permit persons to whom the Software is furnished to do
00017  * so, subject to the following conditions:
00018 
00019  * The above copyright notice and this permission notice shall be included in all
00020  * copies or substantial portions of the Software.
00021 
00022  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00023  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00024  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00025  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00026  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00027  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00028  * SOFTWARE.
00029  */
00030 
00031 #include "TinyJS_Functions.h"
00032 #include <math.h>
00033 #include <cstdlib>
00034 #include <sstream>
00035 
00036 using namespace std;
00037 // ----------------------------------------------- Actual Functions
00038 void scTrace(CScriptVar *c, void *userdata) {
00039     CTinyJS *js = (CTinyJS*)userdata;
00040     js->root->trace();
00041 }
00042 
00043 void scObjectDump(CScriptVar *c, void *) {
00044     c->getParameter("this")->trace("> ");
00045 }
00046 
00047 void scObjectClone(CScriptVar *c, void *) {
00048     CScriptVar *obj = c->getParameter("this");
00049     c->getReturnVar()->copyValue(obj);
00050 }
00051 
00052 void scMathRand(CScriptVar *c, void *) {
00053     c->getReturnVar()->setDouble((double)rand()/RAND_MAX);
00054 }
00055 
00056 void scMathRandInt(CScriptVar *c, void *) {
00057     int min = c->getParameter("min")->getInt();
00058     int max = c->getParameter("max")->getInt();
00059     int val = min + (int)(rand()%(1+max-min));
00060     c->getReturnVar()->setInt(val);
00061 }
00062 
00063 void scCharToInt(CScriptVar *c, void *) {
00064     string str = c->getParameter("ch")->getString();;
00065     int val = 0;
00066     if (str.length()>0)
00067         val = (int)str.c_str()[0];
00068     c->getReturnVar()->setInt(val);
00069 }
00070 
00071 void scStringIndexOf(CScriptVar *c, void *) {
00072     string str = c->getParameter("this")->getString();
00073     string search = c->getParameter("search")->getString();
00074     size_t p = str.find(search);
00075     int val = (p==string::npos) ? -1 : p;
00076     c->getReturnVar()->setInt(val);
00077 }
00078 
00079 void scStringSubstring(CScriptVar *c, void *) {
00080     string str = c->getParameter("this")->getString();
00081     int lo = c->getParameter("lo")->getInt();
00082     int hi = c->getParameter("hi")->getInt();
00083 
00084     int l = hi-lo;
00085     if (l>0 && lo>=0 && lo+l<=(int)str.length())
00086       c->getReturnVar()->setString(str.substr(lo, l));
00087     else
00088       c->getReturnVar()->setString("");
00089 }
00090 
00091 void scStringCharAt(CScriptVar *c, void *) {
00092     string str = c->getParameter("this")->getString();
00093     int p = c->getParameter("pos")->getInt();
00094     if (p>=0 && p<(int)str.length())
00095       c->getReturnVar()->setString(str.substr(p, 1));
00096     else
00097       c->getReturnVar()->setString("");
00098 }
00099 
00100 void scStringCharCodeAt(CScriptVar *c, void *) {
00101     string str = c->getParameter("this")->getString();
00102     int p = c->getParameter("pos")->getInt();
00103     if (p>=0 && p<(int)str.length())
00104       c->getReturnVar()->setInt(str.at(p));
00105     else
00106       c->getReturnVar()->setInt(0);
00107 }
00108 
00109 void scStringSplit(CScriptVar *c, void *) {
00110     string str = c->getParameter("this")->getString();
00111     string sep = c->getParameter("separator")->getString();
00112     CScriptVar *result = c->getReturnVar();
00113     result->setArray();
00114     int length = 0;
00115 
00116     size_t pos = str.find(sep);
00117     while (pos != string::npos) {
00118       result->setArrayIndex(length++, new CScriptVar(str.substr(0,pos)));
00119       str = str.substr(pos+1);
00120       pos = str.find(sep);
00121     }
00122 
00123     if (str.size()>0)
00124       result->setArrayIndex(length++, new CScriptVar(str));
00125 }
00126 
00127 void scStringFromCharCode(CScriptVar *c, void *) {
00128     char str[2];
00129     str[0] = c->getParameter("char")->getInt();
00130     str[1] = 0;
00131     c->getReturnVar()->setString(str);
00132 }
00133 
00134 void scIntegerParseInt(CScriptVar *c, void *) {
00135     string str = c->getParameter("str")->getString();
00136     int val = strtol(str.c_str(),0,0);
00137     c->getReturnVar()->setInt(val);
00138 }
00139 
00140 void scIntegerValueOf(CScriptVar *c, void *) {
00141     string str = c->getParameter("str")->getString();
00142 
00143     int val = 0;
00144     if (str.length()==1)
00145       val = str[0];
00146     c->getReturnVar()->setInt(val);
00147 }
00148 
00149 void scJSONStringify(CScriptVar *c, void *) {
00150 #ifndef MBED
00151     std::ostringstream result;
00152     c->getParameter("obj")->getJSON(result);
00153     c->getReturnVar()->setString(result.str());
00154 #else
00155     std::string result;
00156     c->getParameter("obj")->getJSON(result);
00157     c->getReturnVar()->setString(result);
00158 #endif
00159 }
00160 
00161 void scExec(CScriptVar *c, void *data) {
00162     CTinyJS *tinyJS = (CTinyJS *)data;
00163     std::string str = c->getParameter("jsCode")->getString();
00164     tinyJS->execute(str);
00165 }
00166 
00167 void scEval(CScriptVar *c, void *data) {
00168     CTinyJS *tinyJS = (CTinyJS *)data;
00169     std::string str = c->getParameter("jsCode")->getString();
00170     c->setReturnVar(tinyJS->evaluateComplex(str).var);
00171 }
00172 
00173 void scArrayContains(CScriptVar *c, void *data) {
00174   CScriptVar *obj = c->getParameter("obj");
00175   CScriptVarLink *v = c->getParameter("this")->firstChild;
00176 
00177   bool contains = false;
00178   while (v) {
00179       if (v->var->equals(obj)) {
00180         contains = true;
00181         break;
00182       }
00183       v = v->nextSibling;
00184   }
00185 
00186   c->getReturnVar()->setInt(contains);
00187 }
00188 
00189 void scArrayRemove(CScriptVar *c, void *data) {
00190   CScriptVar *obj = c->getParameter("obj");
00191   vector<int> removedIndices;
00192   CScriptVarLink *v;
00193   // remove
00194   v = c->getParameter("this")->firstChild;
00195   while (v) {
00196       if (v->var->equals(obj)) {
00197         removedIndices.push_back(v->getIntName());
00198       }
00199       v = v->nextSibling;
00200   }
00201   // renumber
00202   v = c->getParameter("this")->firstChild;
00203   while (v) {
00204       int n = v->getIntName();
00205       int newn = n;
00206       for (size_t i=0;i<removedIndices.size();i++)
00207         if (n>=removedIndices[i])
00208           newn--;
00209       if (newn!=n)
00210         v->setIntName(newn);
00211       v = v->nextSibling;
00212   }
00213 }
00214 
00215 void scArrayJoin(CScriptVar *c, void *data) {
00216   string sep = c->getParameter("separator")->getString();
00217   CScriptVar *arr = c->getParameter("this");
00218 
00219   ostringstream sstr;
00220   int l = arr->getArrayLength();
00221   for (int i=0;i<l;i++) {
00222     if (i>0) sstr << sep;
00223     sstr << arr->getArrayIndex(i)->getString();
00224   }
00225 
00226   c->getReturnVar()->setString(sstr.str());
00227 }
00228 
00229 // ----------------------------------------------- Register Functions
00230 void registerFunctions(CTinyJS *tinyJS) {
00231     tinyJS->addNative("function exec(jsCode)", scExec, tinyJS); // execute the given code
00232     tinyJS->addNative("function eval(jsCode)", scEval, tinyJS); // execute the given string (an expression) and return the result
00233     tinyJS->addNative("function trace()", scTrace, tinyJS);
00234     tinyJS->addNative("function Object.dump()", scObjectDump, 0);
00235     tinyJS->addNative("function Object.clone()", scObjectClone, 0);
00236     tinyJS->addNative("function Math.rand()", scMathRand, 0);
00237     tinyJS->addNative("function Math.randInt(min, max)", scMathRandInt, 0);
00238     tinyJS->addNative("function charToInt(ch)", scCharToInt, 0); //  convert a character to an int - get its value
00239     tinyJS->addNative("function String.indexOf(search)", scStringIndexOf, 0); // find the position of a string in a string, -1 if not
00240     tinyJS->addNative("function String.substring(lo,hi)", scStringSubstring, 0);
00241     tinyJS->addNative("function String.charAt(pos)", scStringCharAt, 0);
00242     tinyJS->addNative("function String.charCodeAt(pos)", scStringCharCodeAt, 0);
00243     tinyJS->addNative("function String.fromCharCode(char)", scStringFromCharCode, 0);
00244     tinyJS->addNative("function String.split(separator)", scStringSplit, 0);
00245     tinyJS->addNative("function Integer.parseInt(str)", scIntegerParseInt, 0); // string to int
00246     tinyJS->addNative("function Integer.valueOf(str)", scIntegerValueOf, 0); // value of a single character
00247     tinyJS->addNative("function JSON.stringify(obj, replacer)", scJSONStringify, 0); // convert to JSON. replacer is ignored at the moment
00248     // JSON.parse is left out as you can (unsafely!) use eval instead
00249     tinyJS->addNative("function Array.contains(obj)", scArrayContains, 0);
00250     tinyJS->addNative("function Array.remove(obj)", scArrayRemove, 0);
00251     tinyJS->addNative("function Array.join(separator)", scArrayJoin, 0);
00252 }
00253 
00254