23 data InsertOption = |
23 data InsertOption = |
24 IOInsert |
24 IOInsert |
25 | IOLookup |
25 | IOLookup |
26 | IODeferred |
26 | IODeferred |
27 |
27 |
28 type Record = (String, (String, BaseType)) |
28 type Records = Map.Map String [(String, BaseType)] |
29 data RenderState = RenderState |
29 data RenderState = RenderState |
30 { |
30 { |
31 currentScope :: [Record], |
31 currentScope :: Records, |
32 lastIdentifier :: String, |
32 lastIdentifier :: String, |
33 lastType :: BaseType, |
33 lastType :: BaseType, |
34 stringConsts :: [(String, String)], |
34 stringConsts :: [(String, String)], |
35 uniqCounter :: Int, |
35 uniqCounter :: Int, |
36 namespaces :: Map.Map String [Record] |
36 namespaces :: Map.Map String Records |
37 } |
37 } |
38 |
38 |
39 emptyState = RenderState [] "" BTUnknown [] 0 |
39 emptyState = RenderState Map.empty "" BTUnknown [] 0 |
40 |
40 |
41 getUniq :: State RenderState Int |
41 getUniq :: State RenderState Int |
42 getUniq = do |
42 getUniq = do |
43 i <- gets uniqCounter |
43 i <- gets uniqCounter |
44 modify(\s -> s{uniqCounter = uniqCounter s + 1}) |
44 modify(\s -> s{uniqCounter = uniqCounter s + 1}) |
113 |
113 |
114 renderCFiles :: Map.Map String PascalUnit -> IO () |
114 renderCFiles :: Map.Map String PascalUnit -> IO () |
115 renderCFiles units = do |
115 renderCFiles units = do |
116 let u = Map.toList units |
116 let u = Map.toList units |
117 let nss = Map.map (toNamespace nss) units |
117 let nss = Map.map (toNamespace nss) units |
118 hPutStrLn stderr $ "Units: " ++ (show . Map.keys . Map.filter (not . null) $ nss) |
118 hPutStrLn stderr $ "Units: " ++ (show . Map.keys . Map.filter (not . Map.null) $ nss) |
119 --writeFile "pas2c.log" $ unlines . map (\t -> show (fst t) ++ "\n" ++ (unlines . map ((:) '\t' . show) . snd $ t)) . Map.toList $ nss |
119 --writeFile "pas2c.log" $ unlines . map (\t -> show (fst t) ++ "\n" ++ (unlines . map ((:) '\t' . show) . snd $ t)) . Map.toList $ nss |
120 mapM_ (toCFiles nss) u |
120 mapM_ (toCFiles nss) u |
121 where |
121 where |
122 toNamespace :: Map.Map String [Record] -> PascalUnit -> [Record] |
122 toNamespace :: Map.Map String Records -> PascalUnit -> Records |
123 toNamespace nss (System tvs) = |
123 toNamespace nss (System tvs) = |
124 currentScope $ execState (mapM_ (tvar2C True) tvs) (emptyState nss) |
124 currentScope $ execState (mapM_ (tvar2C True) tvs) (emptyState nss) |
125 toNamespace _ (Program {}) = [] |
125 toNamespace _ (Program {}) = Map.empty |
126 toNamespace nss (Unit _ interface _ _ _) = |
126 toNamespace nss (Unit _ interface _ _ _) = |
127 currentScope $ execState (interface2C interface) (emptyState nss) |
127 currentScope $ execState (interface2C interface) (emptyState nss) |
128 |
128 |
129 |
129 |
130 withState' :: (RenderState -> RenderState) -> State RenderState a -> State RenderState a |
130 withState' :: (RenderState -> RenderState) -> State RenderState a -> State RenderState a |
140 |
140 |
141 withLastIdNamespace :: State RenderState Doc -> State RenderState Doc |
141 withLastIdNamespace :: State RenderState Doc -> State RenderState Doc |
142 withLastIdNamespace f = do |
142 withLastIdNamespace f = do |
143 li <- gets lastIdentifier |
143 li <- gets lastIdentifier |
144 nss <- gets namespaces |
144 nss <- gets namespaces |
145 withState' (\st -> st{currentScope = fromMaybe [] $ Map.lookup li (namespaces st)}) f |
145 withState' (\st -> st{currentScope = fromMaybe Map.empty $ Map.lookup li (namespaces st)}) f |
146 |
146 |
147 withRecordNamespace :: String -> [(String, BaseType)] -> State RenderState Doc -> State RenderState Doc |
147 withRecordNamespace :: String -> [(String, BaseType)] -> State RenderState Doc -> State RenderState Doc |
148 withRecordNamespace _ [] = error "withRecordNamespace: empty record" |
148 withRecordNamespace _ [] = error "withRecordNamespace: empty record" |
149 withRecordNamespace prefix recs = withState' f |
149 withRecordNamespace prefix recs = withState' f |
150 where |
150 where |
151 f st = st{currentScope = records ++ currentScope st} |
151 f st = st{currentScope = Map.unionWith un records (currentScope st)} |
152 records = map (\(a, b) -> (map toLower a, (prefix ++ a, b))) recs |
152 records = Map.fromList $ map (\(a, b) -> (map toLower a, [(prefix ++ a, b)])) recs |
153 |
153 un [a] b = a : b |
154 toCFiles :: Map.Map String [Record] -> (String, PascalUnit) -> IO () |
154 |
|
155 toCFiles :: Map.Map String Records -> (String, PascalUnit) -> IO () |
155 toCFiles _ (_, System _) = return () |
156 toCFiles _ (_, System _) = return () |
156 toCFiles ns p@(fn, pu) = do |
157 toCFiles ns p@(fn, pu) = do |
157 hPutStrLn stderr $ "Rendering '" ++ fn ++ "'..." |
158 hPutStrLn stderr $ "Rendering '" ++ fn ++ "'..." |
158 toCFiles' p |
159 toCFiles' p |
159 where |
160 where |
212 mapM_ (id2C IOInsert . setBaseType BTUnit) unitIds |
213 mapM_ (id2C IOInsert . setBaseType BTUnit) unitIds |
213 return $ vcat . map (\i -> text $ "#include \"" ++ i ++ ".h\"") $ uses2List uses |
214 return $ vcat . map (\i -> text $ "#include \"" ++ i ++ ".h\"") $ uses2List uses |
214 where |
215 where |
215 injectNamespace (Identifier i _) = do |
216 injectNamespace (Identifier i _) = do |
216 getNS <- gets (flip Map.lookup . namespaces) |
217 getNS <- gets (flip Map.lookup . namespaces) |
217 let f = flip (foldl (flip (:))) (fromMaybe [] (getNS i)) |
218 modify (\s -> s{currentScope = Map.unionWith (++) (fromMaybe Map.empty (getNS i)) $ currentScope s}) |
218 modify (\s -> s{currentScope = f $ currentScope s}) |
|
219 |
219 |
220 uses2List :: Uses -> [String] |
220 uses2List :: Uses -> [String] |
221 uses2List (Uses ids) = map (\(Identifier i _) -> i) ids |
221 uses2List (Uses ids) = map (\(Identifier i _) -> i) ids |
222 |
222 |
223 |
223 |
227 {-- case t of |
227 {-- case t of |
228 BTUnknown -> do |
228 BTUnknown -> do |
229 ns <- gets currentScope |
229 ns <- gets currentScope |
230 error $ "id2C IOInsert: type BTUnknown for " ++ show i ++ "\nnamespace: " ++ show (take 100 ns) |
230 error $ "id2C IOInsert: type BTUnknown for " ++ show i ++ "\nnamespace: " ++ show (take 100 ns) |
231 _ -> do --} |
231 _ -> do --} |
232 modify (\s -> s{currentScope = (n, (i, t)) : currentScope s, lastIdentifier = n}) |
232 modify (\s -> s{currentScope = Map.insertWith (++) n [(i, t)] (currentScope s), lastIdentifier = n}) |
233 return $ text i |
233 return $ text i |
234 where |
234 where |
235 n = map toLower i |
235 n = map toLower i |
236 id2C IOLookup (Identifier i t) = do |
236 id2C IOLookup (Identifier i t) = do |
237 let i' = map toLower i |
237 let i' = map toLower i |
238 v <- gets $ find (\(a, _) -> a == i') . currentScope |
238 v <- gets $ Map.lookup i' . currentScope |
239 ns <- gets currentScope |
|
240 lt <- gets lastType |
239 lt <- gets lastType |
241 if isNothing v then |
240 if isNothing v then |
242 error $ "Not defined: '" ++ i' ++ "'\n" ++ show lt ++ "\n" ++ show (take 100 ns) |
241 error $ "Not defined: '" ++ i' ++ "'\n" ++ show lt |
243 else |
242 else |
244 let vv = snd $ fromJust v in modify (\s -> s{lastType = snd vv, lastIdentifier = fst vv}) >> (return . text . fst $ vv) |
243 let vv = head $ fromJust v in modify (\s -> s{lastType = snd vv, lastIdentifier = fst vv}) >> (return . text . fst $ vv) |
245 id2C IODeferred (Identifier i t) = do |
244 id2C IODeferred (Identifier i t) = do |
246 let i' = map toLower i |
245 let i' = map toLower i |
247 v <- gets $ find (\(a, _) -> a == i') . currentScope |
246 v <- gets $ Map.lookup i' . currentScope |
248 if (isNothing v) then |
247 if (isNothing v) then |
249 return $ text i |
248 return $ text i |
250 else |
249 else |
251 return . text . fst . snd . fromJust $ v |
250 return . text . fst . head . fromJust $ v |
252 |
251 |
253 id2CTyped :: TypeDecl -> Identifier -> State RenderState Doc |
252 id2CTyped :: TypeDecl -> Identifier -> State RenderState Doc |
254 id2CTyped t (Identifier i _) = do |
253 id2CTyped t (Identifier i _) = do |
255 tb <- resolveType t |
254 tb <- resolveType t |
256 ns <- gets currentScope |
|
257 case tb of |
255 case tb of |
258 BTUnknown -> do |
256 BTUnknown -> do |
259 ns <- gets currentScope |
257 error $ "id2CTyped: type BTUnknown for " ++ show i ++ "\ntype: " ++ show t |
260 error $ "id2CTyped: type BTUnknown for " ++ show i ++ "\ntype: " ++ show t ++ "\nnamespace: " ++ show (take 100 ns) |
|
261 _ -> return () |
258 _ -> return () |
262 id2C IOInsert (Identifier i tb) |
259 id2C IOInsert (Identifier i tb) |
263 |
260 |
264 |
261 |
265 resolveType :: TypeDecl -> State RenderState BaseType |
262 resolveType :: TypeDecl -> State RenderState BaseType |
266 resolveType st@(SimpleType (Identifier i _)) = do |
263 resolveType st@(SimpleType (Identifier i _)) = do |
267 let i' = map toLower i |
264 let i' = map toLower i |
268 v <- gets $ find (\(a, _) -> a == i') . currentScope |
265 v <- gets $ Map.lookup i' . currentScope |
269 if isJust v then return . snd . snd $ fromJust v else return $ f i' |
266 if isJust v then return . snd . head $ fromJust v else return $ f i' |
270 where |
267 where |
271 f "integer" = BTInt |
268 f "integer" = BTInt |
272 f "pointer" = BTPointerTo BTVoid |
269 f "pointer" = BTPointerTo BTVoid |
273 f "boolean" = BTBool |
270 f "boolean" = BTBool |
274 f "float" = BTFloat |
271 f "float" = BTFloat |
285 f (VarDeclaration _ (ids, td) _) = mapM (\(Identifier i _) -> liftM ((,) i) $ resolveType td) ids |
282 f (VarDeclaration _ (ids, td) _) = mapM (\(Identifier i _) -> liftM ((,) i) $ resolveType td) ids |
286 resolveType (ArrayDecl (Just i) t) = do |
283 resolveType (ArrayDecl (Just i) t) = do |
287 t' <- resolveType t |
284 t' <- resolveType t |
288 return $ BTArray i BTInt t' |
285 return $ BTArray i BTInt t' |
289 resolveType (ArrayDecl Nothing t) = liftM (BTArray RangeInfinite BTInt) $ resolveType t |
286 resolveType (ArrayDecl Nothing t) = liftM (BTArray RangeInfinite BTInt) $ resolveType t |
290 resolveType (FunctionType t _) = liftM BTFunction $ resolveType t |
287 resolveType (FunctionType t a) = liftM (BTFunction (length a)) $ resolveType t |
291 resolveType (DeriveType (InitHexNumber _)) = return BTInt |
288 resolveType (DeriveType (InitHexNumber _)) = return BTInt |
292 resolveType (DeriveType (InitNumber _)) = return BTInt |
289 resolveType (DeriveType (InitNumber _)) = return BTInt |
293 resolveType (DeriveType (InitFloat _)) = return BTFloat |
290 resolveType (DeriveType (InitFloat _)) = return BTFloat |
294 resolveType (DeriveType (InitString _)) = return BTString |
291 resolveType (DeriveType (InitString _)) = return BTString |
295 resolveType (DeriveType (InitBinOp {})) = return BTInt |
292 resolveType (DeriveType (InitBinOp {})) = return BTInt |
304 resolveType (Set t) = liftM BTSet $ resolveType t |
301 resolveType (Set t) = liftM BTSet $ resolveType t |
305 |
302 |
306 |
303 |
307 resolve :: String -> BaseType -> State RenderState BaseType |
304 resolve :: String -> BaseType -> State RenderState BaseType |
308 resolve s (BTUnresolved t) = do |
305 resolve s (BTUnresolved t) = do |
309 v <- gets $ find (\(a, _) -> a == t) . currentScope |
306 v <- gets $ Map.lookup t . currentScope |
310 if isJust v then |
307 if isJust v then |
311 resolve s . snd . snd . fromJust $ v |
308 resolve s . snd . head . fromJust $ v |
312 else |
309 else |
313 error $ "Unknown type " ++ show t ++ "\n" ++ s |
310 error $ "Unknown type " ++ show t ++ "\n" ++ s |
314 resolve _ t = return t |
311 resolve _ t = return t |
315 |
312 |
316 fromPointer :: String -> BaseType -> State RenderState BaseType |
313 fromPointer :: String -> BaseType -> State RenderState BaseType |
317 fromPointer s (BTPointerTo t) = resolve s t |
314 fromPointer s (BTPointerTo t) = resolve s t |
318 fromPointer s (BTFunctionReturn _ (BTPointerTo t)) = resolve s t |
315 fromPointer s (BTFunctionReturn _ (BTPointerTo t)) = resolve s t |
319 fromPointer s t = do |
316 fromPointer s t = do |
320 ns <- gets currentScope |
317 error $ "Dereferencing from non-pointer type " ++ show t ++ "\n" ++ s |
321 error $ "Dereferencing from non-pointer type " ++ show t ++ "\n" ++ s ++ "\n\n" ++ show (take 100 ns) |
|
322 |
318 |
323 |
319 |
324 functionParams2C params = liftM (hcat . punctuate comma . concat) $ mapM (tvar2C False) params |
320 functionParams2C params = liftM (hcat . punctuate comma . concat) $ mapM (tvar2C False) params |
325 |
321 |
326 fun2C :: Bool -> String -> TypeVarDeclaration -> State RenderState [Doc] |
322 fun2C :: Bool -> String -> TypeVarDeclaration -> State RenderState [Doc] |
327 fun2C _ _ (FunctionDeclaration name returnType params Nothing) = do |
323 fun2C _ _ (FunctionDeclaration name returnType params Nothing) = do |
328 t <- type2C returnType |
324 t <- type2C returnType |
329 t'<- gets lastType |
325 t'<- gets lastType |
330 p <- withState' id $ functionParams2C params |
326 p <- withState' id $ functionParams2C params |
331 n <- id2C IOInsert $ setBaseType (BTFunction t') name |
327 n <- id2C IOInsert $ setBaseType (BTFunction (length params) t') name |
332 return [t empty <+> n <> parens p] |
328 return [t empty <+> n <> parens p] |
333 |
329 |
334 fun2C True rv (FunctionDeclaration name returnType params (Just (tvars, phrase))) = do |
330 fun2C True rv (FunctionDeclaration name returnType params (Just (tvars, phrase))) = do |
335 let res = docToLower $ text rv <> text "_result" |
331 let res = docToLower $ text rv <> text "_result" |
336 t <- type2C returnType |
332 t <- type2C returnType |
337 t'<- gets lastType |
333 t'<- gets lastType |
338 n <- id2C IOInsert $ setBaseType (BTFunction t') name |
334 n <- id2C IOInsert $ setBaseType (BTFunction (length params) t') name |
339 (p, ph) <- withState' (\st -> st{currentScope = (map toLower rv, (render res, BTFunctionReturn (render n) t')) : currentScope st}) $ do |
335 (p, ph) <- withState' (\st -> st{currentScope = Map.insertWith un (map toLower rv) [(render res, BTFunctionReturn (render n) t')] $ currentScope st}) $ do |
340 p <- functionParams2C params |
336 p <- functionParams2C params |
341 ph <- liftM2 ($+$) (typesAndVars2C False tvars) (phrase2C' phrase) |
337 ph <- liftM2 ($+$) (typesAndVars2C False tvars) (phrase2C' phrase) |
342 return (p, ph) |
338 return (p, ph) |
343 let phrasesBlock = case returnType of |
339 let phrasesBlock = case returnType of |
344 VoidType -> ph |
340 VoidType -> ph |
554 | otherwise = liftM (text "else" $$) $ (phrase2C . wrapPhrase) (fromJust mphrase2) |
551 | otherwise = liftM (text "else" $$) $ (phrase2C . wrapPhrase) (fromJust mphrase2) |
555 phrase2C (Assignment ref expr) = do |
552 phrase2C (Assignment ref expr) = do |
556 r <- ref2C ref |
553 r <- ref2C ref |
557 t <- gets lastType |
554 t <- gets lastType |
558 e <- case (t, expr) of |
555 e <- case (t, expr) of |
559 (BTFunction _, (Reference r')) -> ref2C r' |
556 (BTFunction {}, (Reference r')) -> ref2C r' |
560 _ -> expr2C expr |
557 _ -> expr2C expr |
561 return $ r <+> text "=" <+> e <> semi |
558 return $ r <+> text "=" <+> e <> semi |
562 phrase2C (WhileCycle expr phrase) = do |
559 phrase2C (WhileCycle expr phrase) = do |
563 e <- expr2C expr |
560 e <- expr2C expr |
564 p <- phrase2C $ wrapPhrase phrase |
561 p <- phrase2C $ wrapPhrase phrase |
621 e1 <- expr2C expr1 |
617 e1 <- expr2C expr1 |
622 t1 <- gets lastType |
618 t1 <- gets lastType |
623 e2 <- expr2C expr2 |
619 e2 <- expr2C expr2 |
624 t2 <- gets lastType |
620 t2 <- gets lastType |
625 case (op2C op, t1, t2) of |
621 case (op2C op, t1, t2) of |
626 ("+", BTString, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strconcat" (BTFunction BTString)) |
622 ("+", BTString, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strconcat" (BTFunction 2 BTString)) |
627 ("+", BTString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strappend" (BTFunction BTString)) |
623 ("+", BTString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strappend" (BTFunction 2 BTString)) |
628 ("+", BTChar, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strprepend" (BTFunction BTString)) |
624 ("+", BTChar, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strprepend" (BTFunction 2 BTString)) |
629 ("==", BTString, _) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strcompare" (BTFunction BTBool)) |
625 ("==", BTString, _) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strcompare" (BTFunction 2 BTBool)) |
630 ("!=", BTString, _) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strncompare" (BTFunction BTBool)) |
626 ("!=", BTString, _) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strncompare" (BTFunction 2 BTBool)) |
631 ("&", BTBool, _) -> return $ parens e1 <+> text "&&" <+> parens e2 |
627 ("&", BTBool, _) -> return $ parens e1 <+> text "&&" <+> parens e2 |
632 ("|", BTBool, _) -> return $ parens e1 <+> text "||" <+> parens e2 |
628 ("|", BTBool, _) -> return $ parens e1 <+> text "||" <+> parens e2 |
633 (o, _, _) | o `elem` boolOps -> do |
629 (o, _, _) | o `elem` boolOps -> do |
634 modify(\s -> s{lastType = BTBool}) |
630 modify(\s -> s{lastType = BTBool}) |
635 return $ parens e1 <+> text o <+> parens e2 |
631 return $ parens e1 <+> text o <+> parens e2 |
658 expr2C (BuiltInFunCall params ref) = do |
654 expr2C (BuiltInFunCall params ref) = do |
659 r <- ref2C ref |
655 r <- ref2C ref |
660 t <- gets lastType |
656 t <- gets lastType |
661 ps <- mapM expr2C params |
657 ps <- mapM expr2C params |
662 case t of |
658 case t of |
663 BTFunction t' -> do |
659 BTFunction _ t' -> do |
664 modify (\s -> s{lastType = t'}) |
660 modify (\s -> s{lastType = t'}) |
665 _ -> error $ "BuiltInFunCall lastType: " ++ show t |
661 _ -> error $ "BuiltInFunCall lastType: " ++ show t |
666 return $ |
662 return $ |
667 r <> parens (hsep . punctuate (char ',') $ ps) |
663 r <> parens (hsep . punctuate (char ',') $ ps) |
668 expr2C a = error $ "Don't know how to render " ++ show a |
664 expr2C a = error $ "Don't know how to render " ++ show a |
686 -- conversion routines |
682 -- conversion routines |
687 ref2C ae@(ArrayElement [expr] ref) = do |
683 ref2C ae@(ArrayElement [expr] ref) = do |
688 e <- expr2C expr |
684 e <- expr2C expr |
689 r <- ref2C ref |
685 r <- ref2C ref |
690 t <- gets lastType |
686 t <- gets lastType |
691 ns <- gets currentScope |
|
692 case t of |
687 case t of |
693 (BTArray _ _ t') -> modify (\st -> st{lastType = t'}) |
688 (BTArray _ _ t') -> modify (\st -> st{lastType = t'}) |
694 (BTFunctionReturn _ (BTArray _ _ t')) -> modify (\st -> st{lastType = t'}) |
689 (BTFunctionReturn _ (BTArray _ _ t')) -> modify (\st -> st{lastType = t'}) |
695 (BTFunctionReturn _ (BTString)) -> modify (\st -> st{lastType = BTChar}) |
690 (BTFunctionReturn _ (BTString)) -> modify (\st -> st{lastType = BTChar}) |
696 (BTString) -> modify (\st -> st{lastType = BTChar}) |
691 (BTString) -> modify (\st -> st{lastType = BTChar}) |
697 (BTPointerTo t) -> do |
692 (BTPointerTo t) -> do |
698 t'' <- fromPointer (show t) =<< gets lastType |
693 t'' <- fromPointer (show t) =<< gets lastType |
699 case t'' of |
694 case t'' of |
700 BTChar -> modify (\st -> st{lastType = BTChar}) |
695 BTChar -> modify (\st -> st{lastType = BTChar}) |
701 a -> error $ "Getting element of " ++ show a ++ "\nReference: " ++ show ae ++ "\n" ++ show (take 100 ns) |
696 a -> error $ "Getting element of " ++ show a ++ "\nReference: " ++ show ae |
702 a -> error $ "Getting element of " ++ show a ++ "\nReference: " ++ show ae ++ "\n" ++ show (take 100 ns) |
697 a -> error $ "Getting element of " ++ show a ++ "\nReference: " ++ show ae |
703 case t of |
698 case t of |
704 BTString -> return $ r <> text ".s" <> brackets e |
699 BTString -> return $ r <> text ".s" <> brackets e |
705 _ -> return $ r <> brackets e |
700 _ -> return $ r <> brackets e |
706 ref2C (SimpleReference name) = id2C IOLookup name |
701 ref2C (SimpleReference name) = id2C IOLookup name |
707 ref2C rf@(RecordField (Dereference ref1) ref2) = do |
702 ref2C rf@(RecordField (Dereference ref1) ref2) = do |
708 r1 <- ref2C ref1 |
703 r1 <- ref2C ref1 |
709 t <- fromPointer (show ref1) =<< gets lastType |
704 t <- fromPointer (show ref1) =<< gets lastType |
710 ns <- gets currentScope |
|
711 r2 <- case t of |
705 r2 <- case t of |
712 BTRecord rs -> withRecordNamespace "" rs $ ref2C ref2 |
706 BTRecord rs -> withRecordNamespace "" rs $ ref2C ref2 |
713 BTUnit -> withLastIdNamespace $ ref2C ref2 |
707 BTUnit -> withLastIdNamespace $ ref2C ref2 |
714 a -> error $ "dereferencing from " ++ show a ++ "\n" ++ show rf ++ "\n" ++ show (take 100 ns) |
708 a -> error $ "dereferencing from " ++ show a ++ "\n" ++ show rf |
715 return $ |
709 return $ |
716 r1 <> text "->" <> r2 |
710 r1 <> text "->" <> r2 |
717 ref2C rf@(RecordField ref1 ref2) = do |
711 ref2C rf@(RecordField ref1 ref2) = do |
718 r1 <- ref2C ref1 |
712 r1 <- ref2C ref1 |
719 t <- gets lastType |
713 t <- gets lastType |
720 ns <- gets currentScope |
|
721 r2 <- case t of |
714 r2 <- case t of |
722 BTFunctionReturn s (BTRecord rs) -> withRecordNamespace "" rs $ ref2C ref2 |
715 BTFunctionReturn s (BTRecord rs) -> withRecordNamespace "" rs $ ref2C ref2 |
723 BTRecord rs -> withRecordNamespace "" rs $ ref2C ref2 |
716 BTRecord rs -> withRecordNamespace "" rs $ ref2C ref2 |
724 BTUnit -> withLastIdNamespace $ ref2C ref2 |
717 BTUnit -> withLastIdNamespace $ ref2C ref2 |
725 a -> error $ "dereferencing from " ++ show a ++ "\n" ++ show rf ++ "\n" ++ show (take 100 ns) |
718 a -> error $ "dereferencing from " ++ show a ++ "\n" ++ show rf |
726 return $ |
719 return $ |
727 r1 <> text "." <> r2 |
720 r1 <> text "." <> r2 |
728 ref2C d@(Dereference ref) = do |
721 ref2C d@(Dereference ref) = do |
729 r <- ref2C ref |
722 r <- ref2C ref |
730 t <- fromPointer (show d) =<< gets lastType |
723 t <- fromPointer (show d) =<< gets lastType |
732 return $ (parens $ text "*" <> r) |
725 return $ (parens $ text "*" <> r) |
733 ref2C f@(FunCall params ref) = do |
726 ref2C f@(FunCall params ref) = do |
734 r <- ref2C ref |
727 r <- ref2C ref |
735 t <- gets lastType |
728 t <- gets lastType |
736 case t of |
729 case t of |
737 BTFunction t' -> do |
730 BTFunction _ t' -> do |
738 ps <- liftM (parens . hsep . punctuate (char ',')) $ mapM expr2C params |
731 ps <- liftM (parens . hsep . punctuate (char ',')) $ mapM expr2C params |
739 modify (\s -> s{lastType = t'}) |
732 modify (\s -> s{lastType = t'}) |
740 return $ r <> ps |
733 return $ r <> ps |
741 BTFunctionReturn r t' -> do |
734 BTFunctionReturn r t' -> do |
742 ps <- liftM (parens . hsep . punctuate (char ',')) $ mapM expr2C params |
735 ps <- liftM (parens . hsep . punctuate (char ',')) $ mapM expr2C params |