Changeset c75b30a for src/Validate/Autogen.cpp
- Timestamp:
- Jan 31, 2024, 6:25:02 PM (4 months ago)
- Branches:
- master
- Children:
- 32490deb
- Parents:
- 16afb2a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Validate/Autogen.cpp
r16afb2a rc75b30a 197 197 198 198 bool shouldAutogen() const final { return true; } 199 void genAttrFuncForward(); 200 void __attribute__ ((unused)) genDualFuncs(); 199 201 private: 200 202 void genFuncBody( ast::FunctionDecl * decl ) final; 201 203 void genFieldCtors() final; 202 204 const ast::Decl * getDecl() const final { return decl; } 205 206 ast::ObjectDecl * dualDstParam() const; 207 208 ast::FunctionDecl * genPosProto() const; 209 ast::FunctionDecl * genLabelProto() const; 210 ast::FunctionDecl * genValueProto() const; 211 212 ast::FunctionDecl * genCopyEnumToDualProto() const; 213 ast::FunctionDecl * genAssignEnumToDualProto() const; 214 215 void genDualBody( ast::FunctionDecl * decl ); 203 216 }; 204 217 … … 238 251 // -------------------------------------------------------------------------- 239 252 void AutogenerateRoutines::previsit( const ast::EnumDecl * enumDecl ) { 240 // Must visit children (enum constants) to add them to the symbol table.241 253 if ( !enumDecl->body ) return; 242 243 // if ( auto enumBaseType = enumDecl->base ) {244 // if ( auto enumBaseTypeAsStructInst = dynamic_cast<const ast::StructInstType *>(enumBaseType.get()) ) {245 // const ast::StructDecl * structDecl = enumBaseTypeAsStructInst->base.get();246 // this->previsit( structDecl );247 // }248 // }249 254 250 255 ast::EnumInstType enumInst( enumDecl->name ); 251 256 enumInst.base = enumDecl; 252 257 EnumFuncGenerator gen( enumDecl, &enumInst, functionNesting ); 258 if ( enumDecl->base ) { 259 gen.genAttrFuncForward(); 260 // gen.genDualFuncs(); 261 } 253 262 gen.generateAndAppendFunctions( declsToAddAfter ); 254 263 } … … 742 751 * returns to zero. 743 752 */ 753 auto dstExpr = new ast::VariableExpr( location, dstParam ); 754 const ast::Expr * srcExpr; 755 if ( decl->base ) { 756 srcExpr = new ast::ApplicationExpr( location, 757 ast::VariableExpr::functionPointer( location, genPosProto() ), 758 { 759 new ast::VariableExpr( location, srcParam ) 760 } 761 ); 762 } else { 763 srcExpr = new ast::VariableExpr( location, srcParam ); 764 } 765 744 766 auto callExpr = new ast::ApplicationExpr( location, 745 767 ast::VariableExpr::functionPointer( location, functionDecl ), 746 768 { 747 new ast::VariableExpr( location, dstParam ),748 new ast::VariableExpr( location, srcParam ),769 dstExpr, 770 srcExpr, 749 771 } 750 772 ); 751 // auto fname = ast::getFunctionName( callExpr ); 752 // if (fname == "posE" ) { 753 // std::cerr << "Found posE autogen" << std::endl; 754 // } 773 755 774 functionDecl->stmts = new ast::CompoundStmt( location, 756 775 { new ast::ExprStmt( location, callExpr ) } … … 768 787 forwards.back().get_and_mutate() ); 769 788 addUnusedAttribute( fwd->params.front() ); 789 } 790 } 791 792 ast::FunctionDecl * EnumFuncGenerator::genPosProto() const { 793 return genProto( "posE", 794 { new ast::ObjectDecl( getLocation(), "_i", 795 new ast::EnumInstType( decl ) )}, 796 { new ast::ObjectDecl( getLocation(), "_ret", 797 new ast::BasicType{ ast::BasicType::UnsignedInt } )} ); 798 } 799 800 ast::FunctionDecl * EnumFuncGenerator::genLabelProto() const { 801 return genProto( "labelE", 802 { new ast::ObjectDecl( getLocation(), "_i", 803 new ast::EnumInstType( decl ) ) }, 804 { new ast::ObjectDecl( getLocation(), "_ret", 805 new ast::PointerType( new ast::BasicType{ ast::BasicType::Char } ) ) } ); 806 } 807 808 ast::FunctionDecl * EnumFuncGenerator::genValueProto() const { 809 return genProto( "valueE", 810 { new ast::ObjectDecl( getLocation(), "_i", new ast::EnumInstType( decl ) )}, 811 { new ast::ObjectDecl( getLocation(), "_ret", ast::deepCopy( decl->base ) ) } ); 812 } 813 814 void EnumFuncGenerator::genAttrFuncForward() { 815 if ( decl->base ) { 816 ast::FunctionDecl *(EnumFuncGenerator::*attrProtos[3])() const = { 817 &EnumFuncGenerator::genPosProto, &EnumFuncGenerator::genLabelProto, 818 &EnumFuncGenerator::genValueProto }; 819 for ( auto & generator : attrProtos ) { 820 produceForwardDecl( (this->*generator)() ); 821 } 822 } 823 } 824 825 ast::ObjectDecl * EnumFuncGenerator::dualDstParam() const { 826 auto base = decl->base; 827 assert( base ); 828 return new ast::ObjectDecl( getLocation(), "_dst", 829 new ast::ReferenceType( ast::deepCopy( base ) ) ); 830 } 831 832 // void ?{}(T & _dst, enum E _src ) 833 ast::FunctionDecl * EnumFuncGenerator::genCopyEnumToDualProto() const { 834 return genProto( "?{}", { dualDstParam(), srcParam() }, {} ); 835 } 836 837 // T ?{}(T & _dst, enum E _src ) 838 ast::FunctionDecl * EnumFuncGenerator::genAssignEnumToDualProto() const { 839 auto retval = dualDstParam(); 840 retval->name = "_ret"; 841 return genProto( "?=?", { dualDstParam(), srcParam() }, { retval }); 842 } 843 844 void EnumFuncGenerator::genDualBody( ast::FunctionDecl * functionDecl ) { 845 assert( decl->base ); 846 const CodeLocation& location = functionDecl->location; 847 auto & params = functionDecl->params; 848 849 assert( 2 == params.size() ); 850 auto dstParam = params.front().strict_as<ast::ObjectDecl>(); 851 auto srcParam = params.back().strict_as<ast::ObjectDecl>(); 852 853 auto dstExpr = new ast::VariableExpr( location, dstParam ); 854 855 auto srcExpr = new ast::ApplicationExpr( location, 856 ast::VariableExpr::functionPointer( location, genValueProto() ), 857 { 858 new ast::VariableExpr( location, srcParam ) 859 }); 860 auto callExpr = new ast::ApplicationExpr( location, 861 ast::VariableExpr::functionPointer( location, functionDecl ), 862 { dstExpr, srcExpr } ); 863 functionDecl->stmts = new ast::CompoundStmt( location, 864 { new ast::ExprStmt( location, callExpr)} ); 865 } 866 867 void EnumFuncGenerator::genDualFuncs() { 868 assert( decl->base ); 869 ast::FunctionDecl *(EnumFuncGenerator::*dualProtos[2])() const = { 870 &EnumFuncGenerator::genCopyEnumToDualProto, 871 &EnumFuncGenerator::genAssignEnumToDualProto }; 872 for ( auto & generator : dualProtos ) { 873 ast::FunctionDecl * decl = (this->*generator)(); 874 produceForwardDecl( decl ); 875 genDualBody( decl ); 876 if ( CodeGen::isAssignment( decl->name ) ) { 877 appendReturnThis( decl ); 878 } 879 produceDecl( decl ); 770 880 } 771 881 }
Note: See TracChangeset
for help on using the changeset viewer.