Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions examples/example_to_cpp_custom_function_names.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
"""Example usage of string_to_code.to_cpp with custom function names"""

import itertools
import setup_examples # noqa # pylint: disable=unused-import
from string_to_code import to_cpp

EXAMPLE_STR = "messy code"
FUNCTION_NAMES = (f"some_messy_fun_num_{_}" for _ in itertools.count(100, 100))
CODE = to_cpp.proc(EXAMPLE_STR, FUNCTION_NAMES)
CODE = to_cpp.proc(
EXAMPLE_STR,
function_id_to_name=lambda _: "some_messy_fun_num_" + str(100 * _ + 100),
)

print(f"C++ code below prints '{EXAMPLE_STR}':\n{CODE}")
41 changes: 21 additions & 20 deletions string_to_code/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@
Atom = collections.namedtuple("Atom", "atom_char")


class SimpleFunction(
collections.namedtuple("SimpleFunction", ["function_name", "called_list"])
):
class SimpleFunction(collections.namedtuple("SimpleFunction", ["called_list"])):
"""
represents a function with no arguments and no return value calling
other functions of such type or displaying single characters
Expand Down Expand Up @@ -56,29 +54,27 @@ def _interesting_random_split(in_str):
return res


def gen_function_names(in_name_prefix="f_"):
"""yields 'f_0', 'f_1', 'f_2', ..."""
cur_function_num = 0
while True:
yield f"{in_name_prefix}{cur_function_num}"
cur_function_num += 1
def get_function_namer(in_name_prefix="f_"):
"""returns a defult function namer"""

def _inner(in_id):
return in_name_prefix + str(in_id)

def _prepare_printer_program(in_str, function_names):
return _inner


def _prepare_printer_program(in_str):
needed_functions = []

@functools.lru_cache(maxsize=None)
def _generate_code(in_str):
if len(in_str) == 1:
return Atom(in_str)

cur_function_name = next(function_names)
str_split = _interesting_random_split(in_str)
res = SimpleFunction(
cur_function_name, [_generate_code(_) for _ in str_split]
)
res = SimpleFunction([_generate_code(_) for _ in str_split])
needed_functions.append(res)
return res.function_name
return len(needed_functions) - 1

initial_call = _generate_code(in_str) if in_str else None
return initial_call, needed_functions
Expand All @@ -102,14 +98,19 @@ def _check_data(self):
):
assert self.needed_functions
if self.needed_functions:
assert isinstance(self.initial_call, str)
assert isinstance(self.initial_call, int)

def needed_function_definitions_str_list(self, in_function_to_str):
def needed_function_definitions_str_list(
self, in_function_to_str, **kwargs
):
"""
returns a list of string representations of the definition of
the needed functions
"""
return [in_function_to_str(_) for _ in self.needed_functions]
return [
in_function_to_str(id, fun, **kwargs)
for id, fun in enumerate(self.needed_functions)
]

@property
def initial_call(self):
Expand All @@ -122,6 +123,6 @@ def needed_functions(self):
return self._needed_functions


def get_printer_program(in_str, function_names):
def get_printer_program(in_str):
"""returns a PrinterProgram object diplaying in_str"""
return PrinterProgram(*_prepare_printer_program(in_str, function_names))
return PrinterProgram(*_prepare_printer_program(in_str))
22 changes: 15 additions & 7 deletions string_to_code/to_algol68.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
from . import utils


def _get_function_name(in_function_id, **kwargs):
return kwargs.get("function_id_to_name", core.get_function_namer("p"))(
in_function_id
)


def atom_to_code(in_atom):
"""
returns a string/piece of ALGOL 68 code resulting in printing the
Expand All @@ -18,19 +24,20 @@ def atom_to_code(in_atom):
return f"print({res_char});"


def function_call_str(in_function_name):
def function_call_str(in_function_id, **kwargs):
"""
returns a string calling a function with name in_function_name in ALGOL 68
"""
return f"{in_function_name};"
function_name = _get_function_name(in_function_id, **kwargs)
return f"{function_name};"


_call_function_or_atom = utils.get_call_function_or_atom(
atom_to_code, function_call_str
)


def function_to_code(in_function):
def function_to_code(in_function_id, in_function, **kwargs):
"""
returns a string representing the code of the function/procedure
definiton in ALGOL 68
Expand All @@ -44,18 +51,19 @@ def function_to_code(in_function):
assert function_body[-1] == ";"
function_body = "\n" + function_body[:-1] + "\n"

return f"PROC {in_function.function_name} = VOID :({function_body});"
function_name = _get_function_name(in_function_id, **kwargs)
return f"PROC {function_name} = VOID :({function_body});"


def _main_call_to_code(in_initial_call):
def _main_call_to_code(in_initial_call, **kwargs):
if in_initial_call is None:
return 'print("")'
res = _call_function_or_atom(in_initial_call)
res = _call_function_or_atom(in_initial_call, **kwargs)
assert res[-1] == ";"
return res[:-1]


def _join_to_final(main_call, function_definitions):
def _join_to_final(main_call, function_definitions, **_kwargs):
assert main_call[-1] != "\n"
return "\n\n\n".join(function_definitions + [main_call + "\n"])

Expand Down
24 changes: 16 additions & 8 deletions string_to_code/to_bash.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
from . import utils


def _get_function_name(in_function_id, **kwargs):
return kwargs.get("function_id_to_name", core.get_function_namer("fun_"))(
in_function_id
)


def atom_to_code(in_atom):
"""
returns a string/piece of bash code resulting in printing the
Expand All @@ -23,19 +29,19 @@ def atom_to_code(in_atom):
return f'printf "{res_char}"'


def function_call_str(in_function_name):
def function_call_str(in_function_id, **kwargs):
"""
returns a string calling a function with name in_function_name in bash
"""
return in_function_name
return _get_function_name(in_function_id, **kwargs)


_call_function_or_atom = utils.get_call_function_or_atom(
atom_to_code, function_call_str
)


def function_to_code(in_function):
def function_to_code(in_function_id, in_function, **kwargs):
"""
returns a string representing the code of the function definiton in bash
"""
Expand All @@ -44,20 +50,22 @@ def function_to_code(in_function):
function_body = " true"
if in_function.called_list:
function_body = "\n".join(
" " + _call_function_or_atom(_) for _ in in_function.called_list
" " + _call_function_or_atom(_, **kwargs)
for _ in in_function.called_list
)

return f"{in_function.function_name} ()\n{{\n{function_body}\n}}"
function_name = _get_function_name(in_function_id, **kwargs)
return f"{function_name} ()\n{{\n{function_body}\n}}"


def _main_call_to_code(in_initial_call):
def _main_call_to_code(in_initial_call, **kwargs):
res = ""
if in_initial_call is not None:
res = _call_function_or_atom(in_initial_call)
res = _call_function_or_atom(in_initial_call, **kwargs)
return res


def _join_to_final(main_call, function_definitions):
def _join_to_final(main_call, function_definitions, **_kwargs):
res = "\n\n\n".join(function_definitions + [main_call])
if res:
res = "\n\n" + res
Expand Down
25 changes: 17 additions & 8 deletions string_to_code/to_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
from . import utils


def _get_function_name(in_function_id, **kwargs):
return kwargs.get("function_id_to_name", core.get_function_namer("fun_"))(
in_function_id
)


def atom_to_code(in_atom):
"""
returns a string/piece of C code resulting in printing the
Expand All @@ -22,41 +28,44 @@ def atom_to_code(in_atom):
return f"putchar('{res_char}');"


def function_call_str(in_function_name):
def function_call_str(in_function_id, **kwargs):
"""returns a string calling a function with name in_function_name in C"""
return f"{in_function_name}();"
function_name = _get_function_name(in_function_id, **kwargs)
return f"{function_name}();"


_call_function_or_atom = utils.get_call_function_or_atom(
atom_to_code, function_call_str
)


def function_to_code(in_function):
def function_to_code(in_function_id, in_function, **kwargs):
"""
returns a string representing the code of the function definiton in C
"""
assert isinstance(in_function, core.SimpleFunction)

function_body = "\n".join(
" " + _call_function_or_atom(_) for _ in in_function.called_list
" " + _call_function_or_atom(_, **kwargs)
for _ in in_function.called_list
)

if function_body:
function_body = "\n" + function_body + "\n"

function_name = _get_function_name(in_function_id, **kwargs)
res = "\n".join(
[
f"void {in_function.function_name}()",
f"void {function_name}()",
"{" + function_body + "}",
]
)
return res


def _main_call_to_code(in_initial_call):
def _main_call_to_code(in_initial_call, **kwargs):
initial_call_str = (
" " + _call_function_or_atom(in_initial_call) + "\n "
" " + _call_function_or_atom(in_initial_call, **kwargs) + "\n "
if in_initial_call is not None
else " "
)
Expand All @@ -66,7 +75,7 @@ def _main_call_to_code(in_initial_call):
}}"""


def _join_to_final(main_call, function_definitions):
def _join_to_final(main_call, function_definitions, **_kwargs):
res = "\n\n".join(function_definitions + [main_call]) + "\n"
if function_definitions or "putchar" in main_call:
res = "#include <stdio.h>\n\n" + res
Expand Down
25 changes: 16 additions & 9 deletions string_to_code/to_cobol.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
from . import utils


def _get_function_name(in_function_id, **kwargs):
return kwargs.get("function_id_to_name", core.get_function_namer("P_"))(
in_function_id
)


def atom_to_code(in_atom):
"""
returns a string/piece of cobol code resulting in printing the
Expand All @@ -28,19 +34,20 @@ def proc_char(in_char):
return res


def function_call_str(in_function_name):
def function_call_str(in_function_id, **kwargs):
"""
returns a string calling a function with name in_function_name in cobol
"""
return f"CALL '{in_function_name}' END-CALL."
function_name = _get_function_name(in_function_id, **kwargs)
return f"CALL '{function_name}' END-CALL."


_call_function_or_atom = utils.get_call_function_or_atom(
atom_to_code, function_call_str
)


def function_to_code(in_function):
def function_to_code(in_function_id, in_function, **kwargs):
"""
returns a string representing the code of the function definiton in cobol
"""
Expand All @@ -55,25 +62,25 @@ def function_to_code(in_function):
)
+ "\n"
)

function_name = _get_function_name(in_function_id, **kwargs)
return (
" IDENTIFICATION DIVISION.\n"
f" PROGRAM-ID. {in_function.function_name} IS COMMON.\n"
f" PROGRAM-ID. {function_name} IS COMMON.\n"
" ENVIRONMENT DIVISION.\n"
" PROCEDURE DIVISION.\n"
f"{function_body}"
f" END PROGRAM {in_function.function_name}."
f" END PROGRAM {function_name}."
)


def _main_call_to_code(in_initial_call):
def _main_call_to_code(in_initial_call, **kwargs):
res = ""
if in_initial_call is not None:
res = " " + _call_function_or_atom(in_initial_call)
res = " " + _call_function_or_atom(in_initial_call, **kwargs)
return res


def _join_to_final(main_call, function_definitions):
def _join_to_final(main_call, function_definitions, **_kwargs):
code_str = "\n\n".join([main_call] + function_definitions)
if code_str:
code_str += "\n"
Expand Down
Loading