244 _ -> i |
246 _ -> i |
245 modify (\s -> s{currentScope = Map.insertWith (++) n [(i', t)] (currentScope s), lastIdentifier = n}) |
247 modify (\s -> s{currentScope = Map.insertWith (++) n [(i', t)] (currentScope s), lastIdentifier = n}) |
246 return $ text i' |
248 return $ text i' |
247 where |
249 where |
248 n = map toLower i |
250 n = map toLower i |
249 id2C IOLookup (Identifier i t) = do |
251 id2C IOLookup i = id2CLookup head i |
250 let i' = map toLower i |
252 id2C IOLookupLast i = id2CLookup last i |
251 v <- gets $ Map.lookup i' . currentScope |
|
252 lt <- gets lastType |
|
253 if isNothing v then |
|
254 error $ "Not defined: '" ++ i' ++ "'\n" ++ show lt |
|
255 else |
|
256 let vv = head $ fromJust v in modify (\s -> s{lastType = snd vv, lastIdentifier = fst vv}) >> (return . text . fst $ vv) |
|
257 id2C (IOLookupFunction params) (Identifier i t) = do |
253 id2C (IOLookupFunction params) (Identifier i t) = do |
258 let i' = map toLower i |
254 let i' = map toLower i |
259 v <- gets $ Map.lookup i' . currentScope |
255 v <- gets $ Map.lookup i' . currentScope |
260 lt <- gets lastType |
256 lt <- gets lastType |
261 if isNothing v then |
257 if isNothing v then |
272 if (isNothing v) then |
268 if (isNothing v) then |
273 modify (\s -> s{lastType = BTUnknown, lastIdentifier = i}) >> return (text i) |
269 modify (\s -> s{lastType = BTUnknown, lastIdentifier = i}) >> return (text i) |
274 else |
270 else |
275 let vv = head $ fromJust v in modify (\s -> s{lastType = snd vv, lastIdentifier = fst vv}) >> (return . text . fst $ vv) |
271 let vv = head $ fromJust v in modify (\s -> s{lastType = snd vv, lastIdentifier = fst vv}) >> (return . text . fst $ vv) |
276 |
272 |
|
273 id2CLookup :: ([Record] -> Record) -> Identifier -> State RenderState Doc |
|
274 id2CLookup f (Identifier i _) = do |
|
275 let i' = map toLower i |
|
276 v <- gets $ Map.lookup i' . currentScope |
|
277 lt <- gets lastType |
|
278 if isNothing v then |
|
279 error $ "Not defined: '" ++ i' ++ "'\n" ++ show lt |
|
280 else |
|
281 let vv = f $ fromJust v in modify (\s -> s{lastType = snd vv, lastIdentifier = fst vv}) >> (return . text . fst $ vv) |
|
282 |
|
283 |
277 id2CTyped :: TypeDecl -> Identifier -> State RenderState Doc |
284 id2CTyped :: TypeDecl -> Identifier -> State RenderState Doc |
278 id2CTyped t (Identifier i _) = do |
285 id2CTyped t (Identifier i _) = do |
279 tb <- resolveType t |
286 tb <- resolveType t |
280 case tb of |
287 case (t, tb) of |
281 BTUnknown -> do |
288 (_, BTUnknown) -> do |
282 error $ "id2CTyped: type BTUnknown for " ++ show i ++ "\ntype: " ++ show t |
289 error $ "id2CTyped: type BTUnknown for " ++ show i ++ "\ntype: " ++ show t |
283 _ -> return () |
290 (SimpleType {}, BTRecord _ r) -> do |
284 id2C IOInsert (Identifier i tb) |
291 ts <- type2C t |
|
292 id2C IOInsert (Identifier i (BTRecord (render $ ts empty) r)) |
|
293 (_, BTRecord _ r) -> do |
|
294 ts <- type2C t |
|
295 id2C IOInsert (Identifier i (BTRecord i r)) |
|
296 _ -> id2C IOInsert (Identifier i tb) |
|
297 |
285 |
298 |
286 |
299 |
287 resolveType :: TypeDecl -> State RenderState BaseType |
300 resolveType :: TypeDecl -> State RenderState BaseType |
288 resolveType st@(SimpleType (Identifier i _)) = do |
301 resolveType st@(SimpleType (Identifier i _)) = do |
289 let i' = map toLower i |
302 let i' = map toLower i |
299 f _ = error $ "Unknown system type: " ++ show st |
312 f _ = error $ "Unknown system type: " ++ show st |
300 resolveType (PointerTo (SimpleType (Identifier i _))) = return . BTPointerTo $ BTUnresolved (map toLower i) |
313 resolveType (PointerTo (SimpleType (Identifier i _))) = return . BTPointerTo $ BTUnresolved (map toLower i) |
301 resolveType (PointerTo t) = liftM BTPointerTo $ resolveType t |
314 resolveType (PointerTo t) = liftM BTPointerTo $ resolveType t |
302 resolveType (RecordType tv mtvs) = do |
315 resolveType (RecordType tv mtvs) = do |
303 tvs <- mapM f (concat $ tv : fromMaybe [] mtvs) |
316 tvs <- mapM f (concat $ tv : fromMaybe [] mtvs) |
304 return . BTRecord . concat $ tvs |
317 return . BTRecord "" . concat $ tvs |
305 where |
318 where |
306 f :: TypeVarDeclaration -> State RenderState [(String, BaseType)] |
319 f :: TypeVarDeclaration -> State RenderState [(String, BaseType)] |
307 f (VarDeclaration _ (ids, td) _) = mapM (\(Identifier i _) -> liftM ((,) i) $ resolveType td) ids |
320 f (VarDeclaration _ (ids, td) _) = mapM (\(Identifier i _) -> liftM ((,) i) $ resolveType td) ids |
308 resolveType (ArrayDecl (Just i) t) = do |
321 resolveType (ArrayDecl (Just i) t) = do |
309 t' <- resolveType t |
322 t' <- resolveType t |
517 type2C' (String l) = return (text "string255" <+>)--return (text ("string" ++ show l) <+>) |
529 type2C' (String l) = return (text "string255" <+>)--return (text ("string" ++ show l) <+>) |
518 type2C' (PointerTo (SimpleType i)) = do |
530 type2C' (PointerTo (SimpleType i)) = do |
519 i' <- id2C IODeferred i |
531 i' <- id2C IODeferred i |
520 lt <- gets lastType |
532 lt <- gets lastType |
521 case lt of |
533 case lt of |
522 BTRecord _ -> return $ \a -> text "struct __" <> i' <+> text "*" <+> a |
534 BTRecord _ _ -> return $ \a -> text "struct __" <> i' <+> text "*" <+> a |
523 BTUnknown -> return $ \a -> text "struct __" <> i' <+> text "*" <+> a |
535 BTUnknown -> return $ \a -> text "struct __" <> i' <+> text "*" <+> a |
524 _ -> return $ \a -> i' <+> text "*" <+> a |
536 _ -> return $ \a -> i' <+> text "*" <+> a |
525 type2C' (PointerTo t) = liftM (\t a -> t (parens $ text "*" <> a)) $ type2C t |
537 type2C' (PointerTo t) = liftM (\t a -> t (parens $ text "*" <> a)) $ type2C t |
526 type2C' (RecordType tvs union) = do |
538 type2C' (RecordType tvs union) = do |
527 t <- withState' f $ mapM (tvar2C False) tvs |
539 t <- withState' f $ mapM (tvar2C False) tvs |
636 return $ text "do" <+> p <+> text "while" <> parens (text "!" <> parens e) <> semi |
648 return $ text "do" <+> p <+> text "while" <> parens (text "!" <> parens e) <> semi |
637 phrase2C NOP = return $ text ";" |
649 phrase2C NOP = return $ text ";" |
638 |
650 |
639 phrase2C (BuiltInFunctionCall [] (SimpleReference (Identifier "exit" BTUnknown))) = return $ text "return" <> semi |
651 phrase2C (BuiltInFunctionCall [] (SimpleReference (Identifier "exit" BTUnknown))) = return $ text "return" <> semi |
640 phrase2C (BuiltInFunctionCall [] (SimpleReference (Identifier "break" BTUnknown))) = return $ text "break" <> semi |
652 phrase2C (BuiltInFunctionCall [] (SimpleReference (Identifier "break" BTUnknown))) = return $ text "break" <> semi |
|
653 phrase2C (BuiltInFunctionCall [] (SimpleReference (Identifier "continue" BTUnknown))) = return $ text "continue" <> semi |
641 phrase2C (BuiltInFunctionCall [e] (SimpleReference (Identifier "exit" BTUnknown))) = liftM (\e -> text "return" <+> e <> semi) $ expr2C e |
654 phrase2C (BuiltInFunctionCall [e] (SimpleReference (Identifier "exit" BTUnknown))) = liftM (\e -> text "return" <+> e <> semi) $ expr2C e |
642 phrase2C (BuiltInFunctionCall [e] (SimpleReference (Identifier "dec" BTUnknown))) = liftM (\e -> text "--" <> e <> semi) $ expr2C e |
655 phrase2C (BuiltInFunctionCall [e] (SimpleReference (Identifier "dec" BTUnknown))) = liftM (\e -> text "--" <> e <> semi) $ expr2C e |
643 phrase2C (BuiltInFunctionCall [e1, e2] (SimpleReference (Identifier "dec" BTUnknown))) = liftM2 (\a b -> a <> text " -= " <> b <> semi) (expr2C e1) (expr2C e2) |
656 phrase2C (BuiltInFunctionCall [e1, e2] (SimpleReference (Identifier "dec" BTUnknown))) = liftM2 (\a b -> a <> text " -= " <> b <> semi) (expr2C e1) (expr2C e2) |
644 phrase2C (BuiltInFunctionCall [e] (SimpleReference (Identifier "inc" BTUnknown))) = liftM (\e -> text "++" <> e <> semi) $ expr2C e |
657 phrase2C (BuiltInFunctionCall [e] (SimpleReference (Identifier "inc" BTUnknown))) = liftM (\e -> text "++" <> e <> semi) $ expr2C e |
645 phrase2C (BuiltInFunctionCall [e1, e2] (SimpleReference (Identifier "inc" BTUnknown))) = liftM2 (\a b -> a <+> text "+=" <+> b <> semi) (expr2C e1) (expr2C e2) |
658 phrase2C (BuiltInFunctionCall [e1, e2] (SimpleReference (Identifier "inc" BTUnknown))) = liftM2 (\a b -> a <+> text "+=" <+> b <> semi) (expr2C e1) (expr2C e2) |
661 ("+", BTChar, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strprepend" (BTFunction 2 BTString)) |
674 ("+", BTChar, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strprepend" (BTFunction 2 BTString)) |
662 ("==", BTString, _) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strcompare" (BTFunction 2 BTBool)) |
675 ("==", BTString, _) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strcompare" (BTFunction 2 BTBool)) |
663 ("!=", BTString, _) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strncompare" (BTFunction 2 BTBool)) |
676 ("!=", BTString, _) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strncompare" (BTFunction 2 BTBool)) |
664 ("&", BTBool, _) -> return $ parens e1 <+> text "&&" <+> parens e2 |
677 ("&", BTBool, _) -> return $ parens e1 <+> text "&&" <+> parens e2 |
665 ("|", BTBool, _) -> return $ parens e1 <+> text "||" <+> parens e2 |
678 ("|", BTBool, _) -> return $ parens e1 <+> text "||" <+> parens e2 |
|
679 (_, BTRecord t1 _, BTRecord t2 _) -> do |
|
680 i <- op2CTyped op [SimpleType (Identifier t1 undefined), SimpleType (Identifier t2 undefined)] |
|
681 ref2C $ FunCall [expr1, expr2] (SimpleReference i) |
666 (o, _, _) | o `elem` boolOps -> do |
682 (o, _, _) | o `elem` boolOps -> do |
667 modify(\s -> s{lastType = BTBool}) |
683 modify(\s -> s{lastType = BTBool}) |
668 return $ parens e1 <+> text o <+> parens e2 |
684 return $ parens e1 <+> text o <+> parens e2 |
669 | otherwise -> return $ parens e1 <+> text o <+> parens e2 |
685 | otherwise -> return $ parens e1 <+> text o <+> parens e2 |
670 where |
686 where |
671 boolOps = ["==", "!=", "<", ">", "<=", ">="] |
687 boolOps = ["==", "!=", "<", ">", "<=", ">="] |
672 expr2C (NumberLiteral s) = return $ text s |
688 expr2C (NumberLiteral s) = do |
|
689 modify(\s -> s{lastType = BTInt}) |
|
690 return $ text s |
673 expr2C (FloatLiteral s) = return $ text s |
691 expr2C (FloatLiteral s) = return $ text s |
674 expr2C (HexNumber s) = return $ text "0x" <> (text . map toLower $ s) |
692 expr2C (HexNumber s) = return $ text "0x" <> (text . map toLower $ s) |
675 expr2C (StringLiteral [a]) = do |
693 expr2C (StringLiteral [a]) = do |
676 modify(\s -> s{lastType = BTChar}) |
694 modify(\s -> s{lastType = BTChar}) |
677 return . quotes $ text [a] |
695 return . quotes $ text [a] |
678 expr2C (StringLiteral s) = addStringConst s |
696 expr2C (StringLiteral s) = addStringConst s |
679 expr2C (Reference ref) = ref2CF ref |
697 expr2C (Reference ref) = ref2CF ref |
680 expr2C (PrefixOp op expr) = liftM (text (op2C op) <>) (expr2C expr) |
698 expr2C (PrefixOp op expr) = do |
|
699 e <- expr2C expr |
|
700 lt <- gets lastType |
|
701 case lt of |
|
702 BTRecord t _ -> do |
|
703 i <- op2CTyped op [SimpleType (Identifier t undefined)] |
|
704 ref2C $ FunCall [expr] (SimpleReference i) |
|
705 _ -> return $ text (op2C op) <> e |
681 expr2C Null = return $ text "NULL" |
706 expr2C Null = return $ text "NULL" |
682 expr2C (CharCode a) = do |
707 expr2C (CharCode a) = do |
683 modify(\s -> s{lastType = BTChar}) |
708 modify(\s -> s{lastType = BTChar}) |
684 return $ quotes $ text "\\x" <> text (showHex (read a) "") |
709 return $ quotes $ text "\\x" <> text (showHex (read a) "") |
685 expr2C (HexCharCode a) = return $ quotes $ text "\\x" <> text (map toLower a) |
710 expr2C (HexCharCode a) = return $ quotes $ text "\\x" <> text (map toLower a) |
757 ref2C (SimpleReference name) = id2C IOLookup name |
782 ref2C (SimpleReference name) = id2C IOLookup name |
758 ref2C rf@(RecordField (Dereference ref1) ref2) = do |
783 ref2C rf@(RecordField (Dereference ref1) ref2) = do |
759 r1 <- ref2C ref1 |
784 r1 <- ref2C ref1 |
760 t <- fromPointer (show ref1) =<< gets lastType |
785 t <- fromPointer (show ref1) =<< gets lastType |
761 r2 <- case t of |
786 r2 <- case t of |
762 BTRecord rs -> withRecordNamespace "" rs $ ref2C ref2 |
787 BTRecord _ rs -> withRecordNamespace "" rs $ ref2C ref2 |
763 BTUnit -> withLastIdNamespace $ ref2CF ref2 |
788 BTUnit -> withLastIdNamespace $ ref2CF ref2 |
764 a -> error $ "dereferencing from " ++ show a ++ "\n" ++ show rf |
789 a -> error $ "dereferencing from " ++ show a ++ "\n" ++ show rf |
765 return $ |
790 return $ |
766 r1 <> text "->" <> r2 |
791 r1 <> text "->" <> r2 |
767 ref2C rf@(RecordField ref1 ref2) = do |
792 ref2C rf@(RecordField ref1 ref2) = do |
768 r1 <- ref2C ref1 |
793 r1 <- ref2C ref1 |
769 t <- gets lastType |
794 t <- gets lastType |
770 case t of |
795 case t of |
771 BTRecord rs -> do |
796 BTRecord _ rs -> do |
772 r2 <- withRecordNamespace "" rs $ ref2C ref2 |
797 r2 <- withRecordNamespace "" rs $ ref2C ref2 |
773 return $ r1 <> text "." <> r2 |
798 return $ r1 <> text "." <> r2 |
774 BTUnit -> withLastIdNamespace $ ref2CF ref2 |
799 BTUnit -> withLastIdNamespace $ ref2CF ref2 |
775 a -> error $ "dereferencing from " ++ show a ++ "\n" ++ show rf |
800 a -> error $ "dereferencing from " ++ show a ++ "\n" ++ show rf |
776 ref2C d@(Dereference ref) = do |
801 ref2C d@(Dereference ref) = do |