Changeset 78d3a00 in mainline
- Timestamp:
- 2012-07-31T21:07:26Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3f2ea63
- Parents:
- 20ac1a4
- Location:
- uspace
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bithenge/expression.c
r20ac1a4 r78d3a00 63 63 } 64 64 65 typedef struct { 66 bithenge_expression_t base; 67 bithenge_binary_op_t op; 68 bithenge_expression_t *a, *b; 69 } binary_expression_t; 70 71 static inline binary_expression_t *expression_as_binary( 72 bithenge_expression_t *base) 73 { 74 return (binary_expression_t *)base; 75 } 76 77 static inline bithenge_expression_t *binary_as_expression( 78 binary_expression_t *self) 79 { 80 return &self->base; 81 } 82 83 static int binary_expression_evaluate(bithenge_expression_t *base, 84 bithenge_scope_t *scope, bithenge_node_t **out) 85 { 86 binary_expression_t *self = expression_as_binary(base); 87 bithenge_node_t *a, *b; 88 int rc = bithenge_expression_evaluate(self->a, scope, &a); 89 if (rc != EOK) 90 return rc; 91 rc = bithenge_expression_evaluate(self->b, scope, &b); 92 if (rc != EOK) { 93 bithenge_node_dec_ref(a); 94 return rc; 95 } 96 switch (self->op) { 97 case BITHENGE_EXPRESSION_EQUALS: 98 rc = bithenge_new_boolean_node(out, bithenge_node_equal(a, b)); 99 break; 100 } 101 bithenge_node_dec_ref(a); 102 bithenge_node_dec_ref(b); 103 return rc; 104 } 105 106 static void binary_expression_destroy(bithenge_expression_t *base) 107 { 108 binary_expression_t *self = expression_as_binary(base); 109 bithenge_expression_dec_ref(self->a); 110 bithenge_expression_dec_ref(self->b); 111 free(self); 112 } 113 114 static const bithenge_expression_ops_t binary_expression_ops = { 115 .evaluate = binary_expression_evaluate, 116 .destroy = binary_expression_destroy, 117 }; 118 119 /** Create a binary expression. Takes ownership of @a a and @a b. 120 * @param[out] out Holds the new expression. 121 * @param op The operator to apply. 122 * @param a The first operand. 123 * @param b The second operand. 124 * @return EOK on success or an error code from errno.h. */ 125 int bithenge_binary_expression(bithenge_expression_t **out, 126 bithenge_binary_op_t op, bithenge_expression_t *a, 127 bithenge_expression_t *b) 128 { 129 int rc; 130 binary_expression_t *self = malloc(sizeof(*self)); 131 if (!self) { 132 rc = ENOMEM; 133 goto error; 134 } 135 136 rc = bithenge_init_expression(binary_as_expression(self), 137 &binary_expression_ops); 138 if (rc != EOK) 139 goto error; 140 141 self->op = op; 142 self->a = a; 143 self->b = b; 144 *out = binary_as_expression(self); 145 return EOK; 146 147 error: 148 bithenge_expression_dec_ref(a); 149 bithenge_expression_dec_ref(b); 150 free(self); 151 return rc; 152 } 153 65 154 static int current_node_evaluate(bithenge_expression_t *self, 66 155 bithenge_scope_t *scope, bithenge_node_t **out) -
uspace/app/bithenge/expression.h
r20ac1a4 r78d3a00 91 91 } 92 92 93 typedef enum { 94 BITHENGE_EXPRESSION_EQUALS, 95 } bithenge_binary_op_t; 96 93 97 int bithenge_init_expression(bithenge_expression_t *, 94 98 const bithenge_expression_ops_t *); 99 int bithenge_binary_expression(bithenge_expression_t **, bithenge_binary_op_t, 100 bithenge_expression_t *, bithenge_expression_t *); 95 101 int bithenge_current_node_expression(bithenge_expression_t **); 96 102 int bithenge_param_expression(bithenge_expression_t **, int); -
uspace/app/bithenge/script.c
r20ac1a4 r78d3a00 62 62 TOKEN_IF, 63 63 TOKEN_STRUCT, 64 TOKEN_SWITCH, 64 65 TOKEN_TRANSFORM, 65 66 TOKEN_TRUE, … … 219 220 } else if (!str_cmp(value, "struct")) { 220 221 state->token = TOKEN_STRUCT; 222 free(value); 223 } else if (!str_cmp(value, "switch")) { 224 state->token = TOKEN_SWITCH; 221 225 free(value); 222 226 } else if (!str_cmp(value, "transform")) { … … 548 552 } 549 553 554 static bithenge_transform_t *parse_switch(state_t *state, bool in_struct) 555 { 556 expect(state, TOKEN_SWITCH); 557 expect(state, '('); 558 bithenge_expression_t *ref_expr = parse_expression(state); 559 expect(state, ')'); 560 expect(state, '{'); 561 int num = 0; 562 bithenge_expression_t **exprs = NULL; 563 bithenge_transform_t **xforms = NULL; 564 while (state->error == EOK && state->token != '}') { 565 bithenge_expression_t *expr; 566 if (state->token == TOKEN_ELSE) { 567 next_token(state); 568 bithenge_node_t *node; 569 int rc = bithenge_new_boolean_node(&node, true); 570 if (rc != EOK) { 571 error_errno(state, rc); 572 break; 573 } 574 rc = bithenge_const_expression(&expr, node); 575 if (rc != EOK) { 576 error_errno(state, rc); 577 break; 578 } 579 } else { 580 expr = parse_expression(state); 581 if (state->error == EOK) { 582 bithenge_expression_inc_ref(ref_expr); 583 int rc = bithenge_binary_expression(&expr, 584 BITHENGE_EXPRESSION_EQUALS, ref_expr, 585 expr); 586 if (rc != EOK) { 587 error_errno(state, rc); 588 break; 589 } 590 } 591 } 592 593 expect(state, ':'); 594 bithenge_transform_t *xform; 595 if (in_struct) { 596 expect(state, '{'); 597 xform = parse_struct(state); 598 expect(state, '}'); 599 } else 600 xform = parse_transform(state); 601 expect(state, ';'); 602 603 exprs = state_realloc(state, exprs, 604 sizeof(*exprs) * (num + 1)); 605 xforms = state_realloc(state, xforms, 606 sizeof(*xforms) * (num + 1)); 607 if (state->error != EOK) { 608 bithenge_expression_dec_ref(expr); 609 bithenge_transform_dec_ref(xform); 610 break; 611 } 612 613 exprs[num] = expr; 614 xforms[num] = xform; 615 num++; 616 } 617 bithenge_expression_dec_ref(ref_expr); 618 619 bithenge_transform_t *switch_xform = &bithenge_invalid_transform; 620 bithenge_transform_inc_ref(switch_xform); 621 while (state->error == EOK && num >= 1) { 622 num--; 623 int rc = bithenge_if_transform(&switch_xform, exprs[num], 624 xforms[num], switch_xform); 625 if (rc != EOK) 626 error_errno(state, rc); 627 } 628 629 while (num >= 1) { 630 num--; 631 bithenge_expression_dec_ref(exprs[num]); 632 bithenge_transform_dec_ref(xforms[num]); 633 } 634 free(exprs); 635 free(xforms); 636 637 expect(state, '}'); 638 return switch_xform; 639 } 640 550 641 /* The TOKEN_STRUCT and '{' must already have been skipped. */ 551 642 static bithenge_transform_t *parse_struct(state_t *state) … … 558 649 if (state->token == TOKEN_IF) { 559 650 subxforms[num].transform = parse_if(state, true); 651 subxforms[num].name = NULL; 652 } else if (state->token == TOKEN_SWITCH) { 653 subxforms[num].transform = parse_switch(state, true); 560 654 subxforms[num].name = NULL; 561 655 } else { … … 609 703 expect(state, '}'); 610 704 return xform; 705 } else if (state->token == TOKEN_SWITCH) { 706 return parse_switch(state, false); 611 707 } else { 612 708 syntax_error(state, "unexpected (transform expected)"); -
uspace/app/bithenge/transform.c
r20ac1a4 r78d3a00 183 183 bithenge_transform_t bithenge_ascii_transform = { 184 184 &ascii_ops, 1, 0 185 }; 186 187 static int invalid_apply(bithenge_transform_t *self, bithenge_scope_t *scope, 188 bithenge_node_t *in, bithenge_node_t **out) 189 { 190 return EINVAL; 191 } 192 193 static const bithenge_transform_ops_t invalid_ops = { 194 .apply = invalid_apply, 195 .destroy = transform_indestructible, 196 }; 197 198 /** A transform that always raises an error. */ 199 bithenge_transform_t bithenge_invalid_transform = { 200 &invalid_ops, 1, 0 185 201 }; 186 202 -
uspace/app/bithenge/transform.h
r20ac1a4 r78d3a00 256 256 extern bithenge_transform_t bithenge_ascii_transform; 257 257 extern bithenge_transform_t bithenge_known_length_transform; 258 extern bithenge_transform_t bithenge_invalid_transform; 258 259 extern bithenge_transform_t bithenge_uint8_transform; 259 260 extern bithenge_transform_t bithenge_uint16le_transform; -
uspace/app/bithenge/tree.c
r20ac1a4 r78d3a00 325 325 326 326 /** Check whether the contents of two nodes are equal. Does not yet work for 327 * internal nodes. 327 * internal nodes. Takes ownership of nothing. 328 328 * @memberof bithenge_node_t 329 329 * @param a, b Nodes to compare. -
uspace/dist/src/bithenge/test.bh
r20ac1a4 r78d3a00 8 8 }; 9 9 10 transform item(first_len, second_len) = struct { 11 .id <- uint32le <- known_length(4); # the known_length is unnecessary 10 transform u32(little_endian) = 11 if (little_endian) { 12 uint32le 13 } else { 14 uint32be 15 }; 16 17 transform item(little_endian, len) = struct { 18 .type <- u32(little_endian); 12 19 .name <- pascal_string; 13 .first <- known_length(first_len); 14 .second <- known_length(second_len); 20 switch (.type) { 21 3: { 22 .val <- u32(little_endian); 23 }; 24 14: { 25 .text <- ascii <- known_length(len); 26 }; 27 else: { 28 .unknown <- known_length(len); 29 }; 30 } 15 31 }; 16 32 17 transform main() = item(3, 0); 33 transform main() = struct { 34 .first_item <- item(true, 3); 35 .second_item <- item(false, 4); 36 };
Note:
See TracChangeset
for help on using the changeset viewer.