-- file MesaScanner.mesa
-- last edit by Russ Atkinson, February 9, 1982 10:42 am

DIRECTORY
  Rope: TYPE
    USING [ROPE];

MesaScanner: DEFINITIONS
  = BEGIN OPEN Rope;

  TokenKind: TYPE =
    {tokenERROR, --	token.msg describes the scanning error
     tokenID, --		an identifier or reserved word
     tokenINT, --		an INT literal
     tokenREAL, --		a REAL literal
     tokenROPE, --		a ROPE literal
     tokenCHAR, --		a CHAR literal
     tokenATOM, --	an ATOM literal
     tokenSINGLE, --	a single-character token
     tokenDOUBLE, --	a double-character token
     tokenCOMMENT, --	a comment
     tokenEOF}; --		the end-of-file marker

  Token: TYPE = RECORD
    [start: INT, next: INT, kind: TokenKind, msg: ROPE];
    -- start gives the 1st char pos of the token
    -- next gives the char pos immediately after the token
    -- (length = next - size)
    -- msg # NIL only for kind = tokenERROR

  GetProcType: TYPE = PROC [index: INT] RETURNS [CHAR];
    -- type of user proc used to get characters
    -- NUL should be returned to indicate fetch beyond end
    -- ability to randomly access characters is assumed
  
  GetToken: PROC
       [get: GetProcType, index: INT]
       RETURNS [token: Token];
    -- gets a token given a character source and a starting position
    -- the current errors (in token.msg) are:
    --   "invalid escape code"
    --   "invalid octal constant"
    --   "invalid character code"
    --   "end-of-file in string literal"
    --   "invalid atom"
    --   "invalid character"

  RealFromToken: PROC
    [get: GetProcType, token: Token] RETURNS [REAL];
    -- takes a Token into a REAL (parses the literal)
    -- signals WrongKind if token.kind # tokenREAL
    -- other errors may be propagated from Real.ReadReal

  IntFromToken: PROC
    [get: GetProcType, token: Token] RETURNS [INT];
    -- takes a Token into a INT (parses the literal)
    -- error WrongKind if token.kind # tokenINT
    -- error IntegerOverflow if decimal and number > LAST[INT]
    -- error IntegerOverflow if octal and number > LAST[LONG CARDINAL]

  CharFromToken: PROC
    [get: GetProcType, token: Token] RETURNS [CHAR];
    -- takes a Token into a CHAR (parses the literal)
    -- signals WrongKind if token.kind # tokenCHAR

  RopeFromToken: PROC
    [get: GetProcType, token: Token] RETURNS [ROPE];
    -- takes a Token into a ROPE (parses the literal)
    -- signals WrongKind if token.kind # tokenROPE

  AtomFromToken: PROC
    [get: GetProcType, token: Token] RETURNS [ATOM];
    -- takes a Token into a ATOM (parses the literal)
    -- signals WrongKind if token.kind # tokenATOM

  ContentsFromToken: PROC
    [get: GetProcType, token: Token] RETURNS [ROPE];
    -- gets the contents of the token as a ROPE
    -- can be used on any token

  WrongKind: ERROR;
    -- raised when attempting to parse the wrong kind of literal

  IntegerOverflow: ERROR;
    -- raised when attempting to parse an excessive integer

  END.