Skip to content

Commit 1a1b633

Browse files
authored
Merge pull request #1418 from diffblue/ebmc_language_api
ebmc language interface implementation for SMV
2 parents 7eae75c + 18618b8 commit 1a1b633

File tree

5 files changed

+207
-24
lines changed

5 files changed

+207
-24
lines changed

src/ebmc/build_transition_system.cpp

Lines changed: 61 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Author: Daniel Kroening, [email protected]
1818
#include <langapi/language.h>
1919
#include <langapi/language_util.h>
2020
#include <langapi/mode.h>
21+
#include <smvlang/smv_ebmc_language.h>
2122
#include <trans-word-level/show_module_hierarchy.h>
2223
#include <trans-word-level/show_modules.h>
2324

@@ -335,39 +336,76 @@ int show_symbol_table(
335336
cmdline, message_handler, dummy_transition_system);
336337
}
337338

338-
std::optional<transition_systemt> ebmc_languagest::transition_system()
339+
static std::set<std::string> file_extensions(const cmdlinet::argst &args)
339340
{
340-
if(cmdline.isset("preprocess"))
341-
{
342-
preprocess(cmdline, message_handler);
343-
return {};
344-
}
341+
std::set<std::string> result;
345342

346-
if(cmdline.isset("show-parse"))
343+
for(auto &arg : args)
347344
{
348-
show_parse(cmdline, message_handler);
349-
return {};
345+
std::size_t ext_pos = arg.rfind('.');
346+
347+
if(ext_pos != std::string::npos)
348+
{
349+
auto ext = std::string(arg, ext_pos + 1, std::string::npos);
350+
result.insert(ext);
351+
}
350352
}
351353

352-
if(
353-
cmdline.isset("show-modules") || cmdline.isset("modules-xml") ||
354-
cmdline.isset("json-modules"))
354+
return result;
355+
}
356+
357+
std::optional<transition_systemt> ebmc_languagest::transition_system()
358+
{
359+
auto extensions = file_extensions(cmdline.args);
360+
auto ext_used = [&extensions](const char *ext)
361+
{ return extensions.find(ext) != extensions.end(); };
362+
363+
bool have_smv = ext_used("smv");
364+
bool have_verilog = ext_used("v") || ext_used("sv");
365+
366+
if(have_smv && have_verilog)
355367
{
356-
show_modules(cmdline, message_handler);
357-
return {};
368+
throw ebmc_errort{} << "no support for mixed-language models";
358369
}
359370

360-
if(cmdline.isset("show-module-hierarchy"))
371+
if(have_smv)
361372
{
362-
show_module_hierarchy(cmdline, message_handler);
363-
return {};
373+
return smv_ebmc_languaget{cmdline, message_handler}.transition_system();
364374
}
365-
366-
if(cmdline.isset("show-symbol-table"))
375+
else
367376
{
368-
show_symbol_table(cmdline, message_handler);
369-
return {};
377+
if(cmdline.isset("preprocess"))
378+
{
379+
preprocess(cmdline, message_handler);
380+
return {};
381+
}
382+
383+
if(cmdline.isset("show-parse"))
384+
{
385+
show_parse(cmdline, message_handler);
386+
return {};
387+
}
388+
389+
if(
390+
cmdline.isset("show-modules") || cmdline.isset("modules-xml") ||
391+
cmdline.isset("json-modules"))
392+
{
393+
show_modules(cmdline, message_handler);
394+
return {};
395+
}
396+
397+
if(cmdline.isset("show-module-hierarchy"))
398+
{
399+
show_module_hierarchy(cmdline, message_handler);
400+
return {};
401+
}
402+
403+
if(cmdline.isset("show-symbol-table"))
404+
{
405+
show_symbol_table(cmdline, message_handler);
406+
return {};
407+
}
408+
409+
return get_transition_system(cmdline, message_handler);
370410
}
371-
372-
return get_transition_system(cmdline, message_handler);
373411
}

src/smvlang/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
SRC = smv_expr.cpp \
1+
SRC = smv_ebmc_language.cpp \
2+
smv_expr.cpp \
23
smv_language.cpp \
34
smv_parser.cpp \
45
smv_typecheck.cpp \

src/smvlang/smv_ebmc_language.cpp

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*******************************************************************\
2+
3+
Module: SMV Language Interface
4+
5+
Author: Daniel Kroening, [email protected]
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// SMV Language Interface
11+
12+
#include "smv_ebmc_language.h"
13+
14+
#include <util/cmdline.h>
15+
#include <util/get_module.h>
16+
#include <util/unicode.h>
17+
18+
#include <ebmc/ebmc_error.h>
19+
#include <ebmc/transition_system.h>
20+
21+
#include "smv_parser.h"
22+
#include "smv_typecheck.h"
23+
24+
#include <fstream>
25+
#include <iostream>
26+
27+
std::string smv_file_name(const cmdlinet &cmdline)
28+
{
29+
if(cmdline.args.size() == 0)
30+
throw ebmc_errort{} << "no file name given";
31+
32+
if(cmdline.args.size() >= 2)
33+
throw ebmc_errort{}.with_exit_code(1) << "SMV only uses a single file";
34+
35+
return cmdline.args.front();
36+
}
37+
38+
smv_parse_treet smv_ebmc_languaget::parse()
39+
{
40+
smv_parsert smv_parser{message_handler};
41+
42+
auto file_name = smv_file_name(cmdline);
43+
44+
std::ifstream infile{widen_if_needed(file_name)};
45+
46+
if(!infile)
47+
throw ebmc_errort{}.with_exit_code(1) << "failed to open " << file_name;
48+
49+
smv_parser.set_file(file_name);
50+
smv_parser.in = &infile;
51+
52+
if(smv_parser.parse())
53+
throw ebmc_errort{}.with_exit_code(1);
54+
55+
return std::move(smv_parser.parse_tree);
56+
}
57+
58+
std::optional<transition_systemt> smv_ebmc_languaget::transition_system()
59+
{
60+
if(cmdline.isset("preprocess"))
61+
{
62+
throw ebmc_errort{}.with_exit_code(1) << "SMV does not use preprocessing";
63+
}
64+
65+
auto parse_tree = parse();
66+
67+
if(cmdline.isset("show-parse"))
68+
{
69+
parse_tree.show(std::cout);
70+
return {};
71+
}
72+
73+
if(
74+
cmdline.isset("show-modules") || cmdline.isset("modules-xml") ||
75+
cmdline.isset("json-modules"))
76+
{
77+
//show_modules(cmdline, message_handler);
78+
return {};
79+
}
80+
81+
if(cmdline.isset("show-module-hierarchy"))
82+
{
83+
//show_module_hierarchy(cmdline, message_handler);
84+
return {};
85+
}
86+
87+
transition_systemt result;
88+
89+
if(smv_typecheck(
90+
parse_tree, result.symbol_table, "smv::main", message_handler))
91+
{
92+
messaget message{message_handler};
93+
message.error() << "CONVERSION ERROR" << messaget::eom;
94+
throw ebmc_errort{}.with_exit_code(2);
95+
}
96+
97+
if(cmdline.isset("show-symbol-table"))
98+
{
99+
std::cout << result.symbol_table;
100+
return {};
101+
}
102+
103+
result.main_symbol =
104+
&get_module(result.symbol_table, "main", message_handler);
105+
106+
result.trans_expr = to_trans_expr(result.main_symbol->value);
107+
108+
return result;
109+
}

src/smvlang/smv_ebmc_language.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*******************************************************************\
2+
3+
Module: SMV Language Interface
4+
5+
Author: Daniel Kroening, [email protected]
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// SMV Language Interface
11+
12+
#ifndef EBMC_SMV_LANGUAGE_H
13+
#define EBMC_SMV_LANGUAGE_H
14+
15+
#include <ebmc/ebmc_language.h>
16+
17+
class smv_parse_treet;
18+
19+
class smv_ebmc_languaget : public ebmc_languaget
20+
{
21+
public:
22+
smv_ebmc_languaget(cmdlinet &_cmdline, message_handlert &_message_handler)
23+
: ebmc_languaget(_cmdline, _message_handler)
24+
{
25+
}
26+
27+
// produce the transition system, and return it
28+
std::optional<transition_systemt> transition_system() override;
29+
30+
protected:
31+
smv_parse_treet parse();
32+
};
33+
34+
#endif // EBMC_SMV_LANGUAGE_H

src/smvlang/smv_parse_tree.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class smv_parse_treet
2020
{
2121
public:
2222
smv_parse_treet() = default;
23+
smv_parse_treet(smv_parse_treet &&) = default;
2324

2425
// don't copy, contains pointers
2526
smv_parse_treet(const smv_parse_treet &) = delete;

0 commit comments

Comments
 (0)