501 "ANY_INT" : "if(search_expression_type->is_integer_type(%(paramname)s_param_value))" |
501 "ANY_INT" : "if(search_expression_type->is_integer_type(%(paramname)s_param_value))" |
502 }.get(typename, |
502 }.get(typename, |
503 "if (typeid(*last_type_symbol) == typeid(%(typename)s_type_name_c))")%{ |
503 "if (typeid(*last_type_symbol) == typeid(%(typename)s_type_name_c))")%{ |
504 "paramname" : paramname, "typename": typename.lower()} |
504 "paramname" : paramname, "typename": typename.lower()} |
505 |
505 |
506 def recurse_and_indent(fdecls, indent): |
506 def recurse_and_indent(fdecls, indent, do_type_search_only = False): |
507 if type(fdecls) != type(tuple()): |
507 if type(fdecls) != type(tuple()): |
508 res = "" |
508 res = "" |
509 for Paramname, ParamTypes in fdecls.iteritems(): |
509 for Paramname, ParamTypes in fdecls.iteritems(): |
510 res += (""" |
510 res += (""" |
511 { |
511 { |
512 indentifier_c param_name("%(input_name)s"); |
512 identifier_c param_name("%(input_name)s"); |
513 /* Get the value from a foo(<param_name> = <param_value>) style call */ |
513 /* Get the value from a foo(<param_name> = <param_value>) style call */ |
514 symbol_c *%(input_name)s_param_value = function_call_param_iterator.search(¶m_name); |
514 symbol_c *%(input_name)s_param_value = function_call_param_iterator.search(¶m_name); |
515 |
515 |
516 /* Get the value from a foo(<param_value>) style call */ |
516 /* Get the value from a foo(<param_value>) style call */ |
517 if (%(input_name)s_param_value == NULL) |
517 if (%(input_name)s_param_value == NULL) |
542 fdecl=fdecls[0] |
542 fdecl=fdecls[0] |
543 |
543 |
544 result_type_rule = fdecl["return_type_rule"] |
544 result_type_rule = fdecl["return_type_rule"] |
545 res += { |
545 res += { |
546 "copy_input" : "symbol_c * return_type_symbol = last_type_symbol;\n", |
546 "copy_input" : "symbol_c * return_type_symbol = last_type_symbol;\n", |
547 "defined" : "symbol_c * return_type_symbol = &%s_type_name_c;\n"%fdecl["outputs"][0][1].lower(), |
547 "defined" : "symbol_c * return_type_symbol = &search_constant_type_c::%s_type_name;\n"%fdecl["outputs"][0][1].lower(), |
548 }.get(result_type_rule, "symbol_c * return_type_symbol = %s;\n"%result_type_rule) |
548 }.get(result_type_rule, "symbol_c * return_type_symbol = %s;\n"%result_type_rule) |
549 |
549 |
550 |
550 if not do_type_search_only: |
551 try: |
551 try: |
552 code_gen = eval(fdecl["python_eval_c_code_format"]) |
552 code_gen = eval(fdecl["python_eval_c_code_format"]) |
553 except Exception: |
553 except Exception: |
554 code_gen = "#error in eval of " + fdecl["name"] |
554 code_gen = "#error in eval of " + fdecl["name"] |
555 |
555 |
556 code_gen_dic_decl = {} |
556 code_gen_dic_decl = {} |
557 for paramname,paramtype,unused in fdecl["inputs"]: |
|
558 code_gen_dic_decl[paramname+"_value"] = '");\n%s_param_value->accept(*this);\ns4o.print("'%(paramname) |
|
559 code_gen_dic_decl[paramname+"_type"] = '");\n%s_type_symbol->accept(*this);\ns4o.print("'%(paramname) |
|
560 code_gen_dic_decl["return_type"] = '");\nreturn_type_symbol->accept(*this);\ns4o.print("' |
|
561 code_gen_dic_decl["param_count"] = '");\ns4o.print_integer(nb_param);\ns4o.print("' |
|
562 |
|
563 if type(code_gen) == type(tuple()): |
|
564 res += 's4o.print("%s");\n'%(code_gen[0]%code_gen_dic_decl) |
|
565 static_param_accept_list = [] |
|
566 for paramname,paramtype,unused in fdecl["inputs"]: |
557 for paramname,paramtype,unused in fdecl["inputs"]: |
567 static_param_accept_list.append("%s_param_value->accept(*this);\n"%(paramname)) |
558 code_gen_dic_decl[paramname+"_value"] = '");\n%s_param_value->accept(*this);\ns4o.print("'%(paramname) |
568 res += ('s4o.print("%s");\n'%(code_gen[1])).join(static_param_accept_list) |
559 code_gen_dic_decl[paramname+"_type"] = '");\n%s_type_symbol->accept(*this);\ns4o.print("'%(paramname) |
569 code = 's4o.print("%s");\nparam_value->accept(*this);\n'%(code_gen[1]) |
560 code_gen_dic_decl["return_type"] = '");\nreturn_type_symbol->accept(*this);\ns4o.print("' |
570 end_code = 's4o.print("%s");\nreturn NULL;\n'%(code_gen[2]) |
561 code_gen_dic_decl["param_count"] = '");\ns4o.print_integer(nb_param);\ns4o.print("' |
571 else: |
562 |
572 code = '' |
563 if type(code_gen) == type(tuple()): |
573 end_code = ('s4o.print("' + code_gen%code_gen_dic_decl + '");\nreturn NULL;\n').replace('s4o.print("");\n','') |
564 res += 's4o.print("%s");\n'%(code_gen[0]%code_gen_dic_decl) |
574 |
565 static_param_accept_list = [] |
575 if fdecl["extensible"]: |
566 for paramname,paramtype,unused in fdecl["inputs"]: |
576 res += (""" |
567 static_param_accept_list.append("%s_param_value->accept(*this);\n"%(paramname)) |
577 int base_num = %d |
568 res += ('s4o.print("%s");\n'%(code_gen[1])).join(static_param_accept_list) |
|
569 code = 's4o.print("%s");\nparam_value->accept(*this);\n'%(code_gen[1]) |
|
570 end_code = 's4o.print("%s");\nreturn NULL;\n'%(code_gen[2]) |
|
571 else: |
|
572 code = '' |
|
573 end_code = ('s4o.print("' + code_gen%code_gen_dic_decl + '");\nreturn NULL;\n').replace('s4o.print("");\n','') |
|
574 |
|
575 if fdecl["extensible"]: |
|
576 res += (""" |
|
577 int base_num = %d; |
|
578 symbol_c *param_value = NULL; |
578 do{ |
579 do{ |
579 char my_name[10]; |
580 char my_name[10]; |
580 sprintf(my_name, "IN%%d", base_num++); |
581 sprintf(my_name, "IN%%d", base_num++); |
581 indentifier_c param_name(my_name); |
582 identifier_c param_name(my_name); |
582 |
583 |
583 /* Get the value from a foo(<param_name> = <param_value>) style call */ |
584 /* Get the value from a foo(<param_name> = <param_value>) style call */ |
584 symbol_c *param_value = function_call_param_iterator.search(¶m_name); |
585 param_value = function_call_param_iterator.search(¶m_name); |
585 |
586 |
586 /* Get the value from a foo(<param_value>) style call */ |
587 /* Get the value from a foo(<param_value>) style call */ |
587 if (param_value == NULL) |
588 if (param_value == NULL) |
588 param_value = function_call_param_iterator.next(); |
589 param_value = function_call_param_iterator.next(); |
589 if (param_value != NULL){ |
590 if (param_value != NULL){ |
592 |
593 |
593 /*Function specific CODE */ |
594 /*Function specific CODE */ |
594 %s |
595 %s |
595 } |
596 } |
596 |
597 |
597 }while(param_value != NULL) |
598 }while(param_value != NULL); |
598 %s |
599 %s |
599 """%(fdecl["baseinputnumber"]+2, code.replace('\n','\n '), end_code)) |
600 """%(fdecl["baseinputnumber"]+2, code.replace('\n','\n '), end_code)) |
|
601 else: |
|
602 #res += code + end_code |
|
603 res += end_code |
600 else: |
604 else: |
601 #res += code + end_code |
605 res += "return return_type_symbol;\n" |
602 res += end_code |
606 |
603 |
607 |
604 return res.replace('\n','\n'+indent) |
608 return res.replace('\n','\n'+indent) |
605 |
609 |
606 ################################################################### |
610 ################################################################### |
607 ### ### |
611 ### ### |
608 ### MAIN ### |
612 ### MAIN ### |
617 # Keep ptrack of original order in a separated list |
621 # Keep ptrack of original order in a separated list |
618 std_fdecls = {} |
622 std_fdecls = {} |
619 official_order = [] |
623 official_order = [] |
620 for section in std_decl: |
624 for section in std_decl: |
621 for fdecl in section["list"]: |
625 for fdecl in section["list"]: |
622 if len(official_order)==0 or official_order[-1] != official_order: |
626 if len(official_order)==0 or official_order[-1] != fdecl["name"]: |
623 official_order.append(fdecl["name"]) |
627 official_order.append(fdecl["name"]) |
624 # store all func by name in a dict |
628 # store all func by name in a dict |
625 std_fdecls_fdecl_name = std_fdecls.get(fdecl["name"], {}) |
629 std_fdecls_fdecl_name = std_fdecls.get(fdecl["name"], {}) |
626 current = std_fdecls_fdecl_name |
630 current = std_fdecls_fdecl_name |
627 for i in fdecl["inputs"]: |
631 for i in fdecl["inputs"]: |
648 } function_type_t; |
652 } function_type_t; |
649 """ |
653 """ |
650 |
654 |
651 # Generate the funct thaat return enumerated according function name |
655 # Generate the funct thaat return enumerated according function name |
652 get_function_type_decl = """ |
656 get_function_type_decl = """ |
|
657 /**** |
|
658 * IEC 61131-3 standard function lib |
|
659 * generated code, do not edit by hand |
|
660 */ |
653 function_type_t get_function_type(identifier_c *function_name) { |
661 function_type_t get_function_type(identifier_c *function_name) { |
654 """ |
662 """ |
655 for fname, fdecls in [ (fname,std_fdecls[fname]) for fname in official_order ]: |
663 for fname, fdecls in [ (fname,std_fdecls[fname]) for fname in official_order ]: |
656 get_function_type_decl += """ |
664 get_function_type_decl += """ |
657 if (!strcasecmp(function_name->value, "%s")) |
665 if (!strcasecmp(function_name->value, "%s")) |
683 |
697 |
684 st_code_gen += """ |
698 st_code_gen += """ |
685 }/*function_%s*/ |
699 }/*function_%s*/ |
686 break; |
700 break; |
687 """ %(fname.lower()) |
701 """ %(fname.lower()) |
688 st_code_gen += "}" |
702 st_code_gen += """ |
|
703 case function_none : |
|
704 ERROR; |
|
705 } |
|
706 return NULL; |
|
707 """ |
|
708 |
|
709 |
|
710 # Generate the part of search_expression_type_c::visit(function_invocation) |
|
711 # that is responsible of returning type symbol for function invocation. |
|
712 search_type_code = """ |
|
713 /**** |
|
714 * IEC 61131-3 standard function lib |
|
715 * generated code, do not edit by hand |
|
716 */ |
|
717 switch(current_function_type){ |
|
718 """ |
|
719 |
|
720 for fname, fdecls in [ (fname,std_fdecls[fname]) for fname in official_order ]: |
|
721 search_type_code += """ |
|
722 /**** |
|
723 *%s |
|
724 */ |
|
725 case function_%s : |
|
726 { |
|
727 symbol_c *last_type_symbol = NULL; |
|
728 """ %(fname, fname.lower()) |
|
729 indent = " " |
|
730 |
|
731 search_type_code += recurse_and_indent(fdecls, indent, True).replace('\n','\n ') |
|
732 |
|
733 search_type_code += """ |
|
734 }/*function_%s*/ |
|
735 break; |
|
736 """ %(fname.lower()) |
|
737 search_type_code += """ |
|
738 case function_none : |
|
739 ERROR; |
|
740 } |
|
741 return NULL; |
|
742 """ |
|
743 |
689 |
744 |
690 # Now, print that out, or write to files from sys.argv |
745 # Now, print that out, or write to files from sys.argv |
691 print function_type_decl |
746 for name, ext in [ |
692 print get_function_type_decl |
747 ('function_type_decl','h'), |
693 print st_code_gen #.replace("\n", "\\\n") |
748 ('get_function_type_decl','c'), |
694 |
749 ('st_code_gen','c'), |
|
750 ('search_type_code','c')]: |
|
751 fd = open(os.path.join(sys.argv[1],name+'.'+ext),'w') |
|
752 fd.write(eval(name)) |
|
753 fd.close() |
695 else: |
754 else: |
696 # Put standard functions declaration in Bloktypes |
755 # Put standard functions declaration in Bloktypes |
697 BlockTypes.extend(get_standard_funtions(csv_file_to_table(open(os.path.join(sys.path[0], "plcopen/iec_std.csv"))))) |
756 BlockTypes.extend(get_standard_funtions(csv_file_to_table(open(os.path.join(sys.path[0], "plcopen/iec_std.csv"))))) |
698 |
757 |