• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&centerResult).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(&centerResult).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