Skip to content

Commit b22b51c

Browse files
committed
Support shebangs
1 parent 70c6218 commit b22b51c

File tree

2 files changed

+27
-8
lines changed

2 files changed

+27
-8
lines changed

Hell.hs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,10 @@ commandParser =
101101
dispatch :: Command -> IO ()
102102
dispatch Version = putStrLn "2023-12-12"
103103
dispatch (Run filePath) = do
104-
string <- readFile filePath
105-
case HSE.parseModuleWithMode HSE.defaultParseMode { HSE.extensions = HSE.extensions HSE.defaultParseMode ++ [HSE.EnableExtension HSE.PatternSignatures, HSE.EnableExtension HSE.BlockArguments, HSE.EnableExtension HSE.TypeApplications] } string >>= parseModule of
106-
HSE.ParseFailed _ e -> error $ e
107-
HSE.ParseOk binds
104+
result <- parseFile filePath
105+
case result of
106+
Left e -> error $ e
107+
Right binds
108108
| anyCycles binds -> error "Cyclic bindings are not supported!"
109109
| otherwise ->
110110
case desugarAll binds of
@@ -126,10 +126,10 @@ dispatch (Run filePath) = do
126126
in action
127127
Nothing -> error $ "Type isn't IO (), but: " ++ show t
128128
dispatch (Check filePath) = do
129-
string <- readFile filePath
130-
case HSE.parseModuleWithMode HSE.defaultParseMode { HSE.extensions = HSE.extensions HSE.defaultParseMode ++ [HSE.EnableExtension HSE.PatternSignatures, HSE.EnableExtension HSE.BlockArguments, HSE.EnableExtension HSE.TypeApplications] } string >>= parseModule of
131-
HSE.ParseFailed _ e -> error $ e
132-
HSE.ParseOk binds
129+
result <- parseFile filePath
130+
case result of
131+
Left e -> error $ e
132+
Right binds
133133
| anyCycles binds -> error "Cyclic bindings are not supported!"
134134
| otherwise ->
135135
case desugarAll binds of
@@ -1171,3 +1171,21 @@ zonk = \case
11711171
ICon c -> pure $ ICon c
11721172
IFun a b -> IFun <$> zonk a <*> zonk b
11731173
IApp a b -> IApp <$> zonk a <*> zonk b
1174+
1175+
--------------------------------------------------------------------------------
1176+
-- Parse with #!/shebangs
1177+
1178+
-- Parse a file into a list of decls, but strip shebangs.
1179+
parseFile :: String -> IO (Either String [(String, HSE.Exp HSE.SrcSpanInfo)])
1180+
parseFile filePath = do
1181+
string <- ByteString.readFile filePath
1182+
pure $ case HSE.parseModuleWithMode HSE.defaultParseMode { HSE.extensions = HSE.extensions HSE.defaultParseMode ++ [HSE.EnableExtension HSE.PatternSignatures, HSE.EnableExtension HSE.BlockArguments, HSE.EnableExtension HSE.TypeApplications] } (Text.unpack (dropShebang (Text.decodeUtf8 string))) >>= parseModule of
1183+
HSE.ParseFailed _ e -> Left e
1184+
HSE.ParseOk binds -> Right binds
1185+
1186+
-- This should be quite efficient because it's essentially a pointer
1187+
-- increase. It leaves the \n so that line numbers are in tact.
1188+
dropShebang :: Text -> Text
1189+
dropShebang t = Maybe.fromMaybe t do
1190+
rest <- Text.stripPrefix "#!" t
1191+
pure $ Text.dropWhile (/= '\n') rest

examples/01-hello-world.hell

100644100755
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
#!/usr/bin/env hell
12
main = Text.putStrLn "Hello, World!"

0 commit comments

Comments
 (0)