Calling parse_element(…) on "1" will result in an Element object containing the int 1. Equivalent to Element element = { .as_int = 1, .type = ELEMENT_INT }; ... but returned by address. This is imilar to how parse_int(…) initialized an int by address and parse_string(…) initialized a char* by address. parse_element(…): If the input string (at *a_pos) start with a digit, then you call parse_int(…) '"', then you call parse_string(…) '[', then you call parse_list(…) Your parse_element(…) should not look at individual characters any more than eating whitespace and deciding which function to call. It should delegate all of the actual parsing to parse_int(…), parse_string(…), and parse_list(…) ---------------------------------- parse_list(…) parse_list(…) with "[1,2]" 1 Eat the '['. (If it wasn't there, you return false.) 2 Call parse_element(…) - WARNING: Do not try to parse the value (int, string, etc.) or even call parse_int(…) and such from within parse_list(…). parse_list(…) must not need to know the types that an Element object can store. 3 Eat either a ',' (if list is continuing) or a ']' if that was the end of the list. 4 If list is continuing, then go back to step 2. If you pass "[]" to parse_list(…), then the list is empty, so you set *a_head to NULL. - same goes for "[ ]" HOW TO START HW13 (suggestion) - parse_element(…) - parse_json(…) - parse_list(…)