-
Notifications
You must be signed in to change notification settings - Fork 358
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
.raw property of literal nodes, or something similar #14
Comments
Acorn also produces |
@RReverser That requires the node location to be specified. A code generator that takes an AST may not need the location at all, but it can benefit from |
@ariya Makes sense, thanks for a good example. |
Remember,
has an optional Also notable, @RReverser: |
@michaelficarra Yes, I already agreed that possible benefits of |
This delves into the realm of a CST, which has lots of interested parties... Perhaps we can defer this discussion until we have a comprehensive discussion of what a concrete syntax tree would look like? |
|
I'm not sure if this comment belongs to this issue, or should be a new one, but here goes. The type of the 'value' property (and 'raw' if added) of Literal cannot be determined. Type switching is bad for performance in JITs, so I've been experimenting with multiple Literals which have type assistance. So rather than You have They are all forms of Literal, but have some minor perf assistance |
@abraidwood Yep, |
@sebmck I'm not sure that backwards compatibility is such a problem - the node created is the same except for the actually class that created it, so any instanceof like operations would fail, but anything checking Node.type would be fine. I'm doing this with my experimental acorn derived parser here https://github.com/abraidwood/overture and specifically in this file https://github.com/abraidwood/overture/blob/master/overture-pre.js |
Oh right, you're suggesting different constructors for the nodes not different node types. Not relevant to ESTree since it only defines the AST representation and no other parser behaviour. |
Ok, if the 'Literal' on the node is just referring to the type within it, then you're right, it doesn't matter for ESTree. |
I would also like to mention that V8 can still pick out all of those Now, adding a If I could redesign the node, without worries about anything like dependent interface Literal <: Node {
kind: "string" |
"boolean" |
"null" |
"undefined" |
"number" |
"regexp";
raw: string;
}
// Examples
kind: "string"
raw: "\"foo\"
kind: "number"
raw: "4.2"
kind: "null"
raw: "null"
kind: "undefined"
raw: "undefined"
kind: "regexp"
raw: "/foo/"
kind: "regexp"
raw: "/foo/i"
kind: "boolean"
raw: "true"
// Usage
let isType = (node, type) =>
node.type === "Literal" &&
node.kind === type;
function assertType(node, type) {
if (!isType(node, type)) {
throw new TypeError();
}
}
function isHex(node) {
assertType(node, "number");
return /0x/i.test(node.raw);
}
function getValue(node) {
if (node.type !== "Literal") {
throw new TypeError();
}
switch (node.kind) {
case "string":
let {raw} = node;
// lint for JSON inconsistencies
if (!/(["'])[^\u2028\u2029]\1/.test(raw)) {
throw new SyntaxError();
}
return JSON.parse(raw);
case "number": return Number(node.raw);
case "null": return null;
case "undefined": return undefined;
case "boolean": return Boolean(node.raw);
case "regexp":
let parts = node.raw.split("/").slice(1);
let flags = parts.pop();
let source = parts.join("/");
return RegExp(source, flags);
default: throw new TypeError();
} I am well aware that such a breaking change wouldn't work in practice, but |
@IMPinball |
Done: #61
|
Would introduction of |
@gibson042 Doubt it. Granted, from a raw property, it would be relatively easy to get each part from it: let [, source, flags] = /^\/(.*)/([a-z]*)$/.exec(regexNode.raw); I like my regex/destructuring-based one-liners. ;) |
I guess you missed at least one more escape character for |
Oops. It should've been this: let [, source, flags] = /^\/(.*)\/([a-z]*)$/.exec(regexNode.raw); |
I don't think I'm qualified to comment on whether .raw should be part of the ESTree spec, but I will note that it has in practice proven to be very useful when consuming ESTree parse trees converted to JSON, because not all non-JS JSON libraries are able to reliably deal with the .value field having variable type (e.g., when unmarshaling into a statically-typed Go struct). |
Discussed some in #6. The
raw
property of literal nodes is an Esprima extension.I have a specific use case for the
raw
property, or at least for more information than is provided byvalue
: in asm.js, the distinction between an int literal and float literal is significant and distinguished by the type system. Writing an asm.js validator in JS requires the ability to distinguish between e.g.17.0
and17
, but thevalue
property does not distinguish these.OTOH, @michaelficarra points out that AST nodes might be produced by tools that don't want to have to specify the raw source. A few options I can see:
raw
unspecified and treat asm.js as a special case that is adequately served by Esprima's extended behaviorraw
in thattype: "int" | "float" | "string" | "boolean" | "null" | "RegExp"
type: "hex" | "octal" | "decimal" | "float" | "boolean" | "null" | "RegExp"
I am hesitant to generalize based on the one use case of asm.js. Without knowing of other use cases, I think the most conservative step is just to document the existing practice of
raw
in an optional spec.Thoughts?
The text was updated successfully, but these errors were encountered: