#ifndef PCC_EXPRNODE_H #define PCC_EXPRNODE_H #include #include "BaseNode.hh" #include "Type.hh" namespace pcc { class ExprNode : public BaseNode { public: ExprNode(Context* context); virtual Value CodeGen() = 0; std::shared_ptr GetType(); protected: std::shared_ptr type_; }; class BinaryExprNode : public ExprNode { public: BinaryExprNode(Context* context, BinaryOperator op, std::shared_ptr left, std::shared_ptr right); virtual Value CodeGen() override; virtual int Travel(Traveler& traveler) override; protected: BinaryOperator op_; std::shared_ptr left_, right_; }; class UnaryExprNode : public ExprNode { public: UnaryExprNode(Context* context, UnaryOperator op, std::shared_ptr value); virtual Value CodeGen() override; virtual int Travel(Traveler& traveler) override; protected: UnaryOperator op_; std::shared_ptr value_; }; // when accessing lvalues, we need an extra load instruction to actually load // the value from the pointer, this is like clang's 'LValueToRValue' node below. // c++: int x=7; int y=x; // `-CompoundStmt 0xd28720 // |-DeclStmt 0xd28638 // | `-VarDecl 0xd285b0 col:6 used x 'int' cinit // | `-IntegerLiteral 0xd28618 'int' 7 // `-DeclStmt 0xd28708 // `-VarDecl 0xd28668 col:6 y 'int' cinit // `-ImplicitCastExpr 0xd286f0 'int' // `-DeclRefExpr 0xd286d0 'int' lvalue Var 0xd285b0 'x' 'int' class L2RCastingNode : public ExprNode { public: L2RCastingNode(Context* context, std::shared_ptr lvalue); virtual Value CodeGen() override; virtual int Travel(Traveler& traveler) override; protected: std::shared_ptr lvalue_; }; // access an rvalue pointer, this generates one GEP instruction class PointerAccessNode : public ExprNode { public: PointerAccessNode(Context* context, std::shared_ptr lhs, std::shared_ptr rhs); virtual Value CodeGen() override; virtual int Travel(Traveler& traveler) override; protected: std::shared_ptr lhs_; std::shared_ptr rhs_; }; // access an array or lvalue pointer class ArrayAccessNode : public ExprNode { public: ArrayAccessNode(Context* context, std::shared_ptr lhs, std::shared_ptr rhs); virtual Value CodeGen() override; virtual int Travel(Traveler& traveler) override; protected: std::shared_ptr lhs_; std::shared_ptr rhs_; }; class DereferenceNode : public ExprNode { public: DereferenceNode(Context* context, std::shared_ptr lhs); virtual Value CodeGen() override; virtual int Travel(Traveler& traveler) override; protected: std::shared_ptr lhs_; }; class MemberAccessNode : public ExprNode { public: MemberAccessNode(Context* context, std::shared_ptr lhs, std::string&& rhs); virtual Value CodeGen() override; virtual int Travel(Traveler& traveler) override; protected: std::shared_ptr lhs_; std::string rhs_; }; class IdentifierNode : public ExprNode { public: IdentifierNode(Context* context, const std::string& name); virtual Value CodeGen() override; virtual int Travel(Traveler& traveler) override; protected: std::string name_; }; class FunctionCallNode : public ExprNode { public: FunctionCallNode(Context* context, const std::string& name, std::list>&& args); virtual Value CodeGen() override; virtual int Travel(Traveler& traveler) override; protected: std::string name_; std::list> args_; }; } // namespace pcc #endif // !PCC_EXPRNODE_H