aboutsummaryrefslogtreecommitdiffstats
path: root/ExpressionCompiler.h
blob: 28a04f525638d1ab211ce3bbde989c7efe00315e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/*
    This file is part of cpp-ethereum.

    cpp-ethereum is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    cpp-ethereum is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/**
 * @author Christian <c@ethdev.com>
 * @date 2014
 * Solidity AST to EVM bytecode compiler for expressions.
 */

#include <libsolidity/ASTVisitor.h>
#include <libsolidity/CompilerUtilities.h>

namespace dev {
namespace solidity {

/// Compiler for expressions, i.e. converts an AST tree whose root is an Expression into a stream
/// of EVM instructions. It needs a compiler context that is the same for the whole compilation
/// unit.
class ExpressionCompiler: private ASTVisitor
{
public:
    /// Compile the given @a _expression into the @a _context.
    static void compileExpression(CompilerContext& _context, Expression& _expression);

    /// Appends code to remove dirty higher order bits in case of an implicit promotion to a wider type.
    static void cleanHigherOrderBitsIfNeeded(Type const& _typeOnStack, Type const& _targetType);

private:
    ExpressionCompiler(CompilerContext& _compilerContext): m_currentLValue(nullptr), m_context(_compilerContext) {}

    virtual bool visit(Assignment& _assignment) override;
    virtual void endVisit(UnaryOperation& _unaryOperation) override;
    virtual bool visit(BinaryOperation& _binaryOperation) override;
    virtual bool visit(FunctionCall& _functionCall) override;
    virtual void endVisit(MemberAccess& _memberAccess) override;
    virtual void endVisit(IndexAccess& _indexAccess) override;
    virtual void endVisit(Identifier& _identifier) override;
    virtual void endVisit(Literal& _literal) override;

    ///@{
    ///@name Append code for various operator types
    void appendAndOrOperatorCode(BinaryOperation& _binaryOperation);
    void appendCompareOperatorCode(Token::Value _operator, Type const& _type);
    void appendOrdinaryBinaryOperatorCode(Token::Value _operator, Type const& _type);

    void appendArithmeticOperatorCode(Token::Value _operator, Type const& _type);
    void appendBitOperatorCode(Token::Value _operator);
    void appendShiftOperatorCode(Token::Value _operator);
    /// @}

    /// Stores the value on top of the stack in the current lvalue and copies that value to the
    /// top of the stack again
    void storeInLValue(Expression const& _expression);
    /// The same as storeInLValue but do not again retrieve the value to the top of the stack.
    void moveToLValue(Expression const& _expression);
    /// Returns the position of @a m_currentLValue in the stack, where 0 is the top of the stack.
    unsigned stackPositionOfLValue() const;
    void adjustStackOffset(eth::Instruction _instruction);

    Declaration* m_currentLValue;
    CompilerContext& m_context;
};


}
}