LINUX.ORG.RU

История изменений

Исправление 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;
   }