Я получаю следующую ошибку при попытке запустить мою программу: Exception in thread "main" java.io.FileNotFoundException: Could not locate apply/clojure/core/vector__init.class or apply/clojure/core/vector.clj on classpath:, compiling:(erbium/compile.clj:1:1)
. Кажется, он указывает на файл ниже и предполагает, что мне нужно добавить clojure.core/vector
в мои зависимости. Не включено ли оно по умолчанию?
(ns erbium.compile
(require '[clojure.string :as string])
)
(defn produce-out "Convert 'command %1 %2 %3' with stack [5 6 7] to 'command 5 6 7'" [word stack definitions]
(let [
code (definitions word) ; dictionary/hash lookup. eg. "println" -> "echo $1"
replacement (fn [match] (-> match second Long/parseLong dec stack str))
]
; evaluate arguments. eg. "echo %1"
; stack=["blah"]
; -> "echo blah"
(string/replace code #"%(\d)" replacement)
)
)
(defn parse-word "Verifies that word is in defintitions and then returns (produce-out word stack)" [word stack definitions]
(if (some #{word} (keys definitions))
(produce-out word stack)
)
)
(defn compile "Main compile function" [code]
(let [
split-code (string/split code #"\s")
definitions {
"println" "echo %1"
"+" "%1 + %2"
"-" "%1 - %2"
}
stack []
]
(for [word [split-code]]
(if (integer? (read-string word))
(do
(println "Found integer" word)
(def stack (conj stack (read-string word)))
(println "Adding to argument stack:" stack)
)
; else
(do
(parse-word word stack definitions)
(def stack [])
)
)
)
)
)
Этот файл загружается основным файлом через (load "compile")
если это имеет значение.
Чтобы расширить ответ, в объявлении пространства имен "ns" появляется запрос "require". ns
- фактически макрос, который расширяется до ряда операторов для создания пространства имен и выполняет некоторую настройку.
Этот макрос рассматривает заявления типа (:require...)
как вызовы функции с именем require
и автоматически цитирует любые следующие аргументы. Поскольку вы сами указали цитату:
(ns erbium.compile
(require '[clojure.string :as string]))
Затем результат заканчивается двойным кавычками, а вызов, require
завершения, составляет:
... (require (quote (quote [clojure.string :as string])))
Поэтому он пытается загрузить пространство имен, называемое "цитатой", за которым следует вектор, который был синтаксически не в том месте. :)
Макрос ns
- это стандартный и удобный способ настройки пространств имен, но мне потребовалось много времени, чтобы изучить его правильно. Я нашел, что лучший способ - скопировать код настройки других людей, пока я не научился делать это правильно.
Кстати, использование require
вместо :require
не имеет значения, хотя стандарт должен использовать :require
чтобы он не выглядел как прямой вызов этой функции.
первая ошибка, которую я вижу, такова:
(require '[clojure.string :as string])
Это должно быть так:
(:require [clojure.string :as string])
в обычном исходном файле clojure. Это исправило это для меня.
Тем не менее, здесь приводятся некоторые общие советы:
split-code (str/split code #"\s")
это не будет работать так, как вам нужно [clojure.string :as string]
Так что измените его на: split-code (string/split code #"\s")