packages feed

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}