Copyright (C) 1994, Digital Equipment Corp.
NOTE: This is a quick and dirty implementation. Please rewrite me to avoid all the allocations.
MODULE; IMPORT Rd, Thread, FloatMode, Lex, Text, TextRd, TextF, Word; <*FATAL Rd.Failure, Thread.Alerted*> PROCEDURE Scan ScanWord (txt: TEXT): Rd.T RAISES {Lex.Error} = (* Ensure that "txt" contains exactly on non-blank substring, and return its span [start..stop) *) VAR len := LAST (txt^); x := 0; start, stop: INTEGER; BEGIN (* skip leading white space *) WHILE (x < len) AND (txt[x] IN Lex.Blanks) DO INC (x); END; start := x; (* skip the non-blank word *) WHILE (x < len) AND (NOT txt[x] IN Lex.Blanks) DO INC (x); END; stop := x; (* verify that the rest of the string is blank *) WHILE (x < len) DO IF (NOT txt[x] IN Lex.Blanks) THEN RAISE Lex.Error; END; INC (x); END; RETURN TextRd.New (Text.Sub (txt, start, stop-start)); END ScanWord; PROCEDUREBool (txt: TEXT): BOOLEAN RAISES {Lex.Error} = VAR rd := ScanWord(txt); res := Lex.Bool(rd); BEGIN IF NOT Rd.EOF(rd) THEN RAISE Lex.Error END; RETURN res END Bool; PROCEDUREInt (txt: TEXT; defaultBase: [2..16]): INTEGER RAISES {Lex.Error, FloatMode.Trap} = VAR rd := ScanWord(txt); res := Lex.Int(rd, defaultBase); BEGIN IF NOT Rd.EOF(rd) THEN RAISE Lex.Error END; RETURN res END Int; PROCEDUREUnsigned (txt: TEXT; defaultBase: [2..16]): Word.T RAISES {Lex.Error, FloatMode.Trap} = VAR rd := ScanWord(txt); res := Lex.Unsigned(rd, defaultBase); BEGIN IF NOT Rd.EOF(rd) THEN RAISE Lex.Error END; RETURN res END Unsigned; PROCEDUREReal (txt: TEXT): REAL RAISES {Lex.Error, FloatMode.Trap} = VAR rd := ScanWord(txt); res := Lex.Real(rd); BEGIN IF NOT Rd.EOF(rd) THEN RAISE Lex.Error END; RETURN res END Real; PROCEDURELongReal (txt: TEXT): LONGREAL RAISES {Lex.Error, FloatMode.Trap} = VAR rd := ScanWord(txt); res := Lex.LongReal(rd); BEGIN IF NOT Rd.EOF(rd) THEN RAISE Lex.Error END; RETURN res END LongReal; PROCEDUREExtended (txt: TEXT): EXTENDED RAISES {Lex.Error, FloatMode.Trap} = VAR rd := ScanWord(txt); res := Lex.Extended(rd); BEGIN IF NOT Rd.EOF(rd) THEN RAISE Lex.Error END; RETURN res END Extended; BEGIN END Scan.