Tutorial Developer Reference 1 Introduction 2 Interface 3 Scanner 4 Parser 5 Analyser 6 Tangle 7 Weave 8 Shell 9 Commands 10 Glossary 11 References SEARCH

4.8 Macros

The third category of construct appearing at the highest syntactic level in a FunnelWeb input file is the macro definition. A macro definition binds a unique macro name to a macro body containing an expression consisting of text, calls to other macros, and formal parameters. The syntax for a macro definition is as follows:

    macro = ("@O" | "@$") name [formal_parameter_list]
            ["@Z"] ["@M"] { "@L" } ["==" | "+="]
            "@{" expression "@}"

The complexity of the macro definition syntax is mostly to enable the user to attach various attributes to the macro. If the user chooses `@O`, then the macro cannot be called, but is instead attached to a product file. If the user chooses `@$`, then the macro is an ordinary macro definition that is not attached to a file. Here are some example macro definitions.

    @O@<example.txt@>@{This is an @<ugly duckling@>.@}

    @$@<ugly duckling@>@M@{swan@}

Number Of Invocations Constraint

By default, a non-file macro must be invoked exactly once by one other macro. Macros that aren't are flagged with errors by the FunnelWeb analyser. However, if the user uses the `@Z` sequence in the macro definition, the macro is then permitted to be invoked zero times, as well as once. Similarly, if the user uses the `@M` sequence in the macro definition, the macro is permitted to be called many times as well as once. If both `@Z` and `@M` are present then the macro is permitted to be invoked zero, one, or many times.

The purpose of enforcing the default "exactly one call" rule is to flag pieces of code that the user may have defined in a macro but not hooked into the rest of the program. Experience shows that this is a common error. Similarly, it can be dangerous to multiply invoke a macro intended to be invoked only once. For example, it may be dangerous to invoke a scrap of non-idempotent initialization code in two different parts of the main function of a program! However, FunnelWeb will not generate an error if a macro without `@M` is called by another macro that is called more than once.

Additive Macros

If the text string `==` (or nothing) follows the macro name, the expression that follows is the entire text of the macro body. If the text string `+=` follows the macro name, then more than one such definition is allowed (but not required) in the document and the body of the macro consists of the concatenation of all such expressions in the order in which they occur in the input file. Such a macro is said to be additive and is additively defined. Thus a macro body can either be defined in one place using one definition (using `==`) or it can be distributed throughout the input file in a sequence of one or more macro definitions (using `+=`). If neither `==` and `+=` are present, FunnelWeb assumes a default of `==`.

Macros attached to product files cannot be additively defined. Additively defined macros can have parameter lists and `@Z` and `@M` attributes, but these must be specified only in the first definition of the macro. However, `+=` must appear in each definition.

Library Macros

An ordinary macro definition can have from zero to five `@L` library level markers. These define the macro definition's library level. A macro having a particular name may be defined up to once at each library level, and each such definition may be multipart (additive). At tangle time, the definition having the lowest library level is used, with all other definitions of the same name being completely ignored. This feature allows the creation of general-purpose include files that contain macro definitions that can be overridden by definitions of the same name in the including file. Similarly, it allows the creation of include files containing macro definitions that override definitions in the including file. How you use the library macro feature is up to you.

In the example below, the ugly duckling macro will be expanded to `swan` because the swan definition has the lowest library level.

    @$@<ugly duckling@>@M@L@L@{egg@}
    @$@<ugly duckling@>@M@{swan@}
    @$@<ugly duckling@>@M@L@{signet@}

Note that the library macro facility imposes no requirement on the order of appearance of the various macros of the same name; all that matters is the library level. This means that macros defined in an include file that is included at the end of a main file can be overridden by macros appearing earlier in the main file.

Webmaster Copyright © Ross N. Williams 1992,1999. All rights reserved.