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