Пример #1
0
    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:
            if len(simple_args) < len(node.block):
                ass = assi(Node('this', pseudo_type=node.this.name), 
                    Node('simple_initializer', name=typename(node.this.name, node.this.name), args=simple_args, pseudo_type=node.this.name))
                node.block = [ass] + node.block[len(simple_args):] + [Node('implicit_return', value=Node('_go_ref', value=
                        local('this', node.this.name), 
                        pseudo_type=node.this.name),
                    pseudo_type=node.this.name)]
            else:
                node.block = [Node('implicit_return',
                        value=Node('_go_ref', value=
                            Node('simple_initializer', name=typename(node.this.name, node.this.name), args=simple_args, pseudo_type=node.this.name),
                        pseudo_type=node.this.name),
                    pseudo_type=node.this.name)]
            return node
Пример #2
0
 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
Пример #3
0
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'])
Пример #4
0
    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:
            if len(simple_args) < len(node.block):
                ass = assi(
                    Node('this', pseudo_type=node.this.name),
                    Node('simple_initializer',
                         name=typename(node.this.name, node.this.name),
                         args=simple_args,
                         pseudo_type=node.this.name))
                node.block = [ass] + node.block[len(simple_args):] + [
                    Node('implicit_return',
                         value=Node('_go_ref',
                                    value=local('this', node.this.name),
                                    pseudo_type=node.this.name),
                         pseudo_type=node.this.name)
                ]
            else:
                node.block = [
                    Node('implicit_return',
                         value=Node('_go_ref',
                                    value=Node('simple_initializer',
                                               name=typename(
                                                   node.this.name,
                                                   node.this.name),
                                               args=simple_args,
                                               pseudo_type=node.this.name),
                                    pseudo_type=node.this.name),
                         pseudo_type=node.this.name)
                ]
            return node
Пример #5
0
 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
Пример #6
0
def object_len(l, _):
    return attr(
        method_call(
            typename('Object', 'Type'),
            'keys',
            [l],
            ['List', l.pseudo_type[1]]),
        'length',
        'Int')
Пример #7
0
 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
Пример #8
0
 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
Пример #9
0

Module = [Node('module', constants=[], code=[])]
Int = [to_node(42)]
Float = [to_node(42.420)]
String = [to_node('la')]
Boolean = [Node('boolean', value='true', pseudo_type='Boolean')]
Null = [Node('null')]
Dictionary = [
    Node('dictionary',
         pairs=[Node('pair', key=to_node('la'), value=to_node(0))],
         pseudo_type=['Dictionary', 'String', 'Int'])
]
List = [Node('list', elements=[to_node('la')], pseudo_type=['List', 'String'])]
Local = [local('egg')]
Typename = [typename('Egg')]
InstanceVariable = [Node('instance_variable', name='egg')]
Attr = [Node('attr', object=local('e'), attr='egg')]
Assignment = [
    Node('assignment',
         target=local('egg', pseudo_type='Int'),
         value=local('ham', pseudo_type='Int')),
    Node('assignment',
         target=Node('instance_variable', name='egg', pseudo_type='Int'),
         value=local('ham', pseudo_type='Int')),
    Node('assignment',
         target=Node('attr',
                     object=Node('typename', name='T'),
                     attr='egg',
                     pseudo_type='String'),
         value=local('ham', pseudo_type='String')),
Пример #10
0
def object_len(l, _):
    return attr(
        method_call(typename('Object', 'Type'), 'keys', [l],
                    ['List', l.pseudo_type[1]]), 'length', 'Int')
Пример #11
0
            namespace['gen_with_imports'] = TestHelpers.gen_with_imports
        namespace['maxDiff'] = None
        return super().__new__(cls, name, bases, namespace)

Module      = [Node('module', constants=[], code=[])]
Int         = [to_node(42)]
Float       = [to_node(42.420)]
String      = [to_node('la')]
Boolean     = [Node('boolean', value='true', pseudo_type='Boolean')]
Null        = [Node('null')]
Dictionary  = [Node('dictionary', pairs=[
                Node('pair', key=to_node('la'), value=to_node(0))],
                pseudo_type=['Dictionary', 'String', 'Int'])]
List        = [Node('list', elements=[to_node('la')], pseudo_type=['List', 'String'])]
Local       = [local('egg')]
Typename    = [typename('Egg')]
InstanceVariable = [Node('instance_variable', name='egg')]
Attr        = [Node('attr', object=local('e'), attr='egg')]
Assignment = [
    Node('assignment', target=local('egg', pseudo_type='Int'), value=local('ham', pseudo_type='Int')),
    Node('assignment', target=Node('instance_variable', name='egg', pseudo_type='Int'), value=local('ham', pseudo_type='Int')),
    Node('assignment', target=Node('attr', object=Node('typename', name='T'), attr='egg', pseudo_type='String'), 
         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')])]
Пример #12
0
 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
Пример #13
0
    def transform_general_call(self, n, in_block=False, assignment=None):
        for j, arg in enumerate(n.args):
            if (arg.type == 'local' or arg.type == 'instance_variable'
                    or arg.type == 'attr'
                    or arg.type == 'typename') and general_type(
                        arg.pseudo_type) == 'Tuple':
                name = arg.name if arg.type != 'attr' else arg.attr
                pseudo_type = arg.pseudo_type
            elif arg.type == 'index' and arg.sequence.type in {
                    'local', 'instance_variable', 'attr', 'typename'
            } and general_type(arg.sequence.pseudo_type) == 'Tuple':
                name = arg.sequence.name if arg.sequence.type != 'attr' else arg.sequence.attr
                pseudo_type = arg.sequence.pseudo_type
            else:
                n.args[j] = self.transform(n.args[j])
                continue
            z = safe_serialize_type(pseudo_type)
            if z not in self.tuple_definition.tuple_definitions:
                self.tuple_definition.tuple_definitions[z] = name, Node(
                    'class_definition',
                    name=name,
                    base=None,
                    constructor=None,
                    this=typename(name),
                    attrs=[
                        Node('immutable_class_attr',
                             name='item%d' % k,
                             is_public=True,
                             pseudo_type=t)
                        for k, t in enumerate(pseudo_type[1:])
                    ],
                    methods=[])
            else:
                self.tuple_definition.tuple_definitions[
                    z] = name, self.tuple_definition.tuple_definitions[z][1]
            for l in self.tuple_definition.params:
                l.name = name

        if n.type == 'call':
            if n.function.type != 'local':
                return n
            namespace, name = 'functions', n.function.name
        elif n.type == 'method_call':
            n.receiver = self.transform(n.receiver)
            namespace, name = general_type(n.receiver.pseudo_type), n.message
        elif n.type == 'new_instance':
            namespace, name = general_type(n.class_name), '__init__'
        else:
            return n

        if hasattr(namespace, 'y'):
            input(namespace.y)
        if namespace not in self.tuple_definition.function_index or name not in self.tuple_definition.function_index[
                namespace]:
            return n

        if self.tuple_index(n):
            pseudo_type = n.args[-1].sequence.pseudo_type
            sequence = n.args[-1].sequence

            if len(n.args) >= len(pseudo_type) - 1 and all(
                    self.successive(sequence, j, a)
                    for j, a in enumerate(n.args[-len(pseudo_type) + 1:])):
                # s(a, b[0], b[1]) -> s(a, b) and def s(a, x, y) -> s(a, k_name)
                t = safe_serialize_type(pseudo_type)
                tuple_class_name, class_node = self.tuple_definition.tuple_definitions[
                    t]
                old_params = self.tuple_definition.function_index[namespace][
                    name].params[-len(pseudo_type) + 1:]
                l = local(
                    tuple_class_name,
                    pseudo_type)  # referencable if we find another tuple name
                self.tuple_definition.params.append(l)
                self.tuple_definition.function_index[namespace][name].params[
                    -len(pseudo_type) + 1:] = [l]
                self.tuple_definition.function_index[namespace][
                    name] = BlockRewriter(
                        {old_param.name
                         for old_param in old_params}, l).transform(
                             self.tuple_definition.function_index[namespace]
                             [name])
                self.tuple_definition.function_index[namespace][
                    name].pseudo_type[-len(pseudo_type):-1] = [
                        camel_case(tuple_class_name)
                    ]
                for class_attr, name in zip(class_node.attrs, old_params):
                    class_attr.name = name.name
                n.args[-len(pseudo_type) + 1:] = [sequence]
                return n
        return n
Пример #14
0
    def transform_general_call(self, n, in_block=False, assignment=None):
        for j, arg in enumerate(n.args):
            if (arg.type == 'local' or arg.type == 'instance_variable' or arg.type == 'attr' or arg.type == 'typename') and general_type(arg.pseudo_type) == 'Tuple':
                name = arg.name if arg.type != 'attr' else arg.attr
                pseudo_type = arg.pseudo_type
            elif arg.type == 'index' and arg.sequence.type in {'local', 'instance_variable', 'attr', 'typename'} and general_type(arg.sequence.pseudo_type) == 'Tuple':
                name = arg.sequence.name if arg.sequence.type != 'attr' else arg.sequence.attr
                pseudo_type = arg.sequence.pseudo_type
            else:
                n.args[j] = self.transform(n.args[j])
                continue
            z = safe_serialize_type(pseudo_type)
            if z not in self.tuple_definition.tuple_definitions:
                self.tuple_definition.tuple_definitions[z] = name, Node('class_definition',
                            name=name,
                            base=None,
                            constructor=None,
                            this=typename(name),
                            attrs=[Node('immutable_class_attr', name='item%d' % k, is_public=True, pseudo_type=t) for k, t in enumerate(pseudo_type[1:])],
                            methods=[])
            else:
                self.tuple_definition.tuple_definitions[z] = name, self.tuple_definition.tuple_definitions[z][1]
            for l in self.tuple_definition.params:
                l.name = name
    
        if n.type == 'call':
            if n.function.type != 'local':
                return n
            namespace, name = 'functions', n.function.name
        elif n.type == 'method_call':
            n.receiver = self.transform(n.receiver)
            namespace, name = general_type(n.receiver.pseudo_type), n.message
        elif n.type == 'new_instance':
            namespace, name = general_type(n.class_name), '__init__'
        else:
            return n

        
        if hasattr(namespace, 'y'):
            input(namespace.y)
        if namespace not in self.tuple_definition.function_index or name not in self.tuple_definition.function_index[namespace]:
            return n

        if self.tuple_index(n):
            pseudo_type = n.args[-1].sequence.pseudo_type
            sequence = n.args[-1].sequence
            
            if len(n.args) >= len(pseudo_type) - 1 and all(self.successive(sequence, j, a) for j, a in enumerate(n.args[-len(pseudo_type) + 1:])):
                # s(a, b[0], b[1]) -> s(a, b) and def s(a, x, y) -> s(a, k_name)
                t = safe_serialize_type(pseudo_type)
                tuple_class_name, class_node = self.tuple_definition.tuple_definitions[t]
                old_params = self.tuple_definition.function_index[namespace][name].params[-len(pseudo_type) + 1:]
                l = local(tuple_class_name, pseudo_type) # referencable if we find another tuple name
                self.tuple_definition.params.append(l)
                self.tuple_definition.function_index[namespace][name].params[-len(pseudo_type) + 1:] = [l]
                self.tuple_definition.function_index[namespace][name] = BlockRewriter({old_param.name for old_param in old_params}, l).transform(self.tuple_definition.function_index[namespace][name])
                self.tuple_definition.function_index[namespace][name].pseudo_type[-len(pseudo_type):-1] = [camel_case(tuple_class_name)]
                for class_attr, name in zip(class_node.attrs, old_params):
                    class_attr.name = name.name
                n.args[-len(pseudo_type) + 1:] = [sequence]
                return n
        return n
Пример #15
0
class RubyTranslator(ApiTranslator):
    '''
    Ruby api translator

    The DSL is explained in the ApiTranslator docstring
    '''

    methods = {
        'List': {
            '@equivalent':
            'Array',
            'push':
            '#push',
            'pop':
            '#pop',
            'length':
            '#length',
            'insert':
            '#insert',
            'remove_at':
            '#delete_at',
            'remove':
            '#delete',
            'slice':
            expand_slice,
            'slice_from':
            expand_slice,
            'slice_to':
            lambda receiver, to, pseudo_type: expand_slice(
                receiver, to_node(0), to, pseudo_type),
            'join':
            '#join',
            'map':
            to_method_rb_block('map'),
            'filter':
            to_method_rb_block('select'),
            'reduce':
            to_method_rb_block('reduce'),
            'any?':
            to_method_rb_block('any?'),
            'all?':
            to_method_rb_block('all?'),
            'sort':
            '#sort!',
            'present?':
            lambda receiver, _: Node('unary_op',
                                     op='not',
                                     value=method_call(receiver, 'empty?', [],
                                                       'Boolean'),
                                     pseudo_type='Boolean'),
            'empty?':
            '#empty?',
            'find':
            '#index',
            'contains?':
            '#include?'
        },
        'Dictionary': {
            '@equivalent':
            'Hash',
            'length':
            '#length',
            'keys':
            '#keys',
            'values':
            '#values',
            'contains?':
            '#include?',
            'present?':
            lambda receiver, _: Node('unary_op',
                                     op='not',
                                     value=method_call(receiver, 'empty?', [],
                                                       'Boolean'),
                                     pseudo_type='Boolean'),
            'empty?':
            '#empty?'
        },
        'Set': {
            '@equivalent':
            'Set',
            'length':
            '#length',
            'contains?':
            '#include?',
            'union':
            to_op('|'),
            'intersection':
            '#intersection',
            'present?':
            lambda receiver, _: Node('unary_op',
                                     op='not',
                                     value=method_call(receiver, 'empty?', [],
                                                       'Boolean'),
                                     pseudo_type='Boolean'),
            'empty?':
            '#empty?'
        },
        'Tuple': {
            '@equivalent': 'Array',
            'length': '#length'
        },
        'Array': {
            '@equivalent': 'Array',
            'length': '#length'
        },
        'String': {
            '@equivalent':
            'String',
            'substr':
            expand_slice,
            'substr_from':
            expand_slice,
            'substr_to':
            lambda receiver, to, _: expand_slice(receiver, None, to, 'String'),
            'length':
            '#length',
            'concat':
            to_op('+'),
            'find':
            '#index',
            'find_from':
            '#index',
            'count':
            '#count',
            'partition':
            '#partition',
            'split':
            '#split',
            'trim':
            '#trim',
            'reversed':
            '#reverse',
            'center':
            '#center',
            'present?':
            lambda receiver, _: Node('unary_op',
                                     op='not',
                                     value=method_call(receiver, 'empty?', [],
                                                       'Boolean'),
                                     pseudo_type='Boolean'),
            'empty?':
            '#empty?',
            'contains?':
            '#include?',
            'to_int':
            '#to_i',
            'pad_left':
            '#ljust',
            'pad_right':
            '#rjust'
        },
        'Regexp': {
            '@equivalent': 'Regexp',
            'match': '%{0}#scan(%{self})'
        },
        'Int': {
            'to_float': '#to_f'
        },
        'Float': {
            'to_int': '#to_i'
        },
        'RegexpMatch': {
            '@equivalent':
            'Regexp_',
            'group':
            lambda receiver, index, _: Node('index',
                                            sequence=Node('index',
                                                          sequence=receiver,
                                                          index=index,
                                                          pseudo_type=
                                                          ['List', 'String']),
                                            index=to_node(0),
                                            pseudo_type='String'),
            'has_match':
            lambda receiver, _: Node('unary_op',
                                     op='not',
                                     value=method_call(receiver, 'empty?', [],
                                                       'Boolean'),
                                     pseudo_type='Boolean')
        }
    }

    functions = {
        'global': {
            'wat': lambda _: Node('block', block=[]),
            'exit': lambda status, _: call('exit', [status])
        },
        'io': {
            'display': display,
            'read': 'gets',
            'read_file': 'File.read',
            'write_file': 'File.write'
        },
        'math': {
            'ln':
            'Math.log',
            'log':
            'Math.log',
            'tan':
            'Math.tan',
            'sin':
            'Math.sin',
            'cos':
            'Math.cos',
            'pow':
            lambda left, right, pseudo_type: Node('binary_op',
                                                  op='**',
                                                  left=left,
                                                  right=right,
                                                  pseudo_type=pseudo_type)
        },
        'regexp': {
            'compile':
            lambda value, _: Node(
                '_rb_regex_interpolation', value=value, pseudo_type='Regexp'),
            'escape':
            'Regexp.escape'
        },
        'system': {
            'args':
            lambda _: typename('ARGV', ['List', 'String']),
            'arg_count':
            lambda _: Node('binary_op',
                           op='+',
                           left=method_call(local('ARGV', ['List', 'String']),
                                            'length', [], 'Int'),
                           right=to_node(1),
                           pseudo_type='Int'),
            'index':
            lambda value, _: Node('index',
                                  sequence=local('ARGV', ['List', 'String']),
                                  index=to_node(value.value - 1) if value.type
                                  == 'int' else Node('binary_op',
                                                     op='-',
                                                     left=value,
                                                     right=to_node(1),
                                                     pseudo_type='Int'),
                                  pseudo_type='String')
            # in ruby args counting starts from 0, not 1
        }
    }

    dependencies = {'http': {'@all': 'Requests'}, 'Set': {'@all': 'set'}}