comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:7ecd1a4ef557
1 package nabble.naml.compiler;
2
3 import fschmidt.util.java.Stack;
4
5 import java.util.HashSet;
6 import java.util.Map;
7 import java.util.Set;
8
9
10 public final class Template extends Compiler.Traceable {
11 private final Program program;
12 private final Chunk chunk;
13 private final Class[] baseClasses;
14 public final Macro macro;
15
16 Template(Compiler compiler,Program program,Chunk chunk,Class[] baseClasses,Macro macro) {
17 super(compiler);
18 this.program = program;
19 this.chunk = chunk;
20 this.baseClasses = baseClasses;
21 this.macro = macro;
22 }
23
24 public String name() {
25 return macro.name;
26 }
27
28 public final Program program() {
29 return program;
30 }
31
32 public final void run(IPrintWriter out,Map<String,Object> args,Object... base) {
33 run(0,Encoder.TEXT,out,args,base);
34 out.flush();
35 }
36
37 final void run(int callDepth,Encoder encoder,IPrintWriter out,Map<String,Object> args,Object... base) {
38 Set<String> argNames = macro.parameters;
39 if( !argNames.containsAll(args.keySet()) ) {
40 Set<String> badArgs = new HashSet<String>(args.keySet());
41 badArgs.removeAll(argNames);
42 throw new RuntimeException("invalid args: "+badArgs);
43 }
44 Stack<StackTrace> stack = StackTrace.stack();
45 stack.push(stackTrace);
46 try {
47 check(base);
48 RunState runState = new RunStateImpl(this,callDepth,encoder);
49 for( Object obj : base ) {
50 runState.push(obj);
51 }
52 for( Map.Entry<String,Object> entry : args.entrySet() ) {
53 String key = entry.getKey();
54 Object value = entry.getValue();
55 if( value instanceof String ) {
56 runState.putArg( key, (String)value );
57 } else {
58 runState.putArg( key, runState.saveNamespace(value) );
59 }
60 }
61 chunk.run(out,runState);
62 } catch (ExitException e) {
63 // do nothing.
64 } finally {
65 stack.pop();
66 }
67 }
68
69 private void check(Object[] base) {
70 if( base.length != baseClasses.length )
71 throw new TemplateRuntimeException("base mismatch base.length="+base.length+" baseClasses.length="+baseClasses.length);
72 for( int i=0; i<baseClasses.length; i++ ) {
73 if( !baseClasses[i].isInstance(base[i]) )
74 throw new TemplateRuntimeException("base mismatch");
75 }
76 }
77
78 // private static void handle(Exception e) {
79 // if( e instanceof RuntimeException )
80 // throw (RuntimeException)e;
81 // throw new TemplateRuntimeException(e);
82 // }
83
84 public static String stringValue(Object obj) {
85 if( obj==null )
86 return null;
87 return obj.toString();
88 }
89
90 public static boolean booleanValue(String s)
91 throws BooleanFormatException
92 {
93 if( s.equalsIgnoreCase("true") )
94 return true;
95 if( s.equalsIgnoreCase("false") )
96 return false;
97 throw new BooleanFormatException("For input string: \""+s+"\"");
98 }
99
100 public static boolean booleanValue(Object obj)
101 throws BooleanFormatException
102 {
103 String s = stringValue(obj);
104 if( s==null )
105 throw new BooleanFormatException("For input string: null");
106 return booleanValue(s);
107 }
108
109 public static boolean booleanValue(Object obj,boolean defaultValue)
110 throws BooleanFormatException
111 {
112 String s = stringValue(obj);
113 if( s==null )
114 return defaultValue;
115 return booleanValue(s);
116 }
117
118 public static int intValue(Object obj)
119 throws NumberFormatException
120 {
121 String s = stringValue(obj);
122 return Integer.parseInt(s);
123 }
124
125 public static int intValue(Object obj, int defaultValue)
126 throws NumberFormatException
127 {
128 String s = stringValue(obj);
129 if( s==null )
130 return defaultValue;
131 return Integer.parseInt(s);
132 }
133
134 public static long longValue(Object obj)
135 throws NumberFormatException
136 {
137 String s = stringValue(obj);
138 return Long.parseLong(s);
139 }
140
141 }