Changeset a66ea217 in mainline
- Timestamp:
- 2012-08-08T00:52:22Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d8bd2ec
- Parents:
- ad5c8a48
- Location:
- uspace
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bithenge/expression.c
rad5c8a48 ra66ea217 63 63 } 64 64 65 66 67 /***************** binary_expression *****************/ 68 65 69 typedef struct { 66 70 bithenge_expression_t base; … … 185 189 } 186 190 191 192 193 /***************** in_node_expression *****************/ 194 195 static 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 207 static const bithenge_expression_ops_t in_node_ops = { 208 .evaluate = in_node_evaluate, 209 .destroy = expression_indestructible, 210 }; 211 212 static 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. */ 219 int 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 187 230 static int current_node_evaluate(bithenge_expression_t *self, 188 231 bithenge_scope_t *scope, bithenge_node_t **out) … … 212 255 return EOK; 213 256 } 257 258 259 260 /***************** param_expression *****************/ 214 261 215 262 typedef struct { … … 270 317 return EOK; 271 318 } 319 320 321 322 /***************** const_expression *****************/ 272 323 273 324 typedef struct { … … 651 702 } 652 703 704 705 706 /***************** expression_transform *****************/ 707 708 /* Also used by inputless_transform. */ 653 709 typedef struct { 654 710 bithenge_transform_t base; … … 672 728 { 673 729 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. */ 692 741 static void expression_transform_destroy(bithenge_transform_t *base) 693 742 { … … 699 748 static const bithenge_transform_ops_t expression_transform_ops = { 700 749 .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. */ 758 int 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 777 error: 778 free(self); 779 bithenge_expression_dec_ref(expr); 780 return rc; 781 } 782 783 784 785 /***************** inputless_transform *****************/ 786 787 static 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 794 static 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 803 static const bithenge_transform_ops_t inputless_transform_ops = { 804 .prefix_length = inputless_transform_prefix_length, 805 .prefix_apply = inputless_transform_prefix_apply, 702 806 .destroy = expression_transform_destroy, 703 807 }; … … 708 812 * @param expr The expression to evaluate. 709 813 * @return EOK on success or an error code from errno.h. */ 710 int bithenge_ expression_transform(bithenge_transform_t ** out,814 int bithenge_inputless_transform(bithenge_transform_t ** out, 711 815 bithenge_expression_t *expr) 712 816 { … … 719 823 720 824 rc = bithenge_init_transform(expression_as_transform(self), 721 & expression_transform_ops, 0);825 &inputless_transform_ops, 0); 722 826 if (rc != EOK) 723 827 goto error; … … 732 836 return rc; 733 837 } 838 839 840 841 /***************** if_transform *****************/ 734 842 735 843 typedef struct { -
uspace/app/bithenge/expression.h
rad5c8a48 ra66ea217 103 103 int bithenge_binary_expression(bithenge_expression_t **, bithenge_binary_op_t, 104 104 bithenge_expression_t *, bithenge_expression_t *); 105 int bithenge_in_node_expression(bithenge_expression_t **); 105 106 int bithenge_current_node_expression(bithenge_expression_t **); 106 107 int bithenge_param_expression(bithenge_expression_t **, int); … … 114 115 int bithenge_expression_transform(bithenge_transform_t **, 115 116 bithenge_expression_t *); 117 int bithenge_inputless_transform(bithenge_transform_t **, 118 bithenge_expression_t *); 116 119 int bithenge_if_transform(bithenge_transform_t **, bithenge_expression_t *, 117 120 bithenge_transform_t *, bithenge_transform_t *); -
uspace/app/bithenge/script.c
rad5c8a48 ra66ea217 64 64 TOKEN_FALSE, 65 65 TOKEN_IF, 66 TOKEN_IN, 66 67 TOKEN_REPEAT, 67 68 TOKEN_STRUCT, … … 225 226 } else if (!str_cmp(value, "if")) { 226 227 state->token = TOKEN_IF; 228 free(value); 229 } else if (!str_cmp(value, "in")) { 230 state->token = TOKEN_IN; 227 231 free(value); 228 232 } else if (!str_cmp(value, "repeat")) { … … 434 438 435 439 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; 436 449 } else if (state->token == TOKEN_INTEGER) { 437 450 bithenge_int_t val = state->token_int; … … 621 634 622 635 bithenge_transform_t *xform; 623 rc = bithenge_ expression_transform(&xform, expr);636 rc = bithenge_inputless_transform(&xform, expr); 624 637 if (rc != EOK) { 625 638 error_errno(state, rc); … … 867 880 static bithenge_transform_t *parse_transform_no_compose(state_t *state) 868 881 { 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) { 870 899 return parse_do_while(state); 871 900 } else if (state->token == TOKEN_IDENTIFIER) { -
uspace/app/bithenge/transform.c
rad5c8a48 ra66ea217 183 183 self->params = NULL; 184 184 self->current_node = NULL; 185 self->in_node = NULL; 185 186 *out = self; 186 187 return EOK; … … 211 212 } 212 213 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. */ 217 bithenge_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 213 224 /** Set the current node being created. Takes a reference to @a node. 214 225 * @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. */ 217 227 void bithenge_scope_set_current_node(bithenge_scope_t *scope, 218 228 bithenge_node_t *node) … … 220 230 bithenge_node_dec_ref(scope->current_node); 221 231 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. */ 237 bithenge_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. */ 247 void 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; 222 251 } 223 252 … … 236 265 { 237 266 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;248 267 } 249 268 -
uspace/app/bithenge/transform.h
rad5c8a48 ra66ea217 58 58 bithenge_node_t **params; 59 59 bithenge_node_t *current_node; 60 bithenge_node_t *in_node; 60 61 } bithenge_scope_t; 61 62 … … 153 154 void bithenge_scope_dec_ref(bithenge_scope_t *); 154 155 bithenge_scope_t *bithenge_scope_outer(bithenge_scope_t *); 156 bithenge_node_t *bithenge_scope_get_current_node(bithenge_scope_t *); 155 157 void bithenge_scope_set_current_node(bithenge_scope_t *, bithenge_node_t *); 158 bithenge_node_t *bithenge_scope_in_node(bithenge_scope_t *); 159 void bithenge_scope_set_in_node(bithenge_scope_t *, bithenge_node_t *); 156 160 void bithenge_scope_set_barrier(bithenge_scope_t *); 157 161 bool bithenge_scope_is_barrier(bithenge_scope_t *); 158 bithenge_node_t *bithenge_scope_get_current_node(bithenge_scope_t *);159 162 int bithenge_scope_alloc_params(bithenge_scope_t *, int); 160 163 int bithenge_scope_set_param(bithenge_scope_t *, int, bithenge_node_t *); -
uspace/dist/src/bithenge/test.bh
rad5c8a48 ra66ea217 16 16 17 17 transform item(little_endian, len) = struct { 18 .type <- u32(little_endian);18 .type <- (3*in+1) <- u32(little_endian); 19 19 .name <- pascal_string; 20 20 switch (.type) { 21 3: {21 10: { 22 22 .val <- u32(little_endian); 23 23 }; 24 1 4: {24 11: { 25 25 .text <- ascii <- known_length(len); 26 26 };
Note:
See TracChangeset
for help on using the changeset viewer.