Most recent activity
-
- 9 comments
- 1,619 views
-
@Gordon—Oh! Mea culpa. I thought I had ruled out internal minification, but I had neglected to defer execution in my experiments, which rather invalidates them :-}. Sorry!
Here are the ones I can think of:
Misinterpreting valid and useful code:
- -
/--
+ +
/++
Wildly misinterpreting technically valid but extremely unlikely code:
/ /
///
⇐ Humorously, the bizarre sequence1 / /a/
does indeed throw an amazing fit, and can produce arbitrarily inappropriate error messages—add a multiline template literal later in the function for total hilarity!Incorrectly allowing syntactically invalid code in an especially confusing way:
/…/ i
//…/i
⇐ The IDE flags/a/ i
as a syntax error, but the runtime sees/a/i
.The obscure example
do x(); while(…);
is already handled correctly, and sequences with- --
and+ ++
display incorrectly in error messages but apparently execute correctly—are the increment and decrement operators internally pretokenised, or something?I can't think of any other examples because alphanumeric tokens already preserve whitespace and JS has few cases where an operator symbol is at the left edge of an expression. Maybe
**
andyield*
, should they ever be implemented, might surprise people carelessly converting C code?HTH.
-
Terminology: a lexer is responsible for tokenisation of the input—breaking it into words, if you will, like
if
,camelVar
,6.02e+23
,{
,'string'
,+
and+=
—while the parser is responsible for syntactic analysis, the grouping of those tokens into statements and expressions (with, admittedly, a few grey areas such as backquotes and regular expressions). It's not a logical necessity that languages be designed with this distinction, but as a practical matter almost all programming languages since the 60s seem to in one way or another. In the C family (to which JS belongs notationally, though not semantically), it's pretty crucial to understanding what's going on, and the formal concept (though not a typical implementation—and certainly not this implementation) is that tokenisation is a separate process that runs ‘before’ parsing. In any case, in JS,--
is one token and- -
is two, just asxx
is different fromx x
and==
is different from= =
, so in this case, the space is significant. The language processor, taken as a whole. is wrong to treat- -
as--
, and would be just as wrong to treat--
as- -
.
Espruino does not always make this mistake—var x
does not get confused withvarx
and the far more obscure exampledo x(); while (!done());
does not get misinterpreted as the (equally legal)dox(); while (!done());
, even during full file interactive upload to the emulator (the context that triggers the bug I was reporting). -
It is obviously not a parsing issue, sensu stricto, both because the distinction between
- -
and--
is lexical, and because, as you point out, the runtime evaluator suffers no such problem when its input is correct. The question that needs to be answered in diagnosing the problem, than, is what could cause the space between the two hyphen-minuses to be elided (or otherwise ignored)? If it is not the minification logic that apparently runs during full-file upload, I'll be surprised. What else is empowered to remove spaces? Why else would the error message actually quote maltransformed input? Why else would the problem vanish on paths where minification is not performed?
I think the key insight here is that the expression1--1
is erroneous (semantically, because1
is not an lvalue, and syntactically, because--
is not an infix operator), but it is not what was written in the source.
I'm sure other explanations are possible, but for now my money is definitely on the assumptions made by the minifier. -
Bangle emulator 2v10.187.
Minimal reproduction:
x = () => print(1 - -1);
Upload into the Bangle.js emulator from the editor panel as full file (not snippet), run
x()
:Uncaught Error: Unable to assign value to non-reference Number at line 1 col 8 print(1--1) ^
The underlying cause has to do with the accidental fusion of the two
-
tokens. This case:x => mod(x- -x, 1)
reports a parse error rather than a semantic error.
+
is similarly affected.As ever, it should be stressed that this is a minimal reproduction and the error also occurs with real, useful code. (Why would I ever explicitly subtract a negative number? Because the numbers I'm using come from tables of data plugged into a regular formula.)
-
-
@Gordon TBH it's as much me trying to speak all languages as close to “natively” as I can, and this was a textbook example of the motivation for the language feature—so I attempted to use it. I don't really do much religion when it comes to language design (none of the religions that I like—total correctness comes to mind—have proven feasible), and I completely understand that there are (a) things that won't fit and (b) more important fish than this to fry.
And sorry if I've come across grumpy—I seem to have come in through the wrong door. I'll go out and come back in again, see if I can do better :). -
- 9 comments
- 1,470 views
Here's a example:
My code is indeed incorrect for the reason given, but the source snippet (if reparsed) is about
x-- - 1
, which is probably what I thought I had typed(!).