tools/pas2c/Pas2C.hs
changeset 10120 b7f632c12784
parent 10113 b26c2772e754
child 10121 8b65699beb56
equal deleted inserted replaced
10119:7e05a397602f 10120:b7f632c12784
   398     f "pointer" = BTPointerTo BTVoid
   398     f "pointer" = BTPointerTo BTVoid
   399     f "boolean" = BTBool
   399     f "boolean" = BTBool
   400     f "float" = BTFloat
   400     f "float" = BTFloat
   401     f "char" = BTChar
   401     f "char" = BTChar
   402     f "string" = BTString
   402     f "string" = BTString
       
   403     f "ansistring" = BTAString
   403     f _ = error $ "Unknown system type: " ++ show st
   404     f _ = error $ "Unknown system type: " ++ show st
   404 resolveType (PointerTo (SimpleType (Identifier i _))) = return . BTPointerTo $ BTUnresolved (map toLower i)
   405 resolveType (PointerTo (SimpleType (Identifier i _))) = return . BTPointerTo $ BTUnresolved (map toLower i)
   405 resolveType (PointerTo t) = liftM BTPointerTo $ resolveType t
   406 resolveType (PointerTo t) = liftM BTPointerTo $ resolveType t
   406 resolveType (RecordType tv mtvs) = do
   407 resolveType (RecordType tv mtvs) = do
   407     tvs <- mapM f (concat $ tv : fromMaybe [] mtvs)
   408     tvs <- mapM f (concat $ tv : fromMaybe [] mtvs)
   425 resolveType (DeriveType (InitPrefixOp _ e)) = initExpr2C e >> gets lastType
   426 resolveType (DeriveType (InitPrefixOp _ e)) = initExpr2C e >> gets lastType
   426 resolveType (DeriveType (BuiltInFunction{})) = return (BTInt True)
   427 resolveType (DeriveType (BuiltInFunction{})) = return (BTInt True)
   427 resolveType (DeriveType (InitReference (Identifier{}))) = return BTBool -- TODO: derive from actual type
   428 resolveType (DeriveType (InitReference (Identifier{}))) = return BTBool -- TODO: derive from actual type
   428 resolveType (DeriveType _) = return BTUnknown
   429 resolveType (DeriveType _) = return BTUnknown
   429 resolveType String = return BTString
   430 resolveType String = return BTString
       
   431 resolveType AString = return BTAString
   430 resolveType VoidType = return BTVoid
   432 resolveType VoidType = return BTVoid
   431 resolveType (Sequence ids) = return $ BTEnum $ map (\(Identifier i _) -> map toLower i) ids
   433 resolveType (Sequence ids) = return $ BTEnum $ map (\(Identifier i _) -> map toLower i) ids
   432 resolveType (RangeType _) = return $ BTVoid
   434 resolveType (RangeType _) = return $ BTVoid
   433 resolveType (Set t) = liftM BTSet $ resolveType t
   435 resolveType (Set t) = liftM BTSet $ resolveType t
   434 resolveType (VarParamType t) = liftM BTVarParam $ resolveType t
   436 resolveType (VarParamType t) = liftM BTVarParam $ resolveType t
   708 
   710 
   709 baseType2C :: String -> BaseType -> Doc
   711 baseType2C :: String -> BaseType -> Doc
   710 baseType2C _ BTFloat = text "float"
   712 baseType2C _ BTFloat = text "float"
   711 baseType2C _ BTBool = text "bool"
   713 baseType2C _ BTBool = text "bool"
   712 baseType2C _ BTString = text "string255"
   714 baseType2C _ BTString = text "string255"
       
   715 baseType2C _ BTAString = text "astring"
   713 baseType2C s a = error $ "baseType2C: " ++ show a ++ "\n" ++ s
   716 baseType2C s a = error $ "baseType2C: " ++ show a ++ "\n" ++ s
   714 
   717 
   715 type2C :: TypeDecl -> State RenderState (Doc -> Doc)
   718 type2C :: TypeDecl -> State RenderState (Doc -> Doc)
   716 type2C (SimpleType i) = liftM (\i' a -> i' <+> a) $ id2C IOLookup i
   719 type2C (SimpleType i) = liftM (\i' a -> i' <+> a) $ id2C IOLookup i
   717 type2C t = do
   720 type2C t = do
   720     modify (\st -> st{lastType = rt})
   723     modify (\st -> st{lastType = rt})
   721     return r
   724     return r
   722     where
   725     where
   723     type2C' VoidType = return (text "void" <+>)
   726     type2C' VoidType = return (text "void" <+>)
   724     type2C' String = return (text "string255" <+>)--return (text ("string" ++ show l) <+>)
   727     type2C' String = return (text "string255" <+>)--return (text ("string" ++ show l) <+>)
       
   728     type2C' AString = return (text "astring" <+>)
   725     type2C' (PointerTo (SimpleType i)) = do
   729     type2C' (PointerTo (SimpleType i)) = do
   726         i' <- id2C IODeferred i
   730         i' <- id2C IODeferred i
   727         lt <- gets lastType
   731         lt <- gets lastType
   728         case lt of
   732         case lt of
   729              BTRecord _ _ -> return $ \a -> text "struct __" <> i' <+> text "*" <+> a
   733              BTRecord _ _ -> return $ \a -> text "struct __" <> i' <+> text "*" <+> a
   810             case lt of
   814             case lt of
   811                 -- assume pointer to char for simplicity
   815                 -- assume pointer to char for simplicity
   812                 BTPointerTo _ -> do
   816                 BTPointerTo _ -> do
   813                     e <- expr2C $ Reference $ FunCall [Reference $ RefExpression expr] (SimpleReference (Identifier "pchar2str" BTUnknown))
   817                     e <- expr2C $ Reference $ FunCall [Reference $ RefExpression expr] (SimpleReference (Identifier "pchar2str" BTUnknown))
   814                     return $ r <+> text "=" <+> e <> semi
   818                     return $ r <+> text "=" <+> e <> semi
       
   819                 BTAString -> do
       
   820                     e <- expr2C $ Reference $ FunCall [Reference $ RefExpression expr] (SimpleReference (Identifier "astr2str" BTUnknown))
       
   821                     return $ r <+> text "=" <+> e <> semi
   815                 BTString -> do
   822                 BTString -> do
   816                     e <- expr2C expr
   823                     e <- expr2C expr
   817                     return $ r <+> text "=" <+> e <> semi
   824                     return $ r <+> text "=" <+> e <> semi
   818                 _ -> error $ "Assignment to string from " ++ show asgn
   825                 _ -> error $ "Assignment to string from " ++ show lt ++ "\n" ++ show asgn
       
   826         (BTAString, _) -> do
       
   827             void $ expr2C expr
       
   828             lt <- gets lastType
       
   829             case lt of
       
   830                 -- assume pointer to char for simplicity
       
   831                 BTPointerTo _ -> do
       
   832                     e <- expr2C $ Reference $ FunCall [Reference $ RefExpression expr] (SimpleReference (Identifier "pchar2astr" BTUnknown))
       
   833                     return $ r <+> text "=" <+> e <> semi
       
   834                 BTString -> do
       
   835                     e <- expr2C $ Reference $ FunCall [Reference $ RefExpression expr] (SimpleReference (Identifier "str2astr" BTUnknown))
       
   836                     return $ r <+> text "=" <+> e <> semi
       
   837                 BTAString -> do
       
   838                     e <- expr2C expr
       
   839                     return $ r <+> text "=" <+> e <> semi
       
   840                 _ -> error $ "Assignment to ansistring from " ++ show lt ++ "\n" ++ show asgn
   819         (BTArray _ _ _, _) -> do
   841         (BTArray _ _ _, _) -> do
   820             case expr of
   842             case expr of
   821                 Reference er -> do
   843                 Reference er -> do
   822                     void $ ref2C er
   844                     void $ ref2C er
   823                     exprT <- gets lastType
   845                     exprT <- gets lastType
   911 wrapPhrase p@(Phrases _) = p
   933 wrapPhrase p@(Phrases _) = p
   912 wrapPhrase p = Phrases [p]
   934 wrapPhrase p = Phrases [p]
   913 
   935 
   914 expr2C :: Expression -> State RenderState Doc
   936 expr2C :: Expression -> State RenderState Doc
   915 expr2C (Expression s) = return $ text s
   937 expr2C (Expression s) = return $ text s
   916 expr2C (BinOp op expr1 expr2) = do
   938 expr2C bop@(BinOp op expr1 expr2) = do
   917     e1 <- expr2C expr1
   939     e1 <- expr2C expr1
   918     t1 <- gets lastType
   940     t1 <- gets lastType
   919     e2 <- expr2C expr2
   941     e2 <- expr2C expr2
   920     t2 <- gets lastType
   942     t2 <- gets lastType
   921     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))
       
   945         ("+", BTAString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strappendA" (BTFunction False [(False, t1), (False, t2)] BTAString))
       
   946         (_, BTAString, _) -> error $ "unhandled bin op with ansistring on the left side: " ++ show bop
       
   947         (_, _, BTAString) -> error $ "unhandled bin op with ansistring on the right side: " ++ show bop
   922         ("+", BTString, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strconcat" (BTFunction False [(False, t1), (False, t2)] BTString))
   948         ("+", BTString, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strconcat" (BTFunction False [(False, t1), (False, t2)] BTString))
   923         ("+", BTString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strappend" (BTFunction False [(False, t1), (False, t2)] BTString))
   949         ("+", BTString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strappend" (BTFunction False [(False, t1), (False, t2)] BTString))
   924         ("+", BTChar, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strprepend" (BTFunction False [(False, t1), (False, t2)] BTString))
   950         ("+", BTChar, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strprepend" (BTFunction False [(False, t1), (False, t2)] BTString))
   925         ("+", BTChar, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_chrconcat" (BTFunction False [(False, t1), (False, t2)] BTString))
   951         ("+", BTChar, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_chrconcat" (BTFunction False [(False, t1), (False, t2)] BTString))
   926         ("==", BTString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strcomparec" (BTFunction False [(False, t1), (False, t2)] BTBool))
   952         ("==", BTString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strcomparec" (BTFunction False [(False, t1), (False, t2)] BTBool))
  1039     e' <- expr2C e
  1065     e' <- expr2C e
  1040     lt <- gets lastType
  1066     lt <- gets lastType
  1041     modify (\s -> s{lastType = BTInt True})
  1067     modify (\s -> s{lastType = BTInt True})
  1042     case lt of
  1068     case lt of
  1043          BTString -> return $ text "fpcrtl_Length" <> parens e'
  1069          BTString -> return $ text "fpcrtl_Length" <> parens e'
       
  1070          BTAString -> return $ text "fpcrtl_LengthA" <> parens e'
  1044          BTArray RangeInfinite _ _ -> error $ "length() called on variable size array " ++ show e'
  1071          BTArray RangeInfinite _ _ -> error $ "length() called on variable size array " ++ show e'
  1045          BTArray (RangeFromTo _ n) _ _ -> initExpr2C (BuiltInFunction "succ" [n])
  1072          BTArray (RangeFromTo _ n) _ _ -> initExpr2C (BuiltInFunction "succ" [n])
  1046          _ -> error $ "length() called on " ++ show lt
  1073          _ -> error $ "length() called on " ++ show lt
       
  1074 expr2C (BuiltInFunCall [e, e1, e2] (SimpleReference (Identifier "copy" _))) = do
       
  1075     e1' <- expr2C e1
       
  1076     e2' <- expr2C e2
       
  1077     e' <- expr2C e
       
  1078     lt <- gets lastType
       
  1079     let f name = return $ text name <> parens (hsep $ punctuate (char ',') [e', e1', e2'])
       
  1080     case lt of
       
  1081          BTString -> f "fpcrtl_copy"
       
  1082          BTAString -> f "fpcrtl_copyA"
       
  1083          _ -> error $ "copy() called on " ++ show lt
       
  1084      
  1047 expr2C (BuiltInFunCall params ref) = do
  1085 expr2C (BuiltInFunCall params ref) = do
  1048     r <- ref2C ref
  1086     r <- ref2C ref
  1049     t <- gets lastType
  1087     t <- gets lastType
  1050     ps <- mapM expr2C params
  1088     ps <- mapM expr2C params
  1051     case t of
  1089     case t of
  1089     t <- gets lastType
  1127     t <- gets lastType
  1090     case t of
  1128     case t of
  1091          (BTArray _ _ t') -> modify (\st -> st{lastType = t'})
  1129          (BTArray _ _ t') -> modify (\st -> st{lastType = t'})
  1092 --         (BTFunctionReturn _ (BTArray _ _ t')) -> modify (\st -> st{lastType = t'})
  1130 --         (BTFunctionReturn _ (BTArray _ _ t')) -> modify (\st -> st{lastType = t'})
  1093 --         (BTFunctionReturn _ (BTString)) -> modify (\st -> st{lastType = BTChar})
  1131 --         (BTFunctionReturn _ (BTString)) -> modify (\st -> st{lastType = BTChar})
  1094          (BTString) -> modify (\st -> st{lastType = BTChar})
  1132          BTString -> modify (\st -> st{lastType = BTChar})
       
  1133          BTAString -> modify (\st -> st{lastType = BTChar})
  1095          (BTPointerTo t) -> do
  1134          (BTPointerTo t) -> do
  1096                 t'' <- fromPointer (show t) =<< gets lastType
  1135                 t'' <- fromPointer (show t) =<< gets lastType
  1097                 case t'' of
  1136                 case t'' of
  1098                      BTChar -> modify (\st -> st{lastType = BTChar})
  1137                      BTChar -> modify (\st -> st{lastType = BTChar})
  1099                      a -> error $ "Getting element of " ++ show a ++ "\nReference: " ++ show ae
  1138                      a -> error $ "Getting element of " ++ show a ++ "\nReference: " ++ show ae
  1157         _ -> return $ text "&" <> parens r
  1196         _ -> return $ text "&" <> parens r
  1158 ref2C (TypeCast t'@(Identifier i _) expr) = do
  1197 ref2C (TypeCast t'@(Identifier i _) expr) = do
  1159     lt <- expr2C expr >> gets lastType
  1198     lt <- expr2C expr >> gets lastType
  1160     case (map toLower i, lt) of
  1199     case (map toLower i, lt) of
  1161         ("pchar", BTString) -> ref2C $ FunCall [expr] (SimpleReference (Identifier "_pchar" $ BTPointerTo BTChar))
  1200         ("pchar", BTString) -> ref2C $ FunCall [expr] (SimpleReference (Identifier "_pchar" $ BTPointerTo BTChar))
       
  1201         ("pchar", BTAString) -> ref2C $ FunCall [expr] (SimpleReference (Identifier "_pcharA" $ BTPointerTo BTChar))
  1162         ("shortstring", BTPointerTo _) -> ref2C $ FunCall [expr] (SimpleReference (Identifier "pchar2str" $ BTString))
  1202         ("shortstring", BTPointerTo _) -> ref2C $ FunCall [expr] (SimpleReference (Identifier "pchar2str" $ BTString))
  1163         (a, _) -> do
  1203         (a, _) -> do
  1164             e <- expr2C expr
  1204             e <- expr2C expr
  1165             t <- id2C IOLookup t'
  1205             t <- id2C IOLookup t'
  1166             return . parens $ parens t <> e
  1206             return . parens $ parens t <> e