C could have a better way of preprocessing, by allowing computations
on a META-Level, where code is not transformed to machine-code.
However, within this META-Level, one could specify which machine code
is actually desired.
#preprocessor_META_level_ON
...
#machine_code_begin
...
#machine_code_end
...
#preprocessor_META_level_OFF
Below there is an example of this idea!
Try with
#define PUT_BYTE0 something
#define PUT_BYTE1 something_else
I know of this, but I want to save writing out "millions" of lines, by
getting the preprocessor to figure out the pattern (on a META-Level),
instead of me having to mundanely hardcode a pattern:
/************** Example: nice to have *****************/
int regA;
#define MEM_MAP_A ®A;
int regB;
#define MEM_MAP_B ®B;
#define GO(val) \
#preprocessor_META_level_ON \
if (!(val % 3)) \
#machine_code_begin \
*((int *) MEM_MAP_A) = val \
#machine_code_end \
else \
#machine_code_begin \
*((int *) MEM_MAP_B) = val \
#machine_code_end \
#preprocessor_META_level_OFF \
/*
if the preprocessor catches a variable in the meta_level e.g.
{
int my_var;
GO(my_var);
}
then a compiler-error (or rather preprocessor-error) should result!
*/
//In the code I'll have:
{
GO(1);
//...
GO(876);
//...
GO(7987);
//...
GO(3);
//...
}
/************** end *****************/
This would be 4294967296 times better
- (assuming val is a 4 byte
int)
than the following:
/************** Example: bitter reality *****************/
//...
#define GO_1 *((int *) MEM_MAP2) = 1
#define GO_2 *((int *) MEM_MAP2) = 2
#define GO_3 *((int *) MEM_MAP1) = 3
#define GO_4 *((int *) MEM_MAP2) = 4
#define GO_5 *((int *) MEM_MAP2) = 5
//...
#define GO_7987 *((int *) MEM_MAP2) = 7987
//many many lines above!
//In the code I'll have:
{
GO_1;
//...
GO_876;
//...
GO_7987;
//...
GO_3;
//...
}
/************** end *****************/
#define PUT_BYTE(const_index, val) ({ *(const_index ? 99 : 77) \
= (val); })
if you know that const_index is either 0 or 1.
Similar to your suggestion above, there'll be people who'll now say:
The compiler will resolve it for you - and that one could go and use
this:
#define GO(val) \
{ if (!(val % 3)) \
*((int *) MEM_MAP_A) = val; \
else \
*((int *) MEM_MAP_B) = val; \
}
But who knows what the compiler will do??? Maby it will NOT resolve it
and actually include the "if" in the machine code. Don't we want
guarantees??
Yes I could also write a program (special_generator.c) to generate a
header file (head.h) with the "millions" of preprocessor-lines I need,
but I'll just argue that it's confusing to have the generator source
(special_generator.c) in a different file, than it's generated result
(head.h)
The beauty of a Meta-Level, would be that the generator information is
not a seperate special C-file, but embedded in itself:
head.h includes a Meta-Level ...
And more importantly, programmers could have guarantees on what is
resolved and what is not resolved.
..
..
..
My main criticism here, is that C does not have a good method of
working on a Meta-Level.
Actually it's not a severe critisism - C is really great!
But it could still evolve, right?!
anon.asdf