Sather Home Page

Section 8.17.3.3:
STR_CURSOR

class STR_CURSOR < $TEXT_CURSOR{CHAR,STR}

Inheritance map

$TEXT_CURSOR

Formal Types

types

SAME = STR_CURSOR ;
STR_CURSOR = token

This class models a pointer referring to the successive elements of a list/string. It provides a convenient mechanism to convert string representations of other objects into objects of the appropriate classes. If the expected object representation was not found then the cursor error state is set appropriately.


External specifications

The following reader routines inherited from $TEXT_CURSOR{CHAR,STR} correspond to the visible components of the internal state of a cursor object.


The following features are required to be implemented for this class in accordance with the specifications given in $TEXT_CURSOR{CHAR,STR} from which this class inherits :-


The following four reader routines are required to be implemented in accordance with the specifications given in the class $CURSOR{CHAR,STR} from which this class inherits :-


The following features are required to be implemented for this class in accordance with the specifications given in $CURSOR{CHAR,STR} from which this class inherits :-


create

This routine creates a new string cursor associated with the string argument, ready to scan from the beginning. There is no error condition and the default skip element is a space character.

create (
str : STR
) : SAME
Formal Signature
create(str : STR) res : SAME
Pre-condition

Since the argument is not optional, the pre-condition is vacuously true.

Post-condition
post buffer = str
      and index(res) = 0
      and line_no(res) = 0
      and comment_start(res) = STR.create(LIBCHARS.Space(STR.index_lib(str)))
      and is_done(res) = (index(res) >= len str)
      and not has_ind(res)

This routine creates and initialises a new cursor to have the buffer given as parameter and to be ready to scan from the beginning, having a space character as skip element.


split

This feature provides a comparable functionality to the split! iter in the class STR. The resultant list of strings omits the 'split' character ch.

split (
ch : CHAR
) : FLIST{STR}
Formal Signature
split(self : SAME, ch : CHAR) res : FLIST{STR}
Pre-condition

Since neither of the arguments is optional the pre-condition is vacuously true.

Post-condition
post let loc_sub : seq of STR be st
         [forall idx1,idx2 | idx1 in set inds loc_sub
            and idx2 in set inds tl loc_sub
            and idx2 = idx1 + 1 &
               loc_sub(idx1) ^ loc_sub(idx2)] = buffer in
                  forall idx | idx in set inds tl loc_sub &
                     hd loc_sub(idx) = ch
                     and forall str_ch | str_ch in set dom tl loc_sub(idx) &
                        str_ch <> ch
                          and res(idx) = tl loc_sub(idx)

This routine splits the buffer string into a list of strings separated at each occurrence of ch.


current_loc_str

This feature is provided to enable a program involved in parsing text to display a line of text in a fixed width font underneath which appears this line with the cursor_char indicating the character to which the program needs to refer.

current_loc_str (
cursor_char : CHAR
) : STR
Formal Signature
current_loc_str(self : SAME, cursor_char : CHAR) res : STR
Pre-condition
pre CHAR.is_print(cursor_char)
Post-condition
post let lmark = CODE_STR.tgt_str(LIBCHARS.Line_Mark(STR.index_lib(buffer))),
            space_idx = len res - 1,
            loc_idx = index + 1 in
         forall idx | idx in set inds buffer((loc_idx - space_idx), ..., index) &
               not STR.contains(lmark,buffer(idx))
            and ((index - space_idx) = 0
               or STR.contains(lmark,buffer(index - space_idx - 1)))
            and ((index = len buffer)
               or STR.contains(lmark,buffer(index)))
         and (res(len res) = cursor_ch)

This routine returns a string which is space-filled up to the position of the cursor on the current line to which the given cursor_ch is then appended.


card

The cursor scan expects that the character at the current position is a valid decimal digit character and scans forward as many characters as necessary to obtain the numeric value, leaving the cursor positioned at the next following character. If the first character is not a valid digit or if the value cannot be represented in the executing computer system then nil is returned and the cursor remains in its initial position.

card : CARD
Formal Signature
card(self : SAME) res : CARD
Pre-condition
pre not is_done(self)
Post-condition
post ((res <> CARD.nil)
         and (index > index~))
      or ((res = CARD.nil)
         and (index = index~))

This routine returns the cardinal number represented by the sequence of decimal digit characters starting at the current cursor position. If there is no such number then CARD::nil is returned and the cursor has not been moved.


get_octal

The cursor scan expects that the character at the current position is a valid octal digit character and scans forward as many characters as necessary to obtain the numeric value, leaving the cursor positioned at the next following character. If the first character is not a valid digit or if the value cannot be represented in the executing computer system then nil is returned and the cursor remains in its initial position.

get_octal : CARD
Formal Signature
get_octal(self : SAME) res : CARD
Pre-condition
pre not is_done(self)
Post-condition
post ((res <> CARD.nil)
         and (index > index~))
      or ((res = CARD.nil)
         and (index = index~))

This routine returns the cardinal number represented by the sequence of octal digit characters starting at the current cursor position. If there is no such number then CARD::nil is returned and the cursor has not been moved.


octal

The cursor scan expects that the character at the current position is the first of the expected octal number prefix '0o' followed by a valid octal digit character; it scans forward as many characters as necessary to obtain the numeric value, leaving the cursor positioned at the next following character. If the first character is not the digit zero (followed by 'o') or if the value cannot be represented in the executing computer system then nil is returned and the cursor remains in its initial position.

octal : CARD
Formal Signature
octal(self : SAME) res : CARD
Pre-condition
pre not is_done(self)
Post-condition
post let prefix : seq of CHAR =
         [CHAR_CODE.char(LIBCHARS.digit(STR.index_lib(buffer),0)),
            [CHAR_CODE.char(LIBCHARS.Octal_Prefix(STR.index_lib(buffer)))] in
         ((res <> CARD.nil)
         and ((buffer(index + 1, index + 2) = prefix)
            and (index > index~)))
         or ((res = CARD.nil)
            and (index = index~))

This routine returns the cardinal number represented by the sequence of octal digit characters starting at the current cursor position. If the expected prefix '0o' is not present or the number is not representable or the prefix is not followed by an octal digit then CARD::nil is returned and the cursor has not been moved.


get_hex

The cursor scan expects that the character at the current position is a valid hexadecimal digit character and scans forward as many characters as necessary to obtain the numeric value, leaving the cursor positioned at the next following character. If the first character is not a valid hexadecimal digit or if the value cannot be represented in the executing computer system then nil is returned and the cursor remains in its initial position.

get_hex : CARD
Formal Signature
get_hex(self : SAME) res : CARD
Pre-condition
pre not is_done(self)
Post-condition
post ((res <> CARD.nil)
         and (index > index~))
      or ((res = CARD.nil)
         and (index = index~))

This routine returns the cardinal number represented by the sequence of hexadecimal digit characters starting at the current cursor position. If there is no such number then CARD::nil is returned and the cursor has not been moved.


hex

The cursor scan expects that the character at the current position is the first of the expected hexadecimal number prefix '0x' followed by a valid hexadecimal digit character; it scans forward as many characters as necessary to obtain the numeric value, leaving the cursor positioned at the next following character. If the first character is not the digit zero (followed by 'x') or if the value cannot be represented in the executing computer system then nil is returned and the cursor remains in its initial position.

hex : CARD
Formal Signature
hex(self : SAME) res : CARD
Pre-condition
pre not is_done(self)
Post-condition
post let prefix : seq of CHAR =
         [CHAR_CODE.char(LIBCHARS.digit(STR.index_lib(buffer),0)),
               [CHAR_CODE.char(LIBCHARS.Hex_Prefix(STR.index_lib(buffer)))] in
         ((res <> CARD.nil)
         and ((buffer(index + 1, index + 2) = prefix)
            and (index > index~)))
         or ((res = CARD.nil)
             and (index = index~))

This routine returns the cardinal number represented by the sequence of hexadecimal digit characters starting at the current cursor position. If the expected prefix '0x' is not present or the number is not representable or the prefix is not followed by a hexadecimal digit then CARD::nil is returned and the cursor has not been moved.


field

The cursor scan expects that the character at the current position is a valid decimal digit character and scans forward as many characters as necessary to obtain the numeric value, leaving the cursor positioned at the next following character. If the first character is not a valid digit or if the value cannot be represented in the executing computer system then nil is returned and the cursor remains in its initial position.

field : FIELD
Formal Signature
field(self : SAME) res : FIELD
Pre-condition
pre not is_done(self)
Post-condition
post ((res <> FIELD.nil)
         and (index > index~))
      or ((res = FIELD.nil)
         and (index = index~))

This routine returns the field number represented by the sequence of decimal digit characters starting at the current cursor position. If the character at the current position is not a decimal digit then FIELD::nil is returned and the cursor has not been moved.


int

The cursor scan expects that the character at the current position is a valid decimal digit character and scans forward as many characters as necessary to obtain the numeric value, leaving the cursor positioned at the next following character. If the first character is not a valid digit or if the value cannot be represented in the executing computer system then nil is returned and the cursor remains in its initial position.

int : INT
Formal Signature
int(self : SAME) res : INT
Pre-condition
pre not is_done(self)
Post-condition
post ((res <> INT.nil)
         and (index > index~))
      or ((res = INT.nil)
         and (index = index~))

This routine returns the integer number represented by the sequence of decimal digit characters (with an optional initial minus sign) starting at the current cursor position. If the character at the current position is not a decimal digit then INT::nil is returned and the cursor has not been moved.


flt

The cursor scan expects that the character at the current position is a valid decimal digit character or, optionally a minus sign, and scans forward as many characters as necessary to obtain the numeric value, leaving the cursor positioned at the next following character. If the first character is not a valid digit or if the value cannot be represented in the executing computer system then nil is returned and the cursor remains in its initial position.

flt : FLT
Formal Signature
flt(self : SAME) res : FLT
Pre-condition
pre not is_done(self)
Post-condition
post ((res <> FLT.nil)
         and (index > index~))
      or ((res = FLT.nil)
         and (index = index~))

This routine returns the approximate number represented by the sequence of characters starting at the current cursor position. If the character at the current position is not a decimal digit (preceded optionally by a minus sugn character) or the number is not representable in the computer executing the program or there is a floating point notation error then FLT::nil is returned and the cursor has not been moved.


fltd

The cursor scan expects that the character at the current position is a valid decimal digit character (optionally preceded by a minus sign) and scans forward as many characters as necessary to obtain the numeric value, leaving the cursor positioned at the next following character. If the first character is not a valid digit or if the value cannot be represented in the executing computer system then nil is returned and the cursor remains in its initial position.

fltd : FLTD
Formal Signature
fltd(self : SAME) res : FLTD
Pre-condition
pre not is_done(self)
Post-condition
post ((res <> FLTD.nil)
         and (index > index~))
      or ((res = FLTD.nil)
         and (index = index~))

This routine returns the approximate number represented by the sequence of characters starting at the current cursor position. If the character at the current position is not a decimal digit or minus sign or the number is not representable in the computer executing the program or there is a floating point notation error then FLTD::nil is returned and the cursor has not been moved.


bool

The cursor scan expects that the character at the current position is the first in an unambiguous text representation of a Boolean value. The actual string value depends on the context in which the program is executing (eg Wahr/Falsch in German, Vrai/Faux in French). The value can be truncated to the smallest unambiguous string of characters (eg in English T/F).

bool : BOOL
Formal Signature
bool(self : SAME) res : BOOL
Pre-condition
pre not is_done(self)
Post-condition

Note that this makes use of an auxiliary function to determine the minimum unambiduous length of the culture-dependent text representations of Boolean values.

functions

unambiguous : seq of CHAR * seq of CHAR -> nat

unambiguous (first,second) ==
   (dcl ans : nat := 1 ;
     
   let limit : nat =
         if len first > len second then
            len second
         else
            len first in

      while ans < limit
         and first(ans) = second(ans) do
            ans = ans + 1 ;
    ans)

post let true_str : seq of CHAR = BOOL.str(true),
         false_str : seq of CHAR = BOOL.str(false) in
            let test_lgth : nat = unambiguous(true_str, false_str) in
               let loc_substr : seq of CHAR = buffer(index + 1, ..., index + test_lgth) in
                  ((res = STR.is_prefix(loc_substr,true_str)
                     or res = STR.is_prefix(loc_substr,false_str))
                  and (index > index~))
      or (not res
         and (index = index~))

This routine expects a Boolean string value representation (in a culture-dependent text representation) as the next item in the buffer, advancing by one or more positions if found, otherwise the cursor position has not changed and the value false is returned.


Language Index Library Index Text Index
Comments or enquiries should be made toKeith Hopper.
Page last modified: Thursday, 5 April 2001.
Produced with Amaya