• 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_context.h"
16 #include <iostream>
17 #include <typeinfo>
18 #include <cmath>
19 #include "script_expression.h"
20 #include "script_interpreter.h"
21 #include "script_utils.h"
22 
23 using namespace std;
24 
25 namespace uscript {
26 static uint32_t g_contextId = 0;
27 
PushParam(int32_t value)28 int32_t UScriptInstructionContext::PushParam(int32_t value)
29 {
30     UScriptValuePtr valuePtr = std::make_shared<IntegerValue>(value);
31     USCRIPT_CHECK(valuePtr != nullptr, return USCRIPT_ERROR_CREATE_OBJ, "Failed to create value");
32     outParam_.push_back(valuePtr);
33     return USCRIPT_SUCCESS;
34 }
35 
PushParam(float value)36 int32_t UScriptInstructionContext::PushParam(float value)
37 {
38     UScriptValuePtr valuePtr = std::make_shared<FloatValue>(value);
39     USCRIPT_CHECK(valuePtr != nullptr, return USCRIPT_ERROR_CREATE_OBJ, "Failed to create value");
40     outParam_.push_back(valuePtr);
41     return USCRIPT_SUCCESS;
42 }
43 
PushParam(const std::string & value)44 int32_t UScriptInstructionContext::PushParam(const std::string& value)
45 {
46     UScriptValuePtr valuePtr = std::make_shared<StringValue>(value);
47     USCRIPT_CHECK(valuePtr != nullptr, return USCRIPT_ERROR_CREATE_OBJ, "Failed to create value");
48     outParam_.push_back(valuePtr);
49     return USCRIPT_SUCCESS;
50 }
51 
GetParamCount()52 int32_t UScriptInstructionContext::GetParamCount()
53 {
54     return innerParam_.size();
55 }
56 
GetParam(int32_t index,int & value)57 int32_t UScriptInstructionContext::GetParam(int32_t index, int &value)
58 {
59     return GetParam<int32_t, IntegerValue>(index, value);
60 }
61 
GetParam(int32_t index,float & value)62 int32_t UScriptInstructionContext::GetParam(int32_t index, float &value)
63 {
64     return GetParam<float, FloatValue>(index, value);
65 }
66 
GetParam(int32_t index,std::string & value)67 int32_t UScriptInstructionContext::GetParam(int32_t index, std::string &value)
68 {
69     return GetParam<std::string, StringValue>(index, value);
70 }
71 
72 template<class T, class TWapper>
GetParam(int32_t index,T & value)73 int32_t UScriptInstructionContext::GetParam(int32_t index, T &value)
74 {
75     USCRIPT_CHECK(static_cast<size_t>(index) < this->innerParam_.size(),
76         return UScriptContext::PARAM_TYPE_INVALID, "Invalid index %d", index);
77     TWapper* inter = (TWapper*)(innerParam_[index].get());
78     USCRIPT_CHECK(inter != nullptr, return USCRIPT_INVALID_PARAM, "Invalid index %d", index);
79     value = inter->GetValue();
80     return USCRIPT_SUCCESS;
81 }
82 
GetParamType(int32_t index)83 UScriptContext::ParamType UScriptInstructionContext::GetParamType(int32_t index)
84 {
85     USCRIPT_CHECK(static_cast<size_t>(index) < this->innerParam_.size(),
86         return UScriptContext::PARAM_TYPE_INVALID, "Invalid index %d", index);
87     UScriptValue::UScriptValueType type = innerParam_[index]->GetValueType();
88     return (UScriptContext::ParamType)type;
89 }
90 
AddInputParam(UScriptValuePtr value)91 int32_t UScriptInstructionContext::AddInputParam(UScriptValuePtr value)
92 {
93     innerParam_.push_back(value);
94     return USCRIPT_SUCCESS;
95 }
96 
FindVariable(const ScriptInterpreter & inter,std::string id)97 UScriptValuePtr UScriptInterpretContext::FindVariable(const ScriptInterpreter &inter, std::string id)
98 {
99     INTERPRETER_LOGI(inter, this, "FindVariable varName:%s ", id.c_str());
100     if (localVariables_.find(id) != localVariables_.end()) {
101         return localVariables_[id];
102     }
103     return nullptr;
104 }
105 
UScriptInterpretContext(bool top)106 UScriptInterpretContext::UScriptInterpretContext(bool top) : top_(top)
107 {
108     contextId_ = ++g_contextId;
109 }
110 
UpdateVariable(const ScriptInterpreter & inter,std::string id,UScriptValuePtr value)111 void UScriptInterpretContext::UpdateVariable(const ScriptInterpreter &inter, std::string id,
112     UScriptValuePtr value)
113 {
114     INTERPRETER_LOGI(inter, this, " Update varName:%s value: %s", id.c_str(),
115         UScriptValue::ScriptToString(value).c_str());
116     localVariables_[id] = value;
117 }
118 
UpdateVariables(const ScriptInterpreter & inter,UScriptValuePtr value,std::vector<std::string> ids,size_t & startIndex)119 void UScriptInterpretContext::UpdateVariables(const ScriptInterpreter &inter,
120     UScriptValuePtr value,
121     std::vector<std::string> ids,
122     size_t &startIndex)
123 {
124     if (value->GetValueType() != UScriptValue::VALUE_TYPE_LIST) {
125         USCRIPT_CHECK(startIndex < ids.size(), return, "Invalid startIndex %d", startIndex);
126         UpdateVariable(inter, ids[startIndex], value);
127         startIndex++;
128         return;
129     }
130 
131     ReturnValue* values = (ReturnValue*)(value.get());
132     for (auto out : values->GetValues()) {
133         USCRIPT_CHECK(startIndex < ids.size(), return, "Invalid startIndex %d", startIndex);
134         UpdateVariable(inter, ids[startIndex], out);
135         startIndex++;
136     }
137 }
138 
Computer(int32_t action,UScriptValuePtr rightValue)139 UScriptValuePtr UScriptValue::Computer(int32_t action, UScriptValuePtr rightValue)
140 {
141     return std::make_shared<ErrorValue>(USCRIPT_ERROR_INTERPRET);
142 }
143 
144 #define INTEGER_MATH_COMPUTER(op, rightValue)                                     \
145     do {                                                                          \
146         if (rightValue->GetValueType() == UScriptValue::VALUE_TYPE_INTEGER) {      \
147             IntegerValue* value = (IntegerValue*)(rightValue.get());  \
148             USCRIPT_CHECK(value != nullptr, return defReturn, "Failed to cast ");   \
149             return make_shared<IntegerValue>(GetValue() op value->GetValue());    \
150         } else if (rightValue->GetValueType() == UScriptValue::VALUE_TYPE_FLOAT) { \
151             FloatValue* value = (FloatValue*)(rightValue.get());      \
152             USCRIPT_CHECK(value != nullptr, return defReturn, "Failed to cast ");   \
153             return make_shared<FloatValue>(GetValue() op value->GetValue());      \
154         }                                                                         \
155     } while (0)
156 
157 #define INTEGER_LOGIC_COMPUTER(op, rightValue)                                    \
158     do {                                                                          \
159         if (rightValue->GetValueType() == UScriptValue::VALUE_TYPE_INTEGER) {      \
160             IntegerValue* value = (IntegerValue*)(rightValue.get());  \
161             USCRIPT_CHECK(value != nullptr, return defReturn, "Failed to cast ");   \
162             return make_shared<IntegerValue>(GetValue() op value->GetValue());    \
163         } else if (rightValue->GetValueType() == UScriptValue::VALUE_TYPE_FLOAT) { \
164             FloatValue* value = (FloatValue*)(rightValue.get());      \
165             USCRIPT_CHECK(value != nullptr, return defReturn, "Failed to cast ");   \
166             return make_shared<IntegerValue>(GetValue() op value->GetValue());    \
167         }                                                                         \
168     } while (0)
169 
170 #define INTEGER_MATH_COMPUTER_DIV(rightValue)                                       \
171     do {                                                                            \
172         if (rightValue->GetValueType() == UScriptValue::VALUE_TYPE_INTEGER) {       \
173             IntegerValue* value = (IntegerValue*)(rightValue.get());                \
174             USCRIPT_CHECK(value != nullptr, return defReturn, "Failed to cast ");     \
175             if (value->GetValue() == 0) {                                           \
176                 return defReturn;                                                   \
177             }                                                                       \
178             return make_shared<IntegerValue>(this->GetValue() / value->GetValue()); \
179         } else if (rightValue->GetValueType() == UScriptValue::VALUE_TYPE_FLOAT) {  \
180             FloatValue* value = (FloatValue*)(rightValue.get());                    \
181             USCRIPT_CHECK(value != nullptr, return defReturn, "Failed to cast ");     \
182             if (value->GetValue() == 0) {                                           \
183                 return defReturn;                                                   \
184             }                                                                       \
185             return make_shared<FloatValue>(this->GetValue() / value->GetValue());   \
186         }                                                                           \
187     } while (0)
188 
Computer(int32_t action,UScriptValuePtr value)189 UScriptValuePtr IntegerValue::Computer(int32_t action, UScriptValuePtr value)
190 {
191     UScriptValuePtr rightValue = UScriptValue::GetRightCompluteValue(value);
192     UScriptValuePtr defReturn = std::make_shared<ErrorValue>(USCRIPT_ERROR_INTERPRET);
193     USCRIPT_CHECK(rightValue != nullptr, return defReturn, "Check param error");
194     switch (action) {
195         case UScriptExpression::ADD_OPERATOR: {
196             INTEGER_MATH_COMPUTER(+, rightValue);
197             break;
198         }
199         case UScriptExpression::SUB_OPERATOR: {
200             INTEGER_MATH_COMPUTER(-, rightValue);
201             break;
202         }
203         case UScriptExpression::MUL_OPERATOR: {
204             INTEGER_MATH_COMPUTER(*, rightValue);
205             break;
206         }
207         case UScriptExpression::DIV_OPERATOR: {
208             INTEGER_MATH_COMPUTER_DIV(rightValue);
209             break;
210         }
211         case UScriptExpression::GT_OPERATOR:
212             INTEGER_LOGIC_COMPUTER(>, rightValue);
213             break;
214         case UScriptExpression::GE_OPERATOR:
215             INTEGER_LOGIC_COMPUTER(>=, rightValue);
216             break;
217         case UScriptExpression::LT_OPERATOR:
218             INTEGER_LOGIC_COMPUTER(<, rightValue);
219             break;
220         case UScriptExpression::LE_OPERATOR:
221             INTEGER_LOGIC_COMPUTER(<=, rightValue);
222             break;
223         case UScriptExpression::EQ_OPERATOR:
224             INTEGER_LOGIC_COMPUTER(==, rightValue);
225             break;
226         case UScriptExpression::NE_OPERATOR:
227             INTEGER_LOGIC_COMPUTER(!=, rightValue);
228             break;
229         case UScriptExpression::AND_OPERATOR:
230             INTEGER_LOGIC_COMPUTER(&&, rightValue);
231             break;
232         case UScriptExpression::OR_OPERATOR:
233             INTEGER_LOGIC_COMPUTER(||, rightValue);
234             break;
235         default:
236             break;
237     }
238     return defReturn;
239 }
240 
241 #define FLOAT_MATH_COMPUTER(op, rightValue)                                       \
242     do {                                                                          \
243         if (rightValue->GetValueType() == UScriptValue::VALUE_TYPE_INTEGER) {      \
244             IntegerValue* value = (IntegerValue*)(rightValue.get());  \
245             USCRIPT_CHECK(value != nullptr, return defReturn, "Failed to cast ");   \
246             return make_shared<FloatValue>(GetValue() op value->GetValue());      \
247         } else if (rightValue->GetValueType() == UScriptValue::VALUE_TYPE_FLOAT) { \
248             FloatValue* value = (FloatValue*)(rightValue.get());      \
249             USCRIPT_CHECK(value != nullptr, return defReturn, "Failed to cast ");   \
250             return make_shared<FloatValue>(GetValue() op value->GetValue());      \
251         }                                                                         \
252     } while (0)
253 
254 #define FLOAT_LOGIC_COMPUTER(op, rightValue)                                      \
255     do {                                                                          \
256         if (rightValue->GetValueType() == UScriptValue::VALUE_TYPE_INTEGER) {      \
257             IntegerValue* value = (IntegerValue*)(rightValue.get());  \
258             USCRIPT_CHECK(value != nullptr, return defReturn, "Failed to cast ");   \
259             return make_shared<FloatValue>(GetValue() op value->GetValue());      \
260         } else if (rightValue->GetValueType() == UScriptValue::VALUE_TYPE_FLOAT) { \
261             FloatValue* value = (FloatValue*)(rightValue.get());      \
262             USCRIPT_CHECK(value != nullptr, return defReturn, "Failed to cast ");   \
263             return make_shared<IntegerValue>(GetValue() op value->GetValue());    \
264         }                                                                         \
265     } while (0)
266 
267 #define FLOAT_MATH_COMPUTER_DIV(rightValue)                                       \
268     do {                                                                          \
269         if (rightValue->GetValueType() == UScriptValue::VALUE_TYPE_INTEGER) {     \
270             IntegerValue* value = (IntegerValue*)(rightValue.get());              \
271             USCRIPT_CHECK(value != nullptr, return defReturn, "Failed to cast ");   \
272             UPDATER_CHECK_ONLY_RETURN (value->GetValue() != 0, break);            \
273             return make_shared<FloatValue>(this->GetValue() / value->GetValue()); \
274         } else if (rightValue->GetValueType() == UScriptValue::VALUE_TYPE_FLOAT) { \
275             FloatValue* value = (FloatValue*)(rightValue.get());                  \
276             USCRIPT_CHECK(value != nullptr, return defReturn, "Failed to cast ");   \
277             UPDATER_CHECK_ONLY_RETURN (value->GetValue() != 0, break);            \
278             return make_shared<FloatValue>(this->GetValue() / value->GetValue());  \
279         }                                                                          \
280     } while (0)
281 
Computer(int32_t action,UScriptValuePtr value)282 UScriptValuePtr FloatValue::Computer(int32_t action, UScriptValuePtr value)
283 {
284     UScriptValuePtr rightValue = UScriptValue::GetRightCompluteValue(value);
285     UScriptValuePtr defReturn = std::make_shared<ErrorValue>(USCRIPT_ERROR_INTERPRET);
286     USCRIPT_CHECK(rightValue != nullptr, return defReturn, "Check param error");
287     switch (action) {
288         case UScriptExpression::ADD_OPERATOR: {
289             FLOAT_MATH_COMPUTER(+, rightValue);
290             break;
291         }
292         case UScriptExpression::SUB_OPERATOR: {
293             FLOAT_MATH_COMPUTER(-, rightValue);
294             break;
295         }
296         case UScriptExpression::MUL_OPERATOR: {
297             FLOAT_MATH_COMPUTER(*, rightValue);
298             break;
299         }
300         case UScriptExpression::DIV_OPERATOR: {
301             FLOAT_MATH_COMPUTER_DIV(rightValue);
302             break;
303         }
304         case UScriptExpression::GT_OPERATOR:
305             FLOAT_LOGIC_COMPUTER(>, rightValue);
306             break;
307         case UScriptExpression::GE_OPERATOR:
308             FLOAT_LOGIC_COMPUTER(>=, rightValue);
309             break;
310         case UScriptExpression::LT_OPERATOR:
311             FLOAT_LOGIC_COMPUTER(<, rightValue);
312             break;
313         case UScriptExpression::LE_OPERATOR:
314             FLOAT_LOGIC_COMPUTER(<=, rightValue);
315             break;
316         case UScriptExpression::EQ_OPERATOR:
317             return make_shared<IntegerValue>(ComputerEqual(rightValue));
318         case UScriptExpression::NE_OPERATOR:
319             return make_shared<IntegerValue>(!ComputerEqual(rightValue));
320         case UScriptExpression::AND_OPERATOR:
321             FLOAT_LOGIC_COMPUTER(&&, rightValue);
322             break;
323         case UScriptExpression::OR_OPERATOR:
324             FLOAT_LOGIC_COMPUTER(||, rightValue);
325             break;
326         default:
327             break;
328     }
329     return defReturn;
330 }
331 
ComputerEqual(UScriptValuePtr rightValue)332 bool FloatValue::ComputerEqual(UScriptValuePtr rightValue)
333 {
334     if (rightValue->GetValueType() == UScriptValue::VALUE_TYPE_INTEGER) {
335         IntegerValue* value = (IntegerValue*)(rightValue.get());
336         USCRIPT_CHECK(value != nullptr, return 0, "Failed to cast ");
337         float v2 = value->GetValue();
338         USCRIPT_LOGI("ComputerEqual %f   v2: %f", GetValue(), v2);
339         float diff = GetValue() - v2;
340         diff = abs(diff);
341         return diff < 0.0001f;
342     } else if (rightValue->GetValueType() == UScriptValue::VALUE_TYPE_FLOAT) {
343         FloatValue* value = (FloatValue*)(rightValue.get());
344         USCRIPT_CHECK(value != nullptr, return 0, "Failed to cast ");
345         float diff = GetValue() - value->GetValue();
346         diff = abs(diff);
347         USCRIPT_LOGI("ComputerEqual %f %f diff: %f", GetValue(), value->GetValue(), diff);
348         return diff < 0.0001f;
349     }
350     return 0;
351 }
352 
ComputerReturn(int32_t action,UScriptValuePtr rightValue,UScriptValuePtr defReturn) const353 UScriptValuePtr StringValue::ComputerReturn(int32_t action, UScriptValuePtr rightValue,
354     UScriptValuePtr defReturn) const
355 {
356     switch (action) {
357         case UScriptExpression::GT_OPERATOR: {
358             return make_shared<IntegerValue>(ComputerLogic(rightValue) > 0);
359         }
360         case UScriptExpression::GE_OPERATOR: {
361             return make_shared<IntegerValue>(ComputerLogic(rightValue) >= 0);
362         }
363         case UScriptExpression::LT_OPERATOR: {
364             return make_shared<IntegerValue>(ComputerLogic(rightValue) < 0);
365         }
366         case UScriptExpression::LE_OPERATOR: {
367             return make_shared<IntegerValue>(ComputerLogic(rightValue) <= 0);
368         }
369         case UScriptExpression::EQ_OPERATOR: {
370             return make_shared<IntegerValue>(ComputerLogic(rightValue) == 0);
371         }
372         case UScriptExpression::NE_OPERATOR: {
373             return make_shared<IntegerValue>(ComputerLogic(rightValue) != 0);
374         }
375         case UScriptExpression::AND_OPERATOR:
376             return defReturn;
377         case UScriptExpression::OR_OPERATOR:
378             return defReturn;
379         default:
380             break;
381     }
382     return std::make_shared<ErrorValue>(USCRIPT_ERROR_INTERPRET);
383 }
384 
Computer(int32_t action,UScriptValuePtr value)385 UScriptValuePtr StringValue::Computer(int32_t action, UScriptValuePtr value)
386 {
387     UScriptValuePtr rightValue = UScriptValue::GetRightCompluteValue(value);
388     UScriptValuePtr defReturn = std::make_shared<ErrorValue>(USCRIPT_ERROR_INTERPRET);
389     USCRIPT_CHECK(rightValue != nullptr, return defReturn, "Check param error");
390 
391     std::string str;
392     if (action == UScriptExpression::ADD_OPERATOR) {
393         if (rightValue->GetValueType() == UScriptValue::VALUE_TYPE_INTEGER) {
394             IntegerValue* value = (IntegerValue*)(rightValue.get());
395             USCRIPT_CHECK(value != nullptr, return defReturn, "Failed to cast ");
396             str.assign(this->GetValue());
397             return make_shared<StringValue>(str + to_string(value->GetValue()));
398         } else if (rightValue->GetValueType() == UScriptValue::VALUE_TYPE_FLOAT) {
399             FloatValue* value = (FloatValue*)(rightValue.get());
400             USCRIPT_CHECK(value != nullptr, return defReturn, "Failed to cast ");
401             str.assign(this->GetValue());
402             return make_shared<StringValue>(str + to_string(value->GetValue()));
403         } else {
404             StringValue* value = (StringValue*)(rightValue.get());
405             USCRIPT_CHECK(value != nullptr, return defReturn, "Failed to cast ");
406             str.assign(this->GetValue());
407             return make_shared<StringValue>(str + value->GetValue());
408         }
409     }
410     if (rightValue->GetValueType() != UScriptValue::VALUE_TYPE_STRING) {
411         return defReturn;
412     }
413 
414     return ComputerReturn(action, rightValue, defReturn);
415 }
416 
ComputerLogic(UScriptValuePtr rightValue) const417 int32_t StringValue::ComputerLogic(UScriptValuePtr rightValue) const
418 {
419     StringValue* value = (StringValue*)(rightValue.get());
420     USCRIPT_CHECK(value != nullptr, return -1, "Failed to cast ");
421     std::string str;
422     str.assign(this->GetValue());
423     return str.compare(value->GetValue());
424 }
425 
ToString()426 std::string UScriptValue::ToString()
427 {
428     return std::string("null");
429 }
430 
Computer(int32_t action,UScriptValuePtr value)431 UScriptValuePtr ReturnValue::Computer(int32_t action, UScriptValuePtr value)
432 {
433     UScriptValuePtr defReturn = std::make_shared<ErrorValue>(USCRIPT_ERROR_INTERPRET);
434     // 只支持一个返回值时参与数值计算
435     if (values_.size() == 0 || values_.size() > 1) {
436         return defReturn;
437     }
438     return values_[0]->Computer(action, value);
439 }
440 
AddValue(const UScriptValuePtr value)441 void ReturnValue::AddValue(const UScriptValuePtr value)
442 {
443     if (value != nullptr) {
444         values_.push_back(value);
445     }
446 }
447 
AddValues(const std::vector<UScriptValuePtr> values)448 void ReturnValue::AddValues(const std::vector<UScriptValuePtr> values)
449 {
450     for (auto out : values) {
451         values_.push_back(out);
452     }
453 }
454 
GetValues() const455 std::vector<UScriptValuePtr> ReturnValue::GetValues() const
456 {
457     return values_;
458 }
459 
ToString()460 std::string IntegerValue::ToString()
461 {
462     return to_string(value_);
463 }
464 
ToString()465 std::string FloatValue::ToString()
466 {
467     return to_string(value_);
468 }
469 
ToString()470 std::string StringValue::ToString()
471 {
472     return value_;
473 }
474 
ToString()475 std::string ErrorValue::ToString()
476 {
477     return to_string(retCode_);
478 }
479 
ToString()480 std::string ReturnValue::ToString()
481 {
482     std::string str;
483     for (size_t index = 0; index < values_.size(); index++) {
484         if (values_[index]->GetValueType() != VALUE_TYPE_RETURN) {
485             str += " [" + to_string(index) + "] = " + values_[index]->ToString();
486         } else {
487             str += "error type";
488         }
489     }
490     return str;
491 }
492 
ScriptToString(UScriptValuePtr value)493 std::string UScriptValue::ScriptToString(UScriptValuePtr value)
494 {
495     if (value == nullptr) {
496         std::string str("null");
497         return str;
498     }
499     static std::map<int8_t, std::string> typsMaps = {
500         {VALUE_TYPE_INTEGER, "type: Integer "},
501         {VALUE_TYPE_FLOAT, "type: Float "},
502         {VALUE_TYPE_STRING, "type: String "},
503         {VALUE_TYPE_ERROR, "type: Error "},
504         {VALUE_TYPE_LIST, "type: List "},
505         {VALUE_TYPE_RETURN, "type: Return "}
506     };
507     std::string str = typsMaps[value->GetValueType()];
508     return str + value->ToString();
509 }
510 
GetRightCompluteValue(UScriptValuePtr rightValue)511 UScriptValuePtr UScriptValue::GetRightCompluteValue(UScriptValuePtr rightValue)
512 {
513     if (rightValue->GetValueType() == VALUE_TYPE_LIST) {
514         ReturnValue* value = (ReturnValue*)(rightValue.get());
515         std::vector<UScriptValuePtr> retValues = value->GetValues();
516         if (retValues.size() == 0 || retValues.size() > 1) {
517             return nullptr;
518         }
519         return retValues[0];
520     }
521     return rightValue;
522 }
523 } // namespace uscript
524