Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site watmath.UUCP Path: utzoo!watmath!kpmartin From: kpmartin@watmath.UUCP (Kevin Martin) Newsgroups: net.lang.c Subject: Fuel for your flames: Things I would like in CPP Message-ID: <9225@watmath.UUCP> Date: Sun, 30-Sep-84 14:03:27 EDT Article-I.D.: watmath.9225 Posted: Sun Sep 30 14:03:27 1984 Date-Received: Mon, 1-Oct-84 03:37:19 EDT Organization: U of Waterloo, Ontario Lines: 84 There are several things which I would like in CPP, but before I describe them, I would like to stifle the obvious flame: *USING M4 IS NOT A SUITABLE SOLUTION* 1) Not every system has m4 (e.g. non-unix systems) 2) Having to manually use a pre-processor which is not well-integrated into the language is a pain; ask anyone who uses Troff+Eqn+Tbl how much fun it is to find the original input line which caused Troff to issue an error message 3) m4 can't use CPP macros, nor vice versa. For instance, m4 can't use names such as NOFILE (in), since the include file is brought in by CPP's #include directive (which m4 doesn't understand), and even if m4 understood #include, it wouldn't understand #define. Now, on to things I would like to see: 1) The ability to define a token to be the result of an expression: e.g. #eval XXX 1+2 would define 'XXX' to have the value 3, just as if I had typed #define XXX 3 The expression would be macro-expanded just as it is for #if This is useful for two purposes: Any defined constants within the expression can be re-defined without changing the new constant, e.g. /* Define offsets */ #define X 1 #define Y 2 #define Z 3 /* Define first group */ #define BASE 10 #eval XX BASE+X #eval YY BASE+Y #eval ZZ BASE+Z /* Define second group */ #define BASE 20 ... /* the value of XX, when expanded, remaine unchanged */ The other use is to generate new identifiers. This requires some form of token concatenation to work: #eval NUM NUM+1 #define NAME tempvar/**/NUM /* (or however token concatenation works) */ 2) The ability to put newlines in a macro definition, in order that the macro, when expanded, can perform other #directives This should probably use a directive other than #define, since escaping the newline for #define already has meaning. Perhaps: #macro name(formals) /* put macro body here */ #endm name (The 'name' on the #endm would be optional, and default to the macro which is currently being defined; it is there so that the invokation of a macro can define other macros) 3) The ability to temporarily send output to another file, to be later included by a form of the #include directive. This is similar to the diversion facility in m4. This facility, combined with macros (as in (2) above), allows the generation of parallel tables, since the macro can put the entry into the first table, switch to another diversion, and put the entry for the second table, then switch back. 4) Given proper macros, it is now useful to have the ability to issue error messages, perhaps including a severity (warning -- the compile can continue, error -- CPP can continue, but the compiler should not be called up, fatal -- force CPP to give up immediately). #message 0 "Warning: NUM < 0" Maybe the quotes aren't needed... The combination of the first three features allows generation of ragged initialized arrays: Each row is given a name using #eval and token concatanation, the row is given storage class 'static', and, by switching to another diversion, the row pointer in the edge vector can be initialized to point to the row. Note that none of these changes will harm existing C programs. And with a well-written CPP, none of these changes are terribly difficult to implement. Kevin Martin, UofW Software Development Group