diff -r fbdaa08aaa42 -r ba670c48f3c8 src/mem/protocol/SConscript --- a/src/mem/protocol/SConscript Tue May 05 09:25:59 2015 -0700 +++ b/src/mem/protocol/SConscript Sat May 09 14:20:22 2015 -0500 @@ -63,10 +63,10 @@ env.Append(SCANNERS=slicc_scanner) def slicc_emitter(target, source, env): - assert len(source) == 1 filepath = source[0].srcnode().abspath + other_protocol_sources = source[1:] - slicc = SLICC(filepath, protocol_base.abspath, verbose=False) + slicc = SLICC(filepath, other_protocol_sources, protocol_base.abspath, verbose=False) slicc.process() slicc.writeCodeFiles(output_dir.abspath, slicc_includes) if env['SLICC_HTML']: @@ -76,10 +76,10 @@ return target, source def slicc_action(target, source, env): - assert len(source) == 1 filepath = source[0].srcnode().abspath + other_protocol_sources = source[1:] - slicc = SLICC(filepath, protocol_base.abspath, verbose=True) + slicc = SLICC(filepath, other_protocol_sources, protocol_base.abspath, verbose=True) slicc.process() slicc.writeCodeFiles(output_dir.abspath, slicc_includes) if env['SLICC_HTML']: @@ -88,18 +88,22 @@ slicc_builder = Builder(action=MakeAction(slicc_action, Transform("SLICC")), emitter=slicc_emitter) -protocol = env['PROTOCOL'] +sources = [] +build_protocol = env['PROTOCOL'] protocol_dir = None -for path in protocol_dirs: - if os.path.exists(os.path.join(path, "%s.slicc" % protocol)): - protocol_dir = Dir(path) - break +for proto in all_protocols: + for path in protocol_dirs: + if os.path.exists(os.path.join(path, "%s.slicc" % proto)): + if proto == build_protocol: + # Insert the build protocol file at sources list head + protocol_dir = Dir(path) + sources.insert(0, Dir(path).File("%s.slicc" % proto)) + else: + sources.append(Dir(path).File("%s.slicc" % proto)) if not protocol_dir: raise ValueError, "Could not find %s.slicc in protocol_dirs" % protocol -sources = [ protocol_dir.File("%s.slicc" % protocol) ] - env.Append(BUILDERS={'SLICC' : slicc_builder}) nodes = env.SLICC([], sources) env.Depends(nodes, slicc_depends) diff -r fbdaa08aaa42 -r ba670c48f3c8 src/mem/slicc/ast/DeclAST.py --- a/src/mem/slicc/ast/DeclAST.py Tue May 05 09:25:59 2015 -0700 +++ b/src/mem/slicc/ast/DeclAST.py Sat May 09 14:20:22 2015 -0500 @@ -36,3 +36,6 @@ def findMachines(self): return + + def getMachineTypes(self): + return None diff -r fbdaa08aaa42 -r ba670c48f3c8 src/mem/slicc/ast/DeclListAST.py --- a/src/mem/slicc/ast/DeclListAST.py Tue May 05 09:25:59 2015 -0700 +++ b/src/mem/slicc/ast/DeclListAST.py Sat May 09 14:20:22 2015 -0500 @@ -38,6 +38,13 @@ def __repr__(self): return "[DeclListAST: %s]" % (', '.join(repr(d) for d in self.decls)) + def addExternalDeclarations(self, decls): + # Add declarations that were generated outside the tree + for decl in decls: + # Make sure they point to the same SLICC instance + decl.setSlicc(self.slicc) + self.decls.append(decl) + def files(self, parent=None): s = set() for decl in self.decls: @@ -51,3 +58,11 @@ def findMachines(self): for decl in self.decls: decl.findMachines() + + def getMachineTypes(self): + machine_types = [] + for decl in self.decls: + mtypes = decl.getMachineTypes() + if mtypes is not None: + machine_types += mtypes + return machine_types diff -r fbdaa08aaa42 -r ba670c48f3c8 src/mem/slicc/ast/MachineAST.py --- a/src/mem/slicc/ast/MachineAST.py Tue May 05 09:25:59 2015 -0700 +++ b/src/mem/slicc/ast/MachineAST.py Sat May 09 14:20:22 2015 -0500 @@ -87,3 +87,45 @@ # Generate code for all the internal decls self.decls.findMachines() + + def getMachineTypes(self): + return [ MinimalMachineAST(self) ] + +class MinimalMachineAST(MachineAST): + def __init__(self, machine): + super(MinimalMachineAST, self).__init__(machine.slicc, + machine.machine_types, + machine.pairs_ast, + machine.config_parameters, + machine.decls) + + def __repr__(self): + return "[MinimalMachine: %r]" % self.ident + + def setSlicc(self, slicc): + # Since MinimalMachineAST instances are generated under separate + # SLICC instances, must set the SLICC instance for the tree to + # which they will be added + self.slicc = slicc + + def files(self, parent=None): + # Overload the files function to keep this MachineType + # from generating any controller files. + return set() + + def generate(self): + return + + def findMachines(self): + # Add to MachineType enumeration + for mtype in self.machine_types: + machine_type = self.symtab.find("MachineType", Type) + pairs = self.pairs_ast.pairs + + # Setting Primary = False keeps the code generator from adding + # an include header in MachineTypes.hh for this MinimalMachine + pairs["Primary"] = False + + if not machine_type.addEnum(mtype, pairs): + self.warning("Skipping existing machine name: %s:%s" % ( + machine_type, mtype)) diff -r fbdaa08aaa42 -r ba670c48f3c8 src/mem/slicc/parser.py --- a/src/mem/slicc/parser.py Tue May 05 09:25:59 2015 -0700 +++ b/src/mem/slicc/parser.py Sat May 09 14:20:22 2015 -0500 @@ -35,10 +35,10 @@ import slicc.ast as ast import slicc.util as util -from slicc.symbols import SymbolTable +from slicc.symbols import SymbolTable, Type class SLICC(Grammar): - def __init__(self, filename, base_dir, verbose=False, traceback=False, **kwargs): + def __init__(self, filename, other_sources, base_dir, verbose=False, traceback=False, **kwargs): self.protocol = None self.traceback = traceback self.verbose = verbose @@ -52,6 +52,23 @@ sys.exit(str(e)) raise + if len(other_sources) > 0: + # Create a SLICC instance for each other protocol in order to + # generate their MachineTypes. Gather those MachineTypes for + # inclusion in the dynamically generated MachineType enumeration + other_machine_types = [] + for source in other_sources: + try: + filepath = source.srcnode().abspath + slicc = SLICC(filepath, [], base_dir) + other_machine_types += slicc.decl_list.getMachineTypes() + except ParseError, e: + if not self.traceback: + sys.exit(str(e)) + raise + + self.decl_list.addExternalDeclarations(other_machine_types) + def currentLocation(self): return util.Location(self.current_source, self.current_line, no_warning=not self.verbose)