Esempio n. 1
0
    def generate(self):
        resources = {}

        machine = self.symtab.state_machine
        if machine is None:
            self.error("Action declaration not part of a machine.")

        if self.statement_list:
            # Add new local vars
            self.symtab.pushFrame()

            addr_type = self.symtab.find("Addr", Type)

            if addr_type is None:
                self.error("Type 'Addr' not declared.")

            var = Var(self.symtab, "address", self.location, addr_type,
                      "addr", self.pairs)
            self.symtab.newSymbol(var)

            #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            #fanyao added
            int_type = self.symtab.find("int", Type)

            if int_type is None:
                self.error("Type 'int' not declared.")
            var = Var(self.symtab, "core_id", self.location, int_type,
                      "core_id", self.pairs)
            self.symtab.newSymbol(var)
            #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++

            if machine.TBEType != None:
                var = Var(self.symtab, "tbe", self.location, machine.TBEType,
                      "m_tbe_ptr", self.pairs)
                self.symtab.newSymbol(var)

            if machine.EntryType != None:
                var = Var(self.symtab, "cache_entry", self.location,
                          machine.EntryType, "m_cache_entry_ptr", self.pairs)
                self.symtab.newSymbol(var)

            # Do not allows returns in actions
            code = self.slicc.codeFormatter()
            self.statement_list.generate(code, None)
            self.pairs["c_code"] = str(code)

            self.statement_list.findResources(resources)

            self.symtab.popFrame()

        action = Action(self.symtab, self.ident, resources, self.location,
                        self.pairs)
        machine.addAction(action)
Esempio n. 2
0
    def generate(self):
        resources = {}
        if self.statement_list:
            # Add new local vars
            self.symtab.pushFrame()

            addr_type = self.symtab.find("Address", Type)

            if addr_type is None:
                self.error("Type 'Address' not declared.")

            var = Var(self.symtab, "address", self.location, addr_type, "addr",
                      self.pairs)
            self.symtab.newSymbol(var)

            # Do not allows returns in actions
            code = self.slicc.codeFormatter()
            self.statement_list.generate(code, None)
            self.pairs["c_code"] = str(code)

            self.statement_list.findResources(resources)

            self.symtab.popFrame()

        machine = self.symtab.state_machine
        if machine is None:
            self.error("Action declaration not part of a machine.")

        action = Action(self.symtab, self.ident, resources, self.location,
                        self.pairs)
        machine.addAction(action)
Esempio n. 3
0
    def generate(self, code, return_type):
        code("{")
        code.indent()
        self.symtab.pushFrame()

        msg_type = self.type_ast.type

        # Add new local var to symbol table
        v = Var(self.symtab, "out_msg", self.location, msg_type, "*out_msg",
                self.pairs)
        self.symtab.newSymbol(v)

        # Declare message
        code("std::shared_ptr<${{msg_type.c_ident}}> out_msg = "\
             "std::make_shared<${{msg_type.c_ident}}>(clockEdge());")

        # The other statements
        t = self.statements.generate(code, None)
        self.queue_name.assertType("OutPort")

        if self.latexpr != None:
            ret_type, rcode = self.latexpr.inline(True)
            code("(${{self.queue_name.var.code}}).enqueue(" \
                 "out_msg, clockEdge(), cyclesToTicks(Cycles($rcode)));")
        else:
            code("(${{self.queue_name.var.code}}).enqueue(out_msg, "\
                 "clockEdge(), cyclesToTicks(Cycles(1)));")

        # End scope
        self.symtab.popFrame()
        code.dedent()
        code("}")
Esempio n. 4
0
    def generate(self):
        type = self.type_ast.type
        param = "param_%s" % self.ident

        # Add to symbol table
        v = Var(self.symtab, self.ident, self.location, type, param,
                self.pairs)
        self.symtab.newSymbol(v)

        # Qualifier is always a pointer for TBE table and Cache entries.
        # It's expected to be left unspecified or specified as ptr.
        qualifier = self.qualifier
        if str(type) == "TBE" or ("interface" in type and
                                  (type["interface"] == "AbstractCacheEntry")):
            if qualifier not in ["", "PTR"]:
                self.warning("Parameter \'%s\' is always pointer. "
                             "%s qualifier ignored" % (self.ident, qualifier))
            qualifier = "PTR"

        # default
        if qualifier == "":
            qualifier = "CONST_REF"

        if qualifier == "PTR":
            return type, "%s* %s" % (type.c_ident, param)
        elif qualifier == "REF":
            return type, "%s& %s" % (type.c_ident, param)
        elif qualifier == "CONST_REF":
            return type, "const %s& %s" % (type.c_ident, param)
        else:
            self.error("Invalid qualifier for param \'%s\'" % self.ident)
    def generate(self, code, return_type, **kwargs):
        code("{")
        code.indent()
        self.symtab.pushFrame()

        msg_type = self.type_ast.type

        # Add new local var to symbol table
        v = Var(self.symtab, "out_msg", self.location, msg_type, "*out_msg",
                self.pairs)
        self.symtab.newSymbol(v)

        # Declare message
        code("std::shared_ptr<${{msg_type.c_ident}}> out_msg = "\
             "std::make_shared<${{msg_type.c_ident}}>(clockEdge());")

        # The other statements
        t = self.statements.generate(code, None)
        self.queue_name.assertType("OutPort")

        code("(${{self.queue_name.var.code}}).deferEnqueueingMessage(addr, "\
             "out_msg);")

        # End scope
        self.symtab.popFrame()
        code.dedent()
        code("}")
Esempio n. 6
0
    def generate(self, parent=None):
        if "network" in self and not ("virtual_network" in self
                                      or "physical_network" in self):
            self.error("Network queues require a 'virtual_network' attribute")

        type = self.type_ast.type

        if type.isBuffer and "ordered" not in self:
            self.error("Buffer object decls require an 'ordered' attribute")

        if "ordered" in self:
            value = self["ordered"]

            if value not in ("true", "false"):
                self.error("The 'ordered' attribute is '%s' " + \
                           "must be 'true' or 'false'.", value)

        if "random" in self:
            value = self["random"]
            if value not in ("true", "false"):
                self.error("The 'random' attribute is '%s' " + \
                           "must be 'true' or 'false'.", value)

        # FIXME : should all use accessors here to avoid public member
        # variables
        if self.ident == "version":
            c_code = "m_version"
        elif self.ident == "machineID":
            c_code = "m_machineID"
        elif self.ident == "clusterID":
            c_code = "m_clusterID"
        else:
            c_code = "(*m_%s_ptr)" % (self.ident)

        # check type if this is a initialization
        init_code = ""
        if self.rvalue:
            rvalue_type, init_code = self.rvalue.inline(True)
            if type != rvalue_type:
                self.error("Initialization type mismatch '%s' and '%s'" % \
                           (type, rvalue_type))

        machine = self.symtab.state_machine

        v = Var(self.symtab, self.ident, self.location, type, c_code,
                self.pairs, machine)

        # Add data member to the parent type
        if parent:
            if not parent.addDataMember(self.ident, type, self.pairs,
                                        init_code):
                self.error("Duplicate data member: %s:%s" %
                           (parent, self.ident))

        elif machine:
            machine.addObject(v)

        else:
            self.symtab.newSymbol(v)
Esempio n. 7
0
    def generate(self):
        type = self.type_ast.type
        param = "param_%s" % self.ident

        # Add to symbol table
        v = Var(self.symtab, self.ident, self.location, type, param,
                self.pairs)
        self.symtab.newSymbol(v)
        return type, "%s %s" % (type.c_ident, param)
    def generate(self):
        machineComponentSym = False

        self["chip_object"] = "yes"

        if "hack" in self:
            warning("'hack=' is now deprecated")

        if "network" in self and "virtual_network" not in self:
            self.error("Network queues require a 'virtual_network' attribute")

        type = self.type_ast.type
        if type.isBuffer and "ordered" not in self:
            self.error("Buffer object decls require an 'ordered' attribute")

        if "ordered" in self:
            value = self["ordered"]

            if value not in ("true", "false"):
                self.error("The 'ordered' attribute is '%s' " + \
                           "must be 'true' or 'false'.", value)

        if "random" in self:
            value = self["random"]
            if value not in ("true", "false"):
                self.error("The 'random' attribute is '%s' " + \
                           "must be 'true' or 'false'.", value)

        machine = self.symtab.state_machine

        # FIXME : should all use accessors here to avoid public member
        # variables
        if self.ident == "id":
            c_code = "m_chip_ptr.getID()"
        elif self.ident == "version":
            c_code = "m_version"
        elif self.ident == "machineID":
            c_code = "m_machineID"
        elif machine:
            c_code = "(*m_%s_%s_ptr)" % (machine.ident, self.ident)
        else:
            c_code = "(*m_%s_ptr)" % (self.ident)

        v = Var(self.symtab, self.ident, self.location, type, c_code,
                self.pairs, machine)

        if machine:
            machine.addObject(v)

        self.symtab.newSymbol(v)

        # used to cheat-- that is, access components in other machines
        if machineComponentSym:
            self.symtab.newMachComponentSym(v)
Esempio n. 9
0
    def generate(self, code, return_type):
        self.symtab.pushFrame()

        msg_type = self.type_ast.type

        # Add new local var to symbol table
        var = Var(self.symtab, "in_msg", self.location, msg_type, "(*in_msg_ptr)",
                  self.pairs)
        self.symtab.newSymbol(var)

        # Check the queue type
        self.queue_name.assertType("InPort")

        # Declare the new "in_msg_ptr" variable
        mtid = msg_type.c_ident
        qcode = self.queue_name.var.code
        code('''
{
    // Declare message
    const $mtid* in_msg_ptr M5_VAR_USED;
    in_msg_ptr = dynamic_cast<const $mtid *>(($qcode).${{self.method}}());
    if (in_msg_ptr == NULL) {
        // If the cast fails, this is the wrong inport (wrong message type).
        // Throw an exception, and the caller will decide to either try a
        // different inport or punt.
        throw RejectException();
    }
''')

        if self.pairs.has_key("block_on"):
            address_field = self.pairs['block_on']
            code('''
    if (m_is_blocking &&
        (m_block_map.count(in_msg_ptr->m_$address_field) == 1) &&
        (m_block_map[in_msg_ptr->m_$address_field] != &$qcode)) {
            $qcode.delayHead();
            continue;
    }
            ''')

        if self.pairs.has_key("wake_up"):
            address_field = self.pairs['wake_up']
            code('''
    if (m_waiting_buffers.count(in_msg_ptr->m_$address_field) > 0) {
        wakeUpBuffers(in_msg_ptr->m_$address_field);
    }
            ''')

        # The other statements
        self.statements.generate(code, return_type)
        self.symtab.popFrame()
        code("}")
Esempio n. 10
0
    def generate(self):
        type = self.type_ast.type
        param = "param_%s" % self.ident

        # Add to symbol table
        v = Var(self.symtab, self.ident, self.location, type, param,
                self.pairs)
        self.symtab.newSymbol(v)
        if self.pointer or str(type) == "TBE" or (
                "interface" in type and
            (type["interface"] == "AbstractCacheEntry"
             or type["interface"] == "AbstractEntry")):
            return type, "%s* %s" % (type.c_ident, param)
        else:
            return type, "const %s& %s" % (type.c_ident, param)
Esempio n. 11
0
    def generate(self, code, return_type):
        self.symtab.pushFrame()

        msg_type = self.type_ast.type

        # Add new local var to symbol table
        var = Var(self.symtab, "in_msg", self.location, msg_type,
                  "(*in_msg_ptr)", self.pairs)
        self.symtab.newSymbol(var)

        # Check the queue type
        self.queue_name.assertType("InPort")

        # Declare the new "in_msg_ptr" variable
        mtid = msg_type.ident
        qcode = self.queue_name.var.code
        code('''
{
    // Declare message
    const $mtid* in_msg_ptr M5_VAR_USED;
    in_msg_ptr = dynamic_cast<const $mtid *>(($qcode).${{self.method}}());
    assert(in_msg_ptr != NULL); // Check the cast result
''')

        if self.pairs.has_key("block_on"):
            address_field = self.pairs['block_on']
            code('''
    if ( (m_is_blocking == true) &&
         (m_block_map.count(in_msg_ptr->m_$address_field) == 1) ) {
         if (m_block_map[in_msg_ptr->m_$address_field] != &$qcode) {
            $qcode.delayHead();
            continue;
         }
    }
            ''')

        if self.pairs.has_key("wake_up"):
            address_field = self.pairs['wake_up']
            code('''
    if (m_waiting_buffers.count(in_msg_ptr->m_$address_field) > 0) {
        wakeUpBuffers(in_msg_ptr->m_$address_field);
    }
            ''')

        # The other statements
        self.statements.generate(code, return_type)
        self.symtab.popFrame()
        code("}")
Esempio n. 12
0
    def generate(self, code):
        type = self.type_ast.type
        ident = "%s" % self.ident

        # Add to symbol table
        v = Var(self.symtab, self.ident, self.location, type, ident,
                self.pairs)
        self.symtab.newSymbol(v)
        if self.pointer or str(type) == "TBE" or (
                "interface" in type and
            (type["interface"] == "AbstractCacheEntry"
             or type["interface"] == "AbstractEntry")):
            code += "%s* %s" % (type.c_ident, ident)
        else:
            code += "%s %s" % (type.c_ident, ident)
        return type
Esempio n. 13
0
    def generate(self, code):
        type = self.type_ast.type;
        ident = "%s" % self.ident;

        # Add to symbol table
        v = Var(self.symtab, self.ident, self.location, type, ident,
                self.pairs)
        self.symtab.newSymbol(v)
        if self.pointer or str(type) == "TBE" or (
        # Check whether type is Entry by checking interface since
        # entries in protocol files use AbstractCacheEntry as interfaces.
           "interface" in type and (
               type["interface"] == "AbstractCacheEntry")):
            code += "%s* %s" % (type.c_ident, ident)
        else:
            code += "%s %s" % (type.c_ident, ident)
        return type
Esempio n. 14
0
    def generate(self):
        code = self.slicc.codeFormatter(newlines=False)

        queue_type = self.var_expr.generate(code)
        if not queue_type.isOutPort:
            self.error(
                "The outport queue's type must have the 'outport' " +
                "attribute.  Type '%s' does not have this attribute.",
                (queue_type))

        if not self.symtab.find(self.msg_type.ident, Type):
            self.error("The message type '%s' does not exist.",
                       self.msg_type.ident)

        var = Var(self.symtab, self.ident, self.location, self.queue_type.type,
                  str(code), self.pairs)
        self.symtab.newSymbol(var)
Esempio n. 15
0
    def generate(self):
        type = self.type_ast.type
        param = "param_%s" % self.ident

        # Add to symbol table
        v = Var(self.symtab, self.ident, self.location, type, param,
                self.pairs)
        self.symtab.newSymbol(v)

        if self.pointer or str(type) == "TBE" or (
                # Check whether type is entry by checking the interface since
                # in protocol files, entries use AbstractCacheEntry as interfaces.
                "interface" in type and
            (type["interface"] == "AbstractCacheEntry")):
            return type, "%s* %s" % (type.c_ident, param)
        else:
            return type, "const %s& %s" % (type.c_ident, param)
    def generate(self):
        if "network" in self and not ("virtual_network" in self
                                      or "physical_network" in self):
            self.error("Network queues require a 'virtual_network' attribute")

        type = self.type_ast.type
        if type.isBuffer and "ordered" not in self:
            self.error("Buffer object decls require an 'ordered' attribute")

        if "ordered" in self:
            value = self["ordered"]

            if value not in ("true", "false"):
                self.error("The 'ordered' attribute is '%s' " + \
                           "must be 'true' or 'false'.", value)

        if "random" in self:
            value = self["random"]
            if value not in ("true", "false"):
                self.error("The 'random' attribute is '%s' " + \
                           "must be 'true' or 'false'.", value)

        machine = self.symtab.state_machine

        # FIXME : should all use accessors here to avoid public member
        # variables
        if self.ident == "version":
            c_code = "m_version"
        elif self.ident == "machineID":
            c_code = "m_machineID"
        elif self.ident == "clusterID":
            c_code = "m_clusterID"
        elif machine:
            c_code = "(*m_%s_%s_ptr)" % (machine.ident, self.ident)
        else:
            c_code = "(*m_%s_ptr)" % (self.ident)

        v = Var(self.symtab, self.ident, self.location, type, c_code,
                self.pairs, machine)

        if machine:
            machine.addObject(v)

        self.symtab.newSymbol(v)
Esempio n. 17
0
    def generate(self, parent = None):
        if "network" in self and not ("virtual_network" in self or
                                      "physical_network" in self) :
            self.error("Network queues require a 'virtual_network' attribute")

        type = self.type_ast.type

        # FIXME : should all use accessors here to avoid public member
        # variables
        if self.ident == "version":
            c_code = "m_version"
        elif self.ident == "machineID":
            c_code = "m_machineID"
        elif self.ident == "clusterID":
            c_code = "m_clusterID"
        elif self.ident == "recycle_latency":
            c_code = "m_recycle_latency"
        else:
            c_code = "(*m_%s_ptr)" % (self.ident)

        # check type if this is a initialization
        init_code = ""
        if self.rvalue:
            rvalue_type,init_code = self.rvalue.inline(True)
            if type != rvalue_type:
                self.error("Initialization type mismatch '%s' and '%s'" % \
                           (type, rvalue_type))

        machine = self.symtab.state_machine

        v = Var(self.symtab, self.ident, self.location, type, c_code,
                self.pairs, machine)

        # Add data member to the parent type
        if parent:
            if not parent.addDataMember(self.ident, type, self.pairs, init_code):
                self.error("Duplicate data member: %s:%s" % (parent, self.ident))

        elif machine:
            machine.addObject(v)

        else:
            self.symtab.newSymbol(v)
Esempio n. 18
0
    def generate(self, code, return_type):
        code("{")
        code.indent()
        self.symtab.pushFrame()

        msg_type = self.type_ast.type

        # Add new local var to symbol table
        v = Var(self.symtab, "out_msg", self.location, msg_type, "*out_msg",
                self.pairs)
        self.symtab.newSymbol(v)

        # Declare message
        code("${{msg_type.ident}} *out_msg = "\
             "new ${{msg_type.ident}}(clockEdge());")

        # The other statements
        t = self.statements.generate(code, None)

        self.queue_name.assertType("OutPort")

        args = ["out_msg"]
        if "latency" in self:
            latency = self["latency"]
            try:
                # see if this is an integer
                latency = int(latency)
                args.append("Cycles(%s)" % latency)
            except ValueError:
                # if not, it should be a member
                args.append("m_%s" % latency)

        args = ", ".join(args)
        code('(${{self.queue_name.var.code}}).enqueue($args);')

        # End scope
        self.symtab.popFrame()
        code.dedent()
        code("}")
Esempio n. 19
0
    def generate(self):
        symtab = self.symtab
        void_type = symtab.find("void", Type)

        machine = symtab.state_machine
        if machine is None:
            self.error("InPort declaration not part of a machine.")

        code = self.slicc.codeFormatter()
        queue_type = self.var_expr.generate(code)
        if not queue_type.isInPort:
            self.error("The inport queue's type must have the 'inport' " + \
                       "attribute.  Type '%s' does not have this attribute.",
                       queue_type)

        type = self.queue_type.type
        in_port = Var(self.symtab, self.ident, self.location, type, str(code),
                      self.pairs)
        symtab.newSymbol(in_port)

        symtab.pushFrame()
        param_types = []

        # Check for Event
        type = symtab.find("Event", Type)
        if type is None:
            self.error("in_port decls require 'Event' enumeration defined")
        param_types.append(type)

        # Check for Address
        type = symtab.find("Address", Type)
        if type is None:
            self.error("in_port decls require 'Address' type to be defined")

        param_types.append(type)

        if machine.EntryType != None:
            param_types.append(machine.EntryType)
        if machine.TBEType != None:
            param_types.append(machine.TBEType)

        # Add the trigger method - FIXME, this is a bit dirty
        pairs = {"external": "yes"}
        func = Func(self.symtab, "trigger", self.location, void_type,
                    param_types, [], "", pairs)
        symtab.newSymbol(func)

        param_types = []
        # Check for Event2
        type = symtab.find("Event", Type)
        if type is None:
            self.error("in_port decls require 'Event' enumeration")

        param_types.append(type)

        # Check for Address2
        type = symtab.find("Address", Type)
        if type is None:
            self.error("in_port decls require 'Address' type to be defined")

        param_types.append(type)

        if self.statements is not None:
            rcode = self.slicc.codeFormatter()
            rcode.indent()
            rcode.indent()
            self.statements.generate(rcode, None)
            in_port["c_code_in_port"] = str(rcode)

        symtab.popFrame()

        # Add port to state machine
        machine.addInPort(in_port)

        # Include max_rank to be used by StateMachine.py
        in_port["max_port_rank"] = InPortDeclAST.max_port_rank
Esempio n. 20
0
    def generate(self):
        symtab = self.symtab
        void_type = symtab.find("void", Type)

        machine = symtab.state_machine
        if machine is None:
            self.error("InPort declaration not part of a machine.")

        code = self.slicc.codeFormatter()
        queue_type = self.var_expr.generate(code)
        if not queue_type.isInPort:
            self.error("The inport queue's type must have the 'inport' " + \
                       "attribute.  Type '%s' does not have this attribute.",
                       queue_type)

        type = self.queue_type.type
        in_port = Var(self.symtab, self.ident, self.location, type, str(code),
                      self.pairs, machine, self.var_expr)
        symtab.newSymbol(in_port)

        symtab.pushFrame()
        param_types = []

        # Check for Event
        type = symtab.find("Event", Type)
        if type is None:
            self.error("in_port decls require 'Event' enumeration defined")
        param_types.append(type)

        # Check for Address
        type = symtab.find("Addr", Type)
        if type is None:
            self.error("in_port decls require 'Addr' type to be defined")

        param_types.append(type)

        if machine.EntryType != None:
            param_types.append(machine.EntryType)
        if machine.TBEType != None:
            param_types.append(machine.TBEType)

        # Add the trigger method - FIXME, this is a bit dirty
        pairs = {"external": "yes"}
        trigger_func_name = "trigger"
        for param in param_types:
            trigger_func_name += "_" + param.ident
        func = Func(self.symtab, trigger_func_name, "trigger", self.location,
                    void_type, param_types, [], "", pairs)
        symtab.newSymbol(func)

        # Add the stallPort method - this hacks reschedules the controller
        # for stalled messages that don't trigger events
        func = Func(self.symtab, "stallPort", "stallPort", self.location,
                    void_type, [], [], "", pairs)
        symtab.newSymbol(func)

        param_types = []
        # Check for Event2
        type = symtab.find("Event", Type)
        if type is None:
            self.error("in_port decls require 'Event' enumeration")

        param_types.append(type)

        # Check for Address2
        type = symtab.find("Addr", Type)
        if type is None:
            self.error("in_port decls require 'Addr' type to be defined")

        param_types.append(type)

        if self.statements is not None:
            rcode = self.slicc.codeFormatter()
            rcode.indent()
            rcode.indent()
            self.statements.generate(rcode, None)
            in_port["c_code_in_port"] = str(rcode)

        symtab.popFrame()

        # Add port to state machine
        machine.addInPort(in_port)
Esempio n. 21
0
    def generate(self):
        symtab = self.symtab
        void_type = symtab.find("void", Type)

        machine = symtab.state_machine
        if machine is None:
            self.error("InPort declaration not part of a machine.")

        code = self.slicc.codeFormatter()
        queue_type = self.var_expr.generate(code)
        if not queue_type.isInPort:
            self.error("The inport queue's type must have the 'inport' " + \
                       "attribute.  Type '%s' does not have this attribute.",
                       queue_type)

        type = self.queue_type.type
        in_port = Var(self.symtab, self.ident, self.location, type, str(code),
                      self.pairs)
        symtab.newSymbol(in_port)

        symtab.pushFrame()
        param_types = []

        # Check for Event
        type = symtab.find("Event", Type)
        if type is None:
            self.error("in_port decls require 'Event' enumeration defined")
        param_types.append(type)

        # Check for Address
        type = symtab.find("Address", Type)
        if type is None:
            self.error("in_port decls require 'Address' type to be defined")

        param_types.append(type)

        if machine.EntryType != None:
            param_types.append(machine.EntryType)
        if machine.TBEType != None:
            param_types.append(machine.TBEType)

        # Add the trigger method - FIXME, this is a bit dirty
        pairs = { "external" : "yes" }
        func = Func(self.symtab, "trigger", self.location, void_type,
                    param_types, [], "", pairs)
        symtab.newSymbol(func)

        param_types = []
        # Check for Event2
        type = symtab.find("Event", Type)
        if type is None:
            self.error("in_port decls require 'Event' enumeration")

        param_types.append(type)

        # Check for Address2
        type = symtab.find("Address", Type)
        if type is None:
            self.error("in_port decls require 'Address' type to be defined")

        param_types.append(type)

        # Add the doubleTrigger method - this hack supports tiggering
        # two simulateous events
        #
        # The key is that the second transistion cannot fail because
        # the first event cannot be undone therefore you must do some
        # checks before calling double trigger to ensure that won't
        # happen
        func = Func(self.symtab, "doubleTrigger", self.location, void_type,
                    param_types, [], "", pairs)
        symtab.newSymbol(func)

        # Add the continueProcessing method - this hack supports
        # messages that don't trigger events
        func = Func(self.symtab, "continueProcessing", self.location,
                    void_type, [], [], "", pairs)
        symtab.newSymbol(func)

        if self.statements is not None:
            rcode = self.slicc.codeFormatter()
            rcode.indent()
            rcode.indent()
            self.statements.generate(rcode, None)
            in_port["c_code_in_port"] = str(rcode)

        symtab.popFrame()

        # Add port to state machine
        machine.addInPort(in_port)

        # Include max_rank to be used by StateMachine.py
        in_port["max_port_rank"] = InPortDeclAST.max_port_rank