Changeset d33bc7c


Ignore:
Timestamp:
Jun 16, 2017, 3:25:58 PM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
0e44184, 1bc9dcb, 20877d2
Parents:
cc3e4d0 (diff), f522618 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

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

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • doc/proposals/tagged-struct.txt

    rcc3e4d0 rd33bc7c  
    33Tagged structures allow for dynamic casting between types in a hierarchy.
    44Children (rather pointers to) can be up-cast to their parents, a safe
    5 conversion that may recive language level support or even be implicate.
     5conversion that may recive language level support or even be implicit.
    66Parents can be down cast to their children, which might fail if the underlying
    77object is not of the child type, or a child of that.
     
    1111function call.
    1212
    13 Tags cannot be used on unions. This is because the different sides interact
    14 with the casts rather badly. There is a similarity with tagged unions still.
    15 Tagged structures also carry data to identify which out of several
    16 possibilies the object actually is. Although the possibilies are dynamic in
    17 this case.
     13The name tagged structure comes from tagged union, which carries a value to
     14say which of the possible values is currently stored in the union. The idea
     15here is similar, however the possibilities are more open ended.
    1816
    1917
     
    2321
    2422The keywords can change (although they currently reflect the concept name
    25 closely). More formally, in terms of grammer this adds:
     23closely). More formally, in terms of grammar this adds:
    2624
    2725struct-or-union-specifier
     
    4846parent type object.
    4947
    50 If the type field is given a simple name, then the user can easily access the
    51 type object. This might be useful depending on what sort of data is in the
    52 type object, especially if the data can be added to by the user in some way.
    53 Ironically one way to accomplish that is to make the type objects tagged
    54 themselves, but that recursion might not have a base case.
     48The type field could be hidden (as best as C can hide it) or it could be
     49visible to the user with easy access to allow the user to examine the type
     50object directly.
    5551
    56 If the name is mangled and direct access to type objects is still wanted, then
    57 a function could be used to access the type object. Say get_type or get_tag
    58 instead of type or tag.
     52Direct access is more useful if the data on the type-objects can change, other
     53wise the build in function could handle all cases. Perhaps each root object
     54can specify a type object to use or the type objects are themselves tagged,
     55although there may not be a base case with the latter.
    5956
    60 If the data on the type object is set, than providing direct access may be
    61 unnessary. Instead the libraries or base code might be able to implement
    62 everything the data is for.
     57In the simplest case the type object is a pointer to the parent type object.
     58Additional data could be added, such as a name, or a function pointer to the
     59destructor.
    6360
    6461
     
    8481
    8582bug#11 might require `bool dynamic_cast(T ** dst, U * src)` instead.
     83
     84
     85Tagging Unions (Extention):
     86
     87Using this system as is does not really work if used on unions directly.
     88No new options to the union can be added, as they must be able to upcast.
     89Similarly, if options are removed, writing to an upcast union is invalid.
     90To allow for growth each option would have to be a structure itself.
     91
     92Which brings us to "tagget struct union", ie. a union of tagged structures
     93as opposed to tagging the union itself. This extention acts as a constraint.
     94If unions are declared tagged instead of creating a new tagged type, all
     95possible values of the union must be of that tagged type or a child type.
  • doc/user/user.tex

    rcc3e4d0 rd33bc7c  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Tue Jun 13 11:50:27 2017
    14 %% Update Count     : 2403
     13%% Last Modified On : Fri Jun 16 12:00:01 2017
     14%% Update Count     : 2433
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    4343\usepackage[pagewise]{lineno}
    4444\renewcommand{\linenumberfont}{\scriptsize\sffamily}
    45 \input{common}                                          % bespoke macros used in the document
     45\input{common}                                          % common CFA document macros
    4646\usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref}
    4747\usepackage{breakurl}
     
    110110\renewcommand{\subsectionmark}[1]{\markboth{\thesubsection\quad #1}{\thesubsection\quad #1}}
    111111\pagenumbering{roman}
    112 \linenumbers                                            % comment out to turn off line numbering
     112%\linenumbers                                            % comment out to turn off line numbering
    113113
    114114\maketitle
     
    881881
    882882
     883\subsection{Initialization}
     884
     885\Index{Initialization} is different than \Index{assignment} because initialization occurs on the empty (uninitialized) storage on an object, while assignment occurs on possibly initialized storage of an object.
     886There are three initialization contexts in \CFA: declaration initialization, argument/parameter binding, return/temporary binding.
     887Because the object being initialized has no value, there is only one meaningful semantics with respect to address duality: it must mean address as there is no pointed-to value.
     888In contrast, the left-hand side of assignment has an address that has a duality.
     889Therefore, for pointer/reference initialization, the initializing value must be an address not a value.
     890\begin{cfa}
     891int * p = &x;                                           §\C{// assign address of x}§
     892®int * p = x;®                                          §\C{// assign value of x}§
     893int & r = x;                                            §\C{// must have address of x}§
     894\end{cfa}
     895Like the previous example with C pointer-arithmetic, it is unlikely assigning the value of ©x© into a pointer is meaningful (again, a warning is usually given).
     896Therefore, for safety, this context requires an address, so it is superfluous to require explicitly taking the address of the initialization object, even though the type is incorrect.
     897Note, this is strictly a convenience and safety feature for a programmer.
     898Hence, \CFA allows ©r© to be assigned ©x© because it infers a reference for ©x©, by implicitly inserting a address-of operator, ©&©, and it is an error to put an ©&© because the types no longer match due to the implicit dereference.
     899Unfortunately, C allows ©p© to be assigned with ©&x© (address) or ©x© (value), but most compilers warn about the latter assignment as being potentially incorrect.
     900Similarly, when a reference type is used for a parameter/return type, the call-site argument does not require a reference operator for the same reason.
     901\begin{cfa}
     902int & f( int & r );                                     §\C{// reference parameter and return}§
     903z = f( x ) + f( y );                            §\C{// reference operator added, temporaries needed for call results}§
     904\end{cfa}
     905Within routine ©f©, it is possible to change the argument by changing the corresponding parameter, and parameter ©r© can be locally reassigned within ©f©.
     906Since operator routine ©?+?© takes its arguments by value, the references returned from ©f© are used to initialize compiler generated temporaries with value semantics that copy from the references.
     907\begin{cfa}
     908int temp1 = f( x ), temp2 = f( y );
     909z = temp1 + temp2;
     910\end{cfa}
     911This \Index{implicit referencing} is crucial for reducing the syntactic burden for programmers when using references;
     912otherwise references have the same syntactic  burden as pointers in these contexts.
     913
     914When a pointer/reference parameter has a ©const© value (immutable), it is possible to pass literals and expressions.
     915\begin{cfa}
     916void f( ®const® int & cr );
     917void g( ®const® int * cp );
     918f( 3 );                   g( ®&®3 );
     919f( x + y );             g( ®&®(x + y) );
     920\end{cfa}
     921Here, the compiler passes the address to the literal 3 or the temporary for the expression ©x + y©, knowing the argument cannot be changed through the parameter.
     922The ©&© before the constant/expression for the pointer-type parameter (©g©) is a \CFA extension necessary to type match and is a common requirement before a variable in C (\eg ©scanf©).
     923Importantly, ©&3© may not be equal to ©&3©, where the references occur across calls because the temporaries maybe different on each call.
     924
     925\CFA \emph{extends} this semantics to a mutable pointer/reference parameter, and the compiler implicitly creates the necessary temporary (copying the argument), which is subsequently pointed-to by the reference parameter and can be changed.\footnote{
     926If whole program analysis is possible, and shows the parameter is not assigned, \ie it is ©const©, the temporary is unnecessary.}
     927\begin{cfa}
     928void f( int & r );
     929void g( int * p );
     930f( 3 );                   g( ®&®3 );            §\C{// compiler implicit generates temporaries}§
     931f( x + y );             g( ®&®(x + y) );        §\C{// compiler implicit generates temporaries}§
     932\end{cfa}
     933Essentially, there is an implicit \Index{rvalue} to \Index{lvalue} conversion in this case.\footnote{
     934This conversion attempts to address the \newterm{const hell} problem, when the innocent addition of a ©const© qualifier causes a cascade of type failures, requiring an unknown number of additional ©const© qualifiers, until it is discovered a ©const© qualifier cannot be added and all the ©const© qualifiers must be removed.}
     935The implicit conversion allows seamless calls to any routine without having to explicitly name/copy the literal/expression to allow the call.
     936
     937%\CFA attempts to handle pointers and references in a uniform, symmetric manner.
     938Finally, C handles \Index{routine object}s in an inconsistent way.
     939A routine object is both a pointer and a reference (\Index{particle and wave}).
     940\begin{cfa}
     941void f( int i );
     942void (*fp)( int );                                      §\C{// routine pointer}§
     943fp = f;                                                         §\C{// reference initialization}§
     944fp = &f;                                                        §\C{// pointer initialization}§
     945fp = *f;                                                        §\C{// reference initialization}§
     946fp(3);                                                          §\C{// reference invocation}§
     947(*fp)(3);                                                       §\C{// pointer invocation}§
     948\end{cfa}
     949While C's treatment of routine objects has similarity to inferring a reference type in initialization contexts, the examples are assignment not initialization, and all possible forms of assignment are possible (©f©, ©&f©, ©*f©) without regard for type.
     950Instead, a routine object should be referenced by a ©const© reference:
     951\begin{cfa}
     952®const® void (®&® fr)( int ) = f;       §\C{// routine reference}§
     953fr = ...                                                        §\C{// error, cannot change code}§
     954&fr = ...;                                                      §\C{// changing routine reference}§
     955fr( 3 );                                                        §\C{// reference call to f}§
     956(*fr)(3);                                                       §\C{// error, incorrect type}§
     957\end{cfa}
     958because the value of the routine object is a routine literal, \ie the routine code is normally immutable during execution.\footnote{
     959Dynamic code rewriting is possible but only in special circumstances.}
     960\CFA allows this additional use of references for routine objects in an attempt to give a more consistent meaning for them.
     961
     962
    883963\subsection{Address-of Semantics}
    884964
     
    9581038
    9591039
    960 \subsection{Initialization}
    961 
    962 \Index{Initialization} is different than \Index{assignment} because initialization occurs on the empty (uninitialized) storage on an object, while assignment occurs on possibly initialized storage of an object.
    963 There are three initialization contexts in \CFA: declaration initialization, argument/parameter binding, return/temporary binding.
    964 Because the object being initialized has no value, there is only one meaningful semantics with respect to address duality: it must mean address as there is no pointed-to value.
    965 In contrast, the left-hand side of assignment has an address that has a duality.
    966 Therefore, for pointer/reference initialization, the initializing value must be an address not a value.
    967 \begin{cfa}
    968 int * p = &x;                                           §\C{// assign address of x}§
    969 ®int * p = x;®                                          §\C{// assign value of x}§
    970 int & r = x;                                            §\C{// must have address of x}§
    971 \end{cfa}
    972 Like the previous example with C pointer-arithmetic, it is unlikely assigning the value of ©x© into a pointer is meaningful (again, a warning is usually given).
    973 Therefore, for safety, this context requires an address, so it is superfluous to require explicitly taking the address of the initialization object, even though the type is incorrect.
    974 Note, this is strictly a convenience and safety feature for a programmer.
    975 Hence, \CFA allows ©r© to be assigned ©x© because it infers a reference for ©x©, by implicitly inserting a address-of operator, ©&©, and it is an error to put an ©&© because the types no longer match due to the implicit dereference.
    976 Unfortunately, C allows ©p© to be assigned with ©&x© (address) or ©x© (value), but most compilers warn about the latter assignment as being potentially incorrect.
    977 Similarly, when a reference type is used for a parameter/return type, the call-site argument does not require a reference operator for the same reason.
    978 \begin{cfa}
    979 int & f( int & r );                                     §\C{// reference parameter and return}§
    980 z = f( x ) + f( y );                            §\C{// reference operator added, temporaries needed for call results}§
    981 \end{cfa}
    982 Within routine ©f©, it is possible to change the argument by changing the corresponding parameter, and parameter ©r© can be locally reassigned within ©f©.
    983 Since operator routine ©?+?© takes its arguments by value, the references returned from ©f© are used to initialize compiler generated temporaries with value semantics that copy from the references.
    984 \begin{cfa}
    985 int temp1 = f( x ), temp2 = f( y );
    986 z = temp1 + temp2;
    987 \end{cfa}
    988 This \Index{implicit referencing} is crucial for reducing the syntactic burden for programmers when using references;
    989 otherwise references have the same syntactic  burden as pointers in these contexts.
    990 
    991 When a pointer/reference parameter has a ©const© value (immutable), it is possible to pass literals and expressions.
    992 \begin{cfa}
    993 void f( ®const® int & cr );
    994 void g( ®const® int * cp );
    995 f( 3 );                   g( ®&®3 );
    996 f( x + y );             g( ®&®(x + y) );
    997 \end{cfa}
    998 Here, the compiler passes the address to the literal 3 or the temporary for the expression ©x + y©, knowing the argument cannot be changed through the parameter.
    999 The ©&© before the constant/expression for the pointer-type parameter (©g©) is a \CFA extension necessary to type match and is a common requirement before a variable in C (\eg ©scanf©).
    1000 Importantly, ©&3© may not be equal to ©&3©, where the references occur across calls because the temporaries maybe different on each call.
    1001 
    1002 \CFA \emph{extends} this semantics to a mutable pointer/reference parameter, and the compiler implicitly creates the necessary temporary (copying the argument), which is subsequently pointed-to by the reference parameter and can be changed.\footnote{
    1003 If whole program analysis is possible, and shows the parameter is not assigned, \ie it is ©const©, the temporary is unnecessary.}
    1004 \begin{cfa}
    1005 void f( int & r );
    1006 void g( int * p );
    1007 f( 3 );                   g( ®&®3 );            §\C{// compiler implicit generates temporaries}§
    1008 f( x + y );             g( ®&®(x + y) );        §\C{// compiler implicit generates temporaries}§
    1009 \end{cfa}
    1010 Essentially, there is an implicit \Index{rvalue} to \Index{lvalue} conversion in this case.\footnote{
    1011 This conversion attempts to address the \newterm{const hell} problem, when the innocent addition of a ©const© qualifier causes a cascade of type failures, requiring an unknown number of additional ©const© qualifiers, until it is discovered a ©const© qualifier cannot be added and all the ©const© qualifiers must be removed.}
    1012 The implicit conversion allows seamless calls to any routine without having to explicitly name/copy the literal/expression to allow the call.
    1013 
    1014 %\CFA attempts to handle pointers and references in a uniform, symmetric manner.
    1015 Finally, C handles \Index{routine object}s in an inconsistent way.
    1016 A routine object is both a pointer and a reference (\Index{particle and wave}).
    1017 \begin{cfa}
    1018 void f( int i );
    1019 void (*fp)( int );                                      §\C{// routine pointer}§
    1020 fp = f;                                                         §\C{// reference initialization}§
    1021 fp = &f;                                                        §\C{// pointer initialization}§
    1022 fp = *f;                                                        §\C{// reference initialization}§
    1023 fp(3);                                                          §\C{// reference invocation}§
    1024 (*fp)(3);                                                       §\C{// pointer invocation}§
    1025 \end{cfa}
    1026 While C's treatment of routine objects has similarity to inferring a reference type in initialization contexts, the examples are assignment not initialization, and all possible forms of assignment are possible (©f©, ©&f©, ©*f©) without regard for type.
    1027 Instead, a routine object should be referenced by a ©const© reference:
    1028 \begin{cfa}
    1029 ®const® void (®&® fr)( int ) = f;       §\C{// routine reference}§
    1030 fr = ...                                                        §\C{// error, cannot change code}§
    1031 &fr = ...;                                                      §\C{// changing routine reference}§
    1032 fr( 3 );                                                        §\C{// reference call to f}§
    1033 (*fr)(3);                                                       §\C{// error, incorrect type}§
    1034 \end{cfa}
    1035 because the value of the routine object is a routine literal, \ie the routine code is normally immutable during execution.\footnote{
    1036 Dynamic code rewriting is possible but only in special circumstances.}
    1037 \CFA allows this additional use of references for routine objects in an attempt to give a more consistent meaning for them.
    1038 
    1039 
    1040 
    10411040\begin{comment}
    1042 \section{References}
    1043 
    1044 By introducing references in parameter types, users are given an easy way to pass a value by reference, without the need for NULL pointer checks.
    1045 In structures, a reference can replace a pointer to an object that should always have a valid value.
    1046 When a structure contains a reference, all of its constructors must initialize the reference and all instances of this structure must initialize it upon definition.
    1047 
    1048 The syntax for using references in \CFA is the same as \CC with the exception of reference initialization.
    1049 Use ©&© to specify a reference, and access references just like regular objects, not like pointers (use dot notation to access fields).
    1050 When initializing a reference, \CFA uses a different syntax which differentiates reference initialization from assignment to a reference.
    1051 The ©&© is used on both sides of the expression to clarify that the address of the reference is being set to the address of the variable to which it refers.
    1052 
    1053 
    10541041From: Richard Bilson <rcbilson@gmail.com>
    10551042Date: Wed, 13 Jul 2016 01:58:58 +0000
     
    12131200\section{Routine Definition}
    12141201
    1215 \CFA also supports a new syntax for routine definition, as well as ISO C and K\&R routine syntax.
     1202\CFA also supports a new syntax for routine definition, as well as \Celeven and K\&R routine syntax.
    12161203The point of the new syntax is to allow returning multiple values from a routine~\cite{Galletly96,CLU}, \eg:
    12171204\begin{cfa}
     
    12331220in both cases the type is assumed to be void as opposed to old style C defaults of int return type and unknown parameter types, respectively, as in:
    12341221\begin{cfa}
    1235 [§\,§] g();                                             §\C{// no input or output parameters}§
    1236 [ void ] g( void );                             §\C{// no input or output parameters}§
     1222[§\,§] g();                                                     §\C{// no input or output parameters}§
     1223[ void ] g( void );                                     §\C{// no input or output parameters}§
    12371224\end{cfa}
    12381225
     
    12521239\begin{cfa}
    12531240typedef int foo;
    1254 int f( int (* foo) );                   §\C{// foo is redefined as a parameter name}§
     1241int f( int (* foo) );                           §\C{// foo is redefined as a parameter name}§
    12551242\end{cfa}
    12561243The string ``©int (* foo)©'' declares a C-style named-parameter of type pointer to an integer (the parenthesis are superfluous), while the same string declares a \CFA style unnamed parameter of type routine returning integer with unnamed parameter of type pointer to foo.
     
    12601247C-style declarations can be used to declare parameters for \CFA style routine definitions, \eg:
    12611248\begin{cfa}
    1262 [ int ] f( * int, int * );              §\C{// returns an integer, accepts 2 pointers to integers}§
    1263 [ * int, int * ] f( int );              §\C{// returns 2 pointers to integers, accepts an integer}§
     1249[ int ] f( * int, int * );                      §\C{// returns an integer, accepts 2 pointers to integers}§
     1250[ * int, int * ] f( int );                      §\C{// returns 2 pointers to integers, accepts an integer}§
    12641251\end{cfa}
    12651252The reason for allowing both declaration styles in the new context is for backwards compatibility with existing preprocessor macros that generate C-style declaration-syntax, as in:
    12661253\begin{cfa}
    12671254#define ptoa( n, d ) int (*n)[ d ]
    1268 int f( ptoa( p, 5 ) ) ...               §\C{// expands to int f( int (*p)[ 5 ] )}§
    1269 [ int ] f( ptoa( p, 5 ) ) ...   §\C{// expands to [ int ] f( int (*p)[ 5 ] )}§
     1255int f( ptoa( p, 5 ) ) ...                       §\C{// expands to int f( int (*p)[ 5 ] )}§
     1256[ int ] f( ptoa( p, 5 ) ) ...           §\C{// expands to [ int ] f( int (*p)[ 5 ] )}§
    12701257\end{cfa}
    12711258Again, programmers are highly encouraged to use one declaration form or the other, rather than mixing the forms.
     
    12891276        int z;
    12901277        ... x = 0; ... y = z; ...
    1291         ®return;® §\C{// implicitly return x, y}§
     1278        ®return;®                                                       §\C{// implicitly return x, y}§
    12921279}
    12931280\end{cfa}
     
    12991286[ int x, int y ] f() {
    13001287        ...
    1301 } §\C{// implicitly return x, y}§
     1288}                                                                               §\C{// implicitly return x, y}§
    13021289\end{cfa}
    13031290In this case, the current values of ©x© and ©y© are returned to the calling routine just as if a ©return© had been encountered.
     1291
     1292Named return values may be used in conjunction with named parameter values;
     1293specifically, a return and parameter can have the same name.
     1294\begin{cfa}
     1295[ int x, int y ] f( int, x, int y ) {
     1296        ...
     1297}                                                                               §\C{// implicitly return x, y}§
     1298\end{cfa}
     1299This notation allows the compiler to eliminate temporary variables in nested routine calls.
     1300\begin{cfa}
     1301[ int x, int y ] f( int, x, int y );    §\C{// prototype declaration}§
     1302int a, b;
     1303[a, b] = f( f( f( a, b ) ) );
     1304\end{cfa}
     1305While the compiler normally ignores parameters names in prototype declarations, here they are used to eliminate temporary return-values by inferring that the results of each call are the inputs of the next call, and ultimately, the left-hand side of the assignment.
     1306Hence, even without the body of routine ©f© (separate compilation), it is possible to perform a global optimization across routine calls.
     1307The compiler warns about naming inconsistencies between routine prototype and definition in this case, and behaviour is \Index{undefined} if the programmer is inconsistent.
    13041308
    13051309
     
    13091313as well, parameter names are optional, \eg:
    13101314\begin{cfa}
    1311 [ int x ] f ();                                 §\C{// returning int with no parameters}§
    1312 [ * int ] g (int y);                    §\C{// returning pointer to int with int parameter}§
    1313 [ ] h (int,char);                               §\C{// returning no result with int and char parameters}§
    1314 [ * int,int ] j (int);                  §\C{// returning pointer to int and int, with int parameter}§
     1315[ int x ] f ();                                                 §\C{// returning int with no parameters}§
     1316[ * int ] g (int y);                                    §\C{// returning pointer to int with int parameter}§
     1317[ ] h ( int, char );                                    §\C{// returning no result with int and char parameters}§
     1318[ * int, int ] j ( int );                               §\C{// returning pointer to int and int, with int parameter}§
    13151319\end{cfa}
    13161320This syntax allows a prototype declaration to be created by cutting and pasting source text from the routine definition header (or vice versa).
     
    13201324\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{C}}        \\
    13211325\begin{cfa}
    1322 [ int ] f(int), g;
     1326[ int ] f( int ), g;
    13231327\end{cfa}
    13241328&
    13251329\begin{cfa}
    1326 int f(int), g(int);
     1330int f( int ), g( int );
    13271331\end{cfa}
    13281332\end{tabular}
     
    13301334Declaration qualifiers can only appear at the start of a \CFA routine declaration,\footref{StorageClassSpecifier} \eg:
    13311335\begin{cfa}
    1332 extern [ int ] f (int);
    1333 static [ int ] g (int);
     1336extern [ int ] f ( int );
     1337static [ int ] g ( int );
    13341338\end{cfa}
    13351339
     
    13391343The syntax for pointers to \CFA routines specifies the pointer name on the right, \eg:
    13401344\begin{cfa}
    1341 * [ int x ] () fp;                      §\C{// pointer to routine returning int with no parameters}§
    1342 * [ * int ] (int y) gp;         §\C{// pointer to routine returning pointer to int with int parameter}§
    1343 * [ ] (int,char) hp;            §\C{// pointer to routine returning no result with int and char parameters}§
    1344 * [ * int,int ] (int) jp;       §\C{// pointer to routine returning pointer to int and int, with int parameter}§
     1345* [ int x ] () fp;                                              §\C{// pointer to routine returning int with no parameters}§
     1346* [ * int ] (int y) gp;                                 §\C{// pointer to routine returning pointer to int with int parameter}§
     1347* [ ] (int,char) hp;                                    §\C{// pointer to routine returning no result with int and char parameters}§
     1348* [ * int,int ] ( int ) jp;                             §\C{// pointer to routine returning pointer to int and int, with int parameter}§
    13451349\end{cfa}
    13461350While parameter names are optional, \emph{a routine name cannot be specified};
    13471351for example, the following is incorrect:
    13481352\begin{cfa}
    1349 * [ int x ] f () fp;            §\C{// routine name "f" is not allowed}§
     1353* [ int x ] f () fp;                                    §\C{// routine name "f" is not allowed}§
    13501354\end{cfa}
    13511355
     
    15341538        int ;                                   §\C{// disallowed, unnamed field}§
    15351539        int *;                                  §\C{// disallowed, unnamed field}§
    1536         int (*)(int);                   §\C{// disallowed, unnamed field}§
     1540        int (*)( int );                 §\C{// disallowed, unnamed field}§
    15371541};
    15381542\end{cfa}
     
    16571661}
    16581662int main() {
    1659         * [int](int) fp = foo();        §\C{// int (*fp)(int)}§
     1663        * [int]( int ) fp = foo();      §\C{// int (*fp)( int )}§
    16601664        sout | fp( 3 ) | endl;
    16611665}
     
    27782782
    27792783
    2780 \subsection{Constructors and Destructors}
     2784\section{Constructors and Destructors}
    27812785
    27822786\CFA supports C initialization of structures, but it also adds constructors for more advanced initialization.
     
    31093113
    31103114
     3115\begin{comment}
    31113116\section{Generics}
    31123117
     
    33153320        }
    33163321\end{cfa}
     3322\end{comment}
    33173323
    33183324
     
    33743380        Complex *p3 = new(0.5, 1.0); // allocate + 2 param constructor
    33753381}
    3376 
    33773382\end{cfa}
    33783383
     
    33863391
    33873392
     3393\begin{comment}
    33883394\subsection{Unsafe C Constructs}
    33893395
     
    33963402The exact set of unsafe C constructs that will be disallowed in \CFA has not yet been decided, but is sure to include pointer arithmetic, pointer casting, etc.
    33973403Once the full set is decided, the rules will be listed here.
     3404\end{comment}
    33983405
    33993406
    34003407\section{Concurrency}
    3401 
    3402 Today's processors for nearly all use cases, ranging from embedded systems to large cloud computing servers, are composed of multiple cores, often heterogeneous.
    3403 As machines grow in complexity, it becomes more difficult for a program to make the most use of the hardware available.
    3404 \CFA includes built-in concurrency features to enable high performance and improve programmer productivity on these multi-/many-core machines.
    34053408
    34063409Concurrency support in \CFA is implemented on top of a highly efficient runtime system of light-weight, M:N, user level threads.
     
    34093412This enables a very familiar interface to all programmers, even those with no parallel programming experience.
    34103413It also allows the compiler to do static type checking of all communication, a very important safety feature.
    3411 This controlled communication with type safety has some similarities with channels in \Index*{Go}, and can actually implement
    3412 channels exactly, as well as create additional communication patterns that channels cannot.
     3414This controlled communication with type safety has some similarities with channels in \Index*{Go}, and can actually implement channels exactly, as well as create additional communication patterns that channels cannot.
    34133415Mutex objects, monitors, are used to contain mutual exclusion within an object and synchronization across concurrent threads.
    34143416
    3415 Three new keywords are added to support these features:
    3416 
    3417 monitor creates a structure with implicit locking when accessing fields
    3418 
    3419 mutex implies use of a monitor requiring the implicit locking
    3420 
    3421 task creates a type with implicit locking, separate stack, and a thread
     3417\begin{figure}
     3418\begin{cfa}
     3419#include <fstream>
     3420#include <coroutine>
     3421
     3422coroutine Fibonacci {
     3423        int fn;                                                         §\C{// used for communication}§
     3424};
     3425void ?{}( Fibonacci * this ) {
     3426        this->fn = 0;
     3427}
     3428void main( Fibonacci * this ) {
     3429        int fn1, fn2;                                           §\C{// retained between resumes}§
     3430        this->fn = 0;                                           §\C{// case 0}§
     3431        fn1 = this->fn;
     3432        suspend();                                                      §\C{// return to last resume}§
     3433
     3434        this->fn = 1;                                           §\C{// case 1}§
     3435        fn2 = fn1;
     3436        fn1 = this->fn;
     3437        suspend();                                                      §\C{// return to last resume}§
     3438
     3439        for ( ;; ) {                                            §\C{// general case}§
     3440                this->fn = fn1 + fn2;
     3441                fn2 = fn1;
     3442                fn1 = this->fn;
     3443                suspend();                                              §\C{// return to last resume}§
     3444        } // for
     3445}
     3446int next( Fibonacci * this ) {
     3447        resume( this );                                         §\C{// transfer to last suspend}§
     3448        return this->fn;
     3449}
     3450int main() {
     3451        Fibonacci f1, f2;
     3452        for ( int i = 1; i <= 10; i += 1 ) {
     3453                sout | next( &f1 ) | ' ' | next( &f2 ) | endl;
     3454        } // for
     3455}
     3456\end{cfa}
     3457\caption{Fibonacci Coroutine}
     3458\label{f:FibonacciCoroutine}
     3459\end{figure}
     3460
     3461
     3462\subsection{Coroutine}
     3463
     3464\Index{Coroutines} are the precursor to tasks.
     3465\VRef[Figure]{f:FibonacciCoroutine} shows a coroutine that computes the \Index*{Fibonacci} numbers.
    34223466
    34233467
     
    34343478\end{cfa}
    34353479
     3480\begin{figure}
     3481\begin{cfa}
     3482#include <fstream>
     3483#include <kernel>
     3484#include <monitor>
     3485#include <thread>
     3486
     3487monitor global_t {
     3488        int value;
     3489};
     3490
     3491void ?{}(global_t * this) {
     3492        this->value = 0;
     3493}
     3494
     3495static global_t global;
     3496
     3497void increment3( global_t * mutex this ) {
     3498        this->value += 1;
     3499}
     3500void increment2( global_t * mutex this ) {
     3501        increment3( this );
     3502}
     3503void increment( global_t * mutex this ) {
     3504        increment2( this );
     3505}
     3506
     3507thread MyThread {};
     3508
     3509void main( MyThread* this ) {
     3510        for(int i = 0; i < 1_000_000; i++) {
     3511                increment( &global );
     3512        }
     3513}
     3514int main(int argc, char* argv[]) {
     3515        processor p;
     3516        {
     3517                MyThread f[4];
     3518        }
     3519        sout | global.value | endl;
     3520}
     3521\end{cfa}
     3522\caption{Atomic-Counter Monitor}
     3523\caption{f:AtomicCounterMonitor}
     3524\end{figure}
     3525
     3526\begin{comment}
    34363527Since a monitor structure includes an implicit locking mechanism, it does not make sense to copy a monitor;
    34373528it is always passed by reference.
     
    34803571}
    34813572\end{cfa}
     3573\end{comment}
    34823574
    34833575
     
    34873579A task provides mutual exclusion like a monitor, and also has its own execution state and a thread of control.
    34883580Similar to a monitor, a task is defined like a structure:
     3581
     3582\begin{figure}
     3583\begin{cfa}
     3584#include <fstream>
     3585#include <kernel>
     3586#include <stdlib>
     3587#include <thread>
     3588
     3589thread First  { signal_once * lock; };
     3590thread Second { signal_once * lock; };
     3591
     3592void ?{}( First * this, signal_once* lock ) { this->lock = lock; }
     3593void ?{}( Second * this, signal_once* lock ) { this->lock = lock; }
     3594
     3595void main( First * this ) {
     3596        for ( int i = 0; i < 10; i += 1 ) {
     3597                sout | "First : Suspend No." | i + 1 | endl;
     3598                yield();
     3599        }
     3600        signal( this->lock );
     3601}
     3602
     3603void main( Second * this ) {
     3604        wait( this->lock );
     3605        for ( int i = 0; i < 10; i += 1 ) {
     3606                sout | "Second : Suspend No." | i + 1 | endl;
     3607                yield();
     3608        }
     3609}
     3610
     3611int main( void ) {
     3612        signal_once lock;
     3613        sout | "User main begin" | endl;
     3614        {
     3615                processor p;
     3616                {
     3617                        First  f = { &lock };
     3618                        Second s = { &lock };
     3619                }
     3620        }
     3621        sout | "User main end" | endl;
     3622}
     3623\end{cfa}
     3624\caption{Simple Tasks}
     3625\label{f:SimpleTasks}
     3626\end{figure}
     3627
     3628
     3629\begin{comment}
    34893630\begin{cfa}
    34903631type Adder = task {
     
    35403681\end{cfa}
    35413682
    3542 
    35433683\subsection{Cooperative Scheduling}
    35443684
     
    36533793}
    36543794\end{cfa}
    3655 
    3656 
     3795\end{comment}
     3796
     3797
     3798\begin{comment}
    36573799\section{Modules and Packages }
    36583800
    3659 \begin{comment}
    36603801High-level encapsulation is useful for organizing code into reusable units, and accelerating compilation speed.
    36613802\CFA provides a convenient mechanism for creating, building and sharing groups of functionality that enhances productivity and improves compile time.
     
    43214462
    43224463
     4464\begin{comment}
    43234465\subsection[Comparing Key Features of CFA]{Comparing Key Features of \CFA}
    43244466
     
    46984840
    46994841
    4700 \begin{comment}
    47014842\subsubsection{Modules / Packages}
    47024843
     
    47784919}
    47794920\end{cfa}
    4780 \end{comment}
    47814921
    47824922
     
    49395079
    49405080\subsection{Summary of Language Comparison}
    4941 
    4942 
    4943 \subsubsection[C++]{\CC}
     5081\end{comment}
     5082
     5083
     5084\subsection[C++]{\CC}
    49445085
    49455086\Index*[C++]{\CC{}} is a general-purpose programming language.
     
    49625103
    49635104
    4964 \subsubsection{Go}
     5105\subsection{Go}
    49655106
    49665107\Index*{Go}, also commonly referred to as golang, is a programming language developed at Google in 2007 [.].
     
    49785119
    49795120
    4980 \subsubsection{Rust}
     5121\subsection{Rust}
    49815122
    49825123\Index*{Rust} is a general-purpose, multi-paradigm, compiled programming language developed by Mozilla Research.
     
    49925133
    49935134
    4994 \subsubsection{D}
     5135\subsection{D}
    49955136
    49965137The \Index*{D} programming language is an object-oriented, imperative, multi-paradigm system programming
     
    51045245\item[Rationale:] keywords added to implement new semantics of \CFA.
    51055246\item[Effect on original feature:] change to semantics of well-defined feature. \\
    5106 Any ISO C programs using these keywords as identifiers are invalid \CFA programs.
     5247Any \Celeven programs using these keywords as identifiers are invalid \CFA programs.
    51075248\item[Difficulty of converting:] keyword clashes are accommodated by syntactic transformations using the \CFA backquote escape-mechanism (see~\VRef{s:BackquoteIdentifiers}).
    51085249\item[How widely used:] clashes among new \CFA keywords and existing identifiers are rare.
  • src/Common/PassVisitor.h

    rcc3e4d0 rd33bc7c  
    253253}
    254254
     255class WithTypeSubstitution {
     256protected:
     257        WithTypeSubstitution() = default;
     258        ~WithTypeSubstitution() = default;
     259
     260public:
     261        TypeSubstitution * env;
     262};
     263
     264class WithStmtsToAdd {
     265protected:
     266        WithStmtsToAdd() = default;
     267        ~WithStmtsToAdd() = default;
     268
     269public:
     270        std::list< Statement* > stmtsToAddBefore;
     271        std::list< Statement* > stmtsToAddAfter;
     272};
     273
     274class WithShortCircuiting {
     275protected:
     276        WithShortCircuiting() = default;
     277        ~WithShortCircuiting() = default;
     278
     279public:
     280        bool skip_children;
     281};
     282
     283class WithScopes {
     284protected:
     285        WithScopes() = default;
     286        ~WithScopes() = default;
     287
     288public:
     289        at_cleanup_t at_cleanup;
     290
     291        template< typename T >
     292        void GuardValue( T& val ) {
     293                at_cleanup( [ val ]( void * newVal ) {
     294                        * static_cast< T * >( newVal ) = val;
     295                }, static_cast< void * >( & val ) );
     296        }
     297};
     298
     299
    255300#include "PassVisitor.impl.h"
  • src/InitTweak/GenInit.cc

    rcc3e4d0 rd33bc7c  
    4444        }
    4545
    46         class ReturnFixer {
     46        class ReturnFixer : public WithStmtsToAdd, public WithScopes {
    4747          public:
    4848                /// consistently allocates a temporary variable for the return value
     
    5353                void premutate( FunctionDecl *functionDecl );
    5454                void premutate( ReturnStmt * returnStmt );
    55 
    56                 at_cleanup_t at_cleanup;
    57                 std::list< Statement * > stmtsToAddBefore;
    5855
    5956          protected:
     
    160157
    161158        void ReturnFixer::premutate( FunctionDecl *functionDecl ) {
    162                 GuardValue( this, ftype );
    163                 GuardValue( this, funcName );
     159                GuardValue( ftype );
     160                GuardValue( funcName );
    164161
    165162                ftype = functionDecl->get_functionType();
Note: See TracChangeset for help on using the changeset viewer.