Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 0191bd3 in mainline


Ignore:
Timestamp:
2012-08-07T04:30:04Z (9 years ago)
Author:
Sean Bartell <wingedtachikoma@…>
Branches:
lfn, master
Children:
a8be91a
Parents:
f9c314a5
Message:

Bithenge: keep track of outer scopes and find parameters there

Location:
uspace/app/bithenge
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bithenge/expression.c

    rf9c314a5 r0191bd3  
    425425        param_wrapper_t *self = transform_as_param_wrapper(base);
    426426        bithenge_scope_t *inner;
    427         int rc = bithenge_scope_new(&inner);
     427        int rc = bithenge_scope_new(&inner, outer);
    428428        if (rc != EOK)
    429429                return rc;
     
    445445        param_wrapper_t *self = transform_as_param_wrapper(base);
    446446        bithenge_scope_t *inner;
    447         int rc = bithenge_scope_new(&inner);
     447        int rc = bithenge_scope_new(&inner, outer);
    448448        if (rc != EOK)
    449449                return rc;
     
    454454        rc = bithenge_transform_prefix_length(self->transform, inner, in, out);
    455455        in = NULL;
     456
     457error:
     458        bithenge_scope_dec_ref(inner);
     459        return rc;
     460}
     461
     462static int param_wrapper_prefix_apply(bithenge_transform_t *base,
     463    bithenge_scope_t *outer, bithenge_blob_t *in, bithenge_node_t **out_node,
     464    aoff64_t *out_length)
     465{
     466        param_wrapper_t *self = transform_as_param_wrapper(base);
     467        bithenge_scope_t *inner;
     468        int rc = bithenge_scope_new(&inner, outer);
     469        if (rc != EOK)
     470                return rc;
     471        rc = param_wrapper_fill_scope(self, inner, outer);
     472        if (rc != EOK)
     473                goto error;
     474
     475        rc = bithenge_transform_prefix_apply(self->transform, inner, in,
     476            out_node, out_length);
    456477
    457478error:
     
    474495        .apply = param_wrapper_apply,
    475496        .prefix_length = param_wrapper_prefix_length,
     497        .prefix_apply = param_wrapper_prefix_apply,
    476498        .destroy = param_wrapper_destroy,
    477499};
  • uspace/app/bithenge/sequence.c

    rf9c314a5 r0191bd3  
    267267        self->num_ends = 0;
    268268        self->end_on_empty = end_on_empty;
    269         int rc = bithenge_scope_new(&self->scope);
    270         if (rc != EOK) {
    271                 free(self->ends);
    272                 return rc;
    273         }
    274         rc = bithenge_scope_copy(self->scope, scope);
    275         if (rc != EOK) {
    276                 bithenge_scope_dec_ref(self->scope);
    277                 free(self->ends);
    278                 return rc;
    279         }
     269        self->scope = scope;
     270        if (self->scope)
     271                bithenge_scope_inc_ref(self->scope);
    280272        return EOK;
    281273}
     
    468460                return rc;
    469461        }
    470 
    471         rc = seq_node_init(struct_as_seq(node), &struct_node_seq_ops, scope,
     462        bithenge_scope_t *inner;
     463        rc = bithenge_scope_new(&inner, scope);
     464        if (rc != EOK) {
     465                free(node);
     466                return rc;
     467        }
     468        /* We should inc_ref(node) here, but that would make a cycle. Instead,
     469         * we leave it 1 too low, so that when the only remaining use of node
     470         * is the scope, node will be destroyed. Also see the comment in
     471         * struct_node_destroy. */
     472        bithenge_scope_set_current_node(inner, struct_as_node(node));
     473
     474        rc = seq_node_init(struct_as_seq(node), &struct_node_seq_ops, inner,
    472475            blob, self->num_subtransforms, false);
     476        bithenge_scope_dec_ref(inner);
    473477        if (rc != EOK) {
    474478                free(node);
     
    480484        node->prefix = prefix;
    481485        *out = struct_as_node(node);
    482 
    483         /* We should inc_ref(*out) here, but that would make a cycle. Instead,
    484          * we leave it 1 too low, so that when the only remaining use of *out
    485          * is the scope, *out will be destroyed. Also see the comment in
    486          * struct_node_destroy. */
    487         bithenge_scope_set_current_node(seq_node_scope(struct_as_seq(node)),
    488             *out);
    489486
    490487        return EOK;
     
    942939
    943940                bithenge_scope_t *scope;
    944                 rc = bithenge_scope_new(&scope);
     941                rc = bithenge_scope_new(&scope,
     942                    seq_node_scope(do_while_as_seq(self)));
    945943                if (rc != EOK) {
    946944                        bithenge_node_dec_ref(subxform_result);
    947945                        return rc;
    948946                }
    949                 rc = bithenge_scope_copy(scope,
    950                     seq_node_scope(do_while_as_seq(self)));
    951947                bithenge_scope_set_current_node(scope, subxform_result);
    952                 if (rc != EOK) {
    953                         bithenge_scope_dec_ref(scope);
    954                         return rc;
    955                 }
    956948                bithenge_node_t *expr_result;
    957949                rc = bithenge_expression_evaluate(self->expr, scope,
  • uspace/app/bithenge/test.c

    rf9c314a5 r0191bd3  
    7373                bithenge_node_t *node = NULL, *node2 = NULL;
    7474
    75                 rc = bithenge_scope_new(&scope);
     75                rc = bithenge_scope_new(&scope, NULL);
    7676                if (rc != EOK) {
    7777                        printf("Error creating scope: %s\n", str_error(rc));
  • uspace/app/bithenge/transform.c

    rf9c314a5 r0191bd3  
    166166
    167167/** Create a transform scope. It must be dereferenced with @a
    168  * bithenge_scope_dec_ref after it is used.
     168 * bithenge_scope_dec_ref after it is used. Takes ownership of nothing.
    169169 * @param[out] out Holds the new scope.
     170 * @param outer The outer scope, or NULL.
    170171 * @return EOK on success or an error code from errno.h. */
    171 int bithenge_scope_new(bithenge_scope_t **out)
     172int bithenge_scope_new(bithenge_scope_t **out, bithenge_scope_t *outer)
    172173{
    173174        bithenge_scope_t *self = malloc(sizeof(*self));
     
    175176                return ENOMEM;
    176177        self->refs = 1;
     178        if (outer)
     179                bithenge_scope_inc_ref(outer);
     180        self->outer = outer;
    177181        self->num_params = 0;
    178182        self->params = NULL;
     
    186190void bithenge_scope_dec_ref(bithenge_scope_t *self)
    187191{
    188         if (!--self->refs) {
    189                 bithenge_node_dec_ref(self->current_node);
    190                 for (int i = 0; i < self->num_params; i++)
    191                         bithenge_node_dec_ref(self->params[i]);
    192                 free(self->params);
    193                 free(self);
    194         }
     192        if (!self)
     193                return;
     194        if (--self->refs)
     195                return;
     196        bithenge_node_dec_ref(self->current_node);
     197        for (int i = 0; i < self->num_params; i++)
     198                bithenge_node_dec_ref(self->params[i]);
     199        bithenge_scope_dec_ref(self->outer);
     200        free(self->params);
     201        free(self);
    195202}
    196203
     
    279286{
    280287        assert(scope);
    281         assert(i >= 0 && i < scope->num_params);
    282         *out = scope->params[i];
    283         bithenge_node_inc_ref(*out);
    284         return EOK;
     288        if (scope->num_params) {
     289                assert(i >= 0 && i < scope->num_params);
     290                *out = scope->params[i];
     291                bithenge_node_inc_ref(*out);
     292                return EOK;
     293        } else {
     294                return bithenge_scope_get_param(scope->outer, i, out);
     295        }
    285296}
    286297
     
    307318        scope_transform_t *self = transform_as_param(base);
    308319        bithenge_scope_t *inner_scope;
    309         int rc = bithenge_scope_new(&inner_scope);
    310         if (rc != EOK)
    311                 return rc;
    312         rc = bithenge_scope_copy(inner_scope, scope);
    313         if (rc != EOK)
    314                 goto error;
    315         bithenge_scope_set_current_node(inner_scope, NULL);
     320        int rc = bithenge_scope_new(&inner_scope, scope);
     321        if (rc != EOK)
     322                return rc;
    316323        rc = bithenge_transform_apply(self->transform, scope, in, out);
    317 error:
    318324        bithenge_scope_dec_ref(inner_scope);
    319325        return rc;
  • uspace/app/bithenge/transform.h

    rf9c314a5 r0191bd3  
    5050
    5151/** Context and parameters used when applying transforms. */
    52 typedef struct {
     52typedef struct bithenge_scope {
    5353        /** @privatesection */
    5454        unsigned int refs;
     55        struct bithenge_scope *outer;
    5556        int num_params;
    5657        bithenge_node_t **params;
     
    148149    bithenge_transform_t **, size_t);
    149150
    150 int bithenge_scope_new(bithenge_scope_t **);
     151int bithenge_scope_new(bithenge_scope_t **, bithenge_scope_t *);
    151152void bithenge_scope_dec_ref(bithenge_scope_t *);
    152153int bithenge_scope_copy(bithenge_scope_t *, bithenge_scope_t *);
Note: See TracChangeset for help on using the changeset viewer.