diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2016-10-18 05:41:45 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2016-10-18 05:41:45 -0700 |
commit | f91ef728d1149d7a849d7c818b3fdc03c61847ad (patch) | |
tree | 1114df7103b610538a25a00ea603afc72960daf7 | |
parent | b25e08a3328ffa4bf29a8a8651973d88ae79b90c (diff) | |
download | txr-f91ef728d1149d7a849d7c818b3fdc03c61847ad.tar.gz txr-f91ef728d1149d7a849d7c818b3fdc03c61847ad.tar.bz2 txr-f91ef728d1149d7a849d7c818b3fdc03c61847ad.zip |
Detect cycles in rlcp_tree.
This will be required when the parser becomes
capable of creating object graphs with cycles.
* parser.c (parser_callgraph_circ_check): New function.
* parser.h (struct circ_stack): New struct.
(parser_callgraph_circ_check): Declared.
* parser.y (rlcp_tree_rec): New static function.
(rlcp_tree): Reduced to wrapper for rlcp_tree_rec.
-rw-r--r-- | parser.c | 10 | ||||
-rw-r--r-- | parser.h | 8 | ||||
-rw-r--r-- | parser.y | 19 |
3 files changed, 34 insertions, 3 deletions
@@ -200,6 +200,16 @@ void prime_parser_post(parser_t *p, enum prime_parser prim) p->recent_tok.yy_char = 0; } +int parser_callgraph_circ_check(struct circ_stack *rs, val obj) +{ + for (; rs; rs = rs->up) { + if (rs->obj == obj) + return 0; + } + + return 1; +} + void open_txr_file(val spec_file, val *txr_lisp_p, val *name, val *stream) { enum { none, tl, txr } suffix; @@ -41,6 +41,11 @@ struct yy_token { YYSTYPE yy_lval; }; +struct circ_stack { + struct circ_stack *up; + val obj; +}; + struct parser { val parser; cnum lineno; @@ -83,6 +88,9 @@ void open_txr_file(val spec_file, val *txr_lisp_p, val *name, val *stream); void prime_parser(parser_t *, val name, enum prime_parser); void prime_parser_post(parser_t *, enum prime_parser); void prime_scanner(scanner_t *, enum prime_parser); +#ifdef SPACE +int parser_callgraph_circ_check(struct circ_stack *rs, val obj); +#endif void scrub_scanner(scanner_t *, int yy_char, wchar_t *lexeme); int parse_once(val stream, val name, parser_t *parser); int parse(parser_t *parser, val name, enum prime_parser); @@ -1501,17 +1501,30 @@ val rlrec(parser_t *parser, val form, val line) return form; } -val rlcp_tree(val to, val from) +static val rlcp_tree_rec(val to, val from, struct circ_stack *up) { val ret = to; - for (; consp(to); to = cdr(to)) { + while (consp(to)) { + val a = car(to); + struct circ_stack rlcs = { up, a }; rlcp(to, from); - rlcp_tree(car(to), from); + if (!parser_callgraph_circ_check(up, a)) + break; + rlcp_tree_rec(a, from, &rlcs); + to = cdr(to); + if (!parser_callgraph_circ_check(up, to)) + break; } return ret; } + +val rlcp_tree(val to, val from) +{ + return rlcp_tree_rec(to, from, 0); +} + static wchar_t char_from_name(const wchar_t *name) { static struct { |