const func type: hash [ (in type: keyType) ] (in type: baseType) is func
result
var type: hashType is void;
local
var type: keyValueType is void;
begin
hashType := get_type(getfunc(hash [ (attr keyType) ] (attr baseType)));
if hashType = void then
global
hashType := newtype;
IN_PARAM_IS_REFERENCE(hashType);
keyValueType := newtype;
IN_PARAM_IS_REFERENCE(keyValueType);
const boolean: isHashType (attr hashType) is TRUE;
const type: hash [ (attr keyType) ] (attr baseType) is hashType;
const type: key_type (attr hashType) is keyType;
const type: base_type (attr hashType) is baseType;
const reference: (attr hashType) . keyHashCode is getfunc(hashCode(in keyType: anElem));
const reference: (attr hashType) . keyCreate is getfunc((ref keyType: dest) ::= (in keyType: source));
const reference: (attr hashType) . keyDestroy is getfunc(destroy(ref keyType: aValue));
const reference: (attr hashType) . keyCopy is getfunc((inout keyType: dest) := (in keyType: source));
const reference: (attr hashType) . keyCompare is getfunc(compare(in keyType: key1, in keyType: key2));
const reference: (attr hashType) . dataCreate is getfunc((ref baseType: dest) ::= (in baseType: source));
const reference: (attr hashType) . dataDestroy is getfunc(destroy(ref baseType: aValue));
const reference: (attr hashType) . dataCopy is getfunc((inout baseType: dest) := (in baseType:source));
const proc: CREATE (ref hashType: dest, in hashType: source,
in reference: keyCreate, in reference: keyDestroy,
in reference: dataCreate, in reference: dataDestroy) is action "HSH_CREATE";
const proc: DESTROY (ref hashType: aValue, in reference: keyDestroy,
in reference: dataDestroy) is action "HSH_DESTR";
const proc: COPY (inout hashType: dest, in hashType: source,
in reference: keyCreate, in reference: keyDestroy,
in reference: dataCreate, in reference: dataDestroy) is action "HSH_CPY";
const proc: FOR_DATA (inout baseType: forVar, in hashType: aHashMap,
in proc: statements, in reference: dataCopy) is action "HSH_FOR";
const proc: FOR_KEY (inout keyType: keyVar, in hashType: aHashMap,
in proc: statements, in reference: keyCop) is action "HSH_FOR_KEY";
const proc: FOR_DATA_KEY (inout baseType: forVar, inout keyType: keyVar,
in hashType: aHashMap, in proc: statements,
in reference: dataCopy, in reference: keyCopy) is action "HSH_FOR_DATA_KEY";
const func array keyType: KEYS (in hashType: aHashMap, in reference: keyCreate,
in reference: keyDestroy) is action "HSH_KEYS";
const func array baseType: VALUES (in hashType: aHashMap, in reference: dataCreate,
in reference: dataDestroy) is action "HSH_VALUES";
const proc: (ref hashType: dest) ::= (in hashType: source) is func
begin
CREATE(dest, source, hashType.keyCreate, hashType.keyDestroy,
hashType.dataCreate, hashType.dataDestroy);
end func;
const proc: destroy (ref hashType: oldHash) is func
begin
DESTROY(oldHash, hashType.keyDestroy, hashType.dataDestroy);
end func;
const proc: (inout hashType: dest) := (in hashType: source) is func
begin
COPY(dest, source, hashType.keyCreate, hashType.keyDestroy,
hashType.dataCreate, hashType.dataDestroy);
end func;
const func integer: length (in hashType: aHashMap) is action "HSH_LNG";
const func baseType: INDEX (in hashType: aHashMap, in keyType: aKey,
in integer: hashCode,
in reference: keyCompare) is action "HSH_IDX";
const varfunc baseType: INDEX (inout hashType: aHashMap, in keyType: aKey,
in integer: hashCode,
in reference: keyCompare) is action "HSH_IDX";
const func baseType: INDEX2 (in hashType: aHashMap, in keyType: aKey,
in integer: hashCode, in baseType: defaultValue,
in reference: keyCompare,
in reference: dataCreate) is action "HSH_IDX2";
const func ptr baseType: REFINDEX (in hashType: aHashMap, in keyType: aKey,
in integer: hashCode,
in reference: keyCompare) is action "HSH_REFIDX";
const proc: INCL (inout hashType: aHashMap, in keyType: aKey,
in baseType: anElem, in integer: hashCode,
in reference: keyCompare, in reference: keyCreate,
in reference: dataCreate, in reference: dataCopy) is action "HSH_INCL";
const proc: EXCL (inout hashType: aHashMap, in keyType: aKey,
in integer: hashCode, in reference: keyCompare,
in reference: keyDestroy, in reference: dataDestroy) is action "HSH_EXCL";
const func baseType: UPDATE (inout hashType: aHashMap, in keyType: aKey,
in baseType: anElem, in integer: hashCode,
in reference: keyCompare, in reference: keyCreate,
in reference: dataCreate) is action "HSH_UPDATE";
const func boolean: CONTAINS (in hashType: aHashMap, in keyType: aKey,
in integer: hashCode,
in reference: keyCompare) is action "HSH_CONTAINS";
const func hashType: GEN_HASH (in keyValueType: keyValuePairs,
in reference: keyHashCode,
in reference: keyCompare,
in reference: keyDestroy,
in reference: dataDestroy) is action "HSH_GEN_HASH";
const func hashType: (attr hashType) . _GENERATE_EMPTY_HASH is action "HSH_EMPTY";
const hashType: (attr hashType) . EMPTY_HASH is hashType._GENERATE_EMPTY_HASH;
const hashType: (attr hashType) . value is hashType._GENERATE_EMPTY_HASH;
const func baseType: (in hashType: aHashMap) [ (in keyType: aKey) ] is
return INDEX(aHashMap, aKey, hashCode(aKey), hashType.keyCompare);
const varfunc baseType: (inout hashType: aHashMap) [ (in keyType: aKey) ] is
return var INDEX(aHashMap, aKey, hashCode(aKey), hashType.keyCompare);
const func baseType: (in hashType: aHashMap) [ (in keyType: aKey) default (in baseType: defaultValue) ] is
return INDEX2(aHashMap, aKey, hashCode(aKey), defaultValue,
hashType.keyCompare, hashType.dataCreate);
const func boolean: (in keyType: aKey) in (in hashType: aHashMap) is
return CONTAINS(aHashMap, aKey, hashCode(aKey), hashType.keyCompare);
const func boolean: (in keyType: aKey) not in (in hashType: aHashMap) is
return not CONTAINS(aHashMap, aKey, hashCode(aKey), hashType.keyCompare);
const proc: incl (inout hashType: aHashMap, in keyType: aKey, in baseType: anElem) is func
begin
INCL(aHashMap, aKey, anElem, hashCode(aKey), hashType.keyCompare,
hashType.keyCreate, hashType.dataCreate, hashType.dataCopy);
end func;
const proc: excl (inout hashType: aHashMap, in keyType: aKey) is func
begin
EXCL(aHashMap, aKey, hashCode(aKey), hashType.keyCompare,
hashType.keyDestroy, hashType.dataDestroy);
end func;
const proc: (inout hashType: aHashMap) @:= [ (in keyType: aKey) ] (in baseType: anElem) is func
begin
INCL(aHashMap, aKey, anElem, hashCode(aKey), hashType.keyCompare,
hashType.keyCreate, hashType.dataCreate, hashType.dataCopy);
end func;
const func baseType: update (inout hashType: aHashMap, in keyType: aKey, in baseType: anElem) is
return UPDATE(aHashMap, aKey, anElem, hashCode(aKey), hashType.keyCompare,
hashType.keyCreate, hashType.dataCreate);
const func keyValueType: [ (in keyType: aKey) : (in baseType: aValue) ] is action "HSH_GEN_KEY_VALUE";
const func keyValueType: (in keyValueType: element1) ,
(in keyValueType: element2) is action "HSH_CONCAT_KEY_VALUE";
const func hashType: [] (in func keyValueType: keyValuePairs) is
return GEN_HASH(keyValuePairs, hashType.keyHashCode, hashType.keyCompare,
hashType.keyDestroy, hashType.dataDestroy);
const proc: for (inout baseType: forVar) range (in hashType: aHashMap) do
(in proc: statements)
end for is func
begin
FOR_DATA(forVar, aHashMap, statements, hashType.dataCopy);
end func;
const proc: for key (inout keyType: keyVar) range (in hashType: aHashMap) do
(in proc: statements)
end for is func
begin
FOR_KEY(keyVar, aHashMap, statements, hashType.keyCopy);
end func;
const proc: for (inout baseType: forVar) key (inout keyType: keyVar) range (in hashType: aHashMap) do
(in proc: statements)
end for is func
begin
FOR_DATA_KEY(forVar, keyVar, aHashMap, statements, hashType.dataCopy, hashType.keyCopy);
end func;
const func array keyType: keys (in hashType: aHashMap) is
return KEYS(aHashMap, hashType.keyCreate, hashType.keyDestroy);
const func array baseType: values (in hashType: aHashMap) is
return VALUES(aHashMap, hashType.dataCreate, hashType.dataDestroy);
if getobj((in baseType: element1) = (in baseType: element2)) <> NIL then
const func boolean: (in hashType: hash1) = (in hashType: hash2) is func
result
var boolean: isEqual is TRUE;
local
var keyType: aKey is keyType.value;
var baseType: aValue is baseType.value;
begin
if length(hash1) <> length(hash2) then
isEqual := FALSE;
else
for aValue key aKey range hash1 do
if not (aKey in hash2 and aValue = hash2[aKey]) then
isEqual := FALSE;
end if;
end for;
end if;
end func;
const func boolean: (in hashType: hash1) <> (in hashType: hash2) is
return not hash1 = hash2;
end if;
if getfunc(hashCode(in baseType: anElem)) <> NIL and
getfunc(compare(in baseType: elem1, in baseType: elem2)) <> NIL then
const func hash [baseType] array keyType: flip (in hashType: aHashMap) is func
result
var hash [baseType] array keyType: inverseHash is (hash [baseType] array keyType).value;
local
var keyType: aKey is keyType.value;
var baseType: aValue is baseType.value;
begin
for aValue key aKey range aHashMap do
if aValue in inverseHash then
inverseHash[aValue] &:= aKey;
else
inverseHash @:= [aValue] [] (aKey);
end if;
end for;
end func;
end if;
end global;
end if;
end func;