diff options
author | Polina Dudnik <pdudnik@gmail.com> | 2009-08-17 11:33:32 -0500 |
---|---|---|
committer | Polina Dudnik <pdudnik@gmail.com> | 2009-08-17 11:33:32 -0500 |
commit | c438b2e431066d9324238e1c678ef68a3b721f33 (patch) | |
tree | b79e72b3074441ce01d5c95207f96f71d16bed35 /src | |
parent | 6654fe02daf6285cb43aa1c6e0e35f6c9c8786f1 (diff) | |
parent | a43ae579dd3128a0ced2238532f26d99db197361 (diff) | |
download | gem5-c438b2e431066d9324238e1c678ef68a3b721f33.tar.xz |
Branch Merge
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/x86/isa/insts/general_purpose/arithmetic/multiply_and_divide.py | 8 | ||||
-rw-r--r-- | src/python/SConscript | 3 | ||||
-rw-r--r-- | src/python/m5/__init__.py | 13 | ||||
-rw-r--r-- | src/python/m5/util/__init__.py | 2 | ||||
-rw-r--r-- | src/python/m5/util/code_formatter.py | 311 | ||||
-rw-r--r-- | src/python/m5/util/grammar.py | 119 | ||||
-rw-r--r-- | src/python/m5/util/orderdict.py | 59 |
7 files changed, 475 insertions, 40 deletions
diff --git a/src/arch/x86/isa/insts/general_purpose/arithmetic/multiply_and_divide.py b/src/arch/x86/isa/insts/general_purpose/arithmetic/multiply_and_divide.py index 47ad1d53c..86f1946ba 100644 --- a/src/arch/x86/isa/insts/general_purpose/arithmetic/multiply_and_divide.py +++ b/src/arch/x86/isa/insts/general_purpose/arithmetic/multiply_and_divide.py @@ -459,7 +459,7 @@ def macroop IDIV_B_M ld t8, seg, sib, disp #Find the sign of the divisor - slli t0, t3, 1, flags=(ECF,), dataSize=1 + slli t0, t8, 1, flags=(ECF,), dataSize=1 # Negate divisor sub t3, t0, t8, dataSize=1 @@ -531,7 +531,7 @@ def macroop IDIV_B_P ld t8, seg, riprel, disp #Find the sign of the divisor - slli t0, t3, 1, flags=(ECF,), dataSize=1 + slli t0, t8, 1, flags=(ECF,), dataSize=1 # Negate divisor sub t3, t0, t8, dataSize=1 @@ -678,7 +678,7 @@ def macroop IDIV_M #Find the sign of the divisor #FIXME!!! This depends on shifts setting the carry flag correctly. - slli t0, t3, 1, flags=(ECF,) + slli t0, t8, 1, flags=(ECF,) # Negate divisor sub t3, t0, t8 @@ -754,7 +754,7 @@ def macroop IDIV_P #Find the sign of the divisor #FIXME!!! This depends on shifts setting the carry flag correctly. - slli t0, t3, 1, flags=(ECF,) + slli t0, t8, 1, flags=(ECF,) # Negate divisor sub t3, t0, t8 diff --git a/src/python/SConscript b/src/python/SConscript index a767545ec..bb892f376 100644 --- a/src/python/SConscript +++ b/src/python/SConscript @@ -53,9 +53,12 @@ PySource('m5', 'm5/ticks.py') PySource('m5', 'm5/trace.py') PySource('m5.util', 'm5/util/__init__.py') PySource('m5.util', 'm5/util/attrdict.py') +PySource('m5.util', 'm5/util/code_formatter.py') +PySource('m5.util', 'm5/util/grammar.py') PySource('m5.util', 'm5/util/jobfile.py') PySource('m5.util', 'm5/util/misc.py') PySource('m5.util', 'm5/util/multidict.py') +PySource('m5.util', 'm5/util/orderdict.py') SwigSource('m5.internal', 'swig/core.i') SwigSource('m5.internal', 'swig/debug.i') diff --git a/src/python/m5/__init__.py b/src/python/m5/__init__.py index 733258acf..c3512cd0d 100644 --- a/src/python/m5/__init__.py +++ b/src/python/m5/__init__.py @@ -103,8 +103,11 @@ try: except ImportError: internal = None -import defines -build_env.update(defines.buildEnv) +try: + import defines + build_env.update(defines.buildEnv) +except ImportError: + defines = None if internal: defines.compileDate = internal.core.compileDate @@ -120,4 +123,8 @@ if internal: import SimObject import params -import objects + +try: + import objects +except ImportError: + objects = None diff --git a/src/python/m5/util/__init__.py b/src/python/m5/util/__init__.py index 5c4a066c6..3930c8b6f 100644 --- a/src/python/m5/util/__init__.py +++ b/src/python/m5/util/__init__.py @@ -27,8 +27,10 @@ # Authors: Nathan Binkert from attrdict import attrdict, optiondict +from code_formatter import code_formatter from misc import * from multidict import multidict +from orderdict import orderdict import jobfile def print_list(items, indent=4): diff --git a/src/python/m5/util/code_formatter.py b/src/python/m5/util/code_formatter.py new file mode 100644 index 000000000..919a6423b --- /dev/null +++ b/src/python/m5/util/code_formatter.py @@ -0,0 +1,311 @@ +# Copyright (c) 2006-2009 Nathan Binkert <nate@binkert.org> +# 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 inspect +import os +import re +import string + +class lookup(object): + def __init__(self, formatter, frame, *args, **kwargs): + self.frame = frame + self.formatter = formatter + self.dict = self.formatter._dict + self.args = args + self.kwargs = kwargs + self.locals = {} + + def __setitem__(self, item, val): + self.locals[item] = val + + def __getitem__(self, item): + if item in self.locals: + return self.locals[item] + + if item in self.kwargs: + return self.kwargs[item] + + if item == '__file__': + return self.frame.f_code.co_filename + + if item == '__line__': + return self.frame.f_lineno + + if item in self.dict: + return self.dict[item] + + if self.formatter.locals or self.formatter.globals: + if self.formatter.locals and item in self.frame.f_locals: + return self.frame.f_locals[item] + + if self.formatter.globals and item in self.frame.f_globals: + return self.frame.f_globals[item] + + if item in __builtins__: + return __builtins__[item] + + try: + item = int(item) + return self.args[item] + except ValueError: + pass + raise IndexError, "Could not find '%s'" % item + +class code_formatter_meta(type): + pattern = r""" + (?: + %(delim)s(?P<escaped>%(delim)s) | # escaped delimiter + ^(?P<indent>[ ]*)%(delim)s(?P<lone>%(ident)s)$ | # lone identifier + %(delim)s(?P<ident>%(ident)s) | # identifier + %(delim)s%(lb)s(?P<b_ident>%(ident)s)%(rb)s | # braced identifier + %(delim)s(?P<pos>%(pos)s) | # positional parameter + %(delim)s%(lb)s(?P<b_pos>%(pos)s)%(rb)s | # braced positional + %(delim)s%(ldb)s(?P<eval>.*?)%(rdb)s | # double braced expression + %(delim)s(?P<invalid>) # ill-formed delimiter exprs + ) + """ + def __init__(cls, name, bases, dct): + super(code_formatter_meta, cls).__init__(name, bases, dct) + if 'pattern' in dct: + pat = cls.pattern + else: + # tuple expansion to ensure strings are proper length + lb,rb = cls.braced + lb1,lb2,rb2,rb1 = cls.double_braced + pat = code_formatter_meta.pattern % { + 'delim' : re.escape(cls.delim), + 'ident' : cls.ident, + 'pos' : cls.pos, + 'lb' : re.escape(lb), + 'rb' : re.escape(rb), + 'ldb' : re.escape(lb1+lb2), + 'rdb' : re.escape(rb2+rb1), + } + cls.pattern = re.compile(pat, re.VERBOSE | re.DOTALL | re.MULTILINE) + +class code_formatter(object): + __metaclass__ = code_formatter_meta + + delim = r'$' + ident = r'[_A-z]\w*' + pos = r'[0-9]+' + braced = r'{}' + double_braced = r'{{}}' + + globals = True + locals = True + fix_newlines = True + def __init__(self, *args, **kwargs): + self._data = [] + self._dict = {} + self._indent_level = 0 + self._indent_spaces = 4 + self.globals = kwargs.pop('globals',type(self).globals) + self.locals = kwargs.pop('locals', type(self).locals) + self._fix_newlines = \ + kwargs.pop('fix_newlines', type(self).fix_newlines) + + if args: + self.__call__(args) + + def indent(self): + self._indent_level += self._indent_spaces + + def dedent(self): + assert self._indent_level >= self._indent_spaces + self._indent_level -= self._indent_spaces + + def fix(self, status): + previous = self._fix_newlines + self._fix_newlines = status + return previous + + def nofix(self): + previous = self._fix_newlines + self._fix_newlines = False + return previous + + def clear(): + self._data = [] + + def write(self, *args): + f = file(os.path.join(*args), "w") + for data in self._data: + f.write(data) + f.close() + + def __str__(self): + data = string.join(self._data, '') + self._data = [ data ] + return data + + def __getitem__(self, item): + return self._dict[item] + + def __setitem__(self, item, value): + self._dict[item] = value + + def __delitem__(self, item): + del self._dict[item] + + def __contains__(self, item): + return item in self._dict + + def __iadd__(self, data): + self.append(data) + + def append(self, data): + if isinstance(data, code_formatter): + self._data.extend(data._data) + else: + self._append(str(data)) + + def _append(self, data): + if not self._fix_newlines: + self._data.append(data) + return + + initial_newline = not self._data or self._data[-1] == '\n' + for line in data.splitlines(): + if line: + if self._indent_level: + self._data.append(' ' * self._indent_level) + self._data.append(line) + + if line or not initial_newline: + self._data.append('\n') + + initial_newline = False + + def insert_newline(self): + self._data.append('\n') + + def __call__(self, format, *args, **kwargs): + frame = inspect.currentframe().f_back + + l = lookup(self, frame, *args, **kwargs) + def convert(match): + ident = match.group('lone') + # check for a lone identifier + if ident: + indent = match.group('indent') # must be spaces + lone = '%s' % (l[ident], ) + + def indent_lines(gen): + for line in gen: + yield indent + yield line + return ''.join(indent_lines(lone.splitlines(True))) + + # check for an identifier, braced or not + ident = match.group('ident') or match.group('b_ident') + if ident is not None: + return '%s' % (l[ident], ) + + # check for a positional parameter, braced or not + pos = match.group('pos') or match.group('b_pos') + if pos is not None: + pos = int(pos) + if pos > len(args): + raise ValueError \ + ('Positional parameter #%d not found in pattern' % pos, + code_formatter.pattern) + return '%s' % (args[int(pos)], ) + + # check for a double braced expression + eval_expr = match.group('eval') + if eval_expr is not None: + result = eval(eval_expr, {}, l) + return '%s' % (result, ) + + # check for an escaped delimiter + if match.group('escaped') is not None: + return '$' + + # At this point, we have to match invalid + if match.group('invalid') is None: + # didn't match invalid! + raise ValueError('Unrecognized named group in pattern', + code_formatter.pattern) + + i = match.start('invalid') + if i == 0: + colno = 1 + lineno = 1 + else: + lines = format[:i].splitlines(True) + colno = i - reduce(lambda x,y: x+y, (len(z) for z in lines)) + lineno = len(lines) + + raise ValueError('Invalid format string: line %d, col %d' % + (lineno, colno)) + + d = code_formatter.pattern.sub(convert, format) + self._append(d) + +__all__ = [ "code_formatter" ] + +if __name__ == '__main__': + from code_formatter import code_formatter + f = code_formatter() + + class Foo(dict): + def __init__(self, **kwargs): + self.update(kwargs) + def __getattr__(self, attr): + return self[attr] + + x = "this is a test" + l = [ [Foo(x=[Foo(y=9)])] ] + + y = code_formatter() + y(''' +{ + this_is_a_test(); +} +''') + f(' $y') + f('''$__file__:$__line__ +{''') + f("${{', '.join(str(x) for x in xrange(4))}}") + f('${x}') + f('$x') + f.indent() + for i in xrange(5): + f('$x') + f('$i') + f('$0', "zero") + f('$1 $0', "zero", "one") + f('${0}', "he went") + f('${0}asdf', "he went") + f.dedent() + + f(''' + ${{l[0][0]["x"][0].y}} +} +''', 1, 9) + + print f, diff --git a/src/python/m5/util/grammar.py b/src/python/m5/util/grammar.py new file mode 100644 index 000000000..93c2c84c4 --- /dev/null +++ b/src/python/m5/util/grammar.py @@ -0,0 +1,119 @@ +# Copyright (c) 2006-2009 Nathan Binkert <nate@binkert.org> +# 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 ply import lex, yacc + +class TokenError(lex.LexError): + def __init__(self, msg, t): + super(TokenError, self).__init__(msg) + self.token = t + +class ParseError(yacc.YaccError): + def __init__(self, message, token=None): + super(ParseError, self).__init__(message) + self.token = token + +class Tokenizer(object): + def __init__(self, lexer, data): + if isinstance(data, basestring): + indata = [ data ] + elif isinstance(data, file): + indata = data.xreadlines() + else: + indata = data + + def _input(): + for i,line in enumerate(indata): + lexer.lineno = i + 1 + lexer.input(line) + while True: + tok = lexer.token() + if not tok: + break + yield tok + self.input = _input() + + def next(self): + return self.input.next() + + def __iter__(self): + return self + + def token(self): + try: + return self.next() + except StopIteration: + return None + +class Grammar(object): + def __init__(self, output=None, debug=False): + self.yacc_args = {} + self.yacc_args['debug'] = debug + + if output: + import os + + dir,tab = os.path.split(output) + if not tab.endswith('.py'): + raise AttributeError, 'The output file must end with .py' + self.yacc_args['outputdir'] = dir + self.yacc_args['tabmodule'] = tab[:-3] + + def t_error(self, t): + raise lex.LexError("Illegal character %s @ %d:%d" % \ + (`t.value[0]`, t.lineno, t.lexpos), `t.value[0]`) + + def p_error(self, t): + if t: + msg = "Syntax error at %d:%d\n>>%s<<" % \ + (t.lineno, t.lexpos + 1, t.value) + else: + msg = "Syntax error at end of input" + raise ParseError(msg, t) + + def __getattr__(self, attr): + if attr == 'parser': + import ply.yacc + parser = ply.yacc.yacc(module=self, **self.yacc_args) + self.parser = parser + return parser + + if attr == 'lexer': + import ply.lex + lexer = ply.lex.lex(module=self) + self.lexer = lexer + return lexer + + raise AttributeError, "'%s' object has no attribute '%s'" % \ + (self.__class__.__name__, attr) + + def parse(self, stmt, **kwargs): + self.lexer.lineno = 1 + result = self.parser.parse(lexer=Tokenizer(self.lexer, stmt), **kwargs) + self.parser.restart() + + return result + diff --git a/src/python/m5/util/orderdict.py b/src/python/m5/util/orderdict.py index 3f755d299..1ffbca87a 100644 --- a/src/python/m5/util/orderdict.py +++ b/src/python/m5/util/orderdict.py @@ -28,17 +28,20 @@ __all__ = [ 'orderdict' ] -class orderdict(dict): - def __init__(self, d = {}): - self._keys = d.keys() - super(orderdict, self).__init__(d) +from UserDict import DictMixin + +class orderdict(dict, DictMixin): + def __init__(self, *args, **kwargs): + if len(args) > 1: + raise TypeError("expected at most one argument, got %d" % \ + len(args)) + self._keys = [] + self.update(*args, **kwargs) def __setitem__(self, key, item): - super(orderdict, self).__setitem__(key, item) - if not hasattr(self, '_keys'): - self._keys = [key,] - if key not in self._keys: + if key not in self: self._keys.append(key) + super(orderdict, self).__setitem__(key, item) def __delitem__(self, key): super(orderdict, self).__delitem__(key) @@ -48,33 +51,23 @@ class orderdict(dict): super(orderdict, self).clear() self._keys = [] - def items(self): - for i in self._keys: - yield i, self[i] + def iterkeys(self): + for key in self._keys: + yield key - def keys(self): - return self._keys + def itervalues(self): + for key in self._keys: + yield self[key] - def popitem(self): - if len(self._keys) == 0: - raise KeyError('dictionary is empty') - else: - key = self._keys[-1] - val = self[key] - del self[key] - return key, val + def iteritems(self): + for key in self._keys: + yield key, self[key] - def setdefault(self, key, failobj = None): - super(orderdict, self).setdefault(key, failobj) - if key not in self._keys: - self._keys.append(key) - - def update(self, d): - for key in d.keys(): - if not self.has_key(key): - self._keys.append(key) - super(orderdict, self).update(d) + def keys(self): + return self._keys[:] def values(self): - for i in self._keys: - yield self[i] + return [ self[key] for key in self._keys ] + + def items(self): + return [ (self[key],key) for key in self._keys ] |