1
mirror of https://github.com/flipperdevices/flipperzero-firmware.git synced 2025-12-12 04:41:26 +04:00

[FL-3918] Full-fledged JS SDK + npm packages (#3963)

* feat: js sdk
* refactor: move js back where it belongs
* docs: generate docs using typedoc
* feat: sdk versioning scheme
* ci: silence pvs warning
* docs: bring back old incomplete js docs
* style: readAnalog naming
* fix: rename script compatibility screens

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
Anna Antonenko
2024-10-31 05:42:57 +03:00
committed by GitHub
parent e4c8270824
commit 85e5642b2a
62 changed files with 3150 additions and 419 deletions

View File

@@ -146,10 +146,17 @@ void mjs_init_builtin(struct mjs* mjs, mjs_val_t obj) {
// mjs_set(mjs, obj, "JSON", ~0, v);
/*
* Populate Object.create()
* Populate Object
*/
v = mjs_mk_object(mjs);
mjs_set(mjs, v, "create", ~0, mjs_mk_foreign_func(mjs, (mjs_func_ptr_t)mjs_op_create_object));
mjs_set(
mjs,
v,
"defineProperty",
~0,
mjs_mk_foreign_func(
mjs, (mjs_func_ptr_t)mjs_op_object_define_property)); // stub, do not use
mjs_set(mjs, obj, "Object", ~0, v);
/*

View File

@@ -294,6 +294,11 @@ clean:
mjs_return(mjs, ret);
}
MJS_PRIVATE void mjs_op_object_define_property(struct mjs* mjs) {
// stub, do not use
mjs_return(mjs, MJS_UNDEFINED);
}
mjs_val_t
mjs_struct_to_obj(struct mjs* mjs, const void* base, const struct mjs_c_struct_member* defs) {
mjs_val_t obj;

View File

@@ -50,6 +50,11 @@ MJS_PRIVATE mjs_err_t mjs_set_internal(
*/
MJS_PRIVATE void mjs_op_create_object(struct mjs* mjs);
/*
* Stub of `Object.defineProperty()`
*/
MJS_PRIVATE void mjs_op_object_define_property(struct mjs* mjs);
/*
* Cell destructor for object arena
*/

View File

@@ -76,7 +76,8 @@ static int s_assign_ops[] = {
static int findtok(int* toks, int tok) {
int i = 0;
while(tok != toks[i] && toks[i] != TOK_EOF) i++;
while(tok != toks[i] && toks[i] != TOK_EOF)
i++;
return toks[i];
}
@@ -87,7 +88,7 @@ static void emit_op(struct pstate* pstate, int tok) {
}
#define BINOP_STACK_FRAME_SIZE 16
#define STACK_LIMIT 8192
#define STACK_LIMIT 8192
// Intentionally left as macro rather than a function, to let the
// compiler to inline calls and mimimize runtime stack usage.
@@ -166,7 +167,8 @@ static mjs_err_t parse_statement_list(struct pstate* p, int et) {
if(drop) emit_byte(p, OP_DROP);
res = parse_statement(p);
drop = 1;
while(p->tok.tok == TOK_SEMICOLON) pnext1(p);
while(p->tok.tok == TOK_SEMICOLON)
pnext1(p);
}
/*
@@ -523,7 +525,11 @@ static mjs_err_t parse_expr(struct pstate* p) {
static mjs_err_t parse_let(struct pstate* p) {
mjs_err_t res = MJS_OK;
LOG(LL_VERBOSE_DEBUG, ("[%.*s]", 10, p->tok.ptr));
EXPECT(p, TOK_KEYWORD_LET);
if((p)->tok.tok != TOK_KEYWORD_VAR && (p)->tok.tok != TOK_KEYWORD_LET &&
(p)->tok.tok != TOK_KEYWORD_CONST)
SYNTAX_ERROR(p);
else
pnext1(p);
for(;;) {
struct tok tmp = p->tok;
EXPECT(p, TOK_IDENT);
@@ -910,6 +916,8 @@ static mjs_err_t parse_statement(struct pstate* p) {
pnext1(p);
return MJS_OK;
case TOK_KEYWORD_LET:
case TOK_KEYWORD_VAR:
case TOK_KEYWORD_CONST:
return parse_let(p);
case TOK_OPEN_CURLY:
return parse_block(p, 1);
@@ -939,7 +947,6 @@ static mjs_err_t parse_statement(struct pstate* p) {
case TOK_KEYWORD_SWITCH:
case TOK_KEYWORD_THROW:
case TOK_KEYWORD_TRY:
case TOK_KEYWORD_VAR:
case TOK_KEYWORD_VOID:
case TOK_KEYWORD_WITH:
mjs_set_errorf(

View File

@@ -80,12 +80,13 @@ static int getnum(struct pstate* p) {
}
static int is_reserved_word_token(const char* s, int len) {
const char* reserved[] = {"break", "case", "catch", "continue", "debugger", "default",
"delete", "do", "else", "false", "finally", "for",
"function", "if", "in", "instanceof", "new", "null",
"return", "switch", "this", "throw", "true", "try",
"typeof", "var", "void", "while", "with", "let",
"undefined", NULL};
const char* reserved[] = {"break", "case", "catch", "continue", "debugger",
"default", "delete", "do", "else", "false",
"finally", "for", "function", "if", "in",
"instanceof", "new", "null", "return", "switch",
"this", "throw", "true", "try", "typeof",
"var", "void", "while", "with", "let",
"const", "undefined", NULL};
int i;
if(!mjs_is_alpha(s[0])) return 0;
for(i = 0; reserved[i] != NULL; i++) {
@@ -95,7 +96,8 @@ static int is_reserved_word_token(const char* s, int len) {
}
static int getident(struct pstate* p) {
while(mjs_is_ident(p->pos[0]) || mjs_is_digit(p->pos[0])) p->pos++;
while(mjs_is_ident(p->pos[0]) || mjs_is_digit(p->pos[0]))
p->pos++;
p->tok.len = p->pos - p->tok.ptr;
p->pos--;
return TOK_IDENT;
@@ -125,7 +127,8 @@ static void skip_spaces_and_comments(struct pstate* p) {
p->pos++;
}
if(p->pos[0] == '/' && p->pos[1] == '/') {
while(p->pos[0] != '\0' && p->pos[0] != '\n') p->pos++;
while(p->pos[0] != '\0' && p->pos[0] != '\n')
p->pos++;
}
if(p->pos[0] == '/' && p->pos[1] == '*') {
p->pos += 2;
@@ -142,8 +145,8 @@ static void skip_spaces_and_comments(struct pstate* p) {
}
static int ptranslate(int tok) {
#define DT(a, b) ((a) << 8 | (b))
#define TT(a, b, c) ((a) << 16 | (b) << 8 | (c))
#define DT(a, b) ((a) << 8 | (b))
#define TT(a, b, c) ((a) << 16 | (b) << 8 | (c))
#define QT(a, b, c, d) ((a) << 24 | (b) << 16 | (c) << 8 | (d))
/* Map token ID produced by mjs_tok.c to token ID produced by lemon */
/* clang-format off */

View File

@@ -125,6 +125,7 @@ enum {
TOK_KEYWORD_WHILE,
TOK_KEYWORD_WITH,
TOK_KEYWORD_LET,
TOK_KEYWORD_CONST,
TOK_KEYWORD_UNDEFINED,
TOK_MAX
};