Skip to content
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

Add helpful error message for invalid number literal like '.42' #4665

Conversation

makenowjust
Copy link
Contributor

Dot-started floating-point number like '.42' is not supported on Crystal. However compiler does not tell us this, so this fix adds to detect such a literal and to show helpful error message.

For example, old compiler shows an error message:

$ crystal run foo.cr
Syntax error in foo.cr:1: unexpected token: .

foo = .42
      ^

And this PR compiler shows:

$ ./bin/crystal run foo.cr
Using compiled compiler at `.build/crystal'
Syntax error in foo.cr:1: .1 style number literal is not supported, put 0 before dot

foo = .42
      ^

If you have more helpful error message text, please tell me. You know, my English is not good.

@straight-shoota
Copy link
Member

straight-shoota commented Jul 3, 2017

I'd suggest a wording like float literals cannot omit a leading zero

@ysbaddaden
Copy link
Contributor

Or just follow the octal literal message (octal constants should be prefixed with 0o):

float constants should be prefixed with 0

@akzhan
Copy link
Contributor

akzhan commented Jul 3, 2017

float literals should be started with decimal digit

@straight-shoota
Copy link
Member

straight-shoota commented Jul 3, 2017

@ysbaddaden I think the wording should differentiate between constant and literal. So we should probably change the octal message to literal as well. Plus, prefixing float literals with 0 in general would actually be wrong (like 03.141).

What about:

float literals always require an integer part, omitting `0` is not supported

@asterite
Copy link
Member

asterite commented Jul 3, 2017

What happens if you write foo.42?

@david50407
Copy link
Contributor

Why Crystal not supporting .123 type floats? Any reason?

@makenowjust
Copy link
Contributor Author

@david50407 .123 number conflicts ... operator: 1...2 means (1)...(2) or (1)..(.2)?

@makenowjust
Copy link
Contributor Author

@asterite .42 is detected by the lexer, so an error against foo.42 is also .1 style number literal is not supported.... Direct foo.42 is rare case, but when we have a macro foo.{{name}} and name is given as number by carelessness, then we get same error. I think it is not helpful. Should I let the parser detect .42 inside parse_atomic_without_location?

@asterite
Copy link
Member

asterite commented Jul 4, 2017

@makenowjust It's hard.

I don't know if we should give an error. I wouldn't expect this:

MOV EAX, 1

to give an error:

MOV EAX, 1
^
this is not assembler, it's Crystal

(this is not C, it's Crystal)

I mean, we can't give an error for every idiom or piece of syntax that appears in other languages. If you get an error in .42 saying "unexpected '.'" then it's probably clear then this style of numbers if not supported.

@makenowjust
Copy link
Contributor Author

@asterite Nevertheless I believe such an error message is helpful and useful. For example ruby shows warning message for .42:

$ ruby -e .42
-e:1: no .<digit> floating literal anymore; put 0 before dot
-e:1: syntax error, unexpected '.'

@straight-shoota
Copy link
Member

There is a difference between those cases: writing .42 instead of 0.42 is typically a mistake by a newcomer to Crystal coming from a language where you can omit leading zeros. For them a more detailed error message would be helpful and encouraging.

@david50407
Copy link
Contributor

@makenowjust oops I missed that possible

How about just give a nicer tip like:

Syntax error in foo.cr:1: unexpected token: .
Tip: If you are trying to declaring a float constant, put 0 before dot.

@makenowjust
Copy link
Contributor Author

@david50407 unexpected_token method takes msg optional argument to show additional information. For example:

$ echo 'def foo bar; end' > foo.cr
$ crystal run foo.cr
Syntax error in foo.cr:1: unexpected token: bar (parentheses are mandatory for def arguments)

def foo bar; end
        ^

I'll try to implement by using it.

@sdogruyol
Copy link
Member

Even though it's a small thing, I believe this kind of small things makes a language more friendly to newcomers 👍

@straight-shoota
Copy link
Member

I'd like to see this merged. It's not a strict necessity, but as @sdogruyol puts it, a small think to make the language more friendly to its users (in this case newcomers specifically).

My preferred error message: float literals require an integer part, a `0` integer part can't be ommited

@beta-ziliani
Copy link
Member

@makenowjust can you rebase this? Let us know otherwise. Thanks!

… '.42'

Dot-started floating-point number like '.42' is not supported on
Crystal. However compiler does not tell us this, so this fix adds to
detect such a literal and to show helpful error message.
@makenowjust makenowjust force-pushed the fix/crystal/lex-special-error-dot-with-number branch from 7033c37 to a6283d4 Compare August 3, 2021 14:10
@makenowjust
Copy link
Contributor Author

rebase is done.

@beta-ziliani beta-ziliani added this to the 1.2.0 milestone Aug 3, 2021
@straight-shoota straight-shoota changed the title Show helpful error message against invalid number literal like '.42' Add helpful error message for invalid number literal like '.42' Aug 4, 2021
@straight-shoota straight-shoota merged commit fe57059 into crystal-lang:master Aug 4, 2021
@makenowjust makenowjust deleted the fix/crystal/lex-special-error-dot-with-number branch August 4, 2021 17:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants