A stream is a generalization of internal and external text objects. An internal text object (text) is a sequence (repetition) of chars. An external text object (file) corresponds to a traditional text file. Stream, text and file are organized in the following hierarchy:
Stream, text, and file
stream: (# ... #); text: stream(# ... #); file: stream(# ... #); (* described in a later chapter *) unixFile: file(# ... #);(* described in a later chapter *) macFile: file(# ... #); (* described in the Macintosh * Library manual *)
The stream pattern is an abstract superpattern: which provides general stream manipulating procedure patterns: getPos, setPos, eos, length, reset, newline, put, get, peek, putint, getint, puttext, gettext, putline, getNonBlank, getline, getAtom, scan, scanBlanks, scanToNL and scanAtom. The stream pattern also defines exception patterns (e.g. EOSerror). See the interface of stream for more details.
There is an additional library called substreams.bet, which implements a substrems concept (and a subtext concept). A substream refers to a (consequtive) portion of another stream. Manipulations on the substream will thereby actually change that portion of this other stream. All usual stream operations applies to a substream. See the interface of substream for more details.
The text concept is intended for 'small' texts, but there is no size limit. Some of the operations might however be inefficient on large text objects.
A text is a sequence of characters. The range of a text object T is [1,T.length]. A text can be initialized by executing T.clear or by assigning it with another (initialized) text. Like the predefined patterns integer, real, char and boolean, Text objects are self-assignable. A text constant has the form 'foo' or 'a'. The ' character may by specified as part of a text constant by repeating it, e.g. 'is''s like this' is the text constant: is's like this.
Besides defining the implementations of the abstract stream operations (e.g. put and get), the text pattern defines the following patterns: empty, clear, inxGet, inxPut, append, prepend, scanAll, sub, insert, delete, equal, equalNCS, less, greater, makeLC, makeUC, find, findAll, findText, findTextAll, copy, and asInt.
All error messages from exceptions originating from text objects are followed by the text lines:
Error in text which begins as follows: <THIS(text)>.....
where <THIS(text)> is the text where the error occurred.
The library textUtils.bet contains a number of additional text attributes, such as getBoolean, putBoolean, set, setText, setInt, setBased, setReal, and setBoolean. See the interface of textUtils for more details.
The library texthash.bet contains a single operation: honeyman, which is an efficient and nearly optimal hash-function for text hash keys. See the interface of texthash for more details.
This example gives examples of how to use the text pattern. The text object Records consists of a sequence of records. Each record has the form:
name Job:aJob Salary:aSalary /
The program shows various patterns for manipulating the Records text:
ORIGIN '~beta/basiclib/betaenv'; --- program: descriptor -- (* Demo example shwoing examples of how to use the text concept from betaenv. * The text object Records, consists of a sequence of records. Each record * has the form: * name Job:aJob Salary:aSalary / * The program shows various patterns for manipulating the Records text. *) (# GetName: (* read next name from T *) (# T: ^text; T1: @text enter T[] do (* scan and skip until a letter is met *) T.scan(# while::<(#do NOT (ch->Ascii.isLetter)->value #)#); (* scan and read while letters in T *) T.scan (# while::<(#do ch->Ascii.isLetter->value #) do ch->T1.put #) exit T1 #); GetRecord: (* Get the record with the name N and return name and dat part *) (# N: ^Text; name,data: @Text enter N[] do Records.reset; FindName: (if not Records.eos then Records[]->getName->name; data.clear; (* scan and read until '/' is met *) Records.scan(# while::<(#do (ch<>'/')->value#) do ch->data.put #); (if not (N[]->name.equal) then restart FindName if)if) exit(name,data) #); GetJobAndSalary: (* get the job and salary from data part, which is the part after name *) (# Data: ^Text; Job: @Text; Salary: @integer enter Data[] do Data.reset; Data[]->GetName; Data.get (* skip ':' *); Data[]->GetName->Job; Data[]->GetName; Data.get; Data.GetInt->Salary exit(Job,Salary) #); Records: @Text; do '----------1:'->putLine; (* initialize Records *) 'John Job:Programmer salary:120000 / '->Records.append; 'Joan Job:Doctor salary:130000 / '->Records.append; 'Mary Job:Boss salary:140000 / '->Records.append; Records[]->putLine; '----------2:'->putLine; (* split Records into atoms *) Records.reset; scan: cycle (# do Records.getAtom->putline; (if Records.eos then leave scan if)#); '----------3:'->putLine; (* Find record with name Joan and decode data part *) (# Name,Data,Job: @ text; Salary: @Integer do 'Joan'->GetRecord->(Name,Data); 'Ms. '->Name.prePend; ' II'->name.append; Name[]->putText; ' has the data: '->putText; Data[]->GetJobAndSalary->(Job,Salary); 'Job='->putText; Job.makeUC; Job[]->putText; ' Salary='->putText; Salary->putInt; newline; #) #)
Besides these two patterns, this fragment defines a conversion pattern ascii2wtext, which takes a regular BETA text and converts it into a UniCode text (a wtext instance). Furthermere, this fragment extends the text interface with one additional operation aswtext, which converts the text instance to a wtext instance.
See the interface file for wtext for further details.
Basic Libraries - Reference Manual | © 1990-2002 Mjølner Informatics |
[Modified: Friday October 27th 2000 at 13:15]
|