Mercurial Hosting > nabble
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); + } + +}