From: <nr...@us...> - 2009-07-22 21:15:46
|
Revision: 6559 http://jython.svn.sourceforge.net/jython/?rev=6559&view=rev Author: nriley Date: 2009-07-22 21:15:39 +0000 (Wed, 22 Jul 2009) Log Message: ----------- JSR 223: support for compile and eval with Readers. Modified Paths: -------------- branches/jsr223/src/org/python/core/ParserFacade.java branches/jsr223/src/org/python/jsr223/PyScriptEngine.java branches/jsr223/src/org/python/util/PythonInterpreter.java branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java Modified: branches/jsr223/src/org/python/core/ParserFacade.java =================================================================== --- branches/jsr223/src/org/python/core/ParserFacade.java 2009-07-22 02:18:24 UTC (rev 6558) +++ branches/jsr223/src/org/python/core/ParserFacade.java 2009-07-22 21:15:39 UTC (rev 6559) @@ -10,6 +10,7 @@ import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Reader; +import java.io.StringReader; import java.io.Writer; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; @@ -108,6 +109,34 @@ } /** + * Parse a string of Python source as either an expression (if possible) or module. + * + * Designed for use by a JSR 223 implementation: "the Scripting API does not distinguish + * between scripts which return values and those which do not, nor do they make the + * corresponding distinction between evaluating or executing objects." (SCR.4.2.1) + */ + public static mod parseExpressionOrModule(Reader reader, + String filename, + CompilerFlags cflags) { + ExpectedEncodingBufferedReader bufReader = null; + try { + bufReader = prepBufReader(reader, cflags, filename); + // first, try parsing as an expression + return parse(bufReader, CompileMode.eval, filename, cflags ); + } catch (Throwable t) { + try { + // then, try parsing as a module + bufReader.reset(); + return parse(bufReader, CompileMode.exec, filename, cflags); + } catch (Throwable tt) { + throw fixParseError(bufReader, tt, filename); + } + } finally { + close(bufReader); + } + } + + /** * Internal parser entry point. * * Users of this method should call fixParseError on any Throwable thrown @@ -130,6 +159,21 @@ } } + public static mod parse(Reader reader, + CompileMode kind, + String filename, + CompilerFlags cflags) { + ExpectedEncodingBufferedReader bufReader = null; + try { + bufReader = prepBufReader(reader, cflags, filename); + return parse(bufReader, kind, filename, cflags ); + } catch (Throwable t) { + throw fixParseError(bufReader, t, filename); + } finally { + close(bufReader); + } + } + public static mod parse(InputStream stream, CompileMode kind, String filename, @@ -223,6 +267,13 @@ } } + private static ExpectedEncodingBufferedReader prepBufReader(Reader reader, + CompilerFlags cflags, + String filename) + throws IOException { + return new ExpectedEncodingBufferedReader(new BufferedReader(reader), null); + } + private static ExpectedEncodingBufferedReader prepBufReader(InputStream input, CompilerFlags cflags, String filename, @@ -290,20 +341,10 @@ CompilerFlags cflags, String filename) throws IOException { - byte[] stringBytes; - if (cflags.source_is_utf8) { - // Passed unicode, re-encode the String to raw bytes - // NOTE: This could be more efficient if we duplicate - // prepBufReader/adjustForBOM/readEncoding to work on Readers, instead of - // encoding - ByteArrayOutputStream out = new ByteArrayOutputStream(); - Writer w = new OutputStreamWriter(out, "utf-8"); - w.write(string); - w.close(); - stringBytes = out.toByteArray(); - } else { - stringBytes = StringUtil.toBytes(string); - } + if (cflags.source_is_utf8) + return prepBufReader(new StringReader(string), cflags, filename); + + byte[] stringBytes = StringUtil.toBytes(string); return prepBufReader(new ByteArrayInputStream(stringBytes), cflags, filename, true, false); } Modified: branches/jsr223/src/org/python/jsr223/PyScriptEngine.java =================================================================== --- branches/jsr223/src/org/python/jsr223/PyScriptEngine.java 2009-07-22 02:18:24 UTC (rev 6558) +++ branches/jsr223/src/org/python/jsr223/PyScriptEngine.java 2009-07-22 21:15:39 UTC (rev 6559) @@ -35,10 +35,8 @@ } } - // it would be nice if we supported a Reader interface in Py.compileFlags, instead of having - // to create a string here public Object eval(Reader reader, ScriptContext context) throws ScriptException { - throw new UnsupportedOperationException("Not supported yet."); + return eval(compileScript(reader, context)); } public Bindings createBindings() { @@ -53,21 +51,33 @@ return new PyCompiledScript(compileScript(script, context)); } - public CompiledScript compile(Reader script) throws ScriptException { - throw new UnsupportedOperationException("Not supported yet."); + public CompiledScript compile(Reader reader) throws ScriptException { + return new PyCompiledScript(compileScript(reader, context)); } private PyCode compileScript(String script, ScriptContext context) throws ScriptException { try { String filename = (String) context.getAttribute(ScriptEngine.FILENAME); if (filename == null) - return interp.compileExpressionOrModule(script); + return interp.compile(script); else - return interp.compileExpressionOrModule(script, filename); + return interp.compile(script, filename); } catch (PyException e) { throw scriptException(e); } } + + private PyCode compileScript(Reader reader, ScriptContext context) throws ScriptException { + try { + String filename = (String) context.getAttribute(ScriptEngine.FILENAME); + if (filename == null) + return interp.compile(reader); + else + return interp.compile(reader, filename); + } catch (PyException e) { + throw scriptException(e); + } + } public Object invokeMethod(Object thiz, String name, Object... args) throws ScriptException, NoSuchMethodException { try { Modified: branches/jsr223/src/org/python/util/PythonInterpreter.java =================================================================== --- branches/jsr223/src/org/python/util/PythonInterpreter.java 2009-07-22 02:18:24 UTC (rev 6558) +++ branches/jsr223/src/org/python/util/PythonInterpreter.java 2009-07-22 21:15:39 UTC (rev 6559) @@ -1,5 +1,9 @@ package org.python.util; +import java.io.FilterReader; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; import java.util.Properties; import org.python.antlr.base.mod; @@ -184,23 +188,17 @@ * between scripts which return values and those which do not, nor do they make the * corresponding distinction between evaluating or executing objects." (SCR.4.2.1) */ - public PyCode compileExpressionOrModule(String script) { - return compileExpressionOrModule(script, "<script>"); + public PyCode compile(String script) { + return compile(script, "<script>"); } - - public PyCode compileExpressionOrModule(String script, String filename) { - mod node; - try { - // first, try parsing as an expression - node = ParserFacade.parse(script, CompileMode.eval, filename, cflags); - } catch (PySyntaxError e) { - try { - // then, try parsing as a module - node = ParserFacade.parse(script, CompileMode.exec, filename, cflags); - } catch (PySyntaxError ee) { - throw ee; - } - } + public PyCode compile(Reader reader) { + return compile(reader, "<script>"); + } + public PyCode compile(String script, String filename) { + return compile(new StringReader(script), filename); + } + public PyCode compile(Reader reader, String filename) { + mod node = ParserFacade.parseExpressionOrModule(reader, filename, cflags); return Py.compile_flags(node, filename, CompileMode.eval, cflags); } Modified: branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java =================================================================== --- branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java 2009-07-22 02:18:24 UTC (rev 6558) +++ branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java 2009-07-22 21:15:39 UTC (rev 6559) @@ -1,5 +1,6 @@ package org.python.jsr223; +import java.io.StringReader; import javax.script.Compilable; import javax.script.CompiledScript; import javax.script.ScriptContext; @@ -69,4 +70,20 @@ CompiledScript five = ((Compilable)pythonEngine).compile("5"); assertEquals(Integer.valueOf(5), five.eval()); } + + public void testEvalReader() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + + assertNull(pythonEngine.eval(new StringReader("x = 5"))); + assertEquals(Integer.valueOf(5), pythonEngine.eval(new StringReader("x"))); + } + + public void testCompileEvalReader() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + + CompiledScript five = ((Compilable)pythonEngine).compile(new StringReader("5")); + assertEquals(Integer.valueOf(5), five.eval()); + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |