Permalink
Browse files

Moved some Js objects implementation in another file.

Renamed Engine.Debug and Engine.Output to lower case to avoid confusion with constants.


git-svn-id: http://yate.null.ro/svn/yate/trunk@5035 acf43c95-373e-0410-b603-e72c3f656dc1
  • Loading branch information...
1 parent 3823269 commit 1eec7eb43b5c8b4726fc4e60f83abc9e4a26999c paulc committed May 2, 2012
Showing with 138 additions and 30 deletions.
  1. +57 −7 libs/yscript/javascript.cpp
  2. +48 −11 libs/yscript/jsobjects.cpp
  3. +21 −5 libs/yscript/yatescript.h
  4. +12 −7 modules/javascript.cpp
@@ -83,6 +83,7 @@ class JsCode : public ScriptCode, public ExpEvaluator
OpcTrue,
OpcFalse,
OpcInclude,
+ OpcRequire,
};
inline JsCode()
: ExpEvaluator(C), m_label(0), m_depth(0)
@@ -99,6 +100,8 @@ class JsCode : public ScriptCode, public ExpEvaluator
virtual bool initialize(ScriptContext* context) const;
virtual bool evaluate(ScriptRun& runner, ObjList& results) const;
bool link();
+ JsObject* parseArray(const char*& expr, bool constOnly);
+ JsObject* parseObject(const char*& expr, bool constOnly);
protected:
virtual bool keywordChar(char c) const;
virtual int getKeyword(const char* str) const;
@@ -118,7 +121,8 @@ class JsCode : public ScriptCode, public ExpEvaluator
virtual bool runAssign(ObjList& stack, const ExpOperation& oper, GenObject* context) const;
private:
ObjVector m_linked;
- bool preProcessInclude(const char*& expr, GenObject* context);
+ ObjList m_included;
+ bool preProcessInclude(const char*& expr, bool once, GenObject* context);
bool evalList(ObjList& stack, GenObject* context) const;
bool evalVector(ObjList& stack, GenObject* context) const;
bool jumpToLabel(long int label, GenObject* context) const;
@@ -196,6 +200,7 @@ static const TokenDict s_bools[] =
static const TokenDict s_preProc[] =
{
MAKEOP("#include", Include),
+ MAKEOP("#require", Require),
{ 0, 0 }
};
#undef MAKEOP
@@ -427,7 +432,7 @@ char JsCode::skipComments(const char*& expr, GenObject* context) const
return c;
}
-bool JsCode::preProcessInclude(const char*& expr, GenObject* context)
+bool JsCode::preProcessInclude(const char*& expr, bool once, GenObject* context)
{
if (m_depth > 5)
return gotError("Possible recursive include");
@@ -444,9 +449,18 @@ bool JsCode::preProcessInclude(const char*& expr, GenObject* context)
String str(start,expr-start-1);
DDebug(this,DebugAll,"Found include '%s'",str.safe());
parser->adjustPath(str);
- m_depth++;
- bool ok = parser->parseFile(str,true);
- m_depth--;
+ str.trimSpaces();
+ bool ok = !str.null();
+ if (ok) {
+ bool already = m_included.find(str);
+ if (!(once && already)) {
+ m_depth++;
+ ok = parser->parseFile(str,true);
+ m_depth--;
+ if (ok && !already)
+ m_included.append(new String(str));
+ }
+ }
return ok || gotError("Failed to include " + str);
}
expr--;
@@ -459,9 +473,11 @@ int JsCode::preProcess(const char*& expr, GenObject* context)
{
int rval = -1;
for (;;) {
- switch ((JsOpcode)ExpEvaluator::getOperator(expr,s_preProc)) {
+ JsOpcode opc = (JsOpcode)ExpEvaluator::getOperator(expr,s_preProc);
+ switch (opc) {
case OpcInclude:
- if (preProcessInclude(expr,context)) {
+ case OpcRequire:
+ if (preProcessInclude(expr,(OpcRequire == opc),context)) {
if (rval < 0)
rval = 1;
else
@@ -731,6 +747,31 @@ bool JsCode::getSeparator(const char*& expr, bool remove)
return ExpEvaluator::getSeparator(expr,remove);
}
+// Parse an inline Javascript [ array ]
+JsObject* JsCode::parseArray(const char*& expr, bool constOnly)
+{
+ if (skipComments(expr) != '[')
+ return 0;
+ expr++;
+ JsObject* jso = new JsObject;
+ if (skipComments(expr) != ']')
+ TelEngine::destruct(jso);
+ return jso;
+}
+
+
+// Parse an inline Javascript { object }
+JsObject* JsCode::parseObject(const char*& expr, bool constOnly)
+{
+ if (skipComments(expr) != '{')
+ return 0;
+ expr++;
+ JsObject* jso = new JsObject;
+ if (skipComments(expr) != '}')
+ TelEngine::destruct(jso);
+ return jso;
+}
+
bool JsCode::runOperation(ObjList& stack, const ExpOperation& oper, GenObject* context) const
{
switch ((JsOpcode)oper.opcode()) {
@@ -1098,4 +1139,13 @@ ScriptRun::Status JsParser::eval(const String& text, ExpOperation** result, Scri
return rval;
}
+// Parse JSON using native methods
+JsObject* JsParser::parseJSON(const char* text)
+{
+ JsCode* code = new JsCode;
+ JsObject* jso = code->parseObject(text,true);
+ TelEngine::destruct(code);
+ return jso;
+}
+
/* vi: set ts=8 sw=4 sts=4 noet: */
View
@@ -50,17 +50,11 @@ class JsArray : public JsObject
public:
inline JsArray(Mutex* mtx)
: JsObject("Array",mtx)
- { }
-};
-
-// Object constructor
-class JsConstructor : public JsFunction
-{
- YCLASS(JsConstructor,JsFunction)
-public:
- inline JsConstructor(Mutex* mtx)
- : JsFunction(mtx)
- { }
+ {
+ params().addParam(new ExpFunction("push"));
+ }
+protected:
+ bool runNative(ObjList& stack, const ExpOperation& oper, GenObject* context);
};
// Object object
@@ -134,6 +128,7 @@ JsObject::JsObject(const char* name, Mutex* mtx, bool frozen)
params().addParam(new ExpFunction("freeze"));
params().addParam(new ExpFunction("isFrozen"));
params().addParam(new ExpFunction("toString"));
+ params().addParam(new ExpFunction("hasOwnProperty"));
}
JsObject::~JsObject()
@@ -230,6 +225,17 @@ bool JsObject::runNative(ObjList& stack, const ExpOperation& oper, GenObject* co
ExpEvaluator::pushOne(stack,new ExpOperation(frozen()));
else if (oper.name() == YSTRING("toString"))
ExpEvaluator::pushOne(stack,new ExpOperation(params()));
+ else if (oper.name() == YSTRING("hasOwnProperty")) {
+ bool ok = true;
+ for (long int i = oper.number(); i; i--) {
+ ExpOperation* op = popValue(stack,context);
+ if (!op)
+ continue;
+ ok = ok && params().getParam(*op);
+ TelEngine::destruct(op);
+ }
+ ExpEvaluator::pushOne(stack,new ExpOperation(ok));
+ }
else
return false;
return true;
@@ -276,6 +282,13 @@ bool JsObjectObj::runNative(ObjList& stack, const ExpOperation& oper, GenObject*
return true;
}
+
+bool JsArray::runNative(ObjList& stack, const ExpOperation& oper, GenObject* context)
+{
+ return JsObject::runNative(stack,oper,context);
+}
+
+
bool JsMath::runNative(ObjList& stack, const ExpOperation& oper, GenObject* context)
{
if (oper.name() == YSTRING("abs")) {
@@ -328,6 +341,30 @@ bool JsDate::runNative(ObjList& stack, const ExpOperation& oper, GenObject* cont
}
+JsFunction::JsFunction(Mutex* mtx)
+ : JsObject("Function",mtx,true)
+{
+ params().addParam(new ExpFunction("apply"));
+ params().addParam(new ExpFunction("call"));
+}
+
+bool JsFunction::runNative(ObjList& stack, const ExpOperation& oper, GenObject* context)
+{
+ if (oper.name() == YSTRING("apply")) {
+ // func.apply(new_this,["array","of","params",...])
+ if (oper.number() != 2)
+ return false;
+ }
+ else if (oper.name() == YSTRING("call")) {
+ // func.call(new_this,param1,param2,...)
+ if (!oper.number())
+ return false;
+ }
+ else
+ return JsObject::runNative(stack,oper,context);
+ return true;
+}
+
bool JsFunction::runDefined(ObjList& stack, const ExpOperation& oper, GenObject* context)
{
return false;
View
@@ -307,14 +307,14 @@ class YSCRIPT_API ExpEvaluator : public DebugEnabler
/**
* Dump a list of operations according to current operators dictionary
* @param codes List of operation codes
- * @result String representation of operations
+ * @return String representation of operations
*/
inline String dump(const ObjList& codes) const
{ String s; dump(codes,s); return s; }
/**
* Dump the postfix expression according to current operators dictionary
- * @result String representation of operations
+ * @return String representation of operations
*/
inline String dump() const
{ String s; dump(s); return s; }
@@ -1475,9 +1475,7 @@ class YSCRIPT_API JsFunction : public JsObject
* Constructor
* @param mtx Pointer to the mutex that serializes this object
*/
- inline JsFunction(Mutex* mtx = 0)
- : JsObject("Function",mtx,true)
- { }
+ JsFunction(Mutex* mtx = 0);
/**
* Try to evaluate a single user defined method
@@ -1489,6 +1487,17 @@ class YSCRIPT_API JsFunction : public JsObject
*/
virtual bool runDefined(ObjList& stack, const ExpOperation& oper, GenObject* context);
+protected:
+ /**
+ * Try to evaluate a single native method
+ * @param stack Evaluation stack in use, parameters are popped off this stack
+ * and results are pushed back on stack
+ * @param oper Function to evaluate
+ * @param context Pointer to arbitrary object passed from evaluation methods
+ * @return True if evaluation succeeded
+ */
+ virtual bool runNative(ObjList& stack, const ExpOperation& oper, GenObject* context);
+
};
/**
@@ -1558,6 +1567,13 @@ class YSCRIPT_API JsParser : public ScriptParser
*/
static ScriptRun::Status eval(const String& text, ExpOperation** result = 0, ScriptContext* context = 0);
+ /**
+ * Parse a complete block of JSON text
+ * @param text JSON text to parse
+ * @return JsObject holding the content of JSON, must be dereferenced after use, NULL if parse error
+ */
+ static JsObject* parseJSON(const char* text);
+
private:
String m_basePath;
};
View
@@ -54,8 +54,13 @@ class JsModule : public ChanAssistList
class JsAssist : public ChanAssist
{
public:
+ enum State {
+ NotRouted,
+ Routing,
+ ReRoute,
+ };
inline JsAssist(ChanAssistList* list, const String& id, ScriptRun* runner)
- : ChanAssist(list, id), m_runner(runner)
+ : ChanAssist(list, id), m_runner(runner), m_state(NotRouted)
{ }
virtual ~JsAssist();
virtual void msgStartup(Message& msg);
@@ -70,6 +75,7 @@ class JsAssist : public ChanAssist
private:
bool runFunction(const char* name, Message& msg);
ScriptRun* m_runner;
+ State m_state;
};
#define MKDEBUG(lvl) params().addParam(new ExpOperation((long int)Debug ## lvl,"Debug" # lvl))
@@ -91,8 +97,8 @@ class JsEngine : public JsObject
MKDEBUG(Note);
MKDEBUG(Info);
MKDEBUG(All);
- params().addParam(new ExpFunction("Output"));
- params().addParam(new ExpFunction("Debug"));
+ params().addParam(new ExpFunction("output"));
+ params().addParam(new ExpFunction("debug"));
}
static void initialize(ScriptContext* context);
protected:
@@ -196,7 +202,7 @@ static inline void addObject(NamedList& params, const char* name, JsObject* obj)
bool JsEngine::runNative(ObjList& stack, const ExpOperation& oper, GenObject* context)
{
- if (oper.name() == YSTRING("Output")) {
+ if (oper.name() == YSTRING("output")) {
String str;
for (long int i = oper.number(); i; i--) {
ExpOperation* op = popValue(stack,context);
@@ -208,18 +214,16 @@ bool JsEngine::runNative(ObjList& stack, const ExpOperation& oper, GenObject* co
if (str)
Output("%s",str.c_str());
}
- else if (oper.name() == YSTRING("Debug")) {
+ else if (oper.name() == YSTRING("debug")) {
int level = DebugNote;
String str;
for (long int i = oper.number(); i; i--) {
ExpOperation* op = popValue(stack,context);
if (!op)
continue;
-Debug(DebugTest,"Popped [%ld] '%s' %ld",i,op->c_str(),op->number());
if ((i == 1) && oper.number() > 1 && op->isInteger())
level = op->number();
else if (*op) {
-Debug(DebugTest,"Prepend '%s'",op->c_str());
if (str)
str = *op + " " + str;
else
@@ -535,6 +539,7 @@ bool JsAssist::msgPreroute(Message& msg)
bool JsAssist::msgRoute(Message& msg)
{
+ m_state = Routing;
return false;
}

0 comments on commit 1eec7eb

Please sign in to comment.