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