diff src/luan/interp/LuaParser.java @ 12:9cea1aea5eef

CmdLine can run files git-svn-id: https://luan-java.googlecode.com/svn/trunk@13 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Fri, 23 Nov 2012 10:37:40 +0000
parents b7d7069fee58
children 2ddf85634d20
line wrap: on
line diff
--- a/src/luan/interp/LuaParser.java	Thu Nov 22 10:51:56 2012 +0000
+++ b/src/luan/interp/LuaParser.java	Fri Nov 23 10:37:40 2012 +0000
@@ -1,5 +1,8 @@
 package luan.interp;
 
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Arrays;
 import java.util.List;
 import java.util.ArrayList;
 import java.util.Scanner;
@@ -20,14 +23,64 @@
 		return Sequence(
 			Spaces(),
 			FirstOf(
-				Sequence( Expressions(), EOI ),
-				Sequence( Stmt(), EOI )
+				Sequence( ExpList(), EOI ),
+				Sequence( Chunk(), EOI )
 			)
 		);
 	}
 
+	Rule Chunk() {
+		return Sequence(
+			push(new ArrayList<Stmt>()),
+			Optional( Stmt() ),
+			ZeroOrMore(
+				StmtSep(),
+				Optional( Stmt() )
+			),
+			push( newChunk() )
+		);
+	}
+
+	boolean addStmt() {
+		Stmt stmt = (Stmt)pop();
+		@SuppressWarnings("unchecked")
+		List<Stmt> stmts = (List<Stmt>)peek();
+		stmts.add(stmt);
+		return true;
+	}
+
+	Stmt newChunk() {
+		@SuppressWarnings("unchecked")
+		List<Stmt> stmts = (List<Stmt>)peek();
+		switch( stmts.size() ) {
+		case 0:
+			return Stmt.EMPTY;
+		case 1:
+			return stmts.get(0);
+		default:
+			return new Block(stmts.toArray(new Stmt[0]));
+		}
+	}
+
+	Rule StmtSep() {
+		return Sequence( OneOrMore(AnyOf(";\r\n")), Spaces() );
+	}
+
 	Rule Stmt() {
-		return SetStmt();
+		return Sequence(
+			FirstOf(
+				SetStmt(),
+				ExpressionsStmt()
+			),
+			addStmt()
+		);
+	}
+
+	Rule ExpressionsStmt() {
+		return Sequence(
+			ExpList(),
+			push( new ExpressionsStmt((Expressions)pop()) )
+		);
 	}
 
 	Rule SetStmt() {
@@ -332,7 +385,7 @@
 					FirstOf( NameStart(), Digit() )
 				)
 			),
-			push( new ConstExpr(match()) ),
+			pushNameExpr(),
 			Spaces()
 		);
 	}
@@ -345,6 +398,38 @@
 		);
 	}
 
+	boolean pushNameExpr() {
+		String name = match();
+		if( keywords.contains(name) )
+			return false;
+		return push( new ConstExpr(name) );
+	}
+
+	private static final Set<String> keywords = new HashSet<String>(Arrays.asList(
+		"and",
+		"break",
+		"do",
+		"else",
+		"elseif",
+		"end",
+		"false",
+		"for",
+		"function",
+		"goto",
+		"if",
+		"in",
+		"local",
+		"nil",
+		"not",
+		"or",
+		"repeat",
+		"return",
+		"then",
+		"true",
+		"until",
+		"while"
+	));
+
 	Rule LiteralExpr() {
 		return Sequence(
 			Literal(), Spaces(),
@@ -493,10 +578,16 @@
 		return true;
 	}
 
-	public Rule Spaces() {
+	Rule Spaces() {
 		return ZeroOrMore(AnyOf(" \t"));
 	}
 
+	// for debugging
+	boolean print(String s) {
+		System.out.println(s);
+		return true;
+	}
+
 	// for testing
 	public static void main(String[] args) throws Exception {
 		LuaParser parser = Parboiled.createParser(LuaParser.class);