You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在CLJS的Lumo环境开发自定义Lisp解释器,如何实现用户输入读取?

在Lumo的ClojureScript环境中读取用户输入

嘿,很高兴你在跟着《Lisp in Small Pieces》开发自定义Lisp解释器——这绝对是个能深入理解Lisp本质的好项目!关于在Lumo里实现类似Shell read或Python input()的用户输入功能,其实有两种非常实用的方式,我给你详细说说:

方法1:用Node.js的readline模块(异步方式)

Lumo本质上运行在Node.js之上,所以可以直接调用Node的核心readline模块来处理交互式输入。这种方式是异步的,适合不需要阻塞程序的场景,用Promise封装后很符合CLJS的风格:

(require '[cljs.nodejs :as node])

;; 引入Node的readline模块
(def readline (node/require "readline"))

(defn read-input [prompt]
  (js/Promise.
   (fn [resolve _reject]
     (let [rl (readline/createInterface
               #js {:input node/process.stdin
                    :output node/process.stdout})]
       (.question rl prompt
                  (fn [user-input]
                    (.close rl)
                    (resolve user-input)))))))

;; 使用示例
(defn -main []
  (-> (read-input "请输入你的Lisp表达式: ")
      (.then (fn [input]
               (println "你输入的内容是:" input)
               ;; 这里调用你的解释器处理逻辑,比如 (my-interpreter/eval input)
               ))
      (.catch (fn [err]
                (println "读取输入时出错:" err)))))

;; 设置Lumo的入口函数
(set! *main-cli-fn* -main)

方法2:用Lumo内置的lumo.io/read-line(同步方式)

如果你想要更接近Python input()的同步阻塞行为,Lumo提供了lumo.io/read-line这个便捷函数,它可以同步读取用户输入的一行文本,用法超简单:

(require '[lumo.io :as io])

(defn -main []
  (print "请输入表达式: ")
  (flush) ;; 一定要调用flush,确保提示符立刻显示(避免输出缓冲问题)
  (let [input (io/read-line)]
    (println "处理你的输入:" input)
    ;; 在这里把input传给你的解释器处理
    ))

(set! *main-cli-fn* -main)

扩展:实现REPL风格的持续输入

如果你的解释器需要像标准Lisp REPL一样持续接受输入,直到用户主动退出,可以用递归循环来实现:

(require '[lumo.io :as io])

;; 假设这是你的解释器核心求值函数
(defn interpret-expr [expr]
  ;; 这里替换成你的实际解析、求值逻辑
  (str "[求值结果] " expr))

(defn my-lisp-repl []
  (print "my-lisp> ")
  (flush)
  (when-let [input (io/read-line)]
    (cond
      (#{"quit" "exit" "q"} input) (println "再见!")
      :else
      (do
        (println (interpret-expr input))
        (my-lisp-repl)))))

(defn -main []
  (println "欢迎使用自定义Lisp解释器!输入quit/exit/q退出")
  (my-lisp-repl))

(set! *main-cli-fn* -main)

小提示

  • 使用同步read-line时,务必调用(flush),否则提示符可能会因为输出缓冲延迟显示,让用户误以为程序没响应。
  • 两种方式都能很好地跨平台工作,Lumo已经帮我们处理了Node.js环境下stdin/stdout的细节。

内容的提问来源于stack exchange,提问作者Gra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:13:27