Open jlongster opened 12 years ago
I hear ya, but it seems to be the only way to parse without having to require type declarations. This is a problem with C style casting syntax. We actually have to parse assuming they are function calls and then disambiguate the casts after the parser is done.
I don't know much about esprima, but how else can (int)num
be parsed? Is that parsed in a way that can't be used?
I guess it seems like you could parse (
, the type, and )
, and then parse the next expression and wrap it in a cast. I'm sure I'm over-simplifying this. It seems like this could work since the compiler knows what types are at compile time (or are they not known at parse time?)
Parsing C-style casts are really a pain in the ass. There are a couple of problems with C-style casts:
(e1)(e2)
could be a call or a cast, depending on whether e1 is a type or not. C solves this by requiring all types be forward-declared.Different associativity. Casts associate right to left:
(e1)(e2)(e3)
is really ((e1)((e2)(e3)))
Calls associate left to right:
(e1)(e2)(e3)
is really (((e1)(e2))(e3))
So to disambiguate calls and casts without knowing which identifiers are types ahead of time would actually require reparsing. Note that I actually mean reparsing the entire file, not backtracking, because it's only after we parse the entire file that we know what the types are.
So there are a couple of solutions here:
Number(e)
.(e1)e2
, but this would not associate in the C way. That is, (e1)(e2)e3
would be a parsing error since the parser doesn't know what to do with ((e1)(e2))e3
.as
operator, like e1 as ty
.I personally like (c), but that would be a radical syntactic departure from C.
edit: formatting
I actually didn't realize that e1(e2)
was valid for casting in lljs. Although it's not the same as C, I think it's good enough. The main annoyance was having to type 4 parentheses just to cast. So int(foo)
isn't too bad, and like you said it is kind of how javascript conversions are already done.
I also didn't realize that lljs didn't require forward declarations, which is kind of neat. It makes sense that C-style casting is difficult without knowing all the types.
It's annoying to have to write:
etc, every time I want to cast something. I should be able to just do:
but it seems to require the explicit parentheses.