curry-base-0.2.9: Curry/Base/Position.lhs
> {-# LANGUAGE DeriveDataTypeable #-}
% -*- LaTeX -*-
% $Id: Position.lhs,v 1.2 2000/10/08 09:55:43 lux Exp $
%
% $Log: Position.lhs,v $
% Revision 1.2 2000/10/08 09:55:43 lux
% Column numbers now start at 1. If the column number is less than 1 it
% will not be shown.
%
% Revision 1.1 2000/07/23 11:03:37 lux
% Positions now implemented in a separate module.
%
%
\nwfilename{Position.lhs}
\section{Positions}
A source file position consists of a filename, a line number, and a
column number. A tab stop is assumed at every eighth column.
\begin{verbatim}
> module Curry.Base.Position where
> import Data.Generics
> -- | A pointer to the origin
> newtype SrcRef = SrcRef [Int] deriving (Data,Typeable)
-- the instances for standard classes or such that SrcRefs are invisible
> instance Show SrcRef where show _ = ""
> instance Read SrcRef where readsPrec _ s = [(noRef,s)]
> instance Eq SrcRef where _ == _ = True
> instance Ord SrcRef where compare _ _ = EQ
> -- | The empty source code reference
> noRef :: SrcRef
> noRef = SrcRef []
> -- | Increment a source code reference by a given number
> incSrcRef :: SrcRef -> Int -> SrcRef
> incSrcRef (SrcRef [i]) j = SrcRef [i+j]
> incSrcRef is _ = error $
> "internal error; increment source ref: " ++ show is
> -- | Source code positions
> data Position
> -- | Normal source code position
> = Position
> { file :: FilePath -- ^ 'FilePath' of the source file
> , line :: Int -- ^ line number, beginning at 1
> , column :: Int -- ^ column number, beginning at 1
> , astRef :: SrcRef -- ^ reference to the abstract syntax tree
> }
> -- | Position in the abstract syntax tree
> | AST
> { astRef :: SrcRef -- ^ reference to the abstract syntax tree
> }
> -- | no position
> | NoPos
> deriving (Eq, Ord,Data,Typeable)
> -- | Increment the position in the abstract syntax tree
> incPosition :: Position -> Int -> Position
> incPosition NoPos _ = NoPos
> incPosition p j = p { astRef = incSrcRef (astRef p) j }
> instance Read Position where
> readsPrec p s =
> [ (Position{file="",line=i,column=j,astRef=noRef},s') |
> ((i,j),s') <- readsPrec p s]
> instance Show Position where
> showsPrec _ Position{file=fn,line=l,column=c} =
> (if null fn then id else shows fn . showString ", ") .
> showString "line " . shows l .
> (if c > 0 then showChar '.' . shows c else id)
> showsPrec _ AST{} = id
> showsPrec _ NoPos = id
> -- | Number of spaces for a tabulator
> tabWidth :: Int
> tabWidth = 8
> -- | Absolute first position of a file
> first :: FilePath -> Position
> first fn = Position fn 1 1 noRef
> -- | Increment a position by a number of columns
> incr :: Position -> Int -> Position
> incr p@Position{column=c} n = p{column=c + n}
> incr p _ = p
> -- | Next position to the right
> next :: Position -> Position
> next = flip incr 1
> -- | First position after the next tabulator
> tab :: Position -> Position
> tab p@Position{column=c} = p{column=c + tabWidth - (c - 1) `mod` tabWidth}
> tab p = p
> -- | First position of the next line
> nl :: Position -> Position
> nl p@Position{line=l} = p{line=l + 1, column=1}
> nl p = p
> -- | Show the line and column of the 'Position'
> showLine :: Position -> String
> showLine NoPos = ""
> showLine AST{} = ""
> showLine Position{line=l,column=c}
> = "(line " ++ show l ++ "." ++ show c ++ ") "
> -- | Type class for data type containing source code references
> class SrcRefOf a where
> -- | Retrieve all 'SrcRef's
> srcRefsOf :: a -> [SrcRef]
> srcRefsOf = (:[]) . srcRefOf
> -- | Retrieve the first 'SrcRef'
> srcRefOf :: a -> SrcRef
> srcRefOf = head . srcRefsOf
> instance SrcRefOf Position where
> srcRefOf NoPos = noRef
> srcRefOf x = astRef x
\end{verbatim}