SymbolTable.py (6794:b431ec0ad43d) SymbolTable.py (6877:2a1a3d916ca8)
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
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" ]
136 def writeHTMLFiles(self, path):
137 machines = list(self.getAllType(StateMachine))
138 if len(machines) > 1:
139 name = "%s_table.html" % machines[0].ident
140 else:
141 name = "empty.html"
142
143 code = code_formatter()
144 code('''
145<html>
146<head>
147<title>$path</title>
148</head>
149<frameset rows="*,30">
150 <frame name="Table" src="$name">
151 <frame name="Status" src="empty.html">
152</frameset>
153</html>
154''')
155 code.write(path, "index.html")
156
157 code = code_formatter()
158 code("<HTML></HTML>")
159 code.write(path, "empty.html")
160
161 for symbol in self.sym_vec:
162 symbol.writeHTMLFiles(path)
163
164__all__ = [ "SymbolTable" ]