cint_operators.c (44660B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: cint_operators.c 8 * Purpose: CINT operator functions 9 */ 10 11 #include "cint_operators.h" 12 #include "cint_porting.h" 13 #include "cint_variables.h" 14 #include "cint_eval_asts.h" 15 #include "cint_internal.h" 16 #include "cint_debug.h" 17 #include "cint_error.h" 18 #include "cint_datatypes.h" 19 20 21 22 /******************************************************************************* 23 * 24 * These macros are used to implement most of the arithmetic and logical 25 * operators 26 */ 27 28 /* Perform a binary operation based on the given operand type */ 29 #define _CINT_BINARY_RESULT(_op,_type) ( (cint_##_type##_value(left)) _op (cint_##_type##_value(right))) 30 /* Perform a binary operation based on the given operand type and create an autovar for the result */ 31 #define _CINT_BINARY_CREATE(_op,_type) ( (cint_auto_##_type(_CINT_BINARY_RESULT(_op,_type))) ) 32 33 /* Perform a unary operation based on the given operand type */ 34 #define _CINT_UNARY_RESULT(_op,_type) ( (_op cint_##_type##_value(right)) ) 35 /* Perform a unary operation based on the given operand type and create an autovar for the result */ 36 #define _CINT_UNARY_CREATE(_op,_type) ( cint_auto_##_type(_CINT_UNARY_RESULT(_op,_type)) ) 37 38 /* Perform a complete unary/binary arithmetical assign/create operation */ 39 #define _CINT_ARITH_OPERATION(_op,_ub,_ac) \ 40 switch(optype) { \ 41 case cintOperandInt: return _CINT##_ub##_ac(_op, integer); \ 42 case cintOperandUInt: return _CINT##_ub##_ac(_op, uinteger); \ 43 case cintOperandLong: return _CINT##_ub##_ac(_op, long); \ 44 case cintOperandULong: return _CINT##_ub##_ac(_op, ulong); \ 45 case cintOperandLongLong: return _CINT##_ub##_ac(_op, longlong); \ 46 case cintOperandULongLong: return _CINT##_ub##_ac(_op, ulonglong); \ 47 case cintOperandDouble: return _CINT##_ub##_ac(_op, double); \ 48 case cintOperandPointer: return _CINT##_ub##_ac(_op, logical); \ 49 default: cint_internal_error(__FILE__, __LINE__, "_CINT_ARITH_OPERATION: unexpected operand type 0x%x", optype); return NULL; } \ 50 51 /* Perform a complete unary/binary arithmetical assign/create operation */ 52 #define _CINT_INTEGRAL_OPERATION(_op,_ub,_ac) \ 53 switch(optype) { \ 54 case cintOperandInt: return _CINT##_ub##_ac(_op, integer); \ 55 case cintOperandUInt: return _CINT##_ub##_ac(_op, uinteger); \ 56 case cintOperandULong: return _CINT##_ub##_ac(_op, ulong); \ 57 case cintOperandLongLong: return _CINT##_ub##_ac(_op, longlong); \ 58 case cintOperandULongLong: return _CINT##_ub##_ac(_op, ulonglong); \ 59 default: cint_internal_error(__FILE__, __LINE__, "_CINT_INTEGRAL_OPERATION: unexpected operand type 0x%x", optype); return NULL; } \ 60 61 62 63 /* Perform arithmetical and integral operations */ 64 #define CINT_BINARY_RESULT(_op) _CINT_ARITH_OPERATION(_op,_BINARY,_RESULT) 65 #define CINT_BINARY_CREATE(_op) _CINT_ARITH_OPERATION(_op,_BINARY,_CREATE) 66 #define CINT_UNARY_RESULT(_op) _CINT_ARITH_OPERATION(_op,_UNARY,_RESULT) 67 #define CINT_UNARY_CREATE(_op) _CINT_ARITH_OPERATION(_op,_UNARY,_CREATE) 68 69 /* Perform integral-only operations */ 70 #define CINT_IBINARY_RESULT(_op) _CINT_INTEGRAL_OPERATION(_op,_BINARY,_RESULT) 71 #define CINT_IBINARY_CREATE(_op) _CINT_INTEGRAL_OPERATION(_op,_BINARY,_CREATE) 72 #define CINT_IUNARY_RESULT(_op) _CINT_INTEGRAL_OPERATION(_op,_UNARY,_RESULT) 73 #define CINT_IUNARY_CREATE(_op) _CINT_INTEGRAL_OPERATION(_op,_UNARY,_CREATE) 74 75 /* Pointer Comparison Operations */ 76 #define CINT_PCBINARY_CREATE(_op) if(optype == cintOperandPointer) return cint_auto_integer(cint_pointer_value(left) _op cint_pointer_value(right)) 77 #define CINT_PCUNARY_CREATE(_op) if(optype == cintOperandPointer) return _op cint_pointer_value(right) 78 #define CINT_PBINARY_CREATE(_op) CINT_PCBINARY_CREATE(_op); CINT_BINARY_CREATE(_op) 79 #define CINT_PUNARY_CREATE(_op) CINT_PCUNARY_CREATE(_op); CINT_UNARY_CREATE(_op) 80 81 /* 82 * Check the actual operand value to be zero based on the given operand type 83 */ 84 static int 85 __cint_operator_operand_is_zero(cint_variable_t* operand, cint_operand_type_t optype) 86 { 87 if (operand != NULL) { 88 switch(optype) { 89 case cintOperandInt: return (0 == cint_integer_value(operand)); 90 case cintOperandUInt: return (0 == cint_uinteger_value(operand)); 91 case cintOperandLong: return (0 == cint_long_value(operand)); 92 case cintOperandULong: return (0 == cint_ulong_value(operand)); 93 case cintOperandLongLong: return (0 == cint_longlong_value(operand)); 94 case cintOperandULongLong: return (0 == cint_ulonglong_value(operand)); 95 case cintOperandDouble: return ((CINT_DOUBLE)0.0 == cint_double_value(operand)); 96 case cintOperandPointer: return (NULL == cint_pointer_value(operand)); 97 default: cint_internal_error(__FILE__, __LINE__, "__cint_operand_value_is_zero: unexpected operand type 0x%x", optype); return 1; 98 } 99 } 100 return(1); 101 } 102 103 /* 104 * Calculate the size of the datatype to which a variable points 105 */ 106 static int 107 __cint_pointer_datatype_size(cint_variable_t* v) 108 { 109 cint_datatype_t dt; 110 dt = v->dt; 111 dt.desc.pcount--; 112 return cint_datatype_size(&dt); 113 } 114 115 116 /* 117 * Add a constant value to a pointer variable and return a 118 * new variable with the result. 119 */ 120 static cint_variable_t* 121 __cint_pointer_add_constant(cint_variable_t* v, int count) 122 { 123 char* cp; 124 cint_variable_t* rv; 125 char* fptr = NULL; 126 127 /* Clone the variable */ 128 rv = cint_variable_clone(v); 129 130 /* cp gets the pointer value */ 131 cp = (char*) *(void**)rv->data; 132 fptr = cp; 133 cp += __cint_pointer_datatype_size(v) * count; 134 if(rv->flags & CINT_VARIABLE_F_CSTRING) { 135 /* 136 * if incremented ptr is 'char*' 137 * 1. re-assing new pointer based on incremented address. 138 * 2. free original ptr 139 */ 140 *(void**)rv->data = (void*) CINT_STRDUP(cp); 141 if(fptr) { 142 CINT_FREE(fptr); 143 } 144 } else { 145 *(void**)rv->data = (void*)cp; 146 } 147 return rv; 148 } 149 150 static int 151 __cint_pointer_conversion(cint_variable_t** v) 152 { 153 int dim_index; 154 cint_error_t rc = CINT_E_NONE; 155 /* 156 * Convert arrays to pointers to first element 157 */ 158 if(v && *v && (*v)->dt.desc.num_dimensions != 0) { 159 160 cint_variable_t* rv; 161 cint_parameter_desc_t desc = (*v)->dt.desc; 162 163 /* Drop the array and increase the pointer count */ 164 desc.num_dimensions = 0; 165 desc.pcount++; 166 167 /* allocate pointer */ 168 rc = cint_variable_create(&rv, NULL, &desc, CINT_VARIABLE_F_AUTO, NULL); 169 if (rc == CINT_E_NONE) { 170 /* Point to first element */ 171 *(void**)rv->data = (*v)->data; 172 173 /* Pass the original array size along for bounds checking 174 and debug */ 175 rv->cached_num_dimensions = (*v)->dt.desc.num_dimensions; 176 rv->dt.cap = (*v)->dt.cap; 177 rv->dt.type_num_dimensions = (*v)->dt.type_num_dimensions; 178 rv->dt.desc.num_dimensions = 0; 179 for(dim_index = 0; 180 dim_index < (*v)->dt.desc.num_dimensions; 181 dim_index++) { 182 rv->dt.desc.dimensions[dim_index] = 183 desc.dimensions[dim_index]; 184 } 185 186 /* Pass along AUTOCASTS */ 187 if((*v)->flags & CINT_VARIABLE_F_AUTOCAST) { 188 rv->flags |= CINT_VARIABLE_F_AUTOCAST; 189 (*v)->flags &= ~CINT_VARIABLE_F_AUTOCAST; 190 } 191 *v = rv; 192 } 193 } 194 return rc; 195 } 196 197 static void __cint_bad_operands(cint_ast_t* ast, int op); 198 199 static int 200 __cint_check_operand(cint_variable_t* v, unsigned opflags) 201 { 202 if(v) { 203 unsigned vflags = cint_atomic_flags(v); 204 205 if(v->dt.desc.pcount > 0) { 206 /* This is a pointer */ 207 return (opflags & CINT_OPERATOR_F_ACCEPT_POINTER); 208 } 209 210 if(vflags & CINT_ATOMIC_TYPE_FLAGS_INTEGRAL) { 211 /* This is an integral type */ 212 return (opflags & CINT_OPERATOR_F_ACCEPT_INTEGRAL); 213 } 214 215 if(vflags & CINT_ATOMIC_TYPE_F_DOUBLE) { 216 /* This is a double type */ 217 return (opflags & CINT_OPERATOR_F_ACCEPT_DOUBLE); 218 } 219 220 /* All other types */ 221 return (opflags & CINT_OPERATOR_F_ACCEPT_ALL); 222 } 223 return 1; 224 } 225 226 /* 227 * All operator handlers. 228 */ 229 230 static cint_variable_t* 231 __cint_operator_RightShift(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 232 { 233 CINT_IBINARY_CREATE(>>); 234 } 235 236 237 static cint_variable_t* 238 __cint_operator_LeftShift(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 239 { 240 CINT_IBINARY_CREATE(<<); 241 } 242 243 244 static cint_variable_t* 245 __cint_operator_Increment(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 246 { 247 cint_variable_t* rv = NULL; 248 249 if(left) { 250 /* Post Increment */ 251 rv = cint_variable_clone(left); 252 cint_eval_operator_internal(ast, cintOpAssign, left, 253 cint_eval_operator_internal(ast, cintOpAdd, left, cint_auto_integer(1))); 254 } 255 else if(right) { 256 /* Pre Increment */ 257 rv = right; 258 cint_eval_operator_internal(ast, cintOpAssign, right, 259 cint_eval_operator_internal(ast, cintOpAdd, right, cint_auto_integer(1))); 260 } 261 return rv; 262 } 263 264 265 static cint_variable_t* 266 __cint_operator_Decrement(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 267 { 268 cint_variable_t* rv = NULL; 269 270 if(left) { 271 /* Post Decrement */ 272 rv = cint_variable_clone(left); 273 cint_eval_operator_internal(ast, cintOpAssign, left, 274 cint_eval_operator_internal(ast, cintOpSubtract, left, cint_auto_integer(1))); 275 } 276 else if(right) { 277 /* Pre Decrement */ 278 rv = right; 279 cint_eval_operator_internal(ast, cintOpAssign, right, 280 cint_eval_operator_internal(ast, cintOpSubtract, right, cint_auto_integer(1))); 281 } 282 return rv; 283 } 284 285 286 static cint_variable_t* 287 __cint_operator_LogicalAnd(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 288 { 289 /* 290 * Left and Right are not yet evaluated. 291 */ 292 293 left = cint_eval_ast(ast->utype.operator.left); 294 if(left == NULL || (__cint_check_operand(left, CINT_OPERATOR_FLAGS_PBINARY) == 0)) { 295 __cint_bad_operands(ast, cintOpLogicalAnd); 296 return NULL; 297 } 298 299 if(cint_logical_value(left) == 0) { 300 /* Shortcut evaluation */ 301 return cint_auto_integer(0); 302 } 303 304 right = cint_eval_ast(ast->utype.operator.right); 305 if(right == NULL || (__cint_check_operand(right, CINT_OPERATOR_FLAGS_PBINARY) == 0)) { 306 __cint_bad_operands(ast, cintOpLogicalAnd); 307 return NULL; 308 } 309 310 return cint_auto_integer(cint_logical_value(right)); 311 } 312 313 314 static cint_variable_t* 315 __cint_operator_LogicalOr(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 316 { 317 /* 318 * Left and Right are not yet evaluated. 319 */ 320 321 left = cint_eval_ast(ast->utype.operator.left); 322 if(left == NULL || (__cint_check_operand(left, CINT_OPERATOR_FLAGS_PBINARY) == 0)) { 323 __cint_bad_operands(ast, cintOpLogicalOr); 324 return NULL; 325 } 326 327 if(cint_logical_value(left) == 1) { 328 /* Shortcut evaluation */ 329 return cint_auto_integer(1); 330 } 331 332 right = cint_eval_ast(ast->utype.operator.right); 333 if(right == NULL || (__cint_check_operand(right, CINT_OPERATOR_FLAGS_PBINARY) == 0)) { 334 __cint_bad_operands(ast, cintOpLogicalOr); 335 return NULL; 336 } 337 338 return cint_auto_integer(cint_logical_value(right)); 339 } 340 341 342 static cint_variable_t* 343 __cint_operator_LessThanOrEqual(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 344 { 345 CINT_PBINARY_CREATE(<=); 346 } 347 348 349 static cint_variable_t* 350 __cint_operator_GreaterThanOrEqual(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 351 { 352 CINT_PBINARY_CREATE(>=); 353 } 354 355 356 static cint_variable_t* 357 __cint_operator_Equal(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 358 { 359 CINT_PBINARY_CREATE(==); 360 } 361 362 363 static cint_variable_t* 364 __cint_operator_NotEqual(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 365 { 366 CINT_PBINARY_CREATE(!=); 367 } 368 369 370 static cint_variable_t* 371 __cint_operator_OpenBrace(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 372 { 373 cint_variable_lscope_push("}"); 374 return NULL; 375 } 376 377 378 static cint_variable_t* 379 __cint_operator_CloseBrace(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 380 { 381 cint_variable_lscope_pop("{"); 382 return NULL; 383 } 384 385 386 static cint_variable_t* 387 __cint_operator_Assign(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 388 { 389 unsigned lflags; 390 unsigned rflags; 391 cint_error_t rc; 392 char _rstr[256] = {0}; 393 394 /* 395 * Left may not be a constant 396 */ 397 if(left->flags & CINT_VARIABLE_F_CONST) { 398 cint_ast_error(ast, CINT_E_BAD_OPERANDS, "constant lvalue in assignment"); 399 return NULL; 400 } 401 /* 402 * Is right a bracket initializer? 403 */ 404 if(right == NULL) { 405 /* Left must be a structure or array */ 406 if(left->dt.desc.num_dimensions) { 407 cint_ast_t* init; 408 409 410 411 /* Foreach entry in the array */ 412 int i; 413 for(i = 0, init = ast->utype.operator.right->utype.initializer.initializers; 414 init && i < left->dt.desc.dimensions[0]; 415 i++, init = init->next) { 416 /* 417 * Build an AST for this assignment 418 */ 419 cint_ast_t* l = cint_ast_identifier(left->name); 420 cint_ast_t* r = cint_ast_integer(i); 421 cint_ast_t* m = cint_ast_operator(cintOpOpenBracket, l, r); 422 cint_ast_t* nast = cint_ast_operator(cintOpAssign, m, init); 423 cint_eval_ast(nast); 424 425 /* Free up the ASTs as initializer evaluation is complete. */ 426 cint_ast_free_single(nast); 427 cint_ast_free_single(m); 428 cint_ast_free_single(r); 429 cint_ast_free_single(l); 430 } 431 if(init) { 432 cint_ast_error(ast, CINT_E_BAD_OPERANDS, "too many initializers"); 433 return NULL; 434 } 435 return left; 436 } 437 else if(left->dt.flags & CINT_DATATYPE_F_STRUCT) { 438 cint_ast_t* init; 439 440 /* Foreach parameter in the structure */ 441 const cint_parameter_desc_t* pd; 442 for(init = ast->utype.operator.right->utype.initializer.initializers, pd = left->dt.basetype.sp->struct_members; 443 pd->name && init; 444 pd++, init = init->next) 445 { 446 /* 447 * Build an AST for this assignment 448 */ 449 cint_ast_t* l = cint_ast_identifier(left->name); 450 cint_ast_t* r = cint_ast_identifier(pd->name); 451 cint_ast_t* m = cint_ast_operator(cintOpDot, l, r); 452 cint_ast_t* nast = cint_ast_operator(cintOpAssign, m, init); 453 cint_eval_ast(nast); 454 455 /* Free up the ASTs as initializer evaluation is complete. */ 456 cint_ast_free_single(nast); 457 cint_ast_free_single(m); 458 cint_ast_free_single(r); 459 cint_ast_free_single(l); 460 } 461 462 if(init) { 463 cint_ast_error(ast, CINT_E_BAD_OPERANDS, "too many initializers"); 464 return NULL; 465 } 466 } 467 else { 468 cint_ast_error(ast, CINT_E_BAD_OPERANDS, "bad initializer"); 469 return NULL; 470 } 471 return left; 472 } 473 474 475 lflags = cint_atomic_flags(left); 476 rflags = cint_atomic_flags(right); 477 478 if(lflags && rflags) { 479 480 /* Atomic types accept conversion/truncation */ 481 switch(lflags & CINT_ATOMIC_TYPE_FLAGS_MASK) 482 { 483 case CINT_ATOMIC_TYPE_F_CHAR: 484 if (lflags & CINT_ATOMIC_TYPE_F_SIGNED) { 485 cint_char_set(left, cint_char_value(right)); return left; 486 } else { 487 cint_char_set(left, cint_uchar_value(right)); return left; 488 } 489 case CINT_ATOMIC_TYPE_F_SHORT: cint_short_set(left, cint_short_value(right)); return left; 490 case CINT_ATOMIC_TYPE_F_INT: cint_integer_set(left, cint_integer_value(right)); return left; 491 case CINT_ATOMIC_TYPE_F_LONG: cint_long_set(left, cint_long_value(right)); return left; 492 case CINT_ATOMIC_TYPE_F_LONGLONG: cint_longlong_set(left, cint_longlong_value(right)); return left; 493 case CINT_ATOMIC_TYPE_F_DOUBLE: cint_double_set(left, cint_double_value(right)); return left; 494 default: cint_internal_error(__FILE__, __LINE__, "unexpected atomic type flags 0x%x", (unsigned int)lflags); return NULL; 495 } 496 } 497 498 /* Pointer conversion for right hand side is allowed */ 499 if(cint_type_check(&left->dt, &right->dt) == 0) { 500 __cint_pointer_conversion(&right); 501 } 502 503 if(right == NULL) { 504 cint_internal_error(__FILE__, __LINE__, "unexpected error"); 505 return NULL; 506 } 507 508 if( (left->dt.desc.pcount == 0) && 509 ( (left->dt.flags & CINT_DATATYPE_F_ATOMIC) || left->dt.cap) && 510 (((ast->utype.operator.right) && 511 (ast->utype.operator.right->ntype == cintAstString)) || 512 (right->flags & CINT_VARIABLE_F_CSTRING))) { 513 /* 514 * This is a string assignment to a custom/atomic type. Pass the string to the type's 515 * assignment handler. 516 */ 517 518 if(left->dt.cap && left->dt.cap->assign) { 519 if((rc = left->dt.cap->assign(left->data, *(char**)right->data)) != CINT_E_NONE) { 520 cint_ast_error(ast, rc, "datatype '%s' assignment error", left->dt.cap->name); 521 return NULL; 522 } 523 } else if(left->dt.basetype.ap->assign) { 524 cint_error_t rc = left->dt.basetype.ap->assign(left->data, *(char**)right->data); 525 if(rc != CINT_E_NONE) { 526 cint_ast_error(ast, rc, "datatype '%s' assignment error", cint_datatype_format(&left->dt,_rstr,0)); 527 return NULL; 528 } 529 } 530 else { 531 cint_ast_error(ast, CINT_E_UNSUPPORTED, "datatype '%s' from '%s' has no assignment function.", 532 cint_datatype_format(&left->dt, _rstr, 0), left->dt.type); 533 return NULL; 534 } 535 536 return left; 537 } 538 539 /* 540 * Function Pointer Assignments 541 */ 542 if( (left->dt.flags & CINT_DATATYPE_F_FUNC_POINTER) ) { 543 544 if(right->dt.flags & CINT_DATATYPE_F_FUNC) { 545 /* function pointer = compiled function reference */ 546 CINT_MEMCPY(left->data, right->data, left->size); 547 } 548 else if(right->dt.flags & CINT_DATATYPE_F_FUNC_DYNAMIC) { 549 /* 550 * function pointer = dynamic function reference. 551 * 552 * This can only be supported if there is a matching function pointer 553 * type for the dynamic function 554 */ 555 556 /* Copy compiled callback handler type into address */ 557 CINT_MEMCPY(left->data, &left->dt.basetype.fpp->cb, sizeof(cint_fpointer_t)); 558 /* Set the data as the name of the dynamic function */ 559 left->dt.basetype.fpp->data = (void*)right->dt.basetype.fp->name; 560 } 561 return left; 562 } 563 564 /* 565 * Otherwise left and right must be of the same type with the following exceptions: 566 * void* = any pointer 567 * any pointer = void* 568 * variables with the AUTOCAST flag set. 569 */ 570 if( (cint_type_check(&left->dt, &right->dt) == 0) && /* different types */ 571 ((cint_is_vpointer(left) && cint_is_pointer(right)) == 0) && /* not void* = pointer assignement */ 572 ((cint_is_pointer(left) && cint_is_vpointer(right)) == 0) && /* not a pointer = void* assignment */ 573 ((right->flags & CINT_VARIABLE_F_AUTOCAST) == 0) ) /* right side is not an autocast */ 574 { 575 char* f1 = cint_datatype_format(&left->dt, _rstr, 1); 576 cint_ast_error(ast, CINT_E_BAD_OPERANDS, "incompatible types in assignment (%s = %s)", 577 f1, cint_datatype_format(&right->dt, _rstr, 0)); 578 CINT_FREE(f1); 579 return NULL; 580 } 581 582 if(left->size != right->size && 583 right->dt.desc.pcount == 0) { 584 /* Not allowed, even with autocasting */ 585 char* f1 = cint_datatype_format(&left->dt, _rstr, 1); 586 cint_ast_error(ast, CINT_E_BAD_OPERANDS, "incompatible sizes in assignment (%s = %s)", 587 f1, cint_datatype_format(&right->dt, _rstr, 0)); 588 CINT_FREE(f1); 589 return NULL; 590 } 591 592 cint_variable_data_copy(left, right); 593 594 /* Clear any autocast flags set for this assignment */ 595 if(CINT_VARIABLE_F_AUTOCAST) { 596 right->flags &= ~CINT_VARIABLE_F_AUTOCAST; 597 } 598 599 return left; 600 } 601 602 603 static cint_variable_t* 604 __cint_operator_OpenBracket(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 605 { 606 int index = 0; 607 608 /* 609 * Left must resolve to a pointer 610 */ 611 if(left->dt.desc.pcount == 0) { 612 cint_ast_error(ast, CINT_E_BAD_TYPE, "subscripted value is not a pointer"); 613 return NULL; 614 } 615 616 /* 617 * Left must not be void 618 */ 619 if(cint_is_vpointer(left)) { 620 cint_ast_error(ast, CINT_E_BAD_TYPE, "cannot dereference void pointer"); 621 return NULL; 622 } 623 624 /* 625 * Left must not be NULL 626 */ 627 if( (*(char**)left->data) == NULL) { 628 cint_ast_error(ast, CINT_E_BAD_VARIABLE, "subscripted value is NULL"); 629 return NULL; 630 } 631 632 /* 633 * Right must resolve to integral value 634 */ 635 if((cint_atomic_flags(right) & CINT_ATOMIC_TYPE_FLAGS_INTEGRAL) == 0) { 636 cint_ast_error(ast, CINT_E_BAD_TYPE, "array subscript is not an integral"); 637 return NULL; 638 } 639 else { 640 index = cint_integer_value(right); 641 } 642 643 /* If the original variable was a pointer-converted array, check the bounds */ 644 if(left->cached_num_dimensions) { 645 if(index < 0 || index >= left->dt.desc.dimensions[0]) { 646 cint_ast_error(ast, CINT_E_BAD_TYPE, "array subscript out of range"); 647 return NULL; 648 } 649 } 650 { 651 cint_error_t rc; 652 cint_parameter_desc_t desc; 653 cint_variable_t* rv; 654 char* p; 655 int dim_index; 656 int dataTypeSize; 657 658 desc = left->dt.desc; 659 660 if(left->cached_num_dimensions <= 1) { 661 /* dereference to base element type */ 662 desc.pcount--; 663 rc = cint_variable_create( 664 &rv, 665 NULL, 666 &desc, 667 CINT_VARIABLE_F_AUTO|CINT_VARIABLE_F_SDATA, 668 (void*)0x1); 669 dataTypeSize = rv->size; 670 } 671 else { 672 /* remove one dimension */ 673 desc.pcount = 1; 674 desc.num_dimensions = 0; 675 rc = cint_variable_create( 676 &rv, 677 NULL, 678 &desc, 679 CINT_VARIABLE_F_AUTO|CINT_VARIABLE_F_SDATA, 680 (void*)0x1); 681 682 rv->dt.desc.num_dimensions = left->cached_num_dimensions - 1; 683 for(dim_index = 0; 684 dim_index < rv->dt.desc.num_dimensions; 685 dim_index++) { 686 rv->dt.desc.dimensions[dim_index] = 687 desc.dimensions[dim_index + 1]; 688 } 689 690 rv->dt.desc.pcount = left->dt.desc.pcount - 1; 691 692 dataTypeSize = cint_datatype_size(&rv->dt); 693 } 694 695 if(rv->dt.desc.num_dimensions > 0 && 696 rv->dt.desc.dimensions[0] == 697 CINT_CONFIG_POINTER_INFINITE_DIMENSION) { 698 rv->cached_num_dimensions = rv->dt.desc.num_dimensions; 699 rv->dt.desc.num_dimensions = 0; 700 } 701 702 if(rv->cached_num_dimensions >= left->dt.type_num_dimensions || 703 rv->dt.desc.num_dimensions >= left->dt.type_num_dimensions) { 704 rv->dt.cap = left->dt.cap; 705 rv->dt.type_num_dimensions = left->dt.type_num_dimensions; 706 } 707 708 if (rc == CINT_E_NONE) { 709 /* Replace the address */ 710 p = *(char**)left->data; 711 p += (dataTypeSize * cint_integer_value(right)); 712 rv->data = p; 713 } 714 return rv; 715 } 716 return NULL; 717 } 718 719 static cint_variable_t* 720 __cint_operator_BitwiseAnd(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 721 { 722 CINT_IBINARY_CREATE(&); 723 } 724 725 726 static cint_variable_t* 727 __cint_operator_Not(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 728 { 729 CINT_UNARY_CREATE(!); 730 } 731 732 733 static cint_variable_t* 734 __cint_operator_Tilde(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 735 { 736 CINT_IUNARY_CREATE(~); 737 } 738 739 740 static cint_variable_t* 741 __cint_operator_Subtract(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 742 { 743 if(left->dt.desc.pcount) { 744 /* 745 * We can subtract constant integral values and other pointers of the same type 746 */ 747 if((cint_atomic_flags(right) & CINT_ATOMIC_TYPE_FLAGS_INTEGRAL) == 0) { 748 749 if(cint_type_check(&left->dt, &right->dt)) { 750 /* Same pointer type */ 751 char* leftp = (char*) *(void**)left->data; 752 char* rightp = (char*) *(void**)right->data; 753 754 /* Return the difference between the pointers */ 755 return cint_auto_integer( (leftp-rightp) / __cint_pointer_datatype_size(left)); 756 } 757 else { 758 cint_ast_error(ast, CINT_E_BAD_OPERANDS, "invalid pointer subtraction"); 759 return NULL; 760 } 761 } 762 else { 763 return __cint_pointer_add_constant(left, -1*cint_integer_value(right)); 764 } 765 } 766 CINT_BINARY_CREATE(-); 767 } 768 769 770 static cint_variable_t* 771 __cint_operator_Add(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 772 { 773 if(left->dt.desc.pcount) { 774 /* 775 * We can only add constant integral values to pointers 776 */ 777 if((cint_atomic_flags(right) & CINT_ATOMIC_TYPE_FLAGS_INTEGRAL) == 0) { 778 cint_ast_error(ast, CINT_E_BAD_OPERANDS, "invalid pointer addition"); 779 return NULL; 780 } 781 return __cint_pointer_add_constant(left, cint_integer_value(right)); 782 } 783 CINT_BINARY_CREATE(+); 784 } 785 786 787 static cint_variable_t* 788 __cint_operator_Multiply(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 789 { 790 CINT_BINARY_CREATE(*); 791 } 792 793 794 static cint_variable_t* 795 __cint_operator_Divide(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 796 { 797 if ((0 == cint_logical_value(right)) || (0 != __cint_operator_operand_is_zero(right, optype))) { 798 cint_ast_error(ast, CINT_E_BAD_OPERANDS, "attempt to divide by zero"); 799 return NULL; 800 } 801 802 CINT_BINARY_CREATE(/); 803 } 804 805 806 static cint_variable_t* 807 __cint_operator_Mod(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 808 { 809 if ((0 == cint_logical_value(right)) || (0 != __cint_operator_operand_is_zero(right, optype))) { 810 cint_ast_error(ast, CINT_E_BAD_OPERANDS, "attempt to divide by zero"); 811 return NULL; 812 } 813 814 CINT_IBINARY_CREATE(%); 815 } 816 817 818 static cint_variable_t* 819 __cint_operator_LessThan(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 820 { 821 CINT_PBINARY_CREATE(<); 822 } 823 824 825 static cint_variable_t* 826 __cint_operator_GreaterThan(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 827 { 828 CINT_PBINARY_CREATE(>); 829 } 830 831 832 static cint_variable_t* 833 __cint_operator_BitwiseXor(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 834 { 835 CINT_IBINARY_CREATE(^); 836 } 837 838 839 static cint_variable_t* 840 __cint_operator_BitwiseOr(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 841 { 842 CINT_IBINARY_CREATE(|); 843 } 844 845 846 static cint_variable_t* 847 __cint_operator_Question(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 848 { 849 /* 850 * Left contains the condition. 851 */ 852 if(cint_logical_value(left)) { 853 /* Right contains the true expression */ 854 return cint_eval_ast(ast->utype.operator.right); 855 } 856 else { 857 return cint_eval_ast(ast->utype.operator.extra); 858 } 859 } 860 861 862 static cint_variable_t* 863 __cint_operator_AddressOf(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 864 { 865 return cint_variable_address(right); 866 } 867 868 869 static cint_variable_t* 870 __cint_operator_Dereference(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 871 { 872 int dim_index; 873 if(right->dt.desc.pcount == 0) { 874 cint_ast_error(ast, CINT_E_BAD_OPERANDS, "cannot dereference non-pointer"); 875 return NULL; 876 } 877 else if (!CINT_STRCMP(right->dt.desc.basetype, "void")) { 878 cint_ast_error(ast, CINT_E_BAD_OPERANDS, "attempt to dereference void pointer"); 879 return NULL; 880 } 881 else { 882 cint_error_t rc; 883 cint_parameter_desc_t desc; 884 cint_variable_t* rv; 885 886 desc = right->dt.desc; 887 desc.pcount--; 888 desc.num_dimensions = right->cached_num_dimensions - 1; 889 for(dim_index = 0; 890 dim_index < desc.num_dimensions; 891 dim_index++) { 892 desc.dimensions[dim_index] = 893 desc.dimensions[dim_index + 1]; 894 } 895 896 if((*(void**)right->data) == NULL) { 897 cint_ast_error(ast, CINT_E_BAD_OPERANDS, "attempt to dereference NULL pointer"); 898 return NULL; 899 } 900 901 rc = cint_variable_create( 902 &rv, 903 NULL, 904 &desc, 905 CINT_VARIABLE_F_AUTO|CINT_VARIABLE_F_SDATA, 906 *(void**)right->data); 907 rv->dt.desc.pcount = right->dt.desc.pcount - 1; 908 rv->dt.desc.num_dimensions = right->cached_num_dimensions - 1; 909 for(dim_index = 0; 910 dim_index < rv->dt.desc.num_dimensions; 911 dim_index++) { 912 rv->dt.desc.dimensions[dim_index] = 913 right->dt.desc.dimensions[dim_index + 1]; 914 } 915 916 if(rv->dt.desc.num_dimensions > 0 && 917 rv->dt.desc.dimensions[0] == 918 CINT_CONFIG_POINTER_INFINITE_DIMENSION) { 919 rv->cached_num_dimensions = rv->dt.desc.num_dimensions; 920 rv->dt.desc.num_dimensions = 0; 921 } 922 923 rv->dt.cap = right->dt.cap; 924 rv->dt.type_num_dimensions = right->dt.type_num_dimensions; 925 return (rc == CINT_E_NONE) ? rv : NULL; 926 } 927 } 928 929 930 static cint_variable_t* 931 __cint_operator_Positive(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 932 { 933 CINT_UNARY_CREATE(+); 934 } 935 936 937 static cint_variable_t* 938 __cint_operator_Negative(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 939 { 940 CINT_UNARY_CREATE(-); 941 } 942 943 944 static cint_variable_t* 945 __cint_operator_Sizeof(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 946 { 947 return cint_auto_integer(right->size); 948 } 949 950 951 static int 952 __find_struct_member_index(const char* member, const cint_parameter_desc_t* table) 953 { 954 const cint_parameter_desc_t* sm; 955 956 for(sm = table; sm->name; sm++) { 957 if(!CINT_STRCMP(sm->name, member)) { 958 return sm-table; 959 } 960 } 961 return CINT_E_NOT_FOUND; 962 } 963 964 static cint_variable_t* 965 __cint_operator_Dot(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 966 { 967 int idx; 968 void* addr; 969 cint_variable_t* rv; 970 971 /* 972 * Left must always be a structure 973 * Right must always be an identifier 974 */ 975 const char* member = ast->utype.operator.right->utype.identifier.s; 976 977 if( ((left->dt.flags & CINT_DATATYPE_F_STRUCT) == 0) || 978 left->dt.desc.pcount != 0 ) { 979 cint_ast_error(ast, CINT_E_PARAM, "request for member '%s' in something not a structure", 980 member); 981 return NULL; 982 } 983 984 /* 985 * Left points to a structure 986 */ 987 idx = __find_struct_member_index(member, left->dt.basetype.sp->struct_members); 988 if(idx < 0) { 989 /* Member does no exist in this structure */ 990 cint_ast_error(ast, CINT_E_PARAM, "struct '%s' has no member '%s'", 991 left->dt.basetype.sp->name, member); 992 return NULL; 993 } 994 995 /* 996 * Get the address of this member 997 */ 998 addr = left->dt.basetype.sp->maddr(left->data, idx, left->dt.basetype.sp); 999 1000 /* 1001 * Create a variable of this type with this address 1002 */ 1003 cint_variable_create(&rv, 1004 NULL, 1005 left->dt.basetype.sp->struct_members+idx, 1006 CINT_VARIABLE_F_SDATA, 1007 addr); 1008 1009 return rv; 1010 } 1011 1012 static cint_variable_t* 1013 __cint_operator_Arrow(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 1014 { 1015 int idx; 1016 void* addr; 1017 cint_variable_t* rv; 1018 1019 /* 1020 * Left must always be a structure pointer 1021 * Right must always be an identifier 1022 */ 1023 const char* member = ast->utype.operator.right->utype.identifier.s; 1024 1025 if( ((left->dt.flags & CINT_DATATYPE_F_STRUCT) == 0) || 1026 left->dt.desc.pcount != 1 ) { 1027 cint_ast_error(ast, CINT_E_PARAM, "request for member '%s' in something not a structure", 1028 member); 1029 return NULL; 1030 } 1031 1032 /* 1033 * Left points to a structure pointer 1034 */ 1035 idx = __find_struct_member_index(member, left->dt.basetype.sp->struct_members); 1036 if(idx < 0) { 1037 /* Member does no exist in this structure */ 1038 cint_ast_error(ast, CINT_E_PARAM, "struct '%s' has no member '%s'", 1039 left->dt.basetype.sp->name, member); 1040 return NULL; 1041 } 1042 1043 /* 1044 * Check for NULL pointer dereference 1045 */ 1046 if((*(void**)left->data) == NULL) { 1047 cint_ast_error(ast, CINT_E_BAD_OPERANDS, "attempt to dereference a NULL structure member pointer"); 1048 return NULL; 1049 } 1050 1051 /* 1052 * Get the address of this member 1053 */ 1054 addr = left->dt.basetype.sp->maddr(*((void**)left->data), idx, left->dt.basetype.sp); 1055 1056 1057 /* 1058 * Create a variable of this type with this address 1059 */ 1060 cint_variable_create(&rv, 1061 NULL, 1062 left->dt.basetype.sp->struct_members+idx, 1063 CINT_VARIABLE_F_SDATA, 1064 addr); 1065 1066 return rv; 1067 } 1068 1069 1070 static cint_variable_t* 1071 __cint_operator_Typecast(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right) 1072 { 1073 /* 1074 * Right is the evaluated expression to typecast. 1075 * The left Ast contains the typename. 1076 * 1077 * Full typename parsing is not yet implemented. 1078 * 1079 * Only the following are currently supported: 1080 * 1081 * Casts to 'void*' -- left == 1 (See grammar) 1082 * Autocasts -- left == 2 (See grammer) allow variables to be any required type 1083 */ 1084 cint_ast_t* type = ast->utype.operator.left; 1085 if(type == CINT_AST_PTR_VOID) { 1086 /* Cast to 'void*' */ 1087 if(cint_is_pointer(right) || cint_is_integer(right)) { 1088 return cint_auto_pointer("void", cint_pointer_value(right)); 1089 } 1090 else { 1091 cint_ast_error(ast, CINT_E_BAD_TYPE, "bad type in cast"); 1092 return NULL; 1093 } 1094 } 1095 1096 if(type == CINT_AST_PTR_AUTO) { 1097 /* Autocast */ 1098 right->flags |= CINT_VARIABLE_F_AUTOCAST; 1099 return right; 1100 } 1101 return NULL; 1102 } 1103 1104 1105 static int 1106 __cint_arithmetic_conversions(cint_variable_t** left, cint_variable_t** right) 1107 { 1108 unsigned lflags = 0; 1109 unsigned rflags = 0; 1110 1111 /* Convert enums to ints */ 1112 if(left && cint_is_enum(*left)) { 1113 *left = cint_auto_integer(cint_integer_value(*left)); 1114 } 1115 if(right && cint_is_enum(*right)) { 1116 *right = cint_auto_integer(cint_integer_value(*right)); 1117 } 1118 1119 if(left == NULL || *left == NULL || right == NULL || *right == NULL) { 1120 /* Nothing else to do */ 1121 return CINT_E_NONE; 1122 } 1123 1124 if(cint_type_check(&(*left)->dt, &(*right)->dt)) { 1125 /* They are already the same type. Nothing to do. */ 1126 return CINT_E_NONE; 1127 } 1128 1129 lflags = cint_atomic_flags(*left); 1130 rflags = cint_atomic_flags(*right); 1131 1132 if( ((lflags & CINT_ATOMIC_TYPE_FLAGS_ARITH) == 0) || 1133 ((rflags & CINT_ATOMIC_TYPE_FLAGS_ARITH) == 0)) { 1134 /* They are not both atomic arithmetic types. Nothing to do. */ 1135 return CINT_E_NONE; 1136 } 1137 1138 1139 /* If either is 'double', convert both to double */ 1140 if((lflags & CINT_ATOMIC_TYPE_F_DOUBLE) || (rflags & CINT_ATOMIC_TYPE_F_DOUBLE)) { 1141 if(lflags & CINT_ATOMIC_TYPE_F_DOUBLE) { 1142 *right = cint_auto_double(cint_double_value(*right)); 1143 } 1144 else { 1145 *left = cint_auto_double(cint_double_value(*left)); 1146 } 1147 return CINT_E_NONE; 1148 } 1149 1150 /* 1151 * Integral promotions. All char, short, and enum => integer. 1152 * It is assumed all values will fit in an integer. 1153 * We don't perform conversion to unsigned integer 1154 */ 1155 if(lflags & (CINT_ATOMIC_TYPE_F_CHAR | CINT_ATOMIC_TYPE_F_SHORT) ) { 1156 *left = cint_auto_integer(cint_integer_value(*left)); 1157 lflags = cint_atomic_flags(*left); 1158 } 1159 if(rflags & (CINT_ATOMIC_TYPE_F_CHAR | CINT_ATOMIC_TYPE_F_SHORT)) { 1160 *right = cint_auto_integer(cint_integer_value(*right)); 1161 rflags = cint_atomic_flags(*right); 1162 } 1163 1164 if(rflags == lflags) { 1165 /* At this point if the flags are equal they are the same type. */ 1166 return CINT_E_NONE; 1167 } 1168 1169 /* 1170 * Long Long and long promotion 1171 */ 1172 if( (lflags & CINT_ATOMIC_TYPE_F_LONGLONG) || 1173 (lflags & CINT_ATOMIC_TYPE_F_LONGLONG) ) { 1174 1175 if(lflags & CINT_ATOMIC_TYPE_F_LONGLONG) { 1176 *right = cint_auto_longlong(cint_longlong_value(*right)); 1177 } 1178 else { 1179 *left = cint_auto_longlong(cint_longlong_value(*left)); 1180 } 1181 return CINT_E_NONE; 1182 } 1183 if( (lflags & CINT_ATOMIC_TYPE_F_LONG) || 1184 (rflags & CINT_ATOMIC_TYPE_F_LONG) ) { 1185 1186 if(lflags & CINT_ATOMIC_TYPE_F_LONG) { 1187 *right = cint_auto_long(cint_long_value(*right)); 1188 } 1189 else { 1190 *left = cint_auto_long(cint_long_value(*left)); 1191 } 1192 return CINT_E_NONE; 1193 } 1194 1195 return CINT_E_NONE; 1196 } 1197 1198 1199 static struct { 1200 1201 const char* name; 1202 const char* iname; 1203 cint_variable_t* (*handler)(cint_ast_t* ast, cint_operand_type_t optype, cint_variable_t* left, cint_variable_t* right); 1204 unsigned flags; 1205 1206 } __operator_table[] = { 1207 1208 #define CINT_OPERATOR_LIST_ENTRY(iname, _entry,f) { iname, #_entry, __cint_operator_##_entry, f }, 1209 #include "cint_op_entry.h" 1210 1211 { NULL } 1212 }; 1213 1214 1215 cint_variable_t* 1216 cint_eval_operator_internal(cint_ast_t* ast, cint_operator_t op, cint_variable_t* left, cint_variable_t* right) 1217 { 1218 unsigned flags; 1219 int optype = 0; 1220 cint_variable_t* rv = NULL; 1221 1222 flags = __operator_table[op].flags; 1223 1224 if((flags & CINT_OPERATOR_F_ACCEPT_ALL) == 0) { 1225 1226 /* 1227 * Perform all arithmetic type conversions 1228 */ 1229 __cint_arithmetic_conversions(&left, &right); 1230 1231 /* 1232 * Perform pointer conversions 1233 */ 1234 __cint_pointer_conversion(&left); 1235 __cint_pointer_conversion(&right); 1236 /* 1237 * Not all types are accepted by the operator. 1238 * Check the operands for compatibility. 1239 */ 1240 if(__cint_check_operand(left, flags) == 0) { 1241 __cint_bad_operands(ast, op); 1242 return NULL; 1243 } 1244 if(__cint_check_operand(right, flags) == 0) { 1245 __cint_bad_operands(ast, op); 1246 return NULL; 1247 } 1248 } 1249 1250 if( (left && left->dt.desc.pcount) || 1251 (right && right->dt.desc.pcount) ) { 1252 1253 /* Pointer operands */ 1254 optype = cintOperandPointer; 1255 } 1256 else { 1257 1258 unsigned flags = cint_atomic_flags(right) | cint_atomic_flags(left); 1259 1260 switch(flags & CINT_ATOMIC_TYPE_FLAGS_MASK) 1261 { 1262 case CINT_ATOMIC_TYPE_F_INT: optype = cintOperandInt; break; 1263 case CINT_ATOMIC_TYPE_F_LONG: optype = cintOperandLong; break; 1264 case CINT_ATOMIC_TYPE_F_LONGLONG: optype = cintOperandLongLong; break; 1265 case CINT_ATOMIC_TYPE_F_DOUBLE: optype = cintOperandDouble; break; 1266 } 1267 /* If either operand is unsigned, treat all as unsigned */ 1268 optype += ( (flags & CINT_ATOMIC_TYPE_F_UNSIGNED) != 0); 1269 } 1270 1271 rv = __operator_table[op].handler(ast, optype, left, right); 1272 1273 1274 if(flags & CINT_OPERATOR_F_LOGICAL) { 1275 /* 1276 * The result of this operator should be a logical integer. 1277 */ 1278 rv = cint_auto_integer(cint_logical_value(rv)); 1279 } 1280 1281 return rv; 1282 } 1283 1284 cint_variable_t* 1285 cint_eval_operator(cint_ast_t* ast) 1286 { 1287 cint_operator_t op = ast->utype.operator.op; 1288 cint_variable_t* left = NULL; 1289 cint_variable_t* right = NULL; 1290 unsigned flags = 0; 1291 1292 if(op >= cintOpLast) { 1293 cint_errno = CINT_E_BAD_OPERATOR; 1294 return NULL; 1295 } 1296 1297 if(ast->ntype != cintAstOperator) { 1298 cint_internal_error(__FILE__, __LINE__, "cint_eval_operator on non operator ast"); 1299 return NULL; 1300 } 1301 1302 CINT_DTRACE(("OP '%s' %s", __operator_table[op].name, __operator_table[op].iname)); 1303 1304 flags = __operator_table[op].flags; 1305 1306 /* 1307 * Evaluate Left Value 1308 */ 1309 if(flags & CINT_OPERATOR_F_LEFT) { 1310 left = cint_eval_ast(ast->utype.operator.left); 1311 if(left == NULL && 1312 !(flags & CINT_OPERATOR_F_OPTIONAL)) { 1313 __cint_bad_operands(ast, op); 1314 return NULL; 1315 } 1316 } 1317 1318 /* 1319 * Evaluate Right Value 1320 */ 1321 if(flags & CINT_OPERATOR_F_RIGHT) { 1322 right = cint_eval_ast(ast->utype.operator.right); 1323 1324 if(right == NULL && 1325 !(flags & CINT_OPERATOR_F_OPTIONAL) && 1326 ((ast->utype.operator.right == NULL) || 1327 !(op == cintOpAssign && 1328 ast->utype.operator.right->ntype == cintAstInitializer)) ) { 1329 __cint_bad_operands(ast, op); 1330 return NULL; 1331 } 1332 } 1333 1334 return cint_eval_operator_internal(ast, op, left, right); 1335 1336 } 1337 1338 static void __cint_bad_operands(cint_ast_t* ast, int op) 1339 { 1340 cint_ast_error(ast, CINT_E_BAD_OPERANDS, "invalid operand(s) to '%s'", __operator_table[op].name); 1341 } 1342 1343 const char* 1344 cint_operator_name(cint_operator_t op) 1345 { 1346 if(op >= cintOpLast) { 1347 cint_errno = CINT_E_BAD_OPERATOR; 1348 return NULL; 1349 } 1350 else { 1351 return __operator_table[op].name; 1352 } 1353 } 1354 1355 cint_operator_t 1356 cint_operator_type(cint_ast_t* ast) 1357 { 1358 cint_operator_t rc = cintOpLast; 1359 1360 if(ast->ntype == cintAstOperator) { 1361 rc = ast->utype.operator.op; 1362 } 1363 1364 return rc; 1365 } 1366