diff --git a/front/constred.c b/front/constred.c index e6f5000b..f5c45367 100644 --- a/front/constred.c +++ b/front/constred.c @@ -931,24 +931,63 @@ int func_list_constred(func_list * list, int * result) { func_constred(value, result); } - node = node->next; } return 0; } -int never_constred(never * nev) +int use_constred(use * value, int * result) +{ + if (value->decl != NULL && + value->decl->type == MODULE_DECL_TYPE_MOD) + { + module_constred(value->decl, result); + } + + return 0; +} + +int use_list_constred(use_list * list, int * result) { - int result = CONSTRED_SUCC; + use_list_node * node = list->tail; + while (node != NULL) + { + use * value = node->value; + if (value != NULL) + { + use_constred(value, result); + } + node = node->next; + } + return 0; +} + +int never_constred(never * nev, int * result) +{ + if (nev->uses) + { + use_list_constred(nev->uses, result); + } if (nev->binds) { - bind_list_constred(nev->binds, &result); + bind_list_constred(nev->binds, result); } if (nev->funcs) { - func_list_constred(nev->funcs, &result); + func_list_constred(nev->funcs, result); } - return result; + return 0; } + +int module_constred(module_decl * value, int * result) +{ + if (value->nev != NULL) + { + never_constred(value->nev, result); + } + + return 0; +} + diff --git a/front/constred.h b/front/constred.h index 2bfca259..dad60775 100644 --- a/front/constred.h +++ b/front/constred.h @@ -48,6 +48,9 @@ int func_constred_ffi(func * value, int * result); int func_constred_native(func * value, int * result); int func_constred(func * value, int * result); int func_list_constred(func_list * list, int * result); -int never_constred(never * nev); +int use_constred(use * value, int * result); +int use_list_constred(use_list * list, int * result); +int never_constred(never * nev, int * result); +int module_constred(module_decl * value, int * result); #endif /* __CONSTRED_H__ */ diff --git a/front/optimize.c b/front/optimize.c index cc887864..d1443555 100644 --- a/front/optimize.c +++ b/front/optimize.c @@ -21,18 +21,21 @@ */ #include "optimize.h" #include "constred.h" +#include -int never_optimize(never * nev) +int module_optimize(module_decl * value, int * result) { - return never_constred(nev); + return module_constred(value, result); } int module_decl_optimize(module_decl * module_nev) { - if (module_nev->nev) + int result = CONSTRED_SUCC; + + if (module_nev != NULL) { - return never_optimize(module_nev->nev); + module_optimize(module_nev, &result); } - return 0; + return result; } diff --git a/front/optimize.h b/front/optimize.h index acbb0484..78d2c5b6 100644 --- a/front/optimize.h +++ b/front/optimize.h @@ -24,7 +24,7 @@ #include "never.h" -int never_optimize(never * nev); -int module_decl_optimize(module_decl * module_nev); +int module_optimize(module_decl * value, int * result); +int module_decl_optimize(module_decl * value); #endif /* __OPTIMIZE_H__ */ diff --git a/front/tailrec.c b/front/tailrec.c index 954b4ac9..57b54697 100644 --- a/front/tailrec.c +++ b/front/tailrec.c @@ -523,10 +523,42 @@ int func_list_tailrec(unsigned int syn_level, func_list * list) return 0; } +int use_tailrec(use * value) +{ + if (value->decl != NULL && + value->decl->type == MODULE_DECL_TYPE_MOD) + { + module_decl_tailrec(value->decl); + } + + return 0; +} + +int use_list_tailrec(use_list * list) +{ + use_list_node * node = list->tail; + + while (node != NULL) + { + use * value = node->value; + if (value != NULL) + { + use_tailrec(value); + } + node = node->next; + } + + return 0; +} + int never_tailrec(never * nev) { unsigned int syn_level = 0; + if (nev->uses) + { + use_list_tailrec(nev->uses); + } if (nev->binds) { bind_list_tailrec(syn_level, nev->stab, nev->binds, TAILREC_OP_SKIP); diff --git a/front/tailrec.h b/front/tailrec.h index 9eac9ada..0a070b0f 100644 --- a/front/tailrec.h +++ b/front/tailrec.h @@ -68,7 +68,8 @@ int func_tailrec_ffi(unsigned int syn_level, func * value); int func_tailrec_native(unsigned int syn_level, func * value); int func_tailrec(unsigned int syn_level, func * value); int func_list_tailrec(unsigned int syn_level, func_list * list); - +int use_tailrec(use * value); +int use_list_tailrec(use_list * list); int never_tailrec(never * nev); int module_decl_tailrec(module_decl * module_nev); diff --git a/sample/lib/mtail.nev b/sample/lib/mtail.nev new file mode 100644 index 00000000..c45bb255 --- /dev/null +++ b/sample/lib/mtail.nev @@ -0,0 +1,9 @@ + +module mtail { + func spaces(n: int) -> string { + func spaces0(s:string, n:int) -> string { + (n == 0) ? s : spaces0(s+" ", n-1) + } + spaces0(" ", n-1) + } +} diff --git a/sample/sample488.nev b/sample/sample488.nev new file mode 100644 index 00000000..ea9f2b61 --- /dev/null +++ b/sample/sample488.nev @@ -0,0 +1,9 @@ + +use mtail + +func main() -> int +{ + mtail.spaces(200); + 0 +} +