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#ifndef USCRIPT_EXPRESSION_H
16#define USCRIPT_EXPRESSION_H
17
18#include <memory>
19#include "script_context.h"
20
21namespace Uscript {
22class UScriptExpression;
23using UScriptExpressionPtr = std::shared_ptr<UScriptExpression>;
24
25class ScriptParams;
26class ScriptFunction;
27
28class UScriptExpression {
29public:
30    enum ExpressionType {
31        EXPRESSION_TYPE_INTERGER,
32        EXPRESSION_TYPE_FLOAT,
33        EXPRESSION_TYPE_STRING,
34        EXPRESSION_TYPE_IDENTIFIER,
35        EXPRESSION_TYPE_BINARY,
36        EXPRESSION_TYPE_ASSIGN,
37        EXPRESSION_TYPE_INV,
38        EXPRESSION_TYPE_FUNC,
39        EXPRESSION_TYPE_INVALID,
40    };
41    enum ExpressionAction {
42        ADD_OPERATOR = 1,
43        SUB_OPERATOR,
44        MUL_OPERATOR,
45        DIV_OPERATOR,
46        GT_OPERATOR,
47        GE_OPERATOR,
48        LT_OPERATOR,
49        LE_OPERATOR,
50        EQ_OPERATOR,
51        NE_OPERATOR,
52        AND_OPERATOR,
53        OR_OPERATOR
54    };
55
56public:
57    explicit UScriptExpression(ExpressionType expressType);
58    virtual ~UScriptExpression();
59
60    virtual UScriptValuePtr Execute(ScriptInterpreter &inter, UScriptContextPtr local);
61    static UScriptExpression* CreateExpression(ExpressionType expressType)
62    {
63        return new UScriptExpression(expressType);
64    }
65    ExpressionType GetExpressType()
66    {
67        return expressType_;
68    }
69
70private:
71    ExpressionType expressType_;
72};
73
74class IntegerExpression : public UScriptExpression {
75public:
76    explicit IntegerExpression(int v) : UScriptExpression(UScriptExpression::EXPRESSION_TYPE_INTERGER)
77    {
78        value_ = v;
79    }
80
81    ~IntegerExpression() override {}
82
83    UScriptValuePtr Execute(ScriptInterpreter &inter, UScriptContextPtr local) override;
84
85    static UScriptExpression* CreateExpression(int value)
86    {
87        return new IntegerExpression(value);
88    }
89private:
90    int value_;
91};
92
93class FloatExpression : public UScriptExpression {
94public:
95    explicit FloatExpression(float v) : UScriptExpression(UScriptExpression::EXPRESSION_TYPE_FLOAT)
96    {
97        value_ = v;
98    }
99
100    ~FloatExpression() override {}
101
102    UScriptValuePtr Execute(ScriptInterpreter &inter, UScriptContextPtr local) override;
103
104    static UScriptExpression* CreateExpression(float value)
105    {
106        return new FloatExpression(value);
107    }
108
109private:
110    float value_;
111};
112
113class StringExpression : public UScriptExpression {
114public:
115    explicit StringExpression(const std::string str) : UScriptExpression(UScriptExpression::EXPRESSION_TYPE_STRING),
116        value_(str) {}
117
118    ~StringExpression() override {}
119
120    UScriptValuePtr Execute(ScriptInterpreter &inter, UScriptContextPtr local) override;
121
122    static UScriptExpression* CreateExpression(const std::string value)
123    {
124        return new StringExpression(value);
125    }
126private:
127    std::string value_;
128};
129
130class IdentifierExpression : public UScriptExpression {
131public:
132    explicit IdentifierExpression(const std::string str)
133        : UScriptExpression(UScriptExpression::EXPRESSION_TYPE_IDENTIFIER), identifier_(str) {}
134
135    ~IdentifierExpression() override {}
136
137    UScriptValuePtr Execute(ScriptInterpreter &inter, UScriptContextPtr local) override;
138
139    static UScriptExpression* CreateExpression(const std::string value)
140    {
141        return new IdentifierExpression(value);
142    }
143
144    const std::string GetIdentifier()
145    {
146        return identifier_;
147    }
148
149    static int32_t GetIdentifierName(UScriptExpression *expression, std::string &name);
150private:
151    std::string identifier_;
152};
153
154class BinaryExpression : public UScriptExpression {
155public:
156    BinaryExpression(ExpressionAction action, UScriptExpression *left, UScriptExpression *right)
157        : UScriptExpression(UScriptExpression::EXPRESSION_TYPE_BINARY), action_(action), left_(left), right_(right) {}
158
159    ~BinaryExpression() override;
160
161    UScriptValuePtr Execute(ScriptInterpreter &inter, UScriptContextPtr local) override;
162
163    static UScriptExpression* CreateExpression(ExpressionAction action, UScriptExpression *left,
164        UScriptExpression *right);
165private:
166    UScriptExpression::ExpressionAction action_;
167    UScriptExpression* left_ = nullptr;
168    UScriptExpression* right_ = nullptr;
169};
170
171class AssignExpression : public UScriptExpression {
172public:
173    AssignExpression(const std::string identifier, UScriptExpression *expression)
174        : UScriptExpression(UScriptExpression::EXPRESSION_TYPE_ASSIGN), identifier_(identifier),
175        expression_(expression) {}
176
177    ~AssignExpression() override;
178
179    UScriptValuePtr Execute(ScriptInterpreter &inter, UScriptContextPtr local) override;
180
181    void AddIdentifier(const std::string &identifier);
182
183    static UScriptExpression* CreateExpression(const std::string identifier, UScriptExpression *expression);
184    static UScriptExpression* AddIdentifier(UScriptExpression *expression, const std::string identifier);
185private:
186    std::string identifier_;
187    std::vector<std::string> multipleIdentifiers_; // 最大支持4个参数a,b,v = 1
188    UScriptExpression* expression_ = nullptr;
189};
190
191class FunctionCallExpression : public UScriptExpression {
192public:
193    FunctionCallExpression(const std::string identifier, ScriptParams *params)
194        : UScriptExpression(UScriptExpression::EXPRESSION_TYPE_FUNC), functionName_(identifier), params_(params) {}
195
196    ~FunctionCallExpression() override;
197
198    UScriptValuePtr Execute(ScriptInterpreter &inter, UScriptContextPtr local) override;
199
200    static UScriptExpression* CreateExpression(const std::string identifier, ScriptParams *params);
201private:
202    std::string functionName_;
203    ScriptParams* params_ = nullptr;
204};
205} // namespace Uscript
206#endif // _HS_EXPRESSION_H
207