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