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.

reject numeric literals immediately followed by identifier characters

+42 -8
+17
examples/spec/numbers.js
··· 2 2 3 3 console.log('Number Tests\n'); 4 4 5 + function testEvalSyntaxError(name, source) { 6 + let actual = 'none'; 7 + try { 8 + eval(source); 9 + } catch (e) { 10 + actual = e.name; 11 + } 12 + test(name, actual, 'SyntaxError'); 13 + } 14 + 5 15 test('integer literal', 42, 42); 6 16 test('float literal', 3.14, 3.14); 7 17 test('negative number', -5, -5); ··· 53 63 test('toPrecision', (123.456).toPrecision(4), '123.5'); 54 64 test('toExponential', (12345).toExponential(2), '1.23e+4'); 55 65 test('toString', (255).toString(16), 'ff'); 66 + test('integer literal method access with double dot', 27..toString(), '27'); 67 + test('integer literal method access with spaced dot', 27 .toString(), '27'); 68 + test('exponent literal method access', 1e3.toString(), '1000'); 69 + test('leading-dot literal method access', .5.toString(), '0.5'); 70 + testEvalSyntaxError('integer literal dot identifier syntax error', '27.toString()'); 71 + testEvalSyntaxError('integer literal dot property syntax error', '27.a'); 72 + testEvalSyntaxError('leading-dot literal identifier syntax error', '.5foo'); 56 73 57 74 testApprox('addition', 0.1 + 0.2, 0.3, 1e-10); 58 75 test('multiplication', 6 * 7, 42);
+25 -8
src/silver/lexer.c
··· 664 664 return i; 665 665 } 666 666 667 + static inline bool number_literal_has_invalid_tail(const char *buf, ant_offset_t remaining, ant_offset_t toklen) { 668 + return toklen < remaining && is_ident_continue((unsigned char)buf[toklen]); 669 + } 670 + 667 671 static inline uint8_t parse_number(sv_lexer_t *lx, const char *buf, ant_offset_t remaining) { 668 672 double value = 0; 669 673 ant_offset_t numlen = 0; ··· 691 695 } else numlen = parse_decimal(buf, remaining, &value); 692 696 693 697 lx->st.tval = tov(value); 694 - if (numlen < remaining && buf[numlen] == 'n') { 698 + ant_offset_t toklen = numlen; 699 + 700 + if (toklen < remaining && buf[toklen] == 'n') { 695 701 lx->st.tok = TOK_BIGINT; 696 - lx->st.tlen = numlen + 1; 697 - } else { 698 - lx->st.tok = TOK_NUMBER; 699 - lx->st.tlen = numlen; 702 + toklen++; 703 + } else lx->st.tok = TOK_NUMBER; 704 + 705 + if (number_literal_has_invalid_tail(buf, remaining, toklen)) { 706 + lx->st.tok = TOK_ERR; 707 + lx->st.tlen = toklen; 708 + return TOK_ERR; 700 709 } 710 + 711 + lx->st.tlen = toklen; 701 712 702 713 return lx->st.tok; 703 714 } ··· 1032 1043 if (MATCH3('.','.', '.')) { lx->st.tok = TOK_REST; lx->st.tlen = 3; } 1033 1044 else if (rem > 1 && IS_DIGIT(buf[1])) { 1034 1045 double val; 1035 - lx->st.tlen = parse_decimal(buf, rem, &val); 1036 - lx->st.tval = tov(val); 1037 - lx->st.tok = TOK_NUMBER; 1046 + ant_offset_t numlen = parse_decimal(buf, rem, &val); 1047 + if (number_literal_has_invalid_tail(buf, rem, numlen)) { 1048 + lx->st.tok = TOK_ERR; 1049 + lx->st.tlen = numlen; 1050 + } else { 1051 + lx->st.tlen = numlen; 1052 + lx->st.tval = tov(val); 1053 + lx->st.tok = TOK_NUMBER; 1054 + } 1038 1055 } 1039 1056 else { lx->st.tok = TOK_DOT; lx->st.tlen = 1; } 1040 1057 break;