forked from diffblue/cbmc
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathjsil_language.cpp
172 lines (137 loc) · 3.41 KB
/
jsil_language.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/*******************************************************************\
Module: Jsil Language
Author: Michael Tautschnig, [email protected]
\*******************************************************************/
/// \file
/// Jsil Language
#include "jsil_language.h"
#include <util/get_base_name.h>
#include <util/symbol_table.h>
#include "expr2jsil.h"
#include "jsil_convert.h"
#include "jsil_entry_point.h"
#include "jsil_internal_additions.h"
#include "jsil_parser.h"
#include "jsil_typecheck.h"
std::set<std::string> jsil_languaget::extensions() const
{
return { "jsil" };
}
void jsil_languaget::modules_provided(std::set<std::string> &modules)
{
modules.insert(get_base_name(parse_path, true));
}
/// Adding symbols for all procedure declarations
bool jsil_languaget::interfaces(
symbol_table_baset &symbol_table,
message_handlert &message_handler)
{
if(jsil_convert(parse_tree, symbol_table, message_handler))
return true;
jsil_internal_additions(symbol_table);
return false;
}
bool jsil_languaget::preprocess(
std::istream &,
const std::string &,
std::ostream &,
message_handlert &)
{
// there is no preprocessing!
return true;
}
bool jsil_languaget::parse(
std::istream &instream,
const std::string &path,
message_handlert &message_handler)
{
// store the path
parse_path=path;
// parsing
jsil_parsert jsil_parser{message_handler};
jsil_parser.clear();
jsil_parser.set_file(path);
jsil_parser.in=&instream;
bool result=jsil_parser.parse();
// save result
parse_tree.swap(jsil_parser.parse_tree);
// save some memory
jsil_parser.clear();
return result;
}
/// Converting from parse tree and type checking.
bool jsil_languaget::typecheck(
symbol_table_baset &symbol_table,
const std::string &,
message_handlert &message_handler)
{
if(jsil_typecheck(symbol_table, message_handler))
return true;
return false;
}
bool jsil_languaget::generate_support_functions(
symbol_table_baset &symbol_table,
message_handlert &message_handler)
{
return jsil_entry_point(symbol_table, message_handler);
}
void jsil_languaget::show_parse(std::ostream &out, message_handlert &)
{
parse_tree.output(out);
}
std::unique_ptr<languaget> new_jsil_language()
{
return std::make_unique<jsil_languaget>();
}
bool jsil_languaget::from_expr(
const exprt &expr,
std::string &code,
const namespacet &ns)
{
code=expr2jsil(expr, ns);
return false;
}
bool jsil_languaget::from_type(
const typet &type,
std::string &code,
const namespacet &ns)
{
code=type2jsil(type, ns);
return false;
}
bool jsil_languaget::to_expr(
const std::string &code,
const std::string &,
exprt &expr,
const namespacet &ns,
message_handlert &message_handler)
{
expr.make_nil();
std::istringstream instream(code);
// parsing
jsil_parsert jsil_parser{message_handler};
jsil_parser.clear();
jsil_parser.set_file(irep_idt());
jsil_parser.in=&instream;
bool result=jsil_parser.parse();
if(jsil_parser.parse_tree.items.size()!=1)
result=true;
else
{
symbol_tablet symbol_table;
result = jsil_convert(parse_tree, symbol_table, message_handler);
if(symbol_table.symbols.size()!=1)
result=true;
if(!result)
expr=symbol_table.symbols.begin()->second.value;
// typecheck it
if(!result)
result = jsil_typecheck(expr, message_handler, ns);
}
// save some memory
jsil_parser.clear();
return result;
}
jsil_languaget::~jsil_languaget()
{
}