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

Changeset a66ea217 in mainline


Ignore:
Timestamp:
2012-08-08T00:52:22Z (9 years ago)
Author:
Sean Bartell <wingedtachikoma@…>
Branches:
lfn, master
Children:
d8bd2ec
Parents:
ad5c8a48
Message:

Bithenge: use expressions to make transforms

Location:
uspace
Files:
6 edited

Legend:

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

    rad5c8a48 ra66ea217  
    6363}
    6464
     65
     66
     67/***************** binary_expression                         *****************/
     68
    6569typedef struct {
    6670        bithenge_expression_t base;
     
    185189}
    186190
     191
     192
     193/***************** in_node_expression                        *****************/
     194
     195static int in_node_evaluate(bithenge_expression_t *self,
     196    bithenge_scope_t *scope, bithenge_node_t **out)
     197{
     198        for (; scope && !bithenge_scope_is_barrier(scope);
     199            scope = bithenge_scope_outer(scope)) {
     200                *out = bithenge_scope_in_node(scope);
     201                if (*out)
     202                        return EOK;
     203        }
     204        return EINVAL;
     205}
     206
     207static const bithenge_expression_ops_t in_node_ops = {
     208        .evaluate = in_node_evaluate,
     209        .destroy = expression_indestructible,
     210};
     211
     212static bithenge_expression_t in_node_expression = {
     213        &in_node_ops, 1
     214};
     215
     216/** Create an expression that gets the current input node.
     217 * @param[out] out Holds the new expression.
     218 * @return EOK on success or an error code from errno.h. */
     219int bithenge_in_node_expression(bithenge_expression_t **out)
     220{
     221        bithenge_expression_inc_ref(&in_node_expression);
     222        *out = &in_node_expression;
     223        return EOK;
     224}
     225
     226
     227
     228/***************** current_node_expression                   *****************/
     229
    187230static int current_node_evaluate(bithenge_expression_t *self,
    188231    bithenge_scope_t *scope, bithenge_node_t **out)
     
    212255        return EOK;
    213256}
     257
     258
     259
     260/***************** param_expression                          *****************/
    214261
    215262typedef struct {
     
    270317        return EOK;
    271318}
     319
     320
     321
     322/***************** const_expression                          *****************/
    272323
    273324typedef struct {
     
    651702}
    652703
     704
     705
     706/***************** expression_transform           *****************/
     707
     708/* Also used by inputless_transform. */
    653709typedef struct {
    654710        bithenge_transform_t base;
     
    672728{
    673729        expression_transform_t *self = transform_as_expression(base);
    674         if (bithenge_node_type(in) != BITHENGE_NODE_BLOB)
    675                 return EINVAL;
    676         aoff64_t len;
    677         int rc = bithenge_blob_size(bithenge_node_as_blob(in), &len);
    678         if (rc != EOK)
    679                 return rc;
    680         if (len != 0)
    681                 return EINVAL;
    682         return bithenge_expression_evaluate(self->expr, scope, out);
    683 }
    684 
    685 static int expression_transform_prefix_length(bithenge_transform_t *base,
    686     bithenge_scope_t *scope, bithenge_blob_t *in, aoff64_t *out)
    687 {
    688         *out = 0;
    689         return EOK;
    690 }
    691 
     730        bithenge_scope_t *inner;
     731        int rc = bithenge_scope_new(&inner, scope);
     732        if (rc != EOK)
     733                return rc;
     734        bithenge_scope_set_in_node(inner, in);
     735        rc = bithenge_expression_evaluate(self->expr, inner, out);
     736        bithenge_scope_dec_ref(inner);
     737        return rc;
     738}
     739
     740/* Also used by inputless_transform. */
    692741static void expression_transform_destroy(bithenge_transform_t *base)
    693742{
     
    699748static const bithenge_transform_ops_t expression_transform_ops = {
    700749        .apply = expression_transform_apply,
    701         .prefix_length = expression_transform_prefix_length,
     750        .destroy = expression_transform_destroy,
     751};
     752
     753/** Create a transform that evaluates an expression on the input node. Takes a
     754 * reference to the expression.
     755 * @param[out] out Holds the new transform.
     756 * @param expr The expression to evaluate.
     757 * @return EOK on success or an error code from errno.h. */
     758int bithenge_expression_transform(bithenge_transform_t ** out,
     759    bithenge_expression_t *expr)
     760{
     761        int rc;
     762        expression_transform_t *self = malloc(sizeof(*self));
     763        if (!self) {
     764                rc = ENOMEM;
     765                goto error;
     766        }
     767
     768        rc = bithenge_init_transform(expression_as_transform(self),
     769            &expression_transform_ops, 0);
     770        if (rc != EOK)
     771                goto error;
     772
     773        self->expr = expr;
     774        *out = expression_as_transform(self);
     775        return EOK;
     776
     777error:
     778        free(self);
     779        bithenge_expression_dec_ref(expr);
     780        return rc;
     781}
     782
     783
     784
     785/***************** inputless_transform            *****************/
     786
     787static int inputless_transform_prefix_length(bithenge_transform_t *base,
     788    bithenge_scope_t *scope, bithenge_blob_t *in, aoff64_t *out)
     789{
     790        *out = 0;
     791        return EOK;
     792}
     793
     794static int inputless_transform_prefix_apply(bithenge_transform_t *base,
     795    bithenge_scope_t *scope, bithenge_blob_t *in, bithenge_node_t **out_node,
     796    aoff64_t *out_size)
     797{
     798        expression_transform_t *self = transform_as_expression(base);
     799        *out_size = 0;
     800        return bithenge_expression_evaluate(self->expr, scope, out_node);
     801}
     802
     803static const bithenge_transform_ops_t inputless_transform_ops = {
     804        .prefix_length = inputless_transform_prefix_length,
     805        .prefix_apply = inputless_transform_prefix_apply,
    702806        .destroy = expression_transform_destroy,
    703807};
     
    708812 * @param expr The expression to evaluate.
    709813 * @return EOK on success or an error code from errno.h. */
    710 int bithenge_expression_transform(bithenge_transform_t ** out,
     814int bithenge_inputless_transform(bithenge_transform_t ** out,
    711815    bithenge_expression_t *expr)
    712816{
     
    719823
    720824        rc = bithenge_init_transform(expression_as_transform(self),
    721             &expression_transform_ops, 0);
     825            &inputless_transform_ops, 0);
    722826        if (rc != EOK)
    723827                goto error;
     
    732836        return rc;
    733837}
     838
     839
     840
     841/***************** if_transform                              *****************/
    734842
    735843typedef struct {
  • uspace/app/bithenge/expression.h

    rad5c8a48 ra66ea217  
    103103int bithenge_binary_expression(bithenge_expression_t **, bithenge_binary_op_t,
    104104    bithenge_expression_t *, bithenge_expression_t *);
     105int bithenge_in_node_expression(bithenge_expression_t **);
    105106int bithenge_current_node_expression(bithenge_expression_t **);
    106107int bithenge_param_expression(bithenge_expression_t **, int);
     
    114115int bithenge_expression_transform(bithenge_transform_t **,
    115116    bithenge_expression_t *);
     117int bithenge_inputless_transform(bithenge_transform_t **,
     118    bithenge_expression_t *);
    116119int bithenge_if_transform(bithenge_transform_t **, bithenge_expression_t *,
    117120    bithenge_transform_t *, bithenge_transform_t *);
  • uspace/app/bithenge/script.c

    rad5c8a48 ra66ea217  
    6464        TOKEN_FALSE,
    6565        TOKEN_IF,
     66        TOKEN_IN,
    6667        TOKEN_REPEAT,
    6768        TOKEN_STRUCT,
     
    225226                } else if (!str_cmp(value, "if")) {
    226227                        state->token = TOKEN_IF;
     228                        free(value);
     229                } else if (!str_cmp(value, "in")) {
     230                        state->token = TOKEN_IN;
    227231                        free(value);
    228232                } else if (!str_cmp(value, "repeat")) {
     
    434438
    435439                return expr;
     440        } else if (state->token == TOKEN_IN) {
     441                next_token(state);
     442                bithenge_expression_t *expr;
     443                rc = bithenge_in_node_expression(&expr);
     444                if (rc != EOK) {
     445                        error_errno(state, rc);
     446                        return NULL;
     447                }
     448                return expr;
    436449        } else if (state->token == TOKEN_INTEGER) {
    437450                bithenge_int_t val = state->token_int;
     
    621634
    622635        bithenge_transform_t *xform;
    623         rc = bithenge_expression_transform(&xform, expr);
     636        rc = bithenge_inputless_transform(&xform, expr);
    624637        if (rc != EOK) {
    625638                error_errno(state, rc);
     
    867880static bithenge_transform_t *parse_transform_no_compose(state_t *state)
    868881{
    869         if (state->token == TOKEN_DO) {
     882        if (state->token == '(') {
     883                next_token(state);
     884                bithenge_expression_t *expr = parse_expression(state);
     885                expect(state, ')');
     886                if (state->error != EOK) {
     887                        bithenge_expression_dec_ref(expr);
     888                        return NULL;
     889                }
     890
     891                bithenge_transform_t *xform;
     892                int rc = bithenge_expression_transform(&xform, expr);
     893                if (rc != EOK) {
     894                        error_errno(state, rc);
     895                        return NULL;
     896                }
     897                return xform;
     898        } else if (state->token == TOKEN_DO) {
    870899                return parse_do_while(state);
    871900        } else if (state->token == TOKEN_IDENTIFIER) {
  • uspace/app/bithenge/transform.c

    rad5c8a48 ra66ea217  
    183183        self->params = NULL;
    184184        self->current_node = NULL;
     185        self->in_node = NULL;
    185186        *out = self;
    186187        return EOK;
     
    211212}
    212213
     214/** Get the current node being created, which may be NULL.
     215 * @param scope The scope to get the current node from.
     216 * @return The node being created, or NULL. */
     217bithenge_node_t *bithenge_scope_get_current_node(bithenge_scope_t *scope)
     218{
     219        if (scope->current_node)
     220                bithenge_node_inc_ref(scope->current_node);
     221        return scope->current_node;
     222}
     223
    213224/** Set the current node being created. Takes a reference to @a node.
    214225 * @param scope The scope to set the current node in.
    215  * @param node The current node being created, or NULL.
    216  * @return EOK on success or an error code from errno.h. */
     226 * @param node The current node being created, or NULL. */
    217227void bithenge_scope_set_current_node(bithenge_scope_t *scope,
    218228    bithenge_node_t *node)
     
    220230        bithenge_node_dec_ref(scope->current_node);
    221231        scope->current_node = node;
     232}
     233
     234/** Get the current input node, which may be NULL.
     235 * @param scope The scope to get the current input node from.
     236 * @return The input node, or NULL. */
     237bithenge_node_t *bithenge_scope_in_node(bithenge_scope_t *scope)
     238{
     239        if (scope->in_node)
     240                bithenge_node_inc_ref(scope->in_node);
     241        return scope->in_node;
     242}
     243
     244/** Set the current input node. Takes a reference to @a node.
     245 * @param scope The scope to set the input node in.
     246 * @param node The input node, or NULL. */
     247void bithenge_scope_set_in_node(bithenge_scope_t *scope, bithenge_node_t *node)
     248{
     249        bithenge_node_dec_ref(scope->in_node);
     250        scope->in_node = node;
    222251}
    223252
     
    236265{
    237266        return self->barrier;
    238 }
    239 
    240 /** Get the current node being created, which may be NULL.
    241  * @param scope The scope to get the current node from.
    242  * @return The node being created, or NULL. */
    243 bithenge_node_t *bithenge_scope_get_current_node(bithenge_scope_t *scope)
    244 {
    245         if (scope->current_node)
    246                 bithenge_node_inc_ref(scope->current_node);
    247         return scope->current_node;
    248267}
    249268
  • uspace/app/bithenge/transform.h

    rad5c8a48 ra66ea217  
    5858        bithenge_node_t **params;
    5959        bithenge_node_t *current_node;
     60        bithenge_node_t *in_node;
    6061} bithenge_scope_t;
    6162
     
    153154void bithenge_scope_dec_ref(bithenge_scope_t *);
    154155bithenge_scope_t *bithenge_scope_outer(bithenge_scope_t *);
     156bithenge_node_t *bithenge_scope_get_current_node(bithenge_scope_t *);
    155157void bithenge_scope_set_current_node(bithenge_scope_t *, bithenge_node_t *);
     158bithenge_node_t *bithenge_scope_in_node(bithenge_scope_t *);
     159void bithenge_scope_set_in_node(bithenge_scope_t *, bithenge_node_t *);
    156160void bithenge_scope_set_barrier(bithenge_scope_t *);
    157161bool bithenge_scope_is_barrier(bithenge_scope_t *);
    158 bithenge_node_t *bithenge_scope_get_current_node(bithenge_scope_t *);
    159162int bithenge_scope_alloc_params(bithenge_scope_t *, int);
    160163int bithenge_scope_set_param(bithenge_scope_t *, int, bithenge_node_t *);
  • uspace/dist/src/bithenge/test.bh

    rad5c8a48 ra66ea217  
    1616
    1717transform item(little_endian, len) = struct {
    18         .type <- u32(little_endian);
     18        .type <- (3*in+1) <- u32(little_endian);
    1919        .name <- pascal_string;
    2020        switch (.type) {
    21                 3: {
     21                10: {
    2222                        .val <- u32(little_endian);
    2323                };
    24                 14: {
     24                11: {
    2525                        .text <- ascii <- known_length(len);
    2626                };
Note: See TracChangeset for help on using the changeset viewer.