packages feed

alex 3.4.0.0 → 3.4.0.1

raw patch · 22 files changed

+290/−461 lines, 22 filesdep ~base

Dependency ranges changed: base

Files

CHANGELOG.md view
@@ -1,3 +1,12 @@+## Changes in 3.4.0.1++ * Address new `x-partial` warning of GHC 9.8.+ * Alex 3.4.0.1 needs GHC 8.0 or higher to build.+   The code it generates is the same as 3.4.0.0, so it will likely work for older GHCs.+ * Tested with GHC 8.0 - 9.8.1.++_Andreas Abel, 2023-10-29_+ ## Changes in 3.4.0.0   * New wrappers to lex strict `Text`:
alex.cabal view
@@ -1,6 +1,6 @@ cabal-version: >= 1.10 name: alex-version: 3.4.0.0+version: 3.4.0.1 -- don't forget updating changelog.md! license: BSD3 license-file: LICENSE@@ -22,8 +22,9 @@ build-type: Simple  tested-with:-        GHC == 9.6.2-        GHC == 9.4.5+        GHC == 9.8.1+        GHC == 9.6.3+        GHC == 9.4.7         GHC == 9.2.8         GHC == 9.0.2         GHC == 8.10.7@@ -32,11 +33,6 @@         GHC == 8.4.4         GHC == 8.2.2         GHC == 8.0.2-        GHC == 7.10.3-        GHC == 7.8.4-        GHC == 7.6.3-        GHC == 7.4.2-        GHC == 7.0.4  data-dir: data/ @@ -104,39 +100,46 @@   hs-source-dirs: src   main-is: Main.hs -  build-depends: base >= 2.1 && < 5-               , array-               , containers-               , directory--  default-language: Haskell98-  default-extensions: CPP-  other-extensions: MagicHash+  build-depends:+      base >= 4.9 && < 5+        -- Data.List.NonEmpty enters `base` at 4.9+    , array+    , containers+    , directory -  ghc-options: -Wall -rtsopts+  default-language:+    Haskell2010+  default-extensions:+    PatternSynonyms+    ScopedTypeVariables+    TupleSections+  other-extensions:+    CPP+    FlexibleContexts+    MagicHash+    NondecreasingIndentation+    OverloadedLists+  ghc-options: -Wall -Wcompat -rtsopts    other-modules:-        AbsSyn-        CharSet-        DFA-        DFAMin-        DFS-        Info-        Map-        NFA-        Output-        Paths_alex-        Parser-        ParseMonad-        Scan-        Set-        Sort-        Util-        UTF8-        Data.Ranged-        Data.Ranged.Boundaries-        Data.Ranged.RangedSet-        Data.Ranged.Ranges+    AbsSyn+    CharSet+    DFA+    DFAMin+    DFS+    Info+    NFA+    Output+    Paths_alex+    Parser+    ParseMonad+    Scan+    Util+    UTF8+    Data.Ranged+    Data.Ranged.Boundaries+    Data.Ranged.RangedSet+    Data.Ranged.Ranges  test-suite tests   type: exitcode-stdio-1.0@@ -144,6 +147,6 @@   -- This line is important as it ensures that the local `exe:alex` component declared above is built before the test-suite component is invoked, as well as making sure that `alex` is made available on $PATH and `$alex_datadir` is set accordingly before invoking `test.hs`   build-tools: alex -  default-language: Haskell98+  default-language: Haskell2010    build-depends: base, process
src/AbsSyn.hs view
@@ -23,16 +23,15 @@   StrType(..)   ) where -import CharSet ( CharSet, Encoding )-import Map ( Map )-import qualified Map hiding ( Map )-import Data.IntMap (IntMap)-import Sort ( nub' )-import Util ( str, nl )--import Data.Maybe ( fromJust )+import CharSet     ( CharSet, Encoding )+import Data.Maybe  ( fromJust )+import Data.Map    ( Map )+import Data.IntMap ( IntMap )+import Util        ( str, nl )+import qualified Data.Map as Map+import qualified Data.Set as Set -infixl 4 :|+infixl 4 :|| infixl 5 :%%  -- -----------------------------------------------------------------------------@@ -200,7 +199,7 @@ -- `RExp' provides an abstract syntax for regular expressions.  `Eps' will -- match empty strings; `Ch p' matches strings containing a single character -- `c' if `p c' is true; `re1 :%% re2' matches a string if `re1' matches one of--- its prefixes and `re2' matches the rest; `re1 :| re2' matches a string if+-- its prefixes and `re2' matches the rest; `re1 :|| re2' matches a string if -- `re1' or `re2' matches it; `Star re', `Plus re' and `Ques re' can be -- expressed in terms of the other operators.  See the definitions of `ARexp' -- for a formal definition of the semantics of these operators.@@ -209,7 +208,7 @@   = Eps            -- ^ Empty.   | Ch CharSet     -- ^ Singleton.   | RExp :%% RExp  -- ^ Sequence.-  | RExp :| RExp   -- ^ Alternative.+  | RExp :|| RExp   -- ^ Alternative.   | Star RExp      -- ^ Zero or more repetitions.   | Plus RExp      -- ^ One  or more repetitions.   | Ques RExp      -- ^ Zero or one  repetitions.@@ -218,7 +217,7 @@   showsPrec _ Eps = showString "()"   showsPrec _ (Ch _) = showString "[..]"   showsPrec _ (l :%% r)  = shows l . shows r-  showsPrec _ (l :| r)  = shows l . ('|':) . shows r+  showsPrec _ (l :|| r)  = shows l . ('|':) . shows r   showsPrec _ (Star r) = shows r . ('*':)   showsPrec _ (Plus r) = shows r . ('+':)   showsPrec _ (Ques r) = shows r . ('?':)@@ -228,7 +227,7 @@ nullable Eps       = True nullable Ch{}      = False nullable (l :%% r) = nullable l && nullable r-nullable (l :|  r) = nullable l || nullable r+nullable (l :||  r) = nullable l || nullable r nullable Star{}    = True nullable (Plus r)  = nullable r nullable Ques{}    = True@@ -264,7 +263,7 @@ arexp Eps = eps_ar arexp (Ch p) = ch_ar p arexp (re :%% re') = arexp re `seq_ar` arexp re'-arexp (re :| re') = arexp re `bar_ar` arexp re'+arexp (re :|| re') = arexp re `bar_ar` arexp re' arexp (Star re) = star_ar (arexp re) arexp (Plus re) = plus_ar (arexp re) arexp (Ques re) = ques_ar (arexp re)@@ -330,10 +329,14 @@          code_map = Map.fromList name_code_pairs -        name_code_pairs = zip (nub' (<=) nms) [1..]+        name_code_pairs = zip nms [1..] -        nms = [nm | RECtx{reCtxStartCodes = scs} <- scannerTokens scan,-                    (nm,_) <- scs, nm /= "0"]+        nms = Set.toAscList . Set.fromList $+                [ nm+                | RECtx{ reCtxStartCodes = scs } <- scannerTokens scan+                , (nm, _) <- scs+                , nm /= "0"+                ]   -- Grab the code fragments for the token actions, and replace them
src/CharSet.hs view
@@ -10,6 +10,8 @@ -- -- ----------------------------------------------------------------------------} +{-# LANGUAGE OverloadedLists #-}+ module CharSet (   setSingleton, @@ -36,19 +38,30 @@   byteSetElem   ) where -import Data.Array-import Data.Ranged-import Data.Word-import Data.Maybe (catMaybes)-import Data.Char (chr,ord)-import UTF8+import           Data.Array         ( Array, array )+import           Data.Char          ( chr, ord )+import           Data.Maybe         ( catMaybes )+import           Data.Word          ( Word8 )+import           Data.List.NonEmpty ( pattern (:|), (<|) )+import qualified Data.List.NonEmpty as List1 +import           UTF8               ( List1, encode )+import           Data.Ranged+  ( Boundary( BoundaryAbove, BoundaryAboveAll, BoundaryBelow, BoundaryBelowAll )+  , DiscreteOrdered, Range( Range ), RSet+  , makeRangedSet+  , rSetDifference, rSetEmpty, rSetHas, rSetNegation, rSetRanges, rSetUnion, rSingleton+  )++-- import Data.Semigroup (sconcat)+-- import qualified Data.Foldable      as Fold+ type Byte = Word8 -- Implementation as functions type CharSet = RSet Char type ByteSet = RSet Byte -- type Utf8Set = RSet [Byte]-type Utf8Range = Span [Byte]+type Utf8Range = Span (List1 Byte)  data Encoding = Latin1 | UTF8               deriving (Eq, Show)@@ -83,16 +96,19 @@ charSetRange :: Char -> Char -> CharSet charSetRange c1 c2 = makeRangedSet [Range (BoundaryBelow c1) (BoundaryAbove c2)] +{-# INLINE bytes #-}+bytes :: [Byte]+bytes = [minBound..maxBound]+ byteSetToArray :: ByteSet -> Array Byte Bool-byteSetToArray set = array (fst (head ass), fst (last ass)) ass-  where ass = [(c,rSetHas set c) | c <- [0..0xff]]+byteSetToArray set = array (minBound, maxBound) [(c, rSetHas set c) | c <- bytes]  byteSetElems :: ByteSet -> [Byte]-byteSetElems set = [c | c <- [0 .. 0xff], rSetHas set c]+byteSetElems set = filter (rSetHas set) bytes  charToRanges :: Encoding -> CharSet -> [Utf8Range] charToRanges Latin1 =-    map (fmap ((: []).fromIntegral.ord)) -- Span [Byte]+    map (fmap ((:| []) . fromIntegral . ord)) -- Span [Byte]   . catMaybes   . fmap (charRangeToCharSpan False)   . rSetRanges@@ -105,20 +121,20 @@   . rSetRanges  -- | Turns a range of characters expressed as a pair of UTF-8 byte sequences into a set of ranges, in which each range of the resulting set is between pairs of sequences of the same length-toUtfRange :: Span [Byte] -> [Span [Byte]]-toUtfRange (Span x y) = fix x y+toUtfRange :: Span (List1 Byte) -> [Span (List1 Byte)]+toUtfRange (Span x y) = List1.toList $ fix x y -fix :: [Byte] -> [Byte] -> [Span [Byte]]+fix :: List1 Byte -> List1 Byte -> List1 (Span (List1 Byte)) fix x y     | length x == length y = [Span x y]-    | length x == 1 = Span x [0x7F] : fix [0xC2,0x80] y-    | length x == 2 = Span x [0xDF,0xBF] : fix [0xE0,0x80,0x80] y-    | length x == 3 = Span x [0xEF,0xBF,0xBF] : fix [0xF0,0x80,0x80,0x80] y+    | length x == 1 = Span x [0x7F] <| fix [0xC2,0x80] y+    | length x == 2 = Span x [0xDF,0xBF] <| fix [0xE0,0x80,0x80] y+    | length x == 3 = Span x [0xEF,0xBF,0xBF] <| fix [0xF0,0x80,0x80,0x80] y     | otherwise = error "fix: incorrect input given"  -byteRangeToBytePair :: Span [Byte] -> ([Byte],[Byte])-byteRangeToBytePair (Span x y) = (x,y)+byteRangeToBytePair :: Span a -> (a, a)+byteRangeToBytePair (Span x y) = (x, y)  data Span a = Span a a -- lower bound inclusive, higher bound exclusive                        -- (SDM: upper bound inclusive, surely?)@@ -143,8 +159,8 @@             BoundaryAboveAll | uni -> chr 0x10ffff                              | otherwise -> chr 0xff -byteRanges :: Encoding -> CharSet -> [([Byte],[Byte])]-byteRanges enc =  fmap byteRangeToBytePair . charToRanges enc+byteRanges :: Encoding -> CharSet -> [(List1 Byte, List1 Byte)]+byteRanges enc = fmap byteRangeToBytePair . charToRanges enc  byteSetRange :: Byte -> Byte -> ByteSet byteSetRange c1 c2 = makeRangedSet [Range (BoundaryBelow c1) (BoundaryAbove c2)]@@ -164,4 +180,3 @@           quoteH (BoundaryBelow a) = "c < " ++ show a           quoteH (BoundaryAboveAll) = "True"           quoteH (BoundaryBelowAll) = "False"-
src/DFA.hs view
@@ -13,18 +13,21 @@ -- -- ----------------------------------------------------------------------------} -module DFA(scanner2dfa) where+module DFA (scanner2dfa) where -import AbsSyn-import qualified Map+import Data.Array    ( (!) )+import Data.Function ( on )+import Data.Maybe    ( fromJust )+ import qualified Data.IntMap as IntMap+import qualified Data.IntSet as IntSet+import qualified Data.Map    as Map+import qualified Data.List   as List++import AbsSyn import NFA-import Sort ( msort, nub' ) import CharSet -import Data.Array ( (!) )-import Data.Maybe ( fromJust )- {-                        Defined in the Scan Module  -- (This section should logically belong to the DFA module but it has been@@ -128,23 +131,20 @@                    | Acc _ _ _ (RightContextRExp s) <- accs ]          outs :: [(ByteSet,SNum)]-        outs =  [ out | s <- ss, out <- nst_outs (nfa!s) ]+        outs =  [ out | s <- ss, out <- nst_outs (nfa ! s) ] -        accs = sort_accs [acc| s<-ss, acc<-nst_accs (nfa!s)]+        accs = sort_accs [ acc | s <- ss, acc <- nst_accs (nfa ! s) ]  -- `sort_accs' sorts a list of accept values into descending order of priority, -- eliminating any elements that follow an unconditional accept value. -sort_accs:: [Accept a] -> [Accept a]-sort_accs accs = foldr chk [] (msort le accs)+sort_accs :: [Accept a] -> [Accept a]+sort_accs accs = foldr chk [] $ List.sortBy (compare `on` accPrio) accs         where         chk acc@(Acc _ _ Nothing NoRightContext) _   = [acc]         chk acc                                  rst = acc:rst -        le (Acc{accPrio = n}) (Acc{accPrio=n'}) = n<=n' -- {------------------------------------------------------------------------------                           State Sets and Partial DFAs ------------------------------------------------------------------------------}@@ -160,19 +160,17 @@  type StateSet = [SNum] -new_pdfa:: Int -> NFA -> DFA StateSet a+new_pdfa :: Int -> NFA -> DFA StateSet a new_pdfa starts nfa- = DFA { dfa_start_states = start_ss,-         dfa_states = Map.empty+ = DFA { dfa_start_states = [ List.sort $ nst_cl $ nfa ! n | n <- [0 .. starts - 1] ]+       , dfa_states       = Map.empty        }- where-        start_ss = [ msort (<=) (nst_cl(nfa!n)) | n <- [0..(starts-1)]]   -- starts is the number of start states  -- constructs the epsilon-closure of a set of NFA states-mk_ss:: NFA -> [SNum] -> StateSet-mk_ss nfa l = nub' (<=) [s'| s<-l, s'<-nst_cl(nfa!s)]+mk_ss :: NFA -> [SNum] -> StateSet+mk_ss nfa l = IntSet.toAscList $ IntSet.fromList [ s' | s <- l, s' <- nst_cl (nfa ! s) ]  add_pdfa:: StateSet -> State StateSet a -> DFA StateSet a -> DFA StateSet a add_pdfa ss pst (DFA st mp) = DFA st (Map.insert ss pst mp)@@ -205,44 +203,3 @@                                 RightContextRExp s ->                                   RightContextRExp (lookup' (mk_ss nfa [s]))                                 other -> other--{----- `mk_st' constructs a state node from the list of accept values and a list of--- transitions.  The transitions list all the valid transitions out of the--- node; all invalid transitions should be represented in the array by state--- -1.  `mk_st' has to work out whether the accept states contain an--- unconditional entry, in which case the first field of `St' should be true,--- and which default state to use in constructing the array (the array may span--- a sub-range of the character set, the state number given the third argument--- of `St' being taken as the default if an input character lies outside the--- range).  The default values is chosen to minimise the bounds of the array--- and so there are two candidates: the value that 0 maps to (in which case--- some initial segment of the array may be omitted) or the value that 255 maps--- to (in which case a final segment of the array may be omitted), hence the--- calculation of `(df,bds)'.------ Note that empty arrays are avoided as they can cause severe problems for--- some popular Haskell compilers.--mk_st:: [Accept Code] -> [(Char,Int)] -> State Code-mk_st accs as =-        if null as-           then St accs (-1) (listArray ('0','0') [-1])-           else St accs df (listArray bds [arr!c| c<-range bds])-        where-        bds = if sz==0 then ('0','0') else bds0--        (sz,df,bds0) | sz1 < sz2 = (sz1,df1,bds1)-                     | otherwise = (sz2,df2,bds2)--        (sz1,df1,bds1) = mk_bds(arr!chr 0)-        (sz2,df2,bds2) = mk_bds(arr!chr 255)--        mk_bds df = (t-b, df, (chr b, chr (255-t)))-                where-                b = length (takeWhile id [arr!c==df| c<-['\0'..'\xff']])-                t = length (takeWhile id [arr!c==df| c<-['\xff','\xfe'..'\0']])--        arr = listArray ('\0','\xff') (take 256 (repeat (-1))) // as--}
src/DFAMin.hs view
@@ -1,21 +1,23 @@ {-# OPTIONS_GHC -fno-warn-name-shadowing #-} -{-# LANGUAGE PatternGuards       #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TupleSections       #-}+{-# LANGUAGE CPP #-}  module DFAMin (minimizeDFA) where  import AbsSyn -import Data.Map (Map)-import qualified Data.Map as Map-import Data.IntSet (IntSet)-import qualified Data.IntSet as IS-import Data.IntMap (IntMap)-import qualified Data.IntMap as IM-import qualified Data.List as List+import Data.IntMap ( IntMap )+import Data.IntSet ( IntSet )+import Data.Map    ( Map )+#if !MIN_VERSION_containers(0,6,0)+import Data.Maybe  ( mapMaybe )+#endif +import qualified Data.Map    as Map+import qualified Data.IntSet as IntSet+import qualified Data.IntMap as IntMap+import qualified Data.List   as List+ -- % Hopcroft's Algorithm for DFA minimization (cut/pasted from Wikipedia): -- % X refines Y into Y1 and Y2 means -- %  Y1 := Y ∩ X@@ -82,7 +84,7 @@       number :: Int -> [EquivalenceClass] -> [(Int, EquivalenceClass)]       number _ [] = []       number n (ss:sss) =-        case filter (`IS.member` ss) starts of+        case filter (`IntSet.member` ss) starts of           []      -> (n,ss) : number (n+1) sss           starts' -> map (,ss) starts' ++ number n sss           -- if one of the states of the minimized DFA corresponds@@ -91,12 +93,12 @@        states :: [(Int, State Int a)]       states = [-                let old_states = map (lookup statemap) (IS.toList equiv)-                    accs = map fix_acc (state_acc (head old_states))+                let old_states = map (lookup statemap) (IntSet.toList equiv)+                    accs = map fix_acc (state_acc (headWithDefault undefined old_states))                            -- accepts should all be the same-                    out  = IM.fromList [ (b, get_new old)+                    out  = IntMap.fromList [ (b, get_new old)                                            | State _ out <- old_states,-                                             (b,old) <- IM.toList out ]+                                             (b,old) <- IntMap.toList out ]                 in (n, State accs out)                | (n, equiv) <- numbered_states                ]@@ -116,7 +118,7 @@        old_to_new :: Map Int Int       old_to_new = Map.fromList [ (s,n) | (n,ss) <- numbered_states,-                                          s <- IS.toList ss ]+                                          s <- IntSet.toList ss ]  type EquivalenceClass = IntSet @@ -129,7 +131,7 @@        where acc (State as _) = not (List.null as)      nonaccepting_states :: EquivalenceClass-    nonaccepting_states = IS.fromList (Map.keys nonaccepting)+    nonaccepting_states = IntSet.fromList (Map.keys nonaccepting)      -- group the accepting states into equivalence classes     accept_map :: Map [Accept a] [Int]@@ -139,11 +141,11 @@              (Map.toList accepting)      accept_groups :: [EquivalenceClass]-    accept_groups = map IS.fromList (Map.elems accept_map)+    accept_groups = map IntSet.fromList (Map.elems accept_map)      init_r, init_q :: [EquivalenceClass]     init_r  -- Issue #71: each EquivalenceClass needs to be a non-empty set-      | IS.null nonaccepting_states = []+      | IntSet.null nonaccepting_states = []       | otherwise                   = [nonaccepting_states]     init_q = accept_groups @@ -155,10 +157,10 @@     -- since a transition function might not be an injective.     -- This is a cache of the information needed to compute xs below     bigmap :: IntMap (IntMap EquivalenceClass)-    bigmap = IM.fromListWith (IM.unionWith IS.union)-                [ (i, IM.singleton to (IS.singleton from))+    bigmap = IntMap.fromListWith (IntMap.unionWith IntSet.union)+                [ (i, IntMap.singleton to (IntSet.singleton from))                 | (from, state) <- Map.toList statemap,-                  (i,to) <- IM.toList (state_out state) ]+                  (i,to) <- IntMap.toList (state_out state) ]      -- The outer loop: recurse on each set in R and Q     go :: [EquivalenceClass] -> [EquivalenceClass] -> [EquivalenceClass]@@ -168,18 +170,18 @@         preimage :: IntMap EquivalenceClass -- inversed transition function                  -> EquivalenceClass        -- subset of codomain of original transition function                  -> EquivalenceClass        -- preimage of given subset-#if MIN_VERSION_containers(0, 6, 0)-        preimage invMap a = IS.unions (IM.restrictKeys invMap a)+#if MIN_VERSION_containers(0,6,0)+        preimage invMap = IntSet.unions . IntMap.restrictKeys invMap #else-        preimage invMap a = IS.unions [IM.findWithDefault IS.empty s invMap | s <- IS.toList a]+        preimage invMap = IntSet.unions . mapMaybe (`IntMap.lookup` invMap) . IntSet.toList #endif          xs :: [EquivalenceClass]         xs =           [ x-          | invMap <- IM.elems bigmap+          | invMap <- IntMap.elems bigmap           , let x = preimage invMap a-          , not (IS.null x)+          , not (IntSet.null x)           ]          refineWith@@ -187,12 +189,12 @@           -> EquivalenceClass -- input equivalence class           -> Maybe (EquivalenceClass, EquivalenceClass) -- refined equivalence class         refineWith x y =-          if IS.null y1 || IS.null y2+          if IntSet.null y1 || IntSet.null y2             then Nothing             else Just (y1, y2)           where-            y1 = IS.intersection y x-            y2 = IS.difference   y x+            y1 = IntSet.intersection y x+            y2 = IntSet.difference   y x          go0 (r,q) x = go1 r [] []           where@@ -201,11 +203,16 @@             go1 (y:r) r' q' = case refineWith x y of               Nothing                       -> go1 r (y:r') q'               Just (y1, y2)-                | IS.size y1 <= IS.size y2  -> go1 r (y2:r') (y1:q')-                | otherwise                 -> go1 r (y1:r') (y2:q')+                | IntSet.size y1 <= IntSet.size y2 -> go1 r (y2:r') (y1:q')+                | otherwise                        -> go1 r (y1:r') (y2:q')              -- iterates over Q             go2 []    q' = q'             go2 (y:q) q' = case refineWith x y of               Nothing       -> go2 q (y:q')               Just (y1, y2) -> go2 q (y1:y2:q')++-- To pacify GHC 9.8's warning about 'head'+headWithDefault :: a -> [a] -> a+headWithDefault a []    = a+headWithDefault _ (a:_) = a
src/DFS.hs view
@@ -23,10 +23,9 @@  module DFS where -import Set ( Set )-import qualified Set hiding ( Set )- import Data.Array ( (!), accumArray, listArray )+import Data.Set   ( Set )+import qualified Data.Set as Set  -- The result of a depth-first search of a graph is a list of trees, -- `GForest'.  `post_order' provides a post-order traversal of a forest.
src/Data/Ranged/RangedSet.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE CPP #-}+ module Data.Ranged.RangedSet (    -- ** Ranged Set Type    RSet,@@ -27,13 +29,11 @@  import Data.Ranged.Boundaries import Data.Ranged.Ranges-#if MIN_VERSION_base(4,9,0) && !MIN_VERSION_base(4,11,0)+#if !MIN_VERSION_base(4,11,0) import Data.Semigroup-#elif !MIN_VERSION_base(4,9,0)-import Data.Monoid #endif -import Data.List hiding (and, null)+import qualified Data.List as List  infixl 7 -/\- infixl 6 -\/-, -!-@@ -44,35 +44,25 @@ newtype DiscreteOrdered v => RSet v = RSet {rSetRanges :: [Range v]}    deriving (Eq, Show, Ord) -#if MIN_VERSION_base(4,9,0) instance DiscreteOrdered a => Semigroup (RSet a) where     (<>) = rSetUnion-#endif  instance DiscreteOrdered a => Monoid (RSet a) where-#if MIN_VERSION_base(4,9,0)+    mempty  = rSetEmpty     mappend = (<>)-#else-    mappend = rSetUnion-#endif-    mempty = rSetEmpty  -- | Determine if the ranges in the list are both in order and non-overlapping. -- If so then they are suitable input for the unsafeRangedSet function. validRangeList :: DiscreteOrdered v => [Range v] -> Bool--validRangeList [] = True-validRangeList [Range lower upper] = lower <= upper-validRangeList rs = and $ zipWith okAdjacent rs (tail rs)-   where-      okAdjacent (Range lower1 upper1) (Range lower2 upper2) =-         lower1 <= upper1 && upper1 <= lower2 && lower2 <= upper2+validRangeList rs = and $+  all (\ (Range lower upper) -> lower <= upper) rs :+  zipWith (\ (Range _ upper1) (Range lower2 _) -> upper1 <= lower2) rs (drop 1 rs)   -- | Rearrange and merge the ranges in the list so that they are in order and -- non-overlapping. normaliseRangeList :: DiscreteOrdered v => [Range v] -> [Range v]-normaliseRangeList = normalise . sort . filter (not . rangeIsEmpty)+normaliseRangeList = normalise . List.sort . filter (not . rangeIsEmpty)   -- Private routine: normalise a range list that is known to be already sorted.
src/Info.hs view
@@ -11,7 +11,7 @@ module Info (infoDFA) where  import AbsSyn-import qualified Map+import qualified Data.Map as Map import qualified Data.IntMap as IntMap import Util 
src/Main.hs view
@@ -1,4 +1,5 @@-{-# LANGUAGE CPP #-}+{-# LANGUAGE NondecreasingIndentation #-}+ -- ----------------------------------------------------------------------------- -- -- Main.hs, part of Alex@@ -15,56 +16,39 @@ import DFAMin import NFA import Info-import Map ( Map )-import qualified Map hiding ( Map ) import Output-import ParseMonad ( runP, Warning(..) )+import ParseMonad            ( runP, Warning(..) ) import Parser import Scan-import Util ( hline )-import Paths_alex ( version, getDataDir )+import Util                  ( hline )+import Paths_alex            ( version, getDataDir ) -#if __GLASGOW_HASKELL__ < 610-import Control.Exception as Exception ( block, unblock, catch, throw )-#endif-#if __GLASGOW_HASKELL__ >= 610-import Control.Exception ( bracketOnError )-#endif-import Control.Monad ( when, liftM )-import Data.Char ( chr )-import Data.List ( isSuffixOf, nub )-import Data.Version ( showVersion )+import Control.Exception     ( bracketOnError )+import Control.Monad         ( when, liftM )+import Data.Char             ( chr )+import Data.List             ( isSuffixOf, nub )+import Data.Map              ( Map )+import Data.Version          ( showVersion ) import System.Console.GetOpt ( getOpt, usageInfo, ArgOrder(..), OptDescr(..), ArgDescr(..) )-import System.Directory ( removeFile )-import System.Environment ( getProgName, getArgs )-import System.Exit ( ExitCode(..), exitWith )-import System.IO ( stderr, Handle, IOMode(..), openFile, hClose, hPutStr, hPutStrLn )-#if __GLASGOW_HASKELL__ >= 612-import System.IO ( hGetContents, hSetEncoding, utf8 )-#endif+import System.Directory      ( removeFile )+import System.Environment    ( getProgName, getArgs )+import System.Exit           ( ExitCode(..), exitWith )+import System.IO             ( stderr, Handle, IOMode(..), openFile, hClose, hPutStr, hPutStrLn+                             , hGetContents, hSetEncoding, utf8 )+import qualified Data.Map    as Map  -- We need to force every file we open to be read in -- as UTF8 alexReadFile :: FilePath -> IO String-#if __GLASGOW_HASKELL__ >= 612-alexReadFile file = do-  h <- alexOpenFile file ReadMode-  hGetContents h-#else-alexReadFile = readFile-#endif+alexReadFile file = hGetContents =<< alexOpenFile file ReadMode  -- We need to force every file we write to be written -- to as UTF8 alexOpenFile :: FilePath -> IOMode -> IO Handle-#if __GLASGOW_HASKELL__ >= 612 alexOpenFile file mode = do   h <- openFile file mode   hSetEncoding h utf8   return h-#else-alexOpenFile = openFile-#endif  -- `main' decodes the command line arguments and calls `alex'. @@ -521,19 +505,3 @@  dieAlex :: String -> IO a dieAlex s = getProgramName >>= \prog -> die (prog ++ ": " ++ s)--#if __GLASGOW_HASKELL__ < 610-bracketOnError-        :: IO a         -- ^ computation to run first (\"acquire resource\")-        -> (a -> IO b)  -- ^ computation to run last (\"release resource\")-        -> (a -> IO c)  -- ^ computation to run in-between-        -> IO c         -- returns the value from the in-between computation-bracketOnError before after thing =-  block (do-    a <- before-    r <- Exception.catch-           (unblock (thing a))-           (\e -> do { after a; throw e })-    return r- )-#endif
− src/Map.hs
@@ -1,68 +0,0 @@-{-# LANGUAGE CPP #-}-module Map (-   Map,-   member, lookup, findWithDefault,-   empty,-   insert, insertWith,-   delete,-   union, unionWith, unions,-   mapWithKey,-   elems,-   fromList, fromListWith,-   toAscList-) where--#if __GLASGOW_HASKELL__ >= 603-import Data.Map-import Prelude ()-#else-import Data.FiniteMap-import Prelude hiding ( lookup )--type Map k a = FiniteMap k a--member :: Ord k => k -> Map k a -> Bool-member = elemFM--lookup :: Ord k => k -> Map k a -> Maybe a-lookup = flip lookupFM--findWithDefault :: Ord k => a -> k -> Map k a -> a-findWithDefault a k m = lookupWithDefaultFM m a k--empty :: Map k a-empty = emptyFM--insert :: Ord k => k -> a -> Map k a -> Map k a-insert k a m = addToFM m k a--insertWith :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a-insertWith c k a m = addToFM_C c m k a--delete :: Ord k => k -> Map k a -> Map k a-delete = flip delFromFM--union :: Ord k => Map k a -> Map k a -> Map k a-union = flip plusFM--unionWith :: Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a-unionWith c l r = plusFM_C c r l--unions :: Ord k => [Map k a] -> Map k a-unions = foldl (flip plusFM) emptyFM--mapWithKey :: (k -> a -> b) -> Map k a -> Map k b-mapWithKey = mapFM--elems :: Map k a -> [a]-elems = eltsFM--fromList :: Ord k => [(k,a)] -> Map k a-fromList = listToFM--fromListWith :: Ord k => (a -> a -> a) -> [(k,a)] -> Map k a-fromListWith c = addListToFM_C (flip c) emptyFM--toAscList :: Map k a -> [(k,a)]-toAscList = fmToList-#endif
src/NFA.hs view
@@ -16,18 +16,17 @@  module NFA where +import Control.Monad ( forM_, zipWithM, zipWithM_, when, liftM, ap )+import Data.Array    ( Array, (!), array, listArray, assocs, bounds )+import Data.Map      ( Map )+import qualified Data.Map as Map+import qualified Data.List.NonEmpty as List1+ import AbsSyn import CharSet-import DFS ( t_close, out )-import Map ( Map )-import qualified Map hiding ( Map )+import DFS  ( t_close, out ) import Util ( str, space ) -#if __GLASGOW_HASKELL__ < 710-import Control.Applicative ( Applicative(..) )-#endif-import Control.Monad ( forM_, zipWithM, zipWithM_, when, liftM, ap )-import Data.Array ( Array, (!), array, listArray, assocs, bounds )  -- Each state of a nondeterministic automaton contains a list of `Accept' -- values, a list of epsilon transitions (an epsilon transition represents a@@ -132,7 +131,7 @@   s <- newState   rexp2nfa b s re1   rexp2nfa s e re2-rexp2nfa b e (re1 :| re2) = do+rexp2nfa b e (re1 :|| re2) = do   rexp2nfa b e re1   rexp2nfa b e re2 rexp2nfa b e (Star re) = do@@ -226,10 +225,8 @@ charEdge from charset to = do   -- trace ("charEdge: " ++ (show $ charset) ++ " => " ++ show (byteRanges charset)) $   e <- getEncoding-  forM_ (byteRanges e charset) $ \(xs,ys) -> do-    bytesEdge from xs ys to--+  forM_ (byteRanges e charset) $ \ (xs, ys) -> do+    bytesEdge from (List1.toList xs) (List1.toList ys) to  byteEdge :: SNum -> ByteSet -> SNum -> NFAM () byteEdge from charset to = N $ \s n _ -> (s, addEdge n, ())@@ -260,7 +257,6 @@            Map.insert state (NSt [new_acc] [] []) n        Just (NSt acc eps trans) ->            Map.insert state (NSt (new_acc:acc) eps trans) n-  rctxt_accept :: Accept Code rctxt_accept = Acc 0 Nothing Nothing NoRightContext
src/Output.hs view
@@ -13,7 +13,7 @@ import AbsSyn import CharSet import Util-import qualified Map+import qualified Data.Map as Map import qualified Data.IntMap as IntMap  import Control.Monad.ST ( ST, runST )@@ -24,7 +24,8 @@ import Data.Maybe (isJust) import Data.Bits import Data.Char ( ord, chr )-import Data.List ( maximumBy, sortBy, groupBy, mapAccumR )+import Data.List ( maximumBy, sortBy, mapAccumR )+import qualified Data.List.NonEmpty as List1  -- ----------------------------------------------------------------------------- -- Printing the output@@ -399,10 +400,10 @@         best_default :: [(Int,SNum)] -> SNum         best_default prod_list            | null sorted = -1-           | otherwise   = snd (head (maximumBy lengths eq))+           | otherwise   = snd (List1.head (maximumBy lengths eq))            where sorted  = sortBy compareSnds prod_list                  compareSnds (_,a) (_,b) = compare a b-                 eq = groupBy (\(_,a) (_,b) -> a == b) sorted+                 eq = List1.groupBy (\(_,a) (_,b) -> a == b) sorted                  lengths  a b = length a `compare` length b          -- remove all the default productions from the DFA@@ -493,18 +494,19 @@                -> [(Int, Int)]                -> ST s Int findFreeOffset off check off_arr state = do-    -- offset 0 isn't allowed++  -- offset 0 isn't allowed   if off == 0 then try_next else do      -- don't use an offset we've used before-  b <- readArray off_arr off-  if b /= 0 then try_next else do+    b <- readArray off_arr off+    if b /= 0 then try_next else do -    -- check whether the actions for this state fit in the table-  ok <- fits off state check-  if ok then return off else try_next- where-        try_next = findFreeOffset (off+1) check off_arr state+      -- check whether the actions for this state fit in the table+      ok <- fits off state check+      if ok then return off else try_next+  where+    try_next = findFreeOffset (off+1) check off_arr state  -- This is an inner loop, so we use some strictness hacks, and avoid -- array bounds checks (unsafeRead instead of readArray) to speed
src/ParseMonad.hs view
@@ -14,17 +14,16 @@         setStartCode, getStartCode, getInput, setInput,  ) where -import AbsSyn hiding ( StartCode )-import CharSet ( CharSet )-import Map ( Map )-import qualified Map hiding ( Map )+import Control.Monad       ( liftM, ap, when )+import Data.Map            ( Map )+import Data.List.NonEmpty  ( pattern (:|) )+import Data.Word           ( Word8 )+import qualified Data.Map as Map++import AbsSyn   hiding ( StartCode )+import CharSet  ( CharSet ) import UTF8 -#if __GLASGOW_HASKELL__ < 710-import Control.Applicative ( Applicative(..) )-#endif-import Control.Monad ( liftM, ap, when )-import Data.Word (Word8) -- ----------------------------------------------------------------------------- -- The input type --import Codec.Binary.UTF8.Light as UTF8@@ -40,18 +39,20 @@ alexInputPrevChar (_,c,_,_) = c  -alexGetChar :: AlexInput -> Maybe (Char,AlexInput)-alexGetChar (_,_,[],[]) = Nothing-alexGetChar (p,_,[],(c:s))  = let p' = alexMove p c in p' `seq`-                                Just (c, (p', c, [], s))-alexGetChar (_, _ ,_ : _, _) = undefined -- hide compiler warning+alexGetChar :: AlexInput -> Maybe (Char, AlexInput)+alexGetChar (_, _, [], [])  = Nothing+alexGetChar (p, _, [], c:s) = p' `seq` Just (c, (p', c, [], s))+  where+    p' = alexMove p c+alexGetChar (_, _ , _:_, _) = undefined -- hide compiler warning -alexGetByte :: AlexInput -> Maybe (Byte,AlexInput)-alexGetByte (p,c,(b:bs),s) = Just (b,(p,c,bs,s))-alexGetByte (_,_,[],[]) = Nothing-alexGetByte (p,_,[],(c:s))  = let p' = alexMove p c-                                  (b:bs) = UTF8.encode c-                              in p' `seq`  Just (b, (p', c, bs, s))+alexGetByte :: AlexInput -> Maybe (Byte, AlexInput)+alexGetByte (p, c, b:bs, s)   = Just (b, (p, c, bs, s))+alexGetByte (_, _, [],   [])  = Nothing+alexGetByte (p, _, [],   c:s) = p' `seq`  Just (b, (p', c, bs, s))+  where+    p' = alexMove p c+    b :| bs = UTF8.encode c  -- ----------------------------------------------------------------------------- -- Token positions
src/Parser.hs view
@@ -724,7 +724,7 @@ 	 =  case happyOut24 happy_x_1 of { (HappyWrap24 happy_var_1) ->  	case happyOut23 happy_x_3 of { (HappyWrap23 happy_var_3) ->  	happyIn23-		 (happy_var_1 :| happy_var_3+		 (happy_var_1 :|| happy_var_3 	)}}  happyReduce_41 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn )
src/Parser.y.boot view
@@ -159,7 +159,7 @@ 	| {- empty -}	{ NoRightContext }  rexp	:: { RExp }-	: alt '|' rexp 			{ $1 :| $3 }+	: alt '|' rexp 			{ $1 :|| $3 } 	| alt		 		{ $1 }  alt	:: { RExp }
src/Scan.hs view
@@ -2,11 +2,18 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-} {-# LINE 13 "src/Scan.x" #-}+{-# LANGUAGE CPP #-}++-- Switch off partiality warning about 'head' and 'tail'+#if __GLASGOW_HASKELL__ >= 908+{-# OPTIONS_GHC -Wno-x-partial #-}+#endif+ module Scan (lexer, AlexPosn(..), Token(..), Tkn(..), tokPosn, multiplicity) where  import Data.Char import ParseMonad---import Debug.Trace+-- import Debug.Trace #if __GLASGOW_HASKELL__ >= 603 #include "ghcconfig.h" #elif defined(__GLASGOW_HASKELL__)@@ -546,7 +553,7 @@         -- match when checking the right context, just         -- the first match will do. #endif-{-# LINE 84 "src/Scan.x" #-}+{-# LINE 91 "src/Scan.x" #-} -- ----------------------------------------------------------------------------- -- Token type @@ -587,7 +594,7 @@ string    (p,_,str) ln = return $ T p (StringT (extract ln str)) bind      (p,_,str) _  = return $ T p (BindT (takeWhile isIdChar str)) escape    (p,_,str) _  = return $ T p (CharT (esc str))-decch     (p,_,str) ln = return $ T p (CharT (do_ech 10 ln (take (ln-1) (tail str))))+decch     (p,_,str) ln = return $ T p (CharT (do_ech 10 ln (take (ln-1) (drop 1 str)))) hexch     (p,_,str) ln = return $ T p (CharT (do_ech 16 ln (take (ln-2) (drop 2 str)))) octch     (p,_,str) ln = return $ T p (CharT (do_ech 8  ln (take (ln-2) (drop 2 str)))) char      (p,_,str) _  = return $ T p (CharT (head str))@@ -607,7 +614,7 @@ isIdChar c = isAlphaNum c || c `elem` "_'"  extract :: Int -> String -> String-extract ln str = take (ln-2) (tail str)+extract ln str = take (ln-2) (drop 1 str)  do_ech :: Int -> Int -> String -> Char do_ech radix _ln str = chr (parseInt radix str)@@ -640,7 +647,7 @@ -- implementing a large chunk of the Haskell lexical syntax).  code :: Action-code (p,_,_inp) _ = do+code (p, _, _inp) _ = do   currentInput <- getInput   go currentInput 1 ""   where@@ -686,10 +693,10 @@  lexError :: String -> P a lexError s = do-  (_,_,_,input) <- getInput-  failP (s ++ (if (not (null input))-                  then " at " ++ show (head input)-                  else " at end of file"))+  (_, _, _, input) <- getInput+  failP $ s ++ " at " ++ case input of+    c:_ -> show c+    []  -> "end of file"  lexer :: (Token -> P a) -> P a lexer cont = lexToken >>= cont
src/Scan.x.boot view
@@ -11,11 +11,18 @@ -------------------------------------------------------------------------------  {+{-# LANGUAGE CPP #-}++-- Switch off partiality warning about 'head' and 'tail'+#if __GLASGOW_HASKELL__ >= 908+{-# OPTIONS_GHC -Wno-x-partial #-}+#endif+ module Scan (lexer, AlexPosn(..), Token(..), Tkn(..), tokPosn, multiplicity) where  import Data.Char import ParseMonad---import Debug.Trace+-- import Debug.Trace }  $digit    = 0-9@@ -123,7 +130,7 @@ string    (p,_,str) ln = return $ T p (StringT (extract ln str)) bind      (p,_,str) _  = return $ T p (BindT (takeWhile isIdChar str)) escape    (p,_,str) _  = return $ T p (CharT (esc str))-decch     (p,_,str) ln = return $ T p (CharT (do_ech 10 ln (take (ln-1) (tail str))))+decch     (p,_,str) ln = return $ T p (CharT (do_ech 10 ln (take (ln-1) (drop 1 str)))) hexch     (p,_,str) ln = return $ T p (CharT (do_ech 16 ln (take (ln-2) (drop 2 str)))) octch     (p,_,str) ln = return $ T p (CharT (do_ech 8  ln (take (ln-2) (drop 2 str)))) char      (p,_,str) _  = return $ T p (CharT (head str))@@ -143,7 +150,7 @@ isIdChar c = isAlphaNum c || c `elem` "_'"  extract :: Int -> String -> String-extract ln str = take (ln-2) (tail str)+extract ln str = take (ln-2) (drop 1 str)  do_ech :: Int -> Int -> String -> Char do_ech radix _ln str = chr (parseInt radix str)@@ -176,7 +183,7 @@ -- implementing a large chunk of the Haskell lexical syntax).  code :: Action-code (p,_,_inp) _ = do+code (p, _, _inp) _ = do   currentInput <- getInput   go currentInput 1 ""   where@@ -222,10 +229,10 @@  lexError :: String -> P a lexError s = do-  (_,_,_,input) <- getInput-  failP (s ++ (if (not (null input))-                  then " at " ++ show (head input)-                  else " at end of file"))+  (_, _, _, input) <- getInput+  failP $ s ++ " at " ++ case input of+    c:_ -> show c+    []  -> "end of file"  lexer :: (Token -> P a) -> P a lexer cont = lexToken >>= cont
− src/Set.hs
@@ -1,15 +0,0 @@-{-# LANGUAGE CPP #-}-module Set ( Set, member, empty, insert ) where--import Data.Set--#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 603-member :: Ord a => a -> Set a -> Bool-member = elementOf--empty  :: Set a-empty = emptySet--insert :: Ord a => a -> Set a -> Set a-insert = flip addToSet-#endif
− src/Sort.hs
@@ -1,58 +0,0 @@-{-------------------------------------------------------------------------------                                 SORTING LISTS--This module provides a properly parameterised merge sort function, complete-with associated functions. It is based on a Bob Buckley's (Bob Buckley-18-AUG-95) coding of Knuth's natural merge sort (see Vol. 2).  It seems to be-fast in the average case; it makes use of natural runs in the data becomming-linear on ordered data; and it completes in worst time O(n.log(n)).  It is-divinely elegant.--`nub'' is an n.log(n) version of `nub' and `group_sort' sorts a list into-strictly ascending order, using a combining function in its arguments to-amalgamate duplicates.--Chris Dornan, 14-Aug-93, 17-Nov-94, 29-Dec-95-------------------------------------------------------------------------------}--module Sort where---- Hide (<=) so that we don't get name shadowing warnings for it-import Prelude hiding ((<=))--msort :: (a->a->Bool) -> [a] -> [a]-msort _    [] = []                    -- (foldb f []) is undefined-msort (<=) xs = foldb (mrg (<=)) (runs (<=) xs)--runs :: (a->a->Bool) -> [a] -> [[a]]-runs (<=) xs0 = foldr op [] xs0-      where-        op z xss@(xs@(x:_):xss') | z<=x      = (z:xs):xss'-                                 | otherwise = [z]:xss-        op z xss                             = [z]:xss--foldb :: (a->a->a) -> [a] -> a-foldb _ [x] = x-foldb f xs0 = foldb f (fold xs0)-      where-        fold (x1:x2:xs) = f x1 x2 : fold xs-        fold xs         = xs--mrg:: (a->a->Bool) -> [a] -> [a] -> [a]-mrg _    [] l = l-mrg _    l@(_:_) [] = l-mrg (<=) l1@(h1:t1) l2@(h2:t2) =-        if h1<=h2-           then h1:mrg (<=) t1 l2-           else h2:mrg (<=) l1 t2---nub':: (a->a->Bool) -> [a] -> [a]-nub' (<=) l = group_sort (<=) const l---group_sort:: (a->a->Bool) -> (a->[a]->b) -> [a] -> [b]-group_sort le cmb l = s_m (msort le l)-        where-        s_m [] = []-        s_m (h:t) = cmb h (takeWhile (`le` h) t):s_m (dropWhile (`le` h) t)
src/UTF8.hs view
@@ -1,9 +1,15 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE OverloadedLists  #-}+ module UTF8 where -import Data.Word-import Data.Bits-import Data.Char+import Data.Word ( Word8 )+import Data.Bits ( (.&.), shiftR )+import Data.Char ( ord ) +import qualified Data.List.NonEmpty as List1+type List1 = List1.NonEmpty+ {- -- Could also be imported: @@ -15,8 +21,8 @@ -}  -- | Encode a Haskell String to a list of Word8 values, in UTF8 format.-encode :: Char -> [Word8]-encode = map fromIntegral . go . ord+encode :: Char -> List1 Word8+encode = fmap fromIntegral . go . ord  where   go oc    | oc <= 0x7f       = [oc]
tests/Makefile view
@@ -32,14 +32,14 @@ GHC_VERSION_WORDS=$(subst ., ,$(GHC_VERSION)) GHC_MAJOR_VERSION=$(word 1,$(GHC_VERSION_WORDS)) GHC_MINOR_VERSION=$(word 2,$(GHC_VERSION_WORDS))+ # Text dependency comes with GHC from 8.4 onwards GHC_SHIPS_WITH_TEXT:=$(shell if [ $(GHC_MAJOR_VERSION) -gt 8 -o $(GHC_MAJOR_VERSION) -ge 8 -a $(GHC_MINOR_VERSION) -ge 4 ]; then echo "yes"; else echo "no"; fi)-# -fwarn-incomplete-uni-patterns only from 7.4-WARNS_FOR_GHC_GTEQ_7_4=-fwarn-incomplete-uni-patterns-WARNS_FOR_GHC_LT_7_4=-fno-warn-lazy-unlifted-bindings-WARNS_DEP_GHC_GTEQ_7_4:=$(shell if [ $(GHC_MAJOR_VERSION) -gt 7 -o $(GHC_MAJOR_VERSION) -ge 7 -a $(GHC_MINOR_VERSION) -ge 4 ]; then echo "$(WARNS_FOR_GHC_GTEQ_7_4)"; else echo "$(WARNS_FOR_GHC_LT_7_4)"; fi) -HC_OPTS=-Wall $(WARNS_DEP_GHC_GTEQ_7_4) -fno-warn-missing-signatures -fno-warn-unused-imports -fno-warn-tabs -Werror+# Turn off x-partial warning (new in GHC 9.8)+WARNS_DEP_GHC_GTEQ_9_8:=$(shell if [ $(GHC_MAJOR_VERSION) -gt 9 -o $(GHC_MAJOR_VERSION) -ge 9 -a $(GHC_MINOR_VERSION) -ge 8 ]; then echo "-Wno-x-partial"; fi)++HC_OPTS=-Wall $(WARNS_DEP_GHC_GTEQ_9_8) -fwarn-incomplete-uni-patterns -fno-warn-missing-signatures -fno-warn-unused-imports -fno-warn-tabs -Werror  .PRECIOUS: %.n.hs %.g.hs %.o %.exe %.bin