aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/formal/Why3Translator.cpp
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-11-23 07:26:04 +0800
committerchriseth <c@ethdev.com>2015-11-23 07:58:17 +0800
commit82a6ab486d6ee1fa565db1d0b02f2b34c855e796 (patch)
tree0b7f3c868e5d4d6ae074980cb76f633c5e4e038c /libsolidity/formal/Why3Translator.cpp
parent58110b27c14962b6a46bc3b09e8ea1a75a4087e7 (diff)
downloaddexon-solidity-82a6ab486d6ee1fa565db1d0b02f2b34c855e796.tar.gz
dexon-solidity-82a6ab486d6ee1fa565db1d0b02f2b34c855e796.tar.zst
dexon-solidity-82a6ab486d6ee1fa565db1d0b02f2b34c855e796.zip
Why3: Direct references to variables using `#`.
Diffstat (limited to 'libsolidity/formal/Why3Translator.cpp')
-rw-r--r--libsolidity/formal/Why3Translator.cpp69
1 files changed, 68 insertions, 1 deletions
diff --git a/libsolidity/formal/Why3Translator.cpp b/libsolidity/formal/Why3Translator.cpp
index 4c187a56..8a3b767b 100644
--- a/libsolidity/formal/Why3Translator.cpp
+++ b/libsolidity/formal/Why3Translator.cpp
@@ -198,6 +198,14 @@ bool Why3Translator::visit(FunctionDefinition const& _function)
return false;
}
+ m_localVariables.clear();
+ for (auto const& var: _function.parameters())
+ m_localVariables[var->name()] = var.get();
+ for (auto const& var: _function.returnParameters())
+ m_localVariables[var->name()] = var.get();
+ for (auto const& var: _function.localVariables())
+ m_localVariables[var->name()] = var;
+
add("let rec _" + _function.name());
add(" (state: state)");
for (auto const& param: _function.parameters())
@@ -268,6 +276,11 @@ bool Why3Translator::visit(FunctionDefinition const& _function)
return false;
}
+void Why3Translator::endVisit(FunctionDefinition const&)
+{
+ m_localVariables.clear();
+}
+
bool Why3Translator::visit(Block const& _node)
{
addSourceFromDocStrings(_node.annotation());
@@ -569,6 +582,28 @@ bool Why3Translator::isStateVariable(VariableDeclaration const* _var) const
return false;
}
+bool Why3Translator::isStateVariable(string const& _name) const
+{
+ solAssert(!!m_stateVariables, "");
+ for (auto const& var: *m_stateVariables)
+ if (var->name() == _name)
+ return true;
+ return false;
+}
+
+bool Why3Translator::isLocalVariable(VariableDeclaration const* _var) const
+{
+ for (auto const& var: m_localVariables)
+ if (var.second == _var)
+ return true;
+ return false;
+}
+
+bool Why3Translator::isLocalVariable(string const& _name) const
+{
+ return m_localVariables.count(_name);
+}
+
void Why3Translator::visitIndentedUnlessBlock(Statement const& _statement)
{
bool isBlock = !!dynamic_cast<Block const*>(&_statement);
@@ -587,5 +622,37 @@ void Why3Translator::addSourceFromDocStrings(DocumentedAnnotation const& _annota
{
auto why3Range = _annotation.docTags.equal_range("why3");
for (auto i = why3Range.first; i != why3Range.second; ++i)
- addLine(i->second.content);
+ addLine(transformVariableReferences(i->second.content));
}
+
+string Why3Translator::transformVariableReferences(string const& _annotation)
+{
+ string ret;
+ auto pos = _annotation.begin();
+ while (true)
+ {
+
+ auto hash = find(pos, _annotation.end(), '#');
+ ret.append(pos, hash);
+ if (hash == _annotation.end())
+ break;
+
+ auto hashEnd = find_if(hash + 1, _annotation.end(), [](char _c)
+ {
+ return _c != '_' && _c != '$' && !('a' <= _c && _c <= 'z') && !('A' <= _c && _c <= 'Z') && !('0' <= _c && _c <= '9');
+ });
+ string varName(hash + 1, hashEnd);
+ if (isLocalVariable(varName))
+ ret += "(to_int !_" + varName + ")";
+ else if (isStateVariable(varName))
+ ret += "(to_int !(state._" + varName + "))";
+ else if (varName == "result") //@todo actually use the name of the return parameters
+ ret += "(to_int result)";
+ else
+ ret.append(hash, hashEnd);
+
+ pos = hashEnd;
+ }
+ return ret;
+}
+