diff src/nabble/naml/compiler/Template.java @ 0:7ecd1a4ef557

add content
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 21 Mar 2019 19:15:52 -0600
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/nabble/naml/compiler/Template.java	Thu Mar 21 19:15:52 2019 -0600
@@ -0,0 +1,141 @@
+package nabble.naml.compiler;
+
+import fschmidt.util.java.Stack;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+
+public final class Template extends Compiler.Traceable {
+	private final Program program;
+	private final Chunk chunk;
+	private final Class[] baseClasses;
+	public final Macro macro;
+
+	Template(Compiler compiler,Program program,Chunk chunk,Class[] baseClasses,Macro macro) {
+		super(compiler);
+		this.program = program;
+		this.chunk = chunk;
+		this.baseClasses = baseClasses;
+		this.macro = macro;
+	}
+
+	public String name() {
+		return macro.name;
+	}
+
+	public final Program program() {
+		return program;
+	}
+
+	public final void run(IPrintWriter out,Map<String,Object> args,Object... base) {
+		run(0,Encoder.TEXT,out,args,base);
+		out.flush();
+	}
+
+	final void run(int callDepth,Encoder encoder,IPrintWriter out,Map<String,Object> args,Object... base) {
+		Set<String> argNames = macro.parameters;
+		if( !argNames.containsAll(args.keySet()) ) {
+			Set<String> badArgs = new HashSet<String>(args.keySet());
+			badArgs.removeAll(argNames);
+			throw new RuntimeException("invalid args: "+badArgs);
+		}
+		Stack<StackTrace> stack = StackTrace.stack();
+		stack.push(stackTrace);
+		try {
+			check(base);
+			RunState runState = new RunStateImpl(this,callDepth,encoder);
+			for( Object obj : base ) {
+				runState.push(obj);
+			}
+			for( Map.Entry<String,Object> entry : args.entrySet() ) {
+				String key = entry.getKey();
+				Object value = entry.getValue();
+				if( value instanceof String ) {
+					runState.putArg( key, (String)value );
+				} else {
+					runState.putArg( key, runState.saveNamespace(value) );
+				}
+			}
+			chunk.run(out,runState);
+		} catch (ExitException e) {
+			// do nothing.
+		} finally {
+			stack.pop();
+		}
+	}
+
+	private void check(Object[] base) {
+		if( base.length != baseClasses.length )
+			throw new TemplateRuntimeException("base mismatch base.length="+base.length+" baseClasses.length="+baseClasses.length);
+		for( int i=0; i<baseClasses.length; i++ ) {
+			if( !baseClasses[i].isInstance(base[i]) )
+				throw new TemplateRuntimeException("base mismatch");
+		}
+	}
+
+//	private static void handle(Exception e) {
+//		if( e instanceof RuntimeException )
+//			throw (RuntimeException)e;
+//		throw new TemplateRuntimeException(e);
+//	}
+
+	public static String stringValue(Object obj) {
+		if( obj==null )
+			return null;
+		return obj.toString();
+	}
+
+	public static boolean booleanValue(String s)
+		throws BooleanFormatException
+	{
+		if( s.equalsIgnoreCase("true") )
+			return true;
+		if( s.equalsIgnoreCase("false") )
+			return false;
+		throw new BooleanFormatException("For input string: \""+s+"\"");
+	}
+
+	public static boolean booleanValue(Object obj)
+		throws BooleanFormatException
+	{
+		String s = stringValue(obj);
+		if( s==null )
+			throw new BooleanFormatException("For input string: null");
+		return booleanValue(s);
+	}
+
+	public static boolean booleanValue(Object obj,boolean defaultValue)
+		throws BooleanFormatException
+	{
+		String s = stringValue(obj);
+		if( s==null )
+			return defaultValue;
+		return booleanValue(s);
+	}
+
+	public static int intValue(Object obj)
+		throws NumberFormatException
+	{
+		String s = stringValue(obj);
+		return Integer.parseInt(s);
+	}
+
+	public static int intValue(Object obj, int defaultValue)
+		throws NumberFormatException
+	{
+		String s = stringValue(obj);
+		if( s==null )
+			return defaultValue;
+		return Integer.parseInt(s);
+	}
+
+	public static long longValue(Object obj)
+		throws NumberFormatException
+	{
+		String s = stringValue(obj);
+		return Long.parseLong(s);
+	}
+
+}