system/base/1.7.5/src/text

Raw file
Back to index

(* ------------------- VERSION 3     06.03.86 ------------------- *)
PACKET text DEFINES
 
            max text length ,
            SUB ,
            subtext ,
            text ,
            length , LENGTH ,
            CAT ,
            + ,
            * ,
            replace ,
            change ,
            change all ,
            compress ,
            pos ,
            code ,
            ISUB ,
            RSUB ,
            delete char ,
            insert char ,
            delete int ,
            insert int ,
            heap size ,
            collect heap garbage ,
            stranalyze ,
            LEXEQUAL ,
            LEXGREATER ,
            LEXGREATEREQUAL :

 
 
TEXT VAR text buffer , tail buffer ;
 
INT CONST max text length := 32000 ;
 
TEXT OP SUB (TEXT CONST text, INT CONST pos ) :
 EXTERNAL 48
END OP SUB ;
 
TEXT PROC subtext (TEXT CONST source, INT CONST from, to ):
 EXTERNAL 49 
ENDPROC subtext ;
 
TEXT PROC subtext (TEXT CONST source, INT CONST from ) : 
 EXTERNAL 50 
ENDPROC subtext ; 
 
INT PROC code (TEXT CONST text) :
 EXTERNAL 46
END PROC code ;
 
TEXT PROC code (INT CONST code) :
 EXTERNAL 47 
ENDPROC code ;

INT OP ISUB (TEXT CONST text, INT CONST index) :
 EXTERNAL 44
ENDOP ISUB ;
 
PROC replace (TEXT VAR text, INT CONST index, value) :
 EXTERNAL 45
ENDPROC replace ;

REAL OP RSUB (TEXT CONST text, INT CONST index) :
 EXTERNAL 100
ENDOP RSUB ;

PROC replace (TEXT VAR text, INT CONST index, REAL CONST code) :
 EXTERNAL 101
ENDPROC replace ;
 
 
PROC replace (TEXT VAR dest, INT CONST pos, TEXT CONST source) : 
 EXTERNAL 51 
ENDPROC replace ; 
 
TEXT PROC text (TEXT CONST source, INT CONST length ) : 

  IF length < LENGTH source 
     THEN text buffer := subtext (source,1,length) 
     ELSE text buffer := source ;
          mit blanks auffuellen 
  FI ; 
  text buffer .
 
mit blanks auffuellen : 
  INT VAR i ;
  FOR i FROM 1 UPTO length - LENGTH source REP
    text buffer CAT " "
  PER .

ENDPROC text ; 
 
TEXT PROC text (TEXT CONST source, INT CONST length, from) : 
  text ( subtext (source, from) , length ) 
ENDPROC text ; 
 
OP CAT (TEXT VAR right, TEXT CONST left ) :
 EXTERNAL 52 
ENDOP CAT ;
 
TEXT OP + (TEXT CONST left, right) : 
 text buffer := left ;
 text buffer CAT right ; 
 text buffer
ENDOP + ; 
 
TEXT OP * (INT CONST times, TEXT CONST source ) : 

  text buffer := "" ;
  INT VAR i ;
  FOR i FROM 1 UPTO times REP
    text buffer CAT source
  PER ;
  text buffer

ENDOP * ;
 
INT PROC length (TEXT CONST text ) : 
 EXTERNAL 53 
ENDPROC length ; 
 
INT OP LENGTH (TEXT CONST text ) : 
 EXTERNAL 53 
ENDOP LENGTH ;
 
INT PROC pos (TEXT CONST source, pattern) : 
 EXTERNAL 54 
ENDPROC pos ; 
 
INT PROC pos (TEXT CONST source, pattern, INT CONST from) : 
 EXTERNAL 55 
ENDPROC pos ;

INT PROC pos (TEXT CONST source, pattern, INT CONST from, to) :
 EXTERNAL 56 
ENDPROC pos ;
 
INT PROC pos (TEXT CONST source, low, high, INT CONST from) :
 EXTERNAL 58
ENDPROC pos ;

TEXT PROC compress (TEXT CONST text) : 
 
  INT VAR begin, end ;
 
  search first non blank ;
  search last non blank ;
  text buffer := subtext (text, begin, end) ;
  text buffer .
 
search first non blank : 
  begin := 1 ;
  WHILE (text SUB begin) = " " REP
    begin INCR 1
  PER .
 
search last non blank : 
  end := LENGTH text ;
  WHILE (text SUB end) = " " REP
    end DECR 1
  PER .
 
ENDPROC compress ;
 
PROC change (TEXT VAR destination, INT CONST from, to, TEXT CONST new) :
 
  IF LENGTH new = to - from + 1 AND to <= LENGTH destination
    THEN replace (destination, from, new)
    ELSE change via buffer
  FI .

change via buffer :
  text buffer := subtext (destination, 1, from-1) ;
  text buffer CAT new ;
  tail buffer := subtext (destination, to + 1) ;
  text buffer CAT tail buffer ;
  destination := text buffer
 
ENDPROC change ;
 
PROC change (TEXT VAR destination, TEXT CONST old, new) :
 
  INT CONST position := pos (destination, old) ;
  IF position > 0
    THEN change (destination, position, position + LENGTH old -1, new)
  FI
 
ENDPROC change ;
 
PROC change all (TEXT VAR destination, TEXT CONST old, new) :
 
  INT VAR position := pos (destination, old) ;
  IF LENGTH old = LENGTH new
    THEN change by replace
    ELSE change by change
  FI .

change by replace :
  WHILE position > 0 REP
    replace (destination, position, new) ;
    position := pos (destination, old, position + LENGTH new)
  PER .

change by change :
  WHILE position > 0 REP
    change (destination, position, position + LENGTH old - 1 , new) ;
    position := pos (destination, old, position + LENGTH new)
  PER .
 
ENDPROC change all ;
 
PROC delete char (TEXT VAR string, INT CONST delete pos) : 
 
  IF delete pos > 0
    THEN tail buffer := subtext (string, delete pos + 1) ;
         string := subtext (string, 1, delete pos - 1) ;
         string CAT tail buffer
  FI
 
END PROC delete char ; 
 
PROC insert char (TEXT VAR string, TEXT CONST char,
                  INT CONST insert pos) : 
 
  IF insert pos > 0 AND insert pos <= LENGTH string + 1
    THEN tail buffer := subtext (string, insert pos) ;
         string := subtext (string, 1, insert pos - 1) ;
         string CAT char ;
         string CAT tail buffer
  FI
 
END PROC insert char ; 
 
INT PROC heap size :
  EXTERNAL 93
ENDPROC heap size ;

PROC collect heap garbage :
  EXTERNAL 94
ENDPROC collect heap garbage ;

PROC stranalyze (ROW 256 INT CONST table, INT VAR sum, INT CONST max sum,
                 TEXT CONST string, INT VAR index, INT CONST to,
                 INT VAR exit code) :
  EXTERNAL 57
ENDPROC stranalyze ;

(*******************************************************************)
(* lexikographische Vergleiche                                     *)
(* Nach DIN 5007, Abschnitt 1 und Abschnitt 3.2 (Bindestrich)      *)
(* Autor: Rainer Hahn, Jochen Liedtke                              *)
(* Stand: 1.7.4 (Jan. 1985)                                        *)
(*******************************************************************)
LET first umlaut = ""214"" ,
    umlauts      = ""214""215""216""217""218""219""251"" ;

 
TEXT VAR left letter, right letter; 
 
BOOL OP LEXEQUAL (TEXT CONST left, right) : 
 
  compare (left, right) ; 
  left letter = right letter 
 
ENDOP LEXEQUAL ; 
 
BOOL OP LEXGREATER (TEXT CONST left, right) : 
 
  compare (left, right) ; 
  left letter > right letter 
 
ENDOP LEXGREATER ; 
 
BOOL OP LEXGREATEREQUAL (TEXT CONST left, right) : 
 
  compare (left, right) ; 
  left letter >= right letter 
 
ENDOP LEXGREATEREQUAL ; 
 
PROC compare (TEXT CONST left, right) :
 
  to begin of lex relevant text ; 
  REP 
    get left letter ; 
    get right letter 
  UNTIL NOT letter match OR both ended PER . 
 
to begin of lex relevant text : 
  INT VAR 
  left pos  := pos (left, ""65"",""254"", 1) , 
  right pos := pos (right,""65"",""254"", 1) ;
  IF left pos = 0
    THEN left pos := LENGTH left + 1
  FI ;
  IF right pos = 0
    THEN right pos := LENGTH right + 1
  FI .

get left letter :
  left letter := left SUB left pos ;
  left pos INCR 1 .

get right letter :
  right letter := right SUB right pos ;
  right pos INCR 1 .

letter match :
  IF left letter = right letter
    THEN TRUE
    ELSE dine (left, left letter, left pos) ;
         dine (right, right letter, right pos) ;
         IF exactly one letter is double letter
           THEN expand other letter
         FI ;
         left letter = right letter
  FI .

exactly one letter is double letter :
  LENGTH left letter <> LENGTH right letter.

expand other letter :
  IF LENGTH left letter = 1
    THEN left letter CAT (left SUB left pos) ;
         left pos INCR 1
    ELSE right letter CAT (right SUB right pos) ;
         right pos INCR 1
  FI .

both ended : left letter = "" .

ENDPROC compare ;

PROC dine (TEXT CONST string, TEXT VAR char, INT VAR string pos) :

  skip non letter chars ;
  IF is capital letter
    THEN translate to small letter
  ELIF char >= first umlaut
    THEN translate umlaut
  FI .

skip non letter chars :
  WHILE NOT (is letter OR end of string) REP
    char := string SUB string pos ;
    string pos INCR 1
  PER .

translate to small letter :
  char := code (code (char) + 32) .

translate umlaut :
  SELECT pos (umlauts, char) OF
    CASE 1,4 : char := "ae"
    CASE 2,5 : char := "oe"
    CASE 3,6 : char := "ue"
    CASE 7   : char := "ss"
  ENDSELECT .

is capital letter : 
  INT VAR char code := code (char) ;
  65 <= char code AND char code <= 90 .

is letter :
  char code := code (char) OR 32 ;
  (97 <= char code AND char code <= 122)  OR  char code >= 128 .

end of string : char = "" .

ENDPROC dine ;

OP CAT (TEXT VAR result, INT CONST number) :
    result CAT "  ";
    replace (result, LENGTH result DIV 2, number);
END OP CAT;
 
PROC insert int (TEXT VAR result, INT CONST insert pos, number) :
    INT VAR pos := insert pos * 2 - 1; 
    change  (result, pos, pos - 1, "  ");
    replace (result, insert pos, number);
END PROC insert int;
 
PROC delete int (TEXT VAR result, INT CONST delete pos) :
    INT VAR pos := delete pos * 2;
    change  (result, pos - 1, pos, "")
END PROC delete int; 
 
ENDPACKET text ;