Интерпретация нескольких модулей

Я хотел бы иметь несколько модулей в моей программе. Например. модуль foo и модуль bar. Модуль foo будет ссылаться на модуль bar. Затем я хотел бы иметь возможность протестировать эти модули в версии csi (interpreted). Корень этого вопроса в том, могу ли я запустить свой код без его компиляции. Ниже мой пример.

Примечание. Я новичок в схемах, поэтому с этим кодом могут быть другие проблемы. Не стесняйтесь указывать что-нибудь, и я постараюсь исправить.

foo.scm

(use r7rs)
(define-library (foo)
  (import (scheme base)
          (prefix bar bar:))
  (export add-some-stuff)
  (begin

    (define baz 1)

    (define (add-some-stuff)
      (+ baz bar:bork))

    ))

bar.scm

(use r7rs)
(define-library (bar)
  (import (scheme base))
  (export bork)
  (begin

    (define bork 2)))

Ожидается, что результаты будут:

$ csi
> ,l foo.scm
> (import (prefix foo foo:))
> (foo:add-some-stuff)
;;=> 3

Вот ошибка, которую я получаю:

$ csi -q
#;1> ,l foo.scm
; loading foo.scm ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/chicken.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/numbers.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/foreign.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/srfi-4.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/scheme.base.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs-support.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/extras.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/srfi-13.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs-compile-time.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs-library.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs-support.so ...

Note: re-importing already imported syntax: syntax-rules

Note: re-importing already imported syntax: cond-expand

Note: re-importing already imported syntax: define-record-type

Note: re-importing already imported syntax: include

Note: re-importing already imported syntax: include

Note: re-importing already imported syntax: import

Note: re-importing already imported syntax: import-for-syntax

Note: re-importing already imported syntax: cond-expand

Note: re-importing already imported syntax: import-for-syntax

Note: re-importing already imported syntax: import
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/numbers.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/scheme.base.so ...

Note: re-importing already imported syntax: syntax-rules

Note: re-importing already imported syntax: import-for-syntax

Note: re-importing already imported syntax: import

Note: re-importing already imported syntax: cond-expand

Note: re-importing already imported syntax: import-for-syntax

Note: re-importing already imported syntax: import

Error: (import) during expansion of (import ...) - cannot import from undefined module: bar

    Call history:

    numbers.scm:1672: scan-real
    <syntax>      (define-library (foo) (import (scheme base) (prefix bar bar:)) (export add-some-stuff) (begin (defin...
    <syntax>      (##core#module foo ((##r7rs#foo)) (##core#define-syntax ##r7rs#foo (##core#lambda _ (quote (##core#u...
    <syntax>      (##core#define-syntax ##r7rs#foo (##core#lambda _ (quote (##core#undefined))))
    <syntax>      (##core#lambda _ (quote (##core#undefined)))
    <syntax>      (##core#begin (##core#quote (##core#undefined)))
    <syntax>      (##core#quote (##core#undefined))
    <syntax>      (##core#undefined)
    <syntax>      (##sys#provide (##core#quote foo))
    <syntax>      (##core#quote foo)
    <syntax>      (import-for-syntax (only r7rs begin cond-expand export import import-for-syntax include include-ci s...
    <syntax>      (##core#undefined)
    <syntax>      (import (only r7rs begin cond-expand export import import-for-syntax include include-ci syntax-rules...
    <syntax>      (##core#undefined)
    <syntax>      (##core#begin (import (scheme base) (prefix bar bar:)) (##core#begin (export add-some-stuff) (##core...
    <syntax>      (import (scheme base) (prefix bar bar:))  <--
#;1>

person Frank Henard    schedule 06.10.2017    source источник


Ответы (2)


С этим есть несколько проблем:

  1. Синтаксис загрузки модуля bar неверен, import ожидает список библиотек, где (scheme base) будет одной, а (prefix bar bar:) другой.

  2. В то время как яйцо R7RS добавляет поддержку синтаксиса своего модуля, оно повторно использует существующую поддержку загрузки модулей, которая зависит от компиляции модулей в общую библиотеку и библиотеку импорта в загружаемом месте, таком как репозиторий яйца или текущий каталог. Поэтому вам придется скомпилировать оба модуля в правильном порядке с помощью csc -R r7rs -sJ перед их использованием.

  3. csc -R r7rs -sJ bar.scm получается, csc -R r7rs -sJ foo.scm нет. Это связано с тем, что предыдущий вызов выдает other-module.import.scm из-за (define-library (other-module) ...). Это необходимо изменить, чтобы оно соответствовало идентификатору, который вы импортируете.

С этими изменениями я могу успешно воспроизвести ваш пример сеанса. Вот краткое изложение шагов сборки и входных файлов:

csc -R r7rs -sJ bar.scm
csc -R r7rs -sJ foo.scm

foo.scm

(use r7rs)
(define-library (foo)
  (import (scheme base)
          (prefix bar bar:))
  (export add-some-stuff)
  (begin

    (define baz 1)

    (define (add-some-stuff)
      (+ baz bar:bork))

    ))

bar.scm

(use r7rs)
(define-library (bar)
(import (scheme base))
(export bork)
(begin

    (define bork 2)))
person wasamasa    schedule 06.10.2017
comment
спасибо за ваш обстоятельный ответ! Корень моего вопроса действительно в том, могу ли я использовать интерпретатор кода в моем проекте без компиляции. Кажется, что я не могу, но, возможно, это еще не окончательно. Я исправил другие ошибки в моем примере. - person Frank Henard; 06.10.2017

Kooda с irc-канала #chicken порекомендовал системное яйцо, и, похоже, делать то, что я ищу. Короче говоря, нужно создать файл .system, указывающий дерево зависимостей, которое описано ниже. Немного жаль, что Chicken Scheme не может определить внутренние зависимости модуля, просматривая операторы импорта в каждом модуле, но я думаю, что это следующая лучшая вещь.

$ chicken-install system

создайте файл с именем so-question-chicken-scheme.system. Этот файл должен содержать:

(define-system so-question-chicken-scheme
  (scheme-file "bar")
  (scheme-file "foo" depends: '("bar")))

Вот результаты интерпретатора

$ csi -q
#;1> (use system)
#;2> (load "so-question-chicken-scheme.system")
#;3> (load-system so-question-chicken-scheme)
#;4> (import (prefix foo foo:))
#;5> foo:add-some-stuff
#<procedure (add-some-stuff)>
#;6> (foo:add-some-stuff)
3
person Frank Henard    schedule 06.10.2017