Sather Home Page

Section 8.10.3.10:
SOURCE

class SOURCE

Formal Types

types

SAME = SOURCE ;
SOURCE = seq of Line ;

Line = seq of CHAR
inv ln ==
forall elem in set ln &
elem not in set CODE_STR.str(LIBCHARS.Line_Mark(LIBCHARS.default()))

This class implements a source of logical text lines from which all comments, blank lines and escaped linemarks have been eliminated. A further source of conditional pre-processing is available to eliminate unwanted lines. This is done in a similar manner to the pre-processing of 'if', 'elseif' etc directives done by the C language compiler pre-processing pass.

Reader Routine

The following reader routine shall be provided -


create

This creation routine presumes that the string argument is the name of a file to be opened as source for text data.

create (
fname : STR
) : SAME
Formal Signature
create(fname : STR) res : [SAME]
Pre-condition
pre len fname > 0
and let path = FILE_PATH.create(name) in
(path <> nil)
and let dir = DIRECTORY.existent(FILE_PATH.head(path)) in
(dir <> nil)
and DIRECTORY.exists(dir, FILE_PATH.leaf(path))
Post-condition
post ((res <> nil)
and (comment(res) = CODE_STR.str(LIBCHARS.Space(LIBCHARS.default())))
and (escape(res) = CHAR_CODE.char(LIBCHARS.Null(LIBCHARS.default())))
or let msg : seq of CHAR be st len msg > 0 in
ERR = ERR~ ^ msg

This routine attempts to open the file with the given name for reading and, if successful, reads its contents and closes the file. If the file is not found or may not be read then void is returned after issuing an error message.


create

This creation routine presumes that the file path identifies the file to be opened as source for text data.

create (
path : FILE_PATH
) : SAME
Formal Signature
create2(path : FILE_PATH) res : [SAME]
Pre-condition
pre let dir = DIRECTORY.existent(FILE_PATH.head(path)) in
(dir <> nil)
and DIRECTORY.exists(dir, FILE_PATH.leaf(path))
Post-condition
post ((res <> nil)
and (comment(res) = CODE_STR.str(LIBCHARS.Space(LIBCHARS.default())))
and (escape(res) = CHAR_CODE.char(LIBCHARS.Null(LIBCHARS.default())))
or let msg : seq of CHAR be st len msg > 0 in
ERR = ERR~ ^ msg

This routine attempts to open the file with the given path for reading and, if successful, reads its contents and closes the file. If the file is not found or may not be read then void is returned after issuing an error message.


create

This creation routine presumes that the file path identifies the file which has been passed as the source for data.

create (
fyle : TEXT_FILE,
path : FILE_PATH
) : SAME
Formal Signature
create3(fyle : TEXT_FILE, path : FILE_PATH) res : [SAME]
Pre-condition
pre TEXT_FILE.is_open(fyle)
Post-condition
post ((res <> nil)
and (comment(res) = CODE_STR.str(LIBCHARS.Space(LIBCHARS.default())))
and (escape(res) = CHAR_CODE.char(LIBCHARS.Null(LIBCHARS.default())))
or let msg : seq of CHAR be st len msg > 0 in
ERR = ERR~ ^ msg

This routine assumes that the given path is the source name of the open file presented as the first argument. In creating the source the file given is closed.


comment

This routine returns the value most recently set for the start of line comment string.

comment : STR
Formal Signature
comment(self : SAME) res : STR
Pre-condition

Since a default value is provided on creation, the pre-condition is vacuously true.

Post-condition
post len res > 0

This routine returns the string currently in use as the start of line comment marker.


comment

This routine sets its argument as the start of line comment for further use until a subsequent call of this routine.

comment (
chars : STR
)
Formal Signature
comment2(self : SAME, chars : STR)
Pre-condition
pre len chars > 0
Post-condition
post comment(self) = chars(1, ..., 2)

This routine establishes the first two characters of the argument as the comment characters to be used henceforth in analysing this source text.


escape

This routine returns the value most recently set for the escape character.

escape : CHAR
Formal Signature
escape(self : SAME) res : CHAR
Pre-condition

Since a default value is provided on creation, the pre-condition is vacuously true.

Post-condition
post true

This routine returns the character currently in use as the escape character.


escape

This routine sets its argument as the escape character for further use until a subsequent call of this routine.

escape (
ch : CHAR
)
Formal Signature
escape2(self : SAME, ch : CHAR)
Pre-condition
pre true
Post-condition
post escape(self) = ch

This routine establishes the argument character as the escape character to be used henceforth in analysing this source text.


finished

This predicate returns true if and only if there are no more text lines in the source.

finished : BOOL
Formal Signature
finished(self : SAME) res : BOOL
Pre-condition

Since this is a predicate, the pre-condition is true.

Post-condition
post res =
let pplast = pp_line(self) in
(pplast = nil)
or let last = line(self) in
(last = nil)

This predicate returns true if and only if there are no more lines to be returned from this source, otherwise false.


line!

This iter yields a cursor indicating the next logical line in self. All blank and comment lines are removed and an escaped line-mark is ignored, allowing text to flow on as a continuation of what preceded it.

line! : STR_CURSOR
Formal Signature

Note that the formal name of the iter has been changed to replace the exclamation mark iter symbol to a name acceptable to vdm tools.

line_iter(self : SAME) res : STR_CURSOR
Pre-condition

This iter effectively has a true pre-condition since it has no arguments. If the iter is called after the last line has been yielded than, of course, it quits.

pre true
Post-condition

This post-condition makes use of the history concept from vdm++ (see the vdm dialect notes).

post let loc_res = self(len history~ + 1) in
history = history~ ^ [loc_res]
and res = STR_CURSOR.create(loc_res)
Quit condition

For quit actions see the specification of the quit statement.

errs QUIT : len history = len self -> quit

This iter assembles one or more source lines into a logical line without conditional pre-processing, omitting comment lines and blank lines - stripping unwanted line marks at the end as necessary.


line

This routine returns a cursor indicating the next logical line in self. All blank and comment lines are removed and an escaped line-mark is ignored, allowing text to flow on as a continuation of what preceded it.

line : STR_CURSOR
Formal Signature
line(self : SAME) res : [STR_CURSOR]
Pre-condition
pre not finished(self)
Post-condition
post (res = nil)
or (line_no > line_no~)

This routine assembles and returns one or more source lines into a logical line without conditional pre-processing, omitting comment lines and blank lines - stripping unwanted line marks at the end as necessary.


pp_line!

This iter yields a cursor indicating the next logical line in self. All blank and comment lines are removed and an escaped line-mark is ignored, allowing text to flow on as a continuation of what preceded it. Pre-processing is carried out on the source in accordance with the semantics defined for the pre-processing tags in the class CONDITIONALS.

pp_line! : STR_CURSOR
Formal Signature

Note that the formal name of the iter has been changed to replace the exclamation mark iter symbol to a name acceptable to vdm tools.

pp_line_iter(self : SAME) res : STR_CURSOR
Pre-condition

This iter effectively has a true pre-condition since it has no arguments. If the iter is called after the last line has been yielded than, of course, it quits.

pre true
Post-condition

This post-condition makes use of the history concept from vdm++ (see the vdm dialect notes).

post let loc_res = self(len history~ + 1) in
history = history~ ^ [loc_res]
and res = STR_CURSOR.create(loc_res)
Quit condition

For quit actions see the specification of the quit statement.

errs QUIT : len history = len self -> quit

This iter yields a sequence of logical lines, each formed by assembling one or more source lines into a logical line with conditional pre-processing as defined by the semantics attached to the pre-processing tags defined in the class CONDITIONALS, omitting comment lines and blank lines - stripping unwanted line marks at the end as necessary.


pp_line

This routine returns the next single pre-processed line in the source. See the class CONDITIONALS for pre-processing details.

pp_line : STR_CURSOR
Formal Signature
pp_line(self : SAME) res : [STR_CURSOR]
Pre-condition
pre not finished(self)
Post-condition
post (res = nil)
or (line_no > line_no~)

This routine assembles and returns one or more source lines into a logical line with conditional pre-processing as defined by the semantics attached to the pre-processing tags defined in the class CONDITIONALS, omitting comment lines and blank lines - stripping unwanted line marks at the end as necessary. If there is no more valid text in the source then void shall be returned.


Language Index Library Index Input/Output Index
Comments or enquiries should be made to Keith Hopper.
Page last modified: Friday, 24 November 2000.
Produced with Amaya