def transform_special_f(self, n, in_block=False, assignment=None): for a in n.params: if general_type(a.pseudo_type) == 'Tuple': s = safe_serialize_type(a.pseudo_type) if s not in self.tuple_definitions: self.tuple_definitions[s] = a, Node( 'class_definition', name=a.name, base=None, attrs=[ Node('immutable_class_attr', name='item%d' % j, is_public=True, pseudo_type=q) for j, q in enumerate(a.pseudo_type[1:]) ], constructor=None, methods=[]) if n.type == 'constructor': if self.current_class.name not in self.function_index: self.function_index[self.current_class.name] = {} self.function_index[self.current_class.name]['__init__'] = n elif n.type == 'method_definition': if self.current_class.name not in self.function_index: self.function_index[self.current_class.name] = {} self.function_index[self.current_class.name][n.name] = n else: self.function_index['functions'][n.name] = n return n
def normalize(f, from_, to): if to.type == 'int': if to.value < 0: if from_.type != 'int': return Node('binary_op', op='-', left=Node('binary_op', op='-', left=attr(f, 'Length', 'Int'), right=to, pseudo_type='Int'), right=from_, pseudo_type='Int') else: return Node('binary_op', op='-', left=attr(f, 'Length', 'Int'), right=to_node(-to.value + from_.value), pseudo_type='Int') else: if from_.type != 'int': return Node('binary_op', op='-', left=to, right=from_, pseudo_type='Int') else: return to_node(to.value - from_.value) else: if from_.type == 'int' and from_.value == 0: return to else: return Node('binary_op', op='-', left=to, right=from_, pseudo_type='Int')
def as_expression(self, target=None): _index = local('_index', 'Int') name = self.temp_name(target or self.default) z = local(name, pseudo_type=self.args[0].pseudo_type) if self.args[1].type == 'anonymous_function': block_test = self.args[1].block[-1].value initial = self.args[1].block[:-1] z_arg = self.args[1].params[0] else: z_arg = local('_value', z.pseudo_type[1]) block_test = call(self.args[1], z_arg, 'Boolean') initial = [] return [ Node('_go_declaration', decl=name, decl_type=z.pseudo_type), Node('for_statement', sequences=Node('for_sequence_with_index', sequence=self.args[0]), iterators=Node('for_iterator_with_index', index=_index, iterator=z_arg), block=initial + [ Node('if_statement', test=block_test, block=[ assignment( z, call('append', [z, z_arg], z.pseudo_type)) ], otherwise=None) ]), z ], None
def as_expression(self, target=None): t = self.temp_name(target or 'accumulator') if self.args[1].type == 'anonymous_function': initial = self.args[1].block[:-1] element = self.args[1].params[1] if target is None: target = self.args[1].params[0] elif target.name != self.args[1].params[0].name: self.args[1].block = ReduceRewriter( self.args[1].params[0].name, target.name).transform(self.args[1].block) self.args[1].params[0] = target block_result = self.args[1].block[-1].value else: initial = [] element = local('_element', self.args[0].pseudo_type[1]) if target is None: target = local(t, self.args[1].pseudo_type[-1]) block_result = call(self.args[1], [element, target], target.pseudo_type) return [ assignment(target, self.args[2]), Node('for_statement', sequences=Node('for_sequence', sequence=self.args[0]), iterators=Node('for_iterator', iterator=element), block=initial + [assignment(target, block_result)]), target ], None
def expand_slice(receiver, from_=None, to=None, pseudo_type=None): if from_: if pseudo_type: #to if from_.type == 'int' and from_.value == 0: return Node('_py_slice_to', sequence=receiver, to=to, pseudo_type=pseudo_type) else: return Node('_py_slice', sequence=receiver, from_=from_, to=to, pseudo_type=pseudo_type) else: pseudo_type = to return Node('_py_slice_from', sequence=receiver, from_=from_, pseudo_type=pseudo_type) elif to: return Node('_py_slice_to', sequence=receiver, to=to, pseudo_type=pseudo_type) else: return None
def split(f, delimiter, pseudo_type): if delimiter.type == 'string' and (len(delimiter.value) == 1 or delimiter.value == '\\n'): return method_call(f, 'Split', [Node('char', value=delimiter.value, pseudo_type='Char')], ['List', 'String']) else: return method_call(f, 'Split', [Node('array', elements=[delimiter]), attr(typename('StringSplitOptions', 'Library'), 'None', 'CSharpNone')], pseudo_type=['List', 'String'])
def as_expression(self): return [ Node('_cpp_declaration', name='_dummy', args=[], decl_type='String', pseudo_type='Void'), Node('_cpp_cin', args=[local('_dummy', 'String')]) ], None
def expand_slice(receiver, from_, to, pseudo_type=None): return method_call( method_call( receiver, 'Take', [Node('binary_op', op='-', left=attr(receiver, 'Length', 'Int'), right=to_node(-to.value), pseudo_type='Int') if to.type == 'int' and to.value < 0 else to], pseudo_type=pseudo_type), 'Drop', [Node('binary_op', op='-', left=attr(receiver, 'Length', 'Int'), right=to_node(-from_.value), pseudo_type='Int') if from_.type == 'int' and from_.value < 0 else from_], pseudo_type=pseudo_type)
def l(receiver, *args): f, *args, pseudo_type = args return Node('_rb_method_call_block', receiver=receiver, message=name, args=args, block=Node('_rb_block', params=f.params, block=f.block, pseudo_type=f.pseudo_type), pseudo_type=pseudo_type)
def _expand_api(self, api, receiver, args, pseudo_type, equivalent): ''' the heart of api translation dsl function or <z>(<arg>, ..) can be expanded, <z> can be just a name for a global function, or #name for method, <arg> can be %{self} for self or %{n} for nth arg ''' if callable(api): if receiver: return api(receiver, *(args + [pseudo_type])) else: return api(*(args + [pseudo_type])) elif isinstance(api, str): if '(' in api: call_api, arg_code = api[:-1].split('(') new_args = [ self._parse_part(a.strip(), receiver, args, equivalent) for a in arg_code.split(',') ] else: call_api, arg_code = api, '' new_args = args if '#' in call_api: a, b = call_api.split('#') method_receiver = self._parse_part( a, receiver, args, equivalent) if a else receiver return method_call(method_receiver, b, new_args, pseudo_type=pseudo_type) elif '.' in call_api: a, b = call_api.split('.') static_receiver = self._parse_part( a, receiver, args, equivalent) if a else receiver if b[-1] != '!': return Node('static_call', receiver=static_receiver, message=b, args=new_args, pseudo_type=pseudo_type) else: return Node('attr', object=static_receiver, attr=b[:-1], pseudo_type=pseudo_type) else: if receiver: return call(call_api, [receiver] + new_args, pseudo_type=pseudo_type) else: return call(call_api, new_args, pseudo_type=pseudo_type) else: raise PseudoDSLError('%s not supported by api dsl' % str(api))
def transformer(receiver, param, pseudo_type): if not reversed: return Node('binary_op', op=op, left=receiver, right=param, pseudo_type=pseudo_type) return Node('binary_op', op=op, left=param, right=receiver, pseudo_type=pseudo_type)
def x(receiver, test, pseudo_type): return call(local(method, ['Function', test.pseudo_type, 'Boolean']), [ Node('_py_generatorcomp', sequences=Node('for_sequence', sequence=receiver), iterators=Node('for_iterator', iterator=local(test.params[0].name, test.pseudo_type[1])), block=test.block[0].value, test=None, pseudo_type=['PyGenerator', 'Boolean']) ], pseudo_type='Boolean')
def as_expression(self): t = self.temp_name('', False) target = local(t, 'Int') return [ Node('_go_multi_assignment', targets=[target, local('_', 'Error')], values=[ Node('static_call', receiver=local('strconv', 'Library'), message='Atoi', args=[self.args[0]], pseudo_type=['GoResultWithError', 'Int']) ]), target ], None
def as_expression(self): l = local(self.temp_name(''), 'String') return [ Node('_go_multi_assignment', targets=[l, local('_', 'Error')], values=[ Node('static_call', message='ReadFile', receiver=local('ioutil', 'Library'), args=self.args, pseudo_type='MaybeBytez') ]), call('string', [l], 'String') ], None
def as_expression(self, target=None): t = self.temp_name(target or self.default) element = '_%sElement' % extract_name(self.args[0], t) element = local(element, self.args[0].pseudo_type[1]) if target is None: target = local(t, 'Int') return [ assignment(target, Node('boolean', value='false', pseudo_type='Boolean')), Node('for_statement', sequences=Node('for_sequence', sequence=self.args[0]), iterators=Node('for_iterator', iterator=element), block=[ Node('if_statement', test=Node('comparison', op='==', pseudo_type='Boolean', left=element, right=self.args[1]), block=[ assignment( target, Node('boolean', value='true', pseudo_type='Boolean')), Node('break_') ], otherwise=None, pseudo_type='Void') ]), target ], None
def as_expression(self): return [ Node('_go_multi_assignment', targets=[ local('_', self.args[0].pseudo_type[1]), local(self.temp_name(''), pseudo_type='Boolean') ], values=[ Node('index', sequence=self.args[0], index=self.args[1], pseudo_type='MaybeElement') ]), local(self.temp_name(''), pseudo_type='Boolean') ], None
def transform_assignment(self, node, in_block=False, assignment=None): if node.value.type == 'binary_op' and node.target == node.value.left: return Node('aug_assignment', op=node.value.op, target=node.target, value=node.value.right) else: return node
def as_expression(self): return [Node('static_call', receiver=typename('Console', 'Library'), message='WriteLine', args=[arg], pseudo_type='Void') for arg in self.args], None
def gen(self, custom_exceptions, ast): return generate( Node('module', definitions=[], dependencies=[], constants=[], custom_exceptions=custom_exceptions, main=ast if isinstance(ast, list) else [ast]), self._language).rstrip()
def as_expression(self): return [ Node( '_py_with', call=call('open', [self.args[0], to_node('r')], 'File'), context='_f', block=[method_call(local('_f', 'File'), 'read', [], 'String')], pseudo_type='Void') ], None
def transform_new_instance(self, node, in_block=False, assignment=None): if isinstance( node.pseudo_type, str ) and node.pseudo_type in self.classes_with_simple_initializers: return Node('_go_simple_initializer', name=typename(node.pseudo_type, node.pseudo_type), args=node.args) else: return node
def zip_iterators(self, node, depth): return '\n'.join( '%sauto %s = %s;' % (self.offset(depth) if j else '', q.name, self._generate_node( Node('index', sequence=node.sequences.sequences[j], index=local('_index', 'Int'), pseudo_type=node.sequences.sequences[j].pseudo_type[1]))) for j, q in enumerate(node.iterators.iterators))
def as_expression(self): return [], Node('_py_with', call=call('open', [self.args[0], to_node('w')], 'File'), context='_f', block=[ method_call(local('_f', 'File'), 'write', [self.args[1]], 'Void') ], pseudo_type='Void')
def with_constructor(self, t): t = t[1] t.name = camel_case(t.name) if self.all == False: t.constructor = Node( 'constructor', params=[ local(field.name, field.pseudo_type) for field in t.attrs ], this=typename(t.name), pseudo_type=['Function'] + [field.pseudo_type for field in t.attrs] + [t.name], return_type=t.name, block=[ assignment(Node('instance_variable', name=field.name, pseudo_type=field.pseudo_type), local(field.name, field.pseudo_type), first_mention=False) for field in t.attrs ]) return t
def as_expression(self, target=None): _index = local('_index', 'Int') name = self.temp_name(target or self.default) z = local(name, pseudo_type=['List', self.args[-1].pseudo_type[2]]) z_arg = local('_value', z.pseudo_type[1]) return [ assignment( z, Node('_go_make_slice', slice_type=z.pseudo_type, length=call('len', [self.args[0]], 'Int'))), Node( 'for_statement', sequences=Node('for_sequence_with_index', sequence=self.args[0]), iterators=Node( 'for_iterator_with_index', index=_index, iterator=self.args[1].params[0] if self.args[1].type == 'anonymous_function' else z_arg), block=self.args[1].block[:-1] + [ assignment( Node('index', sequence=z, index=_index, pseudo_type=z.pseudo_type[1]), self.args[1].block[-1].value) ] if self.args[1].type == 'anonymous_function' else assignment( Node('index', sequence=z, index=_index, pseudo_type=z.pseudo_type[1]), call(self.args[1], z_arg, z.pseudo_type[1]))), z ], None
def as_expression(self, target=None): t = self.temp_name(target or self.default) element = '_%sElement' % extract_name(self.args[0], t) j = '_%sIndex' % extract_name(self.args[0], t) element = local(element, self.args[0].pseudo_type[1]) j = local(j, 'Int') if target is None: target = local(t, 'Int') return [ assignment(target, to_node(-1)), Node('for_statement', sequences=Node('for_sequence_with_index', sequence=self.args[0]), iterators=Node('for_iterator_with_index', index=j, iterator=element), block=[ Node('if_statement', test=Node('comparison', op='==', pseudo_type='Boolean', left=element, right=self.args[1]), block=[assignment(target, j), Node('break_')], otherwise=None) ]), target ], None
def expand_slice(receiver, from_=None, to=None, pseudo_type=None): if from_: if pseudo_type: #to return Node('_rb_slice', sequence=receiver, from_=from_, to=to, pseudo_type=pseudo_type) else: pseudo_type = to return Node('_rb_slice_from', sequence=receiver, from_=from_, pseudo_type=pseudo_type) elif to: return Node('_rb_slice', sequence=receiver, from_=to_node(0), to=to, pseudo_type=pseudo_type) else: return None
def convert_to_syntax_tree(tree): if isinstance(tree, dict) and 'type' in tree: return Node( tree['type'], **{ k: convert_to_syntax_tree(v) for k, v in tree.items() if k != 'type' }) elif isinstance(tree, dict): return {k: convert_to_syntax_tree(v) for k, v in tree.items()} elif isinstance(tree, list): return [convert_to_syntax_tree(v) for v in tree] else: return tree
def transform_tuple(self, node, in_block=False, assignment=None): name = safe_serialize_type(node.pseudo_type) if name in self.tuple_definitions: return Node('simple_initializer', name=camel_case(self.tuple_definitions[name][0]), args=node.elements) else: if self.all: # go: we have to change all tuples self.tuple_definitions[name] = Node( 'class_definition', name=name, base=None, constructor=None, attrs=[ Node('immutable_class_attr', name='item%d' % j, is_public=True, pseudo_type=q) for j, q in enumerate(node.pseudo_type[1:]) ], methods=[]) else: # c#: we can just use tuples return node
def pad(f, count, fill, pseudo_type): return method_call( method_call( f, 'PadLeft', [Node('binary_op', op='+', left=Node('binary_op', op='/', left=Node('binary_op', op='-', left=count, right=attr(f, 'Length', 'Int'), pseudo_type='Int'), right=to_node(2), pseudo_type='Int'), right=attr(f, 'Length', 'Int'), pseudo_type='Int'), fill], pseudo_type='String'), 'PadRight', [count, fill], 'String')