• 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     if (value == nullptr) {
27         USCRIPT_LOGE("Invalid value");
28         SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR);
29         SetError(USCRIPT_INVALID_PARAM);
30         return;
31     }
32     switch (value->GetValueType()) {
33         case UScriptValue::VALUE_TYPE_INTEGER:
34             /* fallthrough */
35         case UScriptValue::VALUE_TYPE_FLOAT:
36             /* fallthrough */
37         case UScriptValue::VALUE_TYPE_STRING:
38             SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_NORMAL);
39             SetResultValue(value);
40             break;
41         case UScriptValue::VALUE_TYPE_ERROR:
42             SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR);
43             SetError(USCRIPT_ERROR_INTERPRET);
44             if (value->GetValueType() == UScriptValue::VALUE_TYPE_ERROR) {
45                 SetError((static_cast<ErrorValue*>(value.get()))->GetValue());
46             }
47             break;
48         case UScriptValue::VALUE_TYPE_LIST:
49             SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_NORMAL);
50             SetResultValue(value);
51             break;
52         case UScriptValue::VALUE_TYPE_RETURN:
53             SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_RTN);
54             SetResultValue(value);
55             break;
56         default:
57             SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR);
58             SetError(USCRIPT_INVALID_SCRIPT);
59             break;
60     }
61     return;
62 }
63 
ScriptToString(UScriptStatementResult * result)64 std::string UScriptStatementResult::ScriptToString(UScriptStatementResult *result)
65 {
66     std::string str;
67     USCRIPT_CHECK(result != nullptr, return str, "null value");
68 
69     str.append("type: " + to_string(result->GetResultType()));
70     if (result->GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR) {
71         str.append("  errorCode : " + std::to_string(result->GetError()));
72     } else {
73         str.append("  value : " + UScriptValue::ScriptToString(result->GetResultValue()));
74     }
75     return str;
76 }
77 
CreateStatement(UScriptStatement::StatementType type)78 UScriptStatement* UScriptStatement::CreateStatement(UScriptStatement::StatementType type)
79 {
80     return new UScriptStatementCtrl(type);
81 }
82 
83 // ExpressionStatement
CreateExpressionStatement(UScriptExpression * expression)84 UScriptStatement* UScriptStatement::CreateExpressionStatement(UScriptExpression *expression)
85 {
86     return new UScriptExpressionStatement(expression);
87 }
88 
89 // IFStatement
CreateIfStatement(UScriptExpression * condition,UScriptStatementList * list1,UScriptStatementList * list2,UScriptStatement * nextIfState)90 UScriptStatement* UScriptStatement::CreateIfStatement(UScriptExpression *condition,
91     UScriptStatementList *list1,
92     UScriptStatementList *list2,
93     UScriptStatement *nextIfState)
94 {
95     auto ifStatement = new(std::nothrow) UScriptIfStatement(condition, list1);
96     USCRIPT_CHECK(ifStatement != nullptr, return nullptr, "Create if statement failed ");
97     ifStatement->AddFalseStatementList(list2);
98     ifStatement->AddNextStatement(reinterpret_cast<UScriptIfStatement*>(nextIfState));
99     return ifStatement;
100 }
101 
102 // FORStatement
CreateForStatement(UScriptExpression * before,UScriptExpression * condition,UScriptExpression * after,UScriptStatementList * list)103 UScriptStatement* UScriptStatement::CreateForStatement(UScriptExpression *before,
104     UScriptExpression *condition,
105     UScriptExpression *after,
106     UScriptStatementList *list)
107 {
108     return new UScriptForStatement(before, condition, after, list);
109 }
110 
CreateWhileStatement(UScriptExpression * condition,UScriptStatementList * list)111 UScriptStatement* UScriptStatement::CreateWhileStatement(UScriptExpression *condition,
112     UScriptStatementList *list)
113 {
114     return new UScriptWhileStatement(condition, list);
115 }
116 
CreateInstance(UScriptStatement * statement)117 UScriptStatementList* UScriptStatementList::CreateInstance(UScriptStatement *statement)
118 {
119     auto list = new(std::nothrow) UScriptStatementList();
120     USCRIPT_CHECK(list != nullptr, return nullptr, "Failed to create statement list ");
121     list->AddScriptStatement(statement);
122     return list;
123 }
124 
~UScriptStatementList()125 UScriptStatementList::~UScriptStatementList()
126 {
127     for (auto iter = statements_.begin(); iter != statements_.end();) {
128         delete *iter;
129         iter = statements_.erase(iter);
130     }
131     statements_.clear();
132 }
133 
AddScriptStatement(UScriptStatement * statement)134 void UScriptStatementList::AddScriptStatement(UScriptStatement *statement)
135 {
136     statements_.push_back(statement);
137 }
138 
Execute(ScriptInterpreter & interpreter,UScriptContextPtr context)139 UScriptStatementResult UScriptStatementCtrl::Execute(ScriptInterpreter &interpreter, UScriptContextPtr context)
140 {
141     UScriptStatementResult result;
142     switch (GetType()) {
143         case STATEMENT_TYPE_BREAK:
144             result.SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_BREAK);
145             break;
146         case STATEMENT_TYPE_RTN:
147             result.SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_RTN);
148             break;
149         case STATEMENT_TYPE_CONTINUE:
150             result.SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_CONTINUE);
151             break;
152         default:
153             result.SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR);
154             result.SetError(USCRIPT_INVALID_STATEMENT);
155             break;
156     }
157     INTERPRETER_LOGI(interpreter, context, "UScriptStatementList::statement result :%s",
158                      UScriptStatementResult::ScriptToString(&result).c_str());
159     return result;
160 }
161 
Execute(ScriptInterpreter & interpreter,UScriptContextPtr context)162 UScriptStatementResult UScriptExpressionStatement::Execute(ScriptInterpreter &interpreter,
163     UScriptContextPtr context)
164 {
165     UScriptStatementResult result(UScriptStatementResult::STATEMENT_RESULT_TYPE_NORMAL, nullptr);
166     INTERPRETER_LOGI(interpreter, context, "UScriptExpressionStatement::statement ");
167     UScriptValuePtr value = expression_->Execute(interpreter, context);
168     result.UpdateStatementResult(value);
169     INTERPRETER_LOGI(interpreter, context, "UScriptExpressionStatement::Execute result: %s",
170         UScriptStatementResult::ScriptToString(&result).c_str());
171     return result;
172 }
173 
Execute(ScriptInterpreter & interpreter,UScriptContextPtr context)174 UScriptStatementResult UScriptForStatement::Execute(ScriptInterpreter &interpreter, UScriptContextPtr context)
175 {
176     INTERPRETER_LOGI(interpreter, context, "UScriptForStatement::statement ");
177     UScriptStatementResult result(UScriptStatementResult::STATEMENT_RESULT_TYPE_NORMAL, nullptr);
178     if (before_ != nullptr) {
179         INTERPRETER_LOGE(interpreter, context, "Execute before");
180         before_->Execute(interpreter, context);
181     }
182 
183     while (1) {
184         if (condition_ != nullptr) {
185             UScriptValuePtr v = condition_->Execute(interpreter, context);
186             if (v == nullptr || v->GetValueType() == UScriptValue::VALUE_TYPE_ERROR) {
187                 INTERPRETER_LOGE(interpreter, context, "Execute for condition failed: %s",
188                     UScriptValue::ScriptToString(v).c_str());
189                 result.SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR);
190                 result.SetError(USCRIPT_INVALID_PARAM);
191                 return result;
192             }
193             if (!v->IsTrue()) {
194                 break;
195             }
196         }
197         UScriptStatementResult centerResult = statements_->Execute(interpreter, context);
198         INTERPRETER_LOGI(interpreter, context, "Execute statements result %s ",
199             UScriptStatementResult::ScriptToString(&centerResult).c_str());
200         if (centerResult.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_BREAK) {
201             break;
202         }
203         if (centerResult.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_RTN ||
204             centerResult.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR) {
205             return centerResult;
206         }
207 
208         if (after_ != nullptr) {
209             INTERPRETER_LOGI(interpreter, context, "Execute after");
210             after_->Execute(interpreter, context);
211         }
212     }
213     return result;
214 }
215 
Execute(ScriptInterpreter & interpreter,UScriptContextPtr context)216 UScriptStatementResult UScriptWhileStatement::Execute(ScriptInterpreter &interpreter, UScriptContextPtr context)
217 {
218     INTERPRETER_LOGI(interpreter, context, "UScriptStatementResult::statement ");
219     UScriptStatementResult result(UScriptStatementResult::STATEMENT_RESULT_TYPE_NORMAL, nullptr);
220     while (1) {
221         if (condition_ != nullptr) {
222             UScriptValuePtr v = condition_->Execute(interpreter, context);
223             if (v == nullptr || v->GetValueType() == UScriptValue::VALUE_TYPE_ERROR) {
224                 INTERPRETER_LOGE(interpreter, context, "Execute while condition failed: %s",
225                     UScriptValue::ScriptToString(v).c_str());
226                 result.SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR);
227                 result.SetError(USCRIPT_INVALID_PARAM);
228                 return result;
229             }
230             if (!v->IsTrue()) {
231                 break;
232             }
233         }
234         UScriptStatementResult centerResult = statements_->Execute(interpreter, context);
235         INTERPRETER_LOGI(interpreter, context, "Execute statements result %s ",
236             UScriptStatementResult::ScriptToString(&centerResult).c_str());
237         if (centerResult.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_BREAK) {
238             break;
239         }
240         if (centerResult.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_CONTINUE) {
241             continue;
242         }
243         if (centerResult.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_RTN ||
244             centerResult.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR) {
245             return centerResult;
246         }
247     }
248     return result;
249 }
250 
Execute(ScriptInterpreter & interpreter,UScriptContextPtr context)251 UScriptStatementResult UScriptIfStatement::Execute(ScriptInterpreter &interpreter, UScriptContextPtr context)
252 {
253     UScriptStatementResult result(UScriptStatementResult::STATEMENT_RESULT_TYPE_NORMAL, nullptr);
254     UScriptValuePtr v = expression_->Execute(interpreter, context);
255     if (v == nullptr || v->GetValueType() == UScriptValue::VALUE_TYPE_ERROR) {
256         INTERPRETER_LOGE(interpreter, context, "Execute for condition failed: %s",
257             UScriptValue::ScriptToString(v).c_str());
258         result.SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR);
259         result.SetError(USCRIPT_INVALID_PARAM);
260         return result;
261     }
262 
263     if (v->IsTrue()) {
264         if (trueStatements_ == nullptr) {
265             return result;
266         }
267         UScriptContextPtr local = std::make_shared<UScriptInterpretContext>();
268         return trueStatements_->Execute(interpreter, local);
269     } else if (falseStatements_ != nullptr) {
270         UScriptContextPtr local = std::make_shared<UScriptInterpretContext>();
271         return falseStatements_->Execute(interpreter, local);
272     } else if (nextStatement_ != nullptr) {
273         return nextStatement_->Execute(interpreter, context);
274     }
275     return result;
276 }
277 
Execute(ScriptInterpreter & inter,UScriptContextPtr context)278 UScriptStatementResult UScriptStatementList::Execute(ScriptInterpreter &inter, UScriptContextPtr context)
279 {
280     INTERPRETER_LOGI(inter, context, "UScriptStatementList::Execute ");
281     inter.ContextPush(context);
282     UScriptStatementResult result(UScriptStatementResult::STATEMENT_RESULT_TYPE_NORMAL, nullptr);
283     for (auto statement : statements_) {
284         result = statement->Execute(inter, context);
285         if (result.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_BREAK) {
286             break;
287         } else if (result.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_CONTINUE) {
288             break;
289         } else if (result.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_RTN) {
290             break;
291         } else if (result.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR) {
292             break;
293         }
294     }
295     inter.ContextPop();
296     INTERPRETER_LOGI(inter, context, "UScriptStatementList finish %s",
297         UScriptStatementResult::ScriptToString(&result).c_str());
298     return result;
299 }
300 
~UScriptExpressionStatement()301 UScriptExpressionStatement::~UScriptExpressionStatement()
302 {
303     delete expression_;
304 }
305 
~UScriptIfStatement()306 UScriptIfStatement::~UScriptIfStatement()
307 {
308     delete expression_;
309     delete trueStatements_;
310     delete falseStatements_;
311     delete nextStatement_;
312 }
313 
~UScriptForStatement()314 UScriptForStatement::~UScriptForStatement()
315 {
316     delete before_;
317     delete condition_;
318     delete after_;
319     delete statements_;
320 }
321 
~UScriptWhileStatement()322 UScriptWhileStatement::~UScriptWhileStatement()
323 {
324     delete condition_;
325     delete statements_;
326 }
327 
328 
~UScriptReturnStatement()329 UScriptReturnStatement::~UScriptReturnStatement()
330 {
331     delete params_;
332 }
333 
CreateStatement(ScriptParams * params)334 UScriptReturnStatement* UScriptReturnStatement::CreateStatement(ScriptParams *params)
335 {
336     auto statement = new(std::nothrow) UScriptReturnStatement();
337     USCRIPT_CHECK(statement != nullptr, return nullptr, "Create statement failed");
338     if (params != nullptr) {
339         statement->AddParams(params);
340     }
341     return statement;
342 }
343 
Execute(ScriptInterpreter & interpreter,UScriptContextPtr context)344 UScriptStatementResult UScriptReturnStatement::Execute(ScriptInterpreter &interpreter, UScriptContextPtr context)
345 {
346     UScriptStatementResult result(UScriptStatementResult::STATEMENT_RESULT_TYPE_RTN, nullptr);
347     USCRIPT_CHECK(params_ != nullptr, return result, "Invalid parm");
348 
349     std::shared_ptr<ReturnValue> retValue = std::make_shared<ReturnValue>();
350     USCRIPT_CHECK(retValue != nullptr, return result, "Create ret value failed");
351     for (auto id : params_->GetParams()) {
352         UScriptValuePtr var = id->Execute(interpreter, context);
353         INTERPRETER_LOGI(interpreter, context, "params result: %s", UScriptValue::ScriptToString(var).c_str());
354         if (var->GetValueType() == UScriptValue::VALUE_TYPE_LIST) {
355             retValue->AddValues((static_cast<ReturnValue*>(var.get()))->GetValues());
356         } else {
357             retValue->AddValue(var);
358         }
359     }
360     result.SetResultType(UScriptStatementResult::STATEMENT_RESULT_TYPE_RTN);
361     result.SetResultValue(retValue);
362     return result;
363 }
364 } // namespace Uscript
365