Changeset 20ac1a4 in mainline
 Timestamp:
 20120730T02:07:10Z (10 years ago)
 Branches:
 lfn, master, serial
 Children:
 78d3a00
 Parents:
 10334c2e
 Location:
 uspace/app/bithenge
 Files:

 3 edited
Legend:
 Unmodified
 Added
 Removed

uspace/app/bithenge/expression.c
r10334c2e r20ac1a4 420 420 bithenge_transform_t base; 421 421 bithenge_expression_t *expr; 422 } expression_transform_t; 423 424 static inline bithenge_transform_t *expression_as_transform( 425 expression_transform_t *self) 426 { 427 return &self>base; 428 } 429 430 static inline expression_transform_t *transform_as_expression( 431 bithenge_transform_t *base) 432 { 433 return (expression_transform_t *)base; 434 } 435 436 static int expression_transform_apply(bithenge_transform_t *base, 437 bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out) 438 { 439 expression_transform_t *self = transform_as_expression(base); 440 if (bithenge_node_type(in) != BITHENGE_NODE_BLOB) 441 return EINVAL; 442 aoff64_t len; 443 int rc = bithenge_blob_size(bithenge_node_as_blob(in), &len); 444 if (rc != EOK) 445 return rc; 446 if (len != 0) 447 return EINVAL; 448 return bithenge_expression_evaluate(self>expr, scope, out); 449 } 450 451 static int expression_transform_prefix_length(bithenge_transform_t *base, 452 bithenge_scope_t *scope, bithenge_blob_t *in, aoff64_t *out) 453 { 454 *out = 0; 455 return EOK; 456 } 457 458 static void expression_transform_destroy(bithenge_transform_t *base) 459 { 460 expression_transform_t *self = transform_as_expression(base); 461 bithenge_expression_dec_ref(self>expr); 462 free(self); 463 } 464 465 static const bithenge_transform_ops_t expression_transform_ops = { 466 .apply = expression_transform_apply, 467 .prefix_length = expression_transform_prefix_length, 468 .destroy = expression_transform_destroy, 469 }; 470 471 /** Create a transform that takes an empty blob and produces the result of an 472 * expression. Takes a reference to the expression. 473 * @param[out] out Holds the new transform. 474 * @param expr The expression to evaluate. 475 * @return EOK on success or an error code from errno.h. */ 476 int bithenge_expression_transform(bithenge_transform_t ** out, 477 bithenge_expression_t *expr) 478 { 479 int rc; 480 expression_transform_t *self = malloc(sizeof(*self)); 481 if (!self) { 482 rc = ENOMEM; 483 goto error; 484 } 485 486 rc = bithenge_init_transform(expression_as_transform(self), 487 &expression_transform_ops, 0); 488 if (rc != EOK) 489 goto error; 490 491 self>expr = expr; 492 *out = expression_as_transform(self); 493 return EOK; 494 495 error: 496 free(self); 497 bithenge_expression_dec_ref(expr); 498 return rc; 499 } 500 501 typedef struct { 502 bithenge_transform_t base; 503 bithenge_expression_t *expr; 422 504 bithenge_transform_t *true_xform, *false_xform; 423 505 } if_transform_t; 
uspace/app/bithenge/expression.h
r10334c2e r20ac1a4 100 100 int bithenge_param_wrapper(bithenge_transform_t **, bithenge_transform_t *, 101 101 bithenge_expression_t **); 102 int bithenge_expression_transform(bithenge_transform_t **, 103 bithenge_expression_t *); 102 104 int bithenge_if_transform(bithenge_transform_t **, bithenge_expression_t *, 103 105 bithenge_transform_t *, bithenge_transform_t *); 
uspace/app/bithenge/script.c
r10334c2e r20ac1a4 342 342 343 343 static bithenge_transform_t *parse_transform(state_t *state); 344 static bithenge_transform_t *parse_struct(state_t *state); 344 345 345 346 static bithenge_expression_t *parse_expression(state_t *state) … … 490 491 } 491 492 492 static bithenge_transform_t *parse_if(state_t *state )493 static bithenge_transform_t *parse_if(state_t *state, bool in_struct) 493 494 { 494 495 expect(state, TOKEN_IF); … … 497 498 expect(state, ')'); 498 499 expect(state, '{'); 499 bithenge_transform_t *true_xform = parse_transform(state); 500 bithenge_transform_t *true_xform = 501 in_struct ? parse_struct(state) : parse_transform(state); 500 502 expect(state, '}'); 501 expect(state, TOKEN_ELSE); 502 expect(state, '{'); 503 bithenge_transform_t *false_xform = parse_transform(state); 504 expect(state, '}'); 503 bithenge_transform_t *false_xform = NULL; 504 if (state>token == TOKEN_ELSE) { 505 next_token(state); 506 expect(state, '{'); 507 false_xform = 508 in_struct ? parse_struct(state) : parse_transform(state); 509 expect(state, '}'); 510 } else { 511 if (in_struct) { 512 bithenge_node_t *node; 513 int rc = bithenge_new_empty_internal_node(&node); 514 if (rc != EOK) { 515 error_errno(state, rc); 516 goto error; 517 } 518 bithenge_expression_t *expr; 519 rc = bithenge_const_expression(&expr, node); 520 if (rc != EOK) { 521 error_errno(state, rc); 522 goto error; 523 } 524 rc = bithenge_expression_transform(&false_xform, expr); 525 if (rc != EOK) { 526 error_errno(state, rc); 527 false_xform = NULL; 528 goto error; 529 } 530 } else 531 syntax_error(state, "else expected"); 532 } 505 533 if (state>error != EOK) { 534 error: 506 535 bithenge_expression_dec_ref(expr); 507 536 bithenge_transform_dec_ref(true_xform); … … 519 548 } 520 549 550 /* The TOKEN_STRUCT and '{' must already have been skipped. */ 521 551 static bithenge_transform_t *parse_struct(state_t *state) 522 552 { … … 525 555 /* We keep an extra space for the {NULL, NULL} terminator. */ 526 556 subxforms = state_malloc(state, sizeof(*subxforms)); 527 expect(state, TOKEN_STRUCT);528 expect(state, '{');529 557 while (state>error == EOK && state>token != '}') { 530 if (state>token == '.') { 531 expect(state, '.'); 532 subxforms[num].name = expect_identifier(state); 558 if (state>token == TOKEN_IF) { 559 subxforms[num].transform = parse_if(state, true); 560 subxforms[num].name = NULL; 561 } else { 562 if (state>token == '.') { 563 next_token(state); 564 subxforms[num].name = expect_identifier(state); 565 } else { 566 subxforms[num].name = NULL; 567 } 533 568 expect(state, TOKEN_LEFT_ARROW); 534 } else { 535 subxforms[num].name = NULL; 536 expect(state, TOKEN_LEFT_ARROW); 537 } 538 subxforms[num].transform = parse_transform(state); 539 expect(state, ';'); 569 subxforms[num].transform = parse_transform(state); 570 expect(state, ';'); 571 } 540 572 num++; 541 573 subxforms = state_realloc(state, subxforms, 542 574 (num + 1)*sizeof(*subxforms)); 543 575 } 544 expect(state, '}');545 576 546 577 if (state>error != EOK) { … … 571 602 return parse_invocation(state); 572 603 } else if (state>token == TOKEN_IF) { 573 return parse_if(state );604 return parse_if(state, false); 574 605 } else if (state>token == TOKEN_STRUCT) { 575 return parse_struct(state); 606 next_token(state); 607 expect(state, '{'); 608 bithenge_transform_t *xform = parse_struct(state); 609 expect(state, '}'); 610 return xform; 576 611 } else { 577 612 syntax_error(state, "unexpected (transform expected)");
Note: See TracChangeset
for help on using the changeset viewer.