diff --git a/src/json.nr b/src/json.nr index a39b7b7..b7fff9f 100644 --- a/src/json.nr +++ b/src/json.nr @@ -226,35 +226,63 @@ impl object, context == 1 => array) + // If current token is END_OBJECT_TOKEN or END_ARRAY_TOKEN, set context to the context value in previous_stack_entry + // (i.e. restore the context to whatever the parent of the object/array is) + // Pseudocode: + // if (is_end_of_object_or_array) { + // context = previous_stack_entry.context + // } else { + // context = new_context + // } // 1 gate // if `is_end_of_object_or_array == 1`, `new_context = 0` so we can do something cheaper than a conditional select: context = cast_num_to_u32( previous_stack_entry.context * is_end_of_object_or_array + new_context, ); std::as_witness(context as Field); + + // Update data that describes the key for the current token. + // If we are creating a JSON entry, we also populate `self.key_data` with info that describes the current entry's key + // key_data contains 3 members that are packed into a Field: + // * the key index (where in the original JSON blob does the key start?) + // * the key length (length of the key in bytes) + // * current_identity_value (unique identifier for the key's JSON object. starts at 0) + // * in the current parent object/array, how many JSON entries deep is the key's associated JSON object? + // TODO: would be much more readable if we have a custom struct `KeyData` that wrapped a Field elemenet with sensible helper methods + // Pseudocode: + // if (create_json_entry) { + // let mut new_key_data; + // if (is_value_token) { + // new_key_data = make_key(current_key_index_and_length, current_identity_value, num_entries_at_current_depth - 1); + // } else if (is_end_of_object_or_array) { + // new_key_data = make_key(previous_stack_entry.current_key_index_and_length, current_identity_value, num_entries_at_current_depth - 1); + // } + // self.key_data[entry_ptr] = new_key_data; + // } // 3 gates let common_term = current_identity_value + context as Field * (num_entries_at_current_depth - 1) * 0x1000000000000; @@ -382,29 +515,15 @@ impl Self { let bytes: [u8; 7] = f.to_be_bytes(); let create_json_entry = bytes[0] != 0; @@ -31,6 +51,7 @@ impl TokenFlags { } } + /// Convert a Field element that contains a packed TokenFlags object into a real TokenFlags object pub(crate) fn from_field(f: Field) -> Self { // 10 gates // Safety: check the comments below @@ -41,7 +62,8 @@ impl TokenFlags { r } - // 4 gates + /// Pack a TokenFlags object into a Field element + /// 4 gates pub(crate) fn to_field(self) -> Field { (self.preserve_num_entries as Field) + (self.is_value_token as Field) * 0x100