enums.sa
Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
-------------------------> GNU Sather - sourcefile <-------------------------
-- Copyright (C) 2000 by K Hopper, University of Waikato, New Zealand --
-- This file is part of the GNU Sather library. It is free software; you may --
-- redistribute and/or modify it under the terms of the GNU Library General --
-- Public License (LGPL) as published by the Free Software Foundation; --
-- either version 2 of the license, or (at your option) any later version. --
-- This library is distributed in the hope that it will be useful, but --
-- WITHOUT ANY WARRANTY without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See Doc/LGPL for more details. --
-- The license text is also available from: Free Software Foundation, Inc., --
-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
--------------> Please email comments to <bug-sather@gnu.org> <--------------
abstract class $ENUMS{ITP} < $IS_EQ, $HASH, $BINARY,$TEXT, $NIL, $ANCHORED_FMT
abstract class $ENUMS{ITP} < $IS_EQ, $HASH, $BINARY,$TEXT, $NIL, $ANCHORED_FMT is
-- This abstraction provides a generic enumeration coding facility.
-- The definition of routines is assumed not to include the numeric encoding
-- of zero -- which is the 'void' (meaning undefined) value. The values do
-- not, however, have to commence with the code number one - they are assumed
-- to start with the code number given by the offset feature (see comment
-- below).
-- Version 1.4 May 2001. Copyright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 5 May 96 kh Original following Klawitter
-- 10 Dec 96 kh Modified to include Names.
-- 3 Jan 97 kh Modified for cardinals and portability.
-- 24 Dec 98 kh Added offset and val_count
-- 16 May 01 kh Changed null to nil, is_void to is_nil
enum : CARD ; -- The internal encoding!
nil : SAME ; -- This feature returns a nil value for the enumeration
hash : CARD ;
-- Since the encoding is likely to be small numbers, the cardinal hash
-- function will normally be used.
is_eq(other : ITP) : BOOL ;
-- The required equality test. Note that individual implementations
-- may provide for ordering of the values.
is_nil : BOOL ; -- This feature returns true if and only if self is nil.
card : CARD ; -- This is a routine to return the encoding value as a number.
fmt(format : ANCHORED_DESCR,lib : LIBCHARS) : STR ;
-- This routine accepts a format string argument and returns a formatted
-- version of self in accordance with this in the given representation and
-- encoding.
fmt(format : ANCHORED_DESCR) : STR ;
-- This routine accepts a format string argument and returns a formatted
-- version of self in accordance with this.
elt! : SAME ; -- This iter yields in turn all of the values of the enumeration.
end ; -- $ENUMS
partial class ENUM_AUXILIARY
partial class ENUM_AUXILIARY is
-- This partial class embodies all those components of the enumeration
-- abstraction which are independent of whether the enumeration is exact
-- or not. It is intended only to be included in the classes ENUM{T} and
-- EXACT_ENUM{T}.
-- Version 1.1 May 2001. Copyright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 22 Jul 98 kh Original from ENUM{T} and EXACT_ENUM{T}
-- 16 May 01 kh Changed null/is_void to nil/is_nil
include COMPARABLE ;
include BINARY ;
include ENUM_STR ;
readonly attr enum : CARD ; -- Used also for transforming
-- an enum to a cardinal value.
private stub lookup(name : STR) : CARD ;
-- This routine returns the index of the name in the Names array.
create(num : CARD) : SAME
pre (num >= offset) and (num < (offset + val_count))
post true
is
-- This routine is used internally to create enumeration encodings from
-- cardinal numbers.
return enum(num)
end ;
build(cursor : BIN_CURSOR) : SAME
pre ~void(cursor)
and (((val_count < OCTET::Octet_Max)
and (cursor.remaining >= 1))
or (cursor.remaining >= 2))
post true
is
-- This routine is used internally to create enumeration encodings from
-- the binary string associated with the cursor.
num : CARD ;
loc_size : CARD := 1 ; -- the most likely case!
if val_count > OCTET::Octet_Max then
loc_size := 2
end ;
case loc_size
when 1 then
num := OCTET::build(cursor).card ;
if (num >= offset) and (num < (offset + val_count)) then
-- need to satisfy pre-condition
return enum(num)
else -- couldn't so is void!
return enum(0) -- should be void
end
when 2 then
num := HEXTET::build(cursor).card ;
if (num >= offset) and (num < (offset + val_count)) then
-- need to satisfy pre-condition
return enum(num)
else -- couldn't so is void!
return enum(0) -- should be void
end
else -- not possible!
return enum(0) -- should be void!
end
end ;
binstr : BINSTR
pre ~is_nil
post ((val_count <= OCTET::Octet_Max)
and (result.size = 1))
or ((val_count > OCTET::Octet_Max)
and (result.size = 2))
is
-- This routine returns the enumeration as a short binary string.
if val_count > OCTET::Octet_Max then
return HEXTET::create(enum).binstr
else
return OCTET::create(enum).binstr
end
end ;
nil : SAME is
-- This feature returns a value which is a 'void' for the enumeration.
-- The language-defined void may be implemented differently.
return enum(0)
end ;
hash : CARD
pre ~is_nil
post true
is
-- This is a hash function for use when mapping by this key. It merely
-- uses the library cardinal hash function.
return enum.hash
end ;
is_nil : BOOL is
-- This predicate returns true if and only if self is 'void'.
return enum = 0
end ;
is_eq(other : SAME) : BOOL is
-- This predicate returns true if and only if self and other are the same
-- value except if either is void when false is returned identically.
if is_nil
or other.is_nil then -- They are incomparable!
return false
else
return (enum = other.enum)
end
end ;
card : CARD
pre ~is_nil
is
-- This trivially returns the value of enum.
return enum
end ;
elt! : SAME is
-- This iter yields in turn all of the values in the domain of the enumeration.
loc_limit : CARD := offset + cardinality - 1 ;
loop
yield enum(offset.upto!(loc_limit))
end
end ;
end ; -- ENUM_AUXILIARY
partial class ENUM{T}
partial class ENUM{T} is
--This class is designed to be included in any class which defines
-- an enumeration. It provides all of the functionality for an enumeration
-- abstraction, leaving only the constant value routines and their count
-- to be defined in a specific enumeration implementation.
-- Version 1.3 Jul 98. Copyright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 5 May 96 kh Original following Klawitter
-- 10 Dec 96 kh Modified to include Names.
-- 3 Jan 97 kh Modified for cardinals and portability.
-- 22 Jul 98 kh split off ENUM_AUXILIARY components.
include ENUM_AUXILIARY ;
private equals(first_lcase,second : STR) : BOOL is
--This routine tests for string equality up to the length of first!
-- The test is case independent.
--pre (first_lcase.size > 0) and (second.size > 0)
-- post (first_lcase.lower = second.lower) or ~result
--#OUT+"enums.sa equals."+"s1=["+first_lcase+"], s2=["+ second+"]\n";
--if ~((first_lcase.size > 0) and (second.size > 0)) then raise "string is empty\n"; end;
if first_lcase.size > second.size then return false; end;
one : STR := first_lcase ;
two : STR := second.lower ;
loop
if ~(one.elt! = two.elt!) then
return false
end
end ;
return true
end ;
private scan!(str : STR) : CARD
pre ~void(str)
post (result >= offset) and (result < (offset + val_count))
is
--This iter does the majority of the work for the lookup routine which follows.
res : CARD := 0 ; -- ie not found!
found : BOOL := false ;
lcase_str : STR := str.lower ;
loop
index : CARD := 0.upto!(Names.size - 1) ;
if equals(lcase_str,Names[index]) then -- ignoring letter case!
if found then -- Not unique!
quit
else
found := true ;
res := index;
end
end
end ;
if ~found then
quit
else -- exist and unique.
yield res + offset
end
end ;
private lookup(str : STR) : CARD
pre str.size > 0
post (result = 0) or ((result >= offset) and (result < (offset + val_count)))
is
--This function returns the enumeration value specified in text
-- string form in str. Matching the string in the table is done
-- case independently and only until the str is found to be unambiguous.
-- [eg if all table entries start with a different character then that is all that is checked].
res : CARD := 0 ; -- NOT a valid value of this class
loop -- only done once!
res := scan!(str)
end ;
return res
end ;
end ; -- ENUM{T}
partial class EXACT_ENUM{T}
partial class EXACT_ENUM{T} is
-- This class is designed to be included in any class which defines
-- an enumeration. It provides all of the functionality for en enumeration
-- abstraction, leaving only the constant value routines and their count
-- to be defined in a specific enumeration implementation. This version
-- requires that creation using a string matches exactly the value in the
-- name table!
-- Version 1.1 Jul 98. Copyright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 8 May 97 kh Original from ENUM{T}
-- 22 Jul 98 kh Split off ENUM_AUXILIARY components.
include ENUM_AUXILIARY ;
private lookup(str : STR) : CARD
pre (str.size > 0)
post (result = 0)
or ((result >= offset)
and (result < (offset + val_count)))
is
-- This routine does the work of looking up the string in Names and
-- returning index + offset -- unless no match was found when void is returned!
loop
index : CARD := 0.upto!(Names.size - 1) ;
if (str = Names[index]) then
return index + offset
end
end ;
return 0 -- didn't find it!
end ;
end ; -- EXACT_ENUM{T}