Compiler testing method

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Compiler testing method

Devo
The text suggests testing your compiler by compiling the test programs and then trying to run them in the VM emulator. If they don't behave as expected, you would then try to figure out why and correct the problem.

I've found it much, much more helpful to compile the test programs using both my compiler and the supplied compiler, and then use the TextComparer to compare the outputs. If the comparision succeeds, I know my compiler is generating the correct output in .vm language. If it doesn't succeed, I can see right where the problem is.

Is there a reason I shouldn't be doing it this way, or why the text doesn't recommend this method?
Reply | Threaded
Open this post in threaded view
|

Re: Compiler testing method

ybakos
Well, the book leaves much of the workflow up to the reader. Your approach is certainly valid. Another approach is to script the entire process, for example. And there are many other things, such as using version control, that the book doesn't mention either. I personally feel the book leaves some problems open ended allowing the reader to find his own solutions to problems. This allows the reader to experience, say, the pain of manually comparing files, and to reach the conclusion of "there must be a better way," and to discover tools that take the pain out of the problem. Keeps the horse before the cart, so to speak, rather than recommending tools/workflow explicitly.

Thanks for sharing your approach here on the forum.

yong


Reply | Threaded
Open this post in threaded view
|

Re: Compiler testing method

rgravina
This post was updated on .
In reply to this post by Devo
> I've found it much, much more helpful to compile the test programs using both my compiler and the supplied compiler

Same for me. Once I had built the symbol table, which is covered reasonably well in text and by Fig 11.6, I really didn't know where to start. I guess with function declaration, but where do you start with that?

So, I found if I ran the supplied compiler against the first/simplest test program listed in the project (Seven), the results showed a function definition, pushing some constants and calling Math.multiply on them  (expression parsing), calling Output.printInt ('do' statement, returning void and throwing away return value) etc. and how it all works made more sense. I could start to place calls to VMWriter at the appropriate places during parsing and get the same output (since in stage one my XML files matched the test output exactly).

Then, the next program 'ConvertToBin' introduces more ops (negation), then the 'let' statement and so on.

This for me was the only real thing which made sense, since the book doesn't go into very much detail on code generation.
Reply | Threaded
Open this post in threaded view
|

Re: Compiler testing method

cadet1620
Administrator
rgravina wrote
So, I found if I ran the supplied compiler against the first/simplest test program listed in the project (Seven), the results showed a function definition, pushing some constants and calling Math.multiply on them (expression parsing), calling Output.printInt ('do' statement, returning void and throwing away return value) etc.
It can also help to write your own even simpler test programs to compare between the compilers. For example, if method calls are causing trouble you could try this
class Test {
    method int test(int x) {
        var Test t;
        var int y;
        let y = test(x);
        let y = t.test(x);
        return y;
    }
}
Another thing that can be quite helpful is to write the source code as comments in the generated vm. You probably want to make writing the comments an option.

Here's what my compiler generates with the -d option is set.

/// 1: class Test {
/// 2:     method int test(int x) {
/// 3:         var Test t;
/// 4:         var int y;
function Test.test 2            // 0
push argument 0                 // 1    this
pop pointer 0                   // 2    this
/// 5:         let y = test(x);
push pointer 0                  // 3    this
push argument 1                 // 4    x
call Test.test 2                // 5
pop local 1                     // 6    y
/// 6:         let y = t.test(x);
push local 0                    // 7    t
push argument 1                 // 8    x
call Test.test 2                // 9
pop local 1                     // 10    y
/// 7:         return y;
push local 1                    // 11    y
return                          // 12
/// 8:     }
/// 9: }
(The numbers to the right are the vm line numbers displayed in the VMEmulator—every vm command gets a number except for label.)

--Mark

Reply | Threaded
Open this post in threaded view
|

Re: Compiler testing method

ivant
In reply to this post by Devo
There is more than one correct way to compile Jack to VM code. E.g. you can compile the "if" statement like this:
// test
neg
if-goto else
// then part
goto fi
label else
// else part
fi
Or like this:
// test
if-goto then
// else part
goto fi
label then
// then part
label fi

 I think, the authors didn't want to "force" their way as being the right one.