如何使用控制台作为 Guile Scheme 的输入和输出?

How to use console as input and output for Guile Scheme?

我了解 Scheme 使用端口来执行输入和输出。在尝试学习如何获取控制台输入和输出时,我遇到了 MIT-Scheme 的 console-i/o-port 变量。

但是,狡猾的解释器说它是一个未绑定的变量。我想知道我们如何使用端口在 Guile Scheme 脚本中从控制台(Unix 中的终端)获取输入和输出。我还是Scheme的菜鸟,Linux,清晰的步骤表示赞赏。

此外,(display <object>) 是如何工作的?它是固有地使用端口还是有其他方式。

P.S。如果有另一种不使用端口的方法,请告诉我如何使用它。

如果你想读写 SExps,你有 (read)、(write)、(display) 等,如果你只想读取字符,请使用 (read-char) 和 (write-char) ) -- 他们都使用 input/output 端口。你选择了,默认情况下它们是 stdin 和 stdout。一切都相当简单 (https://www.gnu.org/software/guile/manual/html_node/Input-and-Output.html#Input-and-Output)。

您可能还对 guile-ncurses (https://www.gnu.org/software/guile-ncurses/) 感兴趣。

从 ice-9 中查看漂亮的打印模块(在很长的 sexps 上它很慢但输出它们的格式非常好,非常适合代码生成):

  (use-modules (ice-9 pretty-print))
  (pretty-print `(super cool stuff (+ 2 3) => ,(+ 2 3)))

如果您需要自己的解析器,请查看 lalr 模块(系统基础 lalr)。

编辑一个小例子,它读取一个数字,自相乘并打印出结果:

#!/usr/bin/guile -s
!#

(let ((x (read)))
  (display (* x x))
  (newline))

(记得chmod +x这个脚本)。

edit 按照 Chris 的建议将表达式更改为 let 形式,确实括号越少越好

你有 2 个函数:current-input-portcurrent-output-port (the docs)

读取文本并将其放入字符串(如果您不想读取 s 表达式),您可以使用此函数:

(define (read-port port)
    (let iter ((result '()) (chr (read-char port)))
        (if (eof-object? chr)
            (list->string result)
            (iter (append result (list chr)) (read-char port)))))

从标准输入读取将是:

(read-port (current-input-port))

要写入标准输出,您可以使用 display 它也接受第二个参数,即端口 relevant docs