changeset 326:db37d6aee4db

remove try-catch statement; add Luan.try() and Luan.pcall(); git-svn-id: https://luan-java.googlecode.com/svn/trunk@327 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Thu, 19 Mar 2015 00:01:57 +0000
parents 78a6a71afbfd
children 0be73ac9103d
files core/src/luan/cmd_line.luan core/src/luan/impl/LuanParser.java core/src/luan/impl/TryStmt.java core/src/luan/modules/BasicLuan.java core/src/luan/modules/Debug.luan core/src/luan/modules/Luan.luan web/src/luan/modules/web/web_run.luan web/src/luan/modules/web/web_shell.luan
diffstat 8 files changed, 100 insertions(+), 78 deletions(-) [+]
line wrap: on
line diff
--- a/core/src/luan/cmd_line.luan	Tue Mar 03 06:00:59 2015 +0000
+++ b/core/src/luan/cmd_line.luan	Thu Mar 19 00:01:57 2015 +0000
@@ -2,6 +2,7 @@
 local ipairs = Luan.ipairs
 local load = Luan.load
 local load_file = Luan.load_file
+local try = Luan.try
 require "luan:String"  -- for String methods
 local Table = require "luan:Table"
 local Io = require "luan:Io"
@@ -72,12 +73,15 @@
 	for j,v in ipairs(args) do
 		Luan.arg[j-i] = v
 	end
-	try
-		local main_file = load_file("file:"..file)
-		main_file( Table.unpack(Luan.arg) )
-	catch e do
-		Io.print_to(Io.stderr, e )
-	end
+	try {
+		function()
+			local main_file = load_file("file:"..file)
+			main_file( Table.unpack(Luan.arg) )
+		end;
+		catch = function(e)
+			Io.print_to(Io.stderr, e )
+		end;
+	}
 end
 if interactive then
 	Debug.debug("> ")
--- a/core/src/luan/impl/LuanParser.java	Tue Mar 03 06:00:59 2015 +0000
+++ b/core/src/luan/impl/LuanParser.java	Thu Mar 19 00:01:57 2015 +0000
@@ -251,7 +251,6 @@
 			|| (stmt=LocalFunctionStmt()) != null
 			|| (stmt=BreakStmt()) != null
 			|| (stmt=ForStmt()) != null
-			|| (stmt=TryStmt()) != null
 			|| (stmt=DoStmt()) != null
 			|| (stmt=WhileStmt()) != null
 			|| (stmt=FunctionStmt()) != null
@@ -373,22 +372,6 @@
 		return parser.success(stmt);
 	}
 
-	private Stmt TryStmt() throws ParseException {
-		parser.begin();
-		if( !Keyword("try",In.NOTHING) )
-			return parser.failure(null);
-		Stmt tryBlock = RequiredBlock();
-		RequiredKeyword("catch",In.NOTHING);
-		String name = RequiredName(In.NOTHING);
-		addSymbol(name);
-		RequiredKeyword("do",In.NOTHING);
-		Stmt catchBlock = RequiredBlock();
-		RequiredKeyword("end",In.NOTHING);
-		Stmt stmt = new TryStmt( tryBlock, symbolsSize()-1, catchBlock );
-		popSymbols(1);
-		return parser.success(stmt);
-	}
-
 	private Stmt DoStmt() throws ParseException {
 		parser.begin();
 		if( !Keyword("do",In.NOTHING) )
@@ -1095,7 +1078,6 @@
 	private static final Set<String> keywords = new HashSet<String>(Arrays.asList(
 		"and",
 		"break",
-		"catch",
 		"do",
 		"else",
 		"elseif",
@@ -1114,7 +1096,6 @@
 		"return",
 		"then",
 		"true",
-		"try",
 		"until",
 		"while"
 	));
--- a/core/src/luan/impl/TryStmt.java	Tue Mar 03 06:00:59 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-package luan.impl;
-
-import luan.Luan;
-import luan.LuanException;
-
-
-final class TryStmt implements Stmt {
-	private final Stmt tryBlock;
-	private final int iExceptionVar;
-	private final Stmt catchBlock;
-
-	TryStmt(Stmt tryBlock,int iExceptionVar,Stmt catchBlock) {
-		this.tryBlock = tryBlock;
-		this.iExceptionVar = iExceptionVar;
-		this.catchBlock = catchBlock;
-	}
-
-	@Override public void eval(LuanStateImpl luan) throws LuanException {
-		try {
-			tryBlock.eval(luan);
-		} catch(LuanException e) {
-			try {
-				luan.stackSet( iExceptionVar, e );
-				catchBlock.eval(luan);
-			} finally {
-				luan.stackClear(iExceptionVar,iExceptionVar+1);
-			}
-		}
-	}
-}
--- a/core/src/luan/modules/BasicLuan.java	Tue Mar 03 06:00:59 2015 +0000
+++ b/core/src/luan/modules/BasicLuan.java	Thu Mar 19 00:01:57 2015 +0000
@@ -15,6 +15,7 @@
 import luan.LuanException;
 import luan.LuanSource;
 import luan.LuanElement;
+import luan.LuanMethod;
 import luan.impl.LuanCompiler;
 
 
@@ -200,4 +201,56 @@
 		};
 	}
 
+	private LuanFunction fn(Object obj) {
+		return obj instanceof LuanFunction ? (LuanFunction)obj : null;
+	}
+
+	public static void try_(LuanState luan,LuanTable blocks) throws LuanException {
+		Utils.checkNotNull(luan,blocks);
+		Object obj = blocks.get(1);
+		if( obj == null )
+			throw luan.exception("missing 'try' value");
+		if( !(obj instanceof LuanFunction) )
+			throw luan.exception("bad 'try' value (function expected, got "+Luan.type(obj)+")");
+		LuanFunction tryFn = (LuanFunction)obj;
+		LuanFunction catchFn = null;
+		obj = blocks.get("catch");
+		if( obj != null ) {
+			if( !(obj instanceof LuanFunction) )
+				throw luan.exception("bad 'catch' value (function expected, got "+Luan.type(obj)+")");
+			catchFn = (LuanFunction)obj;
+		}
+		LuanFunction finallyFn = null;
+		obj = blocks.get("finally");
+		if( obj != null ) {
+			if( !(obj instanceof LuanFunction) )
+				throw luan.exception("bad 'finally' value (function expected, got "+Luan.type(obj)+")");
+			finallyFn = (LuanFunction)obj;
+		}
+		try {
+			luan.call(tryFn);
+		} catch(LuanException e) {
+			if( catchFn == null )
+				throw e;
+			luan.call(catchFn,new Object[]{e});
+		} finally {
+			if( finallyFn != null )
+				luan.call(finallyFn);
+		}
+	}
+
+	@LuanMethod public static Object[] pcall(LuanState luan,LuanFunction f,Object... args) {
+		try {
+			Object[] r = Luan.array(luan.call(f,args));
+			Object[] rtn = new Object[r.length+1];
+			rtn[0] = true;
+			for( int i=0; i<r.length; i++ ) {
+				rtn[i+1] = r[i];
+			}
+			return rtn;
+		} catch(LuanException e) {
+			return new Object[]{false,e};
+		}
+	}
+
 }
--- a/core/src/luan/modules/Debug.luan	Tue Mar 03 06:00:59 2015 +0000
+++ b/core/src/luan/modules/Debug.luan	Thu Mar 19 00:01:57 2015 +0000
@@ -1,5 +1,6 @@
 local Luan = require "luan:Luan"
 local load = Luan.load
+local try = Luan.try
 local Io = require "luan:Io"
 local print = Io.print
 local Table = require "luan:Table"
@@ -18,12 +19,15 @@
 	end
 	local env = {}
 	for line in console do
-		try
-			local fn = load(line,"stdin",env,true)
-			print_if_something( fn() )
-		catch e do
-			print(e)
-		end
+		try {
+			function()
+				local fn = load(line,"stdin",env,true)
+				print_if_something( fn() )
+			end;
+			catch = function(e)
+				print(e)
+			end;
+		}
 	end
 end
 
--- a/core/src/luan/modules/Luan.luan	Tue Mar 03 06:00:59 2015 +0000
+++ b/core/src/luan/modules/Luan.luan	Thu Mar 19 00:01:57 2015 +0000
@@ -16,6 +16,7 @@
 load = BasicLuan.load
 load_file = BasicLuan.load_file
 pairs = BasicLuan.pairs
+pcall = BasicLuan.pcall
 range = BasicLuan.range
 raw_equal = BasicLuan.raw_equal
 raw_get = BasicLuan.raw_get
@@ -26,6 +27,7 @@
 to_boolean = BasicLuan.to_boolean
 to_number = BasicLuan.to_number
 to_string = BasicLuan.to_string
+try = BasicLuan.try_
 type = BasicLuan.type
 values = BasicLuan.values
 
--- a/web/src/luan/modules/web/web_run.luan	Tue Mar 03 06:00:59 2015 +0000
+++ b/web/src/luan/modules/web/web_run.luan	Thu Mar 19 00:01:57 2015 +0000
@@ -1,5 +1,6 @@
 local Luan = require "luan:Luan"
 local load = Luan.load
+local try = Luan.try
 local Io = require "luan:Io"
 local print = Io.print
 local Http = require "luan:web/Http"
@@ -59,14 +60,17 @@
 		request = Http.request;
 		response = Http.response;
 	}
-	try
-		local run = load(code,"<web_run>",env)
-		run()
-	catch e do
-		Http.response.content_type = "text/plain"
-		print(e)
-		print()
-		print()
-		print_with_line_numbers(code)
-	end
+	try {
+		function()
+			local run = load(code,"<web_run>",env)
+			run()
+		end;
+		catch = function(e)
+			Http.response.content_type = "text/plain"
+			print(e)
+			print()
+			print()
+			print_with_line_numbers(code)
+		end;
+	}
 end
--- a/web/src/luan/modules/web/web_shell.luan	Tue Mar 03 06:00:59 2015 +0000
+++ b/web/src/luan/modules/web/web_shell.luan	Thu Mar 19 00:01:57 2015 +0000
@@ -1,6 +1,7 @@
 local Luan = require "luan:Luan"
 local ipairs = Luan.ipairs
 local load = Luan.load
+local try = Luan.try
 local Io = require "luan:Io"
 local print = Io.print
 local Debug = require "luan:Debug"
@@ -25,13 +26,16 @@
 				end
 			end
 			print( "% "..cmd )
-			try
-				local line = load(cmd,"<web_shell>",env,true)
-				Debug.print_if_something( line() )
-			catch e do
-				Io.print_to(Io.stderr,e)
-				print(e)
-			end
+			try {
+				function()
+					local line = load(cmd,"<web_shell>",env,true)
+					Debug.print_if_something( line() )
+				end;
+				catch = function(e)
+					Io.print_to(Io.stderr,e)
+					print(e)
+				end;
+			}
 		end
 	end