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.

bigint .toString fixes

+125 -12
+2 -1
examples/spec/run.js
··· 25 25 const name = path.basename(file, '.js'); 26 26 27 27 try { 28 - const result = await $`ant ${filePath}`; 28 + const result = await $`./build/ant ${filePath}`; 29 + console.log(result.text()); 29 30 30 31 if (result.exitCode === 0) { 31 32 console.log(`${GREEN}โœ“${RESET} ${name}`);
+3
maidfile.toml
··· 12 12 [tasks.run] 13 13 script = ["maid build -q", "./build/ant %{arg.1}"] 14 14 15 + [tasks.spec] 16 + script = ["maid build -q", "./build/ant examples/spec/%{arg.1}.js"] 17 + 15 18 [tasks.debug] 16 19 script = ["maid build -q", "./build/ant -d %{arg.1}"] 17 20
+1 -1
meson.build
··· 74 74 build_date = run_command('date', '+%Y-%m-%d', check: true).stdout().strip() 75 75 76 76 version_conf = configuration_data() 77 - version_conf.set('ANT_VERSION', '0.1.0.21') 77 + version_conf.set('ANT_VERSION', '0.1.0.22') 78 78 version_conf.set('ANT_GIT_HASH', git_hash) 79 79 version_conf.set('ANT_BUILD_DATE', build_date) 80 80
+119 -10
src/ant.c
··· 2053 2053 return mkbigint(js, digits, len, !neg); 2054 2054 } 2055 2055 2056 + static jsval_t bigint_exp(struct js *js, jsval_t base, jsval_t exp) { 2057 + if (bigint_IsNegative(js, exp)) return js_mkerr(js, "Exponent must be positive"); 2058 + size_t explen; 2059 + const char *expd = bigint_digits(js, exp, &explen); 2060 + if (explen == 1 && expd[0] == '0') return mkbigint(js, "1", 1, false); 2061 + jsval_t result = mkbigint(js, "1", 1, false); 2062 + jsval_t b = base; 2063 + jsval_t e = exp; 2064 + jsval_t two = mkbigint(js, "2", 1, false); 2065 + while (true) { 2066 + size_t elen; 2067 + const char *ed = bigint_digits(js, e, &elen); 2068 + if (elen == 1 && ed[0] == '0') break; 2069 + int last_digit = ed[elen - 1] - '0'; 2070 + if (last_digit % 2 == 1) { 2071 + result = bigint_mul(js, result, b); 2072 + if (is_err(result)) return result; 2073 + } 2074 + b = bigint_mul(js, b, b); 2075 + if (is_err(b)) return b; 2076 + e = bigint_div(js, e, two); 2077 + if (is_err(e)) return e; 2078 + } 2079 + return result; 2080 + } 2081 + 2056 2082 static int bigint_compare(struct js *js, jsval_t a, jsval_t b) { 2057 2083 bool aneg = bigint_IsNegative(js, a), bneg = bigint_IsNegative(js, b); 2058 2084 size_t alen, blen; ··· 2123 2149 return js_mkerr(js, "BigInt.asUintN not implemented"); 2124 2150 } 2125 2151 2152 + static jsval_t builtin_bigint_toString(struct js *js, jsval_t *args, int nargs) { 2153 + jsval_t val = js->this_val; 2154 + if (vtype(val) != T_BIGINT) return js_mkerr(js, "toString called on non-BigInt"); 2155 + 2156 + int radix = 10; 2157 + if (nargs >= 1 && vtype(args[0]) == T_NUM) { 2158 + radix = (int)tod(args[0]); 2159 + if (radix < 2 || radix > 36) { 2160 + return js_mkerr(js, "radix must be between 2 and 36"); 2161 + } 2162 + } 2163 + 2164 + bool neg = bigint_IsNegative(js, val); 2165 + size_t dlen; 2166 + const char *digits = bigint_digits(js, val, &dlen); 2167 + 2168 + if (radix == 10) { 2169 + char buf[1024]; 2170 + size_t n = 0; 2171 + if (neg) buf[n++] = '-'; 2172 + memcpy(buf + n, digits, dlen); 2173 + n += dlen; 2174 + return js_mkstr(js, buf, n); 2175 + } 2176 + 2177 + char result[2048]; 2178 + size_t rpos = sizeof(result) - 1; 2179 + result[rpos] = '\0'; 2180 + 2181 + char *num = (char *)malloc(dlen + 1); 2182 + if (!num) return js_mkerr(js, "oom"); 2183 + memcpy(num, digits, dlen); 2184 + num[dlen] = '\0'; 2185 + size_t numlen = dlen; 2186 + 2187 + while (numlen > 0 && !(numlen == 1 && num[0] == '0')) { 2188 + int remainder = 0; 2189 + for (size_t i = 0; i < numlen; i++) { 2190 + int d = remainder * 10 + (num[i] - '0'); 2191 + num[i] = '0' + (d / radix); 2192 + remainder = d % radix; 2193 + } 2194 + size_t start = 0; 2195 + while (start < numlen - 1 && num[start] == '0') start++; 2196 + memmove(num, num + start, numlen - start + 1); 2197 + numlen -= start; 2198 + if (numlen == 1 && num[0] == '0') numlen = 0; 2199 + rpos--; 2200 + result[rpos] = remainder < 10 ? '0' + remainder : 'a' + (remainder - 10); 2201 + } 2202 + 2203 + free(num); 2204 + 2205 + if (rpos == sizeof(result) - 1) { 2206 + result[--rpos] = '0'; 2207 + } 2208 + 2209 + if (neg) result[--rpos] = '-'; 2210 + 2211 + return js_mkstr(js, result + rpos, sizeof(result) - 1 - rpos); 2212 + } 2213 + 2126 2214 static jsval_t mkobj(struct js *js, jsoff_t parent) { 2127 2215 return mkentity(js, 0 | T_OBJ, &parent, sizeof(parent)); 2128 2216 } ··· 3119 3207 case T_FUNC: return get_ctor_proto(js, "Function", 8); 3120 3208 case T_PROMISE: return get_ctor_proto(js, "Promise", 7); 3121 3209 case T_OBJ: return get_ctor_proto(js, "Object", 6); 3210 + case T_BIGINT: return get_ctor_proto(js, "BigInt", 6); 3122 3211 default: return js_mknull(); 3123 3212 } 3124 3213 } ··· 3148 3237 cur = get_proto(js, cur); 3149 3238 if (vtype(cur) == T_NULL || vtype(cur) == T_UNDEF) break; 3150 3239 depth++; 3151 - } else if (t == T_STR || t == T_NUM || t == T_BOOL) { 3240 + } else if (t == T_STR || t == T_NUM || t == T_BOOL || t == T_BIGINT) { 3152 3241 jsval_t proto = get_prototype_for_type(js, t); 3153 3242 if (vtype(proto) == T_NULL || vtype(proto) == T_UNDEF) break; 3154 3243 cur = proto; ··· 3454 3543 return resolveprop(js, mkval(T_PROP, off)); 3455 3544 } 3456 3545 3457 - if (t == T_STR || t == T_NUM || t == T_BOOL) { 3546 + if (t == T_STR || t == T_NUM || t == T_BOOL || t == T_BIGINT) { 3458 3547 jsoff_t off = lkp_proto(js, l, ptr, plen); 3459 3548 if (off != 0) { 3460 3549 return resolveprop(js, mkval(T_PROP, off)); ··· 4185 4274 if (is_assign(op) && vtype(lhs) != T_PROP && vtype(lhs) != T_PROPREF) return js_mkerr(js, "bad lhs"); 4186 4275 4187 4276 switch (op) { 4188 - case TOK_TYPEOF: return js_mkstr(js, typestr(vtype(r)), strlen(typestr(vtype(r)))); 4189 - case TOK_VOID: return js_mkundef(); 4190 - case TOK_INSTANCEOF: return do_instanceof(js, l, r); 4191 - case TOK_IN: return do_in(js, l, r); 4192 - case TOK_CALL: return do_call_op(js, l, r); 4193 - case TOK_BRACKET: return do_bracket_op(js, l, rhs); 4194 - case TOK_ASSIGN: return assign(js, lhs, r); 4277 + case TOK_TYPEOF: return js_mkstr(js, typestr(vtype(r)), strlen(typestr(vtype(r)))); 4278 + case TOK_VOID: return js_mkundef(); 4279 + case TOK_INSTANCEOF: return do_instanceof(js, l, r); 4280 + case TOK_IN: return do_in(js, l, r); 4281 + case TOK_CALL: return do_call_op(js, l, r); 4282 + case TOK_BRACKET: return do_bracket_op(js, l, rhs); 4283 + case TOK_ASSIGN: return assign(js, lhs, r); 4284 + case TOK_DOT: return do_dot_op(js, l, r); 4285 + case TOK_OPTIONAL_CHAIN: return do_optional_chain_op(js, l, r); 4195 4286 case TOK_POSTINC: { 4196 4287 if (vtype(lhs) != T_PROP) return js_mkerr(js, "bad lhs for ++"); 4197 4288 do_assign_op(js, TOK_PLUS_ASSIGN, lhs, tov(1)); return l; ··· 4225 4316 } else { 4226 4317 eq = vdata(l) == vdata(r); 4227 4318 } 4319 + } else if ((vtype(l) == T_BIGINT && vtype(r) == T_NUM) || 4320 + (vtype(l) == T_NUM && vtype(r) == T_BIGINT)) { 4321 + double num_val = vtype(l) == T_NUM ? tod(l) : tod(r); 4322 + jsval_t bigint_val = vtype(l) == T_BIGINT ? l : r; 4323 + if (isfinite(num_val) && num_val == trunc(num_val)) { 4324 + bool neg = num_val < 0; 4325 + if (neg) num_val = -num_val; 4326 + char buf[64]; 4327 + snprintf(buf, sizeof(buf), "%.0f", num_val); 4328 + jsval_t num_as_bigint = mkbigint(js, buf, strlen(buf), neg); 4329 + eq = bigint_compare(js, bigint_val, num_as_bigint) == 0; 4330 + } 4228 4331 } 4229 4332 return mkval(T_BOOL, op == TOK_EQ ? eq : !eq); 4230 4333 } ··· 4238 4341 case TOK_MUL: return bigint_mul(js, l, r); 4239 4342 case TOK_DIV: return bigint_div(js, l, r); 4240 4343 case TOK_REM: return bigint_mod(js, l, r); 4344 + case TOK_EXP: return bigint_exp(js, l, r); 4241 4345 case TOK_LT: return mkval(T_BOOL, bigint_compare(js, l, r) < 0); 4242 4346 case TOK_GT: return mkval(T_BOOL, bigint_compare(js, l, r) > 0); 4243 4347 case TOK_LE: return mkval(T_BOOL, bigint_compare(js, l, r) <= 0); ··· 8633 8737 jsval_t obj = args[0]; 8634 8738 uint8_t t = vtype(obj); 8635 8739 8636 - if (t == T_STR || t == T_NUM || t == T_BOOL) return get_prototype_for_type(js, t); 8740 + if (t == T_STR || t == T_NUM || t == T_BOOL || t == T_BIGINT) return get_prototype_for_type(js, t); 8637 8741 if (t == T_OBJ || t == T_ARR || t == T_FUNC) return get_proto(js, obj); 8638 8742 8639 8743 return js_mknull(); ··· 13571 13675 jsval_t boolean_proto = js_mkobj(js); 13572 13676 set_proto(js, boolean_proto, object_proto); 13573 13677 13678 + jsval_t bigint_proto = js_mkobj(js); 13679 + set_proto(js, bigint_proto, object_proto); 13680 + setprop(js, bigint_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_bigint_toString)); 13681 + 13574 13682 jsval_t error_proto = js_mkobj(js); 13575 13683 set_proto(js, error_proto, object_proto); 13576 13684 setprop(js, error_proto, js_mkstr(js, "name", 4), js_mkstr(js, "Error", 5)); ··· 13728 13836 setprop(js, bigint_ctor_obj, js_mkstr(js, "__native_func", 13), js_mkfun(builtin_BigInt)); 13729 13837 setprop(js, bigint_ctor_obj, js_mkstr(js, "asIntN", 6), js_mkfun(builtin_BigInt_asIntN)); 13730 13838 setprop(js, bigint_ctor_obj, js_mkstr(js, "asUintN", 7), js_mkfun(builtin_BigInt_asUintN)); 13839 + setprop(js, bigint_ctor_obj, js_mkstr(js, "prototype", 9), bigint_proto); 13731 13840 setprop(js, glob, js_mkstr(js, "BigInt", 6), mkval(T_FUNC, vdata(bigint_ctor_obj))); 13732 13841 13733 13842 setprop(js, glob, js_mkstr(js, "eval", 4), js_mkfun(builtin_eval));