summaryrefslogtreecommitdiffstats
path: root/src/expr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/expr.c')
-rw-r--r--src/expr.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/src/expr.c b/src/expr.c
index 2002fc7..3e0033f 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -23,7 +23,12 @@ struct bfs_expr *bfs_expr_new(struct bfs_ctx *ctx, bfs_eval_fn *eval_fn, size_t
expr->argc = argc;
expr->argv = argv;
expr->probability = 0.5;
- SLIST_PREPEND(&ctx->expr_list, expr);
+ SLIST_PREPEND(&ctx->expr_list, expr, freelist);
+
+ if (bfs_expr_is_parent(expr)) {
+ SLIST_INIT(&expr->children);
+ }
+
return expr;
}
@@ -34,6 +39,36 @@ bool bfs_expr_is_parent(const struct bfs_expr *expr) {
|| expr->eval_fn == eval_comma;
}
+struct bfs_expr *bfs_expr_children(const struct bfs_expr *expr) {
+ if (bfs_expr_is_parent(expr)) {
+ return expr->children.head;
+ } else {
+ return NULL;
+ }
+}
+
+void bfs_expr_append(struct bfs_expr *expr, struct bfs_expr *child) {
+ bfs_assert(bfs_expr_is_parent(expr));
+
+ SLIST_APPEND(&expr->children, child);
+
+ if (!child->pure) {
+ expr->pure = false;
+ }
+
+ expr->persistent_fds += child->persistent_fds;
+ if (expr->ephemeral_fds < child->ephemeral_fds) {
+ expr->ephemeral_fds = child->ephemeral_fds;
+ }
+}
+
+void bfs_expr_extend(struct bfs_expr *expr, struct bfs_exprs *children) {
+ while (!SLIST_EMPTY(children)) {
+ struct bfs_expr *child = SLIST_POP(children);
+ bfs_expr_append(expr, child);
+ }
+}
+
bool bfs_expr_never_returns(const struct bfs_expr *expr) {
// Expressions that never return are vacuously both always true and always false
return expr->always_true && expr->always_false;