view src/luan/Luan.java @ 1306:97e7c25e9e70

start version 0.24
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 23 Jan 2019 12:48:47 -0700
parents 9fa8b8389578
children f41919741100
line wrap: on
line source

package luan;

import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.LinkedHashMap;
import java.util.Set;
import java.util.Arrays;
import java.util.Iterator;
import luan.modules.BasicLuan;
import luan.modules.Utils;
import luan.impl.LuanCompiler;


public final class Luan {

	public static void main(String[] args) throws LuanException {
		doFile( "classpath:luan/cmd_line.luan", args );
	}

	public static void doFile(String uri,String... args) throws LuanException {
		LuanState luan = new LuanState();
		LuanFunction fn = (LuanFunction)BasicLuan.load_file(luan,uri);
		fn.call(luan,args);
	}

	public static Object first(Object obj) {
		if( !(obj instanceof Object[]) )
			return obj;
		Object[] a = (Object[])obj;
		return a.length==0 ? null : a[0];
	}

	public static Object[] array(Object obj) {
		return obj instanceof Object[] ? (Object[])obj : new Object[]{obj};
	}

	public static String type(Object obj) {
		if( obj == null )
			return "nil";
		if( obj instanceof String )
			return "string";
		if( obj instanceof Boolean )
			return "boolean";
		if( obj instanceof Number )
			return "number";
		if( obj instanceof LuanTable )
			return "table";
		if( obj instanceof LuanFunction )
			return "function";
		if( obj instanceof byte[] )
			return "binary";
		return "java";
	}

	public static String toString(Number n) {
		if( n instanceof Integer )
			return n.toString();
		int i = n.intValue();
		if( i == n.doubleValue() )
			return Integer.toString(i);
		String s = n.toString();
		int iE = s.indexOf('E');
		String ending  = null;
		if( iE != -1 ) {
			ending = s.substring(iE);
			s = s.substring(0,iE);
		}
		if( s.endsWith(".0") )
			s = s.substring(0,s.length()-2);
		if( ending != null )
			s += ending;
		return s;
	}

	public static Integer asInteger(Object obj) {
		if( obj instanceof Integer )
			return (Integer)obj;
		if( !(obj instanceof Number) )
			return null;
		Number n = (Number)obj;
		int i = n.intValue();
		return i==n.doubleValue() ? Integer.valueOf(i) : null;
	}

	public static String stringEncode(String s) {
		s = s.replace("\\","\\\\");
		s = s.replace("\u0007","\\a");
		s = s.replace("\b","\\b");
		s = s.replace("\f","\\f");
		s = s.replace("\n","\\n");
		s = s.replace("\r","\\r");
		s = s.replace("\t","\\t");
		s = s.replace("\u000b","\\v");
		s = s.replace("\"","\\\"");
		s = s.replace("\'","\\'");
		return s;
	}


	// from LuanState

	public static Boolean checkBoolean(Object obj) throws LuanException {
		if( obj instanceof Boolean )
			return (Boolean)obj;
		throw new LuanException("attempt to use a " + Luan.type(obj) + " value as a boolean" );
	}

	public static String checkString(Object obj) throws LuanException {
		if( obj instanceof String )
			return (String)obj;
		throw new LuanException("attempt to use a " + Luan.type(obj) + " value as a string" );
	}

	public static LuanFunction checkFunction(Object obj) throws LuanException {
		if( obj instanceof LuanFunction )
			return (LuanFunction)obj;
		throw new LuanException("attempt to call a " + Luan.type(obj) + " value" );
	}

	public static LuanFunction load(String text,String sourceName,LuanTable env)
		throws LuanException
	{
		return LuanCompiler.compile(text,sourceName,env);
	}

	public static LuanFunction load(String text,String sourceName)
		throws LuanException
	{
		return load(text,sourceName,null);
	}

/*
	public static Object toLuan(Object obj) throws LuanException {
		if( !type(obj).equals("java") )
			return obj;
		LuanTable tbl = new LuanTable();
		if( obj instanceof Map ) {
			Map map = (Map)obj;
			for( Object stupid : map.entrySet() ) {
				Map.Entry entry = (Map.Entry)stupid;
				Object key = entry.getKey();
				Object value = entry.getValue();
				if( key != null && value != null )
					tbl.rawPut(toLuan(key),toLuan(value));
			}
			return tbl;
		}
		if( obj instanceof Set ) {
			Set set = (Set)obj;
			for( Object el : set ) {
				if( el != null )
					tbl.rawPut(toLuan(el),Boolean.TRUE);
			}
			return tbl;
		}
		List list;
		if( obj instanceof List ) {
			list = (List)obj;
		} else {
			Class cls = obj.getClass();
			if( cls.isArray() && !cls.getComponentType().isPrimitive() ) {
				Object[] a = (Object[])obj;
				list = Arrays.asList(a);
			} else
				throw new LuanException("can't convert type "+obj.getClass().getName()+" to luan");
		}
		int n = list.size();
		for( int i=0; i<n; i++ ) {
			Object val = list.get(i);
			if( val != null )
				tbl.rawPut(i+1,toLuan(val));
		}
		return tbl;
	}
*/

	public static Object toJava(Object obj) throws LuanException {
		if( !(obj instanceof LuanTable) )
			return obj;
		LuanTable tbl = (LuanTable)obj;
		if( tbl.isList() ) {
			List list = new ArrayList();
			for( Object el : tbl.asList() ) {
				list.add( toJava(el) );
			}
			return list;
		} else {
			Map map = new LinkedHashMap();
			Iterator<Map.Entry> iter = tbl.rawIterator();
			while( iter.hasNext() ) {
				Map.Entry entry = iter.next();
				map.put( toJava(entry.getKey()), toJava(entry.getValue()) );
			}
			return map;
		}
	}
/*
	public static LuanTable table(LuanTable v) throws LuanException {
		Utils.checkNotNull(v);
		return v;
	}
*/

	private Luan() {}  // never
}