on master help sign in
Handle new tokens in kernel code for field renaming

The __jsField tokens will be for local renaming within the file. The __$elmField tokens are for field names that must match the Elm code. By separating these two, we do not unnecessarily crowd the one character [a-zA-Z_] namespace.

commitca0d6e0b6ebeeaecef4d0104c76d90b680e07b34 authorEvan Czaplicki <evancz@users.noreply.github.com> dateWed 19 Jul 2017, 14:17 (9 years ago) parentf71ac0b
4 files changed+89−33
src/AST/Kernel.hs+9−4 src/Generate/JavaScript.hs+4 src/Parse/Kernel.hs+55−18 src/Parse/Primitives.hs+21−11
src/AST/Kernel.hs+9−4
@@ -28,6 +28,7 @@ data Info =
2828data Chunk
2929 = JS BS.ByteString
3030 | Var ModuleName.Raw Text.Text
31+ | Field Text.Text
3132 | Prod Bool
3233
3334
@@ -52,17 +53,21 @@ instance Binary Chunk where
5253 Var home name ->
5354 putWord8 1 >> put home >> put name
5455
56+ Field field ->
57+ putWord8 2 >> put field
58+
5559 Prod True ->
56− putWord8 2
60+ putWord8 3
5761
5862 Prod False ->
59− putWord8 3
63+ putWord8 4
6064
6165 get =
6266 do word <- getWord8
6367 case word of
6468 0 -> liftM JS get
6569 1 -> liftM2 Var get get
66− 2 -> return (Prod True)
67− 3 -> return (Prod False)
70+ 2 -> liftM Field get
71+ 3 -> return (Prod True)
72+ 4 -> return (Prod False)
6873 _ -> error "problem deserializing Parse.Kernel.Chunk"
src/Generate/JavaScript.hs+4
@@ -8,6 +8,7 @@ import qualified Data.List as List
88import qualified Data.Map as Map
99import qualified Data.Set as Set
1010import qualified Data.Text as Text
11+import qualified Data.Text.Encoding as Text
1112import qualified Data.ByteString.Builder as BS
1213
1314import qualified AST.Effects as Effects
@@ -156,6 +157,9 @@ chunkToBuilder builder chunk =
156157 do expr <- JS.global (Var.Global (ModuleName.inCore home) name)
157158 return $ JsBuilder.exprToBuilder expr <> builder
158159
160+ Kernel.Field name ->
161+ return $ Text.encodeUtf8Builder name
162+
159163 Kernel.Prod isProd ->
160164 if isProd then
161165 return "_UNUSED"
src/Parse/Kernel.hs+55−18
@@ -19,6 +19,7 @@ import qualified AST.Kernel as Kernel
1919import qualified AST.Module as Module
2020import qualified AST.Module.Name as Module
2121import Generate.JavaScript.Helpers as Help (toFieldName)
22+import Generate.JavaScript.Variable as Var (intToAscii)
2223import Parse.Helpers (Parser)
2324import qualified Parse.Helpers as Parse
2425import qualified Parse.Module as Parse
@@ -31,18 +32,14 @@ import qualified Reporting.Annotation as A
3132
3233parser :: Parser Kernel.Info
3334parser =
34− do imports <- Parse.kernelHeader
35− let table = Map.unions (map importToTable imports)
36− chunks <- parserHelp table Map.empty []
37− return (Kernel.Info (Map.elems table) chunks)
35+ do header <- Parse.kernelHeader
36+ let imports = Map.unions (map headerToImport header)
37+ chunks <- parserHelp imports Map.empty Map.empty []
38+ return (Kernel.Info (Map.elems imports) chunks)
3839
3940
40−type Enums =
41− Map.Map Word8 (Map.Map Text BS.ByteString)
42−
43−
44−parserHelp :: Table -> Enums -> [Kernel.Chunk] -> Parser [Kernel.Chunk]
45−parserHelp table enums chunks =
41+parserHelp :: Imports -> Enums -> Fields -> [Kernel.Chunk] -> Parser [Kernel.Chunk]
42+parserHelp imports enums fields chunks =
4643 do (javascript, maybeTag) <- Parse.kernelChunk
4744 case maybeTag of
4845 Nothing ->
@@ -51,22 +48,62 @@ parserHelp table enums chunks =
5148 Just tag ->
5249 case tag of
5350 Parse.KernelProd isProd ->
54− parserHelp table enums (Kernel.Prod isProd : Kernel.JS javascript : chunks)
51+ parserHelp imports enums fields (Kernel.Prod isProd : Kernel.JS javascript : chunks)
5552
5653 Parse.KernelImport var ->
57− case Map.lookup var table of
54+ case Map.lookup var imports of
5855 Nothing ->
5956 error ("Bad kernel symbol: " ++ Text.unpack var)
6057
6158 Just (home, name) ->
62− parserHelp table enums (Kernel.Var home name : Kernel.JS javascript : chunks)
59+ parserHelp imports enums fields (Kernel.Var home name : Kernel.JS javascript : chunks)
6360
6461 Parse.KernelEnum n var ->
6562 let
6663 (bytes, newEnums) =
6764 lookupEnum n var enums
6865 in
69− parserHelp table newEnums (Kernel.JS bytes : Kernel.JS javascript : chunks)
66+ parserHelp imports newEnums fields (Kernel.JS bytes : Kernel.JS javascript : chunks)
67+
68+ Parse.KernelElmField name ->
69+ parserHelp imports enums fields (Kernel.Field name : Kernel.JS javascript : chunks)
70+
71+ Parse.KernelJsField name ->
72+ let
73+ (bytes, newFields) =
74+ lookupField name fields
75+ in
76+ parserHelp imports enums newFields (Kernel.JS bytes : Kernel.JS javascript : chunks)
77+
78+
79+
80+-- FIELDS
81+
82+
83+type Fields =
84+ Map.Map Text BS.ByteString
85+
86+
87+lookupField :: Text -> Fields -> (BS.ByteString, Fields)
88+lookupField longName fields =
89+ case Map.lookup longName fields of
90+ Just bytes ->
91+ ( bytes, fields )
92+
93+ Nothing ->
94+ let
95+ shortName =
96+ Var.intToAscii (Map.size fields)
97+ in
98+ ( shortName, Map.insert longName shortName fields )
99+
100+
101+
102+-- ENUMS
103+
104+
105+type Enums =
106+ Map.Map Word8 (Map.Map Text BS.ByteString)
70107
71108
72109lookupEnum :: Word8 -> Text -> Enums -> (BS.ByteString, Enums)
@@ -88,15 +125,15 @@ lookupEnum word var allEnums =
88125
89126
90127
91−-- SYMBOL TABLE
128+-- IMPORTS
92129
93130
94−type Table =
131+type Imports =
95132 Map.Map Text (Module.Raw, Text)
96133
97134
98−importToTable :: Module.UserImport -> Table
99−importToTable (A.A _ ( A.A _ fullName, Module.ImportMethod maybeAlias exposed )) =
135+headerToImport :: Module.UserImport -> Imports
136+headerToImport (A.A _ ( A.A _ fullName, Module.ImportMethod maybeAlias exposed )) =
100137 let
101138 shortName =
102139 case maybeAlias of
src/Parse/Primitives.hs+21−11
@@ -1311,6 +1311,8 @@ data ChunkTag
13111311 = KernelEnum Word8 Text
13121312 | KernelProd Bool
13131313 | KernelImport Text
1314+ | KernelJsField Text
1315+ | KernelElmField Text
13141316
13151317
13161318kernelChunk :: Parser (BS.ByteString, Maybe ChunkTag)
@@ -1355,22 +1357,30 @@ chompChunkTag :: Text.Array -> Int -> Int -> Int -> Int -> Int -> (# Maybe Chunk
13551357chompChunkTag array jsOffset offset length row col =
13561358 let
13571359 (# newOffset, newLength, newCol #) =
1358− varPrimHelp array offset length col
1360+ varPrimHelp array (offset + 1) (length - 1) (col + 1)
13591361
13601362 !word =
13611363 Text.unsafeIndex array offset
13621364
1363− !kernelSymbol =
1364− Text.Text array offset (newOffset - offset)
1365−
13661365 !chunkTag =
1367− if isDigit word then
1368− KernelEnum (fromIntegral (word - 0x0030 {- 0 -})) kernelSymbol
1369− else if kernelSymbol == "DEV" then
1370− KernelProd False
1371− else if kernelSymbol == "PROD" then
1372− KernelProd True
1366+ if word == 0x0024 {- $ -} then
1367+ KernelElmField (Text.Text array (offset + 1) (newOffset - offset - 1))
1368+
13731369 else
1374− KernelImport kernelSymbol
1370+ let !chunk = Text.Text array offset (newOffset - offset) in
1371+ if isDigit word then
1372+ KernelEnum (fromIntegral (word - 0x0030 {- 0 -})) chunk
1373+
1374+ else if 0x0061 {- a -} <= word && word <= 0x007A {- z -} then
1375+ KernelJsField chunk
1376+
1377+ else if chunk == "DEV" then
1378+ KernelProd False
1379+
1380+ else if chunk == "PROD" then
1381+ KernelProd True
1382+
1383+ else
1384+ KernelImport chunk
13751385 in
13761386 (# Just chunkTag, jsOffset, newOffset, newLength, row, newCol #)