MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

improve support for destructuring patterns

+65 -137
+1 -1
meson.build
··· 79 79 build_date = run_command('date', '+%Y-%m-%d', check: true).stdout().strip() 80 80 81 81 version_conf = configuration_data() 82 - version_conf.set('ANT_VERSION', '0.2.2.33') 82 + version_conf.set('ANT_VERSION', '0.2.2.34') 83 83 version_conf.set('ANT_GIT_HASH', git_hash) 84 84 version_conf.set('ANT_BUILD_DATE', build_date) 85 85
+64 -136
src/ant.c
··· 6924 6924 return obj; 6925 6925 } 6926 6926 6927 + static void skip_default_value(struct js *js) { 6928 + int depth = 0; 6929 + while (next(js) != TOK_EOF) { 6930 + uint8_t tok = next(js); 6931 + if (depth == 0 && (tok == TOK_RPAREN || tok == TOK_COMMA)) break; 6932 + js->consumed = 1; 6933 + if (tok == TOK_LPAREN || tok == TOK_LBRACKET || tok == TOK_LBRACE) depth++; 6934 + else if (tok == TOK_RPAREN || tok == TOK_RBRACKET || tok == TOK_RBRACE) depth--; 6935 + } 6936 + } 6937 + 6938 + static void skip_destructuring_pattern(struct js *js) { 6939 + uint8_t open_tok = js->tok; 6940 + uint8_t close_tok = (open_tok == TOK_LBRACE) ? TOK_RBRACE : TOK_RBRACKET; 6941 + int depth = 1; 6942 + js->consumed = 1; 6943 + while (depth > 0 && next(js) != TOK_EOF) { 6944 + if (js->tok == open_tok) depth++; 6945 + else if (js->tok == close_tok) depth--; 6946 + if (depth > 0) js->consumed = 1; 6947 + } 6948 + js->consumed = 1; 6949 + } 6950 + 6951 + typedef struct { const char *name; size_t len; } param_entry_t; 6952 + static const UT_icd param_entry_icd = { sizeof(param_entry_t), NULL, NULL, NULL }; 6953 + 6927 6954 static bool parse_func_params(struct js *js, uint8_t *flags, int *out_count) { 6928 - int param_count = 0; 6929 - int param_capacity = 16; 6930 - const char **param_names = (const char **)ANT_GC_MALLOC(param_capacity * sizeof(char *)); 6931 - size_t *param_lens = (size_t *)ANT_GC_MALLOC(param_capacity * sizeof(size_t)); 6955 + UT_array *params; 6956 + utarray_new(params, &param_entry_icd); 6932 6957 6933 - if (!param_names || !param_lens) { 6934 - if (flags) js->flags = *flags; 6935 - js_mkerr_typed(js, JS_ERR_SYNTAX, "out of memory"); 6936 - return false; 6937 - } 6958 + #define FAIL(msg, ...) do { \ 6959 + if (flags) js->flags = *flags; \ 6960 + js_mkerr_typed(js, JS_ERR_SYNTAX, msg, ##__VA_ARGS__); \ 6961 + utarray_free(params); \ 6962 + return false; \ 6963 + } while(0) 6938 6964 6939 - for (bool comma = false; next(js) != TOK_EOF; comma = true) { 6940 - if (!comma && next(js) == TOK_RPAREN) break; 6941 - 6942 - bool is_rest = false; 6943 - if (next(js) == TOK_REST) { 6944 - is_rest = true; 6945 - js->consumed = 1; 6946 - next(js); 6947 - } 6965 + while (next(js) != TOK_EOF && next(js) != TOK_RPAREN) { 6966 + bool is_rest = (next(js) == TOK_REST); 6967 + if (is_rest) { js->consumed = 1; next(js); } 6948 6968 6949 6969 if (next(js) == TOK_LBRACE || next(js) == TOK_LBRACKET) { 6950 - uint8_t open_tok = js->tok; 6951 - uint8_t close_tok = (open_tok == TOK_LBRACE) ? TOK_RBRACE : TOK_RBRACKET; 6952 - int depth = 1; 6953 - js->consumed = 1; 6954 - while (depth > 0 && next(js) != TOK_EOF) { 6955 - if (js->tok == open_tok) depth++; 6956 - else if (js->tok == close_tok) depth--; 6957 - if (depth > 0) js->consumed = 1; 6958 - } 6959 - js->consumed = 1; 6960 - param_count++; 6970 + skip_destructuring_pattern(js); 6971 + param_entry_t entry = {NULL, 0}; 6972 + utarray_push_back(params, &entry); 6973 + if (next(js) == TOK_ASSIGN) { js->consumed = 1; skip_default_value(js); } 6974 + } else if (next(js) == TOK_IDENTIFIER) { 6975 + const char *name = &js->code[js->toff]; 6976 + size_t len = js->tlen; 6961 6977 6962 - if (next(js) == TOK_ASSIGN) { 6963 - js->consumed = 1; 6964 - int ddepth = 0; 6965 - bool done = false; 6966 - while (!done && next(js) != TOK_EOF) { 6967 - uint8_t tok = next(js); 6968 - if (ddepth == 0 && (tok == TOK_RPAREN || tok == TOK_COMMA)) { 6969 - done = true; 6970 - } else if (tok == TOK_LPAREN || tok == TOK_LBRACKET || tok == TOK_LBRACE) { 6971 - ddepth++; 6972 - js->consumed = 1; 6973 - } else if (tok == TOK_RPAREN || tok == TOK_RBRACKET || tok == TOK_RBRACE) { 6974 - ddepth--; 6975 - js->consumed = 1; 6976 - } else { 6977 - js->consumed = 1; 6978 - } 6979 - } 6980 - } 6978 + if ((js->flags & F_STRICT) && is_strict_restricted(name, len)) 6979 + FAIL("cannot use '%.*s' as parameter name in strict mode", (int)len, name); 6981 6980 6982 - if (is_rest && next(js) != TOK_RPAREN) { 6983 - if (flags) js->flags = *flags; 6984 - js_mkerr_typed(js, JS_ERR_SYNTAX, "rest parameter must be last"); 6985 - return false; 6986 - } 6987 - if (next(js) == TOK_RPAREN) break; 6988 - if (next(js) != TOK_COMMA) { 6989 - if (flags) js->flags = *flags; 6990 - js_mkerr_typed(js, JS_ERR_SYNTAX, "parse error"); 6991 - return false; 6992 - } 6993 - js->consumed = 1; 6994 - continue; 6995 - } 6996 - 6997 - if (next(js) != TOK_IDENTIFIER) { 6998 - if (flags) js->flags = *flags; 6999 - js_mkerr_typed(js, JS_ERR_SYNTAX, "identifier expected"); 7000 - return false; 7001 - } 7002 - 7003 - const char *param_name = &js->code[js->toff]; 7004 - size_t param_len = js->tlen; 7005 - 7006 - if ((js->flags & F_STRICT) && is_strict_restricted(param_name, param_len)) { 7007 - if (flags) js->flags = *flags; 7008 - js_mkerr_typed(js, JS_ERR_SYNTAX, "cannot use '%.*s' as parameter name in strict mode", (int) param_len, param_name); 7009 - return false; 7010 - } 7011 - 7012 - if (js->flags & F_STRICT) { 7013 - for (int i = 0; i < param_count; i++) { 7014 - if (param_lens[i] == param_len && memcmp(param_names[i], param_name, param_len) == 0) { 7015 - if (flags) js->flags = *flags; 7016 - js_mkerr_typed(js, JS_ERR_SYNTAX, "duplicate parameter name '%.*s' in strict mode", (int) param_len, param_name); 7017 - return false; 6981 + if (js->flags & F_STRICT) { 6982 + param_entry_t *p = NULL; 6983 + while ((p = (param_entry_t *)utarray_next(params, p))) { 6984 + if (p->len == len && p->name && memcmp(p->name, name, len) == 0) 6985 + FAIL("duplicate parameter name '%.*s' in strict mode", (int)len, name); 7018 6986 } 7019 6987 } 7020 - } 7021 - 7022 - if (param_count >= param_capacity) { 7023 - param_capacity *= 2; 7024 - const char **new_names = (const char **)ANT_GC_MALLOC(param_capacity * sizeof(char *)); 7025 - size_t *new_lens = (size_t *)ANT_GC_MALLOC(param_capacity * sizeof(size_t)); 7026 - if (!new_names || !new_lens) { 7027 - if (flags) js->flags = *flags; 7028 - js_mkerr_typed(js, JS_ERR_SYNTAX, "out of memory"); 7029 - return false; 7030 - } 7031 - memcpy(new_names, param_names, param_count * sizeof(char *)); 7032 - memcpy(new_lens, param_lens, param_count * sizeof(size_t)); 7033 - param_names = new_names; 7034 - param_lens = new_lens; 7035 - } 7036 - 7037 - param_names[param_count] = param_name; 7038 - param_lens[param_count] = param_len; 7039 - param_count++; 7040 - 7041 - js->consumed = 1; 7042 - 7043 - if (next(js) == TOK_ASSIGN) { 6988 + 6989 + param_entry_t entry = {name, len}; 6990 + utarray_push_back(params, &entry); 7044 6991 js->consumed = 1; 7045 - int depth = 0; 7046 - bool done = false; 7047 - while (!done && next(js) != TOK_EOF) { 7048 - uint8_t tok = next(js); 7049 - if (depth == 0 && (tok == TOK_RPAREN || tok == TOK_COMMA)) { 7050 - done = true; 7051 - } else if (tok == TOK_LPAREN || tok == TOK_LBRACKET || tok == TOK_LBRACE) { 7052 - depth++; 7053 - js->consumed = 1; 7054 - } else if (tok == TOK_RPAREN || tok == TOK_RBRACKET || tok == TOK_RBRACE) { 7055 - depth--; 7056 - js->consumed = 1; 7057 - } else { 7058 - js->consumed = 1; 7059 - } 7060 - } 6992 + if (next(js) == TOK_ASSIGN) { js->consumed = 1; skip_default_value(js); } 6993 + } else { 6994 + FAIL("identifier expected"); 7061 6995 } 7062 6996 7063 - if (is_rest && next(js) != TOK_RPAREN) { 7064 - if (flags) js->flags = *flags; 7065 - js_mkerr_typed(js, JS_ERR_SYNTAX, "rest parameter must be last"); 7066 - return false; 7067 - } 6997 + if (is_rest && next(js) != TOK_RPAREN) FAIL("rest parameter must be last"); 7068 6998 if (next(js) == TOK_RPAREN) break; 7069 - 7070 - if (next(js) != TOK_COMMA) { 7071 - if (flags) js->flags = *flags; 7072 - js_mkerr_typed(js, JS_ERR_SYNTAX, "parse error"); 7073 - return false; 7074 - } 6999 + if (next(js) != TOK_COMMA) FAIL("parse error"); 7075 7000 js->consumed = 1; 7076 7001 } 7077 7002 7078 - if (out_count) *out_count = param_count; 7003 + #undef FAIL 7004 + 7005 + if (out_count) *out_count = (int)utarray_len(params); 7006 + utarray_free(params); 7079 7007 return true; 7080 7008 } 7081 7009