Нужен пример использования Ипсилона

Я начал связываться с Ypsilon, которая является реализацией схемы на C ++.

Соответствует R6RS, имеет быстрый сборщик мусора, поддерживает многоядерные процессоры и Unicode, но имеет ОТСУТСТВИЕ документации, примеры кода C ++ и комментарии в коде!

Авторы предоставляют его как отдельное консольное приложение.
Моя цель — использовать его в качестве механизма сценариев в приложении для обработки изображений.

Исходный код хорошо структурирован, но структура незнакома.
Я потратил на это две недели, и вот что я узнал:

  1. Все общение с внешним миром осуществляется через структуры C ++, называемые
    порты, они соответствуют схемам портов.
  2. Виртуальная машина имеет 3 порта: IN, OUT и ERROR.
  3. Порты могут быть стандартными (через консоль), сокет-портами,
    bytevector-ports, named-file-ports и custom-port.
  4. Каждый пользовательский порт должен содержать заполненную структуру обработчики.
  5. Обработчики вектор, содержащий 6 элементов: 1-й является логическим
    (будь то
    порт является текстовым), а остальные пять являются указателями на функции (onRead, onWrite, onSetPos, onGetPos, onClose).

Насколько я понимаю, мне нужно реализовать 3 пользовательских порта (IN, OUT и ERROR).
Но пока я не могу понять, каковы входные параметры каждой функции (onRead, onWrite, onSetPos, onGetPos, onClose) в обработчики.

К сожалению, нет ни одного примера реализации пользовательского порта, нет примера следующего:

  1. Привязки функций C ++ к Scheme (приведенные примеры представляют собой связку
    .scm-файлы, пока неясно, что делать на стороне C ++).
  2. Компиляция и
    работает bytecode (через bytevector-ports? Но как скомпилировать текст в
    байткод?).

подведение, если кто-нибудь предоставит C ++ пример какого-либо сценария, упомянутого выше, это значительно сэкономит мое время.
Заранее спасибо!

5

Решение

Хорошо, из того, что я могу прочитать из исходного кода, вот как называются различные обработчики (это все неофициально, основано исключительно на проверке исходного кода):

  1. Читать обработчик: (lambda (bv off len)): принимает байтовый вектор (в который ваш обработчик поместит прочитанные данные), смещение (fixnum) и длину (fixnum). Вы должны прочитать до len байты, помещая эти байты в bv начинается с off, Возвращает количество фактически прочитанных байтов (как fixnum).
  2. Написать обработчик: (lambda (bv off len)): принимает байтовый вектор (который содержит данные для записи), смещение (fixnum) и длину (fixnum). Возьми до len байты из bv, начинается с offи выпиши их. Возвращает количество фактически записанных байтов (как fixnum).
  3. Получить обработчик позиции: (lambda (pos)) (вызывается только в текстовом режиме): позволяет хранить некоторые данные для pos так что будущий вызов к обработчику установленной позиции с тем же pos значение сбросит позицию обратно в текущую позицию. Возвращаемое значение игнорируется.
  4. Установить позицию обработчика: (lambda (pos)): Переместить текущую позицию в значение pos, Возвращаемое значение игнорируется.
  5. Закрыть обработчик: (lambda ()): Закрыть порт. Возвращаемое значение игнорируется.
2

Другие решения

Чтобы ответить на другой вопрос, который у вас был, о компиляции и запуске «bytecode»:

  1. Чтобы скомпилировать выражение, используйте compile, Это возвращает объект кода.
  2. Не существует публично экспортируемого подхода для запуска этого объекта кода. Внутренне, код использует run-vmi, но вы не можете получить доступ к этому извне кода.
  3. Внутренне единственное место, где скомпилированный код загружается и используется, находится в его auto-compile-cache система.

Посмотри на heap/boot/eval.scm для деталей. (Опять же, это не официальный ответ, а основанный исключительно на личных экспериментах и ​​проверке исходного кода.)

2