root / src / Ganeti / Hs2Py / GenOpCodes.hs @ f3e38e89
History | View | Annotate | Download (2.6 kB)
1 |
{-| GenOpCodes handles Python opcode generation. |
---|---|
2 |
|
3 |
GenOpCodes contains the helper functions that generate the Python |
4 |
opcodes as strings from the Haskell opcode description. |
5 |
|
6 |
-} |
7 |
|
8 |
{- |
9 |
|
10 |
Copyright (C) 2011, 2012, 2013 Google Inc. |
11 |
|
12 |
This program is free software; you can redistribute it and/or modify |
13 |
it under the terms of the GNU General Public License as published by |
14 |
the Free Software Foundation; either version 2 of the License, or |
15 |
(at your option) any later version. |
16 |
|
17 |
This program is distributed in the hope that it will be useful, but |
18 |
WITHOUT ANY WARRANTY; without even the implied warranty of |
19 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
20 |
General Public License for more details. |
21 |
|
22 |
You should have received a copy of the GNU General Public License |
23 |
along with this program; if not, write to the Free Software |
24 |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
25 |
02110-1301, USA. |
26 |
|
27 |
-} |
28 |
|
29 |
module Ganeti.Hs2Py.GenOpCodes (showPyClasses) where |
30 |
|
31 |
import Data.List (intercalate, zipWith4) |
32 |
|
33 |
import Ganeti.OpCodes |
34 |
import Ganeti.THH |
35 |
|
36 |
-- | Generates the Python class docstring. |
37 |
pyClassDoc :: String -> String |
38 |
pyClassDoc doc |
39 |
| length (lines doc) > 1 = |
40 |
" \"\"\"" ++ doc ++ "\n\n" ++ " \"\"\"" ++ "\n" |
41 |
| otherwise = |
42 |
" \"\"\"" ++ doc ++ "\"\"\"" ++ "\n" |
43 |
|
44 |
-- | Generates an opcode parameter in Python. |
45 |
pyClassField :: String -> String -> Maybe PyValueEx -> String -> String |
46 |
pyClassField name typ Nothing doc = |
47 |
"(" ++ intercalate ", " [show name, "None", typ, show doc] ++ ")" |
48 |
|
49 |
pyClassField name typ (Just (PyValueEx def)) doc = |
50 |
"(" ++ intercalate ", " [show name, showValue def, typ, show doc] ++ ")" |
51 |
|
52 |
-- | Comma intercalates and indents opcode parameters in Python. |
53 |
intercalateIndent :: [String] -> String |
54 |
intercalateIndent xs = intercalate "," (map ("\n " ++) xs) |
55 |
|
56 |
-- | Generates an opcode as a Python class. |
57 |
showPyClass :: OpCodeDescriptor -> String |
58 |
showPyClass (name, typ, doc, fields, types, defs, docs, dsc) = |
59 |
let |
60 |
baseclass |
61 |
| name == "OpInstanceMultiAlloc" = "OpInstanceMultiAllocBase" |
62 |
| otherwise = "OpCode" |
63 |
opDscField |
64 |
| null dsc = "" |
65 |
| otherwise = " OP_DSC_FIELD = " ++ show dsc ++ "\n" |
66 |
withLU |
67 |
| name == "OpTestDummy" = "\n WITH_LU = False" |
68 |
| otherwise = "" |
69 |
in |
70 |
"class " ++ name ++ "(" ++ baseclass ++ "):" ++ "\n" ++ |
71 |
pyClassDoc doc ++ |
72 |
opDscField ++ |
73 |
" OP_PARAMS = [" ++ |
74 |
intercalateIndent (zipWith4 pyClassField fields types defs docs) ++ |
75 |
"\n ]" ++ "\n" ++ |
76 |
" OP_RESULT = " ++ typ ++ |
77 |
withLU ++ "\n\n" |
78 |
|
79 |
-- | Generates all opcodes as Python classes. |
80 |
showPyClasses :: String |
81 |
showPyClasses = concatMap showPyClass pyClasses |