Fixed broken string encoding in getJSString() Removed getInitCode and added getJSON instead Added nil Added rough JSON parsing Improved example appmaster
parent
a3c6d28059
commit
f9e358d3b8
@ -1,62 +1,71 @@
|
||||
/*
|
||||
* TinyJS
|
||||
*
|
||||
* A single-file Javascript-alike engine
|
||||
*
|
||||
* Authored By Gordon Williams <gw@pur3.co.uk>
|
||||
*
|
||||
* Copyright (C) 2009 Pur3 Ltd
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* TinyJS
|
||||
*
|
||||
* A single-file Javascript-alike engine
|
||||
*
|
||||
* Authored By Gordon Williams <gw@pur3.co.uk>
|
||||
*
|
||||
* Copyright (C) 2009 Pur3 Ltd
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a simple program showing how to use TinyJS
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "TinyJS.h"
|
||||
#include "TinyJS_Functions.h"
|
||||
|
||||
//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) {
|
||||
printf("> %s\n", v->findChild("text")->getString().c_str());
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a simple program showing how to use TinyJS
|
||||
*/
|
||||
void js_dump(CScriptVar *v) {
|
||||
v->getRoot()->trace("> ");
|
||||
}
|
||||
|
||||
#include <assert.h>
|
||||
#include "TinyJS.h"
|
||||
#include "TinyJS_Functions.h"
|
||||
|
||||
//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) {
|
||||
printf(">%s\n", v->findChild("text")->getString().c_str());
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
try {
|
||||
CTinyJS s;
|
||||
|
||||
/* add the functions from TinyJS_Functions.cpp */
|
||||
registerFunctions(&s);
|
||||
/* Add a native function */
|
||||
s.addNative("function print(text)", &js_print);
|
||||
/* Execute out bit of code - we could call 'evaluate' here if
|
||||
we wanted something returned */
|
||||
s.execute(code);
|
||||
|
||||
printf("Symbol table contents:\n");
|
||||
s.trace();
|
||||
} catch (CScriptException *e) {
|
||||
printf("ERROR: %s\n", e->text.c_str());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
CTinyJS s;
|
||||
/* add the functions from TinyJS_Functions.cpp */
|
||||
registerFunctions(&s);
|
||||
/* Add a native function */
|
||||
s.addNative("function print(text)", &js_print);
|
||||
s.addNative("function dump()", &js_dump);
|
||||
/* Execute out bit of code - we could call 'evaluate' here if
|
||||
we wanted something returned */
|
||||
s.execute("var lets_quit = 0; function quit() { lets_quit = 1; }");
|
||||
s.execute("print(\"Interactive mode... Type quit(); to exit, or print(...); to print something, or dump() to dump the symbol table!\");");
|
||||
|
||||
while (s.evaluate("lets_quit") == "0") {
|
||||
char buffer[2048];
|
||||
fgets ( buffer, sizeof(buffer), stdin );
|
||||
try {
|
||||
s.execute(buffer);
|
||||
} catch (CScriptException *e) {
|
||||
printf("ERROR: %s\n", e->text.c_str());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,228 +1,231 @@
|
||||
/*
|
||||
* TinyJS
|
||||
*
|
||||
* A single-file Javascript-alike engine
|
||||
*
|
||||
* Authored By Gordon Williams <gw@pur3.co.uk>
|
||||
*
|
||||
* Copyright (C) 2009 Pur3 Ltd
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef TINYJS_H
|
||||
#define TINYJS_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#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_NEQUAL,
|
||||
LEX_LEQUAL,
|
||||
LEX_GEQUAL,
|
||||
LEX_PLUSEQUAL,
|
||||
LEX_MINUSEQUAL,
|
||||
LEX_PLUSPLUS,
|
||||
LEX_MINUSMINUS,
|
||||
LEX_ANDAND,
|
||||
LEX_OROR,
|
||||
// reserved words
|
||||
LEX_R_IF,
|
||||
LEX_R_ELSE,
|
||||
LEX_R_WHILE,
|
||||
LEX_R_FOR,
|
||||
LEX_R_FUNCTION,
|
||||
LEX_R_RETURN,
|
||||
LEX_R_VAR,
|
||||
LEX_R_TRUE,
|
||||
LEX_R_FALSE,
|
||||
};
|
||||
|
||||
enum SCRIPTVAR_FLAGS {
|
||||
SCRIPTVAR_FUNCTION = 1,
|
||||
SCRIPTVAR_NATIVE = 2,
|
||||
SCRIPTVAR_NUMERIC = 4,
|
||||
SCRIPTVAR_INTEGER = 8, // eg. not floating point
|
||||
SCRIPTVAR_VARTYPEMASK = 12,
|
||||
SCRIPTVAR_PARAMETER = 16
|
||||
};
|
||||
|
||||
#define TINYJS_RETURN_VAR "return"
|
||||
#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 tokenPosition; ///< Position in the data at the beginning of the token we have here
|
||||
std::string tkStr; ///< Data contained in the token we have here
|
||||
|
||||
void match(int expected_tk); ///< Lexical match wotsit
|
||||
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); ///< 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
|
||||
|
||||
void getNextCh();
|
||||
void getNextToken(); ///< Get the text token from our text string
|
||||
};
|
||||
|
||||
class CScriptVar;
|
||||
|
||||
typedef void (*JSCallback)(CScriptVar *var);
|
||||
|
||||
/// Variable class (containing a doubly-linked list of children)
|
||||
class CScriptVar
|
||||
{
|
||||
public:
|
||||
CScriptVar(void);
|
||||
CScriptVar(std::string varName, std::string varData=TINYJS_BLANK_DATA, int varFlags = 0);
|
||||
CScriptVar(double varData);
|
||||
CScriptVar(int val);
|
||||
~CScriptVar(void);
|
||||
|
||||
CScriptVar *findChild(std::string childName); ///< Tries to find a child with the given name, may return 0
|
||||
CScriptVar *getChild(std::string childName); ///< Gets a child with the given name, produces error on fail
|
||||
CScriptVar *findRecursive(std::string childName); ///< Finds a child, looking recursively up the tree
|
||||
void addChild(CScriptVar *child);
|
||||
CScriptVar *addChildNoDup(CScriptVar *child); ///< add a child overwriting any with the same name
|
||||
void removeChild(CScriptVar *child);
|
||||
void removeAllChildren();
|
||||
CScriptVar *getRoot(); ///< Get the absolute root of the tree
|
||||
|
||||
std::string getName();
|
||||
int getInt();
|
||||
bool getBool() { return getInt() != 0; }
|
||||
double getDouble();
|
||||
std::string &getString();
|
||||
void setInt(int num);
|
||||
void setDouble(double val);
|
||||
void setString(std::string str);
|
||||
void setVoid();
|
||||
|
||||
bool isInt() { return (flags&SCRIPTVAR_NUMERIC)!=0 && (flags&SCRIPTVAR_INTEGER)!=0; }
|
||||
bool isDouble() { return (flags&SCRIPTVAR_NUMERIC)!=0 && (flags&SCRIPTVAR_INTEGER)==0; }
|
||||
bool isNumeric() { return (flags&SCRIPTVAR_NUMERIC)!=0; }
|
||||
bool isFunction() { return (flags&SCRIPTVAR_FUNCTION)!=0; }
|
||||
bool isParameter() { return (flags&SCRIPTVAR_PARAMETER)!=0; }
|
||||
bool isNative() { return (flags&SCRIPTVAR_NATIVE)!=0; }
|
||||
|
||||
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 = ""); ///< Dump out the contents of this using trace
|
||||
void getInitialiseCode(std::ostringstream &destination, const std::string &prefix = ""); ///< Write out all the JS code needed to recreate this script variable to the stream
|
||||
void setCallback(JSCallback callback);
|
||||
|
||||
CScriptVar *firstChild;
|
||||
CScriptVar *lastChild;
|
||||
CScriptVar *nextSibling;
|
||||
CScriptVar *prevSibling;
|
||||
CScriptVar *parent;
|
||||
protected:
|
||||
std::string name;
|
||||
std::string data;
|
||||
int flags;
|
||||
JSCallback jsCallback;
|
||||
|
||||
void init(); // initilisation of data members
|
||||
|
||||
friend class CTinyJS;
|
||||
};
|
||||
|
||||
class CTinyJS {
|
||||
public:
|
||||
CTinyJS();
|
||||
~CTinyJS();
|
||||
|
||||
void execute(const std::string &code);
|
||||
std::string evaluate(const std::string &code);
|
||||
|
||||
/// add a function to the root scope
|
||||
/** example:
|
||||
\code
|
||||
void scRandInt(CScriptVar *c) { ... }
|
||||
tinyJS->addNative("function randInt(min, max)", scRandInt);
|
||||
\endcode
|
||||
*/
|
||||
void addNative(const std::string &funcDesc, JSCallback ptr);
|
||||
|
||||
/// Get the value of the given variable, or return 0
|
||||
std::string *getVariable(const std::string &path);
|
||||
|
||||
/// Send all variables to stdout
|
||||
void trace();
|
||||
|
||||
CScriptVar *root; /// root of symbol table
|
||||
private:
|
||||
CScriptLex *l; /// current lexer
|
||||
CScriptVar *symbol_base; /// current symbol table base
|
||||
|
||||
// parsing - in order of precedence
|
||||
CScriptVar *factor(bool &execute);
|
||||
CScriptVar *unary(bool &execute);
|
||||
CScriptVar *term(bool &execute);
|
||||
CScriptVar *expression(bool &execute);
|
||||
CScriptVar *condition(bool &execute);
|
||||
CScriptVar *logic(bool &execute);
|
||||
CScriptVar *base(bool &execute);
|
||||
void block(bool &execute);
|
||||
void statement(bool &execute);
|
||||
};
|
||||
|
||||
#endif
|
||||
/*
|
||||
* TinyJS
|
||||
*
|
||||
* A single-file Javascript-alike engine
|
||||
*
|
||||
* Authored By Gordon Williams <gw@pur3.co.uk>
|
||||
*
|
||||
* Copyright (C) 2009 Pur3 Ltd
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef TINYJS_H
|
||||
#define TINYJS_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#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_NEQUAL,
|
||||
LEX_LEQUAL,
|
||||
LEX_GEQUAL,
|
||||
LEX_PLUSEQUAL,
|
||||
LEX_MINUSEQUAL,
|
||||
LEX_PLUSPLUS,
|
||||
LEX_MINUSMINUS,
|
||||
LEX_ANDAND,
|
||||
LEX_OROR,
|
||||
// reserved words
|
||||
LEX_R_IF,
|
||||
LEX_R_ELSE,
|
||||
LEX_R_WHILE,
|
||||
LEX_R_FOR,
|
||||
LEX_R_FUNCTION,
|
||||
LEX_R_RETURN,
|
||||
LEX_R_VAR,
|
||||
LEX_R_TRUE,
|
||||
LEX_R_FALSE,
|
||||
LEX_R_NIL,
|
||||
};
|
||||
|
||||
enum SCRIPTVAR_FLAGS {
|
||||
SCRIPTVAR_FUNCTION = 1,
|
||||
SCRIPTVAR_NATIVE = 2,
|
||||
SCRIPTVAR_NUMERIC = 4,
|
||||
SCRIPTVAR_INTEGER = 8, // eg. not floating point
|
||||
SCRIPTVAR_VARTYPEMASK = 12,
|
||||
SCRIPTVAR_PARAMETER = 16
|
||||
};
|
||||
|
||||
#define TINYJS_RETURN_VAR "return"
|
||||
#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 tokenPosition; ///< Position in the data at the beginning of the token we have here
|
||||
std::string tkStr; ///< Data contained in the token we have here
|
||||
|
||||
void match(int expected_tk); ///< Lexical match wotsit
|
||||
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); ///< 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
|
||||
|
||||
void getNextCh();
|
||||
void getNextToken(); ///< Get the text token from our text string
|
||||
};
|
||||
|
||||
class CScriptVar;
|
||||
|
||||
typedef void (*JSCallback)(CScriptVar *var);
|
||||
|
||||
/// Variable class (containing a doubly-linked list of children)
|
||||
class CScriptVar
|
||||
{
|
||||
public:
|
||||
CScriptVar(void);
|
||||
CScriptVar(std::string varName, std::string varData=TINYJS_BLANK_DATA, int varFlags = 0);
|
||||
CScriptVar(double varData);
|
||||
CScriptVar(int val);
|
||||
~CScriptVar(void);
|
||||
|
||||
CScriptVar *findChild(const std::string &childName); ///< Tries to find a child with the given name, may return 0
|
||||
CScriptVar *findChildOrCreate(const std::string &childName); ///< Tries to find a child with the given name, or will create it
|
||||
CScriptVar *findRecursive(const std::string &childName); ///< Finds a child, looking recursively up the tree
|
||||
void addChild(CScriptVar *child);
|
||||
void addNamedChild(const std::string &childName, CScriptVar *child); ///< add the named child. if it is already owned, copy it.
|
||||
CScriptVar *addChildNoDup(CScriptVar *child); ///< add a child overwriting any with the same name
|
||||
void removeChild(CScriptVar *child);
|
||||
void removeAllChildren();
|
||||
CScriptVar *getRoot(); ///< Get the absolute root of the tree
|
||||
|
||||
const std::string &getName();
|
||||
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 setVoid();
|
||||
|
||||
bool isInt() { return (flags&SCRIPTVAR_NUMERIC)!=0 && (flags&SCRIPTVAR_INTEGER)!=0; }
|
||||
bool isDouble() { return (flags&SCRIPTVAR_NUMERIC)!=0 && (flags&SCRIPTVAR_INTEGER)==0; }
|
||||
bool isNumeric() { return (flags&SCRIPTVAR_NUMERIC)!=0; }
|
||||
bool isFunction() { return (flags&SCRIPTVAR_FUNCTION)!=0; }
|
||||
bool isParameter() { return (flags&SCRIPTVAR_PARAMETER)!=0; }
|
||||
bool isNative() { return (flags&SCRIPTVAR_NATIVE)!=0; }
|
||||
|
||||
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 = ""); ///< Dump out the contents of this using trace
|
||||
void getJSON(std::ostringstream &destination); ///< Write out all the JS code needed to recreate this script variable to the stream (as JSON)
|
||||
void setCallback(JSCallback callback);
|
||||
|
||||
CScriptVar *firstChild;
|
||||
CScriptVar *lastChild;
|
||||
CScriptVar *nextSibling;
|
||||
CScriptVar *prevSibling;
|
||||
CScriptVar *parent;
|
||||
protected:
|
||||
std::string name;
|
||||
std::string data;
|
||||
int flags;
|
||||
JSCallback jsCallback;
|
||||
|
||||
void init(); // initilisation of data members
|
||||
|
||||
friend class CTinyJS;
|
||||
};
|
||||
|
||||
class CTinyJS {
|
||||
public:
|
||||
CTinyJS();
|
||||
~CTinyJS();
|
||||
|
||||
void execute(const std::string &code);
|
||||
std::string evaluate(const std::string &code);
|
||||
|
||||
/// add a function to the root scope
|
||||
/** example:
|
||||
\code
|
||||
void scRandInt(CScriptVar *c) { ... }
|
||||
tinyJS->addNative("function randInt(min, max)", scRandInt);
|
||||
\endcode
|
||||
*/
|
||||
void addNative(const std::string &funcDesc, JSCallback ptr);
|
||||
|
||||
/// Get the value of the given variable, or return 0
|
||||
const std::string *getVariable(const std::string &path);
|
||||
|
||||
/// Send all variables to stdout
|
||||
void trace();
|
||||
|
||||
CScriptVar *root; /// root of symbol table
|
||||
private:
|
||||
CScriptLex *l; /// current lexer
|
||||
CScriptVar *symbol_base; /// current symbol table base
|
||||
|
||||
// parsing - in order of precedence
|
||||
CScriptVar *factor(bool &execute);
|
||||
CScriptVar *unary(bool &execute);
|
||||
CScriptVar *term(bool &execute);
|
||||
CScriptVar *expression(bool &execute);
|
||||
CScriptVar *condition(bool &execute);
|
||||
CScriptVar *logic(bool &execute);
|
||||
CScriptVar *base(bool &execute);
|
||||
void block(bool &execute);
|
||||
void statement(bool &execute);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,86 +1,86 @@
|
||||
/*
|
||||
* TinyJS
|
||||
*
|
||||
* A single-file Javascript-alike engine
|
||||
*
|
||||
* Authored By Gordon Williams <gw@pur3.co.uk>
|
||||
*
|
||||
* Copyright (C) 2009 Pur3 Ltd
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "TinyJS_Functions.h"
|
||||
#include <math.h>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
// ----------------------------------------------- Actual Functions
|
||||
|
||||
void scTrace(CScriptVar *c) {
|
||||
while (c->parent) c = c->parent;
|
||||
c->trace();
|
||||
}
|
||||
|
||||
void scRand(CScriptVar *c) {
|
||||
c->getChild(TINYJS_RETURN_VAR)->setDouble((double)rand()/RAND_MAX);
|
||||
}
|
||||
|
||||
void scRandInt(CScriptVar *c) {
|
||||
int min = c->getChild("min")->getInt();
|
||||
int max = c->getChild("max")->getInt();
|
||||
int val = min + (int)((long)rand()*(1+max-min)/RAND_MAX);
|
||||
if (val>max) val=max;
|
||||
c->getChild(TINYJS_RETURN_VAR)->setInt(val);
|
||||
}
|
||||
|
||||
void scCharToInt(CScriptVar *c) {
|
||||
string str = c->getChild("ch")->getString();;
|
||||
int val = 0;
|
||||
if (str.length()>0)
|
||||
val = (int)str.c_str()[0];
|
||||
c->getChild(TINYJS_RETURN_VAR)->setInt(val);
|
||||
}
|
||||
|
||||
void scStrLen(CScriptVar *c) {
|
||||
string str = c->getChild("str")->getString();;
|
||||
int val = str.length();
|
||||
c->getChild(TINYJS_RETURN_VAR)->setInt(val);
|
||||
}
|
||||
|
||||
void scStrPos(CScriptVar *c) {
|
||||
string str = c->getChild("string")->getString();
|
||||
string search = c->getChild("search")->getString();
|
||||
size_t p = str.find(search);
|
||||
int val = (p==string::npos) ? -1 : p;
|
||||
c->getChild(TINYJS_RETURN_VAR)->setInt(val);
|
||||
}
|
||||
|
||||
void scAtoi(CScriptVar *c) {
|
||||
int val = c->getChild("str")->getInt();
|
||||
c->getChild(TINYJS_RETURN_VAR)->setInt(val);
|
||||
}
|
||||
|
||||
// ----------------------------------------------- Register Functions
|
||||
void registerFunctions(CTinyJS *tinyJS) {
|
||||
tinyJS->addNative("function trace()", scTrace);
|
||||
tinyJS->addNative("function rand()", scRand);
|
||||
tinyJS->addNative("function randInt(min, max)", scRandInt);
|
||||
tinyJS->addNative("function charToInt(ch)", scCharToInt); // convert a character to an int - get its value
|
||||
tinyJS->addNative("function strlen(str)", scStrLen); // length of a string
|
||||
tinyJS->addNative("function strpos(string,search)", scStrPos); // find the position of a string in a string, -1 if not
|
||||
tinyJS->addNative("function atoi(str)", scAtoi); // string to int
|
||||
}
|
||||
/*
|
||||
* TinyJS
|
||||
*
|
||||
* A single-file Javascript-alike engine
|
||||
*
|
||||
* Authored By Gordon Williams <gw@pur3.co.uk>
|
||||
*
|
||||
* Copyright (C) 2009 Pur3 Ltd
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "TinyJS_Functions.h"
|
||||
#include <math.h>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
// ----------------------------------------------- Actual Functions
|
||||
|
||||
void scTrace(CScriptVar *c) {
|
||||
while (c->parent) c = c->parent;
|
||||
c->trace();
|
||||
}
|
||||
|
||||
void scRand(CScriptVar *c) {
|
||||
c->findChildOrCreate(TINYJS_RETURN_VAR)->setDouble((double)rand()/RAND_MAX);
|
||||
}
|
||||
|
||||
void scRandInt(CScriptVar *c) {
|
||||
int min = c->findChildOrCreate("min")->getInt();
|
||||
int max = c->findChildOrCreate("max")->getInt();
|
||||
int val = min + (int)((long)rand()*(1+max-min)/RAND_MAX);
|
||||
if (val>max) val=max;
|
||||
c->findChildOrCreate(TINYJS_RETURN_VAR)->setInt(val);
|
||||
}
|
||||
|
||||
void scCharToInt(CScriptVar *c) {
|
||||
string str = c->findChildOrCreate("ch")->getString();;
|
||||
int val = 0;
|
||||
if (str.length()>0)
|
||||
val = (int)str.c_str()[0];
|
||||
c->findChildOrCreate(TINYJS_RETURN_VAR)->setInt(val);
|
||||
}
|
||||
|
||||
void scStrLen(CScriptVar *c) {
|
||||
string str = c->findChildOrCreate("str")->getString();;
|
||||
int val = str.length();
|
||||
c->findChildOrCreate(TINYJS_RETURN_VAR)->setInt(val);
|
||||
}
|
||||
|
||||
void scStrPos(CScriptVar *c) {
|
||||
string str = c->findChildOrCreate("string")->getString();
|
||||
string search = c->findChildOrCreate("search")->getString();
|
||||
size_t p = str.find(search);
|
||||
int val = (p==string::npos) ? -1 : p;
|
||||
c->findChildOrCreate(TINYJS_RETURN_VAR)->setInt(val);
|
||||
}
|
||||
|
||||
void scAtoi(CScriptVar *c) {
|
||||
int val = c->findChildOrCreate("str")->getInt();
|
||||
c->findChildOrCreate(TINYJS_RETURN_VAR)->setInt(val);
|
||||
}
|
||||
|
||||
// ----------------------------------------------- Register Functions
|
||||
void registerFunctions(CTinyJS *tinyJS) {
|
||||
tinyJS->addNative("function trace()", scTrace);
|
||||
tinyJS->addNative("function rand()", scRand);
|
||||
tinyJS->addNative("function randInt(min, max)", scRandInt);
|
||||
tinyJS->addNative("function charToInt(ch)", scCharToInt); // convert a character to an int - get its value
|
||||
tinyJS->addNative("function strlen(str)", scStrLen); // length of a string
|
||||
tinyJS->addNative("function strpos(string,search)", scStrPos); // find the position of a string in a string, -1 if not
|
||||
tinyJS->addNative("function atoi(str)", scAtoi); // string to int
|
||||
}
|
||||
|
@ -1,34 +1,34 @@
|
||||
/*
|
||||
* TinyJS
|
||||
*
|
||||
* A single-file Javascript-alike engine
|
||||
*
|
||||
* Authored By Gordon Williams <gw@pur3.co.uk>
|
||||
*
|
||||
* Copyright (C) 2009 Pur3 Ltd
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef TINYJS_FUNCTIONS_H
|
||||
#define TINYJS_FUNCTIONS_H
|
||||
|
||||
#include "TinyJS.h"
|
||||
|
||||
/// Register useful functions with the TinyJS interpreter
|
||||
extern void registerFunctions(CTinyJS *tinyJS);
|
||||
|
||||
#endif
|
||||
/*
|
||||
* TinyJS
|
||||
*
|
||||
* A single-file Javascript-alike engine
|
||||
*
|
||||
* Authored By Gordon Williams <gw@pur3.co.uk>
|
||||
*
|
||||
* Copyright (C) 2009 Pur3 Ltd
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef TINYJS_FUNCTIONS_H
|
||||
#define TINYJS_FUNCTIONS_H
|
||||
|
||||
#include "TinyJS.h"
|
||||
|
||||
/// Register useful functions with the TinyJS interpreter
|
||||
extern void registerFunctions(CTinyJS *tinyJS);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in new issue