‮Сдвиг по фазе (kincajou) wrote,
‮Сдвиг по фазе
kincajou

Немного изощрений.

В самом деле, код на основе массива получается в чём-то проще и гибче: индекс ведь не обязан быть той же разрядности, что и физический адрес, соотв., структуры для хранения этих данных можно сделать меньше. Так и сделал - 16-битный индекс (то есть в массиве не может быть больше 65536 ячеек в принципе, а на самом деле там ещё на один бит меньше, поэтому не более 32768 ячеек). Изменив один #define и перекомпилировав программу, можно сделать 32-битные индексы, соответственно увеличив максимальное количество ячеек до прям таки ниииивааабразимых величин.

Но, подозреваю, однажды выяснится, что одним массивом не обойтись и нужно заводить какую-то параллельную структуру данных для хранения чего-нибудь типа списка (или таблицы) встроенных констанкт, функций и операторов - я не хочу тратить драгоценное ОЗУ контроллера для хранения того, что всё равно не меняется (подобные вещи можно и нужно хранить в памяти программ, всегда).

Пока пишу код мелкими кусочками, отлаживая и исследуя его поведение. Вот, например, обобщённые функции получения данных атома по его индексу и копирования атома:

void* data_of(uclptr_t atom)
{
  int type_id = CAR(atom);
  int type_valid = (type_id <= TYPES_TOTAL);
  return (void*)((type_valid && (UCL_Types[type_id].data != 0)) ? UCL_Types[type_id].data(atom) : 0);
}

uclptr_t copy_atom (uclptr_t original)
{
  uclptr_t n = cell_alloc();
  if (!IS_NIL(n))
  {
    int type_id;
    int type_valid = ((CAR(n) = (type_id = CAR(original))) <= TYPES_TOTAL);
    void *sample_data = (void*)((type_valid && (UCL_Types[type_id].data != 0)) ? UCL_Types[type_id].data(original) : 0);
    CDR(n) = (type_valid && (UCL_Types[type_id].create != 0)) ? UCL_Types[type_id].create(sample_data) : NIL;
    TAG(n) = TAG_ATOM;
    return n;
  }
  else
  {
    return NIL;
  };
}

Люблю, знаете ли, такой вот вырвиглазный стиль, делающий из старого доброго Си ужасающую мешанину скобок, точек, амперсандов, звёздочек и прочего мусора, за который почему-то не любят простой и прозрачный синтаксис Лиспа.

Простенькая защита от дурака присутствует. Работает, прикольно. Во второй функции можно было бы вставить вызов data_of, но тогда два раза вычислялось бы значение флага type_valid, а зачем мне такие сложности?
Tags: uncommon lisp
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments