HklValue* hklr_op_size(HklValue* value) { // Dereference if (value->type == HKL_TYPE_REF) { HklValue* temp = value; value = hklr_object_dereference(value->as.object); hkl_value_free(temp); } switch (value->type) { case HKL_TYPE_STRING: { HklString* string = value->as.string; value->type = HKL_TYPE_INT; value->as.integer = string->length; hkl_string_free(string); } break; default: assert(false); break; } return value; }
void hklr_expression_free(HklrExpression* expr) { assert(expr != NULL); switch (expr->type) { case HKL_EXPR_STRING: // free the internal string hkl_string_free(expr->arg[0].string); break; case HKL_EXPR_UNARY: hklr_expression_free(expr->arg[1].expression); break; case HKL_EXPR_BINARY: hklr_expression_free(expr->arg[0].expression); hklr_expression_free(expr->arg[2].expression); break; case HKL_EXPR_VAR: hkl_string_free(expr->arg[0].string); hkl_list_traverse(expr->arg[1].list, hklr_var_free_list, NULL); hkl_list_free(expr->arg[1].list); break; case HKL_EXPR_ARRAY: hkl_list_traverse(expr->arg[0].list, hklr_array_free_list, NULL); hkl_list_free(expr->arg[0].list); break; case HKL_EXPR_HASH: hkl_list_traverse(expr->arg[0].list, hklr_hash_free_list, NULL); hkl_list_free(expr->arg[0].list); break; default: break; } hkl_free_object(expr); }
void hkl_value_free(HklValue* value) { assert(value != NULL); switch (value->type) { case HKL_TYPE_STRING: hkl_string_free(value->as.string); break; default: break; } hkl_free_object(value); }
int main(int argc, const char* argv[]) { HklTree* testtree = hkl_tree_new(); HklString* testname = hkl_string_new(); // Registered tests // This line gives the function "hashtest" defined in test/hash.c // external linkage. If you don't know what that means, don't worry bout it. // :P :3 extern HklTestFunction hashtest; hkl_string_set_utf8(testname, "hash"); hkl_tree_insert(testtree, testname, &hashtest); extern HklTestFunction gctest; hkl_string_set_utf8(testname, "gc"); hkl_tree_insert(testtree, testname, &gctest); extern HklTestFunction traversaltest; hkl_string_set_utf8(testname, "traversal"); hkl_tree_insert(testtree, testname, &traversaltest); if (argv[1] == NULL) { fprintf(stderr, "No test given. Exiting.\n"); return 1; } hkl_string_set_utf8(testname, argv[1]); HklPair* pair = hkl_tree_search(testtree, testname); if (pair == NULL) { fprintf(stderr, "Test \"%s\" does not exist!\n", argv[1]); return 1; } HklTestFunction test = pair->value; if (test) test(&argv[2]); hkl_string_free(testname); hkl_tree_free(testtree); return 0; }
void hklr_object_free(HklrObject* object) { assert(object != NULL); switch (object->type) { case HKL_TYPE_STRING: hkl_string_free(object->as.string); break; default: break; } hkl_free_object(object); }
void hkl_expression_free(HklExpression* expr) { assert(expr != NULL); switch (expr->type) { case HKL_EXPR_STRING: // free the internal string hkl_string_free(expr->arg[0].string); break; default: break; } hkl_free_object(expr); }
void hkl_pair_free(HklPair* pair) { hkl_string_free(pair->key); hkl_free_object(pair); }
static bool free_names(void* key, void* data) { hkl_string_free((HklString*) key); return false; }
void hklr_statement_assign(HklrExpression* lhs, HklrExpression* rhs) { // Evaluate the left hand side and then discard the value object HklValue* vobj = hklr_expression_eval(lhs); HklrObject* object = vobj->as.object; hkl_value_free(vobj); HklValue* value = hklr_expression_eval(rhs); assert(object != NULL); assert(value != NULL); // dereference the objcet if (value->type == HKL_TYPE_REF) { HklValue* temp = value; value = hklr_object_dereference(value->as.object); hkl_value_free(temp); } // wipe out the original value // Composite objects will // create new objects to replace the variable // and decrease the ref count of the original switch (object->type) { case HKL_TYPE_STRING: hkl_string_free(object->as.string); break; default: break; } switch (value->type) { case HKL_TYPE_NIL: object->type = HKL_TYPE_NIL; break; case HKL_TYPE_INT: object->type = HKL_TYPE_INT; object->as.integer = value->as.integer; break; case HKL_TYPE_REAL: object->type = HKL_TYPE_REAL; object->as.real = value->as.real; break; case HKL_TYPE_STRING: object->type = HKL_TYPE_STRING; object->as.string = hkl_string_new_from_string(value->as.string); break; default: break; } hkl_value_free(value); }
HklValue* hklr_op_size(HklValue* value) { bool temporary = true; // Dereference if (value->type == HKL_TYPE_REF) { HklValue* temp = value; value = hklr_object_dereference(value->as.object); // Don't free the deque or hash since it can't be a temporary if (value->type == HKL_TYPE_ARRAY || value->type == HKL_TYPE_HASH || value->type == HKL_TYPE_FUNCTION) { temporary = false; // simply spoof the value temp->type = HKL_TYPE_NIL; } hkl_value_free(temp); } switch (value->type) { case HKL_TYPE_STRING: { HklString* string = value->as.string; value->type = HKL_TYPE_INT; value->as.integer = string->length; hkl_string_free(string); } break; case HKL_TYPE_ARRAY: { HklDeque* deque = value->as.deque; value->type = HKL_TYPE_INT; value->as.integer = deque->size; if (temporary) { // Free the deque hkl_value_free(hkl_value_new(HKL_TYPE_ARRAY, deque)); } } break; case HKL_TYPE_HASH: { HklHash* hash = value->as.hash; value->type = HKL_TYPE_INT; value->as.integer = hash->length; if (temporary) { // Free the hash hkl_value_free(hkl_value_new(HKL_TYPE_HASH, hash)); } } break; case HKL_TYPE_FUNCTION: { HklrFunction* function = value->as.function; value->type = HKL_TYPE_INT; value->as.integer = function->stmt_list->size; if (temporary) { // Free the function hklr_function_free(function); } } break; default: assert(false); break; } return value; }