@@ -1222,7 +1222,8 @@ export class Tokenizer extends DiagnosticEmitter {
12221222 if ( c == CharCode . DOT || c == CharCode . E || c == CharCode . e ) {
12231223 return false ;
12241224 }
1225- if ( c < CharCode . _0 || c > CharCode . _9 ) break ;
1225+ if ( ( c < CharCode . _0 || c > CharCode . _9 ) && c != CharCode . _ ) break ;
1226+ // does not validate separator placement (this is done in readXYInteger)
12261227 pos ++ ;
12271228 }
12281229 return true ;
@@ -1267,8 +1268,10 @@ export class Tokenizer extends DiagnosticEmitter {
12671268 var start = this . pos ;
12681269 var value = i64_new ( 0 , 0 ) ;
12691270 var i64_16 = i64_new ( 16 , 0 ) ;
1271+ var sepEnd = start ;
12701272 while ( this . pos < this . end ) {
1271- let c = text . charCodeAt ( this . pos ) ;
1273+ let pos = this . pos ;
1274+ let c = text . charCodeAt ( pos ) ;
12721275 if ( c >= CharCode . _0 && c <= CharCode . _9 ) {
12731276 // value = value * 16 + c - CharCode._0;
12741277 value = i64_add (
@@ -1287,16 +1290,31 @@ export class Tokenizer extends DiagnosticEmitter {
12871290 i64_mul ( value , i64_16 ) ,
12881291 i64_new ( 10 + c - CharCode . a , 0 )
12891292 ) ;
1293+ } else if ( c == CharCode . _ ) {
1294+ if ( sepEnd == pos ) {
1295+ this . error (
1296+ sepEnd == start
1297+ ? DiagnosticCode . Numeric_separators_are_not_allowed_here
1298+ : DiagnosticCode . Multiple_consecutive_numeric_separators_are_not_permitted ,
1299+ this . range ( pos )
1300+ ) ;
1301+ }
1302+ sepEnd = pos + 1 ;
12901303 } else {
12911304 break ;
12921305 }
1293- ++ this . pos ;
1306+ this . pos = pos + 1 ;
12941307 }
12951308 if ( this . pos == start ) {
12961309 this . error (
12971310 DiagnosticCode . Hexadecimal_digit_expected ,
12981311 this . range ( start )
12991312 ) ;
1313+ } else if ( sepEnd == this . pos ) {
1314+ this . error (
1315+ DiagnosticCode . Numeric_separators_are_not_allowed_here ,
1316+ this . range ( sepEnd - 1 )
1317+ ) ;
13001318 }
13011319 return value ;
13021320 }
@@ -1306,24 +1324,41 @@ export class Tokenizer extends DiagnosticEmitter {
13061324 var start = this . pos ;
13071325 var value = i64_new ( 0 , 0 ) ;
13081326 var i64_10 = i64_new ( 10 , 0 ) ;
1327+ var sepEnd = start ;
13091328 while ( this . pos < this . end ) {
1310- let c = text . charCodeAt ( this . pos ) ;
1329+ let pos = this . pos ;
1330+ let c = text . charCodeAt ( pos ) ;
13111331 if ( c >= CharCode . _0 && c <= CharCode . _9 ) {
13121332 // value = value * 10 + c - CharCode._0;
13131333 value = i64_add (
13141334 i64_mul ( value , i64_10 ) ,
13151335 i64_new ( c - CharCode . _0 , 0 )
13161336 ) ;
1337+ } else if ( c == CharCode . _ ) {
1338+ if ( sepEnd == pos ) {
1339+ this . error (
1340+ sepEnd == start
1341+ ? DiagnosticCode . Numeric_separators_are_not_allowed_here
1342+ : DiagnosticCode . Multiple_consecutive_numeric_separators_are_not_permitted ,
1343+ this . range ( pos )
1344+ ) ;
1345+ }
1346+ sepEnd = pos + 1 ;
13171347 } else {
13181348 break ;
13191349 }
1320- ++ this . pos ;
1350+ this . pos = pos + 1 ;
13211351 }
13221352 if ( this . pos == start ) {
13231353 this . error (
13241354 DiagnosticCode . Digit_expected ,
13251355 this . range ( start )
13261356 ) ;
1357+ } else if ( sepEnd == this . pos ) {
1358+ this . error (
1359+ DiagnosticCode . Numeric_separators_are_not_allowed_here ,
1360+ this . range ( sepEnd - 1 )
1361+ ) ;
13271362 }
13281363 return value ;
13291364 }
@@ -1333,14 +1368,26 @@ export class Tokenizer extends DiagnosticEmitter {
13331368 var start = this . pos ;
13341369 var value = i64_new ( 0 , 0 ) ;
13351370 var i64_8 = i64_new ( 8 , 0 ) ;
1371+ var sepEnd = start ;
13361372 while ( this . pos < this . end ) {
1337- let c = text . charCodeAt ( this . pos ) ;
1373+ let pos = this . pos ;
1374+ let c = text . charCodeAt ( pos ) ;
13381375 if ( c >= CharCode . _0 && c <= CharCode . _7 ) {
13391376 // value = value * 8 + c - CharCode._0;
13401377 value = i64_add (
13411378 i64_mul ( value , i64_8 ) ,
13421379 i64_new ( c - CharCode . _0 , 0 )
13431380 ) ;
1381+ } else if ( c == CharCode . _ ) {
1382+ if ( sepEnd == pos ) {
1383+ this . error (
1384+ sepEnd == start
1385+ ? DiagnosticCode . Numeric_separators_are_not_allowed_here
1386+ : DiagnosticCode . Multiple_consecutive_numeric_separators_are_not_permitted ,
1387+ this . range ( pos )
1388+ ) ;
1389+ }
1390+ sepEnd = pos + 1 ;
13441391 } else {
13451392 break ;
13461393 }
@@ -1351,6 +1398,11 @@ export class Tokenizer extends DiagnosticEmitter {
13511398 DiagnosticCode . Octal_digit_expected ,
13521399 this . range ( start )
13531400 ) ;
1401+ } else if ( sepEnd == this . pos ) {
1402+ this . error (
1403+ DiagnosticCode . Numeric_separators_are_not_allowed_here ,
1404+ this . range ( sepEnd - 1 )
1405+ ) ;
13541406 }
13551407 return value ;
13561408 }
@@ -1361,8 +1413,10 @@ export class Tokenizer extends DiagnosticEmitter {
13611413 var value = i64_new ( 0 , 0 ) ;
13621414 var i64_2 = i64_new ( 2 , 0 ) ;
13631415 var i64_1 = i64_new ( 1 , 0 ) ;
1416+ var sepEnd = start ;
13641417 while ( this . pos < this . end ) {
1365- let c = text . charCodeAt ( this . pos ) ;
1418+ let pos = this . pos ;
1419+ let c = text . charCodeAt ( pos ) ;
13661420 if ( c == CharCode . _0 ) {
13671421 // value = value * 2;
13681422 value = i64_mul (
@@ -1375,16 +1429,31 @@ export class Tokenizer extends DiagnosticEmitter {
13751429 i64_mul ( value , i64_2 ) ,
13761430 i64_1
13771431 ) ;
1432+ } else if ( c == CharCode . _ ) {
1433+ if ( sepEnd == pos ) {
1434+ this . error (
1435+ sepEnd == start
1436+ ? DiagnosticCode . Numeric_separators_are_not_allowed_here
1437+ : DiagnosticCode . Multiple_consecutive_numeric_separators_are_not_permitted ,
1438+ this . range ( pos )
1439+ ) ;
1440+ }
1441+ sepEnd = pos + 1 ;
13781442 } else {
13791443 break ;
13801444 }
1381- ++ this . pos ;
1445+ this . pos = pos + 1 ;
13821446 }
13831447 if ( this . pos == start ) {
13841448 this . error (
13851449 DiagnosticCode . Binary_digit_expected ,
13861450 this . range ( start )
13871451 ) ;
1452+ } else if ( sepEnd == this . pos ) {
1453+ this . error (
1454+ DiagnosticCode . Numeric_separators_are_not_allowed_here ,
1455+ this . range ( sepEnd - 1 )
1456+ ) ;
13881457 }
13891458 return value ;
13901459 }
@@ -1404,6 +1473,7 @@ export class Tokenizer extends DiagnosticEmitter {
14041473 }
14051474
14061475 readDecimalFloat ( ) : f64 {
1476+ // TODO: numeric separators (parseFloat can't handle these)
14071477 var start = this . pos ;
14081478 var text = this . source . text ;
14091479 while ( this . pos < this . end && isDecimalDigit ( text . charCodeAt ( this . pos ) ) ) {
0 commit comments