author | unc0rr |
Thu, 10 Nov 2011 23:14:40 +0300 | |
changeset 6317 | 83b93a2d2741 |
parent 6307 | 25cfd9f4a567 |
child 6355 | 734fed7aefd3 |
permissions | -rw-r--r-- |
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 |
|
6307 | 22 |
tvar2C (FunctionDeclaration (Identifier name) returnType Nothing) = |
23 |
type2C returnType <+> text (name ++ "();") |
|
6273 | 24 |
|
25 |
||
6307 | 26 |
tvar2C (FunctionDeclaration (Identifier name) returnType (Just phrase)) = |
27 |
type2C returnType <+> text (name ++ "()") |
|
6273 | 28 |
$$ |
29 |
phrase2C phrase |
|
30 |
tvar2C _ = empty |
|
31 |
||
6307 | 32 |
type2C :: TypeDecl -> Doc |
33 |
type2C UnknownType = text "void" |
|
34 |
type2C _ = text "<<type>>" |
|
6273 | 35 |
|
36 |
phrase2C :: Phrase -> Doc |
|
6307 | 37 |
phrase2C (Phrases p) = text "{" $+$ (nest 4 . vcat . map phrase2C $ p) $+$ text "}" |
6273 | 38 |
phrase2C (ProcCall (Identifier name) params) = text name <> parens (hsep . punctuate (char ',') . map expr2C $ params) <> semi |
6307 | 39 |
phrase2C (IfThenElse (expr) phrase1 mphrase2) = text "if" <> parens (expr2C expr) $+$ (phrase2C . wrapPhrase) phrase1 $+$ elsePart |
6273 | 40 |
where |
41 |
elsePart | isNothing mphrase2 = empty |
|
6307 | 42 |
| otherwise = text "else" $$ (phrase2C . wrapPhrase) (fromJust mphrase2) |
6277 | 43 |
phrase2C (Assignment ref expr) = ref2C ref <> text " = " <> expr2C expr <> semi |
6307 | 44 |
phrase2C (WhileCycle expr phrase) = text "while" <> parens (expr2C expr) $$ (phrase2C $ wrapPhrase phrase) |
45 |
phrase2C (SwitchCase expr cases mphrase) = text "switch" <> parens (expr2C expr) <> text "of" $+$ (nest 4 . vcat . map case2C) cases |
|
6273 | 46 |
where |
47 |
case2C :: (Expression, Phrase) -> Doc |
|
6307 | 48 |
case2C (e, p) = text "case" <+> parens (expr2C e) <> char ':' <> nest 4 (phrase2C p $+$ text "break;") |
6273 | 49 |
{- |
50 |
| RepeatCycle Expression Phrase |
|
51 |
| ForCycle |
|
52 |
-} |
|
53 |
phrase2C _ = empty |
|
54 |
||
6307 | 55 |
wrapPhrase p@(Phrases _) = p |
56 |
wrapPhrase p = Phrases [p] |
|
6273 | 57 |
|
58 |
expr2C :: Expression -> Doc |
|
59 |
expr2C (Expression s) = text s |
|
6307 | 60 |
expr2C (BinOp op expr1 expr2) = parens $ (expr2C expr1) <+> op2C op <+> (expr2C expr2) |
6277 | 61 |
expr2C (NumberLiteral s) = text s |
62 |
expr2C (HexNumber s) = text "0x" <> (text . map toLower $ s) |
|
63 |
expr2C (StringLiteral s) = doubleQuotes $ text s |
|
64 |
expr2C (Reference ref) = ref2C ref |
|
6307 | 65 |
expr2C (PrefixOp op expr) = op2C op <+> expr2C expr |
66 |
{- |
|
6277 | 67 |
| PostfixOp String Expression |
68 |
| CharCode String |
|
6273 | 69 |
-} |
70 |
expr2C _ = empty |
|
71 |
||
6307 | 72 |
|
73 |
ref2C :: Reference -> Doc |
|
6317
83b93a2d2741
Improve parsing of complex references like "a^[b[c], d]"
unc0rr
parents:
6307
diff
changeset
|
74 |
ref2C (ArrayElement exprs ref) = ref2C ref <> (brackets . hcat) (punctuate comma $ map expr2C exprs) |
6307 | 75 |
ref2C (SimpleReference (Identifier name)) = text name |
76 |
ref2C (RecordField (Dereference ref1) ref2) = ref2C ref1 <> text "->" <> ref2C ref2 |
|
77 |
ref2C (RecordField ref1 ref2) = ref2C ref1 <> text "." <> ref2C ref2 |
|
78 |
ref2C (Dereference ref) = parens $ text "*" <> ref2C ref |
|
6317
83b93a2d2741
Improve parsing of complex references like "a^[b[c], d]"
unc0rr
parents:
6307
diff
changeset
|
79 |
ref2C (FunCall params ref) = ref2C ref <> parens (hsep . punctuate (char ',') . map expr2C $ params) |
83b93a2d2741
Improve parsing of complex references like "a^[b[c], d]"
unc0rr
parents:
6307
diff
changeset
|
80 |
ref2C (Address ref) = text "&" <> ref2C ref |
6307 | 81 |
|
6275 | 82 |
op2C "or" = text "|" |
83 |
op2C "and" = text "&" |
|
6307 | 84 |
op2C "not" = text "!" |
85 |
op2C "xor" = text "^" |
|
6275 | 86 |
op2C "div" = text "/" |
87 |
op2C "mod" = text "%" |
|
6307 | 88 |
op2C "shl" = text "<<" |
89 |
op2C "shr" = text ">>" |
|
6275 | 90 |
op2C "<>" = text "!=" |
6277 | 91 |
op2C "=" = text "==" |
6275 | 92 |
op2C a = text a |
6273 | 93 |
|
94 |
maybeVoid "" = "void" |
|
95 |
maybeVoid a = a |