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 as_expression(self): e = self.temp_name('') e_singular = self.singular_name() e_index = self.index() if self.field == 'keys': field_type = self.args[0].pseudo_type[1] first = local(e_singular, field_type) second = local('_', self.args[0].pseudo_type[2]) else: field_type = self.args[0].pseudo_type[2] first = local('_', self.args[0].pseudo_type[1]) second = local(e_singular, field_type) e = local(e, field_type) e_singular = local(e_singular, field_type) return [assignment(e, Node('_go_make_slice', slice_type=['List', field_type], length=call('len', [self.args[0]], 'Int'), pseudo_type=['List', field_type])), assignment(e_index, to_node(0)), Node('for_statement', sequences=Node('for_sequence_with_items', sequence=self.args[0]), iterators=Node('for_iterator_with_items', key=first, value=second), block=[ assignment( Node('index', sequence=e, index=e_index, pseudo_type=field_type), e_singular), Node('aug_assignment', op='+', target=e_index, value=to_node(1))]), e], None def as_assignment(self, target): e = self.as_expression()[0] e[3] = assignment(target, e) return e
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 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 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 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) 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, 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 expand_set_slice(receiver, from_=None, to=None, value=None, pseudo_type=None): s = expand_slice(receiver, from_, to, pseudo_type) return assignment(s, value)
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): e = self.temp_name('') e_singular = self.singular_name() e_index = self.index() if self.field == 'keys': field_type = self.args[0].pseudo_type[1] first = local(e_singular, field_type) second = local('_', self.args[0].pseudo_type[2]) else: field_type = self.args[0].pseudo_type[2] first = local('_', self.args[0].pseudo_type[1]) second = local(e_singular, field_type) e = local(e, field_type) e_singular = local(e_singular, field_type) return [ assignment( e, Node('_go_make_slice', slice_type=['List', field_type], length=call('len', [self.args[0]], 'Int'), pseudo_type=['List', field_type])), assignment(e_index, to_node(0)), Node('for_statement', sequences=Node('for_sequence_with_items', sequence=self.args[0]), iterators=Node('for_iterator_with_items', key=first, value=second), block=[ assignment( Node('index', sequence=e, index=e_index, pseudo_type=field_type), e_singular), Node('aug_assignment', op='+', target=e_index, value=to_node(1)) ]), e ], None def as_assignment(self, target): e = self.as_expression()[0] e[3] = assignment(target, e) return e
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) 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 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 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 transform_constructor(self, node, in_block=False, assignment=None): simple_initializer = True simple_args = [] for e, a in zip(node.block, self.current_class.attrs): if e.type == 'assignment' and e.target.type == 'instance_variable' and e.target.name == a.name: simple_args.append(e.value) if e.value.type != 'local' or e.value.name != a.name: simple_initializer = False else: break if simple_initializer: self.classes_with_simple_initializers.add(self.current_class.name) return [] else: ass = assignment(Node('this', pseudo_type=self.current_class.name), Node('_go_simple_initializer', name=typename(self.current_class.name, self.current_class), args=simple_args)) node.block = [ass] + node.block[len(simple_args):] return node
def as_assignment(self, target): e = self.as_expression()[0] e[3] = assignment(target, e) return e
def as_assignment(self, target): expression = self.as_expression()[0][0] expression.block[0] = assignment(target, expression.block[0]) return [expression]
def as_assignment(self, target): expression = self.as_expression()[0] expression[1] = assignment(target, expression[1]) return expression
def expand_set_slice(receiver, from_=None, to=None, value=None, pseudo_type=None): s = expand_slice(receiver, from_, to, pseudo_type) return assignment(s, value)
def as_assignment(self, target): e = self.as_expression()[0] e[3] = assignment(target, e) return e
def as_assignment(self, target): expression = self.as_expression()[0][0] expression.block[0] = assignment(target, expression.block[0]) return [expression]
class GolangTranslator(ApiTranslator): ''' Go api translator The DSL is explained in the ApiTranslator docstring ''' methods = { 'List': { '@equivalent': 'slice', 'push': lambda receiver, element, _: assignment( receiver, call('append', [receiver, element], receiver.pseudo_type)), 'pop': lambda receiver, _: assignment( receiver, Node('_go_slice_to', sequence=receiver, to=Node('binary_op', op='-', left=call('len', [receiver], 'Int'), right=to_node(1), pseudo_type='Int'), pseudo_type=receiver.pseudo_type)), 'length': 'len', 'insert': expand_insert, 'slice': expand_slice, 'slice_from': expand_slice, 'slice_to': lambda receiver, to, pseudo_type: expand_slice( receiver, None, to, pseudo_type), 'join': 'strings.Join(%{self}, %{0})', 'map': expand_map, 'filter': expand_filter, 'find': Find, 'reduce': expand_reduce, 'contains?': ListContains, 'present?': present, 'empty?': empty }, 'Dictionary': { '@equivalent': 'map', 'length': 'len', 'contains?': Contains, 'keys': DictKeys, 'values': DictValues, 'present?': present, 'empty?': empty }, 'String': { '@equivalent': 'str', 'substr': expand_slice, 'substr_from': expand_slice, 'length': 'len', 'substr_to': lambda receiver, to, _: expand_slice( receiver, None, to, pseudo_type='String'), 'find': 'strings.Index(%{self}, %{0})', 'count': 'strings.Count(%{self}, %{0})', 'split': 'strings.Split(%{self}, %{0})', 'concat': to_op('+'), 'contains?': 'strings.Contains(%{self}, %{0})', 'present?': present, 'empty?': empty, 'find_from': lambda f, value, index, _: Node( 'binary_op', op='+', pseudo_type='Int', left=index, right=Node('static_call', receiver=local('strings', 'Library'), message='Index', args=[ Node('_go_slice_from', sequence=f, from_=index, pseudo_type='String'), value ], pseudo_type='Int')), 'to_int': Int }, 'Regexp': { '@equivalent': 'Regexp', 'match': lambda receiver, word, _: method_call( receiver, 'FindAllSubmatch', [ Node('_go_bytes', value=word, pseudo_type='Bytes'), to_node(-1) ], pseudo_type='RegexpMatch') }, 'RegexpMatch': { '@equivalent': 'R', 'group': lambda receiver, index, _: Node('index', sequence=receiver, index=Node('binary_op', op='+', left=index, right=to_node(1), pseudo_type='Int'), pseudo_type='String'), 'has_match': lambda receiver, _: Node('comparison', op='!=', left=receiver, right=Node('null', pseudo_type='None'), pseudo_type='Boolean') }, 'Set': { '@equivalent': 'map[bool]struct{}', 'length': 'len', 'contains?': Contains, 'present?': present, 'empty?': empty }, 'Tuple': { '@equivalent': 'L', 'length': lambda receiver, _: to_node(len(receiver.pseudo_type) - 1) }, 'Array': { '@equivalent': 'int[]', 'length': lambda receiver, _: to_node(receiver.pseudo_type[2]) } } functions = { 'regexp': { 'compile': 'regexp.MustCompile', 'escape': 'regexp.QuoteMeta' }, 'io': { 'display': 'fmt.Println', 'read': Read, 'read_file': ReadFile, 'write_file': 'ioutil.WriteFile' }, 'math': { 'ln': 'math.Log', 'log': 'math.Log', 'tan': 'math.Tan', 'sin': 'math.Sin', 'cos': 'math.Cos', 'pow': 'math.Pow' }, 'system': { 'args': 'os.Args!', 'arg_count': lambda _: call('len', [ attr(local('os', 'Library'), 'Args', ['List', 'String']) ], 'Int'), 'index': lambda value, _: Node('index', sequence=attr(local('os', 'Library'), 'Args', ['List', 'String']), index=value, pseudo_type='String') } } dependencies = { 'regexp': { '@all': 'regexp' }, 'io': { 'display': 'fmt', 'read': ['bufio', 'os'], 'read_file': ['io/ioutil'], 'write_file': ['io/ioutil'] }, 'math': { '@all': 'math' }, 'List': { 'join': 'strings' }, 'String': { 'find': 'strings', 'count': 'strings', 'split': 'strings', 'contains?': 'strings', 'find_from': 'strings', 'to_int': 'strconv' }, 'system': { '@all': 'os' } } errors = {}
value=local('ham', pseudo_type='String')), Node('assignment', target=Node('index', sequence=local('x', pseudo_type=['List', 'String']), index=to_node(4), pseudo_type='String'), value=to_node('String')) ] Call = [call('map', [local('x')])] MethodCall = [method_call(local('e', 'E'), 'filter', [to_node(42)])] StandardCall = [ Node('standard_call', namespace='io', function='display', args=[to_node(42)], pseudo_type='Void'), Node('standard_call', namespace='io', function='read', args=[], pseudo_type='String'), Node('standard_call', namespace='math', function='ln', args=[Node('local', name='ham', pseudo_type='Int')], pseudo_type='Float'), assignment( local('source', pseudo_type='String'), Node('standard_call', namespace='io', function='read_file', args=[to_node('f.py')], pseudo_type='String')) ] IoDisplay = standard_call('io', 'display', [to_node(2), to_node('z')], 'Void') IoRead = assignment(local('source', 'String'), standard_call('io', 'read', [], 'String')) IoReadFile = assignment(local('source', 'String'), standard_call('io', 'read_file', [to_node('z.py')], 'String')) IoWriteFile = standard_call('io', 'write_file', [to_node('z.py'), local('source', 'String')], 'Void') INT_EXAMPLE = local('z', 'Int') MathLn = standard_call('math', 'ln', [INT_EXAMPLE], 'Float') MathLog = standard_call('math', 'log', [INT_EXAMPLE, to_node(2.0)], 'Float') MathTan = standard_call('math', 'tan', [INT_EXAMPLE], 'Float') MathSin = standard_call('math', 'sin', [INT_EXAMPLE], 'Float') MathCos = standard_call('math', 'cos', [INT_EXAMPLE], 'Float')
args=[to_node(42)], pseudo_type='Void'), Node('standard_call', namespace='io', function='read', args=[], pseudo_type='String'), Node('standard_call', namespace='math', function='ln', args=[Node('local', name='ham', pseudo_type='Int')], pseudo_type='Float'), assignment( local('source', pseudo_type='String'), Node('standard_call', namespace='io', function='read_file', args=[to_node('f.py')], pseudo_type='String')) ] IoDisplay = standard_call('io', 'display', [to_node(2), to_node('z')], 'Void') IoRead = assignment(local('source', 'String'), standard_call('io', 'read', [], 'String')) IoReadFile = assignment( local('source', 'String'), standard_call('io', 'read_file', [to_node('z.py')], 'String')) IoWriteFile = standard_call( 'io', 'write_file', [to_node('z.py'), local('source', 'String')], 'Void')
def as_assignment(self, target): expression = self.as_expression()[0] expression[1] = assignment(target, expression[1]) return expression