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 20using namespace std; 21 22namespace Uscript { 23UScriptExpression::UScriptExpression(ExpressionType expressType) : expressType_(expressType) {} 24UScriptExpression::~UScriptExpression() {} 25 26UScriptExpression* AssignExpression::CreateExpression(const std::string identifier, UScriptExpression *expression) 27{ 28 return new AssignExpression(identifier, expression); 29} 30void AssignExpression::AddIdentifier(const std::string &identifier) 31{ 32 multipleIdentifiers_.push_back(identifier); 33} 34 35UScriptExpression* 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 45UScriptExpression* BinaryExpression::CreateExpression(ExpressionAction action, 46 UScriptExpression *left, 47 UScriptExpression *right) 48{ 49 return new BinaryExpression(action, left, right); 50} 51UScriptExpression* FunctionCallExpression::CreateExpression(const std::string identifier, ScriptParams *params) 52{ 53 return new FunctionCallExpression(identifier, params); 54} 55UScriptValuePtr UScriptExpression::Execute(ScriptInterpreter &inter, UScriptContextPtr local) 56{ 57 return std::make_shared<UScriptValue>(UScriptValue::VALUE_TYPE_ERROR); 58} 59UScriptValuePtr IntegerExpression::Execute(ScriptInterpreter &inter, UScriptContextPtr local) 60{ 61 return std::make_shared<IntegerValue>(this->value_); 62} 63UScriptValuePtr FloatExpression::Execute(ScriptInterpreter &inter, UScriptContextPtr local) 64{ 65 return std::make_shared<FloatValue>(this->value_); 66} 67UScriptValuePtr StringExpression::Execute(ScriptInterpreter &inter, UScriptContextPtr local) 68{ 69 return std::make_shared<StringValue>(this->value_); 70} 71UScriptValuePtr 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 83int32_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} 99UScriptValuePtr 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 121UScriptValuePtr 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 152UScriptValuePtr 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 163BinaryExpression::~BinaryExpression() 164{ 165 delete left_; 166 delete right_; 167} 168AssignExpression::~AssignExpression() 169{ 170 delete this->expression_; 171} 172FunctionCallExpression::~FunctionCallExpression() 173{ 174 delete params_; 175} 176} // namespace Uscript 177