diff options
author | Joe Crayne <joe@jerkface.net> | 2019-03-18 17:28:38 -0400 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2019-03-18 17:28:38 -0400 |
commit | d7c3ede006e7a767bf5906e908d40caaa2951d4b (patch) | |
tree | cfc457867c01d5c482c35d1f24f00a3807cb112a | |
parent | 5ea1ee91c2ad1db38ada2590f30dc0ea4ed6ef29 (diff) |
Handle function calls and address-of operator.
-rw-r--r-- | monkeypatch.hs | 121 |
1 files changed, 86 insertions, 35 deletions
diff --git a/monkeypatch.hs b/monkeypatch.hs index 9060c3e..beaa58f 100644 --- a/monkeypatch.hs +++ b/monkeypatch.hs | |||
@@ -146,31 +146,6 @@ data Computation st = Computation | |||
146 | } | 146 | } |
147 | deriving (Eq,Ord,Functor) | 147 | deriving (Eq,Ord,Functor) |
148 | 148 | ||
149 | {- | ||
150 | CUnary CAdrOp (CVar _) LT) LT | ||
151 | -} | ||
152 | |||
153 | grokExpression (CVar cv _) = Just Computation | ||
154 | { compFree = Map.singleton (identToString cv) () | ||
155 | , compIntro = Map.empty | ||
156 | , comp = hsvar (identToString cv) | ||
157 | } | ||
158 | grokExpression (CConst (CIntConst n _)) = Just Computation | ||
159 | { compFree = Map.empty | ||
160 | , compIntro = Map.empty | ||
161 | , comp = Lit () (Int () (getCInteger n) (show n)) | ||
162 | } | ||
163 | grokExpression (CBinary CNeqOp a b _) = do | ||
164 | ca <- grokExpression a | ||
165 | cb <- grokExpression b | ||
166 | return Computation | ||
167 | { compFree = compFree ca `Map.union` compFree cb | ||
168 | , compIntro = Map.empty | ||
169 | , comp = InfixApp () (comp ca) hsopNeq (comp cb) | ||
170 | } | ||
171 | grokExpression _ = Nothing | ||
172 | |||
173 | |||
174 | hsvar :: String -> HS.Exp () | 149 | hsvar :: String -> HS.Exp () |
175 | hsvar v = Var () (UnQual () (HS.Ident () v)) | 150 | hsvar v = Var () (UnQual () (HS.Ident () v)) |
176 | 151 | ||
@@ -209,12 +184,79 @@ applyComputation a b = a | |||
209 | varmap :: [String] -> Map String () | 184 | varmap :: [String] -> Map String () |
210 | varmap vs = Map.fromList $ map (,()) vs | 185 | varmap vs = Map.fromList $ map (,()) vs |
211 | 186 | ||
187 | {- | ||
188 | CUnary CAdrOp (CVar _ _) LT) LT | ||
189 | CCall (CVar i _) exps _ | ||
190 | |||
191 | -} | ||
192 | |||
193 | -- Returns a list of statements bringing variables into scope and an | ||
194 | -- expression. | ||
195 | grokExpression (CVar cv _) = Just $ (,) [] $ Computation | ||
196 | { compFree = Map.singleton (identToString cv) () | ||
197 | , compIntro = Map.empty | ||
198 | , comp = hsvar (identToString cv) | ||
199 | } | ||
200 | grokExpression (CConst (CIntConst n _)) = Just $ (,) [] $ Computation | ||
201 | { compFree = Map.empty | ||
202 | , compIntro = Map.empty | ||
203 | , comp = Lit () (Int () (getCInteger n) (show n)) | ||
204 | } | ||
205 | grokExpression (CBinary CNeqOp a b _) = do | ||
206 | (as,ca) <- grokExpression a | ||
207 | (bs,cb) <- grokExpression b | ||
208 | let ss = as ++ bs -- TODO: resolve variable name conflicts | ||
209 | return $ (,) ss $ Computation | ||
210 | { compFree = compFree ca `Map.union` compFree cb | ||
211 | , compIntro = Map.empty | ||
212 | , comp = InfixApp () (comp ca) hsopNeq (comp cb) | ||
213 | } | ||
214 | grokExpression (CUnary CAdrOp (CVar cv0 _) _) = do | ||
215 | let cv = identToString cv0 | ||
216 | hv = "p" ++ cv | ||
217 | k = uniqIdentifier "go" (Map.empty {-todo-}) | ||
218 | ss = pure Computation | ||
219 | { compFree = Map.singleton cv () | ||
220 | , compIntro = Map.singleton hv () | ||
221 | , comp = Lambda () [hspvar k] | ||
222 | $ InfixApp () | ||
223 | (App () (hsvar "withPointer") (hsvar cv)) | ||
224 | hsopBind | ||
225 | (Lambda () [hspvar hv] (hsvar k)) | ||
226 | } | ||
227 | return $ (,) ss Computation | ||
228 | { compFree = Map.singleton hv () | ||
229 | , compIntro = Map.empty | ||
230 | , comp = hsvar hv | ||
231 | } | ||
232 | grokExpression (C.CCall (CVar fn _) exps _) = do | ||
233 | gs <- mapM grokExpression exps | ||
234 | let ss = concatMap fst gs -- TODO: resolve variable name conflicts | ||
235 | hv = "r" ++ identToString fn | ||
236 | cll = foldl (App ()) (hsvar (identToString fn)) $ map (comp . snd) gs | ||
237 | frees = foldr Map.union (Map.singleton (identToString fn) ()) (map (compFree . snd) gs) | ||
238 | k = uniqIdentifier "go" frees | ||
239 | s = Computation | ||
240 | { compFree = frees | ||
241 | , compIntro = Map.singleton hv () | ||
242 | , comp = Lambda () [hspvar k] | ||
243 | $ InfixApp () cll hsopBind | ||
244 | $ Lambda () [hspvar hv] (hsvar k) | ||
245 | } | ||
246 | return $ (,) (ss++[s]) Computation | ||
247 | { compFree = Map.singleton hv () | ||
248 | , compIntro = Map.empty | ||
249 | , comp = hsvar hv | ||
250 | } | ||
251 | grokExpression _ = Nothing | ||
252 | |||
212 | 253 | ||
213 | grokStatement :: CCompoundBlockItem a -> Maybe (Computation (HS.Exp ())) | 254 | grokStatement :: CCompoundBlockItem a -> Maybe (Computation (HS.Exp ())) |
214 | grokStatement (CBlockStmt (CReturn (Just exp) _)) = do | 255 | grokStatement (CBlockStmt (CReturn (Just exp) _)) = do |
215 | x <- grokExpression exp | 256 | (xs,x) <- grokExpression exp |
216 | let k = uniqIdentifier "go" (compFree x `Map.union` compIntro x) | 257 | let k = uniqIdentifier "go" (compFree x `Map.union` compIntro x) |
217 | return $ fmap (\y -> Lambda () [hspvar k] $ App () (hsvar "return") y) x | 258 | x' = fmap (\y -> App () (hsvar "return") y) x |
259 | return $ fmap (\y -> Lambda () [hspvar k] y) $ foldr applyComputation x' xs | ||
218 | grokStatement (CBlockStmt (CExpr (Just | 260 | grokStatement (CBlockStmt (CExpr (Just |
219 | (CAssign CAssignOp cvarnew | 261 | (CAssign CAssignOp cvarnew |
220 | (C.CCall cvarfun [] _) _)) _)) = do | 262 | (C.CCall cvarfun [] _) _)) _)) = do |
@@ -229,21 +271,26 @@ grokStatement (CBlockStmt (CExpr (Just | |||
229 | $ Lambda () [hspvar v] (hsvar k) | 271 | $ Lambda () [hspvar v] (hsvar k) |
230 | } | 272 | } |
231 | grokStatement (CBlockStmt (CIf exp (CCompound [] stmts _) Nothing _)) = do | 273 | grokStatement (CBlockStmt (CIf exp (CCompound [] stmts _) Nothing _)) = do |
232 | x <- grokExpression exp | 274 | (xs,x) <- grokExpression exp |
233 | ss <- sequence $ map grokStatement stmts | 275 | ss <- sequence $ map grokStatement stmts |
234 | let s = foldr applyComputation (Computation Map.empty Map.empty (hsvar k)) ss | 276 | let s = foldr applyComputation (Computation Map.empty Map.empty (hsvar k)) ss |
235 | k = uniqIdentifier "go" (Map.union (compFree x) (compFree s)) | 277 | k = uniqIdentifier "go" (Map.union (compFree x) (compFree s)) |
236 | return Computation | 278 | return $ flip (foldr applyComputation) xs Computation |
237 | { compFree = compFree x `Map.union` compFree s | 279 | { compFree = compFree x `Map.union` compFree s |
238 | , compIntro = compIntro s | 280 | , compIntro = compIntro s |
239 | , comp = Lambda () [hspvar k] $ If () (comp x) (comp s) (hsvar k) | 281 | , comp = Lambda () [hspvar k] $ If () (comp x) (comp s) (hsvar k) |
240 | } | 282 | } |
241 | grokStatement (CBlockDecl (CDecl (t:_) (v:vs) _)) = do | 283 | grokStatement (CBlockDecl (CDecl (t:_) (v:vs) _)) = do |
242 | return Computation | 284 | -- case mapMaybe (\(cdeclr,_,_) -> cdeclr >>= \(CDeclr i _ initial _ _) -> initial) (v:vs) of |
243 | { compFree = Map.empty | 285 | -- case mapMaybe (\(cdeclr,_,_) -> cdeclr >>= \(CInitList xs _) -> Just xs) (v:vs) of |
244 | , compIntro = Map.empty | 286 | case mapMaybe (\(_,inits,_) -> inits) (v:vs) of |
245 | , comp = Lambda () [hspvar "go"] $ hsvar "go" | 287 | [] -> |
246 | } | 288 | return Computation |
289 | { compFree = Map.empty | ||
290 | , compIntro = Map.empty | ||
291 | , comp = Lambda () [hspvar "go"] $ hsvar "go" | ||
292 | } | ||
293 | initials -> Nothing -- TODO | ||
247 | grokStatement _ = Nothing | 294 | grokStatement _ = Nothing |
248 | 295 | ||
249 | isFunctionDecl (CDeclExt (CDecl _ [(Just (CDeclr _ [CFunDeclr _ _ _] _ _ _),_,_)] _)) = True | 296 | isFunctionDecl (CDeclExt (CDecl _ [(Just (CDeclr _ [CFunDeclr _ _ _] _ _ _),_,_)] _)) = True |
@@ -296,8 +343,12 @@ transpile o fname incs (CTranslUnit edecls _) = do | |||
296 | forM_ bdy $ \d -> do | 343 | forM_ bdy $ \d -> do |
297 | putStrLn $ " C: " ++ show (pretty d) | 344 | putStrLn $ " C: " ++ show (pretty d) |
298 | case grokStatement d of | 345 | case grokStatement d of |
299 | Just hd -> putStrLn $ "HS: " ++ HS.prettyPrint (comp hd) | 346 | |
347 | Just hd -> do putStrLn $ "fr: " ++ intercalate " " (Map.keys (compFree hd)) | ||
348 | putStrLn $ "HS: " ++ HS.prettyPrint (comp hd) | ||
349 | |||
300 | Nothing -> putStrLn $ "??: " ++ ppShow (cleanTree d) | 350 | Nothing -> putStrLn $ "??: " ++ ppShow (cleanTree d) |
351 | putStrLn "" | ||
301 | return () | 352 | return () |
302 | 353 | ||
303 | isHeaderDecl :: CNode a => a -> Bool | 354 | isHeaderDecl :: CNode a => a -> Bool |