SymbolTable.py revision 6657
1# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 2# Copyright (c) 2009 The Hewlett-Packard Development Company 3# All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions are 7# met: redistributions of source code must retain the above copyright 8# notice, this list of conditions and the following disclaimer; 9# redistributions in binary form must reproduce the above copyright 10# notice, this list of conditions and the following disclaimer in the 11# documentation and/or other materials provided with the distribution; 12# neither the name of the copyright holders nor the names of its 13# contributors may be used to endorse or promote products derived from 14# this software without specific prior written permission. 15# 16# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28from m5.util import code_formatter 29 30from slicc.generate import html 31from slicc.symbols.StateMachine import StateMachine 32from slicc.symbols.Type import Type 33from slicc.util import Location 34 35class SymbolTable(object): 36 def __init__(self): 37 self.sym_vec = [] 38 self.sym_map_vec = [ {} ] 39 self.machine_components = {} 40 41 pairs = {} 42 pairs["enumeration"] = "yes" 43 MachineType = Type(self, "MachineType", Location("init", 0), pairs) 44 self.newSymbol(MachineType) 45 46 pairs = {} 47 pairs["primitive"] = "yes" 48 pairs["external"] = "yes" 49 void = Type(self, "void", Location("init", 0), pairs) 50 self.newSymbol(void) 51 52 def __repr__(self): 53 return "[SymbolTable]" # FIXME 54 55 def newSymbol(self, sym): 56 self.registerSym(str(sym), sym) 57 self.sym_vec.append(sym) 58 59 def registerSym(self, id, sym): 60 # Check for redeclaration (in the current frame only) 61 if id in self.sym_map_vec[-1]: 62 sym.error("Symbol '%s' redeclared in same scope.", id) 63 64 # FIXME - warn on masking of a declaration in a previous frame 65 self.sym_map_vec[-1][id] = sym 66 67 def find(self, ident, types=None): 68 for sym_map in reversed(self.sym_map_vec): 69 try: 70 symbol = sym_map[ident] 71 except KeyError: 72 continue 73 74 if types is not None: 75 assert isinstance(symbol, types) 76 77 return symbol 78 79 return None 80 81 def newMachComponentSym(self, symbol): 82 # used to cheat-- that is, access components in other machines 83 machine = self.find("current_machine", StateMachine) 84 if machine: 85 self.machine_components[str(machine)][str(symbol)] = symbol 86 87 def newCurrentMachine(self, sym): 88 self.registerGlobalSym(str(sym), sym) 89 self.registerSym("current_machine", sym) 90 self.sym_vec.append(sym) 91 92 self.machine_components[str(sym)] = {} 93 94 @property 95 def state_machine(self): 96 return self.find("current_machine", StateMachine) 97 98 def pushFrame(self): 99 self.sym_map_vec.append({}) 100 101 def popFrame(self): 102 assert len(self.sym_map_vec) > 0 103 self.sym_map_vec.pop() 104 105 def registerGlobalSym(self, ident, symbol): 106 # Check for redeclaration (global frame only) 107 if ident in self.sym_map_vec[0]: 108 symbol.error("Symbol '%s' redeclared in global scope." % ident) 109 110 self.sym_map_vec[0][ident] = symbol 111 112 def getAllType(self, type): 113 for symbol in self.sym_vec: 114 if isinstance(symbol, type): 115 yield symbol 116 117 def writeCodeFiles(self, path): 118 code = code_formatter() 119 code(''' 120/** Auto generated C++ code started by $__file__:$__line__ */ 121 122#include "mem/ruby/slicc_interface/RubySlicc_includes.hh" 123''') 124 for symbol in self.sym_vec: 125 if isinstance(symbol, Type) and not symbol.isPrimitive: 126 code('#include "mem/protocol/${{symbol.c_ident}}.hh"') 127 128 code.write(path, "Types.hh") 129 130 for symbol in self.sym_vec: 131 symbol.writeCodeFiles(path) 132 133 self.writeControllerFactory(path) 134 135 def writeControllerFactory(self, path): 136 code = code_formatter() 137 138 code(''' 139/** \\file ControllerFactory.hh 140 * Auto generatred C++ code started by $__file__:$__line__ 141 */ 142 143#ifndef CONTROLLERFACTORY_H 144#define CONTROLLERFACTORY_H 145 146#include <string> 147class Network; 148class AbstractController; 149 150class ControllerFactory { 151 public: 152 static AbstractController *createController(const std::string &controller_type, const std::string &name); 153}; 154#endif // CONTROLLERFACTORY_H''') 155 code.write(path, "ControllerFactory.hh") 156 157 code = code_formatter() 158 code(''' 159/** \\file ControllerFactory.cc 160 * Auto generatred C++ code started by $__file__:$__line__ 161 */ 162 163#include "mem/protocol/ControllerFactory.hh" 164#include "mem/ruby/slicc_interface/AbstractController.hh" 165#include "mem/protocol/MachineType.hh" 166''') 167 168 controller_types = [] 169 for symbol in self.getAllType(StateMachine): 170 code('#include "mem/protocol/${{symbol.ident}}_Controller.hh"') 171 controller_types.append(symbol.ident) 172 173 code(''' 174AbstractController *ControllerFactory::createController(const std::string &controller_type, const std::string &name) { 175''') 176 177 for ct in controller_types: 178 code(''' 179 if (controller_type == "$ct") 180 return new ${ct}_Controller(name); 181''') 182 183 code(''' 184 assert(0); // invalid controller type 185 return NULL; 186} 187''') 188 code.write(path, "ControllerFactory.cc") 189 190 def writeHTMLFiles(self, path): 191 machines = list(self.getAllType(StateMachine)) 192 if len(machines) > 1: 193 name = "%s_table.html" % machines[0].ident 194 else: 195 name = "empty.html" 196 197 code = code_formatter() 198 code(''' 199<html> 200<head> 201<title>$path</title> 202</head> 203<frameset rows="*,30"> 204 <frame name="Table" src="$name"> 205 <frame name="Status" src="empty.html"> 206</frameset> 207</html> 208''') 209 code.write(path, "index.html") 210 211 code = code_formatter() 212 code("<HTML></HTML>") 213 code.write(path, "empty.html") 214 215 for symbol in self.sym_vec: 216 symbol.writeHTMLFiles(path) 217 218__all__ = [ "SymbolTable" ] 219