def translate_value(val):
    if isinstance(val, (str, int, bool, type(None))):
        return val
    if isinstance(val, float):
        # Close enough.
        return d.Decimal(val)
    if isinstance(val, list):
        return t.list(sym('vector'), *(translate_value(v) for v in val))
    if isinstance(val, dict):
        return t.list(
            sym('let'),
            t.list(t.list(sym('o'), t.list(sym('object'))), ),
            *(translate_set_key(sym('o'), k, v) for (k, v) in val.items()),
            sym('o'),
        )
def translate_create(path, **kwargs):
    pointer = jp.JsonPointer(path)

    def generate_create_for_prefix(subpointer, part, pointer):
        return t.list(
            sym('if'),
            t.list(
                sym('not'),
                t.list(
                    sym('list-contains'),
                    t.list(
                        sym('object-keys'),
                        t.list(
                            sym('get'),
                            subpointer.path,
                        ),
                    ),
                    part,
                ),
            ),
            t.list(
                sym('set'),
                pointer.path,
                t.list(sym('object')),
            ),
        )

    def generate_prefixes():
        parts = []
        for part in pointer.parts:
            subpointer = jp.JsonPointer.from_parts(parts)
            parts.append(part)
            part_pointer = jp.JsonPointer.from_parts(parts)
            yield generate_create_for_prefix(subpointer, part, part_pointer)

    return t.list(sym('begin'), *(p for p in generate_prefixes()))
 def generate_create_for_prefix(subpointer, part, pointer):
     return t.list(
         sym('if'),
         t.list(
             sym('not'),
             t.list(
                 sym('list-contains'),
                 t.list(
                     sym('object-keys'),
                     t.list(
                         sym('get'),
                         subpointer.path,
                     ),
                 ),
                 part,
             ),
         ),
         t.list(
             sym('set'),
             pointer.path,
             t.list(sym('object')),
         ),
     )
def translate_set(path, value, **kwargs):
    return t.list(sym('set'), path, translate_value(value))
def translate_set_key(target, key, val):
    return t.list(sym('object-set'), target, translate_value(key),
                  translate_value(val))
def translate_event(event):
    return t.list(sym('event'), event['office'], event['message'])
def object_keys(obj):
    return t.list(*obj.keys())