-
Notifications
You must be signed in to change notification settings - Fork 28
Add experimental support for tables of pointers #35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Tries to address rluba#15 Example: ```jai main :: () { json_string := "{\"foo\": 69, \"bar\": 420}"; success, json := json_parse_string(json_string, Table(string, *int)); if !success exit(69); for json { print("% => %\n", it_index, it.*); } } #import "jaison"; ``` Why Tables of Pointers only: Currently all the `Type_Info` handling is happening at Runtime. But supporting Tables of Values that differ in size requires polymorphing such operations as `table_add()` which means we need to know the `Type_Info`-s at compile time. Until the type.jai is refactored to pass all the necessary `Type_Info` with `$` we can only offer that. Unless I'm missing something. Please let me know if I do. If I get a spare minute in the foreseeable future, I can spend it on doing the refactoring to bring the support for more Table kinds, but if somebody else wants to tuckle it I won't mind it. Please let me know if you want me to make any changes to the patch. Thank you for making this very useful library!
Since Table is a .STRUCT anyway expecting a .STRUCT when encountring a JSON object should work out well in this case.
|
I posted this on X but it's probably better here: If your issue is finding the size+type of the table value at runtime, you can do this: #import "Hash_Table";
test :: ($T: Type) {
val_ti := type_info(T.Value_Type);
print("Table value type info = %\n", val_ti.*);
}
test(Table(string, s16));This works because |
Thank you for the suggestion! The problem is actually that we need to know it at compile time. Otherwise we can't polymorph the |
Ah I see, sorry for the confusion. A slight modification of your code makes it work for both pointers and non-pointers: parse_object_as_table_of_pointers :: (str: string, slot: *u8, $T: Type, value_info: *Type_Info, ignore_unknown: bool, rename: Rename_Proc, float_handling: Special_Float_Handling) -> remainder: string, success: bool {
assert(str[0] == #char "{", "Invalid object start %", str);
remainder := advance(str);
remainder = trim_left(remainder, WHITESPACE_CHARS);
if !remainder return "", false;
if remainder[0] == #char "}" {
remainder = advance(remainder);
return remainder, true;
}
IS_TABLE :: #run begins_with(tprint("%", T), "Table(");
IS_POINTER_VALUE_TYPE :: #run -> bool {
#if IS_TABLE {
return type_info(T.Value_Type).type == .POINTER;
}
return false;
};
#if IS_TABLE {
table := cast(*Table(string, T.Value_Type))slot;
while true {
if !remainder || remainder[0] != #char "\"" return remainder, false;
key: string;
success: bool;
key, remainder, success = parse_string(remainder);
if !success return remainder, false;
defer free(key);
remainder = trim_left(remainder, WHITESPACE_CHARS);
if !remainder || remainder[0] != #char ":" return remainder, false;
remainder = advance(remainder);
#if IS_POINTER_VALUE_TYPE {
member_info := value_info.(*Type_Info_Pointer).pointer_to;
member_slot := NewArray(member_info.runtime_size, u8).data;
remainder, success = parse_value(remainder, member_slot, T, member_info, ignore_unknown, key, rename, float_handling=float_handling);
if !success return remainder, false;
table_add(table, copy_string(key), member_slot.(T.Value_Type));
} else {
member_info := value_info;
member_slot: T.Value_Type;
remainder, success = parse_value(remainder, (*member_slot).(*u8), T, member_info, ignore_unknown, key, rename, float_handling=float_handling);
if !success return remainder, false;
table_add(table, copy_string(key), member_slot);
}
remainder = trim_left(remainder, WHITESPACE_CHARS);
if !remainder || remainder[0] != #char "," break;
remainder = advance(remainder);
remainder = trim_left(remainder, WHITESPACE_CHARS);
}
if !remainder || remainder[0] != #char "}" return remainder, false;
remainder = advance(remainder);
return remainder, true;
} else {
// Should never happen
return "", false;
}
}Of course the only requirement is that Notes:
|
|
@bloeys please submit an actual patch to https://github.com/tsoding/jaison to the branch |
Tries to address #15
Example:
Why Tables of Pointers only:
Currently all the
Type_Infohandling is happening at Runtime. But supporting Tables of Values that differ in size requires polymorphing such operations astable_add()which means we need to know theType_Info-s at compile time. Until the type.jai is refactored to pass all the necessaryType_Infowith$we can only offer that.Unless I'm missing something. Please let me know if I do.
If I get a spare minute in the foreseeable future, I can spend it on doing the refactoring to bring the support for more Table kinds, but if somebody else wants to tackle it I won't mind it.
Please let me know if you want me to make any changes to the patch.
Thank you for making this very useful library!