Perl-style autovivification.

.foo.bar = 1 will cause objects to be created if they don't exist.
This commit is contained in:
Stephen Dolan committed 2012-09-03 16:50:38 +01:00
1 parent c9dbe1aff8
commit eea05ff924
3 files changed
+57 -12

No files matched your search

+14 -5
View File
@@ -125,10 +125,13 @@ static int jvp_array_length(jv_complex* a) {
} }
static jv* jvp_array_read(jv_complex* a, int i) { static jv* jvp_array_read(jv_complex* a, int i) {
assert(i >= 0 && i < jvp_array_length(a)); if (i >= 0 && i < jvp_array_length(a)) {
jvp_array* array = jvp_array_ptr(a); jvp_array* array = jvp_array_ptr(a);
assert(i + a->i[0] < array->length); assert(i + a->i[0] < array->length);
return &array->elements[i + a->i[0]]; return &array->elements[i + a->i[0]];
} else {
return 0;
}
} }
static jv* jvp_array_write(jv_complex* a, int i) { static jv* jvp_array_write(jv_complex* a, int i) {
@@ -223,7 +226,13 @@ int jv_array_length(jv j) {
jv jv_array_get(jv j, int idx) { jv jv_array_get(jv j, int idx) {
assert(jv_get_kind(j) == JV_KIND_ARRAY); assert(jv_get_kind(j) == JV_KIND_ARRAY);
jv val = jv_copy(*jvp_array_read(&j.val.complex, idx)); jv* slot = jvp_array_read(&j.val.complex, idx);
jv val;
if (slot) {
val = jv_copy(*slot);
} else {
val = jv_invalid();
}
jv_free(j); jv_free(j);
return val; return val;
} }
+27 -5
View File
@@ -104,6 +104,14 @@ static jv jv_lookup(jv t, jv k) {
} else if (jv_get_kind(t) == JV_KIND_ARRAY && jv_get_kind(k) == JV_KIND_NUMBER) { } else if (jv_get_kind(t) == JV_KIND_ARRAY && jv_get_kind(k) == JV_KIND_NUMBER) {
// FIXME: don't do lookup for noninteger index // FIXME: don't do lookup for noninteger index
v = jv_array_get(t, (int)jv_number_value(k)); v = jv_array_get(t, (int)jv_number_value(k));
if (!jv_is_valid(v)) {
v = jv_null();
}
} else if (jv_get_kind(t) == JV_KIND_NULL &&
(jv_get_kind(k) == JV_KIND_STRING || jv_get_kind(k) == JV_KIND_NUMBER)) {
jv_free(t);
jv_free(k);
v = jv_null();
} else { } else {
assert(0&&"bad lookup"); assert(0&&"bad lookup");
} }
@@ -118,12 +126,26 @@ static jv jv_lookup(jv t, jv k) {
} }
static jv jv_modify(jv t, jv k, jv v) { static jv jv_modify(jv t, jv k, jv v) {
if (jv_get_kind(t) == JV_KIND_OBJECT && jv_get_kind(k) == JV_KIND_STRING) { if (jv_get_kind(k) == JV_KIND_STRING) {
t = jv_object_set(t, k, v); if (jv_get_kind(t) == JV_KIND_NULL) {
} else if (jv_get_kind(t) == JV_KIND_ARRAY && jv_get_kind(k) == JV_KIND_NUMBER) { t = jv_object();
t = jv_array_set(t, (int)jv_number_value(k), v); }
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");
}
} else { } else {
assert(0 && "bad mod"); assert(0 && "bad mod - seriously, wtf");
} }
return t; return t;
} }
+16 -2
View File
@@ -133,12 +133,18 @@ null
# Builtin functions # Builtin functions
# #
# FIXME: floats vs. integer
1+1 1+1
null null
2 2
1+1
"wtasdf"
2.0
1e+0+0.001e3
"I wonder what this will be?"
20e-1
.+4 .+4
15 15
19.0 19.0
@@ -212,3 +218,11 @@ def id(x):x; 2000 as $x | def f(x):1 as $x | id([$x, x, x]); def g(x): 100 as $x
def inc(x): x |= .+1; inc(.[].a) def inc(x): x |= .+1; inc(.[].a)
[{"a":1,"b":2},{"a":2,"b":4},{"a":7,"b":8}] [{"a":1,"b":2},{"a":2,"b":4},{"a":7,"b":8}]
[{"a":2,"b":2},{"a":3,"b":4},{"a":8,"b":8}] [{"a":2,"b":2},{"a":3,"b":4},{"a":8,"b":8}]
.[2][3] = 1
[4]
[4, null, [null, null, null, 1]]
.foo[2].bar = 1
{"foo":[11], "bar":42}
{"foo":[11,null,{"bar":1}], "bar":42}