changeset 481:5d4a78c93383

luan errors are now tables
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 11 May 2015 20:26:36 -0600
parents 44caaa6a3d92
children 7e9fcfbf22ec
files core/src/luan/Luan.java core/src/luan/LuanBit.java core/src/luan/LuanElement.java core/src/luan/LuanException.java core/src/luan/LuanState.java core/src/luan/StackTraceElement.java core/src/luan/modules/BasicLuan.java core/src/luan/modules/Luan.luan lucene/src/luan/modules/lucene/LuceneSearcher.java web/src/luan/modules/web/LuanHandler.java
diffstat 10 files changed, 101 insertions(+), 92 deletions(-) [+]
line wrap: on
line diff
--- a/core/src/luan/Luan.java	Mon May 11 16:43:04 2015 -0600
+++ b/core/src/luan/Luan.java	Mon May 11 20:26:36 2015 -0600
@@ -6,16 +6,10 @@
 
 public final class Luan {
 
-	public static void main(String[] args) {
+	public static void main(String[] args) throws LuanException {
 		LuanState luan = LuanState.newInstance();
-		try {
-			LuanFunction standalone = (LuanFunction)BasicLuan.load_file(luan,"classpath:luan/cmd_line.luan",null);
-			luan.call(standalone,args);
-		} catch(LuanException e) {
-			System.err.println(e.getFullMessage());
-//			e.printStackTrace();
-			System.exit(-1);
-		}
+		LuanFunction standalone = (LuanFunction)BasicLuan.load_file(luan,"classpath:luan/cmd_line.luan",null);
+		luan.call(standalone,args);
 	}
 
 	public static Object first(Object obj) {
--- a/core/src/luan/LuanBit.java	Mon May 11 16:43:04 2015 -0600
+++ b/core/src/luan/LuanBit.java	Mon May 11 20:26:36 2015 -0600
@@ -12,18 +12,18 @@
 		this.el = el;
 	}
 
-	public LuanException exception(Object msg) {
+	public LuanException exception(Object msg) throws LuanException {
 		return new LuanException(this,msg);
 	}
 
-	public String stackTrace() {
-		StringBuilder buf = new StringBuilder();
+	public StackTraceElement[] stackTrace() {
+		List<StackTraceElement> stackTrace = luan.stackTrace;
 		if( el != null )
-			buf.append( "\n\t" ).append( el.toString(null) );
-		for( int i  = luan.stackTrace.size() - 1; i>=0; i-- ) {
-			buf.append( "\n\t" ).append( luan.stackTrace.get(i) );
-		}
-		return buf.toString();
+			stackTrace.add(new StackTraceElement(el,null));
+		StackTraceElement[] rtn = stackTrace.toArray(new StackTraceElement[0]);
+		if( el != null )
+			stackTrace.remove(stackTrace.size()-1);
+		return rtn;
 	}
 
 	public void dumpStack() {
@@ -93,10 +93,6 @@
 			return "nil";
 		if( obj instanceof Number )
 			return Luan.toString((Number)obj);
-		if( obj instanceof LuanException ) {
-			LuanException le = (LuanException)obj;
-			return le.getFullMessage();
-		}
 		if( obj instanceof byte[] )
 			return "binary: " + Integer.toHexString(obj.hashCode());
 		return obj.toString();
--- a/core/src/luan/LuanElement.java	Mon May 11 16:43:04 2015 -0600
+++ b/core/src/luan/LuanElement.java	Mon May 11 20:26:36 2015 -0600
@@ -27,11 +27,7 @@
 		return text!=null ? text : source.text.substring(start,end);
 	}
 
-	private String location() {
-		return source.name + " line " + lineNumber();
-	}
-
-	private int lineNumber() {
+	int lineNumber() {
 		int line = 0;
 		int i = -1;
 		do {
@@ -41,11 +37,4 @@
 		return line;
 	}
 
-	String toString(String fnName) {
-		String s = location();
-		if( fnName != null )
-			s += " in call to '" + fnName + "'";
-		return s;
-	}
-
 }
--- a/core/src/luan/LuanException.java	Mon May 11 16:43:04 2015 -0600
+++ b/core/src/luan/LuanException.java	Mon May 11 20:26:36 2015 -0600
@@ -4,59 +4,87 @@
 import java.io.PrintWriter;
 
 
-public final class LuanException extends Exception {
-	private final String stackTrace;
+public final class LuanException extends Exception implements DeepCloneable {
+	private LuanTable table = new LuanTable();
 
-	LuanException(LuanBit bit,Object msg) {
-		super(message(msg),cause(msg));
-		stackTrace = stackTrace(bit,msg);
-	}
-
-	@Override public String getMessage() {
-		return super.getMessage() + stackTrace;
+	private LuanException(String msg,Throwable cause) {
+		super(msg,cause);
 	}
 
-	public String getFullMessage() {
-		String msg = getMessage();
-		Throwable cause = getCause();
-		if( cause != null ) {
-			msg += "\nCaused by: ";
-			StringWriter sw = new StringWriter();
-			cause.printStackTrace(new PrintWriter(sw));
-			msg += sw;
+	LuanException(LuanBit bit,Object msg) throws LuanException {
+		this( bit.luan.toString(msg), msg instanceof Throwable ? (Throwable)msg : null );
+		if( msg instanceof LuanException )
+			throw new RuntimeException();
+		table.rawPut("message",msg);
+		for( StackTraceElement ste : bit.stackTrace() ) {
+			LuanTable tbl = new LuanTable();
+			tbl.rawPut( "source", ste.call.source.name );
+			tbl.rawPut( "line", ste.call.lineNumber() );
+			tbl.rawPut( "call_to", ste.fnName );
+			table.rawPut( table.rawLength() + 1, tbl );
 		}
-		return msg;
-	}
-
-	private String message() {
-		return super.getMessage();
-	}
-
-	private static Throwable cause(Object msg) {
-		return msg instanceof Throwable ? (Throwable)msg : null;
-	}
-
-	private static String message(Object msg) {
-		if( msg instanceof LuanException ) {
-			LuanException le = (LuanException)msg;
-			return le.message();
-/*
-		} else if( msg instanceof Throwable ) {
-			Throwable t = (Throwable)msg;
-			return t.getMessage();
-*/
-		} else {
-			return msg.toString();
+		LuanTable metatable = new LuanTable();
+		table.setMetatable(metatable);
+		try {
+			table.rawPut( "throw", new LuanJavaFunction(
+				LuanException.class.getMethod( "throwThis" ), this
+			) );
+			metatable.rawPut( "__to_string", new LuanJavaFunction(
+				LuanException.class.getMethod( "__to_string", LuanState.class, LuanTable.class ), null
+			) );
+		} catch(NoSuchMethodException e) {
+			throw new RuntimeException(e);
 		}
 	}
 
-	private static String stackTrace(LuanBit bit,Object msg) {
+	@Override public LuanException shallowClone() {
+		return new LuanException(getMessage(),getCause());
+	}
+
+	@Override public void deepenClone(DeepCloneable dc,DeepCloner cloner) {
+		LuanException clone = (LuanException)dc;
+		clone.table = (LuanTable)cloner.get(table);
+	}
+
+	public LuanTable table() {
+		return table;
+	}
+
+	public void throwThis() throws LuanException {
+		throw this;
+	}
+
+	public String getFullMessage(LuanState luan) {
+		try {
+			return __to_string(luan,table);
+		} catch(LuanException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	public static String __to_string(LuanState luan,LuanTable table) throws LuanException {
 		StringBuilder buf = new StringBuilder();
-		buf.append( bit.stackTrace() );
-		if( msg instanceof LuanException ) {
-			LuanException le = (LuanException)msg;
-			buf.append( "\ncaused by:" ).append( le.stackTrace );
+
+		Object msg = table.rawGet("message");
+		buf.append( luan.toString(msg) );
+
+		for( int i = table.rawLength(); i>=1; i-- ) {
+			LuanTable tbl = (LuanTable)table.rawGet(i);
+			buf.append( "\n\t" ).append( tbl.rawGet("source") ).append( " line " ).append( tbl.rawGet("line") );
+			Object callTo = tbl.rawGet("call_to");
+			if( callTo != null )
+				buf.append( " in call to '" ).append( callTo ).append( "'" );
 		}
+
+		if( msg instanceof Throwable ) {
+			buf.append( "\nCaused by: " );
+			Throwable cause = (Throwable)msg;
+			StringWriter sw = new StringWriter();
+			cause.printStackTrace(new PrintWriter(sw));
+			buf.append( sw );
+		}
+
 		return buf.toString();
 	}
+
 }
--- a/core/src/luan/LuanState.java	Mon May 11 16:43:04 2015 -0600
+++ b/core/src/luan/LuanState.java	Mon May 11 20:26:36 2015 -0600
@@ -52,7 +52,7 @@
 
 	private final LuanBit JAVA = bit(null);
 
-	public LuanException exception(Object msg) {
+	public LuanException exception(Object msg) throws LuanException {
 		return JAVA.exception(msg);
 	}
 
--- a/core/src/luan/StackTraceElement.java	Mon May 11 16:43:04 2015 -0600
+++ b/core/src/luan/StackTraceElement.java	Mon May 11 20:26:36 2015 -0600
@@ -9,8 +9,4 @@
 		this.call = call;
 		this.fnName = fnName;
 	}
-
-	@Override public String toString() {
-		return call.toString(fnName);
-	}
 }
--- a/core/src/luan/modules/BasicLuan.java	Mon May 11 16:43:04 2015 -0600
+++ b/core/src/luan/modules/BasicLuan.java	Mon May 11 20:26:36 2015 -0600
@@ -108,8 +108,8 @@
 		return luan.toString(v);
 	}
 
-	public static void error(LuanState luan,Object msg) throws LuanException {
-		throw luan.exception(msg);
+	public static LuanTable new_error(LuanState luan,Object msg) throws LuanException {
+		return luan.exception(msg).table();
 	}
 
 	public static String assert_string(LuanState luan,String v) throws LuanException {
@@ -204,7 +204,7 @@
 		} catch(LuanException e) {
 			if( catchFn == null )
 				throw e;
-			return luan.call(catchFn,new Object[]{e});
+			return luan.call(catchFn,new Object[]{e.table()});
 		} finally {
 			if( finallyFn != null )
 				luan.call(finallyFn);
@@ -221,7 +221,7 @@
 			}
 			return rtn;
 		} catch(LuanException e) {
-			return new Object[]{false,e};
+			return new Object[]{false,e.table()};
 		}
 	}
 
--- a/core/src/luan/modules/Luan.luan	Mon May 11 16:43:04 2015 -0600
+++ b/core/src/luan/modules/Luan.luan	Mon May 11 20:26:36 2015 -0600
@@ -8,11 +8,11 @@
 assert_number = BasicLuan.assert_number
 assert_string = BasicLuan.assert_string
 assert_table = BasicLuan.assert_table
-error = BasicLuan.error
 get_metatable = BasicLuan.get_metatable
 ipairs = BasicLuan.ipairs
 load = BasicLuan.load
 load_file = BasicLuan.load_file
+new_error = BasicLuan.new_error
 pairs = BasicLuan.pairs
 pcall = BasicLuan.pcall
 range = BasicLuan.range
@@ -32,6 +32,10 @@
 
 VERSION = do_file "classpath:luan/version.luan"
 
+function error(message)
+	new_error(message).throw()
+end
+
 local error = error
 
 function assert(v,message)
--- a/lucene/src/luan/modules/lucene/LuceneSearcher.java	Mon May 11 16:43:04 2015 -0600
+++ b/lucene/src/luan/modules/lucene/LuceneSearcher.java	Mon May 11 20:26:36 2015 -0600
@@ -92,12 +92,14 @@
 			Collector col = new MyCollector() {
 				@Override public void collect(int doc) {
 					try {
-						LuanTable docTbl = doc(luan,docBase+doc);
-						luan.call(fn,new Object[]{docTbl});
+						try {
+							LuanTable docTbl = doc(luan,docBase+doc);
+							luan.call(fn,new Object[]{docTbl});
+						} catch(IOException e) {
+							throw luan.exception(e);
+						}
 					} catch(LuanException e) {
 						throw new LuanRuntimeException(e);
-					} catch(IOException e) {
-						throw new LuanRuntimeException(luan.exception(e));
 					}
 				}
 			};
--- a/web/src/luan/modules/web/LuanHandler.java	Mon May 11 16:43:04 2015 -0600
+++ b/web/src/luan/modules/web/LuanHandler.java	Mon May 11 20:26:36 2015 -0600
@@ -31,7 +31,7 @@
 			if( !HttpServicer.service(luan,request,response,"site:"+target) )
 				return;
 		} catch(LuanException e) {
-			String err = e.getFullMessage();
+			String err = e.getFullMessage(luan);
 			logger.error(err);
 			response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,err);
 		}