void hklr_statement_free(HklrStatement* stmt) { assert(stmt != NULL); switch (stmt->type) { case HKL_STMT_PUTS: // Free the expression hklr_expression_free(stmt->arg[0].expression); break; case HKL_STMT_INIT: hklr_expression_free(stmt->arg[2].expression); break; case HKL_STMT_ASSIGN: hklr_expression_free(stmt->arg[0].expression); hklr_expression_free(stmt->arg[1].expression); break; case HKL_STMT_IF: case HKL_STMT_WHILE: hklr_expression_free(stmt->arg[0].expression); hkl_list_traverse(stmt->arg[1].list, hklr_statement_free_list, NULL); hkl_list_free(stmt->arg[1].list); break; default: break; } hkl_free_object(stmt); }
static bool hklr_hash_free_list(void* pair, void* data) { // each item contains a string expression pair hklr_expression_free((HklrExpression*) ((HklPair*) pair)->value); hkl_pair_free((HklPair*) pair); return false; }
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); }
static bool hklr_array_free_list(void* expr, void* data) { hklr_expression_free(expr); return false; }
void hklr_statement_exec(HklrStatement* stmt) { assert(stmt != NULL); switch (stmt->type) { case HKL_STMT_PUTS: hklr_statement_puts(stmt->arg[0].expression); break; case HKL_STMT_HKLR: // Print runtime information fprintf(stdout, "Ops: %zu\n", HKLR.ops); fprintf(stdout, "Objects Created: %zu\n", HKLR.gc_created); fprintf(stdout, "Objects Freed: %zu\n", HKLR.gc_freed); fprintf(stdout, "Object Cycles: %zu\n", HKLR.gc_rootsize); fprintf(stdout, "GC Runs: %zu\n", HKLR.gc_runs); fprintf(stdout, "Scope Level: %zu\n", HKLR.scope_level); fprintf(stdout, "Globals: %zu\n", HKLR.globals->length); fprintf(stdout, "Locals: %zu\n", ((HklScope*) HKLR.scopes->tail->data)->locals->length); fprintf(stdout, "Upvals: %zu\n", ((HklScope*) HKLR.scopes->tail->data)->upvals->length); fflush(stdout); break; case HKL_STMT_INIT: { // This is very much a hack and needs to be made ALOT better // this doesn't actually play nice with flags, but will // do for now to create globals and locals if (stmt->arg[0].flags & HKL_FLAG_GLOBAL) hklr_global_insert(stmt->arg[1].string, hklr_object_new(HKL_TYPE_NIL, stmt->arg[0].flags)); else hklr_local_insert(stmt->arg[1].string, hklr_object_new(HKL_TYPE_NIL, stmt->arg[0].flags)); HklrExpression* temp = hklr_expression_new(HKL_EXPR_ID, stmt->arg[1].string); hklr_statement_assign(temp, stmt->arg[2].expression); hklr_expression_free(temp); } break; case HKL_STMT_ASSIGN: hklr_statement_assign(stmt->arg[0].expression, stmt->arg[1].expression); break; // HKL_STMT_ASSIGN case HKL_STMT_IF: hklr_statement_if(stmt->arg[0].expression, stmt->arg[1].list); break; case HKL_STMT_WHILE: hklr_statement_while(stmt->arg[0].expression, stmt->arg[1].list); break; default: break; } // Increment numbers of completed operations HKLR.ops++; }