tools/pas2c/Pas2C.hs
changeset 10129 cd2a64a1f4aa
parent 10127 7f29a65aa1e4
child 10131 4b4a043111f4
equal deleted inserted replaced
10128:0f6878b5395a 10129:cd2a64a1f4aa
   235 pascal2C (Unit _ interface implementation _ _) =
   235 pascal2C (Unit _ interface implementation _ _) =
   236     liftM2 ($+$) (interface2C interface True) (implementation2C implementation)
   236     liftM2 ($+$) (interface2C interface True) (implementation2C implementation)
   237 
   237 
   238 pascal2C (Program _ implementation mainFunction) = do
   238 pascal2C (Program _ implementation mainFunction) = do
   239     impl <- implementation2C implementation
   239     impl <- implementation2C implementation
   240     [main] <- tvar2C True False True True (FunctionDeclaration (Identifier "main" (BTInt True)) False False (SimpleType $ Identifier "int" (BTInt True)) [VarDeclaration False False ([Identifier "argc" (BTInt True)], SimpleType (Identifier "Integer" (BTInt True))) Nothing, VarDeclaration False False ([Identifier "argv" BTUnknown], SimpleType (Identifier "PPChar" BTUnknown)) Nothing] (Just (TypesAndVars [], mainFunction)))
   240     [main] <- tvar2C True False True True (FunctionDeclaration (Identifier "main" (BTInt True)) False False False (SimpleType $ Identifier "int" (BTInt True)) [VarDeclaration False False ([Identifier "argc" (BTInt True)], SimpleType (Identifier "Integer" (BTInt True))) Nothing, VarDeclaration False False ([Identifier "argv" BTUnknown], SimpleType (Identifier "PPChar" BTUnknown)) Nothing] (Just (TypesAndVars [], mainFunction)))
   241 
   241 
   242     return $ impl $+$ main
   242     return $ impl $+$ main
   243 
   243 
   244 pascal2C _ = error "pascal2C: pattern not matched"
   244 pascal2C _ = error "pascal2C: pattern not matched"
   245 
   245 
   269     modify $ \s -> s{toMangle = Map.keysSet . Map.filter (> 1) . foldr ins initMap $ tvs}
   269     modify $ \s -> s{toMangle = Map.keysSet . Map.filter (> 1) . foldr ins initMap $ tvs}
   270     where
   270     where
   271         initMap :: Map.Map String Int
   271         initMap :: Map.Map String Int
   272         initMap = Map.empty
   272         initMap = Map.empty
   273         --initMap = Map.fromList [("reset", 2)]
   273         --initMap = Map.fromList [("reset", 2)]
   274         ins (FunctionDeclaration (Identifier i _) _ _ _ _ _) m = Map.insertWith (+) (map toLower i) 1 m
   274         ins (FunctionDeclaration (Identifier i _) _ _ _ _ _ _) m = Map.insertWith (+) (map toLower i) 1 m
   275         ins _ m = m
   275         ins _ m = m
   276 
   276 
   277 -- the second bool indicates whether declare variable as extern or not
   277 -- the second bool indicates whether declare variable as extern or not
   278 -- the third bool indicates whether include types or not
   278 -- the third bool indicates whether include types or not
   279 
   279 
   308 id2C IOInsert i = id2C (IOInsertWithType empty) i
   308 id2C IOInsert i = id2C (IOInsertWithType empty) i
   309 id2C (IOInsertWithType d) (Identifier i t) = do
   309 id2C (IOInsertWithType d) (Identifier i t) = do
   310     tom <- gets (Set.member n . toMangle)
   310     tom <- gets (Set.member n . toMangle)
   311     cu <- gets currentUnit
   311     cu <- gets currentUnit
   312     let (i', t') = case (t, tom) of
   312     let (i', t') = case (t, tom) of
   313             (BTFunction _ p _, True) -> (cu ++ i ++ ('_' : show (length p)), t)
   313             (BTFunction _ e p _, True) -> ((if e then id else (++) cu) $ i ++ ('_' : show (length p)), t)
   314             (BTFunction _ _ _, _) -> (cu ++ i, t)
   314             (BTFunction _ e _ _, _) -> ((if e then id else (++) cu) i, t)
   315             (BTVarParam t'', _) -> ('(' : '*' : i ++ ")" , t'')
   315             (BTVarParam t'', _) -> ('(' : '*' : i ++ ")" , t'')
   316             _ -> (i, t)
   316             _ -> (i, t)
   317     modify (\s -> s{currentScope = Map.insertWith (++) n [Record i' t' d] (currentScope s), lastIdentifier = n})
   317     modify (\s -> s{currentScope = Map.insertWith (++) n [Record i' t' d] (currentScope s), lastIdentifier = n})
   318     return $ text i'
   318     return $ text i'
   319     where
   319     where
   329         error $ "Not defined: '" ++ i' ++ "'\n" ++ show lt ++ "\nwith num of params = " ++ show params ++ "\n" ++ show v
   329         error $ "Not defined: '" ++ i' ++ "'\n" ++ show lt ++ "\nwith num of params = " ++ show params ++ "\n" ++ show v
   330         else
   330         else
   331         let vv = fromMaybe (head $ fromJust v) . find checkParam $ fromJust v in
   331         let vv = fromMaybe (head $ fromJust v) . find checkParam $ fromJust v in
   332             modify (setLastIdValues vv) >> (return . text . lcaseId $ vv)
   332             modify (setLastIdValues vv) >> (return . text . lcaseId $ vv)
   333     where
   333     where
   334         checkParam (Record _ (BTFunction _ p _) _) = (length p) == params
   334         checkParam (Record _ (BTFunction _ _ p _) _) = (length p) == params
   335         checkParam _ = False
   335         checkParam _ = False
   336 id2C IODeferred (Identifier i _) = do
   336 id2C IODeferred (Identifier i _) = do
   337     let i' = map toLower i
   337     let i' = map toLower i
   338     v <- gets $ Map.lookup i' . currentScope
   338     v <- gets $ Map.lookup i' . currentScope
   339     if (isNothing v) then
   339     if (isNothing v) then
   415     t' <- resolveType t
   415     t' <- resolveType t
   416     return $ BTArray i (BTInt True) t'
   416     return $ BTArray i (BTInt True) t'
   417 resolveType (ArrayDecl Nothing t) = liftM (BTArray RangeInfinite (BTInt True)) $ resolveType t
   417 resolveType (ArrayDecl Nothing t) = liftM (BTArray RangeInfinite (BTInt True)) $ resolveType t
   418 resolveType (FunctionType t a) = do
   418 resolveType (FunctionType t a) = do
   419     bts <- typeVarDecl2BaseType a
   419     bts <- typeVarDecl2BaseType a
   420     liftM (BTFunction False bts) $ resolveType t
   420     liftM (BTFunction False False bts) $ resolveType t
   421 resolveType (DeriveType (InitHexNumber _)) = return (BTInt True)
   421 resolveType (DeriveType (InitHexNumber _)) = return (BTInt True)
   422 resolveType (DeriveType (InitNumber _)) = return (BTInt True)
   422 resolveType (DeriveType (InitNumber _)) = return (BTInt True)
   423 resolveType (DeriveType (InitFloat _)) = return BTFloat
   423 resolveType (DeriveType (InitFloat _)) = return BTFloat
   424 resolveType (DeriveType (InitString _)) = return BTString
   424 resolveType (DeriveType (InitString _)) = return BTString
   425 resolveType (DeriveType (InitBinOp {})) = return (BTInt True)
   425 resolveType (DeriveType (InitBinOp {})) = return (BTInt True)
   479         abc = hcat . punctuate comma . map (char . fst) $ ps
   479         abc = hcat . punctuate comma . map (char . fst) $ ps
   480         cparams = hcat . punctuate comma . map (\(c, v) -> if v then char '&' <> parens (char c) else char c) $ ps
   480         cparams = hcat . punctuate comma . map (\(c, v) -> if v then char '&' <> parens (char c) else char c) $ ps
   481         ps = zip ['a'..] (toIsVarList params)
   481         ps = zip ['a'..] (toIsVarList params)
   482 
   482 
   483 fun2C :: Bool -> String -> TypeVarDeclaration -> State RenderState [Doc]
   483 fun2C :: Bool -> String -> TypeVarDeclaration -> State RenderState [Doc]
   484 fun2C _ _ (FunctionDeclaration name _ overload returnType params Nothing) = do
   484 fun2C _ _ (FunctionDeclaration name _ overload external returnType params Nothing) = do
   485     t <- type2C returnType
   485     t <- type2C returnType
   486     t'<- gets lastType
   486     t'<- gets lastType
   487     bts <- typeVarDecl2BaseType params
   487     bts <- typeVarDecl2BaseType params
   488     p <- withState' id $ functionParams2C params
   488     p <- withState' id $ functionParams2C params
   489     n <- liftM render . id2C IOInsert $ setBaseType (BTFunction False bts t') name
   489     n <- liftM render . id2C IOInsert $ setBaseType (BTFunction False external bts t') name
   490     let decor = if overload then text "__attribute__((overloadable))" else empty
   490     let decor = if overload then text "__attribute__((overloadable))" else empty
   491     return [t empty <+> decor <+> text n <> parens p]
   491     return [t empty <+> decor <+> text n <> parens p]
   492 
   492 
   493 fun2C True rv (FunctionDeclaration name@(Identifier i _) inline overload returnType params (Just (tvars, phrase))) = do
   493 fun2C True rv (FunctionDeclaration name@(Identifier i _) inline overload external returnType params (Just (tvars, phrase))) = do
   494     let isVoid = case returnType of
   494     let isVoid = case returnType of
   495             VoidType -> True
   495             VoidType -> True
   496             _ -> False
   496             _ -> False
   497 
   497 
   498     let res = docToLower $ text rv <> if isVoid then empty else text "_result"
   498     let res = docToLower $ text rv <> if isVoid then empty else text "_result"
   501 
   501 
   502     bts <- typeVarDecl2BaseType params
   502     bts <- typeVarDecl2BaseType params
   503     --cu <- gets currentUnit
   503     --cu <- gets currentUnit
   504     notDeclared <- liftM isNothing . gets $ Map.lookup (map toLower i) . currentScope
   504     notDeclared <- liftM isNothing . gets $ Map.lookup (map toLower i) . currentScope
   505 
   505 
   506     n <- liftM render . id2C IOInsert $ setBaseType (BTFunction hasVars bts t') name
   506     n <- liftM render . id2C IOInsert $ setBaseType (BTFunction hasVars external bts t') name
   507     let resultId = if isVoid
   507     let resultId = if isVoid
   508                     then n -- void type doesn't have result, solving recursive procedure calls
   508                     then n -- void type doesn't have result, solving recursive procedure calls
   509                     else (render res)
   509                     else (render res)
   510 
   510 
   511     (p, ph) <- withState' (\st -> st{currentScope = Map.insertWith un (map toLower rv) [Record resultId (if isVoid then (BTFunction hasVars bts t') else t') empty] $ currentScope st
   511     (p, ph) <- withState' (\st -> st{currentScope = Map.insertWith un (map toLower rv) [Record resultId (if isVoid then (BTFunction hasVars False bts t') else t') empty] $ currentScope st
   512             , currentFunctionResult = if isVoid then [] else render res}) $ do
   512             , currentFunctionResult = if isVoid then [] else render res}) $ do
   513         p <- functionParams2C params
   513         p <- functionParams2C params
   514         ph <- liftM2 ($+$) (typesAndVars2C False False True tvars) (phrase2C' phrase)
   514         ph <- liftM2 ($+$) (typesAndVars2C False False True tvars) (phrase2C' phrase)
   515         return (p, ph)
   515         return (p, ph)
   516 
   516 
   537     phrase2C' p = phrase2C p
   537     phrase2C' p = phrase2C p
   538     un [a] b = a : b
   538     un [a] b = a : b
   539     un _ _ = error "fun2C u: pattern not matched"
   539     un _ _ = error "fun2C u: pattern not matched"
   540     hasVars = hasPassByReference params
   540     hasVars = hasPassByReference params
   541 
   541 
   542 fun2C False _ (FunctionDeclaration (Identifier name _) _ _ _ _ _) = error $ "nested functions not allowed: " ++ name
   542 fun2C False _ (FunctionDeclaration (Identifier name _) _ _ _ _ _ _) = error $ "nested functions not allowed: " ++ name
   543 fun2C _ tv _ = error $ "fun2C: I don't render " ++ show tv
   543 fun2C _ tv _ = error $ "fun2C: I don't render " ++ show tv
   544 
   544 
   545 -- the second bool indicates whether declare variable as extern or not
   545 -- the second bool indicates whether declare variable as extern or not
   546 -- the third bool indicates whether include types or not
   546 -- the third bool indicates whether include types or not
   547 -- the fourth bool indicates whether ignore initialization or not (basically for dynamic arrays since we cannot do initialization in function params)
   547 -- the fourth bool indicates whether ignore initialization or not (basically for dynamic arrays since we cannot do initialization in function params)
   548 tvar2C :: Bool -> Bool -> Bool -> Bool -> TypeVarDeclaration -> State RenderState [Doc]
   548 tvar2C :: Bool -> Bool -> Bool -> Bool -> TypeVarDeclaration -> State RenderState [Doc]
   549 tvar2C b _ includeType _ f@(FunctionDeclaration (Identifier name _) _ _ _ _ _) = do
   549 tvar2C b _ includeType _ f@(FunctionDeclaration (Identifier name _) _ _ _ _ _ _) = do
   550     t <- fun2C b name f
   550     t <- fun2C b name f
   551     if includeType then return t else return []
   551     if includeType then return t else return []
   552 tvar2C _ _ includeType _ (TypeDeclaration i' t) = do
   552 tvar2C _ _ includeType _ (TypeDeclaration i' t) = do
   553     i <- id2CTyped t i'
   553     i <- id2CTyped t i'
   554     tp <- type2C t
   554     tp <- type2C t
   610         ArrayDecl _ _ -> error "Mixed dynamic array and static array are not supported."
   610         ArrayDecl _ _ -> error "Mixed dynamic array and static array are not supported."
   611         _ -> 0
   611         _ -> 0
   612 
   612 
   613 tvar2C f _ _ _ (OperatorDeclaration op (Identifier i _) inline ret params body) = do
   613 tvar2C f _ _ _ (OperatorDeclaration op (Identifier i _) inline ret params body) = do
   614     r <- op2CTyped op (extractTypes params)
   614     r <- op2CTyped op (extractTypes params)
   615     fun2C f i (FunctionDeclaration r inline False ret params body)
   615     fun2C f i (FunctionDeclaration r inline False False ret params body)
   616 
   616 
   617 
   617 
   618 op2CTyped :: String -> [TypeDecl] -> State RenderState Identifier
   618 op2CTyped :: String -> [TypeDecl] -> State RenderState Identifier
   619 op2CTyped op t = do
   619 op2CTyped op t = do
   620     t' <- liftM (render . hcat . punctuate (char '_') . map (\txt -> txt empty)) $ mapM type2C t
   620     t' <- liftM (render . hcat . punctuate (char '_') . map (\txt -> txt empty)) $ mapM type2C t
   645 initExpr2C' InitNull = return $ text "NULL"
   645 initExpr2C' InitNull = return $ text "NULL"
   646 initExpr2C' (InitAddress expr) = do
   646 initExpr2C' (InitAddress expr) = do
   647     ie <- initExpr2C' expr
   647     ie <- initExpr2C' expr
   648     lt <- gets lastType
   648     lt <- gets lastType
   649     case lt of
   649     case lt of
   650         BTFunction True _ _ -> return $ text "&" <> ie -- <> text "__vars"
   650         BTFunction True _ _ _ -> return $ text "&" <> ie -- <> text "__vars"
   651         _ -> return $ text "&" <> ie
   651         _ -> return $ text "&" <> ie
   652 initExpr2C' (InitPrefixOp op expr) = liftM (text (op2C op) <>) (initExpr2C' expr)
   652 initExpr2C' (InitPrefixOp op expr) = liftM (text (op2C op) <>) (initExpr2C' expr)
   653 initExpr2C' (InitBinOp op expr1 expr2) = do
   653 initExpr2C' (InitBinOp op expr1 expr2) = do
   654     e1 <- initExpr2C' expr1
   654     e1 <- initExpr2C' expr1
   655     e2 <- initExpr2C' expr2
   655     e2 <- initExpr2C' expr2
   939     e1 <- expr2C expr1
   939     e1 <- expr2C expr1
   940     t1 <- gets lastType
   940     t1 <- gets lastType
   941     e2 <- expr2C expr2
   941     e2 <- expr2C expr2
   942     t2 <- gets lastType
   942     t2 <- gets lastType
   943     case (op2C op, t1, t2) of
   943     case (op2C op, t1, t2) of
   944         ("+", BTAString, BTAString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strconcatA" (BTFunction False [(False, t1), (False, t2)] BTString))
   944         ("+", BTAString, BTAString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strconcatA" (fff t1 t2 BTString))
   945         ("+", BTAString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strappendA" (BTFunction False [(False, t1), (False, t2)] BTAString))
   945         ("+", BTAString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strappendA" (fff t1 t2  BTAString))
   946         ("!=", BTAString, BTAString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strncompareA" (BTFunction False [(False, t1), (False, t2)] BTBool))
   946         ("!=", BTAString, BTAString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strncompareA" (fff t1 t2  BTBool))
   947         (_, BTAString, _) -> error $ "unhandled bin op with ansistring on the left side: " ++ show bop
   947         (_, BTAString, _) -> error $ "unhandled bin op with ansistring on the left side: " ++ show bop
   948         (_, _, BTAString) -> error $ "unhandled bin op with ansistring on the right side: " ++ show bop
   948         (_, _, BTAString) -> error $ "unhandled bin op with ansistring on the right side: " ++ show bop
   949         ("+", BTString, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strconcat" (BTFunction False [(False, t1), (False, t2)] BTString))
   949         ("+", BTString, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strconcat" (fff t1 t2  BTString))
   950         ("+", BTString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strappend" (BTFunction False [(False, t1), (False, t2)] BTString))
   950         ("+", BTString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strappend" (fff t1 t2  BTString))
   951         ("+", BTChar, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strprepend" (BTFunction False [(False, t1), (False, t2)] BTString))
   951         ("+", BTChar, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strprepend" (fff t1 t2  BTString))
   952         ("+", BTChar, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_chrconcat" (BTFunction False [(False, t1), (False, t2)] BTString))
   952         ("+", BTChar, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_chrconcat" (fff t1 t2  BTString))
   953         ("==", BTString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strcomparec" (BTFunction False [(False, t1), (False, t2)] BTBool))
   953         ("==", BTString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strcomparec" (fff t1 t2  BTBool))
   954 
   954 
   955         -- for function/procedure comparision
   955         -- for function/procedure comparision
   956         ("==", BTVoid, _) -> procCompare expr1 expr2 "=="
   956         ("==", BTVoid, _) -> procCompare expr1 expr2 "=="
   957         ("==", BTFunction _ _ _, _) -> procCompare expr1 expr2 "=="
   957         ("==", BTFunction _ _ _ _, _) -> procCompare expr1 expr2 "=="
   958 
   958 
   959         ("!=", BTVoid, _) -> procCompare expr1 expr2 "!="
   959         ("!=", BTVoid, _) -> procCompare expr1 expr2 "!="
   960         ("!=", BTFunction _ _ _, _) -> procCompare expr1 expr2 "!="
   960         ("!=", BTFunction _ _ _ _, _) -> procCompare expr1 expr2 "!="
   961 
   961 
   962         ("==", BTString, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strcompare" (BTFunction False [(False, t1), (False, t2)] BTBool))
   962         ("==", BTString, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strcompare" (fff t1 t2  BTBool))
   963         ("!=", BTString, _) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strncompare" (BTFunction False [(False, t1), (False, t2)] BTBool))
   963         ("!=", BTString, _) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strncompare" (fff t1 t2  BTBool))
   964         ("&", BTBool, _) -> return $ parens e1 <+> text "&&" <+> parens e2
   964         ("&", BTBool, _) -> return $ parens e1 <+> text "&&" <+> parens e2
   965         ("|", BTBool, _) -> return $ parens e1 <+> text "||" <+> parens e2
   965         ("|", BTBool, _) -> return $ parens e1 <+> text "||" <+> parens e2
   966         (_, BTRecord t1 _, BTRecord t2 _) -> do
   966         (_, BTRecord t1 _, BTRecord t2 _) -> do
   967             i <- op2CTyped op [SimpleType (Identifier t1 undefined), SimpleType (Identifier t2 undefined)]
   967             i <- op2CTyped op [SimpleType (Identifier t1 undefined), SimpleType (Identifier t2 undefined)]
   968             ref2C $ FunCall [expr1, expr2] (SimpleReference i)
   968             ref2C $ FunCall [expr1, expr2] (SimpleReference i)
   990                         e2' <- return $ case (o, t1, t2) of
   990                         e2' <- return $ case (o, t1, t2) of
   991                                 ("-", BTInt False, BTInt False) -> parens $ text "(int64_t)" <+> parens e2
   991                                 ("-", BTInt False, BTInt False) -> parens $ text "(int64_t)" <+> parens e2
   992                                 _ -> parens e2
   992                                 _ -> parens e2
   993                         return $ e1' <+> o' <+> e2'
   993                         return $ e1' <+> o' <+> e2'
   994     where
   994     where
       
   995         fff t1 t2 = BTFunction False False [(False, t1), (False, t2)]
   995         boolOps = ["==", "!=", "<", ">", "<=", ">="]
   996         boolOps = ["==", "!=", "<", ">", "<=", ">="]
   996         procCompare expr1 expr2 op =
   997         procCompare expr1 expr2 op =
   997             case (expr1, expr2) of
   998             case (expr1, expr2) of
   998                 (Reference r1, Reference r2) -> do
   999                 (Reference r1, Reference r2) -> do
   999                     id1 <- ref2C r1
  1000                     id1 <- ref2C r1
  1086 expr2C (BuiltInFunCall params ref) = do
  1087 expr2C (BuiltInFunCall params ref) = do
  1087     r <- ref2C ref
  1088     r <- ref2C ref
  1088     t <- gets lastType
  1089     t <- gets lastType
  1089     ps <- mapM expr2C params
  1090     ps <- mapM expr2C params
  1090     case t of
  1091     case t of
  1091         BTFunction _ _ t' -> do
  1092         BTFunction _ _ _ t' -> do
  1092             modify (\s -> s{lastType = t'})
  1093             modify (\s -> s{lastType = t'})
  1093         _ -> error $ "BuiltInFunCall lastType: " ++ show t
  1094         _ -> error $ "BuiltInFunCall lastType: " ++ show t
  1094     return $
  1095     return $
  1095         r <> parens (hsep . punctuate (char ',') $ ps)
  1096         r <> parens (hsep . punctuate (char ',') $ ps)
  1096 expr2C a = error $ "Don't know how to render " ++ show a
  1097 expr2C a = error $ "Don't know how to render " ++ show a
  1098 ref2CF :: Reference -> Bool -> State RenderState Doc
  1099 ref2CF :: Reference -> Bool -> State RenderState Doc
  1099 ref2CF (SimpleReference name) addParens = do
  1100 ref2CF (SimpleReference name) addParens = do
  1100     i <- id2C IOLookup name
  1101     i <- id2C IOLookup name
  1101     t <- gets lastType
  1102     t <- gets lastType
  1102     case t of
  1103     case t of
  1103          BTFunction _ _ rt -> do
  1104          BTFunction _ _ _ rt -> do
  1104              modify(\s -> s{lastType = rt})
  1105              modify(\s -> s{lastType = rt})
  1105              return $ if addParens then i <> parens empty else i --xymeng: removed parens
  1106              return $ if addParens then i <> parens empty else i --xymeng: removed parens
  1106          _ -> return $ i
  1107          _ -> return $ i
  1107 ref2CF r@(RecordField (SimpleReference _) (SimpleReference _)) addParens = do
  1108 ref2CF r@(RecordField (SimpleReference _) (SimpleReference _)) addParens = do
  1108     i <- ref2C r
  1109     i <- ref2C r
  1109     t <- gets lastType
  1110     t <- gets lastType
  1110     case t of
  1111     case t of
  1111          BTFunction _ _ rt -> do
  1112          BTFunction _ _ _ rt -> do
  1112              modify(\s -> s{lastType = rt})
  1113              modify(\s -> s{lastType = rt})
  1113              return $ if addParens then i <> parens empty else i
  1114              return $ if addParens then i <> parens empty else i
  1114          _ -> return $ i
  1115          _ -> return $ i
  1115 ref2CF r _ = ref2C r
  1116 ref2CF r _ = ref2C r
  1116 
  1117 
  1168     return $ (parens $ text "*" <> r)
  1169     return $ (parens $ text "*" <> r)
  1169 ref2C f@(FunCall params ref) = do
  1170 ref2C f@(FunCall params ref) = do
  1170     r <- fref2C ref
  1171     r <- fref2C ref
  1171     t <- gets lastType
  1172     t <- gets lastType
  1172     case t of
  1173     case t of
  1173         BTFunction _ bts t' -> do
  1174         BTFunction _ _ bts t' -> do
  1174             ps <- liftM (parens . hsep . punctuate (char ',')) $
  1175             ps <- liftM (parens . hsep . punctuate (char ',')) $
  1175                     if (length params) == (length bts) -- hot fix for pas2cSystem and pas2cRedo functions since they don't have params
  1176                     if (length params) == (length bts) -- hot fix for pas2cSystem and pas2cRedo functions since they don't have params
  1176                     then
  1177                     then
  1177                         mapM expr2CHelper (zip params bts)
  1178                         mapM expr2CHelper (zip params bts)
  1178                     else mapM expr2C params
  1179                     else mapM expr2C params
  1183                   _ -> error $ "ref2C FunCall erroneous type cast detected: " ++ show f ++ "\nType detected: " ++ show t ++ "\n" ++ show ref ++ "\n" ++ show params ++ "\n" ++ show t
  1184                   _ -> error $ "ref2C FunCall erroneous type cast detected: " ++ show f ++ "\nType detected: " ++ show t ++ "\n" ++ show ref ++ "\n" ++ show params ++ "\n" ++ show t
  1184     where
  1185     where
  1185     fref2C (SimpleReference name) = id2C (IOLookupFunction $ length params) name
  1186     fref2C (SimpleReference name) = id2C (IOLookupFunction $ length params) name
  1186     fref2C a = ref2C a
  1187     fref2C a = ref2C a
  1187     expr2CHelper :: (Expression, (Bool, BaseType)) -> State RenderState Doc
  1188     expr2CHelper :: (Expression, (Bool, BaseType)) -> State RenderState Doc
  1188     expr2CHelper (e, (_, BTFunction _ _ _)) = do
  1189     expr2CHelper (e, (_, BTFunction _ _ _ _)) = do
  1189         modify (\s -> s{isFunctionType = True})
  1190         modify (\s -> s{isFunctionType = True})
  1190         expr2C e
  1191         expr2C e
  1191     expr2CHelper (e, (isVar, _)) = if isVar then liftM (((<>) $ text "&") . parens) $ (expr2C e) else expr2C e
  1192     expr2CHelper (e, (isVar, _)) = if isVar then liftM (((<>) $ text "&") . parens) $ (expr2C e) else expr2C e
  1192 
  1193 
  1193 ref2C (Address ref) = do
  1194 ref2C (Address ref) = do
  1194     r <- ref2C ref
  1195     r <- ref2C ref
  1195     lt <- gets lastType
  1196     lt <- gets lastType
  1196     case lt of
  1197     case lt of
  1197         BTFunction True _ _ -> return $ text "&" <> parens r
  1198         BTFunction True _ _ _ -> return $ text "&" <> parens r
  1198         _ -> return $ text "&" <> parens r
  1199         _ -> return $ text "&" <> parens r
  1199 ref2C (TypeCast t'@(Identifier i _) expr) = do
  1200 ref2C (TypeCast t'@(Identifier i _) expr) = do
  1200     lt <- expr2C expr >> gets lastType
  1201     lt <- expr2C expr >> gets lastType
  1201     case (map toLower i, lt) of
  1202     case (map toLower i, lt) of
  1202         ("pchar", BTString) -> ref2C $ FunCall [expr] (SimpleReference (Identifier "_pchar" $ BTPointerTo BTChar))
  1203         ("pchar", BTString) -> ref2C $ FunCall [expr] (SimpleReference (Identifier "_pchar" $ BTPointerTo BTChar))