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