Changeset b3f9a0cb for doc/refrat
- Timestamp:
- Apr 4, 2016, 1:18:17 PM (10 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
- Children:
- afc1045
- Parents:
- 89173242 (diff), 3cfe27f (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. - File:
-
- 1 edited
-
doc/refrat/refrat.tex (modified) (76 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/refrat/refrat.tex
r89173242 rb3f9a0cb 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 \ urlstyle{sf}19 \renewcommand{\UrlFont}{\small\sf} 20 20 21 21 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% … … 23 23 % Names used in the document. 24 24 25 \newcommand{\CFA}{C forall\xspace} % set language textname26 \newcommand{\CF AA}{C$\forall$\xspace} % set language symbolicname25 \newcommand{\CFA}{C$\forall$\xspace} % set language symbolic name 26 \newcommand{\CFL}{Cforall\xspace} % set language text 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 lstinline 36 %\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 4pt 42 \abovedisplayshortskip \z@ \@plus 2pt 43 \belowdisplayshortskip 4pt \@plus 2pt \@minus 2pt 44 \def\@listi{\leftmargin\leftmargini 45 \topsep 4pt \@plus 2pt \@minus 2pt 46 \parsep 2pt \@pluspt \@minuspt 47 \itemsep \parsep}% 48 \belowdisplayskip \abovedisplayskip 49 } 50 \usepackage{relsize} % must be after change to small 51 35 52 \renewcommand{\labelitemi}{{\raisebox{0.25ex}{\footnotesize$\bullet$}}} 36 53 \renewenvironment{itemize}{\begin{list}{\labelitemi}{\topsep=5pt\itemsep=5pt\parsep=0pt}}{\end{list}} … … 59 76 \renewcommand\section{\@startsection{section}{1}{\z@}{-3.0ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\large\bfseries}} 60 77 \renewcommand\subsection{\@startsection{subsection}{2}{\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}}78 \renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}} 62 79 \renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}{-2.0ex \@plus -1ex \@minus -.2ex}{-1em}{\normalfont\normalsize\bfseries}} 63 80 81 % index macros 64 82 \newcommand{\italic}[1]{\emph{\hyperpage{#1}}} 65 83 \newcommand{\definition}[1]{\textbf{\hyperpage{#1}}} … … 97 115 98 116 % blocks and titles 99 \newcommand{\define}[1]{\emph{#1\/}\index{#1}}100 117 \newenvironment{rationale}{% 101 118 \begin{quotation}\noindent$\Box$\enspace … … 103 120 \hfill\enspace$\Box$\end{quotation} 104 121 }% 122 \newcommand{\define}[1]{\emph{#1\/}\index{#1}} 105 123 \newcommand{\rewrite}{\(\Rightarrow\)} 106 124 \newcommand{\rewriterules}{\paragraph{Rewrite Rules}~\par\noindent} … … 131 149 \newcommand{\VPageref}[2][page]{\ifx#1\@empty\else{#1}\nobreakspace\fi\pageref{#2}} 132 150 133 % adjust listings macros151 % CFA based on ANSI C 134 152 \lstdefinelanguage{CFA}[ANSI]{C}% 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,},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,}, 138 156 }% 139 157 … … 141 159 language=CFA, 142 160 columns=flexible, 143 basicstyle=\sf\ small,161 basicstyle=\sf\relsize{-1}, 144 162 tabsize=4, 145 163 xleftmargin=\parindent, 146 164 escapechar=@, 147 165 keepspaces=true, 148 %showtabs=true,149 %tab=\rightarrowfill,166 showstringspaces=false, 167 showlines=true, 150 168 }% 151 169 … … 174 192 175 193 \title{\Huge 176 \CFA (\CF AA) Reference Manual and Rationale194 \CFA (\CFL) Reference Manual and Rationale 177 195 }% title 178 196 \author{\huge … … 280 298 An instantiation of the generic type is written by specifying the type parameters in parentheses after the name of the generic type generator: 281 299 \begin{lstlisting} 282 forall( type T | sumable( T ) ) struct pair {300 forall( otype T | sumable( T ) ) struct pair { 283 301 T x; 284 302 T y; … … 292 310 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: 293 311 \begin{lstlisting} 294 forall( type T ) void swap( pair(T) *p ) {312 forall( otype T ) void swap( pair(T) *p ) { 295 313 T z = p->x; 296 314 p->x = p->y; … … 302 320 \subsubsection{Constraints} 303 321 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. 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. 305 324 306 325 \examples 307 326 \begin{lstlisting} 308 forall( type T ) struct A;309 310 forall( type T ) struct B {327 forall( otype T ) struct A; 328 329 forall( otype T ) struct B { 311 330 A(T) *a; // legal, but cannot instantiate B(T) 312 331 }; … … 314 333 B(T) x; // illegal, *x.a is of an incomplete generic type 315 334 316 forall( type T ) struct A {335 forall( otype T ) struct A { 317 336 B( T ) *b; 318 337 }; … … 321 340 322 341 // box.h: 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 );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 ); 326 345 327 346 // main.c: … … 410 429 411 430 \subsubsection{Specialization} 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}. 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}. 414 432 Any value that is legal for the inferred parameter may be used, including other inferred parameters. 415 433 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.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. 418 436 419 437 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. … … 422 440 The type 423 441 \begin{lstlisting} 424 forall( type T,type U ) void (*)( T, U );442 forall( otype T, otype U ) void (*)( T, U ); 425 443 \end{lstlisting} 426 444 can be specialized to (among other things) 427 445 \begin{lstlisting} 428 forall( type T ) void (*)( T, T ); // U bound to T429 forall( type T ) void (*)( T, real ); // U bound to real430 forall( type U ) void (*)( real, U ); // T bound to real446 forall( otype T ) void (*)( T, T ); // U bound to T 447 forall( otype T ) void (*)( T, real ); // U bound to real 448 forall( otype U ) void (*)( real, U ); // T bound to real 431 449 void f( real, real ); // both bound to real 432 450 \end{lstlisting} … … 434 452 The type 435 453 \begin{lstlisting} 436 forall( type T | T ?+?( T, T ) ) T (*)( T );454 forall( otype T | T ?+?( T, T ) ) T (*)( T ); 437 455 \end{lstlisting} 438 456 can be specialized to (among other things) … … 494 512 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: 495 513 \lstinline$unsigned short$ to \lstinline$int$ to \lstinline$unsigned$. 496 Otherwise, 497 \lstinline$unsigned short$ is converted directly to \lstinline$unsigned$, and the cost is 1. 514 Otherwise, \lstinline$unsigned short$ is converted directly to \lstinline$unsigned$, and the cost is 1. 498 515 499 516 \item … … 508 525 \rhs \lstinline$forall$ 509 526 \rhs \lstinline$lvalue$ 510 \rhs \lstinline$ context$527 \rhs \lstinline$trait$ 511 528 \rhs \lstinline$dtype$ 512 529 \rhs \lstinline$ftype$ … … 539 556 A \nonterm{constant-expression} that evaluates to 0 is effectively compatible with every pointer type. 540 557 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. 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. 543 559 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. 544 560 Defining special constants for a user-defined type is more efficient than defining a conversion to the type from \lstinline$_Bool$. … … 836 852 \predefined 837 853 \begin{lstlisting} 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 );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 ); 854 870 \end{lstlisting} 855 871 \semantics … … 914 930 \begin{rationale} 915 931 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}. 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$.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$. 917 933 918 934 \CFA\index{deficiencies!generalizability} does not fully possess this property, because … … 928 944 f = g( d, f ); // (3) (unsafe conversion to float) 929 945 \end{lstlisting} 930 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 to946 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 to 931 947 \lstinline$double$, and the result would be a \lstinline$double$. 932 948 933 949 Another example is the function ``\lstinline$void h( int *);$''. 934 950 This function can be passed a 935 \lstinline$void *$ argument, but the generalization ``\lstinline$forall( type T ) void h( T *);$'' can not.951 \lstinline$void *$ argument, but the generalization ``\lstinline$forall( otype T ) void h( T *);$'' can not. 936 952 In this case, \lstinline$void$ is not a valid value for \lstinline$T$ because it is not an object type. 937 953 If unsafe conversions were allowed, \lstinline$T$ could be inferred to be \emph{any} object type, which is undesirable. … … 941 957 A function called ``\lstinline$?()$'' might be part of a numerical differentiation package. 942 958 \begin{lstlisting} 943 extern type Derivative;959 extern otype Derivative; 944 960 extern double ?()( Derivative, double ); 945 961 extern Derivative derivative_of( double (*f)( double ) ); … … 962 978 963 979 \begin{lstlisting} 964 forall( type T ) T h( T );980 forall( otype T ) T h( T ); 965 981 double d = h( 1.5 ); 966 982 \end{lstlisting} … … 969 985 970 986 \begin{lstlisting} 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)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) 974 990 void g( long, long ); // (7) 975 991 double d; … … 991 1007 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. 992 1008 \begin{lstlisting} 993 forall( type T ) T min( T, T );1009 forall( otype T ) T min( T, T ); 994 1010 double max( double, double ); 995 context min_max( T ) {@\impl{min_max}@1011 trait min_max( T ) {@\impl{min_max}@ 996 1012 T min( T, T ); 997 1013 T max( T, T ); 998 1014 } 999 forall( type U | min_max( U ) ) void shuffle( U, U );1015 forall( otype U | min_max( U ) ) void shuffle( U, U ); 1000 1016 shuffle( 9, 10 ); 1001 1017 \end{lstlisting} … … 1047 1063 long double ?++( volatile long double * ), ?++( _Atomic volatile long double * ); 1048 1064 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 * ),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 * ), 1055 1071 * ?++( _Atomic const T * _Atomic restrict volatile * ); 1056 forall( type T ) _Atomic restrict T * ?++( _Atomic restrict T * restrict volatile * ),1072 forall( otype T ) _Atomic restrict T * ?++( _Atomic restrict T * restrict volatile * ), 1057 1073 * ?++( _Atomic restrict T * _Atomic restrict volatile * ); 1058 forall( type T ) _Atomic volatile T * ?++( _Atomic volatile T * restrict volatile * ),1074 forall( otype T ) _Atomic volatile T * ?++( _Atomic volatile T * restrict volatile * ), 1059 1075 * ?++( _Atomic volatile T * _Atomic restrict volatile * ); 1060 forall( type T ) const restrict T * ?++( const restrict T * restrict volatile * ),1076 forall( otype T ) const restrict T * ?++( const restrict T * restrict volatile * ), 1061 1077 * ?++( const restrict T * _Atomic restrict volatile * ); 1062 forall( type T ) const volatile T * ?++( const volatile T * restrict volatile * ),1078 forall( otype T ) const volatile T * ?++( const volatile T * restrict volatile * ), 1063 1079 * ?++( const volatile T * _Atomic restrict volatile * ); 1064 forall( type T ) restrict volatile T * ?++( restrict volatile T * restrict volatile * ),1080 forall( otype T ) restrict volatile T * ?++( restrict volatile T * restrict volatile * ), 1065 1081 * ?++( restrict volatile T * _Atomic restrict volatile * ); 1066 forall( type T ) _Atomic const restrict T * ?++( _Atomic const restrict T * restrict volatile * ),1082 forall( otype T ) _Atomic const restrict T * ?++( _Atomic const restrict T * restrict volatile * ), 1067 1083 * ?++( _Atomic const restrict T * _Atomic restrict volatile * ); 1068 forall( type T ) _Atomic const volatile T * ?++( _Atomic const volatile T * restrict volatile * ),1084 forall( otype T ) _Atomic const volatile T * ?++( _Atomic const volatile T * restrict volatile * ), 1069 1085 * ?++( _Atomic const volatile T * _Atomic restrict volatile * ); 1070 forall( type T ) _Atomic restrict volatile T * ?++( _Atomic restrict volatile T * restrict volatile * ),1086 forall( otype T ) _Atomic restrict volatile T * ?++( _Atomic restrict volatile T * restrict volatile * ), 1071 1087 * ?++( _Atomic restrict volatile T * _Atomic restrict volatile * ); 1072 forall( type T ) const restrict volatile T * ?++( const restrict volatile T * restrict volatile * ),1088 forall( otype T ) const restrict volatile T * ?++( const restrict volatile T * restrict volatile * ), 1073 1089 * ?++( const restrict volatile T * _Atomic restrict volatile * ); 1074 forall( type T ) _Atomic const restrict volatile T * ?++( _Atomic const restrict volatile T * restrict volatile * ),1090 forall( otype T ) _Atomic const restrict volatile T * ?++( _Atomic const restrict volatile T * restrict volatile * ), 1075 1091 * ?++( _Atomic const restrict volatile T * _Atomic restrict volatile * ); 1076 1092 … … 1091 1107 long double ?--( volatile long double * ), ?--( _Atomic volatile long double * ); 1092 1108 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 * ),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 * ), 1099 1115 * ?--( _Atomic const T * _Atomic restrict volatile * ); 1100 forall( type T ) _Atomic restrict T * ?--( _Atomic restrict T * restrict volatile * ),1116 forall( otype T ) _Atomic restrict T * ?--( _Atomic restrict T * restrict volatile * ), 1101 1117 * ?--( _Atomic restrict T * _Atomic restrict volatile * ); 1102 forall( type T ) _Atomic volatile T * ?--( _Atomic volatile T * restrict volatile * ),1118 forall( otype T ) _Atomic volatile T * ?--( _Atomic volatile T * restrict volatile * ), 1103 1119 * ?--( _Atomic volatile T * _Atomic restrict volatile * ); 1104 forall( type T ) const restrict T * ?--( const restrict T * restrict volatile * ),1120 forall( otype T ) const restrict T * ?--( const restrict T * restrict volatile * ), 1105 1121 * ?--( const restrict T * _Atomic restrict volatile * ); 1106 forall( type T ) const volatile T * ?--( const volatile T * restrict volatile * ),1122 forall( otype T ) const volatile T * ?--( const volatile T * restrict volatile * ), 1107 1123 * ?--( const volatile T * _Atomic restrict volatile * ); 1108 forall( type T ) restrict volatile T * ?--( restrict volatile T * restrict volatile * ),1124 forall( otype T ) restrict volatile T * ?--( restrict volatile T * restrict volatile * ), 1109 1125 * ?--( restrict volatile T * _Atomic restrict volatile * ); 1110 forall( type T ) _Atomic const restrict T * ?--( _Atomic const restrict T * restrict volatile * ),1126 forall( otype T ) _Atomic const restrict T * ?--( _Atomic const restrict T * restrict volatile * ), 1111 1127 * ?--( _Atomic const restrict T * _Atomic restrict volatile * ); 1112 forall( type T ) _Atomic const volatile T * ?--( _Atomic const volatile T * restrict volatile * ),1128 forall( otype T ) _Atomic const volatile T * ?--( _Atomic const volatile T * restrict volatile * ), 1113 1129 * ?--( _Atomic const volatile T * _Atomic restrict volatile * ); 1114 forall( type T ) _Atomic restrict volatile T * ?--( _Atomic restrict volatile T * restrict volatile * ),1130 forall( otype T ) _Atomic restrict volatile T * ?--( _Atomic restrict volatile T * restrict volatile * ), 1115 1131 * ?--( _Atomic restrict volatile T * _Atomic restrict volatile * ); 1116 forall( type T ) const restrict volatile T * ?--( const restrict volatile T * restrict volatile * ),1132 forall( otype T ) const restrict volatile T * ?--( const restrict volatile T * restrict volatile * ), 1117 1133 * ?--( const restrict volatile T * _Atomic restrict volatile * ); 1118 forall( type T ) _Atomic const restrict volatile T * ?--( _Atomic const restrict volatile T * restrict volatile * ),1134 forall( otype T ) _Atomic const restrict volatile T * ?--( _Atomic const restrict volatile T * restrict volatile * ), 1119 1135 * ?--( _Atomic const restrict volatile T * _Atomic restrict volatile * ); 1120 1136 \end{lstlisting} … … 1195 1211 The expression would be valid if \lstinline$?++$ were declared by 1196 1212 \begin{lstlisting} 1197 forall( type T ) T * ?++( T * * );1213 forall( otype T ) T * ?++( T * * ); 1198 1214 \end{lstlisting} with \lstinline$T$ inferred to be \lstinline$char$. 1199 1215 … … 1203 1219 Hence the actual predefined function is 1204 1220 \begin{lstlisting} 1205 forall( type T ) T * ?++( T * restrict volatile * );1221 forall( otype T ) T * ?++( T * restrict volatile * ); 1206 1222 \end{lstlisting} which also accepts a \lstinline$char * *$ argument, because of the safe conversions that add 1207 1223 \lstinline$volatile$ and \lstinline$restrict$ qualifiers. (The parameter is not const-qualified, so constant pointers cannot be incremented.) … … 1217 1233 \lstinline$char const volatile *$, so a new overloading is needed: 1218 1234 \begin{lstlisting} 1219 forall( type T ) T const volatile * ?++( T const volatile *restrict volatile * );1235 forall( otype T ) T const volatile * ?++( T const volatile *restrict volatile * ); 1220 1236 \end{lstlisting} 1221 1237 One overloading is needed for each combination of qualifiers in the pointed-at type\index{deficiencies!pointers to qualified types}. … … 1225 1241 The \lstinline$restrict$ qualifier is handled just like \lstinline$const$ and \lstinline$volatile$ in the previous case: 1226 1242 \begin{lstlisting} 1227 forall( type T ) T restrict * ?++( T restrict *restrict volatile * );1243 forall( otype T ) T restrict * ?++( T restrict *restrict volatile * ); 1228 1244 \end{lstlisting} with \lstinline$T$ inferred to be \lstinline$float *$. 1229 1245 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. … … 1283 1299 long double ++?( volatile long double * ), ++?( _Atomic volatile long double * ); 1284 1300 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 * ),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 * ), 1291 1307 * ++?( _Atomic const T * _Atomic restrict volatile * ); 1292 forall( type T ) _Atomic volatile T * ++?( _Atomic volatile T * restrict volatile * ),1308 forall( otype T ) _Atomic volatile T * ++?( _Atomic volatile T * restrict volatile * ), 1293 1309 * ++?( _Atomic volatile T * _Atomic restrict volatile * ); 1294 forall( type T ) _Atomic restrict T * ++?( _Atomic restrict T * restrict volatile * ),1310 forall( otype T ) _Atomic restrict T * ++?( _Atomic restrict T * restrict volatile * ), 1295 1311 * ++?( _Atomic restrict T * _Atomic restrict volatile * ); 1296 forall( type T ) const volatile T * ++?( const volatile T * restrict volatile * ),1312 forall( otype T ) const volatile T * ++?( const volatile T * restrict volatile * ), 1297 1313 * ++?( const volatile T * _Atomic restrict volatile * ); 1298 forall( type T ) const restrict T * ++?( const restrict T * restrict volatile * ),1314 forall( otype T ) const restrict T * ++?( const restrict T * restrict volatile * ), 1299 1315 * ++?( const restrict T * _Atomic restrict volatile * ); 1300 forall( type T ) restrict volatile T * ++?( restrict volatile T * restrict volatile * ),1316 forall( otype T ) restrict volatile T * ++?( restrict volatile T * restrict volatile * ), 1301 1317 * ++?( restrict volatile T * _Atomic restrict volatile * ); 1302 forall( type T ) _Atomic const volatile T * ++?( _Atomic const volatile T * restrict volatile * ),1318 forall( otype T ) _Atomic const volatile T * ++?( _Atomic const volatile T * restrict volatile * ), 1303 1319 * ++?( _Atomic const volatile T * _Atomic restrict volatile * ); 1304 forall( type T ) _Atomic const restrict T * ++?( _Atomic const restrict T * restrict volatile * ),1320 forall( otype T ) _Atomic const restrict T * ++?( _Atomic const restrict T * restrict volatile * ), 1305 1321 * ++?( _Atomic const restrict T * _Atomic restrict volatile * ); 1306 forall( type T ) _Atomic restrict volatile T * ++?( _Atomic restrict volatile T * restrict volatile * ),1322 forall( otype T ) _Atomic restrict volatile T * ++?( _Atomic restrict volatile T * restrict volatile * ), 1307 1323 * ++?( _Atomic restrict volatile T * _Atomic restrict volatile * ); 1308 forall( type T ) const restrict volatile T * ++?( const restrict volatile T * restrict volatile * ),1324 forall( otype T ) const restrict volatile T * ++?( const restrict volatile T * restrict volatile * ), 1309 1325 * ++?( const restrict volatile T * _Atomic restrict volatile * ); 1310 forall( type T ) _Atomic const restrict volatile T * ++?( _Atomic const restrict volatile T * restrict volatile * ),1326 forall( otype T ) _Atomic const restrict volatile T * ++?( _Atomic const restrict volatile T * restrict volatile * ), 1311 1327 * ++?( _Atomic const restrict volatile T * _Atomic restrict volatile * ); 1312 1328 … … 1327 1343 long double --?( volatile long double * ), --?( _Atomic volatile long double * ); 1328 1344 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 * ),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 * ), 1335 1351 * --?( _Atomic const T * _Atomic restrict volatile * ); 1336 forall( type T ) _Atomic volatile T * --?( _Atomic volatile T * restrict volatile * ),1352 forall( otype T ) _Atomic volatile T * --?( _Atomic volatile T * restrict volatile * ), 1337 1353 * --?( _Atomic volatile T * _Atomic restrict volatile * ); 1338 forall( type T ) _Atomic restrict T * --?( _Atomic restrict T * restrict volatile * ),1354 forall( otype T ) _Atomic restrict T * --?( _Atomic restrict T * restrict volatile * ), 1339 1355 * --?( _Atomic restrict T * _Atomic restrict volatile * ); 1340 forall( type T ) const volatile T * --?( const volatile T * restrict volatile * ),1356 forall( otype T ) const volatile T * --?( const volatile T * restrict volatile * ), 1341 1357 * --?( const volatile T * _Atomic restrict volatile * ); 1342 forall( type T ) const restrict T * --?( const restrict T * restrict volatile * ),1358 forall( otype T ) const restrict T * --?( const restrict T * restrict volatile * ), 1343 1359 * --?( const restrict T * _Atomic restrict volatile * ); 1344 forall( type T ) restrict volatile T * --?( restrict volatile T * restrict volatile * ),1360 forall( otype T ) restrict volatile T * --?( restrict volatile T * restrict volatile * ), 1345 1361 * --?( restrict volatile T * _Atomic restrict volatile * ); 1346 forall( type T ) _Atomic const volatile T * --?( _Atomic const volatile T * restrict volatile * ),1362 forall( otype T ) _Atomic const volatile T * --?( _Atomic const volatile T * restrict volatile * ), 1347 1363 * --?( _Atomic const volatile T * _Atomic restrict volatile * ); 1348 forall( type T ) _Atomic const restrict T * --?( _Atomic const restrict T * restrict volatile * ),1364 forall( otype T ) _Atomic const restrict T * --?( _Atomic const restrict T * restrict volatile * ), 1349 1365 * --?( _Atomic const restrict T * _Atomic restrict volatile * ); 1350 forall( type T ) _Atomic restrict volatile T * --?( _Atomic restrict volatile T * restrict volatile * ),1366 forall( otype T ) _Atomic restrict volatile T * --?( _Atomic restrict volatile T * restrict volatile * ), 1351 1367 * --?( _Atomic restrict volatile T * _Atomic restrict volatile * ); 1352 forall( type T ) const restrict volatile T * --?( const restrict volatile T * restrict volatile * ),1368 forall( otype T ) const restrict volatile T * --?( const restrict volatile T * restrict volatile * ), 1353 1369 * --?( const restrict volatile T * _Atomic restrict volatile * ); 1354 forall( type T ) _Atomic const restrict volatile T * --?( _Atomic const restrict volatile T * restrict volatile * ),1370 forall( otype T ) _Atomic const restrict volatile T * --?( _Atomic const restrict volatile T * restrict volatile * ), 1355 1371 * --?( _Atomic const restrict volatile T * _Atomic restrict volatile * ); 1356 1372 \end{lstlisting} … … 1380 1396 \predefined 1381 1397 \begin{lstlisting} 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 * );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 * ); 1398 1414 forall( ftype FT ) FT *?( FT * ); 1399 1415 \end{lstlisting} … … 1510 1526 \begin{rationale} 1511 1527 \begin{lstlisting} 1512 type Pair = struct { int first, second; };1528 otype Pair = struct { int first, second; }; 1513 1529 size_t p_size = sizeof(Pair); // constant expression 1514 extern type Rational;@\use{Rational}@1530 extern otype Rational;@\use{Rational}@ 1515 1531 size_t c_size = sizeof(Rational); // non-constant expression 1516 1532 forall(type T) T f(T p1, T p2) { … … 1636 1652 Consider 1637 1653 \begin{lstlisting} 1638 forall( type T | T ?*?( T, T ) ) T square( T );1654 forall( otype T | T ?*?( T, T ) ) T square( T ); 1639 1655 short s; 1640 1656 square( s ); … … 1647 1663 A more troubling example is 1648 1664 \begin{lstlisting} 1649 forall( type T | ?*?( T, T ) ) T product( T[], int n );1665 forall( otype T | ?*?( T, T ) ) T product( T[], int n ); 1650 1666 short sa[5]; 1651 1667 product( sa, 5); … … 1704 1720 ?+?( _Complex long double, _Complex long double ), ?-?( _Complex long double, _Complex long double ); 1705 1721 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 * ),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 * ), 1708 1724 * ?-?( _Atomic T *, ptrdiff_t ); 1709 forall( type T ) const T * ?+?( const T *, ptrdiff_t ), * ?+?( ptrdiff_t, const T * ),1725 forall( otype T ) const T * ?+?( const T *, ptrdiff_t ), * ?+?( ptrdiff_t, const T * ), 1710 1726 * ?-?( const T *, ptrdiff_t ); 1711 forall( type T ) restrict T * ?+?( restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, restrict T * ),1727 forall( otype T ) restrict T * ?+?( restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, restrict T * ), 1712 1728 * ?-?( restrict T *, ptrdiff_t ); 1713 forall( type T ) volatile T * ?+?( volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, volatile T * ),1729 forall( otype T ) volatile T * ?+?( volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, volatile T * ), 1714 1730 * ?-?( volatile T *, ptrdiff_t ); 1715 forall( type T ) _Atomic const T * ?+?( _Atomic const T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic const T * ),1731 forall( otype T ) _Atomic const T * ?+?( _Atomic const T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic const T * ), 1716 1732 * ?-?( _Atomic const T *, ptrdiff_t ); 1717 forall( type T ) _Atomic restrict T * ?+?( _Atomic restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic restrict T * ),1733 forall( otype T ) _Atomic restrict T * ?+?( _Atomic restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic restrict T * ), 1718 1734 * ?-?( _Atomic restrict T *, ptrdiff_t ); 1719 forall( type T ) _Atomic volatile T * ?+?( _Atomic volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic volatile T * ),1735 forall( otype T ) _Atomic volatile T * ?+?( _Atomic volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic volatile T * ), 1720 1736 * ?-?( _Atomic volatile T *, ptrdiff_t ); 1721 forall( type T ) const restrict T * ?+?( const restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, const restrict T * ),1737 forall( otype T ) const restrict T * ?+?( const restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, const restrict T * ), 1722 1738 * ?-?( const restrict T *, ptrdiff_t ); 1723 forall( type T ) const volatile T * ?+?( const volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, const volatile T * ),1739 forall( otype T ) const volatile T * ?+?( const volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, const volatile T * ), 1724 1740 * ?-?( const volatile T *, ptrdiff_t ); 1725 forall( type T ) restrict volatile T * ?+?( restrict volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, restrict volatile T * ),1741 forall( otype T ) restrict volatile T * ?+?( restrict volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, restrict volatile T * ), 1726 1742 * ?-?( restrict volatile T *, ptrdiff_t ); 1727 forall( type T ) _Atomic const restrict T * ?+?( _Atomic const restrict T *, ptrdiff_t ),1743 forall( otype T ) _Atomic const restrict T * ?+?( _Atomic const restrict T *, ptrdiff_t ), 1728 1744 * ?+?( ptrdiff_t, _Atomic const restrict T * ), 1729 1745 * ?-?( _Atomic const restrict T *, ptrdiff_t ); 1730 forall( type T ) ptrdiff_t1746 forall( otype T ) ptrdiff_t 1731 1747 * ?-?( const restrict volatile T *, const restrict volatile T * ), 1732 1748 * ?-?( _Atomic const restrict volatile T *, _Atomic const restrict volatile T * ); … … 2052 2068 2053 2069 \begin{lstlisting} 2054 extern type Rational;@\use{Rational}@2070 extern otype Rational;@\use{Rational}@ 2055 2071 extern const Rational 0;@\use{0}@ 2056 2072 extern int ?!=?( Rational, Rational ); … … 2095 2111 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 2096 2112 \begin{lstlisting} 2097 forall( type T ) T cond( int, T, T );2113 forall( otype T ) T cond( int, T, T ); 2098 2114 forall( dtype D ) void * cond( int, D *, void * ), * cond( int, void *, D * ); 2099 2115 forall( dtype D ) _atomic void * cond( … … 2455 2471 \predefined 2456 2472 \begin{lstlisting} 2457 forall( type T ) T2473 forall( otype T ) T 2458 2474 * ?+=?( T * restrict volatile *, ptrdiff_t ), 2459 2475 * ?-=?( T * restrict volatile *, ptrdiff_t ), 2460 2476 * ?+=?( T * _Atomic restrict volatile *, ptrdiff_t ), 2461 2477 * ?-=?( T * _Atomic restrict volatile *, ptrdiff_t ); 2462 forall( type T ) T _Atomic2478 forall( otype T ) T _Atomic 2463 2479 * ?+=?( T _Atomic * restrict volatile *, ptrdiff_t ), 2464 2480 * ?-=?( T _Atomic * restrict volatile *, ptrdiff_t ), 2465 2481 * ?+=?( T _Atomic * _Atomic restrict volatile *, ptrdiff_t ), 2466 2482 * ?-=?( T _Atomic * _Atomic restrict volatile *, ptrdiff_t ); 2467 forall( type T ) T const2483 forall( otype T ) T const 2468 2484 * ?+=?( T const * restrict volatile *, ptrdiff_t ), 2469 2485 * ?-=?( T const * restrict volatile *, ptrdiff_t ), 2470 2486 * ?+=?( T const * _Atomic restrict volatile *, ptrdiff_t ), 2471 2487 * ?-=?( T const * _Atomic restrict volatile *, ptrdiff_t ); 2472 forall( type T ) T restrict2488 forall( otype T ) T restrict 2473 2489 * ?+=?( T restrict * restrict volatile *, ptrdiff_t ), 2474 2490 * ?-=?( T restrict * restrict volatile *, ptrdiff_t ), 2475 2491 * ?+=?( T restrict * _Atomic restrict volatile *, ptrdiff_t ), 2476 2492 * ?-=?( T restrict * _Atomic restrict volatile *, ptrdiff_t ); 2477 forall( type T ) T volatile2493 forall( otype T ) T volatile 2478 2494 * ?+=?( T volatile * restrict volatile *, ptrdiff_t ), 2479 2495 * ?-=?( T volatile * restrict volatile *, ptrdiff_t ), 2480 2496 * ?+=?( T volatile * _Atomic restrict volatile *, ptrdiff_t ), 2481 2497 * ?-=?( T volatile * _Atomic restrict volatile *, ptrdiff_t ); 2482 forall( type T ) T _Atomic const2498 forall( otype T ) T _Atomic const 2483 2499 * ?+=?( T _Atomic const restrict volatile *, ptrdiff_t ), 2484 2500 * ?-=?( T _Atomic const restrict volatile *, ptrdiff_t ), 2485 2501 * ?+=?( T _Atomic const _Atomic restrict volatile *, ptrdiff_t ), 2486 2502 * ?-=?( T _Atomic const _Atomic restrict volatile *, ptrdiff_t ); 2487 forall( type T ) T _Atomic restrict2503 forall( otype T ) T _Atomic restrict 2488 2504 * ?+=?( T _Atomic restrict * restrict volatile *, ptrdiff_t ), 2489 2505 * ?-=?( T _Atomic restrict * restrict volatile *, ptrdiff_t ), 2490 2506 * ?+=?( T _Atomic restrict * _Atomic restrict volatile *, ptrdiff_t ), 2491 2507 * ?-=?( T _Atomic restrict * _Atomic restrict volatile *, ptrdiff_t ); 2492 forall( type T ) T _Atomic volatile2508 forall( otype T ) T _Atomic volatile 2493 2509 * ?+=?( T _Atomic volatile * restrict volatile *, ptrdiff_t ), 2494 2510 * ?-=?( T _Atomic volatile * restrict volatile *, ptrdiff_t ), 2495 2511 * ?+=?( T _Atomic volatile * _Atomic restrict volatile *, ptrdiff_t ), 2496 2512 * ?-=?( T _Atomic volatile * _Atomic restrict volatile *, ptrdiff_t ); 2497 forall( type T ) T const restrict2513 forall( otype T ) T const restrict 2498 2514 * ?+=?( T const restrict * restrict volatile *, ptrdiff_t ), 2499 2515 * ?-=?( T const restrict * restrict volatile *, ptrdiff_t ), 2500 2516 * ?+=?( T const restrict * _Atomic restrict volatile *, ptrdiff_t ), 2501 2517 * ?-=?( T const restrict * _Atomic restrict volatile *, ptrdiff_t ); 2502 forall( type T ) T const volatile2518 forall( otype T ) T const volatile 2503 2519 * ?+=?( T const volatile * restrict volatile *, ptrdiff_t ), 2504 2520 * ?-=?( T const volatile * restrict volatile *, ptrdiff_t ), 2505 2521 * ?+=?( T const volatile * _Atomic restrict volatile *, ptrdiff_t ), 2506 2522 * ?-=?( T const volatile * _Atomic restrict volatile *, ptrdiff_t ); 2507 forall( type T ) T restrict volatile2523 forall( otype T ) T restrict volatile 2508 2524 * ?+=?( T restrict volatile * restrict volatile *, ptrdiff_t ), 2509 2525 * ?-=?( T restrict volatile * restrict volatile *, ptrdiff_t ), 2510 2526 * ?+=?( T restrict volatile * _Atomic restrict volatile *, ptrdiff_t ), 2511 2527 * ?-=?( T restrict volatile * _Atomic restrict volatile *, ptrdiff_t ); 2512 forall( type T ) T _Atomic const restrict2528 forall( otype T ) T _Atomic const restrict 2513 2529 * ?+=?( T _Atomic const restrict * restrict volatile *, ptrdiff_t ), 2514 2530 * ?-=?( T _Atomic const restrict * restrict volatile *, ptrdiff_t ), 2515 2531 * ?+=?( T _Atomic const restrict * _Atomic restrict volatile *, ptrdiff_t ), 2516 2532 * ?-=?( T _Atomic const restrict * _Atomic restrict volatile *, ptrdiff_t ); 2517 forall( type T ) T _Atomic const volatile2533 forall( otype T ) T _Atomic const volatile 2518 2534 * ?+=?( T _Atomic const volatile * restrict volatile *, ptrdiff_t ), 2519 2535 * ?-=?( T _Atomic const volatile * restrict volatile *, ptrdiff_t ), 2520 2536 * ?+=?( T _Atomic const volatile * _Atomic restrict volatile *, ptrdiff_t ), 2521 2537 * ?-=?( T _Atomic const volatile * _Atomic restrict volatile *, ptrdiff_t ); 2522 forall( type T ) T _Atomic restrict volatile2538 forall( otype T ) T _Atomic restrict volatile 2523 2539 * ?+=?( T _Atomic restrict volatile * restrict volatile *, ptrdiff_t ), 2524 2540 * ?-=?( T _Atomic restrict volatile * restrict volatile *, ptrdiff_t ), 2525 2541 * ?+=?( T _Atomic restrict volatile * _Atomic restrict volatile *, ptrdiff_t ), 2526 2542 * ?-=?( T _Atomic restrict volatile * _Atomic restrict volatile *, ptrdiff_t ); 2527 forall( type T ) T const restrict volatile2543 forall( otype T ) T const restrict volatile 2528 2544 * ?+=?( T const restrict volatile * restrict volatile *, ptrdiff_t ), 2529 2545 * ?-=?( T const restrict volatile * restrict volatile *, ptrdiff_t ), 2530 2546 * ?+=?( T const restrict volatile * _Atomic restrict volatile *, ptrdiff_t ), 2531 2547 * ?-=?( T const restrict volatile * _Atomic restrict volatile *, ptrdiff_t ); 2532 forall( type T ) T _Atomic const restrict volatile2548 forall( otype T ) T _Atomic const restrict volatile 2533 2549 * ?+=?( T _Atomic const restrict volatile * restrict volatile *, ptrdiff_t ), 2534 2550 * ?-=?( T _Atomic const restrict volatile * restrict volatile *, ptrdiff_t ), … … 2842 2858 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. 2843 2859 \begin{lstlisting} 2844 forall( type T ) struct Pair { T a, b;2860 forall( otype T ) struct Pair { T a, b; 2845 2861 } mkPair( T, T ); // illegal 2846 2862 \end{lstlisting} … … 2867 2883 If this restriction were lifted, it would be possible to write 2868 2884 \begin{lstlisting} 2869 forall( type T ) T * alloc( void );@\use{alloc}@ int *p = alloc();2885 forall( otype T ) T * alloc( void );@\use{alloc}@ int *p = alloc(); 2870 2886 \end{lstlisting} 2871 2887 Here \lstinline$alloc()$ would receive \lstinline$int$ as an inferred argument, and return an … … 2876 2892 \lstinline$T$: 2877 2893 \begin{lstlisting} 2878 forall( type T ) T * alloc( T initial_value );@\use{alloc}@2894 forall( otype T ) T * alloc( T initial_value );@\use{alloc}@ 2879 2895 \end{lstlisting} 2880 2896 \end{rationale} … … 2899 2915 \begin{lstlisting} 2900 2916 int fi( int ); 2901 forall( type T ) T fT( T );2917 forall( otype T ) T fT( T ); 2902 2918 \end{lstlisting} 2903 2919 \lstinline$fi()$ takes an \lstinline$int$ and returns an \lstinline$int$. \lstinline$fT()$ takes a … … 2905 2921 \begin{lstlisting} 2906 2922 int (*pfi )( int ) = fi; 2907 forall( type T ) T (*pfT )( T ) = fT;2923 forall( otype T ) T (*pfT )( T ) = fT; 2908 2924 \end{lstlisting} 2909 2925 \lstinline$pfi$ and \lstinline$pfT$ are pointers to functions. \lstinline$pfT$ is not polymorphic, but the function it points at is. … … 2912 2928 return pfi; 2913 2929 } 2914 forall( type T ) T (*fvpfT( void ))( T ) {2930 forall( otype T ) T (*fvpfT( void ))( T ) { 2915 2931 return pfT; 2916 2932 } … … 2918 2934 \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. 2919 2935 \begin{lstlisting} 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 );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 ); 2923 2939 \end{lstlisting} 2924 2940 \lstinline$fTpfi()$ is a polymorphic function that returns a pointer to a monomorphic function taking an integer and returning an integer. … … 2930 2946 \lstinline$char *$. 2931 2947 \begin{lstlisting} 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 );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 ); 2934 2950 \end{lstlisting} 2935 2951 The functions \lstinline$f()$ and \lstinline$g()$ have compatible types. … … 2939 2955 Replacing every \(f_i\) by \(g_i\) in \(f\) gives 2940 2956 \begin{lstlisting} 2941 forall( type V, type U,type W ) U * f( V *, U, W * const );2957 forall( otype V, otype U, otype W ) U * f( V *, U, W * const ); 2942 2958 \end{lstlisting} which has a return type and parameter list that is compatible with \(g\). 2943 2959 \begin{rationale} … … 3127 3143 \examples 3128 3144 \begin{lstlisting} 3129 forall( type T | T ?*?( T, T ))@\use{?*?}@3145 forall( otype T | T ?*?( T, T ))@\use{?*?}@ 3130 3146 T square( T val ) {@\impl{square}@ 3131 3147 return val + val; 3132 3148 } 3133 context summable(type T ) {@\impl{summable}@3149 trait summable( otype T ) {@\impl{summable}@ 3134 3150 T ?+=?( T *, T );@\use{?+=?}@ 3135 3151 const T 0;@\use{0}@ 3136 3152 }; 3137 context list_of( type List,type Element ) {@\impl{list_of}@3153 trait list_of( otype List, otype Element ) {@\impl{list_of}@ 3138 3154 Element car( List ); 3139 3155 List cdr( List ); … … 3142 3158 int is_nil( List ); 3143 3159 }; 3144 context sum_list( type List,type Element | summable( Element ) | list_of( List, Element ) ) {};3160 trait sum_list( otype List, otype Element | summable( Element ) | list_of( List, Element ) ) {}; 3145 3161 \end{lstlisting} 3146 3162 \lstinline$sum_list$ contains seven declarations, which describe a list whose elements can be added up. … … 3204 3220 Incomplete type declarations allow compact mutually-recursive types. 3205 3221 \begin{lstlisting} 3206 type t1; // incomplete type declaration3207 type t2 = struct { t1 * p; ... };3208 type t1 = struct { t2 * p; ... };3222 otype t1; // incomplete type declaration 3223 otype t2 = struct { t1 * p; ... }; 3224 otype t1 = struct { t2 * p; ... }; 3209 3225 \end{lstlisting} 3210 3226 Without them, mutual recursion could be handled by declaring mutually recursive structures, then initializing the types to those structures. 3211 3227 \begin{lstlisting} 3212 3228 struct s1; 3213 type t2 = struct s2 { struct s1 * p; ... };3214 type t1 = struct s1 { struct s2 * p; ... };3229 otype t2 = struct s2 { struct s1 * p; ... }; 3230 otype t1 = struct s1 { struct s2 * p; ... }; 3215 3231 \end{lstlisting} 3216 3232 This introduces extra names, and may force the programmer to cast between the types and their implementations. … … 3267 3283 This prevents the declaration of types that contain each other. 3268 3284 \begin{lstlisting} 3269 type t1;3270 type t2 = t1; // illegal: incomplete type t13271 type t1 = t2;3285 otype t1; 3286 otype t2 = t1; // illegal: incomplete type t1 3287 otype t1 = t2; 3272 3288 \end{lstlisting} 3273 3289 … … 3276 3292 types}. 3277 3293 \begin{lstlisting} 3278 extern type Huge; // extended-precision integer type3279 type Rational = struct {3294 extern otype Huge; // extended-precision integer type 3295 otype Rational = struct { 3280 3296 Huge numerator, denominator; // illegal 3281 3297 }; … … 3316 3332 \begin{lstlisting} 3317 3333 #include <stdlib.h> 3318 T * new( type T ) { return ( T * )malloc( sizeof( T) ); };3334 T * new( otype T ) { return ( T * )malloc( sizeof( T) ); }; 3319 3335 @\ldots@ int * ip = new( int ); 3320 3336 \end{lstlisting} … … 3327 3343 Since type declarations create new types, instances of types are always passed by value. 3328 3344 \begin{lstlisting} 3329 type A1 = int[2];3345 otype A1 = int[2]; 3330 3346 void f1( A1 a ) { a[0] = 0; }; 3331 typedef int A2[2];3347 otypedef int A2[2]; 3332 3348 void f2( A2 a ) { a[0] = 0; }; 3333 3349 A1 v1; … … 3346 3362 That unit might contain the declarations 3347 3363 \begin{lstlisting} 3348 type Complex = struct { float re, im; };@\impl{Complex}@3364 otype Complex = struct { float re, im; };@\impl{Complex}@ 3349 3365 Complex cplx_i = { 0.0, 1.0 };@\impl{cplx_i}@ 3350 3366 float abs( Complex c ) {@\impl{abs( Complex )}@ … … 3355 3371 3356 3372 \begin{lstlisting} 3357 type Time_of_day = int;@\impl{Time_of_day}@ // seconds since midnight.3373 otype Time_of_day = int;@\impl{Time_of_day}@ // seconds since midnight. 3358 3374 Time_of_day ?+?( Time_of_day t1, int seconds ) {@\impl{?+?}@ 3359 3375 return (( int)t1 + seconds ) % 86400; … … 3429 3445 \examples 3430 3446 \begin{lstlisting} 3431 context s(type T ) {3447 trait s( otype T ) { 3432 3448 T a, b; 3433 3449 } struct impl { int left, right; } a = { 0, 0 }; 3434 type Pair | s( Pair ) = struct impl;3450 otype Pair | s( Pair ) = struct impl; 3435 3451 Pair b = { 1, 1 }; 3436 3452 \end{lstlisting} … … 3440 3456 \lstinline$Pair b$ is compulsory because there is no \lstinline$struct impl b$ to construct a value from. 3441 3457 \begin{lstlisting} 3442 context ss(type T ) {3458 trait ss( otype T ) { 3443 3459 T clone( T ); 3444 3460 void munge( T * ); 3445 3461 } 3446 type Whatsit | ss( Whatsit );@\use{Whatsit}@3447 type Doodad | ss( Doodad ) = struct doodad {@\use{Doodad}@3462 otype Whatsit | ss( Whatsit );@\use{Whatsit}@ 3463 otype Doodad | ss( Doodad ) = struct doodad {@\use{Doodad}@ 3448 3464 Whatsit; // anonymous member 3449 3465 int extra; … … 3466 3482 Default functions and objects are subject to the normal scope rules. 3467 3483 \begin{lstlisting} 3468 type T = @\ldots@;3484 otype T = @\ldots@; 3469 3485 T a_T = @\ldots@; // Default assignment used. 3470 3486 T ?=?( T *, T ); … … 3735 3751 The assertion ``\lstinline$scalar( Complex )$'' should be read as ``type \lstinline$Complex$ is scalar''. 3736 3752 \begin{lstlisting} 3737 context scalar(type T ) {@\impl{scalar}@3753 trait scalar( otype T ) {@\impl{scalar}@ 3738 3754 int !?( T ); 3739 3755 int ?<?( T, T ), ?<=?( T, T ), ?==?( T, T ), ?>=?( T, T ), ?>?( T, T ), ?!=?( T, T ); … … 3745 3761 This is equivalent to inheritance of specifications. 3746 3762 \begin{lstlisting} 3747 context arithmetic(type T | scalar( T ) ) {@\impl{arithmetic}@@\use{scalar}@3763 trait arithmetic( otype T | scalar( T ) ) {@\impl{arithmetic}@@\use{scalar}@ 3748 3764 T +?( T ), -?( T ); 3749 3765 T ?*?( T, T ), ?/?( T, T ), ?+?( T, T ), ?-?( T, T ); … … 3754 3770 \define{integral types}. 3755 3771 \begin{lstlisting} 3756 context integral(type T | arithmetic( T ) ) {@\impl{integral}@@\use{arithmetic}@3772 trait integral( otype T | arithmetic( T ) ) {@\impl{integral}@@\use{arithmetic}@ 3757 3773 T ~?( T ); 3758 3774 T ?&?( T, T ), ?|?( T, T ), ?^?( T, T ); … … 3768 3784 The only operation that can be applied to all modifiable lvalues is simple assignment. 3769 3785 \begin{lstlisting} 3770 context m_lvalue(type T ) {@\impl{m_lvalue}@3786 trait m_lvalue( otype T ) {@\impl{m_lvalue}@ 3771 3787 T ?=?( T *, T ); 3772 3788 }; … … 3778 3794 Scalars can also be incremented and decremented. 3779 3795 \begin{lstlisting} 3780 context m_l_scalar(type T | scalar( T ) | m_lvalue( T ) ) {@\impl{m_l_scalar}@3796 trait m_l_scalar( otype T | scalar( T ) | m_lvalue( T ) ) {@\impl{m_l_scalar}@ 3781 3797 T ?++( T * ), ?--( T * );@\use{scalar}@@\use{m_lvalue}@ 3782 3798 T ++?( T * ), --?( T * ); … … 3787 3803 Note that this results in the ``inheritance'' of \lstinline$scalar$ along both paths. 3788 3804 \begin{lstlisting} 3789 context m_l_arithmetic(type T | m_l_scalar( T ) | arithmetic( T ) ) {@\impl{m_l_arithmetic}@3805 trait m_l_arithmetic( otype T | m_l_scalar( T ) | arithmetic( T ) ) {@\impl{m_l_arithmetic}@ 3790 3806 T ?/=?( T *, T ), ?*=?( T *, T );@\use{m_l_scalar}@@\use{arithmetic}@ 3791 3807 T ?+=?( T *, T ), ?-=?( T *, T ); 3792 3808 }; 3793 context m_l_integral(type T | m_l_arithmetic( T ) | integral( T ) ) {@\impl{m_l_integral}@3809 trait m_l_integral( otype T | m_l_arithmetic( T ) | integral( T ) ) {@\impl{m_l_integral}@ 3794 3810 T ?&=?( T *, T ), ?|=?( T *, T ), ?^=?( T *, T );@\use{m_l_arithmetic}@ 3795 3811 T ?%=?( T *, T ), ?<<=?( T *, T ), ?>>=?( T *, T );@\use{integral}@ … … 3811 3827 \lstinline$arithmetic$, so these operators cannot be consolidated in \lstinline$scalar$. 3812 3828 \begin{lstlisting} 3813 context pointer( type P | scalar( P ) ) {@\impl{pointer}@@\use{scalar}@3829 trait pointer( type P | scalar( P ) ) {@\impl{pointer}@@\use{scalar}@ 3814 3830 P ?+?( P, long int ), ?+?( long int, P ), ?-?( P, long int ); 3815 3831 ptrdiff_t ?-?( P, P ); 3816 3832 }; 3817 context m_l_pointer( type P | pointer( P ) | m_l_scalar( P ) ) {@\impl{m_l_pointer}@3833 trait m_l_pointer( type P | pointer( P ) | m_l_scalar( P ) ) {@\impl{m_l_pointer}@ 3818 3834 P ?+=?( P *, long int ), ?-=?( P *, long int ); 3819 3835 P ?=?( P *, void * ); … … 3827 3843 ``\lstinline$Safe_pointer$ acts like a pointer to \lstinline$int$''. 3828 3844 \begin{lstlisting} 3829 context ptr_to( type P | pointer( P ),type T ) {@\impl{ptr_to}@@\use{pointer}@3845 trait ptr_to( type P | pointer( P ), otype T ) {@\impl{ptr_to}@@\use{pointer}@ 3830 3846 lvalue T *?( P ); 3831 3847 lvalue T ?[?]( P, long int ); 3832 3848 }; 3833 context ptr_to_const( type P | pointer( P ),type T ) {@\impl{ptr_to_const}@3849 trait ptr_to_const( type P | pointer( P ), otype T ) {@\impl{ptr_to_const}@ 3834 3850 const lvalue T *?( P ); 3835 3851 const lvalue T ?[?]( P, long int );@\use{pointer}@ 3836 3852 }; 3837 context ptr_to_volatile( type P | pointer( P ),type T ) }@\impl{ptr_to_volatile}@3853 trait ptr_to_volatile( type P | pointer( P ), otype T ) }@\impl{ptr_to_volatile}@ 3838 3854 volatile lvalue T *?( P ); 3839 3855 volatile lvalue T ?[?]( P, long int );@\use{pointer}@ 3840 3856 }; 3841 context ptr_to_const_volatile( type P | pointer( P ),type T ) }@\impl{ptr_to_const_volatile}@3857 trait ptr_to_const_volatile( type P | pointer( P ), otype T ) }@\impl{ptr_to_const_volatile}@ 3842 3858 const volatile lvalue T *?( P );@\use{pointer}@ 3843 3859 const volatile lvalue T ?[?]( P, long int ); … … 3849 3865 ``\lstinline$ptr_to$'' specifications. 3850 3866 \begin{lstlisting} 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}@ {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}@ { 3852 3868 P ?=?( P *, T * ); 3853 3869 T * ?=?( T **, P ); 3854 3870 }; 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}@) {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}@) { 3856 3872 P ?=?( P *, const T * ); 3857 3873 const T * ?=?( const T **, P ); 3858 3874 }; 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}@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}@ 3860 3876 P ?=?( P *, volatile T * ); 3861 3877 volatile T * ?=?( volatile T **, P ); 3862 3878 }; 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}@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}@ 3864 3880 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}@ 3865 3881 P ?=?( P *, const volatile T * ); … … 3871 3887 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. 3872 3888 \begin{lstlisting} 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 ) ) {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 ) ) { 3874 3890 MyP ?=?( MyP *, CP ); 3875 3891 CP ?=?( CP *, MyP ); … … 3904 3920 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. 3905 3921 \begin{lstlisting} 3906 context comparable(type T ) {3922 trait comparable( otype T ) { 3907 3923 const T 0; 3908 3924 int compare( T, T ); 3909 3925 } 3910 forall( type T | comparable( T ) ) int ?<?( T l, T r ) {3926 forall( otype T | comparable( T ) ) int ?<?( T l, T r ) { 3911 3927 return compare( l, r ) < 0; 3912 3928 } 3913 3929 // ... similarly for <=, ==, >=, >, and !=. 3914 forall( type T | comparable( T ) ) int !?( T operand ) {3930 forall( otype T | comparable( T ) ) int !?( T operand ) { 3915 3931 return !compare( operand, 0 ); 3916 3932 } … … 3924 3940 Similarly, a complete integral type would provide integral operations based on integral assignment operations. 3925 3941 \begin{lstlisting} 3926 context arith_base(type T ) {3942 trait arith_base( otype T ) { 3927 3943 const T 1; 3928 3944 T ?+=?( T *, T ), ?-=?( T *, T ), ?*=?( T *, T ), ?/=?( T *, T ); 3929 3945 } 3930 forall( type T | arith_base( T ) ) T ?+?( T l, T r ) {3946 forall( otype T | arith_base( T ) ) T ?+?( T l, T r ) { 3931 3947 return l += r; 3932 3948 } 3933 forall( type T | arith_base( T ) ) T ?++( T * operand ) {3949 forall( otype T | arith_base( T ) ) T ?++( T * operand ) { 3934 3950 T temporary = *operand; 3935 3951 *operand += 1; 3936 3952 return temporary; 3937 3953 } 3938 forall( type T | arith_base( T ) ) T ++?( T * operand ) {3954 forall( otype T | arith_base( T ) ) T ++?( T * operand ) { 3939 3955 return *operand += 1; 3940 3956 } 3941 3957 // ... similarly for -, --, *, and /. 3942 context int_base(type T ) {3958 trait int_base( otype T ) { 3943 3959 T ?&=?( T *, T ), ?|=?( T *, T ), ?^=?( T *, T ); 3944 3960 T ?%=?( T *, T ), ?<<=?( T *, T ), ?>>=?( T *, T ); 3945 3961 } 3946 forall( type T | int_base( T ) ) T ?&?( T l, T r ) {3962 forall( otype T | int_base( T ) ) T ?&?( T l, T r ) { 3947 3963 return l &= r; 3948 3964 }
Note:
See TracChangeset
for help on using the changeset viewer.