@@ -1,3 +1,5 @@
1+{-# OPTIONS_GHC -Wall #-}
2+{-# LANGUAGE BangPatterns, UnboxedTuples #-}
1module Elm.Version
3module Elm.Version
2 ( Version(..)
4 ( Version(..)
@@ -7,10 +9,11 @@ module Elm.Version
7 , bumpMinor
9 , bumpMinor
8 , bumpMajor
10 , bumpMajor
@@ -18,13 +21,15 @@ module Elm.Version
18import Prelude hiding (max)
21import Prelude hiding (max)
19import Control.Monad (liftM3)
22import Control.Monad (liftM3)
20import Data.Binary (Binary, get, put, getWord8, putWord8)
23import Data.Binary (Binary, get, put, getWord8, putWord8)
21−import qualified Data.Utf8 as Utf8
22import qualified Data.Version as Version
24import qualified Data.Version as Version
23−import Data.Word (Word16)
25+import Data.Word (Word8, Word16)
26+import Foreign.Ptr (Ptr, plusPtr, minusPtr)
24import qualified Paths_elm
27import qualified Paths_elm
26import qualified Json.Decode as D
29import qualified Json.Decode as D
27import qualified Json.Encode as E
30import qualified Json.Encode as E
31+import qualified Parse.Primitives as P
32+import Parse.Primitives (Row, Col)
@@ -86,58 +91,26 @@ bumpMajor (Version major _minor _patch) =
89−-- TO STRING
94+-- TO CHARS
92−toChars :: Version -> String
97+toChars :: Version -> [Char]
94− Utf8.toChars (toString vsn)
97−toString :: Version -> Utf8.String
98−toString (Version major minor patch) =
98+toChars (Version major minor patch) =
99− Utf8.join 0x2E {- . -}
99+ show major ++ '.' : show minor ++ '.' : show patch
100− [ Utf8.fromWord16 major
101− , Utf8.fromWord16 minor
102− , Utf8.fromWord16 patch
110−fromString :: Utf8.String -> Maybe Version
112− case Utf8.split 0x2E {- . -} str of
113− [major, minor, patch] ->
115− <$> Utf8.toWord16 major
116− <*> Utf8.toWord16 minor
117− <*> Utf8.toWord16 patch
127−decoder :: D.Decoder Utf8.String Version
106+decoder :: D.Decoder (Row, Col) Version
129− do str <- D.string
108+ D.customString parser (,)
130− case fromString str of
138encode :: Version -> E.Value
111encode :: Version -> E.Value
139encode version =
112encode version =
140− E.string (toString version)
113+ E.chars (toChars version)
@@ -164,3 +137,60 @@ instance Binary Version where
164 put major
137 put major
165 put minor
138 put minor
166 put patch
139 put patch
146+parser :: P.Parser (Row, Col) Version
148+ do major <- numberParser
149+ P.word1 0x2E {-.-} (,)
150+ minor <- numberParser
151+ P.word1 0x2E {-.-} (,)
152+ patch <- numberParser
153+ return (Version major minor patch)
156+numberParser :: P.Parser (Row, Col) Word16
158+ P.Parser $ \(P.State src pos end indent row col) cok _ _ eerr ->
162+ let !word = P.unsafeIndex pos in
163+ if word == 0x30 {-0-} then
166+ !newState = P.State src (plusPtr pos 1) end indent row (col + 1)
170+ else if isDigit word then
173+ (# total, newPos #) = chompWord16 (plusPtr pos 1) end (fromIntegral (word - 0x30))
174+ !newState = P.State src newPos end indent row (col + fromIntegral (minusPtr newPos pos))
182+chompWord16 :: Ptr Word8 -> Ptr Word8 -> Word16 -> (# Word16, Ptr Word8 #)
183+chompWord16 pos end total =
187+ let !word = P.unsafeIndex pos in
188+ if isDigit word then
189+ chompWord16 (plusPtr pos 1) end (10 * total + fromIntegral (word - 0x30))
194+isDigit :: Word8 -> Bool
196+ 0x30 {-0-} <= word && word <= 0x39 {-9-}