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_expression.h"
16fb299fa2Sopenharmony_ci#include "script_function.h"
17fb299fa2Sopenharmony_ci#include "script_interpreter.h"
18fb299fa2Sopenharmony_ci#include "script_utils.h"
19fb299fa2Sopenharmony_ci
20fb299fa2Sopenharmony_ciusing namespace std;
21fb299fa2Sopenharmony_ci
22fb299fa2Sopenharmony_cinamespace Uscript {
23fb299fa2Sopenharmony_ciUScriptExpression::UScriptExpression(ExpressionType expressType) : expressType_(expressType) {}
24fb299fa2Sopenharmony_ciUScriptExpression::~UScriptExpression() {}
25fb299fa2Sopenharmony_ci
26fb299fa2Sopenharmony_ciUScriptExpression* AssignExpression::CreateExpression(const std::string identifier, UScriptExpression *expression)
27fb299fa2Sopenharmony_ci{
28fb299fa2Sopenharmony_ci    return new AssignExpression(identifier, expression);
29fb299fa2Sopenharmony_ci}
30fb299fa2Sopenharmony_civoid AssignExpression::AddIdentifier(const std::string &identifier)
31fb299fa2Sopenharmony_ci{
32fb299fa2Sopenharmony_ci    multipleIdentifiers_.push_back(identifier);
33fb299fa2Sopenharmony_ci}
34fb299fa2Sopenharmony_ci
35fb299fa2Sopenharmony_ciUScriptExpression* AssignExpression::AddIdentifier(UScriptExpression *expression, const std::string identifier)
36fb299fa2Sopenharmony_ci{
37fb299fa2Sopenharmony_ci    auto assign = reinterpret_cast<AssignExpression*>(expression);
38fb299fa2Sopenharmony_ci    if (assign != nullptr) {
39fb299fa2Sopenharmony_ci        assign->AddIdentifier(identifier);
40fb299fa2Sopenharmony_ci    }
41fb299fa2Sopenharmony_ci    return assign;
42fb299fa2Sopenharmony_ci}
43fb299fa2Sopenharmony_ci
44fb299fa2Sopenharmony_ci// binary operator
45fb299fa2Sopenharmony_ciUScriptExpression* BinaryExpression::CreateExpression(ExpressionAction action,
46fb299fa2Sopenharmony_ci    UScriptExpression *left,
47fb299fa2Sopenharmony_ci    UScriptExpression *right)
48fb299fa2Sopenharmony_ci{
49fb299fa2Sopenharmony_ci    return new BinaryExpression(action, left, right);
50fb299fa2Sopenharmony_ci}
51fb299fa2Sopenharmony_ciUScriptExpression* FunctionCallExpression::CreateExpression(const std::string identifier, ScriptParams *params)
52fb299fa2Sopenharmony_ci{
53fb299fa2Sopenharmony_ci    return new FunctionCallExpression(identifier, params);
54fb299fa2Sopenharmony_ci}
55fb299fa2Sopenharmony_ciUScriptValuePtr UScriptExpression::Execute(ScriptInterpreter &inter, UScriptContextPtr local)
56fb299fa2Sopenharmony_ci{
57fb299fa2Sopenharmony_ci    return std::make_shared<UScriptValue>(UScriptValue::VALUE_TYPE_ERROR);
58fb299fa2Sopenharmony_ci}
59fb299fa2Sopenharmony_ciUScriptValuePtr IntegerExpression::Execute(ScriptInterpreter &inter, UScriptContextPtr local)
60fb299fa2Sopenharmony_ci{
61fb299fa2Sopenharmony_ci    return std::make_shared<IntegerValue>(this->value_);
62fb299fa2Sopenharmony_ci}
63fb299fa2Sopenharmony_ciUScriptValuePtr FloatExpression::Execute(ScriptInterpreter &inter, UScriptContextPtr local)
64fb299fa2Sopenharmony_ci{
65fb299fa2Sopenharmony_ci    return std::make_shared<FloatValue>(this->value_);
66fb299fa2Sopenharmony_ci}
67fb299fa2Sopenharmony_ciUScriptValuePtr StringExpression::Execute(ScriptInterpreter &inter, UScriptContextPtr local)
68fb299fa2Sopenharmony_ci{
69fb299fa2Sopenharmony_ci    return std::make_shared<StringValue>(this->value_);
70fb299fa2Sopenharmony_ci}
71fb299fa2Sopenharmony_ciUScriptValuePtr IdentifierExpression::Execute(ScriptInterpreter &inter, UScriptContextPtr local)
72fb299fa2Sopenharmony_ci{
73fb299fa2Sopenharmony_ci    INTERPRETER_LOGI(inter, local, "Execute statements identifier %s ", identifier_.c_str());
74fb299fa2Sopenharmony_ci    UScriptValuePtr variable = inter.FindVariable(local, identifier_);
75fb299fa2Sopenharmony_ci    INTERPRETER_LOGI(inter, local, "IdentifierExpression::Execute '%s = %s ' ", identifier_.c_str(),
76fb299fa2Sopenharmony_ci        UScriptValue::ScriptToString(variable).c_str());
77fb299fa2Sopenharmony_ci    if (variable != nullptr) {
78fb299fa2Sopenharmony_ci        return variable;
79fb299fa2Sopenharmony_ci    }
80fb299fa2Sopenharmony_ci    return std::make_shared<UScriptValue>(UScriptValue::VALUE_TYPE_ERROR);
81fb299fa2Sopenharmony_ci}
82fb299fa2Sopenharmony_ci
83fb299fa2Sopenharmony_ciint32_t IdentifierExpression::GetIdentifierName(UScriptExpression *expression, std::string &name)
84fb299fa2Sopenharmony_ci{
85fb299fa2Sopenharmony_ci    if (expression == nullptr) {
86fb299fa2Sopenharmony_ci        return USCRIPT_INVALID_PARAM;
87fb299fa2Sopenharmony_ci    }
88fb299fa2Sopenharmony_ci    if (expression->GetExpressType() != EXPRESSION_TYPE_IDENTIFIER) {
89fb299fa2Sopenharmony_ci        return USCRIPT_INVALID_PARAM;
90fb299fa2Sopenharmony_ci    } else {
91fb299fa2Sopenharmony_ci        auto identifier = reinterpret_cast<IdentifierExpression*>(expression);
92fb299fa2Sopenharmony_ci        if (identifier != nullptr) {
93fb299fa2Sopenharmony_ci            name = identifier->GetIdentifier();
94fb299fa2Sopenharmony_ci            return USCRIPT_SUCCESS;
95fb299fa2Sopenharmony_ci        }
96fb299fa2Sopenharmony_ci    }
97fb299fa2Sopenharmony_ci    return USCRIPT_INVALID_PARAM;
98fb299fa2Sopenharmony_ci}
99fb299fa2Sopenharmony_ciUScriptValuePtr AssignExpression::Execute(ScriptInterpreter &inter, UScriptContextPtr local)
100fb299fa2Sopenharmony_ci{
101fb299fa2Sopenharmony_ci    UScriptValuePtr result = expression_->Execute(inter, local);
102fb299fa2Sopenharmony_ci    INTERPRETER_LOGI(inter, local, "AssignExpression::Execute update local var '%s = %s ' ", identifier_.c_str(),
103fb299fa2Sopenharmony_ci        UScriptValue::ScriptToString(result).c_str());
104fb299fa2Sopenharmony_ci    if (result->GetValueType() == UScriptValue::VALUE_TYPE_ERROR) {
105fb299fa2Sopenharmony_ci        return result;
106fb299fa2Sopenharmony_ci    }
107fb299fa2Sopenharmony_ci    UScriptValuePtr var = inter.FindVariable(local, identifier_);
108fb299fa2Sopenharmony_ci    if (var != nullptr) {
109fb299fa2Sopenharmony_ci        inter.UpdateVariable(local, identifier_, result);
110fb299fa2Sopenharmony_ci        return result;
111fb299fa2Sopenharmony_ci    }
112fb299fa2Sopenharmony_ci
113fb299fa2Sopenharmony_ci    std::vector<std::string> identifiers;
114fb299fa2Sopenharmony_ci    identifiers.push_back(identifier_);
115fb299fa2Sopenharmony_ci    identifiers.insert(identifiers.begin() + 1, multipleIdentifiers_.begin(), multipleIdentifiers_.end());
116fb299fa2Sopenharmony_ci    size_t index = 0;
117fb299fa2Sopenharmony_ci    local->UpdateVariables(inter, result, identifiers, index);
118fb299fa2Sopenharmony_ci    return result;
119fb299fa2Sopenharmony_ci}
120fb299fa2Sopenharmony_ci
121fb299fa2Sopenharmony_ciUScriptValuePtr BinaryExpression::Execute(ScriptInterpreter &inter, UScriptContextPtr local)
122fb299fa2Sopenharmony_ci{
123fb299fa2Sopenharmony_ci    static std::vector<std::string> opStr = {
124fb299fa2Sopenharmony_ci        "", "add", "sub", "mul", "div", ">", ">=", "<", "<=", "==", "!=", "&&", "||"
125fb299fa2Sopenharmony_ci    };
126fb299fa2Sopenharmony_ci    UScriptValuePtr left;
127fb299fa2Sopenharmony_ci    UScriptValuePtr right;
128fb299fa2Sopenharmony_ci
129fb299fa2Sopenharmony_ci    INTERPRETER_LOGI(inter, local, "BinaryExpression::Execute ");
130fb299fa2Sopenharmony_ci    if (left_ != nullptr) {
131fb299fa2Sopenharmony_ci        left = left_->Execute(inter, local);
132fb299fa2Sopenharmony_ci    }
133fb299fa2Sopenharmony_ci
134fb299fa2Sopenharmony_ci    if (action_ == OR_OPERATOR && left != nullptr && left->IsTrue()) {
135fb299fa2Sopenharmony_ci        INTERPRETER_LOGE(inter, local, "BinaryExpression::Execute left:%s %s",
136fb299fa2Sopenharmony_ci            UScriptValue::ScriptToString(left).c_str(), opStr[action_].c_str());
137fb299fa2Sopenharmony_ci        return std::make_shared<IntegerValue>(1);
138fb299fa2Sopenharmony_ci    }
139fb299fa2Sopenharmony_ci    if (right_ != nullptr) {
140fb299fa2Sopenharmony_ci        right = right_->Execute(inter, local);
141fb299fa2Sopenharmony_ci    }
142fb299fa2Sopenharmony_ci    if (left != nullptr && right != nullptr) {
143fb299fa2Sopenharmony_ci        UScriptValuePtr value = left->Computer(action_, right);
144fb299fa2Sopenharmony_ci        INTERPRETER_LOGI(inter, local, "BinaryExpression::Execute left:%s %s right:%s result:%s",
145fb299fa2Sopenharmony_ci            UScriptValue::ScriptToString(left).c_str(), opStr[action_].c_str(),
146fb299fa2Sopenharmony_ci            UScriptValue::ScriptToString(right).c_str(), UScriptValue::ScriptToString(value).c_str());
147fb299fa2Sopenharmony_ci        return value;
148fb299fa2Sopenharmony_ci    }
149fb299fa2Sopenharmony_ci    return std::make_shared<ErrorValue>(USCRIPT_ERROR_INTERPRET);
150fb299fa2Sopenharmony_ci}
151fb299fa2Sopenharmony_ci
152fb299fa2Sopenharmony_ciUScriptValuePtr FunctionCallExpression::Execute(ScriptInterpreter &inter, UScriptContextPtr local)
153fb299fa2Sopenharmony_ci{
154fb299fa2Sopenharmony_ci    UScriptValuePtr v;
155fb299fa2Sopenharmony_ci    INTERPRETER_LOGD(inter, local, "FunctionCallExpression::Execute %s ", functionName_.c_str());
156fb299fa2Sopenharmony_ci
157fb299fa2Sopenharmony_ci    if (inter.IsNativeFunction(functionName_)) {
158fb299fa2Sopenharmony_ci        return inter.ExecuteNativeFunc(local, functionName_, params_);
159fb299fa2Sopenharmony_ci    }
160fb299fa2Sopenharmony_ci    return inter.ExecuteFunction(local, functionName_, params_);
161fb299fa2Sopenharmony_ci}
162fb299fa2Sopenharmony_ci
163fb299fa2Sopenharmony_ciBinaryExpression::~BinaryExpression()
164fb299fa2Sopenharmony_ci{
165fb299fa2Sopenharmony_ci    delete left_;
166fb299fa2Sopenharmony_ci    delete right_;
167fb299fa2Sopenharmony_ci}
168fb299fa2Sopenharmony_ciAssignExpression::~AssignExpression()
169fb299fa2Sopenharmony_ci{
170fb299fa2Sopenharmony_ci    delete this->expression_;
171fb299fa2Sopenharmony_ci}
172fb299fa2Sopenharmony_ciFunctionCallExpression::~FunctionCallExpression()
173fb299fa2Sopenharmony_ci{
174fb299fa2Sopenharmony_ci    delete params_;
175fb299fa2Sopenharmony_ci}
176fb299fa2Sopenharmony_ci} // namespace Uscript
177