@@ -1,13 +1,13 @@
1−{-# LANGUAGE OverloadedStrings #-}
1+{-# LANGUAGE BangPatterns, OverloadedStrings, UnboxedTuples #-}
2module Elm.ModuleName
2module Elm.ModuleName
6 , toFilePath
5 , toFilePath
7 , toHyphenPath
6 , toHyphenPath
11 , Canonical(..)
11 , Canonical(..)
12 , basics, char, string
12 , basics, char, string
13 , maybe, result, list, array, dict, tuple
13 , maybe, result, list, array, dict, tuple
@@ -25,12 +25,17 @@ import Data.Binary (Binary(..))
25import qualified Data.Char as Char
25import qualified Data.Char as Char
26import qualified Data.Name as Name
26import qualified Data.Name as Name
27import qualified Data.Utf8 as Utf8
27import qualified Data.Utf8 as Utf8
28+import Data.Word (Word8)
29+import Foreign.Ptr (Ptr, plusPtr, minusPtr)
28import Prelude hiding (maybe)
30import Prelude hiding (maybe)
29import qualified System.FilePath as FP
31import qualified System.FilePath as FP
31import qualified Elm.Package as Pkg
33import qualified Elm.Package as Pkg
32−import qualified Json.Decode as Decode
34+import qualified Json.Decode as D
33−import qualified Json.Encode as Encode
35+import qualified Json.Encode as E
36+import qualified Parse.Variable as Var
37+import qualified Parse.Primitives as P
38+import Parse.Primitives (Row, Col)
@@ -45,11 +50,6 @@ toChars =
45 Name.toChars
50 Name.toChars
48−toString :: Raw -> Utf8.String
53toFilePath :: Raw -> FilePath
53toFilePath :: Raw -> FilePath
54toFilePath name =
54toFilePath name =
55 map (\c -> if c == '.' then FP.pathSeparator else c) (Name.toChars name)
55 map (\c -> if c == '.' then FP.pathSeparator else c) (Name.toChars name)
@@ -60,38 +60,68 @@ toHyphenPath name =
60 map (\c -> if c == '.' then '-' else c) (Name.toChars name)
60 map (\c -> if c == '.' then '-' else c) (Name.toChars name)
63−fromHyphenPath :: Utf8.String -> Maybe Raw
67− Utf8.split 0x2D {- - -} str
69− if all isGoodChunk chunks
70− then Just (Name.fromUtf8 (Utf8.join 0x2E {- . -} chunks))
78−encode :: Raw -> Encode.Value
67+encode :: Raw -> E.Value
80− Encode.name
69+ E.name
83−decoder :: Decode.Decoder Utf8.String Raw
72+decoder :: D.Decoder (Row, Col) Raw
85− do str <- Decode.string
74+ D.customString parser (,)
86− if all isGoodChunk (Utf8.split 0x2E {- . -} str)
75+
87− then return (Name.fromUtf8 str)
76+
88− else Decode.failure str
91−isGoodChunk :: Utf8.String -> Bool
80+
92−isGoodChunk chunk =
81+parser :: P.Parser (Row, Col) Raw
93− Utf8.startsWithChar Char.isUpper chunk
82+parser =
94− && Utf8.all (\c -> Char.isAlphaNum c || c == '_') chunk
83+ P.Parser $ \(P.State src pos end indent row col) cok _ cerr eerr ->
85+ (# isGood, newPos, newCol #) = chompStart pos end col
87+ if isGood && minusPtr newPos pos < 256 then
88+ let !newState = P.State src newPos end indent row newCol in
89+ cok (Utf8.fromPtr pos newPos) newState
91+ else if col == newCol then
98+chompStart :: Ptr Word8 -> Ptr Word8 -> Col -> (# Bool, Ptr Word8, Col #)
99+chompStart pos end col =
101+ !width = Var.getUpperWidth pos end
104+ (# False, pos, col #)
106+ chompInner (plusPtr pos width) end (col + 1)
109+chompInner :: Ptr Word8 -> Ptr Word8 -> Col -> (# Bool, Ptr Word8, Col #)
110+chompInner pos end col =
112+ (# True, pos, col #)
115+ !word = P.unsafeIndex pos
116+ !width = Var.getInnerWidthHelp pos end word
119+ if word == 0x2E {-.-} then
120+ chompStart (plusPtr pos 1) end (col + 1)
122+ (# True, pos, col #)
124+ chompInner (plusPtr pos width) end (col + 1)
@@ -105,6 +135,7 @@ data Canonical =
108-- INSTANCES
139-- INSTANCES