changeset 654:ea7dbd2dfa65

compile TemplateStmt
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 05 Apr 2016 14:16:14 -0600
parents 538b0ae08faa
children e2be71451d04
files core/src/luan/impl/$Luan.java core/src/luan/impl/LuanImpl.java core/src/luan/impl/LuanParser.java
diffstat 3 files changed, 327 insertions(+), 296 deletions(-) [+]
line wrap: on
line diff
--- a/core/src/luan/impl/$Luan.java	Tue Apr 05 13:01:04 2016 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,230 +0,0 @@
-package luan.impl;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.ArrayList;
-import luan.Luan;
-import luan.LuanState;
-import luan.LuanTable;
-import luan.LuanFunction;
-import luan.LuanException;
-
-
-public final class $Luan {
-	private $Luan() {}  // never
-
-
-	private static List<Expressions> listExpressions = new ArrayList<Expressions>();
-
-	static int addExpressions(Expressions exp) {
-		int i = listExpressions.size();
-		listExpressions.add(exp);
-		return i;
-	}
-
-	public static Expressions getExpressions(int i) {
-		return listExpressions.get(i);
-	}
-
-
-	private static List<Stmt> listStmt = new ArrayList<Stmt>();
-
-	static int addStmt(Stmt stmt) {
-		int i = listStmt.size();
-		listStmt.add(stmt);
-		return i;
-	}
-
-	public static Stmt getStmt(int i) {
-		return listStmt.get(i);
-	}
-
-
-	private static List<Settable> listSettable = new ArrayList<Settable>();
-
-	static int addSettable(Settable settable) {
-		int i = listSettable.size();
-		listSettable.add(settable);
-		return i;
-	}
-
-	public static Settable getSettable(int i) {
-		return listSettable.get(i);
-	}
-
-
-	public static Object first(Object obj) {
-		return Luan.first(obj);
-	}
-
-	public static int len(LuanState luan,Object o) throws LuanException {
-		if( o instanceof String ) {
-			String s = (String)o;
-			return s.length();
-		}
-		if( o instanceof byte[] ) {
-			byte[] a = (byte[])o;
-			return a.length;
-		}
-		if( o instanceof LuanTable ) {
-			LuanTable t = (LuanTable)o;
-			return t.length(luan);
-		}
-		throw new LuanException( "attempt to get length of a " + Luan.type(o) + " value" );
-	}
-
-	public static Object unm(LuanState luan,Object o) throws LuanException {
-		if( o instanceof Number )
-			return -((Number)o).doubleValue();
-		if( o instanceof LuanTable ) {
-			LuanFunction fn = Luan.getHandlerFunction("__unm",(LuanTable)o);
-			if( fn != null ) {
-				return Luan.first(fn.call(luan,new Object[]{o}));
-			}
-		}
-		throw new LuanException("attempt to perform arithmetic on a "+Luan.type(o)+" value");
-	}
-
-	public static boolean checkBoolean(Object o) throws LuanException {
-		return Luan.checkBoolean(o);
-	}
-
-	public static LuanFunction checkFunction(Object o) throws LuanException {
-		return Luan.checkFunction(o);
-	}
-
-	public static boolean not(Object o) throws LuanException {
-		return !checkBoolean(o);
-	}
-
-	private static Object arithmetic(LuanState luan,String op,Object o1,Object o2) throws LuanException {
-		LuanFunction fn = Luan.getBinHandler(op,o1,o2);
-		if( fn != null )
-			return Luan.first(fn.call(luan,new Object[]{o1,o2}));
-		String type = !(o1 instanceof Number) ? Luan.type(o1) : Luan.type(o2);
-		throw new LuanException("attempt to perform arithmetic on a "+type+" value");
-	}
-
-	public static Object pow(LuanState luan,Object o1,Object o2) throws LuanException {
-		if( o1 instanceof Number && o2 instanceof Number )
-			return Math.pow( ((Number)o1).doubleValue(), ((Number)o2).doubleValue() );
-		return arithmetic(luan,"__pow",o1,o2);
-	}
-
-	public static Object mul(LuanState luan,Object o1,Object o2) throws LuanException {
-		if( o1 instanceof Number && o2 instanceof Number )
-			return ((Number)o1).doubleValue() * ((Number)o2).doubleValue();
-		return arithmetic(luan,"__mul",o1,o2);
-	}
-
-	public static Object div(LuanState luan,Object o1,Object o2) throws LuanException {
-		if( o1 instanceof Number && o2 instanceof Number )
-			return ((Number)o1).doubleValue() / ((Number)o2).doubleValue();
-		return arithmetic(luan,"__div",o1,o2);
-	}
-
-	public static Object mod(LuanState luan,Object o1,Object o2) throws LuanException {
-		if( o1 instanceof Number && o2 instanceof Number ) {
-			double d1 = ((Number)o1).doubleValue();
-			double d2 = ((Number)o2).doubleValue();
-			return d1 - Math.floor(d1/d2)*d2;
-		}
-		return arithmetic(luan,"__mod",o1,o2);
-	}
-
-	public static Object add(LuanState luan,Object o1,Object o2) throws LuanException {
-		if( o1 instanceof Number && o2 instanceof Number )
-			return ((Number)o1).doubleValue() + ((Number)o2).doubleValue();
-		return arithmetic(luan,"__add",o1,o2);
-	}
-
-	public static Object sub(LuanState luan,Object o1,Object o2) throws LuanException {
-		if( o1 instanceof Number && o2 instanceof Number )
-			return ((Number)o1).doubleValue() - ((Number)o2).doubleValue();
-		return arithmetic(luan,"__sub",o1,o2);
-	}
-
-	public static Object concat(LuanState luan,Object o1,Object o2) throws LuanException {
-		LuanFunction fn = Luan.getBinHandler("__concat",o1,o2);
-		if( fn != null )
-			return Luan.first(fn.call(luan,new Object[]{o1,o2}));
-		String s1 = luan.toString(o1);
-		String s2 = luan.toString(o2);
-		return s1 + s2;
-	}
-
-	public static boolean eq(LuanState luan,Object o1,Object o2) throws LuanException {
-		if( o1 == o2 || o1 != null && o1.equals(o2) )
-			return true;
-		if( o1 instanceof Number && o2 instanceof Number ) {
-			Number n1 = (Number)o1;
-			Number n2 = (Number)o2;
-			return n1.doubleValue() == n2.doubleValue();
-		}
-		if( o1 instanceof byte[] && o2 instanceof byte[] ) {
-			byte[] b1 = (byte[])o1;
-			byte[] b2 = (byte[])o2;
-			return Arrays.equals(b1,b2);
-		}
-		if( !(o1 instanceof LuanTable && o2 instanceof LuanTable) )
-			return false;
-		LuanTable t1 = (LuanTable)o1;
-		LuanTable t2 = (LuanTable)o2;
-		LuanTable mt1 = t1.getMetatable();
-		LuanTable mt2 = t2.getMetatable();
-		if( mt1==null || mt2==null )
-			return false;
-		Object f = mt1.rawGet("__eq");
-		if( f == null || !f.equals(mt2.rawGet("__eq")) )
-			return false;
-		LuanFunction fn = Luan.checkFunction(f);
-		return Luan.checkBoolean( Luan.first(fn.call(luan,new Object[]{o1,o2})) );
-	}
-
-	public static boolean le(LuanState luan,Object o1,Object o2) throws LuanException {
-		if( o1 instanceof Number && o2 instanceof Number ) {
-			Number n1 = (Number)o1;
-			Number n2 = (Number)o2;
-			return n1.doubleValue() <= n2.doubleValue();
-		}
-		if( o1 instanceof String && o2 instanceof String ) {
-			String s1 = (String)o1;
-			String s2 = (String)o2;
-			return s1.compareTo(s2) <= 0;
-		}
-		LuanFunction fn = Luan.getBinHandler("__le",o1,o2);
-		if( fn != null )
-			return Luan.checkBoolean( Luan.first(fn.call(luan,new Object[]{o1,o2})) );
-		fn = Luan.getBinHandler("__lt",o1,o2);
-		if( fn != null )
-			return !Luan.checkBoolean( Luan.first(fn.call(luan,new Object[]{o2,o1})) );
-		throw new LuanException( "attempt to compare " + Luan.type(o1) + " with " + Luan.type(o2) );
-	}
-
-	public static boolean lt(LuanState luan,Object o1,Object o2) throws LuanException {
-		return Luan.isLessThan(luan,o1,o2);
-	}
-
-	public static boolean cnd(Object o) throws LuanException {
-		return !(o == null || Boolean.FALSE.equals(o));
-	}
-
-	public static void nop(Object o) {}
-
-
-	public static void set(LuanStateImpl luan,Settable[] vars,Object obj) throws LuanException {
-		if( obj instanceof Object[] ) {
-			Object[] vals = (Object[])obj;
-			for( int i=0; i<vars.length; i++ ) {
-				Object val = i < vals.length ? vals[i] : null;
-				vars[i].set(luan,val);
-			}
-		} else {
-			vars[0].set(luan,obj);
-			for( int i=1; i<vars.length; i++ ) {
-				vars[i].set(luan,null);
-			}
-		}
-	}
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/src/luan/impl/LuanImpl.java	Tue Apr 05 14:16:14 2016 -0600
@@ -0,0 +1,245 @@
+package luan.impl;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.ArrayList;
+import luan.Luan;
+import luan.LuanState;
+import luan.LuanTable;
+import luan.LuanFunction;
+import luan.LuanException;
+
+
+public final class LuanImpl {
+	private LuanImpl() {}  // never
+
+
+	private static List<Expressions> listExpressions = new ArrayList<Expressions>();
+
+	static int addExpressions(Expressions exp) {
+		int i = listExpressions.size();
+		listExpressions.add(exp);
+		return i;
+	}
+
+	public static Expressions getExpressions(int i) {
+		return listExpressions.get(i);
+	}
+
+
+	private static List<Stmt> listStmt = new ArrayList<Stmt>();
+
+	static int addStmt(Stmt stmt) {
+		int i = listStmt.size();
+		listStmt.add(stmt);
+		return i;
+	}
+
+	public static Stmt getStmt(int i) {
+		return listStmt.get(i);
+	}
+
+
+	private static List<Settable> listSettable = new ArrayList<Settable>();
+
+	static int addSettable(Settable settable) {
+		int i = listSettable.size();
+		listSettable.add(settable);
+		return i;
+	}
+
+	public static Settable getSettable(int i) {
+		return listSettable.get(i);
+	}
+
+
+	public static int len(LuanState luan,Object o) throws LuanException {
+		if( o instanceof String ) {
+			String s = (String)o;
+			return s.length();
+		}
+		if( o instanceof byte[] ) {
+			byte[] a = (byte[])o;
+			return a.length;
+		}
+		if( o instanceof LuanTable ) {
+			LuanTable t = (LuanTable)o;
+			return t.length(luan);
+		}
+		throw new LuanException( "attempt to get length of a " + Luan.type(o) + " value" );
+	}
+
+	public static Object unm(LuanState luan,Object o) throws LuanException {
+		if( o instanceof Number )
+			return -((Number)o).doubleValue();
+		if( o instanceof LuanTable ) {
+			LuanFunction fn = Luan.getHandlerFunction("__unm",(LuanTable)o);
+			if( fn != null ) {
+				return Luan.first(fn.call(luan,new Object[]{o}));
+			}
+		}
+		throw new LuanException("attempt to perform arithmetic on a "+Luan.type(o)+" value");
+	}
+
+	private static Object arithmetic(LuanState luan,String op,Object o1,Object o2) throws LuanException {
+		LuanFunction fn = Luan.getBinHandler(op,o1,o2);
+		if( fn != null )
+			return Luan.first(fn.call(luan,new Object[]{o1,o2}));
+		String type = !(o1 instanceof Number) ? Luan.type(o1) : Luan.type(o2);
+		throw new LuanException("attempt to perform arithmetic on a "+type+" value");
+	}
+
+	public static Object pow(LuanState luan,Object o1,Object o2) throws LuanException {
+		if( o1 instanceof Number && o2 instanceof Number )
+			return Math.pow( ((Number)o1).doubleValue(), ((Number)o2).doubleValue() );
+		return arithmetic(luan,"__pow",o1,o2);
+	}
+
+	public static Object mul(LuanState luan,Object o1,Object o2) throws LuanException {
+		if( o1 instanceof Number && o2 instanceof Number )
+			return ((Number)o1).doubleValue() * ((Number)o2).doubleValue();
+		return arithmetic(luan,"__mul",o1,o2);
+	}
+
+	public static Object div(LuanState luan,Object o1,Object o2) throws LuanException {
+		if( o1 instanceof Number && o2 instanceof Number )
+			return ((Number)o1).doubleValue() / ((Number)o2).doubleValue();
+		return arithmetic(luan,"__div",o1,o2);
+	}
+
+	public static Object mod(LuanState luan,Object o1,Object o2) throws LuanException {
+		if( o1 instanceof Number && o2 instanceof Number ) {
+			double d1 = ((Number)o1).doubleValue();
+			double d2 = ((Number)o2).doubleValue();
+			return d1 - Math.floor(d1/d2)*d2;
+		}
+		return arithmetic(luan,"__mod",o1,o2);
+	}
+
+	public static Object add(LuanState luan,Object o1,Object o2) throws LuanException {
+		if( o1 instanceof Number && o2 instanceof Number )
+			return ((Number)o1).doubleValue() + ((Number)o2).doubleValue();
+		return arithmetic(luan,"__add",o1,o2);
+	}
+
+	public static Object sub(LuanState luan,Object o1,Object o2) throws LuanException {
+		if( o1 instanceof Number && o2 instanceof Number )
+			return ((Number)o1).doubleValue() - ((Number)o2).doubleValue();
+		return arithmetic(luan,"__sub",o1,o2);
+	}
+
+	public static Object concat(LuanState luan,Object o1,Object o2) throws LuanException {
+		LuanFunction fn = Luan.getBinHandler("__concat",o1,o2);
+		if( fn != null )
+			return Luan.first(fn.call(luan,new Object[]{o1,o2}));
+		String s1 = luan.toString(o1);
+		String s2 = luan.toString(o2);
+		return s1 + s2;
+	}
+
+	public static boolean eq(LuanState luan,Object o1,Object o2) throws LuanException {
+		if( o1 == o2 || o1 != null && o1.equals(o2) )
+			return true;
+		if( o1 instanceof Number && o2 instanceof Number ) {
+			Number n1 = (Number)o1;
+			Number n2 = (Number)o2;
+			return n1.doubleValue() == n2.doubleValue();
+		}
+		if( o1 instanceof byte[] && o2 instanceof byte[] ) {
+			byte[] b1 = (byte[])o1;
+			byte[] b2 = (byte[])o2;
+			return Arrays.equals(b1,b2);
+		}
+		if( !(o1 instanceof LuanTable && o2 instanceof LuanTable) )
+			return false;
+		LuanTable t1 = (LuanTable)o1;
+		LuanTable t2 = (LuanTable)o2;
+		LuanTable mt1 = t1.getMetatable();
+		LuanTable mt2 = t2.getMetatable();
+		if( mt1==null || mt2==null )
+			return false;
+		Object f = mt1.rawGet("__eq");
+		if( f == null || !f.equals(mt2.rawGet("__eq")) )
+			return false;
+		LuanFunction fn = Luan.checkFunction(f);
+		return Luan.checkBoolean( Luan.first(fn.call(luan,new Object[]{o1,o2})) );
+	}
+
+	public static boolean le(LuanState luan,Object o1,Object o2) throws LuanException {
+		if( o1 instanceof Number && o2 instanceof Number ) {
+			Number n1 = (Number)o1;
+			Number n2 = (Number)o2;
+			return n1.doubleValue() <= n2.doubleValue();
+		}
+		if( o1 instanceof String && o2 instanceof String ) {
+			String s1 = (String)o1;
+			String s2 = (String)o2;
+			return s1.compareTo(s2) <= 0;
+		}
+		LuanFunction fn = Luan.getBinHandler("__le",o1,o2);
+		if( fn != null )
+			return Luan.checkBoolean( Luan.first(fn.call(luan,new Object[]{o1,o2})) );
+		fn = Luan.getBinHandler("__lt",o1,o2);
+		if( fn != null )
+			return !Luan.checkBoolean( Luan.first(fn.call(luan,new Object[]{o2,o1})) );
+		throw new LuanException( "attempt to compare " + Luan.type(o1) + " with " + Luan.type(o2) );
+	}
+
+	public static boolean lt(LuanState luan,Object o1,Object o2) throws LuanException {
+		return Luan.isLessThan(luan,o1,o2);
+	}
+
+	public static boolean cnd(Object o) throws LuanException {
+		return !(o == null || Boolean.FALSE.equals(o));
+	}
+
+	public static void nop(Object o) {}
+
+
+	public static void set(LuanStateImpl luan,Settable[] vars,Object obj) throws LuanException {
+		if( obj instanceof Object[] ) {
+			Object[] vals = (Object[])obj;
+			for( int i=0; i<vars.length; i++ ) {
+				Object val = i < vals.length ? vals[i] : null;
+				vars[i].set(luan,val);
+			}
+		} else {
+			vars[0].set(luan,obj);
+			for( int i=1; i<vars.length; i++ ) {
+				vars[i].set(luan,null);
+			}
+		}
+	}
+
+	public static Object[] concatArgs(Object o1,Object o2) {
+		if( o1 instanceof Object[] ) {
+			Object[] a1 = (Object[])o1;
+			if( o2 instanceof Object[] ) {
+				Object[] a2 = (Object[])o2;
+				Object[] rtn = new Object[a1.length+a2.length];
+				System.arraycopy(a1,0,rtn,0,a1.length);
+				System.arraycopy(a2,0,rtn,a1.length,a2.length);
+				return rtn;
+			} else {
+				Object[] rtn = new Object[a1.length+1];
+				System.arraycopy(a1,0,rtn,0,a1.length);
+				rtn[a1.length] = o2;
+				return rtn;
+			}
+		} else {
+			if( o2 instanceof Object[] ) {
+				Object[] a2 = (Object[])o2;
+				Object[] rtn = new Object[1+a2.length];
+				rtn[0] = o1;
+				System.arraycopy(a2,0,rtn,1,a2.length);
+				return rtn;
+			} else {
+				Object[] rtn = new Object[2];
+				rtn[0] = o1;
+				rtn[2] = o2;
+				return rtn;
+			}
+		}
+	}
+
+}
--- a/core/src/luan/impl/LuanParser.java	Tue Apr 05 13:01:04 2016 -0600
+++ b/core/src/luan/impl/LuanParser.java	Tue Apr 05 14:16:14 2016 -0600
@@ -217,7 +217,7 @@
 				+"try {\n"
 				+ code
 				+"} finally {\n"
-				+"	$luan.stackClear("+stackStart+","+stackEnd+");\n"
+				+"	luan.stackClear("+stackStart+","+stackEnd+");\n"
 				+"}\n"
 			;
 		return new StmtString(code);
@@ -230,7 +230,7 @@
 		if( EndOfLine() )
 			return parser.success();
 		parser.rollback();
-		StmtString stmt = stmtStr(TemplateStmt());
+		StmtString stmt = TemplateStmt();
 		if( stmt != null ) {
 			stmts.append(stmt.code);
 			return parser.success();
@@ -262,19 +262,33 @@
 		}
 	}
 
-	private Stmt TemplateStmt() throws ParseException {
-		parser.currentIndex();
-		Expressions exprs = TemplateExpressions(In.NOTHING);
+	private ExpString indexExpStr(ExpString exp1,ExpString exp2) {
+		String code = "luan.index(" + exp1.expr().code + "," + exp2.expr().code + ")";
+		return new ExpString(code,true,false);
+	}
+
+	private ExpString constExpStr(Object obj) {
+		return new ExpString(new ConstExpr(obj));
+	}
+
+	private ExpString callExpStr(ExpString fn,ExpString args) {
+		String code = "Luan.checkFunction(" + fn.expr().code + ").call(luan,Luan.array(" + args.code + "))";
+		return new ExpString(code,false,true);
+	}
+
+	private StmtString TemplateStmt() throws ParseException {
+		ExpString exprs = TemplateExpressions(In.NOTHING);
 		if( exprs == null )
 			return null;
-		FnCall requireCall = new FnCall( new ConstExpr(PackageLuan.requireFn), new ConstExpr("luan:Io") );
-		Expr stdoutExp = new IndexExpr( expr(requireCall), new ConstExpr("stdout") );
-		Expr writeExp = new IndexExpr( stdoutExp, new ConstExpr("write") );
-		FnCall writeCall = new FnCall( writeExp, exprs );
-		return new ExpressionsStmt(writeCall);
+		ExpString requireCall = callExpStr( constExpStr(PackageLuan.requireFn), constExpStr("luan:Io") );
+		ExpString stdoutExp = indexExpStr( requireCall.expr(), constExpStr("stdout") );
+		ExpString writeExp = indexExpStr( stdoutExp, constExpStr("write") );
+		ExpString writeCall = callExpStr( writeExp, exprs );
+		String code = writeCall.code + ";\n";
+		return new StmtString(code);
 	}
 
-	private Expressions TemplateExpressions(In in) throws ParseException {
+	private ExpString TemplateExpressions(In in) throws ParseException {
 		if( in.template )
 			return null;
 		int start = parser.begin();
@@ -282,15 +296,15 @@
 			return parser.failure(null);
 		EndOfLine();
 		In inTemplate = in.template();
-		List<Expressions> builder = new ArrayList<Expressions>();
+		List<ExpString> builder = new ArrayList<ExpString>();
 		while(true) {
 			if( parser.match( "<%=" ) ) {
 				Spaces(inTemplate);
-				builder.add( exp(RequiredExpr(inTemplate)) );
+				builder.add( RequiredExpr(inTemplate) );
 				RequiredMatch( "%>" );
 			} else if( parser.match( "<%" ) ) {
 				Spaces(inTemplate);
-				return parser.success(ExpList.build(builder));
+				return parser.success(expString(builder));
 			} else {
 				int i = parser.currentIndex();
 				do {
@@ -300,7 +314,7 @@
 						throw parser.exception("Unclosed template expression");
 				} while( !parser.test( "<%" ) );
 				String match = parser.textFrom(i);
-				builder.add( new ConstExpr(match) );
+				builder.add( constExpStr(match) );
 			}
 		}
 	}
@@ -377,20 +391,20 @@
 		addSymbols(names);
 		StmtString loop = RequiredLoopBlock();
 		RequiredKeyword("end",In.NOTHING);
-		String fnVar = "$fn"+ ++forCounter;
+		String fnVar = "fn"+ ++forCounter;
 		String code = ""
 			+"try {\n"
-			+"LuanFunction "+fnVar+" = $Luan.checkFunction(" + expr.code + ");\n"
+			+"LuanFunction "+fnVar+" = Luan.checkFunction(" + expr.code + ");\n"
 			+"while(true) {\n"
 			+"for( int i="+stackStart+"; i<"+symbolsSize()+"; i++ ) {\n"
-			+"$luan.stackSet(i,null);\n"
+			+"luan.stackSet(i,null);\n"
 			+"}\n"
-			+"$Luan.set($luan," + varsStr + ", "+fnVar+".call($luan) );\n"
+			+"LuanImpl.set(luan," + varsStr + ", "+fnVar+".call(luan) );\n"
 			+"if( " + firstVar.code + "==null )  break;\n"
 			+ loop.code
 			+"}"
 			+"} finally {\n"
-			+"$luan.stackClear("+stackStart+","+symbolsSize()+");\n"
+			+"luan.stackClear("+stackStart+","+symbolsSize()+");\n"
 			+"}\n"
 		;
 		StmtString stmt = new StmtString(code);
@@ -428,7 +442,7 @@
 				vars[i] = new SetLocalVar(stackStart+i);
 			}
 			String varsStr = varsToString(vars);
-			String code = "$Luan.set($luan," + varsStr + "," + values.code + ");\n";
+			String code = "LuanImpl.set(luan," + varsStr + "," + values.code + ");\n";
 			stmts.append(code);
 		}
 		addSymbols(names);
@@ -475,7 +489,7 @@
 		StmtString loop = RequiredLoopBlock();
 		RequiredKeyword("end",In.NOTHING);
 		String code = ""
-			+"while( $Luan.checkBoolean(" + cnd.code + ") ) {\n"
+			+"while( Luan.checkBoolean(" + cnd.code + ") ) {\n"
 			+ loop.code
 			+"}\n"
 		;
@@ -492,7 +506,7 @@
 		String code = ""
 			+"do {\n"
 			+ loop.code
-			+"} while( !$Luan.checkBoolean(" + cnd.code + ") );\n"
+			+"} while( !Luan.checkBoolean(" + cnd.code + ") );\n"
 		;
 		return parser.success( new StmtString(code) );
 	}
@@ -514,12 +528,12 @@
 		cnd = RequiredExpr(In.NOTHING).expr();
 		RequiredKeyword("then",In.NOTHING);
 		block = RequiredBlock();
-		sb.append( "if( $Luan.checkBoolean(" ).append( cnd.code ).append( ") ) {\n" ).append( block.code );
+		sb.append( "if( Luan.checkBoolean(" ).append( cnd.code ).append( ") ) {\n" ).append( block.code );
 		while( Keyword("elseif",In.NOTHING) ) {
 			cnd = RequiredExpr(In.NOTHING).expr();
 			RequiredKeyword("then",In.NOTHING);
 			block = RequiredBlock();
-			sb.append( "} else if( $Luan.checkBoolean(" ).append( cnd.code ).append( ") ) {\n" ).append( block.code );
+			sb.append( "} else if( Luan.checkBoolean(" ).append( cnd.code ).append( ") ) {\n" ).append( block.code );
 		}
 		if( Keyword("else",In.NOTHING) ) {
 			block = RequiredBlock();
@@ -552,7 +566,7 @@
 //			throw parser.exception("Expressions expected");
 			return parser.failure(null);
 		String varsStr = varsToString(vars.toArray(new Settable[0]));
-		String code = "$Luan.set($luan," + varsStr + "," + values.code + "); ";
+		String code = "LuanImpl.set(luan," + varsStr + "," + values.code + "); ";
 		return parser.success( new StmtString(code) );
 	}
 
@@ -572,7 +586,7 @@
 		if( exp != null && exp.isStmt ) {
 			String code = exp.code;
 			if( exp.isExpr )
-				code = "$Luan.nop(" + code + ")";
+				code = "LuanImpl.nop(" + code + ")";
 			code += ";\n";
 			return parser.success( new StmtString(code) );
 		}
@@ -604,7 +618,7 @@
 		while( Keyword("or",in) ) {
 			exp = exp.expr();
 			ExpString exp2 = required(RelExpr(in)).expr();
-			String code = "($Luan.cnd($cnd = " + exp.code + ") ? $cnd : (" + exp2.code + "))";
+			String code = "(LuanImpl.cnd(cnd = " + exp.code + ") ? cnd : (" + exp2.code + "))";
 			exp = new ExpString(code,true,true);
 		}
 		return parser.success(exp);
@@ -618,7 +632,7 @@
 		while( Keyword("and",in) ) {
 			exp = exp.expr();
 			ExpString exp2 = required(RelExpr(in)).expr();
-			String code = "($Luan.cnd($cnd = " + exp.code + ") ? (" + exp2.code + ") : $cnd)";
+			String code = "(LuanImpl.cnd(cnd = " + exp.code + ") ? (" + exp2.code + ") : cnd)";
 			exp = new ExpString(code,true,true);
 		}
 		return parser.success(exp);
@@ -634,37 +648,37 @@
 				Spaces(in);
 				exp = exp.expr();
 				ExpString exp2 = required(ConcatExpr(in)).expr();
-				String code = "$Luan.eq($luan," + exp.code + "," + exp2.code + ")";
+				String code = "LuanImpl.eq(luan," + exp.code + "," + exp2.code + ")";
 				exp = new ExpString(code,true,false);
 			} else if( parser.match("~=") ) {
 				Spaces(in);
 				exp = exp.expr();
 				ExpString exp2 = required(ConcatExpr(in)).expr();
-				String code = "!$Luan.eq($luan," + exp.code + "," + exp2.code + ")";
+				String code = "!LuanImpl.eq(luan," + exp.code + "," + exp2.code + ")";
 				exp = new ExpString(code,true,false);
 			} else if( parser.match("<=") ) {
 				Spaces(in);
 				exp = exp.expr();
 				ExpString exp2 = required(ConcatExpr(in)).expr();
-				String code = "$Luan.le($luan," + exp.code + "," + exp2.code + ")";
+				String code = "LuanImpl.le(luan," + exp.code + "," + exp2.code + ")";
 				exp = new ExpString(code,true,false);
 			} else if( parser.match(">=") ) {
 				Spaces(in);
 				exp = exp.expr();
 				ExpString exp2 = required(ConcatExpr(in)).expr();
-				String code = "$Luan.le($luan," + exp2.code + "," + exp.code + ")";
+				String code = "LuanImpl.le(luan," + exp2.code + "," + exp.code + ")";
 				exp = new ExpString(code,true,false);
 			} else if( parser.match("<") ) {
 				Spaces(in);
 				exp = exp.expr();
 				ExpString exp2 = required(ConcatExpr(in)).expr();
-				String code = "$Luan.lt($luan," + exp.code + "," + exp2.code + ")";
+				String code = "LuanImpl.lt(luan," + exp.code + "," + exp2.code + ")";
 				exp = new ExpString(code,true,false);
 		} else if( parser.match(">") ) {
 				Spaces(in);
 				exp = exp.expr();
 				ExpString exp2 = required(ConcatExpr(in)).expr();
-				String code = "$Luan.lt($luan," + exp2.code + "," + exp.code + ")";
+				String code = "LuanImpl.lt(luan," + exp2.code + "," + exp.code + ")";
 				exp = new ExpString(code,true,false);
 			} else
 				break;
@@ -681,7 +695,7 @@
 			Spaces(in);
 			exp = exp.expr();
 			ExpString exp2 = required(ConcatExpr(in)).expr();
-			String code = "$Luan.concat($luan," + exp.code + "," + exp2.code + ")";
+			String code = "LuanImpl.concat(luan," + exp.code + "," + exp2.code + ")";
 			exp = new ExpString(code,true,false);
 		}
 		return parser.success(exp);
@@ -697,13 +711,13 @@
 				Spaces(in);
 				exp = exp.expr();
 				ExpString exp2 = required(TermExpr(in)).expr();
-				String code = "$Luan.add($luan," + exp.code + "," + exp2.code + ")";
+				String code = "LuanImpl.add(luan," + exp.code + "," + exp2.code + ")";
 				exp = new ExpString(code,true,false);
 			} else if( Minus() ) {
 				Spaces(in);
 				exp = exp.expr();
 				ExpString exp2 = required(TermExpr(in)).expr();
-				String code = "$Luan.sub($luan," + exp.code + "," + exp2.code + ")";
+				String code = "LuanImpl.sub(luan," + exp.code + "," + exp2.code + ")";
 				exp = new ExpString(code,true,false);
 			} else
 				break;
@@ -726,19 +740,19 @@
 				Spaces(in);
 				exp = exp.expr();
 				ExpString exp2 = required(UnaryExpr(in)).expr();
-				String code = "$Luan.mul($luan," + exp.code + "," + exp2.code + ")";
+				String code = "LuanImpl.mul(luan," + exp.code + "," + exp2.code + ")";
 				exp = new ExpString(code,true,false);
 			} else if( parser.match('/') ) {
 				Spaces(in);
 				exp = exp.expr();
 				ExpString exp2 = required(UnaryExpr(in)).expr();
-				String code = "$Luan.div($luan," + exp.code + "," + exp2.code + ")";
+				String code = "LuanImpl.div(luan," + exp.code + "," + exp2.code + ")";
 				exp = new ExpString(code,true,false);
 			} else if( Mod() ) {
 				Spaces(in);
 				exp = exp.expr();
 				ExpString exp2 = required(UnaryExpr(in)).expr();
-				String code = "$Luan.mod($luan," + exp.code + "," + exp2.code + ")";
+				String code = "LuanImpl.mod(luan," + exp.code + "," + exp2.code + ")";
 				exp = new ExpString(code,true,false);
 			} else
 				break;
@@ -756,21 +770,21 @@
 		if( parser.match('#') ) {
 			Spaces(in);
 			ExpString exp = required(UnaryExpr(in)).expr();
-			String code = "$Luan.len($luan," + exp.code + ")";
+			String code = "LuanImpl.len(luan," + exp.code + ")";
 			exp = new ExpString(code,true,false);
 			return parser.success(exp);
 		}
 		if( Minus() ) {
 			Spaces(in);
 			ExpString exp = required(UnaryExpr(in)).expr();
-			String code = "$Luan.unm($luan," + exp.code + ")";
+			String code = "LuanImpl.unm(luan," + exp.code + ")";
 			exp = new ExpString(code,true,false);
 			return parser.success(exp);
 		}
 		if( Keyword("not",in) ) {
 			Spaces(in);
 			ExpString exp = required(UnaryExpr(in)).expr();
-			String code = "$Luan.not(" + exp.code + ")";
+			String code = "!Luan.checkBoolean(" + exp.code + ")";
 			exp = new ExpString(code,true,false);
 			return parser.success(exp);
 		}
@@ -789,7 +803,7 @@
 		if( parser.match('^') ) {
 			Spaces(in);
 			ExpString exp2 = required(PowExpr(in));
-			String code = "$Luan.pow($luan," + exp1.code + "," + exp2.code + ")";
+			String code = "LuanImpl.pow(luan," + exp1.code + "," + exp2.code + ")";
 			exp1 = new ExpString(code,true,false);
 		}
 		return parser.success(exp1);
@@ -865,7 +879,7 @@
 			Spaces(In.NOTHING);
 			Field(fields,builder);
 		}
-		Expressions exp = TemplateExpressions(In.NOTHING);
+		Expressions exp = exp(TemplateExpressions(In.NOTHING));
 		if( exp != null )
 			builder.add(exp);
 		if( !parser.match('}') )
@@ -1073,25 +1087,25 @@
 
 	private ExpString ExpStringList(In in) throws ParseException {
 		List<ExpString> builder = new ArrayList<ExpString>();
-		return ExpList(in,builder) ? exp(builder) : null;
+		return ExpList(in,builder) ? expString(builder) : null;
 	}
 
 	private boolean ExpList(In in,List<ExpString> builder) throws ParseException {
 		parser.begin();
-		Expressions exp = TemplateExpressions(in);
+		ExpString exp = TemplateExpressions(in);
 		if( exp != null ) {
-			builder.add(new ExpString(exp));
+			builder.add(exp);
 			return parser.success();
 		}
-		ExpString es = ExprZ(in);
-		if( es==null )
+		exp = ExprZ(in);
+		if( exp==null )
 			return parser.failure();
-		builder.add(es);
+		builder.add(exp);
 		while( parser.match(',') ) {
 			Spaces(in);
 			exp = TemplateExpressions(in);
 			if( exp != null ) {
-				builder.add(new ExpString(exp));
+				builder.add(exp);
 				return parser.success();
 			}
 			builder.add( RequiredExpr(in) );
@@ -1466,8 +1480,8 @@
 
 		ExpString(Expressions exp) {
 			if( exp==null )  throw new NullPointerException();
-			int i = $Luan.addExpressions(exp);
-			code = "$Luan.getExpressions(" + i + ").eval($luan)";
+			int i = LuanImpl.addExpressions(exp);
+			code = "LuanImpl.getExpressions(" + i + ").eval(luan)";
 			isExpr = exp instanceof Expr;
 			isStmt = exp instanceof StmtExp;
 		}
@@ -1479,7 +1493,7 @@
 		}
 
 		ExpString expr() {
-			return isExpr ? this : new ExpString( "$Luan.first(" + code + ")", true, isStmt );
+			return isExpr ? this : new ExpString( "Luan.first(" + code + ")", true, isStmt );
 		}
 
 		Expressions toExpressions() {
@@ -1487,11 +1501,12 @@
 			String className = "EXP" + ++classCounter;
 			String classCode = ""
 				+"package luan.impl;\n"
+				+"import luan.Luan;\n"
 				+"import luan.LuanException;\n"
 				+"\n"
 				+"public class " + className +" implements " + superClass + " {\n"
-				+"	@Override public Object eval(LuanStateImpl $luan) throws LuanException {\n"
-				+"		Object $cnd;\n"
+				+"	@Override public Object eval(LuanStateImpl luan) throws LuanException {\n"
+				+"		Object cnd;\n"
 				+"		return " + code + ";\n"
 				+"	}\n"
 				+"}\n"
@@ -1514,7 +1529,7 @@
 		return expStr==null ? null : expStr.toExpressions();
 	}
 
-	private ExpString exp(List<ExpString> list) {
+	private ExpString expString(List<ExpString> list) {
 		switch(list.size()) {
 		case 0:
 			return new ExpString("LuanFunction.NOTHING",false,false);
@@ -1533,7 +1548,7 @@
 				return new ExpString(sb.toString(),false,false);
 			} else {
 				sb.append( '}' );
-				String s = "$Luan.concatArgs(" + sb + "," + last.code + ")";
+				String s = "LuanImpl.concatArgs(" + sb + "," + last.code + ")";
 				return new ExpString(s,false,false);
 			}
 		}
@@ -1552,8 +1567,8 @@
 
 		StmtString(Stmt stmt) {
 			if( stmt==null )  throw new NullPointerException();
-			int i = $Luan.addStmt(stmt);
-			code = "$Luan.getStmt(" + i + ").eval($luan);\n";
+			int i = LuanImpl.addStmt(stmt);
+			code = "LuanImpl.getStmt(" + i + ").eval(luan);\n";
 		}
 
 		StmtString(String code) {
@@ -1565,12 +1580,13 @@
 			String className = "EXP" + ++classCounter;
 			String classCode = ""
 				+"package luan.impl;\n"
+				+"import luan.Luan;\n"
 				+"import luan.LuanFunction;\n"
 				+"import luan.LuanException;\n"
 				+"\n"
 				+"public class " + className +" implements Stmt {\n"
-				+"	@Override public void eval(LuanStateImpl $luan) throws LuanException {\n"
-				+"		Object $cnd;\n"
+				+"	@Override public void eval(LuanStateImpl luan) throws LuanException {\n"
+				+"		Object cnd;\n"
 				+"		" + code
 				+"	}\n"
 				+"}\n"
@@ -1605,8 +1621,8 @@
 
 		SettableString(Settable settable) {
 			if( settable==null )  throw new NullPointerException();
-			int i = $Luan.addSettable(settable);
-			code = "$Luan.getSettable(" + i + ")";
+			int i = LuanImpl.addSettable(settable);
+			code = "LuanImpl.getSettable(" + i + ")";
 		}
 
 		SettableString(String code) {