2013-02-19 12 views
5

Ho iniziato a pasticciare con Ypsilon, che è un'implementazione C++ di Scheme.Ho bisogno di un esempio di utilizzo Ypsilon

Si conforma R6RS, dispone garbage collector veloce, supporta CPU multi-core e Unicode ma ha un LACK di documentazione, esempi e commenti nel codice C++!

Gli autori lo forniscono come applicazione console standalone. Il mio obiettivo è usarlo come motore di scripting in un'applicazione di elaborazione delle immagini.

Il codice sorgente è ben strutturato, ma la struttura non è familiare. Ho trascorso due settimane penetrante, ed ecco cosa ho scoperto:

  1. Tutte le comunicazioni con il mondo esterno avviene tramite strutture C++ chiamato porte, essi corrispondono a porte Scheme.
  2. La macchina virtuale ha 3 porte: IN, OUT ed ERRORE.
  3. Le porte possono essere porte std (tramite console), porte socket, porte bytevector, named-file-ports e custom-ports.
  4. Ogni porta personalizzata deve fornire una struttura piena denominata gestori.
  5. gestori è un vettore contenente 6 elementi: 1 ° uno è un valore booleano (se porta è testuale), e altri cinque sono puntatori a funzione (OnRead, OnWrite, onSetPos, onGetPos, onClose).

Per quanto ho capito, ho bisogno di implementare 3 porte personalizzate (IN, OUT ed ERRORE). Ma per ora non riesco a capire, quali sono i parametri di input di ogni funzione (onRead, onWrite, onSetPos, onGetPos, onClose) nei gestori .

Purtroppo, non c'è né esempio di implementazione di una porta personalizzata alcun esempio di seguire roba:

  1. C++ per binding funzione Scheme (esempi forniti sono un mucchio di .scm-files, ancora poco chiaro che cosa fare sul lato C++).
  2. Compilazione e in esecuzione bytecode (tramite bytevector-ports? Ma come compilare il testo in bytecode?).

Riassumendo, se qualcuno fornisce un C++ esempio di qualsiasi scenario di cui sopra, si potrebbero salvare significativamente il mio tempo. Grazie in anticipo!

+0

Hai provato a contattare il responsabile del progetto del progetto? Potrebbe farti risparmiare tempo. – Seki

+1

@Seki, Sì. Non hanno risposto. –

risposta

2

Va bene, da quello che posso leggere il codice sorgente, ecco come i vari gestori vengono chiamati (questo è tutto non ufficiale, basata esclusivamente sul codice di controllo sorgente):

  1. Leggi gestore: (lambda (bv off len)): prende un bytevector (in cui il gestore inserirà i dati letti), un offset (fixnum) e una lunghezza (fixnum). È necessario leggere fino a len byte, inserendo tali byte in bv a partire da off. Restituisce il numero di byte effettivamente letti (come fixnum).
  2. Gestore scrittura: (lambda (bv off len)): accetta un bytevector (che contiene i dati da scrivere), un offset (fixnum) e una lunghezza (fixnum). Afferra fino a len byte da bv, a partire da off e scrivili. Restituisce il numero di byte effettivamente scritto (come fixnum).
  3. Get gestore posizione: (lambda (pos)) (chiamata in modalità solo testo): consente di memorizzare alcuni dati per pos in modo che una futura chiamata al gestore posizione impostata con lo stesso valore pos ripristinerà la posizione indietro alla posizione corrente. Valore di ritorno ignorato.
  4. Set position handler: (lambda (pos)): sposta la posizione corrente sul valore di pos. Valore di ritorno ignorato.
  5. Chiudi gestore: (lambda()): chiudere la porta. Valore di ritorno ignorato.
+0

Questo aiuterà, grazie, @Chris! Sei collegato allo sviluppo di Ypsilon? –

+0

Il mio piacere. Non sono affatto correlato: ho appena scaricato Ypsilon dopo aver visto questa domanda e ho deciso di scavare. Tuttavia, due cose hanno aiutato: 1. Sono un committer per Guile (un'altra implementazione di Scheme) quindi so come funzionano le implementazioni di Scheme in generale, e 2. Ho esperienza professionale in C++ e considero C++ una delle mie lingue primarie. –

2

Per rispondere a un'altra domanda che avevi, sulla compilazione e l'esecuzione di "bytecode":

  1. Per compilare un'espressione, utilizzare compile. Questo restituisce un oggetto codice.
  2. Non esiste un approccio pubblicamente esportato per eseguire questo oggetto codice. Internamente, il codice utilizza run-vmi, ma non è possibile accedervi da codice esterno.
  3. Internamente, l'unico punto in cui il codice compilato viene caricato e utilizzato è nel suo sistema auto-compile-cache.

Dai un'occhiata a heap/boot/eval.scm per i dettagli. (Anche in questo caso, questa non è una risposta ufficiale, ma basata esclusivamente sulla sperimentazione personale e sull'ispezione del codice sorgente.)

+0

Grazie per le risposte e grazie per il tuo tempo, @Chris! –

Problemi correlati