Skip to content

Commit c4a5172

Browse files
committed
Merge branch 'sql-to-cpp' into cpp-unparsing-extensions
2 parents 46fb024 + d8efae6 commit c4a5172

2 files changed

Lines changed: 86 additions & 12 deletions

File tree

transpyle/cpp/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99
__all__ = ['CppParser', 'CppAstGeneralizer', 'Cpp14Unparser', 'CppSwigCompiler']
1010

11+
# Annotation to mark a class as a struct. (Python -> Cpp)
12+
def struct(f):
13+
return f
1114

1215
class CppBinder(Binder):
1316

transpyle/cpp/unparser.py

Lines changed: 83 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ def for_header_to_tuple(target, target_type, iter_) -> t.Tuple[
101101
init = typed_ast3.Assign(targets=[target], value=begin, type_comment=None)
102102
else:
103103
init = typed_ast3.AnnAssign(target=target, annotation=target_type, value=begin, simple=True)
104-
condition = typed_ast3.Compare(left=target, ops=[typed_ast3.Lt()], comparators=[end])
104+
condition = typed_ast3.Expr(typed_ast3.Compare(left=target, ops=[typed_ast3.Lt()], comparators=[end]))
105105
increment = typed_ast3.AugAssign(target=target, op=typed_ast3.Add(), value=step)
106106
return init, condition, increment
107107

@@ -133,6 +133,7 @@ def _unsupported_syntax(self, syntax, comment: str = None):
133133
self.fill('! TODO: unsupported syntax')
134134
unparsing_unsupported('C++', syntax, comment)
135135

136+
# Misusing ast.Index to signify reference types. Should probably fork typed-ast or something. The ast generalizer does something string based.
136137
def dispatch_type(self, type_hint):
137138
_LOG.debug('dispatching type hint %s', type_hint)
138139
if is_generic_type(type_hint):
@@ -154,8 +155,27 @@ def dispatch_type(self, type_hint):
154155
self.write('*')
155156
return
156157
if isinstance(type_hint, typed_ast3.Subscript):
157-
_LOG.error('encountered unsupported subscript form: %s',
158-
horast.unparse(type_hint).strip())
158+
if isinstance(type_hint.value, typed_ast3.Attribute) \
159+
and isinstance(type_hint.value.value, typed_ast3.Name):
160+
unparsed = horast.unparse(type_hint.value).strip()
161+
self.write(PY_TO_CPP_TYPES[unparsed])
162+
if unparsed == 'st.ndarray':
163+
self.write('<')
164+
sli = type_hint.slice
165+
self.write('>')
166+
return
167+
elif isinstance(type_hint.value, typed_ast3.Name):
168+
unparsed = horast.unparse(type_hint.value).strip()
169+
self.write(unparsed)
170+
self.write('<')
171+
if isinstance(type_hint.slice, typed_ast3.Subscript):
172+
self.dispatch_type(type_hint.slice)
173+
else:
174+
self.write(horast.unparse(type_hint.slice).strip())
175+
self.write(' >')
176+
if isinstance(type_hint.slice, typed_ast3.Index):
177+
self.write('&')
178+
return
159179
self._unsupported_syntax(type_hint)
160180
if isinstance(type_hint, typed_ast3.Attribute):
161181
if isinstance(type_hint.value, typed_ast3.Name):
@@ -169,12 +189,19 @@ def dispatch_type(self, type_hint):
169189
assert type_hint.value is None
170190
self.write('void')
171191
return
192+
172193
self.dispatch(type_hint)
194+
if isinstance(type_hint, typed_ast3.Index):
195+
if isinstance(type_hint.value, typed_ast3.Name):
196+
self.write('&')
173197

174198
def _Expr(self, tree):
175199
super()._Expr(tree)
176200
self.write(';')
177201

202+
def _Pass(self, tree):
203+
self.fill('/* pass */')
204+
178205
def _Import(self, t):
179206
self.fill('/* Python import')
180207
# raise NotImplementedError('not supported yet')
@@ -183,7 +210,11 @@ def _Import(self, t):
183210
# #include "boost/multi_array.hpp"
184211

185212
def _ImportFrom(self, t):
186-
raise NotImplementedError('not supported yet')
213+
self.fill('/* Python import')
214+
# raise NotImplementedError('not supported yet')
215+
super()._ImportFrom(t)
216+
self.fill('*/')
217+
# #include "boost/multi_array.hpp"
187218

188219
def _Assign(self, t):
189220
if self._context != 'for header':
@@ -213,7 +244,10 @@ def _AnnAssign(self, t):
213244
self._unsupported_syntax(t, 'which is not simple')
214245
self.dispatch_type(t.annotation)
215246
self.write(' ')
216-
self.dispatch(t.target)
247+
try:
248+
self.dispatch(t.target)
249+
except AttributeError as e:
250+
print(e)
217251
if t.value:
218252
self.write(' = ')
219253
self.dispatch(t.value)
@@ -229,9 +263,14 @@ def _Pass(self, t):
229263

230264
def _ClassDef(self, t):
231265
self.write('\n')
232-
if t.decorator_list:
233-
self._unsupported_syntax(t, 'with decorators')
234-
self.fill('class {}'.format(t.name))
266+
if len(t.decorator_list) > 1:
267+
self._unsupported_syntax(t, 'with too many decorators')
268+
269+
if is_struct:
270+
self.fill('struct {}'.format(t.name))
271+
else:
272+
self.fill('class {}'.format(t.name))
273+
235274
if t.bases:
236275
_LOG.warning('C++: assuming base classes are inherited as public')
237276
self.write(': public ')
@@ -248,7 +287,7 @@ def _ClassDef(self, t):
248287
else:
249288
comma = True
250289
self.dispatch(e)
251-
290+
252291
self.enter()
253292
for stmt in t.body:
254293
if isinstance(stmt, typed_ast3.FunctionDef):
@@ -507,12 +546,44 @@ def _arg(self, t):
507546
self.write(t.arg)
508547

509548
def _Comment(self, node):
510-
if node.eol:
511-
self.write(' //')
549+
if node.value.s.startswith("pragma"):
550+
if node.eol:
551+
self.write('\n#')
552+
else:
553+
self.fill('#')
512554
else:
513-
self.fill('//')
555+
if node.eol:
556+
self.write(' //')
557+
else:
558+
self.fill('//')
514559
self.write(node.value.s)
515560

561+
def _NameConstant(self, node):
562+
if node.value == 'False':
563+
self.write("false")
564+
elif node.value == 'True':
565+
self.write("true")
566+
elif node.value == 'None':
567+
self.write("null")
568+
else:
569+
self.write(node.value)
570+
571+
def _Str(self, node):
572+
self.write('"')
573+
self.write(node.s.replace('"', '\\"').replace("\0", "\\0").replace("\n", "\\n").replace("\t", "\\t").replace("\r", "\\r"))
574+
self.write('"')
575+
576+
def _Bytes(self, node):
577+
# Char
578+
if len(node.s) == 1:
579+
self.write("'")
580+
self.write(node.s.replace("'", "\\'").replace("\0", "\\0").replace("\n", "\\n").replace("\t", "\\t").replace("\r", "\\r"))
581+
self.write("'")
582+
else:
583+
self._Str(node)
584+
585+
def _unsupported_syntax(self, tree, comment: str = ''):
586+
raise SyntaxError('unparsing {}{} to C++ is not supported'.format(type(tree), comment))
516587

517588
class Cpp14HeaderUnparserBackend(Cpp14UnparserBackend):
518589

0 commit comments

Comments
 (0)