changeset 34:0cdc1da466ee

implement _G and _ENV git-svn-id: https://luan-java.googlecode.com/svn/trunk@35 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Sun, 16 Dec 2012 09:23:56 +0000
parents 8793c71ad47a
children e51906de0f11
files src/luan/CmdLine.java src/luan/LuaState.java src/luan/interp/EnvExpr.java src/luan/interp/LuaParser.java src/luan/interp/LuaStateImpl.java src/luan/interp/UpValue.java src/luan/lib/BasicLib.java
diffstat 7 files changed, 53 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/src/luan/CmdLine.java	Sun Dec 16 05:07:42 2012 +0000
+++ b/src/luan/CmdLine.java	Sun Dec 16 09:23:56 2012 +0000
@@ -65,7 +65,7 @@
 			for( int j=0; j<args.length; j++ ) {
 				argsTable.set( new LuaNumber(j), args[j] );
 			}
-			lua.env().set("arg",argsTable);
+			lua.global().set("arg",argsTable);
 			try {
 				LuaFunction fn = BasicLib.loadfile(lua,file);
 				fn.call(lua,varArgs);
--- a/src/luan/LuaState.java	Sun Dec 16 05:07:42 2012 +0000
+++ b/src/luan/LuaState.java	Sun Dec 16 09:23:56 2012 +0000
@@ -2,5 +2,5 @@
 
 
 public interface LuaState {
-	public LuaTable env();
+	public LuaTable global();
 }
--- a/src/luan/interp/EnvExpr.java	Sun Dec 16 05:07:42 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-package luan.interp;
-
-
-final class EnvExpr implements Expr {
-	static final EnvExpr INSTANCE = new EnvExpr();
-
-	private EnvExpr() {}
-
-	@Override public Object eval(LuaStateImpl lua) {
-		return lua.env();
-	}
-}
--- a/src/luan/interp/LuaParser.java	Sun Dec 16 05:07:42 2012 +0000
+++ b/src/luan/interp/LuaParser.java	Sun Dec 16 09:23:56 2012 +0000
@@ -23,6 +23,9 @@
 
 class LuaParser extends BaseParser<Object> {
 
+	static final String _G = "_G";
+	static final String _ENV = "_ENV";
+
 	static final class Frame {
 		final Frame parent;
 		final List<String> symbols = new ArrayList<String>();
@@ -32,6 +35,14 @@
 		final List<String> upValueSymbols = new ArrayList<String>();
 		final List<UpValue.Getter> upValueGetters = new ArrayList<UpValue.Getter>();
 
+		Frame() {
+			this.parent = null;
+			upValueSymbols.add(_G);
+			upValueGetters.add(UpValue.globalGetter);
+			upValueSymbols.add(_ENV);
+			upValueGetters.add(UpValue.globalGetter);
+		}
+
 		Frame(Frame parent) {
 			this.parent = parent;
 		}
@@ -71,7 +82,7 @@
 
 	int nEquals;
 	int parens = 0;
-	Frame frame = new Frame(null);
+	Frame frame = new Frame();
 
 	boolean nEquals(int n) {
 		nEquals = n;
@@ -433,7 +444,7 @@
 		index = upValueIndex(name);
 		if( index != -1 )
 			return push( new SetUpVar(index) );
-		return push( new SetTableEntry( EnvExpr.INSTANCE, new ConstExpr(name) ) );
+		return push( new SetTableEntry( env(), new ConstExpr(name) ) );
 	}
 
 	Rule Expr() {
@@ -537,8 +548,8 @@
 	Rule Function() {
 		Var<List<String>> names = new Var<List<String>>(new ArrayList<String>());
 		return Sequence(
+			'(', incParens(), Spaces(),
 			action( frame = new Frame(frame) ),
-			'(', incParens(), Spaces(),
 			Optional(
 				FirstOf(
 					Sequence(
@@ -646,6 +657,16 @@
 		);
 	}
 
+	Expr env() {
+		int index = stackIndex(_ENV);
+		if( index != -1 )
+			return new GetLocalVar(index);
+		index = upValueIndex(_ENV);
+		if( index != -1 )
+			return new GetUpVar(index);
+		throw new RuntimeException("_ENV not found");
+	}
+
 	boolean makeVarExp() {
 		Object obj2 = pop();
 		if( obj2==null )
@@ -660,7 +681,7 @@
 		index = upValueIndex(name);
 		if( index != -1 )
 			return push( new GetUpVar(index) );
-		return push( new GetExpr( EnvExpr.INSTANCE, new ConstExpr(name) ) );
+		return push( new GetExpr( env(), new ConstExpr(name) ) );
 	}
 
 	// function should be on top of the stack
--- a/src/luan/interp/LuaStateImpl.java	Sun Dec 16 05:07:42 2012 +0000
+++ b/src/luan/interp/LuaStateImpl.java	Sun Dec 16 09:23:56 2012 +0000
@@ -6,10 +6,10 @@
 
 
 final class LuaStateImpl implements LuaState {
-	private final LuaTable env = new LuaTable();
+	private final LuaTable global = new LuaTable();
 
-	@Override public LuaTable env() {
-		return env;
+	@Override public LuaTable global() {
+		return global;
 	}
 
 
--- a/src/luan/interp/UpValue.java	Sun Dec 16 05:07:42 2012 +0000
+++ b/src/luan/interp/UpValue.java	Sun Dec 16 09:23:56 2012 +0000
@@ -4,23 +4,35 @@
 final class UpValue {
 	private Object[] stack;
 	private int index;
+	private boolean isClosed = false;
+	private Object value;
 
 	UpValue(Object[] stack,int index) {
 		this.stack = stack;
 		this.index = index;
 	}
 
+	UpValue(Object value) {
+		this.value = value;
+		this.isClosed = true;
+	}
+
 	Object get() {
-		return stack[index];
+		return isClosed ? value : stack[index];
 	}
 
 	void set(Object value) {
-		stack[index] = value;
+		if( isClosed ) {
+			this.value = value;
+		} else {
+			stack[index] = value;
+		}
 	}
 
 	void close() {
-		stack = new Object[]{get()};
-		index = 0;
+		value = stack[index];
+		isClosed = true;
+		stack = null;
 	}
 
 	static interface Getter {
@@ -51,4 +63,10 @@
 		}
 	}
 
+	static final Getter globalGetter = new Getter() {
+		public UpValue get(LuaStateImpl lua) {
+			return new UpValue(lua.global());
+		}
+	};
+
 }
--- a/src/luan/lib/BasicLib.java	Sun Dec 16 05:07:42 2012 +0000
+++ b/src/luan/lib/BasicLib.java	Sun Dec 16 09:23:56 2012 +0000
@@ -20,7 +20,7 @@
 public class BasicLib {
 
 	public static void register(LuaState lua) {
-		LuaTable t = lua.env();
+		LuaTable t = lua.global();
 		add( t, "print", new Object[0].getClass() );
 		add( t, "type", Object.class );
 		add( t, "load", LuaState.class, String.class );