Changeset 5e718d9 in mainline for uspace/lib/bithenge/script.c
- Timestamp:
- 2012-08-21T10:04:16Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 67edca6
- Parents:
- 0da6c04 (diff), 6a97f2e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/bithenge/script.c
r0da6c04 r5e718d9 38 38 #include <stdio.h> 39 39 #include <stdlib.h> 40 #include "compound.h" 40 41 #include "expression.h" 41 42 #include "os.h" … … 45 46 #include "tree.h" 46 47 48 /** @cond internal */ 49 #define BUFFER_SIZE 4096 50 /** @endcond */ 51 47 52 /** Tokens with more characters than this may be read incorrectly. */ 48 #define MAX_TOKEN_SIZE 256 49 #define BUFFER_SIZE 4096 50 51 /** Single-character symbols are represented by the character itself. Every53 static const int MAX_TOKEN_SIZE = 256; 54 55 /** @cond internal 56 * Single-character symbols are represented by the character itself. Every 52 57 * other token uses one of these values: */ 53 58 typedef enum { 54 TOKEN_EQUALS = -128, 55 TOKEN_ERROR, 59 TOKEN_ERROR = -128, 60 61 TOKEN_AND, 62 TOKEN_CONCAT, 63 TOKEN_EQUALS, 56 64 TOKEN_EOF, 65 TOKEN_GREATER_THAN_OR_EQUAL, 57 66 TOKEN_IDENTIFIER, 58 67 TOKEN_INTEGER, 68 TOKEN_INTEGER_DIVIDE, 59 69 TOKEN_LEFT_ARROW, 70 TOKEN_LESS_THAN_OR_EQUAL, 71 TOKEN_NOT_EQUAL, 72 TOKEN_OR, 60 73 61 74 /* Keywords */ … … 65 78 TOKEN_IF, 66 79 TOKEN_IN, 80 TOKEN_PARTIAL, 67 81 TOKEN_REPEAT, 68 82 TOKEN_STRUCT, … … 72 86 TOKEN_WHILE, 73 87 } token_type_t; 88 /** @endcond */ 74 89 75 90 /** Singly-linked list of named transforms. */ … … 232 247 state->token = TOKEN_IN; 233 248 free(value); 249 } else if (!str_cmp(value, "partial")) { 250 state->token = TOKEN_PARTIAL; 251 free(value); 234 252 } else if (!str_cmp(value, "repeat")) { 235 253 state->token = TOKEN_REPEAT; … … 267 285 state->buffer_pos++; 268 286 state->token = TOKEN_LEFT_ARROW; 287 } else if (state->buffer[state->buffer_pos] == '=') { 288 state->buffer_pos++; 289 state->token = TOKEN_LESS_THAN_OR_EQUAL; 290 } 291 } else if (ch == '>') { 292 state->token = ch; 293 state->buffer_pos++; 294 if (state->buffer[state->buffer_pos] == '=') { 295 state->buffer_pos++; 296 state->token = TOKEN_GREATER_THAN_OR_EQUAL; 269 297 } 270 298 } else if (ch == '=') { … … 275 303 state->buffer_pos++; 276 304 } 305 } else if (ch == '/') { 306 state->token = ch; 307 state->buffer_pos++; 308 if (state->buffer[state->buffer_pos] == '/') { 309 state->token = TOKEN_INTEGER_DIVIDE; 310 state->buffer_pos++; 311 } 312 } else if (ch == '!') { 313 state->token = ch; 314 state->buffer_pos++; 315 if (state->buffer[state->buffer_pos] == '=') { 316 state->token = TOKEN_NOT_EQUAL; 317 state->buffer_pos++; 318 } 319 } else if (ch == '&') { 320 state->token = ch; 321 state->buffer_pos++; 322 if (state->buffer[state->buffer_pos] == '&') { 323 state->token = TOKEN_AND; 324 state->buffer_pos++; 325 } 326 } else if (ch == '|') { 327 state->token = ch; 328 state->buffer_pos++; 329 if (state->buffer[state->buffer_pos] == '|') { 330 state->token = TOKEN_OR; 331 state->buffer_pos++; 332 } 333 } else if (ch == '+') { 334 state->token = ch; 335 state->buffer_pos++; 336 if (state->buffer[state->buffer_pos] == '+') { 337 state->token = TOKEN_CONCAT; 338 state->buffer_pos++; 339 } 277 340 } else { 278 341 state->token = ch; … … 380 443 /***************** Expressions *****************/ 381 444 445 /** @cond internal */ 382 446 typedef enum { 383 447 PRECEDENCE_NONE, 448 PRECEDENCE_AND, 384 449 PRECEDENCE_EQUALS, 450 PRECEDENCE_COMPARE, 385 451 PRECEDENCE_ADD, 386 452 PRECEDENCE_MULTIPLY, 387 453 } precedence_t; 454 /** @endcond */ 388 455 389 456 static bithenge_binary_op_t token_as_binary_operator(token_type_t token) … … 396 463 case '*': 397 464 return BITHENGE_EXPRESSION_MULTIPLY; 465 case TOKEN_INTEGER_DIVIDE: 466 return BITHENGE_EXPRESSION_INTEGER_DIVIDE; 467 case '%': 468 return BITHENGE_EXPRESSION_MODULO; 469 case '<': 470 return BITHENGE_EXPRESSION_LESS_THAN; 471 case TOKEN_LESS_THAN_OR_EQUAL: 472 return BITHENGE_EXPRESSION_LESS_THAN_OR_EQUAL; 473 case '>': 474 return BITHENGE_EXPRESSION_GREATER_THAN; 475 case TOKEN_GREATER_THAN_OR_EQUAL: 476 return BITHENGE_EXPRESSION_GREATER_THAN_OR_EQUAL; 398 477 case TOKEN_EQUALS: 399 478 return BITHENGE_EXPRESSION_EQUALS; 479 case TOKEN_NOT_EQUAL: 480 return BITHENGE_EXPRESSION_NOT_EQUALS; 481 case TOKEN_AND: 482 return BITHENGE_EXPRESSION_AND; 483 case TOKEN_OR: 484 return BITHENGE_EXPRESSION_OR; 485 case TOKEN_CONCAT: 486 return BITHENGE_EXPRESSION_CONCAT; 400 487 default: 401 488 return BITHENGE_EXPRESSION_INVALID_BINARY_OP; … … 407 494 switch (op) { 408 495 case BITHENGE_EXPRESSION_ADD: /* fallthrough */ 409 case BITHENGE_EXPRESSION_SUBTRACT: 496 case BITHENGE_EXPRESSION_SUBTRACT: /* fallthrough */ 497 case BITHENGE_EXPRESSION_CONCAT: 410 498 return PRECEDENCE_ADD; 411 case BITHENGE_EXPRESSION_MULTIPLY: 499 case BITHENGE_EXPRESSION_MULTIPLY: /* fallthrough */ 500 case BITHENGE_EXPRESSION_INTEGER_DIVIDE: /* fallthrough */ 501 case BITHENGE_EXPRESSION_MODULO: 412 502 return PRECEDENCE_MULTIPLY; 413 case BITHENGE_EXPRESSION_EQUALS: 503 case BITHENGE_EXPRESSION_LESS_THAN: /* fallthrough */ 504 case BITHENGE_EXPRESSION_LESS_THAN_OR_EQUAL: /* fallthrough */ 505 case BITHENGE_EXPRESSION_GREATER_THAN: /* fallthrough */ 506 case BITHENGE_EXPRESSION_GREATER_THAN_OR_EQUAL: 507 return PRECEDENCE_COMPARE; 508 case BITHENGE_EXPRESSION_EQUALS: /* fallthrough */ 509 case BITHENGE_EXPRESSION_NOT_EQUALS: 414 510 return PRECEDENCE_EQUALS; 511 case BITHENGE_EXPRESSION_AND: /* fallthrough */ 512 case BITHENGE_EXPRESSION_OR: 513 return PRECEDENCE_AND; 415 514 default: 416 515 assert(false); … … 480 579 } 481 580 581 next_token(state); 582 482 583 bithenge_expression_t *expr; 483 584 rc = bithenge_param_expression(&expr, i); … … 486 587 return NULL; 487 588 } 488 489 next_token(state);490 491 589 return expr; 492 590 } else if (state->token == '.') { … … 530 628 } 531 629 630 static bithenge_expression_t *parse_postfix_expression(state_t *state) 631 { 632 int rc; 633 bithenge_expression_t *expr = parse_term(state); 634 while (state->error == EOK) { 635 if (state->token == '.') { 636 next_token(state); 637 638 const char *id = expect_identifier(state); 639 640 if (state->error != EOK) { 641 free((char *)id); 642 bithenge_expression_dec_ref(expr); 643 return NULL; 644 } 645 646 bithenge_node_t *key = NULL; 647 rc = bithenge_new_string_node(&key, id, true); 648 if (rc != EOK) { 649 error_errno(state, rc); 650 bithenge_expression_dec_ref(expr); 651 return NULL; 652 } 653 654 bithenge_expression_t *key_expr; 655 rc = bithenge_const_expression(&key_expr, key); 656 if (rc != EOK) { 657 error_errno(state, rc); 658 bithenge_expression_dec_ref(expr); 659 return NULL; 660 } 661 662 rc = bithenge_binary_expression(&expr, 663 BITHENGE_EXPRESSION_MEMBER, expr, key_expr); 664 if (rc != EOK) { 665 error_errno(state, rc); 666 return NULL; 667 } 668 } else if (state->token == '[') { 669 next_token(state); 670 bithenge_expression_t *start = parse_expression(state); 671 bool absolute_limit = false; 672 if (state->token == ',' || state->token == ':') { 673 absolute_limit = state->token == ':'; 674 next_token(state); 675 bithenge_expression_t *limit = NULL; 676 if (!(state->token == ']' && absolute_limit)) 677 limit = parse_expression(state); 678 expect(state, ']'); 679 680 if (state->error != EOK) { 681 bithenge_expression_dec_ref(expr); 682 bithenge_expression_dec_ref(start); 683 bithenge_expression_dec_ref(limit); 684 return NULL; 685 } 686 rc = bithenge_subblob_expression(&expr, expr, start, 687 limit, absolute_limit); 688 if (rc != EOK) { 689 error_errno(state, rc); 690 return NULL; 691 } 692 } else if (state->token == ']') { 693 next_token(state); 694 695 if (state->error != EOK) { 696 bithenge_expression_dec_ref(expr); 697 bithenge_expression_dec_ref(start); 698 return NULL; 699 } 700 rc = bithenge_binary_expression(&expr, 701 BITHENGE_EXPRESSION_MEMBER, expr, start); 702 if (rc != EOK) { 703 error_errno(state, rc); 704 return NULL; 705 } 706 } else { 707 syntax_error(state, "expected ',', ':', or ']'"); 708 bithenge_expression_dec_ref(expr); 709 bithenge_expression_dec_ref(start); 710 return NULL; 711 } 712 } else { 713 break; 714 } 715 } 716 return expr; 717 } 718 532 719 static bithenge_expression_t *parse_expression_precedence(state_t *state, 533 720 precedence_t prev_precedence) 534 721 { 535 bithenge_expression_t *expr = parse_ term(state);722 bithenge_expression_t *expr = parse_postfix_expression(state); 536 723 while (state->error == EOK) { 537 724 bithenge_binary_op_t op = … … 544 731 next_token(state); 545 732 546 bithenge_expression_t *expr2 = parse_term(state); 733 bithenge_expression_t *expr2 = 734 parse_expression_precedence(state, precedence); 547 735 if (state->error != EOK) { 548 736 bithenge_expression_dec_ref(expr2); … … 550 738 } 551 739 int rc = bithenge_binary_expression(&expr, op, expr, expr2); 552 if (rc != EOK) 553 error_errno(state, rc); 740 if (rc != EOK) { 741 expr = NULL; 742 error_errno(state, rc); 743 } 554 744 } 555 745 if (state->error != EOK) { … … 759 949 int rc = bithenge_if_transform(&switch_xform, exprs[num], 760 950 xforms[num], switch_xform); 761 if (rc != EOK) 762 error_errno(state, rc); 951 if (rc != EOK) { 952 switch_xform = NULL; 953 error_errno(state, rc); 954 } 763 955 } 764 956 … … 827 1019 } 828 1020 return do_while_xform; 1021 } 1022 1023 static bithenge_transform_t *parse_partial(state_t *state) 1024 { 1025 expect(state, TOKEN_PARTIAL); 1026 bithenge_transform_t *offset_xform = NULL; 1027 if (state->token == '(') { 1028 next_token(state); 1029 bithenge_expression_t *offset = parse_expression(state); 1030 expect(state, ')'); 1031 1032 bithenge_expression_t *in_expr; 1033 int rc = bithenge_in_node_expression(&in_expr); 1034 if (rc != EOK) 1035 error_errno(state, rc); 1036 if (state->error != EOK) { 1037 bithenge_expression_dec_ref(offset); 1038 return NULL; 1039 } 1040 1041 rc = bithenge_subblob_expression(&offset, in_expr, offset, 1042 NULL, true); 1043 if (rc != EOK) { 1044 error_errno(state, rc); 1045 return NULL; 1046 } 1047 1048 rc = bithenge_expression_transform(&offset_xform, offset); 1049 if (rc != EOK) { 1050 error_errno(state, rc); 1051 return NULL; 1052 } 1053 } 1054 expect(state, '{'); 1055 bithenge_transform_t *xform = parse_transform(state); 1056 expect(state, '}'); 1057 if (state->error != EOK) { 1058 bithenge_transform_dec_ref(offset_xform); 1059 bithenge_transform_dec_ref(xform); 1060 return NULL; 1061 } 1062 1063 int rc = bithenge_partial_transform(&xform, xform); 1064 if (rc != EOK) { 1065 error_errno(state, rc); 1066 bithenge_transform_dec_ref(offset_xform); 1067 return NULL; 1068 } 1069 1070 if (offset_xform) { 1071 bithenge_transform_t **xforms = malloc(2 * sizeof(*xforms)); 1072 if (!xforms) { 1073 error_errno(state, ENOMEM); 1074 bithenge_transform_dec_ref(xform); 1075 bithenge_transform_dec_ref(offset_xform); 1076 return NULL; 1077 } 1078 xforms[0] = xform; 1079 xforms[1] = offset_xform; 1080 rc = bithenge_new_composed_transform(&xform, xforms, 2); 1081 if (rc != EOK) { 1082 error_errno(state, rc); 1083 return NULL; 1084 } 1085 } 1086 1087 return xform; 829 1088 } 830 1089 … … 910 1169 } else if (state->token == TOKEN_IF) { 911 1170 return parse_if(state, false); 1171 } else if (state->token == TOKEN_PARTIAL) { 1172 return parse_partial(state); 912 1173 } else if (state->token == TOKEN_REPEAT) { 913 1174 return parse_repeat(state); … … 939 1200 if (state->error != EOK) 940 1201 break; 941 xforms[num] = parse_transform_no_compose(state); 942 num++; 1202 xforms[num++] = parse_transform_no_compose(state); 943 1203 } 944 1204 if (state->error != EOK) { 945 while (xforms && num --)946 bithenge_transform_dec_ref(xforms[ num]);1205 while (xforms && num > 1) 1206 bithenge_transform_dec_ref(xforms[--num]); 947 1207 free(xforms); 948 1208 bithenge_transform_dec_ref(result); … … 982 1242 } 983 1243 1244 bithenge_transform_t *barrier = NULL; 1245 if (state->error == EOK) { 1246 int rc = bithenge_new_barrier_transform(&barrier, 1247 state->num_params); 1248 if (rc != EOK) { 1249 barrier = NULL; 1250 error_errno(state, rc); 1251 } 1252 } 1253 1254 add_named_transform(state, barrier, name); 1255 984 1256 expect(state, '='); 985 1257 bithenge_transform_t *xform = parse_transform(state); … … 987 1259 988 1260 if (state->error == EOK) { 989 int rc = bithenge_ new_barrier_transform(&xform, xform,990 state->num_params);991 if (rc != EOK) {992 xform = NULL;993 error_errno(state, rc); 994 995 } 996 997 add_named_transform(state, xform, name);1261 int rc = bithenge_barrier_transform_set_subtransform(barrier, 1262 xform); 1263 xform = NULL; 1264 if (rc != EOK) 1265 error_errno(state, rc); 1266 } 1267 1268 if (state->error != EOK) 1269 bithenge_transform_dec_ref(xform); 998 1270 999 1271 for (int i = 0; i < state->num_params; i++)
Note:
See TracChangeset
for help on using the changeset viewer.