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 string ops

+461 -2
+1 -1
meson.build
··· 41 41 build_date = run_command('date', '+%Y-%m-%d', check: true).stdout().strip() 42 42 43 43 version_conf = configuration_data() 44 - version_conf.set('ANT_VERSION', '0.0.5.51') 44 + version_conf.set('ANT_VERSION', '0.0.5.52') 45 45 version_conf.set('ANT_GIT_HASH', git_hash) 46 46 version_conf.set('ANT_BUILD_DATE', build_date) 47 47
+383 -1
src/ant.c
··· 206 206 static jsval_t builtin_string_replace(struct js *js, jsval_t *args, int nargs); 207 207 static jsval_t builtin_string_template(struct js *js, jsval_t *args, int nargs); 208 208 static jsval_t builtin_string_charCodeAt(struct js *js, jsval_t *args, int nargs); 209 + static jsval_t builtin_string_toLowerCase(struct js *js, jsval_t *args, int nargs); 210 + static jsval_t builtin_string_toUpperCase(struct js *js, jsval_t *args, int nargs); 211 + static jsval_t builtin_string_trim(struct js *js, jsval_t *args, int nargs); 212 + static jsval_t builtin_string_repeat(struct js *js, jsval_t *args, int nargs); 213 + static jsval_t builtin_string_padStart(struct js *js, jsval_t *args, int nargs); 214 + static jsval_t builtin_string_padEnd(struct js *js, jsval_t *args, int nargs); 215 + static jsval_t builtin_string_charAt(struct js *js, jsval_t *args, int nargs); 216 + static jsval_t builtin_number_toString(struct js *js, jsval_t *args, int nargs); 217 + static jsval_t builtin_number_toFixed(struct js *js, jsval_t *args, int nargs); 218 + static jsval_t builtin_number_toPrecision(struct js *js, jsval_t *args, int nargs); 219 + static jsval_t builtin_number_toExponential(struct js *js, jsval_t *args, int nargs); 220 + static jsval_t builtin_parseInt(struct js *js, jsval_t *args, int nargs); 221 + static jsval_t builtin_parseFloat(struct js *js, jsval_t *args, int nargs); 209 222 static jsval_t builtin_Object(struct js *js, jsval_t *args, int nargs); 210 223 static jsval_t builtin_RegExp(struct js *js, jsval_t *args, int nargs); 211 224 static jsval_t builtin_Promise(struct js *js, jsval_t *args, int nargs); ··· 1271 1284 return js_mkfun(builtin_string_template); 1272 1285 } else if (streq(ptr, codereflen(r), "charCodeAt", 10)) { 1273 1286 return js_mkfun(builtin_string_charCodeAt); 1287 + } else if (streq(ptr, codereflen(r), "toLowerCase", 11)) { 1288 + return js_mkfun(builtin_string_toLowerCase); 1289 + } else if (streq(ptr, codereflen(r), "toUpperCase", 11)) { 1290 + return js_mkfun(builtin_string_toUpperCase); 1291 + } else if (streq(ptr, codereflen(r), "trim", 4)) { 1292 + return js_mkfun(builtin_string_trim); 1293 + } else if (streq(ptr, codereflen(r), "repeat", 6)) { 1294 + return js_mkfun(builtin_string_repeat); 1295 + } else if (streq(ptr, codereflen(r), "padStart", 8)) { 1296 + return js_mkfun(builtin_string_padStart); 1297 + } else if (streq(ptr, codereflen(r), "padEnd", 6)) { 1298 + return js_mkfun(builtin_string_padEnd); 1299 + } else if (streq(ptr, codereflen(r), "charAt", 6)) { 1300 + return js_mkfun(builtin_string_charAt); 1301 + } 1302 + } 1303 + 1304 + if (vtype(l) == T_NUM) { 1305 + if (streq(ptr, codereflen(r), "toString", 8)) { 1306 + return js_mkfun(builtin_number_toString); 1307 + } else if (streq(ptr, codereflen(r), "toFixed", 7)) { 1308 + return js_mkfun(builtin_number_toFixed); 1309 + } else if (streq(ptr, codereflen(r), "toPrecision", 11)) { 1310 + return js_mkfun(builtin_number_toPrecision); 1311 + } else if (streq(ptr, codereflen(r), "toExponential", 13)) { 1312 + return js_mkfun(builtin_number_toExponential); 1274 1313 } 1275 1314 } 1276 1315 ··· 1748 1787 case TOK_MUL: return tov(a * b); 1749 1788 case TOK_PLUS: return tov(a + b); 1750 1789 case TOK_MINUS: return tov(a - b); 1790 + case TOK_EXP: return tov(pow(a, b)); 1751 1791 case TOK_XOR: return tov((double)((long) a ^ (long) b)); 1752 1792 case TOK_AND: return tov((double)((long) a & (long) b)); 1753 1793 case TOK_OR: return tov((double)((long) a | (long) b)); ··· 2775 2815 } 2776 2816 } 2777 2817 2818 + static jsval_t js_exp(struct js *js) { 2819 + jsval_t base = js_unary(js); 2820 + if (is_err(base)) return base; 2821 + if (next(js) == TOK_EXP) { 2822 + js->consumed = 1; 2823 + jsval_t exponent = js_exp(js); 2824 + if (is_err(exponent)) return exponent; 2825 + return do_op(js, TOK_EXP, base, exponent); 2826 + } 2827 + return base; 2828 + } 2829 + 2778 2830 static jsval_t js_mul_div_rem(struct js *js) { 2779 - LTR_BINOP(js_unary, (next(js) == TOK_MUL || js->tok == TOK_DIV || js->tok == TOK_REM)); 2831 + LTR_BINOP(js_exp, (next(js) == TOK_MUL || js->tok == TOK_DIV || js->tok == TOK_REM)); 2780 2832 } 2781 2833 2782 2834 static jsval_t js_plus_minus(struct js *js) { ··· 5411 5463 return tov((double) ch); 5412 5464 } 5413 5465 5466 + static jsval_t builtin_string_toLowerCase(struct js *js, jsval_t *args, int nargs) { 5467 + (void) args; (void) nargs; 5468 + jsval_t str = js->this_val; 5469 + if (vtype(str) != T_STR) return js_mkerr(js, "toLowerCase called on non-string"); 5470 + 5471 + jsoff_t str_len, str_off = vstr(js, str, &str_len); 5472 + const char *str_ptr = (char *) &js->mem[str_off]; 5473 + jsval_t result = js_mkstr(js, NULL, str_len); 5474 + if (is_err(result)) return result; 5475 + 5476 + jsoff_t result_len, result_off = vstr(js, result, &result_len); 5477 + char *result_ptr = (char *) &js->mem[result_off]; 5478 + 5479 + for (jsoff_t i = 0; i < str_len; i++) { 5480 + char ch = str_ptr[i]; 5481 + result_ptr[i] = (ch >= 'A' && ch <= 'Z') ? ch + 32 : ch; 5482 + } 5483 + 5484 + return result; 5485 + } 5486 + 5487 + static jsval_t builtin_string_toUpperCase(struct js *js, jsval_t *args, int nargs) { 5488 + (void) args; (void) nargs; 5489 + jsval_t str = js->this_val; 5490 + if (vtype(str) != T_STR) return js_mkerr(js, "toUpperCase called on non-string"); 5491 + 5492 + jsoff_t str_len, str_off = vstr(js, str, &str_len); 5493 + const char *str_ptr = (char *) &js->mem[str_off]; 5494 + jsval_t result = js_mkstr(js, NULL, str_len); 5495 + if (is_err(result)) return result; 5496 + 5497 + jsoff_t result_len, result_off = vstr(js, result, &result_len); 5498 + char *result_ptr = (char *) &js->mem[result_off]; 5499 + 5500 + for (jsoff_t i = 0; i < str_len; i++) { 5501 + char ch = str_ptr[i]; 5502 + result_ptr[i] = (ch >= 'a' && ch <= 'z') ? ch - 32 : ch; 5503 + } 5504 + 5505 + return result; 5506 + } 5507 + 5508 + static jsval_t builtin_string_trim(struct js *js, jsval_t *args, int nargs) { 5509 + (void) args; (void) nargs; 5510 + jsval_t str = js->this_val; 5511 + if (vtype(str) != T_STR) return js_mkerr(js, "trim called on non-string"); 5512 + 5513 + jsoff_t str_len, str_off = vstr(js, str, &str_len); 5514 + const char *str_ptr = (char *) &js->mem[str_off]; 5515 + 5516 + jsoff_t start = 0, end = str_len; 5517 + while (start < end && is_space(str_ptr[start])) start++; 5518 + while (end > start && is_space(str_ptr[end - 1])) end--; 5519 + 5520 + return js_mkstr(js, str_ptr + start, end - start); 5521 + } 5522 + 5523 + static jsval_t builtin_string_repeat(struct js *js, jsval_t *args, int nargs) { 5524 + jsval_t str = js->this_val; 5525 + if (vtype(str) != T_STR) return js_mkerr(js, "repeat called on non-string"); 5526 + if (nargs < 1 || vtype(args[0]) != T_NUM) return js_mkerr(js, "repeat count required"); 5527 + 5528 + double count_d = tod(args[0]); 5529 + if (count_d < 0 || count_d != (double)(long)count_d) return js_mkerr(js, "invalid repeat count"); 5530 + jsoff_t count = (jsoff_t) count_d; 5531 + 5532 + jsoff_t str_len, str_off = vstr(js, str, &str_len); 5533 + const char *str_ptr = (char *) &js->mem[str_off]; 5534 + 5535 + if (count == 0 || str_len == 0) return js_mkstr(js, "", 0); 5536 + 5537 + jsval_t result = js_mkstr(js, NULL, str_len * count); 5538 + if (is_err(result)) return result; 5539 + 5540 + jsoff_t result_len, result_off = vstr(js, result, &result_len); 5541 + char *result_ptr = (char *) &js->mem[result_off]; 5542 + 5543 + for (jsoff_t i = 0; i < count; i++) { 5544 + memcpy(result_ptr + i * str_len, str_ptr, str_len); 5545 + } 5546 + 5547 + return result; 5548 + } 5549 + 5550 + static jsval_t builtin_string_padStart(struct js *js, jsval_t *args, int nargs) { 5551 + jsval_t str = js->this_val; 5552 + if (vtype(str) != T_STR) return js_mkerr(js, "padStart called on non-string"); 5553 + if (nargs < 1 || vtype(args[0]) != T_NUM) return str; 5554 + 5555 + jsoff_t target_len = (jsoff_t) tod(args[0]); 5556 + jsoff_t str_len, str_off = vstr(js, str, &str_len); 5557 + const char *str_ptr = (char *) &js->mem[str_off]; 5558 + 5559 + if (target_len <= str_len) return str; 5560 + 5561 + const char *pad_str = " "; 5562 + jsoff_t pad_len = 1; 5563 + if (nargs >= 2 && vtype(args[1]) == T_STR) { 5564 + pad_len = vstr(js, args[1], &pad_len); 5565 + pad_str = (char *) &js->mem[pad_len]; 5566 + pad_len = offtolen(loadoff(js, (jsoff_t) vdata(args[1]))); 5567 + } 5568 + 5569 + if (pad_len == 0) return str; 5570 + 5571 + jsoff_t fill_len = target_len - str_len; 5572 + jsval_t result = js_mkstr(js, NULL, target_len); 5573 + if (is_err(result)) return result; 5574 + 5575 + jsoff_t result_len, result_off = vstr(js, result, &result_len); 5576 + char *result_ptr = (char *) &js->mem[result_off]; 5577 + 5578 + jsoff_t pos = 0; 5579 + while (pos < fill_len) { 5580 + jsoff_t copy_len = (fill_len - pos < pad_len) ? fill_len - pos : pad_len; 5581 + memcpy(result_ptr + pos, pad_str, copy_len); 5582 + pos += copy_len; 5583 + } 5584 + memcpy(result_ptr + fill_len, str_ptr, str_len); 5585 + 5586 + return result; 5587 + } 5588 + 5589 + static jsval_t builtin_string_padEnd(struct js *js, jsval_t *args, int nargs) { 5590 + jsval_t str = js->this_val; 5591 + if (vtype(str) != T_STR) return js_mkerr(js, "padEnd called on non-string"); 5592 + if (nargs < 1 || vtype(args[0]) != T_NUM) return str; 5593 + 5594 + jsoff_t target_len = (jsoff_t) tod(args[0]); 5595 + jsoff_t str_len, str_off = vstr(js, str, &str_len); 5596 + const char *str_ptr = (char *) &js->mem[str_off]; 5597 + 5598 + if (target_len <= str_len) return str; 5599 + 5600 + const char *pad_str = " "; 5601 + jsoff_t pad_len = 1; 5602 + if (nargs >= 2 && vtype(args[1]) == T_STR) { 5603 + pad_len = vstr(js, args[1], &pad_len); 5604 + pad_str = (char *) &js->mem[pad_len]; 5605 + pad_len = offtolen(loadoff(js, (jsoff_t) vdata(args[1]))); 5606 + } 5607 + 5608 + if (pad_len == 0) return str; 5609 + 5610 + jsval_t result = js_mkstr(js, NULL, target_len); 5611 + if (is_err(result)) return result; 5612 + 5613 + jsoff_t result_len, result_off = vstr(js, result, &result_len); 5614 + char *result_ptr = (char *) &js->mem[result_off]; 5615 + 5616 + memcpy(result_ptr, str_ptr, str_len); 5617 + jsoff_t pos = str_len; 5618 + while (pos < target_len) { 5619 + jsoff_t copy_len = (target_len - pos < pad_len) ? target_len - pos : pad_len; 5620 + memcpy(result_ptr + pos, pad_str, copy_len); 5621 + pos += copy_len; 5622 + } 5623 + 5624 + return result; 5625 + } 5626 + 5627 + static jsval_t builtin_string_charAt(struct js *js, jsval_t *args, int nargs) { 5628 + jsval_t str = js->this_val; 5629 + if (vtype(str) != T_STR) return js_mkerr(js, "charAt called on non-string"); 5630 + if (nargs < 1 || vtype(args[0]) != T_NUM) return js_mkstr(js, "", 0); 5631 + 5632 + double idx_d = tod(args[0]); 5633 + if (idx_d < 0 || idx_d != (double)(long)idx_d) return js_mkstr(js, "", 0); 5634 + 5635 + jsoff_t idx = (jsoff_t) idx_d; 5636 + jsoff_t str_len = offtolen(loadoff(js, (jsoff_t) vdata(str))); 5637 + 5638 + if (idx >= str_len) return js_mkstr(js, "", 0); 5639 + 5640 + jsoff_t str_off = (jsoff_t) vdata(str) + sizeof(jsoff_t); 5641 + char ch = js->mem[str_off + idx]; 5642 + 5643 + return js_mkstr(js, &ch, 1); 5644 + } 5645 + 5646 + static jsval_t builtin_number_toString(struct js *js, jsval_t *args, int nargs) { 5647 + (void) args; (void) nargs; 5648 + jsval_t num = js->this_val; 5649 + if (vtype(num) != T_NUM) return js_mkerr(js, "toString called on non-number"); 5650 + 5651 + char buf[64]; 5652 + size_t len = strnum(num, buf, sizeof(buf)); 5653 + return js_mkstr(js, buf, len); 5654 + } 5655 + 5656 + static jsval_t builtin_number_toFixed(struct js *js, jsval_t *args, int nargs) { 5657 + jsval_t num = js->this_val; 5658 + if (vtype(num) != T_NUM) return js_mkerr(js, "toFixed called on non-number"); 5659 + 5660 + int digits = 0; 5661 + if (nargs >= 1 && vtype(args[0]) == T_NUM) { 5662 + digits = (int) tod(args[0]); 5663 + if (digits < 0) digits = 0; 5664 + if (digits > 20) digits = 20; 5665 + } 5666 + 5667 + char buf[64]; 5668 + snprintf(buf, sizeof(buf), "%.*f", digits, tod(num)); 5669 + return js_mkstr(js, buf, strlen(buf)); 5670 + } 5671 + 5672 + static jsval_t builtin_number_toPrecision(struct js *js, jsval_t *args, int nargs) { 5673 + jsval_t num = js->this_val; 5674 + if (vtype(num) != T_NUM) return js_mkerr(js, "toPrecision called on non-number"); 5675 + 5676 + if (nargs < 1 || vtype(args[0]) != T_NUM) { 5677 + char buf[64]; 5678 + size_t len = strnum(num, buf, sizeof(buf)); 5679 + return js_mkstr(js, buf, len); 5680 + } 5681 + 5682 + int precision = (int) tod(args[0]); 5683 + if (precision < 1) precision = 1; 5684 + if (precision > 21) precision = 21; 5685 + 5686 + char buf[64]; 5687 + snprintf(buf, sizeof(buf), "%.*g", precision, tod(num)); 5688 + return js_mkstr(js, buf, strlen(buf)); 5689 + } 5690 + 5691 + static jsval_t builtin_number_toExponential(struct js *js, jsval_t *args, int nargs) { 5692 + jsval_t num = js->this_val; 5693 + if (vtype(num) != T_NUM) return js_mkerr(js, "toExponential called on non-number"); 5694 + 5695 + int digits = 6; 5696 + if (nargs >= 1 && vtype(args[0]) == T_NUM) { 5697 + digits = (int) tod(args[0]); 5698 + if (digits < 0) digits = 0; 5699 + if (digits > 20) digits = 20; 5700 + } 5701 + 5702 + char buf[64]; 5703 + snprintf(buf, sizeof(buf), "%.*e", digits, tod(num)); 5704 + return js_mkstr(js, buf, strlen(buf)); 5705 + } 5706 + 5707 + static jsval_t builtin_parseInt(struct js *js, jsval_t *args, int nargs) { 5708 + if (nargs < 1) return tov(NAN); 5709 + 5710 + jsval_t str_val = args[0]; 5711 + if (vtype(str_val) != T_STR) { 5712 + const char *str = js_str(js, str_val); 5713 + str_val = js_mkstr(js, str, strlen(str)); 5714 + } 5715 + 5716 + jsoff_t str_len, str_off = vstr(js, str_val, &str_len); 5717 + const char *str = (char *) &js->mem[str_off]; 5718 + 5719 + int radix = 10; 5720 + if (nargs >= 2 && vtype(args[1]) == T_NUM) { 5721 + radix = (int) tod(args[1]); 5722 + if (radix < 2 || radix > 36) return tov(NAN); 5723 + } 5724 + 5725 + jsoff_t i = 0; 5726 + while (i < str_len && is_space(str[i])) i++; 5727 + 5728 + if (i >= str_len) return tov(NAN); 5729 + 5730 + int sign = 1; 5731 + if (str[i] == '-') { 5732 + sign = -1; 5733 + i++; 5734 + } else if (str[i] == '+') { 5735 + i++; 5736 + } 5737 + 5738 + if (radix == 16 && i + 1 < str_len && str[i] == '0' && (str[i + 1] == 'x' || str[i + 1] == 'X')) { 5739 + i += 2; 5740 + } 5741 + 5742 + double result = 0; 5743 + bool found_digit = false; 5744 + 5745 + while (i < str_len) { 5746 + char ch = str[i]; 5747 + int digit = -1; 5748 + 5749 + if (ch >= '0' && ch <= '9') { 5750 + digit = ch - '0'; 5751 + } else if (ch >= 'a' && ch <= 'z') { 5752 + digit = ch - 'a' + 10; 5753 + } else if (ch >= 'A' && ch <= 'Z') { 5754 + digit = ch - 'A' + 10; 5755 + } 5756 + 5757 + if (digit < 0 || digit >= radix) break; 5758 + 5759 + result = result * radix + digit; 5760 + found_digit = true; 5761 + i++; 5762 + } 5763 + 5764 + if (!found_digit) return tov(NAN); 5765 + 5766 + return tov(sign * result); 5767 + } 5768 + 5769 + static jsval_t builtin_parseFloat(struct js *js, jsval_t *args, int nargs) { 5770 + if (nargs < 1) return tov(NAN); 5771 + 5772 + jsval_t str_val = args[0]; 5773 + if (vtype(str_val) != T_STR) { 5774 + const char *str = js_str(js, str_val); 5775 + str_val = js_mkstr(js, str, strlen(str)); 5776 + } 5777 + 5778 + jsoff_t str_len, str_off = vstr(js, str_val, &str_len); 5779 + const char *str = (char *) &js->mem[str_off]; 5780 + 5781 + jsoff_t i = 0; 5782 + while (i < str_len && is_space(str[i])) i++; 5783 + 5784 + if (i >= str_len) return tov(NAN); 5785 + 5786 + char *end; 5787 + double result = strtod(&str[i], &end); 5788 + 5789 + if (end == &str[i]) return tov(NAN); 5790 + 5791 + return tov(result); 5792 + } 5793 + 5414 5794 static jsval_t builtin_resolve_internal(struct js *js, jsval_t *args, int nargs); 5415 5795 static jsval_t builtin_reject_internal(struct js *js, jsval_t *args, int nargs); 5416 5796 static void resolve_promise(struct js *js, jsval_t p, jsval_t val); ··· 5970 6350 setprop(js, glob, js_mkstr(js, "Array", 5), js_mkfun(builtin_Array)); 5971 6351 setprop(js, glob, js_mkstr(js, "Error", 5), js_mkfun(builtin_Error)); 5972 6352 setprop(js, glob, js_mkstr(js, "RegExp", 6), js_mkfun(builtin_RegExp)); 6353 + setprop(js, glob, js_mkstr(js, "parseInt", 8), js_mkfun(builtin_parseInt)); 6354 + setprop(js, glob, js_mkstr(js, "parseFloat", 10), js_mkfun(builtin_parseFloat)); 5973 6355 5974 6356 jsval_t date_ctor_obj = mkobj(js, 0); 5975 6357 setprop(js, date_ctor_obj, js_mkstr(js, "__native_func", 13), js_mkfun(builtin_Date));
+7
tests/test_exp_associativity.cjs
··· 1 + // Test right-associativity of exponentiation 2 + // 2 ** 3 ** 2 should be 2 ** (3 ** 2) = 2 ** 9 = 512 3 + // NOT (2 ** 3) ** 2 = 8 ** 2 = 64 4 + console.log('2 ** 3 ** 2 =', 2 ** 3 ** 2); 5 + console.log('Expected: 512 (right-associative)'); 6 + console.log('(2 ** 3) ** 2 =', (2 ** 3) ** 2); 7 + console.log('Expected: 64 (left-associative, for comparison)');
+14
tests/test_exponentiation.cjs
··· 1 + // Short test for exponentiation operator 2 + console.log('2 ** 3 =', 2 ** 3); 3 + console.log('5 ** 2 =', 5 ** 2); 4 + console.log('2 ** 10 =', 2 ** 10); 5 + console.log('(2 + 3) ** 2 =', (2 + 3) ** 2); 6 + 7 + // Test bit shifts 8 + console.log('8 << 2 =', 8 << 2); 9 + console.log('32 >> 2 =', 32 >> 2); 10 + 11 + // Test bitwise operations 12 + console.log('12 & 10 =', 12 & 10); 13 + console.log('12 | 10 =', 12 | 10); 14 + console.log('12 ^ 10 =', 12 ^ 10);
+32
tests/test_math_ops.cjs
··· 1 + // Test exponentiation operator 2 + console.log('Exponentiation tests:'); 3 + console.log('2 ** 3 =', 2 ** 3); // Should be 8 4 + console.log('5 ** 2 =', 5 ** 2); // Should be 25 5 + console.log('10 ** 0 =', 10 ** 0); // Should be 1 6 + console.log('2 ** 10 =', 2 ** 10); // Should be 1024 7 + console.log('3 ** 3 =', 3 ** 3); // Should be 27 8 + 9 + // Test bit shift operators 10 + console.log('\nBit shift tests:'); 11 + console.log('8 << 2 =', 8 << 2); // Should be 32 (8 * 4) 12 + console.log('32 >> 2 =', 32 >> 2); // Should be 8 (32 / 4) 13 + console.log('1 << 5 =', 1 << 5); // Should be 32 14 + console.log('64 >> 3 =', 64 >> 3); // Should be 8 15 + 16 + // Test bitwise operators 17 + console.log('\nBitwise tests:'); 18 + console.log('12 & 10 =', 12 & 10); // Should be 8 (binary: 1100 & 1010 = 1000) 19 + console.log('12 | 10 =', 12 | 10); // Should be 14 (binary: 1100 | 1010 = 1110) 20 + console.log('12 ^ 10 =', 12 ^ 10); // Should be 6 (binary: 1100 ^ 1010 = 0110) 21 + console.log('~5 =', ~5); // Should be -6 22 + 23 + // Test combined operations 24 + console.log('\nCombined operations:'); 25 + console.log('2 ** 3 + 4 =', 2 ** 3 + 4); // Should be 12 26 + console.log('(2 + 3) ** 2 =', (2 + 3) ** 2); // Should be 25 27 + console.log('2 << 3 >> 1 =', 2 << 3 >> 1); // Should be 8 28 + 29 + // Test with negative numbers 30 + console.log('\nNegative number tests:'); 31 + console.log('(-2) ** 3 =', (-2) ** 3); // Should be -8 32 + console.log('-8 >> 1 =', -8 >> 1); // Should be -4
+24
tests/test_string_number_methods.cjs
··· 1 + // Test String methods 2 + console.log('String methods:'); 3 + console.log('"hello".toUpperCase() =', "hello".toUpperCase()); 4 + console.log('"HELLO".toLowerCase() =', "HELLO".toLowerCase()); 5 + console.log('" hello ".trim() =', " hello ".trim()); 6 + console.log('"abc".repeat(3) =', "abc".repeat(3)); 7 + console.log('"5".padStart(3, "0") =', "5".padStart(3, "0")); 8 + console.log('"5".padEnd(3, "0") =', "5".padEnd(3, "0")); 9 + console.log('"hello".charAt(1) =', "hello".charAt(1)); 10 + 11 + // Test Number methods 12 + console.log('\nNumber methods:'); 13 + console.log('(42).toString() =', (42).toString()); 14 + console.log('(3.14159).toFixed(2) =', (3.14159).toFixed(2)); 15 + console.log('(123.456).toPrecision(4) =', (123.456).toPrecision(4)); 16 + console.log('(1234).toExponential(2) =', (1234).toExponential(2)); 17 + 18 + // Test parseInt and parseFloat 19 + console.log('\nparseInt and parseFloat:'); 20 + console.log('parseInt("42") =', parseInt("42")); 21 + console.log('parseInt("ff", 16) =', parseInt("ff", 16)); 22 + console.log('parseInt("1010", 2) =', parseInt("1010", 2)); 23 + console.log('parseFloat("3.14") =', parseFloat("3.14")); 24 + console.log('parseFloat("3.14e2") =', parseFloat("3.14e2"));