diff options
author | johnvg | 2010-07-06 10:22:14 +0000 |
---|---|---|
committer | johnvg | 2010-07-06 10:22:14 +0000 |
commit | 8362a2da8f1baa6643e0aa4f80b209b0a513d23f (patch) | |
tree | 1e447d7e81f5b3f548a89e5c522b7ea4effdf11a | |
parent | dont pass icl functions array to/from checkDclMacros, (diff) |
move some functions from module check to new module checkgenerics
git-svn-id: https://svn.cs.ru.nl/repos/clean-compiler/trunk@1793 1f8540f1-abd5-4d5b-9d24-4c5ce8603e2d
-rw-r--r-- | frontend/check.icl | 311 | ||||
-rw-r--r-- | frontend/checkgenerics.dcl | 16 | ||||
-rw-r--r-- | frontend/checkgenerics.icl | 321 |
3 files changed, 339 insertions, 309 deletions
diff --git a/frontend/check.icl b/frontend/check.icl index 6ce659b..2888ece 100644 --- a/frontend/check.icl +++ b/frontend/check.icl @@ -6,6 +6,7 @@ import syntax, typesupport, parse, checksupport, utilities, checktypes, transfor import explicitimports, comparedefimp, checkFunctionBodies, containers, compilerSwitches import genericsupport import typereify +from checkgenerics import checkGenericDefs,checkGenericCaseDefs,convert_generic_instances,create_gencase_funtypes // import RWSDebug cUndef :== (-1) @@ -14,253 +15,6 @@ cDummyArray :== {} isMainModule :: ModuleKind -> Bool isMainModule MK_Main = True isMainModule _ = False - -checkGenericDefs :: !Index !(Optional (CopiedDefinitions, Int)) !*{#GenericDef} !*{#CheckedTypeDef} !*{#ClassDef} !*{#DclModule} !*Heaps !*CheckState - -> (!*{#GenericDef}, !*{#CheckedTypeDef}, !*{#ClassDef}, !*{#DclModule}, !*Heaps, !*CheckState) -checkGenericDefs mod_index opt_icl_info gen_defs type_defs class_defs modules heaps cs - = check_generics 0 mod_index opt_icl_info gen_defs type_defs class_defs modules heaps cs -where - check_generics index mod_index opt_icl_info gen_defs type_defs class_defs modules heaps cs - # (n_generics, gen_defs) = usize gen_defs - | index == n_generics - = (gen_defs, type_defs, class_defs, modules, heaps, cs) - # (gen_defs, type_defs, class_defs, modules, heaps, cs) - = check_generic_def index mod_index opt_icl_info gen_defs type_defs class_defs modules heaps cs - = check_generics (inc index) mod_index opt_icl_info gen_defs type_defs class_defs modules heaps cs - - check_generic_def index mod_index opt_icl_info gen_defs type_defs class_defs modules heaps cs - | has_to_be_checked mod_index index opt_icl_info - = check_generic index mod_index gen_defs type_defs class_defs modules heaps cs - //---> ("check_generic", mod_index, index) - = (gen_defs, type_defs, class_defs, modules, heaps, cs) - //---> ("skipped check_generic", mod_index, index) - - has_to_be_checked module_index generic_index No - = True - has_to_be_checked module_index generic_index (Yes ({copied_generic_defs}, n_cached_dcl_mods)) - = not (module_index < n_cached_dcl_mods && generic_index < size copied_generic_defs && copied_generic_defs.[generic_index]) - - check_generic index mod_index gen_defs type_defs class_defs modules heaps cs - - #(gen_def=:{gen_ident, gen_pos}, gen_defs) = gen_defs ! [index] - # cs = pushErrorAdmin (newPosition gen_ident gen_pos) cs - - # (gen_def, heaps) = alloc_gen_info gen_def heaps - - # (gen_def, type_defs, class_defs, modules, heaps, cs) - = check_generic_type gen_def mod_index type_defs class_defs modules heaps cs - - //# (heaps, cs) = check_generic_vars gen_def heaps cs - - # gen_defs = {gen_defs & [index] = gen_def} - # (cs=:{cs_x}) = popErrorAdmin cs - #! cs = { cs & cs_x = {cs_x & x_needed_modules = cs_x.x_needed_modules bitor cNeedStdGeneric}} - = (gen_defs, type_defs, class_defs, modules, heaps, cs) - //---> ("check_generic", gen_ident, gen_def.gen_vars, gen_def.gen_type) - - alloc_gen_info gen_def heaps=:{hp_generic_heap} - # initial_info = - { gen_classes = createArray 32 [] - , gen_var_kinds = [] - } - # (gen_info_ptr, hp_generic_heap) = newPtr initial_info hp_generic_heap - = ( {gen_def & gen_info_ptr = gen_info_ptr}, - {heaps & hp_generic_heap = hp_generic_heap}) - - check_generic_vars {gen_vars,gen_type} heaps=:{hp_type_heaps=hp_type_heaps=:{th_vars}} cs - #! types = [gen_type.st_result:gen_type.st_args] - #! th_vars = performOnTypeVars mark_var types th_vars - #! (th_vars,cs) = foldSt check_var_marked gen_vars (th_vars,cs) - #! th_vars = performOnTypeVars initializeToTVI_Empty types th_vars - = ({heaps & hp_type_heaps={hp_type_heaps&th_vars=th_vars}}, cs) - where - mark_var _ {tv_ident,tv_info_ptr} th_vars - = writePtr tv_info_ptr TVI_Used th_vars - check_var_marked {tv_ident,tv_info_ptr} (th_vars,cs=:{cs_error}) - #! (tv_info, th_vars) = readPtr tv_info_ptr th_vars - #! cs_error = case tv_info of - TVI_Empty -> checkError tv_ident "generic variable not used" cs_error - TVI_Used -> cs_error - = (th_vars, {cs & cs_error = cs_error}) - - check_generic_type gen_def=:{gen_type, gen_vars, gen_ident, gen_pos} module_index type_defs class_defs modules heaps=:{hp_type_heaps} cs - - #! (checked_gen_type, _, type_defs, class_defs, modules, hp_type_heaps, cs) = - checkFunctionType module_index gen_type SP_None type_defs class_defs modules hp_type_heaps cs - - #! (checked_gen_vars, cs) = check_generic_vars gen_vars checked_gen_type.st_vars cs - #! checked_gen_type = { checked_gen_type & st_vars = move_gen_vars checked_gen_vars checked_gen_type.st_vars} - - #! (hp_type_heaps, cs) = check_no_generic_vars_in_contexts checked_gen_type checked_gen_vars hp_type_heaps cs - = ( {gen_def & gen_type = checked_gen_type, gen_vars = checked_gen_vars} - , type_defs - , class_defs - , modules - , {heaps & hp_type_heaps = hp_type_heaps} - , cs - ) - //---> ("check_genric_type", gen_vars, checked_gen_vars, checked_gen_type) - where - check_generic_vars gen_vars st_vars cs=:{cs_error} - # (gen_vars, _, cs_error) = foldSt check_generic_var gen_vars ([], st_vars, cs_error) - = (reverse gen_vars, {cs & cs_error = cs_error}) - - // make sure generic variables are first - move_gen_vars gen_vars st_vars - = gen_vars ++ (removeMembers st_vars gen_vars) - - check_generic_var gv (acc_gvs, [], error) - = (acc_gvs, [], checkError gv.tv_ident "generic variable not used" error) - check_generic_var gv (acc_gvs, [tv:tvs], error) - | gv.tv_ident.id_name == tv.tv_ident.id_name - = ([tv:acc_gvs], tvs, error) - # (acc_gvs, tvs, error) = check_generic_var gv (acc_gvs, tvs, error) - = (acc_gvs, [tv:tvs], error) - - // returns reversed variable list - add_vars_to_symbol_table gen_vars type_heaps=:{th_vars} cs=:{cs_error, cs_symbol_table} - #! (rev_gen_vars,cs_symbol_table,th_vars, cs_error) - = foldSt add_var_to_symbol_table gen_vars ([],cs.cs_symbol_table,th_vars, cs_error) - = ( rev_gen_vars, - {type_heaps & th_vars = th_vars}, - {cs & cs_error = cs_error, cs_symbol_table = cs_symbol_table}) - - add_var_to_symbol_table :: !TypeVar !(![TypeVar], !*SymbolTable, !*TypeVarHeap, !*ErrorAdmin) - -> (![TypeVar],!*SymbolTable,!*TypeVarHeap,!*ErrorAdmin) - add_var_to_symbol_table tv=:{tv_ident={id_name,id_info}} (rev_class_args, symbol_table, th_vars, error) - #! (entry, symbol_table) = readPtr id_info symbol_table - | entry.ste_kind == STE_Empty || entry.ste_def_level < cGlobalScope - # (new_var_ptr, th_vars) = newPtr TVI_Empty th_vars - # symbol_table = NewEntry symbol_table id_info (STE_TypeVariable new_var_ptr) NoIndex cGlobalScope entry - = ([{ tv & tv_info_ptr = new_var_ptr} : rev_class_args], symbol_table, th_vars, error) - = (rev_class_args, symbol_table, th_vars, checkError id_name "generic variable already defined" error) - - // also reverses variable list (but does not make coffe) - remove_vars_from_symbol_table rev_gen_vars cs=:{cs_symbol_table} - #! (gen_vars, cs_symbol_table) = foldSt remove_var_from_symbol_table rev_gen_vars ([], cs_symbol_table) - = (gen_vars, { cs & cs_symbol_table = cs_symbol_table}) - remove_var_from_symbol_table tv=:{tv_ident={id_name,id_info}} (gen_vars, symbol_table) - #! (entry, symbol_table) = readPtr id_info symbol_table - #! symbol_table = writePtr id_info entry.ste_previous symbol_table - =([tv:gen_vars], symbol_table) - - check_no_generic_vars_in_contexts :: !SymbolType ![TypeVar] !*TypeHeaps !*CheckState -> (!*TypeHeaps, !*CheckState) - check_no_generic_vars_in_contexts gen_type gen_vars th=:{th_vars} cs=:{cs_error} - #! th_vars = clear_type_vars gen_type.st_vars th_vars - #! th_vars = mark_type_vars_used gen_vars th_vars - #! (th_vars, cs_error) = check_type_vars_not_used gen_type.st_context th_vars cs_error - #! th_vars = clear_type_vars gen_type.st_vars th_vars - - = ({th & th_vars = th_vars}, {cs & cs_error = cs_error}) - where - mark_type_vars_used gen_vars th_vars - = foldSt (write_type_var_info TVI_Used) gen_vars th_vars - clear_type_vars gen_vars th_vars - = foldSt (write_type_var_info TVI_Empty) gen_vars th_vars - write_type_var_info tvi {tv_ident, tv_info_ptr} th_vars - = writePtr tv_info_ptr tvi th_vars - - check_type_vars_not_used :: ![TypeContext] !*TypeVarHeap !*ErrorAdmin -> (!*TypeVarHeap, !*ErrorAdmin) - check_type_vars_not_used contexts th_vars cs_error - # types = flatten [tc_types \\ {tc_types} <- contexts] - # atypes = [{at_type=t,at_attribute=TA_None} \\ t <- types] - = performOnTypeVars check_type_var_not_used atypes (th_vars, cs_error) - check_type_var_not_used attr tv=:{tv_ident, tv_info_ptr} (th_vars, cs_error) - #! (tv_info, th_vars) = readPtr tv_info_ptr th_vars - = case tv_info of - TVI_Empty - -> (th_vars, cs_error) - TVI_Used - #! cs_error = checkError tv_ident "context restrictions on generic variables are not allowed" cs_error - -> (th_vars, cs_error) - _ -> abort ("check_no_generic_vars_in_contexts: wrong TVI" ---> (tv, tv_info)) - -checkGenericCaseDefs :: !Index !*{#GenericCaseDef} !*{#GenericDef} !u:{#CheckedTypeDef} !*{#DclModule} !*Heaps !*CheckState - -> (!*{#GenericCaseDef}, !*{#GenericDef}, !u:{#CheckedTypeDef}, !*{#DclModule},!.Heaps,!.CheckState) -checkGenericCaseDefs mod_index gen_case_defs generic_defs type_defs modules heaps cs - = check_instances 0 mod_index gen_case_defs generic_defs type_defs modules heaps cs -where - check_instances index mod_index gen_case_defs generic_defs type_defs modules heaps cs - # (n_gc, gen_inst_defs) = usize gen_case_defs - | index == n_gc - = (gen_case_defs, generic_defs, type_defs, modules, heaps, cs) - # (gen_case_defs, generic_defs, type_defs, modules, heaps, cs) - = check_instance index mod_index gen_case_defs generic_defs type_defs modules heaps cs - = check_instances (inc index) mod_index gen_case_defs generic_defs type_defs modules heaps cs - - check_instance index mod_index gen_case_defs generic_defs type_defs modules heaps cs - - #! (case_def=:{gc_ident,gc_gident,gc_pos,gc_type}, gen_case_defs) = gen_case_defs ! [index] - - #! cs = pushErrorAdmin (newPosition gc_ident gc_pos) cs - - #! (gc_type, gc_type_cons, type_defs, modules, heaps, cs) - = check_instance_type mod_index gc_type type_defs modules heaps cs - - #! (generic_gi, cs) = get_generic_index gc_gident mod_index cs - | not cs.cs_error.ea_ok - # cs = popErrorAdmin cs - = (gen_case_defs, generic_defs, type_defs, modules, heaps, cs) - - #! case_def = - { case_def - & gc_generic = generic_gi - , gc_type = gc_type - , gc_type_cons = gc_type_cons - } - #! gen_case_defs = { gen_case_defs & [index] = case_def } - - #! (cs=:{cs_x}) = popErrorAdmin cs - #! cs = { cs & cs_x = {cs_x & x_needed_modules = cs_x.x_needed_modules bitor cNeedStdGeneric}} - = (gen_case_defs, generic_defs, type_defs, modules, heaps, cs) - //---> ("check_generic_case", gc_ident, gc_type_cons) - - check_instance_type module_index (TA type_cons []) type_defs modules heaps=:{hp_type_heaps} cs - # (entry, cs_symbol_table) = readPtr type_cons.type_ident.id_info cs.cs_symbol_table - # cs = {cs & cs_symbol_table = cs_symbol_table} - # (type_index, type_module) = retrieveGlobalDefinition entry STE_Type module_index - | type_index == NotFound - # cs_error = checkError type_cons.type_ident "generic argument type undefined" cs.cs_error - = (TA type_cons [], TypeConsSymb type_cons, type_defs, modules,{heaps&hp_type_heaps = hp_type_heaps}, {cs&cs_error=cs_error}) - # (type_def, type_defs, modules) - = getTypeDef module_index {glob_module=type_module, glob_object=type_index} type_defs modules - # type_cons = { type_cons & type_index = { glob_object = type_index, glob_module = type_module }} - | type_synonym_with_arguments type_def.td_rhs type_def.td_arity - # cs = {cs & cs_error = checkError type_def.td_ident "synonym type not allowed" cs.cs_error} - = (TA type_cons [], TypeConsSymb type_cons, type_defs, modules,{heaps&hp_type_heaps = hp_type_heaps}, cs) - = (TA type_cons [], TypeConsSymb type_cons, type_defs, modules,{heaps&hp_type_heaps = hp_type_heaps}, cs) - where - type_synonym_with_arguments (SynType _) arity - = arity>0 - type_synonym_with_arguments _ _ - = False - check_instance_type module_index (TB b) type_defs modules heaps cs - = (TB b, TypeConsBasic b, type_defs, modules,heaps, cs) - check_instance_type module_index TArrow type_defs modules heaps cs - = (TArrow, TypeConsArrow, type_defs, modules, heaps , cs) -// General instance .. - check_instance_type module_index (TV tv) type_defs modules heaps=:{hp_type_heaps} cs - # (tv_info_ptr, th_vars) = newPtr TVI_Empty hp_type_heaps.th_vars - # tv = {tv & tv_info_ptr = tv_info_ptr} - = ( TV tv, TypeConsVar tv, type_defs, modules - , {heaps& hp_type_heaps = {hp_type_heaps & th_vars = th_vars}}, cs) -// .. General instance - check_instance_type module_index ins_type type_defs modules heaps cs=:{cs_error} - # cs_error = checkError {id_name="<>",id_info=nilPtr} "invalid generic type argument" cs_error - = (ins_type, TypeConsArrow, type_defs, modules, heaps, {cs & cs_error=cs_error}) - - get_generic_index :: !Ident !Index !*CheckState -> (!GlobalIndex, !*CheckState) - get_generic_index {id_name,id_info} mod_index cs=:{cs_symbol_table} - # (ste, cs_symbol_table) = readPtr id_info cs_symbol_table - # cs = {cs & cs_symbol_table = cs_symbol_table} - = case ste.ste_kind of - STE_Generic - -> ({gi_module=mod_index,gi_index = ste.ste_index}, cs) - STE_Imported STE_Generic imported_generic_module - -> ({gi_module=imported_generic_module,gi_index = ste.ste_index}, cs) - _ -> //abort "--------------" ---> ("STE_Kind", ste.ste_kind) - ( {gi_module=NoIndex,gi_index = NoIndex} - , {cs & cs_error = checkError id_name "generic undefined" cs.cs_error}) checkTypeClasses :: !Index !(Optional (CopiedDefinitions, Int)) !*{#ClassDef} !*{#MemberDef} !*{#CheckedTypeDef} !*{#DclModule} !*Heaps !*CheckState -> (!*{#ClassDef}, !*{#MemberDef}, !*{#CheckedTypeDef}, !*{#DclModule}, !*Heaps, !*CheckState) @@ -2409,31 +2163,6 @@ check_module1 cdefs icl_global_function_range fun_defs optional_dcl_mod optional = (ins_members ++ next_fun_defs, [ParsedInstanceToClassInstance pi { member \\ member <- member_symbols} : cins]) convert_class_instances [] next_fun_index = ([], []) - - convert_generic_instances :: !.[GenericCaseDef] !Int -> (!.[FunDef], !.[GenericCaseDef]) - convert_generic_instances [gc=:{gc_ident, gc_body=GCB_FunDef fun_def} : gcs] next_fun_index - # (fun_defs, gcs) = convert_generic_instances gcs (inc next_fun_index) - # gc = { gc & gc_body = GCB_FunIndex next_fun_index } - = ([fun_def : fun_defs], [gc:gcs]) - //---> ("convert generic case: user defined function", gc.gc_ident, gc.gc_type_cons, next_fun_index) - convert_generic_instances [gc=:{gc_ident,gc_pos, gc_type_cons, gc_body=GCB_None} : gcs] next_fun_index - # (fun_defs, gcs) = convert_generic_instances gcs (inc next_fun_index) - # fun_def = - { fun_ident = genericIdentToFunIdent gc_ident.id_name gc_type_cons - , fun_arity = 0 - , fun_priority = NoPrio - , fun_body = GeneratedBody - , fun_type = No - , fun_pos = gc_pos - , fun_kind = FK_Unknown - , fun_lifted = 0 - , fun_info = EmptyFunInfo - } - # gc = { gc & gc_body = GCB_FunIndex next_fun_index } - = ([fun_def:fun_defs], [gc:gcs]) - //---> ("convert generic case: function to derive ", gc.gc_ident, gc.gc_type_cons, next_fun_index) - convert_generic_instances [] next_fun_index - = ([], []) determine_indexes_of_members [{fun_ident,fun_arity}:members] next_fun_index #! (member_symbols, last_fun_index) = determine_indexes_of_members members (inc next_fun_index) @@ -3311,43 +3040,7 @@ checkInstancesOfDclModule mod_index (nr_of_dcl_functions_and_instances, nr_of_dc dcl_modules = { dcl_modules & [mod_index] = dcl_mod } = (dcl_modules, heaps, cs) - where - create_gencase_funtypes :: !Index !*{#GenericCaseDef} !*Heaps - -> (!Index, ![FunType], !*{#GenericCaseDef}, !*Heaps) - create_gencase_funtypes fun_index gencase_defs heaps - #! (fun_index, new_funs, gencase_defs, hp_var_heap) - = create_funs 0 fun_index gencase_defs heaps.hp_var_heap - = (fun_index, new_funs, gencase_defs, {heaps & hp_var_heap = hp_var_heap}) - where - - create_funs gc_index fun_index gencase_defs hp_var_heap - | gc_index == size gencase_defs - = (fun_index, [], gencase_defs, hp_var_heap) - #! (fun, gencase_defs,hp_var_heap) - = create_fun gc_index fun_index gencase_defs hp_var_heap - #! (fun_index, funs, gencase_defs,hp_var_heap) - = create_funs (inc gc_index) (inc fun_index) gencase_defs hp_var_heap - = (fun_index, [fun:funs], gencase_defs, hp_var_heap) - create_fun gc_index fun_index gencase_defs hp_var_heap - # (gencase_def=:{gc_ident, gc_pos, gc_type_cons}, gencase_defs) = gencase_defs ! [gc_index] - # gencase_def = { gencase_def & gc_body = GCB_FunIndex fun_index } - # gencase_defs = {gencase_defs & [gc_index] = gencase_def} - - #! fun_ident = genericIdentToFunIdent gc_ident.id_name gc_type_cons - #! (var_info_ptr, hp_var_heap) = newPtr VI_Empty hp_var_heap - #! fun = - { ft_ident = fun_ident - , ft_arity = 0 - , ft_priority = NoPrio - , ft_type = {st_vars=[],st_attr_vars=[],st_arity=0,st_args=[],st_result={at_type=TE,at_attribute=TA_Multi},st_attr_env=[],st_context=[],st_args_strictness=NotStrict} - , ft_pos = gc_pos - , ft_specials = SP_None - , ft_type_ptr = var_info_ptr - } - - = (fun, gencase_defs, hp_var_heap) - //---> ("create_gencase_funtypes", gc_ident, gc_type_cons, gc_index, fun_index) - + where adjust_instance_types_of_array_functions_in_std_array_dcl array_mod_index class_members class_instances fun_types cs=:{cs_predef_symbols} #! nr_of_instances = size class_instances # ({pds_def}, cs_predef_symbols) = cs_predef_symbols![PD_ArrayClass] diff --git a/frontend/checkgenerics.dcl b/frontend/checkgenerics.dcl new file mode 100644 index 0000000..18c0281 --- /dev/null +++ b/frontend/checkgenerics.dcl @@ -0,0 +1,16 @@ +definition module checkgenerics + +import syntax +from checksupport import ::Heaps,::CheckState + +checkGenericDefs :: !Index !(Optional (CopiedDefinitions, Int)) + !*{#GenericDef} !*{#CheckedTypeDef} !*{#ClassDef} !*{#DclModule} !*Heaps !*CheckState + -> (!*{#GenericDef},!*{#CheckedTypeDef},!*{#ClassDef},!*{#DclModule},!*Heaps,!*CheckState) + +checkGenericCaseDefs :: !Index !*{#GenericCaseDef} !*{#GenericDef} !u:{#CheckedTypeDef} !*{#DclModule} !*Heaps !*CheckState + -> (!*{#GenericCaseDef},!*{#GenericDef},!u:{#CheckedTypeDef},!*{#DclModule},!.Heaps,!.CheckState) + +convert_generic_instances :: !.[GenericCaseDef] !Int -> (!.[FunDef], !.[GenericCaseDef]) + +create_gencase_funtypes :: !Index !*{#GenericCaseDef} !*Heaps + -> (!Index, ![FunType], !*{#GenericCaseDef},!*Heaps) diff --git a/frontend/checkgenerics.icl b/frontend/checkgenerics.icl new file mode 100644 index 0000000..eb44eaf --- /dev/null +++ b/frontend/checkgenerics.icl @@ -0,0 +1,321 @@ +implementation module checkgenerics + +import syntax,checksupport,checktypes,genericsupport + +checkGenericDefs :: !Index !(Optional (CopiedDefinitions, Int)) + !*{#GenericDef} !*{#CheckedTypeDef} !*{#ClassDef} !*{#DclModule} !*Heaps !*CheckState + -> (!*{#GenericDef},!*{#CheckedTypeDef},!*{#ClassDef},!*{#DclModule},!*Heaps,!*CheckState) +checkGenericDefs mod_index opt_icl_info gen_defs type_defs class_defs modules heaps cs + = check_generics 0 mod_index opt_icl_info gen_defs type_defs class_defs modules heaps cs +where + check_generics index mod_index opt_icl_info gen_defs type_defs class_defs modules heaps cs + # (n_generics, gen_defs) = usize gen_defs + | index == n_generics + = (gen_defs, type_defs, class_defs, modules, heaps, cs) + # (gen_defs, type_defs, class_defs, modules, heaps, cs) + = check_generic_def index mod_index opt_icl_info gen_defs type_defs class_defs modules heaps cs + = check_generics (inc index) mod_index opt_icl_info gen_defs type_defs class_defs modules heaps cs + + check_generic_def index mod_index opt_icl_info gen_defs type_defs class_defs modules heaps cs + | has_to_be_checked mod_index index opt_icl_info + = check_generic index mod_index gen_defs type_defs class_defs modules heaps cs + //---> ("check_generic", mod_index, index) + = (gen_defs, type_defs, class_defs, modules, heaps, cs) + //---> ("skipped check_generic", mod_index, index) + + has_to_be_checked module_index generic_index No + = True + has_to_be_checked module_index generic_index (Yes ({copied_generic_defs}, n_cached_dcl_mods)) + = not (module_index < n_cached_dcl_mods && generic_index < size copied_generic_defs && copied_generic_defs.[generic_index]) + + check_generic index mod_index gen_defs type_defs class_defs modules heaps cs + + #(gen_def=:{gen_ident, gen_pos}, gen_defs) = gen_defs ! [index] + # cs = pushErrorAdmin (newPosition gen_ident gen_pos) cs + + # (gen_def, heaps) = alloc_gen_info gen_def heaps + + # (gen_def, type_defs, class_defs, modules, heaps, cs) + = check_generic_type gen_def mod_index type_defs class_defs modules heaps cs + + //# (heaps, cs) = check_generic_vars gen_def heaps cs + + # gen_defs = {gen_defs & [index] = gen_def} + # (cs=:{cs_x}) = popErrorAdmin cs + #! cs = { cs & cs_x = {cs_x & x_needed_modules = cs_x.x_needed_modules bitor cNeedStdGeneric}} + = (gen_defs, type_defs, class_defs, modules, heaps, cs) + //---> ("check_generic", gen_ident, gen_def.gen_vars, gen_def.gen_type) + + alloc_gen_info gen_def heaps=:{hp_generic_heap} + # initial_info = + { gen_classes = createArray 32 [] + , gen_var_kinds = [] + } + # (gen_info_ptr, hp_generic_heap) = newPtr initial_info hp_generic_heap + = ( {gen_def & gen_info_ptr = gen_info_ptr}, + {heaps & hp_generic_heap = hp_generic_heap}) + + check_generic_vars {gen_vars,gen_type} heaps=:{hp_type_heaps=hp_type_heaps=:{th_vars}} cs + #! types = [gen_type.st_result:gen_type.st_args] + #! th_vars = performOnTypeVars mark_var types th_vars + #! (th_vars,cs) = foldSt check_var_marked gen_vars (th_vars,cs) + #! th_vars = performOnTypeVars initializeToTVI_Empty types th_vars + = ({heaps & hp_type_heaps={hp_type_heaps&th_vars=th_vars}}, cs) + where + mark_var _ {tv_ident,tv_info_ptr} th_vars + = writePtr tv_info_ptr TVI_Used th_vars + check_var_marked {tv_ident,tv_info_ptr} (th_vars,cs=:{cs_error}) + #! (tv_info, th_vars) = readPtr tv_info_ptr th_vars + #! cs_error = case tv_info of + TVI_Empty -> checkError tv_ident "generic variable not used" cs_error + TVI_Used -> cs_error + = (th_vars, {cs & cs_error = cs_error}) + + check_generic_type gen_def=:{gen_type, gen_vars, gen_ident, gen_pos} module_index type_defs class_defs modules heaps=:{hp_type_heaps} cs + + #! (checked_gen_type, _, type_defs, class_defs, modules, hp_type_heaps, cs) = + checkFunctionType module_index gen_type SP_None type_defs class_defs modules hp_type_heaps cs + + #! (checked_gen_vars, cs) = check_generic_vars gen_vars checked_gen_type.st_vars cs + #! checked_gen_type = { checked_gen_type & st_vars = move_gen_vars checked_gen_vars checked_gen_type.st_vars} + + #! (hp_type_heaps, cs) = check_no_generic_vars_in_contexts checked_gen_type checked_gen_vars hp_type_heaps cs + = ( {gen_def & gen_type = checked_gen_type, gen_vars = checked_gen_vars} + , type_defs + , class_defs + , modules + , {heaps & hp_type_heaps = hp_type_heaps} + , cs + ) + //---> ("check_genric_type", gen_vars, checked_gen_vars, checked_gen_type) + where + check_generic_vars gen_vars st_vars cs=:{cs_error} + # (gen_vars, _, cs_error) = foldSt check_generic_var gen_vars ([], st_vars, cs_error) + = (reverse gen_vars, {cs & cs_error = cs_error}) + + // make sure generic variables are first + move_gen_vars gen_vars st_vars + = gen_vars ++ (removeMembers st_vars gen_vars) + + check_generic_var gv (acc_gvs, [], error) + = (acc_gvs, [], checkError gv.tv_ident "generic variable not used" error) + check_generic_var gv (acc_gvs, [tv:tvs], error) + | gv.tv_ident.id_name == tv.tv_ident.id_name + = ([tv:acc_gvs], tvs, error) + # (acc_gvs, tvs, error) = check_generic_var gv (acc_gvs, tvs, error) + = (acc_gvs, [tv:tvs], error) + + // returns reversed variable list + add_vars_to_symbol_table gen_vars type_heaps=:{th_vars} cs=:{cs_error, cs_symbol_table} + #! (rev_gen_vars,cs_symbol_table,th_vars, cs_error) + = foldSt add_var_to_symbol_table gen_vars ([],cs.cs_symbol_table,th_vars, cs_error) + = ( rev_gen_vars, + {type_heaps & th_vars = th_vars}, + {cs & cs_error = cs_error, cs_symbol_table = cs_symbol_table}) + + add_var_to_symbol_table :: !TypeVar !(![TypeVar], !*SymbolTable, !*TypeVarHeap, !*ErrorAdmin) + -> (![TypeVar],!*SymbolTable,!*TypeVarHeap,!*ErrorAdmin) + add_var_to_symbol_table tv=:{tv_ident={id_name,id_info}} (rev_class_args, symbol_table, th_vars, error) + #! (entry, symbol_table) = readPtr id_info symbol_table + | entry.ste_kind == STE_Empty || entry.ste_def_level < cGlobalScope + # (new_var_ptr, th_vars) = newPtr TVI_Empty th_vars + # symbol_table = NewEntry symbol_table id_info (STE_TypeVariable new_var_ptr) NoIndex cGlobalScope entry + = ([{ tv & tv_info_ptr = new_var_ptr} : rev_class_args], symbol_table, th_vars, error) + = (rev_class_args, symbol_table, th_vars, checkError id_name "generic variable already defined" error) + + // also reverses variable list (but does not make coffe) + remove_vars_from_symbol_table rev_gen_vars cs=:{cs_symbol_table} + #! (gen_vars, cs_symbol_table) = foldSt remove_var_from_symbol_table rev_gen_vars ([], cs_symbol_table) + = (gen_vars, { cs & cs_symbol_table = cs_symbol_table}) + remove_var_from_symbol_table tv=:{tv_ident={id_name,id_info}} (gen_vars, symbol_table) + #! (entry, symbol_table) = readPtr id_info symbol_table + #! symbol_table = writePtr id_info entry.ste_previous symbol_table + =([tv:gen_vars], symbol_table) + + check_no_generic_vars_in_contexts :: !SymbolType ![TypeVar] !*TypeHeaps !*CheckState -> (!*TypeHeaps, !*CheckState) + check_no_generic_vars_in_contexts gen_type gen_vars th=:{th_vars} cs=:{cs_error} + #! th_vars = clear_type_vars gen_type.st_vars th_vars + #! th_vars = mark_type_vars_used gen_vars th_vars + #! (th_vars, cs_error) = check_type_vars_not_used gen_type.st_context th_vars cs_error + #! th_vars = clear_type_vars gen_type.st_vars th_vars + + = ({th & th_vars = th_vars}, {cs & cs_error = cs_error}) + where + mark_type_vars_used gen_vars th_vars + = foldSt (write_type_var_info TVI_Used) gen_vars th_vars + clear_type_vars gen_vars th_vars + = foldSt (write_type_var_info TVI_Empty) gen_vars th_vars + write_type_var_info tvi {tv_ident, tv_info_ptr} th_vars + = writePtr tv_info_ptr tvi th_vars + + check_type_vars_not_used :: ![TypeContext] !*TypeVarHeap !*ErrorAdmin -> (!*TypeVarHeap, !*ErrorAdmin) + check_type_vars_not_used contexts th_vars cs_error + # types = flatten [tc_types \\ {tc_types} <- contexts] + # atypes = [{at_type=t,at_attribute=TA_None} \\ t <- types] + = performOnTypeVars check_type_var_not_used atypes (th_vars, cs_error) + check_type_var_not_used attr tv=:{tv_ident, tv_info_ptr} (th_vars, cs_error) + #! (tv_info, th_vars) = readPtr tv_info_ptr th_vars + = case tv_info of + TVI_Empty + -> (th_vars, cs_error) + TVI_Used + #! cs_error = checkError tv_ident "context restrictions on generic variables are not allowed" cs_error + -> (th_vars, cs_error) + _ -> abort ("check_no_generic_vars_in_contexts: wrong TVI" ---> (tv, tv_info)) + +checkGenericCaseDefs :: !Index !*{#GenericCaseDef} !*{#GenericDef} !u:{#CheckedTypeDef} !*{#DclModule} !*Heaps !*CheckState + -> (!*{#GenericCaseDef},!*{#GenericDef},!u:{#CheckedTypeDef},!*{#DclModule},!.Heaps,!.CheckState) +checkGenericCaseDefs mod_index gen_case_defs generic_defs type_defs modules heaps cs + = check_instances 0 mod_index gen_case_defs generic_defs type_defs modules heaps cs +where + check_instances index mod_index gen_case_defs generic_defs type_defs modules heaps cs + # (n_gc, gen_inst_defs) = usize gen_case_defs + | index == n_gc + = (gen_case_defs, generic_defs, type_defs, modules, heaps, cs) + # (gen_case_defs, generic_defs, type_defs, modules, heaps, cs) + = check_instance index mod_index gen_case_defs generic_defs type_defs modules heaps cs + = check_instances (inc index) mod_index gen_case_defs generic_defs type_defs modules heaps cs + + check_instance index mod_index gen_case_defs generic_defs type_defs modules heaps cs + + #! (case_def=:{gc_ident,gc_gident,gc_pos,gc_type}, gen_case_defs) = gen_case_defs ! [index] + + #! cs = pushErrorAdmin (newPosition gc_ident gc_pos) cs + + #! (gc_type, gc_type_cons, type_defs, modules, heaps, cs) + = check_instance_type mod_index gc_type type_defs modules heaps cs + + #! (generic_gi, cs) = get_generic_index gc_gident mod_index cs + | not cs.cs_error.ea_ok + # cs = popErrorAdmin cs + = (gen_case_defs, generic_defs, type_defs, modules, heaps, cs) + + #! case_def = + { case_def + & gc_generic = generic_gi + , gc_type = gc_type + , gc_type_cons = gc_type_cons + } + #! gen_case_defs = { gen_case_defs & [index] = case_def } + + #! (cs=:{cs_x}) = popErrorAdmin cs + #! cs = { cs & cs_x = {cs_x & x_needed_modules = cs_x.x_needed_modules bitor cNeedStdGeneric}} + = (gen_case_defs, generic_defs, type_defs, modules, heaps, cs) + //---> ("check_generic_case", gc_ident, gc_type_cons) + + check_instance_type module_index (TA type_cons []) type_defs modules heaps=:{hp_type_heaps} cs + # (entry, cs_symbol_table) = readPtr type_cons.type_ident.id_info cs.cs_symbol_table + # cs = {cs & cs_symbol_table = cs_symbol_table} + # (type_index, type_module) = retrieveGlobalDefinition entry STE_Type module_index + | type_index == NotFound + # cs_error = checkError type_cons.type_ident "generic argument type undefined" cs.cs_error + = (TA type_cons [], TypeConsSymb type_cons, type_defs, modules,{heaps&hp_type_heaps = hp_type_heaps}, {cs&cs_error=cs_error}) + # (type_def, type_defs, modules) + = getTypeDef module_index {glob_module=type_module, glob_object=type_index} type_defs modules + # type_cons = { type_cons & type_index = { glob_object = type_index, glob_module = type_module }} + | type_synonym_with_arguments type_def.td_rhs type_def.td_arity + # cs = {cs & cs_error = checkError type_def.td_ident "synonym type not allowed" cs.cs_error} + = (TA type_cons [], TypeConsSymb type_cons, type_defs, modules,{heaps&hp_type_heaps = hp_type_heaps}, cs) + = (TA type_cons [], TypeConsSymb type_cons, type_defs, modules,{heaps&hp_type_heaps = hp_type_heaps}, cs) + where + type_synonym_with_arguments (SynType _) arity + = arity>0 + type_synonym_with_arguments _ _ + = False + check_instance_type module_index (TB b) type_defs modules heaps cs + = (TB b, TypeConsBasic b, type_defs, modules,heaps, cs) + check_instance_type module_index TArrow type_defs modules heaps cs + = (TArrow, TypeConsArrow, type_defs, modules, heaps , cs) +// General instance .. + check_instance_type module_index (TV tv) type_defs modules heaps=:{hp_type_heaps} cs + # (tv_info_ptr, th_vars) = newPtr TVI_Empty hp_type_heaps.th_vars + # tv = {tv & tv_info_ptr = tv_info_ptr} + = ( TV tv, TypeConsVar tv, type_defs, modules + , {heaps& hp_type_heaps = {hp_type_heaps & th_vars = th_vars}}, cs) +// .. General instance + check_instance_type module_index ins_type type_defs modules heaps cs=:{cs_error} + # cs_error = checkError {id_name="<>",id_info=nilPtr} "invalid generic type argument" cs_error + = (ins_type, TypeConsArrow, type_defs, modules, heaps, {cs & cs_error=cs_error}) + + get_generic_index :: !Ident !Index !*CheckState -> (!GlobalIndex, !*CheckState) + get_generic_index {id_name,id_info} mod_index cs=:{cs_symbol_table} + # (ste, cs_symbol_table) = readPtr id_info cs_symbol_table + # cs = {cs & cs_symbol_table = cs_symbol_table} + = case ste.ste_kind of + STE_Generic + -> ({gi_module=mod_index,gi_index = ste.ste_index}, cs) + STE_Imported STE_Generic imported_generic_module + -> ({gi_module=imported_generic_module,gi_index = ste.ste_index}, cs) + _ -> //abort "--------------" ---> ("STE_Kind", ste.ste_kind) + ( {gi_module=NoIndex,gi_index = NoIndex} + , {cs & cs_error = checkError id_name "generic undefined" cs.cs_error}) + +convert_generic_instances :: !.[GenericCaseDef] !Int -> (!.[FunDef], !.[GenericCaseDef]) +convert_generic_instances [gc=:{gc_ident, gc_body=GCB_FunDef fun_def} : gcs] next_fun_index + # (fun_defs, gcs) = convert_generic_instances gcs (inc next_fun_index) + # gc = { gc & gc_body = GCB_FunIndex next_fun_index } + = ([fun_def : fun_defs], [gc:gcs]) + //---> ("convert generic case: user defined function", gc.gc_ident, gc.gc_type_cons, next_fun_index) +convert_generic_instances [gc=:{gc_ident,gc_pos, gc_type_cons, gc_body=GCB_None} : gcs] next_fun_index + # (fun_defs, gcs) = convert_generic_instances gcs (inc next_fun_index) + # fun_def = + { fun_ident = genericIdentToFunIdent gc_ident.id_name gc_type_cons + , fun_arity = 0 + , fun_priority = NoPrio + , fun_body = GeneratedBody + , fun_type = No + , fun_pos = gc_pos + , fun_kind = FK_Unknown + , fun_lifted = 0 + , fun_info = EmptyFunInfo + } + # gc = { gc & gc_body = GCB_FunIndex next_fun_index } + = ([fun_def:fun_defs], [gc:gcs]) + //---> ("convert generic case: function to derive ", gc.gc_ident, gc.gc_type_cons, next_fun_index) +convert_generic_instances [] next_fun_index + = ([], []) + +create_gencase_funtypes :: !Index !*{#GenericCaseDef} !*Heaps + -> (!Index, ![FunType], !*{#GenericCaseDef},!*Heaps) +create_gencase_funtypes fun_index gencase_defs heaps + #! (fun_index, new_funs, gencase_defs, hp_var_heap) + = create_funs 0 fun_index gencase_defs heaps.hp_var_heap + = (fun_index, new_funs, gencase_defs, {heaps & hp_var_heap = hp_var_heap}) +where + create_funs gc_index fun_index gencase_defs hp_var_heap + | gc_index == size gencase_defs + = (fun_index, [], gencase_defs, hp_var_heap) + #! (fun, gencase_defs,hp_var_heap) + = create_fun gc_index fun_index gencase_defs hp_var_heap + #! (fun_index, funs, gencase_defs,hp_var_heap) + = create_funs (inc gc_index) (inc fun_index) gencase_defs hp_var_heap + = (fun_index, [fun:funs], gencase_defs, hp_var_heap) + + create_fun gc_index fun_index gencase_defs hp_var_heap + # (gencase_def=:{gc_ident, gc_pos, gc_type_cons}, gencase_defs) = gencase_defs ! [gc_index] + # gencase_def = { gencase_def & gc_body = GCB_FunIndex fun_index } + # gencase_defs = {gencase_defs & [gc_index] = gencase_def} + #! fun_ident = genericIdentToFunIdent gc_ident.id_name gc_type_cons + #! (var_info_ptr, hp_var_heap) = newPtr VI_Empty hp_var_heap + #! fun = + { ft_ident = fun_ident + , ft_arity = 0 + , ft_priority = NoPrio + , ft_type = {st_vars=[],st_attr_vars=[],st_arity=0,st_args=[],st_result={at_type=TE,at_attribute=TA_Multi},st_attr_env=[],st_context=[],st_args_strictness=NotStrict} + , ft_pos = gc_pos + , ft_specials = SP_None + , ft_type_ptr = var_info_ptr + } + = (fun, gencase_defs, hp_var_heap) + +NewEntry symbol_table symb_ptr def_kind def_index level previous :== + symbol_table <:= (symb_ptr,{ ste_kind = def_kind, ste_index = def_index, ste_def_level = level, ste_previous = previous }) + +getTypeDef :: !Index !(Global Index) !v:{#CheckedTypeDef} !w:{#DclModule} + -> (!CheckedTypeDef, !v:{#CheckedTypeDef}, !w:{#DclModule}) +getTypeDef x_main_dcl_module_n {glob_module,glob_object} type_defs modules + | glob_module==x_main_dcl_module_n + # (type_def, type_defs) = type_defs![glob_object] + = (type_def, type_defs, modules) + # (type_def, modules) = modules![glob_module].dcl_common.com_type_defs.[glob_object] + = (type_def, type_defs, modules) |