implementation module explicitimports
// compile using the "reuse unique nodes" option
import StdEnv
import syntax, typesupport, parse, checksupport, utilities, checktypes, transform, predef, RWSDebug
temporary_import_solution_XXX yes no :== yes
// to switch between importing modes.
// iff this is yes, then explicit imports happen in the old Clean 1.3 fashion.
// This feature will be removed, when all programs are ported to Clean 2.0. The last Constructors of AtomType
// and StructureType should then be removed also
do_temporary_import_solution_XXX :== temporary_import_solution_XXX True False
:: ExplicitImports :== (![AtomicImport], ![StructureImport])
:: AtomicImport :== (!Ident, !AtomType)
:: StructureImport :== (!Ident, !StructureInfo, !StructureType, !OptimizeInfo)
:: AtomType = AT_Function | AT_Class | AT_Instance | AT_RecordType | AT_AlgType | AT_Type
| AT_stomme_funktion_die_alle_symbolen_kann_importeren_omdat_niemand_zin_heft_oude_pragrammen_naar_de_nieuwe_syntax_te_vertalen Bool // XXX
:: StructureInfo = SI_DotDot
// The .. notation was used for the structure
// (currently nothing is known about the elements)
| SI_Elements ![Ident] !Bool
// list of elements, that were not imported yet.
// Bool: the elements were listed explicitly in the structure
:: StructureType = ST_AlgType | ST_RecordType | ST_Class
| ST_stomm_stomm_stomm String
:: IdentWithKind :== (!Ident, !STE_Kind)
:: OptimizeInfo :== Optional Index
possibly_filter_decls :: .[ImportDeclaration] u:[w:(.Index,y:Declarations)] (.FileName,.LineNr) *{#.DclModule} *CheckState -> (v:[x:(Index,z:Declarations)],.{#DclModule},.CheckState), [y <= z, w <= x, u <= v];
possibly_filter_decls [] decls_of_imported_module _ modules cs // implicit import can't go wrong
= (decls_of_imported_module, modules, cs)
possibly_filter_decls listed_symbols decls_of_imported_module (file_name, line_nr) modules cs
// explicit import
#! ident_pos = { ip_ident= { id_name="", id_info=nilPtr }
, ip_line = line_nr
, ip_file = file_name
}
cs = { cs & cs_error = pushErrorAdmin ident_pos cs.cs_error }
(result, modules, cs) = filter_explicitly_imported_decl listed_symbols decls_of_imported_module [] line_nr modules cs
cs = { cs & cs_error = popErrorAdmin cs.cs_error }
= (result, modules, cs)
filter_explicitly_imported_decl _ [] akku _ modules cs
= (akku, modules, cs)
filter_explicitly_imported_decl import_symbols [(index,{dcls_import,dcls_local,dcls_explicit}):new_decls] akku
line_nr modules cs
# undefined = -1
atoms = flatten (map toAtom import_symbols)
structures = flatten (map toStructure import_symbols)
(checked_atoms, cs) = checkAtoms atoms cs
unimported = (checked_atoms, structures)
(dcls_import,unimported, modules, cs) = filter_decl_array 0 dcls_import unimported undefined modules cs
((dcls_local,unimported), modules, cs)
= filter_decl dcls_local unimported index modules cs
cs_error = foldSt checkAtomError (fst unimported) cs.cs_error
cs_error = foldSt checkStructureError (snd unimported) cs_error
cs = { cs & cs_error=cs_error }
| isEmpty dcls_import && isEmpty dcls_local && size dcls_explicit==0
= filter_explicitly_imported_decl import_symbols new_decls akku line_nr modules cs
# local_imports = [ { declaration & dcl_kind = STE_Imported declaration.dcl_kind index } \\ declaration <- dcls_local]
new_dcls_explicit = [ ExplicitImport dcls line_nr \\ dcls<-dcls_import++local_imports ]
dcls_import = {dcls_import\\dcls_import<-dcls_import}
newAkku = [(index, { dcls_import=dcls_import, dcls_local=dcls_local ,
dcls_local_for_import = {local_declaration_for_import decl index \\ decl<-dcls_local},
// dcls_explicit=new_dcls_explicit}) : akku]
dcls_explicit={new_dcls_explicit\\new_dcls_explicit<-new_dcls_explicit}}) : akku]
= filter_explicitly_imported_decl import_symbols new_decls newAkku line_nr modules cs
where
local_declaration_for_import decl=:{dcl_kind=STE_FunctionOrMacro _} module_n
= decl
local_declaration_for_import decl=:{dcl_kind=STE_Imported _ _} module_n
= abort "local_declaration_for_import"
local_declaration_for_import decl=:{dcl_kind} module_n
= {decl & dcl_kind = STE_Imported dcl_kind module_n}
toAtom (ID_Function {ii_ident})
= [(ii_ident, temporary_import_solution_XXX
(AT_stomme_funktion_die_alle_symbolen_kann_importeren_omdat_niemand_zin_heft_oude_pragrammen_naar_de_nieuwe_syntax_te_vertalen False)
AT_Function)]
toAtom (ID_Class {ii_ident} _)
= [(ii_ident, AT_Class)]
toAtom (ID_Type {ii_ident} (Yes _))
= [(ii_ident, AT_AlgType)]
toAtom (ID_Type {ii_ident} No)
= [(ii_ident, AT_Type)]
toAtom (ID_Record {ii_ident} yesOrNo)
= [(ii_ident, AT_RecordType)]
toAtom (ID_Instance _ ident _)
= [(ident, AT_Instance)]
toAtom _
= []
atomTypeString AT_Function = "function"
atomTypeString AT_Class = "class"
atomTypeString AT_Instance = "instance"
atomTypeString _ = "type"
toStructure (ID_Class {ii_ident} yesOrNo)
= to_structure ii_ident yesOrNo ST_Class
toStructure (ID_Type {ii_ident} yesOrNo)
= to_structure ii_ident yesOrNo ST_AlgType
toStructure (ID_Record {ii_ident} yesOrNo)
= to_structure ii_ident yesOrNo ST_RecordType
// MW added
toStructure (ID_Function {ii_ident})
| do_temporary_import_solution_XXX
= [(ii_ident, SI_DotDot, ST_stomm_stomm_stomm ii_ident.id_name, No)]
// ..MW
toStructure _
= []
to_structure _ No _
= []
to_structure ident (Yes []) structureType
= [(ident, SI_DotDot, structureType, No)]
to_structure ident (Yes elements) structureType
# element_idents = removeDup [ ii_ident \\ {ii_ident}<-elements]
= [(ident, (SI_Elements element_idents True),structureType, No)]
checkAtoms l cs
# groups = grouped l
wrong = filter isErroneous groups
unique = map hd groups
| isEmpty wrong
= (unique, cs)
= (unique, foldSt error wrong cs)
where
isErroneous l=:[(_,AT_Type),_:_] = True
isErroneous l=:[(_,AT_AlgType),_:_] = True
isErroneous l=:[(_,AT_RecordType),_:_] = True
isErroneous _ = False
error [(ident, atomType):_] cs
= { cs & cs_error = checkError ("type "+++ident.id_name) "imported more than once in one from statement"
cs.cs_error }
checkAtomError (id, AT_Instance) cs_error
= checkError ("specified instance of class "+++id.id_name) "not exported by the specified module" cs_error
checkAtomError (id, AT_stomme_funktion_die_alle_symbolen_kann_importeren_omdat_niemand_zin_heft_oude_pragrammen_naar_de_nieuwe_syntax_te_vertalen was_imported_at_least_once) cs_error
| do_temporary_import_solution_XXX
= case was_imported_at_least_once of
True -> cs_error
_ -> checkError id ("not exported by the specified module") cs_error
checkAtomError (id, atomType) cs_error
= checkError id ("not exported as a "+++atomTypeString atomType+++" by the specified module") cs_error
// MW remove this later..
checkStructureError (_,_, ST_stomm_stomm_stomm _, _) cs_error
| do_temporary_import_solution_XXX
= cs_error
// further with next alternative
// ..MW
checkStructureError (struct_id, (SI_Elements wrong_elements _), st, _) cs_error
= foldSt err wrong_elements cs_error
where
err element_id cs_error
# (element_type, structure_type) = case st of
ST_AlgType -> ("constructor", "algebraic type")
ST_RecordType -> ("field", "record type")
ST_Class -> ("member", "class")
= checkError element_id ( "not a "+++element_type+++" of "+++structure_type
+++" "+++struct_id.id_name) cs_error
checkStructureError _ cs_error
= cs_error
// collect groups, e.g. grouped [3,5,1,3,1] = [[1,1],[3,3],[5]]
grouped []
= []
grouped l
# sorted = qsort l
= grouped_ [hd sorted] (tl sorted) []
where
grouped_ group [] akku
= [group:akku]
grouped_ group=:[x:_] [h:t] akku
| x==h = grouped_ [h:group] t akku
= grouped_ [h] t [group:akku]
qsort [] = []
qsort [h:t] = qsort left++[h: qsort right]
where
left = [x \\ x<-t | greater x h]
right = [x \\ x<-t | not (greater x h) || x==h]
greater ({id_name=id_name_l}, atomType_l) ({id_name=id_name_r}, atomType_r)
| id_name_l >id_name_r = True
| id_name_l==id_name_r = toInt atomType_l > toInt atomType_r
= False
instance == AtomType
where
(==) l r = toInt l==toInt r
instance toInt AtomType
where
toInt AT_Function = 0
toInt AT_Class = 1
toInt AT_Instance = 2
toInt AT_RecordType = 3
toInt AT_AlgType = 3
toInt AT_Type = 3 // AT_RecordType, AT_AlgType & AT_Type are in one class !!!
toInt (AT_stomme_funktion_die_alle_symbolen_kann_importeren_omdat_niemand_zin_heft_oude_pragrammen_naar_de_nieuwe_syntax_te_vertalen _)
= 0
NoPosition :== -1
filter_decl :: [.Declaration] ([(Ident,AtomType)],[(Ident,StructureInfo,StructureType,Optional Int)]) Int *{#DclModule} *CheckState -> (!(!.[Declaration],!([(Ident,AtomType)],![(Ident,StructureInfo,StructureType,Optional Int)])),!.{#DclModule},!.CheckState);
filter_decl [] unimported _ modules cs
= (([], unimported), modules, cs)
filter_decl [decl:decls] unimported index modules cs
# ((appears,unimported), modules, cs) = decl_appears decl unimported index modules cs
| appears
# ((recurs, unimported), modules, cs) = filter_decl decls unimported index modules cs
= (([decl:recurs],unimported), modules, cs)
= filter_decl decls unimported index modules cs
filter_decl_array :: !Int {!.Declaration} ([(Ident,AtomType)],[(Ident,StructureInfo,StructureType,Optional Int)]) Int *{#DclModule} *CheckState -> (!.[Declaration],!([(Ident,AtomType)],![(Ident,StructureInfo,StructureType,Optional Int)]),!.{#DclModule},!.CheckState);
filter_decl_array decl_index decls unimported index modules cs
| decl_index<size decls
# (decl,decls) = decls![decl_index]
# ((appears,unimported), modules, cs) = decl_appears decl unimported index modules cs
| appears
# (recurs, unimported, modules, cs) = filter_decl_array (decl_index+1) decls unimported index modules cs
= ([decl:recurs],unimported, modules, cs)
= filter_decl_array (decl_index+1) decls unimported index modules cs
= ([], unimported, modules, cs)
decl_appears :: !Declaration !ExplicitImports !Index !*{#DclModule} !*CheckState
-> (!(!Bool, !ExplicitImports), !*{#DclModule}, !*CheckState)
decl_appears dec=:{dcl_kind=STE_Imported ste_Kind def_index} unimported _ modules cs
= decl_appears {dec & dcl_kind=ste_Kind} unimported def_index modules cs
/* MW2 was:
decl_appears {dcl_ident,dcl_kind=STE_Constructor,dcl_index} unimported index modules cs
= elementAppears ST_AlgType dcl_ident dcl_index unimported index modules cs
*/
decl_appears {dcl_ident,dcl_kind=STE_Constructor,dcl_index} unimported index modules cs
# (result=:((appears, unimported), modules, cs))
= elementAppears ST_AlgType dcl_ident dcl_index unimported index modules cs
| appears || not do_temporary_import_solution_XXX
= result
= atomAppears dcl_ident dcl_index unimported index modules cs
/* MW2 was
decl_appears { dcl_ident,dcl_kind=(STE_Field _),dcl_index} unimported index modules cs
= elementAppears ST_RecordType dcl_ident dcl_index unimported index modules cs
*/
decl_appears { dcl_ident,dcl_kind=(STE_Field _),dcl_index} unimported index modules cs
# (result=:((appears, unimported), modules, cs))
= elementAppears ST_RecordType dcl_ident dcl_index unimported index modules cs
| appears || not do_temporary_import_solution_XXX
= result
= atomAppears dcl_ident dcl_index unimported index modules cs
/* MW2 was
decl_appears { dcl_ident,dcl_kind=STE_Member,dcl_index} unimported index modules cs
= elementAppears ST_Class dcl_ident dcl_index unimported index modules cs
*/
decl_appears { dcl_ident,dcl_kind=STE_Member,dcl_index} unimported index modules cs
# (result=:((appears, unimported), modules, cs))
= elementAppears ST_Class dcl_ident dcl_index unimported index modules cs
| appears || not do_temporary_import_solution_XXX
= result
= atomAppears dcl_ident dcl_index unimported index modules cs
decl_appears {dcl_ident, dcl_kind, dcl_index} unimported index modules cs
| isAtom dcl_kind
= atomAppears dcl_ident dcl_index unimported index modules cs
where
isAtom STE_DclFunction = True
isAtom (STE_FunctionOrMacro _) = True
isAtom STE_Class = True
isAtom STE_Type = True
isAtom STE_Instance = True
elementAppears :: .StructureType Ident !.Int !(.a,![(Ident,.StructureInfo,.StructureType,Optional .Int)]) !.Int !*{#.DclModule} !*CheckState -> (!(!Bool,(!.a,![(Ident,StructureInfo,StructureType,Optional Int)])),!.{#DclModule},!.CheckState);
elementAppears imported_st dcl_ident dcl_index (atomicImports, structureImports) index modules cs
# ((result, structureImports), modules, cs)
= element_appears imported_st dcl_ident dcl_index structureImports structureImports 0 index modules cs
= ((result, (atomicImports, structureImports)), modules, cs)
atomAppears dcl_ident dcl_index (atomicImports, structureImports) index modules cs
# ((result, atomicImports), modules, cs)
= atom_appears dcl_ident dcl_index atomicImports atomicImports 0 index modules cs
= ((result, (atomicImports, structureImports)), modules, cs)
atom_appears :: Ident !.Int [(Ident,.AtomType)] w:[y:(Ident,u1:AtomType)] !Int !.Int !u:{#u3:DclModule} !*CheckState -> (!(.Bool,x:[z:(Ident,u2:AtomType)]),!v:{#DclModule},!.CheckState) , [u <= v, u1 <= u2, y <= z, w <= x, u <= u3];
atom_appears _ _ [] atomic_imports _ _ modules cs
= ((False, atomic_imports), modules, cs)
atom_appears ident dcl_index [h=:(import_ident, atomType):t] atomic_imports unimp_index index modules cs
// MW2..
| do_temporary_import_solution_XXX
&& ident.id_name==import_ident.id_name
&& atomType==(AT_stomme_funktion_die_alle_symbolen_kann_importeren_omdat_niemand_zin_heft_oude_pragrammen_naar_de_nieuwe_syntax_te_vertalen True) // True or False doesn't matter in this line
# new_h = (import_ident, AT_stomme_funktion_die_alle_symbolen_kann_importeren_omdat_niemand_zin_heft_oude_pragrammen_naar_de_nieuwe_syntax_te_vertalen True)
= ((True, [new_h: removeAt unimp_index atomic_imports]), modules, cs)
// ..MW2
| ident==import_ident
# (modules, cs) = checkRecordError atomType import_ident dcl_index index modules cs
= ((True, removeAt unimp_index atomic_imports), modules, cs)
// goes further with next alternative
where
checkRecordError atomType import_ident dcl_index index modules cs
# (td_rhs, modules, cs) = lookup_type dcl_index index modules cs
cs_error = cs.cs_error
cs_error = case atomType of
AT_RecordType
-> case td_rhs of
RecordType _ -> cs_error
_ -> checkError import_ident "imported as a record type" cs_error
AT_AlgType
-> case td_rhs of
AlgType _ -> cs_error
_ -> checkError import_ident "imported as an algebraic type" cs_error
_ -> cs_error
= (modules, { cs & cs_error=cs_error })
atom_appears ident dcl_index [h:t] atomic_imports unimp_index index modules cs
= atom_appears ident dcl_index t atomic_imports (inc unimp_index) index modules cs
instance == StructureType
where
(==) ST_AlgType ST_AlgType = True
(==) ST_RecordType ST_RecordType = True
(==) ST_Class ST_Class = True
(==) _ _ = False
element_appears :: StructureType Ident !Int [(Ident,.StructureInfo,u2:StructureType,z:Optional .Int)] u:[w:(Ident,u5:StructureInfo,u3:StructureType,y:Optional Int)] !Int !Int !*{#DclModule} !*CheckState -> (!(!Bool,!v:[x:(Ident,u6:StructureInfo,u4:StructureType,u1:Optional Int)]),!.{#DclModule},!.CheckState), [y z <= u1, u3 <= u4, u5 <= u6, w <= x, u <= v, u2 <= u3];
element_appears _ _ _ [] atomic_imports _ _ modules cs
= ((False, atomic_imports), modules, cs)
// MW2 remove this later ..
element_appears imported_st element_ident dcl_index
[(_, SI_DotDot, ST_stomm_stomm_stomm type_name_string, optInfo):t] atomic_imports unimp_index
index modules cs
| do_temporary_import_solution_XXX
# (appears, modules, cs)
= element_appears_in_stomm_struct imported_st element_ident dcl_index index type_name_string modules cs
| appears
= ((appears, atomic_imports), modules, cs)
= element_appears imported_st element_ident dcl_index t atomic_imports (inc unimp_index) index modules cs
// otherwise go further with next alternative
// ..MW2
element_appears imported_st element_ident dcl_index
[(_, _, st, _):t] atomic_imports unimp_index
index modules cs
| imported_st<>st
= element_appears imported_st element_ident dcl_index t atomic_imports (inc unimp_index) index modules cs
// goes further with next alternative
element_appears imported_st element_ident dcl_index
[(_, _, _, (Yes notDefinedHere)):t] atomic_imports unimp_index
index modules cs
| notDefinedHere==dcl_index
= element_appears imported_st element_ident dcl_index t atomic_imports (inc unimp_index) index modules cs
// goes further with next alternative
element_appears imported_st element_ident dcl_index
[(struct_id, (SI_Elements elements explicit), st, optInfo):t] atomic_imports unimp_index
index modules cs
| not (isMember element_ident elements)
= element_appears imported_st element_ident dcl_index t atomic_imports (inc unimp_index) index modules cs
# (l,r) = span ((<>) element_ident) elements
oneLess = l++(tl r)
newStructure = (struct_id, (SI_Elements oneLess explicit), st, optInfo)
atomic_imports_1 = removeAt unimp_index atomic_imports
| not explicit
= ((True, [newStructure: atomic_imports_1]), modules, cs)
// the found element was explicitly specified by the programmer: check it
# (appears, _, _, modules, cs)
= element_appears_in_struct imported_st element_ident dcl_index struct_id index modules cs
| appears
= ((True, [newStructure: atomic_imports_1]), modules, cs)
# message = "does not belong to specified "+++(case st of
ST_Class -> "class."
_ -> "type.")
cs = { cs & cs_error= checkError element_ident message cs.cs_error}
= ((False, atomic_imports_1), modules, cs)
element_appears imported_st element_ident dcl_index
[(struct_id, SI_DotDot, st, optInfo):t] atomic_imports unimp_index
index modules cs
| (case st of
ST_stomm_stomm_stomm _
-> True
_ -> False) && (False->>"element_appears weird case")
= undef
# (appears, defined, opt_element_idents, modules, cs)
= element_appears_in_struct imported_st element_ident dcl_index struct_id index modules cs
| not appears
# structureInfo = case opt_element_idents of
No -> SI_DotDot
Yes element_idents -> (SI_Elements element_idents False)
newStructure = (struct_id, structureInfo, st, (if defined No (Yes dcl_index)))
new_atomic_imports = [newStructure : removeAt unimp_index atomic_imports]
= element_appears imported_st element_ident dcl_index t new_atomic_imports (inc unimp_index) index modules cs
# (Yes element_idents) = opt_element_idents
oneLess = filter ((<>) element_ident) element_idents
newStructure = (struct_id, (SI_Elements oneLess False), st, No)
new_atomic_imports = [newStructure : removeAt unimp_index atomic_imports]
= ((True,new_atomic_imports), modules, cs)
element_appears imported_st element_ident dcl_index [h:t] atomic_imports unimp_index index modules cs
= element_appears imported_st element_ident dcl_index t atomic_imports (inc unimp_index) index modules cs
lookup_type dcl_index index modules cs
# (dcl_module=:{dcl_name=dcl_name=:{id_info}}, modules) = modules ! [index]
(module_entry, cs_symbol_table) = readPtr id_info cs.cs_symbol_table
cs = { cs & cs_symbol_table=cs_symbol_table }
= continuation module_entry.ste_kind dcl_module modules cs
where
continuation (STE_OpenModule _ modul) _ modules cs
# allTypes = modul.mod_defs.def_types
= ((allTypes !! dcl_index).td_rhs, modules, cs)
continuation STE_ClosedModule dcl_module modules cs
# com_type_def = dcl_module.dcl_common.com_type_defs.[dcl_index]
= (com_type_def.td_rhs, modules, cs)
element_appears_in_stomm_struct :: .StructureType Ident .Int .Int .String *{#DclModule} !*CheckState -> (!Bool,!.{#DclModule},!.CheckState)
// MW remove this later CCC
element_appears_in_stomm_struct imported_st element_ident dcl_index index type_name_string modules cs
| not do_temporary_import_solution_XXX
= abort "element_appears_in_stomm_struct will be never called, when the above guard holds. This statement is only to remind people to remove this function."
# (dcl_module=:{dcl_name=dcl_name=:{id_info}}, modules) = modules ! [index]
(module_entry, cs_symbol_table) = readPtr id_info cs.cs_symbol_table
#! cs = { cs & cs_symbol_table=cs_symbol_table }
// = continuation imported_st module_entry.ste_kind dcl_module modules cs
= (appears imported_st module_entry.ste_kind dcl_module.dcl_common,modules,cs);
where
appears ST_RecordType (STE_OpenModule _ modul) _
// lookup the constructors/fields for the algebraic type/record
# allTypes = modul.mod_defs.def_types
search = dropWhile (\{td_name} -> td_name.id_name<>type_name_string) allTypes
| isEmpty search
= False
# {td_rhs} = hd search
| not (isRecordType td_rhs)
= False
# element_idents = getElements td_rhs
= isMember element_ident element_idents
appears ST_RecordType STE_ClosedModule dcl_common
// lookup the type of the constructor and compare
# type_index = dcl_common.com_selector_defs.[dcl_index].sd_type_index
com_type_def = dcl_common.com_type_defs.[type_index]
appears = com_type_def.td_name.id_name==type_name_string
= appears
appears ST_Class (STE_OpenModule _ modul) _
// lookup the members for the class
# allClasses = modul.mod_defs.def_classes
search = dropWhile (\{class_name} -> class_name.id_name<>type_name_string) allClasses
| isEmpty search
= False
# {class_members} = hd search
element_idents = [ ds_ident \\ {ds_ident} <-:class_members ]
= isMember element_ident element_idents
appears ST_Class STE_ClosedModule dcl_common
// lookup the class and compare
# com_member_def = dcl_common.com_member_defs.[dcl_index]
{glob_object} = com_member_def.me_class
com_class_def = dcl_common.com_class_defs.[glob_object]
appears = com_class_def.class_name.id_name==type_name_string
= appears
appears _ _ _
= False
getElements (RecordType {rt_fields})
= [ fs_name \\ {fs_name}<-:rt_fields ]
getElements _
= []
isRecordType (RecordType _) = True
isRecordType _ = False
// ..MW
/* 1st result: whether the element appears in the structure
2nd result: whether the structure is defined at all in the module
3rd result: Yes: a list of all idents of the elements of the structure
the first bool implies the second
*/
element_appears_in_struct imported_st element_ident dcl_index struct_ident index modules cs
# (dcl_module=:{dcl_name=dcl_name=:{id_info}}, modules) = modules ! [index]
(module_entry, cs_symbol_table) = readPtr id_info cs.cs_symbol_table
cs = { cs & cs_symbol_table=cs_symbol_table }
= continuation imported_st module_entry.ste_kind dcl_module modules cs
where
continuation ST_Class (STE_OpenModule _ modul) _ modules cs
// lookup the members for the class
# allClasses = modul.mod_defs.def_classes
search = dropWhile (\{class_name} -> class_name<>struct_ident) allClasses
| isEmpty search
= (False, False, No, modules, cs)
# {class_members} = hd search
element_idents = [ ds_ident \\ {ds_ident} <-:class_members ]
= (isMember element_ident element_idents, True, Yes element_idents, modules, cs)
continuation imported_st (STE_OpenModule _ modul) _ modules cs
// lookup the constructors/fields for the algebraic type/record
# allTypes = modul.mod_defs.def_types
search = dropWhile (\{td_name} -> td_name<>struct_ident) allTypes
| isEmpty search
= (False, False, No, modules, cs)
# {td_rhs} = hd search
| not (isAlgOrRecordType td_rhs)
= (False, True, No, modules, cs)
# element_idents = getElements td_rhs
= (isMember element_ident element_idents, True, Yes element_idents, modules, cs)
continuation ST_Class STE_ClosedModule dcl_module modules cs
// lookup the class and compare
# com_member_def = dcl_module.dcl_common.com_member_defs.[dcl_index]
{glob_object} = com_member_def.me_class
com_class_def = dcl_module.dcl_common.com_class_defs.[glob_object]
allMembers = com_class_def.class_members
member_idents = [ ds_ident \\ {ds_ident} <-: allMembers]
appears = com_class_def.class_name==struct_ident
= (appears, True, if appears (Yes member_idents) No, modules, cs)
continuation imported_st STE_ClosedModule dcl_module modules cs
// lookup the type of the constructor and compare
# type_index = if (imported_st==ST_AlgType)
dcl_module.dcl_common.com_cons_defs.[dcl_index].cons_type_index
dcl_module.dcl_common.com_selector_defs.[dcl_index].sd_type_index
com_type_def = dcl_module.dcl_common.com_type_defs.[type_index]
element_idents = getElements com_type_def.td_rhs
appears = com_type_def.td_name==struct_ident
= (appears, True, if appears (Yes element_idents) No, modules, cs)
isAlgOrRecordType (AlgType _) = True
isAlgOrRecordType (RecordType _) = True
isAlgOrRecordType _ = False
getElements (AlgType constructor_symbols)
= [ds_ident \\ {ds_ident} <- constructor_symbols]
getElements (RecordType {rt_fields})
= [ fs_name \\ {fs_name}<-:rt_fields ]
getElements _
= []
:: CheckCompletenessState =
{ ccs_dcl_modules :: !.{#DclModule}
, ccs_icl_functions :: !.{#FunDef}
, ccs_set_of_visited_icl_funs :: !.{#Bool} // ccs_set_of_visited_icl_funs.[i] <=> function nr i has been considered
, ccs_expr_heap :: !.ExpressionHeap
, ccs_symbol_table :: !.SymbolTable
, ccs_error :: !.ErrorAdmin
, ccs_heap_changes_accu :: ![SymbolPtr]
}
:: *CheckCompletenessStateBox = { box_ccs :: !*CheckCompletenessState }
:: CheckCompletenessInput =
{ cci_line_nr :: !Int
, cci_filename :: !String
, cci_expl_imported_ident :: !Ident
, cci_main_dcl_module_n::!Int
}
:: CheckCompletenessInputBox = { box_cci :: !CheckCompletenessInput }
checkExplicitImportCompleteness :: !String !Int ![ExplicitImport] !*{#DclModule} !*{#FunDef} !*ExpressionHeap !*CheckState
-> (!.{#DclModule},!.{#FunDef},!.ExpressionHeap,!.CheckState)
checkExplicitImportCompleteness filename main_dcl_module_n dcls_explicit dcl_modules icl_functions expr_heap
cs=:{cs_symbol_table, cs_error}
#! nr_icl_functions = size icl_functions
box_ccs = { ccs_dcl_modules = dcl_modules, ccs_icl_functions = icl_functions,
ccs_set_of_visited_icl_funs = createArray nr_icl_functions False,
ccs_expr_heap = expr_heap, ccs_symbol_table = cs_symbol_table,
ccs_error = cs_error, ccs_heap_changes_accu = [] }
ccs = foldSt (checkCompleteness filename) dcls_explicit { box_ccs = box_ccs }
{ ccs_dcl_modules, ccs_icl_functions, ccs_expr_heap, ccs_symbol_table, ccs_error, ccs_heap_changes_accu }
= ccs.box_ccs
// repair heap contents
ccs_symbol_table = foldSt replace_ste_with_previous ccs_heap_changes_accu ccs_symbol_table
cs = { cs & cs_symbol_table = ccs_symbol_table, cs_error = ccs_error }
= (ccs_dcl_modules, ccs_icl_functions, ccs_expr_heap, cs)
where
checkCompleteness :: !String !ExplicitImport *CheckCompletenessStateBox -> *CheckCompletenessStateBox
checkCompleteness filename (ExplicitImport {dcl_ident, dcl_index, dcl_kind=STE_FunctionOrMacro _} line_nr) ccs
= checkCompletenessOfMacro filename dcl_ident dcl_index main_dcl_module_n line_nr ccs
checkCompleteness filename (ExplicitImport {dcl_ident, dcl_index, dcl_kind=STE_Imported (STE_FunctionOrMacro _) mod_index} line_nr) ccs
= checkCompletenessOfMacro filename dcl_ident dcl_index main_dcl_module_n line_nr ccs
checkCompleteness filename (ExplicitImport {dcl_ident, dcl_index, dcl_kind=STE_Imported expl_imp_kind mod_index} line_nr) ccs
#! ({dcl_common,dcl_functions}, ccs) = ccs!box_ccs.ccs_dcl_modules.[mod_index]
cci = { box_cci = { cci_line_nr = line_nr, cci_filename = filename, cci_expl_imported_ident = dcl_ident,cci_main_dcl_module_n=main_dcl_module_n }}
/* XXX
this case expression causes the compiler to be not self compilable anymore (12.7.2000). The bug is probably
in module refmark. The corresponding continuation function can be compiled
= case expl_imp_kind of
STE_Type -> check_completeness dcl_common.com_type_defs.[dcl_index] cci ccs
STE_Constructor -> check_completeness dcl_common.com_cons_defs.[dcl_index] cci ccs
(STE_Field _) -> check_completeness dcl_common.com_selector_defs.[dcl_index] cci ccs
STE_Class -> check_completeness dcl_common.com_class_defs.[dcl_index] cci ccs
STE_Member -> check_completeness dcl_common.com_member_defs.[dcl_index] cci ccs
STE_Instance -> check_completeness dcl_common.com_instance_defs.[dcl_index] cci ccs
STE_DclFunction -> check_completeness dcl_functions.[dcl_index] cci ccs
*/
= continuation expl_imp_kind dcl_common dcl_functions cci ccs
where
continuation STE_Type dcl_common dcl_functions cci ccs
= check_completeness dcl_common.com_type_defs.[dcl_index] cci ccs
continuation STE_Constructor dcl_common dcl_functions cci ccs
= check_completeness dcl_common.com_cons_defs.[dcl_index] cci ccs
continuation (STE_Field _) dcl_common dcl_functions cci ccs
= check_completeness dcl_common.com_selector_defs.[dcl_index] cci ccs
continuation STE_Class dcl_common dcl_functions cci ccs
= check_completeness dcl_common.com_class_defs.[dcl_index] cci ccs
continuation STE_Member dcl_common dcl_functions cci ccs
= check_completeness dcl_common.com_member_defs.[dcl_index] cci ccs
continuation STE_Instance dcl_common dcl_functions cci ccs
= check_completeness dcl_common.com_instance_defs.[dcl_index] cci ccs
continuation STE_DclFunction dcl_common dcl_functions cci ccs
= check_completeness dcl_functions.[dcl_index] cci ccs
checkCompletenessOfMacro :: !String !Ident !Index !Int !Int *CheckCompletenessStateBox -> *CheckCompletenessStateBox
checkCompletenessOfMacro filename dcl_ident dcl_index main_dcl_module_n line_nr ccs
#! ({fun_body}, ccs) = ccs!box_ccs.ccs_icl_functions.[dcl_index]
ccs = { ccs & box_ccs.ccs_set_of_visited_icl_funs.[dcl_index] = True }
cci = { box_cci = { cci_line_nr = line_nr, cci_filename = filename, cci_expl_imported_ident = dcl_ident,cci_main_dcl_module_n=main_dcl_module_n }}
= check_completeness fun_body cci ccs
replace_ste_with_previous :: !SymbolPtr !*SymbolTable -> .SymbolTable
replace_ste_with_previous changed_ste_ptr symbol_table
#! ({ste_previous}, symbol_table) = readPtr changed_ste_ptr symbol_table
= writePtr changed_ste_ptr ste_previous symbol_table
instance toString STE_Kind where
toString (STE_FunctionOrMacro _) = "function/macro"
toString STE_Type = "type"
toString STE_Constructor = "constructor"
toString (STE_Field _) = "field"
toString STE_Class = "class"
toString STE_Member = "class member"
check_whether_ident_is_imported :: !Ident !STE_Kind !CheckCompletenessInputBox !*CheckCompletenessStateBox
-> *CheckCompletenessStateBox
check_whether_ident_is_imported ident wanted_ste_kind cci ccs=:{box_ccs=box_ccs=:{ccs_symbol_table}}
#! (ste=:{ste_kind}, ccs_symbol_table) = readPtr ident.id_info ccs_symbol_table
ccs = { ccs & box_ccs = { box_ccs & ccs_symbol_table = ccs_symbol_table } }
| is_imported ste_kind wanted_ste_kind
= ccs
#! (ccs=:{box_ccs=box_ccs=:{ccs_symbol_table, ccs_error, ccs_heap_changes_accu}}) = ccs
{box_cci={cci_line_nr, cci_filename, cci_expl_imported_ident}} = cci
ident_pos = {ip_ident= { id_name="import", id_info=nilPtr }, ip_line=cci_line_nr, ip_file=cci_filename}
ccs_error = checkErrorWithIdentPos ident_pos
(cci_expl_imported_ident.id_name+++" explicitly imported without importing "
+++toString wanted_ste_kind+++" "+++ident.id_name)
ccs_error
// pretend that the unimported symbol was imported to prevent doubling error mesages
ccs_symbol_table = writePtr ident.id_info { ste & ste_kind = wanted_ste_kind, ste_previous = ste } ccs_symbol_table
= { ccs & box_ccs = { box_ccs & ccs_error = ccs_error, ccs_symbol_table = ccs_symbol_table,
ccs_heap_changes_accu = [ident.id_info:ccs_heap_changes_accu] }}
where
is_imported (STE_Imported ste_kind _) wanted_ste_kind
= ste_kind==wanted_ste_kind
is_imported ste_kind wanted_ste_kind
= ste_kind==wanted_ste_kind
class check_completeness x :: !x !CheckCompletenessInputBox !*CheckCompletenessStateBox -> *CheckCompletenessStateBox
instance check_completeness App where
check_completeness {app_symb, app_args} cci ccs
= check_completeness app_symb cci
(check_completeness app_args cci ccs)
instance check_completeness AlgebraicPattern where
check_completeness {ap_symbol, ap_expr} cci ccs
= check_completeness ap_expr cci
(check_whether_ident_is_imported ap_symbol.glob_object.ds_ident STE_Constructor cci ccs)
instance check_completeness AType where
check_completeness {at_type} cci ccs
= check_completeness at_type cci ccs
instance check_completeness BasicPattern where
check_completeness {bp_expr} cci ccs
= check_completeness bp_expr cci ccs
instance check_completeness LetBind where
check_completeness {lb_src} cci ccs
= check_completeness lb_src cci ccs
instance check_completeness Case where
check_completeness { case_expr, case_guards, case_default } cci ccs
= ( (check_completeness case_expr cci)
o (check_completeness case_guards cci)
o (check_completeness case_default cci)
) ccs
instance check_completeness CasePatterns where
check_completeness (AlgebraicPatterns _ algebraicPatterns) cci ccs
= check_completeness algebraicPatterns cci ccs
check_completeness (BasicPatterns _ basicPatterns) cci ccs
= check_completeness basicPatterns cci ccs
check_completeness (DynamicPatterns dynamicPatterns) cci ccs
= check_completeness dynamicPatterns cci ccs
check_completeness NoPattern _ ccs
= ccs
instance check_completeness CheckedAlternative where
check_completeness {ca_rhs} cci ccs
= check_completeness ca_rhs cci ccs
instance check_completeness CheckedBody where
check_completeness {cb_rhs} cci ccs
= check_completeness cb_rhs cci ccs
instance check_completeness ClassDef where
check_completeness {class_context} cci ccs
= check_completeness class_context cci ccs
instance check_completeness ClassInstance where
check_completeness {ins_type} cci ccs
= check_completeness ins_type cci ccs
instance check_completeness ConsDef
where
check_completeness {cons_type} cci ccs
= check_completeness cons_type cci ccs
instance check_completeness DynamicPattern where
check_completeness { dp_rhs, dp_type } cci ccs
= check_completeness dp_rhs cci
(check_completeness_of_dyn_expr_ptr dp_type cci ccs)
instance check_completeness DynamicExpr where
check_completeness { dyn_expr, dyn_opt_type } cci ccs
= check_completeness dyn_expr cci
(check_completeness dyn_opt_type cci ccs)
instance check_completeness DynamicType where
check_completeness { dt_type } cci ccs
= check_completeness dt_type cci ccs
instance check_completeness Expression where
check_completeness (Var _) cci ccs
= ccs
check_completeness (App app) cci ccs
= check_completeness app cci ccs
check_completeness (expression @ expressions) cci ccs
= check_completeness expression cci
(check_completeness expressions cci ccs)
check_completeness (Let lad) cci ccs
= check_completeness lad cci ccs
check_completeness (Case keesje) cci ccs
= check_completeness keesje cci ccs
check_completeness (Selection _ expression selections) cci ccs
= check_completeness expression cci
(check_completeness selections cci ccs)
check_completeness (TupleSelect _ _ expression) cci ccs
= check_completeness expression cci ccs
check_completeness (BasicExpr _ _) _ ccs
= ccs
check_completeness (AnyCodeExpr _ _ _) _ ccs
= ccs
check_completeness (ABCCodeExpr _ _) _ ccs
= ccs
check_completeness (MatchExpr _ constructor expression) cci ccs
= check_completeness expression cci
(check_whether_ident_is_imported constructor.glob_object.ds_ident STE_Constructor cci ccs)
check_completeness (FreeVar _) _ ccs
= ccs
check_completeness (DynamicExpr dynamicExpr) cci ccs
= check_completeness dynamicExpr cci ccs
check_completeness EE _ ccs
= ccs
check_completeness (Update expr1 selections expr2) cci ccs
= ( (check_completeness expr1 cci)
o (check_completeness selections cci)
o (check_completeness expr2) cci
) ccs
check_completeness expr _ _
= abort "explicitimports:check_completeness (Expression) does not match" <<- expr
instance check_completeness FunctionBody where
check_completeness (CheckedBody body) cci ccs
= check_completeness body cci ccs
check_completeness (TransformedBody body) cci ccs
= check_completeness body cci ccs
check_completeness (RhsMacroBody body) cci ccs
= check_completeness body cci ccs
instance check_completeness FunDef where
check_completeness {fun_type, fun_body, fun_info} cci ccs
= ( (check_completeness fun_type cci)
o (check_completeness fun_body cci)
o (foldSt (flipM check_completeness_of_dyn_expr_ptr cci) fun_info.fi_dynamics)
) ccs
instance check_completeness FunType where
check_completeness {ft_type} cci ccs
= check_completeness ft_type cci ccs
instance check_completeness (Global x) | check_completeness x where
check_completeness { glob_object } cci ccs
= check_completeness glob_object cci ccs
instance check_completeness InstanceType where
check_completeness {it_types, it_context} cci ccs
= check_completeness it_types cci
(check_completeness it_context cci ccs)
instance check_completeness Let where
check_completeness { let_strict_binds, let_lazy_binds, let_expr } cci ccs
= ( (check_completeness let_expr cci)
o (check_completeness let_strict_binds cci)
o (check_completeness let_lazy_binds cci)
) ccs
instance check_completeness MemberDef where
check_completeness {me_type} cci ccs
= check_completeness me_type cci ccs
instance check_completeness (Optional x) | check_completeness x where
check_completeness (Yes x) cci ccs
= check_completeness x cci ccs
check_completeness No _ ccs
= ccs
instance check_completeness Selection where
check_completeness (RecordSelection {glob_object,glob_module} _) cci ccs
#! ({dcl_common}, ccs) = ccs!box_ccs.ccs_dcl_modules.[glob_module] // the selector's filed has to be looked up
({sd_field}) = dcl_common.com_selector_defs.[glob_object.ds_index]
= check_whether_ident_is_imported sd_field ste_field cci ccs
check_completeness (ArraySelection _ _ index_expr) cci ccs
= check_completeness index_expr cci ccs
check_completeness (DictionarySelection _ selections _ index_expr) cci ccs
= check_completeness selections cci
(check_completeness index_expr cci ccs)
instance check_completeness SelectorDef where
check_completeness {sd_type} cci ccs
= check_completeness sd_type cci ccs
instance check_completeness SymbIdent where
check_completeness {symb_name, symb_kind} cci ccs
= case symb_kind of
SK_Constructor _
-> check_whether_ident_is_imported symb_name STE_Constructor cci ccs
SK_Function global_index
-> check_completeness_for_function symb_name global_index ste_fun_or_macro cci ccs
SK_LocalMacroFunction function_index
-> check_completeness_for_local_macro_function symb_name function_index ste_fun_or_macro cci ccs
SK_OverloadedFunction global_index
-> check_completeness_for_function symb_name global_index STE_Member cci ccs
SK_Macro global_index
-> check_completeness_for_function symb_name global_index ste_fun_or_macro cci ccs
where
check_completeness_for_function symb_name {glob_object,glob_module} wanted_ste_kind cci ccs
| glob_module<>cci.box_cci.cci_main_dcl_module_n
// the function that is referred from within a macro is a DclFunction
// -> must be global -> has to be imported
= check_whether_ident_is_imported symb_name wanted_ste_kind cci ccs
#! (fun_def, ccs) = ccs!box_ccs.ccs_icl_functions.[glob_object]
// otherwise the function was defined locally in a macro
// it is not a consequence, but it's type and body are consequences !
#! (already_visited, ccs) = ccs!box_ccs.ccs_set_of_visited_icl_funs.[glob_object]
| already_visited
= ccs
#! ccs = { ccs & box_ccs.ccs_set_of_visited_icl_funs.[glob_object] = True }
= check_completeness fun_def cci ccs
check_completeness_for_local_macro_function symb_name glob_object wanted_ste_kind cci ccs
#! (fun_def, ccs) = ccs!box_ccs.ccs_icl_functions.[glob_object]
// otherwise the function was defined locally in a macro
// it is not a consequence, but it's type and body are consequences !
#! (already_visited, ccs) = ccs!box_ccs.ccs_set_of_visited_icl_funs.[glob_object]
| already_visited
= ccs
#! ccs = { ccs & box_ccs.ccs_set_of_visited_icl_funs.[glob_object] = True }
= check_completeness fun_def cci ccs
instance check_completeness SymbolType where
check_completeness {st_args, st_result, st_context} cci ccs
= ( (check_completeness st_args cci)
o (check_completeness st_result cci)
o (check_completeness st_context cci)
) ccs
instance check_completeness TransformedBody where
check_completeness {tb_rhs} cci ccs
= check_completeness tb_rhs cci ccs
instance check_completeness Type where
check_completeness (TA {type_name} arguments) cci ccs
= check_completeness arguments cci
(check_whether_ident_is_imported type_name STE_Type cci ccs)
check_completeness (l --> r) cci ccs
= check_completeness l cci
(check_completeness r cci ccs)
check_completeness (_ :@: arguments) cci ccs
= check_completeness arguments cci ccs
check_completeness _ _ ccs
= ccs
instance check_completeness TypeContext where
check_completeness {tc_class, tc_types} cci ccs
= check_completeness tc_types cci
(check_whether_ident_is_imported tc_class.glob_object.ds_ident STE_Class cci ccs)
instance check_completeness (TypeDef TypeRhs) where
check_completeness {td_rhs, td_context} cci ccs
= check_completeness td_rhs cci
(check_completeness td_context cci ccs)
instance check_completeness TypeRhs where
check_completeness (SynType aType) cci ccs
= check_completeness aType cci ccs
check_completeness _ _ ccs
= ccs
instance check_completeness [a] | check_completeness a
where
check_completeness [] _ ccs
= ccs
check_completeness [h:t] cci ccs
= check_completeness h cci
(check_completeness t cci ccs)
check_completeness_of_dyn_expr_ptr :: !ExprInfoPtr !CheckCompletenessInputBox !*CheckCompletenessStateBox
-> *CheckCompletenessStateBox
check_completeness_of_dyn_expr_ptr dyn_expr_ptr cci ccs=:{box_ccs=box_ccs=:{ccs_expr_heap}}
#! (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)
-> ccs
(EI_Dynamic (Yes dynamic_type))
-> check_completeness dynamic_type cci ccs
(EI_DynamicType dynamic_type further_dynamic_ptrs)
-> check_completeness dynamic_type cci
(foldSt (flipM check_completeness_of_dyn_expr_ptr cci) further_dynamic_ptrs ccs)
(EI_DynamicTypeWithVars _ dynamic_type further_dynamic_ptrs)
-> check_completeness dynamic_type cci
(foldSt (flipM check_completeness_of_dyn_expr_ptr cci) further_dynamic_ptrs ccs)
flipM f a b :== f b a
// STE_Kinds just for comparision
ste_field =: STE_Field { id_name="", id_info=nilPtr }
ste_fun_or_macro =: STE_FunctionOrMacro []