plcopen/structures.py
changeset 78 049f2e7090a2
parent 58 39cd981ff242
child 92 76d5001393df
equal deleted inserted replaced
77:346a43f179a5 78:049f2e7090a2
    25 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    25 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    26 
    26 
    27 
    27 
    28 LANGUAGES = ["IL","ST","FBD","LD","SFC"]
    28 LANGUAGES = ["IL","ST","FBD","LD","SFC"]
    29 
    29 
       
    30 def generate_block(generator, block, body, link):
       
    31     name = block.getInstanceName()
       
    32     type = block.getTypeName()
       
    33     block_infos = GetBlockType(type)
       
    34     if block_infos["type"] == "function" and link:
       
    35         generator.GeneratePouProgram(type)
       
    36         vars = []
       
    37         for variable in block.inputVariables.getVariable():
       
    38             connections = variable.connectionPointIn.getConnections()
       
    39             if connections and len(connections) == 1:
       
    40                 value = generator.ComputeFBDExpression(body, connections[0])
       
    41                 vars.append(generator.ExtractModifier(variable, value))
       
    42         variable = block.outputVariables.getVariable()[0]
       
    43         return generator.ExtractModifier(variable, "%s(%s)"%(type, ", ".join(vars)))
       
    44     elif block_infos["type"] == "functionBlock":
       
    45         if not generator.ComputedBlocks.get(name, False):
       
    46             vars = []
       
    47             for variable in block.inputVariables.getVariable():
       
    48                 connections = variable.connectionPointIn.getConnections()
       
    49                 if connections and len(connections) == 1:
       
    50                     parameter = variable.getFormalParameter()
       
    51                     value = generator.ComputeFBDExpression(body, connections[0])
       
    52                     vars.append("%s := %s"%(parameter, generator.ExtractModifier(variable, value)))
       
    53             generator.Program += "  %s(%s);\n"%(name, ", ".join(vars))
       
    54             generator.ComputedBlocks[name] = True
       
    55         if link:
       
    56             connectionPoint = link.getPosition()[-1]
       
    57         else:
       
    58             connectionPoint = None
       
    59         for variable in block.outputVariables.getVariable():
       
    60             blockPointx, blockPointy = variable.connectionPointOut.getRelPosition()
       
    61             if not connectionPoint or block.getX() + blockPointx == connectionPoint.getX() and block.getY() + blockPointy == connectionPoint.getY():
       
    62                 return generator.ExtractModifier(variable, "%s.%s"%(name, variable.getFormalParameter()))
       
    63         raise ValueError, "No output variable found"
    30 
    64 
    31 #-------------------------------------------------------------------------------
    65 #-------------------------------------------------------------------------------
    32 #                        Function Block Types definitions
    66 #                        Function Block Types definitions
    33 #-------------------------------------------------------------------------------
    67 #-------------------------------------------------------------------------------
    34 
    68 
    40     - "type" : The block type. It can be "function", "functionBlock" or "program"
    74     - "type" : The block type. It can be "function", "functionBlock" or "program"
    41     - "extensible" : Boolean that define if the block is extensible
    75     - "extensible" : Boolean that define if the block is extensible
    42     - "inputs" : List of the block inputs
    76     - "inputs" : List of the block inputs
    43     - "outputs" : List of the block outputs
    77     - "outputs" : List of the block outputs
    44     - "comment" : Comment that will be displayed in the block popup
    78     - "comment" : Comment that will be displayed in the block popup
       
    79     - "generate" : Method that generator will call for generating ST block code
    45 Inputs and outputs are a tuple of characteristics that are in order:
    80 Inputs and outputs are a tuple of characteristics that are in order:
    46     - The name
    81     - The name
    47     - The data type
    82     - The data type
    48     - The default modifier which can be "none", "negated", "rising" or "falling"
    83     - The default modifier which can be "none", "negated", "rising" or "falling"
    49 """
    84 """
    50 
    85 
    51 BlockTypes = [{"name" : "Standard function blocks", "list":
    86 BlockTypes = [{"name" : "Standard function blocks", "list":
    52                [{"name" : "SR", "type" : "functionBlock", "extensible" : False, 
    87                [{"name" : "SR", "type" : "functionBlock", "extensible" : False, 
    53                     "inputs" : [("S1","BOOL","none"),("R","BOOL","none")], 
    88                     "inputs" : [("S1","BOOL","none"),("R","BOOL","none")], 
    54                     "outputs" : [("Q1","BOOL","none")],
    89                     "outputs" : [("Q1","BOOL","none")],
    55                     "comment" : "SR bistable\nThe SR bistable is a latch where the Set dominates."},
    90                     "comment" : "SR bistable\nThe SR bistable is a latch where the Set dominates.",
       
    91                     "generate" : generate_block},
    56                 {"name" : "RS", "type" : "functionBlock", "extensible" : False, 
    92                 {"name" : "RS", "type" : "functionBlock", "extensible" : False, 
    57                     "inputs" : [("S","BOOL","none"),("R1","BOOL","none")], 
    93                     "inputs" : [("S","BOOL","none"),("R1","BOOL","none")], 
    58                     "outputs" : [("Q1","BOOL","none")],
    94                     "outputs" : [("Q1","BOOL","none")],
    59                     "comment" : "RS bistable\nThe RS bistable is a latch where the Reset dominates."},
    95                     "comment" : "RS bistable\nThe RS bistable is a latch where the Reset dominates.",
       
    96                     "generate" : generate_block},
    60                 {"name" : "SEMA", "type" : "functionBlock", "extensible" : False, 
    97                 {"name" : "SEMA", "type" : "functionBlock", "extensible" : False, 
    61                     "inputs" : [("CLAIM","BOOL","none"),("RELEASE","BOOL","none")], 
    98                     "inputs" : [("CLAIM","BOOL","none"),("RELEASE","BOOL","none")], 
    62                     "outputs" : [("BUSY","BOOL","none")],
    99                     "outputs" : [("BUSY","BOOL","none")],
    63                     "comment" : "Semaphore\nThe semaphore provides a mechanism to allow software elements mutually exclusive access to certain ressources."},
   100                     "comment" : "Semaphore\nThe semaphore provides a mechanism to allow software elements mutually exclusive access to certain ressources.",
       
   101                     "generate" : generate_block},
    64                 {"name" : "R_TRIG", "type" : "functionBlock", "extensible" : False, 
   102                 {"name" : "R_TRIG", "type" : "functionBlock", "extensible" : False, 
    65                     "inputs" : [("CLK","BOOL","none")], 
   103                     "inputs" : [("CLK","BOOL","none")], 
    66                     "outputs" : [("Q","BOOL","none")],
   104                     "outputs" : [("Q","BOOL","none")],
    67                     "comment" : "Rising edge detector\nThe output produces a single pulse when a rising edge is detected."},
   105                     "comment" : "Rising edge detector\nThe output produces a single pulse when a rising edge is detected.",
       
   106                     "generate" : generate_block},
    68                 {"name" : "F_TRIG", "type" : "functionBlock", "extensible" : False, 
   107                 {"name" : "F_TRIG", "type" : "functionBlock", "extensible" : False, 
    69                     "inputs" : [("CLK","BOOL","none")], 
   108                     "inputs" : [("CLK","BOOL","none")], 
    70                     "outputs" : [("Q","BOOL","none")],
   109                     "outputs" : [("Q","BOOL","none")],
    71                     "comment" : "Falling edge detector\nThe output produces a single pulse when a falling edge is detected."},
   110                     "comment" : "Falling edge detector\nThe output produces a single pulse when a falling edge is detected.",
       
   111                     "generate" : generate_block},
    72                 {"name" : "CTU", "type" : "functionBlock", "extensible" : False, 
   112                 {"name" : "CTU", "type" : "functionBlock", "extensible" : False, 
    73                     "inputs" : [("CU","BOOL","rising"),("R","BOOL","none"),("PV","INT","none")], 
   113                     "inputs" : [("CU","BOOL","rising"),("R","BOOL","none"),("PV","INT","none")], 
    74                     "outputs" : [("Q","BOOL","none"),("CV","INT","none")],
   114                     "outputs" : [("Q","BOOL","none"),("CV","INT","none")],
    75                     "comment" : "Up-counter\nThe up-counter can be used to signal when a count has reached a maximum value."},
   115                     "comment" : "Up-counter\nThe up-counter can be used to signal when a count has reached a maximum value.",
       
   116                     "generate" : generate_block},
    76                 {"name" : "CTD", "type" : "functionBlock", "extensible" : False, 
   117                 {"name" : "CTD", "type" : "functionBlock", "extensible" : False, 
    77                     "inputs" : [("CD","BOOL","rising"),("LD","BOOL","none"),("PV","INT","none")], 
   118                     "inputs" : [("CD","BOOL","rising"),("LD","BOOL","none"),("PV","INT","none")], 
    78                     "outputs" : [("Q","BOOL","none"),("CV","INT","none")],
   119                     "outputs" : [("Q","BOOL","none"),("CV","INT","none")],
    79                     "comment" : "Down-counter\nThe down-counter can be used to signal when a count has reached zero, on counting down from a preset value."},
   120                     "comment" : "Down-counter\nThe down-counter can be used to signal when a count has reached zero, on counting down from a preset value.",
       
   121                     "generate" : generate_block},
    80                 {"name" : "CTUD", "type" : "functionBlock", "extensible" : False, 
   122                 {"name" : "CTUD", "type" : "functionBlock", "extensible" : False, 
    81                     "inputs" : [("CU","BOOL","rising"),("CD","BOOL","rising"),("R","BOOL","none"),("LD","BOOL","none"),("PV","INT","none")], 
   123                     "inputs" : [("CU","BOOL","rising"),("CD","BOOL","rising"),("R","BOOL","none"),("LD","BOOL","none"),("PV","INT","none")], 
    82                     "outputs" : [("QU","BOOL","none"),("QD","BOOL","none"),("CV","INT","none")],
   124                     "outputs" : [("QU","BOOL","none"),("QD","BOOL","none"),("CV","INT","none")],
    83                     "comment" : "Up-down counter\nThe up-down counter has two inputs CU and CD. It can be used to both count up on one input ans down on the other."},
   125                     "comment" : "Up-down counter\nThe up-down counter has two inputs CU and CD. It can be used to both count up on one input ans down on the other.",
       
   126                     "generate" : generate_block},
    84                 {"name" : "TP", "type" : "functionBlock", "extensible" : False, 
   127                 {"name" : "TP", "type" : "functionBlock", "extensible" : False, 
    85                     "inputs" : [("IN","BOOL","none"),("PT","TIME","none")], 
   128                     "inputs" : [("IN","BOOL","none"),("PT","TIME","none")], 
    86                     "outputs" : [("Q","BOOL","none"),("ET","TIME","none")],
   129                     "outputs" : [("Q","BOOL","none"),("ET","TIME","none")],
    87                     "comment" : "Pulse timer\nThe pulse timer can be used to generate output pulses of a given time duration."},
   130                     "comment" : "Pulse timer\nThe pulse timer can be used to generate output pulses of a given time duration.",
       
   131                     "generate" : generate_block},
    88                 {"name" : "TOF", "type" : "functionBlock", "extensible" : False, 
   132                 {"name" : "TOF", "type" : "functionBlock", "extensible" : False, 
    89                     "inputs" : [("IN","BOOL","none"),("PT","TIME","none")], 
   133                     "inputs" : [("IN","BOOL","none"),("PT","TIME","none")], 
    90                     "outputs" : [("Q","BOOL","none"),("ET","TIME","none")],
   134                     "outputs" : [("Q","BOOL","none"),("ET","TIME","none")],
    91                     "comment" : "On-delay timer\nThe on-delay timer can be used to delay setting an output true, for fixed period after an input becomes true."},
   135                     "comment" : "On-delay timer\nThe on-delay timer can be used to delay setting an output true, for fixed period after an input becomes true.",
       
   136                     "generate" : generate_block},
    92                 {"name" : "TON", "type" : "functionBlock", "extensible" : False, 
   137                 {"name" : "TON", "type" : "functionBlock", "extensible" : False, 
    93                     "inputs" : [("IN","BOOL","none"),("PT","TIME","none")], 
   138                     "inputs" : [("IN","BOOL","none"),("PT","TIME","none")], 
    94                     "outputs" : [("Q","BOOL","none"),("ET","TIME","none")],
   139                     "outputs" : [("Q","BOOL","none"),("ET","TIME","none")],
    95                     "comment" : "Off-delay timer\nThe off-delay timer can be used to delay setting an output false, for fixed period after input goes false."},
   140                     "comment" : "Off-delay timer\nThe off-delay timer can be used to delay setting an output false, for fixed period after input goes false.",
       
   141                     "generate" : generate_block},
    96                 {"name" : "RTC", "type" : "functionBlock", "extensible" : False, 
   142                 {"name" : "RTC", "type" : "functionBlock", "extensible" : False, 
    97                     "inputs" : [("EN","BOOL","none"),("PDT","DATE_AND_TIME","none")], 
   143                     "inputs" : [("EN","BOOL","none"),("PDT","DATE_AND_TIME","none")], 
    98                     "outputs" : [("Q","BOOL","none"),("CDT","DATE_AND_TIME","none")],
   144                     "outputs" : [("Q","BOOL","none"),("CDT","DATE_AND_TIME","none")],
    99                     "comment" : "Real time clock\nThe real time clock has many uses including time stamping, setting dates and times of day in batch reports, in alarm messages and so on."},
   145                     "comment" : "Real time clock\nThe real time clock has many uses including time stamping, setting dates and times of day in batch reports, in alarm messages and so on.",
       
   146                     "generate" : generate_block},
   100                 {"name" : "INTEGRAL", "type" : "functionBlock", "extensible" : False, 
   147                 {"name" : "INTEGRAL", "type" : "functionBlock", "extensible" : False, 
   101                     "inputs" : [("RUN","BOOL","none"),("R1","BOOL","none"),("XIN","REAL","none"),("X0","REAL","none"),("CYCLE","TIME","none")], 
   148                     "inputs" : [("RUN","BOOL","none"),("R1","BOOL","none"),("XIN","REAL","none"),("X0","REAL","none"),("CYCLE","TIME","none")], 
   102                     "outputs" : [("Q","BOOL","none"),("XOUT","REAL","none")],
   149                     "outputs" : [("Q","BOOL","none"),("XOUT","REAL","none")],
   103                     "comment" : "Integral\nThe integral function block integrates the value of input XIN over time."},
   150                     "comment" : "Integral\nThe integral function block integrates the value of input XIN over time.",
       
   151                     "generate" : generate_block},
   104                 {"name" : "DERIVATIVE", "type" : "functionBlock", "extensible" : False, 
   152                 {"name" : "DERIVATIVE", "type" : "functionBlock", "extensible" : False, 
   105                     "inputs" : [("RUN","BOOL","none"),("XIN","REAL","none"),("CYCLE","TIME","none")], 
   153                     "inputs" : [("RUN","BOOL","none"),("XIN","REAL","none"),("CYCLE","TIME","none")], 
   106                     "outputs" : [("XOUT","REAL","none")],
   154                     "outputs" : [("XOUT","REAL","none")],
   107                     "comment" : "Derivative\nThe derivative function block produces an output XOUT proportional to the rate of change of the input XIN."},
   155                     "comment" : "Derivative\nThe derivative function block produces an output XOUT proportional to the rate of change of the input XIN.",
       
   156                     "generate" : generate_block},
   108                 {"name" : "PID", "type" : "functionBlock", "extensible" : False, 
   157                 {"name" : "PID", "type" : "functionBlock", "extensible" : False, 
   109                     "inputs" : [("AUTO","BOOL","none"),("PV","REAL","none"),("SP","REAL","none"),("X0","REAL","none"),("KP","REAL","none"),("TR","REAL","none"),("TD","REAL","none"),("CYCLE","TIME","none")], 
   158                     "inputs" : [("AUTO","BOOL","none"),("PV","REAL","none"),("SP","REAL","none"),("X0","REAL","none"),("KP","REAL","none"),("TR","REAL","none"),("TD","REAL","none"),("CYCLE","TIME","none")], 
   110                     "outputs" : [("XOUT","REAL","none")],
   159                     "outputs" : [("XOUT","REAL","none")],
   111                     "comment" : "PID\nThe PID (proportional, Integral, Derivative) function block provides the classical three term controller for closed loop control."},
   160                     "comment" : "PID\nThe PID (proportional, Integral, Derivative) function block provides the classical three term controller for closed loop control.",
       
   161                     "generate" : generate_block},
   112                 {"name" : "RAMP", "type" : "functionBlock", "extensible" : False, 
   162                 {"name" : "RAMP", "type" : "functionBlock", "extensible" : False, 
   113                     "inputs" : [("RUN","BOOL","none"),("X0","REAL","none"),("X1","REAL","none"),("TR","TIME","none"),("CYCLE","TIME","none"),("HOLDBACK","BOOL","none"),("ERROR","REAL","none"),("PV","REAL","none")], 
   163                     "inputs" : [("RUN","BOOL","none"),("X0","REAL","none"),("X1","REAL","none"),("TR","TIME","none"),("CYCLE","TIME","none"),("HOLDBACK","BOOL","none"),("ERROR","REAL","none"),("PV","REAL","none")], 
   114                     "outputs" : [("RAMP","BOOL","none"),("XOUT","REAL","none")],
   164                     "outputs" : [("RAMP","BOOL","none"),("XOUT","REAL","none")],
   115                     "comment" : "Ramp\nThe RAMP function block is modelled on example given in the standard but with the addition of a 'Holdback' feature."},
   165                     "comment" : "Ramp\nThe RAMP function block is modelled on example given in the standard but with the addition of a 'Holdback' feature.",
       
   166                     "generate" : generate_block},
   116                 {"name" : "HYSTERESIS", "type" : "functionBlock", "extensible" : False, 
   167                 {"name" : "HYSTERESIS", "type" : "functionBlock", "extensible" : False, 
   117                     "inputs" : [("XIN1","REAL","none"),("XIN2","REAL","none"),("EPS","REAL","none")], 
   168                     "inputs" : [("XIN1","REAL","none"),("XIN2","REAL","none"),("EPS","REAL","none")], 
   118                     "outputs" : [("Q","BOOL","none")],
   169                     "outputs" : [("Q","BOOL","none")],
   119                     "comment" : "Hysteresis\nThe hysteresis function block provides a hysteresis boolean output driven by the difference of two floating point (REAL) inputs XIN1 and XIN2."},
   170                     "comment" : "Hysteresis\nThe hysteresis function block provides a hysteresis boolean output driven by the difference of two floating point (REAL) inputs XIN1 and XIN2.",
       
   171                     "generate" : generate_block},
   120                 {"name" : "RATIO_MONITOR", "type" : "functionBlock", "extensible" : False, 
   172                 {"name" : "RATIO_MONITOR", "type" : "functionBlock", "extensible" : False, 
   121                     "inputs" : [("PV1","REAL","none"),("PV2","REAL","none"),("RATIO","REAL","none"),("TIMON","TIME","none"),("TIMOFF","TIME","none"),("TOLERANCE","BOOL","none"),("RESET","BOOL","none"),("CYCLE","TIME","none")], 
   173                     "inputs" : [("PV1","REAL","none"),("PV2","REAL","none"),("RATIO","REAL","none"),("TIMON","TIME","none"),("TIMOFF","TIME","none"),("TOLERANCE","BOOL","none"),("RESET","BOOL","none"),("CYCLE","TIME","none")], 
   122                     "outputs" : [("ALARM","BOOL","none"),("TOTAL_ERR","BOOL","none")],
   174                     "outputs" : [("ALARM","BOOL","none"),("TOTAL_ERR","BOOL","none")],
   123                     "comment" : "Ratio monitor\nThe ratio_monitor function block checks that one process value PV1 is always a given ratio (defined by input RATIO) of a second process value PV2."}
   175                     "comment" : "Ratio monitor\nThe ratio_monitor function block checks that one process value PV1 is always a given ratio (defined by input RATIO) of a second process value PV2.",
       
   176                     "generate" : generate_block}
   124                 ]},
   177                 ]},
   125             {"name" : "SVGUI function blocks", "list":
       
   126                 [{"name" : "Container", "type" : "functionBlock", "extensible" : False, 
       
   127                     "inputs" : [("X","FLOAT","none"),("SetX","BOOL","none"),("Y","FLOAT","none"),("SetY","BOOL","none"),("Angle","FLOAT","none"),("SetAngle","BOOL","none")], 
       
   128                     "outputs" : [("X","FLOAT","none"),("X Changed","BOOL","none"),("Y","FLOAT","none"),("Y Changed","BOOL","none"),("Angle","FLOAT","none"),("Angle Changed","BOOL","none")],
       
   129                     "comment" : "SVGUI Container"},
       
   130                 {"name" : "Button", "type" : "functionBlock", "extensible" : False, 
       
   131                     "inputs" : [("Show","BOOL","none"),("Toggle","BOOL","none")], 
       
   132                     "outputs" : [("Visible","BOOL","none"),("State","BOOL","none")],
       
   133                     "comment" : "SVGUI Button"},
       
   134                 {"name" : "TextCtrl", "type" : "functionBlock", "extensible" : False, 
       
   135                     "inputs" : [("Text","STRING","none"),("Set Text","BOOL","none")], 
       
   136                     "outputs" : [("Text","STRING","none"),("Text Changed","BOOL","none")],
       
   137                     "comment" : "SVGUI Text Control"},
       
   138                 {"name" : "ScrollBar", "type" : "functionBlock", "extensible" : False, 
       
   139                     "inputs" : [("Position","UINT","none"),("Set Position","BOOL","none")], 
       
   140                     "outputs" : [("Position","UINT","none"),("Position Changed","BOOL","none")],
       
   141                     "comment" : "SVGUI ScrollBar"},
       
   142                 {"name" : "NoteBook", "type" : "functionBlock", "extensible" : False, 
       
   143                     "inputs" : [("Selected","UINT","none"),("Set Selected","BOOL","none")], 
       
   144                     "outputs" : [("Selected","UINT","none"),("Selected Changed","BOOL","none")],
       
   145                     "comment" : "SVGUI Notebook"},
       
   146                 {"name" : "RotatingCtrl", "type" : "functionBlock", "extensible" : False, 
       
   147                     "inputs" : [("Angle","FLOAT","none"),("Set Angle","BOOL","none")], 
       
   148                     "outputs" : [("Angle","FLOAT","none"),("Angle changed","BOOL","none")],
       
   149                     "comment" : "SVGUI Rotating Control"},
       
   150                ]}
       
   151              ]
   178              ]
       
   179              
       
   180 PluginTypes = []
   152 
   181 
   153 """
   182 """
   154 Function that returns the block definition associated to the block type given
   183 Function that returns the block definition associated to the block type given
   155 """
   184 """
   156 
   185 
   157 def GetBlockType(type, inputs = None):
   186 def GetBlockType(type, inputs = None):
   158     for category in BlockTypes:
   187     for category in BlockTypes + PluginTypes:
   159         for blocktype in category["list"]:
   188         for blocktype in category["list"]:
   160             if inputs:
   189             if inputs:
   161                 block_inputs = tuple([var_type for name, var_type, modifier in blocktype["inputs"]])
   190                 block_inputs = tuple([var_type for name, var_type, modifier in blocktype["inputs"]])
   162                 same_inputs = inputs == block_inputs
   191                 same_inputs = inputs == block_inputs
   163             else:
   192             else:
   164                 same_inputs = True
   193                 same_inputs = True
   165             if blocktype["name"] == type and same_inputs:
   194             if blocktype["name"] == type and same_inputs:
   166                 return blocktype
   195                 return blocktype
   167     return None
   196     return None
   168 
   197 
       
   198 """
       
   199 Function that add a new plugin to the plugin list
       
   200 """
       
   201 
       
   202 def AddPlugin(blocklist):
       
   203     PluginTypes.append(blocklist)
   169 
   204 
   170 #-------------------------------------------------------------------------------
   205 #-------------------------------------------------------------------------------
   171 #                           Data Types definitions
   206 #                           Data Types definitions
   172 #-------------------------------------------------------------------------------
   207 #-------------------------------------------------------------------------------
   173 
   208 
   453                 Current_section = {"name" : fields[0], "list" : []}
   488                 Current_section = {"name" : fields[0], "list" : []}
   454                 Standard_Functions_Decl.append(Current_section)
   489                 Standard_Functions_Decl.append(Current_section)
   455                 Function_decl_list = []
   490                 Function_decl_list = []
   456             if Current_section:
   491             if Current_section:
   457                 Function_decl = dict([(champ, val) for champ, val in zip(fonctions, fields[1:]) if champ])
   492                 Function_decl = dict([(champ, val) for champ, val in zip(fonctions, fields[1:]) if champ])
       
   493                 Function_decl["generate"] = generate_block
   458                 baseinputnumber = int(Function_decl.get("baseinputnumber",1))
   494                 baseinputnumber = int(Function_decl.get("baseinputnumber",1))
   459                 Function_decl["baseinputnumber"] = baseinputnumber
   495                 Function_decl["baseinputnumber"] = baseinputnumber
   460                 for param, value in Function_decl.iteritems():
   496                 for param, value in Function_decl.iteritems():
   461                     if param in translate:
   497                     if param in translate:
   462                         Function_decl[param] = translate[param](value)
   498                         Function_decl[param] = translate[param](value)