view src/luan/LuanException.java @ 1091:20d5968e65cc

add end_do, end_for, end_function, end_if, end_while
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 02 Jan 2017 21:28:30 -0700
parents 6a7c6879158d
children 4cf541886663
line wrap: on
line source

package luan;

import java.io.StringWriter;
import java.io.PrintWriter;
import java.util.List;
import java.util.ArrayList;


public final class LuanException extends Exception implements LuanCloneable {
	private LuanTable table;

	public LuanException(String msg,Throwable cause) {
		super(msg,cause);
	}

	public LuanException(String msg) {
		super(msg);
	}

	public LuanException(Throwable cause) {
		super(cause);
	}

	private LuanException(String msg,Throwable cause,int nonsense) {
		super(msg,cause);
	}

	@Override public LuanException shallowClone() {
		return new LuanException(getMessage(),getCause(),99);
	}

	@Override public void deepenClone(LuanCloneable dc,LuanCloner cloner) {
		LuanException clone = (LuanException)dc;
		clone.table = (LuanTable)cloner.clone(table);
	}

	public LuanTable table() {
		if( table==null ) {
			table = new LuanTable();
			table.rawPut( "java", this );
			LuanTable metatable = new LuanTable();
			table.setMetatable(metatable);
			try {
				table.rawPut( "get_message", new LuanJavaFunction(
					LuanException.class.getMethod( "getMessage" ), this
				) );
				table.rawPut( "throw", new LuanJavaFunction(
					LuanException.class.getMethod( "throwThis" ), this
				) );
				table.rawPut( "get_java_stack_trace_string", new LuanJavaFunction(
					LuanException.class.getMethod( "getJavaStackTraceString" ), this
				) );
				metatable.rawPut( "__to_string", new LuanJavaFunction(
					LuanException.class.getMethod( "getFullMessage" ), this
				) );
			} catch(NoSuchMethodException e) {
				throw new RuntimeException(e);
			}
		}
		return table;
	}

	public void throwThis() throws LuanException {
		throw this;
	}

	public String getFullMessage() {
		return getLuanStackTraceString();
//		return getLuanStackTraceString()+"\n"+getJavaStackTraceString();
/*
		StringBuilder buf = new StringBuilder();

		Object msg = table.rawGet("message");
		String msgStr = (String)table.rawGet("message_string");
		buf.append( msgStr );

		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();
*/
	}

	public String getJavaStackTraceString() {
		return getJavaStackTraceString(this);
	}

	private static String getJavaStackTraceString(Throwable th) {
		StringWriter sw = new StringWriter();
		th.printStackTrace(new PrintWriter(sw));
		return sw.toString();
	}

	public static List<StackTraceElement> justLuan(StackTraceElement[] orig) {
		List<StackTraceElement> list = new ArrayList<StackTraceElement>();
		for( int i=0; i<orig.length; i++ ) {
			StackTraceElement ste = orig[i];
			if( !ste.getClassName().startsWith("luan.impl.EXP") )
				continue;
			list.add(ste);
			if( !ste.getMethodName().equals("doCall") )
				i++;
		}
		return list;
	}

	public static String toString(StackTraceElement ste) {
		StringBuilder sb = new StringBuilder();
		sb.append( ste.getFileName() ).append( " line " ).append( ste.getLineNumber() );
		String method = ste.getMethodName();
		if( !method.equals("doCall") )
			sb.append( " in function '" ).append( method.substring(1) ).append( "'" );
		return sb.toString();
	}

	public String getLuanStackTraceString() {
		StringBuilder sb = new StringBuilder();
		sb.append( getMessage() );
		for( StackTraceElement ste : justLuan(getStackTrace()) ) {
			sb.append( "\n\t" ).append( toString(ste) );
		}
		Throwable cause = getCause();
		if( cause != null )
			sb.append( "\nCaused by: " ).append( getJavaStackTraceString(cause) );
		return sb.toString();
	}

	public static String currentSource() {
		LuanException ex = new LuanException("currentSource");
		List<StackTraceElement> st = ex.justLuan(ex.getStackTrace());
		return st.isEmpty() ? null : st.get(0).getFileName();
	}

}