Changeset 0b60d2d in mainline
- Timestamp:
- 2012-08-09T04:46:44Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3c70376
- Parents:
- d8bd2ec
- Location:
- uspace/app/bithenge
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bithenge/expression.c
rd8bd2ec r0b60d2d 545 545 546 546 547 /***************** subblob_expression *****************/ 548 549 typedef struct { 550 bithenge_expression_t base; 551 bithenge_expression_t *blob, *start, *limit; 552 bool absolute_limit; 553 } subblob_expression_t; 554 555 static subblob_expression_t *expression_as_subblob(bithenge_expression_t *base) 556 { 557 return (subblob_expression_t *)base; 558 } 559 560 static bithenge_expression_t *subblob_as_expression(subblob_expression_t *expr) 561 { 562 return &expr->base; 563 } 564 565 static int subblob_expression_evaluate(bithenge_expression_t *base, 566 bithenge_scope_t *scope, bithenge_node_t **out) 567 { 568 subblob_expression_t *self = expression_as_subblob(base); 569 bithenge_node_t *start_node; 570 int rc = bithenge_expression_evaluate(self->start, scope, &start_node); 571 if (rc != EOK) 572 return rc; 573 if (bithenge_node_type(start_node) != BITHENGE_NODE_INTEGER) { 574 bithenge_node_dec_ref(start_node); 575 return EINVAL; 576 } 577 bithenge_int_t start = bithenge_integer_node_value(start_node); 578 bithenge_node_dec_ref(start_node); 579 580 bithenge_int_t limit = -1; 581 if (self->limit) { 582 bithenge_node_t *limit_node; 583 rc = bithenge_expression_evaluate(self->limit, scope, 584 &limit_node); 585 if (rc != EOK) 586 return rc; 587 if (bithenge_node_type(limit_node) != BITHENGE_NODE_INTEGER) { 588 bithenge_node_dec_ref(limit_node); 589 return EINVAL; 590 } 591 limit = bithenge_integer_node_value(limit_node); 592 bithenge_node_dec_ref(limit_node); 593 if (self->absolute_limit) 594 limit -= start; 595 } 596 597 if (start < 0 || (self->limit && limit < 0)) 598 return EINVAL; 599 600 bithenge_node_t *blob; 601 rc = bithenge_expression_evaluate(self->blob, scope, &blob); 602 if (rc != EOK) 603 return rc; 604 if (bithenge_node_type(blob) != BITHENGE_NODE_BLOB) { 605 bithenge_node_dec_ref(blob); 606 return EINVAL; 607 } 608 609 if (self->limit) 610 return bithenge_new_subblob(out, bithenge_node_as_blob(blob), 611 start, limit); 612 else 613 return bithenge_new_offset_blob(out, 614 bithenge_node_as_blob(blob), start); 615 } 616 617 static void subblob_expression_destroy(bithenge_expression_t *base) 618 { 619 subblob_expression_t *self = expression_as_subblob(base); 620 bithenge_expression_dec_ref(self->start); 621 bithenge_expression_dec_ref(self->limit); 622 free(self); 623 } 624 625 static const bithenge_expression_ops_t subblob_expression_ops = { 626 .evaluate = subblob_expression_evaluate, 627 .destroy = subblob_expression_destroy, 628 }; 629 630 /** Create an expression that gets a subblob. Takes references to @a blob, 631 * @a start, and @a limit. 632 * @param[out] out Holds the new expression. 633 * @param blob Calculates the blob. 634 * @param start Calculates the start offset within the blob. 635 * @param limit Calculates the limit. Can be NULL, in which case an offset blob 636 * is returned. 637 * @param absolute_limit If true, the limit is an absolute offset; otherwise, 638 * it is relative to the start. 639 * @return EOK on success or an error code from errno.h. */ 640 int bithenge_subblob_expression(bithenge_expression_t **out, 641 bithenge_expression_t *blob, bithenge_expression_t *start, 642 bithenge_expression_t *limit, bool absolute_limit) 643 { 644 int rc; 645 subblob_expression_t *self = malloc(sizeof(*self)); 646 if (!self) { 647 rc = ENOMEM; 648 goto error; 649 } 650 651 rc = bithenge_init_expression(subblob_as_expression(self), 652 &subblob_expression_ops); 653 if (rc != EOK) 654 goto error; 655 656 self->blob = blob; 657 self->start = start; 658 self->limit = limit; 659 self->absolute_limit = absolute_limit; 660 *out = subblob_as_expression(self); 661 return EOK; 662 663 error: 664 bithenge_expression_dec_ref(blob); 665 bithenge_expression_dec_ref(start); 666 bithenge_expression_dec_ref(limit); 667 free(self); 668 return rc; 669 } 670 547 671 /***************** param_wrapper *****************/ 548 672 -
uspace/app/bithenge/expression.h
rd8bd2ec r0b60d2d 111 111 int bithenge_scope_member_expression(bithenge_expression_t **, 112 112 bithenge_node_t *); 113 int bithenge_subblob_expression(bithenge_expression_t **, 114 bithenge_expression_t *, bithenge_expression_t *, bithenge_expression_t *, 115 bool); 113 116 int bithenge_param_wrapper(bithenge_transform_t **, bithenge_transform_t *, 114 117 bithenge_expression_t **); -
uspace/app/bithenge/script.c
rd8bd2ec r0b60d2d 530 530 } 531 531 532 static bithenge_expression_t *parse_postfix_expression(state_t *state) 533 { 534 bithenge_expression_t *expr = parse_term(state); 535 while (state->error == EOK) { 536 if (state->token == '[') { 537 next_token(state); 538 bithenge_expression_t *start = parse_expression(state); 539 bool absolute_limit; 540 if (state->token == ',') { 541 absolute_limit = false; 542 next_token(state); 543 } else if (state->token == ':') { 544 absolute_limit = true; 545 next_token(state); 546 } else { 547 syntax_error(state, "expected ',' or ':'"); 548 } 549 bithenge_expression_t *limit = NULL; 550 if (!(state->token == ']' && absolute_limit)) 551 limit = parse_expression(state); 552 expect(state, ']'); 553 554 if (state->error != EOK) { 555 bithenge_expression_dec_ref(expr); 556 bithenge_expression_dec_ref(start); 557 bithenge_expression_dec_ref(limit); 558 return NULL; 559 } 560 int rc = bithenge_subblob_expression(&expr, expr, 561 start, limit, absolute_limit); 562 if (rc != EOK) { 563 error_errno(state, rc); 564 return NULL; 565 } 566 } else { 567 break; 568 } 569 } 570 return expr; 571 } 572 532 573 static bithenge_expression_t *parse_expression_precedence(state_t *state, 533 574 precedence_t prev_precedence) 534 575 { 535 bithenge_expression_t *expr = parse_ term(state);576 bithenge_expression_t *expr = parse_postfix_expression(state); 536 577 while (state->error == EOK) { 537 578 bithenge_binary_op_t op = … … 544 585 next_token(state); 545 586 546 bithenge_expression_t *expr2 = parse_ term(state);587 bithenge_expression_t *expr2 = parse_postfix_expression(state); 547 588 if (state->error != EOK) { 548 589 bithenge_expression_dec_ref(expr2);
Note:
See TracChangeset
for help on using the changeset viewer.