Ejemplo n.º 1
0
class RubyGenerator(CodeGenerator):
    '''Ruby code generator'''

    indent = 2
    use_spaces = True
    middlewares = []

    def ruby_dict(self, node, indent):
        short_syntax = True
        result = []
        for pair in node.pairs:
            if short_syntax and pair.key.type == 'string' and re.match(SHORT_SYNTAX, pair.key.value):
                result.append('%s: %s' % (pair.key.value, self._generate_node(pair.value)))
            else:
                short_syntax = False
                result.append('%s => %s' % (self._generate_node(pair.key), self._generate_node(pair.value)))
        return ', '.join(result)

    call_args = ("(%<args:join ', '>)", '')
    function_params = ("(%<params:join ', '>)", '')

    templates = dict(
        module         = '''
            %<dependencies:lines>
            %<custom_exceptions:lines>
            %<definitions:lines>
            %<main:lines>''',

        function_definition = '''
            def %<name>%<.params>
              %<block:line_join>
            end''',

        function_definition_params = function_params,

        method_definition =     '''
            def %<name>%<.params>
              %<block:line_join>
            end''',

        method_definition_params = function_params,

        constructor = '''
            def initialize%<.params>
              %<block:line_join>
            end''',

        constructor_params = function_params,

        class_definition     = '''
            class %<name>%<.base>
              %<.constructor>
              %<methods:lines>
            end''',

        class_definition_constructor = ('%<constructor>', ''),

        class_definition_base = ('< %<base>', ''),

        local           = '%<name>',
        typename        = '%<name>',
        int             = '%<value>',
        float           = '%<value>',
        string          = '%<#safe_single_except_nl>',
        boolean         = '%<value>',
        null            = 'nil',

        dependency      = "require '%<name>'",

        list            = "[%<elements:join ', '>]",
        dictionary      = '{%<#ruby_dict>}',
        attr            = '%<object>.%<attr>',
        
        assignment = '%<target> = %<value>',

        binary_op   = '%<#binary_left> %<#op> %<#binary_right>',
        unary_op    = '%<#op>%<value>',
        comparison  = '%<#right>',

        static_call = "%<receiver>.%<message>%<.args>",
        static_call_args = call_args,
        call        = switch(
            lambda c: c.function.type == 'local' and c.function.name in ['puts', 'p'] or len(c.args) == 0,

            true       = "%<function>%<args:join_lws ', '>",
            _otherwise = "%<function>(%<args:join ', '>)"
        ),
        call_args   = call_args,
        method_call_args = call_args,
        method_call = "%<receiver>.%<message>%<.args>",
        this_method_call = "%<message:camel_case 'title'>%<.args>",
        this_method_call_args=call_args,
        

        this            = 'self',

        instance_variable = '@%<name>',

        throw_statement = 'throw %<exception>.new(%<value>)',

        new_instance    = "%<class_name>.new%<args:join ', '>",

        new_instance_args = call_args,

        standard_iterable_call = "%<sequences.sequence>.select { |%<iterators>| %<test:first> }.map { |%<iterators>| %<block:first> }",

        if_statement    = '''
            if %<test>
              %<block:line_join>
            %<.otherwise>''',

        if_statement_otherwise = ('%<otherwise>', 'end'),

        elseif_statement = '''
            elsif %<test>
              %<block:line_join>
            %<.otherwise>''',

        elseif_statement_otherwise = ('%<otherwise>', 'end'),

        else_statement = '''
            else
              %<block:line_join>
            end''',

        not_null_check = '!%<value>.nil?',

        while_statement = '''
            while %<test>
              %<block:line_join>
            end''',

        try_statement = '''
            begin
              %<block:line_join>
            %<handlers:line_join>end
            ''',

        exception_handler = '''
            rescue %<.is_builtin> => %<instance>
              %<block:line_join>''',

        exception_handler_is_builtin = ('StandardError', '%<exception>'),

        for_statement = '''
            %<sequences> do |%<iterators>|
              %<block:line_join>
            end''',

        for_range_statement = '''
            (%<.first>...%<end>)%<.step>.each do |%<index>|
              %<block:line_join>
            end''',

        for_range_statement_first = ('%<start>', '0'),

        for_range_statement_step = ('.step(%<step>)', ''),

        for_each_with_index_statement = '''
            %<#index_sequence> do |%<#index_iterator>|
              %<block:line_join>
            end''',

        for_sequence = '%<sequence>.each',

        for_sequence_zip = "%<sequences:first>.zip(%<sequences:join_rest ', '>).each",

        for_sequence_with_index = '%<sequence>.each_with_index',

        for_sequence_with_items = '%<sequence>.each',

        for_iterator = '%<iterator>',

        for_iterator_zip = "%<iterators:join ', '>",

        for_iterator_with_index = '%<iterator>, %<index>',

        for_iterator_with_items = '%<key>, %<value>',

        explicit_return = 'return %<value>',

        implicit_return = '%<value>',

        custom_exception = '''
            class %<name> < %<.base>
            end''',

        custom_exception_base = ('%<base>', 'StandardError'),

        _rb_slice          = '%<sequence>[%<from_>...%<to>]',
        _rb_slice_from     = '%<sequence>[%<from_>..-1]',
        _rb_slice_to       = '%<sequence>[0..%<to>]',

        anonymous_function = switch(
            lambda a: len(a.block) == 1,
            true         = "->%<params:join_lws ', '> { %<block:join ''> }",
            _otherwise   = '''
                            ->%<params:join_lws ', '> do
                              %<block:line_join>
                            end'''
        ),

        _rb_method_call_block = "%<receiver>.%<message>%<.args> %<block>",
        _rb_method_call_block_args = call_args,
        _rb_block = switch(lambda b: len(b.block) == 1,
            true  = "{ |%<params:join ', '>| %<block:first> }",
            _otherwise = '''
                do |%<params:join ', '>|
                    %<block:line_join>
                end'''),

        _rb_regex_interpolation = "/#{%<value>}/",

        index           = '%<sequence>[%<index>]',

        interpolation = "\"%<args:join ''>\"",

        interpolation_literal = '%<value>',

        interpolation_placeholder = '#{%<value>}',

        aug_assignment = '%<target> %<op>= %<value>',

        tuple    = "[%<elements:join ', '>]",

        array    = "[%<elements:join ', '>]",

        set      = "Set.new([%<elements:join ', '>])",

        block           = '%<block:line_join>',

        regex    = "/%<value>/",

    )
    
    def op(self, node, depth):
        return OPS.get(node.op, node.op)

    def right(self, node, depth):
        '''when compared with argv length, decrement'''
        if node.left.type != 'binary_op' or node.left.op != '+' or node.left.right.type != 'int' or node.right.type != 'int':# 'attr' or node.left.object.type != 'local' or node.left.object.name != 'ARGV':
        #     print('woah')
            pass
        else:
            node.right.value -= node.left.right.value
            node.left = node.left.left

        return '%s %s %s' % (self.binary_left(node, depth), node.op, self.binary_right(node, depth))
Ejemplo n.º 2
0
class CppGenerator(CodeGenerator):
    '''Cpp code generator'''

    indent = 4
    use_spaces = True

    middlewares = [
        DeclarationMiddleware, CppPointerMiddleware,
        CppDisplayExceptionMiddleware
    ]

    types = {
        'Int':
        'int',
        'Float':
        'float',
        'Boolean':
        'bool',
        'String':
        'string',
        'List':
        'vector<{0}>',
        'Dictionary':
        'unordered_map<{0}, {1}>',
        'Tuple':
        lambda t: 'pair<{0}{1}>'.format(*t)
        if len(t) == 2 else 'tuple<{0}>'.format(', '.join(t)),
        'Array':
        '{0}*',
        'Set':
        'set<{0}>',
        'Void':
        'void',
        'Pointer':
        'smart_ptr<{0}>'
    }

    templates = dict(
        module='''
          %<dependencies:lines>
          %<#exception_dependencies>
          %<constants:lines>
          %<custom_exceptions:lines>
          %<definitions:lines>
          int main() {
              %<main:semi>
          }
          ''',
        function_definition='''
            %<@return_type> %<name>(%<#params>) {
                %<block:semi>
            }''',
        method_definition='''
            %<@return_type> %<name>(%<#params>) {
                %<block:semi>
            }''',
        class_definition='''
              class %<name>%<.base> {
                  %<attrs:lines>
                  %<.constructor>
                  %<methods:lines>
              }''',
        class_definition_base=(': %<base>', ''),
        class_definition_constructor=('%<constructor>', ''),
        class_attr='%<.is_public> %<@pseudo_type> %<name>;',
        class_attr_is_public=('public', 'private'),
        anonymous_function='[](%<#params>) %<#anon_block>',
        constructor='''
            %<this>(%<#params>) {
                %<block:semi>
            }''',
        dependency='#include<%<name>>',
        local='%<name>',
        typename='%<name>',
        int='%<value>',
        float='%<value>',
        string='%<#safe_double>',
        boolean='%<value>',
        null='NULL',
        list="{%<elements:join ', '>}",
        dictionary="%<@pseudo_type>{{%<pairs:join ', '>}}",
        set="%<@pseudo_type>({%<elements:join ', '>})",
        regex='regex("%<value>")',
        pair="%<key>: %<value>",
        attr="%<object>.%<attr>",
        assignment=switch('first_mention',
                          true='%<@value.pseudo_type> %<target> = %<value>',
                          _otherwise='%<target> = %<value>'),
        binary_op='%<left> %<op> %<right>',
        unary_op='%<op>%<value>',
        comparison='%<left> %<op> %<right>',
        static_call="%<receiver>.%<message>(%<args:join ', '>)",
        call="%<function>(%<args:join ', '>)",
        method_call="%<receiver>.%<message>(%<args:join ', '>)",
        pointer_method_call="%<receiver>->%<message>(%<args:join ', '>)",
        this='this',
        instance_variable='this->%<name>',
        new_instance="new %<class_name>(%<args:join ', '>)",
        throw_statement='throw %<exception>(%<value>)',
        if_statement='''
            if (%<test>) {
                %<block:semi>
            } %<.otherwise>''',
        if_statement_otherwise=('%<otherwise>', ''),
        elseif_statement='''
            else if (%<test>) {
                %<block:semi>
            } %<.otherwise>''',
        elseif_statement_otherwise=('%<otherwise>', ''),
        else_statement='''
            else {
                %<block:semi>
            }''',
        while_statement='''
            while (%<test>) {
                %<block:semi>
            }''',
        try_statement='''
            try {
                %<block:semi>
            }
            %<handlers:lines>''',
        exception_handler='''
            catch (%<.exception>& %<instance>) {
                %<block:semi>
            }''',
        exception_handler_exception=('%<exception>', 'exception'),
        for_statement=switch(lambda f: f.iterators.type,
                             for_iterator_with_index='''
                for(int %<iterators.index> = 0; %<iterators.index> < %<sequences.sequence>.size(); %<iterators.index> ++) {
                    auto %<iterators.iterator> = %<sequences.sequence>[%<iterators.index>];
                    %<block:semi>
                }''',
                             for_iterator_zip='''
                for(int _index = 0; _index < %<#first_sequence>.size(); _index ++) {
                    %<#zip_iterators>
                    %<block:semi>
                }''',
                             for_iterator_with_items='''
                for(auto& _item : %<sequences.sequence>) {
                    auto %<iterators.key> = _item.first;
                    auto %<iterators.value> = _item.second;
                    %<block:semi>
                }''',
                             _otherwise='''
                for(%<iterators>: %<sequences>) {
                    %<block:semi>
                }'''),
        for_range_statement='''
            for(int %<index> = %<.first>; %<index> != %<end>; %<index> += %<.step>) {
                %<block:semi>
            }''',
        for_range_statement_first=('%<start>', '0'),
        for_range_statement_step=('%<step>', '1'),
        for_iterator='auto %<iterator>',
        for_iterator_zip="var %<iterators:join ', '>",
        for_iterator_with_index='int %<index>, var %<iterator>',
        for_iterator_with_items='%<key>, %<value>',
        for_sequence='%<sequence>',
        implicit_return='return %<value>',
        explicit_return='return %<value>',
        _with='''
            with %<call> as %<context>:
                %<block:semi>''',
        index='%<sequence>[%<index>]',
        block='%<block:semi>',
        custom_exception='''
            class %<name> : runtime_error {
            }''',
        _cpp_declaration='%<@decl_type> %<name>%<.args>',
        _cpp_declaration_args=("(%<args:join ', '>)", ''),
        _cpp_anon_declaration="%<@decl_type>(%<args:join ', '>)",
        _cpp_group='(%<value>)',
        _cpp_cin='cin >> %<args:first>',  # support only one for now
        _cpp_cout="cout << %<args:join ' << '> << endl")

    def namespace(self, node, indent):
        return self.name.capitalize()

    def header(self, node, indent):
        return 'using System;\nnamespace %s;\n{\n' % self.namespace()

    def params(self, node, indent):
        return ', '.join(
            '%s %s' % (PseudoType('').expand_type(k.pseudo_type, self), k.name)
            for j, k in enumerate(node.params))

    def anon_block(self, node, indent):
        if len(node.block) == 1:
            b = self._generate_node(node.block[0])
            return '{ %s; }' % b
        else:
            b = ';\n'.join(
                self.offset(indent + 1) + self._generate_node(e, indent + 1)
                for e in node.block) + ';'
            return '{\n%s\n%s}' % (b, self.offset(indent))

    def exception_dependencies(self, node, indent):
        if node.custom_exceptions:
            iostream = ''
            for d in node.dependencies:
                if d.name == 'iostream':
                    break
            else:
                iostream = '#include<iostream>\n'
            return '%s#include<stdexcept>\n#include<exception>\n' % iostream
        else:
            return ''

    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 first_sequence(self, node, depth):
        return self._generate_node(node.sequences.sequences[0])
Ejemplo n.º 3
0
class JSGenerator(CodeGenerator):
    '''JS generator'''

    indent = 2
    use_spaces = True
    middlewares = [DeclarationMiddleware]

    templates = dict(
        module=
        "%<dependencies:lines>\n_ = require('lodash');\n%<constants:lines>%<custom_exceptions:lines>%<definitions:lines>%<main:semi>",
        function_definition='''
            function %<name>(%<params:join ', '>) {
              %<block:semi>
            }''',
        method_definition='''
            %<this>.prototype.%<name> = function (%<params:join ', '>) {
              %<block:semi>
            }''',
        class_definition='''
              %<.constructor>
              %<.base>
              %<methods:lines>''',
        class_definition_base=
        ('%<name>.prototype = _.create(%<base>.prototype, {constructor: %<name>})',
         ''),
        class_definition_constructor=('%<constructor>', ''),
        dependency=switch('name',
                          lodash="var _ = require('%<name>');",
                          _otherwise="var %<name> = require('%<name>');"),
        anonymous_function='''
            function (%<params:join ', '>) {
              %<block:semi>
            }''',
        constructor='''
            function %<this>(%<params:join ', '>) {
              %<block:semi>
            }''',
        local='%<name>',
        typename='%<name>',
        int='%<value>',
        float='%<value>',
        string='%<#safe_single>',
        boolean='%<value>',
        null='null',
        list="[%<elements:join ', '>]",
        dictionary="{%<pairs:join ', '>}",
        pair=switch(lambda p: p.key.type == 'string' and JS_NAME.match(
            p.key.value) is not None,
                    true='%<key.value>: %<value>',
                    _otherwise='%<key>: %<value>'),
        attr="%<object>.%<attr>",
        custom_exception='''
            function %<name>(message) {
              this.message = message;
            }

            %<name>.prototype = _.create(%<.base>.prototype, {constructor: %<name>});''',
        custom_exception_base=('%<base>', 'Error'),
        assignment=switch('first_mention',
                          true='var %<target> = %<value>',
                          _otherwise='%<target> = %<value>'),
        binary_op='%<#binary_left> %<#op> %<#binary_right>',
        unary_op='%<#op>%<value>',
        comparison='%<#comparison>',
        static_call="%<receiver>.%<message>(%<#args_join>)",
        call="%<function>(%<#args_join>)",
        method_call="%<receiver>.%<message>(%<#args_join>)",
        this_method_call="this.%<message>(%<#args_join>)",
        this='this',
        instance_variable='this.%<name>',
        throw_statement='throw new %<exception>(%<value>)',
        new_instance="new %<class_name>(%<args:join ', '>)",
        if_statement='''
            if (%<test>) {
              %<block:semi>
            } %<.otherwise>''',
        if_statement_otherwise=(' %<otherwise>', ''),
        elseif_statement='''
            else if (%<test>) {
              %<block:semi>
            } %<.otherwise>''',
        elseif_statement_otherwise=(' %<otherwise>', ''),
        else_statement='''
            else {
              %<block:semi>
            }''',
        while_statement='''
            while (%<test>) {
                %<block:semi>
            }''',
        try_statement='''
            try {
              %<block:semi>
            } catch(%<#handler_>) {
              if %<handlers:join_depth_aware ' else if '> else {
                throw %<#handler_>;
              }
            }''',
        exception_handler='''
            (%<instance> isinstanceof %<.is_builtin>) {
              %<block:semi>
            }''',  # obvsly its an Error, but we'll have other builtin errors in next versions
        exception_handler_is_builtin=('Error', '%<exception>'),
        for_statement='''
            _.forEach(%<sequences>, function (%<iterators>) {
              %<block:semi>
            })''',
        for_range_statement='''
            for(var %<index> = %<.first>;%<index> != %<end>;%<index> += %<.step>) {
              %<block:semi>
            }''',
        for_range_statement_first=('%<start>', '0'),
        for_range_statement_step=('%<step>', '1'),
        for_iterator='%<iterator>',
        for_iterator_zip="%<iterators:join ', '>",
        for_iterator_with_index='%<iterator>, %<index>',
        for_iterator_with_items='%<value>, %<key>',
        for_sequence='%<sequence>',
        for_sequence_zip="_.zip(%<sequences:join ', '>)",
        for_sequence_with_index='%<sequence>',
        for_sequence_with_items='%<sequence>',
        tuple="[%<elements:join ', '>]",
        array="[%<elements:join ', '>]",
        set="{%<.elements>}",
        set_elements=("%<elements:join ': true, '>: true", ''),
        implicit_return='return %<value>',
        explicit_return='return %<value>',
        index=switch(index_switch,
                     string='%<sequence>.%<index.value>',
                     normal='%<sequence>[%<index>]',
                     _otherwise='%<sequence>[%<sequence>.length - %<#index>]'),
        interpolation="%<args:join ' + '>",
        interpolation_literal='%<#safe_single>',
        interpolation_placeholder='%<value>',
        constant='%<constant> = %<init>',
        aug_assignment='%<target> += %<value>',
        standard_iterable_call='''
            _.filter(%<sequences.sequence>, function (%<iterators>) {
              return %<test:first>;
            }).map(function (%<iterators>) {
              return %<block:first>;
            })''',
        block='%<block:semi>',
        not_null_check='%<value>',
        regex='/%<value>/',
    )

    def handler_(self, node, indent):
        if node.handlers:
            return node.handlers[0].instance
        else:
            return '_e'

    def op(self, node, depth):
        return OPS.get(node.op, node.op)

    def args_join(self, node, depth):
        return ', '.join(
            self._generate_node(n, depth).lstrip() for n in node.args)

    def comparison(self, node, depth):
        if node.left.type == 'binary_op' and node.left.op == '-' and node.left.right.type == 'int' and node.right.type == 'int':
            node.right.value += node.left.right.value
            node.left = node.left.left
        if node.op == '==' and isinstance(
                node.left.pseudo_type,
                list) and node.left.pseudo_type[0] == 'List':
            return '_.isEqual(%s, %s)' % (self.binary_left(
                node, depth), self.binary_right(node, depth))
        return '%s %s %s' % (self.binary_left(
            node, depth), node.op, self.binary_right(node, depth))

    def index(self, node, depth):
        return str(-node.index.value)
Ejemplo n.º 4
0
class PythonGenerator(CodeGenerator):
    '''Python code generator'''

    indent = 4
    use_spaces = True
    middlewares = []

    templates = dict(
        module     = '''
            %<dependencies:lines>
            %<constants:lines>
            %<custom_exceptions:lines>
            %<definitions:lines>
            %<main:lines>''',

        function_definition   = '''
             def %<name>(%<params:join ', '>):
                 %<block:line_join_pass>''',

        function_definition_block = ("%<block:line_join>", 'pass'),

        method_definition =     '''
            def %<name>(self%<params:each_lpad ', '>):
                %<block:line_join_pass>''',

        method_definition_block = ('%<block:line_join>', 'pass'),

        class_definition = '''
              class %<name>%<.base>:
                  %<.constructor>
                  %<methods:line_join>
                  %<#class_pass>''',

        class_definition_base = ('(%<base>)', ''),

        class_definition_constructor = ('%<constructor>', ''),

        new_instance = "%<class_name>(%<args:join ', '>)",

        anonymous_function = '%<#anonymous_function>',

        constructor = '''
            def __init__(self%<.params>):
                %<block:line_join_pass>''',

        constructor_params = ("%<params:each_lpad ', '>", ''),

        dependency  = 'import %<name>',


        local       = '%<name>',
        typename    = '%<name>',
        int         = '%<value>',
        float       = '%<value>',
        string      = '%<#safe_single>',
        boolean     = '%<#to_boolean>',
        null        = 'None',

        list        = "[%<elements:join ', '>]",
        dictionary  = "{%<pairs:join ', '>}",
        pair        = "%<key>: %<value>",
        attr        = "%<object>.%<attr>",

        assignment    = '%<target> = %<value>',

        operation_assign    = '%<slot> %<op>= %<value>',

        binary_op   = '%<#binary_left> %<op> %<#binary_right>',
        
        unary_op    = switch(lambda u: u.op == 'not',
            true       = 'not %<value>',
            _otherwise = '%<op>%<value>'
        ),

        comparison  = '%<#binary_left> %<op> %<#binary_right>',

        _py_del        = 'del %<value>',
        _py_setitem    = '%<sequence>[%<key>] = %<value>',
        _py_slice      = '%<sequence>[%<from_>:%<to>]',
        _py_slice_from = '%<sequence>[%<from_>:]',
        _py_slice_to   = '%<sequence>[:%<to>]',


        static_call = switch(lambda s: len(s.args) == 1 and s.args[0].type == '_py_generatorcomp',
                true       = '%<receiver>.%<message>%<args:first>',
                _otherwise = "%<receiver>.%<message>(%<args:join ', '>)"),

        call        = switch(lambda s: len(s.args) == 1 and s.args[0].type == '_py_generatorcomp',
                true       = '%<function>%<args:first>',
                _otherwise = "%<function>(%<args:join ', '>)"),

        method_call = switch(lambda s: len(s.args) == 1 and s.args[0].type == '_py_generatorcomp',
                true       = '%<receiver>.%<message>%<args:first>',
                _otherwise = "%<receiver>.%<message>(%<args:join ', '>)"),
        
        this_method_call = switch(lambda s: len(s.args) == 1 and s.args[0].type == '_py_generatorcomp',
                true       = 'self.%<message>%<args:first>',
                _otherwise = "self.%<message>(%<args:join ', '>)"),

        block       = '%<block:lines>',

        this        = 'self',

        instance_variable = 'self.%<name>',

        throw_statement = 'raise %<exception>(%<value>)',

        if_statement    = '''
            if %<test>:
                %<block:line_join_pass>
            %<.otherwise>''',

        if_statement_otherwise = ('%<otherwise>', ''),

        elseif_statement = '''
            elif %<test>:
                %<block:line_join_pass>
            %<.otherwise>''',

        elseif_statement_otherwise = ('%<otherwise>', ''),

        else_statement = '''
            else:
                %<block:line_join_pass>''',

        while_statement = '''
            while %<test>:
                %<block:line_join_pass>''',

        try_statement = '''
            try:
                %<block:line_join_pass>
            %<handlers:lines>''',

        exception_handler = '''
            except %<.is_builtin> as %<instance>:
                %<block:line_join_pass>''',

        exception_handler_is_builtin = ('Exception', '%<exception>'),

        for_statement = '''
            for %<iterators> in %<sequences>:
                %<block:line_join_pass>''',
    
        for_range_statement = '''
            for %<index> in range(%<.first>%<end>%<.step>):
                %<block:line_join_pass>''',

        for_range_statement_first = ('%<start>, ', '%<start>, '), 

        for_range_statement_step = (', %<step>', ''),

        implicit_return = 'return %<value>',
        explicit_return = 'return %<value>',

        _py_with = '''
            with %<call> as %<context>:
                %<block:line_join_pass>''',

        custom_exception = '''
            class %<name>(%<.base>):
                pass''',

        custom_exception_base = ('%<base>', 'Exception'),

        constant = '%<constant> = %<init>',

        # standard_iterable_call = switch('function',
        #     map = '[%<.block>]',
        #     filter_map = "[%<.block> if %<test:join ''>]",
        #     _otherwise = '%<function>([%<.block>])'
        # ),

        # standard_iterable_call_range = "[%<block:join ''> for %<index> in range(%<.first>%<last>%<.step>)]",

        # standard_iterable_call_block = ("%<block:join ''> for %<iterators> in %<sequences>", ''),

        # standard_iterable_call_first = ('%<first>, ', ''), 

        # standard_iterable_call_step = (', %<step>', ''),
        
        for_iterator = '%<iterator>',

        for_iterator_zip = "%<iterators:join ', '>",

        for_iterator_with_index = '%<index>, %<iterator>',

        for_iterator_with_items = '%<key>, %<value>',

        for_sequence = '%<sequence>',

        for_sequence_zip = "zip(%<sequences:join ', '>)",

        for_sequence_with_index = 'enumerate(%<sequence>)',

        for_sequence_with_items = '%<sequence>.items()',

        tuple    = "(%<elements:join ', '>)",

        array    = "(%<elements:join ', '>)",

        set      = '%<.elements>',

        set_elements = (
            "{%<elements:join ', '>}",
            'set()'
        ),

        index    = '%<sequence>[%<index>]',

        interpolation = "'%<args:join ''>'.format(%<#placeholders>)",

        interpolation_literal = '%<value>',

        break_ = 'break',

        interpolation_placeholder = '{%<index>}',

        _py_listcomp = '[%<block> for %<iterators> in %<sequences>%<#test>]',

        _py_generatorcomp = '(%<block> for %<iterators> in %<sequences>%<#test>)',

        _py_in   = '%<value> in %<sequence>',

        _py_step = '%<sequence>[::%<step>]',

        not_null_check = '%<value> is not None',

        aug_assignment = '%<target> %<op>= %<value>',

        standard_iterable_call = '[%<block:first> for %<iterators> in %<sequences> if %<test:first>]',

        regex    = "re.compile(r'%<value>')",

    )
    
    def to_boolean(self, node, indent):
        if node.value == 'true':
            return 'True'
        else:
            return 'False'

    def block(self, node, indent):
        if node.block:
            e = self._generate_node(node.block[0])
            other = [self.offset(indent) + self._generate_node(n, indent) for n in node.block[1:]]
            return '\n'.join([e] + other)
        else:
            return 'pass'

    def anonymous_function(self, node, indent):
        params = ', '.join(map(self._generate_node, node.params))
        lambda_head = 'lambda%s:' % (' ' + params if params else '')
        if not node.block:
            return '%s pass' % lambda_head
        elif len(node.block) == 1 and node.block[0].type in EXPRESSION_TYPES:
            if node.block[0].type == 'implicit_return' or node.block[0].type == 'explicit_return':
                block = node.block[0].value
            else:
                block = node.block[0]
            return '%s %s' % (lambda_head, self._generate_node(block))
        else:
            name = 'a_%d' % len(self.a)
            block = [self.offset(1) + self._generate_node(z) for z in node.block]
            code = 'def %s(%s):\n%s\n' % (name, params, '\n'.join(block))
            self.a.append(code)
            return name

    def class_pass(self, node, indent):
        if not node.constructor and not node.methods:
            return 'pass'
        else:
            return ''

    def test(self, node, indent):
        if node.test:
            return ' if %s' % self._generate_node(node.test)
        else:
            return ''

    def placeholders(self, node, indent):
        return ', '.join(self._generate_node(placeholder.value) for placeholder in node.args[1::2])
Ejemplo n.º 5
0
class CSharpGenerator(CodeGenerator):
    '''CSharp code generator'''

    indent = 4
    use_spaces = True
    middlewares = [
        TupleMiddleware(all=False), DeclarationMiddleware,
        NameMiddleware(normal_name='camel_case',
                       method_name='pascal_case',
                       function_name='pascal_case')
    ]

    types = {
        'Int': 'int',
        'Float': 'float',
        'Boolean': 'bool',
        'String': 'string',
        'List': 'List<{0}>',
        'Dictionary': 'Dictionary<{0}, {1}>',
        'Set': 'HashSet<{0}>',
        'Tuple': lambda x: 'Tuple<{0}>'.format(', '.join(x)),
        'Array': '{0}[]',
        # fixed-size buffers in c# are not widely used
        # they require a struct and an unsafe annotation
        # we can a unsafe-fixed-size-buffer option to config
        'Void': 'void',
        'Regexp': 'Regex',
        'RegexpMatch': 'Match'
    }

    templates = dict(
        module='''
            using System;
            %<dependencies:lines>
            %<custom_exceptions:lines>
            %<tuple_definitions:lines>
            %<#class_definitions>
            public class Program
            {
                %<constants:lines>
            %<#function_definitions>
                public static void Main(string[] args)
                {
                    %<main:semi>
                }
            }''',
        function_definition='''
            static %<@return_type> %<name>(%<#params>)
            {
                %<block:semi>
            }''',
        method_definition='''
            %<.is_public> %<@return_type> %<name>(%<#params>)
            {
                %<block:semi>
            }''',
        method_definition_is_public=('public', 'private'),
        class_definition='''
            public class %<name>%<.base>
            {
                %<attrs:lines>
                %<.constructor>
                %<methods:line_join>
            }''',
        class_definition_base=('%<#base>', ''),
        class_definition_constructor=('%<constructor>', ''),
        class_attr="%<.is_public>%<@pseudo_type> %<name:camel_case 'lower'>;",
        class_attr_is_public=('public ', 'private '),
        immutable_class_attr='''
            private readonly %<@pseudo_type> %<name>;
            public %<@pseudo_type> %<name:camel_case 'title'> { get { return %<name>; } }''',
        anonymous_function="%<#anon_params> =>%<#anon_block>",
        constructor='''
            public %<this>(%<#params>)
            {
                %<block:semi>
            }''',
        dependency='using %<name>;',
        local='%<name>',
        typename='%<name>',
        int='%<value>',
        float='%<value>',
        string='%<#safe_double>',
        boolean='%<value>',
        null='null',
        simple_initializer="new %<name>(%<args:join ', '>)",
        list=switch(lambda l: len(l.elements) > 0,
                    true="new[] {%<elements:join ', '>}",
                    _otherwise="Enumerable.Empty<int>()"),
        dictionary=switch(lambda d: len(d.pairs) > 0,
                          true="new %<@pseudo_type> { %<pairs:join ', '> }",
                          _otherwise="new Dictionary<int, int> {}"),
        pair="{%<key>, %<value>}",
        attr="%<object>.%<attr>",
        new_instance="new %<class_name>(%<args:join ', '>)",

        # assignment  = '%<#z>',
        assignment=switch(
            'first_mention',
            true=
            'var %<target> = %<value>',  # in v0.3 add config/use var only for generic types
            _otherwise='%<target> = %<value>'),
        tuple=switch(lambda e: len(e.elements) <= 2,
                     true="Tuple.Create(%<elements:join ', '>)",
                     _otherwise='''
                            Tuple.Create(
                                %<elements:c_lines>
                            )'''),
        array="new[] { %<elements:join ', '> }",
        set=switch(lambda s: len(s.elements) > 0,
                   true="new %<@pseudo_type>(new[] {%<elements:join ', '>})",
                   _otherwise="new HashSet<int>()"),
        char="%<#char>",
        binary_op='%<#binary_left> %<#op> %<#binary_right>',
        unary_op='%<#op>%<value>',
        comparison='%<#comparison>',
        static_call="%<receiver>.%<message>(%<args:join ', '>)",
        call="%<function>(%<args:join ', '>)",
        method_call="%<receiver>.%<message>(%<args:join ', '>)",
        this_method_call=
        "this.%<message:camel_case 'title'>(%<args:join ', '>)",
        this='this',
        instance_variable='this.%<name>',
        throw_statement='throw new %<exception>(%<value>)',
        if_statement='''
            if (%<test>)
            {
                %<block:semi>
            }
            %<.otherwise>''',
        if_statement_otherwise=('%<otherwise>', ''),
        elseif_statement='''
            else if (%<test>)
            {
                %<block:semi>
            }
            %<.otherwise>''',
        elseif_statement_otherwise=('%<otherwise>', ''),
        else_statement='''
            else 
            {
                %<block:semi>
            }''',
        while_statement='''
            while (%<test>)
            {
                %<block:semi>
            }''',
        try_statement='''
            try
            {
                %<block:semi>
            }
            %<handlers:lines>''',
        exception_handler='''
            catch (%<.exception> %<instance>)
            {
                %<block:semi>
            }''',
        exception_handler_exception=('%<exception>', 'Exception'),
        for_each_statement='''
            for %<iterator> in %<sequence>:
                %<#block>''',
        for_each_with_index_statement='''
            for %<index>, %<iterator> in %<.sequence>:
                %<#block>''',
        for_each_with_index_statement_sequence=('%<#index_sequence>', ''),
        for_each_in_zip_statement='''
            for %<iterators:join ', '> in zip(%<sequences:join ', '>):
                %<#block>''',
        implicit_return='return %<value>',
        explicit_return='return %<value>',
        index=switch(index_switch,
                     tuple='%<sequence>.Item%<#tuple_index>',
                     normal='%<sequence>[%<index>]',
                     _otherwise='%<sequence>[%<sequence>.Length - %<#index>]'),
        interpolation="string.Format(\"%<args:join ''>\",  %<#placeholders>)",
        interpolation_placeholder="{%<index>}",
        interpolation_literal="%<value>",
        index_assignment='%<sequence>[%<index>] = %<value>',
        not_null_check='%<value> != null',
        constant='%<constant> = %<init>',
        for_statement=switch(lambda f: f.iterators.type,
                             for_iterator_with_index='''
                for (int %<iterators.index> = 0; %<iterators.index> < %<sequences.sequence>.Length; %<iterators.index> ++)
                {
                    var %<iterators.iterator> = %<sequences.sequence>[%<iterators.index>];
                    %<block:semi>
                }''',
                             for_iterator_zip='''
                for (int _index = 0; _index < %<#first_sequence>.Length; _index ++)
                {
                    %<#zip_iterators>
                    %<block:semi>
                }''',
                             for_iterator_with_items='''
                foreach(var _item in %<sequences.sequence>)
                {
                    var %<iterators.key> = _item.key;
                    var %<iterators.value> = _item.value;
                    %<block:semi>
                }''',
                             _otherwise='''
                foreach(%<iterators> in %<sequences>)
                {
                    %<block:semi>
                }'''),
        for_range_statement='''
            for (int %<index> = %<.first>; %<index> != %<last>; %<index> += %<.step>)
            {
                %<block:semi>
            }''',
        for_range_statement_first=('%<first>', '0'),
        for_range_statement_step=('%<step>', '1'),
        for_iterator='var %<iterator>',
        for_iterator_zip="var %<iterators:join ', '>",
        for_iterator_with_index='int %<index>, var %<iterator>',
        for_iterator_with_items='%<key>, %<value>',
        for_sequence='%<sequence>',
        custom_exception='''
            public class %<name> : Exception
            {
                public %<name>(string message)
                    : base(message)
                {
                }
            }''',
        standard_iterable_call='''
                    %<sequences>
                        .Where(%<iterators.iterator> => %<test:first>)
                        .Select(%<iterators.iterator> => %<block:first>)
                        .ToList()''',
        aug_assignment='%<target> %<op>= %<value>',
        block='%<block:semi>',
        regex='@"%<value>')

    def params(self, node, indent):
        return ', '.join(
            '%s %s' %
            (self.render_type(node.pseudo_type[j + 1]), self._generate_node(k))
            for j, k in enumerate(node.params))

    def anon_params(self, node, indent):
        if len(node.params) == 0:
            return ''
        else:
            l, r = ('(', ')') if len(node.params) > 1 else ('', '')
            return '%s%s%s' % (l, ', '.join(
                param if isinstance(param, str) else self._generate_node(param)
                for param in node.params), r)

    def anon_block(self, node, indent):
        # print(indent);input(node.params[0].y)
        if indent < 2:
            indent = 2  # anon cant be before method lvl

        if len(node.block) == 1:
            if node.block[0].type == 'implicit_return' or node.block[
                    0].type == 'explicit_return':
                e = node.block[0].value
            else:
                e = node.block[0]
            b = self._generate_node(e)
            return ' ' + b
        else:
            b = ';\n'.join(
                self.offset(indent + 1) + self._generate_node(e, indent + 1)
                for e in node.block) + ';\n'
            return ' {\n%s%s}' % (b, self.offset(indent))

    def class_definitions(self, node, depth):
        result = '\n'.join(
            self._generate_node(k) for k in node.definitions
            if k.type == 'class_definition')
        if result:
            return result + '\n'
        else:
            return ''

    def function_definitions(self, node, depth):
        result = '\n'.join(
            self.offset(1) + self._generate_node(f, 1)
            for f in node.definitions if f.type == 'function_definition')
        if result:
            return result + '\n'
        else:
            return ''

    def base(self, node, depth):
        if node.base:
            return ' : %s' % node.base
        else:
            return ''

    def first_sequence(self, node, depth):
        return self._generate_node(node.sequences.sequences[0])

    def zip_iterators(self, node, depth):
        return '\n'.join(
            '%svar %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 tuple_index(self, node, depth):
        return str(node.index.value + 1)

    def op(self, node, depth):
        return OPS.get(node.op, node.op)

    def char(self, node, depth):
        if node.value == "'":
            return "'\\''"
        else:
            return "'%s'" % node.value

    # args starting from 0
    def comparison(self, node, depth):
        if node.left.type != 'binary_op' or node.left.op != '+' or node.left.right.type != 'int' or node.right.type != 'int':  # 'attr' or node.left.object.type != 'local' or node.left.object.name != 'ARGV':
            pass
        else:
            node.right.value -= node.left.right.value
            node.left = node.left.left

        return '%s %s %s' % (self.binary_left(
            node, depth), node.op, self.binary_right(node, depth))

    def z(self, node, depth):
        print(node.y)
        input()
        return '!!!'

    def index(self, node, depth):
        return str(-node.index.value)

    def placeholders(self, node, depth):
        return ', '.join(
            self._generate_node(child.value) for child in node.args[1::2])
Ejemplo n.º 6
0
class GolangGenerator(CodeGenerator):
    '''Go generator'''

    indent = 1
    use_spaces = False

    middlewares = [
        TupleMiddleware(True), GoConstructorMiddleware, DeclarationMiddleware,
        NameMiddleware(normal_name='camel_case',
                       method_name='pascal_case',
                       function_name='pascal_case',
                       attr_name='pascal_case'), StandardMiddleware
    ]  # GoErrorHandlingMiddleware

    types = {
        'Int': 'int',
        'Float': 'float',
        'Boolean': 'bool',
        'String': 'string',
        'List': '[]{0}',
        'Dictionary': 'map[{0}]{1}',
        'Set': 'map[{0}]struct{}',
        'Tuple': lambda x: safe_serialize_type(['Tuple'] + x),
        # uh yea, in next version we'll add some kind of smart-name / config option
        'Array': '[{1}]{0}',
        'Void': 'void',
        'Regexp': '*regexp.Regexp',
        'RegexpMatch': '[][][]byte'
    }

    templates = dict(
        module='''
          package main

          %<#dependencies>
          %<constants:lines>
          %<custom_exceptions:lines>
          %<definitions:lines>
          %<tuple_definitions:line_join>
          func main() {
              %<main:line_join>
          }''',
        function_definition='''
            func %<name>(%<#params>) %<#return_type> {
                %<block:line_join>
            }''',
        method_definition='''
            func (this *%<this>) %<name>(%<#params>) %<#return_type> {
                %<block:line_join>
            }''',
        class_definition='''
            type %<name> struct {
               %<.base>
               %<attrs:line_join>
            }

            %<.constructor>
            %<methods:line_join>''',
        class_definition_base=('extend %<base>', ''),
        class_definition_constructor=('%<constructor>', ''),
        class_attr=switch('is_public',
                          true="%<name> %<@pseudo_type>",
                          _otherwise="%<name> %<@pseudo_type>"),
        immutable_class_attr="%<name:camel_case 'title'> %<@pseudo_type>",
        anonymous_function=switch(lambda a: len(a.block) == 1,
                                  true='func (%<#params>) { %<block:first> }',
                                  _otherwise='''
                func (%<#params>) {
                    %<block:line_join>
                }'''),
        constructor='''
            func new%<this>(%<#params>) *%<this> {
                %<block:line_join>
            }''',
        new_instance="new%<class_name>(%<args:join ', '>)",
        _go_bytes='[]byte(%<value>)',
        _go_make_slice='make(%<@slice_type>, %<#initial>, %<length>)',
        _go_simple_initializer="%<name>{%<args:join ', '>}",
        _go_declaration='var %<decl> %<@decl_type>',
        dependency='"%<name>"',
        break_='break',
        local='%<name>',
        typename='%<name>',
        int='%<value>',
        float='%<value>',
        string='%<#safe_double>',
        boolean='%<value>',
        null='nil',
        list=switch(lambda l: len(l.elements) > 0,
                    true="%<@pseudo_type> {%<elements:join ', '>}",
                    _otherwise="[]int {}"),
        dictionary=switch(lambda l: len(l.pairs) > 0,
                          true="%<@pseudo_type> { %<pairs:join ', '> }",
                          _otherwise="map[int]int {}"),
        pair="%<key>: %<value>",
        attr="%<object>.%<attr>",
        array="[...]%<#element_type>{%<elements:join ', '>}",
        _go_slice='%<sequence>[%<from_>:%<to>]',
        _go_slice_from='%<sequence>[%<from_>:]',
        _go_slice_to='%<sequence>[:%<to>]',
        assignment=switch('first_mention',
                          true='%<target> := %<value>',
                          _otherwise='%<target> = %<value>'),
        _go_multi_assignment=switch(
            'first_mention',
            true="%<targets:join ', '> := %<values:join ', '>",
            _otherwise="%<targets:join ', '> = %<values:join ', '>"),
        _go_ref='&%<value>',
        binary_op='%<#binary_left> %<#op> %<#binary_right>',
        unary_op='%<#op>%<value>',
        comparison='%<#binary_left> %<op> %<#binary_right>',
        set=switch(lambda l: len(l.elements) > 0,
                   true="%<@pseudo_type> { #set_pairs }",
                   _otherwise="map[int]struct{} {}"),
        static_call="%<receiver>.%<message>(%<args:join ', '>)",
        call="%<function>(%<args:join ', '>)",
        method_call="%<receiver>.%<message>(%<args:join ', '>)",
        this_method_call="this.%<message>(%<args:join ', '>)",
        this='this',
        instance_variable='this.%<name>',
        not_null_check='false',  #'%<value> != nil',
        throw_statement='throw %<exception>(%<value>)',
        if_statement='''
            if %<test> {
                %<block:line_join>
            } %<.otherwise>''',
        if_statement_otherwise=('%<otherwise>', ''),
        elseif_statement='''
            else if %<test> {
                %<block:line_join>
            } %<.otherwise>''',
        elseif_statement_otherwise=('%<otherwise>', ''),
        else_statement='''
            else {
                %<block:line_join>
            }''',
        while_statement='''
            for %<test> {
                %<block:line_join>
            }''',

        # try_statement = '''
        #     try
        #     {
        #         %<block:semi>
        #     }
        #     %<handlers:lines>''',

        # exception_handler = '''
        #     except %<exception> as %<instance>
        #     {
        #         %<block:semi>''',
        for_statement=switch(lambda f: f.iterators.type,
                             for_iterator_zip='''
                for _index, _ := range %<sequences> {
                    %<#zip_iterators>
                    %<block:line_join>
                }
            ''',
                             _otherwise='''
                for %<iterators> := range %<sequences> {
                    %<block:line_join>
                }'''),
        for_range_statement='''
            for %<index> := %<.first>; %<index> != %<end>; %<index> += %<.step> {
                %<block:line_join>
            }''',
        for_range_statement_first=('%<start>', '0'),
        for_range_statement_step=('%<step>', '1'),
        for_iterator='_, %<iterator>',
        for_iterator_zip='%<#zip_iterators>',
        for_iterator_with_index='%<index>, %<iterator>',
        for_iterator_with_items='%<key>, %<value>',
        for_sequence='%<sequence>',
        for_sequence_zip='len(%<sequences:first>)',
        for_sequence_with_index='%<sequence>',
        for_sequence_with_items='%<sequence>',
        implicit_return='return %<value>',
        explicit_return='return %<value>',
        aug_assignment='%<target> %<op>= %<value>',
        index=switch(lambda i: i.index.type != 'int' or i.index.value >= 0,
                     true='%<sequence>[%<index>]',
                     _otherwise='%<sequence>[len(%<sequence>) - %<#index>]'),
        interpolation="fmt.Sprintf(\"%<args:join ''>\", %<#placeholderz>)",
        interpolation_literal='%<value>',
        interpolation_placeholder=switch(lambda i: i.pseudo_type == 'Int',
                                         true='%d',
                                         _otherwise='%s'),
        index_assignment='%<sequence>[%<index>] = %<value>',
        constant='%<constant> = %<init>',
        custom_exception='''
            class %<name> : Exception
        ''',
        simple_initializer="%<name>{%<args:join ', '>}",
        standard_iterable_call='''
            var _results %<@pseudo_type>
            for %<iterators> := range %<sequences> {
                if %<test:first> {
                    _results = append(_results, %<block:first>)
                }
            }
            _results''',
        standard_iterable_call_return='''
            var _results %<@pseudo_type>
            for %<iterators> := range %<sequences> {
                if %<test:first> {
                    _results = append(_results, %<block:first>)
                }
            }
            return _results''',
        block='%<block:line_join>',
        regex='"%<value>"',
    )

    def params(self, node, depth):
        return ', '.join(
            '%s %s' %
            (self._generate_node(k), self.render_type(node.pseudo_type[j + 1]))
            for j, k in enumerate(node.params))

    def dependencies(self, node, depth):
        if len(node.dependencies) == 1:
            return 'import "%s"' % node.dependencies[0].name
        elif len(node.dependencies) > 1:
            return 'import (\n\t%s\n)\n' % '\n\t'.join(
                '"%s"' % q.name for q in node.dependencies)
        else:
            return ''

    def element_type(self, node, _):
        return PseudoType('').expand_type(node.pseudo_type[1], self)

    def op(self, node, depth):
        return OPS.get(node.op, node.op)

    # keys in pseudo can be only string or int float bool
    def initial(self, node, _):
        '''initial value for make'''
        return {
            'Int': '0',
            'Float': '0.0',
            'String': '""',
            'Bool': 'true'
        }.get(node.slice_type[1], 'nil')

    def zip_iterators(self, node, depth):
        return '\n'.join(
            '%s%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 placeholderz(self, node, _):
        return ', '.join(
            self._generate_node(placeholder.value)
            for placeholder in node.args[1::2])

    def index(self, node, depth):
        return str(-node.index.value)

    def return_type(self, node, depth):
        format = self.render_type(node.return_type)
        if isinstance(node.return_type,
                      list) or node.return_type in self.types:
            return format
        else:
            return '*%s' % format