git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Support 'project' prefix for generated code modules
01be38eAndy Arvanitis
app/Main.hs+35−22
@@ -112,7 +112,8 @@ main = do
112 let command = case cmd of
112 let command = case cmd of
113 Build -> "build"
113 Build -> "build"
114 Run -> "run"
114 Run -> "run"
115+ project <- envVar goproject
115− (_, _, _, p) <- createProcess (proc "go" [command, T.unpack modPrefix <> "/Main"])
116+ (_, _, _, p) <- createProcess (proc "go" [command, T.unpack $ project <> modPrefix <> "/Main"])
116 waitForProcess p
117 waitForProcess p
117 return ()
118 return ()
118
119
@@ -136,8 +137,9 @@ generateCode opts baseOutpath jsonFile = do
136transpile :: [String] -> FilePath -> FilePath -> IO ()
137transpile :: [String] -> FilePath -> FilePath -> IO ()
137transpile opts baseOutpath jsonFile = do
138transpile opts baseOutpath jsonFile = do
138 jsonText <- T.decodeUtf8 <$> B.readFile jsonFile
139 jsonText <- T.decodeUtf8 <$> B.readFile jsonFile
140+ project <- envVar goproject
139 let module' = jsonToModule $ parseJson jsonText
141 let module' = jsonToModule $ parseJson jsonText
140− ((_, foreigns, asts, implHeader, implFooter), _) <- runSupplyT 5 (moduleToIL module' Nothing)
142+ ((_, foreigns, asts, implHeader, implFooter), _) <- runSupplyT 5 (moduleToIL module' project)
141 let mn = moduleNameToIL' $ moduleName module'
143 let mn = moduleNameToIL' $ moduleName module'
142 implementation = prettyPrintIL asts
144 implementation = prettyPrintIL asts
143 outpath = joinPath [baseOutpath, T.unpack mn]
145 outpath = joinPath [baseOutpath, T.unpack mn]
@@ -149,36 +151,44 @@ transpile opts baseOutpath jsonFile = do
149writeSupportFiles :: FilePath -> IO ()
151writeSupportFiles :: FilePath -> IO ()
150writeSupportFiles baseOutpath = do
152writeSupportFiles baseOutpath = do
151 currentDir <- getCurrentDirectory
153 currentDir <- getCurrentDirectory
152− let goModSource = currentDir </> "go.mod"
154+ let outputdir = T.pack $ baseOutpath \\ currentDir
153− goModSourceExists <- doesFileExist goModSource
155+ ffiOutpath = currentDir </> "purescript-native"
154− when (not goModSourceExists) $ do
155− let modText = $(embedFile "support/go.mod.working")
156− subdir = baseOutpath \\ currentDir
157− modText' = T.replace "/$OUTPUT" (T.pack subdir) $ T.decodeUtf8 modText
158− B.writeFile goModSource $ T.encodeUtf8 modText'
159 createDirectoryIfMissing True baseOutpath
156 createDirectoryIfMissing True baseOutpath
160− let goModSource = baseOutpath </> "go.mod"
157+ createDirectoryIfMissing True ffiOutpath
161− goModSourceExists <- doesFileExist goModSource
158+ writeModuleFile outputdir currentDir $(embedFile "support/go.mod.working")
162− when (not goModSourceExists) $ do
163− B.writeFile goModSource $(embedFile "support/go.mod.output")
159+ writeModuleFile outputdir baseOutpath $(embedFile "support/go.mod.output")
164− createDirectoryIfMissing True $ currentDir </> "purescript-native"
160+ writeModuleFile outputdir ffiOutpath $(embedFile "support/go.mod.ffi-loader")
165− let goModSource = currentDir </> "purescript-native" </> "go.mod"
161+ writeLoaderFile ffiOutpath $(embedFile "support/ffi-loader.go")
162+ where
163+ writeModuleFile :: Text -> FilePath -> B.ByteString -> IO ()
164+ writeModuleFile outputdir path modText = do
165+ let goModSource = path </> "go.mod"
166− goModSourceExists <- doesFileExist goModSource
166+ goModSourceExists <- doesFileExist goModSource
167− when (not goModSourceExists) $ do
167+ when (not goModSourceExists) $ do
168+ project <- envVar goproject
169+ let modText' = T.replace "/$OUTPUT/" outputdir $ T.decodeUtf8 modText
170+ modText'' = T.replace "$PROJECT/" project modText'
168− B.writeFile goModSource $(embedFile "support/go.mod.ffi-loader")
171+ B.writeFile goModSource $ T.encodeUtf8 modText''
172+ writeLoaderFile :: FilePath -> B.ByteString -> IO ()
173+ writeLoaderFile ffiOutpath loaderText = do
169− let loaderSource = currentDir </> "purescript-native" </> "ffi_loader.go"
174+ let loaderSource = ffiOutpath </> "ffi_loader.go"
170− loaderSourceExists <- doesFileExist loaderSource
175+ loaderSourceExists <- doesFileExist loaderSource
171− when (not loaderSourceExists) $ do
176+ when (not loaderSourceExists) $ do
172− B.writeFile loaderSource $(embedFile "support/ffi-loader.go")
177+ B.writeFile loaderSource loaderText
173
178
174implFileName :: Text -> FilePath
179implFileName :: Text -> FilePath
175implFileName mn = ((\c -> if c == '.' then '_' else c) <$> T.unpack mn) <> ".go"
180implFileName mn = ((\c -> if c == '.' then '_' else c) <$> T.unpack mn) <> ".go"
176
181
182+envVar :: String -> IO Text
183+envVar var = do
184+ T.pack . maybe "" (<> "/") <$> lookupEnv var
185+
177help :: String
186help :: String
178help = "Usage: psgo OPTIONS COREFN-FILES\n\
187help = "Usage: psgo OPTIONS COREFN-FILES\n\
179 \ PureScript to native (via go) compiler\n\n\
188 \ PureScript to native (via go) compiler\n\n\
180 \Available options:\n\
189 \Available options:\n\
181 \ --help Show this help text\n\n\
190 \ --help Show this help text\n\n\
191+ \ --version Show the version number\n\n\
182 \ --run Run the generated go code directly, without building an\n\
192 \ --run Run the generated go code directly, without building an\n\
183 \ executable\n\
193 \ executable\n\
184 \ --no-build Generate go source files, but do not build an executable\n\
194 \ --no-build Generate go source files, but do not build an executable\n\
@@ -192,6 +202,9 @@ corefn = "corefn.json"
192goSrc :: String
202goSrc :: String
193goSrc = ".go"
203goSrc = ".go"
194
204
205+goproject :: String
206+goproject = "GOPROJECT"
207+
195errorNoCorefnFiles :: IO ()
208errorNoCorefnFiles :: IO ()
196errorNoCorefnFiles = do
209errorNoCorefnFiles = do
197 ioError . userError $ "no compiled purescript '" <> corefn <> "' files found –\n" <>
210 ioError . userError $ "no compiled purescript '" <> corefn <> "' files found –\n" <>
src/CodeGen/IL.hs+3−3
@@ -48,9 +48,9 @@ moduleToIL
48 -- . (Monad m, MonadReader Options m, MonadSupply m, MonadError MultipleErrors m)
48 -- . (Monad m, MonadReader Options m, MonadSupply m, MonadError MultipleErrors m)
49 . (Monad m, MonadSupply m)
49 . (Monad m, MonadSupply m)
50 => Module Ann
50 => Module Ann
51− -> Maybe AST
51+ -> Text
52 -> m (Text, [Text], [AST], Text, Text)
52 -> m (Text, [Text], [AST], Text, Text)
53−moduleToIL (Module _ coms mn _ imps _ foreigns decls) _ =
53+moduleToIL (Module _ coms mn _ imps _ foreigns decls) project =
54 do
54 do
55 let usedNames = concatMap getNames decls
55 let usedNames = concatMap getNames decls
56 let mnLookup = renameImports usedNames imps
56 let mnLookup = renameImports usedNames imps
@@ -62,7 +62,7 @@ moduleToIL (Module _ coms mn _ imps _ foreigns decls) _ =
62 foreigns' = moduleIdentToIL <$> foreigns
62 foreigns' = moduleIdentToIL <$> foreigns
63 interface = interfaceSource modName values foreigns
63 interface = interfaceSource modName values foreigns
64 imports = nub . concat $ importToIL <$> optimized'
64 imports = nub . concat $ importToIL <$> optimized'
65− implHeader = implHeaderSource modName imports ""
65+ implHeader = implHeaderSource modName imports project
66 implFooter = implFooterSource (runModuleName mn) foreigns
66 implFooter = implFooterSource (runModuleName mn) foreigns
67 return $ (interface, foreigns', optimized', implHeader, implFooter)
67 return $ (interface, foreigns', optimized', implHeader, implFooter)
68 where
68 where
src/CodeGen/IL/Printer.hs+3−3
@@ -439,20 +439,20 @@ interfaceSource :: Text -> [(Text,Bool)] -> [Ident] -> Text
439interfaceSource _ _ _ = ""
439interfaceSource _ _ _ = ""
440
440
441implHeaderSource :: Text -> [Text] -> Text -> Text
441implHeaderSource :: Text -> [Text] -> Text -> Text
442−implHeaderSource mn imports _ =
442+implHeaderSource mn imports otherPrefix =
443 let imports' = T.replace "_" "." <$> imports in
443 let imports' = T.replace "_" "." <$> imports in
444 "// Code generated by psgo. DO NOT EDIT.\n\n" <>
444 "// Code generated by psgo. DO NOT EDIT.\n\n" <>
445 "package " <> (if mn == "Main" then "main" else mn) <> "\n\n" <>
445 "package " <> (if mn == "Main" then "main" else mn) <> "\n\n" <>
446 "import . \"" <> runtime <> "\"\n" <>
446 "import . \"" <> runtime <> "\"\n" <>
447 (if mn == "Main"
447 (if mn == "Main"
448− then "import _ \"" <> ffiLoader <> "\"\n"
448+ then "import _ \"" <> otherPrefix <> ffiLoader <> "\"\n"
449 else "\n") <>
449 else "\n") <>
450 "import (\n" <>
450 "import (\n" <>
451 (T.concat $ formatImport <$> imports') <> ")\n\n" <>
451 (T.concat $ formatImport <$> imports') <> ")\n\n" <>
452 "type _ = Any\n\n"
452 "type _ = Any\n\n"
453 where
453 where
454 formatImport :: Text -> Text
454 formatImport :: Text -> Text
455− formatImport s = " \"" <> modPrefix <> "/" <> s <> "\"\n"
455+ formatImport s = " \"" <> otherPrefix <> modPrefix <> "/" <> s <> "\"\n"
456
456
457implFooterSource :: Text -> [Ident] -> Text
457implFooterSource :: Text -> [Ident] -> Text
458implFooterSource mn foreigns =
458implFooterSource mn foreigns =
support/go.mod.ffi-loader+1−1
@@ -1,2 +1,2 @@
1−module purescript-native/ffi-loader
1+module $PROJECT/purescript-native/ffi-loader
2
2
support/go.mod.output+1−1
@@ -1,2 +1,2 @@
1−module purescript-native/output
1+module $PROJECT/purescript-native/output
2
2
support/go.mod.working+2−2
@@ -1,5 +1,5 @@
1module example.com/example
1module example.com/example
2
2
3−replace purescript-native/output => ./$OUTPUT/
3+replace $PROJECT/purescript-native/output => ./$OUTPUT/
4
4
5−replace purescript-native/ffi-loader => ./purescript-native/
5+replace $PROJECT/purescript-native/ffi-loader => ./purescript-native/