blob: 102efe46fd966b9ad1b5b16f14a57f1057299b5b [file] [log] [blame]
Quick and Dirty Guide to Extending and Testing Treecc
1. Adding a new output language - Scaffolding
The following is the bare scaffolding to link a new language into treecc:
- Add a new identifier to the TREECC_LANG_* list in "info.h".
- Recognise the language name for the "lang" option in "options.c",
function "LangOption".
- Add a new case to the switch statement in "TreeCCGenerate" function
in the file "gen.c" for the language identifier, which calls a
function called "TreeCCGenerateLang", which you should prototype
in "gen.h".
- Add a new "gen_lang.c" file to the project (don't forget to
update, which implements the output routines.
2. Adding a new output language - Details
The "gen_lang.c" file needs to export a single function called
"TreeCCGenerateLang", which iterates over all the nodes and operations
to output the final code.
The "TreeCCGenerateLang" function must perform the following tasks,
roughly in this order:
- Output any source header information that is required.
- Output node kinds, which are used to uniquely identify each
node type (e.g. "#define expression_kind 1" in C). In an OO
language, you can output these kind values
- Perform forward declaration of the node classes and operations,
if required by the output language (C# and Java don't need this,
but C does).
- Output the node allocation skeleton (normally not needed if
your language is garbage-collected).
- Define the node classes, and any factory create methods that
are required. You may also need to define a "state type" which
holds common allocation information.
- Output non-virtual operations, by calling "TreeCCGenerateNonVirtuals",
and passing it a function block ("TreeCCNonVirtual" type) to
assist with the output process.
- Output any source footer information that is required, including
helper functions for node allocation, kind testing, etc.
It is usually easiest to start with one of the existing output languages
and then cut-and-paste yourself a new one. If you are using a non garbage
collected language such as C or C++, then start with either "gen_c.c" or
"gen_cpp.c" as a base. If you are using a garbage collected language
like C# or Java, then start with either "gen_cs.c" or "gen_java.c".
The function "TreeCCNodeVisitAll" can be very useful for iterating over
all node types in the system: pass it a callback that provides your
language-specific node handling code. See "info.h" and "gen.h" for
other helper functions.
Nodes and operations can be written to multiple output files, and you
must handle this properly. The functions in "stream.h" can assist with
this. The "header" and "source" fields in "TreeCCNode" and "TreeCCOperation"
describe where to output node and operation implementations.
The actual API to nodes and operations is language-specific, but try
to follow the existing styles where possible. See "doc/treecc.texi"
for documentation on the existing API styles.
2. Testing all possible variants.
There are lots of different output modes (re-entrant vs non re-entrant,
line tracking vs no line tracking, abstract factories, virtual vs non-virtual
operations, inline vs non-inline, etc).
Your test cases in the "tests" directory should attempt to cover the
major areas. See the "output*.tst" files for the existing tests. You
shouldn't need to create "input" or "parse" tests, as they are generic.
Once you have written a new "outputN.tst" file, generate test output
using "./test_output outputN.tst >outputN.out". Then hand-inspect the
"outputN.out" file for problems. Once you are satisfied that your
"gen_lang.c" code is generating the right output, add the following
line to "tests/test_list":
test_output outputN
After you have done this, you can run "make check" to verify that you
haven't broken anything as you made changes to the system.
3. Add an example.
Go into the "examples" directory and add a new version of the expression
example for your language, to demonstrate how to use treecc with the
language. The examples doesn't necessarily need to compile - just give
a guide as to how to use the tool.
4. Write documentation.
Add a new section to "doc/treecc.texi" describing the API for your
language, using the existing sections as to a guide to the text.
5. It's not as hard as your think!
The above may look daunting, but it's mostly a cut-and-paste exercise.