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

[Discussion] [Bugfix] casts, automatic toString(), null, etc. #56

Draft
wants to merge 13 commits into
base: master
Choose a base branch
from

Conversation

Informa-Tiger
Copy link
Contributor

@Informa-Tiger Informa-Tiger commented Jul 2, 2022

I noticed several bugs regarding casts, automatic toString() and null, i.e. behaviours that differ from the behaviour in Java.
I'm not sure, whether some of the differences are on purpose (it's not a bug, it's a feature).
If so, I suggest to add these differences to the page LernJ vs. Java: Unterschiede in the documentation instead.
As the problems are unfortunately very closely interwoven, there were quite a lot of changes in the interpreter and the compiler nescessary.
They are primarily meant as suggestions to be discussed. This is why I created this pull request only as draft.
While some changes (like b5c3a53) can probably be adopted directly, you may have better suggestions for other problems.

In the following I listed the bugs and how I fixed them in a table:

Bugs

BugExampleOutputExpectedAnalysisFix
1d and 1f are ints
println(3 / 2d);
11.5 There is an syntax error (== instead of =) in line 917 of the lexer. b5c3a53
String representation of doubles and floats
println(3.);
3.03 In normal java, when printing doubles or floats, that are ∈ ℤ, they end on .0. Since javascript only knows one number type, this has to be done manually. This was by accident split up in multiple commits and mixed with other changes
Casting from Integer to long
println((long)(Integer) 1); 
compiler error: Der Datentyp Integer kann (zumindest durch casting) nicht in den Datentyp long umgewandelt werden.1 longPrimitiveType is missing in unboxableAs of IntegerClass
  • dc08466: added longPrimitiveType
  • ed88f6e: added "Long" to the canCastToMap of IntPrimitiveType (Although in Java it is not possible to cast an int to a Long, I think this makes sense, as there is no real difference, since everything is stored as javascript-number internally, and in the Online IDE it is also possible to cast a float to a Double)
String representation of null
println(null);
leere Zeilenull The PrintManager prints an empty line, when text == null. 5c2f340: Before the Interpreter calls the PrintManager, it checks, whether println is called without parameters, than still null is passed, or if it is called with null as parameter, than "null" is passed.
println((Rectangle)null);
run time error: Fehler: Aufruf der Methode toString des null-Objekts The automatic conversion to a String in the current version is done in getToStringStatement(), which inserts a call of the toString()-method of the respective class. 5c2f340: The new method ensureAutomaticToString() is a bit more complex, but considers this and other cases. Instead of inserting an call of the toString() of the respective class, a call of an artifical method is inserted, which is static and first catches the case, that the parameter is null (then "null" is returned), before invoking the actual toString() method of the respective class.
Concatenation of strings
println((String)null + (String)null);
0nullnull The problem is, that in javascript null + null = 0 (don't ask me why). It has to be fixed in the compute() method of StringPrimitiveType 5c2f340: If the first operand is null, now "null" is used instead of it. Additionally a string now only allows concatenation with other strings (5c2f340, 97c862b). If one of the operands is no string, it is automatically converted to a string in ensureAutomaticToString().
Comparison with null
println(null == (Circle) null);
compiler error: Die Operation == ist für die Operanden der Typen null und Circle nicht definiert. true The NullType allows no operations at all, since getResultType() always returns null. c6fb642: The NullType now allows the operations TokenType.equal and TokenType.notEqual, if the secondOperandType allows this operation with the NullType (so if the operation works the other way around). For both operations compute() was implemented.
Casting an null Object to a primitive type
double a = (Double) null;
no erroran error In the current version of ensureAutomaticCasting(), if the type can be unboxed, it simply returns true without inserting statements. Thus, at run time it won't be checked, whether the unboxed value is null.
Automatic casting / conversion to string
String s = new Rectangle(0,0,0,0); println(s);
(Rectangle)an error In the current version you can cast everything to a String (due to lines 625-627 in Klass.canCastTo()) and everything can be automatically casted to a string (due to line 847-852 in ensureAutomaticCasting in the CodeGenerator.ts). I'm not sure whether this is an feature or a bug. However it don't think it makes sense, since
  1. it is not possible in Java
  2. it breaks with the logic of casting
  3. you can use toString() or +"" instead
  • 5c2f340: removed the lines, that allowed to cast any object to a String (in Klass as well as in the primitive types)
  • 5c2f340: new method ensureAutomaticToString(), that takes care of the auto-conversion when calling print or concatenating with a String
  • 5d4b55a: removed the lines in CodeGenerator.ts, that allowed auto-casting to a String
  • b785877: Because without auto-casting to String something like setFillColor(Color.red) wouldn't work anymore, I added corresponding methods that accept a Color-object as parameter.

You can try out the fixed version in my embedded IDE: 🡭 Start in IDE

Please comment on which of these changes make sense and for which a better solution should be found.

@martin-pabst
Copy link
Owner

Thank you for all this work! I need time to contemplate your commits, so i must ask for patience.

Two months ago i began rewriting the code generator, type resolver and interpreter from scratch (branch newCompiler), so please don't invest too much effort into syntactical details.

Es würde mich freuen, wenn ich das weitere Vorgehen mal telefonisch mit Ihnen besprechen könnte. Ich will mich aber nicht aufdrängen - nur, wenn Ihnen das Recht ist. Bitte schreiben Sie mir ggf. einfach per Mail, wann Sie Zeit hätten: asv.pabst at gmail dot com.

Viele Grüße

Martin Pabst

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants