Fix bug when using print() in Shell, add tag to Shell window title indicating selected language

This commit is contained in:
Skylar 2015-06-02 13:16:40 -06:00
parent 8a5cdb94d1
commit ceaa9be060
2 changed files with 849 additions and 840 deletions

View File

@ -1,303 +1,304 @@
/* /*
* CODE LICENSE ===================== * CODE LICENSE =====================
* Copyright (c) 2015, Apocalypse Laboratories * Copyright (c) 2015, Apocalypse Laboratories
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met: * are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or * this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution. * other materials provided with the distribution.
* *
* 3. Neither the name of the copyright holder nor the names of its contributors * 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without * may be used to endorse or promote products derived from this software without
* specific prior written permission. * specific prior written permission.
* *
* 4. You adhere to the Media License detailed below. If you do not, this license * 4. You adhere to the Media License detailed below. If you do not, this license
* is automatically revoked and you must purge all copies of the software you * is automatically revoked and you must purge all copies of the software you
* possess, in source or binary form. * possess, in source or binary form.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* MEDIA LICENSE ==================== * MEDIA LICENSE ====================
* All images and other graphical files (the "graphics") included with this * All images and other graphical files (the "graphics") included with this
* software are copyright (c) 2015 Apocalypse Laboratories. You may not distribute * software are copyright (c) 2015 Apocalypse Laboratories. You may not distribute
* the graphics or any program, source code repository, or other digital storage * the graphics or any program, source code repository, or other digital storage
* media containing them without written permission from Apocalypse Laboratories. * media containing them without written permission from Apocalypse Laboratories.
* This ban on distribution only applies to publicly available systems. * This ban on distribution only applies to publicly available systems.
* A password-protected network file share, USB drive, or other storage scheme that * A password-protected network file share, USB drive, or other storage scheme that
* cannot be easily accessed by the public is generally allowed. If in doubt, * cannot be easily accessed by the public is generally allowed. If in doubt,
* contact Apocalypse Laboratories. If Apocalypse Laboratories allows or denies * contact Apocalypse Laboratories. If Apocalypse Laboratories allows or denies
* you permission, that decision is considered final and binding. * you permission, that decision is considered final and binding.
*/ */
package net.apocalypselabs.symat; package net.apocalypselabs.symat;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.List; import java.util.List;
import javax.script.ScriptEngine; import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager; import javax.script.ScriptEngineManager;
import javax.script.ScriptException; import javax.script.ScriptException;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
/** /**
* *
* @author Skylar * @author Skylar
*/ */
public class CodeRunner { public class CodeRunner {
private ScriptEngine se; private ScriptEngine se;
private StringWriter sw = new StringWriter(); private StringWriter sw = new StringWriter();
private PrintWriter pw = new PrintWriter(sw); private PrintWriter pw = new PrintWriter(sw);
private String modules = ""; private String modules = "";
private String moduleterm = ""; private String moduleterm = "";
// If we need to wrap code around input to make everything nice. // If we need to wrap code around input to make everything nice.
private boolean wrapRequired = false; private boolean wrapRequired = false;
// What codez are we speaking? // What codez are we speaking?
private String scriptLang = ""; private String scriptLang = "";
public CodeRunner() { public CodeRunner() {
this("javascript"); this("javascript");
} }
public CodeRunner(int lang) { public CodeRunner(int lang) {
this(lang == 0 ? "js" : "py"); this(lang == 0 ? "js" : "py");
} }
public CodeRunner(String lang) { public CodeRunner(String lang) {
scriptLang = lang; scriptLang = lang;
switch (lang) { switch (lang) {
case "javascript": case "javascript":
case "js": case "js":
case "rhino": case "rhino":
scriptLang = "javascript"; scriptLang = "javascript";
se = new ScriptEngineManager().getEngineByName("rhino"); se = new ScriptEngineManager().getEngineByName("rhino");
wrapRequired = true; wrapRequired = true;
try { try {
// Add custom functions. // Add custom functions.
se.eval("importClass(net.apocalypselabs.symat.Functions);" se.eval("importClass(net.apocalypselabs.symat.Functions);"
+ "SyMAT_Functions = new net.apocalypselabs.symat.Functions();" + "SyMAT_Functions = new net.apocalypselabs.symat.Functions();"
+ "SyMAT_Functions.setLang('js');\n" + "SyMAT_Functions.setLang('js');\n"
+ getFunctions("js") + getFunctions("js")
+ loadToolkits()); + loadToolkits());
// Allow engine access from scripts. // Allow engine access from scripts.
se.put("engine", se); se.put("engine", se);
attachWriters(); attachWriters();
} catch (Exception ex) { } catch (Exception ex) {
initError(ex); initError(ex);
} }
break; break;
case "python": case "python":
case "jython": case "jython":
case "py": case "py":
scriptLang = "python"; scriptLang = "python";
se = new ScriptEngineManager().getEngineByName("python"); se = new ScriptEngineManager().getEngineByName("python");
try { try {
se.eval("from math import *\n" se.eval("from math import *\n"
+ "from net.apocalypselabs.symat import Functions\n" + "from net.apocalypselabs.symat import Functions\n"
+ "_=Functions()\n" + "_=Functions()\n"
+ "_.setLang('py')\n\n" + "_.setLang('py')\n\n"
+ getFunctions("py") + getFunctions("py")
+ loadToolkits()); + loadToolkits());
// Allow engine access from scripts. // Allow engine access from scripts.
se.put("engine", se); se.put("engine", se);
attachWriters(); attachWriters();
} catch (Exception ex) { } catch (Exception ex) {
initError(ex); initError(ex);
} }
break; break;
default: default:
throw new UnsupportedOperationException("Script language " + lang + " not supported."); throw new UnsupportedOperationException("Script language " + lang + " not supported.");
} }
} }
public static List<InputStream> loadResources(final String name, public static List<InputStream> loadResources(final String name,
final ClassLoader classLoader) throws IOException { final ClassLoader classLoader) throws IOException {
final List<InputStream> list = new ArrayList<InputStream>(); final List<InputStream> list = new ArrayList<InputStream>();
final Enumeration<URL> systemResources final Enumeration<URL> systemResources
= (classLoader == null ? ClassLoader.getSystemClassLoader() : classLoader) = (classLoader == null ? ClassLoader.getSystemClassLoader() : classLoader)
.getResources(name); .getResources(name);
while (systemResources.hasMoreElements()) { while (systemResources.hasMoreElements()) {
list.add(systemResources.nextElement().openStream()); list.add(systemResources.nextElement().openStream());
} }
return list; return list;
} }
private String loadToolkits() { private String loadToolkits() {
String out = ""; String out = "";
try { try {
List<InputStream> il = loadResources("meta.txt", null); List<InputStream> il = loadResources("meta.txt", null);
InputStream[] ii = new InputStream[il.size()]; InputStream[] ii = new InputStream[il.size()];
for (InputStream i : il.toArray(ii)) { for (InputStream i : il.toArray(ii)) {
BufferedReader br = new BufferedReader(new InputStreamReader(i)); BufferedReader br = new BufferedReader(new InputStreamReader(i));
while (br.ready()) { while (br.ready()) {
String l = br.readLine(); String l = br.readLine();
if (l.contains("=")) { if (l.contains("=")) {
String classname = l.split("=")[0]; String classname = l.split("=")[0];
String varname = l.split("=")[1]; String varname = l.split("=")[1];
if (scriptLang.equals("javascript")) { if (scriptLang.equals("javascript")) {
out += "importClass(" + classname + ");" out += "importClass(" + classname + ");"
+ varname + " = new " + classname + "();"; + varname + " = new " + classname + "();";
} else { } else {
out += "from " out += "from "
+ classname.substring(0, classname.lastIndexOf(".")) + classname.substring(0, classname.lastIndexOf("."))
+ " import " + classname.substring(classname.lastIndexOf(".") + 1) + "\n" + " import " + classname.substring(classname.lastIndexOf(".") + 1) + "\n"
+ varname + " = " + classname.substring(classname.lastIndexOf(".") + 1) + "()\n"; + varname + " = " + classname.substring(classname.lastIndexOf(".") + 1) + "()\n";
} }
} }
} }
} }
} catch (Exception ex) { } catch (Exception ex) {
} }
Debug.println(out); Debug.println(out);
return out; return out;
} }
@Deprecated @Deprecated
public CodeRunner(String lang, boolean shell) { public CodeRunner(String lang, boolean shell) {
this(lang); this(lang);
} }
private void attachWriters() { private void attachWriters() {
se.getContext().setWriter(pw); se.getContext().setWriter(pw);
se.getContext().setErrorWriter(pw); se.getContext().setErrorWriter(pw);
Debug.println("Attached writers."); Debug.println("Attached writers.");
} }
/** /**
* Inits the Python engine on application start. * Inits the Python engine on application start.
* *
* @param fakeInit Set it to true. * @param fakeInit Set it to true.
*/ */
public CodeRunner(boolean fakeInit) { public CodeRunner(boolean fakeInit) {
if (fakeInit) { if (fakeInit) {
se = new ScriptEngineManager().getEngineByName("python"); se = new ScriptEngineManager().getEngineByName("python");
} }
} }
public StringWriter getStringWriter() { public StringWriter getStringWriter() {
return sw; return sw;
} }
public PrintWriter getPrintWriter() { public PrintWriter getPrintWriter() {
return pw; return pw;
} }
public String getBufferDump() { public String getBufferDump() {
String dump = sw.toString(); String dump = sw.toString();
sw.getBuffer().setLength(0); sw.getBuffer().setLength(0);
return dump; return dump;
} }
private void initError(Exception ex) { private void initError(Exception ex) {
JOptionPane.showMessageDialog(null, "Error: " JOptionPane.showMessageDialog(null, "Error: "
+ "Could not properly initialize " + scriptLang + " scripting engine." + "Could not properly initialize " + scriptLang + " scripting engine."
+ "\n\nSome functions may not work.\n\n" + "\n\nSome functions may not work.\n\n"
+ "(" + ex.getMessage() + ")"); + "(" + ex.getMessage() + ")");
} }
/** /**
* Parse a String of code. * Parse a String of code.
* *
* @param eval A String of code to evaluate. * @param eval A String of code to evaluate.
* @return the result. * @return the result.
*/ */
public Object evalString(String eval) { public Object evalString(String eval) {
try { try {
Object res = se.eval(wrapMath(eval)); Object res = se.eval(wrapMath(eval));
if (res == null) { if (res == null) {
res = ""; res = "";
} }
String result = res + sw.getBuffer().toString().trim(); String result = res + sw.getBuffer().toString().trim();
return result; sw.getBuffer().setLength(0);
} catch (ScriptException ex) { return result;
return formatEx(ex); } catch (ScriptException ex) {
} return formatEx(ex);
} }
}
/**
* Parse code and use the default output writers. /**
* * Parse code and use the default output writers.
* @param eval A String of code to evaluate. *
*/ * @param eval A String of code to evaluate.
public void evalCode(String eval) { */
try { public void evalCode(String eval) {
Object res = se.eval(wrapMath(eval)); try {
if (res == null) { Object res = se.eval(wrapMath(eval));
res = ""; if (res == null) {
} res = "";
} catch (ScriptException ex) { }
sw.append(formatEx(ex)); } catch (ScriptException ex) {
} sw.append(formatEx(ex));
} }
}
private String formatEx(ScriptException ex) {
String err = ex.getMessage(); private String formatEx(ScriptException ex) {
//err = err.replace("sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: ", ""); String err = ex.getMessage();
//err = err.replace("<Unknown source>", "file"); //err = err.replace("sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: ", "");
//err = err.replace("sun.org.mozilla.javascript.internal.EvaluatorException: ", ""); //err = err.replace("<Unknown source>", "file");
return "Error: " + err; //err = err.replace("sun.org.mozilla.javascript.internal.EvaluatorException: ", "");
} return "Error: " + err;
}
/**
* Allows use of Math.blah() as just blah(). Also gives access to SyMAT Java /**
* functions. * Allows use of Math.blah() as just blah(). Also gives access to SyMAT Java
* * functions.
* @param eval input string *
* @return wrapped input * @param eval input string
*/ * @return wrapped input
private String wrapMath(String eval) { */
if (wrapRequired) { private String wrapMath(String eval) {
String with = "with(SyMAT_Functions){with(Math){" + eval + "}}"; if (wrapRequired) {
Debug.println(with); String with = "with(SyMAT_Functions){with(Math){" + eval + "}}";
return with; Debug.println(with);
} return with;
return eval; }
} return eval;
}
public void setVar(String var, Object val) {
se.put(var, val); public void setVar(String var, Object val) {
} se.put(var, val);
}
public Object getVar(String var) {
return se.get(var); public Object getVar(String var) {
} return se.get(var);
}
private String getFunctions(String lang) {
String text = ""; private String getFunctions(String lang) {
try { String text = "";
BufferedReader reader = new BufferedReader( try {
new InputStreamReader( BufferedReader reader = new BufferedReader(
CodeRunner.class new InputStreamReader(
.getResourceAsStream("functions." + lang))); CodeRunner.class
String line; .getResourceAsStream("functions." + lang)));
while ((line = reader.readLine()) != null) { String line;
text += line + "\n"; while ((line = reader.readLine()) != null) {
} text += line + "\n";
} catch (Exception e) { }
} } catch (Exception e) {
return text; }
} return text;
} }
}

File diff suppressed because it is too large Load Diff