Jatha Bringing to Java some of the power of Lisp version 1.0 written by Kimberley Burchett http://www.kimbly.com/code/jatha/ 1. Introduction The idea behind Jatha is to do for java what defmacro does for lisp. Jatha is a preprocessor that runs arbitrary java code in order to generate the source code that the compiler sees. What you do is write source code that contains macro invocations. You save this source code in a file with a .jatha extension. Then you run the macro expander which takes each .jatha file, expands the macros, and writes the result to a new file with the .jatha extension removed. For example, you can have a file that uses the @PROP macro like this: class Foo { @PROP(String, name); } And it will be expanded into this: class Foo { private String m_name; public String getName() { return m_name; } public void setName(String name) { m_name = name; } } All "macros" are actually just regular java classes. The @PROP macro is merely a class named "PROP" that lives in the "macros" package. When the expander sees "@PROP(String, name)", it creates an instance of the PROP class on the fly, using dynamic class loading. It then calls the PROP object's expand method, and passes it the arguments {"String", "name"}. The expand method then returns a String which gets inserted into the file in place of the original macro. 2. Running the Expander This is the command line syntax for the macro expander: java jatha.Main [-all | -quiet] [-dir ] The -all switch tells the expander to expand all .jatha files, even if the generated file appears to be up to date (i.e. the generated file is newer than the .jatha file). The -all switch is useful if you change the implementation of one of your macros and have to regenerate everything. The -quiet switch tells the expander to suppress messages about files that appear to be up to date not being regenerated. The -quiet switch and the -all switch cannot be used together. The -dir switch tells the expander to expand all the .jatha files in the specified directory. If the -dir switch is omitted, the current directory is used. Note that there is nothing that requires you to generate java code from Jatha. You could easily use Jatha to generate C++ code -- just name your file myfile.cpp.jatha, and the expander will work as usual. Of course, some of the sample macros won't be very useful for C++, but you don't have to use them. 3. File and Directory Organization ./README.txt is this file. ./COPYING.txt contains a copy of the GNU General Public License. ./index.html is the introductory web page. It is meant to give a quick idea of what Jatha does, and does not contain as much information as this file. ./jatha/ contains the macro expander and the Macro base class. ./macros/ contains sample macros that come in handy when writing java code or when writing new macros. ./macros/test/ contains unit tests for the sample macros. The unit tests do not need to be run -- merely compiling them without errors is enough to prove that the macros work. ./Makefile will build the macro expander, the sample macros, and then the unit tests. 4. Writing New Macros You can write your own macros. All you have to do is make your macro extend the class jatha.Macro, put it in the macros package, and have it somewhere on your classpath. You can use the MacroUtils class to help in implementing your macro. MacroUtils has various functions that I have found useful. I've also included a STRINGIFY macro which frequently comes in handy when writing macros (yes, you can use existing macros when creating new macros). Macros can leave "messages" for each other. For example, every time the @PROP macro is expanded, it leaves a message that later macros can use to find out the type of the property. These messages can be very useful when writing new macros. You look up messages by name, and get back a String value. For example, if I declare a property @PROP(String, name) then a later Macro can retrieve the type of the name property by looking up the message named "PROP`typeof`name", which will be equal to "String". The convention for naming messages is that the name begin with the macro name, followed by a backtic. The names of all the macros that I have written are in UPPER-CASE, but that is only a convention I use because I find it easy to read. You can name your macros in whatever way you like. However, remember that the names are case sensitive. 5. License Jatha is distributed under the terms of the GNU GPL. See the file COPYING.txt for more information. Please note that it is perfectly fine to use Jatha to develop commercial products. Only if you actually distribute Jatha itself will the GPL come into play.