История изменений
Исправление monk, (текущая версия) :
в том числе «макросы», которые просто Си функции без доступа к не константному scope-у (constexpr-функции из C++ или pure-функции из D).
так весь смысле лиспа в том, что во время компиляции есть свой scope (в CL тот же, что и runtime, в Racket — независимый). И, соответственно, во время компиляции можно хранить метаинформацию. Как в моём примере: тут запомнили тип, далее по тексту его прочитали и подставили.
Для C можно было бы сделать на уровне языка аналог (begin-for-syntax ...).
@syntax{
map(char*, char*, strcmp) types;
char* ctype(char* type, char *var) {
char *res = malloc(strlen(type) + strlen(var) + 3);
sprintf(res, "%s %s;" type var);
set_map(var, type);
return res;
}
char *my_type_of(char *var) {
return get_map(var);
}
Соответственно компиляция двухпроходная: сначала компилируется @syntax, затем остальной текст обрабатывается подстановкой macroname(...) => результат выполнения macroname. Затем компилируется остальное.
Исходная версия monk, :
в том числе «макросы», которые просто Си функции без доступа к не константному scope-у (constexpr-функции из C++ или pure-функции из D).
так весь смысле лиспа в том, что во время компиляции есть свой scope (в CL тот же, что и runtime, в Racket — независимый). И, соответственно, во время компиляции можно хранить метаинформацию. Как в моём примере: тут запомнили тип, далее по тексту его прочитали и подставили.
Для C можно было бы сделать на уровне языка аналог (begin-for-syntax ...).
@syntax{
map(char*, char*) types;
char* ctype(char* type, char *var) {
char *res = malloc(strlen(type) + strlen(var) + 3);
sprintf(res, "%s %s;" type var);
set_map(var, type);
return res;
}