Changeset 367725d
- Timestamp:
- Jan 22, 2024, 3:23:12 AM (11 months ago)
- Branches:
- master
- Children:
- 544deb9
- Parents:
- ac939461
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/proposals/enum.tex
rac939461 r367725d 245 245 246 246 247 \subsection{Aggressive Inline} 248 To avoid allocating memory for enumeration data structures, \CFA inline the result of enumeration attribute pseudo-function whenever it is possible. 249 \begin{lstlisting}[label=lst:enumeration_inline] 250 enum(int) OddNumber { A=1, B=3 }; 251 sout | "A: " | OddNumber.A | "B: " | OddNumber.B | "A+B: " | OddNumber.A + OddNumber.B 252 \end{lstlisting} 253 Instead of calling pseudo-function @value@ on expression $OddNumber.A$ and $OddNumber.B$, because the result is known statistically, \CFA will inline the constant expression 1 and 3, respectively. Because no runtime lookup for enumeration value is necessary, \CFA will not generate data structure for enumeration OddNumber. 254 255 \subsection{Weak Reference} 256 \begin{lstlisting}[label=lst:week_ref] 257 enum(int) OddNumber { A=1, B=3 }; 258 enum OddNumber i = ...; 259 ... 260 sout | OddNumber; 261 \end{lstlisting} 262 In this example, \CFA cannot determine the static value of the enum variable i, and Runtime lookup is necessary. The OddNumber can be referenced in multiple compilations, and allocating the arrays in all compilation units is not desirable. \CFA addresses this by declaring the value array as a weak reference. All compilation units reference OddNumber have weak references to the same enumeration data structure. No extra memory is allocated if more compilation units reference OddNumber, and the OddNumber is initialized once. 263 247 \ 264 248 \section{Unification} 265 249 … … 638 622 \section{Implementation} 639 623 640 \subsection{Compiler Representation (Reworking)} 624 \subsection{Static Attribute Expression} 625 \begin{lstlisting}[label=lst:static_attr] 626 enum( char * ) Colour { 627 Red = "red", Blue = "blue", Green = "green" 628 }; 629 \end{lstlisting} 630 An enumerator expression returns its enumerator value as a constant expression with no runtime cost. For example, @Colour.Red@ is equivalent to the constant expression "red", and \CFA finishes the expression evaluation before generating the corresponding C code. Applying a pseudo-function to a constant enumerator expression results in a constant expression as well. @value( Colour.Red )@, @position( Colour. Red )@, and @label( Colour.Red )@ are equivalent to constant expression with char * value "red", int value 0, and char * value "Red", respectively. 631 632 \subsection{Runtime Attribute Expression and Weak Referenced Data} 633 \begin{lstlisting}[label=lst:dynamic_attr] 634 Colour c; 635 ... 636 value( c ); // or c 637 \end{lstlisting} 638 An enumeration variable c is equivalent to an integer variable with the value of @position( c )@ In Example~\ref{lst:dynamic_attr}, the value of enumeration variable c is unknown at compile time. In this case, the pseudo-function calls are reduced to expression that returns the enumerator values at runtime. 639 640 \CFA stores the variables and labels in const arrays to provide runtime lookup for enumeration information. 641 642 \begin{lstlisting}[label=lst:attr_array] 643 const char * Colour_labels [3] = { "Red", "Blue", "Green" }; 644 const char * Colour_values [3] = { "red", "blue", "green" }; 645 \end{lstlisting} 646 The \CFA compiles transforms the attribute expressions into array access. 647 \begin{lstlisting}[label=lst:attr_array_access] 648 position( c ) // c; an integer 649 value( c ); // Colour_values[c] 650 label( c ); // Colour_labels[c] 651 \end{lstlisting} 652 653 To avoid unnecessary memory usage, the labels and values array are only generated as needed, and only generate once across all compilation units. By default, \CFA defers the declaration of the label and value arrays until an call to attribute function with a dynamic value. If an attribute function is never called on a dynamic value of an enumerator, the array will never be allocated. Once the arrays are created, all compilation units share a weak reference to the allocation array. 654 655 \subsection{Enum Prelude} 656 657 \begin{lstlisting}[label=lst:enum_func_dec] 658 forall( T ) { 659 unsigned position( unsigned ); 660 T value( unsigned ); 661 char * label( unsigned ); 662 } 663 \end{lstlisting} 664 \CFA loads the declaration of enumeration function from the enum.hfa. 665 666 \subsection{Internal Representation} 667 641 668 The definition of an enumeration is represented by an internal type called @EnumDecl@. At the minimum, it stores all the information needed to construct the companion object. Therefore, an @EnumDecl@ can be represented as the following: 642 669 \begin{lstlisting}[label=lst:EnumDecl] … … 667 694 668 695 669 \subsection{(Rework) Companion Object and Companion Function}670 671 \begin{lstlisting}[caption={Enum Type Functions}, label=lst:cforall_enum_functions]672 forall( T )673 struct Companion {674 const T * const values;675 const char * label;676 int length;677 };678 \end{lstlisting}679 \CFA generates companion objects, an instance of structure that encloses @necessary@ data to represent an enumeration. The size of the companion is unknown at the compilation time, and it "grows" in size to compensate for the @usage@.680 681 The companion object is singleton across the compilation (investigation).682 683 \CFA generates the definition of companion functions.684 Because \CFA implicitly stores an enumeration instance as its position, the companion function @position@ does nothing but return the position it is passed.685 Companions function @value@ and @label@ return the array item at the given position of @values@ and @labels@, respectively.686 \begin{lstlisting}[label=lst:companion_definition]687 int position( Companion o, int pos ) { return pos; }688 T value( Companion o, int pos ) { return o.values[ pos ]; }689 char * label( Companion o, int pos ) { return o.labels[ pos ]; }690 \end{lstlisting}691 Notably, the @Companion@ structure definition, and all companion objects, are visible to users.692 A user can retrieve values and labels defined in an enumeration by accessing the values and labels directly, or indirectly by calling @Companion@ functions @values@ and @labels@693 \begin{lstlisting}[label=lst:companion_definition_values_labels]694 Colour.values; // read the Companion's values695 values( Colour ); // same as Colour.values696 \end{lstlisting}696 % \subsection{(Rework) Companion Object and Companion Function} 697 698 % \begin{lstlisting}[caption={Enum Type Functions}, label=lst:cforall_enum_functions] 699 % forall( T ) 700 % struct Companion { 701 % const T * const values; 702 % const char * label; 703 % int length; 704 % }; 705 % \end{lstlisting} 706 % \CFA generates companion objects, an instance of structure that encloses @necessary@ data to represent an enumeration. The size of the companion is unknown at the compilation time, and it "grows" in size to compensate for the @usage@. 707 708 % The companion object is singleton across the compilation (investigation). 709 710 % \CFA generates the definition of companion functions. 711 % Because \CFA implicitly stores an enumeration instance as its position, the companion function @position@ does nothing but return the position it is passed. 712 % Companions function @value@ and @label@ return the array item at the given position of @values@ and @labels@, respectively. 713 % \begin{lstlisting}[label=lst:companion_definition] 714 % int position( Companion o, int pos ) { return pos; } 715 % T value( Companion o, int pos ) { return o.values[ pos ]; } 716 % char * label( Companion o, int pos ) { return o.labels[ pos ]; } 717 % \end{lstlisting} 718 % Notably, the @Companion@ structure definition, and all companion objects, are visible to users. 719 % A user can retrieve values and labels defined in an enumeration by accessing the values and labels directly, or indirectly by calling @Companion@ functions @values@ and @labels@ 720 % \begin{lstlisting}[label=lst:companion_definition_values_labels] 721 % Colour.values; // read the Companion's values 722 % values( Colour ); // same as Colour.values 723 % \end{lstlisting} 697 724 698 725 \subsection{Companion Traits (experimental)} -
src/Validate/ReplacePseudoFunc.cpp
rac939461 r367725d 17 17 ast::Expr const * ReplacePseudoFuncCore::postvisit( ast::ApplicationExpr const * expr) { 18 18 auto fname = ast::getFunctionName( expr ); 19 if ( fname == "posE" ) {19 if ( fname == "posE" || fname == "valueE" || fname == "labelE" ) { 20 20 // std::cerr << "Found App in ReplacePseudoFunc" << std::endl; 21 21 if ( expr->args.size() != 1 ) { … … 35 35 for ( size_t i = 0; i < base->members.size(); i++ ) { 36 36 if ( base->members[i]->name == referredName ) { 37 return ast::ConstantExpr::from_int( expr->location, i ); 37 if ( fname == "posE ") 38 return ast::ConstantExpr::from_int( expr->location, i ); 39 else if (fname == "labelE" ) 40 return ast::ConstantExpr::from_string( expr->location, referredName ); 41 else 42 return new ast::TypeExpr( expr->location, argType ); 38 43 } 39 44 }
Note: See TracChangeset
for help on using the changeset viewer.