An implementation of Q floating point format over C++
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 

162 lignes
5.6 KiB

/*
* TinyJS
*
* A single-file Javascript-alike engine
*
* Authored By Gordon Williams <gw@pur3.co.uk>
*
* Copyright (C) 2009 Pur3 Ltd
*
* 42TinyJS
*
* A fork of TinyJS with the goal to makes a more JavaScript/ECMA compliant engine
*
* Authored / Changed By Armin Diedering <armin@diedering.de>
*
* Copyright (C) 2010-2014 ardisoft
*
*
* 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 <math.h>
#include <cstdlib>
#include <sstream>
#include <time.h>
#include "TinyJS/TinyJS.h"
using namespace std;
// ----------------------------------------------- Actual Functions
static void scTrace(const CFunctionsScopePtr &c, void * userdata) {
CTinyJS *js = (CTinyJS*)userdata;
if(c->getArgumentsLength())
c->getArgument(0)->trace();
else
js->getRoot()->trace("root");
}
static void scObjectDump(const CFunctionsScopePtr &c, void *) {
c->getArgument("this")->trace("> ");
}
static void scObjectClone(const CFunctionsScopePtr &c, void *) {
CScriptVarPtr obj = c->getArgument("this");
c->setReturnVar(obj->clone());
}
/*
static void scIntegerValueOf(const CFunctionsScopePtr &c, void *) {
string str = c->getArgument("str")->toString();
int val = 0;
if (str.length()==1)
val = str.operator[](0);
c->setReturnVar(c->newScriptVar(val));
}
*/
static void scJSONStringify(const CFunctionsScopePtr &c, void *) {
uint32_t UniqueID = c->getContext()->allocUniqueID();
bool hasRecursion=false;
c->setReturnVar(c->newScriptVar(c->getArgument("obj")->getParsableString("", " ", UniqueID, hasRecursion)));
c->getContext()->freeUniqueID();
if(hasRecursion) c->throwError(TypeError, "cyclic object value");
}
static void scArrayContains(const CFunctionsScopePtr &c, void *data) {
CScriptVarPtr obj = c->getArgument("obj");
CScriptVarPtr arr = c->getArgument("this");
int l = arr->getArrayLength();
CScriptVarPtr equal = c->constScriptVar(Undefined);
for (int i=0;i<l;i++) {
equal = obj->mathsOp(arr->getArrayIndex(i), LEX_EQUAL);
if(equal->toBoolean()) {
c->setReturnVar(c->constScriptVar(true));
return;
}
}
c->setReturnVar(c->constScriptVar(false));
}
static void scArrayRemove(const CFunctionsScopePtr &c, void *data) {
CScriptVarPtr obj = c->getArgument("obj");
CScriptVarPtr arr = c->getArgument("this");
int i;
vector<int> removedIndices;
int l = arr->getArrayLength();
CScriptVarPtr equal = c->constScriptVar(Undefined);
for (i=0;i<l;i++) {
equal = obj->mathsOp(arr->getArrayIndex(i), LEX_EQUAL);
if(equal->toBoolean()) {
removedIndices.push_back(i);
}
}
if(removedIndices.size()) {
vector<int>::iterator remove_it = removedIndices.begin();
int next_remove = *remove_it;
int next_insert = *remove_it++;
for (i=next_remove;i<l;i++) {
CScriptVarLinkPtr link = arr->findChild(int2string(i));
if(i == next_remove) {
if(link) arr->removeLink(link);
if(remove_it != removedIndices.end())
next_remove = *remove_it++;
} else {
if(link) {
arr->setArrayIndex(next_insert++, link);
arr->removeLink(link);
}
}
}
}
}
static void scArrayJoin(const CFunctionsScopePtr &c, void *data) {
string sep = c->getArgument("separator")->toString();
CScriptVarPtr arr = c->getArgument("this");
ostringstream sstr;
int l = arr->getArrayLength();
for (int i=0;i<l;i++) {
if (i>0) sstr << sep;
sstr << arr->getArrayIndex(i)->toString();
}
c->setReturnVar(c->newScriptVar(sstr.str()));
}
// ----------------------------------------------- Register Functions
void registerFunctions(CTinyJS *tinyJS) {
}
extern "C" void _registerFunctions(CTinyJS *tinyJS) {
tinyJS->addNative("function trace()", scTrace, tinyJS, SCRIPTVARLINK_BUILDINDEFAULT);
tinyJS->addNative("function Object.prototype.dump()", scObjectDump, 0, SCRIPTVARLINK_BUILDINDEFAULT);
tinyJS->addNative("function Object.prototype.clone()", scObjectClone, 0, SCRIPTVARLINK_BUILDINDEFAULT);
// tinyJS->addNative("function Integer.valueOf(str)", scIntegerValueOf, 0, SCRIPTVARLINK_BUILDINDEFAULT); // value of a single character
tinyJS->addNative("function JSON.stringify(obj, replacer)", scJSONStringify, 0, SCRIPTVARLINK_BUILDINDEFAULT); // convert to JSON. replacer is ignored at the moment
tinyJS->addNative("function Array.prototype.contains(obj)", scArrayContains, 0, SCRIPTVARLINK_BUILDINDEFAULT);
tinyJS->addNative("function Array.prototype.remove(obj)", scArrayRemove, 0, SCRIPTVARLINK_BUILDINDEFAULT);
tinyJS->addNative("function Array.prototype.join(separator)", scArrayJoin, 0, SCRIPTVARLINK_BUILDINDEFAULT);
}