diff --git a/compiler/ASTNodes.hpp b/compiler/ASTNodes.hpp index 9a86c3d..640807d 100644 --- a/compiler/ASTNodes.hpp +++ b/compiler/ASTNodes.hpp @@ -19,8 +19,12 @@ -// ------ Abstract syntax tree classes ------ +static std::logic_error compilerError(std::string place, std::string msg) +{ + return std::logic_error("Internal compiler error in " + place + ": " + msg); +} +// ------ Abstract syntax tree classes ------ /// Base class for expression nodes. @@ -76,6 +80,22 @@ class SequenceNode : public Node const std::vector& nodes() { return nodes_; } + virtual int numChildren() + { + return nodes_.size(); + } + virtual Node* getChild(const int index) + { + return nodes_[index]; + } + virtual void setChild(const int index, Node* child) + { + if (index < nodes_.size() && index >= 0) { + nodes_[index] = child; + } else { + throw compilerError("SequenceNode::setChild()", "Index out of range."); + } + } private: std::vector nodes_; }; @@ -99,6 +119,15 @@ class NumberNode : public Node { return num_; } + virtual int numChildren() { return 0; } + virtual Node* getChild(const int index) + { + throw compilerError("NumberNode::getChild()", "NumberNode has no children."); + } + virtual void setChild(const int index, Node* child) + { + throw compilerError("NumberNode::setChild()", "NumberNode has no children."); + } private: double num_; }; @@ -122,6 +151,15 @@ class StringNode : public ExpressionNode { return content_; } + virtual int numChildren(){ return 0; } + virtual Node* getChild(const int index) + { + throw compilerError("StringNode::getChild()", "StringNode has no children."); + } + virtual void setChild(const int index, Node* child) + { + throw compilerError("StringNode::setChild()", "StringNode has no children."); + } private: std::string content_; }; @@ -141,6 +179,18 @@ class TypeNode : public Node { visitor.visit(*this); } + virtual int numChildren() + { + return 0; + } + virtual Node* getChild(const int index) + { + throw compilerError("TypeNode::getChild()", "TypeNode has no children."); + } + virtual void setChild(const int index, Node* child) + { + throw compilerError("TypeNode::setChild()", "TypeNode has no children."); + } private: EquelleType et_; }; @@ -205,6 +255,28 @@ class CollectionTypeNode : public TypeNode } visitor.postVisit(*this); } + virtual int numChildren() + { + return 3; + } + virtual Node* getChild(const int index) + { + switch (index) { + case 0 : return btype_; + case 1 : return gridmapping_; + case 2 : return subsetof_; + default: throw compilerError("CollectionTypeNode::getChild()", "Index is out of range."); + } + } + virtual void setChild(const int index, Node* child) + { + switch (index) { + case 0 : btype_ = dynamic_cast(child); break; + case 1 : gridmapping_ = dynamic_cast(child); break; + case 2 : subsetof_ = dynamic_cast(child); break; + default: throw compilerError("CollectionTypeNode::setChild()", "Index is out of range."); + } + } private: TypeNode* btype_; @@ -241,7 +313,26 @@ class ArrayTypeNode : public TypeNode { visitor.visit(*this); } - + virtual int numChildren() + { + return 1; + } + virtual Node* getChild(const int index) + { + if (index == 0) { + return btype_; + } else { + throw compilerError("ArrayTypeNode::getChild()", "Index is out of range."); + } + } + virtual void setChild(const int index, Node* child) + { + if (index == 0) { + btype_ = dynamic_cast(child); + } else { + throw compilerError("ArrayTypeNode::setChild()", "Index is out of range."); + } + } private: TypeNode* btype_; int array_size_; @@ -275,7 +366,22 @@ class SequenceTypeNode : public TypeNode { visitor.visit(*this); } - + virtual Node* getChild(const int index) + { + if (index == 0) { + return btype_; + } else { + throw compilerError("SequenceTypeNode::getChild()", "Index is out of range."); + } + } + virtual void setChild(const int index, Node* child) + { + if (index == 0) { + btype_ = dynamic_cast(child); + } else { + throw compilerError("SequenceTypeNode::setChild()", "Index is out of range."); + } + } private: TypeNode* btype_; }; @@ -308,7 +414,22 @@ class MutableTypeNode : public TypeNode { visitor.visit(*this); } - + virtual Node* getChild(const int index) + { + if (index == 0) { + return btype_; + } else { + throw compilerError("MutableTypeNode::getChild()", "Index is out of range."); + } + } + virtual void setChild(const int index, Node* child) + { + if (index == 0) { + btype_ = dynamic_cast(child); + } else { + throw compilerError("MutableTypeNode::setChild()", "Index is out of range."); + } + } private: TypeNode* btype_; }; @@ -334,30 +455,7 @@ class BinaryOpNode : public ExpressionNode { EquelleType lt = left_->type(); EquelleType rt = right_->type(); - switch (op_) { - case Add: - return lt; // should be identical to rt. - case Subtract: - return lt; // should be identical to rt. - case Multiply: { - const bool isvec = lt.basicType() == Vector || rt.basicType() == Vector; - const BasicType bt = isvec ? Vector : Scalar; - const bool coll = lt.isCollection() || rt.isCollection(); - const bool sequence = lt.isSequence() || rt.isSequence(); - const CompositeType ct = coll ? Collection : (sequence ? Sequence : None); - const int gm = lt.isCollection() ? lt.gridMapping() : rt.gridMapping(); - return EquelleType(bt, ct, gm); - } - case Divide: { - const BasicType bt = lt.basicType(); - const bool coll = lt.isCollection() || rt.isCollection(); - const int gm = lt.isCollection() ? lt.gridMapping() : rt.gridMapping(); - return EquelleType(bt, coll ? Collection : None, gm); - } - default: - yyerror("internal compiler error in BinaryOpNode::type()."); - return EquelleType(); - } + return getBinaryOpType(op_, lt, rt,"BinaryOpNode::type()"); } Dimension dimension() const { @@ -395,13 +493,180 @@ class BinaryOpNode : public ExpressionNode right_->accept(visitor); visitor.postVisit(*this); } + virtual int numChildren() + { + return 2; + } + virtual Node* getChild(const int index) + { + switch (index) { + case 0 : return left_; + case 1 : return right_; + default: throw compilerError("BinaryOpNode::getChild()", "Index is out of range."); + } + } + virtual void setChild(const int index, Node* child) + { + + ExpressionNode* exprchild = dynamic_cast(child); + switch (index) { + case 0 : left_ = exprchild; break; + case 1 : right_ = exprchild; break; + default: throw compilerError("BinaryOpNode::setChild()", "Index is out of range."); + } + } + static EquelleType getBinaryOpType(BinaryOp op, const EquelleType& lt, const EquelleType& rt, const std::string where) + { + switch (op) { + case Add: + return lt; // should be identical to rt. + case Subtract: + return lt; // should be identical to rt. + case Multiply: { + const bool isvec = lt.basicType() == Vector || rt.basicType() == Vector; + const BasicType bt = isvec ? Vector : Scalar; + const bool coll = lt.isCollection() || rt.isCollection(); + const bool sequence = lt.isSequence() || rt.isSequence(); + const CompositeType ct = coll ? Collection : (sequence ? Sequence : None); + const int gm = lt.isCollection() ? lt.gridMapping() : rt.gridMapping(); + return EquelleType(bt, ct, gm); + } + case Divide: { + const BasicType bt = lt.basicType(); + const bool coll = lt.isCollection() || rt.isCollection(); + const int gm = lt.isCollection() ? lt.gridMapping() : rt.gridMapping(); + return EquelleType(bt, coll ? Collection : None, gm); + } + default: + std::string msg = "internal compiler error in " + where +"."; + yyerror(msg.c_str()); + return EquelleType(); + } + } private: BinaryOp op_; ExpressionNode* left_; ExpressionNode* right_; }; +// Class for the operation a * b + c +class MultiplyAddNode : public ExpressionNode +{ +public: + MultiplyAddNode(ExpressionNode* a, ExpressionNode* b, ExpressionNode* c) + : a_(a), b_(b), c_(c) + { + } + virtual ~MultiplyAddNode() + { + delete a_; + delete b_; + delete c_; + } + virtual EquelleType type() const + { + // Type of left and right side of multiplication + EquelleType lt = a_->type(); + EquelleType rt = b_->type(); + // We return the type of a * b since c must have the same type + return BinaryOpNode::getBinaryOpType(Multiply, lt, rt, "MultiplyAddNode::type()"); + } + virtual void accept(ASTVisitorInterface& visitor) + { + visitor.visit(*this); + a_->accept(visitor); + visitor.midVisit(*this); + b_->accept(visitor); + visitor.midVisit(*this); + c_->accept(visitor); + visitor.postVisit(*this); + } + virtual int numChildren() + { + return 3; + } + virtual Node* getChild(const int index) + { + switch (index) { + case 0 : return a_; + case 1 : return b_; + case 2 : return c_; + default: throw compilerError("MultiplyAddNode::getChild()", "Index out of range.");; + } + } + virtual void setChild(const int index, Node* child) + { + ExpressionNode* exprchild = dynamic_cast(child); + switch (index) { + case 0 : a_ = exprchild; break; + case 1 : b_ = exprchild; break; + case 2 : c_ = exprchild; break; + default: throw compilerError("MultiplyAddNode::setChild()", "Index is out of range."); + } + } +private: + ExpressionNode* a_; + ExpressionNode* b_; + ExpressionNode* c_; +}; + +class MultiplyDivideNode : public ExpressionNode +{ +public: + MultiplyDivideNode(ExpressionNode* a, ExpressionNode* b, ExpressionNode* c) + : a_(a), b_(b), c_(c) + { + } + virtual ~MultiplyDivideNode() + { + delete a_; + delete b_; + delete c_; + } + virtual EquelleType type() const + { + EquelleType mulType = BinaryOpNode::getBinaryOpType(Multiply, a_->type(), b_->type(), "MultiplyDivide::type()"); + return BinaryOpNode::getBinaryOpType(Divide, mulType, c_->type(), "MultiplyDivide::type()"); + } + virtual void accept(ASTVisitorInterface& visitor) + { + visitor.visit(*this); + a_->accept(visitor); + visitor.midVisit(*this); + b_->accept(visitor); + visitor.midVisit(*this); + c_->accept(visitor); + visitor.postVisit(*this); + } + virtual int numChildren() + { + return 3; + } + virtual Node* getChild(const int index) + { + switch (index) { + case 0 : return a_; + case 1 : return b_; + case 2 : return c_; + default: throw compilerError("MultiplyAddNode::getChild()", "Index out of range.");; + } + } + virtual void setChild(const int index, Node* child) + { + ExpressionNode* exprchild = dynamic_cast(child); + switch (index) { + case 0 : a_ = exprchild; break; + case 1 : b_ = exprchild; break; + case 2 : c_ = exprchild; break; + default: throw compilerError("MultiplyAddNode::setChild()", "Index is out of range."); + } + } +private: + ExpressionNode* a_; + ExpressionNode* b_; + ExpressionNode* c_; +}; enum ComparisonOp { Less, Greater, LessEqual, GreaterEqual, Equal, NotEqual }; @@ -444,6 +709,27 @@ class ComparisonOpNode : public ExpressionNode right_->accept(visitor); visitor.postVisit(*this); } + virtual int numChildren() + { + return 2; + } + virtual Node* getChild(const int index) + { + switch (index) { + case 0 : return left_; + case 1 : return right_; + default: throw compilerError("ComparisonOpNode::getChild()", "Index is out of range."); + } + } + virtual void setChild(const int index, Node* child) + { + ExpressionNode* exprchild = dynamic_cast(child); + switch (index) { + case 0 : left_ = exprchild; break; + case 1 : right_ = exprchild; break; + default: throw compilerError("ComparisonOpNode::setChild()", "Index is out of range."); + } + } private: ComparisonOp op_; ExpressionNode* left_; @@ -508,6 +794,25 @@ class NormNode : public ExpressionNode expr_to_norm_->accept(visitor); visitor.postVisit(*this); } + virtual int numChildren() + { + return 1; + } + virtual Node* getChild(const int index) + { + if (index == 0) { + return expr_to_norm_; + } + throw compilerError("NormNode::getChild()", "Index is out of range."); + } + virtual void setChild(const int index, Node* child) + { + if (index == 0) { + expr_to_norm_ = dynamic_cast(child);; + } else { + throw compilerError("NormNode::setChild()", "Index is out of range."); + } + } private: ExpressionNode* expr_to_norm_; }; @@ -541,6 +846,24 @@ class UnaryNegationNode : public ExpressionNode expr_to_negate_->accept(visitor); visitor.postVisit(*this); } + virtual int numChildren() + { + return 1; + } + virtual Node* getChild(const int index) + { + if (index == 0){ + return expr_to_negate_; + } + throw compilerError("UnaryNegationNode::getChild()", "Index is out of range."); + } + virtual void setChild(const int index, Node* child) + { + if (index == 0){ + expr_to_negate_ = dynamic_cast(child); + } + throw compilerError("UnaryNegationNode::setChild()", "Index is out of range."); + } private: ExpressionNode* expr_to_negate_; }; @@ -588,6 +911,27 @@ class OnNode : public ExpressionNode right_->accept(visitor); visitor.postVisit(*this); } + virtual int numChildren() + { + return 2; + } + virtual Node* getChild(const int index) + { + switch (index) { + case 0 : return left_; + case 1 : return right_; + default: throw compilerError("OnNode::getChild()", "Index out of range."); + } + } + virtual void setChild(const int index, Node* child) + { + ExpressionNode* exprchild = dynamic_cast(child); + switch (index) { + case 0 : left_ = exprchild; break; + case 1 : right_ = exprchild; break; + default: throw compilerError("OnNode::setChild()", "Index out of range."); + } + } private: ExpressionNode* left_; ExpressionNode* right_; @@ -639,6 +983,29 @@ class TrinaryIfNode : public ExpressionNode iffalse_->accept(visitor); visitor.postVisit(*this); } + virtual int numChildren() + { + return 3; + } + virtual Node* getChild(const int index) + { + switch (index) { + case 0 : return predicate_; + case 1 : return iftrue_; + case 2 : return iffalse_; + default: throw compilerError("TrinaryIfNode::getChild()", "Index is out of range."); + } + } + virtual void setChild(const int index, Node* child) + { + ExpressionNode* exprchild = dynamic_cast(child); + switch (index) { + case 0 : predicate_ = exprchild; break; + case 1 : iftrue_ = exprchild; break; + case 2 : iffalse_ = exprchild; break; + default: throw compilerError("TrinaryIfNode::setChild()", "Index out of range."); + } + } private: ExpressionNode* predicate_; ExpressionNode* iftrue_; @@ -673,6 +1040,24 @@ class VarDeclNode : public Node type_->accept(visitor); visitor.postVisit(*this); } + virtual int numChildren() + { + return 1; + } + virtual Node* getChild(const int index) + { + if(index == 0){ + return type_; + } + throw compilerError("VarDeclNode::getChild()", "Index is out of range."); + } + virtual void setChild(const int index, Node* child) + { + switch (index) { + case 0 : type_ = dynamic_cast(child); break; + default: throw compilerError("VarDeclNode::setChild()", "Index is out of range."); + } + } private: std::string varname_; TypeNode* type_; @@ -709,6 +1094,25 @@ class VarAssignNode : public Node expr_->accept(visitor); visitor.postVisit(*this); } + virtual int numChildren() + { + return 1; + } + virtual Node* getChild(const int index) + { + if (index == 0){ + return expr_; + } + throw compilerError("VarAssignNode::getChild()", "Index is out of range."); + } + virtual void setChild(const int index, Node* child) + { + if (index == 0) { + expr_ = dynamic_cast(child); + } else { + throw compilerError("VarAssignNode::setChild()", "Index is out of range."); + } + } private: std::string varname_; ExpressionNode* expr_; @@ -777,6 +1181,18 @@ class VarNode : public ExpressionNode { visitor.visit(*this); } + virtual int numChildren() + { + return 0; + } + virtual Node* getChild(const int index) + { + throw compilerError("VarNode::getChild()", "VarNode has no children."); + } + virtual void setChild(const int index, Node* child) + { + throw compilerError("VarNode::setChild()", "VarNode has no children."); + } private: std::string varname_; int instantiation_index_; @@ -825,6 +1241,18 @@ class FuncArgsDeclNode : public Node } visitor.postVisit(*this); } + virtual int numChildren() + { + return decls_.size(); + } + virtual Node* getChild(const int index) + { + return decls_[index]; + } + virtual void setChild(const int index, Node* child) + { + decls_[index] = dynamic_cast(child); + } private: std::vector decls_; }; @@ -847,6 +1275,30 @@ class FuncTypeNode : public Node { visitor.visit(*this); } + virtual int numChildren() + { + return 2; + } + virtual Node* getChild(const int index) + { + if ( index == 0 ) { + return argtypes_; + } else + if ( index == 1 ) { + return rtype_; + } + throw compilerError("FuncTypeNode::getChild()", "Index is out of range."); + } + virtual void setChild(const int index, Node* child) + { + if ( index == 0 ) { + argtypes_ = dynamic_cast(child); + }else + if ( index == 1 ) { + rtype_ = dynamic_cast(child); + } + throw compilerError("FuncTypeNode::setChild()", "Index is out of range."); + } private: FuncArgsDeclNode* argtypes_; TypeNode* rtype_; @@ -873,6 +1325,18 @@ class FuncRefNode : public ExpressionNode { visitor.visit(*this); } + virtual int numChildren() + { + return 0; + } + virtual Node* getChild(const int index) + { + throw compilerError("FuncRefNode::getChild()", "FuncRefNode has no children."); + } + virtual void setChild(const int index, Node* child) + { + throw compilerError("FuncRefNode::setChild()", "FuncRefNode has no children."); + } private: std::string funcname_; }; @@ -898,6 +1362,18 @@ class JustAnIdentifierNode : public ExpressionNode { visitor.visit(*this); } + virtual int numChildren() + { + return 0; + } + virtual Node* getChild(const int index) + { + throw compilerError("JustAnIdentifierNode::getChild()", "JustAnIdentifierNode has no children."); + } + virtual void setChild(const int index, Node* child) + { + throw compilerError("JustAnIdentifierNode::setChild()", "JustAnIdentifierNode has no children."); + } private: std::string id_; }; @@ -937,6 +1413,25 @@ class FuncDeclNode : public Node SymbolTable::setCurrentFunction(SymbolTable::getCurrentFunction().parentScope()); #endif } + virtual int numChildren() + { + return 1; + } + virtual Node* getChild(const int index) + { + if ( index == 0 ){ + return ftype_; + } + throw compilerError("FuncDeclNode::getChild()", "Index out of range."); + } + virtual void setChild(const int index, Node* child) + { + if ( index == 0 ){ + ftype_ = dynamic_cast(child); + } else { + throw compilerError("FuncDeclNode::setChild()", "Index out of range."); + } + } private: std::string funcname_; FuncTypeNode* ftype_; @@ -990,6 +1485,18 @@ class FuncArgsNode : public Node } visitor.postVisit(*this); } + virtual int numChildren() + { + return args_.size(); + } + virtual Node* getChild(const int index) + { + return args_[index]; + } + virtual void setChild(const int index, Node* child) + { + args_[index] = dynamic_cast(child); + } private: std::vector args_; }; @@ -1025,6 +1532,25 @@ class ReturnStatementNode : public Node expr_->accept(visitor); visitor.postVisit(*this); } + virtual int numChildren() + { + return 1; + } + virtual Node* getChild(const int index) + { + if (index == 0){ + return expr_; + } + throw compilerError("ReturnStatementNode::getChild()", "Index out of range."); + } + virtual void setChild(const int index, Node* child) + { + if (index == 0){ + expr_ = dynamic_cast(child); + } else { + throw compilerError("ReturnStatementNode::setChild()", "Index out of range."); + } + } private: ExpressionNode* expr_; }; @@ -1078,6 +1604,25 @@ class FuncStartNode : public FuncCallLikeNode funcargs_->accept(visitor); visitor.postVisit(*this); } + virtual int numChildren() + { + return 1; + } + virtual Node* getChild(const int index) + { + if (index == 0){ + return funcargs_; + } + throw compilerError("FuncStartNode::getChild()", "Index out of range."); + } + virtual void setChild(const int index, Node* child) + { + if (index == 0){ + funcargs_ = dynamic_cast(child); + } else { + throw compilerError("FuncStartNode::setChild()", "Index out of range."); + } + } private: std::string funcname_; FuncArgsNode* funcargs_; @@ -1115,6 +1660,26 @@ class FuncAssignNode : public Node SymbolTable::setCurrentFunction(SymbolTable::getCurrentFunction().parentScope()); #endif } + virtual int numChildren() + { + return 2; + } + virtual Node* getChild(const int index) + { + switch (index) { + case 0 : return funcstart_; + case 1 : return funcbody_; + default: throw compilerError("FuncAssignNode::getChild()", "Index out of range."); + } + } + virtual void setChild(const int index, Node* child) + { + switch (index) { + case 0 : funcbody_ = dynamic_cast(child); break; + case 1 : funcbody_ = child; break; + default: throw compilerError("FuncAssignNode::setChild()", "Index out of range."); + } + } private: FuncStartNode* funcstart_; Node* funcbody_; @@ -1164,7 +1729,25 @@ class StencilNode : public FuncCallLikeNode args_->accept(visitor); visitor.postVisit(*this); } - + virtual int numChildren() + { + return 1; + } + virtual Node* getChild(const int index) + { + if (index == 0){ + return args_; + } + throw compilerError("StencilNode::getChild()", "Index out of range."); + } + virtual void setChild(const int index, Node* child) + { + if( index == 0 ) { + args_ = dynamic_cast(child); + } else { + throw compilerError("StencilNode::setChild()", "Index out of range."); + } + } private: std::string varname_; FuncArgsNode* args_; @@ -1261,7 +1844,24 @@ class FuncCallNode : public FuncCallLikeNode funcargs_->accept(visitor); visitor.postVisit(*this); } - + virtual int numChildren() + { + return 1; + } + virtual Node* getChild(const int index) + { + switch (index) { + case 0 : return funcargs_; + default: throw compilerError("FuncCallNode::getChild()", "Index out of range."); + } + } + virtual void setChild(const int index, Node* child) + { + switch (index) { + case 0 : funcargs_ = dynamic_cast(child); break; + default: throw compilerError("FuncCallNode::setChild()", "Index out of range."); + } + } private: std::string funcname_; FuncArgsNode* funcargs_; @@ -1297,7 +1897,25 @@ class FuncCallStatementNode : public Node func_call_->accept(visitor); visitor.postVisit(*this); } - + virtual int numChildren() + { + return 1; + } + virtual Node* getChild(const int index) + { + if (index == 0) { + return func_call_; + } + throw compilerError("FuncCallStatementNode::getChild()", "Index out of range."); + } + virtual void setChild(const int index, Node* child) + { + if( index == 0 ) { + func_call_ = dynamic_cast(child); + } else { + throw compilerError("FuncCallStatementNode::setChild()", "Index out of range."); + } + } private: FuncCallNode* func_call_; }; @@ -1345,6 +1963,25 @@ class LoopNode : public Node loop_block_->accept(visitor); visitor.postVisit(*this); } + virtual int numChildren() + { + return 1; + } + virtual Node* getChild(const int index) + { + if (index == 0) { + return loop_block_; + } + throw compilerError("LoopNode::getChild()", "Index out of range."); + } + virtual void setChild(const int index, Node* child) + { + if( index == 0 ) { + loop_block_ = dynamic_cast(child); + } else { + throw compilerError("LoopNode::setChild()", "Index out of range."); + } + } private: std::string loop_variable_; std::string loop_set_; @@ -1377,7 +2014,7 @@ class ArrayNode : public ExpressionNode } Dimension dimension() const { - throw std::logic_error("Internal compiler error in ArrayNode::dimension(). Meaningless to ask for array dimension since array elements may have different dimension."); + throw compilerError("ArrayNode::dimension()", "Meaningless to ask for array dimension since array elements may have different dimension."); return Dimension(); } std::vector arrayDimension() const @@ -1395,6 +2032,26 @@ class ArrayNode : public ExpressionNode expr_list_->accept(visitor); visitor.postVisit(*this); } + virtual int numChildren() + { + return 1; + } + virtual Node* getChild(const int index) + { + if (index == 0){ + return expr_list_; + } + throw compilerError("ArrayNode::getChild()", "Index out of range."); + + } + virtual void setChild(const int index, Node* child) + { + if( index == 0 ) { + expr_list_ = dynamic_cast(child); + } else { + throw compilerError("ArrayNode::setChild()", "Index out of range."); + } + } private: FuncArgsNode* expr_list_; }; @@ -1426,7 +2083,7 @@ class RandomAccessNode : public ExpressionNode } EquelleType type() const { - // Either erpr_ must be an Array, or, if not, + // Either expr_ must be an Array, or, if not, // we must be a (Collection Of) Scalar, // since expr_ must be a (Collection Of) Vector. EquelleType t = expr_->type(); @@ -1453,6 +2110,25 @@ class RandomAccessNode : public ExpressionNode expr_->accept(visitor); visitor.postVisit(*this); } + virtual int numChildren() + { + return 1; + } + virtual Node* getChild(const int index) + { + if (index == 0) { + return expr_; + } + throw compilerError("RandomAccessNode::getChild()", "Index out of range."); + } + virtual void setChild(const int index, Node* child) + { + if (index == 0) { + expr_ = dynamic_cast(child); + } else { + throw compilerError("RandomAccessNode::setChild()", "Index out of range."); + } + } private: ExpressionNode* expr_; int index_; @@ -1487,6 +2163,27 @@ class StencilAssignmentNode : public Node const std::string& name() const { return lhs_->name(); } + + virtual int numChildren() + { + return 2; + } + virtual Node* getChild(const int index) + { + switch (index) { + case 0 : return lhs_; + case 1 : return rhs_; + default: throw compilerError("StencilAssignmentNode::getChild()", "Index out of range."); + } + } + virtual void setChild(const int index, Node* child) + { + switch (index) { + case 0 : lhs_ = dynamic_cast(child); break; + case 1 : rhs_ = dynamic_cast(child); break; + default: throw compilerError("StencilAssignmentNode::setChild()", "Index out of range."); + } + } private: StencilNode* lhs_; ExpressionNode* rhs_; @@ -1504,7 +2201,18 @@ class UnitNode : public Node // current unit with to obtain an SI quantity. // For example for Inch, the factor ie 0.0254. virtual double conversionFactorSI() const = 0; - + virtual int numChildren() + { + return 0; + } + virtual Node* getChild(const int index) + { + throw compilerError("UnitNode::getChild()", "UnitNode has no children."); + } + virtual void setChild(const int index, Node* child) + { + throw compilerError("UnitNode::setChild()", "UnitNode has no children."); + } }; @@ -1606,7 +2314,29 @@ class BinaryOpUnitNode : public UnitNode right_->accept(visitor); visitor.postVisit(*this); } - + + virtual int numChildren() + { + return 2; + } + virtual Node* getChild(const int index) + { + switch (index) { + case 0 : return left_; + case 1 : return right_; + default: throw compilerError("BinaryOpUnitNode::getChild()","Index out of range."); + } + return left_; + return right_; + } + virtual void setChild(const int index, Node* child) + { + switch (index) { + case 0 : left_ = dynamic_cast(child); break; + case 1 : right_ = dynamic_cast(child); break; + default: throw compilerError("BinaryOpUnitNode::setChild()","Index out of range."); + } + } private: BinaryOp op_; UnitNode* left_; @@ -1651,6 +2381,25 @@ class PowerUnitNode : public UnitNode unit_->accept(visitor); visitor.postVisit(*this); } + virtual int numChildren() + { + return 1; + } + virtual Node* getChild(const int index) + { + if ( index == 0 ) { + return unit_; + } + throw compilerError("PowerUnitNode::getChild()","Index out of range."); + } + virtual void setChild(const int index, Node* child) + { + if ( index == 0 ) { + unit_ = dynamic_cast(child); + } else { + throw compilerError("PowerUnitNode::getChild()","Index out of range."); + } + } private: UnitNode* unit_; @@ -1705,6 +2454,27 @@ class QuantityNode : public ExpressionNode return number_->number(); } + virtual int numChildren() + { + return 2; + } + virtual Node* getChild(const int index) + { + switch (index) { + case 0 : return number_; + case 1 : return unit_; + default: throw compilerError("QuantityUnitNode::getChild()","Index out of range."); + } + } + virtual void setChild(const int index, Node* child) + { + switch(index) { + case 0: number_ = dynamic_cast(child); break; + case 1: unit_ = dynamic_cast(child); break; + default: throw compilerError("QuantityUnitNode::setChild()","Index out of range."); + } + } + private: NumberNode* number_; UnitNode* unit_; diff --git a/compiler/ASTRewriter.cpp b/compiler/ASTRewriter.cpp new file mode 100644 index 0000000..48d05db --- /dev/null +++ b/compiler/ASTRewriter.cpp @@ -0,0 +1,132 @@ +#include "ASTRewriter.hpp" +#include + + +// The function assumes that the children have been assigned to a new parent. +void deleteNode(Node* node) +{ + // The node's children needs to be nullptrs before deletion. + // If they aren't the children will be deleted too. + for (int i = 0; i < node->numChildren(); i++) { + node->setChild(i,nullptr); + } + delete node; +} + + +// Helper function for replacing the current node. +// The function assumes that the replacementNode already has received currentNode's children. +void replaceNode(const int childIndex, Node* currentNode, Node* replacementNode) +{ + currentNode->getParent()->setChild(childIndex,replacementNode); + deleteNode(currentNode); +} + + +// The rewriter traverses and modifies the subtree of the root node in a pre-order fashion. +// This means that the algorithm first recurses to the bottom of the tree and modifies the +// tree from the bottom and up. +// The childIndex parameter denotes the placement of root relative to its parent. +// childIndex = 0 means it's the first child, childIndex = 1 means it's the second child. +void ASTRewriter::rewrite(Node* root, const int childIndex) +{ + + if (root == nullptr) { return; } + + if (typeid(*root).name() == typeid(SequenceNode).name()) { + auto current = dynamic_cast(root); + int i = 0; + for (auto n : current->nodes()) { + n->setParent(current); + rewrite(n, i); + ++i; + } + }else + // Pattern match for binary operations + if (typeid(*root).name() == typeid(BinaryOpNode).name()) { + + BinaryOpNode* current = dynamic_cast(root); + + current->getChild(0)->setParent(current); + current->getChild(1)->setParent(current); + rewrite(current->getChild(0), 0); + rewrite(current->getChild(1), 1); + + // Pattern matching for multiply-add + if (current->op() == Add) { + + auto* lhs = dynamic_cast(current->getChild(0)); + auto* rhs = dynamic_cast(current->getChild(1)); + + // Accounts for a*b+c and a+b*c + BinaryOpNode* mulOpNode; + int addOpNodeIndex = 0; + if (lhs != nullptr && lhs->op() == Multiply) { + mulOpNode = lhs; + // child index of rhs + addOpNodeIndex = 1; + } else + if (rhs != nullptr && rhs->op() == Multiply) { + mulOpNode = rhs; + //child index of lhs + addOpNodeIndex = 0; + } else { + return; + } + + auto replacementNode = + new MultiplyAddNode(dynamic_cast(mulOpNode->getChild(0)), + dynamic_cast(mulOpNode->getChild(1)), + dynamic_cast(current->getChild(addOpNodeIndex))); + replaceNode(childIndex, current, replacementNode); + deleteNode(mulOpNode); + } else + if (current->op() == Multiply) { + BinaryOpNode* current = dynamic_cast(root); + current->getChild(0)->setParent(current); + current->getChild(1)->setParent(current); + rewrite(current->getChild(0), 0); + rewrite(current->getChild(1), 1); + + auto* rhs = dynamic_cast(current->getChild(1)); + + if (rhs != nullptr && rhs->op() == Divide) { + + auto replacementNode = + new MultiplyDivideNode(dynamic_cast(current->getChild(0)), + dynamic_cast(rhs->getChild(0)), + dynamic_cast(rhs->getChild(1))); + replaceNode(childIndex, current, replacementNode); + deleteNode(rhs); + } else { + return; + } + } else + if (current->op() == Divide) { + BinaryOpNode* current = dynamic_cast(root); + current->getChild(0)->setParent(current); + current->getChild(1)->setParent(current); + rewrite(current->getChild(0), 0); + rewrite(current->getChild(1), 1); + + auto* lhs = dynamic_cast(current->getChild(0)); + + if (lhs != nullptr && lhs->op() == Multiply) { + + auto replacementNode = + new MultiplyDivideNode(dynamic_cast(lhs->getChild(0)), + dynamic_cast(lhs->getChild(1)), + dynamic_cast(current->getChild(1))); + replaceNode(childIndex, current, replacementNode); + deleteNode(lhs); + } + } + } else { + for ( int i = 0; i < root->numChildren(); i++ ) { + if ( root->getChild(i) != nullptr ){ + root->getChild(i)->setParent(root); + rewrite(root->getChild(i), i); + } + } + } +} \ No newline at end of file diff --git a/compiler/ASTRewriter.hpp b/compiler/ASTRewriter.hpp new file mode 100644 index 0000000..05d5931 --- /dev/null +++ b/compiler/ASTRewriter.hpp @@ -0,0 +1,13 @@ +#ifndef ASTREWRITER_HEADER_INCLUDED +#define ASTREWRITER_HEADER_INCLUDED + +#include "ASTNodes.hpp" +class Node; + +class ASTRewriter +{ +public: + void rewrite(Node* root, const int childIndex); +}; + +#endif // ASTREWRITER_HEADER_INCLUDED diff --git a/compiler/ASTVisitorInterface.hpp b/compiler/ASTVisitorInterface.hpp index 1ca36d9..1e899ae 100644 --- a/compiler/ASTVisitorInterface.hpp +++ b/compiler/ASTVisitorInterface.hpp @@ -40,6 +40,8 @@ class ArrayNode; class RandomAccessNode; class StencilAssignmentNode; class StencilNode; +class MultiplyAddNode; +class MultiplyDivideNode; class ASTVisitorInterface @@ -55,6 +57,12 @@ class ASTVisitorInterface virtual void visit(BinaryOpUnitNode& node) {} virtual void midVisit(BinaryOpUnitNode& node) {} virtual void postVisit(BinaryOpUnitNode& node) {} + virtual void visit(MultiplyAddNode& node) = 0; + virtual void midVisit(MultiplyAddNode& node) = 0; + virtual void postVisit(MultiplyAddNode& node) = 0; + virtual void visit(MultiplyDivideNode& node) = 0; + virtual void midVisit(MultiplyDivideNode& node) = 0; + virtual void postVisit(MultiplyDivideNode& node) = 0; virtual void visit(PowerUnitNode& node) {} virtual void postVisit(PowerUnitNode& node) {} virtual void visit(StringNode& node) = 0; diff --git a/compiler/CheckASTVisitor.cpp b/compiler/CheckASTVisitor.cpp index f29cecd..afdca3b 100644 --- a/compiler/CheckASTVisitor.cpp +++ b/compiler/CheckASTVisitor.cpp @@ -24,7 +24,7 @@ CheckASTVisitor::~CheckASTVisitor() bool CheckASTVisitor::isValid() { - return valid_; + return valid_; } @@ -205,6 +205,30 @@ void CheckASTVisitor::postVisit(BinaryOpNode& node) } } +void CheckASTVisitor::visit(MultiplyAddNode& node) +{ +} + +void CheckASTVisitor::midVisit(MultiplyAddNode& node) +{ +} + +void CheckASTVisitor::postVisit(MultiplyAddNode& node) +{ +} + +void CheckASTVisitor::visit(MultiplyDivideNode& node) +{ +} + +void CheckASTVisitor::midVisit(MultiplyDivideNode& node) +{ +} + +void CheckASTVisitor::postVisit(MultiplyDivideNode& node) +{ +} + void CheckASTVisitor::visit(ComparisonOpNode&) { } diff --git a/compiler/CheckASTVisitor.hpp b/compiler/CheckASTVisitor.hpp index 198d319..d825b78 100644 --- a/compiler/CheckASTVisitor.hpp +++ b/compiler/CheckASTVisitor.hpp @@ -39,6 +39,12 @@ class CheckASTVisitor : public ASTVisitorInterface void visit(BinaryOpNode& node); void midVisit(BinaryOpNode& node); void postVisit(BinaryOpNode& node); + void visit(MultiplyDivideNode& node); + void midVisit(MultiplyDivideNode& node); + void postVisit(MultiplyDivideNode& node); + void visit(MultiplyAddNode& node); + void midVisit(MultiplyAddNode& node); + void postVisit(MultiplyAddNode& node); void visit(ComparisonOpNode& node); void midVisit(ComparisonOpNode& node); void postVisit(ComparisonOpNode& node); diff --git a/compiler/CommandLineOptions.hpp b/compiler/CommandLineOptions.hpp index fe02d7c..8081049 100644 --- a/compiler/CommandLineOptions.hpp +++ b/compiler/CommandLineOptions.hpp @@ -27,7 +27,7 @@ class CommandLineOptions { ("verbose", "Verbose output") ("config,c", boost::program_options::value(), "Configuration filename (specify command line parameters in file)") ("input,i", boost::program_options::value()->required(), "Input Equelle file to compile") - ("backend", boost::program_options::value()->default_value("cpu"), "Backend of compiler to use (io, ast, ast_equelle, cpu*, cuda, mrst)") + ("backend", boost::program_options::value()->default_value("cpu"), "Backend of compiler to use (io, ast, ast_equelle, cpu*, cuda, cuda-ast-rewrite, mrst)") ("nondimensional", "Disable dimension checking") ("dump", boost::program_options::value()->default_value("none"), "Dump compiler internals (symboltable, io)"); } diff --git a/compiler/NodeInterface.hpp b/compiler/NodeInterface.hpp index c9e2d31..f760b32 100644 --- a/compiler/NodeInterface.hpp +++ b/compiler/NodeInterface.hpp @@ -15,6 +15,7 @@ class Node { public: Node() + :parent_(nullptr) {} virtual ~Node() {} @@ -30,7 +31,19 @@ class Node { loc_ = loc; } + Node* getParent() + { + return parent_; + } + void setParent(Node* parent) + { + parent_ = parent; + } + virtual int numChildren() = 0; + virtual Node* getChild(const int index) = 0; + virtual void setChild(const int index, Node* child) = 0; private: + Node* parent_; // No copying. Node(const Node&); // No assignment. diff --git a/compiler/PrintASTVisitor.cpp b/compiler/PrintASTVisitor.cpp index cd38e3a..98bc59f 100644 --- a/compiler/PrintASTVisitor.cpp +++ b/compiler/PrintASTVisitor.cpp @@ -21,8 +21,6 @@ PrintASTVisitor::~PrintASTVisitor() - - void PrintASTVisitor::visit(SequenceNode&) { if (indent_ == 0) { @@ -111,6 +109,14 @@ void PrintASTVisitor::visit(BinaryOpNode& node) ++indent_; } +void PrintASTVisitor::visit(MultiplyAddNode& node) +{ +} + +void PrintASTVisitor::visit(MultiplyDivideNode& node) +{ +} + void PrintASTVisitor::visit(ComparisonOpNode& node) { std::string op(" "); @@ -288,6 +294,22 @@ void PrintASTVisitor::postVisit(BinaryOpNode&) --indent_; } +void PrintASTVisitor::midVisit(MultiplyAddNode& node) +{ +} + +void PrintASTVisitor::postVisit(MultiplyAddNode& node) +{ +} + +void PrintASTVisitor::midVisit(MultiplyDivideNode& node) +{ +} + +void PrintASTVisitor::postVisit(MultiplyDivideNode& node) +{ +} + void PrintASTVisitor::midVisit(ComparisonOpNode&) { } diff --git a/compiler/PrintASTVisitor.hpp b/compiler/PrintASTVisitor.hpp index b1109ca..84c25a2 100644 --- a/compiler/PrintASTVisitor.hpp +++ b/compiler/PrintASTVisitor.hpp @@ -30,6 +30,12 @@ class PrintASTVisitor : public ASTVisitorInterface void visit(BinaryOpNode& node); void midVisit(BinaryOpNode& node); void postVisit(BinaryOpNode& node); + void visit(MultiplyAddNode& node); + void midVisit(MultiplyAddNode& node); + void postVisit(MultiplyAddNode& node); + void visit(MultiplyDivideNode& node); + void midVisit(MultiplyDivideNode& node); + void postVisit(MultiplyDivideNode& node); void visit(ComparisonOpNode& node); void midVisit(ComparisonOpNode& node); void postVisit(ComparisonOpNode& node); diff --git a/compiler/PrintCPUBackendASTVisitor.cpp b/compiler/PrintCPUBackendASTVisitor.cpp index 5965057..8b815ef 100644 --- a/compiler/PrintCPUBackendASTVisitor.cpp +++ b/compiler/PrintCPUBackendASTVisitor.cpp @@ -66,7 +66,7 @@ void PrintCPUBackendASTVisitor::postVisit(SequenceNode&) std::cout << "\n" "void ensureRequirements(const " << namespaceNameString() << - "::" << classNameString() << "& er)\n" + "::" << classNameString() << "& er)\n" "{\n"; if (requirement_strings_.empty()) { std::cout << " (void)er;\n"; @@ -169,6 +169,53 @@ void PrintCPUBackendASTVisitor::postVisit(BinaryOpNode&) std::cout << ')'; } +void PrintCPUBackendASTVisitor::visit(MultiplyAddNode&) +{ + if (isSuppressed()) { + return; + } + std::cout << "er.multiplyAdd("; +} + +void PrintCPUBackendASTVisitor::midVisit(MultiplyAddNode&) +{ + if (isSuppressed()) { + return; + } + std::cout << ", "; +} + +void PrintCPUBackendASTVisitor::postVisit(MultiplyAddNode&) +{ + if (isSuppressed()) { + return; + } + std::cout << ')'; +} + +void PrintCPUBackendASTVisitor::visit(MultiplyDivideNode& node) +{ + if (isSuppressed()) { + return; + } + std::cout << "er.multiplyDivide("; +} + +void PrintCPUBackendASTVisitor::midVisit(MultiplyDivideNode& node) +{ + if (isSuppressed()) { + return; + } + std::cout << ", "; +} + +void PrintCPUBackendASTVisitor::postVisit(MultiplyDivideNode& node) +{ + if (isSuppressed()) { + return; + } + std::cout << ')'; +} void PrintCPUBackendASTVisitor::visit(ComparisonOpNode&) { if (isSuppressed()) { @@ -697,7 +744,7 @@ void PrintCPUBackendASTVisitor::postVisit(RandomAccessNode& node) const char* PrintCPUBackendASTVisitor::cppStartString() const { if ( use_cartesian_ ) { - return ::impl_cppCartesianStartString(); + return ::impl_cppCartesianStartString(); } return ::impl_cppStartString(); } diff --git a/compiler/PrintCPUBackendASTVisitor.hpp b/compiler/PrintCPUBackendASTVisitor.hpp index 3b14f88..6a2cdf4 100644 --- a/compiler/PrintCPUBackendASTVisitor.hpp +++ b/compiler/PrintCPUBackendASTVisitor.hpp @@ -29,6 +29,12 @@ class PrintCPUBackendASTVisitor : public ASTVisitorInterface void visit(BinaryOpNode& node); void midVisit(BinaryOpNode& node); void postVisit(BinaryOpNode& node); + void visit(MultiplyAddNode& node); + void midVisit(MultiplyAddNode& node); + void postVisit(MultiplyAddNode& node); + void visit(MultiplyDivideNode& node); + void midVisit(MultiplyDivideNode& node); + void postVisit(MultiplyDivideNode& node); void visit(ComparisonOpNode& node); void midVisit(ComparisonOpNode& node); void postVisit(ComparisonOpNode& node); diff --git a/compiler/PrintEquelleASTVisitor.cpp b/compiler/PrintEquelleASTVisitor.cpp index 9208b80..f460790 100644 --- a/compiler/PrintEquelleASTVisitor.cpp +++ b/compiler/PrintEquelleASTVisitor.cpp @@ -119,6 +119,30 @@ void PrintEquelleASTVisitor::postVisit(BinaryOpNode&) std::cout << ')'; } +void PrintEquelleASTVisitor::visit(MultiplyAddNode& node) +{ +} + +void PrintEquelleASTVisitor::midVisit(MultiplyAddNode& node) +{ +} + +void PrintEquelleASTVisitor::postVisit(MultiplyAddNode& node) +{ +} + +void PrintEquelleASTVisitor::visit(MultiplyDivideNode& node) +{ +} + +void PrintEquelleASTVisitor::midVisit(MultiplyDivideNode& node) +{ +} + +void PrintEquelleASTVisitor::postVisit(MultiplyDivideNode& node) +{ +} + void PrintEquelleASTVisitor::visit(ComparisonOpNode&) { std::cout << '('; diff --git a/compiler/PrintEquelleASTVisitor.hpp b/compiler/PrintEquelleASTVisitor.hpp index ad96d28..bc3d3b0 100644 --- a/compiler/PrintEquelleASTVisitor.hpp +++ b/compiler/PrintEquelleASTVisitor.hpp @@ -28,6 +28,12 @@ class PrintEquelleASTVisitor : public ASTVisitorInterface void visit(BinaryOpNode& node); void midVisit(BinaryOpNode& node); void postVisit(BinaryOpNode& node); + void visit(MultiplyAddNode& node); + void midVisit(MultiplyAddNode& node); + void postVisit(MultiplyAddNode& node); + void visit(MultiplyDivideNode& node); + void midVisit(MultiplyDivideNode& node); + void postVisit(MultiplyDivideNode& node); void visit(ComparisonOpNode& node); void midVisit(ComparisonOpNode& node); void postVisit(ComparisonOpNode& node); diff --git a/compiler/PrintIOVisitor.cpp b/compiler/PrintIOVisitor.cpp index 6503403..ad41395 100644 --- a/compiler/PrintIOVisitor.cpp +++ b/compiler/PrintIOVisitor.cpp @@ -74,6 +74,8 @@ void PrintIOVisitor::visit(StringNode& node) {} void PrintIOVisitor::visit(TypeNode& node) {} void PrintIOVisitor::visit(FuncTypeNode& node) {} void PrintIOVisitor::visit(BinaryOpNode& node) {} +void PrintIOVisitor::visit(MultiplyAddNode& node) {} +void PrintIOVisitor::visit(MultiplyDivideNode& node) {} void PrintIOVisitor::visit(ComparisonOpNode& node) {} void PrintIOVisitor::visit(NormNode&) {} void PrintIOVisitor::visit(UnaryNegationNode&) {} @@ -101,6 +103,10 @@ void PrintIOVisitor::midVisit(SequenceNode&) {} void PrintIOVisitor::postVisit(SequenceNode&) {} void PrintIOVisitor::midVisit(BinaryOpNode&) {} void PrintIOVisitor::postVisit(BinaryOpNode&) {} +void PrintIOVisitor::midVisit(MultiplyAddNode& node) {} +void PrintIOVisitor::postVisit(MultiplyAddNode& node) {} +void PrintIOVisitor::midVisit(MultiplyDivideNode& node) {} +void PrintIOVisitor::postVisit(MultiplyDivideNode& node) {} void PrintIOVisitor::midVisit(ComparisonOpNode&) {} void PrintIOVisitor::postVisit(ComparisonOpNode&) {} void PrintIOVisitor::postVisit(NormNode&) {} diff --git a/compiler/PrintIOVisitor.hpp b/compiler/PrintIOVisitor.hpp index c07fdf5..bf8c49b 100644 --- a/compiler/PrintIOVisitor.hpp +++ b/compiler/PrintIOVisitor.hpp @@ -26,6 +26,12 @@ class PrintIOVisitor : public ASTVisitorInterface void visit(BinaryOpNode& node); void midVisit(BinaryOpNode& node); void postVisit(BinaryOpNode& node); + void visit(MultiplyAddNode& node); + void midVisit(MultiplyAddNode& node); + void postVisit(MultiplyAddNode& node); + void visit(MultiplyDivideNode& node); + void midVisit(MultiplyDivideNode& node); + void postVisit(MultiplyDivideNode& node); void visit(ComparisonOpNode& node); void midVisit(ComparisonOpNode& node); void postVisit(ComparisonOpNode& node); diff --git a/compiler/PrintMPIBackendASTVisitor.cpp b/compiler/PrintMPIBackendASTVisitor.cpp index e54975d..0c4a482 100644 --- a/compiler/PrintMPIBackendASTVisitor.cpp +++ b/compiler/PrintMPIBackendASTVisitor.cpp @@ -10,7 +10,7 @@ namespace "\n" "#include \n" "#include \n" -"#include \n" +"#include \n" "#include \n" "#include \n" "#include \n" diff --git a/compiler/PrintMRSTBackendASTVisitor.cpp b/compiler/PrintMRSTBackendASTVisitor.cpp index fbae56b..227f0a4 100644 --- a/compiler/PrintMRSTBackendASTVisitor.cpp +++ b/compiler/PrintMRSTBackendASTVisitor.cpp @@ -111,6 +111,30 @@ void PrintMRSTBackendASTVisitor::postVisit(BinaryOpNode&) std::cout << ')'; } +void PrintMRSTBackendASTVisitor::visit(MultiplyAddNode& node) +{ +} + +void PrintMRSTBackendASTVisitor::midVisit(MultiplyAddNode& node) +{ +} + +void PrintMRSTBackendASTVisitor::postVisit(MultiplyAddNode& node) +{ +} + +void PrintMRSTBackendASTVisitor::visit(MultiplyDivideNode& node) +{ +} + +void PrintMRSTBackendASTVisitor::midVisit(MultiplyDivideNode& node) +{ +} + +void PrintMRSTBackendASTVisitor::postVisit(MultiplyDivideNode& node) +{ +} + void PrintMRSTBackendASTVisitor::visit(ComparisonOpNode&) { std::cout << '('; diff --git a/compiler/PrintMRSTBackendASTVisitor.hpp b/compiler/PrintMRSTBackendASTVisitor.hpp index fa470a1..3ea39e4 100644 --- a/compiler/PrintMRSTBackendASTVisitor.hpp +++ b/compiler/PrintMRSTBackendASTVisitor.hpp @@ -27,6 +27,12 @@ class PrintMRSTBackendASTVisitor : public ASTVisitorInterface void visit(BinaryOpNode& node); void midVisit(BinaryOpNode& node); void postVisit(BinaryOpNode& node); + void visit(MultiplyAddNode& node); + void midVisit(MultiplyAddNode& node); + void postVisit(MultiplyAddNode& node); + void visit(MultiplyDivideNode& node); + void midVisit(MultiplyDivideNode& node); + void postVisit(MultiplyDivideNode& node); void visit(ComparisonOpNode& node); void midVisit(ComparisonOpNode& node); void postVisit(ComparisonOpNode& node); diff --git a/compiler/ec.cpp b/compiler/ec.cpp index 8f4550b..49a04af 100644 --- a/compiler/ec.cpp +++ b/compiler/ec.cpp @@ -13,6 +13,7 @@ #include "PrintIOVisitor.hpp" #include "ASTNodes.hpp" #include "CommandLineOptions.hpp" +#include "ASTRewriter.hpp" #include @@ -25,58 +26,58 @@ extern FILE * yyin; */ class YYInOwner { public: - YYInOwner(const std::string filename_) { - yyin = fopen(filename_.c_str(),"r"); + YYInOwner(const std::string filename_) { + yyin = fopen(filename_.c_str(),"r"); if (!yyin) { throw std::runtime_error("Input file not found."); } - } - ~YYInOwner() { - fclose(yyin); - yyin = NULL; - } + } + ~YYInOwner() { + fclose(yyin); + yyin = NULL; + } }; int main(int argc, char** argv) { - CommandLineOptions options; - boost::program_options::variables_map cli_vars; - boost::shared_ptr yyin_owner; + CommandLineOptions options; + boost::program_options::variables_map cli_vars; + boost::shared_ptr yyin_owner; - //Parse commandline - try { - cli_vars = options.parse(argc, argv); + //Parse commandline + try { + cli_vars = options.parse(argc, argv); - if (cli_vars.count("help")) { - std::cout << "Usage: ./eq " << std::endl; - std::cout << "The following options are supported:" << std::endl; - options.printOptions(); - return -1; - } - if (cli_vars.count("verbose")) { - options.printVars(cli_vars); - } - } - catch (const std::exception& e) { - std::cerr << "Usage: ./eq " << std::endl; - std::cerr << "The following options are supported:" << std::endl; - options.printOptions(); - std::cerr << std::endl; + if (cli_vars.count("help")) { + std::cout << "Usage: ./eq " << std::endl; + std::cout << "The following options are supported:" << std::endl; + options.printOptions(); + return -1; + } + if (cli_vars.count("verbose")) { + options.printVars(cli_vars); + } + } + catch (const std::exception& e) { + std::cerr << "Usage: ./eq " << std::endl; + std::cerr << "The following options are supported:" << std::endl; + options.printOptions(); + std::cerr << std::endl; std::cerr << "Error parsing options: "; std::cerr << e.what() << std::endl; - return -1; - } + return -1; + } - //Get input file - if (cli_vars.count("input")) { - std::string infile = cli_vars["input"].as(); - if (infile != "-") { //"-" signifies use stdin - yyin_owner.reset(new YYInOwner(infile)); - } - } + //Get input file + if (cli_vars.count("input")) { + std::string infile = cli_vars["input"].as(); + if (infile != "-") { //"-" signifies use stdin + yyin_owner.reset(new YYInOwner(infile)); + } + } - //Parse equelle program + //Parse equelle program yyparse(); // Check AST (and build symbol table) @@ -109,6 +110,12 @@ int main(int argc, char** argv) PrintCUDABackendASTVisitor v; SymbolTable::program()->accept(v); } + else if (backend == "cuda-ast-rewrite") { + ASTRewriter rewriter; + rewriter.rewrite(SymbolTable::program(),0); + PrintCUDABackendASTVisitor v; + SymbolTable::program()->accept(v); + } else if (backend == "mrst") { PrintMRSTBackendASTVisitor v; SymbolTable::program()->accept(v); @@ -129,10 +136,10 @@ int main(int argc, char** argv) //This assumes that the printing went well. if (check.isValid()) { - return 0; + return 0; } else { - return -1; + return -1; } }