Commit bbb7daf4 authored by Daniel Nemergut's avatar Daniel Nemergut
Browse files

Generated nesting code which has a limited depth since it becomes exponentially expanded

parent 680a05bb
Loading
Loading
Loading
Loading
+92 −0
Original line number Diff line number Diff line
@@ -17,6 +17,47 @@ c_types = {
    "p": ["void *", "type", "c_ptr"]
}

# Nested depth that we can support, 3 will result in 20k+ lines of API code
nested_depth = 2


# Functions to recursively generate API for CDict_nest
def write_nest_c_header(file, str1, str2, currdepth):
    for nnpath, typepath in c_types.items():
        nestpath1 = str1 + "_{}".format(nnpath)
        nestpath2 = str2 + ", {} p{}".format(typepath[0], currdepth)
        if currdepth < nested_depth:
            write_nest_c_header(file, nestpath1, nestpath2, currdepth + 1)
        file.write(nestpath1 + nestpath2 + """);
""")


def write_nest_c_source(file, str1, str2, str3, currdepth):
    for nnpath, typepath in c_types.items():
        nestpath1 = str1 + "_{}".format(nnpath)
        nestpath2 = str2 + ", {} p{}".format(typepath[0], currdepth)
        nestpath3 = str3 + ",p{}".format(currdepth)
        if currdepth < nested_depth:
            write_nest_c_source(file, nestpath1, nestpath2, nestpath3, currdepth + 1)
        file.write(nestpath1 + nestpath2 + ") " + nestpath3 + """);
}
""")


def write_nest_f(file, str1, str2, str3, str4, str5, currdepth):
    for nnpath, typepath in c_types.items():
        nestpath1 = str1 + "_{}".format(nnpath)
        nestpath2 = str2 + ", p{}".format(currdepth)
        nestpath3 = str3 + "_{}".format(nnpath)
        nestpath4 = str4 + """
            {}({}), intent(in), VALUE :: p{}""".format(typepath[1], typepath[2], currdepth)
        nestpath5 = str5 + "_{}".format(nnpath)
        if currdepth < nested_depth:
            write_nest_f(file, nestpath1, nestpath2, nestpath3, nestpath4, nestpath5, currdepth + 1)
        file.write(nestpath1 + nestpath2 + nestpath3 + nestpath4 + nestpath5 + """
""")


# C Header
with open(c_file+".h", 'w') as f:
    f.write("""#pragma once
@@ -59,6 +100,17 @@ CDict_API_function
void f_cdict_set_{}_{}(struct cdict_t * c, {} k, {} v);
""".format(nnkey, nnval, typekey[0], typeval[0]))

    # Cdict_nest for each type pair
    for nnkey, typekey in c_types.items():
        nestkey1 = """
CDict_API_function
void f_cdict_nest_{}""".format(nnkey)
        nestkey2 = "(struct cdict_t * c, {} k".format(typekey[0])
        for nnval, typeval in c_types.items():
            nestval1 = nestkey1 + "_{}".format(nnval)
            nestval2 = nestkey2 + ", {} v".format(typeval[0])
            write_nest_c_header(f, nestval1, nestval2, 1)

    f.write("""
#endif //LIBCDICT_CDICT_FORTRAN_API_H
""")
@@ -112,6 +164,19 @@ void f_cdict_set_{}_{}(struct cdict_t * c, {} k, {} v) {{
}}
""".format(nnkey, nnval, typekey[0], typeval[0]))

    # Cdict_nest for each type pair
    for nnkey, typekey in c_types.items():
        nestkey1 = """
CDict_API_function
void f_cdict_nest_{}""".format(nnkey)
        nestkey2 = "(struct cdict_t * c, {} k".format(typekey[0])
        nestkey3 = """{
    CDict_nest(c,k,v"""
        for nnval, typeval in c_types.items():
            nestval1 = nestkey1 + "_{}".format(nnval)
            nestval2 = nestkey2 + ", {} v".format(typeval[0])
            write_nest_c_source(f, nestval1, nestval2, nestkey3, 1)

# F module
with open(f_file, 'w') as f:
    f.write("""! Automatically generated by make_fortran_api.py
@@ -220,6 +285,33 @@ module libcdict_m
""".format(nnkey, nnval, nnkey, nnval, typekey[1], typekey[2], typeval[1], typeval[2], nnkey, nnval))

    f.write("""    end interface f_cdict_set
    
    ! Nest
    interface f_cdict_nest""")

    # CDict_nest for each type
    for nnkey, typekey in c_types.items():
        nestkey1 = """
        subroutine f_cdict_nest_{}""".format(nnkey)
        nestkey2 = """(cdict, key"""
        nestkey3 = """) bind(c,name="f_cdict_nest_{}""".format(nnkey)
        nestkey4 = """")
            use, intrinsic :: iso_c_binding
            type(c_ptr), intent(in), VALUE :: cdict
            {}({}), intent(in), VALUE :: key""".format(typekey[1], typekey[2])
        nestkey5 = """
        end subroutine f_cdict_nest_{}""".format(nnkey)

        for nnval, typeval in c_types.items():
            nestval1 = nestkey1 + "_{}".format(nnval)
            nestval2 = nestkey2 + ", value"
            nestval3 = nestkey3 + "_{}".format(nnval)
            nestval4 = nestkey4 + """
            {}({}), intent(in), VALUE :: value""".format(typeval[1], typeval[2])
            nestval5 = nestkey5 + "_{}".format(nnval)
            write_nest_f(f, nestval1, nestval2, nestval3, nestval4, nestval5, 1)

    f.write("""    end interface f_cdict_nest
""")

    f.write("""