<commit_before>"""
Go generator
"""
import ast
from .. import (
    parse_eval_stmt,
    prepare_expr
)
from .. import (
    EvalStmt,
    IfStmt,
    ThenStmt,
    ElseStmt,
    ExecuteStmt,
)
from .base import JavaLikeGenerator

class GoGenerator(JavaLikeGenerator):
    """ Go Generator """
    bd_class = 'decimal.Decimal'
    bd_class_constructor = 'decimal.NewFromInt'
    list_const_parens = ('{', '}')
    stmt_separator = ''
    allow_constants = False
    instance_var = 't'

    def __init__(self, parser, outfile, class_name=None, indent=None, package_name='default'):
        super(GoGenerator, self).__init__(parser, outfile, class_name, indent)
        self.package_name = package_name

    def generate(self):
        wr = self.writer
        self._write_comment("This file is automatically generated by LstGen, do not edit!", False)
        wr.writeln('package {}'.format(self.package_name or 'tax'))
        wr.nl()
        wr.writeln('import ( "github.com/shopspring/decimal" )')
        wr.nl()

        # Define the model as a struct.
        with self.writer.indent('type {} struct'.format(self.class_name)):
            wr.writeln("// ------------------------ Constants -------------------------")
            for const in self.parser.constants:
                if const.comment is not None:
                    wr.nl()
                    self._write_comment(const.comment, False)

                if const.type.endswith('[]'):
                    const.value = '[{}]'.format(const.value[1:-1])

                thetype = self._convert_vartype(const.type)
                wr.writeln('{const.name} {thetype}'.format(
                    const=const,
                    thetype=thetype
                ))

            for (comment, variables) in [
                    ('Input variables', self.parser.input_vars),
                    ('Output variables', self.parser.output_vars),
                    ('Internal variables', self.parser.internal_vars),
                ]:
                wr.nl()
                wr.writeln('// {}'.format(comment))

                wr.writeln("// ------------------------ Variables -------------------------")
                for var in variables:
                    if var.comment is not None:
                        wr.nl()
                        self._write_comment(var.comment, False)
                    vartype = self._convert_vartype(var.type)
                    wr.writeln('{} {}'.format(var.name, vartype))

        # Define the New() method that also sets default values.
        with self.writer.indent('func New{cls}() *{cls}'.format(cls=self.class_name)):
            with self.writer.indent('return &{}'.format(self.class_name)):
                wr.writeln("// ------------------------ Constants -------------------------")
                for const in self.parser.constants:
                    if const.comment is not None:
                        wr.nl()
                        self._write_comment(const.comment, False)

                    if const.type.endswith('[]'):
                        const.value = '[{}]'.format(const.value[1:-1])

                    value = self.convert_to_go(const.value)
                    wr.writeln('{const.name}: {value},'.format(
                        const=const,
                        value=value
                    ))

                wr.nl()
                wr.writeln("// ------------------------ Variables -------------------------")
                for (comment, variables) in [
                        ('Input variables', self.parser.input_vars),
                        ('Output variables', self.parser.output_vars),
                        ('Internal variables', self.parser.internal_vars),
                    ]:

                    for var in variables:
                        if var.default is None:
                            continue

                        if var.comment is not None:
                            wr.nl()
                            self._write_comment(var.comment, False)

                        value = self.convert_to_go(var.default)
                        wr.writeln('{}: {},'.format(var.name, value))


        # create setters for input vars
        for var in self.parser.input_vars:
            wr.nl()
            signature = 'func ({instance} *{cls}) Set{cap}(value {type})'.format(
                instance=self.instance_var,
                cls=self.class_name,
                cap=var.name.capitalize(),
                type=self._convert_vartype(var.type)
            )
            with wr.indent(signature):
                wr.writeln('{instance}.{name} = value'.format(
                    instance=self.instance_var,
                    name=var.name
                ))

        # create getters for output vars
        for var in self.parser.output_vars:
            wr.nl()
            signature = 'func ({instance} *{cls}) Get{cap}() {type}'.format(
                instance=self.instance_var,
                cls=self.class_name,
                cap=var.name.capitalize(),
                type=self._convert_vartype(var.type)
            )
            with wr.indent(signature):
                wr.writeln('return {instance}.{name}'.format(
                    instance=self.instance_var,
                    name=var.name
                ))

        self._write_method(self.parser.main_method)
        for method in self.parser.methods:
            self._write_method(method)
        wr.nl()

    def _convert_vartype(self, vartype):
        return {
            'BigDecimal.ZERO': 'decimal.NewFromInt(0)',
            'BigDecimal[]': '[]'+self.bd_class,
            'BigDecimal': ''+self.bd_class,
            'int': 'int64',
            'double': 'int64',
        }[vartype]

    def _conv_list(self, node):
        res = super(GoGenerator, self)._conv_list(node)
        return ['[]' + self.bd_class] + res

    def _conv_attribute(self, node):
        clsmethod = False
        if node.attr == 'valueOf':
            node.attr = 'NewFromInt'
            clsmethod = True
        elif node.attr == 'ZERO':
            node.attr = 'NewFromInt(0)'
            clsmethod = True
        elif node.attr == 'ONE':
            node.attr = 'NewFromInt(1)'
            clsmethod = True
        elif node.attr == 'TEN':
            node.attr = 'NewFromInt(10)'<commit_msg>double should be float64 in Go, not in64<commit_after>"""
Go generator
"""
import ast
from .. import (
    parse_eval_stmt,
    prepare_expr
)
from .. import (
    EvalStmt,
    IfStmt,
    ThenStmt,
    ElseStmt,
    ExecuteStmt,
)
from .base import JavaLikeGenerator

class GoGenerator(JavaLikeGenerator):
    """ Go Generator """
    bd_class = 'decimal.Decimal'
    bd_class_constructor = 'decimal.NewFromInt'
    list_const_parens = ('{', '}')
    stmt_separator = ''
    allow_constants = False
    instance_var = 't'

    def __init__(self, parser, outfile, class_name=None, indent=None, package_name='default'):
        super(GoGenerator, self).__init__(parser, outfile, class_name, indent)
        self.package_name = package_name

    def generate(self):
        wr = self.writer
        self._write_comment("This file is automatically generated by LstGen, do not edit!", False)
        wr.writeln('package {}'.format(self.package_name or 'tax'))
        wr.nl()
        wr.writeln('import ( "github.com/shopspring/decimal" )')
        wr.nl()

        # Define the model as a struct.
        with self.writer.indent('type {} struct'.format(self.class_name)):
            wr.writeln("// ------------------------ Constants -------------------------")
            for const in self.parser.constants:
                if const.comment is not None:
                    wr.nl()
                    self._write_comment(const.comment, False)

                if const.type.endswith('[]'):
                    const.value = '[{}]'.format(const.value[1:-1])

                thetype = self._convert_vartype(const.type)
                wr.writeln('{const.name} {thetype}'.format(
                    const=const,
                    thetype=thetype
                ))

            for (comment, variables) in [
                    ('Input variables', self.parser.input_vars),
                    ('Output variables', self.parser.output_vars),
                    ('Internal variables', self.parser.internal_vars),
                ]:
                wr.nl()
                wr.writeln('// {}'.format(comment))

                wr.writeln("// ------------------------ Variables -------------------------")
                for var in variables:
                    if var.comment is not None:
                        wr.nl()
                        self._write_comment(var.comment, False)
                    vartype = self._convert_vartype(var.type)
                    wr.writeln('{} {}'.format(var.name, vartype))

        # Define the New() method that also sets default values.
        with self.writer.indent('func New{cls}() *{cls}'.format(cls=self.class_name)):
            with self.writer.indent('return &{}'.format(self.class_name)):
                wr.writeln("// ------------------------ Constants -------------------------")
                for const in self.parser.constants:
                    if const.comment is not None:
                        wr.nl()
                        self._write_comment(const.comment, False)

                    if const.type.endswith('[]'):
                        const.value = '[{}]'.format(const.value[1:-1])

                    value = self.convert_to_go(const.value)
                    wr.writeln('{const.name}: {value},'.format(
                        const=const,
                        value=value
                    ))

                wr.nl()
                wr.writeln("// ------------------------ Variables -------------------------")
                for (comment, variables) in [
                        ('Input variables', self.parser.input_vars),
                        ('Output variables', self.parser.output_vars),
                        ('Internal variables', self.parser.internal_vars),
                    ]:

                    for var in variables:
                        if var.default is None:
                            continue

                        if var.comment is not None:
                            wr.nl()
                            self._write_comment(var.comment, False)

                        value = self.convert_to_go(var.default)
                        wr.writeln('{}: {},'.format(var.name, value))


        # create setters for input vars
        for var in self.parser.input_vars:
            wr.nl()
            signature = 'func ({instance} *{cls}) Set{cap}(value {type})'.format(
                instance=self.instance_var,
                cls=self.class_name,
                cap=var.name.capitalize(),
                type=self._convert_vartype(var.type)
            )
            with wr.indent(signature):
                wr.writeln('{instance}.{name} = value'.format(
                    instance=self.instance_var,
                    name=var.name
                ))

        # create getters for output vars
        for var in self.parser.output_vars:
            wr.nl()
            signature = 'func ({instance} *{cls}) Get{cap}() {type}'.format(
                instance=self.instance_var,
                cls=self.class_name,
                cap=var.name.capitalize(),
                type=self._convert_vartype(var.type)
            )
            with wr.indent(signature):
                wr.writeln('return {instance}.{name}'.format(
                    instance=self.instance_var,
                    name=var.name
                ))

        self._write_method(self.parser.main_method)
        for method in self.parser.methods:
            self._write_method(method)
        wr.nl()

    def _convert_vartype(self, vartype):
        return {
            'BigDecimal.ZERO': 'decimal.NewFromInt(0)',
            'BigDecimal[]': '[]'+self.bd_class,
            'BigDecimal': ''+self.bd_class,
            'int': 'int64',
            'double': 'float64',
        }[vartype]

    def _conv_list(self, node):
        res = super(GoGenerator, self)._conv_list(node)
        return ['[]' + self.bd_class] + res

    def _conv_attribute(self, node):
        clsmethod = False
        if node.attr == 'valueOf':
            node.attr = 'NewFromInt'
            clsmethod = True
        elif node.attr == 'ZERO':
            node.attr = 'NewFromInt(0)'
            clsmethod = True
        elif node.attr == 'ONE':
            node.attr = 'NewFromInt(1)'
            clsmethod = True
        elif node.attr == 'TEN':
            node.attr = 'NewFromInt(10)'
{'fraction_non_alphanumeric': 0.14683444750294927, 'fraction_numerical': 0.0023594180102241447, 'mean_word_length': 1.3679702048417133, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7355841', 'n_tokens_mistral': 3437, 'n_tokens_neox': 3248, 'n_words': 668}