this.protomap.put(String.class, new SizzleString());
// this maps scalar Sizzle scalar types names to their classes
// TODO: do this via reflection
this.idmap = new HashMap<String, SizzleType>();
this.idmap.put("any", new SizzleAny());
this.idmap.put("none", null);
this.idmap.put("bool", new SizzleBool());
this.idmap.put("int", new SizzleInt());
this.idmap.put("float", new SizzleFloat());
this.idmap.put("time", new SizzleTime());
this.idmap.put("fingerprint", new SizzleFingerprint());
this.idmap.put("string", new SizzleString());
this.idmap.put("bytes", new SizzleBytes());
// does the same for arrays
// for (final String key : new HashSet<String>(this.idmap.keySet())) {
// final SizzleType value = this.idmap.get(key);
// if (value instanceof SizzleScalar)
// this.idmap.put("array of " + key, new SizzleArray((SizzleScalar)
// value));
// }
// variables with a global scope
this.globals = new HashMap<String, SizzleType>();
// set the type of the input
this.globals.put("input", input);
this.globals.put("true", new SizzleBool());
this.globals.put("false", new SizzleBool());
this.globals.put("PI", new SizzleFloat());
this.globals.put("Inf", new SizzleFloat());
this.globals.put("inf", new SizzleFloat());
this.globals.put("NaN", new SizzleFloat());
this.globals.put("nan", new SizzleFloat());
// variables with a local scope
this.locals = new HashMap<String, SizzleType>();
this.aggregators = new HashMap<String, Class<?>>();
this.functions = new FunctionTrie();
// these generic functions require more finagling than can currently be
// (easily) done with a static method, so they are handled with macros
this.setFunction("def", new SizzleFunction(new SizzleBool(), new SizzleType[] { new SizzleAny() }, "${0} != null"));
this.setFunction("len", new SizzleFunction(new SizzleInt(), new SizzleType[] { new SizzleArray(new SizzleScalar()) }, "${0}.length"));
this.setFunction("len", new SizzleFunction(new SizzleInt(), new SizzleType[] { new SizzleString() }, "${0}.length()"));
this.setFunction("len", new SizzleFunction(new SizzleInt(), new SizzleType[] { new SizzleBytes() }, "${0}.length"));
this.setFunction("len", new SizzleFunction(new SizzleInt(), new SizzleType[] { new SizzleMap(new SizzleScalar(), new SizzleScalar()) },
"${0}.keySet().size()"));