示例#1
0
class RCodeGenerator(CLikeCodeGenerator):

    tpl_return_statement = CodeTemplate("return({value})")
    tpl_var_assignment = CodeTemplate("{var_name} <- {value}")

    def __init__(self, *args, **kwargs):
        super(RCodeGenerator, self).__init__(*args, **kwargs)

    def add_var_declaration(self, size):
        return self.get_var_name()

    def add_function_def(self, name, args):
        function_def = name + " <- function("
        function_def += ",".join([arg for _, arg in args])
        function_def += ") {"
        self.add_code_line(function_def)
        self.increase_indent()

    @contextlib.contextmanager
    def function_definition(self, name, args, is_vector_output):
        self.add_function_def(name, args)
        yield
        self.add_block_termination()

    def array_index_access(self, array_name, index):
        return super().array_index_access(array_name, index + 1)

    def vector_init(self, values):
        return "c(" + ", ".join(values) + ")"
示例#2
0
class RustCodeGenerator(CLikeCodeGenerator):

    tpl_var_declaration = CodeTemplate("let {var_name}: {var_type};")
    tpl_num_value = CodeTemplate("{value}_f64")
    tpl_if_statement = CodeTemplate("if {if_def} {{")
    tpl_return_statement = CodeTemplate("{value}")

    scalar_type = "f64"
    vector_type = "Vec<f64>"

    def add_function_def(self, name, args, is_scalar_output):
        func_args = ", ".join([
            f"{n}: {self._get_var_declare_type(is_vector)}"
            for is_vector, n in args])
        return_type = self._get_var_declare_type(not is_scalar_output)
        function_def = f"fn {name}({func_args}) -> {return_type} {{"
        self.add_code_line(function_def)
        self.increase_indent()

    @contextmanager
    def function_definition(self, name, args, is_scalar_output):
        self.add_function_def(name, args, is_scalar_output)
        yield
        self.add_block_termination()

    def vector_init(self, values):
        return (f"vec![{', '.join(values)}]")

    def _get_var_declare_type(self, is_vector):
        return self.vector_type if is_vector else self.scalar_type
示例#3
0
class RCodeGenerator(CLikeCodeGenerator):

    tpl_return_statement = CodeTemplate("return({value})")
    tpl_var_assignment = CodeTemplate("{var_name} <- {value}")

    def add_var_declaration(self, size):
        return self.get_var_name()

    def add_function_def(self, name, args):
        func_args = ', '.join([arg for _, arg in args])
        function_def = f"{name} <- function({func_args}) {{"
        self.add_code_line(function_def)
        self.increase_indent()

    @contextmanager
    def function_definition(self, name, args, is_vector_output):
        self.add_function_def(name, args)
        yield
        self.add_block_termination()

    def array_index_access(self, array_name, index):
        return super().array_index_access(array_name, index + 1)

    def vector_init(self, values):
        return f"c({', '.join(values)})"
示例#4
0
class PowershellCodeGenerator(CLikeCodeGenerator):

    tpl_var_declare = CodeTemplate("{var_type}{var_name} = {init_val}")
    tpl_var_assignment = CodeTemplate("{var_name} = {value}")
    tpl_array_index_access = CodeTemplate("${array_name}[{index}]")
    tpl_return_statement = CodeTemplate("return {value}")

    scalar_type = "[double]"
    vector_type = "[double[]]"

    operator_map = {
        CompOpType.EQ: "-eq",
        CompOpType.NOT_EQ: "-ne",
        CompOpType.GTE: "-ge",
        CompOpType.LTE: "-le",
        CompOpType.GT: "-gt",
        CompOpType.LT: "-lt"
    }

    def add_function_def(self, name, args, is_scalar_output):
        func_args = ", ".join(
            [f"{self._get_var_type(is_vector)} ${n}" for is_vector, n in args])
        function_def = f"function {name}({func_args}) {{"
        self.add_code_line(function_def)
        self.increase_indent()

    @contextlib.contextmanager
    def function_definition(self, name, args, is_scalar_output):
        self.add_function_def(name, args, is_scalar_output)
        yield
        self.add_block_termination()

    def function_invocation(self, function_name, *args):
        functions_args = " ".join(map(lambda x: f"$({x})", args))
        return f"{function_name} {functions_args}"

    def math_function_invocation(self, function_name, *args):
        return f"{function_name}({', '.join(map(str, args))})"

    def get_var_name(self):
        return f"${super().get_var_name()}"

    def add_var_declaration(self, size):
        var_name = self.get_var_name()
        self.add_code_line(
            self.tpl_var_declare(var_type=self._get_var_type(size > 1),
                                 var_name=var_name,
                                 init_val="@(0.0)" if size > 1 else "0.0"))
        return var_name

    def vector_init(self, values):
        vals = ", ".join(map(lambda x: f"$({x})", values))
        return f"@({vals})"

    def _get_var_type(self, is_vector):
        return self.vector_type if is_vector else self.scalar_type

    def _comp_op_overwrite(self, op):
        return self.operator_map[op]
示例#5
0
class CCodeGenerator(CLikeCodeGenerator):

    tpl_scalar_var_declare = CodeTemplate("double {var_name};")
    tpl_vector_var_declare = CodeTemplate("double {var_name}[{size}];")

    scalar_type = "double"
    vector_type = "double *"

    def add_function_def(self, name, args, is_scalar_output):
        return_type = self.scalar_type if is_scalar_output else "void"

        func_args = ", ".join([
            f"{self._get_var_declare_type(is_vector)} {n}"
            for is_vector, n in args])
        function_def = f"{return_type} {name}({func_args}) {{"
        self.add_code_line(function_def)
        self.increase_indent()

    @contextmanager
    def function_definition(self, name, args, is_scalar_output):
        self.add_function_def(name, args, is_scalar_output)
        yield
        self.add_block_termination()

    def add_var_declaration(self, size):
        var_name = self.get_var_name()

        if size > 1:
            tpl = self.tpl_vector_var_declare
        else:
            tpl = self.tpl_scalar_var_declare

        self.add_code_line(tpl(var_name=var_name, size=size))
        return var_name

    def add_var_assignment(self, var_name, value, value_size):
        if value_size == 1:
            return super().add_var_assignment(var_name, value, value_size)

        # vectors require special handling since we can't just assign
        # vectors in C.
        self.add_assign_array_statement(value, var_name, value_size)

    def add_assign_array_statement(self, source_var, target_var, size):
        self.add_code_line(f"memcpy({target_var}, {source_var}, "
                           f"{size} * sizeof(double));")

    def add_dependency(self, dep):
        self.prepend_code_line(f"#include {dep}")

    def vector_init(self, values):
        return f"(double[]){{{', '.join(values)}}}"

    def _get_var_declare_type(self, is_vector):
        return self.vector_type if is_vector else self.scalar_type
示例#6
0
class PythonCodeGenerator(ImperativeCodeGenerator):

    tpl_num_value = CodeTemplate("{value}")
    tpl_infix_expression = CodeTemplate("({left}) {op} ({right})")
    tpl_return_statement = CodeTemplate("return {value}")
    tpl_array_index_access = CodeTemplate("{array_name}[{index}]")
    tpl_if_statement = CodeTemplate("if {if_def}:")
    tpl_else_statement = CodeTemplate("else:")
    tpl_var_assignment = CodeTemplate("{var_name} = {value}")

    tpl_var_declaration = CodeTemplate("")
    tpl_block_termination = CodeTemplate("")

    def add_function_def(self, name, args):
        function_def = f"def {name}({', '.join(args)}):"
        self.add_code_line(function_def)
        self.increase_indent()

    @contextlib.contextmanager
    def function_definition(self, name, args):
        self.add_function_def(name, args)
        yield

    def vector_init(self, values):
        return f"[{', '.join(values)}]"

    def add_dependency(self, dep, alias=None):
        dep_str = f"import {dep}"
        if alias:
            dep_str += f" as {alias}"
        self.prepend_code_line(dep_str)
示例#7
0
class RubyCodeGenerator(ImperativeCodeGenerator):

    tpl_var_declaration = CodeTemplate("")
    tpl_num_value = CodeTemplate("{value}")
    tpl_infix_expression = CodeTemplate("({left}) {op} ({right})")
    tpl_return_statement = tpl_num_value
    tpl_array_index_access = CodeTemplate("{array_name}[{index}]")
    tpl_if_statement = CodeTemplate("if {if_def}")
    tpl_else_statement = CodeTemplate("else")
    tpl_block_termination = CodeTemplate("end")
    tpl_var_assignment = CodeTemplate("{var_name} = {value}")

    def add_function_def(self, name, args):
        func_def = f"def {name}({', '.join(args)})"
        self.add_code_line(func_def)
        self.increase_indent()

    @contextlib.contextmanager
    def function_definition(self, name, args):
        self.add_function_def(name, args)
        yield
        self.add_block_termination()

    def method_invocation(self, method_name, obj, args):
        return f"({obj}).{method_name}({', '.join(map(str, args))})"

    def vector_init(self, values):
        return f"[{', '.join(values)}]"
示例#8
0
class GoCodeGenerator(ImperativeCodeGenerator):
    tpl_num_value = CodeTemplate("{value}")
    tpl_infix_expression = CodeTemplate("({left}) {op} ({right})")
    tpl_array_index_access = CodeTemplate("{array_name}[{index}]")
    tpl_else_statement = CodeTemplate("}} else {{")
    tpl_block_termination = CodeTemplate("}}")
    tpl_var_declaration = CodeTemplate("var {var_name} {var_type}")
    tpl_return_statement = CodeTemplate("return {value}")
    tpl_if_statement = CodeTemplate("if {if_def} {{")
    tpl_var_assignment = CodeTemplate("{var_name} = {value}")

    scalar_type = "float64"
    vector_type = "[]float64"

    def __init__(self, *args, **kwargs):
        super(GoCodeGenerator, self).__init__(*args, **kwargs)

    def add_function_def(self, name, args, is_scalar_output):
        return_type = self._get_var_declare_type(not is_scalar_output)

        function_def = "func " + name + "("
        function_def += ", ".join([
            n + " " + self._get_var_declare_type(is_vector)
            for is_vector, n in args
        ])
        function_def += ") " + return_type + " {"
        self.add_code_line(function_def)
        self.increase_indent()

    @contextlib.contextmanager
    def function_definition(self, name, args, is_scalar_output):
        self.add_function_def(name, args, is_scalar_output)
        yield
        self.add_block_termination()

    def _get_var_declare_type(self, is_vector):
        return self.vector_type if is_vector else self.scalar_type

    def add_dependency(self, dep):
        dep_str = 'import "' + dep + '"'
        super().prepend_code_line(dep_str)

    @staticmethod
    def vector_init(values):
        return "[]float64{" + ", ".join(values) + "}"
示例#9
0
class GoCodeGenerator(ImperativeCodeGenerator):
    tpl_num_value = CodeTemplate("{value}")
    tpl_infix_expression = CodeTemplate("({left}) {op} ({right})")
    tpl_array_index_access = CodeTemplate("{array_name}[{index}]")
    tpl_else_statement = CodeTemplate("}} else {{")
    tpl_block_termination = CodeTemplate("}}")
    tpl_var_declaration = CodeTemplate("var {var_name} {var_type}")
    tpl_return_statement = CodeTemplate("return {value}")
    tpl_if_statement = CodeTemplate("if {if_def} {{")
    tpl_var_assignment = CodeTemplate("{var_name} = {value}")

    scalar_type = "float64"
    vector_type = "[]float64"

    def add_function_def(self, name, args, is_scalar_output):
        return_type = self._get_var_declare_type(not is_scalar_output)

        func_args = ", ".join([
            f"{n} {self._get_var_declare_type(is_vector)}"
            for is_vector, n in args
        ])
        function_def = f"func {name}({func_args}) {return_type} {{"
        self.add_code_line(function_def)
        self.increase_indent()

    @contextlib.contextmanager
    def function_definition(self, name, args, is_scalar_output):
        self.add_function_def(name, args, is_scalar_output)
        yield
        self.add_block_termination()

    def _get_var_declare_type(self, is_vector):
        return self.vector_type if is_vector else self.scalar_type

    def add_dependency(self, dep):
        super().prepend_code_line(f'import "{dep}"')

    def vector_init(self, values):
        return f"[]float64{{{', '.join(values)}}}"
示例#10
0
class PhpCodeGenerator(CLikeCodeGenerator):

    tpl_array_index_access = CodeTemplate("$$${array_name}[${index}]")

    def __init__(self, *args, **kwargs):
        super(PhpCodeGenerator, self).__init__(*args, **kwargs)

    def add_function_def(self, name, args):
        function_def = "function " + name + "("
        function_def += ", ".join([("array " if is_vector else "") + "$" + n
                                   for is_vector, n in args])
        function_def += ") {"
        self.add_code_line(function_def)
        self.increase_indent()

    @contextlib.contextmanager
    def function_definition(self, name, args):
        self.add_function_def(name, args)
        yield
        self.add_block_termination()

    def get_var_name(self):
        return "$" + super().get_var_name()

    def add_var_declaration(self, size):
        var_name = self.get_var_name()
        self.add_var_assignment(var_name=var_name,
                                value="array()" if size > 1 else "null",
                                value_size=size)
        return var_name

    def vector_init(self, values):
        return "array(" + ", ".join(values) + ")"

    def _comp_op_overwrite(self, op):
        if op == CompOpType.EQ:
            return "==="
        elif op == CompOpType.NOT_EQ:
            return "!=="
        else:
            return op.value
示例#11
0
class PhpCodeGenerator(CLikeCodeGenerator):

    tpl_array_index_access = CodeTemplate("${array_name}[{index}]")

    def add_function_def(self, name, args):
        func_args = ", ".join([
            f"{'array ' if is_vector else ''}${n}"
            for is_vector, n in args])
        function_def = f"function {name}({func_args}) {{"
        self.add_code_line(function_def)
        self.increase_indent()

    @contextmanager
    def function_definition(self, name, args):
        self.add_function_def(name, args)
        yield
        self.add_block_termination()

    def get_var_name(self):
        return f"${super().get_var_name()}"

    def add_var_declaration(self, size):
        var_name = self.get_var_name()
        self.add_var_assignment(
            var_name=var_name,
            value="array()" if size > 1 else "null",
            value_size=size)
        return var_name

    def vector_init(self, values):
        return f"array({', '.join(values)})"

    def _comp_op_overwrite(self, op):
        if op == CompOpType.EQ:
            return "==="
        elif op == CompOpType.NOT_EQ:
            return "!=="
        else:
            return op.value
示例#12
0
class HaskellCodeGenerator(FunctionalCodeGenerator):
    tpl_function_signature = CodeTemplate("{function_name} =")
    tpl_if_statement = CodeTemplate("if ({if_def}) then")
    tpl_else_statement = CodeTemplate("else")
    tpl_num_value = CodeTemplate("{value}")
    tpl_infix_expression = CodeTemplate("({left}) {op} ({right})")
    tpl_module_definition = CodeTemplate("module {module_name} where")

    def array_index_access(self, array_name, index):
        return self.tpl_infix_expression(left=array_name, op="!!", right=index)

    def add_if_termination(self):
        self.decrease_indent()

    def add_function_def(self, name, args, is_scalar_output):
        types = " -> ".join([
            "[Double]" if is_vector else "Double"
            for is_vector, _ in [*args, (not is_scalar_output, None)]
        ])
        signature = f"{name} :: {types}"
        self.add_code_line(signature)

        func_args = " ".join([n for _, n in args])
        function_def = f"{name} {func_args} ="
        self.add_code_line(function_def)

        self.increase_indent()

    @contextlib.contextmanager
    def function_definition(self, name, args, is_scalar_output):
        self.add_function_def(name, args, is_scalar_output)
        yield
        self.decrease_indent()

    def vector_init(self, values):
        return f"[{', '.join(values)}]"

    def _comp_op_overwrite(self, op):
        if op == CompOpType.NOT_EQ:
            return "/="
        else:
            return op.value
示例#13
0
class FSharpCodeGenerator(FunctionalCodeGenerator):
    tpl_function_signature = CodeTemplate("let {function_name} =")
    tpl_if_statement = CodeTemplate("if ({if_def}) then")
    tpl_else_statement = CodeTemplate("else")
    tpl_num_value = CodeTemplate("{value}")
    tpl_infix_expression = CodeTemplate("({left}) {op} ({right})")
    tpl_array_index_access = CodeTemplate("{array_name}.[{index}]")

    def add_if_termination(self):
        self.decrease_indent()

    def add_function_def(self, name, args):
        func_args = " ".join([
            f"({n} : double{' list' if is_vector else ''})"
            for is_vector, n in args
        ])
        function_def = f"let {name} {func_args} ="
        self.add_code_line(function_def)
        self.increase_indent()

    @contextlib.contextmanager
    def function_definition(self, name, args):
        self.add_function_def(name, args)
        yield
        self.decrease_indent()

    def vector_init(self, values):
        return f"[{'; '.join(values)}]"

    def _comp_op_overwrite(self, op):
        if op == CompOpType.EQ:
            return "="
        elif op == CompOpType.NOT_EQ:
            return "<>"
        else:
            return op.value
示例#14
0
class VisualBasicCodeGenerator(BaseCodeGenerator):
    tpl_num_value = CodeTemplate("${value}")
    tpl_infix_expression = CodeTemplate("(${left}) ${op} (${right})")
    tpl_var_declaration = \
        CodeTemplate("Dim ${var_name}${type_modifier} As ${var_type}")
    tpl_return_statement = CodeTemplate("${func_name} = ${value}")
    tpl_if_statement = CodeTemplate("If ${if_def} Then")
    tpl_else_statement = CodeTemplate("Else")
    tpl_block_termination = CodeTemplate("End ${block_name}")
    tpl_array_index_access = CodeTemplate("${array_name}(${index})")
    tpl_array_set_by_index = CodeTemplate("${array_name}(${index}) = ${value}")
    tpl_var_assignment = CodeTemplate("${var_name} = ${value}")
    tpl_module_definition = CodeTemplate("Module ${module_name}")

    scalar_type = "Double"

    def __init__(self, *args, **kwargs):
        super(VisualBasicCodeGenerator, self).__init__(*args, **kwargs)

    def add_return_statement(self, value, func_name):
        self.add_code_line(
            self.tpl_return_statement(func_name=func_name, value=value))

    def add_var_declaration(self, size, exac_size=False):
        var_name = self.get_var_name()
        type_modifier = ("({})".format((size - 1) if exac_size else "")
                         if size > 1 else "")
        self.add_code_line(
            self.tpl_var_declaration(var_name=var_name,
                                     type_modifier=type_modifier,
                                     var_type=self.scalar_type))
        return var_name

    def add_block_termination(self, block_name="If"):
        self.decrease_indent()
        self.add_code_line(self.tpl_block_termination(block_name=block_name))

    def add_function_def(self, name, args, is_scalar_output):
        return_type = self.scalar_type
        return_type += "" if is_scalar_output else "()"

        function_def = "Function " + name + "("
        function_def += ", ".join([
            ("ByRef " if is_vector else "ByVal ") + n +
            ("()" if is_vector else "") + " As " + self.scalar_type
            for is_vector, n in args
        ])
        function_def += ") As " + return_type
        self.add_code_line(function_def)
        self.increase_indent()

    @contextlib.contextmanager
    def function_definition(self, name, args, is_scalar_output):
        self.add_function_def(name, args, is_scalar_output)
        yield
        self.decrease_indent()
        self.add_code_line(self.tpl_block_termination(block_name="Function"))

    def vector_init(self, values):
        var_name = self.add_var_declaration(len(values), exac_size=True)
        for i, val in enumerate(values):
            self.add_code_line(
                self.tpl_array_set_by_index(array_name=var_name,
                                            index=i,
                                            value=val))
        return var_name
示例#15
0
class VisualBasicCodeGenerator(ImperativeCodeGenerator):
    tpl_num_value = CodeTemplate("{value}")
    tpl_infix_expression = CodeTemplate("({left}) {op} ({right})")
    tpl_var_declaration = CodeTemplate("Dim {var_name}{type_modifier} As {var_type}")
    tpl_return_statement = CodeTemplate("{func_name} = {value}")
    tpl_if_statement = CodeTemplate("If {if_def} Then")
    tpl_else_statement = CodeTemplate("Else")
    tpl_block_termination = CodeTemplate("End {block_name}")
    tpl_array_index_access = CodeTemplate("{array_name}({index})")
    tpl_array_set_by_index = CodeTemplate("{array_name}({index}) = {value}")
    tpl_var_assignment = CodeTemplate("{var_name} = {value}")
    tpl_module_definition = CodeTemplate("Module {module_name}")

    scalar_type = "Double"

    def add_return_statement(self, value, func_name):
        self.add_code_line(self.tpl_return_statement(
            func_name=func_name, value=value))

    def add_var_declaration(self, size, exac_size=False):
        var_name = self.get_var_name()
        type_modifier = (f"({(size - 1) if exac_size else ''})"
                         if size > 1 else "")
        self.add_code_line(
            self.tpl_var_declaration(
                var_name=var_name,
                type_modifier=type_modifier,
                var_type=self.scalar_type))
        return var_name

    def add_block_termination(self, block_name="If"):
        self.decrease_indent()
        self.add_code_line(self.tpl_block_termination(block_name=block_name))

    def add_function_def(self, name, args, is_scalar_output):
        return_type = f"{self.scalar_type}{'' if is_scalar_output else '()'}"

        func_args = ", ".join([
            f"{'ByRef' if is_vector else 'ByVal'} {n}"
            f"{'()' if is_vector else ''} As {self.scalar_type}"
            for is_vector, n in args])
        function_def = f"Function {name}({func_args}) As {return_type}"
        self.add_code_line(function_def)
        self.increase_indent()

    @contextlib.contextmanager
    def function_definition(self, name, args, is_scalar_output):
        self.add_function_def(name, args, is_scalar_output)
        yield
        self.decrease_indent()
        self.add_code_line(self.tpl_block_termination(block_name="Function"))

    def vector_init(self, values):
        var_name = self.add_var_declaration(len(values), exac_size=True)
        for i, val in enumerate(values):
            self.add_code_line(self.tpl_array_set_by_index(
                array_name=var_name, index=i, value=val))
        return var_name

    def _comp_op_overwrite(self, op):
        if op == CompOpType.EQ:
            return "="
        elif op == CompOpType.NOT_EQ:
            return "<>"
        else:
            return op.value
示例#16
0
class FastlyVCLCodeGenerator(CLikeCodeGenerator):

    tpl_var_declaration = CodeTemplate("declare local {var_name} FLOAT;")
    tpl_var_assignment = CodeTemplate("set {var_name} = {value};")
    tpl_array_index_access = CodeTemplate("{array_name}_{index}")
    tpl_infix_expression = CodeTemplate("{left} {op} {right}")

    def __init__(self, indent=4, id_prefix="score"):
        self.id_prefix = self.header_var(id_prefix)
        super().__init__(indent)

    def header_var(self, name):
        return f"req.http.{name}"

    def reset_state(self):
        super().reset_state()
        self._sub_prefix = self.id_prefix
        self._sub_start_pos = 0
        self._output_size = 1
        self._input_idxs = {}
        self._var_sizes = {}

    def get_var_name(self):
        var_name = f"var.var{self._var_idx}"
        self._var_idx += 1
        return var_name

    def add_var_declaration(self, size):
        var_name = self.get_var_name()

        self._var_sizes[var_name] = size
        for i in range(size):
            self.add_code_line(
                self.tpl_var_declaration(var_name=f"{var_name}_{i}"))

        if size == 1:
            return var_name + "_0"

        return var_name

    def add_return_statement(self, value):
        if value in self._var_sizes:
            # this wont work if an array is passed directly to value
            # todo: check if that is a possibility
            self._output_size = self._var_sizes[value]

        if self._output_size > 1:
            for i in range(self._output_size):
                self.add_code_line(
                    self.tpl_var_assignment(
                        var_name=f"{self._sub_prefix}_output_{i}",
                        value=f"{value}_{i}"))
        else:
            self.add_code_line(
                self.tpl_var_assignment(
                    var_name=f"{self._sub_prefix}_output_0", value=f"{value}"))

        self.add_code_line("return;")

    def add_var_assignment(self, var_name, value, value_size):
        for i in range(value_size):
            if var_name in self._var_sizes:
                var = f"{var_name}_{i}"
            else:
                var = var_name
            self.add_code_line(
                self.tpl_var_assignment(
                    var_name=var,
                    value=(value[i] if value_size > 1 else value)))

    def add_function_def(self, name, args, is_vector_output):
        if args != [(True, "input")]:
            print(args)
            raise "Unexpected args given from FastlyVCLInterpreter"

        self.add_code_line(f"sub {name} {{")
        self._sub_start_pos = self._code_buf.tell()
        self.increase_indent()

    @contextlib.contextmanager
    def function_definition(self, name, args, is_vector_output):
        if self._sub_prefix != self.header_var(name):
            self._sub_prefix = f"{self._sub_prefix}_{name}"

        self.add_function_def(name, args, is_vector_output)
        yield
        self.add_block_termination()

        self._code_buf.seek(0)
        content = self._code_buf.read(self._sub_start_pos)
        for index, var_name in self._input_idxs.items():
            content += str(self._indent * " ") + \
                self.tpl_var_declaration(var_name=var_name) + "\n"
            content += str(self._indent * " ")
            content += self.tpl_var_assignment(
                var_name=f"{var_name}",
                value=f"std.atof({self.id_prefix}_input_{index})")
            content += "\n\n"

        content += self._code_buf.read()
        self._code_buf.seek(0)
        self._code_buf.write(content)

    def infix_expression(self, left, right, op):
        if op == "=":
            raise "Assignment should be done with add_var_assignment"
        elif op in ["+", "-", "*", "/", "%", "|", "&", "^", "<<", ">>", "rol"]:
            # this could be optimized
            var_name = self.add_var_declaration(1)
            self.add_var_assignment(var_name, left, 1)
            self.add_code_line(f"set {var_name} {op}= {right};")
            return var_name

        return self.tpl_infix_expression(left=left, right=right, op=op)

    def sub_invocation(self, sub_name):
        self.add_code_line(f"call {sub_name};")
        var_name = self.add_var_declaration(1)
        self.add_var_assignment(
            var_name, f"std.atof({self.id_prefix}_{sub_name}_output_0)", 1)
        return var_name

    def array_index_access(self, array_name, index):
        if array_name == "input":
            var_name = f"var.input_{index}"
            self._input_idxs[index] = var_name
            return var_name

        return super().array_index_access(array_name, index)

    def vector_init(self, values):
        # vectors must be assigned value by value
        # this is done in add_var_assignment
        return values
示例#17
0
class HaskellCodeGenerator(BaseCodeGenerator):
    tpl_num_value = CodeTemplate("{value}")
    tpl_infix_expression = CodeTemplate("({left}) {op} ({right})")
    tpl_module_definition = CodeTemplate("module {module_name} where")

    def __init__(self, *args, **kwargs):
        self._func_idx = 0
        super().__init__(*args, **kwargs)

    def reset_state(self):
        super().reset_state()
        self._func_idx = 0

    def array_index_access(self, array_name, index):
        return self.tpl_infix_expression(left=array_name, op="!!", right=index)

    def add_if_statement(self, if_def):
        self.add_code_line("if ({})".format(if_def))
        self.increase_indent()
        self.add_code_line("then")
        self.increase_indent()

    def add_else_statement(self):
        self.decrease_indent()
        self.add_code_line("else")
        self.increase_indent()

    def add_if_termination(self):
        self.decrease_indent()
        self.decrease_indent()

    def get_func_name(self):
        func_name = "func" + str(self._func_idx)
        self._func_idx += 1
        return func_name

    def add_function(self, function_name, function_body):
        self.add_code_line("{} =".format(function_name))
        self.increase_indent()
        self.add_code_lines(function_body)
        self.decrease_indent()

    def function_invocation(self, function_name, *args):
        return (function_name + " " +
                " ".join(map(lambda x: "({})".format(x), args)))

    def add_function_def(self, name, args, is_scalar_output):
        signature = name + " :: "
        signature += " -> ".join([
            "[Double]" if is_vector else "Double"
            for is_vector, _ in [*args, (not is_scalar_output, None)]
        ])
        self.add_code_line(signature)

        function_def = name + " "
        function_def += " ".join([n for _, n in args])
        function_def += " ="
        self.add_code_line(function_def)

        self.increase_indent()

    @contextlib.contextmanager
    def function_definition(self, name, args, is_scalar_output):
        self.add_function_def(name, args, is_scalar_output)
        yield
        self.decrease_indent()

    def vector_init(self, values):
        return "[" + ", ".join(values) + "]"

    def _comp_op_overwrite(self, op):
        if op == CompOpType.NOT_EQ:
            return "/="
        else:
            return op.value
示例#18
0
class FSharpCodeGenerator(BaseCodeGenerator):
    tpl_num_value = CodeTemplate("{value}")
    tpl_infix_expression = CodeTemplate("({left}) {op} ({right})")
    tpl_array_index_access = CodeTemplate("{array_name}.[{index}]")

    def reset_state(self):
        super().reset_state()
        self._func_idx = 0

    def add_if_statement(self, if_def):
        self.add_code_line(f"if ({if_def}) then")
        self.increase_indent()

    def add_else_statement(self):
        self.decrease_indent()
        self.add_code_line("else")
        self.increase_indent()

    def add_if_termination(self):
        self.decrease_indent()

    def get_func_name(self):
        func_name = f"func{self._func_idx}"
        self._func_idx += 1
        return func_name

    def add_function(self, function_name, function_body):
        self.add_code_line(f"let {function_name} =")
        self.increase_indent()
        self.add_code_lines(function_body)
        self.decrease_indent()

    def function_invocation(self, function_name, *args):
        function_args = " ".join(map(lambda x: f"({x})", args))
        return f"{function_name} {function_args}"

    def add_function_def(self, name, args):
        func_args = " ".join([
            f"({n} : double{' list' if is_vector else ''})"
            for is_vector, n in args
        ])
        function_def = f"let {name} {func_args} ="
        self.add_code_line(function_def)
        self.increase_indent()

    @contextlib.contextmanager
    def function_definition(self, name, args):
        self.add_function_def(name, args)
        yield
        self.decrease_indent()

    def vector_init(self, values):
        return f"[{'; '.join(values)}]"

    def _comp_op_overwrite(self, op):
        if op == CompOpType.EQ:
            return "="
        elif op == CompOpType.NOT_EQ:
            return "<>"
        else:
            return op.value