Overwriting type inference rule for constant expression


As in MPS-15877 mentioned there is some difference between Java and baselanguage concerning the type of integer literal expressions. While in Java the type of this constant expressions depends on their values in baselanguage it is always int. The author of the issue suggests to change the subtyping rule of IntegerConstant. But this will not handle the expression types correctly in all cases. Try to compile this examples with javac
byte b1 = 126 + 1;
byte b2 = 127 + 1;
final byte NUM = 127;
byte b3 = NUM + 1;
you will recognize type errors in line 2 and 4. Java seems to fold constant expressions before resolve their types.
This behavior really should be added to baselanguage. I would like to have a similar thing in my language, too. But I don't know how to specify such a type of a constant expression. There must be an inference rule which overwrites other rules if the expression isCompileTimeConstant. The type can then be inferred by the result of the getCompileTimeConstantValue method.
Is it somehow possible to describe such a thing with MPS at the moment?
<table width="100%" cellspacing="0" border="0"><tbody><tr><td align="left"><table width="80%" cellspacing="5" cellpadding="0" border="0"><tbody><tr><td><table width="100%" cellspacing="0" cellpadding="0" border="0"><tbody> <tr><td> <a href="http://youtrack.jetbrains.net/issue/MPS-15877">MPS-15877</a> Assignment of constant value (IntegerConstant) to byte/short variable not allowed</td></tr> <tr><td>The following valid Java code is not allowed in baseLanguage (<em>Error: int is not a subtype of short</em>):<br><pre>short s2 = 0; // valid in Java but not in baseLanguage</pre> <br>It is correct that the following code produces an error (as it also does in Java):<br><pre> int i = 0; short s = i; // correct error </pre> <br>and also values that are to large for the datatype are not valid in Java:<br><pre> byte b0 = 127; // valid byte b1 = 128; // error byte b2 = -128; // valid byte b3 = -129; // error short s0 = 32767; // valid short s1 = 32768; // error short s2 = -32768; // valid short s3 = -32769; // error </pre> <br>The problem is that an <em>IntegerConstant</em> is always of type <em>int</em>, and can therefor not be assigned to a byte or short. To get the same behavior as in Java the type of an <em>IntegerConstant</em> has to depend on the value:<br><br><pre> rule typeOf_IntegerConstant {   applicable for concept = IntegerConstant as integerConstant   overrides true                              do {     if (-128 &lt;= integerConstant.value &amp;&amp; integerConstant.value &lt;= 127) {       typeof(integerConstant) :==: &lt;byte&gt;;     } else if (-32768 &lt;= integerConstant.value &amp;&amp; integerConstant.value &lt;= 32767) {       typeof(integerConstant) :==: &lt;short&gt;;     } else {       typeof(integerConstant) :==: &lt;int&gt;;           }   }            }             </pre> </td></tr> <tr><td>Normal | Bug | Fixed | fisakov</td></tr> </tbody></table></td></tr></tbody></table></td></tr></tbody></table>

Please sign in to leave a comment.