diff core/src/luan/LuanException.java @ 481:5d4a78c93383

luan errors are now tables
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 11 May 2015 20:26:36 -0600
parents 9fb218211763
children 2e17b54e69d9
line wrap: on
line diff
--- 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();
 	}
+
 }