isa_parser: move the formatMap and exportContext into the ISAParser class
This commit is contained in:
parent
4e105f6fe1
commit
4ef6e129d6
|
@ -209,21 +209,9 @@ class Template(object):
|
|||
# a defineInst() method that generates the code for an instruction
|
||||
# definition.
|
||||
|
||||
exportContextSymbols = ('InstObjParams', 'makeList', 're', 'string')
|
||||
|
||||
exportContext = {}
|
||||
|
||||
def updateExportContext():
|
||||
exportContext.update(exportDict(*exportContextSymbols))
|
||||
exportContext.update(parser.templateMap)
|
||||
|
||||
def exportDict(*symNames):
|
||||
return dict([(s, eval(s)) for s in symNames])
|
||||
|
||||
|
||||
class Format(object):
|
||||
def __init__(self, id, params, code):
|
||||
# constructor: just save away arguments
|
||||
def __init__(self, parser, id, params, code):
|
||||
self.parser = parser
|
||||
self.id = id
|
||||
self.params = params
|
||||
label = 'def format ' + id
|
||||
|
@ -238,14 +226,13 @@ class Format(object):
|
|||
self.func = defInst
|
||||
|
||||
def defineInst(self, name, args, lineno):
|
||||
context = {}
|
||||
updateExportContext()
|
||||
context.update(exportContext)
|
||||
self.parser.updateExportContext()
|
||||
context = self.parser.exportContext.copy()
|
||||
if len(name):
|
||||
Name = name[0].upper()
|
||||
if len(name) > 1:
|
||||
Name += name[1:]
|
||||
context.update({ 'name': name, 'Name': Name })
|
||||
context.update({ 'name' : name, 'Name' : Name })
|
||||
try:
|
||||
vars = self.func(self.user_code, context, *args[0], **args[1])
|
||||
except Exception, exc:
|
||||
|
@ -268,17 +255,6 @@ class NoFormat(object):
|
|||
error(lineno,
|
||||
'instruction definition "%s" with no active format!' % name)
|
||||
|
||||
# This dictionary maps format name strings to Format objects.
|
||||
formatMap = {}
|
||||
|
||||
# Define a new format
|
||||
def defFormat(id, params, code, lineno):
|
||||
# make sure we haven't already defined this one
|
||||
if formatMap.get(id, None) != None:
|
||||
error(lineno, 'format %s redefined.' % id)
|
||||
# create new object and store in global map
|
||||
formatMap[id] = Format(id, params, code)
|
||||
|
||||
#####################################################################
|
||||
#
|
||||
# Support Classes
|
||||
|
@ -1250,12 +1226,17 @@ class ISAParser(Grammar):
|
|||
|
||||
self.templateMap = {}
|
||||
|
||||
# This dictionary maps format name strings to Format objects.
|
||||
self.formatMap = {}
|
||||
|
||||
# The format stack.
|
||||
self.formatStack = Stack(NoFormat())
|
||||
|
||||
# The default case stack.
|
||||
self.defaultStack = Stack(None)
|
||||
|
||||
self.exportContext = {}
|
||||
|
||||
#####################################################################
|
||||
#
|
||||
# Lexer
|
||||
|
@ -1516,21 +1497,21 @@ StaticInstPtr
|
|||
# from polluting this script's namespace.
|
||||
def p_global_let(self, t):
|
||||
'global_let : LET CODELIT SEMI'
|
||||
updateExportContext()
|
||||
exportContext["header_output"] = ''
|
||||
exportContext["decoder_output"] = ''
|
||||
exportContext["exec_output"] = ''
|
||||
exportContext["decode_block"] = ''
|
||||
self.updateExportContext()
|
||||
self.exportContext["header_output"] = ''
|
||||
self.exportContext["decoder_output"] = ''
|
||||
self.exportContext["exec_output"] = ''
|
||||
self.exportContext["decode_block"] = ''
|
||||
try:
|
||||
exec fixPythonIndentation(t[2]) in exportContext
|
||||
exec fixPythonIndentation(t[2]) in self.exportContext
|
||||
except Exception, exc:
|
||||
if debug:
|
||||
raise
|
||||
error(t, 'error: %s in global let block "%s".' % (exc, t[2]))
|
||||
t[0] = GenCode(header_output = exportContext["header_output"],
|
||||
decoder_output = exportContext["decoder_output"],
|
||||
exec_output = exportContext["exec_output"],
|
||||
decode_block = exportContext["decode_block"])
|
||||
t[0] = GenCode(header_output=self.exportContext["header_output"],
|
||||
decoder_output=self.exportContext["decoder_output"],
|
||||
exec_output=self.exportContext["exec_output"],
|
||||
decode_block=self.exportContext["decode_block"])
|
||||
|
||||
# Define the mapping from operand type extensions to C++ types and
|
||||
# bit widths (stored in operandTypeMap).
|
||||
|
@ -1553,7 +1534,7 @@ StaticInstPtr
|
|||
if not globals().has_key('operandTypeMap'):
|
||||
error(t, 'error: operand types must be defined before operands')
|
||||
try:
|
||||
user_dict = eval('{' + t[3] + '}', exportContext)
|
||||
user_dict = eval('{' + t[3] + '}', self.exportContext)
|
||||
except Exception, exc:
|
||||
if debug:
|
||||
raise
|
||||
|
@ -1616,7 +1597,7 @@ StaticInstPtr
|
|||
def p_def_format(self, t):
|
||||
'def_format : DEF FORMAT ID LPAREN param_list RPAREN CODELIT SEMI'
|
||||
(id, params, code) = (t[3], t[5], t[7])
|
||||
defFormat(id, params, code, t.lexer.lineno)
|
||||
self.defFormat(id, params, code, t.lexer.lineno)
|
||||
t[0] = GenCode()
|
||||
|
||||
# The formal parameter list for an instruction format is a
|
||||
|
@ -1771,7 +1752,7 @@ StaticInstPtr
|
|||
def p_push_format_id(self, t):
|
||||
'push_format_id : ID'
|
||||
try:
|
||||
self.formatStack.push(formatMap[t[1]])
|
||||
self.formatStack.push(self.formatMap[t[1]])
|
||||
t[0] = ('', '// format %s' % t[1])
|
||||
except KeyError:
|
||||
error(t, 'instruction format "%s" not defined.' % t[1])
|
||||
|
@ -1845,7 +1826,7 @@ StaticInstPtr
|
|||
def p_inst_1(self, t):
|
||||
'inst : ID DBLCOLON ID LPAREN arg_list RPAREN'
|
||||
try:
|
||||
format = formatMap[t[1]]
|
||||
format = self.formatMap[t[1]]
|
||||
except KeyError:
|
||||
error(t, 'instruction format "%s" not defined.' % t[1])
|
||||
codeObj = format.defineInst(t[3], t[5], t.lexer.lineno)
|
||||
|
@ -1945,6 +1926,22 @@ StaticInstPtr
|
|||
|
||||
# END OF GRAMMAR RULES
|
||||
|
||||
exportContextSymbols = ('InstObjParams', 'makeList', 're', 'string')
|
||||
def updateExportContext(self):
|
||||
exportDict = dict([(s, eval(s)) for s in self.exportContextSymbols])
|
||||
self.exportContext.update(exportDict)
|
||||
self.exportContext.update(parser.templateMap)
|
||||
|
||||
def defFormat(self, id, params, code, lineno):
|
||||
'''Define a new format'''
|
||||
|
||||
# make sure we haven't already defined this one
|
||||
if id in self.formatMap:
|
||||
error(lineno, 'format %s redefined.' % id)
|
||||
|
||||
# create new object and store in global map
|
||||
self.formatMap[id] = Format(self, id, params, code)
|
||||
|
||||
def update_if_needed(self, file, contents):
|
||||
'''Update the output file only if the new contents are
|
||||
different from the current contents. Minimizes the files that
|
||||
|
|
Loading…
Reference in a new issue