1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "script_statement.h"
16 #include "script_context.h"
17 #include "script_expression.h"
18 #include "script_interpreter.h"
19 #include "script_utils.h"
20
21 using namespace std;
22
23 namespace uscript {
UpdateStatementResult(UScriptValuePtr value)24 void UScriptStatementResult::UpdateStatementResult(UScriptValuePtr value)
25 {
26 USCRIPT_CHECK(value != nullptr, SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR),
27 "Invalid value");
28 switch (value->GetValueType()) {
29 case UScriptValue::VALUE_TYPE_INTEGER:
30 /* fallthrough */
31 case UScriptValue::VALUE_TYPE_FLOAT:
32 /* fallthrough */
33 case UScriptValue::VALUE_TYPE_STRING:
34 SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_NORMAL);
35 SetResultValue(value);
36 break;
37 case UScriptValue::VALUE_TYPE_ERROR:
38 SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR);
39 SetError(USCRIPT_ERROR_INTERPRET);
40 if (value->GetValueType() == UScriptValue::VALUE_TYPE_ERROR) {
41 SetError(((ErrorValue*)value.get())->GetValue());
42 }
43 break;
44 case UScriptValue::VALUE_TYPE_LIST:
45 SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_NORMAL);
46 SetResultValue(value);
47 break;
48 case UScriptValue::VALUE_TYPE_RETURN:
49 SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_RTN);
50 SetResultValue(value);
51 break;
52 default:
53 SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR);
54 break;
55 }
56 return;
57 }
58
ScriptToString(UScriptStatementResult * result)59 std::string UScriptStatementResult::ScriptToString(UScriptStatementResult *result)
60 {
61 std::string str;
62 USCRIPT_CHECK(result != nullptr, return str, "null value");
63
64 str.append("type: " + to_string(result->GetResultType()));
65 if (result->GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR) {
66 str.append(" errorCode : " + std::to_string(result->GetError()));
67 } else {
68 str.append(" value : " + UScriptValue::ScriptToString(result->GetResultValue()));
69 }
70 return str;
71 }
72
CreateStatement(UScriptStatement::StatementType type)73 UScriptStatement* UScriptStatement::CreateStatement(UScriptStatement::StatementType type)
74 {
75 return new UScriptStatementCtrl(type);
76 }
77
78 // ExpressionStatement
CreateExpressionStatement(UScriptExpression * expression)79 UScriptStatement* UScriptStatement::CreateExpressionStatement(UScriptExpression *expression)
80 {
81 return new UScriptExpressionStatement(expression);
82 }
83
84 // IFStatement
CreateIfStatement(UScriptExpression * condition,UScriptStatementList * list1,UScriptStatementList * list2,UScriptStatement * nextIfState)85 UScriptStatement* UScriptStatement::CreateIfStatement(UScriptExpression *condition,
86 UScriptStatementList *list1,
87 UScriptStatementList *list2,
88 UScriptStatement *nextIfState)
89 {
90 auto ifStatement = new UScriptIfStatement(condition, list1);
91 USCRIPT_CHECK(ifStatement != nullptr, return nullptr, "Create if statement failed ");
92 ifStatement->AddFalseStatementList(list2);
93 ifStatement->AddNextStatement(reinterpret_cast<UScriptIfStatement*>(nextIfState));
94 return ifStatement;
95 }
96
97 // FORStatement
CreateForStatement(UScriptExpression * before,UScriptExpression * condition,UScriptExpression * after,UScriptStatementList * list)98 UScriptStatement* UScriptStatement::CreateForStatement(UScriptExpression *before,
99 UScriptExpression *condition,
100 UScriptExpression *after,
101 UScriptStatementList *list)
102 {
103 return new UScriptForStatement(before, condition, after, list);
104 }
105
CreateWhileStatement(UScriptExpression * condition,UScriptStatementList * list)106 UScriptStatement* UScriptStatement::CreateWhileStatement(UScriptExpression *condition,
107 UScriptStatementList *list)
108 {
109 return new UScriptWhileStatement(condition, list);
110 }
111
CreateInstance(UScriptStatement * statement)112 UScriptStatementList* UScriptStatementList::CreateInstance(UScriptStatement *statement)
113 {
114 auto list = new UScriptStatementList();
115 USCRIPT_CHECK(list != nullptr, return nullptr, "Failed to create statement list ");
116 list->AddScriptStatement(statement);
117 return list;
118 }
119
~UScriptStatementList()120 UScriptStatementList::~UScriptStatementList()
121 {
122 for (auto iter = statements_.begin(); iter != statements_.end();) {
123 delete *iter;
124 iter = statements_.erase(iter);
125 }
126 statements_.clear();
127 }
128
AddScriptStatement(UScriptStatement * statement)129 void UScriptStatementList::AddScriptStatement(UScriptStatement *statement)
130 {
131 statements_.push_back(statement);
132 }
133
Execute(ScriptInterpreter & interpreter,UScriptContextPtr context)134 UScriptStatementResult UScriptStatementCtrl::Execute(ScriptInterpreter &interpreter, UScriptContextPtr context)
135 {
136 UScriptStatementResult result;
137 switch (GetType()) {
138 case STATEMENT_TYPE_BREAK:
139 result.SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_BREAK);
140 break;
141 case STATEMENT_TYPE_RTN:
142 result.SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_RTN);
143 break;
144 case STATEMENT_TYPE_CONTINUE:
145 result.SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_CONTINUE);
146 break;
147 default:
148 result.SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR);
149 result.SetError(USCRIPT_INVALID_STATEMENT);
150 break;
151 }
152 INTERPRETER_LOGI(interpreter, context, "UScriptStatementList::statement result :%s",
153 UScriptStatementResult::ScriptToString(&result).c_str());
154 return result;
155 }
156
Execute(ScriptInterpreter & interpreter,UScriptContextPtr context)157 UScriptStatementResult UScriptExpressionStatement::Execute(ScriptInterpreter &interpreter,
158 UScriptContextPtr context)
159 {
160 UScriptStatementResult result(UScriptStatementResult::STATEMENT_RESULT_TYPE_NORMAL, nullptr);
161 INTERPRETER_LOGI(interpreter, context, "UScriptExpressionStatement::statement ");
162 UScriptValuePtr value = expression_->Execute(interpreter, context);
163 result.UpdateStatementResult(value);
164 INTERPRETER_LOGI(interpreter, context, "UScriptExpressionStatement::Execute result: %s",
165 UScriptStatementResult::ScriptToString(&result).c_str());
166 return result;
167 }
168
Execute(ScriptInterpreter & interpreter,UScriptContextPtr context)169 UScriptStatementResult UScriptForStatement::Execute(ScriptInterpreter &interpreter, UScriptContextPtr context)
170 {
171 INTERPRETER_LOGI(interpreter, context, "UScriptForStatement::statement ");
172 UScriptStatementResult result(UScriptStatementResult::STATEMENT_RESULT_TYPE_NORMAL, nullptr);
173 if (before_ != nullptr) {
174 INTERPRETER_LOGE(interpreter, context, "Execute before");
175 before_->Execute(interpreter, context);
176 }
177
178 while (1) {
179 if (condition_ != nullptr) {
180 UScriptValuePtr v = condition_->Execute(interpreter, context);
181 INTERPRETER_CHECK(interpreter, context, !(v == nullptr || v->GetValueType() ==
182 UScriptValue::VALUE_TYPE_ERROR),
183 result.SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR); return result,
184 "Execute for condition failed: %s", UScriptValue::ScriptToString(v).c_str());
185 if (!v->IsTrue()) {
186 break;
187 }
188 }
189 UScriptStatementResult centerResult = statements_->Execute(interpreter, context);
190 INTERPRETER_LOGI(interpreter, context, "Execute statements result %s ",
191 UScriptStatementResult::ScriptToString(¢erResult).c_str());
192 if (centerResult.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_BREAK) {
193 break;
194 }
195 if (centerResult.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_RTN ||
196 centerResult.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR) {
197 return centerResult;
198 }
199
200 if (after_ != nullptr) {
201 INTERPRETER_LOGI(interpreter, context, "Execute after");
202 after_->Execute(interpreter, context);
203 }
204 }
205 return result;
206 }
207
Execute(ScriptInterpreter & interpreter,UScriptContextPtr local)208 UScriptStatementResult UScriptWhileStatement::Execute(ScriptInterpreter &interpreter, UScriptContextPtr local)
209 {
210 INTERPRETER_LOGI(interpreter, local, "UScriptStatementResult::statement ");
211 UScriptStatementResult result(UScriptStatementResult::STATEMENT_RESULT_TYPE_NORMAL, nullptr);
212 while (1) {
213 if (condition_ != nullptr) {
214 UScriptValuePtr v = condition_->Execute(interpreter, local);
215 INTERPRETER_CHECK(interpreter, local, !(v == nullptr || v->GetValueType() ==
216 UScriptValue::VALUE_TYPE_ERROR),
217 result.SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR); return result,
218 "Execute while condition failed: %s", UScriptValue::ScriptToString(v).c_str());
219 if (!v->IsTrue()) {
220 break;
221 }
222 }
223 UScriptStatementResult centerResult = statements_->Execute(interpreter, local);
224 INTERPRETER_LOGI(interpreter, local, "Execute statements result %s ",
225 UScriptStatementResult::ScriptToString(¢erResult).c_str());
226 if (centerResult.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_BREAK) {
227 break;
228 }
229 if (centerResult.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_CONTINUE) {
230 continue;
231 }
232 if (centerResult.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_RTN ||
233 centerResult.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR) {
234 return centerResult;
235 }
236 }
237 return result;
238 }
239
Execute(ScriptInterpreter & interpreter,UScriptContextPtr context)240 UScriptStatementResult UScriptIfStatement::Execute(ScriptInterpreter &interpreter, UScriptContextPtr context)
241 {
242 UScriptStatementResult result(UScriptStatementResult::STATEMENT_RESULT_TYPE_NORMAL, nullptr);
243 UScriptValuePtr v = expression_->Execute(interpreter, context);
244 INTERPRETER_CHECK(interpreter, context,
245 !(v == nullptr || v->GetValueType() == UScriptValue::VALUE_TYPE_ERROR),
246 result.SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR); return result,
247 "Execute for condition failed: %s", UScriptValue::ScriptToString(v).c_str());
248
249 if (v->IsTrue()) {
250 if (trueStatements_ == nullptr) {
251 return result;
252 }
253 UScriptContextPtr local = std::make_shared<UScriptInterpretContext>();
254 return trueStatements_->Execute(interpreter, local);
255 } else if (falseStatements_ != nullptr) {
256 UScriptContextPtr local = std::make_shared<UScriptInterpretContext>();
257 return falseStatements_->Execute(interpreter, local);
258 } else if (nextStatement_ != nullptr) {
259 return nextStatement_->Execute(interpreter, context);
260 }
261 return result;
262 }
263
Execute(ScriptInterpreter & inter,UScriptContextPtr context)264 UScriptStatementResult UScriptStatementList::Execute(ScriptInterpreter &inter, UScriptContextPtr context)
265 {
266 INTERPRETER_LOGI(inter, context, "UScriptStatementList::Execute ");
267 inter.ContextPush(context);
268 UScriptStatementResult result(UScriptStatementResult::STATEMENT_RESULT_TYPE_NORMAL, nullptr);
269 for (auto statement : statements_) {
270 result = statement->Execute(inter, context);
271 if (result.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_BREAK) {
272 break;
273 } else if (result.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_CONTINUE) {
274 break;
275 } else if (result.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_RTN) {
276 break;
277 } else if (result.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR) {
278 break;
279 }
280 }
281 inter.ContextPop();
282 INTERPRETER_LOGI(inter, context, "UScriptStatementList finish %s",
283 UScriptStatementResult::ScriptToString(&result).c_str());
284 return result;
285 }
286
~UScriptExpressionStatement()287 UScriptExpressionStatement::~UScriptExpressionStatement()
288 {
289 delete expression_;
290 }
291
~UScriptIfStatement()292 UScriptIfStatement::~UScriptIfStatement()
293 {
294 delete expression_;
295 delete trueStatements_;
296 delete falseStatements_;
297 delete nextStatement_;
298 }
299
~UScriptForStatement()300 UScriptForStatement::~UScriptForStatement()
301 {
302 delete before_;
303 delete condition_;
304 delete after_;
305 delete statements_;
306 }
307
~UScriptWhileStatement()308 UScriptWhileStatement::~UScriptWhileStatement()
309 {
310 delete condition_;
311 delete statements_;
312 }
313
314
~UScriptReturnStatement()315 UScriptReturnStatement::~UScriptReturnStatement()
316 {
317 delete params_;
318 }
319
CreateStatement(ScriptParams * params)320 UScriptReturnStatement* UScriptReturnStatement::CreateStatement(ScriptParams *params)
321 {
322 auto statement = new UScriptReturnStatement();
323 if (params != nullptr) {
324 statement->AddParams(params);
325 }
326 return statement;
327 }
328
Execute(ScriptInterpreter & interpreter,UScriptContextPtr context)329 UScriptStatementResult UScriptReturnStatement::Execute(ScriptInterpreter &interpreter, UScriptContextPtr context)
330 {
331 UScriptStatementResult result(UScriptStatementResult::STATEMENT_RESULT_TYPE_RTN, nullptr);
332 USCRIPT_CHECK(params_ != nullptr, return result, "Invalid parm");
333
334 std::shared_ptr<ReturnValue> retValue = std::make_shared<ReturnValue>();
335 USCRIPT_CHECK(retValue != nullptr, return result, "Create ret value failed");
336 for (auto id : params_->GetParams()) {
337 UScriptValuePtr var = id->Execute(interpreter, context);
338 INTERPRETER_LOGI(interpreter, context, "params result: %s", UScriptValue::ScriptToString(var).c_str());
339 if (var->GetValueType() == UScriptValue::VALUE_TYPE_LIST) {
340 retValue->AddValues(((ReturnValue*)var.get())->GetValues());
341 } else {
342 retValue->AddValue(var);
343 }
344 }
345 result.SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_RTN);
346 result.SetResultValue(retValue);
347 return result;
348 }
349 } // namespace uscript
350