SymbolTable.py revision 6794
16657Snate@binkert.org# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 26657Snate@binkert.org# Copyright (c) 2009 The Hewlett-Packard Development Company 36657Snate@binkert.org# All rights reserved. 46657Snate@binkert.org# 56657Snate@binkert.org# Redistribution and use in source and binary forms, with or without 66657Snate@binkert.org# modification, are permitted provided that the following conditions are 76657Snate@binkert.org# met: redistributions of source code must retain the above copyright 86657Snate@binkert.org# notice, this list of conditions and the following disclaimer; 96657Snate@binkert.org# redistributions in binary form must reproduce the above copyright 106657Snate@binkert.org# notice, this list of conditions and the following disclaimer in the 116657Snate@binkert.org# documentation and/or other materials provided with the distribution; 126657Snate@binkert.org# neither the name of the copyright holders nor the names of its 136657Snate@binkert.org# contributors may be used to endorse or promote products derived from 146657Snate@binkert.org# this software without specific prior written permission. 156657Snate@binkert.org# 166657Snate@binkert.org# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176657Snate@binkert.org# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186657Snate@binkert.org# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196657Snate@binkert.org# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206657Snate@binkert.org# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216657Snate@binkert.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226657Snate@binkert.org# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236657Snate@binkert.org# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246657Snate@binkert.org# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256657Snate@binkert.org# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266657Snate@binkert.org# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276657Snate@binkert.org 286657Snate@binkert.orgfrom m5.util import code_formatter 296657Snate@binkert.org 306657Snate@binkert.orgfrom slicc.generate import html 316657Snate@binkert.orgfrom slicc.symbols.StateMachine import StateMachine 326657Snate@binkert.orgfrom slicc.symbols.Type import Type 336657Snate@binkert.orgfrom slicc.util import Location 346657Snate@binkert.org 356657Snate@binkert.orgclass SymbolTable(object): 366657Snate@binkert.org def __init__(self): 376657Snate@binkert.org self.sym_vec = [] 386657Snate@binkert.org self.sym_map_vec = [ {} ] 396657Snate@binkert.org self.machine_components = {} 406657Snate@binkert.org 416657Snate@binkert.org pairs = {} 426657Snate@binkert.org pairs["enumeration"] = "yes" 436657Snate@binkert.org MachineType = Type(self, "MachineType", Location("init", 0), pairs) 446657Snate@binkert.org self.newSymbol(MachineType) 456657Snate@binkert.org 466657Snate@binkert.org pairs = {} 476657Snate@binkert.org pairs["primitive"] = "yes" 486657Snate@binkert.org pairs["external"] = "yes" 496657Snate@binkert.org void = Type(self, "void", Location("init", 0), pairs) 506657Snate@binkert.org self.newSymbol(void) 516657Snate@binkert.org 526657Snate@binkert.org def __repr__(self): 536657Snate@binkert.org return "[SymbolTable]" # FIXME 546657Snate@binkert.org 556657Snate@binkert.org def newSymbol(self, sym): 566657Snate@binkert.org self.registerSym(str(sym), sym) 576657Snate@binkert.org self.sym_vec.append(sym) 586657Snate@binkert.org 596657Snate@binkert.org def registerSym(self, id, sym): 606657Snate@binkert.org # Check for redeclaration (in the current frame only) 616657Snate@binkert.org if id in self.sym_map_vec[-1]: 626657Snate@binkert.org sym.error("Symbol '%s' redeclared in same scope.", id) 636657Snate@binkert.org 646657Snate@binkert.org # FIXME - warn on masking of a declaration in a previous frame 656657Snate@binkert.org self.sym_map_vec[-1][id] = sym 666657Snate@binkert.org 676657Snate@binkert.org def find(self, ident, types=None): 686657Snate@binkert.org for sym_map in reversed(self.sym_map_vec): 696657Snate@binkert.org try: 706657Snate@binkert.org symbol = sym_map[ident] 716657Snate@binkert.org except KeyError: 726657Snate@binkert.org continue 736657Snate@binkert.org 746657Snate@binkert.org if types is not None: 756794SBrad.Beckmann@amd.com if not isinstance(symbol, types): 766794SBrad.Beckmann@amd.com symbol.error("Symbol '%s' is not of types '%s'.", 776794SBrad.Beckmann@amd.com symbol, 786794SBrad.Beckmann@amd.com types) 796657Snate@binkert.org 806657Snate@binkert.org return symbol 816657Snate@binkert.org 826657Snate@binkert.org return None 836657Snate@binkert.org 846657Snate@binkert.org def newMachComponentSym(self, symbol): 856657Snate@binkert.org # used to cheat-- that is, access components in other machines 866657Snate@binkert.org machine = self.find("current_machine", StateMachine) 876657Snate@binkert.org if machine: 886657Snate@binkert.org self.machine_components[str(machine)][str(symbol)] = symbol 896657Snate@binkert.org 906657Snate@binkert.org def newCurrentMachine(self, sym): 916657Snate@binkert.org self.registerGlobalSym(str(sym), sym) 926657Snate@binkert.org self.registerSym("current_machine", sym) 936657Snate@binkert.org self.sym_vec.append(sym) 946657Snate@binkert.org 956657Snate@binkert.org self.machine_components[str(sym)] = {} 966657Snate@binkert.org 976657Snate@binkert.org @property 986657Snate@binkert.org def state_machine(self): 996657Snate@binkert.org return self.find("current_machine", StateMachine) 1006657Snate@binkert.org 1016657Snate@binkert.org def pushFrame(self): 1026657Snate@binkert.org self.sym_map_vec.append({}) 1036657Snate@binkert.org 1046657Snate@binkert.org def popFrame(self): 1056657Snate@binkert.org assert len(self.sym_map_vec) > 0 1066657Snate@binkert.org self.sym_map_vec.pop() 1076657Snate@binkert.org 1086657Snate@binkert.org def registerGlobalSym(self, ident, symbol): 1096657Snate@binkert.org # Check for redeclaration (global frame only) 1106657Snate@binkert.org if ident in self.sym_map_vec[0]: 1116657Snate@binkert.org symbol.error("Symbol '%s' redeclared in global scope." % ident) 1126657Snate@binkert.org 1136657Snate@binkert.org self.sym_map_vec[0][ident] = symbol 1146657Snate@binkert.org 1156657Snate@binkert.org def getAllType(self, type): 1166657Snate@binkert.org for symbol in self.sym_vec: 1176657Snate@binkert.org if isinstance(symbol, type): 1186657Snate@binkert.org yield symbol 1196657Snate@binkert.org 1206657Snate@binkert.org def writeCodeFiles(self, path): 1216657Snate@binkert.org code = code_formatter() 1226657Snate@binkert.org code(''' 1236657Snate@binkert.org/** Auto generated C++ code started by $__file__:$__line__ */ 1246657Snate@binkert.org 1256657Snate@binkert.org#include "mem/ruby/slicc_interface/RubySlicc_includes.hh" 1266657Snate@binkert.org''') 1276657Snate@binkert.org for symbol in self.sym_vec: 1286657Snate@binkert.org if isinstance(symbol, Type) and not symbol.isPrimitive: 1296657Snate@binkert.org code('#include "mem/protocol/${{symbol.c_ident}}.hh"') 1306657Snate@binkert.org 1316657Snate@binkert.org code.write(path, "Types.hh") 1326657Snate@binkert.org 1336657Snate@binkert.org for symbol in self.sym_vec: 1346657Snate@binkert.org symbol.writeCodeFiles(path) 1356657Snate@binkert.org 1366657Snate@binkert.org self.writeControllerFactory(path) 1376657Snate@binkert.org 1386657Snate@binkert.org def writeControllerFactory(self, path): 1396657Snate@binkert.org code = code_formatter() 1406657Snate@binkert.org 1416657Snate@binkert.org code(''' 1426657Snate@binkert.org/** \\file ControllerFactory.hh 1436657Snate@binkert.org * Auto generatred C++ code started by $__file__:$__line__ 1446657Snate@binkert.org */ 1456657Snate@binkert.org 1466657Snate@binkert.org#ifndef CONTROLLERFACTORY_H 1476657Snate@binkert.org#define CONTROLLERFACTORY_H 1486657Snate@binkert.org 1496657Snate@binkert.org#include <string> 1506657Snate@binkert.orgclass Network; 1516657Snate@binkert.orgclass AbstractController; 1526657Snate@binkert.org 1536657Snate@binkert.orgclass ControllerFactory { 1546657Snate@binkert.org public: 1556657Snate@binkert.org static AbstractController *createController(const std::string &controller_type, const std::string &name); 1566657Snate@binkert.org}; 1576657Snate@binkert.org#endif // CONTROLLERFACTORY_H''') 1586657Snate@binkert.org code.write(path, "ControllerFactory.hh") 1596657Snate@binkert.org 1606657Snate@binkert.org code = code_formatter() 1616657Snate@binkert.org code(''' 1626657Snate@binkert.org/** \\file ControllerFactory.cc 1636657Snate@binkert.org * Auto generatred C++ code started by $__file__:$__line__ 1646657Snate@binkert.org */ 1656657Snate@binkert.org 1666657Snate@binkert.org#include "mem/protocol/ControllerFactory.hh" 1676657Snate@binkert.org#include "mem/ruby/slicc_interface/AbstractController.hh" 1686657Snate@binkert.org#include "mem/protocol/MachineType.hh" 1696657Snate@binkert.org''') 1706657Snate@binkert.org 1716657Snate@binkert.org controller_types = [] 1726657Snate@binkert.org for symbol in self.getAllType(StateMachine): 1736657Snate@binkert.org code('#include "mem/protocol/${{symbol.ident}}_Controller.hh"') 1746657Snate@binkert.org controller_types.append(symbol.ident) 1756657Snate@binkert.org 1766657Snate@binkert.org code(''' 1776657Snate@binkert.orgAbstractController *ControllerFactory::createController(const std::string &controller_type, const std::string &name) { 1786657Snate@binkert.org''') 1796657Snate@binkert.org 1806657Snate@binkert.org for ct in controller_types: 1816657Snate@binkert.org code(''' 1826657Snate@binkert.org if (controller_type == "$ct") 1836657Snate@binkert.org return new ${ct}_Controller(name); 1846657Snate@binkert.org''') 1856657Snate@binkert.org 1866657Snate@binkert.org code(''' 1876657Snate@binkert.org assert(0); // invalid controller type 1886657Snate@binkert.org return NULL; 1896657Snate@binkert.org} 1906657Snate@binkert.org''') 1916657Snate@binkert.org code.write(path, "ControllerFactory.cc") 1926657Snate@binkert.org 1936657Snate@binkert.org def writeHTMLFiles(self, path): 1946657Snate@binkert.org machines = list(self.getAllType(StateMachine)) 1956657Snate@binkert.org if len(machines) > 1: 1966657Snate@binkert.org name = "%s_table.html" % machines[0].ident 1976657Snate@binkert.org else: 1986657Snate@binkert.org name = "empty.html" 1996657Snate@binkert.org 2006657Snate@binkert.org code = code_formatter() 2016657Snate@binkert.org code(''' 2026657Snate@binkert.org<html> 2036657Snate@binkert.org<head> 2046657Snate@binkert.org<title>$path</title> 2056657Snate@binkert.org</head> 2066657Snate@binkert.org<frameset rows="*,30"> 2076657Snate@binkert.org <frame name="Table" src="$name"> 2086657Snate@binkert.org <frame name="Status" src="empty.html"> 2096657Snate@binkert.org</frameset> 2106657Snate@binkert.org</html> 2116657Snate@binkert.org''') 2126657Snate@binkert.org code.write(path, "index.html") 2136657Snate@binkert.org 2146657Snate@binkert.org code = code_formatter() 2156657Snate@binkert.org code("<HTML></HTML>") 2166657Snate@binkert.org code.write(path, "empty.html") 2176657Snate@binkert.org 2186657Snate@binkert.org for symbol in self.sym_vec: 2196657Snate@binkert.org symbol.writeHTMLFiles(path) 2206657Snate@binkert.org 2216657Snate@binkert.org__all__ = [ "SymbolTable" ] 222