Changeset 28f8f15
- Timestamp:
- Apr 27, 2023, 3:13:24 PM (5 months ago)
- Branches:
- ADT
- Children:
- 561354f
- Parents:
- b110bcc
- Location:
- src
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
rb110bcc r28f8f15 321 321 get<Type>().accept1(node->base) 322 322 ); 323 decl->data_constructors = get<StructDecl>().acceptL( node->data_constructors ); 324 decl->data_union = get<UnionDecl>().accept1( node->data_union ); 325 decl->tags = get<EnumDecl>().accept1( node->tag ); 326 decl->tag_union = get<StructDecl>().accept1( node->tag_union ); 323 327 return aggregatePostamble( decl, node ); 324 328 } -
src/AST/Decl.cpp
rb110bcc r28f8f15 132 132 133 133 // These must harmonize with the corresponding AggregateDecl::Aggregate enumerations. 134 static const char * aggregateNames[] = { "struct", "union", "enum", "exception", "trait", "generator", "coroutine", "monitor", "thread", "NoAggregateName" };134 static const char * aggregateNames[] = { "struct", "union", "enum", "exception", "trait", "generator", "coroutine", "monitor", "thread", "NoAggregateName", "data" }; 135 135 136 136 const char * AggregateDecl::aggrString( AggregateDecl::Aggregate aggr ) { -
src/AST/Decl.hpp
rb110bcc r28f8f15 248 248 class AggregateDecl : public Decl { 249 249 public: 250 enum Aggregate { Struct, Union, Enum, Exception, Trait, Generator, Coroutine, Monitor, Thread, NoAggregate };250 enum Aggregate { Struct, Union, Enum, Exception, Trait, Generator, Coroutine, Monitor, Thread, NoAggregate, ADT }; 251 251 static const char * aggrString( Aggregate aggr ); 252 252 … … 286 286 bool is_monitor () const { return kind == Monitor ; } 287 287 bool is_thread () const { return kind == Thread ; } 288 bool is_adt () const { return kind == ADT ; } 288 289 289 290 const Decl * accept( Visitor & v ) const override { return v.visit( this ); } … … 320 321 enum class EnumHiding { Visible, Hide } hide; 321 322 323 std::vector<ptr<StructDecl>> data_constructors; 324 bool isData = false; 325 ptr<UnionDecl> data_union; 326 ptr<EnumDecl> tag; 327 ptr<StructDecl> tag_union; 328 322 329 EnumDecl( const CodeLocation& loc, const std::string& name, bool isTyped = false, 323 330 std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall, 324 Type const * base = nullptr, EnumHiding hide = EnumHiding:: Hide,331 Type const * base = nullptr, EnumHiding hide = EnumHiding::Visible, 325 332 std::unordered_map< std::string, long long > enumValues = std::unordered_map< std::string, long long >() ) 326 333 : AggregateDecl( loc, name, std::move(attrs), linkage ), isTyped(isTyped), base(base), hide(hide), enumValues(enumValues) {} -
src/AST/Pass.impl.hpp
rb110bcc r28f8f15 693 693 maybe_accept( node, &EnumDecl::members ); 694 694 maybe_accept( node, &EnumDecl::attributes ); 695 maybe_accept( node, &EnumDecl::data_constructors ); 696 maybe_accept( node, &EnumDecl::data_union ); 697 maybe_accept( node, &EnumDecl::tag ); 698 maybe_accept( node, &EnumDecl::tag_union ); 695 699 } else { 696 700 maybe_accept( node, &EnumDecl::base ); … … 698 702 maybe_accept( node, &EnumDecl::members ); 699 703 maybe_accept( node, &EnumDecl::attributes ); 704 maybe_accept( node, &EnumDecl::data_constructors ); 705 maybe_accept( node, &EnumDecl::data_union ); 706 maybe_accept( node, &EnumDecl::tag ); 707 maybe_accept( node, &EnumDecl::tag_union ); 700 708 } 701 709 } -
src/CodeGen/CodeGenerator.cc
rb110bcc r28f8f15 295 295 } 296 296 297 void CodeGenerator::handleData( EnumDecl * dataDecl ) { 298 output << " /** data type */" << endl; 299 for ( StructDecl * decl : dataDecl->data_constructors ) { 300 postvisit(decl); 301 output << ";" << endl; 302 } 303 postvisit( dataDecl->data_union ); 304 output << ";" << endl; 305 postvisit( dataDecl->tags ); 306 output << ";" << endl; 307 postvisit( dataDecl->tag_union ); 308 output << ";" << endl; 309 } 310 297 311 void CodeGenerator::postvisit( EnumDecl * enumDecl ) { 298 extension( enumDecl ); 312 if ( enumDecl->data_constructors.size() > 0 ) return handleData( enumDecl ); 313 extension( enumDecl ); 299 314 std::list< Declaration* > &memb = enumDecl->get_members(); 300 315 if (enumDecl->base && ! memb.empty()) { -
src/CodeGen/CodeGenerator.h
rb110bcc r28f8f15 165 165 void handleTypedef( NamedTypeDecl *namedType ); 166 166 std::string mangleName( DeclarationWithType * decl ); 167 168 void handleData( EnumDecl * EnumDecl ); 167 169 }; // CodeGenerator 168 170 -
src/Common/PassVisitor.impl.h
rb110bcc r28f8f15 754 754 755 755 // unlike structs, traits, and unions, enums inject their members into the global scope 756 // if ( node->base ) maybeAccept_impl( node->base, *this ); // Need this? Maybe not? 756 maybeAccept_impl( node->data_constructors, *this ); 757 maybeAccept_impl( node->data_union, *this ); 758 maybeAccept_impl( node->tags, *this ); 757 759 maybeAccept_impl( node->parameters, *this ); 758 760 maybeAccept_impl( node->members , *this ); -
src/Parser/DeclarationNode.cc
rb110bcc r28f8f15 279 279 } // DeclarationNode::newEnum 280 280 281 DeclarationNode * DeclarationNode::newADT( const string * name, DeclarationNode * constructors ) { 282 DeclarationNode * newnode = newEnum( name, nullptr, true, false ); 283 newnode->type->enumeration.isData = true; 284 newnode->type->enumeration.data_constructors = constructors; 285 return newnode; 286 } 287 288 281 289 DeclarationNode * DeclarationNode::newName( const string * name ) { 282 290 DeclarationNode * newnode = new DeclarationNode; … … 305 313 } // if 306 314 } // DeclarationNode::newEnumValueGeneric 315 316 DeclarationNode * DeclarationNode::newDataConstructor( const string * name ) { 317 DeclarationNode * newnode = newName(name); 318 return newnode; 319 } 307 320 308 321 DeclarationNode * DeclarationNode::newEnumInLine( const string name ) { … … 1083 1096 } 1084 1097 return nullptr; 1098 } 1099 1100 void buildDataConstructors( DeclarationNode * firstNode, std::vector<ast::ptr<ast::StructDecl>> & outputList ) { 1101 std::back_insert_iterator<std::vector<ast::ptr<ast::StructDecl>>> out( outputList ); 1102 for ( const DeclarationNode * cur = firstNode; cur; cur = strict_next( cur ) ) { 1103 // td->kind == TypeData::Symbolic 1104 assert( cur->type->kind == TypeData::Symbolic ); 1105 const std::string * name = cur->name; 1106 auto ctor = new ast::StructDecl( cur->location, 1107 std::string(*name), 1108 ast::AggregateDecl::Aggregate::Struct 1109 ); 1110 ctor->set_body(true); 1111 TypeData * td = cur->type; 1112 TypeData::Symbolic_t st = td->symbolic; 1113 DeclarationNode * params = st.params; 1114 1115 if ( params ) { 1116 buildList( params, ctor->members ); 1117 } 1118 1119 for ( std::size_t i = 0; i < ctor->members.size(); ++i ) { 1120 assert(ctor->members[i]->name == ""); 1121 ast::Decl * member = ctor->members[i].get_and_mutate(); 1122 member->name = "field_" + std::to_string(i); 1123 } 1124 *out++ = ctor; 1125 } 1126 } 1127 1128 ast::UnionDecl * buildDataUnion( ast::EnumDecl * data, const std::vector<ast::ptr<ast::StructDecl>> & typeList ) { 1129 ast::UnionDecl * out = new ast::UnionDecl( data->location, "temp_data_union" ); 1130 // size_t index = 0; 1131 if ( typeList.size() > 0 ) out->set_body( true ); 1132 size_t i = 0; 1133 for (const ast::ptr<ast::StructDecl> structDecl : typeList ) { 1134 ast::StructInstType * inst = new ast::StructInstType(structDecl); 1135 ast::ObjectDecl * instObj = new ast::ObjectDecl( 1136 structDecl->location, 1137 "option_" + std::to_string(i), 1138 inst 1139 ); 1140 i++; 1141 out->members.push_back( instObj ); 1142 1143 } 1144 return out; 1145 } 1146 1147 ast::EnumDecl * buildTag( ast::EnumDecl * data, const std::vector<ast::ptr<ast::StructDecl>> & typeList ) { 1148 ast::EnumDecl * out = new ast::EnumDecl( data->location, "temp_data_tag" ); 1149 if ( typeList.size() > 0 ) out->set_body( true ); 1150 for ( const ast::ptr<ast::StructDecl> structDecl : typeList ) { 1151 ast::EnumInstType * inst = new ast::EnumInstType( out ); 1152 assert( inst->base != nullptr ); 1153 ast::ObjectDecl * instObj = new ast::ObjectDecl( 1154 structDecl->location, 1155 structDecl->name, 1156 inst 1157 ); 1158 out->members.push_back( instObj ); 1159 } 1160 return out; 1161 } 1162 1163 ast::StructDecl * buildTaggedUnions( const ast::EnumDecl * data, const ast::EnumDecl * tags, const ast::UnionDecl * data_union ) { 1164 assert( tags->members.size() == data_union->members.size() ); 1165 ast::StructDecl * out = new ast::StructDecl( data->location, data->name ); 1166 out->kind = ast::AggregateDecl::ADT; 1167 1168 out->set_body( true ); 1169 1170 ast::EnumInstType * tag = new ast::EnumInstType( tags ); 1171 ast::ObjectDecl * tag_obj = new ast::ObjectDecl( 1172 data->location, 1173 "tag", 1174 tag 1175 ); 1176 ast::UnionInstType * value = new ast::UnionInstType( data_union ); 1177 ast::ObjectDecl * value_obj = new ast::ObjectDecl( 1178 data->location, 1179 "value", 1180 value 1181 ); 1182 1183 out->members.push_back( value_obj ); 1184 out->members.push_back( tag_obj ); 1185 return out; 1085 1186 } 1086 1187 -
src/Parser/DeclarationNode.h
rb110bcc r28f8f15 76 76 static DeclarationNode * newStaticAssert( ExpressionNode * condition, ast::Expr * message ); 77 77 78 // Experimental algebric data type 79 static DeclarationNode * newADT( const std::string * name, DeclarationNode * constructors ); 80 static DeclarationNode * newDataConstructor( const std::string * name ); 81 // static DeclarationNode * newDataConstructor( const std::string * name, DeclarationNode * typeSpecifiers ); 82 78 83 DeclarationNode(); 79 84 ~DeclarationNode(); … … 156 161 ExpressionNode * bitfieldWidth = nullptr; 157 162 std::unique_ptr<ExpressionNode> enumeratorValue; 163 158 164 bool hasEllipsis = false; 159 165 ast::Linkage::Spec linkage; … … 210 216 void buildList( DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ); 211 217 void buildTypeList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::Type>> & outputList ); 218 void buildDataConstructors( DeclarationNode * firstNode, std::vector<ast::ptr<ast::StructDecl>> & outputList ); 219 ast::UnionDecl * buildDataUnion( ast::EnumDecl * data, const std::vector<ast::ptr<ast::StructDecl>> & typeList ); 220 ast::EnumDecl * buildTag( ast::EnumDecl * data, const std::vector<ast::ptr<ast::StructDecl>> & typeList ); 221 ast::StructDecl * buildTaggedUnions( const ast::EnumDecl * data, const ast::EnumDecl * tags, const ast::UnionDecl * data_union ); 212 222 213 223 template<typename AstType, typename NodeType, -
src/Parser/TypeData.cc
rb110bcc r28f8f15 1260 1260 ); 1261 1261 buildList( td->enumeration.constants, ret->members ); 1262 if ( td->enumeration.data_constructors != nullptr ) { 1263 buildDataConstructors( td->enumeration.data_constructors, ret->data_constructors ); 1264 ret->data_union = buildDataUnion( ret, ret->data_constructors ); 1265 ret->tag = buildTag( ret, ret->data_constructors ); 1266 ret->tag_union = buildTaggedUnions( ret, ret->tag.get(), ret->data_union.get() ); 1267 } 1268 1269 if ( ret->data_constructors.size() > 0 ) ret->isData = true; 1262 1270 auto members = ret->members.begin(); 1263 1271 ret->hide = td->enumeration.hiding == EnumHiding::Hide ? ast::EnumDecl::EnumHiding::Hide : ast::EnumDecl::EnumHiding::Visible; -
src/Parser/TypeData.h
rb110bcc r28f8f15 25 25 struct TypeData { 26 26 enum Kind { Basic, Pointer, Reference, Array, Function, Aggregate, AggregateInst, Enum, EnumConstant, Symbolic, 27 SymbolicInst, Tuple, Basetypeof, Typeof, Vtable, Builtin, GlobalScope, Qualified, Unknown };27 SymbolicInst, Tuple, Basetypeof, Typeof, Vtable, Builtin, GlobalScope, Qualified, ADT, Ctor, Unknown }; 28 28 29 29 struct Aggregate_t { … … 58 58 bool typed; 59 59 EnumHiding hiding; 60 bool isData = false; 61 62 DeclarationNode * data_constructors = nullptr; 63 }; 64 65 struct ADT_t { 66 const std::string * name = nullptr; 67 DeclarationNode * constructors; 68 }; 69 70 struct Constructor_t { 71 const std::string * name; 72 DeclarationNode * type; // types? 60 73 }; 61 74 … … 98 111 Array_t array; 99 112 Enumeration_t enumeration; 113 ADT_t adt; 114 Constructor_t data_constructor; 115 100 116 Function_t function; 101 117 Symbolic_t symbolic; -
src/Parser/lex.ll
rb110bcc r28f8f15 353 353 with { KEYWORD_RETURN(WITH); } // CFA 354 354 zero_t { NUMERIC_RETURN(ZERO_T); } // CFA 355 _DATA_ { KEYWORD_RETURN(DATA); } // Experimental 355 356 356 357 /* identifier */ -
src/Parser/parser.yy
rb110bcc r28f8f15 339 339 %token SIZEOF TYPEOF VA_LIST VA_ARG AUTO_TYPE // GCC 340 340 %token OFFSETOF BASETYPEOF TYPEID // CFA 341 %token ENUM STRUCT UNION 341 %token ENUM STRUCT UNION DATA 342 342 %token EXCEPTION // CFA 343 343 %token GENERATOR COROUTINE MONITOR THREAD // CFA … … 453 453 %type<decl> enumerator_list enum_type enum_type_nobody 454 454 %type<init> enumerator_value_opt 455 456 %type<decl> value_list 457 %type<decl> data_constructor type_specifier_list 455 458 456 459 %type<decl> external_definition external_definition_list external_definition_list_opt … … 2441 2444 } 2442 2445 | enum_type 2446 /* | algebric_data_type */ 2443 2447 ; 2444 2448 … … 2694 2698 } 2695 2699 | enum_type_nobody 2696 ; 2700 | DATA identifier 2701 { typedefTable.makeTypedef( *$2 ); } 2702 '{' value_list '}' 2703 { 2704 $$ = DeclarationNode::newADT( $2, $5 ); 2705 } 2706 ; 2707 2708 value_list: 2709 data_constructor 2710 { 2711 $$ = $1; 2712 } 2713 /* | identifier_or_type_name '(' type_specifier ')' 2714 { 2715 $$ = DeclarationNode::newEnumValueGeneric( $1, nullptr ); 2716 } */ 2717 /* | data_constructor '|' value_list */ 2718 | value_list '|' data_constructor 2719 { 2720 { $$ = $1->appendList( $3 ); } 2721 } 2722 ; 2723 2724 data_constructor: 2725 identifier_or_type_name 2726 { 2727 typedefTable.makeTypedef( *$1 ); 2728 $$ = DeclarationNode::newTypeDecl( $1, nullptr );; 2729 } 2730 | identifier_or_type_name '(' type_specifier_list ')' 2731 { 2732 typedefTable.makeTypedef( *$1 ); 2733 $$ = DeclarationNode::newTypeDecl( $1, $3 ); 2734 } 2735 2736 type_specifier_list: 2737 type_specifier 2738 /* | type_specifier ',' type_specifier_list */ 2739 | type_specifier_list ',' type_specifier 2740 { 2741 $$ = $1->appendList($3); 2742 } 2743 ; 2744 2697 2745 2698 2746 hide_opt: -
src/SynTree/AggregateDecl.cc
rb110bcc r28f8f15 29 29 30 30 // These must harmonize with the corresponding AggregateDecl::Aggregate enumerations. 31 static const char * aggregateNames[] = { "struct", "union", "enum", "exception", "trait", "generator", "coroutine", "monitor", "thread", "NoAggregateName" };31 static const char * aggregateNames[] = { "struct", "union", "enum", "exception", "trait", "generator", "coroutine", "monitor", "thread", "NoAggregateName", "data" }; 32 32 33 33 const char * AggregateDecl::aggrString( AggregateDecl::Aggregate aggr ) { -
src/SynTree/Declaration.h
rb110bcc r28f8f15 268 268 typedef Declaration Parent; 269 269 public: 270 enum Aggregate { Struct, Union, Enum, Exception, Trait, Generator, Coroutine, Monitor, Thread, NoAggregate };270 enum Aggregate { Struct, Union, Enum, Exception, Trait, Generator, Coroutine, Monitor, Thread, NoAggregate, ADT }; 271 271 static const char * aggrString( Aggregate aggr ); 272 272 … … 341 341 Type * base; 342 342 enum EnumHiding { Visible, Hide } hide; 343 344 std::list<StructDecl*> data_constructors; 345 UnionDecl * data_union; 346 EnumDecl * tags; 347 StructDecl * tag_union; 343 348 344 349 EnumDecl( const std::string & name, -
src/Validate/Autogen.cpp
rb110bcc r28f8f15 125 125 // Built-ins do not use autogeneration. 126 126 bool shouldAutogen() const final { return !decl->linkage.is_builtin && !structHasFlexibleArray(decl); } 127 void genADTFuncs(); 128 void getADTFuncBody(const ast::ObjectDecl * lhs, ast::FunctionDecl * func); 127 129 private: 128 130 void genFuncBody( ast::FunctionDecl * decl ) final; … … 193 195 } 194 196 195 bool shouldAutogen() const final { return true; }197 bool shouldAutogen() const final { return !(decl->isData); } 196 198 private: 197 199 void genFuncBody( ast::FunctionDecl * decl ) final; … … 238 240 if ( !enumDecl->body ) return; 239 241 240 // if ( auto enumBaseType = enumDecl->base ) {241 // if ( auto enumBaseTypeAsStructInst = dynamic_cast<const ast::StructInstType *>(enumBaseType.get()) ) {242 // const ast::StructDecl * structDecl = enumBaseTypeAsStructInst->base.get();243 // this->previsit( structDecl );244 // }245 // }246 247 242 ast::EnumInstType enumInst( enumDecl->name ); 248 243 enumInst.base = enumDecl; … … 264 259 } 265 260 StructFuncGenerator gen( structDecl, &structInst, functionNesting ); 261 262 gen.genADTFuncs(); 266 263 gen.generateAndAppendFunctions( declsToAddAfter ); 267 264 } … … 475 472 } 476 473 produceDecl( decl ); 474 } 475 } 476 477 void StructFuncGenerator::getADTFuncBody( 478 const ast::ObjectDecl * lhs, 479 ast::FunctionDecl * func 480 ) { 481 const CodeLocation& location = func->location; 482 assert( decl->members.size() == 2 ); 483 auto first = (decl->members[0]).as<ast::ObjectDecl>(); 484 assert(first != nullptr); 485 auto firstType = first->type; 486 auto unionInstDecl = firstType.as<ast::UnionInstType>(); 487 assert(unionInstDecl != nullptr); 488 489 auto unionDecl = unionInstDecl->base; 490 491 const ast::ObjectDecl * dstParam = 492 func->params.front().strict_as<ast::ObjectDecl>(); 493 const ast::ObjectDecl * srcParam = 494 func->params.back().strict_as<ast::ObjectDecl>(); 495 496 ast::Expr * srcSelect = new ast::VariableExpr( location, srcParam ); 497 498 ast::CompoundStmt * stmts = new ast::CompoundStmt( location ); 499 500 InitTweak::InitExpander_new srcParamTweak( srcSelect ); 501 ast::Expr * dstSelect = 502 new ast::MemberExpr( 503 location, 504 lhs, 505 new ast::MemberExpr( 506 location, 507 first, 508 new ast::CastExpr( 509 location, 510 new ast::VariableExpr( location, dstParam ), 511 dstParam->type.strict_as<ast::ReferenceType>()->base 512 ) 513 ) 514 ); 515 auto stmt = genImplicitCall( 516 srcParamTweak, dstSelect, location, func->name, 517 first, SymTab::LoopForward 518 ); 519 stmts->push_back( stmt ); 520 func->stmts = stmts; 521 } 522 523 void StructFuncGenerator::genADTFuncs() { 524 if ( decl->kind != ast::AggregateDecl::ADT ) return; 525 assert( decl->members.size() == 2 ); 526 auto first = (decl->members[0]).as<ast::ObjectDecl>(); 527 assert(first != nullptr); 528 auto firstType = first->type; 529 auto unionInstDecl = firstType.as<ast::UnionInstType>(); 530 assert(unionInstDecl != nullptr); 531 auto unionDecl = unionInstDecl->base; 532 533 // for (auto mem: unionDecl->members) { 534 for ( std::size_t i = 0; i < unionDecl->members.size(); ++i ) { 535 auto mem = unionDecl->members[i]; 536 const ast::ObjectDecl * mem_as_obj = mem.as<ast::ObjectDecl>(); 537 assert( mem_as_obj ); 538 auto mem_type = mem_as_obj->type.as<ast::StructInstType>(); 539 assert( mem_type ); 540 auto location = getLocation(); 541 ast::FunctionDecl * func = new ast::FunctionDecl( 542 getLocation(), 543 "?{}", // name 544 {}, //forall 545 { dstParam(), new ast::ObjectDecl( getLocation(), "_src", ast::deepCopy( mem_type ) ) }, // params 546 {}, // returns 547 {}, // statements 548 // Use static storage if we are at the top level. 549 (0 < functionNesting) ? ast::Storage::Classes() : ast::Storage::Static, 550 proto_linkage, 551 std::vector<ast::ptr<ast::Attribute>>(), 552 // Auto-generated routines are inline to avoid conflicts. 553 ast::Function::Specs( ast::Function::Inline ) 554 ); 555 getADTFuncBody(mem_as_obj, func); 556 func->fixUniqueId(); 557 produceForwardDecl(func); 558 if ( CodeGen::isAssignment( func->name ) ) { 559 appendReturnThis( func ); 560 } 561 produceDecl( func ); 477 562 } 478 563 }
Note: See TracChangeset
for help on using the changeset viewer.