26 #define JUCE_JS_OPERATORS(X) \
27 X(semicolon, ";") X(dot, ".") X(comma, ",") \
28 X(openParen, "(") X(closeParen, ")") X(openBrace, "{") X(closeBrace, "}") \
29 X(openBracket, "[") X(closeBracket, "]") X(colon, ":") X(question, "?") \
30 X(typeEquals, "===") X(equals, "==") X(assign, "=") \
31 X(typeNotEquals, "!==") X(notEquals, "!=") X(logicalNot, "!") \
32 X(plusEquals, "+=") X(plusplus, "++") X(plus, "+") \
33 X(minusEquals, "-=") X(minusminus, "--") X(minus, "-") \
34 X(timesEquals, "*=") X(times, "*") X(divideEquals, "/=") X(divide, "/") \
35 X(moduloEquals, "%=") X(modulo, "%") X(xorEquals, "^=") X(bitwiseXor, "^") \
36 X(andEquals, "&=") X(logicalAnd, "&&") X(bitwiseAnd, "&") \
37 X(orEquals, "|=") X(logicalOr, "||") X(bitwiseOr, "|") \
38 X(leftShiftEquals, "<<=") X(lessThanOrEqual, "<=") X(leftShift, "<<") X(lessThan, "<") \
39 X(rightShiftUnsigned, ">>>") X(rightShiftEquals, ">>=") X(rightShift, ">>") X(greaterThanOrEqual, ">=") X(greaterThan, ">")
41 #define JUCE_JS_KEYWORDS(X) \
42 X(var, "var") X(if_, "if") X(else_, "else") X(do_, "do") X(null_, "null") \
43 X(while_, "while") X(for_, "for") X(break_, "break") X(continue_, "continue") X(undefined, "undefined") \
44 X(function, "function") X(return_, "return") X(true_, "true") X(false_, "false") X(new_, "new") \
49 #define JUCE_DECLARE_JS_TOKEN(name, str) static const char* const name = str;
50 JUCE_JS_KEYWORDS (JUCE_DECLARE_JS_TOKEN)
51 JUCE_JS_OPERATORS (JUCE_DECLARE_JS_TOKEN)
52 JUCE_DECLARE_JS_TOKEN (eof,
"$eof")
53 JUCE_DECLARE_JS_TOKEN (literal, "$literal")
54 JUCE_DECLARE_JS_TOKEN (identifier, "$identifier")
58 #pragma warning (push)
59 #pragma warning (disable: 4702)
67 setMethod (
"exec", exec);
68 setMethod (
"eval", eval);
69 setMethod (
"trace", trace);
70 setMethod (
"charToInt", charToInt);
71 setMethod (
"parseInt", IntegerClass::parseInt);
72 setMethod (
"typeof", typeof_internal);
73 setMethod (
"parseFloat", parseFloat);
79 using TokenType =
const char*;
81 void execute (
const String& code)
84 std::unique_ptr<BlockStatement> (tb.parseStatementList())->perform (
Scope ({}, *
this, *
this),
nullptr);
90 return ExpPtr (tb.parseExpression())->getResult (
Scope ({}, *
this, *
this));
94 static bool areTypeEqual (
const var& a,
const var& b)
96 return a.
hasSameTypeAs (b) && isFunction (a) == isFunction (b)
97 && (((a.isUndefined() || a.isVoid()) && (b.isUndefined() || b.isVoid())) || a == b);
100 static String getTokenName (TokenType t) {
return t[0] ==
'$' ?
String (t + 1) : (
"'" +
String (t) +
"'"); }
101 static bool isFunction (
const var& v) noexcept {
return dynamic_cast<FunctionObject*
> (v.getObject()) !=
nullptr; }
102 static bool isNumeric (
const var& v) noexcept {
return v.isInt() || v.isDouble() || v.isInt64() || v.isBool(); }
103 static bool isNumericOrUndefined (
const var& v) noexcept {
return isNumeric (v) || v.isUndefined(); }
105 static Identifier getPrototypeIdentifier() {
static const Identifier i (
"prototype");
return i; }
111 CodeLocation (
const String& code) noexcept : program (code), location (program.getCharPointer()) {}
114 void throwError (
const String& message)
const
116 int col = 1, line = 1;
118 for (
auto i = program.
getCharPointer(); i < location && ! i.isEmpty(); ++i)
121 if (*i ==
'\n') { col = 1; ++line; }
124 throw "Line " +
String (line) +
", column " +
String (col) +
" : " + message;
135 : parent (p), root (std::move (rt)),
136 scope (std::move (scp)) {}
138 const Scope*
const parent;
144 if (
auto* o = targetObject.getDynamicObject())
146 if (
auto* prop = getPropertyPointer (*o, functionName))
149 for (
auto* p = o->
getProperty (getPrototypeIdentifier()).getDynamicObject(); p !=
nullptr;
150 p = p->getProperty (getPrototypeIdentifier()).getDynamicObject())
152 if (
auto* prop = getPropertyPointer (*p, functionName))
161 if (targetObject.isString())
162 if (
auto* m = findRootClassProperty (StringClass::getClassName(), functionName))
165 if (targetObject.isArray())
166 if (
auto* m = findRootClassProperty (ArrayClass::getClassName(), functionName))
169 if (
auto* m = findRootClassProperty (ObjectClass::getClassName(), functionName))
172 location.throwError (
"Unknown function '" + functionName.
toString() +
"'");
178 if (
auto* cls = root->getProperty (className).getDynamicObject())
179 return getPropertyPointer (*cls, propName);
186 if (
auto v = getPropertyPointer (*scope, name))
189 return parent !=
nullptr ? parent->findSymbolInParentScopes (name)
195 auto* target = args.thisObject.getDynamicObject();
197 if (target ==
nullptr || target == scope.
get())
199 if (
auto* m = getPropertyPointer (*scope,
function))
203 result = fo->
invoke (*
this, args);
211 for (
int i = 0; i < props.size(); ++i)
212 if (
auto* o = props.getValueAt (i).getDynamicObject())
213 if (
Scope (
this, *root, *o).findAndInvokeMethod (
function, args, result))
223 auto* target = args.thisObject.getDynamicObject();
225 if (target ==
nullptr || target == scope.
get())
229 result = fo->
invoke (*
this, args);
241 location.throwError (root->timeout ==
Time() ?
"Interrupted" :
"Execution timed-out");
244 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (
Scope)
253 enum ResultCode { ok = 0, returnWasHit, breakWasHit, continueWasHit };
254 virtual ResultCode perform (
const Scope&,
var*)
const {
return ok; }
257 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (
Statement)
265 virtual void assign (
const Scope&,
const var&)
const { location.throwError (
"Cannot assign to this expression!"); }
267 ResultCode perform (
const Scope& s,
var*)
const override { getResult (s);
return ok; }
270 using ExpPtr = std::unique_ptr<Expression>;
276 ResultCode perform (
const Scope& s,
var* returnedValue)
const override
278 for (
auto* statement : statements)
279 if (
auto r = statement->perform (s, returnedValue))
292 ResultCode perform (
const Scope& s,
var* returnedValue)
const override
294 return (condition->getResult(s) ? trueBranch : falseBranch)->perform (s, returnedValue);
298 std::unique_ptr<Statement> trueBranch, falseBranch;
305 ResultCode perform (
const Scope& s,
var*)
const override
307 s.scope->
setProperty (name, initialiser->getResult (s));
319 ResultCode perform (
const Scope& s,
var* returnedValue)
const override
321 initialiser->perform (s,
nullptr);
323 while (isDoLoop || condition->getResult (s))
325 s.checkTimeOut (location);
326 auto r = body->perform (s, returnedValue);
328 if (r == returnWasHit)
return r;
329 if (r == breakWasHit)
break;
331 iterator->perform (s,
nullptr);
333 if (isDoLoop && r != continueWasHit && ! condition->getResult (s))
340 std::unique_ptr<Statement> initialiser, iterator, body;
349 ResultCode perform (
const Scope& s,
var* ret)
const override
351 if (ret !=
nullptr) *ret = returnValue->getResult (s);
361 ResultCode perform (
const Scope&,
var*)
const override {
return breakWasHit; }
367 ResultCode perform (
const Scope&,
var*)
const override {
return continueWasHit; }
373 var getResult (
const Scope&)
const override {
return value; }
381 var getResult (
const Scope& s)
const override {
return s.findSymbolInParentScopes (name); }
383 void assign (
const Scope& s,
const var& newValue)
const override
385 if (
auto* v = getPropertyPointer (*s.scope, name))
388 s.root->setProperty (name, newValue);
398 var getResult (
const Scope& s)
const override
400 auto p = parent->getResult (s);
403 if (child == lengthID)
405 if (
auto* array = p.getArray())
return array->size();
406 if (p.isString())
return p.toString().length();
409 if (
auto* o = p.getDynamicObject())
410 if (
auto* v = getPropertyPointer (*o, child))
416 void assign (
const Scope& s,
const var& newValue)
const override
418 if (
auto* o = parent->getResult (s).getDynamicObject())
421 Expression::assign (s, newValue);
432 var getResult (
const Scope& s)
const override
434 auto arrayVar =
object->getResult (s);
435 auto key = index->getResult (s);
437 if (
const auto* array = arrayVar.getArray())
438 if (key.isInt() || key.isInt64() || key.isDouble())
439 return (*array) [
static_cast<int> (key)];
441 if (
auto* o = arrayVar.getDynamicObject())
443 if (
auto* v = getPropertyPointer (*o,
Identifier (key)))
449 void assign (
const Scope& s,
const var& newValue)
const override
451 auto arrayVar =
object->getResult (s);
452 auto key = index->getResult (s);
454 if (
auto* array = arrayVar.getArray())
456 if (key.isInt() || key.isInt64() || key.isDouble())
459 while (array->size() < i)
462 array->set (i, newValue);
467 if (
auto* o = arrayVar.getDynamicObject())
476 Expression::assign (s, newValue);
479 ExpPtr object, index;
485 :
Expression (l), lhs (a.release()), rhs (b.release()), operation (op) {}
497 virtual var getWithDoubles (
double,
double)
const {
return throwError (
"Double"); }
498 virtual var getWithInts (int64, int64)
const {
return throwError (
"Integer"); }
499 virtual var getWithArrayOrObject (
const var& a,
const var&)
const {
return throwError (a.isArray() ?
"Array" :
"Object"); }
500 virtual var getWithStrings (
const String&,
const String&)
const {
return throwError (
"String"); }
502 var getResult (
const Scope& s)
const override
504 var a (lhs->getResult (s)), b (rhs->getResult (s));
506 if ((a.isUndefined() || a.isVoid()) && (b.isUndefined() || b.isVoid()))
507 return getWithUndefinedArg();
509 if (isNumericOrUndefined (a) && isNumericOrUndefined (b))
510 return (a.isDouble() || b.isDouble()) ? getWithDoubles (a, b) : getWithInts (a, b);
512 if (a.isArray() || a.isObject())
513 return getWithArrayOrObject (a, b);
515 return getWithStrings (a.toString(), b.toString());
518 var throwError (
const char* typeName)
const
519 { location.throwError (getTokenName (operation) +
" is not allowed on the " + typeName +
" type");
return {}; }
525 var getWithUndefinedArg()
const override {
return true; }
526 var getWithDoubles (
double a,
double b)
const override {
return a == b; }
527 var getWithInts (int64 a, int64 b)
const override {
return a == b; }
528 var getWithStrings (
const String& a,
const String& b)
const override {
return a == b; }
529 var getWithArrayOrObject (
const var& a,
const var& b)
const override {
return a == b; }
535 var getWithUndefinedArg()
const override {
return false; }
536 var getWithDoubles (
double a,
double b)
const override {
return a != b; }
537 var getWithInts (int64 a, int64 b)
const override {
return a != b; }
538 var getWithStrings (
const String& a,
const String& b)
const override {
return a != b; }
539 var getWithArrayOrObject (
const var& a,
const var& b)
const override {
return a != b; }
545 var getWithDoubles (
double a,
double b)
const override {
return a < b; }
546 var getWithInts (int64 a, int64 b)
const override {
return a < b; }
547 var getWithStrings (
const String& a,
const String& b)
const override {
return a < b; }
553 var getWithDoubles (
double a,
double b)
const override {
return a <= b; }
554 var getWithInts (int64 a, int64 b)
const override {
return a <= b; }
555 var getWithStrings (
const String& a,
const String& b)
const override {
return a <= b; }
561 var getWithDoubles (
double a,
double b)
const override {
return a > b; }
562 var getWithInts (int64 a, int64 b)
const override {
return a > b; }
563 var getWithStrings (
const String& a,
const String& b)
const override {
return a > b; }
569 var getWithDoubles (
double a,
double b)
const override {
return a >= b; }
570 var getWithInts (int64 a, int64 b)
const override {
return a >= b; }
571 var getWithStrings (
const String& a,
const String& b)
const override {
return a >= b; }
577 var getWithDoubles (
double a,
double b)
const override {
return a + b; }
578 var getWithInts (int64 a, int64 b)
const override {
return a + b; }
579 var getWithStrings (
const String& a,
const String& b)
const override {
return a + b; }
585 var getWithDoubles (
double a,
double b)
const override {
return a - b; }
586 var getWithInts (int64 a, int64 b)
const override {
return a - b; }
592 var getWithDoubles (
double a,
double b)
const override {
return a * b; }
593 var getWithInts (int64 a, int64 b)
const override {
return a * b; }
599 var getWithDoubles (
double a,
double b)
const override {
return b != 0 ? a / b : std::numeric_limits<double>::infinity(); }
600 var getWithInts (int64 a, int64 b)
const override {
return b != 0 ?
var (a / (
double) b) :
var (std::numeric_limits<double>::infinity()); }
606 var getWithDoubles (
double a,
double b)
const override {
return b != 0 ? fmod (a, b) : std::numeric_limits<double>::infinity(); }
607 var getWithInts (int64 a, int64 b)
const override {
return b != 0 ?
var (a % b) :
var (std::numeric_limits<double>::infinity()); }
613 var getWithInts (int64 a, int64 b)
const override {
return a | b; }
619 var getWithInts (int64 a, int64 b)
const override {
return a & b; }
625 var getWithInts (int64 a, int64 b)
const override {
return a ^ b; }
631 var getWithInts (int64 a, int64 b)
const override {
return ((
int) a) << (int) b; }
637 var getWithInts (int64 a, int64 b)
const override {
return ((
int) a) >> (int) b; }
643 var getWithInts (int64 a, int64 b)
const override {
return (
int) (((uint32) a) >> (int) b); }
649 var getResult (
const Scope& s)
const override {
return lhs->getResult (s) && rhs->getResult (s); }
655 var getResult (
const Scope& s)
const override {
return lhs->getResult (s) || rhs->getResult (s); }
661 var getResult (
const Scope& s)
const override {
return areTypeEqual (lhs->getResult (s), rhs->getResult (s)); }
667 var getResult (
const Scope& s)
const override {
return ! areTypeEqual (lhs->getResult (s), rhs->getResult (s)); }
674 var getResult (
const Scope& s)
const override {
return (condition->getResult (s) ? trueBranch : falseBranch)->getResult (s); }
675 void assign (
const Scope& s,
const var& v)
const override { (condition->getResult (s) ? trueBranch : falseBranch)->assign (s, v); }
677 ExpPtr condition, trueBranch, falseBranch;
684 var getResult (
const Scope& s)
const override
686 auto value = newValue->getResult (s);
687 target->assign (s, value);
691 ExpPtr target, newValue;
697 :
Expression (l), target (dest), newValue (source) {}
699 var getResult (
const Scope& s)
const override
701 auto value = newValue->getResult (s);
702 target->assign (s, value);
715 var getResult (
const Scope& s)
const override
717 auto oldValue = target->getResult (s);
718 target->assign (s, newValue->getResult (s));
727 var getResult (
const Scope& s)
const override
729 if (
auto* dot =
dynamic_cast<DotOperator*
> (
object.get()))
731 auto thisObject = dot->parent->getResult (s);
732 return invokeFunction (s, s.findFunctionCall (location, thisObject, dot->child), thisObject);
735 auto function =
object->getResult (s);
736 return invokeFunction (s,
function,
var (s.scope.
get()));
739 var invokeFunction (
const Scope& s,
const var&
function,
const var& thisObject)
const
741 s.checkTimeOut (location);
744 for (
auto* a : arguments)
745 argVars.
add (a->getResult (s));
749 if (var::NativeFunction nativeFunction =
function.getNativeFunction())
750 return nativeFunction (args);
752 if (
auto* fo =
dynamic_cast<FunctionObject*
> (
function.getObject()))
753 return fo->invoke (s, args);
755 if (
auto* dot =
dynamic_cast<DotOperator*
> (
object.get()))
756 if (
auto* o = thisObject.getDynamicObject())
760 location.throwError (
"This expression is not a function!");
return {};
771 var getResult (
const Scope& s)
const override
773 var classOrFunc =
object->getResult (s);
774 const bool isFunc = isFunction (classOrFunc);
776 if (! (isFunc || classOrFunc.getDynamicObject() !=
nullptr))
782 invokeFunction (s, classOrFunc, newObject.
get());
784 newObject->
setProperty (getPrototypeIdentifier(), classOrFunc);
786 return newObject.
get();
794 var getResult (
const Scope& s)
const override
798 for (
int i = 0; i < names.size(); ++i)
799 newObject->
setProperty (names.getUnchecked(i), initialisers.getUnchecked(i)->getResult (s));
801 return newObject.
get();
812 var getResult (
const Scope& s)
const override
816 for (
int i = 0; i < values.size(); ++i)
817 a.
add (values.getUnchecked(i)->getResult (s));
833 tb.parseFunctionParamsAndBody (*
this);
838 void writeAsJSON (
OutputStream& out,
int ,
bool ,
int )
override
840 out <<
"function " << functionCode;
848 functionRoot->setProperty (thisIdent, args.thisObject);
850 for (
int i = 0; i < parameters.size(); ++i)
851 functionRoot->setProperty (parameters.getReference(i),
855 body->perform (
Scope (&s, s.root, functionRoot), &result);
861 std::unique_ptr<Statement> body;
871 skipWhitespaceAndComments();
872 location.location = p;
873 currentType = matchNextToken();
876 void match (TokenType expected)
878 if (currentType != expected)
879 location.throwError (
"Found " + getTokenName (currentType) +
" when expecting " + getTokenName (expected));
884 bool matchIf (TokenType expected) {
if (currentType == expected) { skip();
return true; }
return false; }
885 bool matchesAny (TokenType t1, TokenType t2)
const {
return currentType == t1 || currentType == t2; }
886 bool matchesAny (TokenType t1, TokenType t2, TokenType t3)
const {
return matchesAny (t1, t2) || currentType == t3; }
889 TokenType currentType;
898 TokenType matchNextToken()
900 if (isIdentifierStart (*p))
903 while (isIdentifierBody (*++end)) {}
905 auto len = (size_t) (end - p);
906 #define JUCE_JS_COMPARE_KEYWORD(name, str) if (len == sizeof (str) - 1 && matchToken (TokenTypes::name, len)) return TokenTypes::name;
907 JUCE_JS_KEYWORDS (JUCE_JS_COMPARE_KEYWORD)
909 currentValue =
String (p, end); p = end;
910 return TokenTypes::identifier;
915 if (parseHexLiteral() || parseFloatLiteral() || parseOctalLiteral() || parseDecimalLiteral())
916 return TokenTypes::literal;
918 location.throwError (
"Syntax error in numeric constant");
921 if (parseStringLiteral (*p) || (*p ==
'.' && parseFloatLiteral()))
922 return TokenTypes::literal;
924 #define JUCE_JS_COMPARE_OPERATOR(name, str) if (matchToken (TokenTypes::name, sizeof (str) - 1)) return TokenTypes::name;
925 JUCE_JS_OPERATORS (JUCE_JS_COMPARE_OPERATOR)
930 return TokenTypes::eof;
933 bool matchToken (TokenType name,
size_t len) noexcept
936 p += (int) len;
return true;
939 void skipWhitespaceAndComments()
953 location.location = p;
955 if (p.
isEmpty()) location.throwError (
"Unterminated '/*' comment");
964 bool parseStringLiteral (juce_wchar quoteType)
966 if (quoteType !=
'"' && quoteType !=
'\'')
970 if (r.failed()) location.throwError (r.getErrorMessage());
974 bool parseHexLiteral()
976 if (*p !=
'0' || (p[1] !=
'x' && p[1] !=
'X'))
return false;
980 if (v < 0)
return false;
985 if (digit < 0)
break;
989 currentValue = v; p = t;
993 bool parseFloatLiteral()
997 while (t.isDigit()) { ++t; ++numDigits; }
999 const bool hasPoint = (*t ==
'.');
1002 while ((++t).isDigit()) ++numDigits;
1008 const bool hasExponent = (c ==
'e' || c ==
'E');
1013 if (c ==
'+' || c ==
'-') ++t;
1014 if (! t.isDigit())
return false;
1015 while ((++t).isDigit()) {}
1018 if (! (hasExponent || hasPoint))
return false;
1024 bool parseOctalLiteral()
1028 if (v != 0)
return false;
1032 auto digit = (int) (*++t -
'0');
1033 if (isPositiveAndBelow (digit, 8)) v = v * 8 + digit;
1034 else if (isPositiveAndBelow (digit, 10)) location.throwError (
"Decimal digit in octal constant");
1038 currentValue = v; p = t;
1042 bool parseDecimalLiteral()
1048 auto digit = (int) (*p -
'0');
1049 if (isPositiveAndBelow (digit, 10)) v = v * 10 + digit;
1059 struct ExpressionTreeBuilder :
private TokenIterator
1061 ExpressionTreeBuilder (
const String code) : TokenIterator (code) {}
1063 BlockStatement* parseStatementList()
1065 std::unique_ptr<BlockStatement> b (
new BlockStatement (location));
1067 while (currentType != TokenTypes::closeBrace && currentType != TokenTypes::eof)
1068 b->statements.add (parseStatement());
1073 void parseFunctionParamsAndBody (FunctionObject& fo)
1075 match (TokenTypes::openParen);
1077 while (currentType != TokenTypes::closeParen)
1079 auto paramName = currentValue.toString();
1080 match (TokenTypes::identifier);
1081 fo.parameters.add (paramName);
1083 if (currentType != TokenTypes::closeParen)
1084 match (TokenTypes::comma);
1087 match (TokenTypes::closeParen);
1088 fo.body.reset (parseBlock());
1091 Expression* parseExpression()
1093 ExpPtr lhs (parseLogicOperator());
1095 if (matchIf (TokenTypes::question))
return parseTernaryOperator (lhs);
1096 if (matchIf (TokenTypes::assign)) { ExpPtr rhs (parseExpression());
return new Assignment (location, lhs, rhs); }
1097 if (matchIf (TokenTypes::plusEquals))
return parseInPlaceOpExpression<AdditionOp> (lhs);
1098 if (matchIf (TokenTypes::minusEquals))
return parseInPlaceOpExpression<SubtractionOp> (lhs);
1099 if (matchIf (TokenTypes::timesEquals))
return parseInPlaceOpExpression<MultiplyOp> (lhs);
1100 if (matchIf (TokenTypes::divideEquals))
return parseInPlaceOpExpression<DivideOp> (lhs);
1101 if (matchIf (TokenTypes::moduloEquals))
return parseInPlaceOpExpression<ModuloOp> (lhs);
1102 if (matchIf (TokenTypes::leftShiftEquals))
return parseInPlaceOpExpression<LeftShiftOp> (lhs);
1103 if (matchIf (TokenTypes::rightShiftEquals))
return parseInPlaceOpExpression<RightShiftOp> (lhs);
1105 return lhs.release();
1109 void throwError (
const String& err)
const { location.throwError (err); }
1111 template <
typename OpType>
1112 Expression* parseInPlaceOpExpression (ExpPtr& lhs)
1114 ExpPtr rhs (parseExpression());
1115 Expression* bareLHS = lhs.get();
1116 return new SelfAssignment (location, bareLHS,
new OpType (location, lhs, rhs));
1119 BlockStatement* parseBlock()
1121 match (TokenTypes::openBrace);
1122 std::unique_ptr<BlockStatement> b (parseStatementList());
1123 match (TokenTypes::closeBrace);
1127 Statement* parseStatement()
1129 if (currentType == TokenTypes::openBrace)
return parseBlock();
1130 if (matchIf (TokenTypes::var))
return parseVar();
1131 if (matchIf (TokenTypes::if_))
return parseIf();
1132 if (matchIf (TokenTypes::while_))
return parseDoOrWhileLoop (
false);
1133 if (matchIf (TokenTypes::do_))
return parseDoOrWhileLoop (
true);
1134 if (matchIf (TokenTypes::for_))
return parseForLoop();
1135 if (matchIf (TokenTypes::return_))
return parseReturn();
1136 if (matchIf (TokenTypes::break_))
return new BreakStatement (location);
1137 if (matchIf (TokenTypes::continue_))
return new ContinueStatement (location);
1138 if (matchIf (TokenTypes::function))
return parseFunction();
1139 if (matchIf (TokenTypes::semicolon))
return new Statement (location);
1140 if (matchIf (TokenTypes::plusplus))
return parsePreIncDec<AdditionOp>();
1141 if (matchIf (TokenTypes::minusminus))
return parsePreIncDec<SubtractionOp>();
1143 if (matchesAny (TokenTypes::openParen, TokenTypes::openBracket))
1144 return matchEndOfStatement (parseFactor());
1146 if (matchesAny (TokenTypes::identifier, TokenTypes::literal, TokenTypes::minus))
1147 return matchEndOfStatement (parseExpression());
1149 throwError (
"Found " + getTokenName (currentType) +
" when expecting a statement");
1153 Expression* matchEndOfStatement (Expression* ex) { ExpPtr e (ex);
if (currentType != TokenTypes::eof) match (TokenTypes::semicolon);
return e.release(); }
1154 Expression* matchCloseParen (Expression* ex) { ExpPtr e (ex); match (TokenTypes::closeParen);
return e.release(); }
1156 Statement* parseIf()
1158 std::unique_ptr<IfStatement> s (
new IfStatement (location));
1159 match (TokenTypes::openParen);
1160 s->condition.reset (parseExpression());
1161 match (TokenTypes::closeParen);
1162 s->trueBranch.reset (parseStatement());
1163 s->falseBranch.reset (matchIf (TokenTypes::else_) ? parseStatement() :
new Statement (location));
1167 Statement* parseReturn()
1169 if (matchIf (TokenTypes::semicolon))
1170 return new ReturnStatement (location,
new Expression (location));
1172 auto* r =
new ReturnStatement (location, parseExpression());
1173 matchIf (TokenTypes::semicolon);
1177 Statement* parseVar()
1179 std::unique_ptr<VarStatement> s (
new VarStatement (location));
1180 s->name = parseIdentifier();
1181 s->initialiser.reset (matchIf (TokenTypes::assign) ? parseExpression() :
new Expression (location));
1183 if (matchIf (TokenTypes::comma))
1185 std::unique_ptr<BlockStatement> block (
new BlockStatement (location));
1186 block->statements.add (s.release());
1187 block->statements.add (parseVar());
1188 return block.release();
1191 match (TokenTypes::semicolon);
1195 Statement* parseFunction()
1198 auto fn = parseFunctionDefinition (name);
1201 throwError (
"Functions defined at statement-level must have a name");
1203 ExpPtr nm (
new UnqualifiedName (location, name)), value (
new LiteralValue (location, fn));
1204 return new Assignment (location, nm, value);
1207 Statement* parseForLoop()
1209 std::unique_ptr<LoopStatement> s (
new LoopStatement (location,
false));
1210 match (TokenTypes::openParen);
1211 s->initialiser.reset (parseStatement());
1213 if (matchIf (TokenTypes::semicolon))
1214 s->condition.reset (
new LiteralValue (location,
true));
1217 s->condition.reset (parseExpression());
1218 match (TokenTypes::semicolon);
1221 if (matchIf (TokenTypes::closeParen))
1222 s->iterator.reset (
new Statement (location));
1225 s->iterator.reset (parseExpression());
1226 match (TokenTypes::closeParen);
1229 s->body.reset (parseStatement());
1233 Statement* parseDoOrWhileLoop (
bool isDoLoop)
1235 std::unique_ptr<LoopStatement> s (
new LoopStatement (location, isDoLoop));
1236 s->initialiser.reset (
new Statement (location));
1237 s->iterator.reset (
new Statement (location));
1241 s->body.reset (parseBlock());
1242 match (TokenTypes::while_);
1245 match (TokenTypes::openParen);
1246 s->condition.reset (parseExpression());
1247 match (TokenTypes::closeParen);
1250 s->body.reset (parseStatement());
1255 Identifier parseIdentifier()
1258 if (currentType == TokenTypes::identifier)
1261 match (TokenTypes::identifier);
1265 var parseFunctionDefinition (Identifier& functionName)
1267 auto functionStart = location.location;
1269 if (currentType == TokenTypes::identifier)
1270 functionName = parseIdentifier();
1272 std::unique_ptr<FunctionObject> fo (
new FunctionObject());
1273 parseFunctionParamsAndBody (*fo);
1274 fo->functionCode = String (functionStart, location.location);
1275 return var (fo.release());
1278 Expression* parseFunctionCall (FunctionCall* call, ExpPtr&
function)
1280 std::unique_ptr<FunctionCall> s (call);
1281 s->object.reset (
function.release());
1282 match (TokenTypes::openParen);
1284 while (currentType != TokenTypes::closeParen)
1286 s->arguments.add (parseExpression());
1287 if (currentType != TokenTypes::closeParen)
1288 match (TokenTypes::comma);
1291 return matchCloseParen (s.release());
1294 Expression* parseSuffixes (Expression* e)
1298 if (matchIf (TokenTypes::dot))
1299 return parseSuffixes (
new DotOperator (location, input, parseIdentifier()));
1301 if (currentType == TokenTypes::openParen)
1302 return parseSuffixes (parseFunctionCall (
new FunctionCall (location), input));
1304 if (matchIf (TokenTypes::openBracket))
1306 std::unique_ptr<ArraySubscript> s (
new ArraySubscript (location));
1307 s->object.reset (input.release());
1308 s->index.reset (parseExpression());
1309 match (TokenTypes::closeBracket);
1310 return parseSuffixes (s.release());
1313 if (matchIf (TokenTypes::plusplus))
return parsePostIncDec<AdditionOp> (input);
1314 if (matchIf (TokenTypes::minusminus))
return parsePostIncDec<SubtractionOp> (input);
1316 return input.release();
1319 Expression* parseFactor()
1321 if (currentType == TokenTypes::identifier)
return parseSuffixes (
new UnqualifiedName (location, parseIdentifier()));
1322 if (matchIf (TokenTypes::openParen))
return parseSuffixes (matchCloseParen (parseExpression()));
1323 if (matchIf (TokenTypes::true_))
return parseSuffixes (
new LiteralValue (location, (
int) 1));
1324 if (matchIf (TokenTypes::false_))
return parseSuffixes (
new LiteralValue (location, (
int) 0));
1325 if (matchIf (TokenTypes::null_))
return parseSuffixes (
new LiteralValue (location, var()));
1326 if (matchIf (TokenTypes::undefined))
return parseSuffixes (
new Expression (location));
1328 if (currentType == TokenTypes::literal)
1330 var v (currentValue); skip();
1331 return parseSuffixes (
new LiteralValue (location, v));
1334 if (matchIf (TokenTypes::openBrace))
1336 std::unique_ptr<ObjectDeclaration> e (
new ObjectDeclaration (location));
1338 while (currentType != TokenTypes::closeBrace)
1340 auto memberName = currentValue.toString();
1341 match ((currentType == TokenTypes::literal && currentValue.isString())
1342 ? TokenTypes::literal : TokenTypes::identifier);
1343 match (TokenTypes::colon);
1345 e->names.add (memberName);
1346 e->initialisers.add (parseExpression());
1348 if (currentType != TokenTypes::closeBrace)
1349 match (TokenTypes::comma);
1352 match (TokenTypes::closeBrace);
1353 return parseSuffixes (e.release());
1356 if (matchIf (TokenTypes::openBracket))
1358 std::unique_ptr<ArrayDeclaration> e (
new ArrayDeclaration (location));
1360 while (currentType != TokenTypes::closeBracket)
1362 e->values.add (parseExpression());
1364 if (currentType != TokenTypes::closeBracket)
1365 match (TokenTypes::comma);
1368 match (TokenTypes::closeBracket);
1369 return parseSuffixes (e.release());
1372 if (matchIf (TokenTypes::function))
1375 var fn = parseFunctionDefinition (name);
1378 throwError (
"Inline functions definitions cannot have a name");
1380 return new LiteralValue (location, fn);
1383 if (matchIf (TokenTypes::new_))
1385 ExpPtr name (
new UnqualifiedName (location, parseIdentifier()));
1387 while (matchIf (TokenTypes::dot))
1388 name.reset (
new DotOperator (location, name, parseIdentifier()));
1390 return parseFunctionCall (
new NewOperator (location), name);
1393 throwError (
"Found " + getTokenName (currentType) +
" when expecting an expression");
1397 template <
typename OpType>
1398 Expression* parsePreIncDec()
1400 Expression* e = parseFactor();
1401 ExpPtr lhs (e), one (
new LiteralValue (location, (
int) 1));
1402 return new SelfAssignment (location, e,
new OpType (location, lhs, one));
1405 template <
typename OpType>
1406 Expression* parsePostIncDec (ExpPtr& lhs)
1408 Expression* e = lhs.release();
1409 ExpPtr lhs2 (e), one (
new LiteralValue (location, (
int) 1));
1410 return new PostAssignment (location, e,
new OpType (location, lhs2, one));
1413 Expression* parseTypeof()
1415 std::unique_ptr<FunctionCall> f (
new FunctionCall (location));
1416 f->object.reset (
new UnqualifiedName (location,
"typeof"));
1417 f->arguments.add (parseUnary());
1421 Expression* parseUnary()
1423 if (matchIf (TokenTypes::minus)) { ExpPtr a (
new LiteralValue (location, (
int) 0)), b (parseUnary());
return new SubtractionOp (location, a, b); }
1424 if (matchIf (TokenTypes::logicalNot)) { ExpPtr a (
new LiteralValue (location, (
int) 0)), b (parseUnary());
return new EqualsOp (location, a, b); }
1425 if (matchIf (TokenTypes::plusplus))
return parsePreIncDec<AdditionOp>();
1426 if (matchIf (TokenTypes::minusminus))
return parsePreIncDec<SubtractionOp>();
1427 if (matchIf (TokenTypes::typeof_))
return parseTypeof();
1429 return parseFactor();
1432 Expression* parseMultiplyDivide()
1434 ExpPtr a (parseUnary());
1438 if (matchIf (TokenTypes::times)) { ExpPtr b (parseUnary()); a.reset (
new MultiplyOp (location, a, b)); }
1439 else if (matchIf (TokenTypes::divide)) { ExpPtr b (parseUnary()); a.reset (
new DivideOp (location, a, b)); }
1440 else if (matchIf (TokenTypes::modulo)) { ExpPtr b (parseUnary()); a.reset (
new ModuloOp (location, a, b)); }
1447 Expression* parseAdditionSubtraction()
1449 ExpPtr a (parseMultiplyDivide());
1453 if (matchIf (TokenTypes::plus)) { ExpPtr b (parseMultiplyDivide()); a.reset (
new AdditionOp (location, a, b)); }
1454 else if (matchIf (TokenTypes::minus)) { ExpPtr b (parseMultiplyDivide()); a.reset (
new SubtractionOp (location, a, b)); }
1461 Expression* parseShiftOperator()
1463 ExpPtr a (parseAdditionSubtraction());
1467 if (matchIf (TokenTypes::leftShift)) { ExpPtr b (parseExpression()); a.reset (
new LeftShiftOp (location, a, b)); }
1468 else if (matchIf (TokenTypes::rightShift)) { ExpPtr b (parseExpression()); a.reset (
new RightShiftOp (location, a, b)); }
1469 else if (matchIf (TokenTypes::rightShiftUnsigned)) { ExpPtr b (parseExpression()); a.reset (
new RightShiftUnsignedOp (location, a, b)); }
1476 Expression* parseComparator()
1478 ExpPtr a (parseShiftOperator());
1482 if (matchIf (TokenTypes::equals)) { ExpPtr b (parseShiftOperator()); a.reset (
new EqualsOp (location, a, b)); }
1483 else if (matchIf (TokenTypes::notEquals)) { ExpPtr b (parseShiftOperator()); a.reset (
new NotEqualsOp (location, a, b)); }
1484 else if (matchIf (TokenTypes::typeEquals)) { ExpPtr b (parseShiftOperator()); a.reset (
new TypeEqualsOp (location, a, b)); }
1485 else if (matchIf (TokenTypes::typeNotEquals)) { ExpPtr b (parseShiftOperator()); a.reset (
new TypeNotEqualsOp (location, a, b)); }
1486 else if (matchIf (TokenTypes::lessThan)) { ExpPtr b (parseShiftOperator()); a.reset (
new LessThanOp (location, a, b)); }
1487 else if (matchIf (TokenTypes::lessThanOrEqual)) { ExpPtr b (parseShiftOperator()); a.reset (
new LessThanOrEqualOp (location, a, b)); }
1488 else if (matchIf (TokenTypes::greaterThan)) { ExpPtr b (parseShiftOperator()); a.reset (
new GreaterThanOp (location, a, b)); }
1489 else if (matchIf (TokenTypes::greaterThanOrEqual)) { ExpPtr b (parseShiftOperator()); a.reset (
new GreaterThanOrEqualOp (location, a, b)); }
1496 Expression* parseLogicOperator()
1498 ExpPtr a (parseComparator());
1502 if (matchIf (TokenTypes::logicalAnd)) { ExpPtr b (parseComparator()); a.reset (
new LogicalAndOp (location, a, b)); }
1503 else if (matchIf (TokenTypes::logicalOr)) { ExpPtr b (parseComparator()); a.reset (
new LogicalOrOp (location, a, b)); }
1504 else if (matchIf (TokenTypes::bitwiseAnd)) { ExpPtr b (parseComparator()); a.reset (
new BitwiseAndOp (location, a, b)); }
1505 else if (matchIf (TokenTypes::bitwiseOr)) { ExpPtr b (parseComparator()); a.reset (
new BitwiseOrOp (location, a, b)); }
1506 else if (matchIf (TokenTypes::bitwiseXor)) { ExpPtr b (parseComparator()); a.reset (
new BitwiseXorOp (location, a, b)); }
1513 Expression* parseTernaryOperator (ExpPtr& condition)
1515 std::unique_ptr<ConditionalOp> e (
new ConditionalOp (location));
1516 e->condition.reset (condition.release());
1517 e->trueBranch.reset (parseExpression());
1518 match (TokenTypes::colon);
1519 e->falseBranch.reset (parseExpression());
1523 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ExpressionTreeBuilder)
1527 static var get (Args a,
int index) noexcept {
return index < a.numArguments ? a.arguments[index] : var(); }
1528 static bool isInt (Args a,
int index) noexcept {
return get (a, index).isInt() || get (a, index).isInt64(); }
1529 static int getInt (
Args a,
int index) noexcept {
return get (a, index); }
1530 static double getDouble (
Args a,
int index) noexcept {
return get (a, index); }
1531 static String getString (Args a,
int index) noexcept {
return get (a, index).toString(); }
1538 setMethod (
"dump", dump);
1539 setMethod (
"clone", cloneFn);
1542 static Identifier getClassName() {
static const Identifier i (
"Object");
return i; }
1544 static var cloneFn (
Args a) {
return a.thisObject.
clone(); }
1552 setMethod (
"contains", contains);
1553 setMethod (
"remove", remove);
1554 setMethod (
"join", join);
1555 setMethod (
"push", push);
1556 setMethod (
"splice", splice);
1557 setMethod (
"indexOf", indexOf);
1560 static Identifier getClassName() {
static const Identifier i (
"Array");
return i; }
1562 static var contains (Args a)
1564 if (
auto* array = a.thisObject.getArray())
1565 return array->contains (get (a, 0));
1570 static var remove (Args a)
1572 if (
auto* array = a.thisObject.getArray())
1573 array->removeAllInstancesOf (get (a, 0));
1578 static var join (Args a)
1580 StringArray strings;
1582 if (
auto* array = a.thisObject.getArray())
1583 for (
auto& v : *array)
1584 strings.add (v.toString());
1586 return strings.joinIntoString (getString (a, 0));
1589 static var push (Args a)
1591 if (
auto* array = a.thisObject.getArray())
1593 for (
int i = 0; i < a.numArguments; ++i)
1594 array->add (a.arguments[i]);
1596 return array->size();
1602 static var splice (Args a)
1604 if (
auto* array = a.thisObject.getArray())
1606 auto arraySize = array->size();
1607 int start = get (a, 0);
1610 start = jmax (0, arraySize + start);
1611 else if (start > arraySize)
1614 const int num = a.numArguments > 1 ? jlimit (0, arraySize - start, getInt (a, 1))
1615 : arraySize - start;
1617 Array<var> itemsRemoved;
1618 itemsRemoved.ensureStorageAllocated (num);
1620 for (
int i = 0; i < num; ++i)
1621 itemsRemoved.add (array->getReference (start + i));
1623 array->removeRange (start, num);
1625 for (
int i = 2; i < a.numArguments; ++i)
1626 array->insert (start++, get (a, i));
1628 return itemsRemoved;
1634 static var indexOf (Args a)
1636 if (
auto* array = a.thisObject.getArray())
1638 auto target = get (a, 0);
1640 for (
int i = (a.numArguments > 1 ? getInt (a, 1) : 0); i < array->size(); ++i)
1641 if (array->getReference(i) == target)
1654 setMethod (
"substring", substring);
1655 setMethod (
"indexOf", indexOf);
1656 setMethod (
"charAt", charAt);
1657 setMethod (
"charCodeAt", charCodeAt);
1658 setMethod (
"fromCharCode", fromCharCode);
1659 setMethod (
"split", split);
1664 static var fromCharCode (Args a) {
return String::charToString (
static_cast<juce_wchar
> (getInt (a, 0))); }
1665 static var substring (Args a) {
return a.thisObject.toString().substring (getInt (a, 0), getInt (a, 1)); }
1666 static var indexOf (Args a) {
return a.thisObject.toString().indexOf (getString (a, 0)); }
1667 static var charCodeAt (Args a) {
return (
int) a.thisObject.toString() [getInt (a, 0)]; }
1668 static var charAt (Args a) {
int p = getInt (a, 0);
return a.thisObject.toString().substring (p, p + 1); }
1670 static var split (Args a)
1672 auto str = a.thisObject.toString();
1673 auto sep = getString (a, 0);
1674 StringArray strings;
1676 if (sep.isNotEmpty())
1677 strings.addTokens (str, sep.substring (0, 1), {});
1679 for (
auto pos = str.getCharPointer(); ! pos.isEmpty(); ++pos)
1684 for (
auto& s : strings)
1696 setMethod (
"abs", Math_abs); setMethod (
"round", Math_round);
1697 setMethod (
"random", Math_random); setMethod (
"randInt", Math_randInt);
1698 setMethod (
"min", Math_min); setMethod (
"max", Math_max);
1699 setMethod (
"range", Math_range); setMethod (
"sign", Math_sign);
1700 setMethod (
"toDegrees", Math_toDegrees); setMethod (
"toRadians", Math_toRadians);
1701 setMethod (
"sin", Math_sin); setMethod (
"asin", Math_asin);
1702 setMethod (
"sinh", Math_sinh); setMethod (
"asinh", Math_asinh);
1703 setMethod (
"cos", Math_cos); setMethod (
"acos", Math_acos);
1704 setMethod (
"cosh", Math_cosh); setMethod (
"acosh", Math_acosh);
1705 setMethod (
"tan", Math_tan); setMethod (
"atan", Math_atan);
1706 setMethod (
"tanh", Math_tanh); setMethod (
"atanh", Math_atanh);
1707 setMethod (
"log", Math_log); setMethod (
"log10", Math_log10);
1708 setMethod (
"exp", Math_exp); setMethod (
"pow", Math_pow);
1709 setMethod (
"sqr", Math_sqr); setMethod (
"sqrt", Math_sqrt);
1710 setMethod (
"ceil", Math_ceil); setMethod (
"floor", Math_floor);
1715 setProperty (
"SQRT1_2", std::sqrt (0.5));
1716 setProperty (
"LN2", std::log (2.0));
1717 setProperty (
"LN10", std::log (10.0));
1724 static var Math_abs (Args a) {
return isInt (a, 0) ? var (std::abs (getInt (a, 0))) : var (std::abs (getDouble (a, 0))); }
1725 static var Math_round (Args a) {
return isInt (a, 0) ? var (roundToInt (getInt (a, 0))) : var (roundToInt (getDouble (a, 0))); }
1726 static var Math_sign (Args a) {
return isInt (a, 0) ? var (sign (getInt (a, 0))) : var (sign (getDouble (a, 0))); }
1727 static var Math_range (Args a) {
return isInt (a, 0) ? var (jlimit (getInt (a, 1), getInt (a, 2), getInt (a, 0))) : var (jlimit (getDouble (a, 1), getDouble (a, 2), getDouble (a, 0))); }
1728 static var Math_min (Args a) {
return (isInt (a, 0) && isInt (a, 1)) ? var (jmin (getInt (a, 0), getInt (a, 1))) : var (jmin (getDouble (a, 0), getDouble (a, 1))); }
1729 static var Math_max (Args a) {
return (isInt (a, 0) && isInt (a, 1)) ? var (jmax (getInt (a, 0), getInt (a, 1))) : var (jmax (getDouble (a, 0), getDouble (a, 1))); }
1730 static var Math_toDegrees (Args a) {
return radiansToDegrees (getDouble (a, 0)); }
1731 static var Math_toRadians (Args a) {
return degreesToRadians (getDouble (a, 0)); }
1732 static var Math_sin (Args a) {
return std::sin (getDouble (a, 0)); }
1733 static var Math_asin (Args a) {
return std::asin (getDouble (a, 0)); }
1734 static var Math_cos (Args a) {
return std::cos (getDouble (a, 0)); }
1735 static var Math_acos (Args a) {
return std::acos (getDouble (a, 0)); }
1736 static var Math_sinh (Args a) {
return std::sinh (getDouble (a, 0)); }
1737 static var Math_cosh (Args a) {
return std::cosh (getDouble (a, 0)); }
1738 static var Math_tan (Args a) {
return std::tan (getDouble (a, 0)); }
1739 static var Math_tanh (Args a) {
return std::tanh (getDouble (a, 0)); }
1740 static var Math_atan (Args a) {
return std::atan (getDouble (a, 0)); }
1741 static var Math_log (Args a) {
return std::log (getDouble (a, 0)); }
1742 static var Math_log10 (Args a) {
return std::log10 (getDouble (a, 0)); }
1743 static var Math_exp (Args a) {
return std::exp (getDouble (a, 0)); }
1744 static var Math_pow (Args a) {
return std::pow (getDouble (a, 0), getDouble (a, 1)); }
1745 static var Math_sqr (Args a) {
return square (getDouble (a, 0)); }
1746 static var Math_sqrt (Args a) {
return std::sqrt (getDouble (a, 0)); }
1747 static var Math_ceil (Args a) {
return std::ceil (getDouble (a, 0)); }
1748 static var Math_floor (Args a) {
return std::floor (getDouble (a, 0)); }
1752 static var Math_asinh (Args a) {
return asinh (getDouble (a, 0)); }
1753 static var Math_acosh (Args a) {
return acosh (getDouble (a, 0)); }
1754 static var Math_atanh (Args a) {
return atanh (getDouble (a, 0)); }
1757 template <
typename Type>
static Type sign (Type n) noexcept {
return n > 0 ? (Type) 1 : (n < 0 ? (Type) -1 : 0); }
1763 JSONClass() { setMethod (
"stringify", stringify); }
1771 IntegerClass() { setMethod (
"parseInt", parseInt); }
1772 static Identifier getClassName() {
static const Identifier i (
"Integer");
return i; }
1774 static var parseInt (Args a)
1776 auto s = getString (a, 0).trim();
1778 return s[0] ==
'0' ? (s[1] ==
'x' ? s.substring(2).getHexValue64() : getOctalValue (s))
1779 : s.getLargeIntValue();
1785 static var charToInt (Args a) {
return (
int) (getString (a, 0)[0]); }
1786 static var parseFloat (Args a) {
return getDouble (a, 0); }
1788 static var typeof_internal (Args a)
1792 if (v.isVoid())
return "void";
1793 if (v.isString())
return "string";
1794 if (isNumeric (v))
return "number";
1795 if (isFunction (v) || v.isMethod())
return "function";
1796 if (v.isObject())
return "object";
1801 static var exec (Args a)
1803 if (
auto* root =
dynamic_cast<RootObject*
> (a.thisObject.getObject()))
1804 root->execute (getString (a, 0));
1809 static var eval (Args a)
1811 if (
auto* root =
dynamic_cast<RootObject*
> (a.thisObject.getObject()))
1812 return root->evaluate (getString (a, 0));
1821 registerNativeObject (RootObject::ObjectClass ::getClassName(),
new RootObject::ObjectClass());
1823 registerNativeObject (RootObject::StringClass ::getClassName(),
new RootObject::StringClass());
1836 root->setProperty (name,
object);
1844 root->execute (code);
1846 catch (String& error)
1859 if (result !=
nullptr) *result =
Result::ok();
1860 return root->evaluate (code);
1862 catch (String& error)
1877 if (result !=
nullptr) *result =
Result::ok();
1878 RootObject::Scope ({}, *root, *root).findAndInvokeMethod (
function, args, returnVal);
1880 catch (String& error)
1889 const var::NativeFunctionArgs& args, Result* result)
1896 if (result !=
nullptr) *result =
Result::ok();
1897 RootObject::Scope rootScope ({}, *root, *root);
1898 RootObject::Scope (&rootScope, *root, DynamicObject::Ptr (objectScope))
1899 .invokeMethod (functionObject, args, returnVal);
1901 catch (String& error)
1911 return root->getProperties();
1915 #pragma warning (pop)