diff options
Diffstat (limited to 'components/external/espruino/src/jsparse.h')
| -rw-r--r-- | components/external/espruino/src/jsparse.h | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/components/external/espruino/src/jsparse.h b/components/external/espruino/src/jsparse.h new file mode 100644 index 0000000000..7abaee4b6e --- /dev/null +++ b/components/external/espruino/src/jsparse.h @@ -0,0 +1,126 @@ +/* + * This file is part of Espruino, a JavaScript interpreter for Microcontrollers + * + * Copyright (C) 2013 Gordon Williams <[email protected]> + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * ---------------------------------------------------------------------------- + * Recursive descent parser for code execution + * ---------------------------------------------------------------------------- + */ +#ifndef JSPARSE_H_ +#define JSPARSE_H_ + +#include "jsvar.h" +#include "jslex.h" + + +typedef struct { + JsVar *root; ///< root of symbol table +} JsParse; + +void jspInit(JsParse *parse); +void jspKill(JsParse *parse); + +// jspSoft* - 'release' or 'claim' anything we are using, but ensure that it doesn't get freed +void jspSoftInit(JsParse *parse); ///< used when recovering from or saving to flash +void jspSoftKill(JsParse *parse); ///< used when recovering from or saving to flash +bool jspIsCreatedObject(JsParse *parse, JsVar *v); ///< Is v likely to have been created by this parser? +/** Returns true if the constructor function given is the same as that + * of the object with the given name. */ +bool jspIsConstructor(JsVar *constructor, const char *constructorName); + +/// Create a new built-in object that jswrapper can use to check for built-in functions +JsVar *jspNewBuiltin(const char *name); +/** Create a new object of the given instance and add it to root with name 'name'. + * If name!=0, added to root with name, and the name is returned + * If name==0, not added to root and Object itself returned */ +JsVar *jspNewObject(JsParse *parse, const char *name, const char *instanceOf); + +/// if interrupting execution, this is set +bool jspIsInterrupted(); +/// if interrupting execution, this is set +void jspSetInterrupted(bool interrupt); +/// Has there been an error during parsing +bool jspHasError(); + +bool jspAddNativeFunction(JsParse *parse, const char *funcDesc, JsCallback callbackPtr); +JsVar *jspEvaluateVar(JsParse *parse, JsVar *str, JsVar *scope); +JsVar *jspEvaluate(JsParse *parse, const char *str); +bool jspExecuteFunction(JsParse *parse, JsVar *func, JsVar *parent, int argCount, JsVar **argPtr); + +/// Evaluate a JavaScript module and return its exports +JsVar *jspEvaluateModule(JsParse *parse, JsVar *moduleContents); + +/** When parsing, this enum defines whether + we are executing or not */ +typedef enum { + EXEC_NO = 0, + EXEC_YES = 1, + EXEC_BREAK = 2, + EXEC_CONTINUE = 4, + + EXEC_INTERRUPTED = 8, // true if execution has been interrupted + EXEC_ERROR = 16, + EXEC_ERROR_LINE_REPORTED = 32, // if an error has been reported, set this so we don't do it too much + + EXEC_FOR_INIT = 64, // when in for initialiser parsing - hack to avoid getting confused about multiple use for IN + EXEC_IN_LOOP = 128, // when in a loop, set this - we can then block break/continue outside it + EXEC_IN_SWITCH = 256, // when in a switch, set this - we can then block break outside it/loops + + EXEC_RUN_MASK = EXEC_YES|EXEC_BREAK|EXEC_CONTINUE|EXEC_INTERRUPTED, + EXEC_ERROR_MASK = EXEC_INTERRUPTED|EXEC_ERROR, + EXEC_SAVE_RESTORE_MASK = EXEC_YES|EXEC_IN_LOOP|EXEC_IN_SWITCH, // the things JSP_SAVE/RESTORE_EXECUTE should keep track of +} JsExecFlags; + +/** This structure is used when parsing the JavaScript. It contains + * everything that should be needed. */ +typedef struct { + JsParse *parse; + JsLex *lex; + + // TODO: could store scopes as JsVar array for speed + JsVarRef scopes[JSPARSE_MAX_SCOPES]; + int scopeCount; + /// Value of 'this' reserved word + JsVar *thisVar; + + JsExecFlags execute; +} JsExecInfo; + +/// flags for jspParseFunction +typedef enum { + JSP_NOSKIP_A = 1, + JSP_NOSKIP_B = 2, + JSP_NOSKIP_C = 4, + JSP_NOSKIP_D = 8, + JSP_NOSKIP_E = 16, + JSP_NOSKIP_F = 32, + JSP_NOSKIP_G = 64, + JSP_NOSKIP_H = 128, +} JspSkipFlags; + +/// parse function with max 4 arguments (can set arg to 0 to avoid parse). Usually first arg will be 0, but if we DON'T want to skip names on an arg stuff, we can say +bool jspParseFunction(JspSkipFlags skipName, JsVar **a, JsVar **b, JsVar **c, JsVar **d); +/// parse function with max 8 arguments (can set arg to 0 to avoid parse). Usually first arg will be 0, but if we DON'T want to skip names on an arg stuff, we can say +bool jspParseFunction8(JspSkipFlags skipName, JsVar **a, JsVar **b, JsVar **c, JsVar **d, JsVar **e, JsVar **f, JsVar **g, JsVar **h); + +bool jspParseVariableName(); ///< parse single variable name +bool jspParseEmptyFunction(); ///< parse function with no arguments +JsVar *jspParseSingleFunction(); ///< parse function with a single argument, return its value (no names!) +JsVar *jspParseFunctionAsArray(); ///< parse a function with any number of argument, and return an array of de-named aruments + +/** Handle a function call (assumes we've parsed the function name and we're + * on the start bracket). 'thisArg' is the value of the 'this' variable when the + * function is executed (it's usually the parent object) + * + * If !isParsing and arg0!=0, argument 0 is set to what is supplied (same with arg1) + * + * functionName is used only for error reporting - and can be 0 + */ +JsVar *jspeFunctionCall(JsVar *function, JsVar *functionName, JsVar *thisArg, bool isParsing, int argCount, JsVar **argPtr); + +#endif /* JSPARSE_H_ */ |
