1 #!/usr/bin/env python2
2 """
3 cpython.py - temporary bridge
4 """
5 from __future__ import print_function
6
7 from _devbuild.gen.runtime_asdl import (
8 value,
9 value_e,
10 value_t,
11 )
12 from _devbuild.gen.syntax_asdl import loc
13 from core import error
14 from core import vm
15 from mycpp.mylib import log, NewDict, tagswitch
16
17 from typing import cast, Any, Dict, List
18
19 _ = log
20
21
22 # XXX this function should be removed once _EvalExpr is completeley refactored.
23 # Until then we'll need this as a bit of scaffolding to allow us to refactor one
24 # kind of expression at a time while still being able to type-check and run
25 # tests.
26 def _PyObjToValue(val):
27 # type: (Any) -> value_t
28
29 if val is None:
30 return value.Null
31
32 elif isinstance(val, bool):
33 return value.Bool(val)
34
35 elif isinstance(val, int):
36 return value.Int(val)
37
38 elif isinstance(val, float):
39 return value.Float(val)
40
41 elif isinstance(val, str):
42 return value.Str(val)
43
44 elif isinstance(val, list):
45 # Hack for converting back and forth
46 is_shell_array = True
47
48 shell_array = [] # type: List[str]
49 typed_array = [] # type: List[value_t]
50
51 for elem in val:
52 if elem is None:
53 shell_array.append(elem)
54 typed_array.append(value.Null)
55
56 elif isinstance(elem, str):
57 shell_array.append(elem)
58 typed_array.append(value.Str(elem))
59
60 elif isinstance(elem, value_t): # Does this happen?
61 is_shell_array = False
62 typed_array.append(elem)
63
64 else:
65 is_shell_array = False
66 typed_array.append(_PyObjToValue(elem))
67 #typed_array.append(elem)
68
69 #if is_shell_array:
70 # return value.BashArray(shell_array)
71 return value.List(typed_array)
72
73 elif isinstance(val, xrange):
74 # awkward, but should go away once everything is typed...
75 l = list(val)
76 if len(l) > 1:
77 return value.Range(l[0], l[-1])
78
79 # Empty range
80 return value.Range(0, 0)
81
82 elif isinstance(val, dict):
83 is_shell_dict = True
84
85 shell_dict = NewDict() # type: Dict[str, str]
86 typed_dict = NewDict() # type: Dict[str, value_t]
87
88 for k, v in val.items():
89 if isinstance(v, str):
90 shell_dict[k] = v
91 typed_dict[k] = value.Str(v)
92
93 elif isinstance(v, value_t): # Does this happen?
94 is_shell_dict = False
95 typed_dict[k] = v
96
97 else:
98 is_shell_dict = False
99 typed_dict[k] = _PyObjToValue(v)
100 #typed_dict[k] = v
101
102 if is_shell_dict:
103 return value.BashAssoc(shell_dict)
104 else:
105 return value.Dict(typed_dict)
106
107 elif isinstance(val, value.Eggex):
108 return val # passthrough
109
110 elif isinstance(val, value.Block):
111 return val # passthrough
112
113 elif isinstance(val, vm._Callable) or callable(val):
114 return value.Func(val)
115
116 else:
117 raise error.Expr(
118 'Trying to convert unexpected type to value_t: %r' % val,
119 loc.Missing)
120
121
122 def _ValueToPyObj(val):
123 # type: (value_t) -> Any
124
125 if not isinstance(val, value_t):
126 raise AssertionError(val)
127
128 UP_val = val
129 with tagswitch(val) as case:
130 if case(value_e.Null):
131 return None
132
133 elif case(value_e.Undef):
134 return None
135
136 elif case(value_e.Bool):
137 val = cast(value.Bool, UP_val)
138 return val.b
139
140 elif case(value_e.Int):
141 val = cast(value.Int, UP_val)
142 return val.i
143
144 elif case(value_e.Float):
145 val = cast(value.Float, UP_val)
146 return val.f
147
148 elif case(value_e.Str):
149 val = cast(value.Str, UP_val)
150 return val.s
151
152 elif case(value_e.BashArray):
153 val = cast(value.BashArray, UP_val)
154 return val.strs
155
156 elif case(value_e.List):
157 val = cast(value.List, UP_val)
158 return list(map(_ValueToPyObj, val.items))
159
160 elif case(value_e.BashAssoc):
161 val = cast(value.BashAssoc, UP_val)
162 return val.d
163
164 elif case(value_e.Dict):
165 val = cast(value.Dict, UP_val)
166 d = NewDict() # type: Dict[str, value_t]
167 for k, v in val.d.items():
168 d[k] = _ValueToPyObj(v)
169 return d
170
171 elif case(value_e.Eggex):
172 return val # passthrough
173
174 elif case(value_e.Range):
175 val = cast(value.Range, UP_val)
176 return xrange(val.lower, val.upper)
177
178 elif case(value_e.Func):
179 val = cast(value.Func, UP_val)
180 return val.callable
181
182 elif case(value_e.Block):
183 return val # passthrough
184
185 else:
186 raise error.Expr(
187 'Trying to convert unexpected type to pyobj: %r' % val,
188 loc.Missing)