// To delete the WHOLE linked list, given its head. void ll_delete_all(ll_cnode*& head) { if (head == NULL) // An empty list; nothing to delete return; ll_delete_all(head->next); // STEP 1: First delete the remaining nodes // For debugging: this shows you what are deleting cout << "deleting " << head->data << endl; delete head; // STEP 2: Then delete the current nodes head = NULL; // STEP 3: To play safe, reset head to NULL }
static statement *get_expression(parse_source *source, int *indent) { parse_token token = get_mandatory_token(source); if(equals_string(token.data, "{")) { statement *expression = new(expression); expression->type = BLOCK; expression->children = ll_new(); expression->data = new_slice(""); int finished = *indent; *indent += 1; while(*indent != finished) { statement *state = get_expression(source, indent); if(state != NULL) ll_add_last(expression->children, state); } return expression; } else if(equals_string(token.data, "}")) { *indent -= 1; return NULL; } else if(equals_string(token.data, "if") || equals_string(token.data, "while") || equals_string(token.data, "for")) { statement *expression = new(expression); if(equals_string(token.data, "if")) expression->type = IF; else if(equals_string(token.data, "while")) expression->type = WHILE; else if(equals_string(token.data, "for")) expression->type = FOR; expression->children = ll_new(); expression->data = new_slice(""); ll_add_last(expression->children, get_expression(source, indent)); //Add the header if(expression->type == FOR) { ll_add_last(expression->children, get_expression(source, indent)); //Add the header ll_add_last(expression->children, get_expression(source, indent)); //Add the header } ll_add_last(expression->children, get_expression(source, indent)); //Add the body if(expression->type == IF) { parse_token next = peek_mandatory_token(source); if(equals_string(next.data, "else")) { get_mandatory_token(source); statement *elseState = new(elseState); elseState->type = ELSE; elseState->children = ll_new(); elseState->data = new_slice(""); ll_add_last(expression->children, elseState); ll_add_first(elseState->children, get_expression(source, indent)); } } return expression; } else if(equals_string(token.data, "break") || equals_string(token.data, "continue")) { statement *expression = new(expression); expression->type = equals_string(token.data, "break") ? BREAK : CONTINUE; expression->data = new_slice(""); expression->children = NULL; parse_token next = get_mandatory_token(source); if(!equals_string(next.data, ";")) semantic_error("Expected a semicolon after a break or continue", next.origin); return expression; } else if(equals_string(token.data, "return")) { statement *expression = new(expression); expression->type = RETURN; expression->data = new_slice(""); expression->children = ll_new(); ll_add_last(expression->children, get_expression(source, indent)); return expression; } else { linked_list *accumulator = ll_new(); parse_token next = token; while(true) { parse_token *allocated = new(allocated); *allocated = token; ll_add_last(accumulator, allocated); next = peek_mandatory_token(source); if(equals_string(next.data, "{") || equals_string(next.data, "}")) break; if(equals_string(next.data, ";")) { get_mandatory_token(source); break; } token = get_mandatory_token(source); } statement *expression = parse_simple_expression(accumulator); ll_delete_all(accumulator); return expression; } }