diff options
author | martijnv | 2001-05-10 08:24:10 +0000 |
---|---|---|
committer | martijnv | 2001-05-10 08:24:10 +0000 |
commit | 99101dfbff1e519834132a038a945257992af4d0 (patch) | |
tree | 300bdf76bae6bd6c08a617bdcaa864b72e6065e1 | |
parent | compiler option added: -dynamics which instructs the compiler to generate (diff) |
bug fixes:
- unused dynamics in where/let clauses do not cause a rule doesn't match
error in overloading.icl instead they are ignored
- default behaviour changed e.g.
f (i :: Int, j :: Int) = abort "Int"
f (r :: Real, s :: Real) = abort "Real"
f _ = abort "stop"
The compiler first matched on the tuple and then did the dynamic pattern
matches. But the last match did not call the last (default) alternative if it
did not match.
- some small changes
git-svn-id: https://svn.cs.ru.nl/repos/clean-compiler/trunk@421 1f8540f1-abd5-4d5b-9d24-4c5ce8603e2d
-rw-r--r-- | frontend/check.icl | 2 | ||||
-rw-r--r-- | frontend/checkFunctionBodies.dcl | 3 | ||||
-rw-r--r-- | frontend/checkFunctionBodies.icl | 11 | ||||
-rw-r--r-- | frontend/checktypes.icl | 14 | ||||
-rw-r--r-- | frontend/explicitimports.icl | 4 | ||||
-rw-r--r-- | frontend/generics.icl | 3 | ||||
-rw-r--r-- | frontend/overloading.icl | 10 | ||||
-rw-r--r-- | frontend/syntax.dcl | 2 | ||||
-rw-r--r-- | frontend/syntax.icl | 2 | ||||
-rw-r--r-- | frontend/transform.dcl | 3 | ||||
-rw-r--r-- | frontend/transform.icl | 69 | ||||
-rw-r--r-- | frontend/type.icl | 8 |
12 files changed, 96 insertions, 35 deletions
diff --git a/frontend/check.icl b/frontend/check.icl index bd3a8e6..74db3f3 100644 --- a/frontend/check.icl +++ b/frontend/check.icl @@ -735,7 +735,7 @@ checkFunction mod_index fun_index def_level fun_defs = check_function_type fun_type mod_index ef_type_defs ef_class_defs ef_modules hp_var_heap hp_type_heaps cs e_info = { e_info & ef_type_defs = ef_type_defs, ef_class_defs = ef_class_defs, ef_modules = ef_modules } e_state = { es_var_heap = hp_var_heap, es_expr_heap = hp_expression_heap, es_type_heaps = hp_type_heaps, - es_dynamics = [], es_calls = [], es_fun_defs = fun_defs } + es_dynamics = [], es_calls = [], es_fun_defs = fun_defs, es_dynamic_expr_count = 0} e_input = { ei_expr_level = inc def_level, ei_fun_index = fun_index, ei_fun_level = inc def_level, ei_mod_index = mod_index } (fun_body, free_vars, e_state, e_info, cs) = checkFunctionBodies fun_body e_input e_state e_info cs diff --git a/frontend/checkFunctionBodies.dcl b/frontend/checkFunctionBodies.dcl index 58ef680..5f655a8 100644 --- a/frontend/checkFunctionBodies.dcl +++ b/frontend/checkFunctionBodies.dcl @@ -9,6 +9,9 @@ import syntax, checksupport , es_calls :: ![FunCall] , es_dynamics :: ![ExprInfoPtr] , es_fun_defs :: !.{# FunDef} +// MV ... + , es_dynamic_expr_count :: !Int // used to give each dynamic expr an unique id +// ... MV } :: ExpressionInput = diff --git a/frontend/checkFunctionBodies.icl b/frontend/checkFunctionBodies.icl index 5378773..065a7ac 100644 --- a/frontend/checkFunctionBodies.icl +++ b/frontend/checkFunctionBodies.icl @@ -16,6 +16,9 @@ cEndWithSelection :== False , es_calls :: ![FunCall] , es_dynamics :: ![ExprInfoPtr] , es_fun_defs :: !.{# FunDef} +// MV ... + , es_dynamic_expr_count :: !Int // used to give each dynamic expr an unique id +// ... MV } :: ExpressionInput = @@ -812,12 +815,14 @@ where get_field_var _ = ({ id_name = "** ERRONEOUS **", id_info = nilPtr }, nilPtr) -checkExpression free_vars (PE_Dynamic expr opt_type) e_input e_state=:{es_expr_heap,es_dynamics} e_info cs=:{cs_x} - # (dyn_info_ptr, es_expr_heap) = newPtr (EI_Dynamic opt_type) es_expr_heap +// MV ... +checkExpression free_vars (PE_Dynamic expr opt_type) e_input e_state=:{es_expr_heap,es_dynamics, es_dynamic_expr_count } e_info cs=:{cs_x} + # (dyn_info_ptr, es_expr_heap) = newPtr (EI_Dynamic opt_type es_dynamic_expr_count) es_expr_heap (dyn_expr, free_vars, e_state, e_info, cs) = checkExpression free_vars expr e_input - {e_state & es_dynamics = [dyn_info_ptr : es_dynamics], es_expr_heap = es_expr_heap } e_info cs + {e_state & es_dynamics = [dyn_info_ptr : es_dynamics], es_expr_heap = es_expr_heap, es_dynamic_expr_count = inc es_dynamic_expr_count} e_info cs = (DynamicExpr { dyn_expr = dyn_expr, dyn_opt_type = opt_type, dyn_info_ptr = dyn_info_ptr, dyn_type_code = TCE_Empty, dyn_uni_vars = [] }, free_vars, e_state, e_info, { cs & cs_x.x_needed_modules = cs_x.x_needed_modules bitor cNeedStdDynamics }) +// ... MV checkExpression free_vars (PE_Basic basic_value) e_input e_state e_info cs # (basic_type, cs) = typeOfBasicValue basic_value cs diff --git a/frontend/checktypes.icl b/frontend/checktypes.icl index 5cee450..b760013 100644 --- a/frontend/checktypes.icl +++ b/frontend/checktypes.icl @@ -904,9 +904,9 @@ where remove_global_type_variables_in_dynamic dyn_info_ptr (expr_heap, symbol_table) # (dyn_info, expr_heap) = readPtr dyn_info_ptr expr_heap = case dyn_info of - EI_Dynamic (Yes {dt_global_vars}) + EI_Dynamic (Yes {dt_global_vars}) _ -> (expr_heap, remove_global_type_variables dt_global_vars symbol_table) - EI_Dynamic No + EI_Dynamic No _ -> (expr_heap, symbol_table) EI_DynamicTypeWithVars loc_type_vars {dt_global_vars} loc_dynamics -> remove_global_type_variables_in_dynamics loc_dynamics (expr_heap, remove_global_type_variables dt_global_vars symbol_table) @@ -943,9 +943,9 @@ where check_global_type_variables_in_dynamic dyn_info_ptr (expr_heap, cs) # (dyn_info, expr_heap) = readPtr dyn_info_ptr expr_heap = case dyn_info of - EI_Dynamic (Yes {dt_global_vars}) + EI_Dynamic (Yes {dt_global_vars}) _ -> (expr_heap, check_global_type_variables dt_global_vars cs) - EI_Dynamic No + EI_Dynamic No _ -> (expr_heap, cs) EI_DynamicTypeWithVars loc_type_vars {dt_global_vars} loc_dynamics -> check_global_type_variables_in_dynamics loc_dynamics (expr_heap, check_global_type_variables dt_global_vars cs) @@ -967,15 +967,15 @@ where check_dynamic mod_index scope dyn_info_ptr (type_defs, modules, type_heaps, expr_heap, cs) # (dyn_info, expr_heap) = readPtr dyn_info_ptr expr_heap = case dyn_info of - EI_Dynamic opt_type + EI_Dynamic opt_type ei_dynamic_id -> case opt_type of Yes dyn_type # (dyn_type, loc_type_vars, type_defs, modules, type_heaps, cs) = check_dynamic_type mod_index scope dyn_type type_defs modules type_heaps cs | isEmpty loc_type_vars - -> (type_defs, modules, type_heaps, expr_heap <:= (dyn_info_ptr, EI_Dynamic (Yes dyn_type)), cs) + -> (type_defs, modules, type_heaps, expr_heap <:= (dyn_info_ptr, EI_Dynamic (Yes dyn_type) ei_dynamic_id), cs) # cs_symbol_table = removeVariablesFromSymbolTable scope loc_type_vars cs.cs_symbol_table cs_error = checkError loc_type_vars "type variable(s) not defined" cs.cs_error - -> (type_defs, modules, type_heaps, expr_heap <:= (dyn_info_ptr, EI_Dynamic (Yes dyn_type)), + -> (type_defs, modules, type_heaps, expr_heap <:= (dyn_info_ptr, EI_Dynamic (Yes dyn_type) ei_dynamic_id), { cs & cs_error = cs_error, cs_symbol_table = cs_symbol_table }) No -> (type_defs, modules, type_heaps, expr_heap, cs) diff --git a/frontend/explicitimports.icl b/frontend/explicitimports.icl index db80c98..0bbdbb7 100644 --- a/frontend/explicitimports.icl +++ b/frontend/explicitimports.icl @@ -856,9 +856,9 @@ check_completeness_of_dyn_expr_ptr dyn_expr_ptr cci ccs=:{box_ccs=box_ccs=:{ccs_ #! (expr_info, ccs_expr_heap) = readPtr dyn_expr_ptr ccs_expr_heap ccs = { ccs & box_ccs = { box_ccs & ccs_expr_heap = ccs_expr_heap }} = case expr_info of - (EI_Dynamic No) + (EI_Dynamic No _) -> ccs - (EI_Dynamic (Yes dynamic_type)) + (EI_Dynamic (Yes dynamic_type) _) -> check_completeness dynamic_type cci ccs (EI_DynamicType dynamic_type further_dynamic_ptrs) -> check_completeness dynamic_type cci diff --git a/frontend/generics.icl b/frontend/generics.icl index 25221ee..e489f09 100644 --- a/frontend/generics.icl +++ b/frontend/generics.icl @@ -3286,6 +3286,9 @@ where , cos_var_heap = hp_var_heap , cos_symbol_heap = hp_expression_heap , cos_alias_dummy = {pds_ident=makeIdent "dummy", pds_module=NoIndex,pds_def=NoIndex} +// MV ... + , cos_removed_dynamic_expr = abort "error, please report to Martijn or Artem" +// ... MV } #! (body_expr, fun_arg_vars, local_vars, {cos_symbol_heap, cos_var_heap}) = determineVariablesAndRefCounts fun_arg_vars body_expr cs diff --git a/frontend/overloading.icl b/frontend/overloading.icl index 4ef4143..f77afab 100644 --- a/frontend/overloading.icl +++ b/frontend/overloading.icl @@ -1410,7 +1410,7 @@ where adjustClassExpression symb_name l=:(TypeCodeExpression type_code_expression) ui # (expr,uni_vars,ui) = convertTypecode type_code_expression [] ui - | not (isEmpty uni_vars) + | False //not (isEmpty uni_vars) # (let_binds,ui) = createVariables uni_vars ui (let_info_ptr,ui) = let_ptr ui = ( Let { let_strict_binds = [] @@ -1425,12 +1425,12 @@ where convertTypecode TCE_Empty uni_vars ui = (EE,uni_vars,ui) // should not match -// convertTypecode (TCE_Var var_info_ptr) uni_vars ui -// = (Var {var_name = a_ij_var_name, var_info_ptr = var_info_ptr, var_expr_ptr = nilPtr},[var_info_ptr:uni_vars],ui) + convertTypecode (TCE_Var var_info_ptr) uni_vars ui + = (Var {var_name = a_ij_var_name, var_info_ptr = var_info_ptr, var_expr_ptr = nilPtr},[var_info_ptr:uni_vars],ui) convertTypecode (TCE_TypeTerm var_info_ptr) uni_vars ui // # v_tc_name = { id_name = "overloadingvTC", id_info = nilPtr } -// = (Var {var_name = v_tc_name, var_info_ptr = var_info_ptr, var_expr_ptr = nilPtr},uni_vars,ui) - = (Var {var_name = v_tc_name, var_info_ptr = var_info_ptr, var_expr_ptr = nilPtr},[var_info_ptr:uni_vars],ui) + = (Var {var_name = v_tc_name, var_info_ptr = var_info_ptr, var_expr_ptr = nilPtr},uni_vars,ui) +// WAS = (Var {var_name = v_tc_name, var_info_ptr = var_info_ptr, var_expr_ptr = nilPtr},[var_info_ptr:uni_vars],ui) convertTypecode (TCE_Constructor index typecode_exprs) uni_vars ui # (typecons_symb,ui) = getSymbol PD_TypeConsSymbol SK_Constructor 2 ui diff --git a/frontend/syntax.dcl b/frontend/syntax.dcl index b1cf44a..1a53ace 100644 --- a/frontend/syntax.dcl +++ b/frontend/syntax.dcl @@ -669,7 +669,7 @@ cNonRecursiveAppl :== False /* For handling dynamics */ - | EI_Dynamic !(Optional DynamicType) + | EI_Dynamic !(Optional DynamicType) !Int | EI_DynamicType !DynamicType ![DynamicPtr] // | EI_DynamicType !DynamicType !(Optional ExprInfoPtr) diff --git a/frontend/syntax.icl b/frontend/syntax.icl index 3c91861..5118121 100644 --- a/frontend/syntax.icl +++ b/frontend/syntax.icl @@ -646,7 +646,7 @@ cNotVarNumber :== -1 /* For handling dynamics */ - | EI_Dynamic !(Optional DynamicType) + | EI_Dynamic !(Optional DynamicType) !Int | EI_DynamicType !DynamicType ![DynamicPtr] /* Auxiliary, was EI_DynamicType before checking */ diff --git a/frontend/transform.dcl b/frontend/transform.dcl index 26cd02a..b75b79c 100644 --- a/frontend/transform.dcl +++ b/frontend/transform.dcl @@ -21,6 +21,9 @@ partitionateMacros :: !IndexRange !Index !PredefinedSymbol !*{# FunDef} !*{# Dcl , cos_symbol_heap :: !.ExpressionHeap , cos_error :: !.ErrorAdmin , cos_alias_dummy :: !PredefinedSymbol +// MV ... + , cos_removed_dynamic_expr :: !.{#Bool} +// ... MV } determineVariablesAndRefCounts :: ![FreeVar] !Expression !*CollectState -> (!Expression , ![FreeVar], ![FreeVar], !*CollectState) diff --git a/frontend/transform.icl b/frontend/transform.icl index d4c5643..2ed3298 100644 --- a/frontend/transform.icl +++ b/frontend/transform.icl @@ -855,8 +855,8 @@ where es_fun_defs=macro_defs, es_main_dcl_module_n = mod_index, es_dcl_modules=modules, es_expand_in_imp_module=expand_in_imp_module,es_new_fun_def_numbers=[] } - # (tb_args, tb_rhs, local_vars, fi_calls, {es_symbol_table, es_var_heap, es_symbol_heap, es_error,es_dcl_modules,es_fun_defs}) - = expandMacrosInBody [] body alias_dummy es + # (tb_args, tb_rhs, local_vars, fi_calls, /* MV ... */ fun_info, /* ... MV */ {es_symbol_table, es_var_heap, es_symbol_heap, es_error,es_dcl_modules,es_fun_defs}) + = expandMacrosInBody [] body alias_dummy /* MV ... */ macro_index /* ... MV */ es # macro = { macro & fun_body = TransformedBody { tb_args = tb_args, tb_rhs = tb_rhs}, fun_info = { fun_info & fi_calls = fi_calls, fi_local_vars = local_vars }} = ({ es_fun_defs & [macro_index] = macro }, es_dcl_modules, @@ -1049,8 +1049,8 @@ where identPos = newPosition fun_symb fun_pos # expand_in_imp_module=case fun_kind of FK_ImpFunction _->True; FK_ImpMacro->True; FK_ImpCaf->True; _ -> False es={ es & es_expand_in_imp_module=expand_in_imp_module, es_error = setErrorAdmin identPos es.es_error } - # (tb_args, tb_rhs, fi_local_vars, fi_calls, es) - = expandMacrosInBody fun_info.fi_calls body alias_dummy es + # (tb_args, tb_rhs, fi_local_vars, fi_calls, /* MV ... */ fun_info, /* ... MV */ es) + = expandMacrosInBody fun_info.fi_calls body alias_dummy /* MV ... */ fun_index /* ... MV */ es fun_def = { fun_def & fun_body = TransformedBody { tb_args = tb_args, tb_rhs = tb_rhs}, fun_info = { fun_info & fi_calls = fi_calls, fi_local_vars = fi_local_vars }} = {es & es_fun_defs.[fun_index] = fun_def } @@ -1102,8 +1102,15 @@ where _ -> (fun_defs, symbol_table) -expandMacrosInBody :: [.FunCall] CheckedBody PredefinedSymbol *ExpandState -> ([FreeVar],Expression,[FreeVar],[FunCall],.ExpandState); -expandMacrosInBody fi_calls {cb_args,cb_rhs} alias_dummy es=:{es_symbol_table,es_fun_defs} +expandMacrosInBody :: [.FunCall] CheckedBody PredefinedSymbol /* MV ... */ !Int /* ... MV */ *ExpandState -> ([FreeVar],Expression,[FreeVar],[FunCall],/* MV ... */ !FunInfo, /* ... MV */ .ExpandState); +expandMacrosInBody fi_calls {cb_args,cb_rhs} alias_dummy /* MV ... */ es_current_fun_index /* ... MV */ es=:{es_symbol_table,es_fun_defs} +// MV ... + # (fun_def=:{fun_info},es_fun_defs) + = es_fun_defs![es_current_fun_index] + # cos_removed_dynamic_expr + = createArray (length fun_info.fi_dynamics) False // means not removed +// ... MV + # (prev_calls, fun_defs, es_symbol_table) = addFunctionCallsToSymbolTable fi_calls es_fun_defs es_symbol_table ([rhs:rhss], (all_calls, es) ) @@ -1112,14 +1119,41 @@ expandMacrosInBody fi_calls {cb_args,cb_rhs} alias_dummy es=:{es_symbol_table,es = removeFunctionCallsFromSymbolTable all_calls es.es_fun_defs es.es_symbol_table ((merged_rhs, _), es_var_heap, es_symbol_heap, es_error) = mergeCases rhs rhss es.es_var_heap es.es_symbol_heap es.es_error - (new_rhs, new_args, local_vars, {cos_error, cos_var_heap, cos_symbol_heap}) + (new_rhs, new_args, local_vars, {cos_error, cos_var_heap, cos_symbol_heap /* MV ... */, cos_removed_dynamic_expr /* ... MV */}) = determineVariablesAndRefCounts cb_args merged_rhs { cos_error = es_error, cos_var_heap = es_var_heap, cos_symbol_heap = es_symbol_heap, - cos_alias_dummy = alias_dummy } - = (new_args, new_rhs, local_vars, all_calls, + cos_alias_dummy = alias_dummy /* MV ... */, cos_removed_dynamic_expr = cos_removed_dynamic_expr /* ... MV */} + // MV ... + # (changed,fi_dynamics,_,cos_symbol_heap) + = foldSt remove_fi_dynamic fun_info.fi_dynamics (False,[],cos_removed_dynamic_expr,cos_symbol_heap) + # fun_info + = if changed { fun_info & fi_dynamics = fi_dynamics } fun_info + // ... MV + = (new_args, new_rhs, local_vars, all_calls, /* MV ... */ fun_info, /* ... MV */ { es & es_error = cos_error, es_var_heap = cos_var_heap, es_symbol_heap = cos_symbol_heap, es_fun_defs=fun_defs, es_symbol_table = symbol_table }) // ---> ("expandMacrosInBody", (cb_args, ca_rhs, '\n'), ("merged_rhs", merged_rhs, '\n'), ("new_rhs", new_args, local_vars, (new_rhs, '\n'))) +// MV ... +where + remove_fi_dynamic dyn_expr_ptr (changed,accu,cos_removed_dynamic_expr,cos_symbol_heap) + # (expr_info,cos_symbol_heap) + = readPtr dyn_expr_ptr cos_symbol_heap + | not (isEI_Dynamic expr_info) + = (changed,[dyn_expr_ptr:accu],cos_removed_dynamic_expr,cos_symbol_heap) + + # (EI_Dynamic _ id) + = expr_info + | cos_removed_dynamic_expr.[id] + // cos_removed_dynamic means cos_used_dynamic + = (changed,[dyn_expr_ptr:accu],cos_removed_dynamic_expr,cos_symbol_heap) + + + // unused + = (True,accu,cos_removed_dynamic_expr,cos_symbol_heap) + where + isEI_Dynamic (EI_Dynamic _ _) = True + isEI_Dynamic _ = False +// ... MV expandCheckedAlternative {ca_rhs, ca_position} ei # (ca_rhs, ei) = expand ca_rhs ei @@ -1701,6 +1735,9 @@ where , cos_symbol_heap :: !.ExpressionHeap , cos_error :: !.ErrorAdmin , cos_alias_dummy :: !PredefinedSymbol +// MV ... + , cos_removed_dynamic_expr :: !.{#Bool} +// ... MV } determineVariablesAndRefCounts :: ![FreeVar] !Expression !*CollectState -> (!Expression , ![FreeVar], ![FreeVar], !*CollectState) @@ -1889,8 +1926,18 @@ where collectVariables (MatchExpr opt_tuple cons_symb expr) free_vars cos # (expr, free_vars, cos) = collectVariables expr free_vars cos = (MatchExpr opt_tuple cons_symb expr, free_vars, cos) - collectVariables (DynamicExpr dynamic_expr=:{dyn_expr}) free_vars cos - #! (dyn_expr, free_vars, cos) = collectVariables dyn_expr free_vars cos + collectVariables (DynamicExpr dynamic_expr=:{dyn_expr /* MV ... */ , dyn_info_ptr /* ... MV */}) free_vars cos + #! (dyn_expr, free_vars, cos /* MV ... */ =:{cos_symbol_heap} /* ... MV */) = collectVariables dyn_expr free_vars cos +// MV ... + # (expr_info,cos_symbol_heap) + = readPtr dyn_info_ptr cos_symbol_heap + # cos + = { cos & cos_symbol_heap = cos_symbol_heap } + # cos + = case expr_info of + EI_Dynamic _ id -> { cos & cos_removed_dynamic_expr = { cos.cos_removed_dynamic_expr & [id] = True } } + _ -> cos +// ... MV = (DynamicExpr {dynamic_expr & dyn_expr = dyn_expr}, free_vars, cos); collectVariables expr free_vars cos = (expr, free_vars, cos) diff --git a/frontend/type.icl b/frontend/type.icl index 5f3b2da..ebd5fe9 100644 --- a/frontend/type.icl +++ b/frontend/type.icl @@ -1686,7 +1686,7 @@ where fresh_dynamic dyn_ptr (var_store, type_heaps, var_heap, expr_heap, predef_symbols) # (dyn_info, expr_heap) = readPtr dyn_ptr expr_heap = case dyn_info of - EI_Dynamic opt_dyn_type=:(Yes {dt_uni_vars,dt_type,dt_global_vars}) + EI_Dynamic opt_dyn_type=:(Yes {dt_uni_vars,dt_type,dt_global_vars}) _ # (th_vars, var_store) = fresh_existential_attributed_variables dt_uni_vars (type_heaps.th_vars, var_store) (th_vars, var_store) = fresh_type_variables dt_global_vars (th_vars, var_store) (tdt_type, {copy_heaps}) = freshCopy dt_type { copy_heaps = { type_heaps & th_vars = th_vars }} @@ -1694,7 +1694,7 @@ where = determine_context_and_expr_ptr dt_global_vars (var_heap, expr_heap, copy_heaps.th_vars, predef_symbols) -> (var_store, { copy_heaps & th_vars = type_var_heap }, var_heap, expr_heap <:= (dyn_ptr, EI_TempDynamicType opt_dyn_type tdt_type contexts expr_ptr type_code_symbol), predef_symbols) - EI_Dynamic No + EI_Dynamic No _ # fresh_var = TempV var_store tdt_type = { at_attribute = TA_Multi, at_annotation = AN_None, at_type = fresh_var } @@ -1726,9 +1726,9 @@ where clear_dynamic dyn_ptr (var_heap, expr_heap) # (dyn_info, expr_heap) = readPtr dyn_ptr expr_heap = case dyn_info of - EI_Dynamic (Yes {dt_global_vars}) + EI_Dynamic (Yes {dt_global_vars}) _ -> (clear_type_vars dt_global_vars var_heap, expr_heap) - EI_Dynamic No + EI_Dynamic No _ -> (var_heap, expr_heap) EI_DynamicTypeWithVars loc_type_vars {dt_global_vars} loc_dynamics -> clear_local_dynamics loc_dynamics (clear_type_vars dt_global_vars var_heap, expr_heap) |