Changes in / [97f9619:68ea8d2]


Ignore:
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • Makefile.am

    r97f9619 r68ea8d2  
    1111## Created On       : Sun May 31 22:14:18 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Tue Jul 16 16:59:12 2024
    14 ## Update Count     : 57
     13## Last Modified On : Wed May 17 11:02:34 2023
     14## Update Count     : 56
    1515###############################################################################
    1616
     
    3535man1_MANS = doc/man/cfa.1
    3636
    37 EXTRA_DIST = LICENSE doc/man/cfa.1 libcfa/configure libcfa/Makefile.dist.am libcfa/Makefile.dist.in tools/build/distcc_hash tools/build/push2dist.sh tools/prettyprinter
     37EXTRA_DIST = LICENSE doc/man/cfa.1 libcfa/configure libcfa/Makefile.dist.am libcfa/Makefile.dist.in tools/build/distcc_hash tools/build/push2dist.sh
    3838
    3939debug ?= yes
  • doc/bibliography/pl.bib

    r97f9619 r68ea8d2  
    18631863    key         = {concurrent locking},
    18641864    author      = {Peter A. Buhr and David Dice and Wim H. Hesselink},
    1865     title       = {Concurrent locking algorithms},
     1865    title       = {concurrent-locking},
    18661866    howpublished= {\url{https://github.com/pabuhr/concurrent-locking}},
    18671867}
     
    40014001    organization= {Google},
    40024002    year        = 2009,
    4003     note        = {\url{https://go.dev/ref/spec}},
     4003    note        = {\url{http://golang.org/ref/spec}},
    40044004}
    40054005
     
    41804180    number      = 12,
    41814181    pages       = {2463-2500},
     4182    note        = {\url{https://onlinelibrary.wiley.com/doi/10.1002/spe.3262}},
    41824183}
    41834184
     
    78017802@book{Scott24,
    78027803    author      = {Michael L. Scott and Trevor Brown},
    7803     title       = {Shared-Memory Synchronization},
     7804    booktitle   = {Shared-Memory Synchronization},
    78047805    series      = {Synthesis Lectures on Computer Architecture},
    78057806    edition     = {2nd},
     
    85318532    key         = {TIOBE Index},
    85328533    author      = {{TIOBE Index}},
    8533     howpublished= {\url{https://www.tiobe.com/tiobe-index}},
     8534    howpublished= {\url{http://www.tiobe.com/tiobe_index}},
    85348535}
    85358536
  • doc/user/Makefile

    r97f9619 r68ea8d2  
    66TeXLIB = .:${Macros}:${Build}:
    77LaTeX  = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error -output-directory=${Build}
    8 BibDir = ../bibliography
    9 BibTeX = BIBINPUTS=${BibDir}: && export BIBINPUTS && bibtex
     8BibTeX = BIBINPUTS=../bibliography: && export BIBINPUTS && bibtex
    109
    1110MAKEFLAGS = --no-print-directory --silent #
     
    6261
    6362${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${Macros}/common.tex ${Macros}/common.sty \
    64                 ${Macros}/lstlang.sty ${Macros}/indexstyle ${BibDir}/pl.bib build/version | ${Build}
     63                ${Macros}/lstlang.sty ${Macros}/indexstyle ../bibliography/pl.bib build/version | ${Build}
    6564        # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run.
    6665        if [ ! -r ${basename $@}.ind ] ; then touch ${Build}/${basename $@}.ind ; fi
  • libcfa/src/enum.cfa

    r97f9619 r68ea8d2  
    4242        if ( eof( is ) ) throwResume ExceptionInst( missing_data );
    4343
    44         // Match longest input enumerator string to enumerator labels, where enumerator names are unique.
    45 
     44        // Match input enumerator string to enumerator labels.
    4645        int N = Countof( e ), lnths[N], max = 0;
    4746//      printf( "N %d\n", N );
     
    6160        for ( c; max ) {
    6261                int args = fmt( is, "%c", &ch );                                // read character
    63           if ( eof( is ) ) {
     62                if ( eof( is ) ) {
    6463//                      fprintf( stderr, "Eof1\n" );
    6564                        if ( c == 0 ) return is;                                        // no characters read ?
    66                         clear( is );                                                            // => read something => reset EOF => detect again on next read
     65                        clear( is );                                                            // => reset EOF => detect again on next read
    6766//                      fprintf( stderr, "Eof2\n" );
    68                         break;
    69                 } // if
     67                        goto W;
     68                }
    7069                if ( args != 1 ) throwResume ExceptionInst( missing_data );
    71 
    7270//              printf( "read '%c'\n", ch );
    73                 for ( i; N ) {                                                                  // scan enumeration strings for winner
     71                for ( i; N ) {
    7472//                      printf( "%d %d %d\n", c, i, lnths[i] );
    7573                        if ( c < lnths[i] ) {                                           // eligible for this checking round ?
    7674                                char match = label( fromInt( i ) )[c];  // optimization
    7775//                              printf( "%c '%c'\n", match, ch );
    78                                 // Stop on first match, could be other matches.
    7976                                if ( (match == ch) && (c == 0 || curr == label( fromInt( i ) )[c - 1]) ) {
    8077//                                      printf( "match %d %d %d '%c' '%c' '%c' '%c' 'c'\n", c, i, lnths[i], match, ch, prev, label( fromInt( i ) )[c - 1] );
     
    9592//              fprintf( stderr, "finished2 %d\n", win );
    9693        } // for
    97   W: ;
    98         for ( i; N ) {                                                                          // scan enumeration strings for winner
     94  W :;
     95        for ( i; N ) {                                                                          // scan for winner, must succeed
    9996                if ( win == lnths[i] - 1 ) {
    10097                        char match = label( fromInt( i ) )[win];        // optimization
     
    103100                                e = fromInt( i );
    104101                                break;
    105                         } // if
     102                        }
    106103                } // if
    107104        } else {
  • libcfa/src/iostream.cfa

    r97f9619 r68ea8d2  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jul 15 08:16:48 2024
    13 // Update Count     : 2020
     12// Last Modified On : Fri Jul 12 05:45:45 2024
     13// Update Count     : 2019
    1414//
    1515
     
    781781                // Optional leading whitespace at start of strings.
    782782                fmt( is, " " FALSE "%n", &len );                                // try false
    783                 if ( len != sizeof( FALSE ) - 1 ) {                             // -1 removes null terminate
     783                if ( len != sizeof( FALSE ) - 1 ) {                             // remove null terminate
    784784                        fmt( is, " " TRUE "%n", &len );                         // try true
    785785                        if ( len != sizeof( TRUE ) - 1 ) throwResume ExceptionInst( missing_data );
  • src/AST/Print.cpp

    r97f9619 r68ea8d2  
    566566                ++indent;
    567567                safe_print( node->cond );
     568                os << indent-1 << "... with body:" << endl;
     569                safe_print( node->body );
    568570
    569571                if ( ! node->inits.empty() ) {
     
    571573                        printAll( node->inits );
    572574                }
    573 
    574                 os << indent-1 << "... with body:" << endl;
    575                 safe_print( node->body );
    576 
    577                 if ( node->else_ ) {
    578                         os << indent-1 << "... with else:" << endl;
    579                         os << indent;
    580                         node->else_->accept( *this );
    581                 }
    582 
    583575                --indent;
    584576
     
    622614                        --indent;
    623615                }
    624 
    625                 if ( node->else_ ) {
    626                         os << indent << "... with else:" << endl;
    627                         ++indent;
    628                         os << indent;
    629                         node->else_->accept( *this );
    630                         --indent;
    631                 }
    632 
    633616                os << endl;
    634617                print( node->labels );
  • src/CodeGen/CodeGenerator.cpp

    r97f9619 r68ea8d2  
    11951195        stmt->body->accept( *visitor );
    11961196
     1197        output << indent;
     1198
    11971199        if ( stmt->isDoWhile ) {
    11981200                output << " while (";
    11991201                stmt->cond->accept( *visitor );
    1200                 output << ( ( nullptr == stmt->else_ ) ? ");" : ")" );
    1201         }
    1202         if ( stmt->else_ ) {
    1203                 output << " else ";
    1204                 stmt->else_->accept( *visitor );
     1202                output << ");";
    12051203        }
    12061204}
     
    12271225                stmt->body->accept( *visitor );
    12281226        }
    1229 
    1230         if ( nullptr != stmt->else_ ) {
    1231                 assertf( !options.genC, "Loop else should not reach code generation." );
    1232                 output << " else ";
    1233                 stmt->else_->accept( *visitor );
    1234         }
    12351227}
    12361228
  • src/ControlStruct/MultiLevelExit.cpp

    r97f9619 r68ea8d2  
    7878                stmt( stmt ), firstTarget( breakExit ), secondTarget(), kind( TryStmtK ) {}
    7979
    80         // Check if this entry can be the target of the given type of control flow.
    8180        bool isContTarget() const { return kind <= WhileDoStmtK; }
    8281        bool isBreakTarget() const { return kind != CaseClauseK; }
     
    208207
    209208        // If the label is empty, do not add unused attribute.
    210         if ( originalTarget.empty() ) return size;
     209  if ( originalTarget.empty() ) return size;
    211210
    212211        // Search for a label that matches the originalTarget.
     
    344343                assert(0);
    345344        }
    346         assert( !exitLabel.empty() );
    347345
    348346        // Add unused attribute to silence warnings.
     
    488486                }
    489487
    490                 auto mutCase = mutStmt->cases.back().get_and_mutate();
     488                auto caseStmt = mutStmt->cases.back().get();
     489                auto mutCase = mutate( caseStmt );
     490                mutStmt->cases.back() = mutCase;
    491491
    492492                Label label( mutCase->location, "breakLabel" );
     
    597597template<typename LoopNode>
    598598void MultiLevelExitCore::prehandleLoopStmt( const LoopNode * loopStmt ) {
    599         // Create temporary labels and mark the enclosing loop before traversal.
     599        // Remember is loop before going onto mutate the body.
    600600        // The labels will be folded in if they are used.
    601601        Label breakLabel = newLabel( "loopBreak", loopStmt );
    602602        Label contLabel = newLabel( "loopContinue", loopStmt );
    603603        enclosing_control_structures.emplace_back( loopStmt, breakLabel, contLabel );
    604 
     604        // labels are added temporarily to see if they are used and then added permanently in postvisit if ther are used
     605        // children will tag labels as being used during their traversal which occurs before postvisit
     606
     607        // GuardAction calls the lambda after the node is done being visited
    605608        GuardAction( [this](){ enclosing_control_structures.pop_back(); } );
    606 
    607         // Because of fixBlock, this should be empty now (and must be).
    608         assert( nullptr == loopStmt->else_ );
    609609}
    610610
     
    617617        // Now check if the labels are used and add them if so.
    618618        return mutate_field( loopStmt, &LoopNode::body, mutateLoop( loopStmt->body, entry ) );
     619        // this call to mutate_field compares loopStmt->body and the result of mutateLoop
     620        //              if they are the same the node isn't mutated, if they differ then the new mutated node is returned
     621        //              the stmts will only differ if a label is used
    619622}
    620623
     
    636639
    637640                ptr<Stmt> else_stmt = nullptr;
    638                 const Stmt * to_visit;
     641                const Stmt * loop_kid = nullptr;
    639642                // check if loop node and if so add else clause if it exists
    640                 if ( auto ptr = kid.as<WhileDoStmt>() ; ptr && ptr->else_ ) {
    641                         else_stmt = ptr->else_;
    642                         to_visit = mutate_field( ptr, &WhileDoStmt::else_, nullptr );
    643                 } else if ( auto ptr = kid.as<ForStmt>() ; ptr && ptr->else_ ) {
    644                         else_stmt = ptr->else_;
    645                         to_visit = mutate_field( ptr, &ForStmt::else_, nullptr );
    646                 } else {
    647                         to_visit = kid.get();
    648                 }
    649 
    650                 // This is the main (safe) visit of the child node.
     643                const WhileDoStmt * whilePtr = kid.as<WhileDoStmt>();
     644                if ( whilePtr && whilePtr->else_ ) {
     645                        else_stmt = whilePtr->else_;
     646                        loop_kid = mutate_field( whilePtr, &WhileDoStmt::else_, nullptr );
     647                }
     648                const ForStmt * forPtr = kid.as<ForStmt>();
     649                if ( forPtr && forPtr->else_ ) {
     650                        else_stmt = forPtr->else_;
     651                        loop_kid = mutate_field( forPtr, &ForStmt::else_, nullptr );
     652                }
     653
    651654                try {
    652                         ret.push_back( to_visit->accept( *visitor ) );
     655                        if (else_stmt) ret.push_back( loop_kid->accept( *visitor ) );
     656                        else ret.push_back( kid->accept( *visitor ) );
    653657                } catch ( SemanticErrorException & e ) {
    654658                        errors.append( e );
    655659                }
    656660
    657                 // The following sections handle visiting loop else clause and makes
    658                 // sure breaking from a loop body does not execute that clause.
    659                 Label local_break_label = std::move( break_label );
    660                 break_label = Label( CodeLocation(), "" );
    661 
    662                 if ( else_stmt ) try {
    663                         ret.push_back( else_stmt->accept( *visitor ) );
    664                 } catch ( SemanticErrorException & e ) {
    665                         errors.append( e );
    666                 }
    667 
    668                 if ( !break_label.empty() ) {
     661                if (else_stmt) ret.push_back(else_stmt);
     662
     663                if ( ! break_label.empty() ) {
    669664                        ret.push_back( labelledNullStmt( ret.back()->location, break_label ) );
    670665                        break_label = Label( CodeLocation(), "" );
    671666                }
    672 
    673                 // This handles a break from the body or non-loop statement.
    674                 if ( !local_break_label.empty() ) {
    675                         ret.push_back( labelledNullStmt( ret.back()->location, local_break_label ) );
    676                 }
    677         }
    678 
    679         if ( !errors.isEmpty() ) {
     667        }
     668
     669        if ( ! errors.isEmpty() ) {
    680670                throw errors;
    681671        }
  • tests/ctrl-flow/.expect/loop_else.txt

    r97f9619 r68ea8d2  
    6363(10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0)else
    6464
    65 before begin else after
  • tests/ctrl-flow/loop_else.cfa

    r97f9619 r68ea8d2  
    7474                i -= 1.7;
    7575        } else { sout | "else"; }                                                                                                               sout | nl | nl;
    76 
     76       
    7777        enum { N = 10 };
    7878        for ( N ) { sout | "N"; } else { sout | "else"; }                                                       sout | nl;
     
    109109        for ( s; (S){0} -~  (S){10,10} ~ (S){1} ) { sout | s; } else { sout | "else"; } sout | nl;
    110110        for ( s; (S){0} -~= (S){10,10} ) { sout | s; } else { sout | "else"; }           sout | nl;
    111         for ( s; (S){0} -~= (S){10,10} ~ (S){1} ) { sout | s; } else { sout | "else"; } sout | nl;
    112         sout | nl;
    113 
    114         // A break (or a continue) in an else clause should target an outer loop.
    115         sout | "before";
    116         while ( true ) {
    117                 sout | " begin";
    118                 while ( false ) {
    119                         sout | "never";
    120                 } else {
    121                         sout | " else";
    122                         break;
    123                 }
    124                 sout | " end";
    125         }
    126         sout | " after" | nl;
     111        for ( s; (S){0} -~= (S){10,10} ~ (S){1} ) { sout | s; } else { sout | "else"; } sout | nl | nl;
    127112}
Note: See TracChangeset for help on using the changeset viewer.