General Category > Ideas
Macros again
lerno:
The SMART C macro system has a bit more stuff to consider: https://repository.upenn.edu/cgi/viewcontent.cgi?referer=https://www.google.com/&httpsredir=1&article=1474&context=cis_papers
Worth a read. Note that they add macro FOR, IF-ELSE, SWITCH. I think this is a reasonable thing to do. "SWITCH" is present in the __Generic macro in C, IF-ELSE is obviously there already, then finally the FOR loop... I think that is an important additions since its lack is making a lot of macros much more complicated.
lerno:
More about macros: http://www.wilfred.me.uk/blog/2014/09/15/comparative-macrology/
lerno:
A tiny way to modify macros would be to simply extend "#define" with a { ... } syntax:
--- Code: ---#define ADD_TO(x, y) {
x += y;
}
ADD_TO(x, 1)
--- End code ---
The { } introduces a multiline macro that does not need explicit linebreaks.
Secondly we could add the "$" symbol to introduce hygienic temporaries:
--- Code: ---#define SWAP(x, y) {
typeof(x) $tmp = x;
x = y;
y = $tmp;
}
--- End code ---
Here $tmp will actually be replaced by __<macro>_<variable_name>_<instance> when translating to C, so __SWAP_tmp_1, __SWAP_tmp_2 etc.
We then introduce the syntax macros using:
--- Code: ---macro swap(&a, &b) {
typeof(a) $tmp = a;
b = a;
a = $tmp;
}
--- End code ---
The use of &a follows C++ standard: it simply refers to a variable OR EXPRESSION that is imported into its scope. Using the unadorned variable name as evaluated expression allows us to write this code:
--- Code: ---macro max(a, b) {
return (a > b ? a : b)
}
--- End code ---
The above code is equivalent to:
--- Code: ---macro max(&a, &b) {
typeof(a) $tmp_a = a;
typeof(b) $tmp_b = b;
$tmp_a > $tmp_b ? $tmp_a : $tmp_b
}
--- End code ---
Or in (GNU) C:
[/code]
--- Code: --- #define max(a,b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a > _b ? _a : _b; })
--- End code ---
To recap:
1. We add the { } format to #define for multiline defines.
2. We add the $<name> format as hygienic variable names.
3. We add the syntax "macro" type of definition.
4. The syntax macro makes a difference between "normal" parameters (with & as prefix) and "evaluated" parameters (unadorned variables)
In addition we need to make macros have a definite scope. I suggest the following:
#define is always defined local to a scope (unlike in C).
This means that
--- Code: ---#define FOO printf("foo");
{
#define BAR printf("bar");
}
FOO // adds printf("foo");
BAR; // Error, define not available in scope;
--- End code ---
This also means that a define can be declared public to be accessed as if defined from the top of the file scope:
--- Code: ---// file 1
module foo
public #define FOO { printf("FOO!\n"); }
// file 2
import foo
func void test() {
foo.FOO
}
--- End code ---
Only defines in the file scope that exists in the file scope may be public and used in other modules.
lerno:
Another C type lang with semantic macros worth looking at: http://zl-lang.org/zl-dissertation-univf.pdf
Navigation
[0] Message Index
[*] Previous page
Go to full version