Writing C is a labor, but writing Haskell causes you fever.
Let's generate real world codes by statically typed code generator, using Template Haskell.
Each of the following quasi-quotations convert the inside string into an abstract syntax tree data type defined in Language.Meta.C99.AST
.
-
Translation unit
[c| ... |]
-
Statements
[cs| ... |]
-
Expression
[ce| ... |]
Every AST data types is an instance of Show
.
import Language.Meta.C99.Quote
-- Translation unit [c| ... |]
translation_unit :: String
translation_unit = show [c|
int main(int argc, char **argv)
{
printf("hello world!\n");
return 0;
}
|]
-- Statements [cs| ... |]
statements :: String
statements = show [cs|
while (1) {
printf("hello world!\n");
}
|]
-- Expression [ce| ... |]
expression :: String
expression = show [ce| x * y * z |]
Quoted string can have anti-quotes in the following formats.
-
${}
takes aString
variable -
${<exp>}
executes arbitrary haskell expression of typeString
Replacement targets are statements, expressions, external declarations, part of identifiers, and inside of string literals.
> :t [ce| x + ${} |]
[ce| x + ${} |] :: [Char] -> Language.Meta.C99.AST.Exp
> [ce| x + ${} |] "y"
x + y
> :t [ce| ${} + ${} |]
[ce| ${} + ${} |]
:: String -> String -> Language.Meta.C99.AST.Exp
> [ce| ${} + ${} |] "x" "y"
x + y
> [ce| x + ${"y"} |]
x + y
> [cs| foo_${}(); |] "bar"
foo_bar();
> [ce| printf("${show [1,2,3,4]}\n") |]
printf("[1,2,3,4]\n")
- Preprocessing is not performed in quoted strings. This means macros for syntax modification could not be parsed.
#define LOOP(i, n) for (i = 0; i < n; ++i)
LOOP(i, 10) {
// parse error
}
- Comments inside a statement or decalaration causes parse error.
int /* parse error */ x;
struct x {
int x; // parse error
};
- Context-sensitive portion of grammers will not be parsed appropriately.
typedef int x;
x * x; // either expression (x * x) or declaration (int *x)
x(y); // either function call (x(y)) or declaration (int (y))
However, those kind of misinterpretations do not really matter when you only concern about their literal representations.
- Quasi-quotations could not be nested inside an anti-quotation.
code = [c| int x = ${ show [ce| x * x |] }; |] -- quotes can not be nested here
- Trigraph/Digraph is not supported (who knows).
C99 (ISO/IEC 9899:TC3)
MIT