changeset 9:600676034a1a

add variables and tables git-svn-id: https://luan-java.googlecode.com/svn/trunk@10 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Wed, 21 Nov 2012 09:40:33 +0000
parents 8896068e0a4b
children 8217d8485715
files src/luan/interp/EnvExpr.java src/luan/interp/LuaParser.java
diffstat 2 files changed, 117 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/luan/interp/EnvExpr.java	Wed Nov 21 06:57:09 2012 +0000
+++ b/src/luan/interp/EnvExpr.java	Wed Nov 21 09:40:33 2012 +0000
@@ -4,6 +4,9 @@
 
 
 final class EnvExpr extends Expr {
+	static final EnvExpr INSTANCE = new EnvExpr();
+
+	private EnvExpr() {}
 
 	@Override Object eval(LuaState lua) {
 		return lua.env();
--- a/src/luan/interp/LuaParser.java	Wed Nov 21 06:57:09 2012 +0000
+++ b/src/luan/interp/LuaParser.java	Wed Nov 21 09:40:33 2012 +0000
@@ -1,5 +1,7 @@
 package luan.interp;
 
+import java.util.List;
+import java.util.ArrayList;
 import java.util.Scanner;
 import org.parboiled.BaseParser;
 import org.parboiled.Parboiled;
@@ -102,11 +104,122 @@
 
 	Rule SingleExpr() {
 		return FirstOf(
-			Sequence( '(', Spaces(), Expr(), ')', Spaces() ),
+			TableExpr(),
+			PrefixExpr(),
 			LiteralExpr()
 		);
 	}
 
+	Rule TableExpr() {
+		return Sequence(
+			'{', Spaces(),
+			push( new ArrayList<TableExpr.Field>() ),
+			push( 1.0 ),  // counter
+			Optional(
+				Field(),
+				ZeroOrMore(
+					FieldSep(),
+					Field()
+				),
+				Optional( FieldSep() )
+			),
+			'}', Spaces(),
+			push( newTableExpr() )
+		);
+	}
+
+	TableExpr newTableExpr() {
+		pop();  // counter
+		@SuppressWarnings("unchecked")
+		List<TableExpr.Field> list = (List<TableExpr.Field>)pop();
+		return new TableExpr(list.toArray(new TableExpr.Field[0]));
+	}
+
+	Rule FieldSep() {
+		return Sequence( AnyOf(",;"), Spaces() );
+	}
+
+	Rule Field() {
+		return FirstOf(
+			Sequence(
+				FirstOf( SubExpr(), Name() ),
+				'=', Spaces(), Expr(),
+				addField()
+			),
+			Sequence(
+				Expr(),
+				addIndexedField()
+			)
+		);
+	}
+
+	boolean addField() {
+		TableExpr.Field field = new TableExpr.Field( (Expr)pop(1), (Expr)pop() );
+		@SuppressWarnings("unchecked")
+		List<TableExpr.Field> list = (List<TableExpr.Field>)peek(1);
+		list.add(field);
+		return true;
+	}
+
+	boolean addIndexedField() {
+		Expr val = (Expr)pop();
+		double i = (Double)pop();
+		TableExpr.Field field = new TableExpr.Field( new ConstExpr(new LuaNumber(i)), val );
+		push( i + 1 );
+		@SuppressWarnings("unchecked")
+		List<TableExpr.Field> list = (List<TableExpr.Field>)peek(1);
+		list.add(field);
+		return true;
+	}
+
+	Rule PrefixExpr() {
+		return Sequence(
+			FirstOf(
+				Sequence( '(', Spaces(), Expr(), ')', Spaces() ),
+				Var()
+			),
+			ZeroOrMore(
+				FirstOf(
+					SubExpr(),
+					Sequence( '.', Spaces(), Name() )
+				),
+				push( new GetExpr( (Expr)pop(1), (Expr)pop() ) )
+			)
+		);
+	}
+
+	Rule SubExpr() {
+		return Sequence( '[', Spaces(), Expr(), ']', Spaces() );
+	}
+
+	Rule Var() {
+		return Sequence(
+			Name(),
+			push( new GetExpr( EnvExpr.INSTANCE, (Expr)pop() ) )
+		);
+	}
+
+	Rule Name() {
+		return Sequence(
+			Sequence(
+				NameStart(),
+				ZeroOrMore(
+					FirstOf( NameStart(), Digit() )
+				)
+			),
+			push( new ConstExpr(match()) ),
+			Spaces()
+		);
+	}
+
+	Rule NameStart() {
+		return FirstOf(
+			CharRange('a', 'z'),
+			CharRange('A', 'Z'),
+			'_'
+		);
+	}
+
 	Rule LiteralExpr() {
 		return Sequence(
 			Literal(), Spaces(),