sophiekoonin / JavaDecaf

A Compiler for JavaDecaf - MSc Computer Science project 2015
0 stars 1 forks source link

Java Compile Errors appear on different lines #15

Open sergutsan opened 9 years ago

sergutsan commented 9 years ago

The Java Decaf compiler preprocesses some Java Decaf code to produce Java code, then invokes the Java compiler to compile that code and produce bytecode.

If there are errors in the Java Code, they are shown "as is" on the screen. As the Java code has a lot of (well-formatted) Java boilerplate, the errors are shown to students as if they were on a different line. For example the following code:

println("Hello!");
print("What's your name? ");
String str = readLine();
if (str.length() >> 5) {
  println("That's a long name!");
} else {
  println("Nice to meet you.");
}

produces the following output:

Hello.java:11: error: ')' expected
    if (str.length() 5) {
                    ^
Hello.java:11: error: not a statement
    if (str.length() 5) {
                     ^
Hello.java:11: error: ';' expected
    if (str.length() 5) {
                      ^
Hello.java:13: error: 'else' without 'if'
    } else {
      ^
4 errors

All those errors are in lines 11 and 13, despite the fact that the original code contains only 8 lines. This is very confusing for students.

Maybe the errors of the Java compiler can be captured and their line numbers modified subtracting 6?

sergutsan commented 9 years ago

If capturing the errors from the Java compiler is difficult, a quick-n-dirty solution could be to write all the "top" boilerplate in one line.

This will still generate an error of one between the JavaDecaf line in error and the Java line in error, but at least this error is (a) small and (b) predictable. Students will accept it better.

Even the scanner (or reader) can be declared after the main method (it can even be made a local variable of method readLine(), see discussion on Issue #18 ), so the only top-boilerplate needed is something like:

import java.io.*; public class XXXX { public static void main(String[] args) {
sergutsan commented 9 years ago

The 1-line boilerplate is implemented in c92bfe7b2c9ec4070e29bd86e395ffe69a6d8b02.

I have looked a bit into capturing the errors and subtracting from the line number. It is not trivial.

The only possibility I see at the moment is to call the java compiler inside a Process, which provides an API to access its standard and error output, so this may enable some string-processing of the errors (if any). Here is an example for Windows.

Creating the Process with ProcessBuilder will require calling javac explicitly, I think. This may be a blessing or a curse, not sure. There may be problems with the amount of memory allocated to the process but I do not think this will be a real problem in our case.