-
Notifications
You must be signed in to change notification settings - Fork 274
Support for outputting JSON version of the GOTO program #448
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
cee7c16
aa5de8e
832cc0c
22708a6
11a4231
c333716
a92d8f8
8644218
efca262
4f54e00
5550c08
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,10 +19,15 @@ Author: Daniel Kroening, [email protected] | |
Function: goto_programt::output_instruction | ||
|
||
Inputs: | ||
ns - the namespace to resolve the expressions in | ||
identifier - the identifier used to find a symbol to identify the | ||
source language | ||
out - the stream to write the goto string to | ||
it - an iterator pointing to the instruction to convert | ||
|
||
Outputs: | ||
Outputs: See below. | ||
|
||
Purpose: | ||
Purpose: See below. | ||
|
||
\*******************************************************************/ | ||
|
||
|
@@ -32,51 +37,81 @@ std::ostream& goto_programt::output_instruction( | |
std::ostream& out, | ||
instructionst::const_iterator it) const | ||
{ | ||
out << " // " << it->location_number << " "; | ||
return output_instruction(ns, identifier, out, *it); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this function just be removed? Isn't there a danger by passing in the iterator the iterator could actually be advanced which would be somewhat surprising to the callee. Passing the actual instruction ensures this won't happen. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that the iterator is passed by value, thus modifications to the iterator are not a risk. Yet the question as to whether we genuinely need both variants is a valid one. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You might want to come up with a brief work estimate on the number of changes that removing this function induces, but I'd encourage getting rid of it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are 25 instances of it, but it should be a case of replacing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks! |
||
} | ||
|
||
/*******************************************************************\ | ||
|
||
Function: goto_programt::output_instruction | ||
|
||
Inputs: | ||
ns - the namespace to resolve the expressions in | ||
identifier - the identifier used to find a symbol to identify the | ||
source language | ||
out - the stream to write the goto string to | ||
instruction - the instruction to convert | ||
|
||
if(!it->source_location.is_nil()) | ||
out << it->source_location.as_string(); | ||
Outputs: Appends to out a two line representation of the instruction | ||
|
||
Purpose: Writes to out a two line string representation of the specific | ||
instruction. It is of the format: | ||
// {location} file {source file} line {line in source file} | ||
{representation of the instruction} | ||
|
||
\*******************************************************************/ | ||
|
||
std::ostream &goto_programt::output_instruction( | ||
const namespacet &ns, | ||
const irep_idt &identifier, | ||
std::ostream &out, | ||
const goto_program_templatet::instructiont &instruction) const | ||
{ | ||
out << " // " << instruction.location_number << " "; | ||
|
||
if(!instruction.source_location.is_nil()) | ||
out << instruction.source_location.as_string(); | ||
else | ||
out << "no location"; | ||
|
||
out << "\n"; | ||
|
||
if(!it->labels.empty()) | ||
if(!instruction.labels.empty()) | ||
{ | ||
out << " // Labels:"; | ||
for(const auto &label : it->labels) | ||
for(const auto &label : instruction.labels) | ||
out << " " << label; | ||
|
||
out << '\n'; | ||
} | ||
|
||
if(it->is_target()) | ||
out << std::setw(6) << it->target_number << ": "; | ||
if(instruction.is_target()) | ||
out << std::setw(6) << instruction.target_number << ": "; | ||
else | ||
out << " "; | ||
|
||
switch(it->type) | ||
switch(instruction.type) | ||
{ | ||
case NO_INSTRUCTION_TYPE: | ||
out << "NO INSTRUCTION TYPE SET" << '\n'; | ||
break; | ||
|
||
case GOTO: | ||
if(!it->guard.is_true()) | ||
if(!instruction.guard.is_true()) | ||
{ | ||
out << "IF " | ||
<< from_expr(ns, identifier, it->guard) | ||
<< from_expr(ns, identifier, instruction.guard) | ||
<< " THEN "; | ||
} | ||
|
||
out << "GOTO "; | ||
|
||
for(instructiont::targetst::const_iterator | ||
gt_it=it->targets.begin(); | ||
gt_it!=it->targets.end(); | ||
gt_it=instruction.targets.begin(); | ||
gt_it!=instruction.targets.end(); | ||
gt_it++) | ||
{ | ||
if(gt_it!=it->targets.begin()) out << ", "; | ||
if(gt_it!=instruction.targets.begin()) | ||
out << ", "; | ||
out << (*gt_it)->target_number; | ||
} | ||
|
||
|
@@ -89,20 +124,20 @@ std::ostream& goto_programt::output_instruction( | |
case DEAD: | ||
case FUNCTION_CALL: | ||
case ASSIGN: | ||
out << from_expr(ns, identifier, it->code) << '\n'; | ||
out << from_expr(ns, identifier, instruction.code) << '\n'; | ||
break; | ||
|
||
case ASSUME: | ||
case ASSERT: | ||
if(it->is_assume()) | ||
if(instruction.is_assume()) | ||
out << "ASSUME "; | ||
else | ||
out << "ASSERT "; | ||
|
||
{ | ||
out << from_expr(ns, identifier, it->guard); | ||
out << from_expr(ns, identifier, instruction.guard); | ||
|
||
const irep_idt &comment=it->source_location.get_comment(); | ||
const irep_idt &comment=instruction.source_location.get_comment(); | ||
if(comment!="") out << " // " << comment; | ||
} | ||
|
||
|
@@ -126,34 +161,35 @@ std::ostream& goto_programt::output_instruction( | |
|
||
{ | ||
const irept::subt &exception_list= | ||
it->code.find(ID_exception_list).get_sub(); | ||
instruction.code.find(ID_exception_list).get_sub(); | ||
|
||
for(const auto &ex : exception_list) | ||
out << " " << ex.id(); | ||
} | ||
|
||
if(it->code.operands().size()==1) | ||
out << ": " << from_expr(ns, identifier, it->code.op0()); | ||
if(instruction.code.operands().size()==1) | ||
out << ": " << from_expr(ns, identifier, instruction.code.op0()); | ||
|
||
out << '\n'; | ||
break; | ||
|
||
case CATCH: | ||
if(!it->targets.empty()) | ||
if(!instruction.targets.empty()) | ||
{ | ||
out << "CATCH-PUSH "; | ||
|
||
unsigned i=0; | ||
const irept::subt &exception_list= | ||
it->code.find(ID_exception_list).get_sub(); | ||
assert(it->targets.size()==exception_list.size()); | ||
instruction.code.find(ID_exception_list).get_sub(); | ||
assert(instruction.targets.size()==exception_list.size()); | ||
for(instructiont::targetst::const_iterator | ||
gt_it=it->targets.begin(); | ||
gt_it!=it->targets.end(); | ||
gt_it=instruction.targets.begin(); | ||
gt_it!=instruction.targets.end(); | ||
gt_it++, | ||
i++) | ||
{ | ||
if(gt_it!=it->targets.begin()) out << ", "; | ||
if(gt_it!=instruction.targets.begin()) | ||
out << ", "; | ||
out << exception_list[i].id() << "->" | ||
<< (*gt_it)->target_number; | ||
} | ||
|
@@ -175,8 +211,8 @@ std::ostream& goto_programt::output_instruction( | |
case START_THREAD: | ||
out << "START THREAD "; | ||
|
||
if(it->targets.size()==1) | ||
out << it->targets.front()->target_number; | ||
if(instruction.targets.size()==1) | ||
out << instruction.targets.front()->target_number; | ||
|
||
out << '\n'; | ||
break; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,8 @@ Author: Daniel Kroening, [email protected] | |
#include <iosfwd> | ||
#include <set> | ||
#include <limits> | ||
#include <sstream> | ||
#include <string> | ||
|
||
#include <util/namespace.h> | ||
#include <util/symbol_table.h> | ||
|
@@ -240,6 +242,13 @@ class goto_program_templatet | |
|
||
return false; | ||
} | ||
|
||
std::string to_string() const | ||
{ | ||
std::ostringstream instruction_id_builder; | ||
instruction_id_builder << type; | ||
return instruction_id_builder.str(); | ||
} | ||
}; | ||
|
||
typedef std::list<class instructiont> instructionst; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the preferred way if we have an overloaded function? It seems like a bad idea to duplicate the documentation but this feels like a bit of a cop out!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At some point we may have proper doxygen (AFAIK @peterschrammel has a patch to transform all comments), where proper referencing can be used.