/src/solidity/libyul/AsmJsonImporter.cpp
Line | Count | Source |
1 | | /* |
2 | | This file is part of solidity. |
3 | | |
4 | | solidity is free software: you can redistribute it and/or modify |
5 | | it under the terms of the GNU General Public License as published by |
6 | | the Free Software Foundation, either version 3 of the License, or |
7 | | (at your option) any later version. |
8 | | |
9 | | solidity is distributed in the hope that it will be useful, |
10 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | | GNU General Public License for more details. |
13 | | |
14 | | You should have received a copy of the GNU General Public License |
15 | | along with solidity. If not, see <http://www.gnu.org/licenses/>. |
16 | | */ |
17 | | // SPDX-License-Identifier: GPL-3.0 |
18 | | /** |
19 | | * @author julius <djudju@protonmail.com> |
20 | | * @date 2019 |
21 | | * Converts an inlineAssembly AST from JSON format to AsmData |
22 | | |
23 | | */ |
24 | | |
25 | | #include <libyul/AsmJsonImporter.h> |
26 | | |
27 | | #include <libyul/AST.h> |
28 | | #include <libyul/Dialect.h> |
29 | | #include <libyul/Exceptions.h> |
30 | | #include <libyul/Utilities.h> |
31 | | |
32 | | #include <liblangutil/Exceptions.h> |
33 | | #include <liblangutil/Scanner.h> |
34 | | |
35 | | #include <boost/algorithm/string/split.hpp> |
36 | | #include <boost/algorithm/string.hpp> |
37 | | |
38 | | #include <vector> |
39 | | |
40 | | using namespace solidity::langutil; |
41 | | |
42 | | namespace solidity::yul |
43 | | { |
44 | | |
45 | | using SourceLocation = langutil::SourceLocation; |
46 | | |
47 | | SourceLocation const AsmJsonImporter::createSourceLocation(Json const& _node) |
48 | 0 | { |
49 | 0 | yulAssert(member(_node, "src").is_string(), "'src' must be a string"); |
50 | |
|
51 | 0 | return solidity::langutil::parseSourceLocation(_node["src"].get<std::string>(), m_sourceNames); |
52 | 0 | } |
53 | | |
54 | | AST AsmJsonImporter::createAST(solidity::Json const& _node) |
55 | 0 | { |
56 | 0 | return {m_dialect, createBlock(_node)}; |
57 | 0 | } |
58 | | |
59 | | template <class T> |
60 | | T AsmJsonImporter::createAsmNode(Json const& _node) |
61 | 0 | { |
62 | 0 | T r; |
63 | 0 | SourceLocation nativeLocation = createSourceLocation(_node); |
64 | 0 | yulAssert(nativeLocation.hasText(), "Invalid source location in Asm AST"); |
65 | | // TODO: We should add originLocation to the AST. |
66 | | // While it's not included, we'll use nativeLocation for it because we only support importing |
67 | | // inline assembly as a part of a Solidity AST and there these locations are always the same. |
68 | 0 | r.debugData = DebugData::create(nativeLocation, nativeLocation); |
69 | 0 | return r; |
70 | 0 | } Unexecuted instantiation: solidity::yul::NameWithDebugData solidity::yul::AsmJsonImporter::createAsmNode<solidity::yul::NameWithDebugData>(nlohmann::json_abi_v3_12_0::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::json_abi_v3_12_0::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >, void> const&) Unexecuted instantiation: solidity::yul::Block solidity::yul::AsmJsonImporter::createAsmNode<solidity::yul::Block>(nlohmann::json_abi_v3_12_0::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::json_abi_v3_12_0::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >, void> const&) Unexecuted instantiation: solidity::yul::Literal solidity::yul::AsmJsonImporter::createAsmNode<solidity::yul::Literal>(nlohmann::json_abi_v3_12_0::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::json_abi_v3_12_0::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >, void> const&) Unexecuted instantiation: solidity::yul::Leave solidity::yul::AsmJsonImporter::createAsmNode<solidity::yul::Leave>(nlohmann::json_abi_v3_12_0::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::json_abi_v3_12_0::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >, void> const&) Unexecuted instantiation: solidity::yul::Identifier solidity::yul::AsmJsonImporter::createAsmNode<solidity::yul::Identifier>(nlohmann::json_abi_v3_12_0::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::json_abi_v3_12_0::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >, void> const&) Unexecuted instantiation: solidity::yul::Assignment solidity::yul::AsmJsonImporter::createAsmNode<solidity::yul::Assignment>(nlohmann::json_abi_v3_12_0::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::json_abi_v3_12_0::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >, void> const&) Unexecuted instantiation: solidity::yul::FunctionCall solidity::yul::AsmJsonImporter::createAsmNode<solidity::yul::FunctionCall>(nlohmann::json_abi_v3_12_0::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::json_abi_v3_12_0::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >, void> const&) Unexecuted instantiation: solidity::yul::BuiltinName solidity::yul::AsmJsonImporter::createAsmNode<solidity::yul::BuiltinName>(nlohmann::json_abi_v3_12_0::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::json_abi_v3_12_0::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >, void> const&) Unexecuted instantiation: solidity::yul::ExpressionStatement solidity::yul::AsmJsonImporter::createAsmNode<solidity::yul::ExpressionStatement>(nlohmann::json_abi_v3_12_0::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::json_abi_v3_12_0::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >, void> const&) Unexecuted instantiation: solidity::yul::VariableDeclaration solidity::yul::AsmJsonImporter::createAsmNode<solidity::yul::VariableDeclaration>(nlohmann::json_abi_v3_12_0::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::json_abi_v3_12_0::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >, void> const&) Unexecuted instantiation: solidity::yul::FunctionDefinition solidity::yul::AsmJsonImporter::createAsmNode<solidity::yul::FunctionDefinition>(nlohmann::json_abi_v3_12_0::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::json_abi_v3_12_0::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >, void> const&) Unexecuted instantiation: solidity::yul::If solidity::yul::AsmJsonImporter::createAsmNode<solidity::yul::If>(nlohmann::json_abi_v3_12_0::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::json_abi_v3_12_0::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >, void> const&) Unexecuted instantiation: solidity::yul::Case solidity::yul::AsmJsonImporter::createAsmNode<solidity::yul::Case>(nlohmann::json_abi_v3_12_0::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::json_abi_v3_12_0::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >, void> const&) Unexecuted instantiation: solidity::yul::Switch solidity::yul::AsmJsonImporter::createAsmNode<solidity::yul::Switch>(nlohmann::json_abi_v3_12_0::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::json_abi_v3_12_0::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >, void> const&) Unexecuted instantiation: solidity::yul::ForLoop solidity::yul::AsmJsonImporter::createAsmNode<solidity::yul::ForLoop>(nlohmann::json_abi_v3_12_0::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::json_abi_v3_12_0::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >, void> const&) Unexecuted instantiation: solidity::yul::Break solidity::yul::AsmJsonImporter::createAsmNode<solidity::yul::Break>(nlohmann::json_abi_v3_12_0::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::json_abi_v3_12_0::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >, void> const&) Unexecuted instantiation: solidity::yul::Continue solidity::yul::AsmJsonImporter::createAsmNode<solidity::yul::Continue>(nlohmann::json_abi_v3_12_0::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::json_abi_v3_12_0::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >, void> const&) |
71 | | |
72 | | Json AsmJsonImporter::member(Json const& _node, std::string const& _name) |
73 | 0 | { |
74 | 0 | if (!_node.contains(_name)) |
75 | 0 | return Json(); |
76 | 0 | return _node[_name]; |
77 | 0 | } |
78 | | |
79 | | NameWithDebugData AsmJsonImporter::createNameWithDebugData(Json const& _node) |
80 | 0 | { |
81 | 0 | auto nameWithDebugData = createAsmNode<NameWithDebugData>(_node); |
82 | 0 | nameWithDebugData.name = YulName{member(_node, "name").get<std::string>()}; |
83 | 0 | return nameWithDebugData; |
84 | 0 | } |
85 | | |
86 | | Statement AsmJsonImporter::createStatement(Json const& _node) |
87 | 0 | { |
88 | 0 | Json jsonNodeType = member(_node, "nodeType"); |
89 | 0 | yulAssert(jsonNodeType.is_string(), "Expected \"nodeType\" to be of type string!"); |
90 | 0 | std::string nodeType = jsonNodeType.get<std::string>(); |
91 | |
|
92 | 0 | yulAssert(nodeType.substr(0, 3) == "Yul", "Invalid nodeType prefix"); |
93 | 0 | nodeType = nodeType.substr(3); |
94 | |
|
95 | 0 | if (nodeType == "ExpressionStatement") |
96 | 0 | return createExpressionStatement(_node); |
97 | 0 | else if (nodeType == "Assignment") |
98 | 0 | return createAssignment(_node); |
99 | 0 | else if (nodeType == "VariableDeclaration") |
100 | 0 | return createVariableDeclaration(_node); |
101 | 0 | else if (nodeType == "FunctionDefinition") |
102 | 0 | return createFunctionDefinition(_node); |
103 | 0 | else if (nodeType == "If") |
104 | 0 | return createIf(_node); |
105 | 0 | else if (nodeType == "Switch") |
106 | 0 | return createSwitch(_node); |
107 | 0 | else if (nodeType == "ForLoop") |
108 | 0 | return createForLoop(_node); |
109 | 0 | else if (nodeType == "Break") |
110 | 0 | return createBreak(_node); |
111 | 0 | else if (nodeType == "Continue") |
112 | 0 | return createContinue(_node); |
113 | 0 | else if (nodeType == "Leave") |
114 | 0 | return createLeave(_node); |
115 | 0 | else if (nodeType == "Block") |
116 | 0 | return createBlock(_node); |
117 | 0 | else |
118 | 0 | yulAssert(false, "Invalid nodeType as statement"); |
119 | | |
120 | | // FIXME: Workaround for spurious GCC 12.1 warning (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105794) |
121 | 0 | util::unreachable(); |
122 | 0 | } |
123 | | |
124 | | Expression AsmJsonImporter::createExpression(Json const& _node) |
125 | 0 | { |
126 | 0 | Json jsonNodeType = member(_node, "nodeType"); |
127 | 0 | yulAssert(jsonNodeType.is_string(), "Expected \"nodeType\" to be of type string!"); |
128 | 0 | std::string nodeType = jsonNodeType.get<std::string>(); |
129 | |
|
130 | 0 | yulAssert(nodeType.substr(0, 3) == "Yul", "Invalid nodeType prefix"); |
131 | 0 | nodeType = nodeType.substr(3); |
132 | |
|
133 | 0 | if (nodeType == "FunctionCall") |
134 | 0 | return createFunctionCall(_node); |
135 | 0 | else if (nodeType == "Identifier") |
136 | 0 | return createIdentifier(_node); |
137 | 0 | else if (nodeType == "Literal") |
138 | 0 | return createLiteral(_node); |
139 | 0 | else |
140 | 0 | yulAssert(false, "Invalid nodeType as expression"); |
141 | | |
142 | | // FIXME: Workaround for spurious GCC 12.1 warning (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105794) |
143 | 0 | util::unreachable(); |
144 | 0 | } |
145 | | |
146 | | std::vector<Expression> AsmJsonImporter::createExpressionVector(Json const& _array) |
147 | 0 | { |
148 | 0 | std::vector<Expression> ret; |
149 | 0 | for (auto& var: _array) |
150 | 0 | ret.emplace_back(createExpression(var)); |
151 | 0 | return ret; |
152 | 0 | } |
153 | | |
154 | | std::vector<Statement> AsmJsonImporter::createStatementVector(Json const& _array) |
155 | 0 | { |
156 | 0 | std::vector<Statement> ret; |
157 | 0 | for (auto& var: _array) |
158 | 0 | ret.emplace_back(createStatement(var)); |
159 | 0 | return ret; |
160 | 0 | } |
161 | | |
162 | | Block AsmJsonImporter::createBlock(Json const& _node) |
163 | 0 | { |
164 | 0 | auto block = createAsmNode<Block>(_node); |
165 | 0 | block.statements = createStatementVector(_node["statements"]); |
166 | 0 | return block; |
167 | 0 | } |
168 | | |
169 | | Literal AsmJsonImporter::createLiteral(Json const& _node) |
170 | 0 | { |
171 | 0 | auto lit = createAsmNode<Literal>(_node); |
172 | 0 | std::string kind = member(_node, "kind").get<std::string>(); |
173 | |
|
174 | 0 | solAssert(member(_node, "hexValue").is_string() || member(_node, "value").is_string(), ""); |
175 | 0 | std::string value; |
176 | 0 | if (_node.contains("hexValue")) |
177 | 0 | value = util::asString(util::fromHex(member(_node, "hexValue").get<std::string>())); |
178 | 0 | else |
179 | 0 | value = member(_node, "value").get<std::string>(); |
180 | 0 | { |
181 | 0 | auto const typeNode = member(_node, "type"); |
182 | 0 | yulAssert( |
183 | 0 | typeNode.empty() || typeNode.get<std::string>().empty(), |
184 | 0 | fmt::format( |
185 | 0 | "Expected literal types to be either empty or absent in the JSON. Got \"{}\".", |
186 | 0 | typeNode.get<std::string>() |
187 | 0 | ) |
188 | 0 | ); |
189 | 0 | } |
190 | 0 | if (kind == "number") |
191 | 0 | { |
192 | 0 | langutil::CharStream charStream(value, ""); |
193 | 0 | langutil::Scanner scanner{charStream}; |
194 | 0 | lit.kind = LiteralKind::Number; |
195 | 0 | yulAssert( |
196 | 0 | scanner.currentToken() == Token::Number, |
197 | 0 | "Expected number but got " + langutil::TokenTraits::friendlyName(scanner.currentToken()) + std::string(" while scanning ") + value |
198 | 0 | ); |
199 | 0 | } |
200 | 0 | else if (kind == "bool") |
201 | 0 | { |
202 | 0 | langutil::CharStream charStream(value, ""); |
203 | 0 | langutil::Scanner scanner{charStream}; |
204 | 0 | lit.kind = LiteralKind::Boolean; |
205 | 0 | yulAssert( |
206 | 0 | scanner.currentToken() == Token::TrueLiteral || |
207 | 0 | scanner.currentToken() == Token::FalseLiteral, |
208 | 0 | "Expected true/false literal!" |
209 | 0 | ); |
210 | 0 | } |
211 | 0 | else if (kind == "string") |
212 | 0 | { |
213 | 0 | lit.kind = LiteralKind::String; |
214 | 0 | yulAssert( |
215 | 0 | value.size() <= 32, |
216 | 0 | "String literal too long (" + std::to_string(value.size()) + " > 32)" |
217 | 0 | ); |
218 | 0 | } |
219 | 0 | else |
220 | 0 | yulAssert(false, "unknown type of literal"); |
221 | | |
222 | | // import only for inline assembly, no unlimited string literals there |
223 | 0 | lit.value = valueOfLiteral(value, lit.kind, false /* _unlimitedLiteralArgument */); |
224 | |
|
225 | 0 | yulAssert(validLiteral(lit)); |
226 | 0 | return lit; |
227 | 0 | } |
228 | | |
229 | | Leave AsmJsonImporter::createLeave(Json const& _node) |
230 | 0 | { |
231 | 0 | return createAsmNode<Leave>(_node); |
232 | 0 | } |
233 | | |
234 | | Identifier AsmJsonImporter::createIdentifier(Json const& _node) |
235 | 0 | { |
236 | 0 | auto identifier = createAsmNode<Identifier>(_node); |
237 | 0 | identifier.name = YulName(member(_node, "name").get<std::string>()); |
238 | 0 | return identifier; |
239 | 0 | } |
240 | | |
241 | | Assignment AsmJsonImporter::createAssignment(Json const& _node) |
242 | 0 | { |
243 | 0 | auto assignment = createAsmNode<Assignment>(_node); |
244 | |
|
245 | 0 | if (_node.contains("variableNames")) |
246 | 0 | for (auto const& var: member(_node, "variableNames")) |
247 | 0 | assignment.variableNames.emplace_back(createIdentifier(var)); |
248 | |
|
249 | 0 | assignment.value = std::make_unique<Expression>(createExpression(member(_node, "value"))); |
250 | 0 | return assignment; |
251 | 0 | } |
252 | | |
253 | | FunctionCall AsmJsonImporter::createFunctionCall(Json const& _node) |
254 | 0 | { |
255 | 0 | auto functionCall = createAsmNode<FunctionCall>(_node); |
256 | |
|
257 | 0 | for (auto const& var: member(_node, "arguments")) |
258 | 0 | functionCall.arguments.emplace_back(createExpression(var)); |
259 | |
|
260 | 0 | auto const functionNameNode = member(_node, "functionName"); |
261 | 0 | auto const name = member(functionNameNode, "name").get<std::string>(); |
262 | 0 | if (std::optional<BuiltinHandle> builtinHandle = m_dialect.findBuiltin(name)) |
263 | 0 | { |
264 | 0 | auto builtin = createAsmNode<BuiltinName>(functionNameNode); |
265 | 0 | builtin.handle = *builtinHandle; |
266 | 0 | functionCall.functionName = builtin; |
267 | 0 | } |
268 | 0 | else |
269 | 0 | functionCall.functionName = createIdentifier(functionNameNode); |
270 | |
|
271 | 0 | return functionCall; |
272 | 0 | } |
273 | | |
274 | | ExpressionStatement AsmJsonImporter::createExpressionStatement(Json const& _node) |
275 | 0 | { |
276 | 0 | auto statement = createAsmNode<ExpressionStatement>(_node); |
277 | 0 | statement.expression = createExpression(member(_node, "expression")); |
278 | 0 | return statement; |
279 | 0 | } |
280 | | |
281 | | VariableDeclaration AsmJsonImporter::createVariableDeclaration(Json const& _node) |
282 | 0 | { |
283 | 0 | auto varDec = createAsmNode<VariableDeclaration>(_node); |
284 | 0 | for (auto const& var: member(_node, "variables")) |
285 | 0 | varDec.variables.emplace_back(createNameWithDebugData(var)); |
286 | |
|
287 | 0 | if (_node.contains("value")) |
288 | 0 | varDec.value = std::make_unique<Expression>(createExpression(member(_node, "value"))); |
289 | |
|
290 | 0 | return varDec; |
291 | 0 | } |
292 | | |
293 | | FunctionDefinition AsmJsonImporter::createFunctionDefinition(Json const& _node) |
294 | 0 | { |
295 | 0 | auto funcDef = createAsmNode<FunctionDefinition>(_node); |
296 | 0 | funcDef.name = YulName{member(_node, "name").get<std::string>()}; |
297 | |
|
298 | 0 | if (_node.contains("parameters")) |
299 | 0 | for (auto const& var: member(_node, "parameters")) |
300 | 0 | funcDef.parameters.emplace_back(createNameWithDebugData(var)); |
301 | |
|
302 | 0 | if (_node.contains("returnVariables")) |
303 | 0 | for (auto const& var: member(_node, "returnVariables")) |
304 | 0 | funcDef.returnVariables.emplace_back(createNameWithDebugData(var)); |
305 | |
|
306 | 0 | funcDef.body = createBlock(member(_node, "body")); |
307 | 0 | return funcDef; |
308 | 0 | } |
309 | | |
310 | | If AsmJsonImporter::createIf(Json const& _node) |
311 | 0 | { |
312 | 0 | auto ifStatement = createAsmNode<If>(_node); |
313 | 0 | ifStatement.condition = std::make_unique<Expression>(createExpression(member(_node, "condition"))); |
314 | 0 | ifStatement.body = createBlock(member(_node, "body")); |
315 | 0 | return ifStatement; |
316 | 0 | } |
317 | | |
318 | | Case AsmJsonImporter::createCase(Json const& _node) |
319 | 0 | { |
320 | 0 | auto caseStatement = createAsmNode<Case>(_node); |
321 | 0 | auto const& value = member(_node, "value"); |
322 | 0 | if (value.is_string()) |
323 | 0 | yulAssert(value.get<std::string>() == "default", "Expected default case"); |
324 | 0 | else |
325 | 0 | caseStatement.value = std::make_unique<Literal>(createLiteral(value)); |
326 | 0 | caseStatement.body = createBlock(member(_node, "body")); |
327 | 0 | return caseStatement; |
328 | 0 | } |
329 | | |
330 | | Switch AsmJsonImporter::createSwitch(Json const& _node) |
331 | 0 | { |
332 | 0 | auto switchStatement = createAsmNode<Switch>(_node); |
333 | 0 | switchStatement.expression = std::make_unique<Expression>(createExpression(member(_node, "expression"))); |
334 | 0 | for (auto const& var: member(_node, "cases")) |
335 | 0 | switchStatement.cases.emplace_back(createCase(var)); |
336 | 0 | return switchStatement; |
337 | 0 | } |
338 | | |
339 | | ForLoop AsmJsonImporter::createForLoop(Json const& _node) |
340 | 0 | { |
341 | 0 | auto forLoop = createAsmNode<ForLoop>(_node); |
342 | 0 | forLoop.pre = createBlock(member(_node, "pre")); |
343 | 0 | forLoop.condition = std::make_unique<Expression>(createExpression(member(_node, "condition"))); |
344 | 0 | forLoop.post = createBlock(member(_node, "post")); |
345 | 0 | forLoop.body = createBlock(member(_node, "body")); |
346 | 0 | return forLoop; |
347 | 0 | } |
348 | | |
349 | | Break AsmJsonImporter::createBreak(Json const& _node) |
350 | 0 | { |
351 | 0 | return createAsmNode<Break>(_node); |
352 | 0 | } |
353 | | |
354 | | Continue AsmJsonImporter::createContinue(Json const& _node) |
355 | 0 | { |
356 | 0 | return createAsmNode<Continue>(_node); |
357 | 0 | } |
358 | | |
359 | | } |