Changes in doc/refrat/refrat.tex [a752883:90c3b1c]
- File:
-
- 1 edited
-
doc/refrat/refrat.tex (modified) (76 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/refrat/refrat.tex
ra752883 r90c3b1c 17 17 \usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref} 18 18 \usepackage{breakurl} 19 \ renewcommand{\UrlFont}{\small\sf}19 \urlstyle{sf} 20 20 21 21 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% … … 23 23 % Names used in the document. 24 24 25 \newcommand{\CFA}{C $\forall$\xspace} % set language symbolicname26 \newcommand{\CF L}{Cforall\xspace} % set language textname25 \newcommand{\CFA}{Cforall\xspace} % set language text name 26 \newcommand{\CFAA}{C$\forall$\xspace} % set language symbolic name 27 27 \newcommand{\CC}{C\kern-.1em\hbox{+\kern-.25em+}\xspace} % CC symbolic name 28 28 \def\c11{ISO/IEC C} % C11 name (cannot have numbers in latex command name) … … 33 33 34 34 \makeatletter 35 % allow escape sequence in lstinline36 %\usepackage{etoolbox}37 %\patchcmd{\lsthk@TextStyle}{\let\lst@DefEsc\@empty}{}{}{\errmessage{failed to patch}}38 39 \renewcommand\small{%40 \@setfontsize\small{8.5}{11}%41 \abovedisplayskip 8.5pt \@plus 3pt \@minus 4pt42 \abovedisplayshortskip \z@ \@plus 2pt43 \belowdisplayshortskip 4pt \@plus 2pt \@minus 2pt44 \def\@listi{\leftmargin\leftmargini45 \topsep 4pt \@plus 2pt \@minus 2pt46 \parsep 2pt \@pluspt \@minuspt47 \itemsep \parsep}%48 \belowdisplayskip \abovedisplayskip49 }50 \usepackage{relsize} % must be after change to small51 52 35 \renewcommand{\labelitemi}{{\raisebox{0.25ex}{\footnotesize$\bullet$}}} 53 36 \renewenvironment{itemize}{\begin{list}{\labelitemi}{\topsep=5pt\itemsep=5pt\parsep=0pt}}{\end{list}} … … 76 59 \renewcommand\section{\@startsection{section}{1}{\z@}{-3.0ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\large\bfseries}} 77 60 \renewcommand\subsection{\@startsection{subsection}{2}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}} 78 \renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}{-2. 5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}}61 \renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}{-2.0ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}} 79 62 \renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}{-2.0ex \@plus -1ex \@minus -.2ex}{-1em}{\normalfont\normalsize\bfseries}} 80 63 81 % index macros82 64 \newcommand{\italic}[1]{\emph{\hyperpage{#1}}} 83 65 \newcommand{\definition}[1]{\textbf{\hyperpage{#1}}} … … 115 97 116 98 % blocks and titles 99 \newcommand{\define}[1]{\emph{#1\/}\index{#1}} 117 100 \newenvironment{rationale}{% 118 101 \begin{quotation}\noindent$\Box$\enspace … … 120 103 \hfill\enspace$\Box$\end{quotation} 121 104 }% 122 \newcommand{\define}[1]{\emph{#1\/}\index{#1}}123 105 \newcommand{\rewrite}{\(\Rightarrow\)} 124 106 \newcommand{\rewriterules}{\paragraph{Rewrite Rules}~\par\noindent} … … 149 131 \newcommand{\VPageref}[2][page]{\ifx#1\@empty\else{#1}\nobreakspace\fi\pageref{#2}} 150 132 151 % CFA based on ANSI C133 % adjust listings macros 152 134 \lstdefinelanguage{CFA}[ANSI]{C}% 153 {morekeywords={asm,_Alignas,_Alignof,_At,_Atomic,_Bool,catch,catchResume,choose,_Complex, trait,disable,dtype,enable,154 fallthru,finally,forall,ftype,_Generic,_Imaginary,inline,lvalue,_Noreturn, otype,restrict,_Static_assert,155 _Thread_local,throw,throwResume,try, },135 {morekeywords={asm,_Alignas,_Alignof,_At,_Atomic,_Bool,catch,catchResume,choose,_Complex,context,disable,dtype,enable, 136 fallthru,finally,forall,ftype,_Generic,_Imaginary,inline,lvalue,_Noreturn,restrict,_Static_assert, 137 _Thread_local,throw,throwResume,try,type,}, 156 138 }% 157 139 … … 159 141 language=CFA, 160 142 columns=flexible, 161 basicstyle=\sf\ relsize{-1},143 basicstyle=\sf\small, 162 144 tabsize=4, 163 145 xleftmargin=\parindent, 164 146 escapechar=@, 165 147 keepspaces=true, 166 showstringspaces=false,167 showlines=true,148 %showtabs=true, 149 %tab=\rightarrowfill, 168 150 }% 169 151 … … 192 174 193 175 \title{\Huge 194 \CFA (\CF L) Reference Manual and Rationale176 \CFA (\CFAA) Reference Manual and Rationale 195 177 }% title 196 178 \author{\huge … … 298 280 An instantiation of the generic type is written by specifying the type parameters in parentheses after the name of the generic type generator: 299 281 \begin{lstlisting} 300 forall( otype T | sumable( T ) ) struct pair {282 forall( type T | sumable( T ) ) struct pair { 301 283 T x; 302 284 T y; … … 310 292 Polymorphic functions may have generic types as parameters, and those generic types may use type parameters of the polymorphic function as type parameters of the generic type: 311 293 \begin{lstlisting} 312 forall( otype T ) void swap( pair(T) *p ) {294 forall( type T ) void swap( pair(T) *p ) { 313 295 T z = p->x; 314 296 p->x = p->y; … … 320 302 \subsubsection{Constraints} 321 303 322 To avoid unduly constraining implementors, the generic type generator definition must be visible at any point where it is instantiated. 323 Forward declarations of generic type generators are not forbidden, but the definition must be visible to instantiate the generic type. Equivalently, instantiations of generic types are not allowed to be incomplete types. 304 To avoid unduly constraining implementors, the generic type generator definition must be visible at any point where it is instantiated. Forward declarations of generic type generators are not forbidden, but the definition must be visible to instantiate the generic type. Equivalently, instantiations of generic types are not allowed to be incomplete types. 324 305 325 306 \examples 326 307 \begin{lstlisting} 327 forall( otype T ) struct A;328 329 forall( otype T ) struct B {308 forall( type T ) struct A; 309 310 forall( type T ) struct B { 330 311 A(T) *a; // legal, but cannot instantiate B(T) 331 312 }; … … 333 314 B(T) x; // illegal, *x.a is of an incomplete generic type 334 315 335 forall( otype T ) struct A {316 forall( type T ) struct A { 336 317 B( T ) *b; 337 318 }; … … 340 321 341 322 // box.h: 342 forall( otype T ) struct box;343 forall( otype T ) box( T ) *make_box( T );344 forall( otype T ) void use_box( box( T ) *b );323 forall( type T ) struct box; 324 forall( type T ) box( T ) *make_box( T ); 325 forall( type T ) void use_box( box( T ) *b ); 345 326 346 327 // main.c: … … 429 410 430 411 \subsubsection{Specialization} 431 A function or value whose type is polymorphic may be implicitly converted to one whose type is \Index{less polymorphic} by binding values to one or more of its \Index{inferred parameter}. 412 A function or value whose type is polymorphic may be implicitly converted to one whose type is 413 \Index{less polymorphic} by binding values to one or more of its \Index{inferred parameter}. 432 414 Any value that is legal for the inferred parameter may be used, including other inferred parameters. 433 415 434 If, after the inferred parameter binding, an \Index{assertion parameter} has no inferred parameters in its type, then an object or function must be visible at the point of the specialization that has the same identifier as the assertion parameter and has a type that is compatible\index{compatible type} with or can be specialized to the type of the assertion parameter.435 The assertion parameter is bound to that object or function.416 If, after the inferred parameter binding, an \Index{assertion parameter} has no inferred parameters in its type, then an object or function must be visible at the point of the specialization that has the same identifier as the assertion parameter and has a type that is compatible\index{compatible 417 type} with or can be specialized to the type of the assertion parameter. The assertion parameter is bound to that object or function. 436 418 437 419 The type of the specialization is the type of the original with the bound inferred parameters and the bound assertion parameters replaced by their bound values. … … 440 422 The type 441 423 \begin{lstlisting} 442 forall( otype T, otype U ) void (*)( T, U );424 forall( type T, type U ) void (*)( T, U ); 443 425 \end{lstlisting} 444 426 can be specialized to (among other things) 445 427 \begin{lstlisting} 446 forall( otype T ) void (*)( T, T ); // U bound to T447 forall( otype T ) void (*)( T, real ); // U bound to real448 forall( otype U ) void (*)( real, U ); // T bound to real428 forall( type T ) void (*)( T, T ); // U bound to T 429 forall( type T ) void (*)( T, real ); // U bound to real 430 forall( type U ) void (*)( real, U ); // T bound to real 449 431 void f( real, real ); // both bound to real 450 432 \end{lstlisting} … … 452 434 The type 453 435 \begin{lstlisting} 454 forall( otype T | T ?+?( T, T ) ) T (*)( T );436 forall( type T | T ?+?( T, T ) ) T (*)( T ); 455 437 \end{lstlisting} 456 438 can be specialized to (among other things) … … 512 494 If \lstinline$int$ can represent all the values of \lstinline$unsigned short$, then the cost of an implicit conversion from \lstinline$unsigned short$ to \lstinline$unsigned$ is 2: 513 495 \lstinline$unsigned short$ to \lstinline$int$ to \lstinline$unsigned$. 514 Otherwise, \lstinline$unsigned short$ is converted directly to \lstinline$unsigned$, and the cost is 1. 496 Otherwise, 497 \lstinline$unsigned short$ is converted directly to \lstinline$unsigned$, and the cost is 1. 515 498 516 499 \item … … 525 508 \rhs \lstinline$forall$ 526 509 \rhs \lstinline$lvalue$ 527 \rhs \lstinline$ trait$510 \rhs \lstinline$context$ 528 511 \rhs \lstinline$dtype$ 529 512 \rhs \lstinline$ftype$ … … 556 539 A \nonterm{constant-expression} that evaluates to 0 is effectively compatible with every pointer type. 557 540 558 In C, the integer constants 0 and 1 suffice because the integer promotion rules can convert them to any arithmetic type, and the rules for pointer expressions treat constant expressions evaluating to 0 as a special case. 541 In C, the integer constants 0 and 1 suffice because the integer promotion rules can convert them to any arithmetic type, and the rules for pointer expressions treat constant expressions evaluating to 542 0 as a special case. 559 543 However, user-defined arithmetic types often need the equivalent of a 1 or 0 for their functions or operators, polymorphic functions often need 0 and 1 constants of a type matching their polymorphic parameters, and user-defined pointer-like types may need a null value. 560 544 Defining special constants for a user-defined type is more efficient than defining a conversion to the type from \lstinline$_Bool$. … … 852 836 \predefined 853 837 \begin{lstlisting} 854 forall( otype T ) lvalue T ?[?]( T *, ptrdiff_t );@\use{ptrdiff_t}@855 forall( otype T ) lvalue _Atomic T ?[?]( _Atomic T *, ptrdiff_t );856 forall( otype T ) lvalue const T ?[?]( const T *, ptrdiff_t );857 forall( otype T ) lvalue restrict T ?[?]( restrict T *, ptrdiff_t );858 forall( otype T ) lvalue volatile T ?[?]( volatile T *, ptrdiff_t );859 forall( otype T ) lvalue _Atomic const T ?[?]( _Atomic const T *, ptrdiff_t );860 forall( otype T ) lvalue _Atomic restrict T ?[?]( _Atomic restrict T *, ptrdiff_t );861 forall( otype T ) lvalue _Atomic volatile T ?[?]( _Atomic volatile T *, ptrdiff_t );862 forall( otype T ) lvalue const restrict T ?[?]( const restrict T *, ptrdiff_t );863 forall( otype T ) lvalue const volatile T ?[?]( const volatile T *, ptrdiff_t );864 forall( otype T ) lvalue restrict volatile T ?[?]( restrict volatile T *, ptrdiff_t );865 forall( otype T ) lvalue _Atomic const restrict T ?[?]( _Atomic const restrict T *, ptrdiff_t );866 forall( otype T ) lvalue _Atomic const volatile T ?[?]( _Atomic const volatile T *, ptrdiff_t );867 forall( otype T ) lvalue _Atomic restrict volatile T ?[?]( _Atomic restrict volatile T *, ptrdiff_t );868 forall( otype T ) lvalue const restrict volatile T ?[?]( const restrict volatile T *, ptrdiff_t );869 forall( otype T ) lvalue _Atomic const restrict volatile T ?[?]( _Atomic const restrict volatile T *, ptrdiff_t );838 forall( type T ) lvalue T ?[?]( T *, ptrdiff_t );@\use{ptrdiff_t}@ 839 forall( type T ) lvalue _Atomic T ?[?]( _Atomic T *, ptrdiff_t ); 840 forall( type T ) lvalue const T ?[?]( const T *, ptrdiff_t ); 841 forall( type T ) lvalue restrict T ?[?]( restrict T *, ptrdiff_t ); 842 forall( type T ) lvalue volatile T ?[?]( volatile T *, ptrdiff_t ); 843 forall( type T ) lvalue _Atomic const T ?[?]( _Atomic const T *, ptrdiff_t ); 844 forall( type T ) lvalue _Atomic restrict T ?[?]( _Atomic restrict T *, ptrdiff_t ); 845 forall( type T ) lvalue _Atomic volatile T ?[?]( _Atomic volatile T *, ptrdiff_t ); 846 forall( type T ) lvalue const restrict T ?[?]( const restrict T *, ptrdiff_t ); 847 forall( type T ) lvalue const volatile T ?[?]( const volatile T *, ptrdiff_t ); 848 forall( type T ) lvalue restrict volatile T ?[?]( restrict volatile T *, ptrdiff_t ); 849 forall( type T ) lvalue _Atomic const restrict T ?[?]( _Atomic const restrict T *, ptrdiff_t ); 850 forall( type T ) lvalue _Atomic const volatile T ?[?]( _Atomic const volatile T *, ptrdiff_t ); 851 forall( type T ) lvalue _Atomic restrict volatile T ?[?]( _Atomic restrict volatile T *, ptrdiff_t ); 852 forall( type T ) lvalue const restrict volatile T ?[?]( const restrict volatile T *, ptrdiff_t ); 853 forall( type T ) lvalue _Atomic const restrict volatile T ?[?]( _Atomic const restrict volatile T *, ptrdiff_t ); 870 854 \end{lstlisting} 871 855 \semantics … … 930 914 \begin{rationale} 931 915 One desirable property of a polymorphic programming language is \define{generalizability}: the ability to replace an abstraction with a more general but equivalent abstraction without requiring changes in any of the uses of the original\cite{Cormack90}. 932 For instance, it should be possible to replace a function ``\lstinline$int f( int );$'' with ``\lstinline$forall( otype T ) T f( T );$'' without affecting any calls of \lstinline$f$.916 For instance, it should be possible to replace a function ``\lstinline$int f( int );$'' with ``\lstinline$forall( type T ) T f( T );$'' without affecting any calls of \lstinline$f$. 933 917 934 918 \CFA\index{deficiencies!generalizability} does not fully possess this property, because … … 944 928 f = g( d, f ); // (3) (unsafe conversion to float) 945 929 \end{lstlisting} 946 If \lstinline$g$ was replaced by ``\lstinline$forall( otype T ) T g( T, T );$'', the first and second calls would be unaffected, but the third would change: \lstinline$f$ would be converted to930 If \lstinline$g$ was replaced by ``\lstinline$forall( type T ) T g( T, T );$'', the first and second calls would be unaffected, but the third would change: \lstinline$f$ would be converted to 947 931 \lstinline$double$, and the result would be a \lstinline$double$. 948 932 949 933 Another example is the function ``\lstinline$void h( int *);$''. 950 934 This function can be passed a 951 \lstinline$void *$ argument, but the generalization ``\lstinline$forall( otype T ) void h( T *);$'' can not.935 \lstinline$void *$ argument, but the generalization ``\lstinline$forall( type T ) void h( T *);$'' can not. 952 936 In this case, \lstinline$void$ is not a valid value for \lstinline$T$ because it is not an object type. 953 937 If unsafe conversions were allowed, \lstinline$T$ could be inferred to be \emph{any} object type, which is undesirable. … … 957 941 A function called ``\lstinline$?()$'' might be part of a numerical differentiation package. 958 942 \begin{lstlisting} 959 extern otype Derivative;943 extern type Derivative; 960 944 extern double ?()( Derivative, double ); 961 945 extern Derivative derivative_of( double (*f)( double ) ); … … 978 962 979 963 \begin{lstlisting} 980 forall( otype T ) T h( T );964 forall( type T ) T h( T ); 981 965 double d = h( 1.5 ); 982 966 \end{lstlisting} … … 985 969 986 970 \begin{lstlisting} 987 forall( otype T, otype U ) void g( T, U ); // (4)988 forall( otype T ) void g( T, T ); // (5)989 forall( otype T ) void g( T, long ); // (6)971 forall( type T, type U ) void g( T, U ); // (4) 972 forall( type T ) void g( T, T ); // (5) 973 forall( type T ) void g( T, long ); // (6) 990 974 void g( long, long ); // (7) 991 975 double d; … … 1007 991 The fourth call has no interpretation for (5), because its arguments must have compatible type. (4) is chosen because it does not involve unsafe conversions. 1008 992 \begin{lstlisting} 1009 forall( otype T ) T min( T, T );993 forall( type T ) T min( T, T ); 1010 994 double max( double, double ); 1011 trait min_max( T ) {@\impl{min_max}@995 context min_max( T ) {@\impl{min_max}@ 1012 996 T min( T, T ); 1013 997 T max( T, T ); 1014 998 } 1015 forall( otype U | min_max( U ) ) void shuffle( U, U );999 forall( type U | min_max( U ) ) void shuffle( U, U ); 1016 1000 shuffle( 9, 10 ); 1017 1001 \end{lstlisting} … … 1063 1047 long double ?++( volatile long double * ), ?++( _Atomic volatile long double * ); 1064 1048 1065 forall( otype T ) T * ?++( T * restrict volatile * ), * ?++( T * _Atomic restrict volatile * );1066 forall( otype T ) _Atomic T * ?++( _Atomic T * restrict volatile * ), * ?++( _Atomic T * _Atomic restrict volatile * );1067 forall( otype T ) const T * ?++( const T * restrict volatile * ), * ?++( const T * _Atomic restrict volatile * );1068 forall( otype T ) volatile T * ?++( volatile T * restrict volatile * ), * ?++( volatile T * _Atomic restrict volatile * );1069 forall( otype T ) restrict T * ?++( restrict T * restrict volatile * ), * ?++( restrict T * _Atomic restrict volatile * );1070 forall( otype T ) _Atomic const T * ?++( _Atomic const T * restrict volatile * ),1049 forall( type T ) T * ?++( T * restrict volatile * ), * ?++( T * _Atomic restrict volatile * ); 1050 forall( type T ) _Atomic T * ?++( _Atomic T * restrict volatile * ), * ?++( _Atomic T * _Atomic restrict volatile * ); 1051 forall( type T ) const T * ?++( const T * restrict volatile * ), * ?++( const T * _Atomic restrict volatile * ); 1052 forall( type T ) volatile T * ?++( volatile T * restrict volatile * ), * ?++( volatile T * _Atomic restrict volatile * ); 1053 forall( type T ) restrict T * ?++( restrict T * restrict volatile * ), * ?++( restrict T * _Atomic restrict volatile * ); 1054 forall( type T ) _Atomic const T * ?++( _Atomic const T * restrict volatile * ), 1071 1055 * ?++( _Atomic const T * _Atomic restrict volatile * ); 1072 forall( otype T ) _Atomic restrict T * ?++( _Atomic restrict T * restrict volatile * ),1056 forall( type T ) _Atomic restrict T * ?++( _Atomic restrict T * restrict volatile * ), 1073 1057 * ?++( _Atomic restrict T * _Atomic restrict volatile * ); 1074 forall( otype T ) _Atomic volatile T * ?++( _Atomic volatile T * restrict volatile * ),1058 forall( type T ) _Atomic volatile T * ?++( _Atomic volatile T * restrict volatile * ), 1075 1059 * ?++( _Atomic volatile T * _Atomic restrict volatile * ); 1076 forall( otype T ) const restrict T * ?++( const restrict T * restrict volatile * ),1060 forall( type T ) const restrict T * ?++( const restrict T * restrict volatile * ), 1077 1061 * ?++( const restrict T * _Atomic restrict volatile * ); 1078 forall( otype T ) const volatile T * ?++( const volatile T * restrict volatile * ),1062 forall( type T ) const volatile T * ?++( const volatile T * restrict volatile * ), 1079 1063 * ?++( const volatile T * _Atomic restrict volatile * ); 1080 forall( otype T ) restrict volatile T * ?++( restrict volatile T * restrict volatile * ),1064 forall( type T ) restrict volatile T * ?++( restrict volatile T * restrict volatile * ), 1081 1065 * ?++( restrict volatile T * _Atomic restrict volatile * ); 1082 forall( otype T ) _Atomic const restrict T * ?++( _Atomic const restrict T * restrict volatile * ),1066 forall( type T ) _Atomic const restrict T * ?++( _Atomic const restrict T * restrict volatile * ), 1083 1067 * ?++( _Atomic const restrict T * _Atomic restrict volatile * ); 1084 forall( otype T ) _Atomic const volatile T * ?++( _Atomic const volatile T * restrict volatile * ),1068 forall( type T ) _Atomic const volatile T * ?++( _Atomic const volatile T * restrict volatile * ), 1085 1069 * ?++( _Atomic const volatile T * _Atomic restrict volatile * ); 1086 forall( otype T ) _Atomic restrict volatile T * ?++( _Atomic restrict volatile T * restrict volatile * ),1070 forall( type T ) _Atomic restrict volatile T * ?++( _Atomic restrict volatile T * restrict volatile * ), 1087 1071 * ?++( _Atomic restrict volatile T * _Atomic restrict volatile * ); 1088 forall( otype T ) const restrict volatile T * ?++( const restrict volatile T * restrict volatile * ),1072 forall( type T ) const restrict volatile T * ?++( const restrict volatile T * restrict volatile * ), 1089 1073 * ?++( const restrict volatile T * _Atomic restrict volatile * ); 1090 forall( otype T ) _Atomic const restrict volatile T * ?++( _Atomic const restrict volatile T * restrict volatile * ),1074 forall( type T ) _Atomic const restrict volatile T * ?++( _Atomic const restrict volatile T * restrict volatile * ), 1091 1075 * ?++( _Atomic const restrict volatile T * _Atomic restrict volatile * ); 1092 1076 … … 1107 1091 long double ?--( volatile long double * ), ?--( _Atomic volatile long double * ); 1108 1092 1109 forall( otype T ) T * ?--( T * restrict volatile * ), * ?--( T * _Atomic restrict volatile * );1110 forall( otype T ) _Atomic T * ?--( _Atomic T * restrict volatile * ), * ?--( _Atomic T * _Atomic restrict volatile * );1111 forall( otype T ) const T * ?--( const T * restrict volatile * ), * ?--( const T * _Atomic restrict volatile * );1112 forall( otype T ) volatile T * ?--( volatile T * restrict volatile * ), * ?--( volatile T * _Atomic restrict volatile * );1113 forall( otype T ) restrict T * ?--( restrict T * restrict volatile * ), * ?--( restrict T * _Atomic restrict volatile * );1114 forall( otype T ) _Atomic const T * ?--( _Atomic const T * restrict volatile * ),1093 forall( type T ) T * ?--( T * restrict volatile * ), * ?--( T * _Atomic restrict volatile * ); 1094 forall( type T ) _Atomic T * ?--( _Atomic T * restrict volatile * ), * ?--( _Atomic T * _Atomic restrict volatile * ); 1095 forall( type T ) const T * ?--( const T * restrict volatile * ), * ?--( const T * _Atomic restrict volatile * ); 1096 forall( type T ) volatile T * ?--( volatile T * restrict volatile * ), * ?--( volatile T * _Atomic restrict volatile * ); 1097 forall( type T ) restrict T * ?--( restrict T * restrict volatile * ), * ?--( restrict T * _Atomic restrict volatile * ); 1098 forall( type T ) _Atomic const T * ?--( _Atomic const T * restrict volatile * ), 1115 1099 * ?--( _Atomic const T * _Atomic restrict volatile * ); 1116 forall( otype T ) _Atomic restrict T * ?--( _Atomic restrict T * restrict volatile * ),1100 forall( type T ) _Atomic restrict T * ?--( _Atomic restrict T * restrict volatile * ), 1117 1101 * ?--( _Atomic restrict T * _Atomic restrict volatile * ); 1118 forall( otype T ) _Atomic volatile T * ?--( _Atomic volatile T * restrict volatile * ),1102 forall( type T ) _Atomic volatile T * ?--( _Atomic volatile T * restrict volatile * ), 1119 1103 * ?--( _Atomic volatile T * _Atomic restrict volatile * ); 1120 forall( otype T ) const restrict T * ?--( const restrict T * restrict volatile * ),1104 forall( type T ) const restrict T * ?--( const restrict T * restrict volatile * ), 1121 1105 * ?--( const restrict T * _Atomic restrict volatile * ); 1122 forall( otype T ) const volatile T * ?--( const volatile T * restrict volatile * ),1106 forall( type T ) const volatile T * ?--( const volatile T * restrict volatile * ), 1123 1107 * ?--( const volatile T * _Atomic restrict volatile * ); 1124 forall( otype T ) restrict volatile T * ?--( restrict volatile T * restrict volatile * ),1108 forall( type T ) restrict volatile T * ?--( restrict volatile T * restrict volatile * ), 1125 1109 * ?--( restrict volatile T * _Atomic restrict volatile * ); 1126 forall( otype T ) _Atomic const restrict T * ?--( _Atomic const restrict T * restrict volatile * ),1110 forall( type T ) _Atomic const restrict T * ?--( _Atomic const restrict T * restrict volatile * ), 1127 1111 * ?--( _Atomic const restrict T * _Atomic restrict volatile * ); 1128 forall( otype T ) _Atomic const volatile T * ?--( _Atomic const volatile T * restrict volatile * ),1112 forall( type T ) _Atomic const volatile T * ?--( _Atomic const volatile T * restrict volatile * ), 1129 1113 * ?--( _Atomic const volatile T * _Atomic restrict volatile * ); 1130 forall( otype T ) _Atomic restrict volatile T * ?--( _Atomic restrict volatile T * restrict volatile * ),1114 forall( type T ) _Atomic restrict volatile T * ?--( _Atomic restrict volatile T * restrict volatile * ), 1131 1115 * ?--( _Atomic restrict volatile T * _Atomic restrict volatile * ); 1132 forall( otype T ) const restrict volatile T * ?--( const restrict volatile T * restrict volatile * ),1116 forall( type T ) const restrict volatile T * ?--( const restrict volatile T * restrict volatile * ), 1133 1117 * ?--( const restrict volatile T * _Atomic restrict volatile * ); 1134 forall( otype T ) _Atomic const restrict volatile T * ?--( _Atomic const restrict volatile T * restrict volatile * ),1118 forall( type T ) _Atomic const restrict volatile T * ?--( _Atomic const restrict volatile T * restrict volatile * ), 1135 1119 * ?--( _Atomic const restrict volatile T * _Atomic restrict volatile * ); 1136 1120 \end{lstlisting} … … 1211 1195 The expression would be valid if \lstinline$?++$ were declared by 1212 1196 \begin{lstlisting} 1213 forall( otype T ) T * ?++( T * * );1197 forall( type T ) T * ?++( T * * ); 1214 1198 \end{lstlisting} with \lstinline$T$ inferred to be \lstinline$char$. 1215 1199 … … 1219 1203 Hence the actual predefined function is 1220 1204 \begin{lstlisting} 1221 forall( otype T ) T * ?++( T * restrict volatile * );1205 forall( type T ) T * ?++( T * restrict volatile * ); 1222 1206 \end{lstlisting} which also accepts a \lstinline$char * *$ argument, because of the safe conversions that add 1223 1207 \lstinline$volatile$ and \lstinline$restrict$ qualifiers. (The parameter is not const-qualified, so constant pointers cannot be incremented.) … … 1233 1217 \lstinline$char const volatile *$, so a new overloading is needed: 1234 1218 \begin{lstlisting} 1235 forall( otype T ) T const volatile * ?++( T const volatile *restrict volatile * );1219 forall( type T ) T const volatile * ?++( T const volatile *restrict volatile * ); 1236 1220 \end{lstlisting} 1237 1221 One overloading is needed for each combination of qualifiers in the pointed-at type\index{deficiencies!pointers to qualified types}. … … 1241 1225 The \lstinline$restrict$ qualifier is handled just like \lstinline$const$ and \lstinline$volatile$ in the previous case: 1242 1226 \begin{lstlisting} 1243 forall( otype T ) T restrict * ?++( T restrict *restrict volatile * );1227 forall( type T ) T restrict * ?++( T restrict *restrict volatile * ); 1244 1228 \end{lstlisting} with \lstinline$T$ inferred to be \lstinline$float *$. 1245 1229 This looks odd, because {\c11} contains a constraint that requires restrict-qualified types to be pointer-to-object types, and \lstinline$T$ is not syntactically a pointer type. \CFA loosens the constraint. … … 1299 1283 long double ++?( volatile long double * ), ++?( _Atomic volatile long double * ); 1300 1284 1301 forall( otype T ) T * ++?( T * restrict volatile * ), * ++?( T * _Atomic restrict volatile * );1302 forall( otype T ) _Atomic T * ++?( _Atomic T * restrict volatile * ), * ++?( _Atomic T * _Atomic restrict volatile * );1303 forall( otype T ) const T * ++?( const T * restrict volatile * ), * ++?( const T * _Atomic restrict volatile * );1304 forall( otype T ) volatile T * ++?( volatile T * restrict volatile * ), * ++?( volatile T * _Atomic restrict volatile * );1305 forall( otype T ) restrict T * ++?( restrict T * restrict volatile * ), * ++?( restrict T * _Atomic restrict volatile * );1306 forall( otype T ) _Atomic const T * ++?( _Atomic const T * restrict volatile * ),1285 forall( type T ) T * ++?( T * restrict volatile * ), * ++?( T * _Atomic restrict volatile * ); 1286 forall( type T ) _Atomic T * ++?( _Atomic T * restrict volatile * ), * ++?( _Atomic T * _Atomic restrict volatile * ); 1287 forall( type T ) const T * ++?( const T * restrict volatile * ), * ++?( const T * _Atomic restrict volatile * ); 1288 forall( type T ) volatile T * ++?( volatile T * restrict volatile * ), * ++?( volatile T * _Atomic restrict volatile * ); 1289 forall( type T ) restrict T * ++?( restrict T * restrict volatile * ), * ++?( restrict T * _Atomic restrict volatile * ); 1290 forall( type T ) _Atomic const T * ++?( _Atomic const T * restrict volatile * ), 1307 1291 * ++?( _Atomic const T * _Atomic restrict volatile * ); 1308 forall( otype T ) _Atomic volatile T * ++?( _Atomic volatile T * restrict volatile * ),1292 forall( type T ) _Atomic volatile T * ++?( _Atomic volatile T * restrict volatile * ), 1309 1293 * ++?( _Atomic volatile T * _Atomic restrict volatile * ); 1310 forall( otype T ) _Atomic restrict T * ++?( _Atomic restrict T * restrict volatile * ),1294 forall( type T ) _Atomic restrict T * ++?( _Atomic restrict T * restrict volatile * ), 1311 1295 * ++?( _Atomic restrict T * _Atomic restrict volatile * ); 1312 forall( otype T ) const volatile T * ++?( const volatile T * restrict volatile * ),1296 forall( type T ) const volatile T * ++?( const volatile T * restrict volatile * ), 1313 1297 * ++?( const volatile T * _Atomic restrict volatile * ); 1314 forall( otype T ) const restrict T * ++?( const restrict T * restrict volatile * ),1298 forall( type T ) const restrict T * ++?( const restrict T * restrict volatile * ), 1315 1299 * ++?( const restrict T * _Atomic restrict volatile * ); 1316 forall( otype T ) restrict volatile T * ++?( restrict volatile T * restrict volatile * ),1300 forall( type T ) restrict volatile T * ++?( restrict volatile T * restrict volatile * ), 1317 1301 * ++?( restrict volatile T * _Atomic restrict volatile * ); 1318 forall( otype T ) _Atomic const volatile T * ++?( _Atomic const volatile T * restrict volatile * ),1302 forall( type T ) _Atomic const volatile T * ++?( _Atomic const volatile T * restrict volatile * ), 1319 1303 * ++?( _Atomic const volatile T * _Atomic restrict volatile * ); 1320 forall( otype T ) _Atomic const restrict T * ++?( _Atomic const restrict T * restrict volatile * ),1304 forall( type T ) _Atomic const restrict T * ++?( _Atomic const restrict T * restrict volatile * ), 1321 1305 * ++?( _Atomic const restrict T * _Atomic restrict volatile * ); 1322 forall( otype T ) _Atomic restrict volatile T * ++?( _Atomic restrict volatile T * restrict volatile * ),1306 forall( type T ) _Atomic restrict volatile T * ++?( _Atomic restrict volatile T * restrict volatile * ), 1323 1307 * ++?( _Atomic restrict volatile T * _Atomic restrict volatile * ); 1324 forall( otype T ) const restrict volatile T * ++?( const restrict volatile T * restrict volatile * ),1308 forall( type T ) const restrict volatile T * ++?( const restrict volatile T * restrict volatile * ), 1325 1309 * ++?( const restrict volatile T * _Atomic restrict volatile * ); 1326 forall( otype T ) _Atomic const restrict volatile T * ++?( _Atomic const restrict volatile T * restrict volatile * ),1310 forall( type T ) _Atomic const restrict volatile T * ++?( _Atomic const restrict volatile T * restrict volatile * ), 1327 1311 * ++?( _Atomic const restrict volatile T * _Atomic restrict volatile * ); 1328 1312 … … 1343 1327 long double --?( volatile long double * ), --?( _Atomic volatile long double * ); 1344 1328 1345 forall( otype T ) T * --?( T * restrict volatile * ), * --?( T * _Atomic restrict volatile * );1346 forall( otype T ) _Atomic T * --?( _Atomic T * restrict volatile * ), * --?( _Atomic T * _Atomic restrict volatile * );1347 forall( otype T ) const T * --?( const T * restrict volatile * ), * --?( const T * _Atomic restrict volatile * );1348 forall( otype T ) volatile T * --?( volatile T * restrict volatile * ), * --?( volatile T * _Atomic restrict volatile * );1349 forall( otype T ) restrict T * --?( restrict T * restrict volatile * ), * --?( restrict T * _Atomic restrict volatile * );1350 forall( otype T ) _Atomic const T * --?( _Atomic const T * restrict volatile * ),1329 forall( type T ) T * --?( T * restrict volatile * ), * --?( T * _Atomic restrict volatile * ); 1330 forall( type T ) _Atomic T * --?( _Atomic T * restrict volatile * ), * --?( _Atomic T * _Atomic restrict volatile * ); 1331 forall( type T ) const T * --?( const T * restrict volatile * ), * --?( const T * _Atomic restrict volatile * ); 1332 forall( type T ) volatile T * --?( volatile T * restrict volatile * ), * --?( volatile T * _Atomic restrict volatile * ); 1333 forall( type T ) restrict T * --?( restrict T * restrict volatile * ), * --?( restrict T * _Atomic restrict volatile * ); 1334 forall( type T ) _Atomic const T * --?( _Atomic const T * restrict volatile * ), 1351 1335 * --?( _Atomic const T * _Atomic restrict volatile * ); 1352 forall( otype T ) _Atomic volatile T * --?( _Atomic volatile T * restrict volatile * ),1336 forall( type T ) _Atomic volatile T * --?( _Atomic volatile T * restrict volatile * ), 1353 1337 * --?( _Atomic volatile T * _Atomic restrict volatile * ); 1354 forall( otype T ) _Atomic restrict T * --?( _Atomic restrict T * restrict volatile * ),1338 forall( type T ) _Atomic restrict T * --?( _Atomic restrict T * restrict volatile * ), 1355 1339 * --?( _Atomic restrict T * _Atomic restrict volatile * ); 1356 forall( otype T ) const volatile T * --?( const volatile T * restrict volatile * ),1340 forall( type T ) const volatile T * --?( const volatile T * restrict volatile * ), 1357 1341 * --?( const volatile T * _Atomic restrict volatile * ); 1358 forall( otype T ) const restrict T * --?( const restrict T * restrict volatile * ),1342 forall( type T ) const restrict T * --?( const restrict T * restrict volatile * ), 1359 1343 * --?( const restrict T * _Atomic restrict volatile * ); 1360 forall( otype T ) restrict volatile T * --?( restrict volatile T * restrict volatile * ),1344 forall( type T ) restrict volatile T * --?( restrict volatile T * restrict volatile * ), 1361 1345 * --?( restrict volatile T * _Atomic restrict volatile * ); 1362 forall( otype T ) _Atomic const volatile T * --?( _Atomic const volatile T * restrict volatile * ),1346 forall( type T ) _Atomic const volatile T * --?( _Atomic const volatile T * restrict volatile * ), 1363 1347 * --?( _Atomic const volatile T * _Atomic restrict volatile * ); 1364 forall( otype T ) _Atomic const restrict T * --?( _Atomic const restrict T * restrict volatile * ),1348 forall( type T ) _Atomic const restrict T * --?( _Atomic const restrict T * restrict volatile * ), 1365 1349 * --?( _Atomic const restrict T * _Atomic restrict volatile * ); 1366 forall( otype T ) _Atomic restrict volatile T * --?( _Atomic restrict volatile T * restrict volatile * ),1350 forall( type T ) _Atomic restrict volatile T * --?( _Atomic restrict volatile T * restrict volatile * ), 1367 1351 * --?( _Atomic restrict volatile T * _Atomic restrict volatile * ); 1368 forall( otype T ) const restrict volatile T * --?( const restrict volatile T * restrict volatile * ),1352 forall( type T ) const restrict volatile T * --?( const restrict volatile T * restrict volatile * ), 1369 1353 * --?( const restrict volatile T * _Atomic restrict volatile * ); 1370 forall( otype T ) _Atomic const restrict volatile T * --?( _Atomic const restrict volatile T * restrict volatile * ),1354 forall( type T ) _Atomic const restrict volatile T * --?( _Atomic const restrict volatile T * restrict volatile * ), 1371 1355 * --?( _Atomic const restrict volatile T * _Atomic restrict volatile * ); 1372 1356 \end{lstlisting} … … 1396 1380 \predefined 1397 1381 \begin{lstlisting} 1398 forall( otype T ) lvalue T *?( T * );1399 forall( otype T ) _Atomic lvalue T *?( _Atomic T * );1400 forall( otype T ) const lvalue T *?( const T * );1401 forall( otype T ) volatile lvalue T *?( volatile T * );1402 forall( otype T ) restrict lvalue T *?( restrict T * );1403 forall( otype T ) _Atomic const lvalue T *?( _Atomic const T * );1404 forall( otype T ) _Atomic volatile lvalue T *?( _Atomic volatile T * );1405 forall( otype T ) _Atomic restrict lvalue T *?( _Atomic restrict T * );1406 forall( otype T ) const volatile lvalue T *?( const volatile T * );1407 forall( otype T ) const restrict lvalue T *?( const restrict T * );1408 forall( otype T ) restrict volatile lvalue T *?( restrict volatile T * );1409 forall( otype T ) _Atomic const volatile lvalue T *?( _Atomic const volatile T * );1410 forall( otype T ) _Atomic const restrict lvalue T *?( _Atomic const restrict T * );1411 forall( otype T ) _Atomic restrict volatile lvalue T *?( _Atomic restrict volatile T * );1412 forall( otype T ) const restrict volatile lvalue T *?( const restrict volatile T * );1413 forall( otype T ) _Atomic const restrict volatile lvalue T *?( _Atomic const restrict volatile T * );1382 forall( type T ) lvalue T *?( T * ); 1383 forall( type T ) _Atomic lvalue T *?( _Atomic T * ); 1384 forall( type T ) const lvalue T *?( const T * ); 1385 forall( type T ) volatile lvalue T *?( volatile T * ); 1386 forall( type T ) restrict lvalue T *?( restrict T * ); 1387 forall( type T ) _Atomic const lvalue T *?( _Atomic const T * ); 1388 forall( type T ) _Atomic volatile lvalue T *?( _Atomic volatile T * ); 1389 forall( type T ) _Atomic restrict lvalue T *?( _Atomic restrict T * ); 1390 forall( type T ) const volatile lvalue T *?( const volatile T * ); 1391 forall( type T ) const restrict lvalue T *?( const restrict T * ); 1392 forall( type T ) restrict volatile lvalue T *?( restrict volatile T * ); 1393 forall( type T ) _Atomic const volatile lvalue T *?( _Atomic const volatile T * ); 1394 forall( type T ) _Atomic const restrict lvalue T *?( _Atomic const restrict T * ); 1395 forall( type T ) _Atomic restrict volatile lvalue T *?( _Atomic restrict volatile T * ); 1396 forall( type T ) const restrict volatile lvalue T *?( const restrict volatile T * ); 1397 forall( type T ) _Atomic const restrict volatile lvalue T *?( _Atomic const restrict volatile T * ); 1414 1398 forall( ftype FT ) FT *?( FT * ); 1415 1399 \end{lstlisting} … … 1526 1510 \begin{rationale} 1527 1511 \begin{lstlisting} 1528 otype Pair = struct { int first, second; };1512 type Pair = struct { int first, second; }; 1529 1513 size_t p_size = sizeof(Pair); // constant expression 1530 extern otype Rational;@\use{Rational}@1514 extern type Rational;@\use{Rational}@ 1531 1515 size_t c_size = sizeof(Rational); // non-constant expression 1532 1516 forall(type T) T f(T p1, T p2) { … … 1652 1636 Consider 1653 1637 \begin{lstlisting} 1654 forall( otype T | T ?*?( T, T ) ) T square( T );1638 forall( type T | T ?*?( T, T ) ) T square( T ); 1655 1639 short s; 1656 1640 square( s ); … … 1663 1647 A more troubling example is 1664 1648 \begin{lstlisting} 1665 forall( otype T | ?*?( T, T ) ) T product( T[], int n );1649 forall( type T | ?*?( T, T ) ) T product( T[], int n ); 1666 1650 short sa[5]; 1667 1651 product( sa, 5); … … 1720 1704 ?+?( _Complex long double, _Complex long double ), ?-?( _Complex long double, _Complex long double ); 1721 1705 1722 forall( otype T ) T * ?+?( T *, ptrdiff_t ), * ?+?( ptrdiff_t, T * ), * ?-?( T *, ptrdiff_t );1723 forall( otype T ) _Atomic T * ?+?( _Atomic T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic T * ),1706 forall( type T ) T * ?+?( T *, ptrdiff_t ), * ?+?( ptrdiff_t, T * ), * ?-?( T *, ptrdiff_t ); 1707 forall( type T ) _Atomic T * ?+?( _Atomic T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic T * ), 1724 1708 * ?-?( _Atomic T *, ptrdiff_t ); 1725 forall( otype T ) const T * ?+?( const T *, ptrdiff_t ), * ?+?( ptrdiff_t, const T * ),1709 forall( type T ) const T * ?+?( const T *, ptrdiff_t ), * ?+?( ptrdiff_t, const T * ), 1726 1710 * ?-?( const T *, ptrdiff_t ); 1727 forall( otype T ) restrict T * ?+?( restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, restrict T * ),1711 forall( type T ) restrict T * ?+?( restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, restrict T * ), 1728 1712 * ?-?( restrict T *, ptrdiff_t ); 1729 forall( otype T ) volatile T * ?+?( volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, volatile T * ),1713 forall( type T ) volatile T * ?+?( volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, volatile T * ), 1730 1714 * ?-?( volatile T *, ptrdiff_t ); 1731 forall( otype T ) _Atomic const T * ?+?( _Atomic const T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic const T * ),1715 forall( type T ) _Atomic const T * ?+?( _Atomic const T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic const T * ), 1732 1716 * ?-?( _Atomic const T *, ptrdiff_t ); 1733 forall( otype T ) _Atomic restrict T * ?+?( _Atomic restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic restrict T * ),1717 forall( type T ) _Atomic restrict T * ?+?( _Atomic restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic restrict T * ), 1734 1718 * ?-?( _Atomic restrict T *, ptrdiff_t ); 1735 forall( otype T ) _Atomic volatile T * ?+?( _Atomic volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic volatile T * ),1719 forall( type T ) _Atomic volatile T * ?+?( _Atomic volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic volatile T * ), 1736 1720 * ?-?( _Atomic volatile T *, ptrdiff_t ); 1737 forall( otype T ) const restrict T * ?+?( const restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, const restrict T * ),1721 forall( type T ) const restrict T * ?+?( const restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, const restrict T * ), 1738 1722 * ?-?( const restrict T *, ptrdiff_t ); 1739 forall( otype T ) const volatile T * ?+?( const volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, const volatile T * ),1723 forall( type T ) const volatile T * ?+?( const volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, const volatile T * ), 1740 1724 * ?-?( const volatile T *, ptrdiff_t ); 1741 forall( otype T ) restrict volatile T * ?+?( restrict volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, restrict volatile T * ),1725 forall( type T ) restrict volatile T * ?+?( restrict volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, restrict volatile T * ), 1742 1726 * ?-?( restrict volatile T *, ptrdiff_t ); 1743 forall( otype T ) _Atomic const restrict T * ?+?( _Atomic const restrict T *, ptrdiff_t ),1727 forall( type T ) _Atomic const restrict T * ?+?( _Atomic const restrict T *, ptrdiff_t ), 1744 1728 * ?+?( ptrdiff_t, _Atomic const restrict T * ), 1745 1729 * ?-?( _Atomic const restrict T *, ptrdiff_t ); 1746 forall( otype T ) ptrdiff_t1730 forall( type T ) ptrdiff_t 1747 1731 * ?-?( const restrict volatile T *, const restrict volatile T * ), 1748 1732 * ?-?( _Atomic const restrict volatile T *, _Atomic const restrict volatile T * ); … … 2068 2052 2069 2053 \begin{lstlisting} 2070 extern otype Rational;@\use{Rational}@2054 extern type Rational;@\use{Rational}@ 2071 2055 extern const Rational 0;@\use{0}@ 2072 2056 extern int ?!=?( Rational, Rational ); … … 2111 2095 If the second and third operands both have interpretations with non-\lstinline$void$ types, the expression is treated as if it were the call ``\lstinline$cond((a)!=0, b, c)$'', with \lstinline$cond$ declared as 2112 2096 \begin{lstlisting} 2113 forall( otype T ) T cond( int, T, T );2097 forall( type T ) T cond( int, T, T ); 2114 2098 forall( dtype D ) void * cond( int, D *, void * ), * cond( int, void *, D * ); 2115 2099 forall( dtype D ) _atomic void * cond( … … 2471 2455 \predefined 2472 2456 \begin{lstlisting} 2473 forall( otype T ) T2457 forall( type T ) T 2474 2458 * ?+=?( T * restrict volatile *, ptrdiff_t ), 2475 2459 * ?-=?( T * restrict volatile *, ptrdiff_t ), 2476 2460 * ?+=?( T * _Atomic restrict volatile *, ptrdiff_t ), 2477 2461 * ?-=?( T * _Atomic restrict volatile *, ptrdiff_t ); 2478 forall( otype T ) T _Atomic2462 forall( type T ) T _Atomic 2479 2463 * ?+=?( T _Atomic * restrict volatile *, ptrdiff_t ), 2480 2464 * ?-=?( T _Atomic * restrict volatile *, ptrdiff_t ), 2481 2465 * ?+=?( T _Atomic * _Atomic restrict volatile *, ptrdiff_t ), 2482 2466 * ?-=?( T _Atomic * _Atomic restrict volatile *, ptrdiff_t ); 2483 forall( otype T ) T const2467 forall( type T ) T const 2484 2468 * ?+=?( T const * restrict volatile *, ptrdiff_t ), 2485 2469 * ?-=?( T const * restrict volatile *, ptrdiff_t ), 2486 2470 * ?+=?( T const * _Atomic restrict volatile *, ptrdiff_t ), 2487 2471 * ?-=?( T const * _Atomic restrict volatile *, ptrdiff_t ); 2488 forall( otype T ) T restrict2472 forall( type T ) T restrict 2489 2473 * ?+=?( T restrict * restrict volatile *, ptrdiff_t ), 2490 2474 * ?-=?( T restrict * restrict volatile *, ptrdiff_t ), 2491 2475 * ?+=?( T restrict * _Atomic restrict volatile *, ptrdiff_t ), 2492 2476 * ?-=?( T restrict * _Atomic restrict volatile *, ptrdiff_t ); 2493 forall( otype T ) T volatile2477 forall( type T ) T volatile 2494 2478 * ?+=?( T volatile * restrict volatile *, ptrdiff_t ), 2495 2479 * ?-=?( T volatile * restrict volatile *, ptrdiff_t ), 2496 2480 * ?+=?( T volatile * _Atomic restrict volatile *, ptrdiff_t ), 2497 2481 * ?-=?( T volatile * _Atomic restrict volatile *, ptrdiff_t ); 2498 forall( otype T ) T _Atomic const2482 forall( type T ) T _Atomic const 2499 2483 * ?+=?( T _Atomic const restrict volatile *, ptrdiff_t ), 2500 2484 * ?-=?( T _Atomic const restrict volatile *, ptrdiff_t ), 2501 2485 * ?+=?( T _Atomic const _Atomic restrict volatile *, ptrdiff_t ), 2502 2486 * ?-=?( T _Atomic const _Atomic restrict volatile *, ptrdiff_t ); 2503 forall( otype T ) T _Atomic restrict2487 forall( type T ) T _Atomic restrict 2504 2488 * ?+=?( T _Atomic restrict * restrict volatile *, ptrdiff_t ), 2505 2489 * ?-=?( T _Atomic restrict * restrict volatile *, ptrdiff_t ), 2506 2490 * ?+=?( T _Atomic restrict * _Atomic restrict volatile *, ptrdiff_t ), 2507 2491 * ?-=?( T _Atomic restrict * _Atomic restrict volatile *, ptrdiff_t ); 2508 forall( otype T ) T _Atomic volatile2492 forall( type T ) T _Atomic volatile 2509 2493 * ?+=?( T _Atomic volatile * restrict volatile *, ptrdiff_t ), 2510 2494 * ?-=?( T _Atomic volatile * restrict volatile *, ptrdiff_t ), 2511 2495 * ?+=?( T _Atomic volatile * _Atomic restrict volatile *, ptrdiff_t ), 2512 2496 * ?-=?( T _Atomic volatile * _Atomic restrict volatile *, ptrdiff_t ); 2513 forall( otype T ) T const restrict2497 forall( type T ) T const restrict 2514 2498 * ?+=?( T const restrict * restrict volatile *, ptrdiff_t ), 2515 2499 * ?-=?( T const restrict * restrict volatile *, ptrdiff_t ), 2516 2500 * ?+=?( T const restrict * _Atomic restrict volatile *, ptrdiff_t ), 2517 2501 * ?-=?( T const restrict * _Atomic restrict volatile *, ptrdiff_t ); 2518 forall( otype T ) T const volatile2502 forall( type T ) T const volatile 2519 2503 * ?+=?( T const volatile * restrict volatile *, ptrdiff_t ), 2520 2504 * ?-=?( T const volatile * restrict volatile *, ptrdiff_t ), 2521 2505 * ?+=?( T const volatile * _Atomic restrict volatile *, ptrdiff_t ), 2522 2506 * ?-=?( T const volatile * _Atomic restrict volatile *, ptrdiff_t ); 2523 forall( otype T ) T restrict volatile2507 forall( type T ) T restrict volatile 2524 2508 * ?+=?( T restrict volatile * restrict volatile *, ptrdiff_t ), 2525 2509 * ?-=?( T restrict volatile * restrict volatile *, ptrdiff_t ), 2526 2510 * ?+=?( T restrict volatile * _Atomic restrict volatile *, ptrdiff_t ), 2527 2511 * ?-=?( T restrict volatile * _Atomic restrict volatile *, ptrdiff_t ); 2528 forall( otype T ) T _Atomic const restrict2512 forall( type T ) T _Atomic const restrict 2529 2513 * ?+=?( T _Atomic const restrict * restrict volatile *, ptrdiff_t ), 2530 2514 * ?-=?( T _Atomic const restrict * restrict volatile *, ptrdiff_t ), 2531 2515 * ?+=?( T _Atomic const restrict * _Atomic restrict volatile *, ptrdiff_t ), 2532 2516 * ?-=?( T _Atomic const restrict * _Atomic restrict volatile *, ptrdiff_t ); 2533 forall( otype T ) T _Atomic const volatile2517 forall( type T ) T _Atomic const volatile 2534 2518 * ?+=?( T _Atomic const volatile * restrict volatile *, ptrdiff_t ), 2535 2519 * ?-=?( T _Atomic const volatile * restrict volatile *, ptrdiff_t ), 2536 2520 * ?+=?( T _Atomic const volatile * _Atomic restrict volatile *, ptrdiff_t ), 2537 2521 * ?-=?( T _Atomic const volatile * _Atomic restrict volatile *, ptrdiff_t ); 2538 forall( otype T ) T _Atomic restrict volatile2522 forall( type T ) T _Atomic restrict volatile 2539 2523 * ?+=?( T _Atomic restrict volatile * restrict volatile *, ptrdiff_t ), 2540 2524 * ?-=?( T _Atomic restrict volatile * restrict volatile *, ptrdiff_t ), 2541 2525 * ?+=?( T _Atomic restrict volatile * _Atomic restrict volatile *, ptrdiff_t ), 2542 2526 * ?-=?( T _Atomic restrict volatile * _Atomic restrict volatile *, ptrdiff_t ); 2543 forall( otype T ) T const restrict volatile2527 forall( type T ) T const restrict volatile 2544 2528 * ?+=?( T const restrict volatile * restrict volatile *, ptrdiff_t ), 2545 2529 * ?-=?( T const restrict volatile * restrict volatile *, ptrdiff_t ), 2546 2530 * ?+=?( T const restrict volatile * _Atomic restrict volatile *, ptrdiff_t ), 2547 2531 * ?-=?( T const restrict volatile * _Atomic restrict volatile *, ptrdiff_t ); 2548 forall( otype T ) T _Atomic const restrict volatile2532 forall( type T ) T _Atomic const restrict volatile 2549 2533 * ?+=?( T _Atomic const restrict volatile * restrict volatile *, ptrdiff_t ), 2550 2534 * ?-=?( T _Atomic const restrict volatile * restrict volatile *, ptrdiff_t ), … … 2858 2842 This sort of declaration is illegal because the scope of the type identifiers ends at the end of the declaration, but the scope of the structure tag does not. 2859 2843 \begin{lstlisting} 2860 forall( otype T ) struct Pair { T a, b;2844 forall( type T ) struct Pair { T a, b; 2861 2845 } mkPair( T, T ); // illegal 2862 2846 \end{lstlisting} … … 2883 2867 If this restriction were lifted, it would be possible to write 2884 2868 \begin{lstlisting} 2885 forall( otype T ) T * alloc( void );@\use{alloc}@ int *p = alloc();2869 forall( type T ) T * alloc( void );@\use{alloc}@ int *p = alloc(); 2886 2870 \end{lstlisting} 2887 2871 Here \lstinline$alloc()$ would receive \lstinline$int$ as an inferred argument, and return an … … 2892 2876 \lstinline$T$: 2893 2877 \begin{lstlisting} 2894 forall( otype T ) T * alloc( T initial_value );@\use{alloc}@2878 forall( type T ) T * alloc( T initial_value );@\use{alloc}@ 2895 2879 \end{lstlisting} 2896 2880 \end{rationale} … … 2915 2899 \begin{lstlisting} 2916 2900 int fi( int ); 2917 forall( otype T ) T fT( T );2901 forall( type T ) T fT( T ); 2918 2902 \end{lstlisting} 2919 2903 \lstinline$fi()$ takes an \lstinline$int$ and returns an \lstinline$int$. \lstinline$fT()$ takes a … … 2921 2905 \begin{lstlisting} 2922 2906 int (*pfi )( int ) = fi; 2923 forall( otype T ) T (*pfT )( T ) = fT;2907 forall( type T ) T (*pfT )( T ) = fT; 2924 2908 \end{lstlisting} 2925 2909 \lstinline$pfi$ and \lstinline$pfT$ are pointers to functions. \lstinline$pfT$ is not polymorphic, but the function it points at is. … … 2928 2912 return pfi; 2929 2913 } 2930 forall( otype T ) T (*fvpfT( void ))( T ) {2914 forall( type T ) T (*fvpfT( void ))( T ) { 2931 2915 return pfT; 2932 2916 } … … 2934 2918 \lstinline$fvpfi()$ and \lstinline$fvpfT()$ are functions taking no arguments and returning pointers to functions. \lstinline$fvpfT()$ is monomorphic, but the function that its return value points at is polymorphic. 2935 2919 \begin{lstlisting} 2936 forall( otype T ) int ( *fTpfi( T ) )( int );2937 forall( otype T ) T ( *fTpfT( T ) )( T );2938 forall( otype T, otype U ) U ( *fTpfU( T ) )( U );2920 forall( type T ) int ( *fTpfi( T ) )( int ); 2921 forall( type T ) T ( *fTpfT( T ) )( T ); 2922 forall( type T, type U ) U ( *fTpfU( T ) )( U ); 2939 2923 \end{lstlisting} 2940 2924 \lstinline$fTpfi()$ is a polymorphic function that returns a pointer to a monomorphic function taking an integer and returning an integer. … … 2946 2930 \lstinline$char *$. 2947 2931 \begin{lstlisting} 2948 forall( otype T, otype U, otype V ) U * f( T *, U, V * const );2949 forall( otype U, otype V, otype W ) U * g( V *, U, W * const );2932 forall( type T, type U, type V ) U * f( T *, U, V * const ); 2933 forall( type U, type V, type W ) U * g( V *, U, W * const ); 2950 2934 \end{lstlisting} 2951 2935 The functions \lstinline$f()$ and \lstinline$g()$ have compatible types. … … 2955 2939 Replacing every \(f_i\) by \(g_i\) in \(f\) gives 2956 2940 \begin{lstlisting} 2957 forall( otype V, otype U, otype W ) U * f( V *, U, W * const );2941 forall( type V, type U, type W ) U * f( V *, U, W * const ); 2958 2942 \end{lstlisting} which has a return type and parameter list that is compatible with \(g\). 2959 2943 \begin{rationale} … … 3143 3127 \examples 3144 3128 \begin{lstlisting} 3145 forall( otype T | T ?*?( T, T ))@\use{?*?}@3129 forall( type T | T ?*?( T, T ))@\use{?*?}@ 3146 3130 T square( T val ) {@\impl{square}@ 3147 3131 return val + val; 3148 3132 } 3149 trait summable( otype T ) {@\impl{summable}@3133 context summable( type T ) {@\impl{summable}@ 3150 3134 T ?+=?( T *, T );@\use{?+=?}@ 3151 3135 const T 0;@\use{0}@ 3152 3136 }; 3153 trait list_of( otype List, otype Element ) {@\impl{list_of}@3137 context list_of( type List, type Element ) {@\impl{list_of}@ 3154 3138 Element car( List ); 3155 3139 List cdr( List ); … … 3158 3142 int is_nil( List ); 3159 3143 }; 3160 trait sum_list( otype List, otype Element | summable( Element ) | list_of( List, Element ) ) {};3144 context sum_list( type List, type Element | summable( Element ) | list_of( List, Element ) ) {}; 3161 3145 \end{lstlisting} 3162 3146 \lstinline$sum_list$ contains seven declarations, which describe a list whose elements can be added up. … … 3220 3204 Incomplete type declarations allow compact mutually-recursive types. 3221 3205 \begin{lstlisting} 3222 otype t1; // incomplete type declaration3223 otype t2 = struct { t1 * p; ... };3224 otype t1 = struct { t2 * p; ... };3206 type t1; // incomplete type declaration 3207 type t2 = struct { t1 * p; ... }; 3208 type t1 = struct { t2 * p; ... }; 3225 3209 \end{lstlisting} 3226 3210 Without them, mutual recursion could be handled by declaring mutually recursive structures, then initializing the types to those structures. 3227 3211 \begin{lstlisting} 3228 3212 struct s1; 3229 otype t2 = struct s2 { struct s1 * p; ... };3230 otype t1 = struct s1 { struct s2 * p; ... };3213 type t2 = struct s2 { struct s1 * p; ... }; 3214 type t1 = struct s1 { struct s2 * p; ... }; 3231 3215 \end{lstlisting} 3232 3216 This introduces extra names, and may force the programmer to cast between the types and their implementations. … … 3283 3267 This prevents the declaration of types that contain each other. 3284 3268 \begin{lstlisting} 3285 otype t1;3286 otype t2 = t1; // illegal: incomplete type t13287 otype t1 = t2;3269 type t1; 3270 type t2 = t1; // illegal: incomplete type t1 3271 type t1 = t2; 3288 3272 \end{lstlisting} 3289 3273 … … 3292 3276 types}. 3293 3277 \begin{lstlisting} 3294 extern otype Huge; // extended-precision integer type3295 otype Rational = struct {3278 extern type Huge; // extended-precision integer type 3279 type Rational = struct { 3296 3280 Huge numerator, denominator; // illegal 3297 3281 }; … … 3332 3316 \begin{lstlisting} 3333 3317 #include <stdlib.h> 3334 T * new( otype T ) { return ( T * )malloc( sizeof( T) ); };3318 T * new( type T ) { return ( T * )malloc( sizeof( T) ); }; 3335 3319 @\ldots@ int * ip = new( int ); 3336 3320 \end{lstlisting} … … 3343 3327 Since type declarations create new types, instances of types are always passed by value. 3344 3328 \begin{lstlisting} 3345 otype A1 = int[2];3329 type A1 = int[2]; 3346 3330 void f1( A1 a ) { a[0] = 0; }; 3347 otypedef int A2[2];3331 typedef int A2[2]; 3348 3332 void f2( A2 a ) { a[0] = 0; }; 3349 3333 A1 v1; … … 3362 3346 That unit might contain the declarations 3363 3347 \begin{lstlisting} 3364 otype Complex = struct { float re, im; };@\impl{Complex}@3348 type Complex = struct { float re, im; };@\impl{Complex}@ 3365 3349 Complex cplx_i = { 0.0, 1.0 };@\impl{cplx_i}@ 3366 3350 float abs( Complex c ) {@\impl{abs( Complex )}@ … … 3371 3355 3372 3356 \begin{lstlisting} 3373 otype Time_of_day = int;@\impl{Time_of_day}@ // seconds since midnight.3357 type Time_of_day = int;@\impl{Time_of_day}@ // seconds since midnight. 3374 3358 Time_of_day ?+?( Time_of_day t1, int seconds ) {@\impl{?+?}@ 3375 3359 return (( int)t1 + seconds ) % 86400; … … 3445 3429 \examples 3446 3430 \begin{lstlisting} 3447 trait s( otype T ) {3431 context s( type T ) { 3448 3432 T a, b; 3449 3433 } struct impl { int left, right; } a = { 0, 0 }; 3450 otype Pair | s( Pair ) = struct impl;3434 type Pair | s( Pair ) = struct impl; 3451 3435 Pair b = { 1, 1 }; 3452 3436 \end{lstlisting} … … 3456 3440 \lstinline$Pair b$ is compulsory because there is no \lstinline$struct impl b$ to construct a value from. 3457 3441 \begin{lstlisting} 3458 trait ss( otype T ) {3442 context ss( type T ) { 3459 3443 T clone( T ); 3460 3444 void munge( T * ); 3461 3445 } 3462 otype Whatsit | ss( Whatsit );@\use{Whatsit}@3463 otype Doodad | ss( Doodad ) = struct doodad {@\use{Doodad}@3446 type Whatsit | ss( Whatsit );@\use{Whatsit}@ 3447 type Doodad | ss( Doodad ) = struct doodad {@\use{Doodad}@ 3464 3448 Whatsit; // anonymous member 3465 3449 int extra; … … 3482 3466 Default functions and objects are subject to the normal scope rules. 3483 3467 \begin{lstlisting} 3484 otype T = @\ldots@;3468 type T = @\ldots@; 3485 3469 T a_T = @\ldots@; // Default assignment used. 3486 3470 T ?=?( T *, T ); … … 3751 3735 The assertion ``\lstinline$scalar( Complex )$'' should be read as ``type \lstinline$Complex$ is scalar''. 3752 3736 \begin{lstlisting} 3753 trait scalar( otype T ) {@\impl{scalar}@3737 context scalar( type T ) {@\impl{scalar}@ 3754 3738 int !?( T ); 3755 3739 int ?<?( T, T ), ?<=?( T, T ), ?==?( T, T ), ?>=?( T, T ), ?>?( T, T ), ?!=?( T, T ); … … 3761 3745 This is equivalent to inheritance of specifications. 3762 3746 \begin{lstlisting} 3763 trait arithmetic( otype T | scalar( T ) ) {@\impl{arithmetic}@@\use{scalar}@3747 context arithmetic( type T | scalar( T ) ) {@\impl{arithmetic}@@\use{scalar}@ 3764 3748 T +?( T ), -?( T ); 3765 3749 T ?*?( T, T ), ?/?( T, T ), ?+?( T, T ), ?-?( T, T ); … … 3770 3754 \define{integral types}. 3771 3755 \begin{lstlisting} 3772 trait integral( otype T | arithmetic( T ) ) {@\impl{integral}@@\use{arithmetic}@3756 context integral( type T | arithmetic( T ) ) {@\impl{integral}@@\use{arithmetic}@ 3773 3757 T ~?( T ); 3774 3758 T ?&?( T, T ), ?|?( T, T ), ?^?( T, T ); … … 3784 3768 The only operation that can be applied to all modifiable lvalues is simple assignment. 3785 3769 \begin{lstlisting} 3786 trait m_lvalue( otype T ) {@\impl{m_lvalue}@3770 context m_lvalue( type T ) {@\impl{m_lvalue}@ 3787 3771 T ?=?( T *, T ); 3788 3772 }; … … 3794 3778 Scalars can also be incremented and decremented. 3795 3779 \begin{lstlisting} 3796 trait m_l_scalar( otype T | scalar( T ) | m_lvalue( T ) ) {@\impl{m_l_scalar}@3780 context m_l_scalar( type T | scalar( T ) | m_lvalue( T ) ) {@\impl{m_l_scalar}@ 3797 3781 T ?++( T * ), ?--( T * );@\use{scalar}@@\use{m_lvalue}@ 3798 3782 T ++?( T * ), --?( T * ); … … 3803 3787 Note that this results in the ``inheritance'' of \lstinline$scalar$ along both paths. 3804 3788 \begin{lstlisting} 3805 trait m_l_arithmetic( otype T | m_l_scalar( T ) | arithmetic( T ) ) {@\impl{m_l_arithmetic}@3789 context m_l_arithmetic( type T | m_l_scalar( T ) | arithmetic( T ) ) {@\impl{m_l_arithmetic}@ 3806 3790 T ?/=?( T *, T ), ?*=?( T *, T );@\use{m_l_scalar}@@\use{arithmetic}@ 3807 3791 T ?+=?( T *, T ), ?-=?( T *, T ); 3808 3792 }; 3809 trait m_l_integral( otype T | m_l_arithmetic( T ) | integral( T ) ) {@\impl{m_l_integral}@3793 context m_l_integral( type T | m_l_arithmetic( T ) | integral( T ) ) {@\impl{m_l_integral}@ 3810 3794 T ?&=?( T *, T ), ?|=?( T *, T ), ?^=?( T *, T );@\use{m_l_arithmetic}@ 3811 3795 T ?%=?( T *, T ), ?<<=?( T *, T ), ?>>=?( T *, T );@\use{integral}@ … … 3827 3811 \lstinline$arithmetic$, so these operators cannot be consolidated in \lstinline$scalar$. 3828 3812 \begin{lstlisting} 3829 trait pointer( type P | scalar( P ) ) {@\impl{pointer}@@\use{scalar}@3813 context pointer( type P | scalar( P ) ) {@\impl{pointer}@@\use{scalar}@ 3830 3814 P ?+?( P, long int ), ?+?( long int, P ), ?-?( P, long int ); 3831 3815 ptrdiff_t ?-?( P, P ); 3832 3816 }; 3833 trait m_l_pointer( type P | pointer( P ) | m_l_scalar( P ) ) {@\impl{m_l_pointer}@3817 context m_l_pointer( type P | pointer( P ) | m_l_scalar( P ) ) {@\impl{m_l_pointer}@ 3834 3818 P ?+=?( P *, long int ), ?-=?( P *, long int ); 3835 3819 P ?=?( P *, void * ); … … 3843 3827 ``\lstinline$Safe_pointer$ acts like a pointer to \lstinline$int$''. 3844 3828 \begin{lstlisting} 3845 trait ptr_to( type P | pointer( P ), otype T ) {@\impl{ptr_to}@@\use{pointer}@3829 context ptr_to( type P | pointer( P ), type T ) {@\impl{ptr_to}@@\use{pointer}@ 3846 3830 lvalue T *?( P ); 3847 3831 lvalue T ?[?]( P, long int ); 3848 3832 }; 3849 trait ptr_to_const( type P | pointer( P ), otype T ) {@\impl{ptr_to_const}@3833 context ptr_to_const( type P | pointer( P ), type T ) {@\impl{ptr_to_const}@ 3850 3834 const lvalue T *?( P ); 3851 3835 const lvalue T ?[?]( P, long int );@\use{pointer}@ 3852 3836 }; 3853 trait ptr_to_volatile( type P | pointer( P ), otype T ) }@\impl{ptr_to_volatile}@3837 context ptr_to_volatile( type P | pointer( P ), type T ) }@\impl{ptr_to_volatile}@ 3854 3838 volatile lvalue T *?( P ); 3855 3839 volatile lvalue T ?[?]( P, long int );@\use{pointer}@ 3856 3840 }; 3857 trait ptr_to_const_volatile( type P | pointer( P ), otype T ) }@\impl{ptr_to_const_volatile}@3841 context ptr_to_const_volatile( type P | pointer( P ), type T ) }@\impl{ptr_to_const_volatile}@ 3858 3842 const volatile lvalue T *?( P );@\use{pointer}@ 3859 3843 const volatile lvalue T ?[?]( P, long int ); … … 3865 3849 ``\lstinline$ptr_to$'' specifications. 3866 3850 \begin{lstlisting} 3867 trait m_l_ptr_to( type P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to}@ otype T | ptr_to( P, T )@\use{ptr_to}@ {3851 context m_l_ptr_to( type P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to}@ type T | ptr_to( P, T )@\use{ptr_to}@ { 3868 3852 P ?=?( P *, T * ); 3869 3853 T * ?=?( T **, P ); 3870 3854 }; 3871 trait m_l_ptr_to_const( type P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to_const}@ otype T | ptr_to_const( P, T )@\use{ptr_to_const}@) {3855 context m_l_ptr_to_const( type P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to_const}@ type T | ptr_to_const( P, T )@\use{ptr_to_const}@) { 3872 3856 P ?=?( P *, const T * ); 3873 3857 const T * ?=?( const T **, P ); 3874 3858 }; 3875 trait m_l_ptr_to_volatile( type P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to_volatile}@ otype T | ptr_to_volatile( P, T )) {@\use{ptr_to_volatile}@3859 context m_l_ptr_to_volatile( type P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to_volatile}@ type T | ptr_to_volatile( P, T )) {@\use{ptr_to_volatile}@ 3876 3860 P ?=?( P *, volatile T * ); 3877 3861 volatile T * ?=?( volatile T **, P ); 3878 3862 }; 3879 trait m_l_ptr_to_const_volatile( type P | ptr_to_const_volatile( P ),@\use{ptr_to_const_volatile}@@\impl{m_l_ptr_to_const_volatile}@3863 context m_l_ptr_to_const_volatile( type P | ptr_to_const_volatile( P ),@\use{ptr_to_const_volatile}@@\impl{m_l_ptr_to_const_volatile}@ 3880 3864 type T | m_l_ptr_to_volatile( P, T ) | m_l_ptr_to_const( P )) {@\use{m_l_ptr_to_const}@@\use{m_l_ptr_to_volatile}@ 3881 3865 P ?=?( P *, const volatile T * ); … … 3887 3871 An alternative specification can make use of the fact that qualification of the pointed-at type is part of a pointer type to capture that regularity. 3888 3872 \begin{lstlisting} 3889 trait m_l_ptr_like( type MyP | m_l_pointer( MyP ),@\use{m_l_pointer}@@\impl{m_l_ptr_like}@ type CP | m_l_pointer( CP ) ) {3873 context m_l_ptr_like( type MyP | m_l_pointer( MyP ),@\use{m_l_pointer}@@\impl{m_l_ptr_like}@ type CP | m_l_pointer( CP ) ) { 3890 3874 MyP ?=?( MyP *, CP ); 3891 3875 CP ?=?( CP *, MyP ); … … 3920 3904 C and \CFA have an extra, non-obvious comparison operator: ``\lstinline$!$'', logical negation, returns 1 if its operand compares equal to 0, and 0 otherwise. 3921 3905 \begin{lstlisting} 3922 trait comparable( otype T ) {3906 context comparable( type T ) { 3923 3907 const T 0; 3924 3908 int compare( T, T ); 3925 3909 } 3926 forall( otype T | comparable( T ) ) int ?<?( T l, T r ) {3910 forall( type T | comparable( T ) ) int ?<?( T l, T r ) { 3927 3911 return compare( l, r ) < 0; 3928 3912 } 3929 3913 // ... similarly for <=, ==, >=, >, and !=. 3930 forall( otype T | comparable( T ) ) int !?( T operand ) {3914 forall( type T | comparable( T ) ) int !?( T operand ) { 3931 3915 return !compare( operand, 0 ); 3932 3916 } … … 3940 3924 Similarly, a complete integral type would provide integral operations based on integral assignment operations. 3941 3925 \begin{lstlisting} 3942 trait arith_base( otype T ) {3926 context arith_base( type T ) { 3943 3927 const T 1; 3944 3928 T ?+=?( T *, T ), ?-=?( T *, T ), ?*=?( T *, T ), ?/=?( T *, T ); 3945 3929 } 3946 forall( otype T | arith_base( T ) ) T ?+?( T l, T r ) {3930 forall( type T | arith_base( T ) ) T ?+?( T l, T r ) { 3947 3931 return l += r; 3948 3932 } 3949 forall( otype T | arith_base( T ) ) T ?++( T * operand ) {3933 forall( type T | arith_base( T ) ) T ?++( T * operand ) { 3950 3934 T temporary = *operand; 3951 3935 *operand += 1; 3952 3936 return temporary; 3953 3937 } 3954 forall( otype T | arith_base( T ) ) T ++?( T * operand ) {3938 forall( type T | arith_base( T ) ) T ++?( T * operand ) { 3955 3939 return *operand += 1; 3956 3940 } 3957 3941 // ... similarly for -, --, *, and /. 3958 trait int_base( otype T ) {3942 context int_base( type T ) { 3959 3943 T ?&=?( T *, T ), ?|=?( T *, T ), ?^=?( T *, T ); 3960 3944 T ?%=?( T *, T ), ?<<=?( T *, T ), ?>>=?( T *, T ); 3961 3945 } 3962 forall( otype T | int_base( T ) ) T ?&?( T l, T r ) {3946 forall( type T | int_base( T ) ) T ?&?( T l, T r ) { 3963 3947 return l &= r; 3964 3948 }
Note:
See TracChangeset
for help on using the changeset viewer.