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

Evaluate constant expressions at compile-time #352

Closed
perlun opened this issue Dec 1, 2022 · 0 comments
Closed

Evaluate constant expressions at compile-time #352

perlun opened this issue Dec 1, 2022 · 0 comments
Labels
enhancement New feature or request
Milestone

Comments

@perlun
Copy link
Collaborator

perlun commented Dec 1, 2022

Moved to GitLab

Please continue to the new version of this issue here: https://gitlab.perlang.org/perlang/perlang/-/issues/352. The GitHub page you are currently reading will not contain the latest information on this issue.


Originally posted by @perlun in #70 (comment):

We should give this some focus; it's quite absurd that the current expression var l = 2147483648; print(l.get_type()); will create an implicitly typed uint variable which is impossible to specify with an explicit type. I.e. you must use type inference for this; the uint type simply does not exist in the language yet.

This should now be in a much better shape. All "implicit" types below which can get created when parsing integer literals are now also able to be specified explicitly. We no longer have to be ashamed of ourselves. 🙂

if (value <= Int32.MaxValue)
{
return new IntegerLiteral<int>((int)value);
}
else if (value <= UInt32.MaxValue)
{
return new IntegerLiteral<uint>((uint)value);
}
else if (value <= Int64.MaxValue)
{
return new IntegerLiteral<long>((long)value);
}
else if (value <= UInt64.MaxValue)
{
return new IntegerLiteral<ulong>((ulong)value);
}
else // Anything else remains a BigInteger
{
return new IntegerLiteral<BigInteger>(value);
}

An incredibly interesting question is what should happen when we start implementing the smaller integer types, like short, ushort and byte. Should we start coercing integer literals to the smallest possible type even in that case? It may sound like the obvious right thing to do if you don't think about it so much, but it has some utterly weird consequences. For example, if we would coerce things to byte just because we are dealing with small integers, the following assignment:

var v = 150 + 150;

...would not lead to the v variable being assigned to 300, but it would be the left-most 8 bits of the 300 (since all the other bits would be silently discarded). In other words, 44. This would be extremely confusing to about 99.9% of what any user would reasonably expect from the language.

One way to deal with it: special-case integer literals and say that "never implicitly type the result of an expression to something smaller than an int". But that will cause its own problems. Imagine the following example program:

var b: byte = 255;
var s: short = 32767;
var u: ushort = 65535;

If we go with the idea described above, all of these assignments will fail because the integer literals will be too large. This is a consequence of us not doing compile-time evaluation of constant expressions. We should, really, since it will be more or less required to be able to provide a great user experience when dealing (small) integer literals.

@perlun perlun added this to the "Later" milestone Dec 1, 2022
@perlun perlun added the enhancement New feature or request label Dec 1, 2022
@perlun perlun closed this as completed Aug 20, 2024
@perlang-org perlang-org locked as resolved and limited conversation to collaborators Aug 20, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant