Changes in / [fbc84ca:e6f1a4b]


Ignore:
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • doc/theses/jiada_liang_MMath/CFAenum.tex

    rfbc84ca re6f1a4b  
    7070As in Section~\ref{s:EnumeratorVisibility}, opening multiple scoped enumerations in a @with@ can result in duplicate enumeration names, but \CFA implicit type resolution and explicit qualification/casting handle ambiguities.
    7171
    72 
    73 \section{Enumeration Pseudo-functions}
    74 
    75 Pseudo-functions are function-like operators that do not result in any run-time computations, \ie like @sizeof@, @alignof@, @typeof@.
    76 A pseudo-function call is often substituted with information extracted from the compilation symbol-table, like storage size or alignment associated with the underlying architecture.
    77 
    78 The attributes of an enumerator are accessed by pseudo-functions @posE@, @valueE@, and @labelE@.
    79 \begin{cfa}
    80 int jane_pos = @posE@( Names.Jane );   $\C{// 2}$
    81 char * jane_value = @valueE@( Names.Jane ); $\C{// "JANE"}$
    82 char * jane_label = @labelE@( Names.Jane ); $\C{// "Jane"}$
    83 sout | posE( Names.Jane) | labelE( Names.Jane ) | valueE( Names.Jane );
    84 \end{cfa}
    85 Note the ability to print all of an enumerator's properties.
     72\section{Enumeration Trait}
     73
     74The header file \lstinline[deletekeywords=enum]{<enum.hfa>} defines the set of traits containing operators and helper functions for @enum@.
     75A \CFA enumeration satisfies all of these traits allowing it to interact with runtime features in \CFA.
     76Each trait is discussed in detail.
     77
     78The trait @Bounded@:
     79\begin{cfa}
     80forall( E ) trait Bounded {
     81        E first();
     82        E last();
     83};
     84\end{cfa}
     85defines the bounds of the enumeration, where @first()@ returns the first enumerator and @last()@ returns the last, \eg:
     86\begin{cfa}
     87Workday day = first();                                  $\C{// Mon}$
     88Planet outermost = last();                              $\C{// NEPTUNE}$
     89\end{cfa}
     90@first()@ and @last()@ are overloaded with return types only, so in the example, the enumeration type is found on the left-hand side of the assignment.
     91Calling either functions without a context results in a type ambiguity, except in the rare case where the type environment has only one enumeration.
     92\begin{cfa}
     93@first();@                                                              $\C{// ambiguous Workday and Planet implement Bounded}$
     94sout | @last()@;
     95Workday day = first();                                  $\C{// day provides type Workday}$
     96void foo( Planet p );
     97foo( last() );                                                  $\C{// parameter provides type Planet}$
     98\end{cfa}
     99
     100The trait @Serial@:
     101\begin{cfa}
     102forall( E | Bounded( E ) ) trait Serial {
     103        unsigned fromInstance( E e );
     104        E fromInt( unsigned int posn );
     105        E succ( E e );
     106        E pred( E e );
     107};
     108\end{cfa}
     109is a @Bounded@ trait, where elements can be mapped to an integer sequence.
     110A type @T@ matching @Serial@ can project to an unsigned @int@ type, \ie an instance of type T has a corresponding integer value.
     111%However, the inverse may not be possible, and possible requires a bound check.
     112The mapping from a serial type to integer is defined by @fromInstance@, which returns the enumerator's position.
     113The inverse operation is @fromInt@, which performs a bound check using @first()@ and @last()@ before casting the integer into an enumerator.
     114Specifically, for enumerator @E@ declaring $N$ enumerators, @fromInt( i )@ returns the $i-1_{th}$ enumerator, if $0 \leq i < N$, or raises the exception @enumBound@.
     115
     116The @Serial@ trait also requires interface functions @succ( E e )@ and @pred( E e )@ be implemented for a serial type, which imply the enumeration positions are consecutive and ordinal.
     117Specifically, if @e@ is the $i_{th}$ enumerator, @succ( e )@ returns the $i+1_{th}$ enumerator when $e \ne last()$, and @pred( e )@ returns the $i-1_{th}$ enumerator when $e \ne first()$.
     118The exception @enumRange@ is raised if the result of either operation is outside the range of type @E@.
     119
     120The trait @TypedEnum@:
     121\begin{cfa}
     122forall( E, T ) trait TypedEnum {
     123        T valueE( E e );
     124        char * labelE( E e );
     125        unsigned int posE( E e );
     126};
     127\end{cfa}
     128captures three basic attributes of an enumeration type: value, label, and position.
     129@TypedEnum@ asserts two types @E@ and @T@, with @T@ being the base type of the enumeration @E@, \eg @enum( T ) E { ... };@.
     130Implementing general functions across all enumeration types is possible by asserting @TypeEnum( E, T )@, \eg:
     131\begin{cfa}
     132forall( E, T | TypeEnum( E, T ) )
     133void printEnum( E e ) {
     134        sout | "Enum "| labelE( e );
     135}
     136printEunm( MARS );
     137\end{cfa}
     138
     139Finally, there is an associated trait defining comparison operators among enumerators.
     140\begin{cfa}
     141forall( E, T | TypedEnum( E, T ) ) {
     142        // comparison
     143        int ?==?( E l, E r );           $\C{// true if l and r are same enumerators}$
     144        int ?!=?( E l, E r );           $\C{// true if l and r are different enumerators}$
     145        int ?!=?( E l, zero_t );        $\C{// true if l is not the first enumerator}$
     146        int ?<?( E l, E r );            $\C{// true if l is an enumerator before r}$
     147        int ?<=?( E l, E r );           $\C{// true if l before or the same as r}$
     148        int ?>?( E l, E r );            $\C{// true if l is an enumerator after r}$
     149        int ?>=?( E l, E r );           $\C{// true if l after or the same as r}$         
     150}
     151\end{cfa}
     152Note, the overloaded operators are defined only when the header @<enum.hfa>@ is included.
     153If not, the compiler converts an enumerator to its value, and applies the operators defined for the value type @E@, \eg:
     154\begin{cfa}
     155// if not include <enum.hfa>
     156enum( int ) Fruits { APPLE = 2, BANANA = 10, CHERRY = 2 };
     157APPLE == CHERRY; // true because valueE( APPLE ) == valueE( CHERRY )
     158
     159#include <enum.hfa>
     160APPLE == CHERRY; // false because posE( APPLE ) != posE( CHERRY )
     161\end{cfa}
     162An enumerator returns its @position@ by default.
     163In particular, @printf( ... )@ from @<stdio.h>@ functions provides no context to its parameter type, so it prints @position@.
     164On the other hand, the pipeline operator @?|?( ostream os, E enumType )@ provides type context for type @E@, and \CFA has overwritten this operator to print the enumeration @value@ over @position@.
     165\begin{cfa}
     166printf( "Position of BANANA is \%d", BANANA ); // Position of BANANA is 1
     167sout | "Value of BANANA is " | BANANA; // Value of BANANA is 10
     168\end{cfa}
     169Programmers can overwrite this behaviour by overloading the pipeline operator themselves.
     170\PAB{This needs discussing because including \lstinline{<enum.hfa>} can change the entire meaning of a program.}
     171
     172
     173% \section{Enumeration Pseudo-functions}
     174
     175% Pseudo-functions are function-like operators that do not result in any run-time computations, \ie like @sizeof@, @alignof@, @typeof@.
     176% A pseudo-function call is often substituted with information extracted from the compilation symbol-table, like storage size or alignment associated with the underlying architecture.
     177
     178% The attributes of an enumerator are accessed by pseudo-functions @posE@, @valueE@, and @labelE@.
     179% \begin{cfa}
     180% int jane_pos = @posE@( Names.Jane );   $\C{// 2}$
     181% char * jane_value = @valueE@( Names.Jane ); $\C{// "JANE"}$
     182% char * jane_label = @labelE@( Names.Jane ); $\C{// "Jane"}$
     183% sout | posE( Names.Jane) | labelE( Names.Jane ) | valueE( Names.Jane );
     184% \end{cfa}
     185% Note the ability to print all of an enumerator's properties.
     186
    86187
    87188
     
    270371
    271372
    272 \section{Enumeration Trait}
    273 
    274 The header file \lstinline[deletekeywords=enum]{<enum.hfa>} defines the set of traits containing operators and helper functions for @enum@.
    275 A \CFA enumeration satisfies all of these traits allowing it to interact with runtime features in \CFA.
    276 Each trait is discussed in detail.
    277 
    278 The trait @Bounded@:
    279 \begin{cfa}
    280 forall( E ) trait Bounded {
    281         E first();
    282         E last();
    283 };
    284 \end{cfa}
    285 defines the bounds of the enumeration, where @first()@ returns the first enumerator and @last()@ returns the last, \eg:
    286 \begin{cfa}
    287 Workday day = first();                                  $\C{// Mon}$
    288 Planet outermost = last();                              $\C{// NEPTUNE}$
    289 \end{cfa}
    290 @first()@ and @last()@ are overloaded with return types only, so in the example, the enumeration type is found on the left-hand side of the assignment.
    291 Calling either functions without a context results in a type ambiguity, except in the rare case where the type environment has only one enumeration.
    292 \begin{cfa}
    293 @first();@                                                              $\C{// ambiguous Workday and Planet implement Bounded}$
    294 sout | @last()@;
    295 Workday day = first();                                  $\C{// day provides type Workday}$
    296 void foo( Planet p );
    297 foo( last() );                                                  $\C{// parameter provides type Planet}$
    298 \end{cfa}
    299 
    300 The trait @Serial@:
    301 \begin{cfa}
    302 forall( E | Bounded( E ) ) trait Serial {
    303         unsigned fromInstance( E e );
    304         E fromInt( unsigned int posn );
    305         E succ( E e );
    306         E pred( E e );
    307 };
    308 \end{cfa}
    309 is a @Bounded@ trait, where elements can be mapped to an integer sequence.
    310 A type @T@ matching @Serial@ can project to an unsigned @int@ type, \ie an instance of type T has a corresponding integer value.
    311 %However, the inverse may not be possible, and possible requires a bound check.
    312 The mapping from a serial type to integer is defined by @fromInstance@, which returns the enumerator's position.
    313 The inverse operation is @fromInt@, which performs a bound check using @first()@ and @last()@ before casting the integer into an enumerator.
    314 Specifically, for enumerator @E@ declaring $N$ enumerators, @fromInt( i )@ returns the $i-1_{th}$ enumerator, if $0 \leq i < N$, or raises the exception @enumBound@.
    315 
    316 The @Serial@ trait also requires interface functions @succ( E e )@ and @pred( E e )@ be implemented for a serial type, which imply the enumeration positions are consecutive and ordinal.
    317 Specifically, if @e@ is the $i_{th}$ enumerator, @succ( e )@ returns the $i+1_{th}$ enumerator when $e \ne last()$, and @pred( e )@ returns the $i-1_{th}$ enumerator when $e \ne first()$.
    318 The exception @enumRange@ is raised if the result of either operation is outside the range of type @E@.
    319 
    320 The trait @TypedEnum@:
    321 \begin{cfa}
    322 forall( E, T ) trait TypedEnum {
    323         T valueE( E e );
    324         char * labelE( E e );
    325         unsigned int posE( E e );
    326 };
    327 \end{cfa}
    328 captures three basic attributes of an enumeration type: value, label, and position.
    329 @TypedEnum@ asserts two types @E@ and @T@, with @T@ being the base type of the enumeration @E@, \eg @enum( T ) E { ... };@.
    330 Implementing general functions across all enumeration types is possible by asserting @TypeEnum( E, T )@, \eg:
    331 \begin{cfa}
    332 forall( E, T | TypeEnum( E, T ) )
    333 void printEnum( E e ) {
    334         sout | "Enum "| labelE( e );
    335 }
    336 printEunm( MARS );
    337 \end{cfa}
    338 
    339 Finally, there is an associated trait defining comparison operators among enumerators.
    340 \begin{cfa}
    341 forall( E, T | TypedEnum( E, T ) ) {
    342         // comparison
    343         int ?==?( E l, E r );           $\C{// true if l and r are same enumerators}$
    344         int ?!=?( E l, E r );           $\C{// true if l and r are different enumerators}$
    345         int ?!=?( E l, zero_t );        $\C{// true if l is not the first enumerator}$
    346         int ?<?( E l, E r );            $\C{// true if l is an enumerator before r}$
    347         int ?<=?( E l, E r );           $\C{// true if l before or the same as r}$
    348         int ?>?( E l, E r );            $\C{// true if l is an enumerator after r}$
    349         int ?>=?( E l, E r );           $\C{// true if l after or the same as r}$         
    350 }
    351 \end{cfa}
    352 Note, the overloaded operators are defined only when the header @<enum.hfa>@ is included.
    353 If not, the compiler converts an enumerator to its value, and applies the operators defined for the value type @E@, \eg:
    354 \begin{cfa}
    355 // if not include <enum.hfa>
    356 enum( int ) Fruits { APPLE = 2, BANANA = 10, CHERRY = 2 };
    357 APPLE == CHERRY; // true because valueE( APPLE ) == valueE( CHERRY )
    358 
    359 #include <enum.hfa>
    360 APPLE == CHERRY; // false because posE( APPLE ) != posE( CHERRY )
    361 \end{cfa}
    362 An enumerator returns its @position@ by default.
    363 In particular, @printf( ... )@ from @<stdio.h>@ functions provides no context to its parameter type, so it prints @position@.
    364 On the other hand, the pipeline operator @?|?( ostream os, E enumType )@ provides type context for type @E@, and \CFA has overwritten this operator to print the enumeration @value@ over @position@.
    365 \begin{cfa}
    366 printf( "Position of BANANA is \%d", BANANA ); // Position of BANANA is 1
    367 sout | "Value of BANANA is " | BANANA; // Value of BANANA is 10
    368 \end{cfa}
    369 Programmers can overwrite this behaviour by overloading the pipeline operator themselves.
    370 \PAB{This needs discussing because including \lstinline{<enum.hfa>} can change the entire meaning of a program.}
    371 
     373
     374\section{Enumerated Arrays}
     375Enumerated array use an \CFA array as their index.
     376\begin{cfa}
     377enum() Colour {
     378        Red, Orange, Yellow, Green, Blue, Indigo, Violet
     379};
     380
     381string colourCode[Colour] = { "#e81416", "#ffa500", "#ffa500", "#ffa500", "#487de7", "#4b369d", "#70369d" };
     382sout | "Colour Code of Orange is " | colourCode[Orange];
     383\end{cfa}
    372384
    373385\section{Planet Example}
  • src/AST/Fwd.hpp

    rfbc84ca re6f1a4b  
    133133class OneType;
    134134class GlobalScopeType;
    135 class EnumAttrType;
    136135
    137136class Designation;
  • src/AST/Pass.hpp

    rfbc84ca re6f1a4b  
    207207        const ast::Type *             visit( const ast::UnionInstType        * ) override final;
    208208        const ast::Type *             visit( const ast::EnumInstType         * ) override final;
    209         const ast::Type *             visit( const ast::EnumAttrType         * ) override final;
    210209        const ast::Type *             visit( const ast::TraitInstType        * ) override final;
    211210        const ast::Type *             visit( const ast::TypeInstType         * ) override final;
  • src/AST/Pass.impl.hpp

    rfbc84ca re6f1a4b  
    19401940
    19411941//--------------------------------------------------------------------------
    1942 // EnumAttrType
    1943 template< typename core_t >
    1944 const ast::Type * ast::Pass< core_t >::visit( const ast::EnumAttrType * node ) {
    1945         VISIT_START( node );
    1946         VISIT_END( Type, node );
    1947 }
    1948 
    1949 //--------------------------------------------------------------------------
    19501942// TraitInstType
    19511943template< typename core_t >
  • src/AST/Print.cpp

    rfbc84ca re6f1a4b  
    15761576        }
    15771577
    1578         virtual const ast::Type * visit( const ast::EnumAttrType * node ) override final {
    1579                 preprint( node );
    1580                 os << "enum attr ";
    1581                 if ( node->attr == ast::EnumAttribute::Label ) {
    1582                         os << "Label ";
    1583                 } else if ( node->attr == ast::EnumAttribute::Value ) {
    1584                         os << "Value ";
    1585                 } else {
    1586                         os << "Posn ";
    1587                 }
    1588                 (*(node->instance)).accept( *this );
    1589                 return node;
    1590         }
    1591 
    15921578        virtual const ast::Type * visit( const ast::TraitInstType * node ) override final {
    15931579                preprint( node );
  • src/AST/Type.hpp

    rfbc84ca re6f1a4b  
    319319using EnumInstType = SueInstType<EnumDecl>;
    320320
    321 class EnumAttrType final : public Type {
    322 public:
    323         readonly<EnumInstType> instance;
    324         EnumAttribute attr;
    325         const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    326         EnumAttrType( const EnumInstType * instance, EnumAttribute attr = EnumAttribute::Posn )
    327                 : instance(instance), attr(attr) {}
    328 
    329         bool match( const ast::EnumAttrType * other) const {
    330                 return instance->base->name == other->instance->base->name && attr == other->attr;
    331         }
    332 private:
    333         EnumAttrType * clone() const override { return new EnumAttrType{ *this }; }
    334         MUTATE_FRIEND
    335 };
    336 
    337321/// An instance of a trait type.
    338322class TraitInstType final : public BaseInstType {
  • src/AST/Visitor.hpp

    rfbc84ca re6f1a4b  
    119119    virtual const ast::Type *             visit( const ast::OneType              * ) = 0;
    120120    virtual const ast::Type *             visit( const ast::GlobalScopeType      * ) = 0;
    121     virtual const ast::Type *             visit( const ast::EnumAttrType         * ) = 0;
    122121    virtual const ast::Designation *      visit( const ast::Designation          * ) = 0;
    123122    virtual const ast::Init *             visit( const ast::SingleInit           * ) = 0;
  • src/CodeGen/GenType.cpp

    rfbc84ca re6f1a4b  
    4747        void postvisit( ast::UnionInstType const * type );
    4848        void postvisit( ast::EnumInstType const * type );
    49         void postvisit( ast::EnumAttrType const * type );
    5049        void postvisit( ast::TypeInstType const * type );
    5150        void postvisit( ast::TupleType const * type );
     
    241240}
    242241
    243 void GenType::postvisit( ast::EnumAttrType const * type ) {
    244         postvisit( type->instance );
    245 }
    246 
    247242void GenType::postvisit( ast::TypeInstType const * type ) {
    248243        assertf( !options.genC, "TypeInstType should not reach code generation." );
  • src/Common/CodeLocationTools.cpp

    rfbc84ca re6f1a4b  
    188188    macro(UnionInstType, Type) \
    189189    macro(EnumInstType, Type) \
    190     macro(EnumAttrType, Type) \
    191190    macro(TraitInstType, Type) \
    192191    macro(TypeInstType, Type) \
  • src/ResolvExpr/CandidateFinder.cpp

    rfbc84ca re6f1a4b  
    906906                                }
    907907                                CandidateRef & choice = winners.front();
    908                                 choice->cost.incSafe();
     908                                choice->cost = Cost::unsafe;
    909909                                candidates.emplace_back( std::move(choice) );
    910910                        }
     
    955955
    956956                CandidateFinder funcFinder( context, tenv );
     957                std::string funcName;
    957958                if (auto nameExpr = untypedExpr->func.as<ast::NameExpr>()) {
     959                        funcName = nameExpr->name;
    958960                        auto kind = ast::SymbolTable::getSpecialFunctionKind(nameExpr->name);
    959961                        if (kind != ast::SymbolTable::SpecialFunctionKind::NUMBER_OF_KINDS) {
     
    10191021                CandidateList found;
    10201022                SemanticErrorException errors;
     1023               
    10211024                for ( CandidateRef & func : funcFinder ) {
    10221025                        try {
     
    10931096                        Cost cvtCost = computeApplicationConversionCost( withFunc, symtab );
    10941097
     1098                        if (funcName == "?|?") {
    10951099                        PRINT(
    10961100                                auto appExpr = withFunc->expr.strict_as< ast::ApplicationExpr >();
     
    11081112                                std::cerr << "cost of conversion is:" << cvtCost << std::endl;
    11091113                        )
    1110 
     1114                        }
    11111115                        if ( cvtCost != Cost::infinity ) {
    11121116                                withFunc->cvtCost = cvtCost;
     
    17741778                                                matches.clear();
    17751779                                        }
    1776                                         // ambiguous case, still output candidates to print in error message
    1777                                         if ( cand->cost == minExprCost && thisCost == minCastCost ) {
    1778                                                 auto commonAsEnumAttr = common.as<ast::EnumAttrType>();
    1779                                                 if ( commonAsEnumAttr && commonAsEnumAttr->attr == ast::EnumAttribute::Value ) {
    1780                                                         auto callExpr = new ast::UntypedExpr(
    1781                                                                 cand->expr->location, new ast::NameExpr( cand->expr->location, "valueE"), {cand->expr} );
    1782                                                         CandidateFinder finder( context, env );
    1783                                                         finder.find( callExpr );
    1784                                                         CandidateList winners = findMinCost( finder.candidates );
    1785                                                         if (winners.size() != 1) {
    1786                                                                 SemanticError( callExpr, "Ambiguous expression in valueE..." );
    1787                                                         }
    1788                                                         CandidateRef & choice = winners.front();
    1789                                                         // assert( valueCall->result );
    1790                                                         CandidateRef newCand = std::make_shared<Candidate>(
    1791                                                                 new ast::InitExpr{
    1792                                                                         initExpr->location,
    1793                                                                         // restructureCast( cand->expr, toType ),
    1794                                                                         choice->expr,
    1795                                                                         initAlt.designation },
    1796                                                                 std::move(env), std::move( open ), std::move( need ), cand->cost + thisCost );
    1797                                                                 inferParameters( newCand, matches );
    1798                                                 } else {
    1799                                                         CandidateRef newCand = std::make_shared<Candidate>(
    1800                                                                 new ast::InitExpr{
    1801                                                                         initExpr->location,
    1802                                                                         restructureCast( cand->expr, toType ),
    1803                                                                         initAlt.designation },
    1804                                                                 std::move(env), std::move( open ), std::move( need ), cand->cost + thisCost );
    1805                                                         // currently assertions are always resolved immediately so this should have no effect.
    1806                                                         // if this somehow changes in the future (e.g. delayed by indeterminate return type)
    1807                                                         // we may need to revisit the logic.
    1808                                                         inferParameters( newCand, matches );
    1809                                                 }
    1810                                         }
     1780                                        CandidateRef newCand = std::make_shared<Candidate>(
     1781                                                new ast::InitExpr{
     1782                                                        initExpr->location,
     1783                                                        restructureCast( cand->expr, toType ),
     1784                                                        initAlt.designation },
     1785                                                std::move(env), std::move( open ), std::move( need ), cand->cost + thisCost );
     1786                                        // currently assertions are always resolved immediately so this should have no effect.
     1787                                        // if this somehow changes in the future (e.g. delayed by indeterminate return type)
     1788                                        // we may need to revisit the logic.
     1789                                        inferParameters( newCand, matches );
    18111790                                }
    18121791                        }
  • src/ResolvExpr/CommonType.cpp

    rfbc84ca re6f1a4b  
    388388                        const ast::EnumDecl* enumDecl = enumInst->base;
    389389                        if ( !enumDecl->base ) {
    390                                 ast::BasicKind kind = commonTypes[ basic->kind ][ ast::BasicKind::SignedInt ];
    391                                 if (
    392                                         ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers )
    393                                                 || widen.first )
    394                                         && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers )
    395                                                 || widen.second )
    396                                 ) {
    397                                         result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
    398                                 }
    399                         }
    400                 } else if ( auto type2AsAttr = dynamic_cast< const ast::EnumAttrType * >( type2 ) ) {
    401                         if ( type2AsAttr->attr == ast::EnumAttribute::Posn ) {
    402390                                ast::BasicKind kind = commonTypes[ basic->kind ][ ast::BasicKind::SignedInt ];
    403391                                if (
     
    656644        }
    657645
    658         void postvisit( const ast::EnumAttrType * ) {}
    659 
    660646        void postvisit( const ast::TraitInstType * ) {}
    661647
  • src/ResolvExpr/ConversionCost.cpp

    rfbc84ca re6f1a4b  
    279279        if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
    280280                conversionCostFromBasicToBasic( basicType, dstAsBasic );
    281         } else if ( dynamic_cast< const ast::EnumAttrType *>(dst) ) {
    282                 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
    283                 cost = costCalc( basicType, integer, srcIsLvalue, symtab, env );
    284         } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
     281        }       else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    285282                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
    286283                        cost = Cost::unsafe;
     
    373370        static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
    374371        cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
    375         if ( cost < Cost::unsafe ) {
    376                 cost.incSafe();
    377         }
    378 }
    379 
    380 void ConversionCost::postvisit( const ast::EnumAttrType * src ) {
    381         auto dstAsEnumAttrType = dynamic_cast<const ast::EnumAttrType *>(dst);
    382         assert( src->attr != ast::EnumAttribute::Label );
    383         if ( src->attr == ast::EnumAttribute::Value ) {
    384                 if ( dstAsEnumAttrType && dstAsEnumAttrType->attr == ast::EnumAttribute::Value) {
    385                         cost = costCalc( src->instance, dstAsEnumAttrType->instance, srcIsLvalue, symtab, env );
    386                 } else {
    387                         auto baseType = src->instance->base->base;
    388                         cost = costCalc( baseType, dst, srcIsLvalue, symtab, env );
    389                         if ( cost < Cost::infinity ) {
    390                                 cost.incUnsafe();
    391                         }
    392                 }
    393         } else { // ast::EnumAttribute::Posn
    394                 if ( auto dstBase = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
    395                         cost = costCalc( src->instance, dstBase, srcIsLvalue, symtab, env );
    396                         if ( cost < Cost::unsafe ) cost.incSafe();
    397                 } else {
    398                         static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
    399                         cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
    400                         if ( cost < Cost::unsafe ) {
    401                                 cost.incSafe();
    402                         }
    403                 }
    404         }
     372        if ( !inst->base->isTyped ) {
     373                if ( cost < Cost::unsafe ) {
     374                        cost.incSafe();
     375                }
     376                return;
     377        }
     378        cost.incUnsafe();
    405379}
    406380
  • src/ResolvExpr/ConversionCost.hpp

    rfbc84ca re6f1a4b  
    7272        void postvisit( const ast::ZeroType * zeroType );
    7373        void postvisit( const ast::OneType * oneType );
    74         void postvisit( const ast::EnumAttrType * posType );
    7574private:
    7675        // refactor for code resue
  • src/ResolvExpr/Unify.cpp

    rfbc84ca re6f1a4b  
    275275
    276276        void postvisit( const ast::VoidType * vt) {
    277                 result = dynamic_cast< const ast::VoidType * >( type2 )
    278                         || tryToUnifyWithEnumValue(vt, type2, tenv, need, have, open, noWiden());
     277                result = dynamic_cast< const ast::VoidType * >( type2 );
     278                        // || tryToUnifyWithEnumValue(vt, type2, tenv, need, have, open, noWiden());
    279279                ;
    280280        }
     
    284284                        result = basic->kind == basic2->kind;
    285285                }
    286                 result = result || tryToUnifyWithEnumValue(basic, type2, tenv, need, have, open, noWiden());
     286                // result = result || tryToUnifyWithEnumValue(basic, type2, tenv, need, have, open, noWiden());
    287287        }
    288288
     
    293293                                noWiden());
    294294                }
    295                 result = result || tryToUnifyWithEnumValue(pointer, type2, tenv, need, have, open, noWiden());
     295                // result = result || tryToUnifyWithEnumValue(pointer, type2, tenv, need, have, open, noWiden());
    296296        }
    297297
     
    311311
    312312                result = unifyExact(
    313                         array->base, array2->base, tenv, need, have, open, noWiden())
    314                         || tryToUnifyWithEnumValue(array, type2, tenv, need, have, open, noWiden());
     313                        array->base, array2->base, tenv, need, have, open, noWiden());
     314                        // || tryToUnifyWithEnumValue(array, type2, tenv, need, have, open, noWiden());
    315315        }
    316316
     
    404404        }
    405405
    406         bool tryToUnifyWithEnumValue( const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
    407                 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
    408                 WidenMode widen) {
    409                 if ( auto attrType2 = dynamic_cast<const ast::EnumAttrType *>(type2)) {
    410                         if (attrType2->attr == ast::EnumAttribute::Value) {
    411                                 return unifyExact( type1, attrType2->instance->base->base, env, need, have, open,
    412                                         widen);
    413                         } else if (attrType2->attr == ast::EnumAttribute::Posn) {
    414                                 return unifyExact( type1, attrType2->instance, env, need, have, open, widen );
    415                         }
    416                 }
    417                 return false;
    418         }
    419 
    420406public:
    421407        void postvisit( const ast::FunctionType * func ) {
     
    527513        void postvisit( const ast::StructInstType * aggrType ) {
    528514                handleGenericRefType( aggrType, type2 );
    529                 result = result || tryToUnifyWithEnumValue(aggrType, type2, tenv, need, have, open, noWiden());
    530515        }
    531516
    532517        void postvisit( const ast::UnionInstType * aggrType ) {
    533518                handleGenericRefType( aggrType, type2 );
    534                 result = result || tryToUnifyWithEnumValue(aggrType, type2, tenv, need, have, open, noWiden());
    535519        }
    536520
    537521        void postvisit( const ast::EnumInstType * aggrType ) {
    538522                handleRefType( aggrType, type2 );
    539                 result = result || tryToUnifyWithEnumValue(aggrType, type2, tenv, need, have, open, noWiden());
    540         }
    541 
    542         void postvisit( const ast::EnumAttrType * enumAttr ) {
    543                 // Lazy approach for now
    544                 if ( auto otherPos = dynamic_cast< const ast::EnumAttrType *>( type2 ) ) {
    545                         if ( enumAttr->match(otherPos) ) {
    546                                 result = otherPos;
    547                         }
    548                 }
    549523        }
    550524
    551525        void postvisit( const ast::TraitInstType * aggrType ) {
    552526                handleRefType( aggrType, type2 );
    553                 result = result || tryToUnifyWithEnumValue(aggrType, type2, tenv, need, have, open, noWiden());
    554527        }
    555528
     
    560533                        this->result = otherInst;
    561534                }
    562                 result = result || tryToUnifyWithEnumValue(typeInst, type2, tenv, need, have, open, noWiden());
    563535        }
    564536
     
    634606                auto types2 = flatten( flat2 );
    635607
    636                 result = unifyList( types, types2, tenv, need, have, open )
    637                         || tryToUnifyWithEnumValue(tuple, type2, tenv, need, have, open, noWiden());
     608                result = unifyList( types, types2, tenv, need, have, open );
     609                        // || tryToUnifyWithEnumValue(tuple, type2, tenv, need, have, open, noWiden());
    638610        }
    639611
    640612        void postvisit( const ast::VarArgsType * vat) {
    641                 result = dynamic_cast< const ast::VarArgsType * >( type2 )
    642                         || tryToUnifyWithEnumValue(vat, type2, tenv, need, have, open, noWiden());
     613                result = dynamic_cast< const ast::VarArgsType * >( type2 );
     614                        // || tryToUnifyWithEnumValue(vat, type2, tenv, need, have, open, noWiden());
    643615        }
    644616
    645617        void postvisit( const ast::ZeroType * zt) {
    646                 result = dynamic_cast< const ast::ZeroType * >( type2 )
    647                         || tryToUnifyWithEnumValue(zt, type2, tenv, need, have, open, noWiden());
     618                result = dynamic_cast< const ast::ZeroType * >( type2 );
     619                        // || tryToUnifyWithEnumValue(zt, type2, tenv, need, have, open, noWiden());
    648620        }
    649621
    650622        void postvisit( const ast::OneType * ot) {
    651                 result = dynamic_cast< const ast::OneType * >( type2 )
    652                         || tryToUnifyWithEnumValue(ot, type2, tenv, need, have, open, noWiden());
     623                result = dynamic_cast< const ast::OneType * >( type2 );
     624                        // || tryToUnifyWithEnumValue(ot, type2, tenv, need, have, open, noWiden());
    653625        }
    654626};
  • src/SymTab/Mangler.cpp

    rfbc84ca re6f1a4b  
    5858        void postvisit( const ast::OneType * oneType );
    5959        void postvisit( const ast::QualifiedType * qualType );
    60         void postvisit( const ast::EnumAttrType * posType );
    6160
    6261        /// The result is the current constructed mangled name.
     
    278277        assertf( decl->kind < ast::TypeDecl::Kind::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );
    279278        mangleName += Encoding::typeVariables[ decl->kind ] + std::to_string( decl->name.length() ) + decl->name;
    280 }
    281 
    282 void Mangler::postvisit( const ast::EnumAttrType * enumAttr ) {
    283         postvisit( enumAttr->instance );
    284         // mangleName += "_pos";
    285         switch ( enumAttr->attr )
    286         {
    287                 case ast::EnumAttribute::Label:
    288                         mangleName += "_label_";
    289                         break;
    290                 case ast::EnumAttribute::Posn:
    291                         mangleName += "_posn_";
    292                         break;
    293                 case ast::EnumAttribute::Value:
    294                         mangleName += "_value_";
    295                         break;
    296         }
    297 
    298279}
    299280
  • src/Validate/ImplementEnumFunc.cpp

    rfbc84ca re6f1a4b  
    7272                ast::DeclWithType* decl = declPtr.get_and_mutate();
    7373                decl->attributes.push_back(new ast::Attribute("unused"));
    74         }
    75 
    76         ast::ObjectDecl* dstParam() const {
    77                 return new ast::ObjectDecl(getLocation(), "_dst",
    78                                            new ast::ReferenceType(new ast::EnumAttrType(
    79                                                ast::deepCopy(instType))));
    80         }
    81 
    82         ast::ObjectDecl* srcParam() const {
    83                 return new ast::ObjectDecl(
    84                         getLocation(), "_src",
    85                         new ast::EnumAttrType(ast::deepCopy(instType)));
    8674        }
    8775
     
    329317}
    330318
    331 inline ast::EnumAttrType * getPosnType( const ast::EnumDecl * decl ) {
    332         return new ast::EnumAttrType(new ast::EnumInstType(decl), ast::EnumAttribute::Posn);
    333 }
    334 
    335319ast::ObjectDecl* EnumAttrFuncGenerator::genAttrArrayProto(
    336320        const ast::EnumAttribute attr, const CodeLocation& location,
     
    360344                        func->location,
    361345                        new ast::VariableExpr( func->location, func->params.front() ),
    362                         new ast::EnumAttrType( new ast::EnumInstType(decl),
    363                                 ast::EnumAttribute::Posn))});
     346                        new ast::BasicType( ast::BasicKind::UnsignedInt ),
     347                        ast::GeneratedFlag::ExplicitCast
     348                )});
    364349        func->stmts = new ast::CompoundStmt(
    365350                func->location, {new ast::ReturnStmt(func->location, untyped)});
     
    370355                func->location,
    371356                new ast::VariableExpr(func->location, func->params.front()),
    372                 new ast::EnumAttrType(new ast::EnumInstType(decl),
    373                                                           ast::EnumAttribute::Posn));
     357                new ast::BasicType( ast::BasicKind::UnsignedInt ),
     358                        ast::GeneratedFlag::ExplicitCast);
    374359        func->stmts = new ast::CompoundStmt(
    375360                func->location, {new ast::ReturnStmt(func->location, castExpr)});
Note: See TracChangeset for help on using the changeset viewer.