Remove compiler dependence on mark()/reset()
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
package lua.addon.compile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.util.Hashtable;
|
||||
|
||||
@@ -8,19 +11,41 @@ import lua.value.LString;
|
||||
|
||||
public class Compiler {
|
||||
|
||||
public int nCcalls;
|
||||
private static final byte LUAC_BINARY_SIG = '\033';
|
||||
|
||||
public static Proto compile( Reader reader, String name ) {
|
||||
/** Try to compile into prototype.
|
||||
* If the supplied stream is a binary file (i.e. lua chunk)
|
||||
* then consume one byte from the input stream, and return null.
|
||||
*
|
||||
* Otherwise, try to compile the file, and return the Prototype
|
||||
* on success, or throw RuntimeException on syntax error or I/O Exception
|
||||
*
|
||||
* @param stream InputStream to read from.
|
||||
* @param name Name of the chunk
|
||||
* @return null if the first byte indicates it is a binary chunk,
|
||||
* a Proto instance if it can be compiled,
|
||||
* or an exception is thrown if there is an error.
|
||||
* @throws IOException if an I/O exception occurs
|
||||
* @throws RuntimeException if there is a syntax error.
|
||||
*/
|
||||
public static Proto compile(InputStream stream, String name) throws IOException {
|
||||
|
||||
int c = stream.read();
|
||||
if ( c == LUAC_BINARY_SIG )
|
||||
return null;
|
||||
// TODO: handle UTF-8 here!
|
||||
InputStreamReader isr = new InputStreamReader(stream);
|
||||
Compiler compiler = new Compiler();
|
||||
return compiler.luaY_parser(reader, name);
|
||||
return compiler.luaY_parser(c, isr, name);
|
||||
}
|
||||
|
||||
public int nCcalls;
|
||||
|
||||
Proto luaY_parser(Reader z, String name) {
|
||||
Proto luaY_parser(int firstByte, Reader z, String name) {
|
||||
LexState lexstate = new LexState(this, z);
|
||||
FuncState funcstate = new FuncState();
|
||||
// lexstate.buff = buff;
|
||||
lexstate.setinput( this, z, new LString(name) );
|
||||
lexstate.setinput( this, firstByte, z, new LString(name) );
|
||||
lexstate.open_func(funcstate);
|
||||
/* main func. is always vararg */
|
||||
funcstate.varargflags = LuaC.VARARG_ISVARARG;
|
||||
@@ -63,4 +88,5 @@ public class Compiler {
|
||||
public LString newlstr(char[] chars, int offset, int len) {
|
||||
return newTString( new String(chars,offset,len) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -252,7 +252,7 @@ public class LexState extends LuaC {
|
||||
syntaxerror("chunk has too many lines");
|
||||
}
|
||||
|
||||
void setinput( Compiler L, Reader z, LString source ) {
|
||||
void setinput( Compiler L, int firstByte, Reader z, LString source ) {
|
||||
this.decpoint = '.';
|
||||
this.L = L;
|
||||
this.lookahead.token = TK_EOS; /* no look-ahead token */
|
||||
@@ -262,7 +262,7 @@ public class LexState extends LuaC {
|
||||
this.lastline = 1;
|
||||
this.source = source;
|
||||
this.nbuff = 0; /* initialize buffer */
|
||||
this.nextChar(); /* read first char */
|
||||
this.current = firstByte; /* read first char */
|
||||
this.skipShebang();
|
||||
}
|
||||
|
||||
|
||||
@@ -468,7 +468,7 @@ public class LuaCompat extends LFunction {
|
||||
|
||||
|
||||
// return true if loaded, false if error put onto stack
|
||||
private static boolean loadfile( VM vm, String fileName ) {
|
||||
public static boolean loadfile( VM vm, String fileName ) {
|
||||
InputStream is;
|
||||
|
||||
String script;
|
||||
|
||||
@@ -239,16 +239,12 @@ public class LoadState {
|
||||
public static Proto undump( VM L, InputStream stream, String name ) throws IOException {
|
||||
|
||||
// is this a source file?
|
||||
stream.mark(1);
|
||||
if ( stream.read() != LUAC_HEADER_SIGNATURE[0] ) {
|
||||
stream.reset();
|
||||
// TODO: handle UTF-8 here!
|
||||
return lua.addon.compile.Compiler.compile(
|
||||
new InputStreamReader(stream),
|
||||
name );
|
||||
}
|
||||
Proto p = lua.addon.compile.Compiler.compile(stream, name);
|
||||
if ( p != null )
|
||||
return p;
|
||||
|
||||
// check signature
|
||||
// check rest of signature
|
||||
// (one byte was consumed by compiler check)
|
||||
for ( int i=1; i<4; i++ ) {
|
||||
if ( stream.read() != LUAC_HEADER_SIGNATURE[i] )
|
||||
throw new IllegalArgumentException("bad signature");
|
||||
|
||||
@@ -37,8 +37,7 @@ public class AbstractUnitTests extends TestCase {
|
||||
|
||||
// compile in memory
|
||||
InputStream is = new ByteArrayInputStream( lua );
|
||||
Reader r = new InputStreamReader( is );
|
||||
Proto p = Compiler.compile(r, dir+"/"+file);
|
||||
Proto p = Compiler.compile(is, dir+"/"+file);
|
||||
String actual = protoToString( p );
|
||||
|
||||
// load expected value from jar
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package lua.addon.compile;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import lua.Print;
|
||||
import lua.StackState;
|
||||
import lua.addon.compile.Compiler;
|
||||
import lua.io.Closure;
|
||||
import lua.io.Proto;
|
||||
import lua.value.LValue;
|
||||
@@ -14,16 +14,19 @@ import lua.value.LValue;
|
||||
public class SimpleTests extends TestCase {
|
||||
|
||||
private void doTest( String script ) {
|
||||
Reader r = new StringReader( script );
|
||||
Proto p = Compiler.compile( r, "script" );
|
||||
assertNotNull( p );
|
||||
Print.printCode( p );
|
||||
|
||||
// try running the code!
|
||||
StackState state = new StackState();
|
||||
Closure c = new Closure( state, p );
|
||||
state.doCall( c, new LValue[0] );
|
||||
try {
|
||||
InputStream is = new ByteArrayInputStream( script.getBytes("UTF8") );
|
||||
Proto p = Compiler.compile( is, "script" );
|
||||
assertNotNull( p );
|
||||
Print.printCode( p );
|
||||
|
||||
// try running the code!
|
||||
StackState state = new StackState();
|
||||
Closure c = new Closure( state, p );
|
||||
state.doCall( c, new LValue[0] );
|
||||
} catch ( Exception e ) {
|
||||
fail("i/o exception: "+e );
|
||||
}
|
||||
}
|
||||
|
||||
public void testTrivial() {
|
||||
|
||||
Reference in New Issue
Block a user