I am getting the following error when I try to run my program: 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)
. It seems to be pointing to file below and suggests that I need to put clojure.core/vector
in my dependencies. Is it not included by default?
(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 [])
)
)
)
)
)
This file is loaded by the core file via (load "compile")
if that makes a difference.
the first error I see is this:
(require `[clojure.string :as string])
It should be like this:
(:require [clojure.string :as string])
in a regular clojure source file. This fixed it for me.
That said, here comes some general advices:
split-code (str/split code #"\\s")
this won't work as you required [clojure.string :as string]
So change it to: split-code (string/split code #"\\s")
To expand on the answer, the "require" appears in the namespace declaration "ns". ns
is actually a macro that expands to a series of statements to create the namespace, and do some setup.
This macro treats statements like (:require ...)
as calls to a function with the name require
, and automatically quotes any following arguments. Since you had specified a quote yourself:
(ns erbium.compile
(require '[clojure.string :as string]))
Then the result ends up being double-quoted, and the call to require
ends up being:
... (require (quote (quote [clojure.string :as string])))
So it ends up trying to load a namespace called "quote" followed by a vector that was syntactically in the wrong place. :)
The ns
macro is a standard and convenient way to set up namespaces, but it took me a long time to learn it properly. I found the best way was to copy other people's setup code until I learnt how to do it right.
Incidentally, the use of require
instead of :require
does not matter, though the standard is to use :require
so it does not look like a direct call to that function.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.