Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need an example of Ypsilon usage

I started to mess with Ypsilon, which is a C++ implementation of Scheme.

It conforms R6RS, features fast garbage collector, supports multi-core CPUs and Unicode but has a LACK of documentation, C++ code examples and comments in the code!

Authors provide it as a standalone console application. My goal is to use it as a scripting engine in an image processing application.

The source code is well structured, but the structure is unfamiliar. I spent two weeks penetrating it, and here's what I've found out:

  1. All communication with outer world is done via C++ structures called ports, they correspond to Scheme ports.
  2. Virtual machine has 3 ports: IN, OUT and ERROR.
  3. Ports can be std-ports (via console), socket-ports, bytevector-ports, named-file-ports and custom-ports.
  4. Each custom port must provide a filled structure called handlers.
  5. Handlers is a vector containing 6 elements: 1st one is a boolean (whether port is textual), and other five are function pointers (onRead, onWrite, onSetPos, onGetPos, onClose).

As far as I understand, I need to implement 3 custom ports (IN, OUT and ERROR). But for now I can't figure out, what are the input parameters of each function (onRead, onWrite, onSetPos, onGetPos, onClose) in handlers.

Unfortunately, there is neither example of implementing a custom port no example of following stuff:

  1. C++ to Scheme function bindings (provided examples are a bunch of .scm-files, still unclear what to do on the C++ side).
  2. Compiling and running bytecode (via bytevector-ports? But how to compile text to bytecode?).

Summarizing, if anyone provides a C++ example of any scenario mentioned above, it would significantly save my time. Thanks in advance!

like image 717
Ivan Goremykin Avatar asked Feb 19 '13 09:02

Ivan Goremykin


1 Answers

Okay, from what I can read of the source code, here's how the various handlers get called (this is all unofficial, based purely on source code inspection):

  1. Read handler: (lambda (bv off len)): takes a bytevector (which your handler will put the read data into), an offset (fixnum), and a length (fixnum). You should read in up to len bytes, placing those bytes into bv starting at off. Return the number of bytes actually read in (as a fixnum).
  2. Write handler: (lambda (bv off len)): takes a bytevector (which contains the data to write), an offset (fixnum), and a length (fixnum). Grab up to len bytes from bv, starting at off, and write them out. Return the number of bytes actually written (as a fixnum).
  3. Get position handler: (lambda (pos)) (called in text mode only): Allows you to store some data for pos so that a future call to the set position handler with the same pos value will reset the position back to the current position. Return value ignored.
  4. Set position handler: (lambda (pos)): Move the current position to the value of pos. Return value ignored.
  5. Close handler: (lambda ()): Close the port. Return value ignored.
like image 56
Chris Jester-Young Avatar answered Oct 19 '22 10:10

Chris Jester-Young