Sometimes it is convenient to build up the definition of a macro in stages throughout the input file. In FunnelWeb, this can be done using an additive macro. An additive macro is identical to an ordinary macro except thattutorial==tutorial+=
The following example shows how additive macros can be used to scatter and regroup information, in this case assisting in the lucid construction of a data abstractiondataabstraction in a language (PascalPascal) that does not support them explicitly.
@!****************************** @O@<prog.pas@>==@{@- program adt(input,output); @<Types@> @<Variables@> @<Procedures@> begin startproc; end. @} @!****************************** @$@<Types@>+=@{@- type buffer_type = record length : integer; buf : array[1..100] of char; end; @} @$@<Variables@>+=@{@- bigbuf : buffer_type; @} @$@<Procedures@>+=@{@- procedure buf_init (var b : buffer_type ) {Body of buf_init} procedure buf_add (var b : buffer_type; ch : char) {Body of buf_add} procedure buf_get (var b : buffer_type; var ch : char) {Body of buf_get} @} @!****************************** @$@<Types@>+=@{@- type complex_type = record r,i : real; end; @} @$@<Procedures@>+=@{@- procedure cm_set (var c: complex_type; a,b: real) {Body of cm_set} procedure cm_add (a,b: complex_type; var c: complex_type) {Body of cm_add} {Other procedures and functions} @} @!****************************** {...more pieces of program...} @!******************************
It is important to remember that the definition of each macro does not change throughout the input file. FunnelWeb parses the entire input file and assembles all the macro definitions before it even starts to expand macros. As a result, each additive macro can only have one definition, and that definition is the concatenation of all its parts.
The example above shows how additive macros can be used to rearrange the presentation of a computer program in the order in which the user wishes to discuss it rather than the order in which the compiler requires that it be consumed. It is easy, however, to abuse the feature of additive macros. In many cases, the same effect can be obtained more clearly by replacing each part of an additive macro in-situ using uniquely named non-additive macros, and then collect them together as a group at the point where the additive macro is called. Doing this is more work, and is more error prone, but can result in a clearer exposition. The following program illustrates this alternative approach.
@!****************************** @O@<prog.pas@>==@{@- program adt(input,output); @<Types@> @<Variables@> @<Procedures@> begin startproc; end. @} @$@<Types@>==@{@- @<Buffer type@> @<Complex type@> @} @$@<Variables@>==@{@- @<Buffer variable@> @} @$@<Procedures@>==@{@- @<Buffer procedures@> @<Complex procedures@> @} @!****************************** @$@<Buffer type@>==@{@- type buffer_type = record length : integer; buf : array[1..100] of char; end; @} @$@<Buffer variable@>==@{@- bigbuf : buffer_type; @} @$@<Buffer procedures@>==@{@- procedure buf_init(var b : buffer_type) {Body of buf_init} procedure buf_add(var b : buffer_type; ch : char) {Body of buf_add} procedure buf_get(var b : buffer_type; var ch : char) {Body of buf_get} @} @!****************************** @$@<Complex type@>==@{@- type complex_type = record r,i : real; end; @} @$@<Complex procedures@>+=@{@- procedure cm_set(var c: complex_type; a,b : real) {Body of cm_set} procedure cm_add(a,b : complex_type; var c: complex_type) {Body of cm_add} {Other procedures and functions} @} @!****************************** {...more pieces of program...} @!******************************
One of advantages of FunnelWeb (and literate programming in general) is that (as shown above) it allows the user to lay out the program in whatever order is desiredprogramlayout with near total independence from the ordering requirements of the target programming language.
Additive macros are allowed to be tagged with @Z and @M just as other macros can, but the tags must appear only on the first definition of the macro. Additive macros cannot be connected directly to product files.