Lexical

Plain source file: Lexical.hs (Nov 30, 2000)

Lexical is imported by: Import, Main, Parse, ParseI, ParseLex, ParseLib, PreImport.

module Lexical(lexical,lexicalCont,Lex{-,PackedString-}
                ,LexState(..),PosToken(..),PosTokenPre(..),Pos(..)) where

import Extra(Pos(..),toPos,strPos)
import Lex
import LexPre
import PackedString(PackedString,packString,unpackPS)
import TokenId

type PosToken = (Pos,Lex, LexState, [PosTokenPre])
type LexState = [Int]

-- 0 : no active indentation (explicit layout)

lexical :: Bool -> [Char] -> [Char] -> [PosToken]
lexical u file l = iLex [0] 0 (beginning (lexPre u file' l))
  where
    file' = packString file
    beginning toks =
       case toks of
           lp@((f,r,c,L_module):_)    ->  lp
           lp@((f,r,c,L_interface):_) ->  lp
           (lp@(f,r,c,L_LANNOT):rest) ->  lp: discard_pragma rest
           lp                         ->  ((file',1,0,L_module)
                                          :(file',1,0,L_ACONID tMain)
                                          :(file',1,0,L_where)
                                          :lp)
    discard_pragma (lp@(f,r,c,L_RANNOT):rest) = lp: beginning rest
    discard_pragma (lp@(f,r,c,_):rest)        = lp: discard_pragma rest

lexicalCont :: PosToken -> Either String [PosToken]
lexicalCont (p,t,(i:s@(i':_)),r) =
                if i > 0
                then -- Right ((p,t,s,r) : iLex s i' r) -- not correct?
                     case r of
                       ((f,_,_,_):_) -> Right (piLex f s i' p t r)
                else Left "Layout }"
lexicalCont (p,t, []  ,r) = 
                Left "Layout }"

---  local

iLex s i [] = []
iLex s i ((f,r,c,t):pt) = 
  seq p $
  if c > i then
    piLex f s i p t pt
  else if c == i && i /= 0 && t /= L_in then
    (p,L_SEMI',s,pt) : piLex f s i p t pt
  else if c == 0 && i == 0 then
    piLex f s i p t pt
  else
    (p,L_RCURL',s,pt) : iLex s' i' ((f,r,c,t):pt)
  where
    (_:s'@(i':_)) = s
    p = toPos r c

piLex :: PackedString -> LexState -> Int -> Pos -> Lex -> [PosTokenPre] -> [PosToken]
piLex file s i p tok tr@((f,r,c,t'):pt)
      | tok `elem` [L_let, L_where, L_of, L_do] =
          (p,tok,s,tr)
          : if t' == L_LCURL then
                let p' = toPos r c in seq p' (p',L_LCURL, s,pt)
                : iLex (0:s) 0 pt 
            else
                (p, L_LCURL',s,tr)
                : if c > i then
                    let p' = toPos r c in seq p' $ piLex f (c:s) c p' t' pt
                  else
                    (p, L_RCURL',s,tr)
                    : iLex s i tr
piLex file s i p L_LCURL  pt =
          (p,L_LCURL,s,pt)
          : iLex (0:s) 0 pt
piLex file s i p L_RCURL  pt = 
      if i == 0
      then case s of 
             (_:s'@(i':_)) -> (p,L_RCURL,s,pt) : iLex s' i' pt
             _             -> failPos file p "Unbalanced '}' (Stack empty)."
      else failPos file p "Unbalanced '}' (No explicit '{' in scope)"
piLex file s i p t pt  =
          (p,t,s,pt)
          : iLex s i pt


failPos file p msg = error ("Internal in " ++ unpackPS file ++ " at " ++ strPos p ++ ": " ++ msg ++ "\n")

Index

(HTML for this module was generated on May 15, 2003. About the conversion tool.)