static yajl_gen_status generate_key(yajl_gen g, Var v, void *ctx) { struct generate_context *gctx = (struct generate_context *)ctx; switch (v.type) { case TYPE_OBJ: case TYPE_INT: case TYPE_FLOAT: case TYPE_ERR: { const char *tmp = value_to_literal(v); if (MODE_EMBEDDED_TYPES == gctx->mode) tmp = append_type(tmp, v.type); return yajl_gen_string(g, (const unsigned char *)tmp, strlen(tmp)); } case TYPE_STR: { const char *tmp = v.v.str; size_t len = strlen(tmp); if (MODE_EMBEDDED_TYPES == gctx->mode) if (TYPE_NONE != valid_type(&tmp, &len)) tmp = append_type(tmp, v.type); return yajl_gen_string(g, (const unsigned char *)tmp, strlen(tmp)); } default: panic("Unsupported type in generate_key()"); } return yajl_gen_keys_must_be_strings; }
static yajl_gen_status generate(yajl_gen g, Var v, void *ctx) { struct generate_context *gctx = (struct generate_context *)ctx; switch (v.type) { case TYPE_INT: return yajl_gen_integer(g, v.v.num); case TYPE_FLOAT: return yajl_gen_double(g, *v.v.fnum); case TYPE_OBJ: case TYPE_ERR: { const char *tmp = value_to_literal(v); if (MODE_EMBEDDED_TYPES == gctx->mode) tmp = append_type(tmp, v.type); return yajl_gen_string(g, (const unsigned char *)tmp, strlen(tmp)); } case TYPE_STR: { const char *tmp = v.v.str; size_t len = strlen(tmp); if (MODE_EMBEDDED_TYPES == gctx->mode) if (TYPE_NONE != valid_type(&tmp, &len)) tmp = append_type(tmp, v.type); return yajl_gen_string(g, (const unsigned char *)tmp, strlen(tmp)); } case TYPE_MAP: { struct do_map_closure dmc; dmc.g = g; dmc.gctx = gctx; dmc.status = yajl_gen_status_ok; yajl_gen_map_open(g); if (mapforeach(v, do_map, &dmc)) return dmc.status; yajl_gen_map_close(g); return yajl_gen_status_ok; } case TYPE_LIST: { int i; yajl_gen_status status; yajl_gen_array_open(g); for (i = 1; i <= v.v.list[0].v.num; i++) { status = generate(g, v.v.list[i], ctx); if (yajl_gen_status_ok != status) return status; } yajl_gen_array_close(g); return yajl_gen_status_ok; } default: panic("Unsupported type in generate()"); } return -1; }
static void unparse_expr(Stream * str, Expr * expr) { switch (expr->kind) { case EXPR_PROP: if (expr->e.bin.lhs->kind == EXPR_VAR && expr->e.bin.lhs->e.var.type == TYPE_OBJ && expr->e.bin.lhs->e.var.v.obj == 0 && expr->e.bin.rhs->kind == EXPR_VAR && expr->e.bin.rhs->e.var.type == TYPE_STR && ok_identifier(expr->e.bin.rhs->e.var.v.str)) { stream_add_char(str, '$'); stream_add_string(str, expr->e.bin.rhs->e.var.v.str); } else { bracket_lt(str, EXPR_PROP, expr->e.bin.lhs); if (expr->e.bin.lhs->kind == EXPR_VAR && expr->e.bin.lhs->e.var.type == TYPE_INT) /* avoid parsing digits followed by dot as floating-point */ stream_add_char(str, ' '); stream_add_char(str, '.'); unparse_name_expr(str, expr->e.bin.rhs); } break; case EXPR_VERB: if (expr->e.verb.obj->kind == EXPR_VAR && expr->e.verb.obj->e.var.type == TYPE_OBJ && expr->e.verb.obj->e.var.v.obj == 0 && expr->e.verb.verb->kind == EXPR_VAR && expr->e.verb.verb->e.var.type == TYPE_STR && ok_identifier(expr->e.verb.verb->e.var.v.str)) { stream_add_char(str, '$'); stream_add_string(str, expr->e.verb.verb->e.var.v.str); } else { bracket_lt(str, EXPR_VERB, expr->e.verb.obj); stream_add_char(str, ':'); unparse_name_expr(str, expr->e.verb.verb); } stream_add_char(str, '('); unparse_arglist(str, expr->e.verb.args); stream_add_char(str, ')'); break; case EXPR_INDEX: bracket_lt(str, EXPR_INDEX, expr->e.bin.lhs); stream_add_char(str, '['); unparse_expr(str, expr->e.bin.rhs); stream_add_char(str, ']'); break; case EXPR_RANGE: bracket_lt(str, EXPR_RANGE, expr->e.range.base); stream_add_char(str, '['); unparse_expr(str, expr->e.range.from); stream_add_string(str, ".."); unparse_expr(str, expr->e.range.to); stream_add_char(str, ']'); break; /* left-associative binary operators */ case EXPR_PLUS: case EXPR_MINUS: case EXPR_TIMES: case EXPR_DIVIDE: case EXPR_MOD: case EXPR_AND: case EXPR_OR: case EXPR_EQ: case EXPR_NE: case EXPR_LT: case EXPR_GT: case EXPR_LE: case EXPR_GE: case EXPR_IN: bracket_lt(str, expr->kind, expr->e.bin.lhs); stream_add_string(str, binop_string[expr->kind]); bracket_le(str, expr->kind, expr->e.bin.rhs); break; /* right-associative binary operators */ case EXPR_EXP: bracket_le(str, expr->kind, expr->e.bin.lhs); stream_add_string(str, binop_string[expr->kind]); bracket_lt(str, expr->kind, expr->e.bin.rhs); break; case EXPR_COND: bracket_le(str, EXPR_COND, expr->e.cond.condition); stream_add_string(str, " ? "); unparse_expr(str, expr->e.cond.consequent); stream_add_string(str, " | "); bracket_le(str, EXPR_COND, expr->e.cond.alternate); break; case EXPR_NEGATE: stream_add_char(str, '-'); bracket_lt(str, EXPR_NEGATE, expr->e.expr); break; case EXPR_NOT: stream_add_char(str, '!'); bracket_lt(str, EXPR_NOT, expr->e.expr); break; case EXPR_VAR: stream_add_string(str, value_to_literal(expr->e.var)); break; case EXPR_ASGN: unparse_expr(str, expr->e.bin.lhs); stream_add_string(str, " = "); unparse_expr(str, expr->e.bin.rhs); break; case EXPR_CALL: stream_add_string(str, name_func_by_num(expr->e.call.func)); stream_add_char(str, '('); unparse_arglist(str, expr->e.call.args); stream_add_char(str, ')'); break; case EXPR_ID: stream_add_string(str, prog->var_names[expr->e.id]); break; case EXPR_LIST: stream_add_char(str, '{'); unparse_arglist(str, expr->e.list); stream_add_char(str, '}'); break; case EXPR_SCATTER: stream_add_char(str, '{'); unparse_scatter(str, expr->e.scatter); stream_add_char(str, '}'); break; case EXPR_CATCH: stream_add_string(str, "`"); unparse_expr(str, expr->e.catchexp.tryexp); stream_add_string(str, " ! "); if (expr->e.catchexp.codes) unparse_arglist(str, expr->e.catchexp.codes); else stream_add_string(str, "ANY"); if (expr->e.catchexp.except) { stream_add_string(str, " => "); unparse_expr(str, expr->e.catchexp.except); } stream_add_string(str, "'"); break; case EXPR_LENGTH: stream_add_string(str, "$"); break; default: errlog("UNPARSE_EXPR: Unknown Expr_Kind: %d\n", expr->kind); stream_add_string(str, "(?!?!?!?!?)"); break; } }