class CCodeGenerator(CLikeCodeGenerator): tpl_scalar_var_declare = CT("double ${var_name};") tpl_vector_var_declare = CT("double ${var_name}[${size}];") scalar_type = "double" vector_type = "double *" def __init__(self, *args, **kwargs): super(CCodeGenerator, self).__init__(*args, **kwargs) def add_function_def(self, name, args, is_scalar_output): return_type = self.scalar_type if is_scalar_output else "void" function_def = return_type + " " + name + "(" function_def += ", ".join( [self._get_var_type(is_vector) + " " + 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, 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("memcpy({}, {}, {} * sizeof(double));".format( target_var, source_var, size)) def add_dependency(self, dep): dep_str = "#include " + dep super().prepend_code_line(dep_str) def vector_init(self, values): return "(double[]){" + ", ".join(values) + "}" def _get_var_type(self, is_vector): return (self.vector_type if is_vector else self.scalar_type)
class PowershellCodeGenerator(CLikeCodeGenerator): tpl_var_declare = CT("{var_type}{var_name} = {init_val}") tpl_var_assignment = CT("{var_name} = {value}") tpl_array_index_access = CT("${array_name}[{index}]") tpl_return_statement = CT("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 __init__(self, *args, **kwargs): super(PowershellCodeGenerator, self).__init__(*args, **kwargs) def add_function_def(self, name, args, is_scalar_output): function_def = "function " + name + "(" function_def += ", ".join([ self._get_var_type(is_vector) + " $" + 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, is_scalar_output): self.add_function_def(name, args, is_scalar_output) yield self.add_block_termination() def function_invocation(self, function_name, *args): return (function_name + " " + " ".join(map(lambda x: "$({})".format(x), args))) def math_function_invocation(self, function_name, *args): return function_name + "(" + ", ".join(map(str, args)) + ")" def get_var_name(self): return "$" + 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)" if size > 1 else "0")) return var_name def vector_init(self, values): return ("@(" + ", ".join(map(lambda x: "$({})".format(x), values)) + ")") 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]
class PowershellCodeGenerator(CLikeCodeGenerator): tpl_var_declare = CT("{var_type}{var_name} = {init_val}") tpl_var_assignment = CT("{var_name} = {value}") tpl_array_index_access = CT("${array_name}[{index}]") tpl_return_statement = CT("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)" if size > 1 else "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]
class CCodeGenerator(CLikeCodeGenerator): tpl_scalar_var_declare = CT("double {var_name};") tpl_vector_var_declare = CT("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_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() @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 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): new_source_var = re.findall('{.*}', source_var)[0] self.add_code_line(f"double temp_array[] = {new_source_var};") self.add_code_line(f"memcpy({target_var}, temp_array, " 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_type(self, is_vector): return (self.vector_type if is_vector else self.scalar_type)
class PythonCodeGenerator(ImperativeCodeGenerator): tpl_num_value = CT("{value}") tpl_infix_expression = CT("({left}) {op} ({right})") tpl_return_statement = CT("return {value}") tpl_array_index_access = CT("{array_name}[{index}]") tpl_if_statement = CT("if {if_def}:") tpl_else_statement = CT("else:") tpl_var_assignment = CT("{var_name} = {value}") tpl_var_declaration = CT("") tpl_block_termination = CT("") 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)
class PythonCodeGenerator(BaseCodeGenerator): tpl_num_value = CT("${value}") tpl_infix_expression = CT("(${left}) ${op} (${right})") tpl_return_statement = CT("return ${value}") tpl_array_index_access = CT("${array_name}[${index}]") tpl_if_statement = CT("if ${if_def}:") tpl_else_statement = CT("else:") tpl_var_assignment = CT("${var_name} = ${value}") tpl_var_declaration = CT("") tpl_block_termination = CT("") def add_function_def(self, name, args): method_def = "def " + name + "(" method_def += ", ".join(args) method_def += "):" self.add_code_line(method_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 "np.asarray([" + ", ".join(values) + "])" def add_dependency(self, dep, alias=None): dep_str = "import " + dep if alias: dep_str += " as " + alias super().prepend_code_line(dep_str)
class RubyCodeGenerator(ImperativeCodeGenerator): tpl_var_declaration = CT("") tpl_num_value = CT("{value}") tpl_infix_expression = CT("({left}) {op} ({right})") tpl_return_statement = tpl_num_value tpl_array_index_access = CT("{array_name}[{index}]") tpl_if_statement = CT("if {if_def}") tpl_else_statement = CT("else") tpl_block_termination = CT("end") tpl_var_assignment = CT("{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)}]"