cpp replaced by m4?
    Ric Werme 
    ewerme at comcast.net
       
    Tue Jul  3 16:07:38 EDT 2007
    
    
  
Thomas Charron may have opened the floodgates:
>  Can we have an example of why you want to do this?
I had refrained from suggesting (somewhat tongue in cheek) that you
should sit down with the MACRO-10 manual (the assembler for the PDP-10)
and implement its macro processor.  However, since I have an opening....
One of the things sadly lacking in C is the ability to create initialized
data structures with circularly linked lists, trees, etc.  I once wrote a
macro to take a list of command names and create a tree to walk character
by character.  TOPS-10 had a module where it would take the disk drive
and file system description and create at compile time all the data structures
the system needed for them.
We also had a most wonderful I/O system (it did some things that printf can't)
that included a tiny lexical analyzer.  The heart of was a macro that
packed characters (or flags), labels, callbacks, jumps, calls, etc into
36 bit control words.  You could parse a TOPS-10 path that looked like
DEV:FILE.EXT[#,#] with this table:
	TBLBEG(FILSPC)
	PROD(	<SG>		,FILI, ,      )	;INIT FILE PARSER FLAGS
NXTATM:	PROD(	<SG>		,CALL, ,SIXSCN)	;GET A NAME
	PROD(	"_"		,NODE,*,NXTATM)	;UNDERSCORE MEANS A NODE
	PROD(	":"		,DEV ,*,NXTATM)	;COLON MEANS A DEVICE
	PROD(	"."		,NAME,*,NXTATM)	;AND PERIOD MEANS NAME
	PROD(	"["		,NAMX,*,PPNSCN)	;THEN BRACKET MEANS NAME OR EXT
	PROD(	<SG>		,NAMX, ,      )	;ANYTHING ELSE IS SAME
PPNDON:	PROD(	<SG>		,SRET, ,      )	;QUIT WHILE AHEAD
PPNSCN:	PROD(	<SG>		,GPRJ, ,      )	;GET PROJECT NUMBER
	PROD(	<SG>		,PROJ,*,      )	;SAVE PROJECT. PROJ WILL FAKE CALL
	PROD(	"]"		,    ,*,      )	;OPTIONAL CLOSE BRACKET
	PROD(	<SG>		,PROG, ,PPNDON)	;MERGE WITH PROJECT
SIXSCN:	PROD(	<BLANK>		,    ,*,.     )	;SKIP BLANKS
	PROD(	<SG>		,SIXI, ,      )	;SETUP SIXBIT PACKER
	PROD(	<LETTER!DIGIT>	,SIXS,*,.     )	;SAVE ANY ALPHANUMERICS
SKPBLA:	PROD(	<BLANK>		,    ,*,.     )	;IGNORE BLANKS
	PROD(	<SG>		,RET , ,      )	;AND RETURN
	TBLEND
The first column matched on characters or types (<SG> matched everthing)
The column with 4 character names went to local callbacks to process
individual characters or other events.  (CALL and RET note subroutine calls
and returns.) The '*' meant to discard the character after the callback, the
last field is the address for the next instruction, blank says execute the
next.
See http://pdp-10.trailing-edge.com/decuslib10-04/01/43,50347/tulip.doc.html
pages 20-22 for better documentation,
see
http://pdp-10.trailing-edge.com/tops10_tools_bb-fp64b-sb/01/10,7/nettst/netlib.mac.html
at the bottom for the code my sample came from.
One very important part of MACRO-10 programming was defining a macro like:
DEFINE	FOO <
	X(item1)
	X(item2)
>
Then define X and call FOO.  Then redefine X and call FOO.
One time might count the number of entries, another might create a circularly
linked list of data structures, etc.  People generally don't redefine C
macros, though it is possible (use #undef first).  IRP and IRPC are very
handy directives, they process indefinite repeats and step through items in
a list of characters in a name.
All in all, cpp was a big disappointment, and m4 offered so little stuff that
was familiar I never bothered to try it.
    -Ric Werme
    
    
More information about the gnhlug-discuss
mailing list