# Changeset fb11446e

Ignore:
Timestamp:
Mar 8, 2018, 7:31:15 AM (5 years ago)
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
5600747, 87555b7
Parents:
f4abc58
Message:

 rf4abc58 The offset arrays are statically generated where possible. If a dynamic generic-type is declared to be passed or returned by value from a polymorphic function, the translator can safely assume the generic type is complete (\ie has a known layout) at any call-site, and the offset array is passed from the caller; if the generic type is concrete at the call site, the elements of this offset array can even be statically generated using the C @offsetof@ macro. if the generic type is concrete at the call site, the elements of this offset array can even be statically generated using the C @offsetof@ macro. As an example, the body of the second @value@ function is implemented like this: \begin{cfa} Hence, function parameter and return lists are flattened for the purposes of type unification allowing the example to pass expression resolution. This relaxation is possible by extending the thunk scheme described by Bilson~\cite{Bilson03}. Whenever a candidate's parameter structure does not exactly match the formal parameter's structure, a thunk is generated to specialize calls to the actual function: \begin{cfa} int _thunk( int _p0, double _p1, double _p2 ) { return f( [_p0, _p1], _p2 ); } \end{cfa} so the thunk provides flattening and structuring conversions to inferred functions, improving the compatibility of tuples and polymorphism. These thunks take advantage of gcc C nested-functions to produce closures that have the usual function-pointer signature WHAT DOES THIS MEAN???. % Whenever a candidate's parameter structure does not exactly match the formal parameter's structure, a thunk is generated to specialize calls to the actual function: % \begin{cfa} % int _thunk( int _p0, double _p1, double _p2 ) { return f( [_p0, _p1], _p2 ); } % \end{cfa} % so the thunk provides flattening and structuring conversions to inferred functions, improving the compatibility of tuples and polymorphism. % These thunks are generated locally using gcc nested-functions, rather hositing them to the external scope, so they can easily access local state. \section{Control Structures} \CFA identifies inconsistent, problematic, and missing control structures in C, and extends, modifies, and adds to control structures to increase functionality and safety. \CFA identifies inconsistent, problematic, and missing control structures in C, and extends, modifies, and adds control structures to increase functionality and safety. \lstMakeShortInline@% \end{cquote} for a contiguous list:\footnote{gcc provides the same mechanism with awkward syntax, \lstinline@2 ... 42@, where spaces are required around the ellipse.} for a contiguous list:\footnote{gcc has the same mechanism but awkward syntax, \lstinline@2 ...42@, because a space is required after a number, otherwise the period is a decimal point.} \begin{cquote} \lstDeleteShortInline@% Coroutines and tasks start with non-local exceptions disabled, allowing handlers to be put in place, before non-local exceptions are explicitly enabled. \begin{cfa} void main( mytask & c ) { try { enable {                        $\C{// now allow non-local exception delivery}$ void main( mytask & c ) {                                       $\C{// thread starts here}$ // non-local exceptions disabled try {                                                                   $\C{// establish handles for non-local exceptions}$ enable {                                                        $\C{// allow non-local exception delivery}$ // task body } // appropriate catchResume/catch // appropriate catchResume/catch handlers } } int & r = *new( int ); ...                                                                                     $\C{// non-null reference}$ delete &r; delete &r;                                                                      $\C{// unmanaged (programmer) memory-management}$ r += 1;                                                                         $\C{// undefined reference}$ \end{cfa} Constructor calls seamlessly integrate with existing C initialization syntax, providing a simple and familiar syntax to C programmers and allowing constructor calls to be inserted into legacy C code with minimal code changes. In \CFA, a constructor is named @?{}@ and a destructor is named @^?{}@. The name @{}@ comes from the syntax for the initializer: @struct S { int i, j; } s = { 2, 3 }@\footnote{% In \CFA, a constructor is named @?{}@ and a destructor is named @^?{}@\footnote{% The symbol \lstinline+^+ is used for the destructor name because it was the last binary operator that could be used in a unary context.}. The name @{}@ comes from the syntax for the initializer: @struct S { int i, j; } s = { 2, 3 }@. Like other \CFA operators, these names represent the syntax used to call the constructor or destructor, \eg @?{}(x, ...)@ or @^{}(x, ...)@. The constructor and destructor have return type @void@, and the first parameter is a reference to the object type to be constructed or destructed. \subsection{0/1} In C, @0@ has the special property that it is the only false'' value; by the standard, any value which compares equal to @0@ is false, while any value that compares unequal to @0@ is true. As such, an expression @x@ in any boolean context (such as the condition of an @if@ or @while@ statement, or the arguments to @&&@, @||@, or @?:@) can be rewritten as @x != 0@ without changing its semantics. The operator overloading feature of \CFA provides a natural means to implement this truth value comparison for arbitrary types, but the C type system is not precise enough to distinguish an equality comparison with @0@ from an equality comparison with an arbitrary integer or pointer. To provide this precision, \CFA introduces a new type @zero_t@ as type type of literal @0@ (somewhat analagous to @nullptr_t@ and @nullptr@ in \CCeleven); @zero_t@ can only take the value @0@, but has implicit conversions to the integer and pointer types so that C code involving @0@ continues to work properly. With this addition, the \CFA compiler rewrites @if (x)@ and similar expressions to @if ((x) != 0)@ or the appropriate analogue, and any type @T@ can be made truthy'' by defining an operator overload @int ?!=?(T, zero_t)@. \CC makes types truthy by adding a conversion to @bool@; prior to the addition of explicit cast operators in \CCeleven this approach had the pitfall of making truthy types transitively convertable to any numeric type; our design for \CFA avoids this issue. \CFA also includes a special type for @1@, @one_t@; like @zero_t@, @one_t@ has built-in implicit conversions to the various integral types so that @1@ maintains its expected semantics in legacy code. The addition of @one_t@ allows generic algorithms to handle the unit value uniformly for types where that is meaningful. \TODO{Make this sentence true} In particular, polymorphic functions in the \CFA prelude define @++x@ and @x++@ in terms of @x += 1@, allowing users to idiomatically define all forms of increment for a type @T@ by defining the single function @T & ?+=(T &, one_t)@; analogous overloads for the decrement operators are present as well. In C, @0@ has the special property that it is the only false'' value; from the standard, any value that compares equal to @0@ is false, while any value that compares unequal to @0@ is true. As such, an expression @x@ in any boolean context (such as the condition of an @if@ or @while@ statement, or the arguments to @&&@, @||@, or @?:@\,) can be rewritten as @x != 0@ without changing its semantics. Operator overloading in \CFA provides a natural means to implement this truth-value comparison for arbitrary types, but the C type system is not precise enough to distinguish an equality comparison with @0@ from an equality comparison with an arbitrary integer or pointer. To provide this precision, \CFA introduces a new type @zero_t@ as the type of literal @0@ (somewhat analagous to @nullptr_t@ and @nullptr@ in \CCeleven); @zero_t@ can only take the value @0@, but has implicit conversions to the integer and pointer types so that C code involving @0@ continues to work. With this addition, \CFA rewrites @if (x)@ and similar expressions to @if ((x) != 0)@ or the appropriate analogue, and any type @T@ is truthy'' by defining an operator overload @int ?!=?(T, zero_t)@. \CC makes types truthy by adding a conversion to @bool@; prior to the addition of explicit cast operators in \CCeleven, this approach had the pitfall of making truthy types transitively convertable to any numeric type; \CFA avoids this issue. Similarly, \CFA also has a special type for @1@, @one_t@; like @zero_t@, @one_t@ has built-in implicit conversions to the various integral types so that @1@ maintains its expected semantics in legacy code for operations @++@ and @--@. The addition of @one_t@ allows generic algorithms to handle the unit value uniformly for types where it is meaningful. \TODO{Make this sentence true} In particular, polymorphic functions in the \CFA prelude define @++x@ and @x++@ in terms of @x += 1@, allowing users to idiomatically define all forms of increment for a type @T@ by defining the single function @T & ?+=(T &, one_t)@; analogous overloads for the decrement operators are present as well. The left of Figure~\ref{f:UserLiteral} shows the \CFA alternative call-syntax (literal argument before function name), using the backquote, to convert basic literals into user literals. The backquote is a small character, making the unit (function name) predominate. For examples, the multi-precision integers in Section~\ref{s:MultiPrecisionIntegers} make use of user literals: For examples, the multi-precision integer-type in Section~\ref{s:MultiPrecisionIntegers} has user literals: {\lstset{language=CFA,moredelim=**[is][\color{red}]{|}{|},deletedelim=**[is][]{}{}} \begin{cfa} \lstMakeShortInline@% \end{cquote} In additon, there are polymorphic functions, like @min@ and @max@, which work on any type with operators @??@. In additon, there are polymorphic functions, like @min@ and @max@, that work on any type with operators @??@. The following shows one example where \CFA \emph{extends} an existing standard C interface to reduce complexity and provide safety. In either case, new storage may or may not be allocated and, if there is a new allocation, as much data from the existing allocation is copied. For an increase in storage size, new storage after the copied data may be filled. \item[alignment] \item[align] an allocation on a specified memory boundary, \eg, an address multiple of 64 or 128 for cache-line purposes. \item[array] allocation of the specified number of elements. allocation with a specified number of elements. An array may be filled, resized, or aligned. \end{description} \lstMakeShortInline~% \begin{tabular}{@{}r|r|l|l|l|l@{}} \multicolumn{1}{c}{}&           & \multicolumn{1}{c|}{fill}     & resize        & alignment     & array \\ \multicolumn{1}{c}{}&           & \multicolumn{1}{c|}{fill}     & resize        & align & array \\ \hline C               & ~malloc~                      & no                    & no            & no            & no    \\ TIMED( "copy_int", ti = si; ) TIMED( "clear_int", clear( si ); ) REPEAT_TIMED( "pop_int", N, int x = pop( ti ); if ( x > max ) max = x; ) REPEAT_TIMED( "pop_int", N, int x = pop( ti ); if ( x > max ) max = x; ) pair( _Bool, char ) max = { (_Bool)0, '\0' }, val = { (_Bool)1, 'a' }; TIMED( "copy_pair", tp = sp; ) TIMED( "clear_pair", clear( sp ); ) REPEAT_TIMED( "pop_pair", N, pair(_Bool, char) x = pop( tp ); if ( x > max ) max = x; ) REPEAT_TIMED( "pop_pair", N, pair(_Bool, char) x = pop( tp ); if ( x > max ) max = x; ) } \end{cfa}