384 |
384 |
385 /***********************************************************************/ |
385 /***********************************************************************/ |
386 /***********************************************************************/ |
386 /***********************************************************************/ |
387 /***********************************************************************/ |
387 /***********************************************************************/ |
388 /***********************************************************************/ |
388 /***********************************************************************/ |
|
389 /* A helper class that analyses if the datatype of a variable is 'complex'. */ |
|
390 /* 'complex' means that it is either a strcuture or an array! */ |
|
391 class print_getter_c: public search_visitor_c { |
|
392 private: |
|
393 static print_getter_c *singleton_; |
|
394 |
|
395 public: |
|
396 print_getter_c(void) {}; |
|
397 |
|
398 static bool is_complex_type(symbol_c *symbol) { |
|
399 if (NULL == symbol) ERROR; |
|
400 if (!get_datatype_info_c::is_type_valid (symbol->datatype)) return false; |
|
401 return ( get_datatype_info_c::is_structure(symbol->datatype) |
|
402 || get_datatype_info_c::is_array (symbol->datatype) |
|
403 ); |
|
404 } |
|
405 |
|
406 |
|
407 private: |
|
408 symbol_c *last_fb, *first_non_fb_identifier; |
|
409 |
|
410 public: |
|
411 /* returns the first element (from left to right) in a structured variable that is not a FB, i.e. is either a structure or an array! */ |
|
412 /* eg: |
|
413 * fb1.fb2.fb3.real returns ?????? |
|
414 * fb1.fb2.struct1.real returns struct1 |
|
415 * struct1.real returns struct1 |
|
416 */ |
|
417 static symbol_c *find_first_nonfb(symbol_c *symbol) { |
|
418 if (NULL == singleton_) singleton_ = new print_getter_c(); |
|
419 if (NULL == singleton_) ERROR; |
|
420 if (NULL == symbol) ERROR; |
|
421 |
|
422 singleton_->last_fb = NULL; |
|
423 singleton_->first_non_fb_identifier = NULL; |
|
424 return (symbol_c *)symbol->accept(*singleton_); |
|
425 } |
|
426 |
|
427 /* returns true if a strcutured variable (e.g. fb1.fb2.strcut1.real) contains a structure or array */ |
|
428 /* eg: |
|
429 * fb1.fb2.fb3.real returns FALSE |
|
430 * fb1.fb2.struct1.real returns TRUE |
|
431 * struct1.real returns TRUE |
|
432 */ |
|
433 static bool contains_complex_type(symbol_c *symbol) { |
|
434 if (NULL == symbol) ERROR; |
|
435 if (!get_datatype_info_c::is_type_valid(symbol->datatype)) ERROR; |
|
436 |
|
437 symbol_c *first_non_fb = (symbol_c *)find_first_nonfb(symbol); |
|
438 return is_complex_type(first_non_fb->datatype); |
|
439 } |
|
440 |
|
441 |
|
442 /* returns the datatype of the variable returned by find_first_nonfb() */ |
|
443 /* eg: |
|
444 * fb1.fb2.fb3.real returns ?????? |
|
445 * fb1.fb2.struct1.real returns datatype of struct1 |
|
446 * struct1.real returns datatype of struct1 |
|
447 */ |
|
448 static search_var_instance_decl_c::vt_t first_nonfb_vardecltype(symbol_c *symbol, symbol_c *scope) { |
|
449 if (NULL == symbol) ERROR; |
|
450 if (!get_datatype_info_c::is_type_valid(symbol->datatype)) ERROR; |
|
451 |
|
452 symbol_c *first_non_fb = (symbol_c *)find_first_nonfb(symbol); |
|
453 if (NULL != singleton_->last_fb) { |
|
454 scope = singleton_->last_fb->datatype; |
|
455 symbol = singleton_->first_non_fb_identifier; |
|
456 } |
|
457 |
|
458 search_var_instance_decl_c search_var_instance_decl(scope); |
|
459 |
|
460 return search_var_instance_decl.get_vartype(symbol); |
|
461 } |
|
462 |
|
463 |
|
464 /*********************/ |
|
465 /* B 1.4 - Variables */ |
|
466 /*********************/ |
|
467 void *visit(symbolic_variable_c *symbol) { |
|
468 if (!get_datatype_info_c::is_type_valid (symbol->datatype)) ERROR; |
|
469 if (!get_datatype_info_c::is_function_block(symbol->datatype)) { |
|
470 first_non_fb_identifier = symbol; |
|
471 return (void *)symbol; |
|
472 } |
|
473 last_fb = symbol; |
|
474 return NULL; |
|
475 } |
|
476 |
|
477 /*************************************/ |
|
478 /* B.1.4.2 Multi-element Variables */ |
|
479 /*************************************/ |
|
480 |
|
481 // SYM_REF2(structured_variable_c, record_variable, field_selector) |
|
482 void *visit(structured_variable_c *symbol) { |
|
483 symbol_c *res = (symbol_c *)symbol->record_variable->accept(*this); |
|
484 if (NULL != res) return res; |
|
485 |
|
486 if (!get_datatype_info_c::is_type_valid (symbol->datatype)) ERROR; |
|
487 if (!get_datatype_info_c::is_function_block(symbol->datatype)) { |
|
488 first_non_fb_identifier = symbol->field_selector; |
|
489 return (void *)symbol; |
|
490 } |
|
491 |
|
492 last_fb = symbol; |
|
493 return NULL; |
|
494 } |
|
495 |
|
496 /* subscripted_variable '[' subscript_list ']' */ |
|
497 //SYM_REF2(array_variable_c, subscripted_variable, subscript_list) |
|
498 void *visit(array_variable_c *symbol) { |
|
499 void *res = symbol->subscripted_variable->accept(*this); |
|
500 if (NULL != res) return res; |
|
501 return (void *)symbol; |
|
502 } |
|
503 |
|
504 |
|
505 }; |
|
506 |
|
507 print_getter_c *print_getter_c::singleton_ = NULL; |
|
508 |
|
509 |
|
510 |
|
511 |
|
512 |
|
513 |
389 |
514 |
390 /* A helper class that analyses if the datatype of a variable is 'complex'. */ |
515 /* A helper class that analyses if the datatype of a variable is 'complex'. */ |
391 /* 'complex' means that it is either a strcuture or an array! */ |
516 /* 'complex' means that it is either a strcuture or an array! */ |
392 class analyse_variable_c: public search_visitor_c { |
517 class analyse_variable_c: public search_visitor_c { |
393 private: |
518 private: |
1571 s4o.indent_right(); |
1696 s4o.indent_right(); |
1572 s4o.print(s4o.indent_spaces); |
1697 s4o.print(s4o.indent_spaces); |
1573 s4o.print(SET_VAR); |
1698 s4o.print(SET_VAR); |
1574 s4o.print("("); |
1699 s4o.print("("); |
1575 s4o.print(FB_FUNCTION_PARAM); |
1700 s4o.print(FB_FUNCTION_PARAM); |
1576 s4o.print("->,ENO,__BOOL_LITERAL(FALSE));\n"); |
1701 s4o.print("->,ENO,,__BOOL_LITERAL(FALSE));\n"); |
1577 s4o.print(s4o.indent_spaces + "return;\n"); |
1702 s4o.print(s4o.indent_spaces + "return;\n"); |
1578 s4o.indent_left(); |
1703 s4o.indent_left(); |
1579 s4o.print(s4o.indent_spaces + "}\n"); |
1704 s4o.print(s4o.indent_spaces + "}\n"); |
1580 s4o.print(s4o.indent_spaces + "else {\n"); |
1705 s4o.print(s4o.indent_spaces + "else {\n"); |
1581 s4o.indent_right(); |
1706 s4o.indent_right(); |
1582 s4o.print(s4o.indent_spaces); |
1707 s4o.print(s4o.indent_spaces); |
1583 s4o.print(SET_VAR); |
1708 s4o.print(SET_VAR); |
1584 s4o.print("("); |
1709 s4o.print("("); |
1585 s4o.print(FB_FUNCTION_PARAM); |
1710 s4o.print(FB_FUNCTION_PARAM); |
1586 s4o.print("->,ENO,__BOOL_LITERAL(TRUE));\n"); |
1711 s4o.print("->,ENO,,__BOOL_LITERAL(TRUE));\n"); |
1587 s4o.indent_left(); |
1712 s4o.indent_left(); |
1588 s4o.print(s4o.indent_spaces + "}\n"); |
1713 s4o.print(s4o.indent_spaces + "}\n"); |
1589 |
1714 |
1590 /* (C.4) Initialize TEMP variables */ |
1715 /* (C.4) Initialize TEMP variables */ |
1591 /* function body */ |
1716 /* function body */ |