plcopen/structures.py
changeset 19 0b499416ebd7
parent 18 ee18a387e80a
child 21 e619d7bea692
equal deleted inserted replaced
18:ee18a387e80a 19:0b499416ebd7
   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(&param_name);
   514 	symbol_c *%(input_name)s_param_value = function_call_param_iterator.search(&param_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)
   527 	{
   527 	{
   528 %(if_good_type_code)s
   528 %(if_good_type_code)s
   529 	}
   529 	}
   530 """%{
   530 """%{
   531 	"type_test":ANY_to_compiler_test_type_GEN(ParamType,Paramname), 
   531 	"type_test":ANY_to_compiler_test_type_GEN(ParamType,Paramname), 
   532 	"if_good_type_code":recurse_and_indent(NextParamDecl,indent).replace('\n','\n	')})
   532 	"if_good_type_code":recurse_and_indent(NextParamDecl,indent,do_type_search_only).replace('\n','\n	')})
   533 
   533 
   534 				res += """	
   534 				res += """	
   535 	ERROR;
   535 	ERROR;
   536 }
   536 }
   537 """
   537 """
   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(&param_name);
   585 	param_value = function_call_param_iterator.search(&param_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"))
   664 
   672 
   665 """
   673 """
   666 
   674 
   667 	# Generate the part of generate_cc_st_c::visit(function_invocation)
   675 	# Generate the part of generate_cc_st_c::visit(function_invocation)
   668 	# that is responsible to generate C code for std lib calls.
   676 	# that is responsible to generate C code for std lib calls.
   669 	st_code_gen = "switch(current_function_type){\n"	
   677 	st_code_gen = """
       
   678 /****
       
   679  * IEC 61131-3 standard function lib
       
   680  * generated code, do not edit by hand
       
   681  */
       
   682 switch(current_function_type){
       
   683 """
   670 	
   684 	
   671 	for fname, fdecls in [ (fname,std_fdecls[fname]) for fname in official_order ]:
   685 	for fname, fdecls in [ (fname,std_fdecls[fname]) for fname in official_order ]:
   672 		st_code_gen += """
   686 		st_code_gen += """
   673 /****
   687 /****
   674  *%s
   688  *%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