diff --git a/c/jv.c b/c/jv.c
index 4484dc9f..9a3d308f 100644
--- a/c/jv.c
+++ b/c/jv.c
@@ -125,10 +125,13 @@ static int jvp_array_length(jv_complex* a) {
 }
 
 static jv* jvp_array_read(jv_complex* a, int i) {
-  assert(i >= 0 && i < jvp_array_length(a));
-  jvp_array* array = jvp_array_ptr(a);
-  assert(i + a->i[0] < array->length);
-  return &array->elements[i + a->i[0]];
+  if (i >= 0 && i < jvp_array_length(a)) {
+    jvp_array* array = jvp_array_ptr(a);
+    assert(i + a->i[0] < array->length);
+    return &array->elements[i + a->i[0]];
+  } else {
+    return 0;
+  }
 }
 
 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) {
   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);
   return val;
 }
diff --git a/c/jv.h b/c/jv.h
index b251329c..8d9ebadb 100644
--- a/c/jv.h
+++ b/c/jv.h
@@ -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) {
     // FIXME: don't do lookup for noninteger index
     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 {
     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) {
-  if (jv_get_kind(t) == JV_KIND_OBJECT && jv_get_kind(k) == JV_KIND_STRING) {
-    t = jv_object_set(t, k, v);
-  } else if (jv_get_kind(t) == JV_KIND_ARRAY && jv_get_kind(k) == JV_KIND_NUMBER) {
-    t = jv_array_set(t, (int)jv_number_value(k), 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");
+    }
   } else {
-    assert(0 && "bad mod");
+    assert(0 && "bad mod - seriously, wtf");
   }
   return t;
 }
diff --git a/c/testdata b/c/testdata
index c6388d67..70071186 100644
--- a/c/testdata
+++ b/c/testdata
@@ -133,12 +133,18 @@ null
 # Builtin functions
 #
 
-# FIXME: floats vs. integer
-
 1+1
 null
 2
 
+1+1
+"wtasdf"
+2.0
+
+1e+0+0.001e3
+"I wonder what this will be?"
+20e-1
+
 .+4
 15
 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)
 [{"a":1,"b":2},{"a":2,"b":4},{"a":7,"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}