Compile ClojureScript in Java application - clojurescript

I'm trying to compile String that contains Clojure Script code in Java/Groovy. I'm not really happy with using "java -jar ...".execute().
Is there any way to invoke clojurescript library (version 1.8.51) to compile code?
Edit:
So combining these two links I got this code (Groovy):
IFn require = Clojure.var("clojure.core", "require");
require.invoke(Clojure.read("cljs.analyzer.api"))
require.invoke(Clojure.read("cljs.compiler.api"))
IFn emptyEnv = Clojure.var("cljs.analyzer.api", "empty-env")
IFn analyze = Clojure.var("cljs.analyzer.api", "analyze")
IFn emit = Clojure.var("cljs.compiler", "emit-str")
final inputText = "(defn plus [a b] (+ a b))"
emit.invoke(
analyze.invoke(emptyEnv.invoke(), "'$inputText"
)
)
My problem is that emit function return empty string :/. Is there anything I'm doing wrong?
Edit2: The analyze method return this:
{
:op :constant,
:env {:ns {:name cljs.user},
:context :statement,
:locals {},
:fn-scope [],
:js-globals ...removed...,
:form #object[org.codehaus.groovy.runtime.GStringImpl 0x37816ea6 "'(defn plus [a b] (+ a b))"],
:tag any
}

It should be very easy to call ClojureScript Compiler API from Clojure, for example as presented in answers to a similar question on how to do it from Clojure.
But as you want to do it from Java or Groovy, you will have to use some Clojure Java API for calling Clojure from Java.

Related

Chisel: How the "read" function (or macro) is implemented for the SyncReadMem class?

Can anyone help me to understand how "read" macro is implemented? I have the feeling that "do_read" function below is actually called, but could not figure out how that is done. I'm intrigued by the "SourceInfoTransform" class. Can anyone give me a hint on its usage?
The "SyncReadMem" implementation is listed below.
Thanks in advance for any help!
Best regards,
-Fei
sealed class SyncReadMem[T <: Data] private (t: T, n: BigInt, val readUnderWrite: SyncReadMem.ReadUnderWrite) extends MemBase[T](t, n) {
def read(x: UInt, en: Bool): T = macro SourceInfoTransform.xEnArg
/** #group SourceInfoTransformMacro */
def do_read(addr: UInt, enable: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
val a = Wire(UInt())
a := DontCare
var port: Option[T] = None
when (enable) {
a := addr
port = Some(read(a))
}
port.get
}
}
The SourceInfoTransform is a scala macro that transforms the def read into the def do_read. The code for the macro is in src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala of github.com/chipsalliance/chisel3. In that file there are a lot of transform classes for handling different chisel constructs with different numbers of arguments. The main use of the SourceInfoTransform is to get the line number of the Chisel/Scala source so it can be reported in Exceptions and in generated Firrtl and Verilog. Here is an article on macros, there are many more available.
Good luck.
Chick's answer is mostly correct--it's correct on the "how" and where to look, but slightly wrong on the "why":
The main use of the SourceInfoTransform is to get the line number of the Chisel/Scala source
This is not quite true, you can get source locators with merely having implicit sourceInfo: SourceInfo, and you could have that on the original def read if you wanted to. What the SourceInfoTransform macros do is resolve ambiguity when you want to do a bit extraction immediately following invoking the read method, eg.
myMem.read(addr, en)(16, 0)
If we had defined read with the implicits directly, the compiler would think you're trying to pass 16 and 0 as the implicit arguments, when in reality, you're trying to call .apply on the resulting T (if it's a subtype of Bits). The macro resolves the ambiguity so that the compiler knowns you're not trying to pass the implicits.
Here's a link to a talk where I describe this (warning while the little part about source locators and the macro are correct, much of this talk is out-of-date): https://youtu.be/2-ZiXNd9wbc?t=2756

Chisel3 REPL Vec assignment into module only works after eval

If we run the following Chisel3 code
class Controller extends Module {
val io = IO(new Bundle {
})
val sff = Module(new SFF)
val frame: Vec[UInt] = Reg(Vec(ProcedureSpaceSize, Integer32Bit))
for(i <- 0 until ProcedureSpaceSize)
frame(i) := 99.U
sff.io.inputDataVector := frame
}
class SFF extends Module {
val io = IO(new Bundle {
val inputDataVector: Vec[UInt] = Input(Vec(ProcedureSpaceSize, Integer32Bit))
})
}
in REPL debug mode. First do
reset;step
peek sff.io_inputDataVector_0;peek sff.io_inputDataVector_1;peek sff.io_inputDataVector_2
The REPL returns
Error: exception Error: getValue(sff.io_inputDataVector_0) returns value not found
Error: exception Error: getValue(sff.io_inputDataVector_1) returns value not found
Error: exception Error: getValue(sff.io_inputDataVector_2) returns value not found
Then do
eval sff.io_inputDataVector_0
which will be a success, yielding
...
resolve dependencies
evaluate sff.io_inputDataVector_0 <= frame_0
evaluated sff.io_inputDataVector_0 <= 99.U<32>
Then perform the above peek again
peek sff.io_inputDataVector_0;peek sff.io_inputDataVector_1;peek sff.io_inputDataVector_2;
This time, it returns
peek sff.io_inputDataVector_0 99
peek sff.io_inputDataVector_1 99
peek sff.io_inputDataVector_2 99
which is more expected.
Why does the REPL act in this way? Or was there something I missed? Thanks!
*chisel-iotesters is in version 1.4.2, and chiseltest is in version 0.2.2. Both should be the newest version.
The firrtl interpreter REPL does not necessarily compute or store values that on a branch of a mux that is not used. This can lead to problems noted above like
Error: exception Error: getValue(sff.io_inputDataVector_0) returns value not found.
eval can be used to force unused branches to be evaluated anyway. The REPL is an experimental feature that has not had a lot of use.
treadle is the more modern chisel scala-based simulator. It is better supported and faster than the interpreter. It has a REPL of its own, but does not have an executeFirrtlRepl equivalent.
It must be run from the command line via the ./treadle.sh script in the root directory. One can also run sbt assembly to create a much faster launching jar that is placed in utils/bin. This REPL also has not been used a lot but I am interested on feedback that will make it better and easier to use.
I think the problem that you are seeing is that all your wires are being eliminated due to dead code elimination. There are a couple of things you should try to fix this.
Make sure you have meaningful connections of your wires. Hardware that does not ultimately affect an output is likely to get eliminated. In your example you do not have anything driving a top level output
You probably need your circuit to compute something with those registers. If the registers are initialized to 99 then constant propagation will likely eliminate them. I'm not sure what you are trying to get the circuit to do so it is hard to make a specific recommendation.
If you get the above done I think the repl will work as expected. I do have a question about which repl you are using (there are two: firrtl-interpreter and treadle) I recommend using the latter. It is more modern and better supported. It also has two commands that would be useful
show lofirrtl will show you the lowered firrtl, this is how you can see that lots of stuff from the high firrtl emitted by chisel3 has been changed.
symbol . shows you all symbols in circuit (. is a regex that matches everything.
Here is a somewhat random edit of your circuit that drives and output based on your frame Vec. This circuit will generate firrtl that will not eliminated the wires you are trying to see.
class Controller extends Module {
val io = IO(new Bundle {
val out = Output(UInt(32.W))
})
val sff = Module(new SFF)
val frame: Vec[UInt] = Reg(Vec(ProcedureSpaceSize, Integer32Bit))
when(reset.asBool()) {
for (i <- 0 until ProcedureSpaceSize) {
frame(i) := 99.U
}
}
frame.zipWithIndex.foreach { case (element, index) => element := element + index.U }
sff.io.inputDataVector := frame
io.out := sff.io.outputDataVector.reduce(_ + _)
}
class SFF extends Module {
val io = IO(new Bundle {
val inputDataVector: Vec[UInt] = Input(Vec(ProcedureSpaceSize, Integer32Bit))
val outputDataVector: Vec[UInt] = Output(Vec(ProcedureSpaceSize, Integer32Bit))
})
io.outputDataVector <> io.inputDataVector
}

Q: Does functionality exist to invoke some promise over an array of arguments and "all"-ify it without boilerplate for-each code?

I was struggling to describe this succintly in the title so I'll paste in my typescript code that achieves what I'm talking about -
aggregate<T, A>(args: A[], invokable: (arg: A) => promise<T>): promise<T[]> {
let allPromises = new Array<promise<T>>();
for (let arg of args) {
allPromises.push(invokable(arg));
}
return promise.all(allPromises);
}
This takes a list of arguments of type A and for each of them invokes some function (which returns a promise which returns type T). Each of these promises are collected into a list which is then all-ified and returned.
My question is, does this function already exist in Bluebird as I'd rather do things properly and use that existing, tested functionality! I had problems getting my head around some of the documentation so I might not have grokked something I should have!
Your problem is perfectly solvable with Array.prototype.map.
Your code can be turned into:
aggregate<T, A>(args: A[], invokable: (arg: A) => promise<T>): promise<T[]> {
return promise.all(args.map(invocable));
}

debugging functions in the clojurescript repl

Does anybody know a good way to debug functions in the clojureScript REPL?
The default, behavior is that the generated JS code of the function is printed.
midi.lib=> (defn f [] (println "hello"))
#'midi.lib/f
midi.lib=> f
#object[midi$lib$f "function midi$lib$f(){
return cljs.core.println.call(null,"hello");
}"]
With longer functions this gets annoying. For many debugging cases, simply the name of the function would be sufficient..
There is currently no support for controlling how function values print in ClojureScript.
But, if you are OK with extending the JavaScript function type, you can evaluate the following in a REPL
(extend-type js/Function
IPrintWithWriter
(-pr-writer [obj writer _]
(let [name (.-name obj)
name (if (empty? name)
"Function"
name)]
(write-all writer "#object[" name "]"))))
and then your example function value would print as #object[midi$lib$f].
Try using the Figwheel REPL, it doesn't print out the generated JS, and behaves similarly to a Clojure REPL.

How to load-string to current namespace (not core)?

I can load arbitrary Clojure source using:
(load-string source)
However, if namespace wasn't provided, it loads code to clojure.core namespace.
For example, following code:
(load-string "(defn add [a b] (+ a b))")
defines a function:
#'clojure.core/add
Now, is there a way to load that code to some other namespace, preferably the same one in which load-string function is called?
(Other than prepending a namespace declaration to source string before evaluation. I know that it would solve the problem - I'd like to know is there a preferred way)
when def needs to decide what namspace a new function should go in it looks at the the current value of the ns var and adds the new function to that namespace. because ns is a var you can dynamically bind it before you call load-string
user> (binding [*ns* (find-ns 'foo)] (load-string "(defn f [] 4)"))
#'foo/f
user> (foo/f)
4