SymbolTable.py revision 6794
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 if not isinstance(symbol, types): 76 symbol.error("Symbol '%s' is not of types '%s'.", 77 symbol, 78 types) 79 80 return symbol 81 82 return None 83 84 def newMachComponentSym(self, symbol): 85 # used to cheat-- that is, access components in other machines 86 machine = self.find("current_machine", StateMachine) 87 if machine: 88 self.machine_components[str(machine)][str(symbol)] = symbol 89 90 def newCurrentMachine(self, sym): 91 self.registerGlobalSym(str(sym), sym) 92 self.registerSym("current_machine", sym) 93 self.sym_vec.append(sym) 94 95 self.machine_components[str(sym)] = {} 96 97 @property 98 def state_machine(self): 99 return self.find("current_machine", StateMachine) 100 101 def pushFrame(self): 102 self.sym_map_vec.append({}) 103 104 def popFrame(self): 105 assert len(self.sym_map_vec) > 0 106 self.sym_map_vec.pop() 107 108 def registerGlobalSym(self, ident, symbol): 109 # Check for redeclaration (global frame only) 110 if ident in self.sym_map_vec[0]: 111 symbol.error("Symbol '%s' redeclared in global scope." % ident) 112 113 self.sym_map_vec[0][ident] = symbol 114 115 def getAllType(self, type): 116 for symbol in self.sym_vec: 117 if isinstance(symbol, type): 118 yield symbol 119 120 def writeCodeFiles(self, path): 121 code = code_formatter() 122 code(''' 123/** Auto generated C++ code started by $__file__:$__line__ */ 124 125#include "mem/ruby/slicc_interface/RubySlicc_includes.hh" 126''') 127 for symbol in self.sym_vec: 128 if isinstance(symbol, Type) and not symbol.isPrimitive: 129 code('#include "mem/protocol/${{symbol.c_ident}}.hh"') 130 131 code.write(path, "Types.hh") 132 133 for symbol in self.sym_vec: 134 symbol.writeCodeFiles(path) 135 136 self.writeControllerFactory(path) 137 138 def writeControllerFactory(self, path): 139 code = code_formatter() 140 141 code(''' 142/** \\file ControllerFactory.hh 143 * Auto generatred C++ code started by $__file__:$__line__ 144 */ 145 146#ifndef CONTROLLERFACTORY_H 147#define CONTROLLERFACTORY_H 148 149#include <string> 150class Network; 151class AbstractController; 152 153class ControllerFactory { 154 public: 155 static AbstractController *createController(const std::string &controller_type, const std::string &name); 156}; 157#endif // CONTROLLERFACTORY_H''') 158 code.write(path, "ControllerFactory.hh") 159 160 code = code_formatter() 161 code(''' 162/** \\file ControllerFactory.cc 163 * Auto generatred C++ code started by $__file__:$__line__ 164 */ 165 166#include "mem/protocol/ControllerFactory.hh" 167#include "mem/ruby/slicc_interface/AbstractController.hh" 168#include "mem/protocol/MachineType.hh" 169''') 170 171 controller_types = [] 172 for symbol in self.getAllType(StateMachine): 173 code('#include "mem/protocol/${{symbol.ident}}_Controller.hh"') 174 controller_types.append(symbol.ident) 175 176 code(''' 177AbstractController *ControllerFactory::createController(const std::string &controller_type, const std::string &name) { 178''') 179 180 for ct in controller_types: 181 code(''' 182 if (controller_type == "$ct") 183 return new ${ct}_Controller(name); 184''') 185 186 code(''' 187 assert(0); // invalid controller type 188 return NULL; 189} 190''') 191 code.write(path, "ControllerFactory.cc") 192 193 def writeHTMLFiles(self, path): 194 machines = list(self.getAllType(StateMachine)) 195 if len(machines) > 1: 196 name = "%s_table.html" % machines[0].ident 197 else: 198 name = "empty.html" 199 200 code = code_formatter() 201 code(''' 202<html> 203<head> 204<title>$path</title> 205</head> 206<frameset rows="*,30"> 207 <frame name="Table" src="$name"> 208 <frame name="Status" src="empty.html"> 209</frameset> 210</html> 211''') 212 code.write(path, "index.html") 213 214 code = code_formatter() 215 code("<HTML></HTML>") 216 code.write(path, "empty.html") 217 218 for symbol in self.sym_vec: 219 symbol.writeHTMLFiles(path) 220 221__all__ = [ "SymbolTable" ] 222