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.

collecting export specifiers first

+63 -47
+5
examples/demo/destr.js
··· 1 + import { $ } from 'ant:shell'; 2 + import parse from 'https://esm.sh/destr'; 3 + 4 + const data = $`maid -g json-hydrated`.text(); 5 + console.log(parse(data));
+49 -13
src/ant.c
··· 19843 19843 if (next(js) == TOK_LBRACE) { 19844 19844 js->consumed = 1; 19845 19845 19846 + typedef struct { const char *local; size_t local_len; const char *exported; size_t export_len; } export_spec_t; 19847 + export_spec_t specs[64]; 19848 + int spec_count = 0; 19849 + 19846 19850 while (next(js) != TOK_RBRACE) { 19847 - EXPECT(TOK_IDENTIFIER, ); 19848 - const char *local_name = &js->code[js->toff]; 19849 - size_t local_len = js->tlen; 19851 + if (spec_count >= 64) return js_mkerr(js, "too many export specifiers"); 19852 + 19853 + if (next(js) != TOK_IDENTIFIER && next(js) != TOK_DEFAULT) { 19854 + return js_mkerr_typed(js, JS_ERR_SYNTAX, "expected identifier or 'default' in export list"); 19855 + } 19856 + specs[spec_count].local = &js->code[js->toff]; 19857 + specs[spec_count].local_len = js->tlen; 19858 + specs[spec_count].exported = specs[spec_count].local; 19859 + specs[spec_count].export_len = specs[spec_count].local_len; 19850 19860 js->consumed = 1; 19851 19861 19852 - const char *export_name = local_name; 19853 - size_t export_len = local_len; 19854 - 19855 19862 if (next(js) == TOK_AS) { 19856 19863 js->consumed = 1; 19857 - EXPECT(TOK_IDENTIFIER, ); 19858 - export_name = &js->code[js->toff]; 19859 - export_len = js->tlen; 19864 + if (next(js) != TOK_IDENTIFIER && next(js) != TOK_DEFAULT) { 19865 + return js_mkerr_typed(js, JS_ERR_SYNTAX, "expected identifier or 'default' after 'as'"); 19866 + } 19867 + specs[spec_count].exported = &js->code[js->toff]; 19868 + specs[spec_count].export_len = js->tlen; 19860 19869 js->consumed = 1; 19861 19870 } 19862 19871 19863 - jsval_t local_val = lookup(js, local_name, local_len); 19864 - if (is_err(local_val)) return local_val; 19865 - 19866 - setprop(js, js->module_ns, js_mkstr(js, export_name, export_len), resolveprop(js, local_val)); 19872 + spec_count++; 19867 19873 if (next(js) == TOK_COMMA) js->consumed = 1; 19868 19874 } 19869 19875 19870 19876 EXPECT(TOK_RBRACE, ); 19877 + 19878 + if (next(js) == TOK_FROM) { 19879 + js->consumed = 1; 19880 + EXPECT(TOK_STRING, ); 19881 + jsval_t spec = js_str_literal(js); 19882 + jsoff_t spec_len; 19883 + char *spec_str = esm_jsval_to_cstr(js, spec, &spec_len); 19884 + 19885 + js_parse_state_t saved; 19886 + JS_SAVE_STATE(js, saved); 19887 + jsval_t ns = esm_resolve_and_load(js, spec_str, spec_len); 19888 + JS_RESTORE_STATE(js, saved); 19889 + free(spec_str); 19890 + 19891 + js->consumed = 1; next(js); js->consumed = 0; 19892 + if (is_err(ns)) return ns; 19893 + 19894 + for (int i = 0; i < spec_count; i++) { 19895 + jsoff_t prop_off = lkp(js, ns, specs[i].local, specs[i].local_len); 19896 + jsval_t import_val = prop_off != 0 ? resolveprop(js, mkval(T_PROP, prop_off)) : js_mkundef(); 19897 + setprop(js, js->module_ns, js_mkstr(js, specs[i].exported, specs[i].export_len), import_val); 19898 + } 19899 + } else { 19900 + for (int i = 0; i < spec_count; i++) { 19901 + jsval_t local_val = lookup(js, specs[i].local, specs[i].local_len); 19902 + if (is_err(local_val)) return local_val; 19903 + setprop(js, js->module_ns, js_mkstr(js, specs[i].exported, specs[i].export_len), resolveprop(js, local_val)); 19904 + } 19905 + } 19906 + 19871 19907 if (next(js) == TOK_SEMICOLON) js->consumed = 1; 19872 19908 return js_mkundef(); 19873 19909 }
+9 -34
src/modules/shell.c
··· 66 66 jsval_t stdout_val = js_mkstr(js, output, output_size); 67 67 free(output); 68 68 69 - js_set(js, result, "stdout", stdout_val); 70 - js_set(js, result, "stderr", js_mkstr(js, "", 0)); 71 69 js_set(js, result, "exitCode", js_mknum(exit_code)); 72 - 73 - jsval_t text_fn = js_mkfun(builtin_shell_text); 74 - js_set(js, result, "text", text_fn); 75 - 76 - jsval_t lines_fn = js_mkfun(builtin_shell_lines); 77 - js_set(js, result, "lines", lines_fn); 70 + js_set(js, result, "text", js_heavy_mkfun(js, builtin_shell_text, stdout_val)); 71 + js_set(js, result, "lines", js_heavy_mkfun(js, builtin_shell_lines, stdout_val)); 78 72 79 73 return result; 80 74 } ··· 83 77 (void)args; 84 78 (void)nargs; 85 79 86 - jsval_t this_val = js_getthis(js); 87 - if (js_type(this_val) != JS_OBJ) { 88 - return js_mkerr(js, "text() must be called on a shell result"); 89 - } 90 - 91 - jsval_t stdout_val = js_get(js, this_val, "stdout"); 92 - return stdout_val; 80 + jsval_t fn = js_getcurrentfunc(js); 81 + return js_get_slot(js, fn, SLOT_DATA); 93 82 } 94 83 95 84 static jsval_t builtin_shell_lines(struct js *js, jsval_t *args, int nargs) { 96 85 (void)args; 97 86 (void)nargs; 98 87 99 - jsval_t this_val = js_getthis(js); 100 - if (js_type(this_val) != JS_OBJ) return js_mkerr(js, "lines() must be called on a shell result"); 101 - 102 - jsval_t stdout_val = js_get(js, this_val, "stdout"); 103 - if (js_type(stdout_val) != JS_STR) return js_mkerr(js, "No stdout available"); 88 + jsval_t fn = js_getcurrentfunc(js); 89 + jsval_t stdout_val = js_get_slot(js, fn, SLOT_DATA); 104 90 105 91 size_t text_len; 106 92 char *text = js_getstr(js, stdout_val, &text_len); 107 - if (!text) return js_mkerr(js, "Failed to get stdout"); 93 + if (!text) return js_mkarr(js); 108 94 109 - jsval_t lines_array = js_mkobj(js); 110 - 111 - size_t line_count = 0; 95 + jsval_t lines_array = js_mkarr(js); 112 96 size_t line_start = 0; 113 97 114 98 for (size_t i = 0; i <= text_len; i++) { 115 99 if (i == text_len || text[i] == '\n') { 116 100 size_t line_len = i - line_start; 117 - if (i < text_len && text[i] == '\n') {} 118 - 119 - char idx_str[32]; 120 - snprintf(idx_str, sizeof(idx_str), "%zu", line_count); 121 - 122 101 jsval_t line_val = js_mkstr(js, text + line_start, line_len); 123 - js_set(js, lines_array, idx_str, line_val); 124 - 125 - line_count++; 102 + js_arr_push(js, lines_array, line_val); 126 103 line_start = i + 1; 127 104 } 128 105 } 129 - 130 - js_set(js, lines_array, "length", js_mknum((double)line_count)); 131 106 132 107 return lines_array; 133 108 }