Reference Developer Tutorial 1 Introduction 2 Macros 3 Typesetting 4 Example 5 Hints 6 Examples 7 Webmaking SEARCH

2.2 Number of Times Called

So far we have seen only tiny, degenerate input files. The next example moves up to the level of "trivial", but starts to convey the flavour of the way FunnelWeb can be used in practice. Normally, there would be documentation text appearing between the macros, but this has been omitted so as to keep the focus on the macros themselves. Although the next example is much longer than the previous example, the only new construct is `@-` which can appear only at the end of a line, and suppresses it, preventing it from appearing in the text. The `@-` construct allows the text of a macro to be aligned at the left margin, rather than having the first line hanging at the end of the `@{`. FunnelWeb could have been set up so that this end of line marker was suppressed. However, it would have been a special case that would have broken the very memorable rule "the text of a macro is the text appearing between the `@{` and `@}`".

Type the following text into the file `hello.fw` and run it through FunnelWeb. The file contains some intentional errors so be sure to type it in exactly and worry only if FunnelWeb doesn't generate some errors.

    @O@<hello.c@>==@{@-
    @<Include Files@>
    @<Include Files@>
    @<Main Program@>
    @}

    @$@<Main Program@>==@{@-
    main()
    {
     doit();
    }
    @}

    @$@<Subroutine@>==@{@-
    void doit()
    {
     int i;
     for (i=0;i<10;i++)
       {
        @<Print@>
        @<Print@>
       }
    }@}

    @$@<Print@>==@{@-
    printf("Hello World!");
    printf("\n");@}

    @$@<Scan@>==@{scanf@}

    @$@<Include Files@>==@{@-
    #include <stdio.h>
    #include <stdlib.h>@}

What happened? Well, if you haven't typed the file in properly, you may get some miscellaneous syntax errors. Fix these before continuing. If the file has been correctly typed, you should be faced with some error messages to do with the number of times some of the macros are called.

By default, FunnelWeb insists that each macro defined is invoked exactly once. However, the file above defines macros that are used more than once and a macro that is not used at all. Let us examine the errors.

First, we see that FunnelWeb has alerted us to the fact that the `Include Files` macro has been called twice. Once alerted to this, a quick look at the program convinces us that calling the macro twice is a mistake, and that one of the calls should be deleted.

Second, we note that FunnelWeb has alerted us to the fact that the `@<subroutine@>` macro is never called. Again, a quick look at the program tells us that this is a mistake (and a very common one in the use of FunnelWeb), and that a call to the `@<subroutine@>` macro should be inserted just above the call to the `@<Main Program@>` macro in the definition of `@<hello.c@>`.

These two cases demonstrate why these checks have been placed in FunnelWeb. It is nearly always acceptable for a macro to be called once. However, if a macro is not called at all, or called more than once, this is often a sign that the user has made a mistake.

These checks have a dark side too. In addition to the errors mentioned above, FunnelWeb has generated two similar errors that do not help us.

First, we are alerted to the fact that the `@<print@>` macro has been called twice. Clearly, in this case, this is not a problem, and so here FunnelWeb's fussiness is a nuisance.

Second, we are alerted to the fact that the `@<scan@>` macro has never been called. Like the `@<print@>` macro, this macro was defined as a notational convenience, and clearly it does not matter here if it is not used. Again, FunnelWeb is being a nuisance.

The four cases above demonstrate the light and dark side of FunnelWeb's insistence that each macro be called exactly once. To resolve the conflict without reducing the strength of the checking, FunnelWeb provides two special sequences `@Z` (for Zero) and `@M` (for Many) that can be attached to macro definitions. Presence of the `@Z` tag allows the designated macro to be called zero times. Presence of the `@M` tag allows the designated macro to be called more than once. A single macro may carry both tags. It is always true that all macros are allowed to be called exactly once.

Here is the revised program with the errors fixed, by eliminating or adding macro calls, or by adding tags. Try processing the file now. There should be no errors.

    @O@<hello.c@>==@{@-
    @<Include Files@>
    @<Function@>
    @<Main Program@>
    @}

    @$@<Main Program@>==@{@-
    main()
    {
     doit();
    }
    @}

    @$@<Function@>==@{@-
    void doit()
    {
     int i;
     for (i=0;i<10;i++)
       {
        @<Print@>
        @<Print@>
       }
    }@}

    @$@<Print@>@M==@{@-
    printf("Hello World!");
    printf("\n");@}

    @$@<Scan@>@Z==@{scanf@}

    @$@<Include Files@>==@{@-
    #include <stdio.h>
    #include <stdlib.h>@}

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