Skip to content

Commit 2464c07

Browse files
committed
SMV: flatten hierarchy on parse tree
SMV module flattening is now implemented as an operation on SMV parse trees, as opposed to an operation on a symbol table post type checking.
1 parent d17641f commit 2464c07

File tree

3 files changed

+54
-123
lines changed

3 files changed

+54
-123
lines changed
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
KNOWNBUG
1+
CORE
22
parameters2.smv
33

44
^EXIT=10$
55
^SIGNAL=0$
66
--
77
^warning: ignoring
88
--
9-
This yields a type-checking error.

src/smvlang/smv_parse_tree.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class smv_parse_treet
2424
struct modulet
2525
{
2626
irep_idt name, base_name;
27-
std::list<irep_idt> parameters;
27+
std::vector<irep_idt> parameters;
2828

2929
struct elementt
3030
{

src/smvlang/smv_typecheck.cpp

Lines changed: 52 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class smv_typecheckt:public typecheckt
6060
} modet;
6161

6262
void convert(smv_parse_treet::modulet &);
63+
6364
void create_var_symbols(const smv_parse_treet::modulet::element_listt &);
6465

6566
void collect_define(const equal_exprt &);
@@ -104,7 +105,7 @@ class smv_typecheckt:public typecheckt
104105
smv_parse_treet::modulet &,
105106
const irep_idt &identifier,
106107
const irep_idt &instance,
107-
const exprt::operandst &operands,
108+
const exprt::operandst &arguments,
108109
const source_locationt &);
109110

110111
typet
@@ -196,8 +197,14 @@ Function: smv_typecheckt::flatten_hierarchy
196197

197198
void smv_typecheckt::flatten_hierarchy(smv_parse_treet::modulet &smv_module)
198199
{
199-
for(auto &element : smv_module.elements)
200+
// Not using ranged for since we will append to the list we are
201+
// iterating over! This avoids recursion.
202+
for(auto element_it = smv_module.elements.begin();
203+
element_it != smv_module.elements.end();
204+
++element_it)
200205
{
206+
auto &element = *element_it;
207+
201208
if(element.is_var() && element.expr.type().id() == ID_smv_submodule)
202209
{
203210
exprt &inst =
@@ -235,145 +242,65 @@ void smv_typecheckt::instantiate(
235242
smv_parse_treet::modulet &smv_module,
236243
const irep_idt &identifier,
237244
const irep_idt &instance,
238-
const exprt::operandst &operands,
245+
const exprt::operandst &arguments,
239246
const source_locationt &location)
240247
{
241-
symbol_table_baset::symbolst::const_iterator s_it =
242-
symbol_table.symbols.find(identifier);
248+
// Find the module
249+
auto module_it = smv_parse_tree.modules.find(identifier);
243250

244-
if(s_it==symbol_table.symbols.end())
251+
if(module_it == smv_parse_tree.modules.end())
245252
{
246253
throw errort().with_location(location)
247254
<< "submodule `" << identifier << "' not found";
248255
}
249256

250-
if(s_it->second.type.id()!=ID_module)
251-
{
252-
throw errort().with_location(location)
253-
<< "submodule `" << identifier << "' not a module";
254-
}
255-
256-
const irept::subt &ports=s_it->second.type.find(ID_ports).get_sub();
257+
const auto &instantiated_module = module_it->second;
258+
const auto &parameters = instantiated_module.parameters;
257259

258-
// do the arguments/ports
259-
260-
if(ports.size()!=operands.size())
260+
// map the arguments to parameters
261+
if(parameters.size() != arguments.size())
261262
{
262263
throw errort().with_location(location)
263264
<< "submodule `" << identifier << "' has wrong number of arguments";
264265
}
265266

266-
std::set<irep_idt> port_identifiers;
267-
rename_mapt rename_map;
267+
rename_mapt parameter_map;
268268

269-
for(std::size_t i = 0; i < ports.size(); i++)
269+
for(std::size_t i = 0; i < parameters.size(); i++)
270270
{
271-
const irep_idt &identifier=ports[i].get(ID_identifier);
272-
rename_map.insert(std::pair<irep_idt, exprt>(identifier, operands[i]));
273-
port_identifiers.insert(identifier);
271+
parameter_map.emplace(parameters[i], arguments[i]);
274272
}
275273

276-
// do the variables
277-
278-
std::string new_prefix=
279-
id2string(smv_module.name)+"::var::"+id2string(instance)+".";
274+
const std::string prefix = id2string(instance)+'.';
280275

281-
std::set<irep_idt> var_identifiers;
282-
283-
for(auto v_it=symbol_table.symbol_module_map.lower_bound(identifier);
284-
v_it!=symbol_table.symbol_module_map.upper_bound(identifier);
285-
v_it++)
276+
// copy the parse tree elements
277+
for(auto &src_element : instantiated_module.elements)
286278
{
287-
symbol_table_baset::symbolst::const_iterator s_it2 =
288-
symbol_table.symbols.find(v_it->second);
289-
290-
if(s_it2==symbol_table.symbols.end())
291-
{
292-
throw errort() << "symbol `" << v_it->second << "' not found";
293-
}
279+
auto copy = src_element;
294280

295-
if(port_identifiers.find(s_it2->first) != port_identifiers.end())
296-
{
297-
}
298-
else if(s_it2->second.type.id() == ID_module)
281+
// replace the parameter identifiers,
282+
// and add the prefix to non-parameter identifiers
283+
copy.expr.visit_post([&parameter_map, &prefix](exprt &expr)
299284
{
300-
}
301-
else
302-
{
303-
symbolt symbol(s_it2->second);
304-
305-
symbol.name=new_prefix+id2string(symbol.base_name);
306-
symbol.module=smv_module.name;
307-
308-
if(smv_module.name == "smv::main")
285+
if(expr.id() == ID_smv_identifier)
309286
{
310-
symbol.pretty_name =
311-
id2string(instance) + '.' + id2string(symbol.base_name);
312-
}
313-
else
314-
{
315-
symbol.pretty_name = strip_smv_prefix(symbol.name);
287+
auto identifier = to_smv_identifier_expr(expr).identifier();
288+
auto parameter_it = parameter_map.find(identifier);
289+
if(parameter_it != parameter_map.end())
290+
{
291+
expr = parameter_it->second;
292+
}
293+
else
294+
{
295+
// add the prefix
296+
to_smv_identifier_expr(expr).identifier(prefix + id2string(identifier));
297+
}
316298
}
299+
});
317300

318-
rename_map.insert(
319-
std::pair<irep_idt, exprt>(s_it2->first, symbol.symbol_expr()));
320-
321-
var_identifiers.insert(symbol.name);
322-
323-
symbol_table.add(symbol);
324-
}
325-
}
326-
327-
// fix values (macros)
328-
329-
for(const auto &v_id : var_identifiers)
330-
{
331-
auto s_it2 = symbol_table.get_writeable(v_id);
332-
333-
if(s_it2==nullptr)
334-
{
335-
throw errort() << "symbol `" << v_id << "' not found";
336-
}
337-
338-
symbolt &symbol=*s_it2;
339-
340-
if(!symbol.value.is_nil())
341-
{
342-
instantiate_rename(symbol.value, rename_map);
343-
typecheck(symbol.value, OTHER);
344-
convert_expr_to(symbol.value, symbol.type);
345-
}
346-
}
347-
348-
// get the transition system
349-
350-
const transt &trans=to_trans_expr(s_it->second.value);
351-
352-
std::string old_prefix=id2string(s_it->first)+"::var::";
353-
354-
// do the transition system
355-
356-
if(!trans.invar().is_true())
357-
{
358-
exprt tmp(trans.invar());
359-
instantiate_rename(tmp, rename_map);
360-
smv_module.add_invar(tmp);
301+
// add to main parse tree
302+
smv_module.elements.push_back(copy);
361303
}
362-
363-
if(!trans.init().is_true())
364-
{
365-
exprt tmp(trans.init());
366-
instantiate_rename(tmp, rename_map);
367-
smv_module.add_init(tmp);
368-
}
369-
370-
if(!trans.trans().is_true())
371-
{
372-
exprt tmp(trans.trans());
373-
instantiate_rename(tmp, rename_map);
374-
smv_module.add_trans(tmp);
375-
}
376-
377304
}
378305

379306
/*******************************************************************\
@@ -2497,10 +2424,10 @@ void smv_typecheckt::convert(smv_parse_treet::modulet &smv_module)
24972424

24982425
define_map.clear();
24992426

2500-
// check for re-use of variables/defines/parameter identifiers
2501-
variable_checks(smv_module);
2427+
// expand the module hierarchy
2428+
flatten_hierarchy(smv_module);
25022429

2503-
// variables/defines first, can be used before their declaration
2430+
// Now do variables/defines, which can be used before their declaration
25042431
create_var_symbols(smv_module.elements);
25052432

25062433
// transition relation
@@ -2524,8 +2451,6 @@ void smv_typecheckt::convert(smv_parse_treet::modulet &smv_module)
25242451
if(!element.is_var() && !element.is_ivar())
25252452
convert(element);
25262453

2527-
flatten_hierarchy(smv_module);
2528-
25292454
// we first need to collect all the defines
25302455

25312456
for(auto &element : smv_module.elements)
@@ -2631,6 +2556,13 @@ Function: smv_typecheckt::typecheck
26312556

26322557
void smv_typecheckt::typecheck()
26332558
{
2559+
if(module != "smv::main")
2560+
return;
2561+
2562+
// check all modules for duplicate identifiers
2563+
for(auto &module_it : smv_parse_tree.modules)
2564+
variable_checks(module_it.second);
2565+
26342566
smv_parse_treet::modulest::iterator it=smv_parse_tree.modules.find(module);
26352567

26362568
if(it==smv_parse_tree.modules.end())

0 commit comments

Comments
 (0)