166
Ideas / Re: one big design item: Macros
« on: May 03, 2015, 11:03:20 AM »
The issue about macros for use in function and for use outside functions remains tricky to understand.
Maybe this post can clear this up.
In C, parsing a macro is easy, just treat it as text and only look for some symbols like arguments etc. Replace
those and you're done.
In C2, parsing macros is a completely different story. The main difference is that the parser is used to
parse them, not the preprocessor. This offers advantages like better checking etc. I think most people agree
on the semantic part.
But a Parser, cannot simply treat the macro body as text, but needs to really understand the syntax, just like
any other part of the program. As a (pseudo) example, when the parser starts with a function definition, it is in a
state that it expects globals, eg in its own function parseFile().
The call stack might look like this:
So to parse a C2 macro, the Parser needs to know what to expect: Can it expect a sequence of Statements (like if, while
, calls, etc). Or should it expect top-level Declarations (like stuff at file scope). It could try to detect, but this would make
the Parser difficult and error-prone again. So a solution would be that the programmer tell the Paser what to expect, so it doesn't have to guess. In Rust this is less of an issue, since most things are Expressions.
I don't think adding this requirement would make the language less simple to use. In C, most macro's can only be used either at function scope or at file scope. But since the preprocessor doesn't care, it's up to the Parser to come up with good error messages.
Maybe this post can clear this up.
In C, parsing a macro is easy, just treat it as text and only look for some symbols like arguments etc. Replace
those and you're done.
In C2, parsing macros is a completely different story. The main difference is that the parser is used to
parse them, not the preprocessor. This offers advantages like better checking etc. I think most people agree
on the semantic part.
But a Parser, cannot simply treat the macro body as text, but needs to really understand the syntax, just like
any other part of the program. As a (pseudo) example, when the parser starts with a function definition, it is in a
state that it expects globals, eg in its own function parseFile().
The call stack might look like this:
Code: [Select]
parseGlobal();
parseFileDecl();
parseType(); // the return type
parseFunctionName();
parseFunctionArguments();
parseFunctionBody() {
while (..) {
parseStatement();
}
}
So to parse a C2 macro, the Parser needs to know what to expect: Can it expect a sequence of Statements (like if, while
, calls, etc). Or should it expect top-level Declarations (like stuff at file scope). It could try to detect, but this would make
the Parser difficult and error-prone again. So a solution would be that the programmer tell the Paser what to expect, so it doesn't have to guess. In Rust this is less of an issue, since most things are Expressions.
I don't think adding this requirement would make the language less simple to use. In C, most macro's can only be used either at function scope or at file scope. But since the preprocessor doesn't care, it's up to the Parser to come up with good error messages.