Skip to content

Commit 3540861

Browse files
committed
1 parent f9aa3a0 commit 3540861

File tree

5 files changed

+464
-0
lines changed

5 files changed

+464
-0
lines changed

LICENSE.txt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
Copyright (c) 2008 - 2014, Board of Regents of the University of
2+
Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
3+
Institute of Molecular Cell Biology and Genetics.
4+
All rights reserved.
5+
6+
Redistribution and use in source and binary forms, with or without modification,
7+
are permitted provided that the following conditions are met:
8+
9+
1. Redistributions of source code must retain the above copyright notice, this
10+
list of conditions and the following disclaimer.
11+
12+
2. Redistributions in binary form must reproduce the above copyright notice,
13+
this list of conditions and the following disclaimer in the documentation
14+
and/or other materials provided with the distribution.
15+
16+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
POSSIBILITY OF SUCH DAMAGE.
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
/*
2+
* #%L
3+
* JSR-223-compliant Clojure scripting language plugin.
4+
* %%
5+
* Copyright (C) 2008 - 2014 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.plugins.scripting.clojure;
33+
34+
import clojure.lang.RT;
35+
import clojure.lang.Symbol;
36+
import clojure.lang.Var;
37+
38+
import java.util.Collection;
39+
import java.util.Map;
40+
import java.util.Set;
41+
42+
import javax.script.Bindings;
43+
44+
/**
45+
* A {@link Bindings} wrapper around Clojure's local variables.
46+
*
47+
* @author Johannes Schindelin
48+
*/
49+
public class ClojureBindings implements Bindings {
50+
51+
public ClojureBindings() {
52+
final Var nameSpace = RT.var("clojure.core", "*ns*");
53+
Var.pushThreadBindings(RT.map(nameSpace, nameSpace.get()));
54+
RT.var("clojure.core", "in-ns").invoke(Symbol.intern("user"));
55+
RT.var("clojure.core", "refer").invoke(Symbol.intern("clojure.core"));
56+
}
57+
58+
@Override
59+
public int size() {
60+
return Var.getThreadBindings().count();
61+
}
62+
63+
@Override
64+
public boolean isEmpty() {
65+
return size() == 0;
66+
}
67+
68+
@Override
69+
public boolean containsKey(final Object key) {
70+
return get(key) != null;
71+
}
72+
73+
@Override
74+
public boolean containsValue(final Object value) {
75+
throw new UnsupportedOperationException();
76+
}
77+
78+
@Override
79+
public Object get(final Object keyObject) {
80+
String key = (String) keyObject;
81+
final int dot = key.lastIndexOf('.');
82+
final String nameSpace;
83+
if (dot < 0) {
84+
nameSpace = "user";
85+
}
86+
else {
87+
nameSpace = key.substring(0, dot);
88+
key = key.substring(dot + 1);
89+
}
90+
try {
91+
return RT.var(nameSpace, key).get();
92+
}
93+
catch (final Error e) {
94+
return null;
95+
}
96+
}
97+
98+
private Object get(final String nameSpace, final String key) {
99+
return RT.var(nameSpace, key);
100+
}
101+
102+
@Override
103+
public Object put(final String name, final Object value) {
104+
final int dot = name.lastIndexOf('.');
105+
final String nameSpace, key;
106+
if (dot < 0) {
107+
nameSpace = "user";
108+
key = name;
109+
}
110+
else {
111+
nameSpace = name.substring(0, dot);
112+
key = name.substring(dot + 1);
113+
}
114+
final Object result = get(nameSpace, key);
115+
try {
116+
final Var var = RT.var(nameSpace, key, null);
117+
var.setDynamic();
118+
Var.pushThreadBindings(RT.map(var, value));
119+
}
120+
catch (final Error e) {
121+
// ignore
122+
}
123+
return result;
124+
}
125+
126+
@Override
127+
public Object remove(final Object key) {
128+
throw new UnsupportedOperationException();
129+
}
130+
131+
@Override
132+
public void putAll(final Map<? extends String, ? extends Object> toMerge) {
133+
for (final Entry<? extends String, ? extends Object> entry : toMerge
134+
.entrySet())
135+
{
136+
put(entry.getKey(), entry.getValue());
137+
}
138+
}
139+
140+
@Override
141+
public void clear() {
142+
throw new UnsupportedOperationException();
143+
}
144+
145+
@Override
146+
public Set<String> keySet() {
147+
throw new UnsupportedOperationException();
148+
}
149+
150+
@Override
151+
public Collection<Object> values() {
152+
throw new UnsupportedOperationException();
153+
}
154+
155+
@Override
156+
public Set<Entry<String, Object>> entrySet() {
157+
throw new UnsupportedOperationException();
158+
}
159+
160+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* #%L
3+
* JSR-223-compliant Clojure scripting language plugin.
4+
* %%
5+
* Copyright (C) 2008 - 2014 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.plugins.scripting.clojure;
33+
34+
import clojure.lang.Compiler;
35+
import clojure.lang.LispReader;
36+
37+
import java.io.PushbackReader;
38+
import java.io.Reader;
39+
import java.io.StringReader;
40+
import java.io.Writer;
41+
42+
import javax.script.ScriptContext;
43+
import javax.script.ScriptEngine;
44+
import javax.script.ScriptException;
45+
46+
import org.scijava.script.AbstractScriptEngine;
47+
48+
/**
49+
* A Clojure interpreter.
50+
*
51+
* @author Johannes Schindelin
52+
*/
53+
public class ClojureScriptEngine extends AbstractScriptEngine
54+
{
55+
public ClojureScriptEngine() {
56+
engineScopeBindings = new ClojureBindings();
57+
}
58+
59+
@Override
60+
public Object eval(final String script) throws ScriptException {
61+
try {
62+
return eval(new StringReader(script));
63+
}
64+
catch (final Exception e) {
65+
throw new ScriptException(e);
66+
}
67+
}
68+
69+
@Override
70+
public Object eval(final Reader reader) throws ScriptException {
71+
setup();
72+
try {
73+
final Object filename = get(ScriptEngine.FILENAME);
74+
if (filename != null) put("clojure.core.*file*", filename);
75+
final Thread thread = Thread.currentThread();
76+
Object finalResult = null;
77+
while (!thread.isInterrupted()) {
78+
final Object form = LispReader.read(new PushbackReader(reader), false, this, false);
79+
if (form == this) break;
80+
finalResult = Compiler.eval(form);
81+
}
82+
return finalResult;
83+
}
84+
catch (final Exception e) {
85+
throw new ScriptException(e);
86+
}
87+
}
88+
89+
protected void setup() {
90+
final ScriptContext context = getContext();
91+
final Reader reader = context.getReader();
92+
if (reader != null) {
93+
engineScopeBindings.put("clojure.core.*in*", reader);
94+
}
95+
final Writer writer = context.getWriter();
96+
if (writer != null) {
97+
engineScopeBindings.put("clojure.core.*out*", writer);
98+
}
99+
final Writer errorWriter = context.getErrorWriter();
100+
if (errorWriter != null) {
101+
engineScopeBindings.put("clojure.core.*err*", errorWriter);
102+
}
103+
}
104+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* #%L
3+
* JSR-223-compliant Clojure scripting language plugin.
4+
* %%
5+
* Copyright (C) 2008 - 2014 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.plugins.scripting.clojure;
33+
34+
import java.util.Arrays;
35+
import java.util.List;
36+
37+
import javax.script.ScriptEngine;
38+
39+
import org.scijava.plugin.Plugin;
40+
import org.scijava.script.AbstractScriptLanguage;
41+
import org.scijava.script.ScriptLanguage;
42+
43+
/**
44+
* An adapter of the Clojure interpreter to ImageJ's scripting interfaces.
45+
*
46+
* @author Johannes Schindelin
47+
* @see ScriptEngine
48+
*/
49+
@Plugin(type = ScriptLanguage.class)
50+
public class ClojureScriptLanguage extends AbstractScriptLanguage {
51+
52+
@Override
53+
public List<String> getExtensions() {
54+
return Arrays.asList("clj");
55+
}
56+
57+
@Override
58+
public ScriptEngine getScriptEngine() {
59+
return new ClojureScriptEngine();
60+
}
61+
62+
}

0 commit comments

Comments
 (0)