# OPP

This page describes OPP, a free open-source preprocessor that you can add to all languages you want to use it in. It is used in the new editions of my languages Sorted!, Smith#, and Java2K.

## Conditional Compilation

What would a preprocessor be without conditional compilation ? In OPP, you have the power of NAND to do all conditional compilation. Use

```##~a|~b
```

(read: not a or not b) to compile the following lines if a is undefined or b is undefined. If you want to check if only a is undefined, use

```##~a|~a
```

If you want to check if a is defined, use

```##~(~a|~a)|~(~a|~a)
```

The statement

```##.
```

ends a conditional compilation block. There is no #else in OPP, but you can use

```##@
```

to do an if-else. For example, if you have a section A to be compiled if B is defined, and a section C to be compiled otherwise, you'd write something like

```##~A|~A
..B..
##@~(~A|~A)|~(~A|~A)
..C..
##.
```

Note that you cannot use whitespaces in the expressions or between ## and ~. Who needs code indentation, anyway ? All of this makes the (recursive) syntax so simple its a joke:

```SYNTAX = '~' OBJECT '|~' OBJECT.
OBJECT = VARIABLE | '(' SYNTAX ')'.
```

Variables can be specified either as environment variables or explicitly as macros (see below).

## Includes

You can use OPP to include other sourcefiles in your code, by using the following statement

```##<<Filename>.
```

Because filenames with dots are frequent, you can use the escape sequence \. to specify a single dot. Because filenames with \ are frequent on certain OSs (OSsi ?) you can use .. to specify a single \ . Because filenames with .. are frequent on ceratin OSs, you can use \\ to specify a single .. . Because filenames with \\ are not so frequent on the OS in question, but still possible, you can use // to specify a single \\, and if your code editor has syntax coloring, you get the rest of the line in comment color, without paying extra. Here is a sample filename in C (on Windows NT) and its equivalent on OPP. Judge for yourself which is more phon - er - fun.

```#include "\\server\users\opp\sample.h"
##<//server..users..opp..sample\.h.
```

Of course, you must specify absolute paths, because OPP does not support proprietary environment variables such as "INCLUDE" or "PATH".

## Defining Macros

OPP supports defining function macros, by utilizing the following syntax.

```##:<name of macro, followed by a single blank> <macro definition>
```

Everything after the single blank is treated as part of the macro body. Macro arguments are implicitly defined by using #0 to refer to the first argument, #1 to the second and so on. Macronames can be virtually anything, including esoteric characters like ? or ä. Here is a macro, that evaluates the max of two arguments as a function "§".

```##:&sect; ((#0<#1)?#1:#0)
```

Now you can write §(a,b) everywhere in your code without unsuspecting people knowing what the deal is.

You can also include varargs in macros, as in the following example, which is a solution to the age-old problem bothering the C macro language: conditional compilation of printf. The syntax for the vararg sequence is

```##<from>..n
```

where <from> specifies the first argument.

```##~(~DEBUG.~DEBUG).~(~DEBUG.~DEBUG)
##:dbg printf(##0..n)
##@~DEBUG.~DEBUG
##:dbg
##.
```

In debug builds, you can use dbg just like normal printf(), in release builds they'll be omitted. To undefine a macro (or an operator, see below), use

```##-<name of macro or operator>
```

## Predefined macros

The following macros are predefined

```##i - the square root of -1 (you need to include complex.h to use this macro)
##_ - the current line number minus 5
##\$ - a pseudo-random number
##{ - The number of { in the code up to this point
##} - The number of } in the code up to this point, modulo 5
```

## Macros inside Macros

In OPP, you can declare macros in other macros. To use macro arguments inside those other macros, use the escape sequence ##, (yes, that comma is part of the seq) as in the following example. After the ##,, a single ## command will be ignored.

```##:foo ##:bar ##,#0->stop(##,#"##,#1..n)
bar(fu,ss)
```

More reasonable examples are possible, but I couldn't think of any.

## Preprocessor operators

In macro or operator definitions, macro arguments are specified by #, followed by a zero-based index. You can use the following macro argument operators.

```#" - stringize operand. Do not confuse with ##"
#' - charize operand. Do confuse with ##'
```

Each of these applies to the next argument expanded, and ONLY to the next argument expanded. You can specify them anywhere in a macro definition.

## Working with Lines

You cannot span macros across multiple lines. Use tense code !

## Using OPP in your own programs

NB: You can include the OPP class in your own programs. You can download the whole package here.