Adding gem5 source to svn.

git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1819 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
friemel
2012-10-24 19:18:57 +00:00
parent f7ff71bd46
commit b41eec3f65
3222 changed files with 658579 additions and 1 deletions

View File

@ -0,0 +1,114 @@
Overview
========
This is SLICC, a domain specific language to specify cache coherence protocol
we have developed in Multifacet group.
It is developed by Milo Martin <milo@cs.wisc.edu>
This document is prepared by Min Xu <mxu@cae.wisc.edu> while I am learning the
system. With minor correctness updates by Brad Beckmann <beckmann@cs.wisc.edu>
It can be used to generate C++ code that works with RUBY cache simulator as
well as generate HTML and other document to describe the target protocol.
Some user document is available in doc directory.
Tech details
============
SLICC take a text input with similar syntax to C++ language and use the lexer
and parser in parser directory to construct a Abstract Syntax Tree (AST)
internally. After having done this first pass, the AST is traversed to fill
several interval table, such as symbol table, type table, etc. Finally the code
is generated by traversing the tree once again.
Note, by Milo's good coding habit, almost all C++ class define their private
copy/assignment constructor. This prevents accidentally copying/assigning an
object by its address.
The AST basically looks like a hierarchical representation of the text input.
At the highest level, it has the "Machine", each Machine has several "states"
and "events" and "actions" and "transistions".
Since the language is domain specific, many assumptions of the target system is
hardcoded in SLICC. For example, ruby would expect the generated code for each
system node, has the following components:
processor(sequencer, not generated?)
cache
directory (with memory block value, only when compiled with tester)
network interface (NI)
Directory generator/ contains routines to generate HTML/MIF format output.
fileio.[Ch] has a routine to conditionally write a file only when the original
content of the file is different from what is going to be written, this avoid
re-make those file after regenerate the protocol. html_gen.[Ch] contains the
symbol name munge and index page generation. mif_gen.[Ch] contains the entire
MIF output generation routine, mainly a table buildup.
Directory symbol/ contains classes to represent symbols in the slicc input
file. Base class is "Symbol". Derived subclasses are "Action Event Func State
StateMachine Transition Type Var". "Symbol" has knowledge about its locations
in the source file and short name, long name. "SymbolTable" is a list of
symbols and g_sym_table is the global SymbolTable of the slicc system.
One can query a SymbolTable by symbol's id. Also SymbolTable is responsible for
keeping track of Symbol's declaration in correct scope. The current
implementation uses a stack which dynamically determine the scope of symbol
lookups. Global scope is at bottom of the stack (vector[0]). SymbolTable is
also the main place to write out the generated C++/HTML/MIF files.
SymbolTable::writeNodeFiles() is one of the place to look for hardcoded C++
code for node.[Ch]. And Type.[Ch] is the place where generating enumeration and
Message/NetworkMessage declaration and implementation. Func.[Ch] is used to
generate function of the class Chip. StateMachine.[Ch] wrap the whole thing
up by putting States, Actions, Events together. It actually has a two dimension
table like the one represented in the HTML output. Actions are indexed with
the initial state and observed event. After the tabel being built, the
StateMachine class can write out Transitions/Controller/wakeup_logic into C++
outputs. Finally, in symbol directory, Var.[Ch] seem to incomplete?
Demystify all those "predefined" external types, like "Address". Where are
they defined? They are in ../protocol/RubySlicc-*.sm and
../protocol/RubySlicc_interfaces.slicc is include in the slicc invocation
command in ../ruby/Makefile.
Another myth: "trigger" method is hardcoded in ast/InPortDeclAST.C and
ast/FuncCallExprAST.C. The function is similar to inlined function in the
output generated code, so you cannot find any occurance of string "trigger" in
the generated code. "trigger" also increment a counter that is checked every
time a transition is done. In one ruby cycle, only TRANSITIONS_PER_RUBY_CYCLE
number of transitions can be done. ast/FuncCallExprAST.C also contains some
code for function "error" and "assert" and "DEBUG_EXPR", all in the same
manner. Ruby always issues transitions from the first port while there is any.
Stalled transition in Ruby does not consume a sub-cycle. This models the
hardware that probe all port in parallel, pick one transition from the highest
priority queue if the transistion was not stalled by any resources constraint.
Another note: scheduleEvent() call of ruby make sure a consumer is woken up at
specified cycle, and only once per cycle.
Action z_stall, where is it? It is hardcoded in symbols/StateMachine.C. In
function StateMachine::printCSwitch(), z_stall cause the generated code return
TransitionResult_ProtocolStall. Also the HTML output for z_stall has to be
consequently hardcoded. I am not sure that's really a good idea or not. :-)
Question: How comes there is no "for" loop statement in slicc?
Answer: Been there, done that. That is easy to add, first of all. But unbound
loop make slicc eventually un-synthesizable. We want to avoid that. If you want
to loop through a bounded array do something, make the action done in a
external interface in RubySlicc_Util.h. Inside, you just pass the vector as
parameter to the external interface to achieve the same effects.
Another bad thing of using loop statement like for is that we can not determine
how many buffer space to allocate before the transition. With a vector, if it
easy to understand we can always allocate the worst case number of hardware
resources.
Question: Wait! It seems statement check_allocate does nothing!
Answer: No, it does call areNSoltsAvailable() function of the object before any
statement is executed in one action. It does *NOT* generate code in its
original place in the code, instead, it scan the body of the action code and
determine how many slots are needed to allocated before hand. So the
transaction is all done or nothing done. I had tried to make all actions return
boolean values and the false return cause a transition to abort with
ResourceStall. But it is later on deemed to be too flexible in its semantics.
We should never introduce control flow inside the transitions, so that each
transition is either "all" or "nothing". Just that simple. BTW, if you call
check_allocate twice, areNSoltsAvailable(2) is generated, three times generates
areNSoltsAvailable(3), etc.

View File

@ -0,0 +1,25 @@
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,67 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.util import PairContainer, Location
class AST(PairContainer):
def __init__(self, slicc, pairs=None):
self.slicc = slicc
self.location = slicc.currentLocation()
self.pairs = {}
if pairs:
self.pairs.update(getattr(pairs, "pairs", pairs))
@property
def symtab(self):
return self.slicc.symtab
@property
def state_machine(self):
return self.slicc.symtab.state_machine
def warning(self, message, *args):
self.location.warning(message, *args)
def error(self, message, *args):
self.location.error(message, *args)
def embedError(self, message, *args):
if args:
message = message % args
code = self.slicc.codeFormatter()
code('''
char c;
cerr << "Runtime Error at ${{self.location}}, Ruby Time: "
<< g_eventQueue_ptr->getTime() << ": "
<< $message
<< ", PID: " << getpid() << endl
<< "press return to continue." << endl;
cin.get(c);
abort();
''')
return code

View File

@ -0,0 +1,81 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.DeclAST import DeclAST
from slicc.symbols import Action, Type, Var
class ActionDeclAST(DeclAST):
def __init__(self, slicc, ident, pairs, statement_list):
super(ActionDeclAST, self).__init__(slicc, pairs)
self.ident = ident
self.statement_list = statement_list
def __repr__(self):
return "[ActionDecl: %r]" % (self.ident)
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("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)
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)

View File

@ -0,0 +1,57 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.StatementAST import StatementAST
class AssignStatementAST(StatementAST):
def __init__(self, slicc, lvalue, rvalue):
super(AssignStatementAST, self).__init__(slicc)
self.lvalue = lvalue
self.rvalue = rvalue
def __repr__(self):
return "[AssignStatementAST: %r := %r]" % (self.lvalue, self.rvalue)
def generate(self, code, return_type):
lcode = self.slicc.codeFormatter()
rcode = self.slicc.codeFormatter()
ltype = self.lvalue.generate(lcode)
rtype = self.rvalue.generate(rcode)
code("$lcode = $rcode;")
if ltype != rtype:
# FIXME - beckmann
# the following if statement is a hack to allow NetDest
# objects to be assigned to Sets this allows for the
# previous NetworkMessage Destiantion 'Set class' to
# migrate to the new NetworkMessage Destiantion 'NetDest
# class'
if str(ltype) != "NetDest" and str(rtype) != "Set":
self.error("Assignment type mismatch '%s' and '%s'",
ltype, rtype)

View File

@ -0,0 +1,47 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.StatementAST import StatementAST
class CheckAllocateStatementAST(StatementAST):
def __init__(self, slicc, variable):
super(StatementAST, self).__init__(slicc)
self.variable = variable
def __repr__(self):
return "[CheckAllocateStatementAst: %r]" % self.variable
def generate(self, code, return_type):
# FIXME - check the type of the variable
# Make sure the variable is valid
self.variable.var
def findResources(self, resources):
var = self.variable.var
res_count = int(resources.get(var, 0))
resources[var] = str(res_count + 1)

View File

@ -0,0 +1,74 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.StatementAST import StatementAST
class CheckStopSlotsStatementAST(StatementAST):
def __init__(self, slicc, variable, condStr, bankStr):
super(StatementAST, self).__init__(slicc)
self.variable = variable
self.condStr = condStr
self.bankStr = bankStr
def __repr__(self):
return "[CheckStopSlotsStatementAst: %r]" % self.variable
def generate(self, code, return_type):
# Make sure the variable is valid
self.variable.var
def findResources(self, resources):
var = self.variable.var
assert var not in self.resources
check_code = self.slicc.codeFormatter()
if self.condStr == "((*in_msg_ptr)).m_isOnChipSearch":
check_code('''
const Response9Msg* in_msg_ptr =
dynamic_cast<const Response9Msg*>(((*(m_chip_ptr.m_L2Cache_responseToL2Cache9_vec[m_version]))).peek());
assert(in_msg_ptr != NULL);
''')
vcode = self.variable.inline()
bank = self.bankStr
cond = self.condStr
check_code('''
if ($cond) {
auto pos = m_chip_ptr.m_DNUCAmover_ptr->getBankPos($bank)
if (!$vcode.isDisableSPossible(pos)) {
return TransitionResult_ResourceStall;
}
} else {
if (!$vcode.isDisableFPossible(pos)) {
return TransitionResult_ResourceStall;
}
}
''')
resources[var] = str(check_code)

View File

@ -0,0 +1,161 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import re
from slicc.ast.ExprAST import ExprAST
from slicc.symbols import Type
class ChipComponentAccessAST(ExprAST):
def __init__(self, slicc, machine, mach_version, component):
super(ChipComponentAccessAST, self).__init__(slicc)
self.mach_var = machine
self.comp_var = component
self.mach_ver_expr = mach_version
def __repr__(self):
return "[ChipAccessExpr: %r]" % self.expr_vec
def generate(self, code):
void_type = self.symtab.find("void", Type)
mname = self.mach_var.name
cname = self.comp_var.name
var = self.symtab.machine_components[mname][cname]
vcode = str(var.code)
if self.chip_ver_expr is not None:
# replace self.chip with specified chip
gcode = "g_system.getChip(%s)" % self.chip_ver_expr.inline()
vcode = re.sub("m_chip", gcode, vcode)
# replace default "m_version" with the version we really want
gcode = "(%s)" % self.mach_ver_expr.inline()
vcode = re.sub("m_version", gcode, vcode)
return_type, gcode = self.generate_access(var)
code("($vcode)$gcode")
return return_type
class ChipMethodAccessAST(ChipComponentAccessAST):
def __init__(self, slicc, chip_version, machine, mach_version, component,
proc_name, expr_vec):
s = super(ChipMethodAccessAST, self)
s.__init__(slicc, machine, mach_version, component)
self.chip_ver_expr = chip_version
self.expr_vec = expr_vec
self.proc_name = proc_name
def generate_access(self, var):
# generate code
paramTypes = []
gcode = []
for expr in self.expr_vec:
t,c = expr.generate()
paramTypes.append(t)
gcode.append(c)
methodId = var.type.methodId(self.proc_name, paramTypes)
# Verify that this is a method of the object
if not var.type.methodExist(methodId):
self.error("%s: Type '%s' does not have a method '%s'" % \
("Invalid method call", var.type, methodId))
expected_size = len(var.type.methodParamType(methodId))
if len(self.expr_vec) != expected_size:
# Right number of parameters
self.error("Wrong number of parameters for function name: " +\
"'%s', expected: %d, actual: %d",
self.proc_name, expected_size, len(self.expr_vec))
for expr,expected,actual in zip(self.expr_vec,
var.type.methodParamType(methodId),
paramTypes):
# Check the types of the parameter
if actual != expected:
expr.error("Type mismatch: expected: %s actual: %s",
expected, actual)
# method call
code = ".%s(%s)" % (self.proc_name, ', '.join(gcode))
# Return the return type of the method
return var.type.methodReturnType(methodId), code
class LocalChipMethodAST(ChipMethodAccessAST):
# method call from local chip
def __init__(self, slicc, machine, mach_version, component, proc_name,
expr_vec):
s = super(LocalChipMethodAST, self)
s.__init__(slicc, None, machine, mach_version, component, proc_name,
expr_vec)
class SpecifiedChipMethodAST(ChipMethodAccessAST):
# method call from specified chip
def __init__(self, slicc, chip_version, machine, mach_version, component,
proc_name, expr_vec):
s = super(SpecifiedChipMethodAST, self)
s.__init__(slicc, chip_version, machine, mach_version, component,
proc_name, expr_vec)
class ChipMemberAccessAST(ChipComponentAccessAST):
# member access from specified chip
def __init__(self, chip_version, machine, mach_version, component,
field_name):
s = super(ChipMemberAccessAST, self)
s.__init__(slicc, machine, mach_version, component)
self.chip_ver_expr = chip_version
self.field_name = field_name
def generate_access(self, var):
# Verify that this is a valid field name for this type
if not var.type.dataMemberExist(self.field_name):
self.error("Invalid object field: " +\
"Type '%s' does not have data member %s",
var.type, self.field_name)
code += ").m_%s" % self.field_name
return var.type.dataMemberType(self.field_name), code
class LocalChipMemberAST(ChipMemberAccessAST):
# member access from local chip
def __init__(self, slicc, machine, mach_version, component, field_name):
s = super(LocalChipMemberAST, self)
s.__init__(slicc, None, machine, mach_version, component, field_name)
class SpecifiedChipMemberAST(ChipMemberAccessAST):
# member access from specified chip
def __init__(self, chip_version, machine, mach_version, component,
field_name):
s = super(SpecifiedChipMemberAST, self)
s.__init__(slicc, chip_version, machine, mach_version, component,
field_name)

View File

@ -0,0 +1,52 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.StatementAST import StatementAST
class CopyHeadStatementAST(StatementAST):
def __init__(self, slicc, in_queue, out_queue, pairs):
super(CopyHeadStatementAST, self).__init__(slicc, pairs)
self.in_queue = in_queue
self.out_queue_ptr = out_queue
def __repr__(self):
return "[CopyHeadStatementAst: %r %r]" % (self.in_queue,
self.out_queue)
def generate(self, code, return_type):
self.in_queue.assertType("InPort")
self.out_queue.assertType("OutPort")
out_code = self.out_queue.var.code
in_code = self.in_queue.var.code
latency = self.get("latency", "COPY_HEAD_LATENCY")
code("$out_code.enqueue($in_code.getMsgPtrCopy(), $latency);")
def findResources(self, resources):
var = self.out_queue.var
resources[var] = str(int(resources.get(var, "0")) + 1)

View File

@ -0,0 +1,38 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.AST import AST
class DeclAST(AST):
def __init__(self, slicc, pairs):
super(DeclAST, self).__init__(slicc, pairs)
def files(self, parent=None):
return set()
def findMachines(self):
return

View File

@ -0,0 +1,53 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.AST import AST
class DeclListAST(AST):
def __init__(self, slicc, decls):
super(DeclListAST, self).__init__(slicc)
if not isinstance(decls, (list, tuple)):
decls = [ decls ]
self.decls = decls
def __repr__(self):
return "[DeclListAST: %s]" % (', '.join(repr(d) for d in self.decls))
def files(self, parent=None):
s = set()
for decl in self.decls:
s |= decl.files(parent)
return s
def generate(self):
for decl in self.decls:
decl.generate()
def findMachines(self):
for decl in self.decls:
decl.findMachines()

View File

@ -0,0 +1,86 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.StatementAST import StatementAST
from slicc.symbols import Var
class EnqueueStatementAST(StatementAST):
def __init__(self, slicc, queue_name, type_ast, pairs, statements):
super(EnqueueStatementAST, self).__init__(slicc, pairs)
self.queue_name = queue_name
self.type_ast = type_ast
self.statements = statements
def __repr__(self):
return "[EnqueueStatementAst: %s %s %s]" % \
(self.queue_name, self.type_ast.ident, self.statements)
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}};")
# 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("%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("}")
def findResources(self, resources):
var = self.queue_name.var
res_count = int(resources.get(var, 0))
resources[var] = str(res_count + 1)

View File

@ -0,0 +1,71 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.DeclAST import DeclAST
from slicc.symbols import Func, Type
class EnumDeclAST(DeclAST):
def __init__(self, slicc, type_ast, pairs, fields):
super(EnumDeclAST, self).__init__(slicc, pairs)
self.type_ast = type_ast
self.fields = fields
def __repr__(self):
return "[EnumDecl: %s]" % (self.type_ast)
def files(self, parent=None):
if "external" in self:
return set()
if parent:
ident = "%s_%s" % (parent, self.type_ast.ident)
else:
ident = self.type_ast.ident
s = set(("%s.hh" % ident, "%s.cc" % ident))
return s
def generate(self):
ident = str(self.type_ast)
# Make the new type
t = Type(self.symtab, ident, self.location, self.pairs,
self.state_machine)
self.symtab.newSymbol(t)
# Add all of the fields of the type to it
for field in self.fields:
field.generate(t)
# Add the implicit State_to_string method - FIXME, this is a bit dirty
func_id = "%s_to_string" % t.c_ident
pairs = { "external" : "yes" }
func = Func(self.symtab, func_id, self.location,
self.symtab.find("std::string", Type), [ t ], [], "",
pairs, None)
self.symtab.newSymbol(func)

View File

@ -0,0 +1,53 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.ExprAST import ExprAST
class EnumExprAST(ExprAST):
def __init__(self, slicc, type_ast, value):
super(EnumExprAST, self).__init__(slicc)
assert type_ast
assert value
self.type_ast = type_ast
self.value = value
def __repr__(self):
return "[EnumExpr: %s:%s]" % (self.type_ast, self.value)
def generate(self, code):
fix = code.nofix()
code('${{self.type_ast.type.c_ident}}_${{self.value}}')
code.fix(fix)
# Make sure the enumeration value exists
if self.value not in self.type_ast.type.enums:
self.error("Type '%s' does not have enumeration '%s'",
self.type_ast, self.value)
return self.type_ast.type

View File

@ -0,0 +1,43 @@
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.AST import AST
class ExprAST(AST):
def __init__(self, slicc):
super(ExprAST, self).__init__(slicc)
def findResources(self, resources):
# The default is no resources
pass
def inline(self, get_type=False):
code = self.slicc.codeFormatter(fix_newlines=False)
return_type = self.generate(code)
if get_type:
return return_type, code
else:
return code

View File

@ -0,0 +1,50 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.StatementAST import StatementAST
from slicc.symbols import Type
class ExprStatementAST(StatementAST):
def __init__(self, slicc, expr):
super(ExprStatementAST, self).__init__(slicc)
self.expr = expr
def __repr__(self):
return "[ExprStatementAST: %s]" % (self.expr)
def generate(self, code, return_type):
actual_type,rcode = self.expr.inline(True)
code("$rcode;")
# The return type must be void
if actual_type != self.symtab.find("void", Type):
self.expr.error("Non-void return must not be ignored, " + \
"return type is '%s'", actual_type.ident)
def findResources(self, resources):
self.expr.findResources(resources)

View File

@ -0,0 +1,60 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.AST import AST
from slicc.symbols import Var
class FormalParamAST(AST):
def __init__(self, slicc, type_ast, ident, default = None, pointer = False):
super(FormalParamAST, self).__init__(slicc)
self.type_ast = type_ast
self.ident = ident
self.default = default
self.pointer = pointer
def __repr__(self):
return "[FormalParamAST: %s]" % self.ident
@property
def name(self):
return self.ident
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)

View File

@ -0,0 +1,231 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.ExprAST import ExprAST
from slicc.symbols import Func, Type
class FuncCallExprAST(ExprAST):
def __init__(self, slicc, proc_name, exprs):
super(FuncCallExprAST, self).__init__(slicc)
self.proc_name = proc_name
self.exprs = exprs
def __repr__(self):
return "[FuncCallExpr: %s %s]" % (self.proc_name, self.exprs)
def generate(self, code):
machine = self.state_machine
if self.proc_name == "DPRINTF":
# Code for inserting the location of the DPRINTF()
# statement in the .sm file in the statement it self.
# 'self.exprs[0].location' represents the location.
# 'format' represents the second argument of the
# original DPRINTF() call. It is left unmodified.
# str_list is used for concatenating the argument
# list following the format specifier. A DPRINTF()
# call may or may not contain any arguments following
# the format specifier. These two cases need to be
# handled differently. Hence the check whether or not
# the str_list is empty.
format = "%s" % (self.exprs[1].inline())
format_length = len(format)
str_list = []
for i in range(2, len(self.exprs)):
str_list.append("%s" % self.exprs[i].inline())
if len(str_list) == 0:
code('DPRINTF(RubySlicc, "$0: $1")',
self.exprs[0].location, format[2:format_length-2])
else:
code('DPRINTF(RubySlicc, "$0: $1", $2)',
self.exprs[0].location, format[2:format_length-2],
', '.join(str_list))
return self.symtab.find("void", Type)
# hack for adding comments to profileTransition
if self.proc_name == "APPEND_TRANSITION_COMMENT":
# FIXME - check for number of parameters
code("APPEND_TRANSITION_COMMENT($0)", self.exprs[0].inline())
return self.symtab.find("void", Type)
# Look up the function in the symbol table
func = self.symtab.find(self.proc_name, Func)
# Check the types and get the code for the parameters
if func is None:
self.error("Unrecognized function name: '%s'", self.proc_name)
if len(self.exprs) != len(func.param_types):
self.error("Wrong number of arguments passed to function : '%s'" +\
" Expected %d, got %d", self.proc_name,
len(func.param_types), len(self.exprs))
cvec = []
type_vec = []
for expr,expected_type in zip(self.exprs, func.param_types):
# Check the types of the parameter
actual_type,param_code = expr.inline(True)
if actual_type != expected_type:
expr.error("Type mismatch: expected: %s actual: %s" % \
(expected_type, actual_type))
cvec.append(param_code)
type_vec.append(expected_type)
# OK, the semantics of "trigger" here is that, ports in the
# machine have different priorities. We always check the first
# port for doable transitions. If nothing/stalled, we pick one
# from the next port.
#
# One thing we have to be careful as the SLICC protocol
# writter is : If a port have two or more transitions can be
# picked from in one cycle, they must be independent.
# Otherwise, if transition A and B mean to be executed in
# sequential, and A get stalled, transition B can be issued
# erroneously. In practice, in most case, there is only one
# transition should be executed in one cycle for a given
# port. So as most of current protocols.
if self.proc_name == "trigger":
code('''
{
Address addr = ${{cvec[1]}};
''')
if machine.TBEType != None and machine.EntryType != None:
code('''
TransitionResult result = doTransition(${{cvec[0]}}, ${{cvec[2]}}, ${{cvec[3]}}, addr);
''')
elif machine.TBEType != None:
code('''
TransitionResult result = doTransition(${{cvec[0]}}, ${{cvec[2]}}, addr);
''')
elif machine.EntryType != None:
code('''
TransitionResult result = doTransition(${{cvec[0]}}, ${{cvec[2]}}, addr);
''')
else:
code('''
TransitionResult result = doTransition(${{cvec[0]}}, addr);
''')
code('''
if (result == TransitionResult_Valid) {
counter++;
continue; // Check the first port again
}
if (result == TransitionResult_ResourceStall) {
g_eventQueue_ptr->scheduleEvent(this, 1);
// Cannot do anything with this transition, go check next doable transition (mostly likely of next port)
}
}
''')
elif self.proc_name == "doubleTrigger":
# NOTE: Use the doubleTrigger call with extreme caution
# the key to double trigger is the second event triggered
# cannot fail becuase the first event cannot be undone
assert len(cvec) == 4
code('''
{
Address addr1 = ${{cvec[1]}};
TransitionResult result1 =
doTransition(${{cvec[0]}}, ${machine}_getState(addr1), addr1);
if (result1 == TransitionResult_Valid) {
//this second event cannont fail because the first event
// already took effect
Address addr2 = ${{cvec[3]}};
TransitionResult result2 = doTransition(${{cvec[2]}}, ${machine}_getState(addr2), addr2);
// ensure the event suceeded
assert(result2 == TransitionResult_Valid);
counter++;
continue; // Check the first port again
}
if (result1 == TransitionResult_ResourceStall) {
g_eventQueue_ptr->scheduleEvent(this, 1);
// Cannot do anything with this transition, go check next
// doable transition (mostly likely of next port)
}
}
''')
elif self.proc_name == "error":
code("$0", self.exprs[0].embedError(cvec[0]))
elif self.proc_name == "assert":
error = self.exprs[0].embedError('"assert failure"')
code('''
#ifndef NDEBUG
if (!(${{cvec[0]}})) {
$error
}
#endif
''')
elif self.proc_name == "continueProcessing":
code("counter++;")
code("continue; // Check the first port again")
elif self.proc_name == "set_cache_entry":
code("set_cache_entry(m_cache_entry_ptr, %s);" %(cvec[0]));
elif self.proc_name == "unset_cache_entry":
code("unset_cache_entry(m_cache_entry_ptr);");
elif self.proc_name == "set_tbe":
code("set_tbe(m_tbe_ptr, %s);" %(cvec[0]));
elif self.proc_name == "unset_tbe":
code("unset_tbe(m_tbe_ptr);");
else:
# Normal function
# if the func is internal to the chip but not the machine
# then it can only be accessed through the chip pointer
internal = ""
if "external" not in func and not func.isInternalMachineFunc:
internal = "m_chip_ptr->"
params = ""
first_param = True
for (param_code, type) in zip(cvec, type_vec):
if first_param:
params = str(param_code)
first_param = False
else:
params += ', '
params += str(param_code);
fix = code.nofix()
code('(${internal}${{func.c_ident}}($params))')
code.fix(fix)
return func.return_type

View File

@ -0,0 +1,79 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.DeclAST import DeclAST
from slicc.symbols import Func, Type
class FuncDeclAST(DeclAST):
def __init__(self, slicc, return_type, ident, formals, pairs, statements):
super(FuncDeclAST, self).__init__(slicc, pairs)
self.return_type = return_type
self.ident = ident
self.formals = formals
self.statements = statements
def __repr__(self):
return "[FuncDecl: %s]" % self.ident
def files(self, parent=None):
return set()
def generate(self):
types = []
params = []
void_type = self.symtab.find("void", Type)
# Generate definition code
self.symtab.pushFrame()
# Lookup return type
return_type = self.return_type.type
# Generate function header
for formal in self.formals:
# Lookup parameter types
type, ident = formal.generate()
types.append(type)
params.append(ident)
body = self.slicc.codeFormatter()
if self.statements is None:
self["external"] = "yes"
else:
rtype = self.statements.generate(body, return_type)
self.symtab.popFrame()
machine = self.state_machine
func = Func(self.symtab, self.ident, self.location, return_type,
types, params, str(body), self.pairs, machine)
if machine is not None:
machine.addFunc(func)
else:
self.symtab.newSymbol(func)

View File

@ -0,0 +1,76 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.StatementAST import StatementAST
from slicc.symbols import Type
class IfStatementAST(StatementAST):
def __init__(self, slicc, cond, then, else_):
super(IfStatementAST, self).__init__(slicc)
assert cond is not None
assert then is not None
self.cond = cond
self.then = then
self.else_ = else_
def __repr__(self):
return "[IfStatement: %r%r%r]" % (self.cond, self.then, self.else_)
def generate(self, code, return_type):
cond_code = self.slicc.codeFormatter()
cond_type = self.cond.generate(cond_code)
if cond_type != self.symtab.find("bool", Type):
self.cond.error("Condition of if stmt must be bool, type was '%s'",
ctype)
# Conditional
code.indent()
code('if ($cond_code) {')
# Then part
code.indent()
self.symtab.pushFrame()
self.then.generate(code, return_type)
self.symtab.popFrame()
code.dedent()
# Else part
if self.else_:
code('} else {')
code.indent()
self.symtab.pushFrame()
self.else_.generate(code, return_type)
self.symtab.popFrame()
code.dedent()
code('}') # End scope
def findResources(self, resources):
# Take a worse case look at both paths
self.then.findResources(resources)
if self.else_ is not None:
self.else_.findResources(resources)

View File

@ -0,0 +1,142 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.DeclAST import DeclAST
from slicc.ast.TypeAST import TypeAST
from slicc.symbols import Func, Type, Var
class InPortDeclAST(DeclAST):
max_port_rank = 0
def __init__(self, slicc, ident, msg_type, var_expr, pairs, statements):
super(InPortDeclAST, self).__init__(slicc, pairs)
self.ident = ident
self.msg_type = msg_type
self.var_expr = var_expr
self.statements = statements
self.queue_type = TypeAST(slicc, "InPort")
if self.pairs.has_key("rank"):
InPortDeclAST.max_port_rank = max(self.pairs["rank"],
InPortDeclAST.max_port_rank)
def __repr__(self):
return "[InPortDecl: %s]" % self.ident
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, None)
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, None)
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, None)
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

View File

@ -0,0 +1,87 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.ExprAST import ExprAST
from slicc.symbols import Type
class InfixOperatorExprAST(ExprAST):
def __init__(self, slicc, left, op, right):
super(InfixOperatorExprAST, self).__init__(slicc)
self.left = left
self.op = op
self.right = right
def __repr__(self):
return "[InfixExpr: %r %s %r]" % (self.left, self.op, self.right)
def generate(self, code):
lcode = self.slicc.codeFormatter()
rcode = self.slicc.codeFormatter()
ltype = self.left.generate(lcode)
rtype = self.right.generate(rcode)
# Figure out what the input and output types should be
if self.op in ("==", "!="):
output = "bool"
if (ltype != rtype):
self.error("Type mismatch: left and right operands of " +
"operator '%s' must be the same type. " +
"left: '%s', right: '%s'",
self.op, ltype, rtype)
else:
if self.op in ("&&", "||"):
# boolean inputs and output
inputs = "bool"
output = "bool"
elif self.op in ("==", "!=", ">=", "<=", ">", "<"):
# Integer inputs, boolean output
inputs = "int"
output = "bool"
else:
# integer inputs and output
inputs = "int"
output = "int"
inputs_type = self.symtab.find(inputs, Type)
if inputs_type != ltype:
self.left.error("Type mismatch: left operand of operator " +
"'%s' expects type '%s', actual was '%s'",
self.op, inputs, ltype)
if inputs_type != rtype:
self.right.error("Type mismatch: right operand of operator " +
"'%s' expects type '%s', actual was '%s'",
self.op, inputs, rtype)
# All is well
fix = code.nofix()
code("($lcode ${{self.op}} $rcode)")
code.fix(fix)
return self.symtab.find(output, Type)

View File

@ -0,0 +1,52 @@
#
# Copyright (c) 2011 Mark D. Hill and David A. Wood
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
from slicc.ast.ExprAST import ExprAST
from slicc.symbols import Type
class IsValidPtrExprAST(ExprAST):
def __init__(self, slicc, variable, flag):
super(IsValidPtrExprAST, self).__init__(slicc)
self.variable = variable
self.flag = flag
def __repr__(self):
return "[IsValidPtrExprAST: %r]" % self.variable
def generate(self, code):
# Make sure the variable is valid
fix = code.nofix()
code("(")
var_type, var_code = self.variable.inline(True);
if self.flag:
code("${var_code} != NULL)")
else:
code("${var_code} == NULL)")
code.fix(fix)
type = self.symtab.find("bool", Type)
return type

View File

@ -0,0 +1,55 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.ExprAST import ExprAST
from slicc.symbols import Type
class LiteralExprAST(ExprAST):
def __init__(self, slicc, literal, type):
super(LiteralExprAST, self).__init__(slicc)
self.literal = literal
self.type = type
def __repr__(self):
return "[Literal: %s]" % self.literal
def generate(self, code):
fix = code.nofix()
if self.type == "std::string":
code('("${{self.literal}}")')
elif self.type == "bool":
code('(${{str(self.literal).lower()}})')
else:
code('(${{self.literal}})')
code.fix(fix)
type = self.symtab.find(self.type, Type)
if type is None:
# Can't find the type
self.error("Internal: can't primitive type '%s'" % self.type)
return type

View File

@ -0,0 +1,61 @@
#
# Copyright (c) 2011 Mark D. Hill and David A. Wood
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
from slicc.ast.StatementAST import StatementAST
from slicc.symbols import Var
class LocalVariableAST(StatementAST):
def __init__(self, slicc, type_ast, ident, pointer = False):
super(LocalVariableAST, self).__init__(slicc)
self.type_ast = type_ast
self.ident = ident
self.pointer = pointer
def __repr__(self):
return "[LocalVariableAST: %r %r]" % (self.type_ast, self.ident)
@property
def name(self):
return self.var_name
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

View File

@ -0,0 +1,84 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.DeclAST import DeclAST
from slicc.symbols import StateMachine, Type
class MachineAST(DeclAST):
def __init__(self, slicc, ident, pairs_ast, config_parameters, decls):
super(MachineAST, self).__init__(slicc, pairs_ast)
self.ident = ident
self.pairs_ast = pairs_ast
self.config_parameters = config_parameters
self.decls = decls
def __repr__(self):
return "[Machine: %r]" % self.ident
def files(self, parent=None):
s = set(('%s_Controller.cc' % self.ident,
'%s_Controller.hh' % self.ident,
'%s_Controller.py' % self.ident,
'%s_Profiler.cc' % self.ident,
'%s_Profiler.hh' % self.ident,
'%s_ProfileDumper.cc' % self.ident,
'%s_ProfileDumper.hh' % self.ident,
'%s_Transitions.cc' % self.ident,
'%s_Wakeup.cc' % self.ident))
s |= self.decls.files(self.ident)
return s
def generate(self):
# Make a new frame
self.symtab.pushFrame()
# Create a new machine
machine = StateMachine(self.symtab, self.ident, self.location,
self.pairs, self.config_parameters)
self.symtab.newCurrentMachine(machine)
# Generate code for all the internal decls
self.decls.generate()
# Build the transition table
machine.buildTable()
# Pop the frame
self.symtab.popFrame()
def findMachines(self):
# Add to MachineType enumeration
machine_type = self.symtab.find("MachineType", Type)
if not machine_type.enumAdd(self.ident, self.pairs_ast.pairs):
self.error("Duplicate machine name: %s:%s" % (machine_type,
self.ident))
# Generate code for all the internal decls
self.decls.findMachines()

View File

@ -0,0 +1,67 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.ExprAST import ExprAST
class MemberExprAST(ExprAST):
def __init__(self, slicc, expr_ast, field):
super(MemberExprAST, self).__init__(slicc)
self.expr_ast = expr_ast
self.field = field
def __repr__(self):
return "[MemberExprAST: %r.%r]" % (self.expr_ast, self.field)
def generate(self, code):
return_type, gcode = self.expr_ast.inline(True)
fix = code.nofix()
if str(return_type) == "TBE" \
or ("interface" in return_type and
(return_type["interface"] == "AbstractCacheEntry" or
return_type["interface"] == "AbstractEntry")):
code("(*$gcode).m_${{self.field}}")
else:
code("($gcode).m_${{self.field}}")
code.fix(fix)
# Verify that this is a valid field name for this type
if self.field in return_type.data_members:
# Return the type of the field
return return_type.data_members[self.field].type
else:
if "interface" in return_type:
interface_type = self.symtab.find(return_type["interface"]);
if interface_type != None:
if self.field in interface_type.data_members:
# Return the type of the field
return interface_type.data_members[self.field].type
self.error("Invalid object field: " +
"Type '%s' does not have data member %s" % \
(return_type, self.field))

View File

@ -0,0 +1,195 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.ExprAST import ExprAST
class MethodCallExprAST(ExprAST):
def __init__(self, slicc, proc_name, expr_ast_vec):
super(MethodCallExprAST, self).__init__(slicc)
self.proc_name = proc_name
self.expr_ast_vec = expr_ast_vec
def generate(self, code):
tmp = self.slicc.codeFormatter()
paramTypes = []
for expr_ast in self.expr_ast_vec:
return_type = expr_ast.generate(tmp)
paramTypes.append(return_type)
obj_type, methodId, prefix = self.generate_prefix(paramTypes)
# generate code
params = []
for expr_ast in self.expr_ast_vec:
return_type,tcode = expr_ast.inline(True)
params.append(str(tcode))
fix = code.nofix()
code("$prefix${{self.proc_name}}(${{', '.join(params)}}))")
code.fix(fix)
# Verify that this is a method of the object
if methodId not in obj_type.methods:
self.error("Invalid method call: Type '%s' does not have a method '%s'",
obj_type, methodId)
if len(self.expr_ast_vec) != \
len(obj_type.methods[methodId].param_types):
# Right number of parameters
self.error("Wrong number of parameters for function name: '%s', " + \
"expected: , actual: ", proc_name,
len(obj_type.methods[methodId].param_types),
len(self.expr_ast_vec))
for actual_type, expected_type in \
zip(paramTypes, obj_type.methods[methodId].param_types):
if actual_type != expected_type and \
str(actual_type["interface"]) != str(expected_type):
self.error("Type mismatch: expected: %s actual: %s",
expected_type, actual_type)
# Return the return type of the method
return obj_type.methods[methodId].return_type
def findResources(self, resources):
pass
class MemberMethodCallExprAST(MethodCallExprAST):
def __init__(self, slicc, obj_expr_ast, proc_name, expr_ast_vec):
s = super(MemberMethodCallExprAST, self)
s.__init__(slicc, proc_name, expr_ast_vec)
self.obj_expr_ast = obj_expr_ast
def __repr__(self):
return "[MethodCallExpr: %r%r %r]" % (self.proc_name,
self.obj_expr_ast,
self.expr_ast_vec)
def generate_prefix(self, paramTypes):
code = self.slicc.codeFormatter()
# member method call
obj_type = self.obj_expr_ast.generate(code)
methodId = obj_type.methodId(self.proc_name, paramTypes)
prefix = ""
implements_interface = False
if methodId in obj_type.methods:
return_type = obj_type.methods[methodId].return_type
else:
#
# Check whether the method is implemented by the super class
if "interface" in obj_type:
interface_type = self.symtab.find(obj_type["interface"]);
if methodId in interface_type.methods:
return_type = interface_type.methods[methodId].return_type
obj_type = interface_type
else:
self.error("Invalid method call: " \
"Type '%s' does not have a method %s, '%s'",
obj_type, self.proc_name, methodId)
else:
#
# The initial method check has failed, but before generating an
# error we must check whether any of the paramTypes implement
# an interface. If so, we must check if the method ids using
# the inherited types exist.
#
# This code is a temporary fix and only checks for the methodId
# where all paramTypes are converted to their inherited type. The
# right way to do this is to replace slicc's simple string
# comparison for determining the correct overloaded method, with a
# more robust param by param check.
#
implemented_paramTypes = []
for paramType in paramTypes:
implemented_paramType = paramType
if paramType.isInterface:
implements_interface = True
implemented_paramType.abstract_ident = paramType["interface"]
else:
implemented_paramType.abstract_ident = paramType.c_ident
implemented_paramTypes.append(implemented_paramType)
if implements_interface:
implementedMethodId = obj_type.methodIdAbstract(self.proc_name,
implemented_paramTypes)
else:
implementedMethodId = ""
if implementedMethodId not in obj_type.methods:
self.error("Invalid method call: " \
"Type '%s' does not have a method %s, '%s' nor '%s'",
obj_type, self.proc_name, methodId, implementedMethodId)
else:
#
# Replace the methodId with the implementedMethodId found in
# the method list.
#
methodId = implementedMethodId
return_type = obj_type.methods[methodId].return_type
if return_type.isInterface:
prefix = "static_cast<%s &>" % return_type.c_ident
if str(obj_type) == "AbstractCacheEntry" or \
str(obj_type) == "AbstractEntry" or \
("interface" in obj_type and (
obj_type["interface"] == "AbstractCacheEntry" or
obj_type["interface"] == "AbstractEntry")):
prefix = "%s((*(%s))." % (prefix, code)
else:
prefix = "%s((%s)." % (prefix, code)
return obj_type, methodId, prefix
class ClassMethodCallExprAST(MethodCallExprAST):
def __init__(self, slicc, type_ast, proc_name, expr_ast_vec):
s = super(ClassMethodCallExprAST, self)
s.__init__(slicc, proc_name, expr_ast_vec)
self.type_ast = type_ast
def __repr__(self):
return "[MethodCallExpr: %r %r]" % (self.proc_name, self.expr_ast_vec)
def generate_prefix(self, paramTypes):
# class method call
prefix = "(%s::" % self.type_ast
obj_type = self.type_ast.type
methodId = obj_type.methodId(self.proc_name, paramTypes)
return obj_type, methodId, prefix
__all__ = [ "MemberMethodCallExprAST", "ClassMethodCallExprAST" ]

View File

@ -0,0 +1,47 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.ExprAST import ExprAST
class NewExprAST(ExprAST):
def __init__(self, slicc, type_ast):
super(NewExprAST, self).__init__(slicc)
self.type_ast = type_ast
def __repr__(self):
return "[NewExprAST: %r]" % self.type_ast
@property
def name(self):
return str(self.type_ast)
def generate(self, code):
type = self.type_ast.type
fix = code.nofix()
code("new ${{type.c_ident}}")
code.fix(fix)
return type

View File

@ -0,0 +1,94 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.DeclAST import DeclAST
from slicc.symbols import Var
class ObjDeclAST(DeclAST):
def __init__(self, slicc, type_ast, ident, pairs):
super(ObjDeclAST, self).__init__(slicc, pairs)
self.type_ast = type_ast
self.ident = ident
def __repr__(self):
return "[ObjDecl: %r]" % self.ident
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)

View File

@ -0,0 +1,40 @@
#
# Copyright (c) 2011 Mark D. Hill and David A. Wood
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
from slicc.ast.ExprAST import ExprAST
class OodAST(ExprAST):
def __init__(self, slicc):
super(OodAST, self).__init__(slicc)
def __repr__(self):
return "[Ood:]"
def generate(self, code):
code += "NULL"
return "OOD"

View File

@ -0,0 +1,60 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.DeclAST import DeclAST
from slicc.ast.TypeAST import TypeAST
from slicc.symbols import Var
from slicc.symbols import Type
class OutPortDeclAST(DeclAST):
def __init__(self, slicc, ident, msg_type, var_expr, pairs):
super(OutPortDeclAST, self).__init__(slicc, pairs)
self.ident = ident
self.msg_type = msg_type
self.var_expr = var_expr
self.queue_type = TypeAST(slicc, "OutPort")
def __repr__(self):
return "[OutPortDecl: %r]" % self.ident
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)

View File

@ -0,0 +1,36 @@
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.AST import AST
class PairAST(AST):
def __init__(self, slicc, key, value):
super(PairAST, self).__init__(slicc)
self.key = key
self.value = value
def __repr__(self):
return '[%s=%s]' % (self.key, self.value)

View File

@ -0,0 +1,37 @@
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.AST import AST
class PairListAST(AST):
def __init__(self, slicc):
super(PairListAST, self).__init__(slicc)
def __repr__(self):
return "[PairListAST] %r" % self.pairs
def addPair(self, pair_ast):
self[pair_ast.key] = pair_ast.value

View File

@ -0,0 +1,94 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.StatementAST import StatementAST
from slicc.symbols import Var
class PeekStatementAST(StatementAST):
def __init__(self, slicc, queue_name, type_ast, pairs, statements, method):
super(PeekStatementAST, self).__init__(slicc, pairs)
self.queue_name = queue_name
self.type_ast = type_ast
self.statements = statements
self.method = method
def __repr__(self):
return "[PeekStatementAST: %r queue_name: %r type: %r %r]" % \
(self.method, self.queue_name, self.type_ast, self.statements)
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("}")
def findResources(self, resources):
self.statements.findResources(resources)

View File

@ -0,0 +1,54 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.StatementAST import StatementAST
class ReturnStatementAST(StatementAST):
def __init__(self, slicc, expr_ast):
super(ReturnStatementAST, self).__init__(slicc)
self.expr_ast = expr_ast
def __repr__(self):
return "[ReturnStatementAST: %r]" % self.expr_ast
def generate(self, code, return_type):
actual_type, ecode = self.expr_ast.inline(True)
code('return $ecode;')
# Is return valid here?
if return_type is None:
self.error("Invalid 'return' statement")
# The return type must match
if actual_type != "OOD" and return_type != actual_type:
self.expr_ast.error("Return type miss-match, expected return " +
"type is '%s', actual is '%s'",
return_type, actual_type)
def findResources(self, resources):
self.expr_ast.findResources(resources)

View File

@ -0,0 +1,49 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# Copyright (c) 2010 Advanced Micro Devices, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.StatementAST import StatementAST
class StallAndWaitStatementAST(StatementAST):
def __init__(self, slicc, in_port, address):
super(StatementAST, self).__init__(slicc)
self.in_port = in_port
self.address = address
def __repr__(self):
return "[StallAndWaitStatementAst: %r]" % self.variable
def generate(self, code, return_type):
self.in_port.assertType("InPort")
self.address.assertType("Address")
in_port_code = self.in_port.var.code
address_code = self.address.var.code
code('''
stallBuffer(&($in_port_code), $address_code);
$in_port_code.stallMessage($address_code);
''')

View File

@ -0,0 +1,79 @@
# Copyright (c) 2011 Advanced Micro Devices, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.DeclAST import DeclAST
from slicc.symbols import Func, Type
class StateDeclAST(DeclAST):
def __init__(self, slicc, type_ast, pairs, states):
super(StateDeclAST, self).__init__(slicc, pairs)
self.type_ast = type_ast
self.states = states
def __repr__(self):
return "[StateDecl: %s]" % (self.type_ast)
def files(self, parent=None):
if "external" in self:
return set()
if parent:
ident = "%s_%s" % (parent, self.type_ast.ident)
else:
ident = self.type_ast.ident
s = set(("%s.hh" % ident, "%s.cc" % ident))
return s
def generate(self):
ident = str(self.type_ast)
# Make the new type
t = Type(self.symtab, ident, self.location, self.pairs,
self.state_machine)
self.symtab.newSymbol(t)
# Add all of the states of the type to it
for state in self.states:
state.generate(t)
# Add the implicit State_to_string method - FIXME, this is a bit dirty
func_id = "%s_to_string" % t.c_ident
pairs = { "external" : "yes" }
func = Func(self.symtab, func_id, self.location,
self.symtab.find("std::string", Type), [ t ], [], "",
pairs, None)
self.symtab.newSymbol(func)
# Add the State_to_permission method
func_id = "%s_to_permission" % t.c_ident
pairs = { "external" : "yes" }
func = Func(self.symtab, func_id, self.location,
self.symtab.find("AccessPermission", Type), [ t ], [], "",
pairs, None)
self.symtab.newSymbol(func)

View File

@ -0,0 +1,34 @@
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.AST import AST
class StatementAST(AST):
def __init__(self, slicc, pairs=None):
super(StatementAST, self).__init__(slicc, pairs)
def findResources(self, resources):
pass

View File

@ -0,0 +1,46 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.AST import AST
class StatementListAST(AST):
def __init__(self, slicc, statements):
super(StatementListAST, self).__init__(slicc)
if not isinstance(statements, (list, tuple)):
statements = [ statements ]
self.statements = statements
def __repr__(self):
return "[StatementListAST: %r]" % self.statements
def generate(self, code, return_type):
for statement in self.statements:
statement.generate(code, return_type)
def findResources(self, resources):
for statement in self.statements:
statement.findResources(resources)

View File

@ -0,0 +1,58 @@
# Copyright (c) 2009 Advanced Micro Devices, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.ExprAST import ExprAST
class StaticCastAST(ExprAST):
def __init__(self, slicc, type_ast, type_modifier, expr_ast):
super(StaticCastAST, self).__init__(slicc)
self.type_ast = type_ast
self.expr_ast = expr_ast
self.type_modifier = type_modifier
def __repr__(self):
return "[StaticCastAST: %r]" % self.expr_ast
def generate(self, code):
actual_type, ecode = self.expr_ast.inline(True)
if self.type_modifier == "pointer":
code('static_cast<${{self.type_ast.type.c_ident}} *>($ecode)')
else:
code('static_cast<${{self.type_ast.type.c_ident}} &>($ecode)')
if not "interface" in self.type_ast.type:
self.expr_ast.error("static cast only premitted for those types " \
"that implement inherit an interface")
# The interface type should match
if str(actual_type) != str(self.type_ast.type["interface"]):
self.expr_ast.error("static cast miss-match, type is '%s'," \
"but inherited type is '%s'",
actual_type, self.type_ast.type["interface"])
return self.type_ast.type

View File

@ -0,0 +1,65 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.DeclAST import DeclAST
from slicc.symbols import Transition
class TransitionDeclAST(DeclAST):
def __init__(self, slicc, states, events, next_state, pairs, actions):
super(TransitionDeclAST, self).__init__(slicc, pairs)
self.states = states
self.events = events
self.next_state = next_state
self.actions = actions
def __repr__(self):
return "[TransitionDecl: ]"
def generate(self):
machine = self.symtab.state_machine
if machine is None:
self.error("Transition declaration not part of a machine.")
for action in self.actions:
if action not in machine.actions:
self.error("Invalid action: %s is not part of machine: %s" % \
(action, machine))
for state in self.states:
if state not in machine.states:
self.error("Invalid state: %s is not part of machine: %s" % \
(state, machine))
next_state = self.next_state or state
for event in self.events:
if event not in machine.events:
self.error("Invalid event: %s is not part of machine: %s" % \
(event, machine))
t = Transition(self.symtab, machine, state, event, next_state,
self.actions, self.location, self.pairs)
machine.addTransition(t)

View File

@ -0,0 +1,53 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.AST import AST
from slicc.symbols import Type
class TypeAST(AST):
def __init__(self, slicc, ident):
super(TypeAST, self).__init__(slicc)
self.ident = ident
def __repr__(self):
return self.ident
def __str__(self):
return self.ident
@property
def type(self, assert_type=None):
type = self.symtab.find(self.ident, Type)
if not type:
self.error("Type '%s' not declared.", self)
if assert_type is not None and type != assert_type:
self.error("Type '%s' is should be type '%s'", self, assert_type)
return type

View File

@ -0,0 +1,66 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.DeclAST import DeclAST
from slicc.symbols.Type import Type
class TypeDeclAST(DeclAST):
def __init__(self, slicc, type_ast, pairs, field_asts):
super(TypeDeclAST, self).__init__(slicc, pairs)
self.type_ast = type_ast
self.field_asts = field_asts
def __repr__(self):
return "[TypeDecl: %r]" % (self.type_ast)
def files(self, parent=None):
if "external" in self:
return set()
if parent:
ident = "%s_%s" % (parent, self.type_ast.ident)
else:
ident = self.type_ast.ident
return set(("%s.hh" % ident, "%s.cc" % ident))
def generate(self):
ident = str(self.type_ast)
machine = self.symtab.state_machine
# Make the new type
new_type = Type(self.symtab, ident, self.location, self.pairs,
self.state_machine)
if machine:
machine.addType(new_type)
self.symtab.newSymbol(new_type)
# Add all of the fields of the type to it
for field in self.field_asts:
field.generate(new_type)

View File

@ -0,0 +1,32 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.AST import AST
class TypeFieldAST(AST):
def __init__(self, slicc, pairs):
super(TypeFieldAST, self).__init__(slicc, pairs)

View File

@ -0,0 +1,56 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.TypeFieldAST import TypeFieldAST
from slicc.symbols import Event, State
class TypeFieldEnumAST(TypeFieldAST):
def __init__(self, slicc, field_id, pairs_ast):
super(TypeFieldEnumAST, self).__init__(slicc, pairs_ast)
self.field_id = field_id
self.pairs_ast = pairs_ast
def __repr__(self):
return "[TypeFieldEnum: %r]" % self.field_id
def generate(self, type):
if str(type) == "State":
self.error("States must in a State Declaration, not a normal enum.")
# Add enumeration
if not type.enumAdd(self.field_id, self.pairs_ast.pairs):
self.error("Duplicate enumeration: %s:%s" % (type, self.field_id))
# Fill machine info
machine = self.symtab.state_machine
if str(type) == "Event":
if not machine:
self.error("Event declaration not part of a machine.")
e = Event(self.symtab, self.field_id, self.location, self.pairs)
machine.addEvent(e)

View File

@ -0,0 +1,57 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.TypeFieldAST import TypeFieldAST
class TypeFieldMemberAST(TypeFieldAST):
def __init__(self, slicc, type_ast, field_id, pairs, rvalue):
super(TypeFieldMemberAST, self).__init__(slicc, pairs)
self.type_ast = type_ast
self.field_id = field_id
self.rvalue = rvalue
def __repr__(self):
return "[TypeFieldMember: %r]" % self.field_id
def generate(self, type):
# Lookup type
field_type = self.type_ast.type
# check type if this is a initialization
init_code = ""
if self.rvalue:
rvalue_type,init_code = self.rvalue.inline(True)
if field_type != rvalue_type:
self.error("Initialization type mismatch '%s' and '%s'" % \
(field_type, rvalue_type))
# Add data member to the parent type
if not type.dataMemberAdd(self.field_id, field_type, self.pairs,
init_code):
self.error("Duplicate data member: %s:%s" % (type_ptr, field_id))

View File

@ -0,0 +1,50 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.TypeFieldAST import TypeFieldAST
class TypeFieldMethodAST(TypeFieldAST):
def __init__(self, slicc, return_type_ast, ident, type_asts, pairs):
super(TypeFieldMethodAST, self).__init__(slicc, pairs)
self.return_type_ast = return_type_ast
self.ident = ident
self.type_asts = type_asts
def __repr__(self):
return ""
def generate(self, type):
# Lookup return type
return_type = self.return_type_ast.type
# Lookup parameter types
types = [ t.type for t in self.type_asts ]
# Add method
if not type.methodAdd(self.ident, return_type, types):
self.error("Duplicate method: %s:%s()" % (type, self.ident))

View File

@ -0,0 +1,61 @@
# Copyright (c) 2011 Advanced Micro Devices, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.TypeFieldAST import TypeFieldAST
from slicc.symbols import Event, State
class TypeFieldStateAST(TypeFieldAST):
def __init__(self, slicc, field_id, perm_ast, pairs_ast):
super(TypeFieldStateAST, self).__init__(slicc, pairs_ast)
self.field_id = field_id
self.perm_ast = perm_ast
if not (perm_ast.type_ast.ident == "AccessPermission"):
self.error("AccessPermission enum value must be specified")
self.pairs_ast = pairs_ast
def __repr__(self):
return "[TypeFieldState: %r]" % self.field_id
def generate(self, type):
if not str(type) == "State":
self.error("State Declaration must be of type State.")
# Add enumeration
if not type.enumAdd(self.field_id, self.pairs_ast.pairs):
self.error("Duplicate enumeration: %s:%s" % (type, self.field_id))
# Fill machine info
machine = self.symtab.state_machine
if not machine:
self.error("State declaration not part of a machine.")
s = State(self.symtab, self.field_id, self.location, self.pairs)
machine.addState(s)
type.statePermPairAdd(s, self.perm_ast.value)

View File

@ -0,0 +1,66 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.ExprAST import ExprAST
from slicc.symbols import Type, Var
class VarExprAST(ExprAST):
def __init__(self, slicc, var):
super(VarExprAST, self).__init__(slicc)
self._var = var
def __repr__(self):
return "[VarExprAST: %r]" % self._var
@property
def name(self):
return str(self._var)
@property
def var(self):
var = self.symtab.find(self._var, Var)
if not var:
self.error("Unrecognized variable: %s", self._var)
return var
def assertType(self, type_ident):
expected_type = self.symtab.find(type_ident, Type)
if not expected_type:
self.error("There must be a type '%s' declared in this scope",
type_ident)
if self.var.type != expected_type:
self.error("Incorrect type: " + \
"'%s' is expected to be type '%s' not '%s'",
self.var.ident, expected_type, self.var.type)
def generate(self, code):
fix = code.nofix()
code("${{self.var.code}}")
code.fix(fix)
return self.var.type

View File

@ -0,0 +1,76 @@
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.ast.AST import *
# actual ASTs
from slicc.ast.ActionDeclAST import *
from slicc.ast.AssignStatementAST import *
from slicc.ast.CheckAllocateStatementAST import *
from slicc.ast.CheckStopSlotsStatementAST import *
from slicc.ast.ChipComponentAccessAST import *
from slicc.ast.CopyHeadStatementAST import *
from slicc.ast.DeclAST import *
from slicc.ast.DeclListAST import *
from slicc.ast.EnqueueStatementAST import *
from slicc.ast.EnumDeclAST import *
from slicc.ast.EnumExprAST import *
from slicc.ast.ExprAST import *
from slicc.ast.ExprStatementAST import *
from slicc.ast.FormalParamAST import *
from slicc.ast.FuncCallExprAST import *
from slicc.ast.FuncDeclAST import *
from slicc.ast.IfStatementAST import *
from slicc.ast.InPortDeclAST import *
from slicc.ast.InfixOperatorExprAST import *
from slicc.ast.IsValidPtrExprAST import *
from slicc.ast.LiteralExprAST import *
from slicc.ast.LocalVariableAST import *
from slicc.ast.MachineAST import *
from slicc.ast.MemberExprAST import *
from slicc.ast.MethodCallExprAST import *
from slicc.ast.NewExprAST import *
from slicc.ast.OodAST import *
from slicc.ast.ObjDeclAST import *
from slicc.ast.OutPortDeclAST import *
from slicc.ast.PairAST import *
from slicc.ast.PairListAST import *
from slicc.ast.PeekStatementAST import *
from slicc.ast.ReturnStatementAST import *
from slicc.ast.StallAndWaitStatementAST import *
from slicc.ast.StateDeclAST import *
from slicc.ast.StatementAST import *
from slicc.ast.StatementListAST import *
from slicc.ast.StaticCastAST import *
from slicc.ast.TransitionDeclAST import *
from slicc.ast.TypeAST import *
from slicc.ast.TypeDeclAST import *
from slicc.ast.TypeFieldAST import *
from slicc.ast.TypeFieldEnumAST import *
from slicc.ast.TypeFieldMemberAST import *
from slicc.ast.TypeFieldMethodAST import *
from slicc.ast.TypeFieldStateAST import *
from slicc.ast.VarExprAST import *

View File

@ -0,0 +1,307 @@
SLICC - Version 0.3 Design Document - January 17, 1999
Milo Martin and Dan Sorin
Question: Rethinking of support for profiling the transactions
Question: How do we deal with functions/methods and resources
Comment: We need to discuss the sequencer interface so it can work now
and for the speculative version buffer.
Overview
--------
We are in the process of designing and implementing SLICC v0.3, an
evolution of SLICC v0.2. The new design includes capabilities for
design of multilevel cache hierarchies including the specification of
multiple protocol state machines (PSMs) and the queues which connect
these PSMs and the network. We actually believe that most of the
network and network topology, including the ordered network, can be
expressed using the new hierarchical extensions to the language.
In addition, many implicit aspects of the language will be eliminated
in favor of explicit declarations. For example functions, queues, and
objects declarations such as "cacheMemory" and "TBETable" will be
explicitly declared. This will allow for full static type checking
and easier extension for the language. Event triggering will be part
of "in_port" declarations and not "event" declarations. Finally, many
less fundamental, but important, features and internal code
improvements will be enhanced.
SLICC History
-------------
v0.1 - Initially the language only handled the generation of the PSM
transition table logic. All actions and event triggering were
still coded in C++. At this point it was still called, "the
language."
v0.2 - Extended the language to include a simple C like syntax for
specifying actions, event triggering, and manipulating queues
and state elements. This version was the first version of the
language known as SLICC (suggested by Amir) and was used for
the Multifacet ISCA 2000 submission.
v0.3 - Development effort started January 2000. Intended features and
enhancements are described by this document.
Specifying Hierarchical Designs
-------------------------------
Right now all of our protocols have two tables, a processor/cache PSM
and a directory PSM. In v0.2 this is a rigid requirement and
the names are implicit. SLICC v0.3 will allow for an arbitrary number
of different PSMs.
The most significant improvement in v0.3 is the ability for the user
to define an arbitrary set of interconnected PSMs. PSMs may include
an L1 cache controller, L2 cache controller, directory controller,
speculative version buffer, network interface, etc. There are a
couple of "primitive PSMs" such as the sequencer.
There will be a notion of a "node" of the system. In a node, each PSM
will be instantiated and connected together with queues. For example,
assume we define a PSMs and want to create a queue of RequestMessages
to communicate between it and the network.
machine(CacheController) {
...
out_port(to_network, RequestMessage, "To the network", desc="...");
...
}
CacheController cache, desc="...";
connect(cache.to_network, network.from_cache, ordered="yes", desc="...");
Explicit State Manipulation
---------------------------
As before, PSMs have states, events, and transitions. New in v0.3 each
PSM must have user defined methods for get_state(address) and
set_state(address, state), and these methods are written explicitly,
instead of being implicit functions of memory states (e.g., our
current implementation which implicitly uses the TBE state if there is
a TBE or uses the cache state). Functions have a return value,
procedures do not. Function calls are expressions, procedure calls
are statements. All function and procedure parameters are considered
pass-by-value.
procedure set_state(Address addr, State state) {
...
}
function State get_state(Address addr) {
...
}
Explicit Declaration
--------------------
PSMs reference or declare structures, such as queues, ports, cache
memories, main memory, TBEs, write buffers, etc. These primitive
types and structures are written in C++, and their semantics are still
specified by the C++ coder. Examples of these primitive types include
"CacheMemory," "TBETable," as well as various types of queues.
One major difference is that in v0.3 the interface for all of these
primitive objects will be declared (but not defined) in the SLICC
language. This also allows adding primitive structures by defining a
C++ implementation and a SLICC interface specification. This will
make the language much more extensible. Specifying the interface of
these primitive types, structures, and queues in SLICC will eliminate
much of the implicit semantics that is currently hiding in the
controllers.
The interface declaration might be in one file and shared between all
protocols. The object instantiation would be internal to each PSM
that requires a cache memory. The syntax for messages will also be
enhanced by using this new syntax. Notice the support for default
values.
structure(CacheMemory, "Cache memory", desc="...") {
void cache_change_state(Address addr, State state), desc="...";
Data dataBlk, default="", desc="";
bool cache_avail(Address addr), desc="...";
Address cache_probe(Address addr), desc="...";
void cache_allocate(Address addr), desc="...";
}
CacheMemory L1cacheMemory, desc="...";
Structure specification is going to require the introduction of an
object model in the language. The "." (dot) operator is going to be
extended beyond the use as structure element access, but also allow
for a object method call syntax similar to C++ and Java.
L1cacheMemory.cache_allocate(addr);
Polymorphism
------------
We are also going to want to allow for polymorphism for many of the
structures. We already have a limited degree of polymorphism between
different protocols by using the same cache memory structure with
different "CacheEntry" types in each protocol. Now that we are going
to have multiple levels of cache, each requiring slightly different
state bits, we are going to want to specify cache memory structures
which have different "CacheEntry" types in the same protocol. To do
this right, this is going to require adding full polymorphism support
to the language. Right now we imagine something like C++'s templates,
since they are a more natural fit to hardware synthesis in the future.
Type Checker
------------
All of the above substantially complicates our type system by
requiring more types and scoping rules. As a step towards
understanding the implications of the type system, a type checking
system will be implemented. This is a hard requirement if we are ever
to distribute the system since receiving compile time errors in the
generated code is not acceptable. In order to ensure that we don't
accidentally design a language that is not statically type checkable,
it is important to add the type checker sooner rather than later.
Event Triggering
----------------
In v0.2, PSM events were individually specified as sets of conditions.
The following SLICC v0.2 code is a simplified example from the origin
protocol.
event(Dir_data_ack_0, "Data ack 0", desc="... ack count == 0") {
if (queue_ready(responseNetwork)) {
peek(responseNetwork, ResponseMsg) {
if(in_msg.NumPendingAcks == 0) {
trigger(in_msg.Address);
}
}
}
}
event(Dir_data_ack_not_0, "Data ack not 0", desc="... ack count != 0") {
if (queue_ready(responseNetwork)) {
peek(responseNetwork, ResponseMsg) {
if(in_msg.NumPendingAcks != 0) {
trigger(in_msg.Address);
}
}
}
}
The above code defines the exact conditions for the events to be
triggered. This type of event specification led to redundant code and
numerous bugs where conditions for different events were not
completely orthogonal.
In v0.3, events will be declared with no accompanying code (similar to
how states are specified). Instead, the code that determines which
event is triggered will be part of each incoming port's declaration.
This approach should eliminate redundancy and bugs in trigger
conditions. The v0.3 code for the above would look like:
event(Dir_data_ack_0, "Data ack 0", desc="... ack count = 0");
event(Dir_data_ack_not_0, "Data ack not 0", desc="... ack count != 0");
in_port(responseNetwork, ResponseMsg, "Response Network", desc="...") {
if(in_msg.NumPendingAcks == 0) {
trigger(Dir_data_ack_0, in_msg.Address);
} else {
trigger(Dir_data_ack_not_0, in_msg.Address);
}
}
Notice that one no longer needs to explicitly check if the queue is
ready or to perform the peek operation.
Also notice that the type of messages that arrives on the port is
explicitly declared. All ports, incoming and outgoing, are now
explicitly type channels. You will still be required to include the
type of message when manipulating the queue. The type specified will
be statically type checked and also acts as self-documenting code.
Other Improvements
------------------
There will be a number of other improvements in v0.3 such as general
performance tuning and clean up of the internals of the compiler. The
compiler will be modified to operate on multiple files. In addition,
the abstract syntax tree internal to the code will need to be extended
to encompass more information, including information parsed in from
multiple files.
The affiliates talk and the document for the language should also be
updated to reflect the changes in the new version.
Looking Forward
---------------
When designing v0.3 we are keeping future plans in mind.
- When our designs of the multilevel cache hierarchy are complete, we
expect to have a large amount of replication between the protocols
and caches controllers within a protocol. For v0.4 we hope to look
at the patterns that have evolved and look for ways in which the
language can capture these patterns. Exploiting reuse will provide
quicker protocol development and maintainability.
- By keeping the specification structural, we are looking towards
generating VHDL/Verilog from SLICC. The type system will help this,
as will more explicit instantiation and declaration of types and
structures. The structures now written in C++ (sequencer, network,
cache arrays) will be ported to the HDL we select. The rest of the
controllers will be generated by the compiler. At first the
generated controller will not be optimized. I believe that with
more effort we can automatically generate reasonably optimized,
pipelined implementation of the controllers.
Implementation Plan
-------------------
- HTML generator
- Extend internal parser AST nodes
- Add get_state function and set_state procedure declarations
- Move trigger logic from events to in_ports
- Types
- Change type declaration syntax
- Declare primitive types and corresponding C++ types
- Add default values to structures and types
- Add object method call syntax
- Write type checker
- Documentation
- Revise document
- Update presentation
Document History
----------------
$Id: SLICC_V03.txt,v 3.0 2000/09/12 20:27:59 sorin Exp $
$Log: SLICC_V03.txt,v $
Revision 3.0 2000/09/12 20:27:59 sorin
Version 3.0 signifies a checkpoint of the source tree right after the
final draft of the ASPLOS '00 paper.
Revision 1.1.1.1 2000/03/09 10:18:38 milo
Initial import
Revision 2.0 2000/01/19 07:21:13 milo
Version 2.0
Revision 1.5 2000/01/18 10:26:24 milo
Changed the SLICC parser so that it generates a full AST. This is the
first step in moving towards v0.3
Revision 1.4 2000/01/17 18:36:15 sorin
*** empty log message ***
Revision 1.3 2000/01/15 10:30:16 milo
Added implementation list
Revision 1.2 2000/01/15 08:11:44 milo
Minor revisions
Revision 1.1 2000/01/15 07:14:17 milo
Converted Dan's first draft into a text file. Significant
modifications were made.

View File

@ -0,0 +1,574 @@
%& latex
\documentclass[11pt]{article}
\usepackage{graphics}
\usepackage{color}
\textheight 9.0 in
\topmargin -0.5 in
\textwidth 6.5 in
\oddsidemargin -0.0 in
\evensidemargin -0.0 in
\begin{document}
\definecolor{dark}{gray}{0.5}
\newcommand{\syntax}[1]{%
\begin{center}
\fbox{\tt \small
\begin{tabular}{l}
#1\end{tabular}}\end{center}}
\begin{center}
{\LARGE Tutorial for SLICC v0.2} \\
\vspace{.25in}
{\large Milo Martin} \\
{\large 8/25/1999}
\end{center}
\section*{Overview}
This document attempts to illustrate the syntax and expressiveness of
the cache coherence protocol specification language through a small
example. A ``stupido'' cache coherence protocol is described in prose
and then expressed in the language.
The protocol used as the running example is described. Then each of
the elements of the protocol is discussed and expressed in the
language: states, events, transitions, and actions.
\section*{Protocol Description}
In order to make this example a simple as possible, the protocol
described is a simple as possible and makes many simplifying
assumptions. These simplifications were made only to clarify the
exposition and are not indications of limitations of the
expressiveness of the description language. We have already specified
a more complicated MSI broadcast snooping protocol, a multicast
snooping protocol, and a directory protocol. The simplifying
assumptions are listed below. The remaining details of the protocol
are described in the sections where we give the syntax of the
language.
\begin{itemize}
\item
The protocol uses broadcast snooping that assumes that a broadcast can
only occur if all processors have processed all of their incoming
address transactions. In essence, when a processor issue an address
request, that request will be next in the global order. This allows
us to avoid needed to handle the cases before we have observed our
request in the global order.
\item
The protocol has only Modified and Idle stable states. (Note: Even
the Shared state is omitted.)
\item
To avoid describing replacement (PutX's) and writebacks, the caches
are in treated as infinite in size.
\item
No forward progress bit is used, so the protocol as specified does not
guarantee forward progress.
\item
Only the mandatory request queue is used. No optional or prefetch
queue is described.
\item
The above simplifications reduce the need for TBEs (Translation Buffer
Entries) and thus the idea of a TBE is not include.
\item
Each memory module is assumed to have some state associated with each
cache block in the memory. This requires a simple directory/memory
state machine to work as a compliment to the processor state machine.
Traditional broadcast snooping protocols often have no ``directory''
state in the memory.
\end{itemize}
\section*{Protocol Messages}
Cache coherence protocols communicate by sending well defined
messages. To fully specify a cache coherence protocol we need to be
able to specify the message types and fields. For this protocol we
have address messages ({\tt AddressMsg}) which are broadcast, and data
messages ({\tt DataMsg}) which are point-to-point. Address messages
have an address field ({\tt Address}), a request type ({\tt Type}),
and which processor made the request ({\tt Requestor}). Data message
have an address field ({\tt Address}), a destination ({\tt
Destination}), and the actual cache block being transfered ({\tt
DataBlk}). The names in parenthesis are important because those are
the names which code later in the specification will reference various
message types and fields in the messages.
Messages are declared by creating types with {\tt new\_type()} and
adding fields with {\tt type\_field()}. The exact syntax for
declaring types and message is a bit ugly right now and is going to be
changed in the near future. If you wish, please see the appendix for
an example of the current syntax.
\section*{Cache States}
Idle and Modified are the two stable states in our protocol. In
addition the we have a single transient processor state. This state
is used after a processor has issued a request and is waiting for the
data response to arrive.
Declaring states in the language is the first of a number of
declarations we will be using. All of these declarations have a
similar format. Below is the format for a state declaration.
\syntax{
{\tt state({\em identifier}, {\em shorthand}, {\em pair1}, {\em pair2}, ...);}
}
{\em identifier} is a name that is used later to
refer to this state later in the description. It must start with a
letter and after than can have any combination of letters, numbers,
and the underscore character. {\em shorthand} is a quoted string
which contains the shorthand that should be used for the state when
generating tables and such.
The {\em pair}'s are used to associate arbitrary information with each
state. Zero or more pairs can be included in each declaration. For
example we want to have a more verbose description of each state when
we generate the table which contains the states and descriptions.
This information is encoded in the language by adding a {\tt desc}
parameter to a declaration. The name of the parameter is followed by
an equal sign and a string with the description. The {\tt desc} pair
technically optional, however the table generation tool will complain
about a missing description if it is not present.
The three states for our protocol are expressed as follows:
\begin{verbatim}
state(I, "I", desc="Idle");
state(M, "M", desc="Modified");
state(IM, "IM", desc="Idle, issued request but have not seen data yet");
\end{verbatim}
\section*{Cache Events}
Events are external stimulus that cause the state machine to take
action. This is most often a message in one of the queues from the
network or processor. Events form the columns of the protocol table.
Our simple protocol has one event per incoming queue. When a message
is waiting in one of these queues and event can occur. We can see a
request from the processor in the mandatory queue, another processor's
request, or a data response.
Events are declared in the language similarly to states. The {\em
identifier}, {\em shorthand}, and {\em pair}'s have the same purpose
as in a state declaration.
\syntax{
event({\em identifier}, {\em shorthand}, {\em pair1}, {\em pair2}, ...) \{ \\
\hspace{.1in} {\em statement\_list} \\
\} \\
}
Events are different in that they have a list of statements which
allows exact specification of when the event should ``trigger'' a
transition. These statements are mini-programming language with
syntax similar to that of C. For example the {\tt peek} construct in
this context checks to see if there is a message at the head of the
specified queue, and if so, conceptually copies the message to a
temporary variable accessed as {\tt in\_msg}. The language also
supports various procedure calls, functions, conditional statements,
assignment, and queue operations such as peek, enqueue and dequeue.
The {\tt trigger()} construct takes an address as the only parameter.
This is the address that should be triggered for the event. To give
you a feel for what this code looks like, the three events for our
simple protocol are below.
\begin{verbatim}
event(LoadStore, "LoadStore", desc="Load or Store request from local processor") {
peek(mandatoryQueue_ptr, CacheMsg) {
trigger(in_msg.Address);
}
}
event(Other_GETX, "Other GETX", desc="Observed a GETX request from another processor") {
peek(addressNetwork_ptr, AddressMsg) {
if (in_msg.Requestor != id) {
trigger(in_msg.Address);
}
}
}
event(Data, "Data", desc="Data for this block from the data network") {
peek(dataNetwork_ptr, DataMsg) {
trigger(in_msg.Address);
}
}
\end{verbatim}
\section*{Cache Actions}
Actions are the privative operations that are performed by various
state transitions. These correspond (by convention) to the lower case
letters in the tables. We need several actions in our protocol
including issuing a GetX request, servicing a cache hit, send data
from the cache to the requestor, writing data into the cache, and
popping the various queues.
The syntax of an action declaration is similar to an event
declaration. The difference is that statements in the statement list
are used to implement the desired action, and not triggering an event.
\syntax{action({\em identifier}, {\em shorthand}, {\em pair1}, {\em pair2}, ...) \{ \\
\hspace{.1in} {\em statement\_list} \\
\}
}
The actions for this protocol use more of the features of the
language. Some of the interesting case are discussed below.
\begin{itemize}
\item
To manipulate values we need assignment statements (notice the use of
{\verb+:=+} as the assignment operator). The action to write data
into the cache looks at the incoming data message and puts the data in
the cache. Notice the use of square brackets to lookup the block in
the cache based on the address of the block.
\begin{verbatim}
action(w_writeDataToCache, "w", desc="Write data from data message into cache") {
peek(dataNetwork_ptr, DataMsg) {
cacheMemory_ptr[address].DataBlk := in_msg.DataBlk;
}
}
\end{verbatim}
\item
In addition to peeking at queues, we also enqueue messages. The {\tt
enqueue} construct works similarly to the {\tt peek} construct. {\tt
enqueue} creates a temporary called {\tt out\_msg}. You can assign
the fields of this message. At the end of the {\tt enqueue} construct
the message is implicitly inserted in the outgoing queue of the
specified network. Notice also how the type of the message is
specified and how the assignment statements use the names of the
fields of the messages. {\tt address} is the address for which the
event was {\tt trigger}ed.
\begin{verbatim}
action(g_issueGETX, "g", desc="Issue GETX.") {
enqueue(addressNetwork_ptr, AddressMsg) {
out_msg.Address := address;
out_msg.Type := "GETX";
out_msg.Requestor := id;
}
}
\end{verbatim}
\item
Some times we need to use both {\tt peek} and {\tt enqueue} together.
In this example we look at an incoming address request to figure out
who to whom to forward the data value.
\begin{verbatim}
action(r_cacheToRequestor, "r", desc="Send data from the cache to the requestor") {
peek(addressNetwork_ptr, AddressMsg) {
enqueue(dataNetwork_ptr, DataMsg) {
out_msg.Address := address;
out_msg.Destination := in_msg.Requestor;
out_msg.DataBlk := cacheMemory_ptr[address].DataBlk;
}
}
}
\end{verbatim}
\item
We also need to pop the various queues.
\begin{verbatim}
action(k_popMandatoryQueue, "k", desc="Pop mandatory queue.") {
dequeue(mandatoryQueue_ptr);
}
\end{verbatim}
\item
Finally we have the ability to call procedures and functions. The
following is an example of a procedure call. Currently all of the
procedures and functions are used to handle all of the more specific
operations. These are currently hard coded into the generator.
\begin{verbatim}
action(h_hit, "h", desc="Service load/store from the cache.") {
serviceLdSt(address, cacheMemory_ptr[address].DataBlk);
}
\end{verbatim}
\end{itemize}
\section*{Cache Transitions}
The cross product of states and events gives us the set of possible
transitions. For example, for our example protocol the empty would
be:
\begin{center}
\begin{tabular}{|l||l|l|l|} \hline
& LoadStore & Other GETX & Data \\ \hline \hline
I & & & \\ \hline
M & & & \\ \hline
IM & & & \\ \hline
\end{tabular}
\end{center}
Transitions are atomic and are the heart of the protocol
specification. The transition specifies both what the next state, and
also what actions are performed for each unique state/event pair. The
transition declaration looks different from the other declarations:
\syntax{
transition({\em state}, {\em event}, {\em new\_state}, {\em pair1}, {\em pair2}, ...) \{ \\
\hspace{.1in} {\em action\_identifier\_list}\\
\}
}
{\em state} and {\em event} are the pair which uniquely identifies the
transition. {\em state} correspond to the row where {\em event}
selects the column. {\em new\_state} is an optional parameter. If
{\em new\_state} is specified, that is the state when the atomic
transition is completed. If the parameter is omitted there is assumed
to be no state change. An impossible transition is specified by
simply not declaring an event for that state/event pair.
We also place list of actions in the curly braces. The {\em
action\_identifier}'s correspond to the identifier specified as the
first parameter of an action declaration. The action list is a list
of operations to be performed when this transition occurs. The
actions also knows what preconditions are necessary are required for
the action to be performed. For example a necessary precondition for
an action which sends a message is that there is a space available in
the outgoing queue. Each transition is considered atomic, and thus
the generated code ensures that all of the actions can be completed
before performing and of the actions.
In our running example protocol it is only possible to receive data in
the {\em IM} state. The other seven cases can occur and are declared
as follows. Below are a couple of examples. See the appendix for a
complete list.
\newpage
\begin{verbatim}
transition(I, LoadStore, IM) {
g_issueGETX;
}
transition(M, LoadStore) {
h_hit;
k_popMandatoryQueue;
}
transition(M, Other_GETX, I) {
r_cacheToRequestor;
i_popAddressQueue;
}
\end{verbatim}
From the above declarations we can generate a table. Each box can
have lower case letters which corresponds to the list of actions
possibly followed by a slash and a state (in uppercase letters). If
there is no slash and state, the transition does not change the state.
\begin{center}
\begin{tabular}{|l||l|l|l|} \hline
& LoadStore & Other GETX & Data \\ \hline \hline
I & g/IM & i & (impossible)\\ \hline
M & hk & ri/I & (impossible)\\ \hline
IM & z & z & wj/M \\ \hline
\end{tabular}
\end{center}
There is a useful shorthand for specifying many transitions with the
same action. One or both of {\em event} and {\em state} can be a list
in curly braces. This defines the cross product of the sets in one
declaration. If no {\em new\_state} is specified none of the
transitions cause a state change. If {\em new\_state} is specified,
all of the transitions in the cross product of the sets has the same
next state. For example, in the below transitions both IM/LoadStore
and IM/Other\_GETX have the action {\tt z\_delayTrans}.
\begin{verbatim}
transition(IM, LoadStore) {
z_delayTrans;
}
transition(IM, Other_GETX) {
z_delayTrans;
}
\end{verbatim}
These can be specified in a single declaration:
\begin{verbatim}
transition(IM, {LoadStore, Other_GETX}) {
z_delayTrans;
}
\end{verbatim}
\newpage
\section*{Appendix - Sample Cache Controller Specification}
{\small
\begin{verbatim}
machine(processor, "Simple MI Processor") {
// AddressMsg
new_type(AddressMsg, "AddressMsg", message="yes", desc="");
type_field(AddressMsg, Address, "address",
desc="Physical address for this request",
c_type=PhysAddress, c_include="Address.hh", murphi_type="");
type_field(AddressMsg, Type, "type",
desc="Type of request (GetS, GetX, PutX, etc)",
c_type=CoherenceRequestType, c_include="CoherenceRequestType.hh", murphi_type="");
type_field(AddressMsg, Requestor, "requestor",
desc="Node who initiated the request",
c_type=ComponentID, c_include="ComponentID.hh", murphi_type="");
// DataMsg
new_type(DataMsg, "DataMsg", message="yes", desc="");
type_field(DataMsg, Address, "address",
desc="Physical address for this request",
c_type=PhysAddress, c_include="Address.hh", murphi_type="");
type_field(DataMsg, Destination, "destination",
desc="Node to whom the data is sent",
c_type=Set, c_include="Set.hh", murphi_type="");
type_field(DataMsg, DataBlk, "data",
desc="Node to whom the data is sent",
c_type=DataBlock, c_include="DataBlock.hh", murphi_type="");
// CacheEntry
new_type(CacheEntry, "CacheEntry");
type_field(CacheEntry, CacheState, "Cache state", desc="cache state",
c_type=CacheState, c_include="CacheState.hh", murphi_type="");
type_field(CacheEntry, DataBlk, "data", desc="data for the block",
c_type=DataBlock, c_include="DataBlock.hh", murphi_type="");
// DirectoryEntry
new_type(DirectoryEntry, "DirectoryEntry");
type_field(DirectoryEntry, DirectoryState, "Directory state", desc="Directory state",
c_type=DirectoryState, c_include="DirectoryState.hh", murphi_type="");
type_field(DirectoryEntry, DataBlk, "data", desc="data for the block",
c_type=DataBlock, c_include="DataBlock.hh", murphi_type="");
\end{verbatim}
\newpage
\begin{verbatim}
// STATES
state(I, "I", desc="Idle");
state(M, "M", desc="Modified");
state(IM, "IM", desc="Idle, issued request but have not seen data yet");
// EVENTS
// From processor
event(LoadStore, "LoadStore", desc="Load or Store request from local processor") {
peek(mandatoryQueue_ptr, CacheMsg) {
trigger(in_msg.Address);
}
}
// From Address network
event(Other_GETX, "Other GETX", desc="Observed a GETX request from another processor") {
peek(addressNetwork_ptr, AddressMsg) {
if (in_msg.Requestor != id) {
trigger(in_msg.Address);
}
}
}
// From Data network
event(Data, "Data", desc="Data for this block from the data network") {
peek(dataNetwork_ptr, DataMsg) {
trigger(in_msg.Address);
}
}
// ACTIONS
action(g_issueGETX, "g", desc="Issue GETX.") {
enqueue(addressNetwork_ptr, AddressMsg) {
out_msg.Address := address;
out_msg.Type := "GETX";
out_msg.Requestor := id;
}
}
action(h_hit, "h", desc="Service load/store from the cache.") {
serviceLdSt(address, cacheMemory_ptr[address].DataBlk);
}
action(i_popAddressQueue, "i", desc="Pop incoming address queue.") {
dequeue(addressNetwork_ptr);
}
action(j_popDataQueue, "j", desc="Pop incoming data queue.") {
dequeue(dataNetwork_ptr);
}
action(k_popMandatoryQueue, "k", desc="Pop mandatory queue.") {
dequeue(mandatoryQueue_ptr);
}
action(r_cacheToRequestor, "r", desc="Send data from the cache to the requestor") {
peek(addressNetwork_ptr, AddressMsg) {
enqueue(dataNetwork_ptr, DataMsg) {
out_msg.Address := address;
out_msg.Destination := in_msg.Requestor;
out_msg.DataBlk := cacheMemory_ptr[address].DataBlk;
}
}
}
action(w_writeDataToCache, "w", desc="Write data from data message into cache") {
peek(dataNetwork_ptr, DataMsg) {
cacheMemory_ptr[address].DataBlk := in_msg.DataBlk;
}
}
action(z_delayTrans, "z", desc="Cannot be handled right now.") {
stall();
}
// TRANSITIONS
// Transitions from Idle
transition(I, LoadStore, IM) {
g_issueGETX;
}
transition(I, Other_GETX) {
i_popAddressQueue;
}
// Transitions from Modified
transition(M, LoadStore) {
h_hit;
k_popMandatoryQueue;
}
transition(M, Other_GETX, I) {
r_cacheToRequestor;
i_popAddressQueue;
}
// Transitions from IM
transition(IM, {LoadStore, Other_GETX}) {
z_delayTrans;
}
transition(IM, Data, M) {
w_writeDataToCache;
j_popDataQueue;
}
}
\end{verbatim}
}
\end{document}

View File

@ -0,0 +1,42 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from m5.util.code_formatter import code_formatter
def printDotty(sm, code):
code('digraph ${{sm.getIdent()}} {')
code.indent()
for t in sm.transitions:
# Don't print ignored transitions
if t.getActionShorthands() in ("--", "z"):
continue
code('${{t.getStateShorthand()}} -> ${{t.getNextStateShorthand()}')
code(' [label="${{t.getEventShorthand()}}/${{t.getActionShorthands()}}"')
code.dedent()
code('}')

View File

@ -0,0 +1,82 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from m5.util.code_formatter import code_formatter
def createSymbol(symbol, title):
code = code_formatter()
code('''
<HTML><BODY><BIG>
$title: ${{formatShorthand(symbol.short)}} - ${{symbol.desc}}
</BIG></BODY></HTML>
''')
return code
def formatShorthand(short):
munged_shorthand = ""
mode_is_normal = True
# -- Walk over the string, processing superscript directives
gen = enumerate(short)
for i,c in gen:
if c == '!':
# -- Reached logical end of shorthand name
break
elif c == '_':
munged_shorthand += " "
elif c == '^':
# -- Process super/subscript formatting
mode_is_normal = not mode_is_normal
if mode_is_normal:
# -- Back to normal mode
munged_shorthand += "</SUP>"
else:
# -- Going to superscript mode
munged_shorthand += "<SUP>"
elif c == '\\':
# -- Process Symbol character set
if i + 1 < len(short):
# -- Proceed to next char. Yes I know that changing
# the loop var is ugly!
i,c = gen.next()
munged_shorthand += "<B><FONT size=+1>"
munged_shorthand += c
munged_shorthand += "</FONT></B>"
else:
# -- FIXME: Add line number info later
panic("Encountered a `\\` without anything following it!")
else:
# -- Pass on un-munged
munged_shorthand += c
# -- Do any other munging
if not mode_is_normal:
# -- Back to normal mode
munged_shorthand += "</SUP>"
return munged_shorthand

View File

@ -0,0 +1,71 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from m5.util.code_formatter import code_formatter
class tex_formatter(code_formatter):
braced = "<>"
double_braced = "<<>>"
def printTexTable(sm, code):
tex = tex_formatter()
tex(r'''
%& latex
\documentclass[12pt]{article}
\usepackage{graphics}
\begin{document}
\begin{tabular}{|l||$<<"l" * len(sm.events)>>|} \hline
''')
for event in sm.events:
code(r" & \rotatebox{90}{$<<event.short>>}")
tex(r'\\ \hline \hline')
for state in sm.states:
state_str = state.short
for event in sm.events:
state_str += ' & '
trans = sm.get_transition(state, event)
if trans:
actions = trans.getActionShorthands()
# FIXME: should compare index, not the string
if trans.getNextStateShorthand() != state.short:
nextState = trans.getNextStateShorthand()
else:
nextState = ""
state_str += actions
if nextState and actions:
state_str += '/'
state_str += nextState
tex(r'$0 \\', state_str)
tex(r'''
\hline
\end{tabular}
\end{document}
''')
code.append(tex)

View File

@ -0,0 +1,97 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import os
import sys
from slicc.parser import SLICC
usage="%prog [options] <files> ... "
version="%prog v0.4"
brief_copyright='''
Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
Copyright (c) 2009 The Hewlett-Packard Development Company
All Rights Reserved.
'''
def nprint(format, *args):
pass
def eprint(format, *args):
if args:
format = format % args
print >>sys.stderr, format
def main(args=None):
import optparse
parser = optparse.OptionParser(usage=usage, version=version,
description=brief_copyright)
parser.add_option("-d", "--debug", default=False, action="store_true",
help="Turn on PLY debugging")
parser.add_option("-C", "--code-path", default="generated",
help="Path where C++ code output code goes")
parser.add_option("-H", "--html-path",
help="Path where html output goes")
parser.add_option("-F", "--print-files",
help="Print files that SLICC will generate")
parser.add_option("--tb", "--traceback", action='store_true',
help="print traceback on error")
parser.add_option("-q", "--quiet",
help="don't print messages")
opts,files = parser.parse_args(args=args)
if len(files) != 1:
parser.print_help()
sys.exit(2)
output = nprint if opts.quiet else eprint
output("SLICC v0.4")
output("Parsing...")
slicc = SLICC(files[0], verbose=True, debug=opts.debug, traceback=opts.tb)
if opts.print_files:
for i in sorted(slicc.files()):
print ' %s' % i
else:
output("Processing AST...")
slicc.process()
output("Writing C++ files...")
slicc.writeCodeFiles(opts.code_path)
if opts.html_path:
output("Writing HTML files...")
slicc.writeHTMLFiles(opts.html_path)
output("SLICC is Done.")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,712 @@
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Nathan Binkert
import os.path
import re
import sys
from m5.util import code_formatter
from m5.util.grammar import Grammar, ParseError
import slicc.ast as ast
import slicc.util as util
from slicc.symbols import SymbolTable
class SLICC(Grammar):
def __init__(self, filename, verbose=False, traceback=False, **kwargs):
self.protocol = None
self.traceback = traceback
self.verbose = verbose
self.symtab = SymbolTable(self)
try:
self.decl_list = self.parse_file(filename, **kwargs)
except ParseError, e:
if not self.traceback:
sys.exit(str(e))
raise
def currentLocation(self):
return util.Location(self.current_source, self.current_line,
no_warning=not self.verbose)
def codeFormatter(self, *args, **kwargs):
code = code_formatter(*args, **kwargs)
code['protocol'] = self.protocol
return code
def process(self):
self.decl_list.findMachines()
self.decl_list.generate()
def writeCodeFiles(self, code_path):
self.symtab.writeCodeFiles(code_path)
def writeHTMLFiles(self, html_path):
self.symtab.writeHTMLFiles(html_path)
def files(self):
f = set([
'MachineType.cc',
'MachineType.hh',
'Types.hh' ])
f |= self.decl_list.files()
return f
t_ignore = '\t '
# C or C++ comment (ignore)
def t_c_comment(self, t):
r'/\*(.|\n)*?\*/'
t.lexer.lineno += t.value.count('\n')
def t_cpp_comment(self, t):
r'//.*'
# Define a rule so we can track line numbers
def t_newline(self, t):
r'\n+'
t.lexer.lineno += len(t.value)
reserved = {
'protocol' : 'PROTOCOL',
'include' : 'INCLUDE',
'global' : 'GLOBAL',
'machine' : 'MACHINE',
'in_port' : 'IN_PORT',
'out_port' : 'OUT_PORT',
'action' : 'ACTION',
'transition' : 'TRANS',
'structure' : 'STRUCT',
'external_type' : 'EXTERN_TYPE',
'enumeration' : 'ENUM',
'state_declaration' : 'STATE_DECL',
'peek' : 'PEEK',
'stall_and_wait' : 'STALL_AND_WAIT',
'enqueue' : 'ENQUEUE',
'copy_head' : 'COPY_HEAD',
'check_allocate' : 'CHECK_ALLOCATE',
'check_stop_slots' : 'CHECK_STOP_SLOTS',
'static_cast' : 'STATIC_CAST',
'if' : 'IF',
'is_valid' : 'IS_VALID',
'is_invalid' : 'IS_INVALID',
'else' : 'ELSE',
'return' : 'RETURN',
'THIS' : 'THIS',
'CHIP' : 'CHIP',
'void' : 'VOID',
'new' : 'NEW',
'OOD' : 'OOD',
}
literals = ':[]{}(),='
tokens = [ 'EQ', 'NE', 'LT', 'GT', 'LE', 'GE',
'LEFTSHIFT', 'RIGHTSHIFT',
'NOT', 'AND', 'OR',
'PLUS', 'DASH', 'STAR', 'SLASH',
'DOUBLE_COLON', 'SEMI',
'ASSIGN', 'DOT',
'IDENT', 'LIT_BOOL', 'FLOATNUMBER', 'NUMBER', 'STRING' ]
tokens += reserved.values()
t_EQ = r'=='
t_NE = r'!='
t_LT = r'<'
t_GT = r'>'
t_LE = r'<='
t_GE = r'>='
t_LEFTSHIFT = r'<<'
t_RIGHTSHIFT = r'>>'
t_NOT = r'!'
t_AND = r'&&'
t_OR = r'\|\|'
t_PLUS = r'\+'
t_DASH = r'-'
t_STAR = r'\*'
t_SLASH = r'/'
t_DOUBLE_COLON = r'::'
t_SEMI = r';'
t_ASSIGN = r':='
t_DOT = r'\.'
precedence = (
('left', 'AND', 'OR'),
('left', 'EQ', 'NE'),
('left', 'LT', 'GT', 'LE', 'GE'),
('left', 'RIGHTSHIFT', 'LEFTSHIFT'),
('left', 'PLUS', 'DASH'),
('left', 'STAR', 'SLASH'),
('right', 'NOT', 'UMINUS'),
)
def t_IDENT(self, t):
r'[a-zA-Z_][a-zA-Z_0-9]*'
if t.value == 'true':
t.type = 'LIT_BOOL'
t.value = True
return t
if t.value == 'false':
t.type = 'LIT_BOOL'
t.value = False
return t
# Check for reserved words
t.type = self.reserved.get(t.value, 'IDENT')
return t
def t_FLOATNUMBER(self, t):
'[0-9]+[.][0-9]+'
try:
t.value = float(t.value)
except ValueError:
raise ParseError("Illegal float", t)
return t
def t_NUMBER(self, t):
r'[0-9]+'
try:
t.value = int(t.value)
except ValueError:
raise ParseError("Illegal number", t)
return t
def t_STRING1(self, t):
r'\"[^"\n]*\"'
t.type = 'STRING'
t.value = t.value[1:-1]
return t
def t_STRING2(self, t):
r"\'[^'\n]*\'"
t.type = 'STRING'
t.value = t.value[1:-1]
return t
def p_file(self, p):
"file : decls"
p[0] = p[1]
def p_empty(self, p):
"empty :"
def p_decls(self, p):
"decls : declsx"
p[0] = ast.DeclListAST(self, p[1])
def p_declsx__list(self, p):
"declsx : decl declsx"
if isinstance(p[1], ast.DeclListAST):
decls = p[1].decls
elif p[1] is None:
decls = []
else:
decls = [ p[1] ]
p[0] = decls + p[2]
def p_declsx__none(self, p):
"declsx : empty"
p[0] = []
def p_decl__protocol(self, p):
"decl : PROTOCOL STRING SEMI"
if self.protocol:
msg = "Protocol can only be set once! Error at %s:%s\n" % \
(self.current_source, self.current_line)
raise ParseError(msg)
self.protocol = p[2]
p[0] = None
def p_decl__include(self, p):
"decl : INCLUDE STRING SEMI"
dirname = os.path.dirname(self.current_source)
filename = os.path.join(dirname, p[2])
p[0] = self.parse_file(filename)
def p_decl__machine(self, p):
"decl : MACHINE '(' ident pairs ')' ':' params '{' decls '}'"
p[0] = ast.MachineAST(self, p[3], p[4], p[7], p[9])
def p_decl__action(self, p):
"decl : ACTION '(' ident pairs ')' statements"
p[0] = ast.ActionDeclAST(self, p[3], p[4], p[6])
def p_decl__in_port(self, p):
"decl : IN_PORT '(' ident ',' type ',' var pairs ')' statements"
p[0] = ast.InPortDeclAST(self, p[3], p[5], p[7], p[8], p[10])
def p_decl__out_port(self, p):
"decl : OUT_PORT '(' ident ',' type ',' var pairs ')' SEMI"
p[0] = ast.OutPortDeclAST(self, p[3], p[5], p[7], p[8])
def p_decl__trans0(self, p):
"decl : TRANS '(' idents ',' idents ',' ident pairs ')' idents"
p[0] = ast.TransitionDeclAST(self, p[3], p[5], p[7], p[8], p[10])
def p_decl__trans1(self, p):
"decl : TRANS '(' idents ',' idents pairs ')' idents"
p[0] = ast.TransitionDeclAST(self, p[3], p[5], None, p[6], p[8])
def p_decl__extern0(self, p):
"decl : EXTERN_TYPE '(' type pairs ')' SEMI"
p[4]["external"] = "yes"
p[0] = ast.TypeDeclAST(self, p[3], p[4], [])
def p_decl__global(self, p):
"decl : GLOBAL '(' type pairs ')' '{' type_members '}'"
p[4]["global"] = "yes"
p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7])
def p_decl__struct(self, p):
"decl : STRUCT '(' type pairs ')' '{' type_members '}'"
p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7])
def p_decl__enum(self, p):
"decl : ENUM '(' type pairs ')' '{' type_enums '}'"
p[4]["enumeration"] = "yes"
p[0] = ast.EnumDeclAST(self, p[3], p[4], p[7])
def p_decl__state_decl(self, p):
"decl : STATE_DECL '(' type pairs ')' '{' type_states '}'"
p[4]["enumeration"] = "yes"
p[4]["state_decl"] = "yes"
p[0] = ast.StateDeclAST(self, p[3], p[4], p[7])
def p_decl__object(self, p):
"decl : type ident pairs SEMI"
p[0] = ast.ObjDeclAST(self, p[1], p[2], p[3])
def p_decl__func_decl(self, p):
"""decl : void ident '(' params ')' pairs SEMI
| type ident '(' params ')' pairs SEMI"""
p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], None)
def p_decl__func_def(self, p):
"""decl : void ident '(' params ')' pairs statements
| type ident '(' params ')' pairs statements"""
p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], p[7])
# Type fields
def p_type_members__list(self, p):
"type_members : type_member type_members"
p[0] = [ p[1] ] + p[2]
def p_type_members__empty(self, p):
"type_members : empty"
p[0] = []
def p_type_method__0(self, p):
"type_member : type_or_void ident '(' types ')' pairs SEMI"
p[0] = ast.TypeFieldMethodAST(self, p[1], p[2], p[4], p[6])
def p_type_member__1(self, p):
"type_member : type_or_void ident pairs SEMI"
p[0] = ast.TypeFieldMemberAST(self, p[1], p[2], p[3], None)
def p_type_member__2(self, p):
"type_member : type_or_void ident ASSIGN expr SEMI"
p[0] = ast.TypeFieldMemberAST(self, p[1], p[2],
ast.PairListAST(self), p[4])
# Enum fields
def p_type_enums__list(self, p):
"type_enums : type_enum type_enums"
p[0] = [ p[1] ] + p[2]
def p_type_enums__empty(self, p):
"type_enums : empty"
p[0] = []
def p_type_enum(self, p):
"type_enum : ident pairs SEMI"
p[0] = ast.TypeFieldEnumAST(self, p[1], p[2])
# States
def p_type_states__list(self, p):
"type_states : type_state type_states"
p[0] = [ p[1] ] + p[2]
def p_type_states__empty(self, p):
"type_states : empty"
p[0] = []
def p_type_state(self, p):
"type_state : ident ',' enumeration pairs SEMI"
p[0] = ast.TypeFieldStateAST(self, p[1], p[3], p[4])
# Type
def p_types__multiple(self, p):
"types : type ',' types"
p[0] = [ p[1] ] + p[3]
def p_types__one(self, p):
"types : type"
p[0] = [ p[1] ]
def p_types__empty(self, p):
"types : empty"
p[0] = []
def p_typestr__multi(self, p):
"typestr : typestr DOUBLE_COLON ident"
p[0] = '%s::%s' % (p[1], p[3])
def p_typestr__single(self, p):
"typestr : ident"
p[0] = p[1]
def p_type__one(self, p):
"type : typestr"
p[0] = ast.TypeAST(self, p[1])
def p_void(self, p):
"void : VOID"
p[0] = ast.TypeAST(self, p[1])
def p_type_or_void(self, p):
"""type_or_void : type
| void"""
p[0] = p[1]
# Formal Param
def p_params__many(self, p):
"params : param ',' params"
p[0] = [ p[1] ] + p[3]
def p_params__one(self, p):
"params : param"
p[0] = [ p[1] ]
def p_params__none(self, p):
"params : empty"
p[0] = []
def p_param(self, p):
"param : type ident"
p[0] = ast.FormalParamAST(self, p[1], p[2])
def p_param__pointer(self, p):
"param : type STAR ident"
p[0] = ast.FormalParamAST(self, p[1], p[3], None, True)
def p_param__pointer_default(self, p):
"param : type STAR ident '=' STRING"
p[0] = ast.FormalParamAST(self, p[1], p[3], p[5], True)
def p_param__default_number(self, p):
"param : type ident '=' NUMBER"
p[0] = ast.FormalParamAST(self, p[1], p[2], p[4])
def p_param__default_bool(self, p):
"param : type ident '=' LIT_BOOL"
p[0] = ast.FormalParamAST(self, p[1], p[2], p[4])
def p_param__default_string(self, p):
"param : type ident '=' STRING"
p[0] = ast.FormalParamAST(self, p[1], p[2], p[4])
# Idents and lists
def p_idents__braced(self, p):
"idents : '{' identx '}'"
p[0] = p[2]
def p_idents__bare(self, p):
"idents : ident"
p[0] = [ p[1] ]
def p_identx__multiple_1(self, p):
"""identx : ident SEMI identx
| ident ',' identx"""
p[0] = [ p[1] ] + p[3]
def p_identx__multiple_2(self, p):
"identx : ident identx"
p[0] = [ p[1] ] + p[2]
def p_identx__single(self, p):
"identx : empty"
p[0] = [ ]
def p_ident(self, p):
"ident : IDENT"
p[0] = p[1]
# Pair and pair lists
def p_pairs__list(self, p):
"pairs : ',' pairsx"
p[0] = p[2]
def p_pairs__empty(self, p):
"pairs : empty"
p[0] = ast.PairListAST(self)
def p_pairsx__many(self, p):
"pairsx : pair ',' pairsx"
p[0] = p[3]
p[0].addPair(p[1])
def p_pairsx__one(self, p):
"pairsx : pair"
p[0] = ast.PairListAST(self)
p[0].addPair(p[1])
def p_pair__assign(self, p):
"""pair : ident '=' STRING
| ident '=' ident
| ident '=' NUMBER"""
p[0] = ast.PairAST(self, p[1], p[3])
def p_pair__literal(self, p):
"pair : STRING"
p[0] = ast.PairAST(self, "short", p[1])
# Below are the rules for action descriptions
def p_statements__inner(self, p):
"statements : '{' statements_inner '}'"
p[0] = ast.StatementListAST(self, p[2])
def p_statements__none(self, p):
"statements : '{' '}'"
p[0] = ast.StatementListAST(self, [])
def p_statements_inner__many(self, p):
"statements_inner : statement statements_inner"
p[0] = [ p[1] ] + p[2]
def p_statements_inner__one(self, p):
"statements_inner : statement"
p[0] = [ p[1] ]
def p_exprs__multiple(self, p):
"exprs : expr ',' exprs"
p[0] = [ p[1] ] + p[3]
def p_exprs__one(self, p):
"exprs : expr"
p[0] = [ p[1] ]
def p_exprs__empty(self, p):
"exprs : empty"""
p[0] = []
def p_statement__expression(self, p):
"statement : expr SEMI"
p[0] = ast.ExprStatementAST(self, p[1])
def p_statement__assign(self, p):
"statement : expr ASSIGN expr SEMI"
p[0] = ast.AssignStatementAST(self, p[1], p[3])
def p_statement__enqueue(self, p):
"statement : ENQUEUE '(' var ',' type pairs ')' statements"
p[0] = ast.EnqueueStatementAST(self, p[3], p[5], p[6], p[8])
def p_statement__stall_and_wait(self, p):
"statement : STALL_AND_WAIT '(' var ',' var ')' SEMI"
p[0] = ast.StallAndWaitStatementAST(self, p[3], p[5])
def p_statement__peek(self, p):
"statement : PEEK '(' var ',' type pairs ')' statements"
p[0] = ast.PeekStatementAST(self, p[3], p[5], p[6], p[8], "peek")
def p_statement__copy_head(self, p):
"statement : COPY_HEAD '(' var ',' var pairs ')' SEMI"
p[0] = ast.CopyHeadStatementAST(self, p[3], p[5], p[6])
def p_statement__check_allocate(self, p):
"statement : CHECK_ALLOCATE '(' var ')' SEMI"
p[0] = ast.CheckAllocateStatementAST(self, p[3])
def p_statement__check_stop(self, p):
"statement : CHECK_STOP_SLOTS '(' var ',' STRING ',' STRING ')' SEMI"
p[0] = ast.CheckStopStatementAST(self, p[3], p[5], p[7])
def p_statement__static_cast(self, p):
"aexpr : STATIC_CAST '(' type ',' expr ')'"
p[0] = ast.StaticCastAST(self, p[3], "ref", p[5])
def p_statement__static_cast_ptr(self, p):
"aexpr : STATIC_CAST '(' type ',' STRING ',' expr ')'"
p[0] = ast.StaticCastAST(self, p[3], p[5], p[7])
def p_statement__return(self, p):
"statement : RETURN expr SEMI"
p[0] = ast.ReturnStatementAST(self, p[2])
def p_statement__if(self, p):
"statement : if_statement"
p[0] = p[1]
def p_if_statement__if(self, p):
"if_statement : IF '(' expr ')' statements"
p[0] = ast.IfStatementAST(self, p[3], p[5], None)
def p_if_statement__if_else(self, p):
"if_statement : IF '(' expr ')' statements ELSE statements"
p[0] = ast.IfStatementAST(self, p[3], p[5], p[7])
def p_statement__if_else_if(self, p):
"if_statement : IF '(' expr ')' statements ELSE if_statement"
p[0] = ast.IfStatementAST(self, p[3], p[5],
ast.StatementListAST(self, p[7]))
def p_expr__var(self, p):
"aexpr : var"
p[0] = p[1]
def p_expr__localvar(self, p):
"aexpr : type ident"
p[0] = ast.LocalVariableAST(self, p[1], p[2])
def p_expr__literal(self, p):
"aexpr : literal"
p[0] = p[1]
def p_expr__enumeration(self, p):
"aexpr : enumeration"
p[0] = p[1]
def p_expr__func_call(self, p):
"aexpr : ident '(' exprs ')'"
p[0] = ast.FuncCallExprAST(self, p[1], p[3])
def p_expr__new(self, p):
"aexpr : NEW type"
p[0] = ast.NewExprAST(self, p[2])
def p_expr__null(self, p):
"aexpr : OOD"
p[0] = ast.OodAST(self)
# globally access a local chip component and call a method
def p_expr__local_chip_method(self, p):
"aexpr : THIS DOT var '[' expr ']' DOT var DOT ident '(' exprs ')'"
p[0] = ast.LocalChipMethodAST(self, p[3], p[5], p[8], p[10], p[12])
# globally access a local chip component and access a data member
def p_expr__local_chip_member(self, p):
"aexpr : THIS DOT var '[' expr ']' DOT var DOT field"
p[0] = ast.LocalChipMemberAST(self, p[3], p[5], p[8], p[10])
# globally access a specified chip component and call a method
def p_expr__specified_chip_method(self, p):
"aexpr : CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT ident '(' exprs ')'"
p[0] = ast.SpecifiedChipMethodAST(self, p[3], p[6], p[8], p[11], p[13],
p[15])
# globally access a specified chip component and access a data member
def p_expr__specified_chip_member(self, p):
"aexpr : CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT field"
p[0] = ast.SpecifiedChipMemberAST(self, p[3], p[6], p[8], p[11], p[13])
def p_expr__member(self, p):
"aexpr : aexpr DOT ident"
p[0] = ast.MemberExprAST(self, p[1], p[3])
def p_expr__member_method_call(self, p):
"aexpr : aexpr DOT ident '(' exprs ')'"
p[0] = ast.MemberMethodCallExprAST(self, p[1], p[3], p[5])
def p_expr__member_method_call_lookup(self, p):
"aexpr : aexpr '[' exprs ']'"
p[0] = ast.MemberMethodCallExprAST(self, p[1], "lookup", p[3])
def p_expr__class_method_call(self, p):
"aexpr : type DOUBLE_COLON ident '(' exprs ')'"
p[0] = ast.ClassMethodCallExprAST(self, p[1], p[3], p[5])
def p_expr__aexpr(self, p):
"expr : aexpr"
p[0] = p[1]
def p_expr__binary_op(self, p):
"""expr : expr STAR expr
| expr SLASH expr
| expr PLUS expr
| expr DASH expr
| expr LT expr
| expr GT expr
| expr LE expr
| expr GE expr
| expr EQ expr
| expr NE expr
| expr AND expr
| expr OR expr
| expr RIGHTSHIFT expr
| expr LEFTSHIFT expr"""
p[0] = ast.InfixOperatorExprAST(self, p[1], p[2], p[3])
# FIXME - unary not
def p_expr__unary_op(self, p):
"""expr : NOT expr
| DASH expr %prec UMINUS"""
p[0] = PrefixOperatorExpr(p[1], p[2])
def p_expr__parens(self, p):
"aexpr : '(' expr ')'"
p[0] = p[2]
def p_expr__is_valid_ptr(self, p):
"aexpr : IS_VALID '(' var ')'"
p[0] = ast.IsValidPtrExprAST(self, p[3], True)
def p_expr__is_invalid_ptr(self, p):
"aexpr : IS_INVALID '(' var ')'"
p[0] = ast.IsValidPtrExprAST(self, p[3], False)
def p_literal__string(self, p):
"literal : STRING"
p[0] = ast.LiteralExprAST(self, p[1], "std::string")
def p_literal__number(self, p):
"literal : NUMBER"
p[0] = ast.LiteralExprAST(self, p[1], "int")
def p_literal__float(self, p):
"literal : FLOATNUMBER"
p[0] = ast.LiteralExprAST(self, p[1], "int")
def p_literal__bool(self, p):
"literal : LIT_BOOL"
p[0] = ast.LiteralExprAST(self, p[1], "bool")
def p_enumeration(self, p):
"enumeration : ident ':' ident"
p[0] = ast.EnumExprAST(self, ast.TypeAST(self, p[1]), p[3])
def p_var(self, p):
"var : ident"
p[0] = ast.VarExprAST(self, p[1])
def p_field(self, p):
"field : ident"
p[0] = p[1]

View File

@ -0,0 +1,38 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.symbols.Symbol import Symbol
class Action(Symbol):
def __init__(self, table, ident, resources, location, pairs):
super(Action, self).__init__(table, ident, location, pairs)
self.resources = resources
def __repr__(self):
return "[Action: %s]" % self.ident
__all__ = [ "Action" ]

View File

@ -0,0 +1,34 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.symbols.Symbol import Symbol
class Event(Symbol):
def __repr__(self):
return "[Event: %s]" % self.ident
__all__ = [ "Event" ]

View File

@ -0,0 +1,100 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.symbols.Symbol import Symbol
from slicc.symbols.Type import Type
class Func(Symbol):
def __init__(self, table, ident, location, return_type, param_types,
param_strings, body, pairs, machine):
super(Func, self).__init__(table, ident, location, pairs)
self.return_type = return_type
self.param_types = param_types
self.param_strings = param_strings
self.body = body
self.isInternalMachineFunc = False
self.c_ident = ident
if machine is None or "external" in self or "primitive" in self:
pass
else:
self.machineStr = str(machine)
self.isInternalMachineFunc = True
def __repr__(self):
return ""
@property
def prototype(self):
if "external" in self:
return ""
return_type = self.return_type.c_ident
void_type = self.symtab.find("void", Type)
if "return_by_ref" in self and self.return_type != void_type:
return_type += "&"
elif "return_by_pointer" in self and self.return_type != void_type:
return_type += "*"
return "%s %s(%s);" % (return_type, self.c_ident,
", ".join(self.param_strings))
def writeCodeFiles(self, path):
return
def generateCode(self):
'''This write a function of object Chip'''
if "external" in self:
return ""
code = self.symtab.codeFormatter()
# Generate function header
void_type = self.symtab.find("void", Type)
return_type = self.return_type.c_ident
if "return_by_ref" in self and self.return_type != void_type:
return_type += "&"
if "return_by_pointer" in self and self.return_type != void_type:
return_type += "*"
if self.isInternalMachineFunc:
klass = "%s_Controller" % self.machineStr
else:
klass = "Chip"
params = ', '.join(self.param_strings)
code('''
$return_type
${klass}::${{self.c_ident}}($params)
{
${{self.body}}
}
''')
return str(code)
__all__ = [ "Func" ]

View File

@ -0,0 +1,34 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.symbols.Symbol import Symbol
class State(Symbol):
def __repr__(self):
return "[State: %s]" % self.ident
__all__ = [ "State" ]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,78 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.util import PairContainer
class Symbol(PairContainer):
def __init__(self, symtab, ident, location, pairs=None):
super(Symbol, self).__init__()
from slicc.util import Location
from slicc.symbols import SymbolTable
if not isinstance(symtab, SymbolTable): raise AttributeError
if not isinstance(ident, str): raise AttributeError
if not isinstance(location, Location): raise AttributeError
self.symtab = symtab
self.ident = ident
self.location = location
if pairs:
self.pairs.update(getattr(pairs, "pairs", pairs))
if "short" not in self:
self["short"] = self.ident
self.used = False
def __repr__(self):
return "[Symbol: %s]" % self.ident
def __str__(self):
return str(self.ident)
def __setitem__(self, key, value):
if key in self.pairs:
self.warning("Pair key '%s' re-defined. new: '%s' old: '%s'",
key, value, self.pairs[key])
super(Symbol, self).__setitem__(key, value)
@property
def short(self):
return self["short"]
@property
def desc(self):
return self["desc"]
def error(self, message, *args):
self.location.error(message, *args)
def warning(self, message, *args):
self.location.warning(message, *args)
def writeHTMLFiles(self, path):
pass
__all__ = [ "Symbol" ]

View File

@ -0,0 +1,175 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from m5.util import makeDir
from slicc.generate import html
from slicc.symbols.StateMachine import StateMachine
from slicc.symbols.Type import Type
from slicc.util import Location
class SymbolTable(object):
def __init__(self, slicc):
self.slicc = slicc
self.sym_vec = []
self.sym_map_vec = [ {} ]
self.machine_components = {}
pairs = {}
pairs["enumeration"] = "yes"
location = Location("init", 0, no_warning=not slicc.verbose)
MachineType = Type(self, "MachineType", location, pairs)
self.newSymbol(MachineType)
pairs = {}
pairs["primitive"] = "yes"
pairs["external"] = "yes"
location = Location("init", 0, no_warning=not slicc.verbose)
void = Type(self, "void", location, pairs)
self.newSymbol(void)
def __repr__(self):
return "[SymbolTable]" # FIXME
def codeFormatter(self, *args, **kwargs):
return self.slicc.codeFormatter(*args, **kwargs)
def newSymbol(self, sym):
self.registerSym(str(sym), sym)
self.sym_vec.append(sym)
def registerSym(self, id, sym):
# Check for redeclaration (in the current frame only)
if id in self.sym_map_vec[-1]:
sym.error("Symbol '%s' redeclared in same scope.", id)
# FIXME - warn on masking of a declaration in a previous frame
self.sym_map_vec[-1][id] = sym
def find(self, ident, types=None):
for sym_map in reversed(self.sym_map_vec):
try:
symbol = sym_map[ident]
except KeyError:
continue
if types is not None:
if not isinstance(symbol, types):
symbol.error("Symbol '%s' is not of types '%s'.",
symbol,
types)
return symbol
return None
def newMachComponentSym(self, symbol):
# used to cheat-- that is, access components in other machines
machine = self.find("current_machine", StateMachine)
if machine:
self.machine_components[str(machine)][str(symbol)] = symbol
def newCurrentMachine(self, sym):
self.registerGlobalSym(str(sym), sym)
self.registerSym("current_machine", sym)
self.sym_vec.append(sym)
self.machine_components[str(sym)] = {}
@property
def state_machine(self):
return self.find("current_machine", StateMachine)
def pushFrame(self):
self.sym_map_vec.append({})
def popFrame(self):
assert len(self.sym_map_vec) > 0
self.sym_map_vec.pop()
def registerGlobalSym(self, ident, symbol):
# Check for redeclaration (global frame only)
if ident in self.sym_map_vec[0]:
symbol.error("Symbol '%s' redeclared in global scope." % ident)
self.sym_map_vec[0][ident] = symbol
def getAllType(self, type):
for symbol in self.sym_vec:
if isinstance(symbol, type):
yield symbol
def writeCodeFiles(self, path):
makeDir(path)
code = self.codeFormatter()
code('''
/** Auto generated C++ code started by $__file__:$__line__ */
#include "mem/ruby/slicc_interface/RubySlicc_includes.hh"
''')
for symbol in self.sym_vec:
if isinstance(symbol, Type) and not symbol.isPrimitive:
code('#include "mem/protocol/${{symbol.c_ident}}.hh"')
code.write(path, "Types.hh")
for symbol in self.sym_vec:
symbol.writeCodeFiles(path)
def writeHTMLFiles(self, path):
makeDir(path)
machines = list(self.getAllType(StateMachine))
if len(machines) > 1:
name = "%s_table.html" % machines[0].ident
else:
name = "empty.html"
code = self.codeFormatter()
code('''
<html>
<head>
<title>$path</title>
</head>
<frameset rows="*,30">
<frame name="Table" src="$name">
<frame name="Status" src="empty.html">
</frameset>
</html>
''')
code.write(path, "index.html")
code = self.codeFormatter()
code("<HTML></HTML>")
code.write(path, "empty.html")
for symbol in self.sym_vec:
symbol.writeHTMLFiles(path)
__all__ = [ "SymbolTable" ]

View File

@ -0,0 +1,61 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.symbols.Symbol import Symbol
class Transition(Symbol):
def __init__(self, table, machine, state, event, nextState, actions,
location, pairs):
ident = "%s|%s" % (state, event)
super(Transition, self).__init__(table, ident, location, pairs)
self.state = machine.states[state]
self.event = machine.events[event]
self.nextState = machine.states[nextState]
self.actions = [ machine.actions[a] for a in actions ]
self.resources = {}
for action in self.actions:
for var,value in action.resources.iteritems():
if var.type.ident != "DNUCAStopTable":
num = int(value)
if var in self.resources:
num += int(value)
self.resources[var] = str(num)
else:
self.resources[var] = value
def __repr__(self):
return "[Transition: (%r, %r) -> %r, %r]" % \
(self.state, self.event, self.nextState, self.actions)
def getActionShorthands(self):
assert self.actions
return ''.join(a.short for a in self.actions)
__all__ = [ "Transition" ]

View File

@ -0,0 +1,778 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from m5.util import orderdict
from slicc.util import PairContainer
from slicc.symbols.Symbol import Symbol
class DataMember(PairContainer):
def __init__(self, ident, type, pairs, init_code):
super(DataMember, self).__init__(pairs)
self.ident = ident
self.type = type
self.init_code = init_code
class Enumeration(PairContainer):
def __init__(self, ident, pairs):
super(Enumeration, self).__init__(pairs)
self.ident = ident
class Method(object):
def __init__(self, return_type, param_types):
self.return_type = return_type
self.param_types = param_types
class Type(Symbol):
def __init__(self, table, ident, location, pairs, machine=None):
super(Type, self).__init__(table, ident, location, pairs)
self.c_ident = ident
self.abstract_ident = ""
if machine:
if self.isExternal or self.isPrimitive:
if "external_name" in self:
self.c_ident = self["external_name"]
else:
# Append with machine name
self.c_ident = "%s_%s" % (machine, ident)
self.pairs.setdefault("desc", "No description avaliable")
# check for interface that this Type implements
if "interface" in self:
interface = self["interface"]
if interface in ("Message", "NetworkMessage"):
self["message"] = "yes"
if interface == "NetworkMessage":
self["networkmessage"] = "yes"
# FIXME - all of the following id comparisons are fragile hacks
if self.ident in ("CacheMemory", "NewCacheMemory",
"TLCCacheMemory", "DNUCACacheMemory",
"DNUCABankCacheMemory", "L2BankCacheMemory",
"CompressedCacheMemory", "PrefetchCacheMemory"):
self["cache"] = "yes"
if self.ident in ("TBETable", "DNUCATBETable", "DNUCAStopTable"):
self["tbe"] = "yes"
if self.ident == "NewTBETable":
self["newtbe"] = "yes"
if self.ident == "TimerTable":
self["timer"] = "yes"
if self.ident == "DirectoryMemory":
self["dir"] = "yes"
if self.ident == "PersistentTable":
self["persistent"] = "yes"
if self.ident == "Prefetcher":
self["prefetcher"] = "yes"
if self.ident == "DNUCA_Movement":
self["mover"] = "yes"
self.isMachineType = (ident == "MachineType")
self.isStateDecl = ("state_decl" in self)
self.statePermPairs = []
self.data_members = orderdict()
# Methods
self.methods = {}
# Enums
self.enums = orderdict()
@property
def isPrimitive(self):
return "primitive" in self
@property
def isNetworkMessage(self):
return "networkmessage" in self
@property
def isMessage(self):
return "message" in self
@property
def isBuffer(self):
return "buffer" in self
@property
def isInPort(self):
return "inport" in self
@property
def isOutPort(self):
return "outport" in self
@property
def isEnumeration(self):
return "enumeration" in self
@property
def isExternal(self):
return "external" in self
@property
def isGlobal(self):
return "global" in self
@property
def isInterface(self):
return "interface" in self
# Return false on error
def dataMemberAdd(self, ident, type, pairs, init_code):
if ident in self.data_members:
return False
member = DataMember(ident, type, pairs, init_code)
self.data_members[ident] = member
return True
def dataMemberType(self, ident):
return self.data_members[ident].type
def methodId(self, name, param_type_vec):
return '_'.join([name] + [ pt.c_ident for pt in param_type_vec ])
def methodIdAbstract(self, name, param_type_vec):
return '_'.join([name] + [ pt.abstract_ident for pt in param_type_vec ])
def statePermPairAdd(self, state_name, perm_name):
self.statePermPairs.append([state_name, perm_name])
def methodAdd(self, name, return_type, param_type_vec):
ident = self.methodId(name, param_type_vec)
if ident in self.methods:
return False
self.methods[ident] = Method(return_type, param_type_vec)
return True
def enumAdd(self, ident, pairs):
if ident in self.enums:
return False
self.enums[ident] = Enumeration(ident, pairs)
# Add default
if "default" not in self:
self["default"] = "%s_NUM" % self.c_ident
return True
def writeCodeFiles(self, path):
if self.isExternal:
# Do nothing
pass
elif self.isEnumeration:
self.printEnumHH(path)
self.printEnumCC(path)
else:
# User defined structs and messages
self.printTypeHH(path)
self.printTypeCC(path)
def printTypeHH(self, path):
code = self.symtab.codeFormatter()
code('''
/** \\file ${{self.c_ident}}.hh
*
*
* Auto generated C++ code started by $__file__:$__line__
*/
#ifndef __${{self.c_ident}}_HH__
#define __${{self.c_ident}}_HH__
#include <iostream>
#include "mem/ruby/common/Global.hh"
''')
for dm in self.data_members.values():
if not dm.type.isPrimitive:
code('#include "mem/protocol/$0.hh"', dm.type.c_ident)
parent = ""
if "interface" in self:
code('#include "mem/protocol/$0.hh"', self["interface"])
parent = " : public %s" % self["interface"]
code('''
$klass ${{self.c_ident}}$parent
{
public:
${{self.c_ident}}()
{
''', klass="class")
code.indent()
if not self.isGlobal:
code.indent()
for dm in self.data_members.values():
ident = dm.ident
if "default" in dm:
# look for default value
code('m_$ident = ${{dm["default"]}}; // default for this field')
elif "default" in dm.type:
# Look for the type default
tid = dm.type.c_ident
code('m_$ident = ${{dm.type["default"]}}; // default value of $tid')
else:
code('// m_$ident has no default')
code.dedent()
code('}')
# ******** Copy constructor ********
if not self.isGlobal:
code('${{self.c_ident}}(const ${{self.c_ident}}&other)')
# Call superclass constructor
if "interface" in self:
code(' : ${{self["interface"]}}(other)')
code('{')
code.indent()
for dm in self.data_members.values():
code('m_${{dm.ident}} = other.m_${{dm.ident}};')
code.dedent()
code('}')
# ******** Full init constructor ********
if not self.isGlobal:
params = [ 'const %s& local_%s' % (dm.type.c_ident, dm.ident) \
for dm in self.data_members.itervalues() ]
params = ', '.join(params)
code('${{self.c_ident}}($params)')
# Call superclass constructor
if "interface" in self:
code(' : ${{self["interface"]}}()')
code('{')
code.indent()
for dm in self.data_members.values():
code('m_${{dm.ident}} = local_${{dm.ident}};')
if "nextLineCallHack" in dm:
code('m_${{dm.ident}}${{dm["nextLineCallHack"]}};')
code.dedent()
code('}')
# create a static factory method and a clone member
code('''
static ${{self.c_ident}}*
create()
{
return new ${{self.c_ident}}();
}
${{self.c_ident}}*
clone() const
{
return new ${{self.c_ident}}(*this);
}
''')
if not self.isGlobal:
# const Get methods for each field
code('// Const accessors methods for each field')
for dm in self.data_members.values():
code('''
/** \\brief Const accessor method for ${{dm.ident}} field.
* \\return ${{dm.ident}} field
*/
const ${{dm.type.c_ident}}&
get${{dm.ident}}() const
{
return m_${{dm.ident}};
}
''')
# Non-const Get methods for each field
code('// Non const Accessors methods for each field')
for dm in self.data_members.values():
code('''
/** \\brief Non-const accessor method for ${{dm.ident}} field.
* \\return ${{dm.ident}} field
*/
${{dm.type.c_ident}}&
get${{dm.ident}}()
{
return m_${{dm.ident}};
}
''')
#Set methods for each field
code('// Mutator methods for each field')
for dm in self.data_members.values():
code('''
/** \\brief Mutator method for ${{dm.ident}} field */
void
set${{dm.ident}}(const ${{dm.type.c_ident}}& local_${{dm.ident}})
{
m_${{dm.ident}} = local_${{dm.ident}};
}
''')
code('void print(std::ostream& out) const;')
code.dedent()
code(' //private:')
code.indent()
# Data members for each field
for dm in self.data_members.values():
if "abstract" not in dm:
const = ""
init = ""
# global structure
if self.isGlobal:
const = "static const "
# init value
if dm.init_code:
# only global structure can have init value here
assert self.isGlobal
init = " = %s" % (dm.init_code)
if "desc" in dm:
code('/** ${{dm["desc"]}} */')
code('$const${{dm.type.c_ident}} m_${{dm.ident}}$init;')
code.dedent()
code('};')
code('''
inline std::ostream&
operator<<(std::ostream& out, const ${{self.c_ident}}& obj)
{
obj.print(out);
out << std::flush;
return out;
}
#endif // __${{self.c_ident}}_HH__
''')
code.write(path, "%s.hh" % self.c_ident)
def printTypeCC(self, path):
code = self.symtab.codeFormatter()
code('''
/** \\file ${{self.c_ident}}.cc
*
* Auto generated C++ code started by $__file__:$__line__
*/
#include <iostream>
#include "mem/protocol/${{self.c_ident}}.hh"
using namespace std;
''')
code('''
/** \\brief Print the state of this object */
void
${{self.c_ident}}::print(ostream& out) const
{
out << "[${{self.c_ident}}: ";
''')
# For each field
code.indent()
for dm in self.data_members.values():
code('out << "${{dm.ident}} = " << m_${{dm.ident}} << " ";''')
if self.isMessage:
code('out << "Time = " << getTime() * g_eventQueue_ptr->getClock() << " ";')
code.dedent()
# Trailer
code('''
out << "]";
}''')
code.write(path, "%s.cc" % self.c_ident)
def printEnumHH(self, path):
code = self.symtab.codeFormatter()
code('''
/** \\file ${{self.c_ident}}.hh
*
* Auto generated C++ code started by $__file__:$__line__
*/
#ifndef __${{self.c_ident}}_HH__
#define __${{self.c_ident}}_HH__
#include <iostream>
#include <string>
''')
if self.isStateDecl:
code('#include "mem/protocol/AccessPermission.hh"')
if self.isMachineType:
code('#include "base/misc.hh"')
code('#include "mem/protocol/GenericMachineType.hh"')
code('#include "mem/ruby/common/Address.hh"')
code('struct MachineID;')
code('''
// Class definition
/** \\enum ${{self.c_ident}}
* \\brief ${{self.desc}}
*/
enum ${{self.c_ident}} {
${{self.c_ident}}_FIRST,
''')
code.indent()
# For each field
for i,(ident,enum) in enumerate(self.enums.iteritems()):
desc = enum.get("desc", "No description avaliable")
if i == 0:
init = ' = %s_FIRST' % self.c_ident
else:
init = ''
code('${{self.c_ident}}_${{enum.ident}}$init, /**< $desc */')
code.dedent()
code('''
${{self.c_ident}}_NUM
};
// Code to convert from a string to the enumeration
${{self.c_ident}} string_to_${{self.c_ident}}(const std::string& str);
// Code to convert state to a string
std::string ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj);
// Code to increment an enumeration type
${{self.c_ident}} &operator++(${{self.c_ident}} &e);
''')
# MachineType hack used to set the base component id for each Machine
if self.isMachineType:
code('''
int ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj);
MachineType ${{self.c_ident}}_from_base_level(int);
int ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj);
int ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj);
''')
for enum in self.enums.itervalues():
if enum.ident == "DMA":
code('''
MachineID map_Address_to_DMA(const Address &addr);
''')
code('''
MachineID get${{enum.ident}}MachineID(NodeID RubyNode);
''')
code('''
inline GenericMachineType
ConvertMachToGenericMach(MachineType machType)
{
''')
for enum in self.enums.itervalues():
code('''
if (machType == MachineType_${{enum.ident}})
return GenericMachineType_${{enum.ident}};
''')
code('''
panic("cannot convert to a GenericMachineType");
}
''')
if self.isStateDecl:
code('''
// Code to convert the current state to an access permission
AccessPermission ${{self.c_ident}}_to_permission(const ${{self.c_ident}}& obj);
''')
# Trailer
code('''
std::ostream& operator<<(std::ostream& out, const ${{self.c_ident}}& obj);
#endif // __${{self.c_ident}}_HH__
''')
code.write(path, "%s.hh" % self.c_ident)
def printEnumCC(self, path):
code = self.symtab.codeFormatter()
code('''
/** \\file ${{self.c_ident}}.hh
*
* Auto generated C++ code started by $__file__:$__line__
*/
#include <cassert>
#include <iostream>
#include <string>
#include "base/misc.hh"
#include "mem/protocol/${{self.c_ident}}.hh"
using namespace std;
''')
if self.isStateDecl:
code('''
// Code to convert the current state to an access permission
AccessPermission ${{self.c_ident}}_to_permission(const ${{self.c_ident}}& obj)
{
switch(obj) {
''')
# For each case
code.indent()
for statePerm in self.statePermPairs:
code(' case ${{self.c_ident}}_${{statePerm[0]}}:')
code(' return AccessPermission_${{statePerm[1]}};')
code.dedent()
code ('''
default:
panic("Unknown state access permission converstion for ${{self.c_ident}}");
}
}
''')
if self.isMachineType:
for enum in self.enums.itervalues():
code('#include "mem/protocol/${{enum.ident}}_Controller.hh"')
code('#include "mem/ruby/system/MachineID.hh"')
code('''
// Code for output operator
ostream&
operator<<(ostream& out, const ${{self.c_ident}}& obj)
{
out << ${{self.c_ident}}_to_string(obj);
out << flush;
return out;
}
// Code to convert state to a string
string
${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj)
{
switch(obj) {
''')
# For each field
code.indent()
for enum in self.enums.itervalues():
code(' case ${{self.c_ident}}_${{enum.ident}}:')
code(' return "${{enum.ident}}";')
code.dedent()
# Trailer
code('''
default:
panic("Invalid range for type ${{self.c_ident}}");
}
}
// Code to convert from a string to the enumeration
${{self.c_ident}}
string_to_${{self.c_ident}}(const string& str)
{
''')
# For each field
start = ""
code.indent()
for enum in self.enums.itervalues():
code('${start}if (str == "${{enum.ident}}") {')
code(' return ${{self.c_ident}}_${{enum.ident}};')
start = "} else "
code.dedent()
code('''
} else {
panic("Invalid string conversion for %s, type ${{self.c_ident}}", str);
}
}
// Code to increment an enumeration type
${{self.c_ident}}&
operator++(${{self.c_ident}}& e)
{
assert(e < ${{self.c_ident}}_NUM);
return e = ${{self.c_ident}}(e+1);
}
''')
# MachineType hack used to set the base level and number of
# components for each Machine
if self.isMachineType:
code('''
/** \\brief returns the base vector index for each machine type to be
* used by NetDest
*
* \\return the base vector index for each machine type to be used by NetDest
* \\see NetDest.hh
*/
int
${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj)
{
switch(obj) {
''')
# For each field
code.indent()
for i,enum in enumerate(self.enums.itervalues()):
code(' case ${{self.c_ident}}_${{enum.ident}}:')
code(' return $i;')
code.dedent()
# total num
code('''
case ${{self.c_ident}}_NUM:
return ${{len(self.enums)}};
default:
panic("Invalid range for type ${{self.c_ident}}");
}
}
/** \\brief returns the machine type for each base vector index used by NetDest
*
* \\return the MachineType
*/
MachineType
${{self.c_ident}}_from_base_level(int type)
{
switch(type) {
''')
# For each field
code.indent()
for i,enum in enumerate(self.enums.itervalues()):
code(' case $i:')
code(' return ${{self.c_ident}}_${{enum.ident}};')
code.dedent()
# Trailer
code('''
default:
panic("Invalid range for type ${{self.c_ident}}");
}
}
/** \\brief The return value indicates the number of components created
* before a particular machine\'s components
*
* \\return the base number of components for each machine
*/
int
${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj)
{
int base = 0;
switch(obj) {
''')
# For each field
code.indent()
code(' case ${{self.c_ident}}_NUM:')
for enum in reversed(self.enums.values()):
code(' base += ${{enum.ident}}_Controller::getNumControllers();')
code(' case ${{self.c_ident}}_${{enum.ident}}:')
code(' break;')
code.dedent()
code('''
default:
panic("Invalid range for type ${{self.c_ident}}");
}
return base;
}
/** \\brief returns the total number of components for each machine
* \\return the total number of components for each machine
*/
int
${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj)
{
switch(obj) {
''')
# For each field
for enum in self.enums.itervalues():
code('''
case ${{self.c_ident}}_${{enum.ident}}:
return ${{enum.ident}}_Controller::getNumControllers();
''')
# total num
code('''
case ${{self.c_ident}}_NUM:
default:
panic("Invalid range for type ${{self.c_ident}}");
}
}
''')
for enum in self.enums.itervalues():
if enum.ident == "DMA":
code('''
MachineID
map_Address_to_DMA(const Address &addr)
{
MachineID dma = {MachineType_DMA, 0};
return dma;
}
''')
code('''
MachineID
get${{enum.ident}}MachineID(NodeID RubyNode)
{
MachineID mach = {MachineType_${{enum.ident}}, RubyNode};
return mach;
}
''')
# Write the file
code.write(path, "%s.cc" % self.c_ident)
__all__ = [ "Type" ]

View File

@ -0,0 +1,50 @@
# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from slicc.symbols.Symbol import Symbol
class Var(Symbol):
def __init__(self, symtab, ident, location, type, code, pairs,
machine=None):
super(Var, self).__init__(symtab, ident, location, pairs)
if machine:
self.c_ident = "%s_%s" % (machine, ident)
else:
self.c_ident = ident
self.machine = machine
self.type = type
self.code = code
def __repr__(self):
return "[Var id: %s]" % (self.c_ident)
def writeCodeFiles(self, path):
pass
__all__ = [ "Var" ]

View File

@ -0,0 +1,38 @@
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Nathan Binkert
from slicc.symbols.Action import Action
from slicc.symbols.Event import Event
from slicc.symbols.Func import Func
from slicc.symbols.State import State
from slicc.symbols.StateMachine import StateMachine
from slicc.symbols.Symbol import Symbol
from slicc.symbols.SymbolTable import SymbolTable
from slicc.symbols.Transition import Transition
from slicc.symbols.Type import Type
from slicc.symbols.Var import Var

View File

@ -0,0 +1,77 @@
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import os
import sys
class PairContainer(object):
def __init__(self, pairs=None):
self.pairs = {}
if pairs:
self.pairs.update(pairs)
def __contains__(self, item):
return item in self.pairs
def __getitem__(self, item):
return self.pairs[item]
def __setitem__(self, item, value):
self.pairs[item] = value
def get(self, item, failobj=None):
return self.pairs.get(item, failobj)
class Location(object):
def __init__(self, filename, lineno, no_warning=False):
if not isinstance(filename, basestring):
raise AttributeError, \
"filename must be a string, found '%s'" % (type(filename), )
if not isinstance(lineno, (int, long)):
raise AttributeError, \
"filename must be an integer, found '%s'" % (type(lineno), )
self.filename = filename
self.lineno = lineno
self.no_warning = no_warning
def __str__(self):
return '%s:%d' % (os.path.basename(self.filename), self.lineno)
def warning(self, message, *args):
if self.no_warning:
return
if args:
message = message % args
#raise Exception, "%s: Warning: %s" % (self, message)
print >>sys.stderr, "%s: Warning: %s" % (self, message)
def error(self, message, *args):
if args:
message = message % args
raise Exception, "%s: Error: %s" % (self, message)
sys.exit("\n%s: Error: %s" % (self, message))
__all__ = [ 'PairContainer', 'Location' ]