Changeset 2988aec7 in mainline for uspace/app/bithenge/expression.c


Ignore:
Timestamp:
2012-08-14T03:17:17Z (12 years ago)
Author:
Sean Bartell <wingedtachikoma@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
71b0d4d4
Parents:
1b6b76d
Message:

Bithenge: read FAT files/subdirs; self-recursion and more operators

File:
1 edited

Legend:

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

    r1b6b76d r2988aec7  
    101101        /* Check types and get values. */
    102102        bithenge_int_t a_int = 0, b_int = 0;
     103        bool a_bool = false, b_bool = false;
    103104        switch (self->op) {
    104105        case BITHENGE_EXPRESSION_ADD: /* fallthrough */
     
    119120                b_int = bithenge_integer_node_value(b);
    120121                break;
     122        case BITHENGE_EXPRESSION_AND: /* fallthrough */
     123        case BITHENGE_EXPRESSION_OR:
     124                rc = EINVAL;
     125                if (bithenge_node_type(a) != BITHENGE_NODE_BOOLEAN)
     126                        goto error;
     127                if (bithenge_node_type(b) != BITHENGE_NODE_BOOLEAN)
     128                        goto error;
     129                a_bool = bithenge_boolean_node_value(a);
     130                b_bool = bithenge_boolean_node_value(b);
     131                break;
     132        case BITHENGE_EXPRESSION_CONCAT:
     133                if (bithenge_node_type(a) != BITHENGE_NODE_BLOB)
     134                        goto error;
     135                if (bithenge_node_type(b) != BITHENGE_NODE_BLOB)
     136                        goto error;
     137                break;
    121138        default:
    122139                break;
     
    135152        case BITHENGE_EXPRESSION_INTEGER_DIVIDE:
    136153                /* Integer division can behave in three major ways when the
    137                  * operands are signed: truncated, floored, or Euclidean. When
     154                  operands are signed: truncated, floored, or Euclidean. When
    138155                 * b > 0, we give the same result as floored and Euclidean;
    139156                 * otherwise, we currently raise an error. See
     
    173190        case BITHENGE_EXPRESSION_NOT_EQUALS:
    174191                rc = bithenge_new_boolean_node(out,
    175                     ~bithenge_node_equal(a, b));
     192                    !bithenge_node_equal(a, b));
     193                break;
     194        case BITHENGE_EXPRESSION_AND:
     195                rc = bithenge_new_boolean_node(out, a_bool && b_bool);
     196                break;
     197        case BITHENGE_EXPRESSION_OR:
     198                rc = bithenge_new_boolean_node(out, a_bool || b_bool);
     199                break;
     200        case BITHENGE_EXPRESSION_MEMBER:
     201                rc = bithenge_node_get(a, b, out);
     202                b = NULL;
     203                break;
     204        case BITHENGE_EXPRESSION_CONCAT:
     205                rc = bithenge_concat_blob(out, bithenge_node_as_blob(a),
     206                    bithenge_node_as_blob(b));
     207                a = NULL;
     208                b = NULL;
    176209                break;
    177210        case BITHENGE_EXPRESSION_INVALID_BINARY_OP:
     
    430463        free(self);
    431464        bithenge_node_dec_ref(node);
    432         return rc;
    433 }
    434 
    435 
    436 
    437 /***************** member_expression                         *****************/
    438 
    439 typedef struct {
    440         bithenge_expression_t base;
    441         bithenge_expression_t *expr;
    442         bithenge_node_t *key;
    443 } member_expression_t;
    444 
    445 static member_expression_t *expression_as_member(bithenge_expression_t *base)
    446 {
    447         return (member_expression_t *)base;
    448 }
    449 
    450 static bithenge_expression_t *member_as_expression(member_expression_t *expr)
    451 {
    452         return &expr->base;
    453 }
    454 
    455 static int member_expression_evaluate(bithenge_expression_t *base,
    456     bithenge_scope_t *scope, bithenge_node_t **out)
    457 {
    458         member_expression_t *self = expression_as_member(base);
    459         bithenge_node_t *node;
    460         int rc = bithenge_expression_evaluate(self->expr, scope, &node);
    461         if (rc != EOK)
    462                 return rc;
    463         bithenge_node_inc_ref(self->key);
    464         rc = bithenge_node_get(node, self->key, out);
    465         bithenge_node_dec_ref(node);
    466         if (rc == ENOENT)
    467                 return bithenge_scope_error(scope, "No member %t", self->key);
    468         return rc;
    469 }
    470 
    471 static void member_expression_destroy(bithenge_expression_t *base)
    472 {
    473         member_expression_t *self = expression_as_member(base);
    474         bithenge_expression_dec_ref(self->expr);
    475         bithenge_node_dec_ref(self->key);
    476         free(self);
    477 }
    478 
    479 static const bithenge_expression_ops_t member_expression_ops = {
    480         .evaluate = member_expression_evaluate,
    481         .destroy = member_expression_destroy,
    482 };
    483 
    484 /** Create an expression that gets a member from a node. Takes references to
    485  * @a expr and @a key.
    486  * @param[out] out Holds the new expression.
    487  * @param expr Calculates the node to get the member of.
    488  * @param key The member to get.
    489  * @return EOK on success or an error code from errno.h. */
    490 int bithenge_member_expression(bithenge_expression_t **out,
    491     bithenge_expression_t *expr, bithenge_node_t *key)
    492 {
    493         int rc;
    494         member_expression_t *self = malloc(sizeof(*self));
    495         if (!self) {
    496                 rc = ENOMEM;
    497                 goto error;
    498         }
    499 
    500         rc = bithenge_init_expression(member_as_expression(self),
    501             &member_expression_ops);
    502         if (rc != EOK)
    503                 goto error;
    504 
    505         self->expr = expr;
    506         self->key = key;
    507         *out = member_as_expression(self);
    508         return EOK;
    509 
    510 error:
    511         bithenge_expression_dec_ref(expr);
    512         bithenge_node_dec_ref(key);
    513         free(self);
    514465        return rc;
    515466}
Note: See TracChangeset for help on using the changeset viewer.