Changes in src/Parser/parser.yy [bb7422a:70056ed]
- File:
-
- 1 edited
-
src/Parser/parser.yy (modified) (87 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/parser.yy
rbb7422a r70056ed 9 9 // Author : Peter A. Buhr 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 // Last Modified By : Andrew Beach12 // Last Modified On : T ue Apr 4 14:02:00202313 // Update Count : 632 911 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Mar 30 21:28:25 2023 13 // Update Count : 6328 14 14 // 15 15 … … 64 64 65 65 extern DeclarationNode * parseTree; 66 extern ast::Linkage::Spec linkage;66 extern LinkageSpec::Spec linkage; 67 67 extern TypedefTable typedefTable; 68 68 69 stack< ast::Linkage::Spec> linkageStack;69 stack<LinkageSpec::Spec> linkageStack; 70 70 71 71 bool appendStr( string & to, string & from ) { … … 200 200 } // fieldDecl 201 201 202 #define NEW_ZERO new ExpressionNode( build_constantInteger( yylloc,*new string( "0" ) ) )203 #define NEW_ONE new ExpressionNode( build_constantInteger( yylloc,*new string( "1" ) ) )202 #define NEW_ZERO new ExpressionNode( build_constantInteger( *new string( "0" ) ) ) 203 #define NEW_ONE new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) 204 204 #define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right) 205 205 #define MISSING_ANON_FIELD "Missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body." … … 208 208 209 209 static ForCtrl * makeForCtrl( 210 const CodeLocation & location,211 210 DeclarationNode * init, 212 211 enum OperKinds compop, … … 214 213 ExpressionNode * inc ) { 215 214 // Wrap both comp/inc if they are non-null. 216 if ( comp ) comp = new ExpressionNode( build_binary_val( location,215 if ( comp ) comp = new ExpressionNode( build_binary_val( 217 216 compop, 218 new ExpressionNode( build_varref( location,new string( *init->name ) ) ),217 new ExpressionNode( build_varref( new string( *init->name ) ) ), 219 218 comp ) ); 220 if ( inc ) inc = new ExpressionNode( build_binary_val( location,219 if ( inc ) inc = new ExpressionNode( build_binary_val( 221 220 // choose += or -= for upto/downto 222 221 compop == OperKinds::LThan || compop == OperKinds::LEThan ? OperKinds::PlusAssn : OperKinds::MinusAssn, 223 new ExpressionNode( build_varref( location,new string( *init->name ) ) ),222 new ExpressionNode( build_varref( new string( *init->name ) ) ), 224 223 inc ) ); 225 224 // The StatementNode call frees init->name, it must happen later. … … 227 226 } 228 227 229 ForCtrl * forCtrl( const CodeLocation & location,DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {228 ForCtrl * forCtrl( DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 230 229 if ( index->initializer ) { 231 230 SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." ); … … 235 234 } // if 236 235 DeclarationNode * initDecl = index->addInitializer( new InitializerNode( start ) ); 237 return makeForCtrl( location,initDecl, compop, comp, inc );236 return makeForCtrl( initDecl, compop, comp, inc ); 238 237 } // forCtrl 239 238 240 ForCtrl * forCtrl( const CodeLocation & location,ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {241 ast::ConstantExpr * constant = dynamic_cast<ast::ConstantExpr *>(type->expr.get());242 if ( constant && (constant-> rep == "0" || constant->rep== "1") ) {243 type = new ExpressionNode( new ast::CastExpr( location, maybeMoveBuild(type), new ast::BasicType( ast::BasicType::SignedInt ) ) );239 ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 240 ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get()); 241 if ( constant && (constant->get_constant()->get_value() == "0" || constant->get_constant()->get_value() == "1") ) { 242 type = new ExpressionNode( new CastExpr( maybeMoveBuild( type ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ) ); 244 243 } // if 245 244 DeclarationNode * initDecl = distAttr( … … 247 246 DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) 248 247 ); 249 return makeForCtrl( location,initDecl, compop, comp, inc );248 return makeForCtrl( initDecl, compop, comp, inc ); 250 249 } // forCtrl 251 250 252 ForCtrl * forCtrl( const CodeLocation & location,ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {253 if ( auto identifier = dynamic_cast<ast::NameExpr *>(index->expr.get()) ) {254 return forCtrl( location,type, new string( identifier->name ), start, compop, comp, inc );255 } else if ( auto commaExpr = dynamic_cast<ast::CommaExpr *>( index->expr.get()) ) {256 if ( auto identifier = commaExpr->arg1.as<ast::NameExpr>() ) {257 return forCtrl( location,type, new string( identifier->name ), start, compop, comp, inc );251 ForCtrl * forCtrl( ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 252 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index->expr.get()) ) { 253 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc ); 254 } else if ( CommaExpr * commaExpr = dynamic_cast<CommaExpr *>(index->expr.get()) ) { 255 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(commaExpr->arg1 ) ) { 256 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc ); 258 257 } else { 259 258 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr; … … 300 299 ExpressionNode * en; 301 300 DeclarationNode * decl; 302 ast::AggregateDecl::Aggregate aggKey;303 ast::TypeDecl::Kind tclass;301 AggregateDecl::Aggregate aggKey; 302 TypeDecl::Kind tclass; 304 303 StatementNode * sn; 305 ast::WaitForStmt * wfs;306 ast::Expr* constant;304 WaitForStmt * wfs; 305 Expression * constant; 307 306 CondCtl * ifctl; 308 307 ForCtrl * fctl; … … 314 313 bool flag; 315 314 EnumHiding hide; 316 ast::ExceptionKind catch_kind;317 ast::GenericExpr * genexpr;315 CatchStmt::Kind catch_kind; 316 GenericExpr * genexpr; 318 317 } 319 318 320 // ************************ TERMINAL TOKENS ********************************319 //************************* TERMINAL TOKENS ******************************** 321 320 322 321 // keywords … … 612 611 constant: 613 612 // ENUMERATIONconstant is not included here; it is treated as a variable with type "enumeration constant". 614 INTEGERconstant { $$ = new ExpressionNode( build_constantInteger( yylloc,*$1 ) ); }615 | FLOATING_DECIMALconstant { $$ = new ExpressionNode( build_constantFloat( yylloc,*$1 ) ); }616 | FLOATING_FRACTIONconstant { $$ = new ExpressionNode( build_constantFloat( yylloc,*$1 ) ); }617 | FLOATINGconstant { $$ = new ExpressionNode( build_constantFloat( yylloc,*$1 ) ); }618 | CHARACTERconstant { $$ = new ExpressionNode( build_constantChar( yylloc,*$1 ) ); }613 INTEGERconstant { $$ = new ExpressionNode( build_constantInteger( *$1 ) ); } 614 | FLOATING_DECIMALconstant { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); } 615 | FLOATING_FRACTIONconstant { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); } 616 | FLOATINGconstant { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); } 617 | CHARACTERconstant { $$ = new ExpressionNode( build_constantChar( *$1 ) ); } 619 618 ; 620 619 … … 642 641 643 642 string_literal: 644 string_literal_list { $$ = build_constantStr( yylloc,*$1 ); }643 string_literal_list { $$ = build_constantStr( *$1 ); } 645 644 ; 646 645 … … 659 658 primary_expression: 660 659 IDENTIFIER // typedef name cannot be used as a variable name 661 { $$ = new ExpressionNode( build_varref( yylloc,$1 ) ); }660 { $$ = new ExpressionNode( build_varref( $1 ) ); } 662 661 | quasi_keyword 663 { $$ = new ExpressionNode( build_varref( yylloc,$1 ) ); }662 { $$ = new ExpressionNode( build_varref( $1 ) ); } 664 663 | TYPEDIMname // CFA, generic length argument 665 664 // { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( DeclarationNode::newFromTypedef( $1 ) ) ) ); } 666 665 // { $$ = new ExpressionNode( build_varref( $1 ) ); } 667 { $$ = new ExpressionNode( build_dimensionref( yylloc,$1 ) ); }666 { $$ = new ExpressionNode( build_dimensionref( $1 ) ); } 668 667 | tuple 669 668 | '(' comma_expression ')' 670 669 { $$ = $2; } 671 670 | '(' compound_statement ')' // GCC, lambda expression 672 { $$ = new ExpressionNode( new ast::StmtExpr( yylloc, dynamic_cast<ast::CompoundStmt *>(maybeMoveBuild( $2 ) ) ) ); }671 { $$ = new ExpressionNode( new StmtExpr( dynamic_cast<CompoundStmt *>(maybeMoveBuild( $2 ) ) ) ); } 673 672 | type_name '.' identifier // CFA, nested type 674 { $$ = new ExpressionNode( build_qualified_expr( yylloc, $1, build_varref( yylloc,$3 ) ) ); }673 { $$ = new ExpressionNode( build_qualified_expr( $1, build_varref( $3 ) ) ); } 675 674 | type_name '.' '[' field_name_list ']' // CFA, nested type / tuple field selector 676 675 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } … … 704 703 { 705 704 // steal the association node from the singleton and delete the wrapper 706 assert( 1 == $3->associations.size() ); 707 $1->associations.push_back( $3->associations.front() ); 705 $1->associations.splice($1->associations.end(), $3->associations); 708 706 delete $3; 709 707 $$ = $1; … … 715 713 { 716 714 // create a GenericExpr wrapper with one association pair 717 $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuildType( $1), maybeMoveBuild( $3 ) } } );715 $$ = new GenericExpr( nullptr, { { maybeMoveBuildType($1), maybeMoveBuild( $3 ) } } ); 718 716 } 719 717 | DEFAULT ':' assignment_expression 720 { $$ = new ast::GenericExpr( yylloc,nullptr, { { maybeMoveBuild( $3 ) } } ); }718 { $$ = new GenericExpr( nullptr, { { maybeMoveBuild( $3 ) } } ); } 721 719 ; 722 720 … … 727 725 // Switching to this behaviour may help check if a C compatibilty case uses comma-exprs in subscripts. 728 726 // Current: Commas in subscripts make tuples. 729 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, new ExpressionNode( build_tuple( yylloc,(ExpressionNode *)($3->set_last( $5 ) ) )) ) ); }727 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $5 ) ) )) ) ); } 730 728 | postfix_expression '[' assignment_expression ']' 731 729 // CFA, comma_expression disallowed in this context because it results in a common user error: subscripting a … … 733 731 // little advantage to this feature and many disadvantages. It is possible to write x[(i,j)] in CFA, which is 734 732 // equivalent to the old x[i,j]. 735 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Index, $1, $3 ) ); }733 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); } 736 734 | constant '[' assignment_expression ']' // 3[a], 'a'[a], 3.5[a] 737 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Index, $1, $3 ) ); }735 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); } 738 736 | string_literal '[' assignment_expression ']' // "abc"[3], 3["abc"] 739 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Index, new ExpressionNode( $1 ), $3 ) ); }737 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, new ExpressionNode( $1 ), $3 ) ); } 740 738 | postfix_expression '{' argument_expression_list_opt '}' // CFA, constructor call 741 739 { 742 740 Token fn; 743 741 fn.str = new std::string( "?{}" ); // location undefined - use location of '{'? 744 $$ = new ExpressionNode( new ast::ConstructorExpr( yylloc, build_func( yylloc, new ExpressionNode( build_varref( yylloc,fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) );742 $$ = new ExpressionNode( new ConstructorExpr( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) ); 745 743 } 746 744 | postfix_expression '(' argument_expression_list_opt ')' 747 { $$ = new ExpressionNode( build_func( yylloc,$1, $3 ) ); }745 { $$ = new ExpressionNode( build_func( $1, $3 ) ); } 748 746 | VA_ARG '(' primary_expression ',' declaration_specifier_nobody abstract_parameter_declarator_opt ')' 749 747 // { SemanticError( yylloc, "va_arg is currently unimplemented." ); $$ = nullptr; } 750 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc,new string( "__builtin_va_arg") ) ),748 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( new string( "__builtin_va_arg") ) ), 751 749 (ExpressionNode *)($3->set_last( (ExpressionNode *)($6 ? $6->addType( $5 ) : $5) )) ) ); } 752 750 | postfix_expression '`' identifier // CFA, postfix call 753 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc,build_postfix_name( $3 ) ) ), $1 ) ); }751 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); } 754 752 | constant '`' identifier // CFA, postfix call 755 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc,build_postfix_name( $3 ) ) ), $1 ) ); }753 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); } 756 754 | string_literal '`' identifier // CFA, postfix call 757 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc,build_postfix_name( $3 ) ) ), new ExpressionNode( $1 ) ) ); }755 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), new ExpressionNode( $1 ) ) ); } 758 756 | postfix_expression '.' identifier 759 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_varref( yylloc,$3 ) ) ); }757 { $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); } 760 758 | postfix_expression '.' INTEGERconstant // CFA, tuple index 761 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_constantInteger( yylloc,*$3 ) ) ); }759 { $$ = new ExpressionNode( build_fieldSel( $1, build_constantInteger( *$3 ) ) ); } 762 760 | postfix_expression FLOATING_FRACTIONconstant // CFA, tuple index 763 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_field_name_FLOATING_FRACTIONconstant( yylloc,*$2 ) ) ); }761 { $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_FLOATING_FRACTIONconstant( *$2 ) ) ); } 764 762 | postfix_expression '.' '[' field_name_list ']' // CFA, tuple field selector 765 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc,$4 ) ) ); }763 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); } 766 764 | postfix_expression '.' aggregate_control 767 { $$ = new ExpressionNode( build_keyword_cast( yylloc,$3, $1 ) ); }765 { $$ = new ExpressionNode( build_keyword_cast( $3, $1 ) ); } 768 766 | postfix_expression ARROW identifier 769 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_varref( yylloc,$3 ) ) ); }767 { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); } 770 768 | postfix_expression ARROW INTEGERconstant // CFA, tuple index 771 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_constantInteger( yylloc,*$3 ) ) ); }769 { $$ = new ExpressionNode( build_pfieldSel( $1, build_constantInteger( *$3 ) ) ); } 772 770 | postfix_expression ARROW '[' field_name_list ']' // CFA, tuple field selector 773 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc,$4 ) ) ); }771 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); } 774 772 | postfix_expression ICR 775 { $$ = new ExpressionNode( build_unary_val( yylloc,OperKinds::IncrPost, $1 ) ); }773 { $$ = new ExpressionNode( build_unary_val( OperKinds::IncrPost, $1 ) ); } 776 774 | postfix_expression DECR 777 { $$ = new ExpressionNode( build_unary_val( yylloc,OperKinds::DecrPost, $1 ) ); }775 { $$ = new ExpressionNode( build_unary_val( OperKinds::DecrPost, $1 ) ); } 778 776 | '(' type_no_function ')' '{' initializer_list_opt comma_opt '}' // C99, compound-literal 779 { $$ = new ExpressionNode( build_compoundLiteral( yylloc,$2, new InitializerNode( $5, true ) ) ); }777 { $$ = new ExpressionNode( build_compoundLiteral( $2, new InitializerNode( $5, true ) ) ); } 780 778 | '(' type_no_function ')' '@' '{' initializer_list_opt comma_opt '}' // CFA, explicit C compound-literal 781 { $$ = new ExpressionNode( build_compoundLiteral( yylloc,$2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); }779 { $$ = new ExpressionNode( build_compoundLiteral( $2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); } 782 780 | '^' primary_expression '{' argument_expression_list_opt '}' // CFA, destructor call 783 781 { 784 782 Token fn; 785 783 fn.str = new string( "^?{}" ); // location undefined 786 $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc,fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) );784 $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) ); 787 785 } 788 786 ; … … 815 813 field_name 816 814 | FLOATING_DECIMALconstant field 817 { $$ = new ExpressionNode( build_fieldSel( yylloc, new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( yylloc,*$1 ) ), maybeMoveBuild( $2 ) ) ); }815 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), maybeMoveBuild( $2 ) ) ); } 818 816 | FLOATING_DECIMALconstant '[' field_name_list ']' 819 { $$ = new ExpressionNode( build_fieldSel( yylloc, new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( yylloc, *$1 ) ), build_tuple( yylloc,$3 ) ) ); }817 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), build_tuple( $3 ) ) ); } 820 818 | field_name '.' field 821 { $$ = new ExpressionNode( build_fieldSel( yylloc,$1, maybeMoveBuild( $3 ) ) ); }819 { $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild( $3 ) ) ); } 822 820 | field_name '.' '[' field_name_list ']' 823 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc,$4 ) ) ); }821 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); } 824 822 | field_name ARROW field 825 { $$ = new ExpressionNode( build_pfieldSel( yylloc,$1, maybeMoveBuild( $3 ) ) ); }823 { $$ = new ExpressionNode( build_pfieldSel( $1, maybeMoveBuild( $3 ) ) ); } 826 824 | field_name ARROW '[' field_name_list ']' 827 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc,$4 ) ) ); }825 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); } 828 826 ; 829 827 830 828 field_name: 831 829 INTEGERconstant fraction_constants_opt 832 { $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_constantInteger( yylloc,*$1 ), $2 ) ); }830 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_constantInteger( *$1 ), $2 ) ); } 833 831 | FLOATINGconstant fraction_constants_opt 834 { $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_field_name_FLOATINGconstant( yylloc,*$1 ), $2 ) ); }832 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_field_name_FLOATINGconstant( *$1 ), $2 ) ); } 835 833 | identifier_at fraction_constants_opt // CFA, allow anonymous fields 836 834 { 837 $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_varref( yylloc,$1 ), $2 ) );835 $$ = new ExpressionNode( build_field_name_fraction_constants( build_varref( $1 ), $2 ) ); 838 836 } 839 837 ; … … 844 842 | fraction_constants_opt FLOATING_FRACTIONconstant 845 843 { 846 ast::Expr * constant = build_field_name_FLOATING_FRACTIONconstant( yylloc,*$2 );847 $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( yylloc, $1,constant ) ) : new ExpressionNode( constant );844 Expression * constant = build_field_name_FLOATING_FRACTIONconstant( *$2 ); 845 $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( $1, constant ) ) : new ExpressionNode( constant ); 848 846 } 849 847 ; … … 864 862 { 865 863 switch ( $1 ) { 866 case OperKinds::AddressOf:867 $$ = new ExpressionNode( new ast::AddressExpr( maybeMoveBuild( $2 ) ) );864 case OperKinds::AddressOf: 865 $$ = new ExpressionNode( new AddressExpr( maybeMoveBuild( $2 ) ) ); 868 866 break; 869 case OperKinds::PointTo:870 $$ = new ExpressionNode( build_unary_val( yylloc,$1, $2 ) );867 case OperKinds::PointTo: 868 $$ = new ExpressionNode( build_unary_val( $1, $2 ) ); 871 869 break; 872 case OperKinds::And:873 $$ = new ExpressionNode( new ast::AddressExpr( new ast::AddressExpr( maybeMoveBuild( $2 ) ) ) );870 case OperKinds::And: 871 $$ = new ExpressionNode( new AddressExpr( new AddressExpr( maybeMoveBuild( $2 ) ) ) ); 874 872 break; 875 default:873 default: 876 874 assert( false ); 877 875 } 878 876 } 879 877 | unary_operator cast_expression 880 { $$ = new ExpressionNode( build_unary_val( yylloc,$1, $2 ) ); }878 { $$ = new ExpressionNode( build_unary_val( $1, $2 ) ); } 881 879 | ICR unary_expression 882 { $$ = new ExpressionNode( build_unary_val( yylloc,OperKinds::Incr, $2 ) ); }880 { $$ = new ExpressionNode( build_unary_val( OperKinds::Incr, $2 ) ); } 883 881 | DECR unary_expression 884 { $$ = new ExpressionNode( build_unary_val( yylloc,OperKinds::Decr, $2 ) ); }882 { $$ = new ExpressionNode( build_unary_val( OperKinds::Decr, $2 ) ); } 885 883 | SIZEOF unary_expression 886 { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc,maybeMoveBuild( $2 ) ) ); }884 { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuild( $2 ) ) ); } 887 885 | SIZEOF '(' type_no_function ')' 888 { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc,maybeMoveBuildType( $3 ) ) ); }886 { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuildType( $3 ) ) ); } 889 887 | ALIGNOF unary_expression // GCC, variable alignment 890 { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc,maybeMoveBuild( $2 ) ) ); }888 { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuild( $2 ) ) ); } 891 889 | ALIGNOF '(' type_no_function ')' // GCC, type alignment 892 { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc,maybeMoveBuildType( $3 ) ) ); }890 { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuildType( $3 ) ) ); } 893 891 | OFFSETOF '(' type_no_function ',' identifier ')' 894 { $$ = new ExpressionNode( build_offsetOf( yylloc, $3, build_varref( yylloc,$5 ) ) ); }892 { $$ = new ExpressionNode( build_offsetOf( $3, build_varref( $5 ) ) ); } 895 893 | TYPEID '(' type_no_function ')' 896 894 { … … 917 915 unary_expression 918 916 | '(' type_no_function ')' cast_expression 919 { $$ = new ExpressionNode( build_cast( yylloc,$2, $4 ) ); }917 { $$ = new ExpressionNode( build_cast( $2, $4 ) ); } 920 918 | '(' aggregate_control '&' ')' cast_expression // CFA 921 { $$ = new ExpressionNode( build_keyword_cast( yylloc,$2, $5 ) ); }919 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); } 922 920 | '(' aggregate_control '*' ')' cast_expression // CFA 923 { $$ = new ExpressionNode( build_keyword_cast( yylloc,$2, $5 ) ); }921 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); } 924 922 | '(' VIRTUAL ')' cast_expression // CFA 925 { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc,maybeMoveBuild( $4 ), maybeMoveBuildType( nullptr ) ) ); }923 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild( $4 ), maybeMoveBuildType( nullptr ) ) ); } 926 924 | '(' VIRTUAL type_no_function ')' cast_expression // CFA 927 { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc,maybeMoveBuild( $5 ), maybeMoveBuildType( $3 ) ) ); }925 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild( $5 ), maybeMoveBuildType( $3 ) ) ); } 928 926 | '(' RETURN type_no_function ')' cast_expression // CFA 929 927 { SemanticError( yylloc, "Return cast is currently unimplemented." ); $$ = nullptr; } … … 933 931 { SemanticError( yylloc, "Qualifier cast is currently unimplemented." ); $$ = nullptr; } 934 932 // | '(' type_no_function ')' tuple 935 // { $$ = new ast::ExpressionNode( build_cast( yylloc,$2, $4 ) ); }933 // { $$ = new ExpressionNode( build_cast( $2, $4 ) ); } 936 934 ; 937 935 … … 951 949 cast_expression 952 950 | exponential_expression '\\' cast_expression 953 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Exp, $1, $3 ) ); }951 { $$ = new ExpressionNode( build_binary_val( OperKinds::Exp, $1, $3 ) ); } 954 952 ; 955 953 … … 957 955 exponential_expression 958 956 | multiplicative_expression '*' exponential_expression 959 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Mul, $1, $3 ) ); }957 { $$ = new ExpressionNode( build_binary_val( OperKinds::Mul, $1, $3 ) ); } 960 958 | multiplicative_expression '/' exponential_expression 961 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Div, $1, $3 ) ); }959 { $$ = new ExpressionNode( build_binary_val( OperKinds::Div, $1, $3 ) ); } 962 960 | multiplicative_expression '%' exponential_expression 963 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Mod, $1, $3 ) ); }961 { $$ = new ExpressionNode( build_binary_val( OperKinds::Mod, $1, $3 ) ); } 964 962 ; 965 963 … … 967 965 multiplicative_expression 968 966 | additive_expression '+' multiplicative_expression 969 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Plus, $1, $3 ) ); }967 { $$ = new ExpressionNode( build_binary_val( OperKinds::Plus, $1, $3 ) ); } 970 968 | additive_expression '-' multiplicative_expression 971 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Minus, $1, $3 ) ); }969 { $$ = new ExpressionNode( build_binary_val( OperKinds::Minus, $1, $3 ) ); } 972 970 ; 973 971 … … 975 973 additive_expression 976 974 | shift_expression LS additive_expression 977 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::LShift, $1, $3 ) ); }975 { $$ = new ExpressionNode( build_binary_val( OperKinds::LShift, $1, $3 ) ); } 978 976 | shift_expression RS additive_expression 979 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::RShift, $1, $3 ) ); }977 { $$ = new ExpressionNode( build_binary_val( OperKinds::RShift, $1, $3 ) ); } 980 978 ; 981 979 … … 983 981 shift_expression 984 982 | relational_expression '<' shift_expression 985 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::LThan, $1, $3 ) ); }983 { $$ = new ExpressionNode( build_binary_val( OperKinds::LThan, $1, $3 ) ); } 986 984 | relational_expression '>' shift_expression 987 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::GThan, $1, $3 ) ); }985 { $$ = new ExpressionNode( build_binary_val( OperKinds::GThan, $1, $3 ) ); } 988 986 | relational_expression LE shift_expression 989 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::LEThan, $1, $3 ) ); }987 { $$ = new ExpressionNode( build_binary_val( OperKinds::LEThan, $1, $3 ) ); } 990 988 | relational_expression GE shift_expression 991 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::GEThan, $1, $3 ) ); }989 { $$ = new ExpressionNode( build_binary_val( OperKinds::GEThan, $1, $3 ) ); } 992 990 ; 993 991 … … 995 993 relational_expression 996 994 | equality_expression EQ relational_expression 997 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Eq, $1, $3 ) ); }995 { $$ = new ExpressionNode( build_binary_val( OperKinds::Eq, $1, $3 ) ); } 998 996 | equality_expression NE relational_expression 999 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Neq, $1, $3 ) ); }997 { $$ = new ExpressionNode( build_binary_val( OperKinds::Neq, $1, $3 ) ); } 1000 998 ; 1001 999 … … 1003 1001 equality_expression 1004 1002 | AND_expression '&' equality_expression 1005 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::BitAnd, $1, $3 ) ); }1003 { $$ = new ExpressionNode( build_binary_val( OperKinds::BitAnd, $1, $3 ) ); } 1006 1004 ; 1007 1005 … … 1009 1007 AND_expression 1010 1008 | exclusive_OR_expression '^' AND_expression 1011 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Xor, $1, $3 ) ); }1009 { $$ = new ExpressionNode( build_binary_val( OperKinds::Xor, $1, $3 ) ); } 1012 1010 ; 1013 1011 … … 1015 1013 exclusive_OR_expression 1016 1014 | inclusive_OR_expression '|' exclusive_OR_expression 1017 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::BitOr, $1, $3 ) ); }1015 { $$ = new ExpressionNode( build_binary_val( OperKinds::BitOr, $1, $3 ) ); } 1018 1016 ; 1019 1017 … … 1021 1019 inclusive_OR_expression 1022 1020 | logical_AND_expression ANDAND inclusive_OR_expression 1023 { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::AndExpr) ); }1021 { $$ = new ExpressionNode( build_and_or( $1, $3, true ) ); } 1024 1022 ; 1025 1023 … … 1027 1025 logical_AND_expression 1028 1026 | logical_OR_expression OROR logical_AND_expression 1029 { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::OrExpr) ); }1027 { $$ = new ExpressionNode( build_and_or( $1, $3, false ) ); } 1030 1028 ; 1031 1029 … … 1033 1031 logical_OR_expression 1034 1032 | logical_OR_expression '?' comma_expression ':' conditional_expression 1035 { $$ = new ExpressionNode( build_cond( yylloc,$1, $3, $5 ) ); }1033 { $$ = new ExpressionNode( build_cond( $1, $3, $5 ) ); } 1036 1034 // FIX ME: computes $1 twice 1037 1035 | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand 1038 { $$ = new ExpressionNode( build_cond( yylloc,$1, $1, $4 ) ); }1036 { $$ = new ExpressionNode( build_cond( $1, $1, $4 ) ); } 1039 1037 ; 1040 1038 … … 1051 1049 // SemanticError( yylloc, "C @= assignment is currently unimplemented." ); $$ = nullptr; 1052 1050 // } else { 1053 $$ = new ExpressionNode( build_binary_val( yylloc,$2, $1, $3 ) );1051 $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) ); 1054 1052 // } // if 1055 1053 } … … 1096 1094 // { $$ = new ExpressionNode( build_tuple( $3 ) ); } 1097 1095 '[' ',' tuple_expression_list ']' 1098 { $$ = new ExpressionNode( build_tuple( yylloc,(ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }1096 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); } 1099 1097 | '[' push assignment_expression pop ',' tuple_expression_list ']' 1100 { $$ = new ExpressionNode( build_tuple( yylloc,(ExpressionNode *)($3->set_last( $6 ) ) )); }1098 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $6 ) ) )); } 1101 1099 ; 1102 1100 … … 1114 1112 assignment_expression 1115 1113 | comma_expression ',' assignment_expression 1116 { $$ = new ExpressionNode( new ast::CommaExpr( yylloc,maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }1114 { $$ = new ExpressionNode( new CommaExpr( maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); } 1117 1115 ; 1118 1116 … … 1141 1139 | asm_statement 1142 1140 | DIRECTIVE 1143 { $$ = new StatementNode( build_directive( yylloc,$1 ) ); }1141 { $$ = new StatementNode( build_directive( $1 ) ); } 1144 1142 ; 1145 1143 … … 1147 1145 // labels cannot be identifiers 0 or 1 1148 1146 identifier_or_type_name ':' attribute_list_opt statement 1149 { $$ = $4->add_label( yylloc,$1, $3 ); }1147 { $$ = $4->add_label( $1, $3 ); } 1150 1148 | identifier_or_type_name ':' attribute_list_opt error // syntax error 1151 1149 { … … 1159 1157 compound_statement: 1160 1158 '{' '}' 1161 { $$ = new StatementNode( build_compound( yylloc,(StatementNode *)0 ) ); }1159 { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); } 1162 1160 | '{' push 1163 1161 local_label_declaration_opt // GCC, local labels appear at start of block 1164 1162 statement_decl_list // C99, intermix declarations and statements 1165 1163 pop '}' 1166 { $$ = new StatementNode( build_compound( yylloc,$4 ) ); }1164 { $$ = new StatementNode( build_compound( $4 ) ); } 1167 1165 ; 1168 1166 … … 1195 1193 expression_statement: 1196 1194 comma_expression_opt ';' 1197 { $$ = new StatementNode( build_expr( yylloc,$1 ) ); }1195 { $$ = new StatementNode( build_expr( $1 ) ); } 1198 1196 ; 1199 1197 … … 1204 1202 { $$ = $2; } 1205 1203 | SWITCH '(' comma_expression ')' case_clause 1206 { $$ = new StatementNode( build_switch( yylloc,true, $3, $5 ) ); }1204 { $$ = new StatementNode( build_switch( true, $3, $5 ) ); } 1207 1205 | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA 1208 1206 { 1209 StatementNode *sw = new StatementNode( build_switch( yylloc,true, $3, $8 ) );1207 StatementNode *sw = new StatementNode( build_switch( true, $3, $8 ) ); 1210 1208 // The semantics of the declaration list is changed to include associated initialization, which is performed 1211 1209 // *before* the transfer to the appropriate case clause by hoisting the declarations into a compound … … 1213 1211 // therefore, are removed from the grammar even though C allows it. The change also applies to choose 1214 1212 // statement. 1215 $$ = $7 ? new StatementNode( build_compound( yylloc,(StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;1213 $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw; 1216 1214 } 1217 1215 | SWITCH '(' comma_expression ')' '{' error '}' // CFA, syntax error 1218 1216 { SemanticError( yylloc, "Only declarations can appear before the list of case clauses." ); $$ = nullptr; } 1219 1217 | CHOOSE '(' comma_expression ')' case_clause // CFA 1220 { $$ = new StatementNode( build_switch( yylloc,false, $3, $5 ) ); }1218 { $$ = new StatementNode( build_switch( false, $3, $5 ) ); } 1221 1219 | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA 1222 1220 { 1223 StatementNode *sw = new StatementNode( build_switch( yylloc,false, $3, $8 ) );1224 $$ = $7 ? new StatementNode( build_compound( yylloc,(StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;1221 StatementNode *sw = new StatementNode( build_switch( false, $3, $8 ) ); 1222 $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw; 1225 1223 } 1226 1224 | CHOOSE '(' comma_expression ')' '{' error '}' // CFA, syntax error … … 1231 1229 IF '(' conditional_declaration ')' statement %prec THEN 1232 1230 // explicitly deal with the shift/reduce conflict on if/else 1233 { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc,$5 ), nullptr ) ); }1231 { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), nullptr ) ); } 1234 1232 | IF '(' conditional_declaration ')' statement ELSE statement 1235 { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), maybe_build_compound( yylloc,$7 ) ) ); }1233 { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), maybe_build_compound( $7 ) ) ); } 1236 1234 ; 1237 1235 … … 1253 1251 constant_expression { $$ = $1; } 1254 1252 | constant_expression ELLIPSIS constant_expression // GCC, subrange 1255 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc,maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }1253 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); } 1256 1254 | subrange // CFA, subrange 1257 1255 ; … … 1269 1267 | CASE case_value_list error // syntax error 1270 1268 { SemanticError( yylloc, "Missing colon after case list." ); $$ = nullptr; } 1271 | DEFAULT ':' { $$ = new StatementNode( build_default( yylloc) ); }1269 | DEFAULT ':' { $$ = new StatementNode( build_default() ); } 1272 1270 // A semantic check is required to ensure only one default clause per switch/choose statement. 1273 1271 | DEFAULT error // syntax error … … 1281 1279 1282 1280 case_clause: // CFA 1283 case_label_list statement { $$ = $1->append_last_case( maybe_build_compound( yylloc,$2 ) ); }1281 case_label_list statement { $$ = $1->append_last_case( maybe_build_compound( $2 ) ); } 1284 1282 ; 1285 1283 … … 1292 1290 switch_clause_list: // CFA 1293 1291 case_label_list statement_list_nodecl 1294 { $$ = $1->append_last_case( new StatementNode( build_compound( yylloc,$2 ) ) ); }1292 { $$ = $1->append_last_case( new StatementNode( build_compound( $2 ) ) ); } 1295 1293 | switch_clause_list case_label_list statement_list_nodecl 1296 { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( yylloc,$3 ) ) ) ) ); }1294 { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( $3 ) ) ) ) ); } 1297 1295 ; 1298 1296 1299 1297 iteration_statement: 1300 1298 WHILE '(' ')' statement %prec THEN // CFA => while ( 1 ) 1301 { $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc,$4 ) ) ); }1299 { $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); } 1302 1300 | WHILE '(' ')' statement ELSE statement // CFA 1303 1301 { 1304 $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc,$4 ) ) );1302 $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); 1305 1303 SemanticWarning( yylloc, Warning::SuperfluousElse ); 1306 1304 } 1307 1305 | WHILE '(' conditional_declaration ')' statement %prec THEN 1308 { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc,$5 ) ) ); }1306 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ) ) ); } 1309 1307 | WHILE '(' conditional_declaration ')' statement ELSE statement // CFA 1310 { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc,$5 ), $7 ) ); }1308 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ), $7 ) ); } 1311 1309 | DO statement WHILE '(' ')' ';' // CFA => do while( 1 ) 1312 { $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc,$2 ) ) ); }1310 { $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); } 1313 1311 | DO statement WHILE '(' ')' ELSE statement // CFA 1314 1312 { 1315 $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc,$2 ) ) );1313 $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); 1316 1314 SemanticWarning( yylloc, Warning::SuperfluousElse ); 1317 1315 } 1318 1316 | DO statement WHILE '(' comma_expression ')' ';' 1319 { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc,$2 ) ) ); }1317 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ) ) ); } 1320 1318 | DO statement WHILE '(' comma_expression ')' ELSE statement // CFA 1321 { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc,$2 ), $8 ) ); }1319 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ), $8 ) ); } 1322 1320 | FOR '(' ')' statement %prec THEN // CFA => for ( ;; ) 1323 { $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc,$4 ) ) ); }1321 { $$ = new StatementNode( build_for( new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( $4 ) ) ); } 1324 1322 | FOR '(' ')' statement ELSE statement // CFA 1325 1323 { 1326 $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc,$4 ) ) );1324 $$ = new StatementNode( build_for( new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( $4 ) ) ); 1327 1325 SemanticWarning( yylloc, Warning::SuperfluousElse ); 1328 1326 } 1329 1327 | FOR '(' for_control_expression_list ')' statement %prec THEN 1330 { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc,$5 ) ) ); }1328 { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ) ) ); } 1331 1329 | FOR '(' for_control_expression_list ')' statement ELSE statement // CFA 1332 { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc,$5 ), $7 ) ); }1330 { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ), $7 ) ); } 1333 1331 ; 1334 1332 … … 1344 1342 if ( $1->condition ) { 1345 1343 if ( $3->condition ) { 1346 $1->condition->expr.reset( new ast::LogicalExpr( yylloc, $1->condition->expr.release(), $3->condition->expr.release(), ast::AndExpr) );1344 $1->condition->expr.reset( new LogicalExpr( $1->condition->expr.release(), $3->condition->expr.release(), true ) ); 1347 1345 } // if 1348 1346 } else $1->condition = $3->condition; 1349 1347 if ( $1->change ) { 1350 1348 if ( $3->change ) { 1351 $1->change->expr.reset( new ast::CommaExpr( yylloc,$1->change->expr.release(), $3->change->expr.release() ) );1349 $1->change->expr.reset( new CommaExpr( $1->change->expr.release(), $3->change->expr.release() ) ); 1352 1350 } // if 1353 1351 } else $1->change = $3->change; … … 1361 1359 | comma_expression ';' comma_expression_opt ';' comma_expression_opt 1362 1360 { 1363 StatementNode * init = $1 ? new StatementNode( new ast::ExprStmt( yylloc,maybeMoveBuild( $1 ) ) ) : nullptr;1361 StatementNode * init = $1 ? new StatementNode( new ExprStmt( maybeMoveBuild( $1 ) ) ) : nullptr; 1364 1362 $$ = new ForCtrl( init, $3, $5 ); 1365 1363 } … … 1373 1371 1374 1372 | comma_expression // CFA, anonymous loop-index 1375 { $$ = forCtrl( yylloc,$1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); }1373 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); } 1376 1374 | downupdowneq comma_expression // CFA, anonymous loop-index 1377 { $$ = forCtrl( yylloc,$2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); }1375 { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); } 1378 1376 1379 1377 | comma_expression updowneq comma_expression // CFA, anonymous loop-index 1380 { $$ = forCtrl( yylloc,$1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); }1378 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); } 1381 1379 | '@' updowneq comma_expression // CFA, anonymous loop-index 1382 1380 { 1383 1381 if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1384 else $$ = forCtrl( yylloc,$3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE );1382 else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE ); 1385 1383 } 1386 1384 | comma_expression updowneq '@' // CFA, anonymous loop-index … … 1390 1388 } 1391 1389 | comma_expression updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index 1392 { $$ = forCtrl( yylloc,$1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); }1390 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); } 1393 1391 | '@' updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index 1394 1392 { 1395 1393 if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1396 else $$ = forCtrl( yylloc,$3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 );1394 else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 ); 1397 1395 } 1398 1396 | comma_expression updowneq '@' '~' comma_expression // CFA, anonymous loop-index … … 1413 1411 1414 1412 | comma_expression ';' comma_expression // CFA 1415 { $$ = forCtrl( yylloc,$3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }1413 { $$ = forCtrl( $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); } 1416 1414 | comma_expression ';' downupdowneq comma_expression // CFA 1417 { $$ = forCtrl( yylloc,$4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); }1415 { $$ = forCtrl( $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); } 1418 1416 1419 1417 | comma_expression ';' comma_expression updowneq comma_expression // CFA 1420 { $$ = forCtrl( yylloc,$3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); }1418 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); } 1421 1419 | comma_expression ';' '@' updowneq comma_expression // CFA 1422 1420 { 1423 1421 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1424 else $$ = forCtrl( yylloc,$5, $1, $5->clone(), $4, nullptr, NEW_ONE );1422 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, NEW_ONE ); 1425 1423 } 1426 1424 | comma_expression ';' comma_expression updowneq '@' // CFA … … 1428 1426 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1429 1427 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1430 else $$ = forCtrl( yylloc,$3, $1, $3->clone(), $4, nullptr, NEW_ONE );1428 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, NEW_ONE ); 1431 1429 } 1432 1430 | comma_expression ';' '@' updowneq '@' // CFA, error … … 1434 1432 1435 1433 | comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA 1436 { $$ = forCtrl( yylloc,$3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }1434 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); } 1437 1435 | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, error 1438 1436 { 1439 1437 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1440 else $$ = forCtrl( yylloc,$5, $1, $5->clone(), $4, nullptr, $7 );1438 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, $7 ); 1441 1439 } 1442 1440 | comma_expression ';' comma_expression updowneq '@' '~' comma_expression // CFA … … 1444 1442 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1445 1443 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1446 else $$ = forCtrl( yylloc,$3, $1, $3->clone(), $4, nullptr, $7 );1444 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, $7 ); 1447 1445 } 1448 1446 | comma_expression ';' comma_expression updowneq comma_expression '~' '@' // CFA 1449 { $$ = forCtrl( yylloc,$3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }1447 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); } 1450 1448 | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, error 1451 1449 { 1452 1450 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1453 else $$ = forCtrl( yylloc,$5, $1, $5->clone(), $4, nullptr, nullptr );1451 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, nullptr ); 1454 1452 } 1455 1453 | comma_expression ';' comma_expression updowneq '@' '~' '@' // CFA … … 1457 1455 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1458 1456 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1459 else $$ = forCtrl( yylloc,$3, $1, $3->clone(), $4, nullptr, nullptr );1457 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, nullptr ); 1460 1458 } 1461 1459 | comma_expression ';' '@' updowneq '@' '~' '@' // CFA … … 1463 1461 1464 1462 | declaration comma_expression // CFA 1465 { $$ = forCtrl( yylloc,$1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }1463 { $$ = forCtrl( $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); } 1466 1464 | declaration downupdowneq comma_expression // CFA 1467 { $$ = forCtrl( yylloc,$1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); }1465 { $$ = forCtrl( $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); } 1468 1466 1469 1467 | declaration comma_expression updowneq comma_expression // CFA 1470 { $$ = forCtrl( yylloc,$1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); }1468 { $$ = forCtrl( $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); } 1471 1469 | declaration '@' updowneq comma_expression // CFA 1472 1470 { 1473 1471 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1474 else $$ = forCtrl( yylloc,$1, $4, $3, nullptr, NEW_ONE );1472 else $$ = forCtrl( $1, $4, $3, nullptr, NEW_ONE ); 1475 1473 } 1476 1474 | declaration comma_expression updowneq '@' // CFA … … 1478 1476 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1479 1477 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1480 else $$ = forCtrl( yylloc,$1, $2, $3, nullptr, NEW_ONE );1478 else $$ = forCtrl( $1, $2, $3, nullptr, NEW_ONE ); 1481 1479 } 1482 1480 1483 1481 | declaration comma_expression updowneq comma_expression '~' comma_expression // CFA 1484 { $$ = forCtrl( yylloc,$1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); }1482 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); } 1485 1483 | declaration '@' updowneq comma_expression '~' comma_expression // CFA 1486 1484 { 1487 1485 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1488 else $$ = forCtrl( yylloc,$1, $4, $3, nullptr, $6 );1486 else $$ = forCtrl( $1, $4, $3, nullptr, $6 ); 1489 1487 } 1490 1488 | declaration comma_expression updowneq '@' '~' comma_expression // CFA … … 1492 1490 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1493 1491 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1494 else $$ = forCtrl( yylloc,$1, $2, $3, nullptr, $6 );1492 else $$ = forCtrl( $1, $2, $3, nullptr, $6 ); 1495 1493 } 1496 1494 | declaration comma_expression updowneq comma_expression '~' '@' // CFA 1497 { $$ = forCtrl( yylloc,$1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); }1495 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); } 1498 1496 | declaration '@' updowneq comma_expression '~' '@' // CFA 1499 1497 { 1500 1498 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1501 else $$ = forCtrl( yylloc,$1, $4, $3, nullptr, nullptr );1499 else $$ = forCtrl( $1, $4, $3, nullptr, nullptr ); 1502 1500 } 1503 1501 | declaration comma_expression updowneq '@' '~' '@' // CFA … … 1505 1503 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1506 1504 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1507 else $$ = forCtrl( yylloc,$1, $2, $3, nullptr, nullptr );1505 else $$ = forCtrl( $1, $2, $3, nullptr, nullptr ); 1508 1506 } 1509 1507 | declaration '@' updowneq '@' '~' '@' // CFA, error … … 1548 1546 jump_statement: 1549 1547 GOTO identifier_or_type_name ';' 1550 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Goto ) ); }1548 { $$ = new StatementNode( build_branch( $2, BranchStmt::Goto ) ); } 1551 1549 | GOTO '*' comma_expression ';' // GCC, computed goto 1552 1550 // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto *i+3; => goto *(i+3); … … 1555 1553 // A semantic check is required to ensure fallthru appears only in the body of a choose statement. 1556 1554 | fall_through_name ';' // CFA 1557 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThrough ) ); }1555 { $$ = new StatementNode( build_branch( BranchStmt::FallThrough ) ); } 1558 1556 | fall_through_name identifier_or_type_name ';' // CFA 1559 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::FallThrough ) ); }1557 { $$ = new StatementNode( build_branch( $2, BranchStmt::FallThrough ) ); } 1560 1558 | fall_through_name DEFAULT ';' // CFA 1561 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThroughDefault ) ); }1559 { $$ = new StatementNode( build_branch( BranchStmt::FallThroughDefault ) ); } 1562 1560 | CONTINUE ';' 1563 1561 // A semantic check is required to ensure this statement appears only in the body of an iteration statement. 1564 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Continue ) ); }1562 { $$ = new StatementNode( build_branch( BranchStmt::Continue ) ); } 1565 1563 | CONTINUE identifier_or_type_name ';' // CFA, multi-level continue 1566 1564 // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and 1567 1565 // the target of the transfer appears only at the start of an iteration statement. 1568 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Continue ) ); }1566 { $$ = new StatementNode( build_branch( $2, BranchStmt::Continue ) ); } 1569 1567 | BREAK ';' 1570 1568 // A semantic check is required to ensure this statement appears only in the body of an iteration statement. 1571 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Break ) ); }1569 { $$ = new StatementNode( build_branch( BranchStmt::Break ) ); } 1572 1570 | BREAK identifier_or_type_name ';' // CFA, multi-level exit 1573 1571 // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and 1574 1572 // the target of the transfer appears only at the start of an iteration statement. 1575 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Break ) ); }1573 { $$ = new StatementNode( build_branch( $2, BranchStmt::Break ) ); } 1576 1574 | RETURN comma_expression_opt ';' 1577 { $$ = new StatementNode( build_return( yylloc,$2 ) ); }1575 { $$ = new StatementNode( build_return( $2 ) ); } 1578 1576 | RETURN '{' initializer_list_opt comma_opt '}' ';' 1579 1577 { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; } 1580 1578 | SUSPEND ';' 1581 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::None) ); }1579 { $$ = new StatementNode( build_suspend( nullptr ) ); } 1582 1580 | SUSPEND compound_statement 1583 { $$ = new StatementNode( build_suspend( yylloc, $2, ast::SuspendStmt::None) ); }1581 { $$ = new StatementNode( build_suspend( $2 ) ); } 1584 1582 | SUSPEND COROUTINE ';' 1585 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Coroutine ) ); }1583 { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Coroutine ) ); } 1586 1584 | SUSPEND COROUTINE compound_statement 1587 { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Coroutine ) ); }1585 { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Coroutine ) ); } 1588 1586 | SUSPEND GENERATOR ';' 1589 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Generator ) ); }1587 { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Generator ) ); } 1590 1588 | SUSPEND GENERATOR compound_statement 1591 { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Generator ) ); }1589 { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Generator ) ); } 1592 1590 | THROW assignment_expression_opt ';' // handles rethrow 1593 { $$ = new StatementNode( build_throw( yylloc,$2 ) ); }1591 { $$ = new StatementNode( build_throw( $2 ) ); } 1594 1592 | THROWRESUME assignment_expression_opt ';' // handles reresume 1595 { $$ = new StatementNode( build_resume( yylloc,$2 ) ); }1593 { $$ = new StatementNode( build_resume( $2 ) ); } 1596 1594 | THROWRESUME assignment_expression_opt AT assignment_expression ';' // handles reresume 1597 1595 { $$ = new StatementNode( build_resume_at( $2, $4 ) ); } … … 1605 1603 with_statement: 1606 1604 WITH '(' tuple_expression_list ')' statement 1607 { $$ = new StatementNode( build_with( yylloc,$3, $5 ) ); }1605 { $$ = new StatementNode( build_with( $3, $5 ) ); } 1608 1606 ; 1609 1607 … … 1613 1611 { 1614 1612 if ( ! $3 ) { SemanticError( yylloc, "mutex argument list cannot be empty." ); $$ = nullptr; } 1615 $$ = new StatementNode( build_mutex( yylloc,$3, $5 ) );1613 $$ = new StatementNode( build_mutex( $3, $5 ) ); 1616 1614 } 1617 1615 ; … … 1652 1650 when_clause_opt waitfor statement %prec THEN 1653 1651 // Called first: create header for WaitForStmt. 1654 { $$ = build_waitfor( yylloc, new ast::WaitForStmt( yylloc ), $1, $2, maybe_build_compound( yylloc,$3 ) ); }1652 { $$ = build_waitfor( new WaitForStmt(), $1, $2, maybe_build_compound( $3 ) ); } 1655 1653 | wor_waitfor_clause wor when_clause_opt waitfor statement 1656 { $$ = build_waitfor( yylloc, $1, $3, $4, maybe_build_compound( yylloc,$5 ) ); }1654 { $$ = build_waitfor( $1, $3, $4, maybe_build_compound( $5 ) ); } 1657 1655 | wor_waitfor_clause wor when_clause_opt ELSE statement 1658 { $$ = build_waitfor_else( yylloc, $1, $3, maybe_build_compound( yylloc,$5 ) ); }1656 { $$ = build_waitfor_else( $1, $3, maybe_build_compound( $5 ) ); } 1659 1657 | wor_waitfor_clause wor when_clause_opt timeout statement %prec THEN 1660 { $$ = build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc,$5 ) ); }1658 { $$ = build_waitfor_timeout( $1, $3, $4, maybe_build_compound( $5 ) ); } 1661 1659 // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless) 1662 1660 | wor_waitfor_clause wor when_clause_opt timeout statement wor ELSE statement // syntax error 1663 1661 { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; } 1664 1662 | wor_waitfor_clause wor when_clause_opt timeout statement wor when_clause ELSE statement 1665 { $$ = build_waitfor_else( yylloc, build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ), $7, maybe_build_compound( yylloc, $9 ) ); } 1666 ; 1663 { $$ = build_waitfor_else( build_waitfor_timeout( $1, $3, $4, maybe_build_compound( $5 ) ), $7, maybe_build_compound( $9 ) ); } 1667 1664 1668 1665 waitfor_statement: … … 1714 1711 wor_waituntil_clause %prec THEN 1715 1712 // SKULLDUGGERY: create an empty compound statement to test parsing of waituntil statement. 1716 { $$ = new StatementNode( build_compound( yylloc, nullptr) ); }1713 { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); } 1717 1714 ; 1718 1715 1719 1716 exception_statement: 1720 TRY compound_statement handler_clause %prec THEN1721 { $$ = new StatementNode( build_try( yylloc,$2, $3, nullptr ) ); }1717 TRY compound_statement handler_clause %prec THEN 1718 { $$ = new StatementNode( build_try( $2, $3, nullptr ) ); } 1722 1719 | TRY compound_statement finally_clause 1723 { $$ = new StatementNode( build_try( yylloc,$2, nullptr, $3 ) ); }1720 { $$ = new StatementNode( build_try( $2, nullptr, $3 ) ); } 1724 1721 | TRY compound_statement handler_clause finally_clause 1725 { $$ = new StatementNode( build_try( yylloc,$2, $3, $4 ) ); }1722 { $$ = new StatementNode( build_try( $2, $3, $4 ) ); } 1726 1723 ; 1727 1724 1728 1725 handler_clause: 1729 1726 handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement 1730 { $$ = new StatementNode( build_catch( yylloc,$1, $4, $6, $8 ) ); }1727 { $$ = new StatementNode( build_catch( $1, $4, $6, $8 ) ); } 1731 1728 | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement 1732 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( yylloc,$2, $5, $7, $9 ) ) ); }1729 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $5, $7, $9 ) ) ); } 1733 1730 ; 1734 1731 … … 1740 1737 1741 1738 handler_key: 1742 CATCH { $$ = ast::Terminate; }1743 | RECOVER { $$ = ast::Terminate; }1744 | CATCHRESUME { $$ = ast::Resume; }1745 | FIXUP { $$ = ast::Resume; }1739 CATCH { $$ = CatchStmt::Terminate; } 1740 | RECOVER { $$ = CatchStmt::Terminate; } 1741 | CATCHRESUME { $$ = CatchStmt::Resume; } 1742 | FIXUP { $$ = CatchStmt::Resume; } 1746 1743 ; 1747 1744 1748 1745 finally_clause: 1749 FINALLY compound_statement { $$ = new StatementNode( build_finally( yylloc,$2 ) ); }1746 FINALLY compound_statement { $$ = new StatementNode( build_finally( $2 ) ); } 1750 1747 ; 1751 1748 … … 1773 1770 asm_statement: 1774 1771 ASM asm_volatile_opt '(' string_literal ')' ';' 1775 { $$ = new StatementNode( build_asm( yylloc,$2, $4, nullptr ) ); }1772 { $$ = new StatementNode( build_asm( $2, $4, nullptr ) ); } 1776 1773 | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ')' ';' // remaining GCC 1777 { $$ = new StatementNode( build_asm( yylloc,$2, $4, $6 ) ); }1774 { $$ = new StatementNode( build_asm( $2, $4, $6 ) ); } 1778 1775 | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ')' ';' 1779 { $$ = new StatementNode( build_asm( yylloc,$2, $4, $6, $8 ) ); }1776 { $$ = new StatementNode( build_asm( $2, $4, $6, $8 ) ); } 1780 1777 | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ':' asm_clobbers_list_opt ')' ';' 1781 { $$ = new StatementNode( build_asm( yylloc,$2, $4, $6, $8, $10 ) ); }1778 { $$ = new StatementNode( build_asm( $2, $4, $6, $8, $10 ) ); } 1782 1779 | ASM asm_volatile_opt GOTO '(' string_literal ':' ':' asm_operands_opt ':' asm_clobbers_list_opt ':' label_list ')' ';' 1783 { $$ = new StatementNode( build_asm( yylloc,$2, $5, nullptr, $8, $10, $12 ) ); }1780 { $$ = new StatementNode( build_asm( $2, $5, nullptr, $8, $10, $12 ) ); } 1784 1781 ; 1785 1782 … … 1805 1802 asm_operand: // GCC 1806 1803 string_literal '(' constant_expression ')' 1807 { $$ = new ExpressionNode( new ast::AsmExpr( yylloc, "", $1, maybeMoveBuild( $3 ) ) ); }1804 { $$ = new ExpressionNode( new AsmExpr( nullptr, $1, maybeMoveBuild( $3 ) ) ); } 1808 1805 | '[' IDENTIFIER ']' string_literal '(' constant_expression ')' 1809 { 1810 $$ = new ExpressionNode( new ast::AsmExpr( yylloc, *$2.str, $4, maybeMoveBuild( $6 ) ) ); 1811 delete $2.str; 1812 } 1806 { $$ = new ExpressionNode( new AsmExpr( $2, $4, maybeMoveBuild( $6 ) ) ); } 1813 1807 ; 1814 1808 … … 1825 1819 identifier 1826 1820 { 1827 $$ = new LabelNode(); $$->labels. emplace_back( yylloc,*$1 );1821 $$ = new LabelNode(); $$->labels.push_back( *$1 ); 1828 1822 delete $1; // allocated by lexer 1829 1823 } 1830 1824 | label_list ',' identifier 1831 1825 { 1832 $$ = $1; $1->labels. emplace_back( yylloc,*$3 );1826 $$ = $1; $1->labels.push_back( *$3 ); 1833 1827 delete $3; // allocated by lexer 1834 1828 } … … 1893 1887 { $$ = DeclarationNode::newStaticAssert( $3, $5 ); } 1894 1888 | STATICASSERT '(' constant_expression ')' ';' // CFA 1895 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( yylloc,*new string( "\"\"" ) ) ); }1889 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( *new string( "\"\"" ) ) ); } 1896 1890 1897 1891 // C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function … … 2093 2087 { 2094 2088 SemanticError( yylloc, ::toString( "Missing ';' after end of ", 2095 $1->type->enumeration.name ? "enum" : ast::AggregateDecl::aggrString( $1->type->aggregate.kind ),2089 $1->type->enumeration.name ? "enum" : AggregateDecl::aggrString( $1->type->aggregate.kind ), 2096 2090 " declaration" ) ); 2097 2091 $$ = nullptr; … … 2327 2321 { $$ = DeclarationNode::newTypeof( $3 ); } 2328 2322 | BASETYPEOF '(' type ')' // CFA: basetypeof( x ) y; 2329 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $3 ) ) ), true ); }2323 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ), true ); } 2330 2324 | BASETYPEOF '(' comma_expression ')' // CFA: basetypeof( a+b ) y; 2331 2325 { $$ = DeclarationNode::newTypeof( $3, true ); } … … 2521 2515 aggregate_data: 2522 2516 STRUCT vtable_opt 2523 { $$ = ast::AggregateDecl::Struct; }2517 { $$ = AggregateDecl::Struct; } 2524 2518 | UNION 2525 { $$ = ast::AggregateDecl::Union; }2519 { $$ = AggregateDecl::Union; } 2526 2520 | EXCEPTION // CFA 2527 { $$ = ast::AggregateDecl::Exception; }2528 // { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = ast::AggregateDecl::NoAggregate; }2521 { $$ = AggregateDecl::Exception; } 2522 // { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2529 2523 ; 2530 2524 2531 2525 aggregate_control: // CFA 2532 2526 MONITOR 2533 { $$ = ast::AggregateDecl::Monitor; }2527 { $$ = AggregateDecl::Monitor; } 2534 2528 | MUTEX STRUCT 2535 { $$ = ast::AggregateDecl::Monitor; }2529 { $$ = AggregateDecl::Monitor; } 2536 2530 | GENERATOR 2537 { $$ = ast::AggregateDecl::Generator; }2531 { $$ = AggregateDecl::Generator; } 2538 2532 | MUTEX GENERATOR 2539 { 2540 SemanticError( yylloc, "monitor generator is currently unimplemented." ); 2541 $$ = ast::AggregateDecl::NoAggregate; 2542 } 2533 { SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2543 2534 | COROUTINE 2544 { $$ = ast::AggregateDecl::Coroutine; }2535 { $$ = AggregateDecl::Coroutine; } 2545 2536 | MUTEX COROUTINE 2546 { 2547 SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); 2548 $$ = ast::AggregateDecl::NoAggregate; 2549 } 2537 { SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2550 2538 | THREAD 2551 { $$ = ast::AggregateDecl::Thread; }2539 { $$ = AggregateDecl::Thread; } 2552 2540 | MUTEX THREAD 2553 { 2554 SemanticError( yylloc, "monitor thread is currently unimplemented." ); 2555 $$ = ast::AggregateDecl::NoAggregate; 2556 } 2541 { SemanticError( yylloc, "monitor thread is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2557 2542 ; 2558 2543 … … 2904 2889 designator_list ':' // C99, CFA uses ":" instead of "=" 2905 2890 | identifier_at ':' // GCC, field name 2906 { $$ = new ExpressionNode( build_varref( yylloc,$1 ) ); }2891 { $$ = new ExpressionNode( build_varref( $1 ) ); } 2907 2892 ; 2908 2893 … … 2916 2901 designator: 2917 2902 '.' identifier_at // C99, field name 2918 { $$ = new ExpressionNode( build_varref( yylloc,$2 ) ); }2903 { $$ = new ExpressionNode( build_varref( $2 ) ); } 2919 2904 | '[' push assignment_expression pop ']' // C99, single array element 2920 2905 // assignment_expression used instead of constant_expression because of shift/reduce conflicts with tuple. … … 2923 2908 { $$ = $3; } 2924 2909 | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements 2925 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc,maybeMoveBuild( $3 ), maybeMoveBuild( $5 ) ) ); }2910 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild( $3 ), maybeMoveBuild( $5 ) ) ); } 2926 2911 | '.' '[' push field_name_list pop ']' // CFA, tuple field selector 2927 2912 { $$ = $4; } … … 2963 2948 { 2964 2949 typedefTable.addToScope( *$2, TYPEDEFname, "9" ); 2965 if ( $1 == ast::TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }2966 if ( $1 == ast::TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }2967 if ( $1 == ast::TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); }2950 if ( $1 == TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); } 2951 if ( $1 == TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); } 2952 if ( $1 == TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); } 2968 2953 } 2969 2954 type_initializer_opt assertion_list_opt … … 2976 2961 { 2977 2962 typedefTable.addToScope( *$2, TYPEDIMname, "9" ); 2978 $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dimension, $2 );2963 $$ = DeclarationNode::newTypeParam( TypeDecl::Dimension, $2 ); 2979 2964 } 2980 2965 // | type_specifier identifier_parameter_declarator 2981 2966 | assertion_list 2982 { $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }2967 { $$ = DeclarationNode::newTypeParam( TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); } 2983 2968 ; 2984 2969 2985 2970 new_type_class: // CFA 2986 2971 // empty 2987 { $$ = ast::TypeDecl::Otype; }2972 { $$ = TypeDecl::Otype; } 2988 2973 | '&' 2989 { $$ = ast::TypeDecl::Dtype; }2974 { $$ = TypeDecl::Dtype; } 2990 2975 | '*' 2991 { $$ = ast::TypeDecl::DStype; } // dtype + sized2976 { $$ = TypeDecl::DStype; } // dtype + sized 2992 2977 // | '(' '*' ')' 2993 // { $$ = ast::TypeDecl::Ftype; }2978 // { $$ = TypeDecl::Ftype; } 2994 2979 | ELLIPSIS 2995 { $$ = ast::TypeDecl::Ttype; }2980 { $$ = TypeDecl::Ttype; } 2996 2981 ; 2997 2982 2998 2983 type_class: // CFA 2999 2984 OTYPE 3000 { $$ = ast::TypeDecl::Otype; }2985 { $$ = TypeDecl::Otype; } 3001 2986 | DTYPE 3002 { $$ = ast::TypeDecl::Dtype; }2987 { $$ = TypeDecl::Dtype; } 3003 2988 | FTYPE 3004 { $$ = ast::TypeDecl::Ftype; }2989 { $$ = TypeDecl::Ftype; } 3005 2990 | TTYPE 3006 { $$ = ast::TypeDecl::Ttype; }2991 { $$ = TypeDecl::Ttype; } 3007 2992 ; 3008 2993 … … 3030 3015 type_list: // CFA 3031 3016 type 3032 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $1 ) ) ); }3017 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); } 3033 3018 | assignment_expression 3034 3019 | type_list ',' type 3035 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $3 ) ) ) )); }3020 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); } 3036 3021 | type_list ',' assignment_expression 3037 3022 { $$ = (ExpressionNode *)( $1->set_last( $3 )); } … … 3140 3125 external_definition: 3141 3126 DIRECTIVE 3142 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( yylloc,$1 ) ) ); }3127 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( $1 ) ) ); } 3143 3128 | declaration 3144 3129 { … … 3146 3131 // unit, which is a dubious task, especially because C uses name rather than structural typing; hence it is 3147 3132 // disallowed at the moment. 3148 if ( $1->linkage == ast::Linkage::Cforall && ! $1->storageClasses.is_static && $1->type && $1->type->kind == TypeData::AggregateInst ) {3133 if ( $1->linkage == LinkageSpec::Cforall && ! $1->storageClasses.is_static && $1->type && $1->type->kind == TypeData::AggregateInst ) { 3149 3134 if ( $1->type->aggInst.aggregate->kind == TypeData::Enum && $1->type->aggInst.aggregate->enumeration.anon ) { 3150 3135 SemanticError( yylloc, "extern anonymous enumeration is currently unimplemented." ); $$ = nullptr; … … 3173 3158 } 3174 3159 | ASM '(' string_literal ')' ';' // GCC, global assembler statement 3175 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( yylloc,false, $3, nullptr ) ) ); }3160 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( false, $3, nullptr ) ) ); } 3176 3161 | EXTERN STRINGliteral 3177 3162 { 3178 3163 linkageStack.push( linkage ); // handle nested extern "C"/"Cforall" 3179 linkage = ast::Linkage::update( yylloc, linkage, $2 );3164 linkage = LinkageSpec::update( yylloc, linkage, $2 ); 3180 3165 } 3181 3166 up external_definition down … … 3188 3173 { 3189 3174 linkageStack.push( linkage ); // handle nested extern "C"/"Cforall" 3190 linkage = ast::Linkage::update( yylloc, linkage, $2 );3175 linkage = LinkageSpec::update( yylloc, linkage, $2 ); 3191 3176 } 3192 3177 '{' up external_definition_list_opt down '}' … … 3312 3297 subrange: 3313 3298 constant_expression '~' constant_expression // CFA, integer subrange 3314 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc,maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }3299 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); } 3315 3300 ; 3316 3301 … … 3841 3826 array_type_list: 3842 3827 basic_type_name 3843 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $1 ) ) ); }3828 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); } 3844 3829 | type_name 3845 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $1 ) ) ); }3830 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); } 3846 3831 | assignment_expression upupeq assignment_expression 3847 3832 | array_type_list ',' basic_type_name 3848 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $3 ) ) ) )); }3849 | array_type_list ',' type_name 3850 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $3 ) ) ) )); }3833 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); } 3834 | array_type_list ',' type_name 3835 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); } 3851 3836 | array_type_list ',' assignment_expression upupeq assignment_expression 3852 3837 ;
Note:
See TracChangeset
for help on using the changeset viewer.