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