Search code examples
c#unit-testingcompiler-constructioncompilationtiger

Writing unit tests in my compiler (which generates IL)


I'm writing a Tiger compiler in C# and I'm going to translate the Tiger code into IL.

While implementing the semantic check of every node in my AST, I created lots of unit tests for this. That is pretty simple, because my CheckSemantic method looks like this:

public override void CheckSemantics(Scope scope, IList<Error> errors) {
...
}

so, if I want to write some unit test for the semantic check of some node, all I have to do is build an AST, and call that method. Then I can do something like:

Assert.That(errors.Count == 0);

or

Assert.That(errors.Count == 1);
Assert.That(errors[0] is UnexpectedTypeError);
Assert.That(scope.ExistsType("some_declared_type"));

but I'm starting the code generation in this moment, and I don't know what could be a good practice when writing unit tests for that phase.

I'm using the ILGenerator class. I've thought about the following:

  1. Generate the code of the sample program I want to test
  2. Save generated code as test.exe
  3. Execute text.exe and store the output in results
  4. Assert against results

but I'm wondering if there is a better way of doing it?


Solution

  • That's exactly what we do on the C# compiler team to test our IL generator.

    We also run the generated executable through ILDASM and verify that the IL is produced as expected, and run it through PEVERIFY to ensure that we're generating verifiable code. (Except of course in those cases where we are deliberately generating unverifiable code.)