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

Changeset c12b2ae in mainline


Ignore:
Timestamp:
2012-08-07T05:00:41Z (9 years ago)
Author:
Sean Bartell <wingedtachikoma@…>
Branches:
lfn, master
Children:
ad5c8a48
Parents:
a8be91a
Message:

Bithenge: search for current node members in outer scopes

Location:
uspace
Files:
6 edited

Legend:

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

    ra8be91a rc12b2ae  
    305305}
    306306
     307
     308
     309/***************** member_expression                         *****************/
     310
    307311typedef struct {
    308312        bithenge_expression_t base;
     
    380384        return rc;
    381385}
     386
     387
     388
     389/***************** scope_member_expression                   *****************/
     390
     391typedef struct {
     392        bithenge_expression_t base;
     393        bithenge_node_t *key;
     394} scope_member_expression_t;
     395
     396static scope_member_expression_t *expression_as_scope_member(
     397    bithenge_expression_t *base)
     398{
     399        return (scope_member_expression_t *)base;
     400}
     401
     402static bithenge_expression_t *scope_member_as_expression(
     403    scope_member_expression_t *expr)
     404{
     405        return &expr->base;
     406}
     407
     408static int scope_member_expression_evaluate(bithenge_expression_t *base,
     409    bithenge_scope_t *scope, bithenge_node_t **out)
     410{
     411        scope_member_expression_t *self = expression_as_scope_member(base);
     412        for (; scope && !bithenge_scope_is_barrier(scope);
     413            scope = bithenge_scope_outer(scope)) {
     414                bithenge_node_inc_ref(self->key);
     415                bithenge_node_t *cur = bithenge_scope_get_current_node(scope);
     416                int rc = bithenge_node_get(cur, self->key, out);
     417                bithenge_node_dec_ref(cur);
     418                if (rc != ENOENT) /* EOK or error */
     419                        return rc;
     420        }
     421        return ENOENT;
     422}
     423
     424static void scope_member_expression_destroy(bithenge_expression_t *base)
     425{
     426        scope_member_expression_t *self = expression_as_scope_member(base);
     427        bithenge_node_dec_ref(self->key);
     428        free(self);
     429}
     430
     431static const bithenge_expression_ops_t scope_member_expression_ops = {
     432        .evaluate = scope_member_expression_evaluate,
     433        .destroy = scope_member_expression_destroy,
     434};
     435
     436int bithenge_scope_member_expression(bithenge_expression_t **out,
     437    bithenge_node_t *key)
     438{
     439        int rc;
     440        scope_member_expression_t *self = malloc(sizeof(*self));
     441        if (!self) {
     442                rc = ENOMEM;
     443                goto error;
     444        }
     445
     446        rc = bithenge_init_expression(scope_member_as_expression(self),
     447            &scope_member_expression_ops);
     448        if (rc != EOK)
     449                goto error;
     450
     451        self->key = key;
     452        *out = scope_member_as_expression(self);
     453        return EOK;
     454
     455error:
     456        bithenge_node_dec_ref(key);
     457        free(self);
     458        return rc;
     459}
     460
     461
     462
     463/***************** param_wrapper                             *****************/
    382464
    383465typedef struct {
  • uspace/app/bithenge/expression.h

    ra8be91a rc12b2ae  
    104104int bithenge_member_expression(bithenge_expression_t **,
    105105    bithenge_expression_t *, bithenge_node_t *);
     106int bithenge_scope_member_expression(bithenge_expression_t **,
     107    bithenge_node_t *);
    106108int bithenge_param_wrapper(bithenge_transform_t **, bithenge_transform_t *,
    107109    bithenge_expression_t **);
  • uspace/app/bithenge/script.c

    ra8be91a rc12b2ae  
    363363static bithenge_expression_t *parse_expression(state_t *state)
    364364{
     365        int rc;
    365366        if (state->token == TOKEN_TRUE || state->token == TOKEN_FALSE) {
    366367                bool val = state->token == TOKEN_TRUE;
    367368                next_token(state);
    368369                bithenge_node_t *node;
    369                 int rc = bithenge_new_boolean_node(&node, val);
     370                rc = bithenge_new_boolean_node(&node, val);
    370371                if (rc != EOK) {
    371372                        error_errno(state, rc);
     
    385386                next_token(state);
    386387                bithenge_node_t *node;
    387                 int rc = bithenge_new_integer_node(&node, val);
     388                rc = bithenge_new_integer_node(&node, val);
    388389                if (rc != EOK) {
    389390                        error_errno(state, rc);
     
    412413
    413414                bithenge_expression_t *expr;
    414                 int rc = bithenge_param_expression(&expr, i);
     415                rc = bithenge_param_expression(&expr, i);
    415416                if (rc != EOK) {
    416417                        error_errno(state, rc);
     
    427428                bithenge_node_t *key = NULL;
    428429                bithenge_expression_t *expr = NULL;
    429                 int rc = bithenge_current_node_expression(&expr);
    430                 error_errno(state, rc);
    431430
    432431                if (state->error == EOK) {
     
    437436
    438437                if (state->error == EOK) {
    439                         rc = bithenge_member_expression(&expr, expr, key);
     438                        rc = bithenge_scope_member_expression(&expr, key);
    440439                        key = NULL;
    441440                        if (rc != EOK)
     
    857856
    858857        if (state->error == EOK) {
    859                 int rc = bithenge_new_scope_transform(&xform, xform,
     858                int rc = bithenge_new_barrier_transform(&xform, xform,
    860859                    state->num_params);
    861860                if (rc != EOK) {
  • uspace/app/bithenge/transform.c

    ra8be91a rc12b2ae  
    179179                bithenge_scope_inc_ref(outer);
    180180        self->outer = outer;
     181        self->barrier = false;
    181182        self->num_params = 0;
    182183        self->params = NULL;
     
    202203}
    203204
     205/** Get the outer scope of a scope, which may be NULL.
     206 * @param self The scope to examine.
     207 * @return The outer scope, which may be NULL. */
     208bithenge_scope_t *bithenge_scope_outer(bithenge_scope_t *self)
     209{
     210        return self->outer;
     211}
     212
    204213/** Set the current node being created. Takes a reference to @a node.
    205214 * @param scope The scope to set the current node in.
     
    211220        bithenge_node_dec_ref(scope->current_node);
    212221        scope->current_node = node;
     222}
     223
     224/** Set a scope as a barrier.
     225 * @param self The scope to change. */
     226void bithenge_scope_set_barrier(bithenge_scope_t *self)
     227{
     228        self->barrier = true;
     229}
     230
     231/** Check whether a scope is a barrier, meaning that variable lookup stops at
     232 * it.
     233 * @param self The scope to check.
     234 * @return Whether the scope is a barrier. */
     235bool bithenge_scope_is_barrier(bithenge_scope_t *self)
     236{
     237        return self->barrier;
    213238}
    214239
     
    277302        bithenge_transform_t base;
    278303        bithenge_transform_t *transform;
    279 } scope_transform_t;
    280 
    281 static inline scope_transform_t *transform_as_param(
     304} barrier_transform_t;
     305
     306static inline barrier_transform_t *transform_as_barrier(
    282307    bithenge_transform_t *base)
    283308{
    284         return (scope_transform_t *)base;
    285 }
    286 
    287 static inline bithenge_transform_t *param_as_transform(
    288     scope_transform_t *self)
     309        return (barrier_transform_t *)base;
     310}
     311
     312static inline bithenge_transform_t *barrier_as_transform(
     313    barrier_transform_t *self)
    289314{
    290315        return &self->base;
    291316}
    292317
    293 static int scope_transform_apply(bithenge_transform_t *base,
     318static int barrier_transform_apply(bithenge_transform_t *base,
    294319    bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out)
    295320{
    296         scope_transform_t *self = transform_as_param(base);
     321        barrier_transform_t *self = transform_as_barrier(base);
    297322        bithenge_scope_t *inner_scope;
    298323        int rc = bithenge_scope_new(&inner_scope, scope);
    299324        if (rc != EOK)
    300325                return rc;
     326        bithenge_scope_set_barrier(inner_scope);
    301327        rc = bithenge_transform_apply(self->transform, scope, in, out);
    302328        bithenge_scope_dec_ref(inner_scope);
     
    304330}
    305331
    306 static int scope_transform_prefix_length(bithenge_transform_t *base,
     332static int barrier_transform_prefix_length(bithenge_transform_t *base,
    307333    bithenge_scope_t *scope, bithenge_blob_t *in, aoff64_t *out)
    308334{
    309         scope_transform_t *self = transform_as_param(base);
    310         return bithenge_transform_prefix_length(self->transform, scope, in,
    311             out);
    312 }
    313 
    314 static void scope_transform_destroy(bithenge_transform_t *base)
    315 {
    316         scope_transform_t *self = transform_as_param(base);
     335        barrier_transform_t *self = transform_as_barrier(base);
     336        bithenge_scope_t *inner_scope;
     337        int rc = bithenge_scope_new(&inner_scope, scope);
     338        if (rc != EOK)
     339                return rc;
     340        bithenge_scope_set_barrier(inner_scope);
     341        rc = bithenge_transform_prefix_length(self->transform, scope, in, out);
     342        bithenge_scope_dec_ref(inner_scope);
     343        return rc;
     344}
     345
     346static int barrier_transform_prefix_apply(bithenge_transform_t *base,
     347    bithenge_scope_t *scope, bithenge_blob_t *in, bithenge_node_t **out_node,
     348    aoff64_t *out_length)
     349{
     350        barrier_transform_t *self = transform_as_barrier(base);
     351        bithenge_scope_t *inner_scope;
     352        int rc = bithenge_scope_new(&inner_scope, scope);
     353        if (rc != EOK)
     354                return rc;
     355        bithenge_scope_set_barrier(inner_scope);
     356        rc = bithenge_transform_prefix_apply(self->transform, scope, in,
     357            out_node, out_length);
     358        bithenge_scope_dec_ref(inner_scope);
     359        return rc;
     360}
     361
     362static void barrier_transform_destroy(bithenge_transform_t *base)
     363{
     364        barrier_transform_t *self = transform_as_barrier(base);
    317365        bithenge_transform_dec_ref(self->transform);
    318366        free(self);
    319367}
    320368
    321 static const bithenge_transform_ops_t scope_transform_ops = {
    322         .apply = scope_transform_apply,
    323         .prefix_length = scope_transform_prefix_length,
    324         .destroy = scope_transform_destroy,
    325 };
    326 
    327 /** Create a wrapper transform that creates a new outer scope. This ensures
    328  * nothing from the transform's users is passed in, other than parameters. The
    329  * wrapper may have a different value for num_params. Takes a reference to
    330  * @a transform, which it will use for all operations.
     369static const bithenge_transform_ops_t barrier_transform_ops = {
     370        .apply = barrier_transform_apply,
     371        .prefix_length = barrier_transform_prefix_length,
     372        .prefix_apply = barrier_transform_prefix_apply,
     373        .destroy = barrier_transform_destroy,
     374};
     375
     376/** Create a wrapper transform that creates a new scope. This ensures nothing
     377 * from the outer scope is passed in, other than parameters. The wrapper may
     378 * have a different value for num_params. Takes a reference to @a transform,
     379 * which it will use for all operations.
    331380 * @param[out] out Holds the created transform.
    332381 * @param transform The transform to wrap.
    333382 * @param num_params The number of parameters to require, which may be 0.
    334383 * @return EOK on success or an error code from errno.h. */
    335 int bithenge_new_scope_transform(bithenge_transform_t **out,
     384int bithenge_new_barrier_transform(bithenge_transform_t **out,
    336385    bithenge_transform_t *transform, int num_params)
    337386{
     
    340389
    341390        int rc;
    342         scope_transform_t *self = malloc(sizeof(*self));
     391        barrier_transform_t *self = malloc(sizeof(*self));
    343392        if (!self) {
    344393                rc = ENOMEM;
    345394                goto error;
    346395        }
    347         rc = bithenge_init_transform(param_as_transform(self),
    348             &scope_transform_ops, num_params);
     396        rc = bithenge_init_transform(barrier_as_transform(self),
     397            &barrier_transform_ops, num_params);
    349398        if (rc != EOK)
    350399                goto error;
    351400        self->transform = transform;
    352         *out = param_as_transform(self);
     401        *out = barrier_as_transform(self);
    353402        return EOK;
    354403error:
  • uspace/app/bithenge/transform.h

    ra8be91a rc12b2ae  
    5454        unsigned int refs;
    5555        struct bithenge_scope *outer;
     56        bool barrier;
    5657        int num_params;
    5758        bithenge_node_t **params;
     
    144145int bithenge_transform_prefix_apply(bithenge_transform_t *, bithenge_scope_t *,
    145146    bithenge_blob_t *, bithenge_node_t **, aoff64_t *);
    146 int bithenge_new_scope_transform(bithenge_transform_t **,
     147int bithenge_new_barrier_transform(bithenge_transform_t **,
    147148    bithenge_transform_t *, int);
    148149int bithenge_new_composed_transform(bithenge_transform_t **,
     
    151152int bithenge_scope_new(bithenge_scope_t **, bithenge_scope_t *);
    152153void bithenge_scope_dec_ref(bithenge_scope_t *);
     154bithenge_scope_t *bithenge_scope_outer(bithenge_scope_t *);
    153155void bithenge_scope_set_current_node(bithenge_scope_t *, bithenge_node_t *);
     156void bithenge_scope_set_barrier(bithenge_scope_t *);
     157bool bithenge_scope_is_barrier(bithenge_scope_t *);
    154158bithenge_node_t *bithenge_scope_get_current_node(bithenge_scope_t *);
    155159int bithenge_scope_alloc_params(bithenge_scope_t *, int);
  • uspace/dist/src/bithenge/test-repeat.bh

    ra8be91a rc12b2ae  
    33        .one <- repeat(1) { uint8 };
    44        .count <- uint8;
    5         .many <- repeat(.count) { uint8 };
     5        if (true) { # test whether .count is still accessible
     6                .many <- repeat(.count) { uint8 };
     7        }
    68};
    79
Note: See TracChangeset for help on using the changeset viewer.