bool Why3Translator::visit(ContractDefinition const& _contract) { if (m_seenContract) error(_contract, "More than one contract not supported."); m_seenContract = true; m_currentContract.contract = &_contract; if (_contract.isLibrary()) error(_contract, "Libraries not supported."); addLine("module Contract_" + _contract.name()); indent(); addLine("use import int.Int"); addLine("use import ref.Ref"); addLine("use import map.Map"); addLine("use import array.Array"); addLine("use import int.ComputerDivision"); addLine("use import mach.int.Unsigned"); addLine("use import UInt256"); addLine("exception Revert"); addLine("exception Return"); if (_contract.stateVariables().empty()) addLine("type state = ()"); else { addLine("type state = {"); indent(); m_currentContract.stateVariables = _contract.stateVariables(); for (VariableDeclaration const* variable: m_currentContract.stateVariables) { string varType; try { varType = toFormalType(*variable->annotation().type); } catch (NoFormalType &err) { string const* typeNamePtr = boost::get_error_info<errinfo_noFormalTypeFrom>(err); string typeName = typeNamePtr ? " \"" + *typeNamePtr + "\"" : ""; fatalError(*variable, "Type" + typeName + " not supported for state variable."); } addLine("mutable _" + variable->name() + ": " + varType); } unindent(); addLine("}"); } addLine("type account = {"); indent(); addLine("mutable balance: uint256;"); addLine("storage: state"); unindent(); addLine("}"); addLine("val external_call (this: account): bool"); indent(); addLine("ensures { result = false -> this = (old this) }"); addLine("writes { this }"); addSourceFromDocStrings(m_currentContract.contract->annotation()); unindent(); if (!_contract.baseContracts().empty()) error(*_contract.baseContracts().front(), "Inheritance not supported."); if (!_contract.definedStructs().empty()) error(*_contract.definedStructs().front(), "User-defined types not supported."); if (!_contract.definedEnums().empty()) error(*_contract.definedEnums().front(), "User-defined types not supported."); if (!_contract.events().empty()) error(*_contract.events().front(), "Events not supported."); if (!_contract.functionModifiers().empty()) error(*_contract.functionModifiers().front(), "Modifiers not supported."); ASTNode::listAccept(_contract.definedFunctions(), *this); return false; }