Changeset 94d484a in mainline for uspace/app/sbi/src/run_expr.c
- Timestamp:
- 2010-03-07T17:45:33Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d0febca
- Parents:
- fa36f29
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/sbi/src/run_expr.c
rfa36f29 r94d484a 36 36 #include "list.h" 37 37 #include "mytypes.h" 38 #include "os/os.h" 38 39 #include "rdata.h" 39 40 #include "run.h" 41 #include "run_texpr.h" 40 42 #include "symbol.h" 41 43 #include "strtab.h" … … 61 63 static void run_binop_int(run_t *run, stree_binop_t *binop, rdata_value_t *v1, 62 64 rdata_value_t *v2, rdata_item_t **res); 65 static void run_binop_string(run_t *run, stree_binop_t *binop, rdata_value_t *v1, 66 rdata_value_t *v2, rdata_item_t **res); 63 67 static void run_binop_ref(run_t *run, stree_binop_t *binop, rdata_value_t *v1, 64 68 rdata_value_t *v2, rdata_item_t **res); … … 66 70 static void run_unop(run_t *run, stree_unop_t *unop, rdata_item_t **res); 67 71 static void run_new(run_t *run, stree_new_t *new_op, rdata_item_t **res); 72 static void run_new_array(run_t *run, stree_new_t *new_op, 73 rdata_titem_t *titem, rdata_item_t **res); 74 static void run_new_object(run_t *run, stree_new_t *new_op, 75 rdata_titem_t *titem, rdata_item_t **res); 68 76 69 77 static void run_access(run_t *run, stree_access_t *access, rdata_item_t **res); … … 78 86 79 87 static void run_call(run_t *run, stree_call_t *call, rdata_item_t **res); 88 static void run_index(run_t *run, stree_index_t *index, rdata_item_t **res); 80 89 static void run_assign(run_t *run, stree_assign_t *assign, rdata_item_t **res); 81 90 … … 111 120 case ec_call: 112 121 run_call(run, expr->u.call, res); 122 break; 123 case ec_index: 124 run_index(run, expr->u.index, res); 113 125 break; 114 126 case ec_assign: … … 442 454 run_binop_int(run, binop, v1, v2, res); 443 455 break; 456 case vc_string: 457 run_binop_string(run, binop, v1, v2, res); 458 break; 444 459 case vc_ref: 445 460 run_binop_ref(run, binop, v1, v2, res); … … 508 523 } 509 524 525 /** Evaluate binary operation on string arguments. */ 526 static void run_binop_string(run_t *run, stree_binop_t *binop, rdata_value_t *v1, 527 rdata_value_t *v2, rdata_item_t **res) 528 { 529 rdata_item_t *item; 530 rdata_value_t *value; 531 rdata_var_t *var; 532 rdata_string_t *string_v; 533 534 char *s1, *s2; 535 536 (void) run; 537 538 item = rdata_item_new(ic_value); 539 value = rdata_value_new(); 540 var = rdata_var_new(vc_string); 541 string_v = rdata_string_new(); 542 543 item->u.value = value; 544 value->var = var; 545 var->u.string_v = string_v; 546 547 s1 = v1->var->u.string_v->value; 548 s2 = v2->var->u.string_v->value; 549 550 switch (binop->bc) { 551 case bo_plus: 552 /* Concatenate strings. */ 553 string_v->value = os_str_acat(s1, s2); 554 break; 555 default: 556 printf("Error: Invalid binary operation on string " 557 "arguments (%d).\n", binop->bc); 558 assert(b_false); 559 } 560 561 *res = item; 562 } 563 510 564 /** Evaluate binary operation on ref arguments. */ 511 565 static void run_binop_ref(run_t *run, stree_binop_t *binop, rdata_value_t *v1, … … 566 620 static void run_new(run_t *run, stree_new_t *new_op, rdata_item_t **res) 567 621 { 622 rdata_titem_t *titem; 623 624 #ifdef DEBUG_RUN_TRACE 625 printf("Run 'new' operation.\n"); 626 #endif 627 /* Evaluate type expression */ 628 run_texpr(run, new_op->texpr, &titem); 629 630 switch (titem->tic) { 631 case tic_tarray: 632 run_new_array(run, new_op, titem, res); 633 break; 634 case tic_tcsi: 635 run_new_object(run, new_op, titem, res); 636 break; 637 default: 638 printf("Error: Invalid argument to operator 'new', " 639 "expected object.\n"); 640 exit(1); 641 } 642 } 643 644 /** Create new array. */ 645 static void run_new_array(run_t *run, stree_new_t *new_op, 646 rdata_titem_t *titem, rdata_item_t **res) 647 { 648 rdata_tarray_t *tarray; 649 rdata_array_t *array; 650 rdata_var_t *array_var; 651 rdata_var_t *elem_var; 652 653 rdata_item_t *rexpr, *rexpr_vi; 654 rdata_var_t *rexpr_var; 655 656 stree_expr_t *expr; 657 658 list_node_t *node; 659 int length; 660 int i; 661 662 #ifdef DEBUG_RUN_TRACE 663 printf("Create new array.\n"); 664 #endif 665 (void) run; 666 (void) new_op; 667 668 assert(titem->tic == tic_tarray); 669 tarray = titem->u.tarray; 670 671 /* Create the array. */ 672 assert(titem->u.tarray->rank > 0); 673 array = rdata_array_new(titem->u.tarray->rank); 674 675 /* Compute extents. */ 676 node = list_first(&tarray->extents); 677 if (node == NULL) { 678 printf("Error: Extents must be specified when constructing " 679 "an array with 'new'.\n"); 680 exit(1); 681 } 682 683 i = 0; length = 1; 684 while (node != NULL) { 685 expr = list_node_data(node, stree_expr_t *); 686 687 /* Evaluate extent argument. */ 688 run_expr(run, expr, &rexpr); 689 rdata_cvt_value_item(rexpr, &rexpr_vi); 690 assert(rexpr_vi->ic == ic_value); 691 rexpr_var = rexpr_vi->u.value->var; 692 693 if (rexpr_var->vc != vc_int) { 694 printf("Error: Array extent must be an integer.\n"); 695 exit(1); 696 } 697 698 #ifdef DEBUG_RUN_TRACE 699 printf("Array extent: %d.\n", rexpr_var->u.int_v->value); 700 #endif 701 array->extent[i] = rexpr_var->u.int_v->value; 702 length = length * array->extent[i]; 703 704 node = list_next(&tarray->extents, node); 705 i += 1; 706 } 707 708 array->element = calloc(length, sizeof(rdata_var_t *)); 709 if (array->element == NULL) { 710 printf("Memory allocation failed.\n"); 711 exit(1); 712 } 713 714 /* Create member variables */ 715 for (i = 0; i < length; ++i) { 716 /* XXX Depends on member variable type. */ 717 elem_var = rdata_var_new(vc_int); 718 elem_var->u.int_v = rdata_int_new(); 719 elem_var->u.int_v->value = 0; 720 721 array->element[i] = elem_var; 722 } 723 724 /* Create array variable. */ 725 array_var = rdata_var_new(vc_array); 726 array_var->u.array_v = array; 727 728 /* Create reference to the new array. */ 729 rdata_reference(array_var, res); 730 } 731 732 /** Create new object. */ 733 static void run_new_object(run_t *run, stree_new_t *new_op, 734 rdata_titem_t *titem, rdata_item_t **res) 735 { 568 736 rdata_object_t *obj; 569 737 rdata_var_t *obj_var; … … 578 746 579 747 #ifdef DEBUG_RUN_TRACE 580 printf("Run 'new' operation.\n"); 581 #endif 748 printf("Create new object.\n"); 749 #endif 750 (void) run; 751 (void) new_op; 752 582 753 /* Lookup object CSI. */ 583 /* XXX Should start in the current CSI. */ 584 csi_sym = symbol_xlookup_in_csi(run->program, NULL, new_op->texpr); 585 csi = symbol_to_csi(csi_sym); 586 if (csi == NULL) { 587 printf("Error: Symbol '"); 588 symbol_print_fqn(run->program, csi_sym); 589 printf("' is not a CSI. CSI required for 'new' operator.\n"); 590 exit(1); 591 } 754 assert(titem->tic == tic_tcsi); 755 csi = titem->u.tcsi->csi; 756 csi_sym = csi_to_symbol(csi); 592 757 593 758 /* Create the object. */ … … 875 1040 } 876 1041 1042 /** Run index operation. */ 1043 static void run_index(run_t *run, stree_index_t *index, rdata_item_t **res) 1044 { 1045 rdata_item_t *rbase; 1046 rdata_item_t *base_i; 1047 list_node_t *node; 1048 stree_expr_t *arg; 1049 rdata_item_t *rarg_i, *rarg_vi; 1050 rdata_array_t *array; 1051 var_class_t vc; 1052 1053 int i; 1054 int elem_index; 1055 int arg_val; 1056 1057 rdata_item_t *ritem; 1058 rdata_address_t *address; 1059 1060 #ifdef DEBUG_RUN_TRACE 1061 printf("Run index operation.\n"); 1062 #endif 1063 run_expr(run, index->base, &rbase); 1064 1065 switch (rbase->ic) { 1066 case ic_value: 1067 vc = rbase->u.value->var->vc; 1068 break; 1069 case ic_address: 1070 vc = rbase->u.address->vref->vc; 1071 break; 1072 default: 1073 /* Silence warning. */ 1074 abort(); 1075 } 1076 1077 if (vc != vc_ref) { 1078 printf("Error: Base of index operation is not a reference.\n"); 1079 exit(1); 1080 } 1081 1082 rdata_dereference(rbase, &base_i); 1083 assert(base_i->ic == ic_address); 1084 1085 if (base_i->u.value->var->vc != vc_array) { 1086 printf("Error: Indexing something which is not an array.\n"); 1087 exit(1); 1088 } 1089 1090 array = base_i->u.value->var->u.array_v; 1091 1092 /* Evaluate arguments (indices). */ 1093 node = list_first(&index->args); 1094 1095 /* 1096 * Linear index of the desired element. Elements are stored in 1097 * lexicographic order with the last index changing the fastest. 1098 */ 1099 elem_index = 0; 1100 1101 i = 0; 1102 while (node != NULL) { 1103 if (i >= array->rank) { 1104 printf("Error: Too many indices for array of rank %d", 1105 array->rank); 1106 exit(1); 1107 } 1108 1109 arg = list_node_data(node, stree_expr_t *); 1110 run_expr(run, arg, &rarg_i); 1111 rdata_cvt_value_item(rarg_i, &rarg_vi); 1112 assert(rarg_vi->ic == ic_value); 1113 1114 if (rarg_vi->u.value->var->vc != vc_int) { 1115 printf("Error: Array index is not an integer.\n"); 1116 exit(1); 1117 } 1118 1119 arg_val = rarg_vi->u.value->var->u.int_v->value; 1120 1121 if (arg_val < 0 || arg_val >= array->extent[i]) { 1122 printf("Error: Array index (value: %d) is out of range.\n", 1123 arg_val); 1124 exit(1); 1125 } 1126 1127 elem_index = elem_index * array->extent[i] + arg_val; 1128 1129 node = list_next(&index->args, node); 1130 i += 1; 1131 } 1132 1133 if (i < array->rank) { 1134 printf("Error: Too few indices for array of rank %d", 1135 array->rank); 1136 exit(1); 1137 } 1138 1139 /* Construct variable address item. */ 1140 ritem = rdata_item_new(ic_address); 1141 address = rdata_address_new(); 1142 ritem->u.address = address; 1143 1144 address->vref = array->element[elem_index]; 1145 1146 *res = ritem; 1147 } 1148 877 1149 /** Execute assignment. */ 878 1150 static void run_assign(run_t *run, stree_assign_t *assign, rdata_item_t **res)
Note:
See TracChangeset
for help on using the changeset viewer.