return r;
}
+#define IN_RECURSION (1<<0)
+#define FOUND_CALLED_NODE 1
static int
-subexp_recursive_check_trav(Node* node, ScanEnv* env)
+subexp_recursive_check_trav(Node* node, ScanEnv* env, int state)
{
-#define FOUND_CALLED_NODE 1
-
int r = 0;
switch (NODE_TYPE(node)) {
{
int ret;
do {
- ret = subexp_recursive_check_trav(NODE_CAR(node), env);
+ ret = subexp_recursive_check_trav(NODE_CAR(node), env, state);
if (ret == FOUND_CALLED_NODE) r = FOUND_CALLED_NODE;
else if (ret < 0) return ret;
} while (IS_NOT_NULL(node = NODE_CDR(node)));
break;
case NODE_QTFR:
- r = subexp_recursive_check_trav(NODE_BODY(node), env);
+ r = subexp_recursive_check_trav(NODE_BODY(node), env, state);
if (QTFR_(node)->upper == 0) {
if (r == FOUND_CALLED_NODE)
QTFR_(node)->is_refered = 1;
{
AnchorNode* an = ANCHOR_(node);
if (ANCHOR_HAS_BODY(an))
- r = subexp_recursive_check_trav(NODE_ANCHOR_BODY(an), env);
+ r = subexp_recursive_check_trav(NODE_ANCHOR_BODY(an), env, state);
}
break;
case NODE_ENCLOSURE:
- if (NODE_IS_CALLED(node)) {
+ if (NODE_IS_CALLED(node) || (state & IN_RECURSION) != 0) {
if (! NODE_IS_RECURSION(node)) {
NODE_STATUS_ADD(node, NST_MARK1);
r = subexp_recursive_check(NODE_BODY(node));
NODE_STATUS_ADD(node, NST_RECURSION);
NODE_STATUS_REMOVE(node, NST_MARK1);
}
- r = FOUND_CALLED_NODE;
+
+ if (NODE_IS_CALLED(node))
+ r = FOUND_CALLED_NODE;
+ }
+
+ {
+ int state1 = state;
+
+ if (NODE_IS_RECURSION(node))
+ state1 |= IN_RECURSION;
+
+ (void) subexp_recursive_check_trav(NODE_BODY(node), env, state1);
}
- (void) subexp_recursive_check_trav(NODE_BODY(node), env);
break;
default:
#define IN_REPEAT (1<<2)
#define IN_VAR_REPEAT (1<<3)
#define IN_CALL (1<<4)
-#define IN_RECCALL (1<<5)
#ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
static int
-quantifiers_memory_node_info(Node* node, int state)
+quantifiers_memory_node_info(Node* node)
{
int r = 0;
{
int v;
do {
- v = quantifiers_memory_node_info(NODE_CAR(node), state);
+ v = quantifiers_memory_node_info(NODE_CAR(node));
if (v > r) r = v;
} while (v >= 0 && IS_NOT_NULL(node = NODE_CDR(node)));
}
return NQ_BODY_IS_EMPTY_REC; /* tiny version */
}
else
- r = quantifiers_memory_node_info(NODE_BODY(node), state);
+ r = quantifiers_memory_node_info(NODE_BODY(node));
break;
#endif
{
QtfrNode* qn = QTFR_(node);
if (qn->upper != 0) {
- r = quantifiers_memory_node_info(NODE_BODY(node), state);
+ r = quantifiers_memory_node_info(NODE_BODY(node));
}
}
break;
EnclosureNode* en = ENCLOSURE_(node);
switch (en->type) {
case ENCLOSURE_MEMORY:
- if (NODE_IS_RECURSION(node) || (state & IN_RECCALL) != 0) {
+ if (NODE_IS_RECURSION(node)) {
return NQ_BODY_IS_EMPTY_REC;
}
return NQ_BODY_IS_EMPTY_MEM;
case ENCLOSURE_OPTION:
case ENCLOSURE_STOP_BACKTRACK:
- r = quantifiers_memory_node_info(NODE_BODY(node), state);
+ r = quantifiers_memory_node_info(NODE_BODY(node));
break;
default:
break;
if (d == 0) {
qn->body_empty_info = NQ_BODY_IS_EMPTY;
#ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
- r = quantifiers_memory_node_info(target, state);
+ r = quantifiers_memory_node_info(target);
if (r < 0) break;
if (r > 0) {
qn->body_empty_info = r;
}
if (NODE_IS_CALLED(node))
state |= IN_CALL;
- if (NODE_IS_RECURSION(node))
- state |= IN_RECCALL;
- else if ((state & IN_RECCALL) != 0)
- NODE_STATUS_ADD(node, NST_RECURSION);
r = setup_tree(NODE_BODY(node), reg, state, env);
break;
scan_env.unset_addr_list = &uslist;
r = setup_call(root, &scan_env);
if (r != 0) goto err_unset;
- r = subexp_recursive_check_trav(root, &scan_env);
+ r = subexp_recursive_check_trav(root, &scan_env, 0);
if (r < 0) goto err_unset;
r = subexp_inf_recursive_check_trav(root, &scan_env);
if (r != 0) goto err_unset;