Changeset bc07190


Ignore:
Timestamp:
Jun 29, 2024, 7:33:28 AM (9 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
011c29e
Parents:
62a38e7 (diff), 115ac1ce (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
18 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified libcfa/src/enum.cfa

    r62a38e7 rbc07190  
    44#pragma GCC visibility push(default)
    55
    6 forall(ostype & | basic_ostream(ostype), E, V| CfaEnum(E, V))
    7 ostype & ?|?(ostype& os, E e) {
    8     return os | type_name(e) | "." | label(e);
     6forall( ostype & | basic_ostream(ostype), E, V | CfaEnum(E, V) ) {
     7        ostype & ?|?( ostype& os, E e ) {
     8                return os | label( e );
     9        }
     10        OSTYPE_VOID_IMPL( E )
    911}
    1012
    11 forall(ostype & | basic_ostream(ostype), E| CfaEnum(E, quasi_void))
    12 ostype & ?|?(ostype& os, E e) {
    13     return os | type_name(e) | "." | label(e);
     13forall( ostype & | basic_ostream(ostype), E | CfaEnum(E, quasi_void) )
     14ostype & ?|?( ostype & os, E e ) {
     15    return os | label( e );
    1416}
    1517
    16 forall(ostype & | basic_ostream(ostype), E, V| CfaEnum(E, V)) {
     18forall( E, V | CfaEnum(E, V) ) {                                                // relational operators
    1719    int ?==?(E l, E r) { return posn(l) == posn(r); }
     20    int ?!=?(E l, E r) { return posn(l) != posn(r); }
     21    int ?<?(E l, E r) { return posn(l) < posn(r); }
    1822    int ?<=?(E l, E r) { return posn(l) <= posn(r); }
     23    int ?>?(E l, E r) { return posn(l) > posn(r); }
    1924    int ?>=?(E l, E r) { return posn(l) >= posn(r); }
    20     int ?<?(E l, E r) { return posn(l) < posn(r); }
    21     int ?>?(E l, E r) { return posn(l) > posn(r); }
    2225}
  • TabularUnified libcfa/src/enum.hfa

    r62a38e7 rbc07190  
    33#include "iostream.hfa"
    44
    5 forall(E) trait Bounded {
     5forall( E ) trait Bounded {
    66    E lowerBound();
    77    E upperBound();
    88};
    99
    10 forall(E | Bounded(E)) trait Serial {
    11     unsigned fromInstance(E e);
    12     E fromInt(unsigned i);
    13     E succ(E e);
    14     E pred(E e);
     10forall( E | Bounded(E) ) trait Serial {
     11    unsigned fromInstance( E e );
     12    E fromInt( unsigned i );
     13    E succ( E e );
     14    E pred( E e );
    1515};
    1616
    1717// Design one
    18 forall(E, V | Serial(E)) trait CfaEnum {
    19     char * label(E e);
    20     unsigned int posn(E e);
    21     V value(E e);
    22     char * type_name(E e);
     18forall( E, V | Serial(E) ) trait CfaEnum {
     19    char * label( E e );
     20    unsigned int posn( E e );
     21    V value( E e );
    2322};
    2423
    25 forall(ostype & | basic_ostream(ostype), E, V | CfaEnum(E, V))
    26 ostype & ?|?(ostype&, E);
     24// I/O
    2725
    28 forall(ostype & | basic_ostream(ostype), E| CfaEnum(E, quasi_void))
    29 ostype & ?|?(ostype&, E);
     26forall( ostype & | basic_ostream(ostype), E, V | CfaEnum(E, V) ) {
     27        ostype & ?|?( ostype &, E );
     28        OSTYPE_VOID( E );
     29}
     30
     31forall( ostype & | basic_ostream(ostype), E | CfaEnum(E, quasi_void) )
     32ostype & ?|?( ostype &, E );
    3033
    3134// Design two <- should go for this if we have change the cost model
     
    3942// };
    4043
    41 forall(ostype & | basic_ostream(ostype), E, V| CfaEnum(E, V)) {
     44forall( E, V | CfaEnum(E, V) ) {                                                // relational operators
    4245    int ?==?(E, E);
     46    int ?!=?(E, E);
     47    int ?<?(E, E);
    4348    int ?<=?(E, E);
     49    int ?>?(E, E);
    4450    int ?>=?(E, E);
    45     int ?<?(E, E);
    46     int ?>?(E, E);
    47 
    48         // E ++?( E & lhs );
    49         // E ?++( E & lhs );
    5051}
  • TabularUnified src/AST/Decl.cpp

    r62a38e7 rbc07190  
    203203}
    204204
     205bool EnumDecl::isTyped() const { return base;}
     206
     207bool EnumDecl::isOpague() const { return isCfa && !isTyped(); }
    205208}
    206209
  • TabularUnified src/AST/Decl.hpp

    r62a38e7 rbc07190  
    308308class EnumDecl final : public AggregateDecl {
    309309public:
    310         // isTyped indicated if the enum has a declaration like:
     310        // isCfa indicated if the enum has a declaration like:
    311311        // enum (type_optional) Name {...}
    312         bool isTyped;
    313         // if isTyped == true && base.get() == nullptr, it is a "void" type enum
     312        bool isCfa;
     313        // if isCfa == true && base.get() == nullptr, it is a "opague" enum
    314314        ptr<Type> base;
    315315        enum class EnumHiding { Visible, Hide } hide;
    316316        std::vector< ast::ptr<ast::EnumInstType>> inlinedDecl; // child enums
    317317
    318         EnumDecl( const CodeLocation& loc, const std::string& name, bool isTyped = false,
     318        EnumDecl( const CodeLocation& loc, const std::string& name, bool isCfa = false,
    319319                std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall,
    320320                Type const * base = nullptr, EnumHiding hide = EnumHiding::Hide,
    321321                std::unordered_map< std::string, long long > enumValues = std::unordered_map< std::string, long long >() )
    322         : AggregateDecl( loc, name, std::move(attrs), linkage ), isTyped(isTyped), base(base), hide(hide), enumValues(enumValues) {}
     322        : AggregateDecl( loc, name, std::move(attrs), linkage ), isCfa(isCfa), base(base), hide(hide), enumValues(enumValues) {}
    323323
    324324        /// gets the integer value for this enumerator, returning true iff value found
     
    336336
    337337        bool isSubTypeOf(const ast::EnumDecl *) const;
     338        bool isTyped() const;
     339        bool isOpague() const;
    338340private:
    339341        EnumDecl * clone() const override { return new EnumDecl{ *this }; }
  • TabularUnified src/AST/Stmt.hpp

    r62a38e7 rbc07190  
    238238        ptr<Expr> inc;
    239239        ptr<Expr> range_over;
     240        bool is_inc;
    240241        ptr<Stmt> body;
    241242        ptr<Stmt> else_;
     
    251252                        range_over(nullptr), body(body), else_(else_) {}
    252253
    253         ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * range_over,
     254        ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * range_over, bool is_inc,
    254255                         const Stmt * body, const Stmt * else_ )
    255                 : Stmt(loc, std::move(labels)), inits(std::move(inits)), range_over(range_over), body(body), else_(else_) {}
     256                : Stmt(loc, std::move(labels)), inits(std::move(inits)), range_over(range_over), is_inc(is_inc),
     257                body(body), else_(else_) {}
    256258
    257259        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
  • TabularUnified src/Common/Stats/Heap.cpp

    r62a38e7 rbc07190  
    2121#include <iostream>
    2222
    23 #if defined(__has_feature)
     23// Most of the other statistics features are deactivated only by defining
     24// NO_STATISTICS (or their NO_%_STATISTICS macro). However the heap has some
     25// other compatability concerns and will disable itself in some cases.
     26//
     27// I do not claim to understand these cases. But TCMALLOC is often defined by
     28// default and you can pass --disable-gprofiler to configure to remove it.
     29
     30#if defined(NO_STATISTICS) || defined(TCMALLOC) || defined(__SANITIZE_ADDRESS__)
     31        #define NO_HEAP_STATISTICS
     32#elif defined(__has_feature)
    2433        #if __has_feature(address_sanitizer)
    25                 #define NO_HEAP_STATISTICS
    26         # endif
    27 #endif
    28 
    29 #if defined( NO_STATISTICS ) || defined( TCMALLOC ) || defined(__SANITIZE_ADDRESS__)
    30         #if !defined(NO_HEAP_STATISTICS)
    3134                #define NO_HEAP_STATISTICS
    3235        #endif
  • TabularUnified src/ControlStruct/TranslateEnumRange.cpp

    r62a38e7 rbc07190  
    2626        auto enumDecl = enumInst->base;
    2727
    28         auto init = stmt->inits.front();
     28        auto objInit = stmt->inits.front();
    2929
    30         if (auto declStmt = init.as<ast::DeclStmt>()) {
     30        auto initLocation = objInit->location;
     31        auto rangeLocation = stmt->range_over->location;
     32        assert( stmt->inits.size() == 1 );
     33
     34        if (auto declStmt = objInit.as<ast::DeclStmt>()) {
    3135            auto decl = declStmt->decl;
    3236            if ( auto objDecl = decl.as<ast::ObjectDecl>()) {
     
    5761                if ( !objDecl->init ) {
    5862                    auto location = stmt->location;
    59                     auto newInit = new ast::SingleInit( location, new ast::NameExpr( location, enumDecl->members.front()->name ) );
     63                    ast::SingleInit * newInit;
     64                    newInit = new ast::SingleInit( location,
     65                        new ast::NameExpr( location,
     66                        stmt->is_inc? enumDecl->members.front()->name: enumDecl->members.back()->name ) );
    6067                    auto objDeclWithInit = ast::mutate_field( objDecl, &ast::ObjectDecl::init, newInit );
    6168                    auto declWithInit = ast::mutate_field( declStmt, &ast::DeclStmt::decl, objDeclWithInit );
     
    7885    auto enumInst = typeExpr->type.strict_as<ast::EnumInstType>();
    7986    auto enumDecl = enumInst->base;
     87   
     88    // Both inc and dec check if the current posn less than the number of enumerator
     89    // for dec, it keeps call pred until it passes 0 (the first enumerator) and underflow,
     90    // it wraps around and become unsigned max
     91    ast::UntypedExpr * condition = ast::UntypedExpr::createCall( location,
     92        "?<=?",
     93        {new ast::CastExpr(location,
     94            new ast::NameExpr( location, indexName ),
     95            new ast::BasicType( ast::BasicKind::UnsignedInt ),
     96            ast::GeneratedFlag::ExplicitCast),
     97        ast::ConstantExpr::from_ulong( location, enumDecl->members.size()-1 ) });
    8098
    81     auto condition = ast::UntypedExpr::createCall( location, "?<=?", {
    82         new ast::NameExpr( location, indexName ),
    83         // ast::ConstantExpr::from_ulong( location, enumDecl->members.size() )
    84         new ast::NameExpr( location, enumDecl->members.back()->name )
    85     });
    86     auto increment = ast::UntypedExpr::createCall( location, "succ", {
    87         new ast::NameExpr( location, indexName )
    88     });
     99    auto increment = ast::UntypedExpr::createCall( location,
     100        stmt->is_inc? "?++": "?--",
     101        { new ast::NameExpr( location, indexName ) });
     102   
    89103    auto assig = ast::UntypedExpr::createAssign( location, new ast::NameExpr( location, indexName ), increment );
    90104    auto mut = ast::mutate_field( stmt, &ast::ForStmt::cond, condition );
  • TabularUnified src/Parser/StatementNode.cpp

    r62a38e7 rbc07190  
    216216                return new ast::ForStmt( location,
    217217                        std::move( astinit ),
    218                         range_over,
     218                        range_over, forctl->kind == OperKinds::LThan,
    219219                        buildMoveSingle( stmt ),
    220220                        buildMoveOptional( else_ )
  • TabularUnified src/Parser/StatementNode.hpp

    r62a38e7 rbc07190  
    6464        ForCtrl( StatementNode * stmt, ExpressionNode * condition, ExpressionNode * change ) :
    6565                init( stmt ), condition( condition ), change( change ), range_over( nullptr ) {}
    66         ForCtrl( StatementNode * decl, ExpressionNode * _range_over) :
    67                 init( decl ), condition( nullptr ), change( nullptr ),  range_over( _range_over ) {}
     66        ForCtrl( StatementNode * decl, ExpressionNode * range_over, OperKinds kind ) :
     67                init( decl ), condition( nullptr ), change( nullptr ),  range_over( range_over ), kind( kind ) {}
    6868
    6969        StatementNode * init;
     
    7171        ExpressionNode * change;
    7272        ExpressionNode * range_over;
     73        OperKinds kind;
    7374};
    7475
  • TabularUnified src/Parser/TypeData.cpp

    r62a38e7 rbc07190  
    14691469                ast::ObjectDecl * object = strict_dynamic_cast<ast::ObjectDecl *>( member );
    14701470                object->isHidden = ast::EnumDecl::EnumHiding::Hide == ret->hide;
    1471                 if ( ret->isTyped && !ret->base && cur->has_enumeratorValue() ) {
    1472                         SemanticError( td->location, "Enumerator of enum(void) cannot have an explicit initializer value." );
     1471                if ( ret->isOpague() && cur->has_enumeratorValue() ) {
     1472                        SemanticError( td->location, "Opague cannot have an explicit initializer value." );
    14731473                } else if ( cur->has_enumeratorValue() ) {
    14741474                        object->init = new ast::SingleInit(
  • TabularUnified src/Parser/lex.ll

    r62a38e7 rbc07190  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Thu Jun 20 16:54:05 2024
    13  * Update Count     : 778
     12 * Last Modified On : Thu Jun 27 14:38:27 2024
     13 * Update Count     : 780
    1414 */
    1515
     
    458458
    459459"@="                    { NAMEDOP_RETURN(ATassign); }                   // CFA
     460"+~"                    { NAMEDOP_RETURN(ErangeUp); }                   // CFA
    460461"~="                    { NAMEDOP_RETURN(ErangeUpEq); }                 // CFA
     462"+~="                   { NAMEDOP_RETURN(ErangeUpEq); }                 // CFA
    461463"-~"                    { NAMEDOP_RETURN(ErangeDown); }                 // CFA
    462464"-~="                   { NAMEDOP_RETURN(ErangeDownEq); }               // CFA
  • TabularUnified src/Parser/parser.yy

    r62a38e7 rbc07190  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jun 24 22:45:20 2024
    13 // Update Count     : 6684
     12// Last Modified On : Thu Jun 27 14:45:57 2024
     13// Update Count     : 6705
    1414//
    1515
     
    224224#define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right)
    225225#define MISSING_ANON_FIELD "illegal syntax, missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body."
    226 #define MISSING_LOW "illegal syntax, missing low value for up-to range so index is uninitialized."
    227 #define MISSING_HIGH "illegal syntax, missing high value for down-to range so index is uninitialized."
    228 
    229 static ForCtrl * makeForCtrl( const CodeLocation & location, DeclarationNode * init, enum OperKinds compop,
    230                                                           ExpressionNode * comp, ExpressionNode * inc ) {
     226#define MISSING_LOW "illegal syntax, missing low value for ascanding range so index is uninitialized."
     227#define MISSING_HIGH "illegal syntax, missing high value for descending range so index is uninitialized."
     228
     229static ForCtrl * makeForCtrl( const CodeLocation & location, DeclarationNode * init, OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    231230        // Wrap both comp/inc if they are non-null.
    232231        if ( comp ) comp = new ExpressionNode( build_binary_val( location,
     
    243242}
    244243
    245 ForCtrl * forCtrl( const CodeLocation & location, DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     244ForCtrl * forCtrl( const CodeLocation & location, DeclarationNode * index, ExpressionNode * start, OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    246245        if ( index->initializer ) {
    247246                SemanticError( yylloc, "illegal syntax, direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." );
     
    254253} // forCtrl
    255254
    256 ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     255ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, string * index, ExpressionNode * start, OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    257256        ast::ConstantExpr * constant = dynamic_cast<ast::ConstantExpr *>(type->expr.get());
    258257        if ( constant && (constant->rep == "0" || constant->rep == "1") ) {
     
    268267#define MISSING_LOOP_INDEX "illegal syntax, only a single identifier or declaration allowed in initialization, e.g., for ( i; ... ) or for ( int i; ... ). Expression disallowed."
    269268
    270 ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     269ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    271270        if ( auto identifier = dynamic_cast<ast::NameExpr *>(index->expr.get()) ) {
    272271                return forCtrl( location, type, new string( identifier->name ), start, compop, comp, inc );
    273         // } else if ( auto commaExpr = dynamic_cast<ast::CommaExpr *>( index->expr.get() ) ) {
    274         //      if ( auto identifier = commaExpr->arg2.as<ast::NameExpr>() ) {
    275         //              return forCtrl( location, type, new string( identifier->name ), start, compop, comp, inc );
    276         //      } else {
    277         //              SemanticError( yylloc, "illegal syntax, loop-index name missing. Expression disallowed." ); return nullptr;
    278         //      } // if
    279272        } else {
    280273                SemanticError( yylloc, MISSING_LOOP_INDEX ); return nullptr;
     
    282275} // forCtrl
    283276
    284 ForCtrl * enumRangeCtrl( ExpressionNode * index_expr, ExpressionNode * range_over_expr ) {
     277ForCtrl * enumRangeCtrl( ExpressionNode * index_expr, __attribute__((unused)) OperKinds compop, ExpressionNode * range_over_expr ) {
    285278        if ( auto identifier = dynamic_cast<ast::NameExpr *>(index_expr->expr.get()) ) {
    286279                DeclarationNode * indexDecl = DeclarationNode::newName( new std::string(identifier->name) );
    287280                assert( range_over_expr );
    288                 return new ForCtrl( new StatementNode( indexDecl ), range_over_expr );
    289         // } else if (auto commaExpr = dynamic_cast<ast::CommaExpr *>( index_expr->expr.get() )) {
    290         //      if ( auto identifier = commaExpr->arg1.as<ast::NameExpr>() ) {
    291         //              assert( range_over_expr );
    292         //              DeclarationNode * indexDecl = distAttr(
    293         //                      DeclarationNode::newTypeof( range_over_expr, true ),
    294         //                      DeclarationNode::newName( new std::string( identifier->name) ) );
    295         //              return new ForCtrl( new StatementNode( indexDecl ), range_over_expr );
    296         //      } else {
    297         //              SemanticError( yylloc, "illegal syntax, loop-index name missing. Comma expression disallowed." ); return nullptr;
    298         //      } // if
     281                return new ForCtrl( new StatementNode( indexDecl ), range_over_expr, compop );
    299282        } else {
    300283                SemanticError( yylloc, MISSING_LOOP_INDEX ); return nullptr;
     
    426409%token ANDassign        ERassign        ORassign                                // &=   ^=      |=
    427410
    428 %token ErangeUpEq       ErangeDown      ErangeDownEq                    // ~=   -~      -~=
     411%token ErangeUp         ErangeUpEq      ErangeDown      ErangeDownEq // +~      +~=/~=  -~      -~=
    429412%token ATassign                                                                                 // @=
    430413
     
    15221505                { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    15231506
     1507                // These rules accept a comma_expression for the initialization, when only an identifier is correct. Being
     1508                // permissive allows for a better error message from forCtrl.
    15241509        | comma_expression ';' comma_expression                         // CFA
    15251510                { $$ = forCtrl( yylloc, $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }
     
    15411526                }
    15421527        | comma_expression ';' '@' updowneq '@'                         // CFA, invalid syntax rule
    1543                 { SemanticError( yylloc, "illegal syntax, missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
     1528                { SemanticError( yylloc, "illegal syntax, missing low/high value for ascending/descending range so index is uninitialized." ); $$ = nullptr; }
    15441529
    15451530        | comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA
     
    15701555                }
    15711556        | comma_expression ';' '@' updowneq '@' '~' '@' // CFA
    1572                 { SemanticError( yylloc, "illegal syntax, missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
     1557                { SemanticError( yylloc, "illegal syntax, missing low/high value for ascending/descending range so index is uninitialized." ); $$ = nullptr; }
    15731558
    15741559        | declaration comma_expression                                          // CFA
     
    16181603                }
    16191604        | declaration '@' updowneq '@' '~' '@'                          // CFA, invalid syntax rule
    1620                 { SemanticError( yylloc, "illegal syntax, missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
     1605                { SemanticError( yylloc, "illegal syntax, missing low/high value for ascending/descending range so index is uninitialized." ); $$ = nullptr; }
    16211606
    16221607        | comma_expression ';' enum_key                                         // CFA, enum type
    16231608                {
    1624                         $$ = enumRangeCtrl( $1, new ExpressionNode( new ast::TypeExpr( yylloc, $3->buildType() ) ) );
     1609                        $$ = enumRangeCtrl( $1, OperKinds::LEThan, new ExpressionNode( new ast::TypeExpr( yylloc, $3->buildType() ) ) );
    16251610                }
    16261611        | comma_expression ';' downupdowneq enum_key            // CFA, enum type, reverse direction
    16271612                {
    1628                         if ( $3 == OperKinds::LEThan || $3 == OperKinds::GEThan ) {
    1629                                 SemanticError( yylloc, "illegal syntax, all enumeration ranges are equal (all values). Remove \"=~\"." ); $$ = nullptr;
    1630                         }
    1631                         SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr;
     1613                        if ( $3 == OperKinds::GThan ) {
     1614                                SemanticError( yylloc, "all enumeration ranges are equal (all values). Add an equal, e.g., ~=, -~=." ); $$ = nullptr;
     1615                                $3 = OperKinds::GEThan;
     1616                        } // if
     1617                        $$ = enumRangeCtrl( $1, $3, new ExpressionNode( new ast::TypeExpr( yylloc, $4->buildType() ) ) );
    16321618                }
    16331619        ;
     
    16421628        ;
    16431629
     1630// This rule exists to handle the ambiguity with unary operator '~'. The rule is the same as updowneq minus the '~'.
     1631// Specifically, "for ( ~5 )" means the complement of 5, not loop 0..4. Hence, in this case "for ( ~= 5 )", i.e., 0..5,
     1632// it is not possible to just remove the '='. The entire '~=' must be removed.
    16441633downupdowneq:
    1645         ErangeDown
     1634        ErangeUp
     1635                { $$ = OperKinds::LThan; }
     1636        | ErangeDown
    16461637                { $$ = OperKinds::GThan; }
    16471638        | ErangeUpEq
     
    16521643
    16531644updown:
    1654         '~'
     1645        '~'                                                                                                     // shorthand 0 ~ 10 => 0 +~ 10
     1646                { $$ = OperKinds::LThan; }
     1647        | ErangeUp
    16551648                { $$ = OperKinds::LThan; }
    16561649        | ErangeDown
  • TabularUnified src/ResolvExpr/CandidateFinder.cpp

    r62a38e7 rbc07190  
    698698                void postvisit( const ast::CountExpr * countExpr );
    699699
    700                 const ast::Expr * makeEnumOffsetCast( const ast::EnumInstType * src,
    701                         const ast::EnumInstType * dst
    702                         , const ast::Expr * expr, Cost minCost );
    703 
    704700                void postvisit( const ast::InitExpr * ) {
    705701                        assertf( false, "CandidateFinder should never see a resolved InitExpr." );
     
    12131209        }
    12141210
    1215         // src is a subset of dst
    1216         const ast::Expr * Finder::makeEnumOffsetCast( const ast::EnumInstType * src,
    1217                 const ast::EnumInstType * dst,
    1218                 const ast::Expr * expr,
    1219                 Cost minCost ) {
    1220                
    1221                 auto srcDecl = src->base;
    1222                 auto dstDecl = dst->base;
    1223 
    1224                 if (srcDecl->name == dstDecl->name) return expr;
    1225 
    1226                 for (auto& dstChild: dstDecl->inlinedDecl) {
    1227                         Cost c = castCost(src, dstChild, false, symtab, tenv);
    1228                         ast::CastExpr * castToDst;
    1229                         if (c<minCost) {
    1230                                 unsigned offset = dstDecl->calChildOffset(dstChild.get());
    1231                                 if (offset > 0) {
    1232                                         auto untyped = ast::UntypedExpr::createCall(
    1233                                                 expr->location,
    1234                                                 "?+?",
    1235                                                 { new ast::CastExpr( expr, new ast::BasicType(ast::BasicKind::SignedInt) ),
    1236                                                 ast::ConstantExpr::from_int(expr->location, offset)});
    1237                                         CandidateFinder finder(context, tenv);
    1238                                         finder.find( untyped );
    1239                                         CandidateList winners = findMinCost( finder.candidates );
    1240                                         CandidateRef & choice = winners.front();
    1241                                         // choice->expr = referenceToRvalueConversion( choice->expr, choice->cost );
    1242                                         choice->expr = new ast::CastExpr(expr->location, choice->expr, dstChild, ast::GeneratedFlag::ExplicitCast);
    1243                                         // castToDst = new ast::CastExpr(choice->expr, dstChild);
    1244                                         castToDst = new ast::CastExpr(
    1245                                                 makeEnumOffsetCast( src, dstChild, choice->expr, minCost ),
    1246                                          dst);
    1247 
    1248                                 } else {
    1249                                         castToDst = new ast::CastExpr( expr, dst );
    1250                                 }
    1251                                 return castToDst;
    1252                         }
    1253                 }
    1254                 SemanticError(expr, src->base->name + " is not a subtype of " + dst->base->name);
    1255                 return nullptr;
    1256         }
    1257 
    12581211        void Finder::postvisit( const ast::CastExpr * castExpr ) {
    12591212                ast::ptr< ast::Type > toType = castExpr->result;
     
    13091262                        auto argAsEnum = cand->expr->result.as<ast::EnumInstType>();
    13101263                        auto toAsEnum = toType.as<ast::EnumInstType>();
    1311                         if ( argAsEnum && toAsEnum && argAsEnum->name != toAsEnum->name ) {     
    1312                                 ast::ptr<ast::Expr> offsetExpr = makeEnumOffsetCast(argAsEnum, toAsEnum, cand->expr, thisCost);
     1264                        if ( argAsEnum && toAsEnum && argAsEnum->name != toAsEnum->name ) {
     1265                                CandidateFinder subFinder(context, tenv);
     1266                                ast::ptr<ast::Expr> offsetExpr = subFinder.makeEnumOffsetCast(argAsEnum, toAsEnum, cand->expr, thisCost);
    13131267                                cand->expr = offsetExpr;
    13141268                        }
     
    21932147                                        expr->location,
    21942148                                        "?+?",
    2195                                         { new ast::CastExpr( expr, new ast::BasicType(ast::BasicKind::SignedInt) ),
    2196                                         ast::ConstantExpr::from_int(expr->location, offset)});
     2149                                        { new ast::CastExpr( expr->location,
     2150                                                expr,
     2151                                                new ast::BasicType(ast::BasicKind::SignedInt),
     2152                                                ast::GeneratedFlag::ExplicitCast ),
     2153                                                ast::ConstantExpr::from_int(expr->location, offset)} );
    21972154                                CandidateFinder finder(context, env);
    21982155                                finder.find( untyped );
  • TabularUnified src/ResolvExpr/CastCost.cpp

    r62a38e7 rbc07190  
    5353                void postvisit( const ast::EnumInstType * enumInst ) {
    5454                        cost = conversionCost( enumInst, dst, srcIsLvalue, symtab, env );
     55                        if ( enumInst->base->isTyped() ) {
     56                                auto baseConversionCost =
     57                                        castCost( enumInst->base->base, dst, srcIsLvalue, symtab, env );
     58                                cost = baseConversionCost < cost? baseConversionCost: cost;
     59                        }
     60                        static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
     61                        Cost intCost = costCalc( integer, dst, srcIsLvalue, symtab, env );
     62                        intCost.incSafe();
     63                        cost = intCost < cost? intCost: cost;
    5564                }
    5665
     
    6372                                cost = conversionCost( basicType, dst, srcIsLvalue, symtab, env );
    6473                                if ( Cost::unsafe < cost ) {
    65                                         if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) {
    66                                                 // Always explict cast only for typed enum
    67                                                 if (enumInst->base->isTyped) cost = Cost::unsafe;
     74                                        if ( dynamic_cast<const ast::EnumInstType *>(dst)) {
     75                                                cost = Cost::unsafe;
    6876                                        }
    6977                                }
     
    7482                        cost = conversionCost( zero, dst, srcIsLvalue, symtab, env );
    7583                        if ( Cost::unsafe < cost ) {
    76                                 if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) {
    77                                         if (enumInst->base->isTyped) cost = Cost::unsafe;
     84                                if ( dynamic_cast<const ast::EnumInstType *>(dst)) {
     85                                        cost = Cost::unsafe;
    7886                                }
    7987                        }
     
    8391                        cost = conversionCost( one, dst, srcIsLvalue, symtab, env );
    8492                        if ( Cost::unsafe < cost ) {
    85                                 if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) {
    86                                         if (enumInst->base->isTyped) cost = Cost::unsafe;
     93                                if ( dynamic_cast<const ast::EnumInstType *>(dst)) {
     94                                        cost = Cost::unsafe;
    8795                                }
    8896                        }
  • TabularUnified src/ResolvExpr/CommonType.cpp

    r62a38e7 rbc07190  
    386386                } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
    387387                        const ast::EnumDecl* enumDecl = enumInst->base;
    388                         if ( !enumDecl->base ) {
     388                        if ( !enumDecl->isCfa ) {
    389389                                ast::BasicKind kind = commonTypes[ basic->kind ][ ast::BasicKind::SignedInt ];
    390390                                if (
     
    642642                        const ast::EnumDecl* argDecl = argAsEnumInst->base;
    643643                        if (argDecl->isSubTypeOf(paramDecl)) result = param;
    644                 } else if ( param->base && !param->base->isTyped ) {
     644                } else if ( param->base && !param->base->isCfa ) {
    645645                        auto basicType = new ast::BasicType( ast::BasicKind::UnsignedInt );
    646646                        result = commonType( basicType, type2, tenv, need, have, open, widen);
  • TabularUnified src/ResolvExpr/ConversionCost.cpp

    r62a38e7 rbc07190  
    162162Cost conversionCost(
    163163        const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
    164         const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
     164const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
    165165) {
    166166        if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
     
    235235                        return ast::Pass<ConversionCost>::read( src, dst, srcIsLvalue, symtab, env, conversionCost );
    236236                }
     237                if (const ast::EnumInstType * srcAsInst = dynamic_cast< const ast::EnumInstType * >( src )) {
     238                        if (srcAsInst->base && !srcAsInst->base->isCfa) {
     239                                static const ast::BasicType* integer = new ast::BasicType( ast::BasicKind::UnsignedInt );
     240                                return ast::Pass<ConversionCost>::read( integer, dst, srcIsLvalue, symtab, env, conversionCost );
     241                        }
     242                }
    237243        } else {
    238244                assert( -1 == diff );
    239245                const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
    240246                assert( dstAsRef );
    241                 if ( typesCompatibleIgnoreQualifiers( src, dstAsRef->base, env ) ) {
     247                auto dstBaseType = dstAsRef->base;
     248                const ast::Type * newSrc = src;
     249                if ( dynamic_cast< const ast::EnumInstType * >( src ) && dstBaseType.as<ast::BasicType>() ) {
     250                        newSrc = new ast::BasicType( ast::BasicKind::UnsignedInt );
     251                }
     252                if ( typesCompatibleIgnoreQualifiers( newSrc, dstAsRef->base, env ) ) {
    242253                        if ( srcIsLvalue ) {
    243254                                if ( src->qualifiers == dstAsRef->base->qualifiers ) {
     
    284295        if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
    285296                conversionCostFromBasicToBasic( basicType, dstAsBasic );
    286         }       else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    287                 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
    288                         cost = Cost::unsafe;
     297        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
     298                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
     299                        cost = Cost::safe;
    289300                }
    290301        }
     
    366377        if ( auto dstInst = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
    367378                cost = enumCastCost(inst, dstInst, symtab, env);
    368                 return;
    369         }
    370         static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
    371         cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
    372         if ( !inst->base->isTyped ) {
    373                 if ( cost < Cost::unsafe ) {
    374                         cost.incSafe();
    375                 }
    376                 return;
    377         }
    378         cost.incUnsafe();
     379        } else if ( !inst->base->isCfa ) {
     380                static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
     381                cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
     382        }
     383        // cost.incUnsafe();
    379384}
    380385
     
    454459                // assuming 0p is supposed to be used for pointers?
    455460        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    456                 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
    457                         cost = Cost::unsafe;
     461                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
     462                        cost = Cost::safe;
    458463                }
    459464        }
     
    475480                }
    476481        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    477                 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
    478                         cost = Cost::unsafe;
     482                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
     483                        cost = Cost::safe;
    479484                }
    480485        }
  • TabularUnified src/ResolvExpr/Unify.cpp

    r62a38e7 rbc07190  
    276276        void postvisit( const ast::VoidType * ) {
    277277                result = dynamic_cast< const ast::VoidType * >( type2 );
    278                         // || tryToUnifyWithEnumValue(vt, type2, tenv, need, have, open, noWiden());
    279                 ;
    280278        }
    281279
     
    284282                        result = basic->kind == basic2->kind;
    285283                }
    286                 // result = result || tryToUnifyWithEnumValue(basic, type2, tenv, need, have, open, noWiden());
    287284        }
    288285
     
    293290                                noWiden());
    294291                }
    295                 // result = result || tryToUnifyWithEnumValue(pointer, type2, tenv, need, have, open, noWiden());
    296292        }
    297293
     
    312308                result = unifyExact(
    313309                        array->base, array2->base, tenv, need, have, open, noWiden());
    314                         // || tryToUnifyWithEnumValue(array, type2, tenv, need, have, open, noWiden());
    315310        }
    316311
     
    607602
    608603                result = unifyList( types, types2, tenv, need, have, open );
    609                         // || tryToUnifyWithEnumValue(tuple, type2, tenv, need, have, open, noWiden());
    610604        }
    611605
    612606        void postvisit( const ast::VarArgsType * ) {
    613607                result = dynamic_cast< const ast::VarArgsType * >( type2 );
    614                         // || tryToUnifyWithEnumValue(vat, type2, tenv, need, have, open, noWiden());
    615608        }
    616609
    617610        void postvisit( const ast::ZeroType * ) {
    618611                result = dynamic_cast< const ast::ZeroType * >( type2 );
    619                         // || tryToUnifyWithEnumValue(zt, type2, tenv, need, have, open, noWiden());
    620612        }
    621613
    622614        void postvisit( const ast::OneType * ) {
    623615                result = dynamic_cast< const ast::OneType * >( type2 );
    624                         // || tryToUnifyWithEnumValue(ot, type2, tenv, need, have, open, noWiden());
    625616        }
    626617};
  • TabularUnified src/Validate/ImplementEnumFunc.cpp

    r62a38e7 rbc07190  
    476476
    477477void ImplementEnumFunc::previsit(const ast::EnumDecl* enumDecl) {
    478         if (!enumDecl->body || !enumDecl->isTyped) return;
     478        if (!enumDecl->body || !enumDecl->isCfa) return;
    479479        ast::EnumInstType enumInst(enumDecl->name);
    480480        enumInst.base = enumDecl;
Note: See TracChangeset for help on using the changeset viewer.