do_backtrack:
case BACKTRACK: {
if (!stack_restore()) {
- // FIXME: invalid jv value
- return jv_null();
+ return jv_invalid();
}
pc = *frame_current_retaddr(&frame_stk);
frame_pop(&frame_stk);
fgets(buf, sizeof(buf), stdin);
jq_init(bc, jv_parse(buf));
jv result;
- while (jv_get_kind(result = jq_next()) != JV_KIND_NULL) {
+ while (jv_is_valid(result = jq_next())) {
jv_dump(result);
printf("\n");
}
return x.kind;
}
+static const jv JV_INVALID = {JV_KIND_INVALID, {0}};
static const jv JV_NULL = {JV_KIND_NULL, {0}};
static const jv JV_FALSE = {JV_KIND_FALSE, {0}};
static const jv JV_TRUE = {JV_KIND_TRUE, {0}};
+jv jv_invalid() {
+ return JV_INVALID;
+}
+
jv jv_true() {
return JV_TRUE;
}
jv jv_object_get(jv object, jv key) {
assert(jv_get_kind(object) == JV_KIND_OBJECT);
assert(jv_get_kind(key) == JV_KIND_STRING);
- jv val = jv_copy(*jvp_object_read(&object.val.complex, jvp_string_ptr(&key.val.complex)));
+ jv* slot = jvp_object_read(&object.val.complex, jvp_string_ptr(&key.val.complex));
+ jv val;
+ if (slot) {
+ val = jv_copy(*slot);
+ } else {
+ val = jv_invalid();
+ }
jv_free(object);
jv_free(key);
return val;
typedef enum {
+ JV_KIND_INVALID,
JV_KIND_NULL,
JV_KIND_FALSE,
JV_KIND_TRUE,
*/
jv_kind jv_get_kind(jv);
+static int jv_is_valid(jv x) { return jv_get_kind(x) != JV_KIND_INVALID; }
jv jv_copy(jv);
void jv_free(jv);
int jv_equal(jv, jv);
+jv jv_invalid();
jv jv_null();
jv jv_true();
jv jv_false();
jv v;
if (jv_get_kind(t) == JV_KIND_OBJECT && jv_get_kind(k) == JV_KIND_STRING) {
v = jv_object_get(t, k);
+ if (!jv_is_valid(v)) {
+ v = jv_null();
+ }
} else if (jv_get_kind(t) == JV_KIND_ARRAY && jv_get_kind(k) == JV_KIND_NUMBER) {
// FIXME: don't do lookup for noninteger index
v = jv_array_get(t, (int)jv_number_value(k));
if (skipline(buf)) break;
jv expected = jv_parse(buf);
jv actual = jq_next();
- if (!1) {
+ if (!jv_is_valid(actual)) {
printf("Insufficient results\n");
pass = 0;
break;
pass = 0;
}
}
- if (pass && 0) { /*
+ if (pass) {
jv extra = jq_next();
- if (extra) {
+ if (jv_is_valid(extra)) {
printf("Superfluous result: ");
- json_dumpf(extra, stdout, JSON_ENCODE_ANY);
+ jv_dump(extra);
printf("\n");
pass = 0;
- }*/
+ }
}
jq_teardown();
bytecode_free(bc);
{"foo": {"bar": 42}, "bar": "badvalue"}
42
-
-# FIXME strings
-# .["foo"].bar
-# {"foo": {"bar": 42}, "bar": "badvalue"}
-# 42
+.["foo"].bar
+{"foo": {"bar": 42}, "bar": "badvalue"}
+42
#
[1]
true
+null,1,null
+"hello"
+null
+1
+null
+
[1,2,3]
[5,6]
[1,2,3]
[[20,10][1,0] as $x | def f: (100,200) as $y | def g: [$x + $y, .]; . + $x | g; f[0] | [f][0][1] | f]
"woo, testing!"
[[110.0, 130.0], [210.0, 130.0], [110.0, 230.0], [210.0, 230.0], [120.0, 160.0], [220.0, 160.0], [120.0, 260.0], [220.0, 260.0]]
+
+#
+# Assignment
+#
+.message = "goodbye"
+{"message": "hello"}
+{"message": "goodbye"}
+
+.foo = .bar
+{"bar":42}
+{"foo":42, "bar":42}
+
+def inc(x): x |= .+1; inc(.[].a)
+[{"a":1,"b":2},{"a":2,"b":4},{"a":7,"b":8}]
+[{"a":2,"b":2},{"a":3,"b":4},{"a":8,"b":8}]