}
}
-
+void print_error(jv value) {
+ assert(!jv_is_valid(value));
+ jv msg = jv_invalid_get_msg(value);
+ if (jv_get_kind(msg) == JV_KIND_STRING) {
+ fprintf(stderr, "jq: error: %s\n", jv_string_value(msg));
+ }
+ jv_free(msg);
+}
#define ON_BACKTRACK(op) ((op)+NUM_OPCODES)
jv jq_next() {
uint16_t v = *pc++;
frame_ptr fp = frame_get_level(&frame_stk, frame_current(&frame_stk), level);
jv* var = frame_local_var(fp, v);
- *var = jv_insert(*var, replacement.value, pathbuf + path_start.pathidx, path_end.pathidx - path_start.pathidx);
+ jv result = jv_insert(*var, replacement.value, pathbuf + path_start.pathidx, path_end.pathidx - path_start.pathidx);
+ if (jv_is_valid(result)) {
+ *var = result;
+ } else {
+ print_error(result);
+ *var = jv_null();
+ }
break;
}
jv k = stack_pop().value;
int pathidx = path_push(t, jv_copy(k));
jv v = jv_lookup(t.value, k);
- if (1 /* fixme invalid lookups */) {
+ if (jv_is_valid(v)) {
stackval sv;
sv.value = v;
sv.pathidx = pathidx;
stack_push(sv);
} else {
- assert(0 && "bad lookup");
+ print_error(v);
+ goto do_backtrack;
}
break;
}
if (jv_is_valid(top.value)) {
stack_push(top);
} else {
- jv msg = jv_invalid_get_msg(top.value);
- if (jv_get_kind(msg) == JV_KIND_STRING) {
- fprintf(stderr, "jq: error: %s\n", jv_string_value(msg));
- }
- jv_free(msg);
+ print_error(top.value);
goto do_backtrack;
}
break;
if (jv_is_valid(top.value)) {
stack_push(top);
} else {
- jv msg = jv_invalid_get_msg(top.value);
- if (jv_get_kind(msg) == JV_KIND_STRING) {
- fprintf(stderr, "jq: error: %s\n", jv_string_value(msg));
- }
- jv_free(msg);
+ print_error(top.value);
goto do_backtrack;
}
break;
case JV_KIND_ARRAY: return "array";
case JV_KIND_OBJECT: return "object";
}
- assert(0);
+ assert(0 && "invalid kind");
return "<unknown>";
}
jv_free(k);
v = jv_null();
} else {
- assert(0&&"bad lookup");
+ v = jv_invalid_with_msg(jv_string_fmt("Cannot index %s with %s",
+ jv_kind_name(jv_get_kind(t)),
+ jv_kind_name(jv_get_kind(k))));
+ jv_free(t);
+ jv_free(k);
}
return v;
- // FIXME: invalid indexes, JV_KIND_INVALID
- /*
- if (v)
- return v;
- else
- return jv_null();
- */
}
static jv jv_modify(jv t, jv k, jv v) {
- if (jv_get_kind(k) == JV_KIND_STRING) {
- if (jv_get_kind(t) == JV_KIND_NULL) {
- t = jv_object();
- }
- if (jv_get_kind(t) == JV_KIND_OBJECT) {
- t = jv_object_set(t, k, v);
- } else {
- assert(0 && "bad mod - not an object");
- }
- } else if (jv_get_kind(k) == JV_KIND_NUMBER) {
- if (jv_get_kind(t) == JV_KIND_NULL) {
- t = jv_array();
- }
- if (jv_get_kind(t) == JV_KIND_ARRAY) {
- t = jv_array_set(t, (int)jv_number_value(k), v);
- } else {
- assert(0 && "bad mod - not an array");
- }
+ int isnull = jv_get_kind(t) == JV_KIND_NULL;
+ if (jv_get_kind(k) == JV_KIND_STRING &&
+ (jv_get_kind(t) == JV_KIND_OBJECT || isnull)) {
+ if (isnull) t = jv_object();
+ t = jv_object_set(t, k, v);
+ } else if (jv_get_kind(k) == JV_KIND_NUMBER &&
+ (jv_get_kind(t) == JV_KIND_ARRAY || isnull)) {
+ if (isnull) t = jv_array();
+ t = jv_array_set(t, (int)jv_number_value(k), v);
} else {
- assert(0 && "bad mod - seriously, wtf");
+ jv err = jv_invalid_with_msg(jv_string_fmt("Cannot update field at %s index of %s",
+ jv_kind_name(jv_get_kind(t)),
+ jv_kind_name(jv_get_kind(v))));
+ jv_free(t);
+ jv_free(k);
+ jv_free(v);
+ t = err;
}
return t;
}