 |
Cerata
A library to generate structural hardware designs
|
22 #include <unordered_map>
24 #include "cerata/object.h"
25 #include "cerata/type.h"
26 #include "cerata/node.h"
27 #include "cerata/pool.h"
37 enum class Op { ADD, SUB, MUL, DIV };
40 static std::shared_ptr<Expression>
Make(
Op op, std::shared_ptr<Node>
lhs, std::shared_ptr<Node>
rhs);
43 std::shared_ptr<Object>
Copy()
const override;
51 std::string
ToString()
const override;
77 std::shared_ptr<Node>
lhs_;
79 std::shared_ptr<Node>
rhs_;
86 #ifndef EXPRESSION_OP_FACTORY
87 #define EXPRESSION_OP_FACTORY(SYMBOL, OPID) \
88 inline std::shared_ptr<Node> operator SYMBOL (const std::shared_ptr<Node>& lhs, \
89 const std::shared_ptr<Node>& rhs) { \
90 return Expression::Make(Expression::Op::OPID, lhs, rhs); \
93 inline std::shared_ptr<Node> operator SYMBOL (const std::shared_ptr<Node>& lhs, \
95 return Expression::Make(Expression::Op::OPID, lhs, rhs->shared_from_this()); \
98 inline std::shared_ptr<Node> operator SYMBOL (const std::shared_ptr<Node>& lhs, int64_t rhs) { \
99 if (lhs->IsLiteral()) { \
100 auto li = std::dynamic_pointer_cast<Literal>(lhs); \
101 if (li->storage_type() == Literal::StorageType::INT) { \
102 return default_node_pool()->GetLiteral(li->IntValue() SYMBOL rhs); \
105 return lhs SYMBOL intl(rhs); \
108 inline std::shared_ptr<Node> operator SYMBOL (Node& lhs, int64_t rhs) { \
109 if (lhs.IsLiteral()) { \
110 auto& li = dynamic_cast<Literal&>(lhs); \
111 if (li.storage_type() == Literal::StorageType::INT) { \
112 return default_node_pool()->GetLiteral(li.IntValue() SYMBOL rhs); \
115 return lhs.shared_from_this() SYMBOL intl(rhs); \
119 EXPRESSION_OP_FACTORY(+, ADD)
120 EXPRESSION_OP_FACTORY(-, SUB)
121 EXPRESSION_OP_FACTORY(*, MUL)
122 EXPRESSION_OP_FACTORY(/, DIV)
static std::shared_ptr< Node > Minimize(Node *node)
Minimize a node, if it is an expression, otherwise just returns a copy of the input.
std::string ToString() const override
Minimize the expression and convert it to a human-readable string.
static std::shared_ptr< Node > EliminateZeroOne(Expression *exp)
Eliminate nodes that have zero or one on either side for specific expressions.
A node representing a binary tree of other nodes.
A graph representing a hardware structure.
static std::shared_ptr< Expression > Make(Op op, std::shared_ptr< Node > lhs, std::shared_ptr< Node > rhs)
Short-hand to create a smart pointer to an expression.
Op
Binary expression operator enum class.
std::shared_ptr< Node > lhs_
The left hand side node.
Contains every Cerata class, function, etc...
Node * lhs() const
Return the left-hand side node of the expression.
std::unordered_map< const Node *, Node * > NodeMap
A mapping from one object to another object, used in e.g. type generic rebinding.
std::string name() const
Return the name of the object.
std::string ToString(Expression::Op operation)
Human-readable expression operator.
std::shared_ptr< Node > rhs_
The right hand side node.
Node * rhs() const
Return the right-hand side node of the expression.
Expression(Op op, std::shared_ptr< Node > lhs, std::shared_ptr< Node > rhs)
Construct a new expression.
void AppendReferences(std::vector< Object * > *out) const override
Depth-first traverse the expression tree and add any nodes owned.
static std::shared_ptr< Node > MergeIntLiterals(Expression *exp)
Merge expressions of integer literals into their resulting integer literal.
Op operation_
The binary operator of this expression.
std::shared_ptr< Object > Copy() const override
Copy this expression.
Node * CopyOnto(Graph *dst, const std::string &name, NodeMap *rebinding) const override
Copy this expression onto a graph and rebind anything in the expression tree.
A no-input, multiple-outputs node.