6273
|
1 |
module Pas2C where
|
|
2 |
|
|
3 |
import PascalParser
|
|
4 |
import Text.PrettyPrint.HughesPJ
|
|
5 |
import Data.Maybe
|
6277
|
6 |
import Data.Char
|
6273
|
7 |
|
|
8 |
|
|
9 |
pascal2C :: PascalUnit -> Doc
|
|
10 |
pascal2C (Unit unitName interface implementation init fin) = implementation2C implementation
|
|
11 |
|
|
12 |
|
|
13 |
implementation2C :: Implementation -> Doc
|
|
14 |
implementation2C (Implementation uses tvars) = typesAndVars2C tvars
|
|
15 |
|
|
16 |
|
|
17 |
typesAndVars2C :: TypesAndVars -> Doc
|
|
18 |
typesAndVars2C (TypesAndVars ts) = vcat $ map tvar2C ts
|
|
19 |
|
|
20 |
|
|
21 |
tvar2C :: TypeVarDeclaration -> Doc
|
|
22 |
tvar2C (FunctionDeclaration (Identifier name) (Identifier returnType) Nothing) =
|
|
23 |
text $ maybeVoid returnType ++ " " ++ name ++ "();"
|
|
24 |
|
|
25 |
|
|
26 |
tvar2C (FunctionDeclaration (Identifier name) (Identifier returnType) (Just phrase)) =
|
|
27 |
text (maybeVoid returnType ++ " " ++ name ++ "()")
|
|
28 |
$$
|
|
29 |
phrase2C phrase
|
|
30 |
tvar2C _ = empty
|
|
31 |
|
|
32 |
|
|
33 |
phrase2C :: Phrase -> Doc
|
|
34 |
phrase2C (Phrases p) = braces . nest 4 . vcat . map phrase2C $ p
|
|
35 |
phrase2C (ProcCall (Identifier name) params) = text name <> parens (hsep . punctuate (char ',') . map expr2C $ params) <> semi
|
6274
|
36 |
phrase2C (IfThenElse (expr) phrase1 mphrase2) = text "if" <> parens (expr2C expr) $$ (braces . nest 4 . phrase2C) phrase1 $+$ elsePart
|
6273
|
37 |
where
|
|
38 |
elsePart | isNothing mphrase2 = empty
|
|
39 |
| otherwise = text "else" $$ (braces . nest 4 . phrase2C) (fromJust mphrase2)
|
6277
|
40 |
phrase2C (Assignment ref expr) = ref2C ref <> text " = " <> expr2C expr <> semi
|
6273
|
41 |
phrase2C (WhileCycle expr phrase) = text "while" <> parens (expr2C expr) $$ nest 4 (phrase2C phrase)
|
|
42 |
phrase2C (SwitchCase expr cases mphrase) = text "switch" <> parens (expr2C expr) <> text "of" $$ (nest 4 . vcat . map case2C) cases
|
|
43 |
where
|
|
44 |
case2C :: (Expression, Phrase) -> Doc
|
|
45 |
case2C (e, p) = text "case" <+> parens (expr2C e) <> char ':' <> nest 4 (phrase2C p $$ text "break;")
|
|
46 |
{-
|
|
47 |
| RepeatCycle Expression Phrase
|
|
48 |
| ForCycle
|
|
49 |
| SwitchCase Expression [(Expression, Phrase)] (Maybe Phrase)
|
|
50 |
| Assignment Identifier Expression
|
|
51 |
-}
|
|
52 |
phrase2C _ = empty
|
|
53 |
|
6277
|
54 |
ref2C :: Reference -> Doc
|
|
55 |
ref2C (ArrayElement (Identifier name) expr) = text name <> brackets (expr2C expr)
|
|
56 |
ref2C (SimpleReference (Identifier name)) = text name
|
|
57 |
ref2C (RecordField ref1 ref2) = ref2C ref1 <> text "." <> ref2C ref2
|
|
58 |
ref2C (Dereference ref) = parens $ text "*" <> ref2C ref
|
6273
|
59 |
|
|
60 |
expr2C :: Expression -> Doc
|
|
61 |
expr2C (Expression s) = text s
|
6277
|
62 |
expr2C (FunCall ref params) = ref2C ref <> parens (hsep . punctuate (char ',') . map expr2C $ params)
|
6273
|
63 |
expr2C (BinOp op expr1 expr2) = (expr2C expr1) <+> op2C op <+> (expr2C expr2)
|
6277
|
64 |
expr2C (NumberLiteral s) = text s
|
|
65 |
expr2C (HexNumber s) = text "0x" <> (text . map toLower $ s)
|
|
66 |
expr2C (StringLiteral s) = doubleQuotes $ text s
|
|
67 |
expr2C (Address ref) = text "&" <> ref2C ref
|
|
68 |
expr2C (Reference ref) = ref2C ref
|
|
69 |
|
|
70 |
{-
|
6273
|
71 |
| PrefixOp String Expression
|
6277
|
72 |
| PostfixOp String Expression
|
|
73 |
| CharCode String
|
6273
|
74 |
-}
|
|
75 |
expr2C _ = empty
|
|
76 |
|
6275
|
77 |
op2C "or" = text "|"
|
|
78 |
op2C "and" = text "&"
|
|
79 |
op2C "div" = text "/"
|
|
80 |
op2C "mod" = text "%"
|
|
81 |
op2C "<>" = text "!="
|
6277
|
82 |
op2C "=" = text "=="
|
6275
|
83 |
op2C a = text a
|
6273
|
84 |
|
|
85 |
maybeVoid "" = "void"
|
|
86 |
maybeVoid a = a
|