Conversation
|
@littledan would love for you to take a look, let me know what other test cases I should add |
|
Awesome @wdhorton!! As for test cases can you add hex, octal, binary and then error for exponential form (you already have the error for decimals)? |
| @@ -0,0 +1 @@ | |||
| 1.0n | |||
There was a problem hiding this comment.
can rename the invalid-0 to just invalid-decimal?
README.md
Outdated
There was a problem hiding this comment.
What do we think about making the plugin name bigInt with camelCase?
There was a problem hiding this comment.
I actually started with the plugin named bigInt. But then when it came time to make a new token type, I saw that the RegExp constructor mapped to regex so I figured that BigInt should map to bigint. So then I changed the plugin to match the token type.
But I'm ok with bigInt if you think that's better
There was a problem hiding this comment.
Yeah I just meant for the plugin string not the tt.bigint in the code if that makes sense (I wasn't clear earlier 😄)
There was a problem hiding this comment.
bigInt seems right for the plugin if the convention is camelCase, while bigint is a pretty reasonable name for a tag IMO, as typeof 1n is "bigint".
| if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.state.pos, "Identifier directly after number"); | ||
|
|
||
| const str = this.input.slice(start, this.state.pos).replace(/_/g, ""); | ||
| const str = this.input.slice(start, this.state.pos).replace(/[_n]/g, ""); |
There was a problem hiding this comment.
Is it worth putting a comment here to explain we are removing the _ for numeric separators and n for BigInt?
There was a problem hiding this comment.
sound like a good idea
littledan
left a comment
There was a problem hiding this comment.
For missing test cases: It'd also be good to have a BigInt that isn't exactly representable as a Number, and check that the output is as expected (and the test expectation shouldn't contain any rounded version).
There was a problem hiding this comment.
Maybe the "value" (and possibly "rawValue", but I don't know much about what that field is for) fields should contain a string with the value of the BigInt as a decimal number (taking care of other bases). Using a Number as the value seems suboptimal as it'll be rounded; no one should use such a value.
There was a problem hiding this comment.
rawValue is basically the same as value and raw is just the actual string of the code
this.addExtra(node, "rawValue", value);
this.addExtra(node, "raw", this.input.slice(startPos, this.state.end));
There was a problem hiding this comment.
@littledan I realized after I pushed this up that using a number as the value would defeat the purpose, since as you said we still couldn't represent 64-bit ints without rounding. I'll change it to strings
README.md
Outdated
There was a problem hiding this comment.
bigInt seems right for the plugin if the convention is camelCase, while bigint is a pretty reasonable name for a tag IMO, as typeof 1n is "bigint".
| @@ -678,7 +687,7 @@ export default class Tokenizer extends LocationParser { | |||
| } else { | |||
| val = parseInt(str, 8); | |||
There was a problem hiding this comment.
None of these parseInt calls are appropriate if isBigInt, as they will round away part of the answer.
There was a problem hiding this comment.
you're very right, that was an oversight on my part
src/tokenizer/index.js
Outdated
There was a problem hiding this comment.
How about using 0x6E instead of 110? It makes it more obvious that this refers to U+006E LATIN SMALL LETTER N.
There was a problem hiding this comment.
The existing code was already checking the charCodes using non-hex integers, so I was just trying to stay consistent with that. I can go ahead and change it if you think that's best
src/tokenizer/index.js
Outdated
There was a problem hiding this comment.
Same could be done here (0x30 instead of 48)
src/tokenizer/index.js
Outdated
There was a problem hiding this comment.
if (next === 0x2B || next === 0x2D)
src/tokenizer/index.js
Outdated
| "rawValue": "0b101011101", | ||
| "raw": "0b101011101n" | ||
| }, | ||
| "value": "0b101011101" |
There was a problem hiding this comment.
Should Babylon handle converting this binary value into a decimal value, or should the transform be responsible for that/
There was a problem hiding this comment.
I was thinking about that, and on a practical level I think it makes sense to delay that until the transform. If there was a binary value that exceeded the max value for a number, then in order to convert it we'd have to import a bigint library here. Whereas with the transform we're already going to need to use a library for the operations, so it makes sense to have it do the conversions as well
There was a problem hiding this comment.
Would this be the same question as for Numeric Separators? We have a babel-plugin-transform-es2015-literals that does binary conversion but only for regular numbers.
https://github.com/babel/babel/pull/5793/files#diff-16974ce04e951262c4c093ce8d8a149cR94
I guess in this case since it's a BigInt, we'd make the new transform handle it. I'd say the transform.
There was a problem hiding this comment.
Oh that makes sense; I didn't realize this was typically handled in a separate transform.
Does it make sense to have the 'value' field at all, though? Why bother, when you have the rawValue?
There was a problem hiding this comment.
Not sure, I guess most of the time value works for all Literals depending on what you want via Boolean, Null, String, etc. I guess for this it's the same thing and can't actually be represented as a number
I think it's fine to include it in the BigInt transform itself if es2015-literals are only going to handle binary, octal, etc for regular numbers.
|
just added @mathiasbynens suggestions |
|
@hzoo @littledan is there anything keeping this from getting merged now? |
|
Yeah we can iterate when we get to the transform part if it doesn't fit, tests wise it's fine to me! |
|
Thanks @wdhorton for the PR, let us know if you want help with the transform as well |
|
@hzoo i have one starting question on the transform—is it ok to pull in an external lib to handle the math operations? idk what babel's policy is on adding 3rd-party dependencies, but it seems unavoidable in this case |
|
@wdhorton shouldn't be an issue (guess it depends on the dep?)... we pull in |
|
Yeah it needs a runtime library like described in #569. It's basically the syntax wrapper -> those calls to the library. It's similar to transform-runtime/regenerator in that way |
For the tokenizer, check if the last character is
n, in which case it should be treated as a BigInt. If it has a dot or an E, throw, otherwise, advance the position one character. Replace the literalnwith "" when parsing the value, and create a new token typebigint.For the parser, when handling a
biginttoken, create a node of the new typeBigIntLiteralwith the given value.