我有clojure的基本口译员。现在我需要实施for (initialisation; finish-test; loop-update) {statements}在我的翻译中。我将附上我到目前为止得到的解释器代码。任何帮助表示赞赏。口译员(declare interpret make-env) ;;(def do-trace false) ;;;; simple utilities(def third ; return third item in a list (fn [a-list] (second (rest a-list))))(def fourth ; return fourth item in a list (fn [a-list] (third (rest a-list))))(def run ; make it easy to test the interpreter (fn [e] (println "Processing: " e) (println "=> " (interpret e (make-env)))));; for the environment(def make-env (fn [] '()))(def add-var (fn [env var val] (cons (list var val) env)))(def lookup-var (fn [env var] (cond (empty? env) 'error (= (first (first env)) var) (second (first env)) :else (lookup-var (rest env) var))));; -- define numbers(def is-number? (fn [expn] (number? expn)))(def interpret-number (fn [expn env] expn));; -- define symbols(def is-symbol? (fn [expn] (symbol? expn)))(def interpret-symbol (fn [expn env] (lookup-var env expn)));; -- define boolean(def is-boolean? (fn [expn] (or (= expn 'true) (= expn 'false))))(def interpret-boolean (fn [expn env] expn));; -- define functions(def is-function? (fn [expn] (and (list? expn) (= 3 (count expn)) (= 'lambda (first expn)))))(def interpret-function (fn [expn env] expn));; -- define addition(def is-plus? (fn [expn] (and (list? expn) (= 3 (count expn)) (= '+ (first expn)))))(def interpret-plus (fn [expn env] (+ (interpret (second expn) env) (interpret (third expn) env))));; -- define subtraction(def is-minus? (fn [expn] (and (list? expn) (= 3 (count expn)) (= '- (first expn)))))(def interpret-minus (fn [expn env] (- (interpret (second expn) env) (interpret (third expn) env))));; -- define multiplication(def is-times? (fn [expn] (and (list? expn) (= 3 (count expn)) (= '* (first expn)))))(def interpret-times (fn [expn env] (* (interpret (second expn) env) (interpret (third expn) env))));; -- define division(def is-divides? (fn [expn] (and (list? expn) (= 3 (count expn)) (= '/ (first expn)))))(def interpret-divides (fn [expn env] (/ (interpret (second expn) env) (interpret (third expn) env))));; -- define equals test(def is-equals? (fn [expn] (and (list? expn) (= 3 (count expn)) (= '= (first expn)))))(def interpret-equals (fn [expn env] (= (interpret (second expn) env) (interpret (third expn) env))));; -- define greater-than test(def is-greater-than? (fn [expn] (and (list? expn) (= 3 (count expn)) (= '> (first expn)))))(def interpret-greater-than (fn [expn env] (> (interpret (second expn) env) (interpret (third expn) env))));; -- define not(def is-not? (fn [expn] (and (list? expn) (= 2 (count expn)) (= 'not (first expn)))))(def interpret-not (fn [expn env] (not (interpret (second expn) env))));; -- define or(def is-or? (fn [expn] (and (list? expn) (= 3 (count expn)) (= 'or (first expn)))))(def interpret-or (fn [expn env] (or (interpret (second expn) env) (interpret (third expn) env))));; -- define and(def is-and? (fn [expn] (and (list? expn) (= 3 (count expn)) (= 'and (first expn)))))(def interpret-and (fn [expn env] (and (interpret (second expn) env) (interpret (third expn) env))));; -- define with(def is-with? (fn [expn] (and (list? expn) (= 3 (count expn)) (= 'with (first expn)))))(def interpret-with (fn [expn env] (interpret (third expn) (add-var env (first (second expn)) (interpret (second (second expn)) env)))));; -- define if(def is-if? (fn [expn] (and (list? expn) (= 4 (count expn)) (= 'if (first expn)))))(def interpret-if (fn [expn env] (cond (interpret (second expn) env) (interpret (third expn) env) :else (interpret (fourth expn) env))));; -- define function-application(def is-function-application? (fn [expn env] (and (list? expn) (= 2 (count expn)) (is-function? (interpret (first expn) env)))))(def interpret-function-application (fn [expn env] (let [function (interpret (first expn) env)] (interpret (third function) (add-var env (first (second function)) (interpret (second expn) env))))));;口译员本身(def interpret (fn [expn env] (cond do-trace (println "Interpret is processing: " expn)) (cond ; basic values (is-number? expn) (interpret-number expn env) (is-symbol? expn) (interpret-symbol expn env) (is-boolean? expn) (interpret-boolean expn env) (is-function? expn) (interpret-function expn env) ; built-in functions (is-plus? expn) (interpret-plus expn env) (is-minus? expn) (interpret-minus expn env) (is-times? expn) (interpret-times expn env) (is-divides? expn) (interpret-divides expn env) (is-equals? expn) (interpret-equals expn env) (is-greater-than? expn) (interpret-greater-than expn env) (is-not? expn) (interpret-not expn env) (is-or? expn) (interpret-or expn env) (is-and? expn) (interpret-and expn env) ; special syntax (is-with? expn) (interpret-with expn env) (is-if? expn) (interpret-if expn env) ; functions (is-function-application? expn env) (interpret-function-application expn env) :else 'error))) 最佳答案 我不确定您的解释语言的语法是什么,但是看起来您已经实现了lambda,这是获取大量语法糖的真正所需。您可以使用for实现类似lambda循环的功能。您真正需要做的就是添加一个for-handler函数,该函数可以解析如下表达式:(for (i 0 (< 1 10)) (print i))变成:((lambda () (define (loop i n) (if (or (< i n) (= i n)) (begin (print i) (loop (+ 1 i) n)))) (loop 1 10)))然后将此新表达式再次传递给interpret。上面的代码是从我的解决方案到SICP Exercise 4.9我没有花太多时间试图弄清楚您的解释器是否支持这种内部定义,但是您似乎拥有with,它可以允许您执行以下操作: (with (loop (lambda (i n) (if (or (< i n) (= i n)) (begin (print i) (loop (+ 1 i) n)))) (loop 1 10))本质上,您需要在递归函数的应用程序中扩展for表达式。上面的代码定义了一个名为loop的函数,并立即调用它。外部lambda强制整个表达式立即运行。如果您想了解更多详细信息,请参阅优秀的Structure and Interpretation of Computer Programs中有关构建元循环解释器的一章,并讨论实现内部定义,以及讨论它们所谓的“派生表达式”,基本上就是像。祝好运!关于java - Clojure解释器中的Java样式FOR循环?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4629464/
10-10 11:19