Consider the following routine, which tries to read a boolean value from a string:
get_bool(file_name:STR):BOOL is
f:FILE := FILE::open_for_read(file_name);
if f.error then
raise #FILE_OPEN_EXC(file_name);
end;
s:STR := f.str; -- Read the file into a string
f.close; -- Close the file
res:BOOL;
bool ::= "";
i:INT := 0;
loop
until!(~(s[i].is_alpha) or (s[i].is_space) or i >= s.size);
bool := bool + s[i];
i := i + 1;
end;
case bool
when "true","t","True","T","TRUE" then
return true;
when "false","f","False","F","FALSE" then
return false;
else
raise #PARSE_BAD_BOOL_EXC(s);
end;
end; |
In the above routine there are two possible errors - either the file could not be opened or it does not contain a valid boolean. The two cases can be distinguised at the point when the exception is caught
protect file_name:STR; ... set to a value b:BOOL := get_bool(s); when FILE_OPEN_EXC then #ERR + "Could not open:" + exception.file_name + "\n"; when PARSE_BAD_BOOL_EXC then #ERR + "Error in reading boolean:" + exception.str + "\n"; end; |
The classes that implement these exceptions can be fairly simple
class FILE_OPEN_EXC is
readonly attr str:STR:
create(file_name:STR):SAME is
res ::= new;
res.str := file_name;
return res;
end;
end; |
The other exception class is very similar.