Changeset 0030b508 for doc/proposals
- Timestamp:
- Nov 13, 2023, 3:43:31 AM (13 months ago)
- Branches:
- master
- Children:
- fc12f05
- Parents:
- 6bd9f9e
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/proposals/enum.tex
r6bd9f9e r0030b508 1 %% 2 %% This is file `sample-manuscript.tex', 3 %% generated with the docstrip utility. 4 %% 5 %% The original source files were: 6 %% 7 %% samples.dtx (with options: `manuscript') 8 %% 9 %% IMPORTANT NOTICE: 10 %% 11 %% For the copyright see the source file. 12 %% 13 %% Any modified versions of this file must be renamed 14 %% with new filenames distinct from sample-manuscript.tex. 15 %% 16 %% For distribution of the original source see the terms 17 %% for copying and modification in the file samples.dtx. 18 %% 19 %% This generated file may be distributed as long as the 20 %% original source files, as listed above, are part of the 21 %% same distribution. (The sources need not necessarily be 22 %% in the same archive or directory.) 23 %% 24 %% Commands for TeXCount 25 %TC:macro \cite [option:text,text] 26 %TC:macro \citep [option:text,text] 27 %TC:macro \citet [option:text,text] 28 %TC:envir table 0 1 29 %TC:envir table* 0 1 30 %TC:envir tabular [ignore] word 31 %TC:envir displaymath 0 word 32 %TC:envir math 0 word 33 %TC:envir comment 0 0 34 %% 35 %% 36 %% The first command in your LaTeX source must be the \documentclass command. 37 \documentclass[manuscript,screen,review]{acmart} 1 \documentclass[12pt]{article} 2 \usepackage{fullpage,times} 3 \usepackage{pslatex} % reduce size of san serif font 38 4 \usepackage{xcolor} 39 5 \usepackage{listings} 40 \usepackage[ligature, inference]{semantic} 41 \usepackage{array} 42 43 \definecolor{mGreen}{rgb}{0,0.6,0} 44 \definecolor{mGray}{rgb}{0.5,0.5,0.5} 45 \definecolor{mPurple}{rgb}{0.58,0,0.82} 46 \definecolor{backgroundColour}{rgb}{0.95,0.95,0.92} 6 %\usepackage{array} 7 \usepackage{graphics} 8 \usepackage{xspace} 9 10 \makeatletter 11 \renewcommand\section{\@startsection{section}{1}{\z@}{-3.0ex \@plus -1ex \@minus -.2ex}{1.5ex \@plus .2ex}{\normalfont\large\bfseries}} 12 \renewcommand\subsection{\@startsection{subsection}{2}{\z@}{-2.75ex \@plus -1ex \@minus -.2ex}{1.25ex \@plus .2ex}{\normalfont\normalsize\bfseries}} 13 \renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}} 14 \renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}{-2.0ex \@plus -1ex \@minus -.2ex}{-1em}{\normalfont\normalsize\bfseries}} 15 \renewcommand\subparagraph{\@startsection{subparagraph}{4}{\z@}{-1.5ex \@plus -1ex \@minus -.2ex}{-1em}{\normalfont\normalsize\bfseries\itshape}} 16 \makeatother 17 18 \newenvironment{cquote}{% 19 \list{}{\lstset{resetmargins=true,aboveskip=0pt,belowskip=0pt}\topsep=4pt\parsep=0pt\leftmargin=\parindent\rightmargin\leftmargin}% 20 \item\relax 21 }{% 22 \endlist 23 }% cquote 24 25 \setlength{\topmargin}{-0.45in} % move running title into header 26 \setlength{\headsep}{0.25in} 27 \setlength{\textheight}{9.0in} 28 29 \newcommand{\CFAIcon}{\textsf{C\raisebox{\depth}{\rotatebox{180}A}}} % Cforall icon 30 \newcommand{\CFA}{\protect\CFAIcon\xspace} % CFA symbolic name 31 \newcommand{\PAB}[1]{{\color{red}PAB: #1}} 32 33 % \definecolor{mGreen}{rgb}{0,0.6,0} 34 % \definecolor{mGray}{rgb}{0.5,0.5,0.5} 35 % \definecolor{mPurple}{rgb}{0.58,0,0.82} 36 % \definecolor{backgroundColour}{rgb}{0.95,0.95,0.92} 47 37 48 38 \lstdefinestyle{CStyle}{ 49 backgroundcolor=\color{backgroundColour}, 50 commentstyle=\color{mGreen}, 51 keywordstyle=\color{magenta}, 52 numberstyle=\tiny\color{mGray}, 53 stringstyle=\color{mPurple}, 54 basicstyle=\footnotesize, 39 % backgroundcolor=\color{backgroundColour}, 40 % commentstyle=\color{mGreen}, 41 % keywordstyle=\color{magenta}, 42 stringstyle=\small\tt, % use typewriter font 43 % stringstyle=\color{mPurple}, 44 columns=fullflexible, 45 basicstyle=\small\linespread{0.9}\sf, % reduce line spacing and use sanserif font 46 % basicstyle=\footnotesize, 55 47 breakatwhitespace=false, 56 breaklines=true,48 % breaklines=true, 57 49 captionpos=b, 58 50 keepspaces=true, 59 numbers=left, 60 numbersep=5pt, 61 showspaces=false, 51 % numbers=left, 52 % numbersep=5pt, 53 % numberstyle=\tiny\color{mGray}, 54 % showspaces=false, 62 55 showstringspaces=false, 63 showtabs=false, 64 tabsize=2, 65 language=C 66 } 67 68 %% 69 %% \BibTeX command to typeset BibTeX logo in the docs 70 \AtBeginDocument{% 71 \providecommand\BibTeX{{% 72 \normalfont B\kern-0.5em{\scshape i\kern-0.25em b}\kern-0.8em\TeX}}} 73 74 75 %% 76 %% end of the preamble, start of the body of the document source. 56 % showtabs=false, 57 showlines=true, % show blank lines at end of code 58 tabsize=5, 59 language=C, 60 aboveskip=4pt, % spacing above/below code block 61 belowskip=2pt, 62 xleftmargin=\parindent, % indent code to paragraph indentation 63 } 64 \lstset{style=CStyle,moredelim=**[is][\color{red}]{@}{@}} 65 \lstMakeShortInline@ % single-character for \lstinline 66 77 67 \begin{document} 78 68 79 %% 80 %% The "title" command has an optional parameter, 81 %% allowing the author to define a "short title" to be used in page headers. 82 \title{Enumeration in Cforall} 83 84 %% 85 %% The "author" command and its associated commands are used to define 86 %% the authors and their affiliations. 87 %% Of note is the shared affiliation of the first two authors, and the 88 %% "authornote" and "authornotemark" commands 89 %% used to denote shared contribution to the research. 69 \title{\vspace*{-0.5in}Enumeration in \CFA} 90 70 \author{Jiada Liang} 91 71 92 93 %% 94 %% The abstract is a short summary of the work to be presented in the 95 %% article. 72 \maketitle 73 96 74 \begin{abstract} 97 An enumeration, or enum in short, is a type that defines a list of named constant values in C. C uses integral type as the underlying representation of enum. Cforall extends C enum to allow more types, including custom types, to be used as enumeration inner representation. 75 An enumeration is a type that defines a list of named constant values in C (and other languages). 76 C uses an integral type as the underlying representation of an enumeration. 77 \CFA extends C enumerations to allow all basic and custom types for the inner representation. 98 78 \end{abstract} 99 79 100 %%101 %% The code below is generated by the tool at http://dl.acm.org/ccs.cfm.102 %% Please copy and paste the code instead of the example below.103 %%104 105 106 %%107 %% This command processes the author and affiliation and title108 %% information and builds the first part of the formatted document.109 \maketitle110 111 80 \section{C-Style Enum} 112 \begin{lstlisting}[style=CStyle, label{lst:weekday}] 81 82 \CFA supports the C-Style enumeration using the same syntax and semantics. 83 \begin{lstlisting}[label=lst:weekday] 113 84 enum Weekday { Monday, Tuesday, Wednesday, Thursday=10, Friday, Saturday, Sunday }; 114 85 \end{lstlisting} 115 Cforall supports the C-Style enumeration (C-enum for short). It has the same syntax as C and resembles the same language semantics. In code~\ref{lst:weekday} example, the syntax defines an enum class $Weekday$ with enumerators $Monday$, $Tuesday$, $Wednesday$, $Thursday$, $Friday$, $Saturday$ and $Sunday$ in order. The successor of $Tuesday$ is $Monday$ and the predecessor of $Tuesday$ is $Wednesday$. Enumerators have an integral type, either being explicitly initialized by an initializer or being assigned a value by the compiler. For example, $Thursday$ has been assigned with value $10$. If not explicitly initialized, the first value of an enum, $Monday$ in the $Weekday$ example, has the integer value 0. Other uninitialized enum value has a value that is equal to their successor $+ 1$. The enum value $Tuesday$, $Wednesday$, $Friday$, $Saturday$, and $Sunday$ have value 1, 2, 11, 12, and 13 respectively. 116 117 \begin{lstlisting}[label{lst:enum_scope}, style=CStyle] 118 { 119 { 120 enum RGB {R, G, B}; 121 int i = R // i == 0 122 } 123 int j = G; // ERROR! G is not declared in this scope 124 } 125 \end{lstlisting} 126 C-enums are unscoped: enumerators declared inside of an enum are visible in the enclosing scope of the enum class. 127 128 \section{Cforall-Style Enum} 129 \begin{lstlisting}[style=CStyle, label{lst:color}] 130 enum Color(char *) { Red="R", Green="G", Blue="B" }; 131 \end{lstlisting} 132 A Cforall enumeration is parameterized by a type declared. Cforall allows any oType in the enum declaration, and values assigned to enumerators must be in the declared type. 133 134 \section{Enumerable Type Traits} 135 A trait is a collection of constraints in Cforall, which can be used to describe types. Cforall standard library defines traits to categorize types that are related enumeration features. 136 \subsection{Enumerable} 137 A type is enumerable if it can map an integer to a value. 138 \begin{lstlisting}[style=CStyle] 139 forall(T) 140 trait Enumerable { 141 T value( *class_name* , int ); 142 }; 143 \end{lstlisting} 144 The parameter class name stands for the name of an enumeration class, Weekday, for example. 145 146 \subsection{AutoInitializable} 147 \begin{lstlisting}[style=CStyle] 86 The example defines an @enum@ type @Weekday@ with ordered enumerators @Monday@, @Tuesday@, @Wednesday@, @Thursday@, @Friday@, @Saturday@ and @Sunday@. 87 The successor of @Tuesday@ is @Monday@ and the predecessor of @Tuesday@ is @Wednesday@. 88 A C enumeration has an integral type, with consecutive enumerator values assigned by the compiler starting at zero or explicitly initialized by the programmer. 89 For example, @Monday@ to @Wednesday@ have values 0--2, @Thursday@ is set to @10@, and after it, @Friday@ to @Sunday@ have values 11--13. 90 91 There are 3 attributes for an enumeration: position, label, and value: 92 \begin{cquote} 93 \small\sf 94 \begin{tabular}{rccccccccccc} 95 enum Weekday \{ & Monday, & Tuesday, & Wednesday, & Thursday=10, & Friday, & Saturday, & Sunday \}; \\ 96 position & 0 & 1 & 2 & 3 & 4 & 5 & 6 \\ 97 label & Monday & Tuesday & Wednesday & Thursday & Friday & Saturday & Sunday \\ 98 value & 0 & 1 & 2 & 10 & 11 & 12 & 13 99 \end{tabular} 100 \end{cquote} 101 102 The enumerators of an enum are unscoped, i.e., enumerators declared inside of an enum are visible in the enclosing scope of the enum class. 103 \begin{lstlisting}[label=lst:enum_scope] 104 { 105 enum RGB { R, G, B }; 106 int i = R // i == 0 107 } 108 int j = G; // ERROR! G is not declared in this scope 109 \end{lstlisting} 110 111 \section{\CFA-Style Enum} 112 113 A \CFA enumeration is parameterized by a type, which specifies the type for each enumerator. 114 \CFA allows any object type for the enumerators, and values assigned to enumerators must be in the declared type. 115 \begin{lstlisting}[label=lst:color] 116 enum Colour( @char *@ ) { Red = "R", Green = "G", Blue = "B" }; 117 \end{lstlisting} 118 The type of @Colour@ is @char *@ and each enumerator is initialized with a C string. 119 Only types have define an ordering can be automatically initialized (see Section~\ref{s:AutoInitializable}). 120 121 122 % An instance of \CFA-enum (denoted as @<enum_instance>@) is a label for the defined enum name. 123 % The label can be retrieved by calling the function @label( <enum_instance> )@. 124 % Similarly, the @value()@ function returns the value used to initialize the \CFA-enum. 125 126 A \CFA-enum is scoped: enumeration constants are not automatically exposed to the global scope. Enumeration constant can be referenced using qualified expressions like an aggregate that supports qualified references to its fields. The syntax of $qualified_expression$ for \CFA-enum is the following: 127 $$<qualified\_expression> := <enum\_type>.<enumerator>$$ 128 129 130 \subsection{enumeration instance} 131 \begin{lstlisting}[label=lst:sample_cforall_enum_usage] 132 Colour green = Colour.Green; 133 \end{lstlisting} 134 The ~\ref{lst:sample_cforall_enum_usage} example declares a $enumeration\ instance$ named \textit{red} and initializes it with $enumeration\ constant$ \textit{Color.Red}. An enumeration instance is a data structure that captures attributes of an enumeration constant, which can be retrieved by functions $position( enumeration\ instance )$, $value( enumeration\ instance )$, and $label( enumeration\ instance )$. 135 136 \begin{lstlisting} 137 int green_pos = position( green ); // 1 138 char * green_value = value( green ); // "G" 139 char * green_label = label( green ); // "Green" 140 \end{lstlisting} 141 142 An enumeration instance can be assigned to a variable or used as its position with type integer, its value with declared type T, or its label with type char *, and the compiler will resolve the usage as a type fits the context. 143 144 \begin{lstlisting}[label=lst:enum_inst_assign_int] 145 int green_pos = green; // equivalent to position( green ); 146 \end{lstlisting} 147 148 A resolution of an enumeration constant is $unambigious$ if only one of the attributes has the resolvable type. In the example~\ref{lst:enum_inst_assign_int }, the right-hand side of the assignment expression expects integer type. The position of an enumeration is int, while the other two cannot be resolved as integers. The expression unambiguously returns the position of green. 149 150 \begin{lstlisting}[label=lst:enum_inst_assign_string] 151 char * green_value = green; // equivalent to value( green ); 152 \end{lstlisting} 153 On the other hand, the resolution of an enumeration constant is $ambigious$ if multiple attributes have the expected type. In the example~\ref{lst:enum_inst_assign_string}, both value and label have the expected type char *. When a resolution is ambiguous, a \textit{resolution precedence} applies: 154 $$value > position > label$$ 155 \CFA uses resolution distance to describe if one type can be used as another. While \CFA calculates the resolution distance between the expected type and types of all three attributes, it would not choose the attribute with the closest distance. Instead, when resolving an enumeration constant, \CFA always chooses value whenever it is a possible resolution (resolution distance is not infinite), followed by position, then label. 156 157 \begin{lstlisting}[label=lst:enum_inst_precedence] 158 enum(double) Foo { Bar }; 159 int tee = Foo.Bar; // value( Bar ); 160 \end{lstlisting} 161 In the example~\ref{lst:enum_inst_precedence}, while $position( Bar )$ has the closest resolution among the three attributes, $Foo.Bar$ is resolved as $value( Bar )$ because of the resolution precedence. 162 163 Although \CFA enumeration captures three different attributes, an instance of enumeration does not occupy extra memory. The $sizeof$ \CFA enumeration instance is always 4 bytes, the same amount of memory to store a C enumeration instance. It comes from the fact that: 1. a \CFA enumeration is always statically typed; 2. it is always resolved as one of its attributes in terms of real usage. 164 165 When creating the enumeration instance green and assigns it with the enumeration constant $Color.Green$, the compilers essentially allocate an integer variables and store the position 1. The invocations of $positions()$, $value()$, and $label()$ turn into calls to special functions defined in the prelude: 166 \begin{lstlisting}[label=lst:companion_call] 167 position( green ); 168 >>> position( Colour, 1 ) -> int 169 value( green ); 170 >>> value( Colour, 1 ) -> T 171 label( green ); 172 >>> label( Colour, 1) -> char * 173 \end{lstlisting} 174 T represents the type declared in the \CFA enumeration defined and char * in the example. 175 These generated functions are $Companion Functions$, they take an $companion$ object and the position as parameters. 176 177 \subsection{Companion Object and Companion Function} 178 \begin{lstlisting}[caption={Enum Type Functions}, label=lst:cforall_enum_functions] 179 forall( T ) { 180 struct Companion { 181 const T * const values; 182 const char** const labels; 183 int length; 184 }; 185 } 186 \end{lstlisting} 187 \CFA creates an object of Companion for every \CFA-enumeration. A companion object has the same name as the enumeration is defined for. A companion object stores values and labels of enumeration constants, in the order of the constants defined in the enumeration. 188 189 \CFA generates the definition of companion functions. Because \CFA implicitly stores enumeration instance as its position, the companion function $position$ does nothing but returns the position it passes it. Companions function $value$ and $label$ return the array item at the given position of $values$ and $labels$, respectively. 190 191 \begin{lstlisting}[label=lst:companion_definition] 192 int position( Companion o, int pos ) { return pos; } 193 T value( Companion o, int pos ) { return o.values[ pos ]; } 194 char * label( Companion o, int pos ) { return o.labels[ pos ]; } 195 \end{lstlisting} 196 197 Notably, the Companion structure definition, and all companion objects, are visible to the users. 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$ 198 \begin{lstlisting}[label=lst:companion_definition_values_labels] 199 Colour.values; // read the Companion's values 200 values( Colour ); // Same as Colour.values 201 \end{lstlisting} 202 203 \subsection{User Define Enumeration Functions} 204 The Companion objects make extending features for \CFA enumeration easy. 205 206 \begin{lstlisting}[label=lst:companion_user_definition] 207 char * charastic_string( Companion o, int position ) { 208 return sprintf("Label: %s; Value: %s", label( o, position ), value( o, position) ); 209 } 210 printf( charactic_string ( Color, 1 ) ); 211 >>> Label: G; Value: G 212 \end{lstlisting} 213 Defining a function takes a Companion object effectively defines functions for all \CFA enumeration. 214 215 The \CFA compiler turns a function call that takes an enumeration instance as a parameter into a function call with a companion object plus a position. Therefore, a user can use the syntax with a user-defined enumeration function call: 216 \begin{lstlisting}[label=lst:companion_user_definition] 217 charactic_string ( Color.Green ); // equivalent to charactic_string ( Color, 1 ) 218 >>> Label: G; Value: G 219 \end{lstlisting} 220 221 Similarly, the user can work with the enumeration type itself: (see section ref...) 222 \begin{lstlisting}[ label=lst:companion_user_definition] 223 void print_enumerators ( Companion o ) { 224 for ( c : Companion o ) { 225 sout | label (c) | value( c ) ; 226 } 227 } 228 print_enumerators( Colour ); 229 \end{lstlisting} 230 231 \subsection{Runtime Enumeration} 232 The Companion structure definition is visible to users, and users can create an instance of Companion object themselves, which effectively constructs a \textit{Runtime Enumeration}. 233 \begin{lstlisting}[ label=lst:runtime_enum ] 234 const char values[] = { "Hello", "World" }; 235 const char labels[] = { "First", "Second" }; 236 Companion (char *) MyEnum = { .values: values, .labels: labels, .length: 2 }; 237 \end{lstlisting} 238 A runtime enumeration can be used to call enumeration functions. 239 \begin{lstlisting}[ label=lst:runtime_enum_usage ] 240 sout | charatstic_string( MyEnum, 1 ); 241 >>> Label: Second; Value: World 242 \end{lstlisting} 243 However, a runtime enumeration cannot create an enumeration instance, and it does not support enum-qualified syntax. 244 \begin{lstlisting}[ label=lst:runtime_enum_usage ] 245 MyEnum e = MyEnum.First; // Does not work: cannot create an enumeration instance e, 246 // and MyEnum.First is not recognizable 247 \end{lstlisting} 248 During the compilation, \CFA adds enumeration declarations to an enumeration symbol table and creates specialized function definitions for \CFA enumeration. \CFA does not recognize runtime enumeration during compilation and would not add them to the enumeration symbol table, resulting in a lack of supports for runtime enumeration. 249 250 \section{Enumeration Features} 251 A trait is a collection of constraints in \CFA, which can be used to describe types. 252 The \CFA standard library defines traits to categorize types with related enumeration features. 253 254 255 \subsection{Auto Initializable} 256 \label{s:AutoInitializable} 257 TODO: make the initialization rule a separate section. 258 259 If no explicit initializer is given to an enumeration constant, C initializes the first enumeration constant with value 0, and the other enumeration constant has a value equal to its $predecessor+1$. \CFA enumerations have the same rule in enumeration constant initialization. However, not all types can be automatically initialized by \CFA because the meaning of $zero$, $one$, and addition operator may not be well-defined. 260 261 A type is auto-initializable if it has defined $zero\_t$, $one\_t$, and an addition operator. 262 \begin{lstlisting} 148 263 forall(T) 149 264 trait AutoInitializable { 150 void ?()( T & t, zero_t ); 151 void ?()( T & t, one_t ); 152 S& ?+=?( T & t, one_t ); 153 void ?{}( T &, T ); 154 T ?{}( T &, T ); 155 }; 156 \end{lstlisting} 157 158 \subsection{AutoInitializable} 159 \begin{lstlisting}[style=CStyle] 160 forall(T) 161 trait AutoInitializable { 162 void ?()( T & t, zero_t ); 163 void ?()( T & t, one_t ); 164 S& ?+=?( T & t, one_t ); 165 void ?{}( T &, T ); 166 T ?{}( T &, T ); 167 }; 168 \end{lstlisting} 169 A type is AutoInitializable if it has defined a zero\_t constructor, a one\_t constructor, an addition assignment operator, a copy constructor, and a copy assignment operator. 170 171 \subsection{Enumerable Type} 172 \begin{lstlisting}[style=CStyle] 173 forall(T) 174 trait enumerable { 175 void ?()( T & t, zero_t ); 176 void ?()( T & t, one_t ); 177 S& ?+=?( T & t, one_t ); 178 void ?{}( T &, T ); 179 T ?{}( T &, T ); 180 }; 181 \end{lstlisting} 182 183 184 185 186 187 (Should change the definition of enumerable to something else. Maybe auto-constructible. If a type is not auto-constructible, all enumeration must be explicitly initialized) 188 \begin{lstlisting}[caption={An example enumerable type}, label{lst:sample_enumerable}, style=CStyle] 189 struct Type { int i; }; 190 void ?()( Type & t, zero_t ) { t.i = 0; }; 191 void ?()( Type & t, one_t ) { t.i = 1; }; 192 int ?!=?( Type t, zero_t ) { return t.i != 0; }; 193 S& ?+=?( Type & t, one_t ) { t.i += 1; return t; }; 194 void ?()( Type & t, Type rhs ) { t.i = rhs.i; }; 195 Type ?()( Type & t, Type rhs ) { t.i = rhs.i; return t; }; 196 \end{lstlisting} 197 198 A Cforall-enum is a C-enum parameterized by an enumerable type. For example, $enum(int)$ turns a C-enum into a Cforall-enum. 199 \begin{lstlisting}[caption={An example Cforall enum}, label{lst:sample_cforall_enum}, style=CStyle] 200 enum Color(Type) { Red, Green, Blue }; 201 202 > Type Color.values[] = { 0, values[0]++, values[1]++ }; 203 > enum Color.Label { Red_Label, Green_Label, Blue_Label }; 204 \end{lstlisting} 205 Declaring a Cforall-enum, the compiler defines a C-enum names every element in the Cforall-enum, and an array that stores Cforall enumeration values. 206 207 \subsection{Cforall Enumerations Behaviour} 208 An instance of Cforall-enum (denoted as $<enum\_instance>$) has a label, the defined enum name. The label can be retrieved by calling the function $label()$ on a $<enum\_instance>$. The $value()$ function on the other hand returns the value used to initialize the Cforall-enum. 209 210 Cforall-enum supports a qualified expression. The syntax of the qualified expression for Cforall-enum is $$<enum\_type\_name>.<enum\_instance\_name>$$. In the $Color$ example, $Color$ is a $<enum\_type\_name>$ and $Red$, $Green$, $Blue$ are $<enum\_instance\_name>$. 211 212 \begin{lstlisting}[caption={An example Cforall enum}, label{lst:sample_cforall_enum_usage}, style=CStyle] 213 enum Color red = Color.Red; 214 > enum Color.Label red = = Color.Label.Red_Label; 215 Type instance = Color.Red; 216 > Type instance = Color.values[ Color.Label.Red_Label ]; 217 \end{lstlisting} 218 219 The expression $Color.Red$ is overloaded to represent both $value(Color.Red)$ and $label(Color.Red)$. The expression returns the $label(Color.Red)$ by default but returns $value()$ whenever the $value()$ is a closer candidate in the context. [more explanation] In \ref{lst:sample_cforall_enum_usage}, when assigned to an enum variable, $Color.Red$ returns the label. This is to reduce the memory to store a Cforall-enum variable. In an assignment expression when the left-hand-side expects a $Type$, the resolution finds $value(Color.Red)$ is a better candidate than $label(Color.Red)$, and returns the value instead. 220 221 \subsection{Enum Type Functions} 222 \begin{lstlisting}[caption={Enum Type Functions}, label{lst:cforall_enum_functions}, style=CStyle] 223 enum Color(string) { // assume String has been defined as an enumerable type 224 R = "Red", G = "Green", B = "Blue" 225 }; 226 values( Color ); 227 > [ String("Red"), String("Green"), String("Blue") ]; 228 label_strings( Color ); 229 > [ "R", "G", "B" ]; 230 enum Color green = Color.G; 231 232 label_string( Color, green ); 233 > "G" 234 label( Color, green ); 235 > 1 236 value( Color, green ) ; 237 > "Green" 238 value( Color, "G" ); 239 > "Green" 240 label( Color, "G" ); 241 > 1 242 value( Color, "DNE" ); 243 > (null) 244 value( Color, 1 ); // "1" is the label "G" 245 > "Green" 246 \end{lstlisting} 247 Names of labels are distinct in an enum declaration. Cforall therefore allows indexing an enum value with its string representation of a label. 265 void ?()( T & t, zero_t ); 266 void ?()( T & t, one_t ); 267 S ?+?( T & t, one_t ); 268 }; 269 \end{lstlisting} 270 271 An example of user-defined @AutoInitializable@ would look like the following: 272 \begin{lstlisting}[label=lst:sample_auto_initializable] 273 struct Odd { int i; }; 274 void ?()( Odd & t, zero_t ) { t.i = 1; }; 275 void ?()( Odd & t, one_t ) { t.i = 2; }; 276 Odd ?+?( Odd t1, Odd t2 ) 277 { return Odd( t1.i + t2.i); }; 278 \end{lstlisting} 279 280 When an enumeration declares an AutoInitializable as its type, no explicit initialization is necessary. 281 \begin{lstlisting}[label=lst:sample_auto_initializable_usage] 282 enum AutoInitUsage(Odd) { 283 A, B, C = 6, D 284 }; 285 \end{lstlisting} 286 287 In the example~\ref{lst:sample_auto_initializable_usage}, because no initializer is specified for the first enumeration constant @A@, \CFA initializes it with the value of $zero_t$, which is 1. B and D have the values of their $predecessor + one_t$, while $one_t$ has the value 2. Therefore, the enumeration is initialized as the following: 288 289 \begin{lstlisting}[label=lst:sample_auto_initializable_usage_gen] 290 enum AutoInitUsage(Odd) { 291 A=1, B=3, C = 6, D=8 292 }; 293 \end{lstlisting} 294 295 In \CFA, integral types, float types, and imaginary numbers are example types that are AutoInitialiable. 296 \begin{lstlisting}[label=lst:letter] 297 enum Alphabet(int) { 298 A='A', B, C, D, E, F, G, H, I, J, K, L, M, 299 N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 300 a='a', b, c, d, e, f, g, h, i, j, k, l, m, 301 n, o, p, q, r, s, t, u, v, w, x, y, z 302 }; 303 print( "%c, %c, %c", Alphabet.F, Alphabet.o, Alphabet.o ); 304 >>> F, o, o 305 \end{lstlisting} 248 306 249 307 \subsection{Iteration and Range} 250 A Cforall enum is iterable and supports range function. 251 \begin{lstlisting}[caption={Range Functions}, label{lst:range_functions}, style=CStyle] 252 struct string; 253 enum(string) Weekday( 254 Monday = "M", Tuesday = "Tu", ... 255 }; 256 for ( i; Weekday ) { sout | i; } 257 >> M Tu W Th F Sat Sun 258 for ( Monday ~= Tuesday ) 259 >> M Tu 308 309 It is convenient to iterate over a \CFA enumeration. Here is the basic usage: 310 \begin{lstlisting}[label=lst:range_functions] 311 for ( Alphabet ch; Alphabet; ) { 312 printf( "%d ", ch ); 313 } 314 >>> A B C (...omit the rest) 315 316 \end{lstlisting} 317 The for-loop uses the enumeration type @Alphabet@ as range. When that happens, \CFA iterates all enumerators in the order they defined in the enumeration. 'ch' is the iterating enumerator, and it returns the value of an Alphabet in this context according to the precedence rule. 318 319 \CFA offers a shorthand for iterating all enumeration constants: 320 \begin{lstlisting}[label=lst:range_functions] 321 for ( Alphabet ch ) { 322 printf( "%d ", ch ); 323 } 324 >>> A B C (...omit the rest) 325 \end{lstlisting} 326 327 Enumeration supports the \CFA loop control syntax for for-loop. 328 \begin{lstlisting}[label=lst:range_functions] 329 for ( Alphabet.D ) 330 for ( ch; Alphabet.g ~ Alphabet.z ) 331 for ( Alphabet ch; Alphabet.R ~ Alphabet.X ~ 2 ) 332 \end{lstlisting} 333 334 Notably, the meaning of "step" of iteration has changed for enumeration. Consider the following example: 335 \begin{lstlisting}[label=lst:range_functions] 336 enum(int) Sequence { 337 A = 10, B = 12, C = 14; 338 } 339 for ( s; Sequence.A ~ Sequence.C ) { 340 printf( "%d ", s ); 341 } 342 343 >>> 10 12 14 344 345 for ( s; Sequence.A ~ Sequence.A ~ 2 ) { 346 printf( "%d ", s ); 347 } 348 >>> 10 14 349 \end{lstlisting} 350 The range iteration of enumeration does not return the $current\_value++$ until it reaches the upper bound. The semantics is to return the next enumeration constant. If a stepping is specified, 2 for example, it returns the 2 enumeration constant after the current one, rather than the $current+2$ 351 352 It is also possible to iterate over an enumeration's labels, implicitly or explicitly: 353 \begin{lstlisting}[label=lst:range_functions_label_implicit] 354 for ( char * ch; Alphabet ) 355 \end{lstlisting} 356 This for-loop implicitly iterates every label of the enumeration, because a label is the only valid resolution to the ch with type $char *$ in this case. If the value can also be resolved as the char *, you might iterate the labels explicitly with the array iteration. 357 \begin{lstlisting}[label=lst:range_functions_label_implicit] 358 for ( char * ch; labels( Alphabet ) ) 260 359 \end{lstlisting} 261 360 262 361 \section{Implementation} 263 264 \subsection{Companion Object} 265 The intuition to create a companion object is that functions that support enumeration features need static information of an enumeration class. For example, values() returns an array of values defined for the enumeration. $label( Color, "G" )$ needs information about enum names defined for the enum class $Color$. Theoretically, enum-type functions can be defined as functions that take $TypeName$ expression as the first parameter. An alternative approach is to define that "companion object". 266 267 \begin{lstlisting}[caption={Enum Type Functions}, label{lst:cforall_enum_functions}, style=CStyle] 268 struct string; 269 enum Color( string ) { 270 R = "Red", G = "Green", B = "Blue" 271 }; 272 273 forall( T | enumerable(T) ) { 274 struct Companion { 275 T* values; 276 char** labels; 277 }; 278 } 279 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 280 enum Color.Label; 281 Companion( string ) Color = { 282 .values = [ "Red", "Green", "Blue" ], 283 .labels = [ "R", "G", "B" ] 284 }; 285 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 286 forall( T | enumerable(T) ) 287 T value( Companion companion, int index ) { return companion.values[ index ]; } 288 T value( Companion, enum Color.Label ); 289 char* label( Companion companion, int index ) { return companion.values[ index ]; } 290 char* label( Companion, enum Color.Label ); 291 292 \end{lstlisting} 293 294 295 \subsection{Companion Trait} 296 Users can define the companion object themselves. A companion object should define an array of any type called values and an array of strings representing a label. Defining a companion object effectively creates a new enumerable type. 297 298 \subsection{Companion Mapping} 299 300 301 302 \begin{lstlisting}[caption={Enum Type Functions}, label{lst:cforall_enum_functions}, style=CStyle] 303 304 \end{lstlisting} 305 %% 306 %% If your work has an appendix, this is the place to put it. 307 \appendix 308 362 \CFA places the definition of Companion structure and non-parameterized Companion functions in the prelude, visible globally. 363 364 \subsection{declaration} 365 The qualified enumeration syntax is dedicated to \CFA enumeration. 366 \begin{lstlisting}[label=lst:range_functions] 367 enum (type_declaration) name { enumerator = const_expr, enumerator = const_expr, ... } 368 \end{lstlisting} 369 A compiler stores the name, the underlying type, and all enumerators in an @enumeration table@. During the $Validation$ pass, the compiler links the type declaration to the type's definition. It ensures that the name of an enumerator is unique within the enumeration body, and checks if all values of the enumerator have the declaration type. If the declared type is not @Auto Initializable@, \CFA rejects the enumeration definition. Otherwise, it attempts to initialize enumerators with the enumeration initialization pattern. (a reference to a future initialization pattern section) 370 371 \begin{lstlisting}[label=lst:init] 372 struct T { ... }; 373 void ?{}( T & t, zero_t ) { ... }; 374 void ?{}( T & t, one_t ) { ... }; 375 T ?+?( T & lhs, T & rhs ) { ... }; 376 377 enum (T) Sample { 378 Zero: 0 /* zero_t */, 379 One: Zero + 1 /* ?+?( Zero, one_t ) */ , ... 380 }; 381 \end{lstlisting} 382 383 Challenge: 384 The value of an enumerator, or the initializer, requires $const\_expr$. While previously getting around the issue by pushing it to the C compiler, it might not work anymore because of the user-defined types, user-defined $zero\_t$, $one\_t$, and addition operation. Might not be able to implement a *Correct* static check. 385 386 \CFA $autogens$ a Companion object for the declared enumeration. 387 \begin{lstlisting}[label=lst:companion] 388 Companion( T ) Sample { 389 .values: { 0, 0+1, 0+1+1, 0+1+1+1, ... }, /* 0: zero_t, 1: one_t, +: ?+?{} */ 390 .labels: { "Zero", "One", "Two", "Three", ...}, 391 .length: /* number of enumerators */ 392 }; 393 \end{lstlisting} 394 \CFA stores values as intermediate expressions because the result of the function call to the function $?+?{}(T\&, T\&)$ is statically unknown to \CFA. But the result will be computed in run time, and the compiler ensures the $values$ will not be changed. 395 396 \subsection{qualified expression} 397 \CFA uses qualified expression to address the scoping of \CFA-enumeration. 398 \begin{lstlisting}[label=lst:qualified_expression] 399 aggregation_name.field; 400 \end{lstlisting} 401 The qualified expression is not dedicated to \CFA enumeration. It is a feature that is supported by other aggregation in \CFA as well, including a C enumeration. When C enumerations are unscoped, the qualified expression syntax still helps to disambiguate names in the context. \CFA recognizes if the expression references a \CFA aggregation by searching the presence of $aggregation\_name$ in the \CFA enumeration table. If the $aggregation\_name$ is identified as a \CFA enumeration, the compiler checks if $field$ presents in the declared \CFA enumeration. 402 403 \subsection{with statement/statement} 404 @Working in Progress@ 405 Instead of qualifying an enumeration expression every time, one can use the $with$ to expose enumerators to the current scope so that they are directly accessible. 406 407 \subsection{instance declaration} 408 @Working in Progress@ 409 \begin{lstlisting}[label=lst:declaration] 410 enum Sample s1; 411 Sample s2; 412 \end{lstlisting} 413 A declaration of \CFA enumeration instance that has no difference than a C enumeration or other \CFA aggregation. The compiler recognizes the type of a variable declaration by searching the name in all possible types. The \textit{enum} keyword is not necessary but helps to disambiguate types (questionable). The generated code for a \CFA enumeration declaration is utterly an integer, which is meant to store the position. 414 \begin{lstlisting}[label=lst:declaration] 415 int s1; 416 int s2; 417 \end{lstlisting} 418 419 \subsection{Compiler Representation} 420 @Working in Progress@ 421 422 The internal representation of an enumeration constant is \textit{EnumInstType}. The minimum information an \textit{EnumInstType} stores is a reference to the \CFA-enumeration declaration and the position of the enumeration constant. 423 \begin{lstlisting}[label=lst:EnumInstType] 424 class EnumInstType { 425 EnumDecl enumDecl; 426 int position; 427 }; 428 \end{lstlisting} 429 430 431 \subsection{unification and resolution } 432 @Working in Progress@ 433 434 \begin{lstlisting} 435 enum Colour( char * ) { Red = "R", Green = "G", Blue = "B" }; 436 \end{lstlisting} 437 The EnumInstType is convertible to other types. A \CFA enumeration expression is implicitly "overloaded" with its three different attributes: value, position, and label. The \CFA compilers need to resolve an EnumInstType as one of its attributes based on the current context. 438 439 \begin{lstlisting}[caption={Null Context}, label=lst:null_context] 440 { 441 Colour.Green; 442 } 443 \end{lstlisting} 444 In the example~\ref{lst:null_context}, the environment gives no information to help with the resolution of $Colour.Green$. In this case, any of the attributes is resolvable. According to the \textit{precedence rule}, the expression with EnumInstType will be resolved as $value( Colour.Green )$. The EnumInstType is converted to the type of the value, which is statically known to the compiler as char *. When the compilation reaches the code generation, the compiler outputs code for type char * with the value "G". 445 \begin{lstlisting}[caption={Null Context Generated Code}, label=lst:null_context] 446 { 447 "G"; 448 } 449 \end{lstlisting} 450 451 452 \begin{lstlisting}[caption={int Context}, label=lst:int_context] 453 { 454 int g = Colour.Green; 455 } 456 \end{lstlisting} 457 458 The assignment expression gives a context for the EnumInstType resolution. The EnumInstType is used as an int, and \CFA needs to determine which of the attributes can be resolved as an int type. 459 The functions $Unify( T1, T2 ): bool$ take two types as parameters and determine if one type can be used as another. In the example\ref{lst:int_context} example, the compiler is trying to unify int and EnumInstType of Colour. 460 $$Unification( int, EnumInstType<Colour> )$$ 461 which turns into three Unification call 462 \begin{lstlisting}[label=lst:attr_resolution_1] 463 { 464 Unify( int, char * ); // unify with the type of value 465 Unify( int, int ); // unify with the type of position 466 Unify( int, char * ); // unify with the type of label 467 } 468 \end{lstlisting} 469 470 \begin{lstlisting}[label=lst:attr_resolution_precedence] 471 { 472 Unification( T1, EnumInstType<T2> ) { 473 if ( Unify( T1, T2 ) ) return T2; 474 if ( Unify( T1, int ) ) return int; 475 if ( Unify( T1, char * ) ) return char *; 476 Error: Cannot Unify T1 with EnumInstType<T2>; 477 } 478 } 479 \end{lstlisting} 480 After the unification, EnumInstType will be replaced by its attributes. 481 482 \begin{lstlisting}[caption={Unification Functions}, label=lst:unification_func_call] 483 { 484 T2 foo ( T1 ); // function take variable with T1 as a parameter 485 foo( EnumInstType<T3> ); // Call foo with a variable has type EnumInstType<T3> 486 >>>> Unification( T1, EnumInstType<T3> ) 487 } 488 \end{lstlisting} 489 490 % The conversion can work backward: in restrictive cases, attributes of can be implicitly converted back to the EnumInstType. 491 Backward conversion: 492 \begin{lstlisting}[caption={Unification Functions}, label=lst:unification_func_call] 493 { 494 enum Colour colour = 1; 495 } 496 \end{lstlisting} 497 498 \begin{lstlisting}[caption={Unification Functions}, label=lst:unification_func_call] 499 { 500 Unification( EnumInstType<Colour>, int ) >>> label 501 } 502 \end{lstlisting} 503 int can be unified with the label of Colour. "5" is a constant expression -> Compiler knows the value during the compilation -> turns it into 504 \begin{lstlisting} 505 { 506 enum Colour colour = Colour.Green; 507 } 508 \end{lstlisting} 509 Steps: 510 1: identify "1" as a constant expression with type int, and the value is statically known as 1 511 2. unification( EnumInstType<Colour>, int ): position( EnumInstType< Colour > ) 512 3. return the enumeration constant at the position 1 513 514 \begin{lstlisting} 515 { 516 enum T (int) { ... } // Declaration 517 enum T t = 1; 518 } 519 \end{lstlisting} 520 Steps: 521 1: identify "1" as a constant expression with type int, and the value is statically known as 1 522 2. unification( EnumInstType<Colour>, int ): value( EnumInstType< Colour > ) 523 3. return the FIRST enumeration constant that has the value 1, by searching through the values array 524 525 The downside of the precedence rule: EnumInstType -> int ( value ) -> EnumInstType may return a different EnumInstType because the value can be repeated and there is no way to know which one is expected -> want uniqueness 309 526 310 527 \end{document} 311 \endinput 312 %% 313 %% End of file `sample-manuscript.tex'. 528 529 % Local Variables: % 530 % tab-width: 4 % 531 % compile-command: "pdflatex enum.tex" % 532 % End: %
Note: See TracChangeset
for help on using the changeset viewer.