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