diff --git a/README.md b/README.md index 85508b21..fe1db890 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,18 @@ A little Clojure-like LISP in JavaScript. + + + ``` 3. Or install the binary with npm: diff --git a/doc/language-essentials.md b/doc/language-essentials.md index ece71c1d..5f34295f 100644 --- a/doc/language-essentials.md +++ b/doc/language-essentials.md @@ -656,8 +656,8 @@ approach and supports only one essential way of importing modules: [fs] [wisp.backend.javascript.writer :as writer] [wisp.sequence - :refer [first rest] - :rename {first car rest cdr}])) + :refer [first rest] + :rename {first car rest cdr}])) ``` Let's go through the above example to get a complete picture regarding @@ -674,20 +674,23 @@ and is completely optional. 3. The `(:require ...)` form defines dependencies that will be imported at runtime, and the example above imports multiple modules: - 1. First it imports the `start-host!` function from the - `interactivate.host` module. That will be loaded from the - `../host` location, since because module paths are resolved - relative to a name, but only if they share the same root. - 2. The second form imports `fs` module and makes it available under - the same name. Note that in this case it could have been - written without wrapping it in brackets. - 3. The third form imports `wisp.backend.javascript.writer` module - from `wisp/backend/javascript/writer` and makes it available - via the name `writer`. - 4. The last and most complex form imports `first` and `rest` - functions from the `wisp.sequence` module, although it also - renames them and there for makes available under different - `car` and `cdr` names. + 1. First it imports the `start-host!` function from the + `interactivate.host` module. That will be loaded from the + `../host` location, since because module paths are resolved + relative to a name, but only if they share the same root. + 2. The second form imports `fs` module and makes it available under + the same name. Note that in this case it could have been + written without wrapping it in brackets. + 3. The third form imports `wisp.backend.javascript.writer` module + from `wisp/backend/javascript/writer` and makes it available + via the name `writer`. + 4. The last and most complex form imports `first` and `rest` + functions from the `wisp.sequence` module, although it also + renames them and there for makes available under different + `car` and `cdr` names. + +It's also possible to specify a string literal instead of a module name; +this allows for providing custom require paths when you're having trouble with generated ones. While Clojure has many other kinds of reference forms they are not recognized by _wisp_ and will therefore be ignored. diff --git a/src/backend/escodegen/writer.wisp b/src/backend/escodegen/writer.wisp index 3076dd29..afdb9eab 100644 --- a/src/backend/escodegen/writer.wisp +++ b/src/backend/escodegen/writer.wisp @@ -711,30 +711,32 @@ (defn resolve [from to] - (let [requirer (split (name from) \.) - requirement (split (name to) \.) - relative? (and (not (identical? (name from) - (name to))) - (identical? (first requirer) - (first requirement)))] - (if relative? - (loop [from requirer - to requirement] - (if (identical? (first from) - (first to)) - (recur (rest from) (rest to)) - (join \/ - (concat [\.] - (repeat (dec (count from)) "..") - to)))) - (join \/ requirement)))) + (if (string? to) + to + (let [requirer (split (name from) \.) + requirement (split (name to) \.) + relative? (and (not (identical? (name from) + (name to))) + (identical? (first requirer) + (first requirement)))] + (if-not relative? + (join \/ requirement) + (loop [from requirer + to requirement] + (if (identical? (first from) + (first to)) + (recur (rest from) (rest to)) + (join \/ + (concat [\.] + (repeat (dec (count from)) "..") + to)))))))) (defn id->ns "Takes namespace identifier symbol and translates to new symbol without . special characters wisp.core -> wisp*core" [id] - (symbol nil (join \* (split (name id) \.)))) + (symbol nil (join \* (split (name id) #"[./]")))) (defn write-require diff --git a/test/ast.wisp b/test/ast.wisp index 59a57334..52a7bd19 100644 --- a/test/ast.wisp +++ b/test/ast.wisp @@ -1,5 +1,5 @@ (ns wisp.test.ast - (:require [wisp.test.util :refe [is thrown?]] + (:require [wisp.test.util :refer [is thrown?]] [wisp.src.reader :refer [read-from-string]] [wisp.src.sequence :refer [list]] [wisp.src.runtime :refer [str =]] diff --git a/test/escodegen.wisp b/test/escodegen.wisp index d017ef3b..04420aca 100644 --- a/test/escodegen.wisp +++ b/test/escodegen.wisp @@ -910,7 +910,7 @@ ;; ns -(is (= (transpile "(ns foo.bar +(is (= (transpile "(ns foo.bar.baz \"hello world\" (:require lib.a [lib.b] @@ -918,11 +918,14 @@ [lib.d :refer [foo bar]] [lib.e :refer [beep baz] :as e] [lib.f :refer [faz] :rename {faz saz}] - [lib.g :refer [beer] :rename {beer coffee} :as booze]))") + [lib.g :refer [beer] :rename {beer coffee} :as booze] + foo.bar.foo + foo.baz + [\"../test/bar\" :as test]))") "{ var _ns_ = { - id: 'foo.bar', + id: 'foo.bar.baz', doc: 'hello world' }; var lib_a = require('lib/a'); @@ -941,6 +944,10 @@ var lib_g = require('lib/g'); var booze = lib_g; var coffee = lib_g.beer; + var foo_bar_foo = require('./foo'); + var foo_baz = require('./../baz'); + var ___test_bar = require('../test/bar'); + var test = ___test_bar; }")) (is (= (transpile "(ns wisp.example.main diff --git a/test/util.wisp b/test/util.wisp index 78b81108..1830b513 100644 --- a/test/util.wisp +++ b/test/util.wisp @@ -42,8 +42,9 @@ (do (.push *failed* '~form) (console.error (str "Fail: " ~msg "\n" - "expected: " (pr-str '~form) "\n" + "expected: " + (pr-str '~expected) "\n" " actual: " (pr-str (try ~actual (catch error (list 'throw (list 'Error (.-message error)))))))) false)))))