void free_task (struct task_s *task) { if ( task->refcnt ) return; switch ( task->t ) { case TASK_EVAL: release_expression (task->d.task_eval_v.expr); release_continuation (task->d.task_eval_v.cont); break; case TASK_APP1: release_function (task->d.task_app1_v.erator); release_expression (task->d.task_app1_v.rand); release_continuation (task->d.task_app1_v.cont); break; case TASK_APP: release_function (task->d.task_app_v.erator); release_function (task->d.task_app_v.erand); release_continuation (task->d.task_app_v.cont); break; case TASK_INVOKE: release_continuation (task->d.task_invoke_v.cont); release_function (task->d.task_invoke_v.val); break; default: ; } free (task); }
// Parses a pair, assuming the opening left parenthesis has already been read. static struct ParseResult parse_pair(const char *text) { struct ParseResult result; result.err_type = -1; const char *s = text; s += skip_whitespace(s); if (*s == ')') { s++; result.expr = new_null(); goto chars_read; } struct ParseResult first = parse(s); s += first.chars_read; if (first.err_type != -1) { result.err_type = first.err_type; goto chars_read; } if (*s == '.') { s++; struct ParseResult second = parse(s); s += second.chars_read; if (second.err_type != -1) { result.err_type = second.err_type; release_expression(first.expr); goto chars_read; } if (*s != ')') { result.err_type = *s ? ERR_EXPECTED_RPAREN : ERR_UNEXPECTED_EOI; release_expression(first.expr); goto chars_read; } s++; result.expr = new_pair(first.expr, second.expr); } else { struct ParseResult rest = parse_pair(s); s += rest.chars_read; if (rest.err_type != -1) { result.err_type = rest.err_type; release_expression(first.expr); goto chars_read; } result.expr = new_pair(first.expr, rest.expr); } chars_read: result.chars_read = (size_t)(s - text); return result; }
void free_function (struct function_s *fun) { if ( fun->refcnt ) return; switch ( fun->t ) { case FUNCTION_K1: release_function (fun->d.function_k1_v); break; case FUNCTION_S2: release_function (fun->d.function_s2_v.x); release_function (fun->d.function_s2_v.y); break; case FUNCTION_S1: release_function (fun->d.function_s1_v); break; case FUNCTION_D1: release_expression (fun->d.function_d1_v); break; case FUNCTION_CONT: case FUNCTION_DCONT: release_continuation (fun->d.function_cont_v); break; default: ; } free (fun); }
void free_expression (struct expression_s *expr) { if ( expr->refcnt ) return; switch ( expr->t ) { case EXPRESSION_FUNCTION: release_function (expr->d.expression_function_v); break; case EXPRESSION_APPLICATION: release_expression (expr->d.expression_application_v.rator); release_expression (expr->d.expression_application_v.rand); break; } free (expr); }
void free_continuation (struct continuation_s *cont) { if ( cont->refcnt ) return; switch ( cont->t ) { case CONTINUATION_APP1: release_expression (cont->d.continuation_app1_v.rand); release_continuation (cont->d.continuation_app1_v.cont); break; case CONTINUATION_APP: release_function (cont->d.continuation_app_v.erator); release_continuation (cont->d.continuation_app_v.cont); break; case CONTINUATION_DEL: release_function (cont->d.continuation_del_v.erand); release_continuation (cont->d.continuation_del_v.cont); break; default: ; } free (cont); }