Changes in src/AST/Convert.cpp [514a791:19e567dd]
- File:
-
- 1 edited
-
src/AST/Convert.cpp (modified) (27 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
r514a791 r19e567dd 10 10 // Created On : Thu May 09 15::37::05 2019 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue May 21 15:30:00 201913 // Update Count : 512 // Last Modified On : Fri May 17 16:01:00 2019 13 // Update Count : 4 14 14 // 15 15 16 16 #include "Convert.hpp" 17 18 #include <unordered_map>19 17 20 18 #include "AST/Attribute.hpp" … … 44 42 class ConverterNewToOld : public ast::Visitor { 45 43 BaseSyntaxNode * node = nullptr; 46 std::unordered_map< ast::Node *, BaseSyntaxNode * > cache;47 44 48 45 template<typename T> … … 50 47 ConverterNewToOld & visitor; 51 48 52 template<typename U, enum ast::Node::ref_type R> 53 T * accept1( const ast::ptr_base<U, R> & ptr ) { 54 if ( ! ptr ) return nullptr; 49 template<typename U> 50 T * accept1( const ast::ptr<U> & ptr ) { 55 51 ptr->accept( visitor ); 56 52 T * ret = strict_dynamic_cast< T * >( visitor.node ); … … 91 87 } 92 88 93 /// get new qualifiers from old type94 Type::Qualifiers cv( const ast::Type * ty ) { return { ty->qualifiers.val }; }95 96 template<typename NewT, typename OldT>97 NewT * cached( const OldT & old ) {98 auto it = cache.find( old.get() );99 if ( it == cache.end() ) {100 // doesn't update cache, that should be handled by the accept function101 return get< NewT >().accept1( old );102 } else {103 return strict_dynamic_cast< NewT * >( it->second );104 }105 }106 107 89 public: 108 90 Declaration * decl( const ast::Decl * declNode ) { … … 111 93 112 94 private: 113 void declPostamble( Declaration * decl, const ast::Decl * node ) {114 decl->location = node->location;115 // name comes from constructor116 // linkage comes from constructor117 decl->extension = node->extension;118 decl->uniqueId = node->uniqueId;119 // storageClasses comes from constructor120 this->node = decl;121 }122 123 const ast::DeclWithType * declWithTypePostamble (124 DeclarationWithType * decl, const ast::DeclWithType * node ) {125 declPostamble( decl, node );126 decl->mangleName = node->mangleName;127 decl->scopeLevel = node->scopeLevel;128 decl->asmName = get<Expression>().accept1( node->asmName );129 // attributes comes from constructor130 decl->isDeleted = node->isDeleted;131 // fs comes from constructor132 return nullptr;133 }134 135 95 const ast::DeclWithType * visit( const ast::ObjectDecl * node ) override final { 136 auto decl = new ObjectDecl( 137 node->name, 138 Type::StorageClasses( node->storage.val ), 139 LinkageSpec::Spec( node->linkage.val ), 140 get<Expression>().accept1( node->bitfieldWidth ), 141 get<Type>().accept1( node->type ), 142 get<Initializer>().accept1( node->init ), 143 get<Attribute>().acceptL( node->attributes ), 144 Type::FuncSpecifiers( node->funcSpec.val ) 145 ); 146 return declWithTypePostamble( decl, node ); 96 (void)node; 97 return nullptr; 147 98 } 148 99 149 100 const ast::DeclWithType * visit( const ast::FunctionDecl * node ) override final { 150 auto decl = new FunctionDecl( 151 node->name, 152 Type::StorageClasses( node->storage.val ), 153 LinkageSpec::Spec( node->linkage.val ), 154 get<FunctionType>().accept1( node->type ), 155 get<CompoundStmt>().accept1( node->stmts ), 156 get<Attribute>().acceptL( node->attributes ), 157 Type::FuncSpecifiers( node->funcSpec.val ) 158 ); 159 decl->withExprs = get<Expression>().acceptL( node->withExprs ); 160 return declWithTypePostamble( decl, node ); 161 } 162 163 // NamedTypeDecl 164 const ast::Decl * namedTypePostamble( NamedTypeDecl * decl, const ast::NamedTypeDecl * node ) { 165 declPostamble( decl, node ); 166 // base comes from constructor 167 decl->parameters = get<TypeDecl>().acceptL( node->params ); 168 decl->assertions = get<DeclarationWithType>().acceptL( node->assertions ); 101 (void)node; 102 return nullptr; 103 } 104 105 const ast::Decl * visit( const ast::StructDecl * node ) override final { 106 (void)node; 107 return nullptr; 108 } 109 110 const ast::Decl * visit( const ast::UnionDecl * node ) override final { 111 (void)node; 112 return nullptr; 113 } 114 115 const ast::Decl * visit( const ast::EnumDecl * node ) override final { 116 (void)node; 117 return nullptr; 118 } 119 120 const ast::Decl * visit( const ast::TraitDecl * node ) override final { 121 (void)node; 169 122 return nullptr; 170 123 } 171 124 172 125 const ast::Decl * visit( const ast::TypeDecl * node ) override final { 173 TypeDecl::Kind kind; 174 switch (node->kind) { 175 case ast::TypeVar::Dtype: 176 kind = TypeDecl::Dtype; 177 break; 178 case ast::TypeVar::Ftype: 179 kind = TypeDecl::Ftype; 180 break; 181 case ast::TypeVar::Ttype: 182 kind = TypeDecl::Ttype; 183 break; 184 default: 185 assertf(false, "Invalid ast::TypeVar::Kind: %d\n", node->kind); 186 }; 187 auto decl = new TypeDecl( 188 node->name, 189 Type::StorageClasses( node->storage.val ), 190 get<Type>().accept1( node->base ), 191 kind, 192 node->sized, 193 get<Type>().accept1( node->init ) 194 ); 195 return namedTypePostamble( decl, node ); 126 (void)node; 127 return nullptr; 196 128 } 197 129 198 130 const ast::Decl * visit( const ast::TypedefDecl * node ) override final { 199 auto decl = new TypedefDecl( 200 node->name, 201 node->location, 202 Type::StorageClasses( node->storage.val ), 203 get<Type>().accept1( node->base ), 204 LinkageSpec::Spec( node->linkage.val ) 205 ); 206 return namedTypePostamble( decl, node ); 207 } 208 209 const ast::Decl * aggregatePostamble( AggregateDecl * decl, const ast::AggregateDecl * node ) { 210 decl->members = get<Declaration>().acceptL( node->members ); 211 decl->parameters = get<TypeDecl>().acceptL( node->params ); 212 decl->body = node->body; 213 // attributes come from constructor 214 // TODO: Need caching for: decl->parent = node->parent; 215 return nullptr; 216 } 217 218 const ast::Decl * visit( const ast::StructDecl * node ) override final { 219 auto decl = new StructDecl( 220 node->name, 221 node->kind, 222 get<Attribute>().acceptL( node->attributes ), 223 LinkageSpec::Spec( node->linkage.val ) 224 ); 225 return aggregatePostamble( decl, node ); 226 } 227 228 const ast::Decl * visit( const ast::UnionDecl * node ) override final { 229 auto decl = new UnionDecl( 230 node->name, 231 get<Attribute>().acceptL( node->attributes ), 232 LinkageSpec::Spec( node->linkage.val ) 233 ); 234 return aggregatePostamble( decl, node ); 235 } 236 237 const ast::Decl * visit( const ast::EnumDecl * node ) override final { 238 auto decl = new EnumDecl( 239 node->name, 240 get<Attribute>().acceptL( node->attributes ), 241 LinkageSpec::Spec( node->linkage.val ) 242 ); 243 return aggregatePostamble( decl, node ); 244 } 245 246 const ast::Decl * visit( const ast::TraitDecl * node ) override final { 247 auto decl = new TraitDecl( 248 node->name, 249 {}, 250 LinkageSpec::Spec( node->linkage.val ) 251 ); 252 return aggregatePostamble( decl, node ); 131 (void)node; 132 return nullptr; 253 133 } 254 134 255 135 const ast::AsmDecl * visit( const ast::AsmDecl * node ) override final { 256 auto decl = new AsmDecl( get<AsmStmt>().accept1( node->stmt ) ); 257 declPostamble( decl, node ); 136 (void)node; 258 137 return nullptr; 259 138 } 260 139 261 140 const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) override final { 262 auto decl = new StaticAssertDecl( 263 get<Expression>().accept1( node->cond ), 264 get<ConstantExpr>().accept1( node->msg ) 265 ); 266 declPostamble( decl, node ); 267 return nullptr; 268 } 269 270 const ast::Stmt * stmtPostamble( Statement * stmt, const ast::Stmt * node ) { 271 stmt->location = node->location; 272 stmt->labels = makeLabelL( stmt, node->labels ); 273 this->node = stmt; 141 (void)node; 274 142 return nullptr; 275 143 } … … 277 145 const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) override final { 278 146 auto stmt = new CompoundStmt( get<Statement>().acceptL( node->kids ) ); 279 stmtPostamble( stmt, node ); 147 stmt->location = node->location; 148 stmt->labels = makeLabelL( stmt, node->labels ); 149 this->node = stmt; 280 150 return nullptr; 281 151 } … … 283 153 const ast::Stmt * visit( const ast::ExprStmt * node ) override final { 284 154 auto stmt = new ExprStmt( get<Expression>().accept1( node->expr ) ); 285 return stmtPostamble( stmt, node ); 155 stmt->location = node->location; 156 stmt->labels = makeLabelL( stmt, node->labels ); 157 this->node = stmt; 158 return nullptr; 286 159 } 287 160 … … 295 168 makeLabelL( nullptr, node->gotoLabels ) // What are these labelling? 296 169 ); 297 return stmtPostamble( stmt, node ); 170 stmt->location = node->location; 171 stmt->labels = makeLabelL( stmt, node->labels ); 172 this->node = stmt; 173 return nullptr; 298 174 } 299 175 300 176 const ast::Stmt * visit( const ast::DirectiveStmt * node ) override final { 301 177 auto stmt = new DirectiveStmt( node->directive ); 302 return stmtPostamble( stmt, node ); 178 stmt->location = node->location; 179 stmt->labels = makeLabelL( stmt, node->labels ); 180 this->node = stmt; 181 return nullptr; 303 182 } 304 183 … … 310 189 get<Statement>().acceptL( node->inits ) 311 190 ); 312 return stmtPostamble( stmt, node ); 191 stmt->location = node->location; 192 stmt->labels = makeLabelL( stmt, node->labels ); 193 this->node = stmt; 194 return nullptr; 313 195 } 314 196 … … 318 200 get<Statement>().acceptL( node->stmts ) 319 201 ); 320 return stmtPostamble( stmt, node ); 202 stmt->location = node->location; 203 stmt->labels = makeLabelL( stmt, node->labels ); 204 this->node = stmt; 205 return nullptr; 321 206 } 322 207 … … 327 212 node->isDefault() 328 213 ); 329 return stmtPostamble( stmt, node ); 214 stmt->location = node->location; 215 stmt->labels = makeLabelL( stmt, node->labels ); 216 this->node = stmt; 217 return nullptr; 330 218 } 331 219 … … 338 226 node->isDoWhile 339 227 ); 340 return stmtPostamble( stmt, node ); 228 stmt->location = node->location; 229 stmt->labels = makeLabelL( stmt, node->labels ); 230 this->node = stmt; 231 return nullptr; 341 232 } 342 233 … … 348 239 get<Statement>().accept1( node->body ) 349 240 ); 350 return stmtPostamble( stmt, node ); 241 stmt->location = node->location; 242 stmt->labels = makeLabelL( stmt, node->labels ); 243 this->node = stmt; 244 return nullptr; 351 245 } 352 246 … … 377 271 stmt->target = makeLabel( stmt, node->target ); 378 272 } 379 return stmtPostamble( stmt, node ); 273 stmt->location = node->location; 274 stmt->labels = makeLabelL( stmt, node->labels ); 275 this->node = stmt; 276 return nullptr; 380 277 } 381 278 382 279 const ast::Stmt * visit( const ast::ReturnStmt * node ) override final { 383 280 auto stmt = new ReturnStmt( get<Expression>().accept1( node->expr ) ); 384 return stmtPostamble( stmt, node ); 281 stmt->location = node->location; 282 stmt->labels = makeLabelL( stmt, node->labels ); 283 this->node = stmt; 284 return nullptr; 385 285 } 386 286 … … 402 302 get<Expression>().accept1( node->target ) 403 303 ); 404 return stmtPostamble( stmt, node ); 304 stmt->location = node->location; 305 stmt->labels = makeLabelL( stmt, node->labels ); 306 this->node = stmt; 307 return nullptr; 405 308 } 406 309 … … 412 315 get<FinallyStmt>().accept1( node->finally ) 413 316 ); 414 return stmtPostamble( stmt, node ); 317 stmt->location = node->location; 318 stmt->labels = makeLabelL( stmt, node->labels ); 319 this->node = stmt; 320 return nullptr; 415 321 } 416 322 … … 433 339 get<Statement>().accept1( node->body ) 434 340 ); 435 return stmtPostamble( stmt, node ); 341 stmt->location = node->location; 342 stmt->labels = makeLabelL( stmt, node->labels ); 343 this->node = stmt; 344 return nullptr; 436 345 } 437 346 438 347 const ast::Stmt * visit( const ast::FinallyStmt * node ) override final { 439 348 auto stmt = new FinallyStmt( get<CompoundStmt>().accept1( node->body ) ); 440 return stmtPostamble( stmt, node ); 349 stmt->location = node->location; 350 stmt->labels = makeLabelL( stmt, node->labels ); 351 this->node = stmt; 352 return nullptr; 441 353 } 442 354 … … 446 358 for ( auto clause : node->clauses ) { 447 359 stmt->clauses.push_back({{ 448 get<Expression>().accept1( clause.target.func ),449 get<Expression>().acceptL( clause.target.arg s ),360 get<Expression>().accept1( clause.target.function ), 361 get<Expression>().acceptL( clause.target.arguments ), 450 362 }, 451 363 get<Statement>().accept1( clause.stmt ), … … 462 374 get<Expression>().accept1( node->orElse.cond ), 463 375 }; 464 return stmtPostamble( stmt, node ); 376 stmt->location = node->location; 377 stmt->labels = makeLabelL( stmt, node->labels ); 378 this->node = stmt; 379 return nullptr; 465 380 } 466 381 … … 470 385 get<Statement>().accept1( node->stmt ) 471 386 ); 472 return stmtPostamble( stmt, node ); 387 stmt->location = node->location; 388 stmt->labels = makeLabelL( stmt, node->labels ); 389 this->node = stmt; 390 return nullptr; 473 391 } 474 392 475 393 const ast::NullStmt * visit( const ast::NullStmt * node ) override final { 476 394 auto stmt = new NullStmt(); 477 stmtPostamble( stmt, node ); 395 stmt->location = node->location; 396 stmt->labels = makeLabelL( stmt, node->labels ); 397 this->node = stmt; 478 398 return nullptr; 479 399 } … … 481 401 const ast::Stmt * visit( const ast::DeclStmt * node ) override final { 482 402 auto stmt = new DeclStmt( get<Declaration>().accept1( node->decl ) ); 483 return stmtPostamble( stmt, node ); 403 stmt->location = node->location; 404 stmt->labels = makeLabelL( stmt, node->labels ); 405 this->node = stmt; 406 return nullptr; 484 407 } 485 408 … … 747 670 748 671 const ast::Type * visit( const ast::VoidType * node ) override final { 749 this->node = new VoidType{ cv( node ) };672 (void)node; 750 673 return nullptr; 751 674 } 752 675 753 676 const ast::Type * visit( const ast::BasicType * node ) override final { 754 this->node = new BasicType{ cv( node ), (BasicType::Kind)(unsigned)node->kind };677 (void)node; 755 678 return nullptr; 756 679 } 757 680 758 681 const ast::Type * visit( const ast::PointerType * node ) override final { 759 this->node = new PointerType{ 760 cv( node ), 761 get<Type>().accept1( node->base ), 762 get<Expression>().accept1( node->dimension ), 763 node->isVarLen, 764 node->isStatic 765 }; 682 (void)node; 766 683 return nullptr; 767 684 } 768 685 769 686 const ast::Type * visit( const ast::ArrayType * node ) override final { 770 this->node = new ArrayType{ 771 cv( node ), 772 get<Type>().accept1( node->base ), 773 get<Expression>().accept1( node->dimension ), 774 node->isVarLen, 775 node->isStatic 776 }; 687 (void)node; 777 688 return nullptr; 778 689 } 779 690 780 691 const ast::Type * visit( const ast::ReferenceType * node ) override final { 781 this->node = new ReferenceType{ 782 cv( node ), 783 get<Type>().accept1( node->base ) 784 }; 692 (void)node; 785 693 return nullptr; 786 694 } 787 695 788 696 const ast::Type * visit( const ast::QualifiedType * node ) override final { 789 this->node = new QualifiedType{ 790 cv( node ), 791 get<Type>().accept1( node->parent ), 792 get<Type>().accept1( node->child ) 793 }; 697 (void)node; 794 698 return nullptr; 795 699 } 796 700 797 701 const ast::Type * visit( const ast::FunctionType * node ) override final { 798 auto ty = new FunctionType { cv( node ), node->isVarArgs }; 799 ty->returnVals = get<DeclarationWithType>().acceptL( node->returns ); 800 ty->parameters = get<DeclarationWithType>().acceptL( node->params ); 801 ty->forall = get<TypeDecl>().acceptL( node->forall ); 802 this->node = ty; 702 (void)node; 803 703 return nullptr; 804 704 } … … 908 808 } 909 809 private: 910 /// conversion output911 810 ast::Node * node; 912 /// cache of nodes that might be referenced by readonly<> for de-duplication913 std::unordered_map< BaseSyntaxNode *, ast::Node * > cache;914 811 915 812 // Local Utilities: … … 917 814 template<typename NewT, typename OldT> 918 815 NewT * getAccept1( OldT old ) { 919 if ( ! old ) return nullptr;920 816 old->accept(*this); 921 817 return strict_dynamic_cast< NewT * >( node ); … … 958 854 # define GET_LABELS_V(labels) \ 959 855 to<std::vector>::from( make_labels( std::move( labels ) ) ) 960 961 static ast::CV::Qualifiers cv( Type * ty ) { return { ty->get_qualifiers().val }; }962 963 template<typename NewT, typename OldT>964 NewT * cached( OldT * old ) {965 auto it = cache.find( old );966 // doesn't update cache, that should be handled by the accept function967 ast::Node * nw = it == cache.end() ? getAccept1< NewT >( old ) : it->second;968 return strict_dynamic_cast< NewT * >( nw );969 }970 856 971 857 // Now all the visit functions: … … 1374 1260 } 1375 1261 1376 void convertInferUnion(ast::Expr::InferUnion &newInferred, 1262 void convertInferUnion(ast::Expr::InferUnion &newInferred, 1377 1263 const std::map<UniqueId,ParamEntry> &oldInferParams, 1378 1264 const std::vector<UniqueId> &oldResnSlots) { … … 1581 1467 } 1582 1468 1583 virtual void visit( VoidType * old ) override final { 1584 this->node = new ast::VoidType{ cv( old ) }; 1585 } 1586 1587 virtual void visit( BasicType * old ) override final { 1588 this->node = new ast::BasicType{ (ast::BasicType::Kind)(unsigned)old->kind, cv( old ) }; 1589 } 1590 1591 virtual void visit( PointerType * old ) override final { 1592 this->node = new ast::PointerType{ 1593 GET_ACCEPT_1( base, Type ), 1594 GET_ACCEPT_1( dimension, Expr ), 1595 (ast::LengthFlag)old->isVarLen, 1596 (ast::DimensionFlag)old->isStatic, 1597 cv( old ) 1598 }; 1599 } 1600 1601 virtual void visit( ArrayType * old ) override final { 1602 this->node = new ast::ArrayType{ 1603 GET_ACCEPT_1( base, Type ), 1604 GET_ACCEPT_1( dimension, Expr ), 1605 (ast::LengthFlag)old->isVarLen, 1606 (ast::DimensionFlag)old->isStatic, 1607 cv( old ) 1608 }; 1609 } 1610 1611 virtual void visit( ReferenceType * old ) override final { 1612 this->node = new ast::ReferenceType{ 1613 GET_ACCEPT_1( base, Type ), 1614 cv( old ) 1615 }; 1616 } 1617 1618 virtual void visit( QualifiedType * old ) override final { 1619 this->node = new ast::QualifiedType{ 1620 GET_ACCEPT_1( parent, Type ), 1621 GET_ACCEPT_1( child, Type ), 1622 cv( old ) 1623 }; 1624 } 1625 1626 virtual void visit( FunctionType * old ) override final { 1627 auto ty = new ast::FunctionType { 1628 (ast::ArgumentFlag)old->isVarArgs, 1629 cv( old ) 1630 }; 1631 ty->returns = GET_ACCEPT_V( returnVals, DeclWithType ); 1632 ty->params = GET_ACCEPT_V( parameters, DeclWithType ); 1633 ty->forall = GET_ACCEPT_V( forall, TypeDecl ); 1634 this->node = ty; 1635 } 1636 1637 void postvisit( ReferenceToType * old, ast::ReferenceToType * ty ) { 1638 ty->forall = GET_ACCEPT_V( forall, TypeDecl ); 1639 ty->params = GET_ACCEPT_V( parameters, Expr ); 1640 ty->hoistType = old->hoistType; 1641 } 1642 1643 virtual void visit( StructInstType * old ) override final { 1644 auto ty = new ast::StructInstType{ 1645 cached< ast::StructDecl >( old->baseStruct ), 1646 cv( old ), 1647 GET_ACCEPT_V( attributes, Attribute ) 1648 }; 1649 postvisit( old, ty ); 1650 this->node = ty; 1651 } 1652 1653 virtual void visit( UnionInstType * old ) override final { 1654 auto ty = new ast::UnionInstType{ 1655 cached< ast::UnionDecl >( old->baseUnion ), 1656 cv( old ), 1657 GET_ACCEPT_V( attributes, Attribute ) 1658 }; 1659 postvisit( old, ty ); 1660 this->node = ty; 1661 } 1662 1663 virtual void visit( EnumInstType * old ) override final { 1664 auto ty = new ast::EnumInstType{ 1665 cached< ast::EnumDecl >( old->baseEnum ), 1666 cv( old ), 1667 GET_ACCEPT_V( attributes, Attribute ) 1668 }; 1669 postvisit( old, ty ); 1670 this->node = ty; 1671 } 1672 1673 virtual void visit( TraitInstType * old ) override final { 1674 auto ty = new ast::TraitInstType{ 1675 cached< ast::TraitDecl >( old->baseTrait ), 1676 cv( old ), 1677 GET_ACCEPT_V( attributes, Attribute ) 1678 }; 1679 postvisit( old, ty ); 1680 this->node = ty; 1681 } 1682 1683 virtual void visit( TypeInstType * old ) override final { 1684 ast::TypeInstType * ty; 1685 if ( old->baseType ) { 1686 ty = new ast::TypeInstType{ 1687 old->name, 1688 cached< ast::TypeDecl >( old->baseType ), 1689 cv( old ), 1690 GET_ACCEPT_V( attributes, Attribute ) 1691 }; 1692 } else { 1693 ty = new ast::TypeInstType{ 1694 old->name, 1695 old->isFtype ? ast::TypeVar::Ftype : ast::TypeVar::Dtype, 1696 cv( old ), 1697 GET_ACCEPT_V( attributes, Attribute ) 1698 }; 1699 } 1700 postvisit( old, ty ); 1701 this->node = ty; 1469 virtual void visit( VoidType * ) override final { 1470 1471 } 1472 1473 virtual void visit( BasicType * ) override final { 1474 1475 } 1476 1477 virtual void visit( PointerType * ) override final { 1478 1479 } 1480 1481 virtual void visit( ArrayType * ) override final { 1482 1483 } 1484 1485 virtual void visit( ReferenceType * ) override final { 1486 1487 } 1488 1489 virtual void visit( QualifiedType * ) override final { 1490 1491 } 1492 1493 virtual void visit( FunctionType * ) override final { 1494 1495 } 1496 1497 virtual void visit( StructInstType * ) override final { 1498 1499 } 1500 1501 virtual void visit( UnionInstType * ) override final { 1502 1503 } 1504 1505 virtual void visit( EnumInstType * ) override final { 1506 1507 } 1508 1509 virtual void visit( TraitInstType * ) override final { 1510 1511 } 1512 1513 virtual void visit( TypeInstType * ) override final { 1514 1702 1515 } 1703 1516
Note:
See TracChangeset
for help on using the changeset viewer.