tools/pas2c.hs
changeset 7019 333afe233886
parent 7002 5d817ba976f7
child 7032 5685ca1ec9bf
equal deleted inserted replaced
7018:6a1f46c026bf 7019:333afe233886
    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
   352         $+$
   348         $+$
   353         text "}"]
   349         text "}"]
   354     where
   350     where
   355     phrase2C' (Phrases p) = liftM vcat $ mapM phrase2C p
   351     phrase2C' (Phrases p) = liftM vcat $ mapM phrase2C p
   356     phrase2C' p = phrase2C p
   352     phrase2C' p = phrase2C p
       
   353     un [a] b = a : b
   357     
   354     
   358 fun2C False _ (FunctionDeclaration (Identifier name _) _ _ _) = error $ "nested functions not allowed: " ++ name
   355 fun2C False _ (FunctionDeclaration (Identifier name _) _ _ _) = error $ "nested functions not allowed: " ++ name
   359 fun2C _ tv _ = error $ "fun2C: I don't render " ++ show tv
   356 fun2C _ tv _ = error $ "fun2C: I don't render " ++ show tv
   360 
   357 
   361 tvar2C :: Bool -> TypeVarDeclaration -> State RenderState [Doc]
   358 tvar2C :: Bool -> TypeVarDeclaration -> State RenderState [Doc]
   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
   585     r <- ref2C ref 
   582     r <- ref2C ref 
   586     t <- gets lastType
   583     t <- gets lastType
   587     case t of
   584     case t of
   588         (BTRecord rs) -> withRecordNamespace (render r ++ ".") rs $ phrase2C $ wrapPhrase p
   585         (BTRecord rs) -> withRecordNamespace (render r ++ ".") rs $ phrase2C $ wrapPhrase p
   589         a -> do
   586         a -> do
   590             ns <- gets currentScope
   587             error $ "'with' block referencing non-record type " ++ show a ++ "\n" ++ show wb
   591             error $ "'with' block referencing non-record type " ++ show a ++ "\n" ++ show wb ++ "\nnamespace: " ++ show (take 100 ns)
       
   592 phrase2C (ForCycle i' e1' e2' p) = do
   588 phrase2C (ForCycle i' e1' e2' p) = do
   593     i <- id2C IOLookup i'
   589     i <- id2C IOLookup i'
   594     e1 <- expr2C e1'
   590     e1 <- expr2C e1'
   595     e2 <- expr2C e2'
   591     e2 <- expr2C e2'
   596     ph <- phrase2C (wrapPhrase p)
   592     ph <- phrase2C (wrapPhrase p)
   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
   670 ref2CF :: Reference -> State RenderState Doc
   666 ref2CF :: Reference -> State RenderState Doc
   671 ref2CF (SimpleReference name) = do
   667 ref2CF (SimpleReference name) = do
   672     i <- id2C IOLookup name
   668     i <- id2C IOLookup name
   673     t <- gets lastType
   669     t <- gets lastType
   674     case t of
   670     case t of
   675          BTFunction _ -> return $ i <> parens empty
   671          BTFunction {} -> return $ i <> parens empty
   676          _ -> return $ i
   672          _ -> return $ i
   677 ref2CF r = ref2C r
   673 ref2CF r = ref2C r
   678 
   674 
   679 ref2C :: Reference -> State RenderState Doc
   675 ref2C :: Reference -> State RenderState Doc
   680 -- rewrite into proper form
   676 -- rewrite into proper form
   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