STRUCT_BASE_NAME = "PlaceholderStructName"
STRUCT_ACTUAL_NAME = "Reg{size}Bits"
FIND_SIZE = 32
MAX_SIZE = 64
DEBUG = 0
REFERENCE_FILE = 'src/reg_reference.rs'
DOC_HIDDEN = '#[doc(hidden)]'
COMMENTS = """
// This file was automatically generated with the `generate_impl_rs.py` script.
// Any bugs in this script should be addressed in the `reg_reference.rs` file.
//
// The contents of this file is as follows:
// 1. Definition of RegXBits struct
// 2. Implementation of operations
// 3. Implementation of traits
""".strip()
BASE_TYPE_EQ = """
impl PartialEq<BaseType> for PlaceholderStructName<i> {
fn eq(&self, other: &BaseType) -> bool {
self.0 == *other
}
}
"""
INTER_SIZE_CONVERT = """
#[cfg(feature = "{1}bit")]
impl From<crate::reg{1}::Reg{1}Bits<{2}>> for crate::reg{0}::Reg{0}Bits<{2}> {{
fn from(item: crate::reg{1}::Reg{1}Bits<{2}>) -> Self {{
<crate::reg{0}::Reg{0}Bits<{0}> as crate::reg{0}::Reg{0}BitsDownCast<{2}>>::
take_low(crate::reg{0}::Reg{0}Bits::new(u{1}::from(item) as u{0}))
}}
}}
#[doc(hidden)]
impl From<crate::reg{0}::Reg{0}Bits<{2}>> for u{1} {{
fn from(item: crate::reg{0}::Reg{0}Bits<{2}>) -> Self {{
item.0 as u{1}
}}
}}
"""
SMALLER_CREATE_IMPL = """
impl From<u{1}> for crate::reg{0}::Reg{0}Bits<{1}> {{
fn from(item: u{1}) -> Self {{
Self(item.into())
}}
}}
"""
DEFAULT_IMPL = """
impl Default for crate::reg{0}::Reg{0}Bits<{1}> {{
fn default() -> Self {{
Self(0)
}}
}}
"""
def i_geq_j(_, i, j):
return i >= j
def sum_of_sizes(size, i, j):
if i + j <= size:
return i + j
return None
trait_2arg_impls = {
"Concat": sum_of_sizes,
}
trait_1arg_impls = {
"DownCast": i_geq_j,
}
sizes = [ 8, 16, 32, 64 ]
def get_1arg_impl_string(struct, trait, x, y):
return "impl {struct}{trait}<{y}> for {struct}<{x}> {{}}".format(
struct=struct,
trait=trait,
x=x, y=y,
)
def get_2arg_impl_string(struct, trait, x, y, outcome):
return "impl {struct}{trait}<{y}, {outcome}> for {struct}<{x}> {{}}".format(
struct=struct,
trait=trait,
x=x, y=y,
outcome=outcome
)
with open(REFERENCE_FILE, 'r') as ref_file:
for size in sizes:
REPLACE_INDICATOR = '[REF_REPLACE]'
STOP_INDICATOR = '[REF_STOP]'
replace_struct_name = STRUCT_ACTUAL_NAME.format(size = size)
ref_file.seek(0, 0)
ref_lines = ref_file.readlines()
filled_txt = COMMENTS
filled_txt += "\n"
print("Generating {} bits struct... ".format(size), end = '')
SKIP_START = "[SKIP-{}]".format(size)
SKIP_END = "[END SKIP-{}]".format(size)
for line_num, line in enumerate(ref_lines):
if REPLACE_INDICATOR in line:
old_line = line
line = line.replace(str(FIND_SIZE), str(size))
if DEBUG == 1:
print("Replaced '{FIND_SIZE}' on line {line_num}".format(
FIND_SIZE=FIND_SIZE,
line_num=line_num+1
))
print("From: `{old_line}`".format(old_line=old_line.strip()))
print("To: `{line}`".format(line=line.strip()))
print("")
if STRUCT_BASE_NAME in line:
old_line = line
num_occurances = 0
while STRUCT_BASE_NAME in line:
line = line.replace(STRUCT_BASE_NAME, replace_struct_name)
num_occurances += 1
if DEBUG == 1:
print("Replaced {num_occurances} of '{STRUCT_BASE_NAME}' on line {line_num}".format(
num_occurances=num_occurances,
STRUCT_BASE_NAME=STRUCT_BASE_NAME,
line_num=line_num+1
))
print("From: `{old_line}`".format(old_line=old_line.strip()))
print("To: `{line}`".format(line=line.strip()))
print("")
if STOP_INDICATOR in line:
break;
filled_txt += line
filled_txt += "\n\n"
for i in range(1, size+1):
for j in range(1, size+1):
for trait_name, trait_fn in trait_1arg_impls.items():
if trait_fn(size, i, j):
filled_txt += DOC_HIDDEN
filled_txt += "\n"
filled_txt += get_1arg_impl_string(replace_struct_name, trait_name, i, j)
filled_txt += "\n"
for trait_name, trait_fn in trait_2arg_impls.items():
outcome = trait_fn(size, i, j)
if outcome != None:
filled_txt += DOC_HIDDEN
filled_txt += "\n"
filled_txt += get_2arg_impl_string(replace_struct_name, trait_name, i, j, outcome)
filled_txt += "\n"
for i in range(2, size+1):
filled_txt += DOC_HIDDEN
filled_txt += "\n"
filled_txt += BASE_TYPE_EQ.strip().replace(STRUCT_BASE_NAME, replace_struct_name).replace('<i>', '<{}>'.format(i))
filled_txt += "\n"
for i in range(1, MAX_SIZE+1):
if i > size:
break;
for other_size in sizes:
if size == other_size:
continue
filled_txt += DOC_HIDDEN
filled_txt += "\n"
filled_txt += INTER_SIZE_CONVERT.strip().format(size, other_size, i)
filled_txt += "\n"
for other_size in sizes:
if size <= other_size:
continue
filled_txt += DOC_HIDDEN
filled_txt += "\n"
filled_txt += SMALLER_CREATE_IMPL.strip().format(size, other_size)
filled_txt += "\n"
for i in range(1, size+1):
filled_txt += DOC_HIDDEN
filled_txt += "\n"
filled_txt += DEFAULT_IMPL.strip().format(size, i)
filled_txt += "\n"
target_filename = 'src/reg{size}.rs'.format(size=size)
with open(target_filename, 'w') as target_file:
target_file.write(filled_txt)
print("done")