diff options
author | johnvg | 2013-04-08 09:16:09 +0000 |
---|---|---|
committer | johnvg | 2013-04-08 09:16:09 +0000 |
commit | 9894d082bd5a0f3c74a2874f9c9a78fd89a089a5 (patch) | |
tree | 9d851f5631f8981893af610d96371b4afd2d1009 /frontend/checkgenerics.icl | |
parent | update derive class for deriving generic functions in class context (from iTa... (diff) |
add generic function dependencies for generic function definitions,
add generic case definitions in definition modules for the types used to make the generic representation,
in generic case definitions in definition modules specify what generic info and dependencies are used
git-svn-id: https://svn.cs.ru.nl/repos/clean-compiler/trunk@2227 1f8540f1-abd5-4d5b-9d24-4c5ce8603e2d
Diffstat (limited to 'frontend/checkgenerics.icl')
-rw-r--r-- | frontend/checkgenerics.icl | 95 |
1 files changed, 88 insertions, 7 deletions
diff --git a/frontend/checkgenerics.icl b/frontend/checkgenerics.icl index d035c89..6f0345e 100644 --- a/frontend/checkgenerics.icl +++ b/frontend/checkgenerics.icl @@ -1,6 +1,6 @@ implementation module checkgenerics -import syntax,checksupport,checktypes,genericsupport,compare_types,typesupport +import syntax,checksupport,checktypes,genericsupport,explicitimports,compare_types,typesupport checkGenericDefs :: !Index !(Optional (CopiedDefinitions, Int)) !*{#GenericDef} !*{#CheckedTypeDef} !*{#ClassDef} !*{#DclModule} !*Heaps !*CheckState @@ -35,6 +35,8 @@ where # (gen_def, type_defs, class_defs, modules, heaps, cs) = check_generic_type gen_def mod_index type_defs class_defs modules heaps cs + # (gen_def, gen_defs, modules, cs) = check_generic_dependencies index mod_index gen_ident gen_def gen_defs modules 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}} @@ -44,7 +46,11 @@ where # initial_info = { gen_classes = createArray 32 [] , gen_var_kinds = [] - , gen_rep_conses = createArray 4 {gcf_module = -1,gcf_index = -1,gcf_ident={id_name="",id_info=nilPtr}} + , gen_rep_conses + = createArray 7 {grc_module = -1, grc_index = GCB_None, grc_local_fun_index = -1, grc_generic_info = -1, + grc_generic_instance_deps = AllGenericInstanceDependencies, + grc_ident={id_name="",id_info=nilPtr}, + grc_optional_fun_type=No} } # (gen_info_ptr, hp_generic_heap) = newPtr initial_info hp_generic_heap = ( {gen_def & gen_info_ptr = gen_info_ptr}, @@ -140,6 +146,70 @@ where -> (th_vars, cs_error) _ -> abort ("check_no_generic_vars_in_contexts: wrong TVI" ---> (tv, tv_info)) + // TODO: TvN: check that a generic function also includes all the dependencies of its dependencies, and so on. This is required when + // deriving generic functions since then the generated function needs to have all the arguments to all the generic functions called. In a + // that process collapses all dependencies. + check_generic_dependencies index mod_index gen_ident gen_def=:{gen_vars, gen_deps} gen_defs modules cs + # (gen_deps, (gen_defs, modules, cs)) = foldSt check_dependency gen_deps ([], (gen_defs, modules, cs)) + = ({gen_def & gen_deps = reverse gen_deps}, gen_defs, modules, cs) + where + check_dependency gen_dep=:{gd_ident, gd_vars} (acc, (gen_defs, modules, cs)) + # (gen_dep, cs) = resolve_dependency_index gen_dep cs + | gen_dep.gd_index.gi_index < 0 + = (acc, (gen_defs, modules, cs)) + # (gen_dep=:{gd_index, gd_vars}, gen_defs, modules, cs) = check_dependency_vars gen_dep gen_defs modules cs + | gd_index.gi_index == index && gd_index.gi_module == mod_index && gd_vars == gen_vars + = (acc, (gen_defs, modules, check_generic_dep_error gd_ident "already implicitly depends on itself" cs)) + | isMember gen_dep acc + = (acc, (gen_defs, modules, check_generic_dep_error gd_ident "duplicate generic dependency" cs)) + // TODO: TvN: This check is to prevent duplicate dependencies with different generic dependency variables + // See functions: generics1.build_specialized_expr and generics1.specialize_type_var + | isMember gen_dep.gd_index [gd_index \\ {gd_index} <- acc] + = (acc, (gen_defs, modules, check_generic_dep_error gd_ident "dependency occurs multiple times with different generic dependency variables, but only one occurrence of the same generic function as a dependency is currently allowed" cs)) + = ([gen_dep:acc], (gen_defs, modules, cs)) + + resolve_dependency_index gen_dep=:{gd_ident} cs + = case gd_ident of + Ident ident + # (index, cs) = get_generic_index ident mod_index cs + = ({gen_dep & gd_index = index}, cs) + QualifiedIdent mod_ident name + # (found, {decl_kind, decl_ident, decl_index}, cs) = search_qualified_ident mod_ident name GenericNameSpaceN cs + | not found + = (gen_dep, check_generic_dep_error gd_ident "generic dependency not defined" cs) + = case decl_kind of + STE_Imported STE_Generic generic_module + -> ({gen_dep & gd_ident = Ident decl_ident, gd_index = {gi_module = generic_module, gi_index = decl_index}}, cs) + _ + -> (gen_dep, check_generic_dep_error gd_ident "not a generic function" cs) + + check_dependency_vars gen_dep=:{gd_ident, gd_vars} gen_defs modules cs + # (gen_defs, modules, cs) = check_dependency_arity gen_dep gen_defs modules cs + # (gd_vars, gd_nums, cs) = mapY2St (resolve_dependency_var 0 gen_vars) gd_vars cs + = ({gen_dep & gd_vars = gd_vars, gd_nums = gd_nums}, gen_defs, modules, cs) + where + check_dependency_arity {gd_ident, gd_index, gd_vars} gen_defs modules cs + # (gen_def, gen_defs, modules) = lookup_dependency_def gd_index gen_defs modules + | not (length gd_vars == length gen_def.gen_vars) + = (gen_defs, modules, check_generic_dep_error gd_ident "incorrect dependency variable arity" cs) + = (gen_defs, modules, cs) + where + lookup_dependency_def {gi_module, gi_index} gen_defs modules + | gi_module == mod_index + # (gen_def, gen_defs) = gen_defs![gi_index] + = (gen_def, gen_defs, modules) + # (gen_def, modules) = modules![gi_module].dcl_common.com_generic_defs.[gi_index] + = (gen_def, gen_defs, modules) + + resolve_dependency_var num [] var cs + = (var, -1, check_generic_dep_error gd_ident "generic dependency is indexed by an unbound generic variable" cs) + resolve_dependency_var num [gen_var:gen_vars] var cs + | var.tv_ident.id_name == gen_var.tv_ident.id_name + = (gen_var, num, cs) + = resolve_dependency_var (inc num) gen_vars var cs + + check_generic_dep_error ident msg cs = {cs & cs_error = checkError ident msg cs.cs_error} + checkGenericCaseDefs :: !Index !*{#GenericCaseDef} !*{#GenericDef} !u:{#CheckedTypeDef} !*{#ClassDef} !*{#DclModule} !*Heaps !*CheckState -> (!*{#GenericCaseDef},!*{#GenericDef},!u:{#CheckedTypeDef},!*{#ClassDef},!*{#DclModule},!.Heaps,!.CheckState) checkGenericCaseDefs mod_index gen_case_defs generic_defs type_defs class_defs modules heaps cs @@ -154,7 +224,7 @@ where = (gen_case_defs, generic_defs, type_defs, class_defs, modules, heaps, cs) # (gen_case_defs, generic_defs, type_defs, class_defs, modules, heaps, cs) = check_generic_case_def index mod_index gen_case_defs generic_defs type_defs class_defs modules heaps cs - = check_generic_case_defs (inc index) mod_index gen_case_defs generic_defs type_defs class_defs modules heaps cs + = check_generic_case_defs (inc index) mod_index gen_case_defs generic_defs type_defs class_defs modules heaps cs check_generic_case_def index mod_index gen_case_defs generic_defs type_defs class_defs modules heaps cs # (case_def=:{gc_pos,gc_type,gc_gcf}, gen_case_defs) = gen_case_defs![index] @@ -220,8 +290,10 @@ where gcf_gident = ds_ident, gcf_generic = {gi_module=NoIndex,gi_index=NoIndex}, gcf_arity = 0, + gcf_generic_info = 0, gcf_body = GCB_None, - gcf_kind = KindError } + gcf_kind = KindError, + gcf_generic_instance_deps = AllGenericInstanceDependencies } # gcfs = convert_generic_contexts type_contexts = [!gcf:gcfs!] convert_generic_contexts [_:type_contexts] @@ -345,8 +417,10 @@ convert_generic_instances gci next_fun_index gencase_defs class_defs symbol_tabl gcf_gident = ds_ident, gcf_generic = {gi_module=NoIndex,gi_index=NoIndex}, gcf_arity = 0, + gcf_generic_info = 0, gcf_body = GCB_FunIndex next_fun_index, - gcf_kind = KindError } + gcf_kind = KindError, + gcf_generic_instance_deps = AllGenericInstanceDependencies } # (gcfs,next_fun_index,new_fun_defs) = convert_generic_contexts type_contexts type_cons pos (next_fun_index+1) new_fun_defs = ([!gcf:gcfs!],next_fun_index,[fun_def:new_fun_defs]) convert_generic_contexts [_:type_contexts] type_cons pos next_fun_index new_fun_defs @@ -366,12 +440,19 @@ where = (fun_index, [], gencase_defs, hp_var_heap) # (gencase_def,gencase_defs) = gencase_defs![gc_index] = case gencase_def of + {gc_gcf=GCF gc_ident gcf=:{gcf_body=GCB_MacroIndex macro_index},gc_pos,gc_type_cons} + # gencase_def & gc_gcf=GCF gc_ident {gcf & gcf_body = GCB_FunAndMacroIndex fun_index macro_index} + gencase_defs & [gc_index] = gencase_def + (fun,hp_var_heap) = create_gencase_function_type gc_ident gc_type_cons gc_pos hp_var_heap + (fun_index,funs,gencase_defs,hp_var_heap) + = create_funs (gc_index+1) (fun_index+1) gencase_defs hp_var_heap + -> (fun_index, [fun:funs], gencase_defs, hp_var_heap) {gc_gcf=GCF gc_ident gcf,gc_pos,gc_type_cons} # gencase_def & gc_gcf=GCF gc_ident {gcf & gcf_body = GCB_FunIndex fun_index} gencase_defs & [gc_index] = gencase_def (fun,hp_var_heap) = create_gencase_function_type gc_ident gc_type_cons gc_pos hp_var_heap - #! (fun_index, funs, gencase_defs,hp_var_heap) - = create_funs (gc_index+1) (inc fun_index) gencase_defs hp_var_heap + (fun_index,funs,gencase_defs,hp_var_heap) + = create_funs (gc_index+1) (fun_index+1) gencase_defs hp_var_heap -> (fun_index, [fun:funs], gencase_defs, hp_var_heap) {gc_gcf=GCFS gcfs,gc_pos,gc_type_cons} # (gcfs,superclass_funs,fun_index,hp_var_heap) |