Changeset 7ff30d07
- Timestamp:
- Jun 14, 2016, 1:23:18 PM (7 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, with_gc
- Children:
- 545ef59, c738ca4, ee51534
- Parents:
- 6cbc25a (diff), c8c03683 (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. - Files:
-
- 36 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/LaTeXmacros/common.tex
r6cbc25a r7ff30d07 11 11 %% Created On : Sat Apr 9 10:06:17 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Fri Jun 3 09:32:19201614 %% Update Count : 6213 %% Last Modified On : Fri Jun 10 16:35:25 2016 14 %% Update Count : 101 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 56 56 % \belowdisplayskip \abovedisplayskip 57 57 %} 58 59 \usepackage{pslatex} % reduce size of san serif font 58 60 \usepackage{relsize} % must be after change to small or selects old size 59 61 … … 79 81 \vskip 50\p@ 80 82 }} 81 \renewcommand\section{\@startsection{section}{1}{\z@}{-3.5ex \@plus -1ex \@minus -.2ex}{ 2.3ex \@plus .2ex}{\normalfont\large\bfseries}}83 \renewcommand\section{\@startsection{section}{1}{\z@}{-3.5ex \@plus -1ex \@minus -.2ex}{1.75ex \@plus .2ex}{\normalfont\large\bfseries}} 82 84 \renewcommand\subsection{\@startsection{subsection}{2}{\z@}{-3.25ex \@plus -1ex \@minus -.2ex}{1.5ex \@plus .2ex}{\normalfont\normalsize\bfseries}} 83 85 \renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}} … … 132 134 133 135 \newenvironment{quote2}{% 134 \list{}{\lstset{resetmargins=true }\leftmargin=\parindent\rightmargin\leftmargin}%136 \list{}{\lstset{resetmargins=true,aboveskip=0pt,belowskip=0pt}\topsep=4pt\parsep=0pt\leftmargin=\parindent\rightmargin\leftmargin}% 135 137 \item\relax 136 138 }{% … … 199 201 language=CFA, 200 202 columns=flexible, 201 basicstyle=\ sf,203 basicstyle=\linespread{0.9}\sf, 202 204 stringstyle=\tt, 203 205 tabsize=4, … … 210 212 showlines=true, 211 213 aboveskip=4pt, 212 belowskip= 2pt,214 belowskip=3pt, 213 215 moredelim=**[is][\color{red}]{®}{®}, % red highlighting 214 % moredelim=**[is][\color{blue}]{¢}{¢}, % blue highlighting 216 moredelim=**[is][\color{blue}]{ß}{ß}, % blue highlighting 217 moredelim=**[is][\color{OliveGreen}]{¢}{¢}, % green highlighting 215 218 moredelim=[is][\lstset{keywords={}}]{¶}{¶}, % temporarily turn off keywords 216 % literate={\\`}{\raisebox{0.3ex}{\ttfamily\upshape \hspace*{-2pt}`}}1, % escape \`, otherwise used for red highlighting 217 literate={...}{{$\dots$}}1 {<-}{{$\leftarrow$}}1 {=>}{{$\Rightarrow$}}1, 219 % replace/adjust listing characters that look bad in sanserif 220 literate={-}{\raisebox{-0.15ex}{\texttt{-}}}1 {^}{\raisebox{0.6ex}{$\scriptscriptstyle\land\,$}}1 221 {~}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}}1 {_}{\makebox[1.2ex][c]{\rule{1ex}{0.1ex}}}1 {`}{\ttfamily\upshape\hspace*{-0.1ex}`}1 222 {<-}{$\leftarrow$}2 {=>}{$\Rightarrow$}2 {...}{$\dots$}2, 218 223 }% 219 224 220 225 \lstMakeShortInline© % single-character for \lstinline 221 222 \makeatletter223 % replace/adjust listings characters that look bad in sanserif224 \lst@CCPutMacro225 \lst@ProcessOther{"22}{\lst@ttfamily{"}{\raisebox{0.3ex}{\ttfamily\upshape "}}} % replace double quote226 \lst@ProcessOther{"27}{\lst@ttfamily{'}{\raisebox{0.3ex}{\ttfamily\upshape '\hspace*{-2pt}}}} % replace single quote227 \lst@ProcessOther{"2D}{\lst@ttfamily{-}{\textbf{\texttt{-}}}} % replace minus228 \lst@ProcessOther{"3C}{\lst@ttfamily{<}{\textbf{\texttt{<}}}} % replace less than229 \lst@ProcessOther{"3E}{\lst@ttfamily{>}{\textbf{\texttt{>}}}} % replace greater than230 \lst@ProcessOther{"5E}{\raisebox{0.4ex}{$\scriptstyle\land\,$}} % replace circumflex231 \lst@ProcessOther{"5F}{\lst@ttfamily{\char95}{{\makebox[1.2ex][c]{\rule{1ex}{0.1ex}}}}} % replace underscore232 \lst@ProcessOther{"60}{\lst@ttfamily{`}{\raisebox{0.3ex}{\ttfamily\upshape \hspace*{-2pt}`}}} % replace backquote233 \lst@ProcessOther{"7E}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}} % replace tilde234 %\lst@ProcessOther{"7E}{\raisebox{-.4ex}[1ex][0pt]{\textasciitilde}} % lower tilde235 \@empty\z@\@empty % NECESSARY DO NOT REMOVE236 \makeatother237 226 238 227 % Local Variables: % -
doc/user/Cdecl.fig
r6cbc25a r7ff30d07 34 34 1 1 1.00 45.00 90.00 35 35 1950 1275 1950 1500 36 4 1 0 50 -1 4 90.0000 2 105 90 1350 1650 0\00137 4 1 0 50 -1 4 90.0000 2 105 90 1500 1650 1\00138 4 1 0 50 -1 4 90.0000 2 105 90 1650 1650 2\00139 4 1 0 50 -1 4 90.0000 2 105 90 1800 1650 3\00140 4 1 0 50 -1 4 90.0000 2 105 90 1950 1650 4\00141 4 1 0 50 -1 4 90.0000 2 75 75 1200 1325 x\00136 4 1 0 50 -1 4 10 0.0000 2 105 90 1350 1650 0\001 37 4 1 0 50 -1 4 10 0.0000 2 105 90 1500 1650 1\001 38 4 1 0 50 -1 4 10 0.0000 2 105 90 1650 1650 2\001 39 4 1 0 50 -1 4 10 0.0000 2 105 90 1800 1650 3\001 40 4 1 0 50 -1 4 10 0.0000 2 105 90 1950 1650 4\001 41 4 1 0 50 -1 4 10 0.0000 2 75 75 1200 1325 x\001 42 42 -6 43 43 6 2325 1200 3600 1350 … … 54 54 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 55 55 2850 1200 3600 1200 3600 1350 2850 1350 2850 1200 56 4 1 0 50 -1 4 90.0000 2 105 90 2925 1325 0\00157 4 1 0 50 -1 4 90.0000 2 105 90 3075 1325 1\00158 4 1 0 50 -1 4 90.0000 2 105 90 3225 1325 2\00159 4 1 0 50 -1 4 90.0000 2 105 90 3375 1325 3\00160 4 1 0 50 -1 4 90.0000 2 105 90 3525 1325 4\00156 4 1 0 50 -1 4 10 0.0000 2 105 90 2925 1325 0\001 57 4 1 0 50 -1 4 10 0.0000 2 105 90 3075 1325 1\001 58 4 1 0 50 -1 4 10 0.0000 2 105 90 3225 1325 2\001 59 4 1 0 50 -1 4 10 0.0000 2 105 90 3375 1325 3\001 60 4 1 0 50 -1 4 10 0.0000 2 105 90 3525 1325 4\001 61 61 -6 62 62 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 … … 66 66 2550 1275 2850 1275 67 67 -6 68 4 1 0 50 -1 4 90.0000 2 75 75 2400 1325 x\00168 4 1 0 50 -1 4 10 0.0000 2 75 75 2400 1325 x\001 69 69 -6 -
doc/user/user.tex
r6cbc25a r7ff30d07 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Fri Jun 3 09:49:31201614 %% Update Count : 28113 %% Last Modified On : Fri Jun 10 16:38:22 2016 14 %% Update Count : 394 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 18 18 19 19 % inline code ©...© (copyright symbol) emacs: C-q M-) 20 % red highlighting ®...® (registered trademark sumbol) emacs: C-q M-. 21 % latex escape §...§ (section symbol) emacs: C-q M-' 20 % red highlighting ®...® (registered trademark symbol) emacs: C-q M-. 21 % blue highlighting ß...ß (sharp s symbol) emacs: C-q M-_ 22 % green highlighting ¢...¢ (cent symbol) emacs: C-q M-" 23 % Latex escape §...§ (section symbol) emacs: C-q M-' 22 24 % keyword escape ¶...¶ (pilcrow symbol) emacs: C-q M-^ 23 25 % math escape $...$ (dollar symbol) 24 26 25 \documentclass[ openright,twoside]{article}27 \documentclass[twoside,11pt]{article} 26 28 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 27 29 … … 32 34 \usepackage{fullpage,times,comment} 33 35 \usepackage{epic,eepic} 34 \usepackage{upquote} % switch curled `' to straight `'36 \usepackage{upquote} % switch curled `'" to straight `'" 35 37 \usepackage{xspace} 36 38 \usepackage{varioref} % extended references 37 39 \usepackage{listings} % format program code 38 \usepackage {footmisc}% support label/reference in footnote40 \usepackage[flushmargin]{footmisc} % support label/reference in footnote 39 41 \usepackage{latexsym} % \Box glyph 40 42 \usepackage{mathptmx} % better math font with "times" 43 \usepackage[usenames]{color} 41 44 \usepackage[pagewise]{lineno} 42 45 \renewcommand{\linenumberfont}{\scriptsize\sffamily} 46 \input{common} % bespoke macros used in the document 43 47 \usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref} 44 48 \usepackage{breakurl} 45 49 \renewcommand{\UrlFont}{\small\sf} 46 50 47 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%48 49 % Bespoke macros used in the document.50 \input{common}51 52 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%53 54 51 % Names used in the document. 55 52 56 53 \newcommand{\Version}{1.0.0} 57 54 \newcommand{\CS}{C\raisebox{-0.9ex}{\large$^\sharp$}\xspace} 55 56 \newcommand{\Textbf}[2][red]{{\color{#1}{\textbf{#2}}}} 57 \newcommand{\Emph}[2][red]{{\color{#1}\textbf{\emph{#2}}}} 58 \newcommand{\R}[1]{\Textbf{#1}} 59 \newcommand{\B}[1]{{\Textbf[blue]{#1}}} 60 \newcommand{\G}[1]{{\Textbf[OliveGreen]{#1}}} 58 61 59 62 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% … … 110 113 111 114 \CFA\footnote{Pronounced ``C-for-all'', and written \CFA, CFA, or \CFL.} is a modern general-purpose programming-language, designed an as evolutionary step forward from the C programming language. 112 The syntax of the \CFA language builds from C, and should look immediately familiar to C programmers.115 The syntax of the \CFA language builds from C, and should look immediately familiar to C/\CC programmers. 113 116 % Any language feature that is not described here can be assumed to be using the standard C11 syntax. 114 \CFA adds many modern programming-language features that directly lead sto increased \emph{safety} and \emph{productivity}, while maintaining interoperability with existing C programs and achieving C performance.117 \CFA adds many modern programming-language features that directly lead to increased \emph{safety} and \emph{productivity}, while maintaining interoperability with existing C programs and achieving C performance. 115 118 Like C, \CFA is a statically typed, procedural language with a low-overhead runtime, meaning there is no global garbage-collection. 116 119 The primary new features include parametric-polymorphism routines and types, exceptions, concurrency, and modules. … … 123 126 New programs can be written in \CFA using a combination of C and \CFA features. 124 127 \CC had a similar goal 30 years ago, but has struggled over the intervening time to incorporate modern programming-language features because of early design choices. 125 \CFA has 30 years of hindsight and clean starting point.128 \CFA has 30 years of hindsight and a clean starting point. 126 129 127 130 Like \CC, there may be both an old and new ways to achieve the same effect. 128 131 For example, the following programs compare the \CFA and C I/O mechanisms. 129 132 \begin{quote2} 130 \begin{tabular}{@{}l@{\hspace{3 0pt}}l@{}}131 \multicolumn{1}{c@{\hspace{3 0pt}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\133 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} 134 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 132 135 \begin{lstlisting} 133 136 #include <fstream> 134 137 int main( void ) { 135 138 int x = 0, y = 1, z = 2; 136 sout | x | y | z | endl;139 ®sout | x | y | z | endl;® 137 140 } 138 141 \end{lstlisting} … … 142 145 int main( void ) { 143 146 int x = 0, y = 1, z = 2; 144 printf( "%d %d %d\n", x, y, z );147 ®printf( "%d %d %d\n", x, y, z );® 145 148 } 146 149 \end{lstlisting} … … 148 151 \end{quote2} 149 152 Both programs output the same result. 150 While the \CFA I/O looks similar to the \CC output style, there are severalimportant differences, such as automatic spacing between variables as in Python (see also~\VRef{s:IOLibrary}).151 152 This document is a referencemanual for the \CFA programming language, targeted at \CFA programmers.153 While the \CFA I/O looks similar to the \CC output style, there are important differences, such as automatic spacing between variables as in Python (see also~\VRef{s:IOLibrary}). 154 155 This document is a user manual for the \CFA programming language, targeted at \CFA programmers. 153 156 Implementers may refer to the \CFA Programming Language Specification for details about the language syntax and semantics. 154 157 In its current state, this document covers the intended core features of the language. … … 159 162 \section{History} 160 163 161 The \CFA project started with K-W C~\cite{ Till89,Buhr94a}, which extended C with new declaration syntax, multiple return values from routines, and extended assignment capabilities using the notion of tuples.164 The \CFA project started with K-W C~\cite{Buhr94a,Till89}, which extended C with new declaration syntax, multiple return values from routines, and extended assignment capabilities using the notion of tuples. 162 165 (See~\cite{Werther96} for some similar work, but for \CC.) 163 166 The original \CFA project~\cite{Ditchfield92} extended the C type system with parametric polymorphism and overloading, as opposed to the \CC approach of object-oriented extensions to the C type-system. 164 167 A first implementation of the core Cforall language was created~\cite{Bilson03,Esteves04}, but at the time there was little interesting in extending C, so work did not continue. 165 As the saying goes, ``What goes around, comes around '', and there is now renewed interest in the C programming language because of legacy code-bases, so the \CFA project has been restarted.168 As the saying goes, ``What goes around, comes around.'', and there is now renewed interest in the C programming language because of legacy code-bases, so the \CFA project has been restarted. 166 169 167 170 … … 169 172 170 173 Even with all its problems, C is a very popular programming language because it allows writing software at virtually any level in a computer system without restriction. 171 For system sprogramming, where direct access to hardware and dealing with real-time issues is a requirement, C is usually the language of choice.174 For system programming, where direct access to hardware and dealing with real-time issues is a requirement, C is usually the language of choice. 172 175 As well, there are millions of lines of C legacy code, forming the base for many software development projects (especially on UNIX systems). 173 176 The TIOBE index (\url{http://www.tiobe.com/tiobe_index}) for March 2016 shows programming-language popularity, with Java 20.5\%, C 14.5\%, \CC 6.7\%, \CS 4.3\%, Python 4.3\%, and all other programming languages below 3\%. 177 As well, for 30 years, C has been the number 1 and 2 most popular programming language: 178 \begin{center} 179 \setlength{\tabcolsep}{1.5ex} 180 \begin{tabular}{@{}r|c|c|c|c|c|c|c@{}} 181 Ranking & 2016 & 2011 & 2006 & 2001 & 1996 & 1991 & 1986 \\ 182 \hline 183 Java & 1 & 1 & 1 & 3 & 29 & - & - \\ 184 \hline 185 \R{C} & \R{2} & \R{2} & \R{2} & \R{1} & \R{1} & \R{1} & \R{1} \\ 186 \hline 187 \CC & 3 & 3 & 3 & 2 & 2 & 2 & 7 \\ 188 \end{tabular} 189 \end{center} 174 190 Hence, C is still an extremely important programming language, with double the usage of \CC, where \CC itself is largely C code. 175 191 Finally, love it or hate it, C has been an important and influential part of computer science for 40 years and it appears it will continue to be for many more years. … … 178 194 The goal of this project is to engineer modern language features into C in an evolutionary rather than revolutionary way. 179 195 \CC~\cite{c++,ANSI14:C++} is an example of a similar project; 180 however, it largely extended the language, and did not address existing problems.\footnote{%196 however, it largely extended the language, and did not address many existing problems.\footnote{% 181 197 Two important existing problems addressed were changing the type of character literals from ©int© to ©char© and enumerator from ©int© to the type of its enumerators.} 182 Fortran~\cite{Fortran08}, Ada~\cite{Ada12}, and Cobol~\cite{Cobol14} are examples of programming languages that took an evolutionary approach, where modern language features are added and problems fixed within the framework of the existing language.198 Fortran~\cite{Fortran08}, Ada~\cite{Ada12}, and Cobol~\cite{Cobol14} are examples of programming languages that took an evolutionary approach, where modern language features (e.g., objects, concurrency) are added and problems fixed within the framework of the existing language. 183 199 Java~\cite{Java8}, Go~\cite{Go}, Rust~\cite{Rust} and D~\cite{D} are examples of the revolutionary approach for modernizing C/\CC, resulting in a new language rather than an extension of the descendent. 184 200 These languages have different syntax and semantics from C, and do not interoperate directly with C, largely because of garbage collection. 185 201 As a result, there is a significant learning curve to move to these languages, and C legacy-code must be rewritten. 186 These costs can be prohibitive for many companies with a large software base in C/\CC, and many programmers that requireretraining to a new programming language.187 188 The result of this project is a language that is largely backwards compatible with C11~\cite{C11}, but containing many modern language features and fixing some of the well known C problems.189 Without significant extension to the C programming language, C will beunable to cope with the needs of modern programming problems and programmers;202 These costs can be prohibitive for many companies with a large software base in C/\CC, and a significant number of programmers requiring retraining to a new programming language. 203 204 The result of this project is a language that is largely backwards compatible with C11~\cite{C11}, but fixing some of the well known C problems and containing many modern language features. 205 Without significant extension to the C programming language, it is becoming unable to cope with the needs of modern programming problems and programmers; 190 206 as a result, it will fade into disuse. 191 207 Considering the large body of existing C code and programmers, there is significant impetus to ensure C is transformed into a modern programming language. … … 200 216 This feature allows users of \CFA to take advantage of the existing panoply of C libraries from inside their \CFA code. 201 217 In fact, one of the biggest issues for any new programming language is establishing a minimum level of library code to support a large body of activities. 202 Programming-language developers often state that adequate library support takes more work than designing and implementing the language itself.218 Language developers often state that adequate library support takes more work than designing and implementing the language itself. 203 219 Like \CC, \CFA starts with immediate access to all exiting C libraries, and in many cases, can easily wrap library routines with simpler and safer interfaces, at very low cost. 220 Hence, \CFA begins by leveraging the large repository of C libraries with little cost. 204 221 205 222 However, it is necessary to differentiate between C and \CFA code because of name overloading, as for \CC. 206 For example, the C math-library provides the following routines for computing the absolute value of the basic type : ©abs©, ©labs©, ©llabs©, ©fabs©, ©fabsf©, ©fabsl©, ©cabsf©, ©cabs©, and ©cabsl©.207 Whereas, \CFA wraps each of these routines into one with the common name ©abs©.223 For example, the C math-library provides the following routines for computing the absolute value of the basic types: ©abs©, ©labs©, ©llabs©, ©fabs©, ©fabsf©, ©fabsl©, ©cabsf©, ©cabs©, and ©cabsl©. 224 Whereas, \CFA wraps each of these routines into ones with the common name ©abs©: 208 225 \begin{lstlisting} 209 226 char abs( char ); 210 227 extern "C" { 211 int abs( int ); // use default C routine for int228 int abs( int ); // use default C routine for int 212 229 } // extern "C" 213 230 long int abs( long int ); … … 233 250 \section[Compiling CFA Program]{Compiling \CFA Program} 234 251 235 The command ©cfa© is used to compile \CFA program(s). 236 This command works like the GNU ©gcc©\index{gcc} command, e.g.: 252 The command ©cfa© is used to compile \CFA program(s), and is based on the GNU ©gcc©\index{gcc} command, e.g.: 237 253 \begin{lstlisting} 238 254 cfa§\indexc{cfa}\index{compilation!cfa@©cfa©}§ [ gcc-options ] C/§\CFA§-files [ assembler/loader-files ] … … 240 256 By default, \CFA programs having the following ©gcc© flags turned on: 241 257 \begin{description} 242 \item\hspace*{- 4pt}\Indexc{-std=gnu99}\index{compilation option!-std=gnu99@{©-std=gnu99©}}258 \item\hspace*{-0.6ex}\Indexc{-std=gnu99}\index{compilation option!-std=gnu99@{©-std=gnu99©}} 243 259 The 1999 C standard plus GNU extensions. 244 \item\hspace*{- 4pt}\Indexc{-fgnu89-¶inline¶}\index{compilation option!-fgnu89-inline@{©-fgnu89-¶inline¶©}}260 \item\hspace*{-0.6ex}\Indexc{-fgnu89-¶inline¶}\index{compilation option!-fgnu89-inline@{©-fgnu89-¶inline¶©}} 245 261 Use the traditional GNU semantics for inline routines in C99 mode, which allows inline routines in header files. 246 262 \end{description} 247 263 The following new \CFA option is available: 248 264 \begin{description} 249 \item\hspace*{- 4pt}\Indexc{-CFA}\index{compilation option!-CFA@{©-CFA©}}265 \item\hspace*{-0.6ex}\Indexc{-CFA}\index{compilation option!-CFA@{©-CFA©}} 250 266 Only the C preprocessor and the \CFA translator steps are performed and the transformed program is written to standard output, which makes it possible to examine the code generated by the \CFA translator. 251 267 \end{description} … … 253 269 The following preprocessor variables are available: 254 270 \begin{description} 255 \item\hspace*{- 4pt}\Indexc{__CFA__}\index{preprocessor variables!__CFA__@{©__CFA__©}}271 \item\hspace*{-0.6ex}\Indexc{__CFA__}\index{preprocessor variables!__CFA__@{©__CFA__©}} 256 272 is always available during preprocessing and its value is the current major \Index{version number} of \CFA.\footnote{ 257 273 The C preprocessor allows only integer values in a preprocessor variable so a value like ``\Version'' is not allowed. 258 274 Hence, the need to have three variables for the major, minor and patch version number.} 259 275 260 \item\hspace*{- 4pt}\Indexc{__CFA_MINOR__}\index{preprocessor variables!__CFA_MINOR__@{©__CFA_MINOR__©}}276 \item\hspace*{-0.6ex}\Indexc{__CFA_MINOR__}\index{preprocessor variables!__CFA_MINOR__@{©__CFA_MINOR__©}} 261 277 is always available during preprocessing and its value is the current minor \Index{version number} of \CFA. 262 278 263 \item\hspace*{- 4pt}\Indexc{__CFA_PATCH__}\index{preprocessor variables!__CFA_PATCH__@©__CFA_PATCH__©}279 \item\hspace*{-0.6ex}\Indexc{__CFA_PATCH__}\index{preprocessor variables!__CFA_PATCH__@©__CFA_PATCH__©} 264 280 is always available during preprocessing and its value is the current patch \Index{version number} of \CFA. 265 281 266 \item\hspace*{- 4pt}\Indexc{__CFORALL__}\index{preprocessor variables!__CFORALL__@©__CFORALL__©}267 is always available during preprocessing and it hasno value.282 \item\hspace*{-0.6ex}\Indexc{__CFA__}\index{preprocessor variables!__CFA__@©__CFA__©} and \Indexc{__CFORALL__}\index{preprocessor variables!__CFORALL__@©__CFORALL__©} 283 are always available during preprocessing and have no value. 268 284 \end{description} 269 285 … … 272 288 \begin{lstlisting} 273 289 #ifndef __CFORALL__ 274 #include <stdio.h> // C header file290 #include <stdio.h> // C header file 275 291 #else 276 #include <fstream> // §\CFA{}§ header file292 #include <fstream> // §\CFA{}§ header file 277 293 #endif 278 294 \end{lstlisting} … … 284 300 Numeric constants are extended to allow \Index{underscore}s within constants\index{constant!underscore}, e.g.: 285 301 \begin{lstlisting} 286 2®_®147®_®483®_®648; // decimal constant287 56_ul; // decimal unsigned long constant288 0_377; // octal constant289 0x_ff_ff; // hexadecimal constant290 0x_ef3d_aa5c; // hexadecimal constant291 3.141_592_654; // floating point constant292 10_e_+1_00; // floating point constant293 0x_ff_ff_p_3; // hexadecimal floating point294 0x_1.ffff_ffff_p_128_l; // hexadecimal floating point long constant295 L_"\x_ff_ee"; // wide character constant302 2®_®147®_®483®_®648; // decimal constant 303 56_ul; // decimal unsigned long constant 304 0_377; // octal constant 305 0x_ff_ff; // hexadecimal constant 306 0x_ef3d_aa5c; // hexadecimal constant 307 3.141_592_654; // floating point constant 308 10_e_+1_00; // floating point constant 309 0x_ff_ff_p_3; // hexadecimal floating point 310 0x_1.ffff_ffff_p_128_l; // hexadecimal floating point long constant 311 L_"\x_ff_ee"; // wide character constant 296 312 \end{lstlisting} 297 313 The rules for placement of underscores is as follows: … … 311 327 \end{enumerate} 312 328 It is significantly easier to read and enter long constants when they are broken up into smaller groupings (most cultures use comma or period among digits for the same purpose). 313 This extension is backwards compatible, matches with the use of underscore in variable names, and appears in Ada and Java .329 This extension is backwards compatible, matches with the use of underscore in variable names, and appears in Ada and Java 8. 314 330 315 331 … … 321 337 \begin{quote2} 322 338 \begin{tabular}{@{}ll@{}} 323 \begin{lstlisting} [aboveskip=0pt,belowskip=0pt]324 int *x[ 5]339 \begin{lstlisting} 340 int *x[5] 325 341 \end{lstlisting} 326 342 & … … 332 348 For example, a routine returning a pointer to an array of integers is defined and used in the following way: 333 349 \begin{lstlisting} 334 int (*f())[ 5 ] {...};// definition mimics usage335 ... (*f())[ 3] += 1;350 int (*f())[5] {...}; // definition mimics usage 351 ... (*f())[3] += 1; 336 352 \end{lstlisting} 337 353 Essentially, the return type is wrapped around the routine name in successive layers (like an onion). 338 354 While attempting to make the two contexts consistent was a laudable goal, it has not worked out in practice. 339 355 340 \CFA provides its own type, variable and routine declarations, using a slightly different syntax. 341 The new declarations place modifiers to the left of the base type, while C declarations place modifiers to the right of the base type. 356 \CFA provides its own type, variable and routine declarations, using a different syntax. 357 The new declarations place qualifiers to the left of the base type, while C declarations place qualifiers to the right of the base type. 358 In the following example, \R{red} is for the base type and \B{blue} is for the qualifiers. 359 The \CFA declarations move the qualifiers to the left of the base type, i.e., blue to the left of the red, while the qualifiers have the same meaning but are ordered left to left to right to specify the variable's type. 360 \begin{quote2} 361 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} 362 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 363 \begin{lstlisting} 364 ß[5] *ß ®int® x1; 365 ß* [5]ß ®int® x2; 366 ß[* [5] int]ß f®( int p )®; 367 \end{lstlisting} 368 & 369 \begin{lstlisting} 370 ®int® ß*ß x1 ß[5]ß; 371 ®int® ß(*ßx2ß)[5]ß; 372 ßint (*ßf®( int p )®ß)[5]ß; 373 \end{lstlisting} 374 \end{tabular} 375 \end{quote2} 342 376 The only exception is bit field specification, which always appear to the right of the base type. 343 C and the new \CFA declarations may appear together in the same program block, but cannot be mixed within a specific declaration. 344 345 In \CFA declarations, the same tokens are used as in C: the character ©*© is used to indicate a pointer, square brackets ©[©\,©]© are used to represent an array, and parentheses ©()© are used to indicate a routine parameter. 346 However, unlike C, \CFA type declaration tokens are specified from left to right and the entire type specification is distributed across all variables in the declaration list. 377 % Specifically, the character ©*© is used to indicate a pointer, square brackets ©[©\,©]© are used to represent an array or function return value, and parentheses ©()© are used to indicate a routine parameter. 378 However, unlike C, \CFA type declaration tokens are distributed across all variables in the declaration list. 347 379 For instance, variables ©x© and ©y© of type pointer to integer are defined in \CFA as follows: 348 380 \begin{quote2} 349 \begin{tabular}{@{}l@{\hspace{3 0pt}}l@{}}350 \multicolumn{1}{c@{\hspace{3 0pt}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\351 \begin{lstlisting} 352 ®* int x, y;®381 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} 382 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 383 \begin{lstlisting} 384 ®*® int x, y; 353 385 \end{lstlisting} 354 386 & 355 387 \begin{lstlisting} 356 int *x, *y;388 int ®*®x, ®*®y; 357 389 \end{lstlisting} 358 390 \end{tabular} … … 360 392 Other examples are: 361 393 \begin{quote2} 362 \begin{tabular}{@{}l@{\hspace{3 0pt}}l@{\hspace{20pt}}l@{}}363 \multicolumn{1}{c@{\hspace{3 0pt}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{20pt}}}{\textbf{C}} \\394 \begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{}} 395 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{2em}}}{\textbf{C}} \\ 364 396 \begin{lstlisting} 365 397 [ 5 ] int z; … … 397 429 \end{quote2} 398 430 399 All type qualifiers, i.e., ©const© and ©volatile©, are used in the normal way with the new declarations butappear left to right, e.g.:431 All type qualifiers, e.g., ©const©, ©volatile©, etc., are used in the normal way with the new declarations and also appear left to right, e.g.: 400 432 \begin{quote2} 401 \begin{tabular}{@{}l@{\hspace{ 30pt}}l@{\hspace{20pt}}l@{}}402 \multicolumn{1}{c@{\hspace{ 30pt}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{20pt}}}{\textbf{C}} \\433 \begin{tabular}{@{}l@{\hspace{1em}}l@{\hspace{1em}}l@{}} 434 \multicolumn{1}{c@{\hspace{1em}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{1em}}}{\textbf{C}} \\ 403 435 \begin{lstlisting} 404 436 const * const int x; … … 417 449 \end{tabular} 418 450 \end{quote2} 419 All declaration qualifiers, i.e., ©extern©, ©static©, etc., are used in the normal way with the new declarations but can only appear at the start of a \CFA routine declaration,\footnote{\label{StorageClassSpecifier}451 All declaration qualifiers, e.g., ©extern©, ©static©, etc., are used in the normal way with the new declarations but can only appear at the start of a \CFA routine declaration,\footnote{\label{StorageClassSpecifier} 420 452 The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature.~\cite[\S~6.11.5(1)]{C11}} e.g.: 421 453 \begin{quote2} 422 \begin{tabular}{@{}l@{\hspace{3 0pt}}l@{\hspace{20pt}}l@{}}423 \multicolumn{1}{c@{\hspace{3 0pt}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{20pt}}}{\textbf{C}} \\454 \begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{}} 455 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{2em}}}{\textbf{C}} \\ 424 456 \begin{lstlisting} 425 457 extern [ 5 ] int x; … … 443 475 e.g.: 444 476 \begin{lstlisting} 445 x; // int x446 *y; // int *y447 f( p1, p2 ); // int f( int p1, int p2 );448 f( p1, p2 ) {} // int f( int p1, int p2 ) {}449 \end{lstlisting} 450 451 As stated above, the two styles of declaration may appear together in the same block.477 x; // int x 478 *y; // int *y 479 f( p1, p2 ); // int f( int p1, int p2 ); 480 f( p1, p2 ) {} // int f( int p1, int p2 ) {} 481 \end{lstlisting} 482 483 Finally, new \CFA declarations may appear together with C declarations in the same program block, but cannot be mixed within a specific declaration. 452 484 Therefore, a programmer has the option of either continuing to use traditional C declarations or take advantage of the new style. 453 485 Clearly, both styles need to be supported for some time due to existing C-style header-files, particularly for UNIX systems. … … 458 490 The new declaration syntax can be used in other contexts where types are required, e.g., casts and the pseudo-routine ©sizeof©: 459 491 \begin{quote2} 460 \begin{tabular}{@{}l@{\hspace{3 0pt}}l@{}}461 \multicolumn{1}{c@{\hspace{3 0pt}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\462 \begin{lstlisting} 463 y = ( * int)x;464 i = sizeof( [ 5 ] * int);492 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} 493 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 494 \begin{lstlisting} 495 y = (®* int®)x; 496 i = sizeof(®[ 5 ] * int®); 465 497 \end{lstlisting} 466 498 & 467 499 \begin{lstlisting} 468 y = ( int *)x;469 i = sizeof( int *[ 5 ]);500 y = (®int *®)x; 501 i = sizeof(®int *[ 5 ]®); 470 502 \end{lstlisting} 471 503 \end{tabular} … … 476 508 477 509 \CFA also supports a new syntax for routine definition, as well as ISO C and K\&R routine syntax. 478 The point of the new syntax is to allow returning multiple values from a routine~\cite{ CLU,Galletly96}, e.g.:510 The point of the new syntax is to allow returning multiple values from a routine~\cite{Galletly96,CLU}, e.g.: 479 511 \begin{lstlisting} 480 512 ®[ int o1, int o2, char o3 ]® f( int i1, char i2, char i3 ) { … … 490 522 Declaration qualifiers can only appear at the start of a routine definition, e.g.: 491 523 \begin{lstlisting} 492 extern[ int x ] g( int y ) {§\,§}524 ®extern® [ int x ] g( int y ) {§\,§} 493 525 \end{lstlisting} 494 526 Lastly, if there are no output parameters or input parameters, the brackets and/or parentheses must still be specified; 495 527 in both cases the type is assumed to be void as opposed to old style C defaults of int return type and unknown parameter types, respectively, as in: 496 528 \begin{lstlisting} 497 [§\,§] g(); // no input or output parameters498 [ void ] g( void ); // no input or output parameters529 [§\,§] g(); // no input or output parameters 530 [ void ] g( void ); // no input or output parameters 499 531 \end{lstlisting} 500 532 … … 503 535 [ i, j, ch ] = f( 3, 'a', ch ); 504 536 \end{lstlisting} 505 The list of return values from f and the grouping on the left-hand side of the assignment is called a tupleand discussed in Section 12.537 The list of return values from f and the grouping on the left-hand side of the assignment is called a \newterm{return list} and discussed in Section 12. 506 538 507 539 \CFA style declarations cannot be used to declare parameters for K\&R style routine definitions because of the following ambiguity: … … 514 546 \begin{lstlisting} 515 547 typedef int foo; 516 int f( int (* foo) ); // foo is redefined as a parameter name548 int f( int (* foo) ); // foo is redefined as a parameter name 517 549 \end{lstlisting} 518 550 The string ``©int (* foo)©'' declares a C-style named-parameter of type pointer to an integer (the parenthesis are superfluous), while the same string declares a \CFA style unnamed parameter of type routine returning integer with unnamed parameter of type pointer to foo. 519 The redefinition of a type name in a parameter list is the only context in C where the character ©*© can appear to the left of a type name, and \CFA relies on all type modifier characters appearing to the right of the type name.551 The redefinition of a type name in a parameter list is the only context in C where the character ©*© can appear to the left of a type name, and \CFA relies on all type qualifier characters appearing to the right of the type name. 520 552 The inability to use \CFA declarations in these two contexts is probably a blessing because it precludes programmers from arbitrarily switching between declarations forms within a declaration contexts. 521 553 522 554 C-style declarations can be used to declare parameters for \CFA style routine definitions, e.g.: 523 555 \begin{lstlisting} 524 [ int ] f( * int, int * ); // returns an integer, accepts 2 pointers to integers525 [ * int, int * ] f( int ); // returns 2 pointers to integers, accepts an integer556 [ int ] f( * int, int * ); // returns an integer, accepts 2 pointers to integers 557 [ * int, int * ] f( int ); // returns 2 pointers to integers, accepts an integer 526 558 \end{lstlisting} 527 559 The reason for allowing both declaration styles in the new context is for backwards compatibility with existing preprocessor macros that generate C-style declaration-syntax, as in: 528 560 \begin{lstlisting} 529 561 #define ptoa( n, d ) int (*n)[ d ] 530 int f( ptoa( p,5) ) ... // expands to int f( int (*p)[ 5 ] )531 [ int ] f( ptoa( p,5) ) ... // expands to [ int ] f( int (*p)[ 5 ] )562 int f( ptoa( p, 5 ) ) ... // expands to int f( int (*p)[ 5 ] ) 563 [ int ] f( ptoa( p, 5 ) ) ... // expands to [ int ] f( int (*p)[ 5 ] ) 532 564 \end{lstlisting} 533 565 Again, programmers are highly encouraged to use one declaration form or the other, rather than mixing the forms. 534 566 535 567 536 \subsection{ ReturningValues}537 538 Named return valueshandle the case where it is necessary to define a local variable whose value is then returned in a ©return© statement, as in:568 \subsection{Named Return Values} 569 570 \Index{Named return values} handle the case where it is necessary to define a local variable whose value is then returned in a ©return© statement, as in: 539 571 \begin{lstlisting} 540 572 int f() { … … 545 577 \end{lstlisting} 546 578 Because the value in the return variable is automatically returned when a \CFA routine terminates, the ©return© statement \emph{does not} contain an expression, as in: 547 \begin{lstlisting} 548 ®[ int x ]® f() { 549 ... x = 0; ... x = y; ... 550 ®return;® // implicitly return x 551 } 552 \end{lstlisting} 553 When the return is encountered, the current value of ©x© is returned to the calling routine. 579 \newline 580 \begin{minipage}{\linewidth} 581 \begin{lstlisting} 582 ®[ int x, int y ]® f() { 583 int z; 584 ... x = 0; ... y = z; ... 585 ®return;® // implicitly return x, y 586 } 587 \end{lstlisting} 588 \end{minipage} 589 \newline 590 When the return is encountered, the current values of ©x© and ©y© are returned to the calling routine. 554 591 As well, ``falling off the end'' of a routine without a ©return© statement is permitted, as in: 555 592 \begin{lstlisting} 556 [ int x ] f() {557 ... x = 0; ... x = y; ...558 } // implicitly return x 559 \end{lstlisting} 560 In this case, the current value of ©x© isreturned to the calling routine just as if a ©return© had been encountered.593 [ int x, int y ] f() { 594 ... 595 } // implicitly return x, y 596 \end{lstlisting} 597 In this case, the current values of ©x© and ©y© are returned to the calling routine just as if a ©return© had been encountered. 561 598 562 599 … … 566 603 as well, parameter names are optional, e.g.: 567 604 \begin{lstlisting} 568 [ int x ] f (); // returning int with no parameters569 [ * int ] g (int y); // returning pointer to int with int parameter570 [ ] h (int,char); // returning no result with int and char parameters571 [ * int,int ] j (int); // returning pointer to int and int, with int parameter605 [ int x ] f (); // returning int with no parameters 606 [ * int ] g (int y); // returning pointer to int with int parameter 607 [ ] h (int,char); // returning no result with int and char parameters 608 [ * int,int ] j (int); // returning pointer to int and int, with int parameter 572 609 \end{lstlisting} 573 610 This syntax allows a prototype declaration to be created by cutting and pasting source text from the routine definition header (or vice versa). 574 611 It is possible to declare multiple routine-prototypes in a single declaration, but the entire type specification is distributed across \emph{all} routine names in the declaration list (see~\VRef{s:Declarations}), e.g.: 575 612 \begin{quote2} 576 \begin{tabular}{@{}l@{\hspace{3 0pt}}l@{}}577 \multicolumn{1}{c@{\hspace{3 0pt}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\613 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} 614 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 578 615 \begin{lstlisting} 579 616 [ int ] f(int), g; … … 604 641 for example, the following is incorrect: 605 642 \begin{lstlisting} 606 * [ int x ] f () fp; // routine name "f" is not allowed643 * [ int x ] f () fp; // routine name "f" is not allowed 607 644 \end{lstlisting} 608 645 … … 737 774 While in theory default arguments can be simulated with overloading, as in: 738 775 \begin{quote2} 739 \begin{tabular}{@{}l@{\hspace{3 0pt}}l@{}}740 \multicolumn{1}{c@{\hspace{3 0pt}}}{\textbf{default arguments}} & \multicolumn{1}{c}{\textbf{overloading}} \\776 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} 777 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{default arguments}} & \multicolumn{1}{c}{\textbf{overloading}} \\ 741 778 \begin{lstlisting} 742 779 void p( int x, int y = 2, int z = 3 ) {...} … … 773 810 \CFA allows \Index{type nesting}, and type qualification of the nested types, where as C hoists\index{type hoisting} (refactors) nested types into the enclosing scope and has no type qualification. 774 811 \begin{quote2} 775 \begin{tabular}{@{}l@{\hspace{3 0pt}}l|l@{}}776 \multicolumn{1}{c@{\hspace{3 0pt}}}{\textbf{C Type Nesting}} & \multicolumn{1}{c}{\textbf{C Implicit Hoisting}} & \multicolumn{1}{|c}{\textbf{\CFA}} \\812 \begin{tabular}{@{}l@{\hspace{3em}}l|l@{}} 813 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{C Type Nesting}} & \multicolumn{1}{c}{\textbf{C Implicit Hoisting}} & \multicolumn{1}{|c}{\textbf{\CFA}} \\ 777 814 \hline 778 815 \begin{lstlisting} … … 880 917 881 918 882 \section{ Tuples}919 \section{Lexical List} 883 920 884 921 In C and \CFA, lists of elements appear in several contexts, such as the parameter list for a routine call. 885 922 (More contexts are added shortly.) 886 A list of such elements is called a tuple.887 The general syntax of a tupleis:923 A list of such elements is called a \newterm{lexical list}. 924 The general syntax of a lexical list is: 888 925 \begin{lstlisting} 889 926 [ §\emph{exprlist}§ ] 890 927 \end{lstlisting} 891 928 where ©$\emph{exprlist}$© is a list of one or more expressions separated by commas. 892 The brackets, ©[]©, allow differentiating between tuples and expressions containing the C comma operator.893 The following are examples of tuples:929 The brackets, ©[]©, allow differentiating between lexical lists and expressions containing the C comma operator. 930 The following are examples of lexical lists: 894 931 \begin{lstlisting} 895 932 [ x, y, z ] … … 1180 1217 \begin{figure} 1181 1218 \centering 1182 \begin{tabular}{@{}l@{\hspace{3 0pt}}l@{}}1183 \multicolumn{1}{c@{\hspace{3 0pt}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\1219 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} 1220 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 1184 1221 \begin{lstlisting} 1185 1222 ®L1:® for ( ... ) { … … 1211 1248 \vspace*{0.25in} 1212 1249 1213 \begin{tabular}{@{}l@{\hspace{3 0pt}}l@{}}1214 \multicolumn{1}{c@{\hspace{3 0pt}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\1250 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} 1251 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 1215 1252 \begin{lstlisting} 1216 1253 ®L1®: for ( ... ) { … … 1453 1490 Therefore, the ©case© clause is extended with a list of values, as in: 1454 1491 \begin{quote2} 1455 \begin{tabular}{@{}l@{\hspace{3 0pt}}l@{\hspace{20pt}}l@{}}1456 \multicolumn{1}{c@{\hspace{3 0pt}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{20pt}}}{\textbf{C}} \\1492 \begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{}} 1493 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{2em}}}{\textbf{C}} \\ 1457 1494 \begin{lstlisting} 1458 1495 switch ( i ) { … … 1485 1522 In addition, two forms of subranges are allowed to specify case values: the GNU C form and a new \CFA form. 1486 1523 \begin{quote2} 1487 \begin{tabular}{@{}l@{\hspace{3 0pt}}l@{\hspace{20pt}}l@{}}1488 \multicolumn{1}{c@{\hspace{3 0pt}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{20pt}}}{\textbf{GNU C}} \\1524 \begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{}} 1525 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{2em}}}{\textbf{GNU C}} \\ 1489 1526 \begin{lstlisting} 1490 1527 switch ( i ) { … … 2007 2044 Auto type-inferencing occurs in a declaration where a variable's type is inferred from its initialization expression type. 2008 2045 \begin{quote2} 2009 \begin{tabular}{@{}l@{\hspace{3 0pt}}ll@{}}2010 \multicolumn{1}{c@{\hspace{3 0pt}}}{\textbf{\CC}} & \multicolumn{1}{c}{©gcc©}\index{gcc} \\2046 \begin{tabular}{@{}l@{\hspace{3em}}ll@{}} 2047 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CC}} & \multicolumn{1}{c}{©gcc©}\index{gcc} \\ 2011 2048 \begin{lstlisting} 2012 2049 … … 4110 4147 The general case is printing out a sequence of variables separated by whitespace. 4111 4148 \begin{quote2} 4112 \begin{tabular}{@{}l@{\hspace{3 0pt}}l@{}}4113 \multicolumn{1}{c@{\hspace{3 0pt}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{\CC}} \\4149 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} 4150 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{\CC}} \\ 4114 4151 \begin{lstlisting} 4115 4152 int x = 0, y = 1, z = 2; -
doc/working/resolver_design.md
r6cbc25a r7ff30d07 81 81 82 82 ## Conversion Costs ## 83 Each possible resolution of an expression has a _cost_ consisting of four 84 integer components: _unsafe_ conversion cost, _polymorphic_ specialization 85 cost, _safe_ conversion cost, and a _count_ of conversions. 86 These components form a lexically-ordered tuple which can be summed 87 element-wise; summation starts at `(0, 0, 0, 0)`. 83 Each possible resolution of an expression has a _cost_ tuple consisting of 84 the following components: _unsafe_ conversion cost, _polymorphic_ 85 specialization cost, _safe_ conversion cost, a count of _explicit_ 86 conversions, and _qualifier_ conversion cost. 87 These components are lexically-ordered and can be summed element-wise; 88 summation starts at `(0, 0, 0, 0, 0)`. 88 89 89 90 ### Lvalue and Qualifier Conversions ### … … 1224 1225 programmers. 1225 1226 1227 ## Resolver Architecture ## 1228 1229 ### Function Application Resolution ### 1230 Our resolution algorithm for function application expressions is based on 1231 Baker's[3] single-pass bottom-up algorithm, with Cormack's[4] single-pass 1232 top-down algorithm applied where appropriate as an optimization. 1233 Broadly speaking, the cost of this resolution per expression will be 1234 proportional to `i^d`, where `i` is the number of interpretations of each 1235 program symbol, and `d` is the maximum depth of the expression DAG. 1236 Since `d` is determined by the user programmer (in general, bounded by a small 1237 constant), opportunities for resolver optimization primarily revolve around 1238 minimizing `i`, the number of interpretations of each symbol that are 1239 considered. 1240 1241 [3] Baker, Theodore P. A one-pass algorithm for overload resolution in Ada. 1242 ACM Transactions on Programming Languages and Systems (1982) 4:4 p.601-614 1243 1244 [4] Cormack, Gordon V. An algorithm for the selection of overloaded functions 1245 in Ada. SIGPLAN Notices (1981) 16:2 p.48-52 1246 1247 Unlike Baker, our system allows implicit type conversions for function 1248 arguments and return types; the problem then becomes to find the valid 1249 interpretation for an expression that has the unique minimal conversion cost, 1250 if such exists. 1251 Interpretations can be produced both by overloaded names and implicit 1252 conversions applied to existing interpretations; we have proposals to reduce 1253 the number of interpretations considered from both sources. 1254 To simplify the problem for this discussion, we will consider application 1255 resolution restricted to a domain of functions applied to variables, possibly 1256 in a nested manner (e.g. `f( g( x ), y )`, where `x` and `y` are variables and 1257 `f` and `g` are functions), and possibly in a typed context such as a variable 1258 initialization (e.g. `int i = f( x );`); the other aspects of Cforall type 1259 resolution should be able to be straightforwardly mapped into this model. 1260 The types of the symbol tables used for variable and function declarations 1261 look somewhat like the following: 1262 1263 variable_table = name_map( variable_name, variable_map ) 1264 1265 function_table = name_map( function_name, function_map ) 1266 1267 variable_map = multi_index( by_type( variable_type ), 1268 variable_decl_set ) 1269 1270 function_map = multi_index( by_int( n_params ), 1271 by_type( return_type ), 1272 function_decl_set ) 1273 1274 `variable_name` and `function_name` are likely simple strings, with `name_map` 1275 a hash table (or perhaps trie) mapping string keys to values. 1276 `variable_decl_set` and `function_decl_set` can be thought of for the moment 1277 as simple bags of typed declarations, where the declaration types are linked 1278 to the graph of available conversions for that type. 1279 In a typed context both the `variable_decl_set` and the `function_decl_set` 1280 should be able to be selected upon by type; this is accomplished by the 1281 `by_type` index of both `variable_map` and `function_map`. 1282 The `by_int` index of `function_map` also provides a way to select functions 1283 by their number of parameters; this index may be used to swiftly discard any 1284 function declaration which does not have the appropriate number of parameters 1285 for the argument interpretations being passed to it; given the likely small 1286 number of entries in this map, it is possible that a binary search of a sorted 1287 vector or even a linear search of an unsorted vector would be more efficient 1288 than the usual hash-based index. 1289 1290 Given these data structures, the general outline of our algorithm follows 1291 Baker, with Cormack's algorithm used as a heuristic filter in typed contexts. 1292 1293 In an untyped context, we use a variant of Baker's bottom-up algorithm. 1294 The leaves of the interpretation DAG are drawn from the variable symbol table, 1295 with entries in the table each producing zero-cost interpretations, and each 1296 implicit conversion available to be applied to the type of an existing entry 1297 producing a further interpretation with the same cost as the conversion. 1298 As in Baker, if two or more interpretations have the same type, only the 1299 minimum cost interpretation with that type is produced; if there is no unique 1300 minimum cost interpretation than resolution with that type is ambiguous, and 1301 not permitted. 1302 It should be relatively simple to produce the list of interpretations sorted 1303 by cost by producing the interpretations via a breadth-first search of the 1304 conversion graph from the initial interpretations provided in the variable 1305 symbol table. 1306 1307 To match a function at one of the internal nodes of the DAG, we first look up 1308 the function's name in the function symbol table, the appropriate number of 1309 parameters for the arguments that are provided through the `by_int` index of 1310 the returned `function_map`, then go through the resulting `function_decl_set` 1311 searching for functions where the parameter types can unify with the provided 1312 argument lists; any such matching function produces an interpretation with a 1313 cost that is the sum of its argument costs. 1314 Though this is not included in our simplified model, this unification step may 1315 include binding of polymorphic variables, which introduces a cost for the 1316 function binding itself which must be added to the argument costs. 1317 Also, checking of function assertions would likely be done at this step as 1318 well, possibly eliminating some possible matching functions (if no suitable 1319 assertions can be satisfied), or adding further conversion costs for the 1320 assertion satisfaction. 1321 Once the set of valid function interpretations is produced, these may also be 1322 expanded by the graph of implicit conversions on their return types, as the 1323 variable interpretations were. 1324 1325 This implicit conversion-based expansion of interpretations should be skipped 1326 for the top-level expression if used in an untyped (void) context, e.g. for 1327 `f` in `f( g ( x ) );` or `x` in `x;`. 1328 On the other hand, if the top-level expression specifies a type, e.g. in 1329 `int i = f( x );`, only top level expressions that return that type are 1330 relevant to the search, so the candidates for `f` can be filtered first by 1331 those that return `int` (or a type convertable to it); this can be 1332 accomplished by performing a top-down filter of the interpretations of `f` by 1333 the `by_type` index of the `function_map` in a manner similar to Cormack's[4] 1334 algorithm. 1335 1336 In a typed context, such as an initialization expression 1337 `T x = f( g( y ), z );`, only interpretations of `f( g( y ), z )` which have 1338 type `T` are valid; since there are likely to be valid interpretations of 1339 `f( g( y ), z )` which cannot be used to initialize a variable of type `T`, we 1340 can use this information to reduce the number of interpretations considered. 1341 Drawing from Cormack[4], we first search for interpretations of `f` where the 1342 return type is `T`; by breadth-first-search of the conversion graph, it should 1343 be straightforward to order the interpretations of `f` by the cost to convert 1344 their return type to `T`. 1345 We can also filter out interpretations of `f` with less than two parameters, 1346 since both `g( y )` and `z` must produce at least one parameter; we may not, 1347 however, rule out interpretations of `f` with more than two parameters, as 1348 there may be a valid interpretation of `g( y )` as a function returning more 1349 than one parameter (if the expression was `f( y, z )` instead, we could use an 1350 exact parameter count, assuming that variables of tuple type don't exist). 1351 For each compatible interpretation of `f`, we can add the type of the first 1352 parameter of that interpretation of `f` to a set `S`, and recursively search 1353 for interpretations of `g( y )` that return some type `Si` in `S`, and 1354 similarly for interpretations of `z` that match the type of any of the second 1355 parameters of some `f`. 1356 Naturally, if no matching interpretation of `g( y )` can be found for the 1357 first parameter of some `f`, the type of the second parameter of that `f` will 1358 not be added to the set of valid types for `z`. 1359 Each node in this interpretation DAG is given a cost the same way it would be 1360 in the bottom-up approach, with the exception that when going top-down there 1361 must be a final bottom-up pass to sum the interpretation costs and sort them 1362 as appropriate. 1363 1364 If a parameter type for some `f` is a polymorphic type variable that is left 1365 unbound by the return type (e.g. `forall(otype S) int f(S x, int y)`), the 1366 matching arguments should be found using the bottom-up algorithm above for 1367 untyped contexts, because the polymorphic type variable does not sufficiently 1368 constrain the available interpretations of the argument expression. 1369 Similarly, it would likely be an advantage to use top-down resolution for 1370 cast expressions (e.g. `(int)x`), even when those cast expressions are 1371 subexpressions of an otherwise untyped expression. 1372 It may also be fruitful to switch between the bottom-up and top-down 1373 algorithms if the number of valid interpretations for a subexpression or valid 1374 types for an argument exceeds some heuristic threshold, but finding such 1375 a threshold (if any exists) will require experimental data. 1376 This hybrid top-down/bottom-up search provides more opportunities for pruning 1377 interpretations than either a bottom-up or top-down approach alone, and thus 1378 may be more efficient than either. 1379 A top-down-only approach, however, devolves to linear search through every 1380 possible interpretation in the solution space in an untyped context, and is 1381 thus likely to be inferior to a strictly bottom-up approach, though this 1382 hypothesis needs to be empirically validated. 1383 1384 Both Baker and Cormack explicitly generate all possible interpretations of a 1385 given expression; thinking of the set of interpretations of an expression as a 1386 list sorted by cost, this is an eager evaluation of the list. 1387 However, since we generally expect that user programmers will not often use 1388 high-cost implicit conversions, one potentially effective way to prune the 1389 search space would be to first find the minimal-cost interpretations of any 1390 given subexpression, then to save the resolution progress of the 1391 subexpressions and attempt to resolve the superexpression using only those 1392 subexpression interpretations. 1393 If no valid interpretation of the superexpression can be found, the resolver 1394 would then repeatedly find the next-most-minimal cost interpretations of the 1395 subexpressions and attempt to produce the minimal cost interpretation of the 1396 superexpression. 1397 This process would proceed until all possible subexpression interpretations 1398 have been found and considered. 1399 1400 A middle ground between the eager and lazy approaches can be taken by 1401 considering the lexical order on the cost tuple; essentially, every 1402 interpretation in each of the classes below will be strictly cheaper than any 1403 interpretation in the class after it, so if a min-cost valid interpretation 1404 can be found while only generating interpretations in a given class, that 1405 interpretation is guaranteed to be the best possible one: 1406 1407 1. Interpretations without polymorphic functions or implicit conversions 1408 2. Interpretations without polymorphic functions using only safe conversions 1409 3. Interpretations using polymorphic functions without unsafe conversions 1410 4. Interpretations using unsafe conversions 1411 1412 In this lazy-eager approach, all the interpretations in one class would be 1413 eagerly generated, while the interpretations in the next class would only be 1414 considered if no match was found in the previous class. 1415 1226 1416 ## Appendix A: Partial and Total Orders ## 1227 1417 The `<=` relation on integers is a commonly known _total order_, and -
src/CodeGen/CodeGenerator.cc
r6cbc25a r7ff30d07 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Fri May 06 16:01:00 201613 // Update Count : 25 511 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jun 9 13:21:00 2016 13 // Update Count : 256 14 14 // 15 15 … … 251 251 //*** Expressions 252 252 void CodeGenerator::visit( ApplicationExpr *applicationExpr ) { 253 extension( applicationExpr ); 253 254 if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( applicationExpr->get_function() ) ) { 254 255 OperatorInfo opInfo; … … 366 367 367 368 void CodeGenerator::visit( UntypedExpr *untypedExpr ) { 369 extension( untypedExpr ); 368 370 if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) { 369 371 OperatorInfo opInfo; … … 450 452 451 453 void CodeGenerator::visit( NameExpr *nameExpr ) { 454 extension( nameExpr ); 452 455 OperatorInfo opInfo; 453 456 if ( operatorLookup( nameExpr->get_name(), opInfo ) ) { … … 460 463 461 464 void CodeGenerator::visit( AddressExpr *addressExpr ) { 465 extension( addressExpr ); 462 466 output << "(&"; 463 467 // this hack makes sure that we don't convert "constant_zero" to "0" if we're taking its address … … 471 475 472 476 void CodeGenerator::visit( CastExpr *castExpr ) { 477 extension( castExpr ); 473 478 output << "("; 474 479 if ( castExpr->get_results().empty() ) { … … 493 498 494 499 void CodeGenerator::visit( MemberExpr *memberExpr ) { 500 extension( memberExpr ); 495 501 memberExpr->get_aggregate()->accept( *this ); 496 502 output << "." << mangleName( memberExpr->get_member() ); … … 498 504 499 505 void CodeGenerator::visit( VariableExpr *variableExpr ) { 506 extension( variableExpr ); 500 507 OperatorInfo opInfo; 501 508 if ( variableExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( variableExpr->get_var()->get_name(), opInfo ) && opInfo.type == OT_CONSTANT ) { … … 508 515 void CodeGenerator::visit( ConstantExpr *constantExpr ) { 509 516 assert( constantExpr->get_constant() ); 517 extension( constantExpr ); 510 518 constantExpr->get_constant()->accept( *this ); 511 519 } 512 520 513 521 void CodeGenerator::visit( SizeofExpr *sizeofExpr ) { 522 extension( sizeofExpr ); 514 523 output << "sizeof("; 515 524 if ( sizeofExpr->get_isType() ) { … … 522 531 523 532 void CodeGenerator::visit( AlignofExpr *alignofExpr ) { 533 extension( alignofExpr ); 524 534 // use GCC extension to avoid bumping std to C11 525 535 output << "__alignof__("; … … 537 547 538 548 void CodeGenerator::visit( OffsetofExpr *offsetofExpr ) { 549 extension( offsetofExpr ); 539 550 // use GCC builtin 540 551 output << "__builtin_offsetof("; … … 549 560 550 561 void CodeGenerator::visit( LogicalExpr *logicalExpr ) { 562 extension( logicalExpr ); 551 563 output << "("; 552 564 logicalExpr->get_arg1()->accept( *this ); … … 561 573 562 574 void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) { 575 extension( conditionalExpr ); 563 576 output << "("; 564 577 conditionalExpr->get_arg1()->accept( *this ); … … 571 584 572 585 void CodeGenerator::visit( CommaExpr *commaExpr ) { 586 extension( commaExpr ); 573 587 output << "("; 574 588 commaExpr->get_arg1()->accept( *this ); … … 583 597 584 598 void CodeGenerator::visit( AsmExpr *asmExpr ) { 599 extension( asmExpr ); 585 600 if ( asmExpr->get_inout() ) { 586 601 output << "[ "; -
src/CodeGen/CodeGenerator.h
r6cbc25a r7ff30d07 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 17:32:24201613 // Update Count : 2 812 // Last Modified On : Thu Jun 9 13:15:58 2016 13 // Update Count : 29 14 14 // 15 15 … … 96 96 std::ostream& operator()(std::ostream & os); 97 97 }; 98 99 void extension( Expression *expr ) { 100 if ( expr->get_extension() ) { 101 output << "__extension__ "; 102 } // if 103 } // extension 98 104 private: 99 105 -
src/Common/utility.h
r6cbc25a r7ff30d07 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Thu Apr 28 13:18:24201613 // Update Count : 1611 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jun 8 17:33:59 2016 13 // Update Count : 22 14 14 // 15 15 … … 33 33 } 34 34 35 template<typename T, typename U> 36 struct maybeBuild_t { 37 static T * doit( const U *orig ) { 38 if ( orig ) { 39 return orig->build(); 40 } else { 41 return 0; 42 } // if 43 } 44 }; 45 35 46 template< typename T, typename U > 36 47 static inline T * maybeBuild( const U *orig ) { 37 if ( orig ) { 38 return orig->build(); 39 } else { 40 return 0; 41 } // if 48 return maybeBuild_t<T,U>::doit(orig); 42 49 } 43 50 -
src/Parser/ExpressionNode.cc
r6cbc25a r7ff30d07 10 10 // Created On : Sat May 16 13:17:07 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Apr 8 15:43:05201613 // Update Count : 29612 // Last Modified On : Mon Jun 13 14:46:17 2016 13 // Update Count : 307 14 14 // 15 15 … … 32 32 using namespace std; 33 33 34 ExpressionNode::ExpressionNode() : ParseNode() , argName( 0 ){}35 36 ExpressionNode::ExpressionNode( const string *name ) : ParseNode( name ) , argName( 0 ){}37 38 ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ) {34 ExpressionNode::ExpressionNode() : ParseNode() {} 35 36 ExpressionNode::ExpressionNode( const string *name ) : ParseNode( name ) {} 37 38 ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ), extension( other.extension ) { 39 39 if ( other.argName ) { 40 40 argName = other.argName->clone(); … … 344 344 345 345 Expression *DesignatorNode::build() const { 346 Expression * ret = get_argName()->build();346 Expression * ret = maybeBuild<Expression>(get_argName()); 347 347 348 348 if ( isArrayIndex ) { … … 389 389 "Cond", "NCond", 390 390 // diadic 391 "SizeOf", "AlignOf", "OffsetOf", "Attr", " CompLit", "?+?", "?-?", "?*?", "?/?", "?%?", "||", "&&",391 "SizeOf", "AlignOf", "OffsetOf", "Attr", "?+?", "?-?", "?*?", "?/?", "?%?", "||", "&&", 392 392 "?|?", "?&?", "?^?", "Cast", "?<<?", "?>>?", "?<?", "?>?", "?<=?", "?>=?", "?==?", "?!=?", 393 393 "?=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?", "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?", … … 466 466 467 467 if ( ! ( op = dynamic_cast<OperatorNode *>( function ) ) ) { // function as opposed to operator 468 return new UntypedExpr( function->build(), args, maybeBuild< Expression >( get_argName() ));468 return new UntypedExpr( maybeBuild<Expression>(function), args, maybeBuild< Expression >( get_argName() )); 469 469 } // if 470 470 … … 550 550 if ( dynamic_cast< VoidType* >( targetType ) ) { 551 551 delete targetType; 552 return new CastExpr( expr_node->build(), maybeBuild< Expression >( get_argName() ) );552 return new CastExpr( maybeBuild<Expression>(expr_node), maybeBuild< Expression >( get_argName() ) ); 553 553 } else { 554 return new CastExpr( expr_node->build(),targetType, maybeBuild< Expression >( get_argName() ) );554 return new CastExpr( maybeBuild<Expression>(expr_node),targetType, maybeBuild< Expression >( get_argName() ) ); 555 555 } // if 556 556 } … … 621 621 assert( var ); 622 622 if ( ! get_args()->get_link() ) { 623 return new AttrExpr( var->build(), ( Expression*)0);623 return new AttrExpr( maybeBuild<Expression>(var), ( Expression*)0); 624 624 } else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()->get_link()) ) { 625 return new AttrExpr( var->build(), arg->get_decl()->buildType());625 return new AttrExpr( maybeBuild<Expression>(var), arg->get_decl()->buildType()); 626 626 } else { 627 return new AttrExpr( var->build(), args.back()); 628 } // if 629 } 630 case OperatorNode::CompLit: 631 throw UnimplementedError( "C99 compound literals" ); 632 // the short-circuited operators 627 return new AttrExpr( maybeBuild<Expression>(var), args.back()); 628 } // if 629 } 633 630 case OperatorNode::Or: 634 631 case OperatorNode::And: … … 719 716 720 717 Expression *AsmExprNode::build() const { 721 return new AsmExpr( maybeBuild< Expression >( inout ), (ConstantExpr *) constraint->build(), operand->build() );718 return new AsmExpr( maybeBuild< Expression >( inout ), (ConstantExpr *)maybeBuild<Expression>(constraint), maybeBuild<Expression>(operand) ); 722 719 } 723 720 … … 796 793 797 794 Expression *ValofExprNode::build() const { 798 return new UntypedValofExpr ( get_body()->build(), maybeBuild< Expression >( get_argName() ) );795 return new UntypedValofExpr ( maybeBuild<Statement>(get_body()), maybeBuild< Expression >( get_argName() ) ); 799 796 } 800 797 … … 908 905 909 906 Expression *CompoundLiteralNode::build() const { 910 Declaration * newDecl = type->build();// compound literal type907 Declaration * newDecl = maybeBuild<Declaration>(type); // compound literal type 911 908 if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type 912 return new CompoundLiteralExpr( newDeclWithType->get_type(), kids->build() );909 return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeBuild<Initializer>(kids) ); 913 910 // these types do not have associated type information 914 911 } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl ) ) { 915 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), kids->build() );912 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), maybeBuild<Initializer>(kids) ); 916 913 } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl ) ) { 917 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), kids->build() );914 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), maybeBuild<Initializer>(kids) ); 918 915 } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl ) ) { 919 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), kids->build() );916 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), maybeBuild<Initializer>(kids) ); 920 917 } else { 921 918 assert( false ); -
src/Parser/ParseNode.h
r6cbc25a r7ff30d07 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 13:28:16 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Thu Apr 14 15:37:52201613 // Update Count : 2 0511 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jun 13 16:04:47 2016 13 // Update Count : 240 14 14 // 15 15 … … 20 20 #include <list> 21 21 #include <iterator> 22 #include <memory> 22 23 23 24 #include "Common/utility.h" 24 25 #include "Parser/LinkageSpec.h" 25 26 #include "SynTree/Type.h" 27 #include "SynTree/Expression.h" 26 28 //#include "SynTree/Declaration.h" 27 29 #include "Common/UniqueName.h" … … 79 81 ExpressionNode *set_argName( const std::string *aName ); 80 82 ExpressionNode *set_argName( ExpressionNode *aDesignator ); 83 bool get_extension() const { return extension; } 84 ExpressionNode *set_extension( bool exten ) { extension = exten; return this; } 81 85 82 86 virtual void print( std::ostream &, int indent = 0) const = 0; … … 87 91 void printDesignation ( std::ostream &, int indent = 0) const; 88 92 private: 89 ExpressionNode *argName; 93 ExpressionNode *argName = 0; 94 bool extension = false; 95 }; 96 97 template< typename T > 98 struct maybeBuild_t<Expression, T> { 99 static inline Expression * doit( const T *orig ) { 100 if ( orig ) { 101 Expression *p = orig->build(); 102 p->set_extension( orig->get_extension() ); 103 return p; 104 } else { 105 return 0; 106 } // if 107 } 90 108 }; 91 109 … … 179 197 Cond, NCond, 180 198 // diadic 181 SizeOf, AlignOf, OffsetOf, Attr, CompLit,Plus, Minus, Mul, Div, Mod, Or, And,199 SizeOf, AlignOf, OffsetOf, Attr, Plus, Minus, Mul, Div, Mod, Or, And, 182 200 BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq, 183 201 Assign, MulAssn, DivAssn, ModAssn, PlusAssn, MinusAssn, LSAssn, RSAssn, AndAssn, ERAssn, OrAssn, … … 574 592 while ( cur ) { 575 593 try { 576 SynTreeType *result = dynamic_cast< SynTreeType *>( cur->build() ); 594 // SynTreeType *result = dynamic_cast< SynTreeType *>( maybeBuild<typename std::result_of<decltype(&NodeType::build)(NodeType)>::type>( cur ) ); 595 SynTreeType *result = dynamic_cast< SynTreeType *>( maybeBuild<typename std::pointer_traits<decltype(cur->build())>::element_type>( cur ) ); 577 596 if ( result ) { 578 597 *out++ = result; -
src/Parser/StatementNode.cc
r6cbc25a r7ff30d07 10 10 // Created On : Sat May 16 14:59:41 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Ju l 30 14:39:39 201513 // Update Count : 13 012 // Last Modified On : Thu Jun 9 14:18:46 2016 13 // Update Count : 132 14 14 // 15 15 … … 222 222 branches.pop_front(); 223 223 } // if 224 return new IfStmt( labs, notZeroExpr( get_control()->build() ), thenb, elseb );224 return new IfStmt( labs, notZeroExpr( maybeBuild<Expression>(get_control()) ), thenb, elseb ); 225 225 } 226 226 case While: 227 227 assert( branches.size() == 1 ); 228 return new WhileStmt( labs, notZeroExpr( get_control()->build() ), branches.front() );228 return new WhileStmt( labs, notZeroExpr( maybeBuild<Expression>(get_control()) ), branches.front() ); 229 229 case Do: 230 230 assert( branches.size() == 1 ); 231 return new WhileStmt( labs, notZeroExpr( get_control()->build() ), branches.front(), true );231 return new WhileStmt( labs, notZeroExpr( maybeBuild<Expression>(get_control()) ), branches.front(), true ); 232 232 case For: 233 233 { … … 244 244 Expression *cond = 0; 245 245 if ( ctl->get_condition() != 0 ) 246 cond = notZeroExpr( ctl->get_condition()->build() );246 cond = notZeroExpr( maybeBuild<Expression>(ctl->get_condition()) ); 247 247 248 248 Expression *incr = 0; 249 249 if ( ctl->get_change() != 0 ) 250 incr = ctl->get_change()->build();250 incr = maybeBuild<Expression>(ctl->get_change()); 251 251 252 252 return new ForStmt( labs, init, cond, incr, branches.front() ); 253 253 } 254 254 case Switch: 255 return new SwitchStmt( labs, get_control()->build(), branches );255 return new SwitchStmt( labs, maybeBuild<Expression>(get_control()), branches ); 256 256 case Choose: 257 return new ChooseStmt( labs, get_control()->build(), branches );257 return new ChooseStmt( labs, maybeBuild<Expression>(get_control()), branches ); 258 258 case Fallthru: 259 259 return new FallthruStmt( labs ); 260 260 case Case: 261 return new CaseStmt( labs, get_control()->build(), branches );261 return new CaseStmt( labs, maybeBuild<Expression>(get_control()), branches ); 262 262 case Default: 263 263 return new CaseStmt( labs, 0, branches, true ); … … 266 266 if ( get_target() == "" ) { // computed goto 267 267 assert( get_control() != 0 ); 268 return new BranchStmt( labs, get_control()->build(), BranchStmt::Goto );268 return new BranchStmt( labs, maybeBuild<Expression>(get_control()), BranchStmt::Goto ); 269 269 } // if 270 270 -
src/Parser/parser.cc
r6cbc25a r7ff30d07 5299 5299 /* Line 1806 of yacc.c */ 5300 5300 #line 432 "parser.yy" 5301 { (yyval.en) = (yyvsp[(2) - (2)].en) ; }5301 { (yyval.en) = (yyvsp[(2) - (2)].en)->set_extension( true ); } 5302 5302 break; 5303 5303 … … 5809 5809 /* Line 1806 of yacc.c */ 5810 5810 #line 685 "parser.yy" 5811 { (yyval.sn) = new StatementNode( (yyvsp[(2) - (2)].decl) ) ; }5811 { (yyval.sn) = new StatementNode( (yyvsp[(2) - (2)].decl) )/*->set_extension( true )*/; } 5812 5812 break; 5813 5813 … … 7122 7122 /* Line 1806 of yacc.c */ 7123 7123 #line 1475 "parser.yy" 7124 { (yyval.decl) = (yyvsp[(2) - (3)].decl) ; }7124 { (yyval.decl) = (yyvsp[(2) - (3)].decl)/*->set_extension( true )*/; } 7125 7125 break; 7126 7126 … … 7129 7129 /* Line 1806 of yacc.c */ 7130 7130 #line 1478 "parser.yy" 7131 { (yyval.decl) = (yyvsp[(2) - (3)].decl) ; }7131 { (yyval.decl) = (yyvsp[(2) - (3)].decl)/*->set_extension( true )*/; } 7132 7132 break; 7133 7133 … … 7913 7913 /* Line 1806 of yacc.c */ 7914 7914 #line 1994 "parser.yy" 7915 { (yyval.decl) = (yyvsp[(2) - (2)].decl) ; }7915 { (yyval.decl) = (yyvsp[(2) - (2)].decl)/*->set_extension( true )*/; } 7916 7916 break; 7917 7917 -
src/Parser/parser.yy
r6cbc25a r7ff30d07 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Jun 7 08:08:31201613 // Update Count : 15 6012 // Last Modified On : Mon Jun 13 15:00:23 2016 13 // Update Count : 1578 14 14 // 15 15 … … 430 430 { $$ = $1; } 431 431 | EXTENSION cast_expression // GCC 432 { $$ = $2 ; }432 { $$ = $2->set_extension( true ); } 433 433 | ptrref_operator cast_expression // CFA 434 434 { $$ = new CompositeExprNode( $1, $2 ); } … … 683 683 { $$ = new StatementNode( $1 ); } 684 684 | EXTENSION declaration // GCC 685 { $$ = new StatementNode( $2 ) ; }685 { $$ = new StatementNode( $2 )/*->set_extension( true )*/; } 686 686 | function_definition 687 687 { $$ = new StatementNode( $1 ); } … … 1473 1473 new_field_declaring_list ';' // CFA, new style field declaration 1474 1474 | EXTENSION new_field_declaring_list ';' // GCC 1475 { $$ = $2 ; }1475 { $$ = $2/*->set_extension( true )*/; } 1476 1476 | field_declaring_list ';' 1477 1477 | EXTENSION field_declaring_list ';' // GCC 1478 { $$ = $2 ; }1478 { $$ = $2/*->set_extension( true )*/; } 1479 1479 ; 1480 1480 … … 1992 1992 } 1993 1993 | EXTENSION external_definition 1994 { $$ = $2 ; }1994 { $$ = $2/*->set_extension( true )*/; } 1995 1995 ; 1996 1996 -
src/ResolvExpr/AlternativeFinder.cc
r6cbc25a r7ff30d07 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sat May 16 23:52:08 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Wed Apr 20 14:24:03201613 // Update Count : 2 411 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jun 13 16:13:54 2016 13 // Update Count : 25 14 14 // 15 15 … … 757 757 for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) { 758 758 VariableExpr newExpr( *i, nameExpr->get_argName() ); 759 newExpr.set_extension( nameExpr->get_extension() ); 759 760 alternatives.push_back( Alternative( newExpr.clone(), env, Cost() ) ); 760 761 PRINT( -
src/SynTree/Expression.cc
r6cbc25a r7ff30d07 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Fri May 13 13:23:11201613 // Update Count : 4 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jun 13 16:03:39 2016 13 // Update Count : 42 14 14 // 15 15 … … 32 32 Expression::Expression( Expression *_aname ) : env( 0 ), argName( _aname ) {} 33 33 34 Expression::Expression( const Expression &other ) : env( maybeClone( other.env ) ), argName( maybeClone( other.get_argName() ) ) {34 Expression::Expression( const Expression &other ) : env( maybeClone( other.env ) ), argName( maybeClone( other.get_argName() ) ), extension( other.extension ) { 35 35 cloneAll( other.results, results ); 36 36 } … … 59 59 os << std::string( indent, ' ' ) << "with designator:"; 60 60 argName->print( os, indent+2 ); 61 } // if 62 63 if ( extension ) { 64 os << std::string( indent, ' ' ) << "with extension:"; 61 65 } // if 62 66 } -
src/SynTree/Expression.h
r6cbc25a r7ff30d07 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Wed Apr 27 17:06:49201613 // Update Count : 2 111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jun 8 17:05:30 2016 13 // Update Count : 22 14 14 // 15 15 … … 38 38 Expression *get_argName() const { return argName; } 39 39 void set_argName( Expression *name ) { argName = name; } 40 bool get_extension() const { return extension; } 41 void set_extension( bool exten ) { extension = exten; } 40 42 41 43 virtual Expression *clone() const = 0; … … 47 49 TypeSubstitution *env; 48 50 Expression* argName; // if expression is used as an argument, it can be "designated" by this name 51 bool extension = false; 49 52 }; 50 53 -
src/Tests/Abstype.c
r6cbc25a r7ff30d07 1 type T | { T x( T ); };1 otype T | { T x( T ); }; 2 2 3 3 T y( T t ) { … … 6 6 } 7 7 8 forall( type T ) lvalue T *?( T * );8 forall( otype T ) lvalue T *?( T * ); 9 9 int ?++( int * ); 10 10 int ?=?( int *, int ); 11 11 forall( dtype DT ) DT * ?=?( DT **, DT * ); 12 12 13 type U = int *;13 otype U = int *; 14 14 15 15 U x( U u ) { -
src/Tests/Attributes.c
r6cbc25a r7ff30d07 6 6 // @max 7 7 // 8 // 2. a direct application to a manifest type8 // 2. a direct application to a manifest otype 9 9 // 10 10 // @max( int ) 11 11 // 12 // 3. constraining a type variable; the application is implicitly performed at the call site as in (2)12 // 3. constraining a otype variable; the application is implicitly performed at the call site as in (2) 13 13 // 14 // forall( type T | { T @max( T ); } ) T x( T t );14 // forall( otype T | { T @max( T ); } ) T x( T t ); 15 15 // 16 16 // … … 23 23 // x = (*attr_var); 24 24 // 25 // 2. an indirect application to a manifest type25 // 2. an indirect application to a manifest otype 26 26 // 27 27 // (*attr_var)( int ) 28 28 // 29 // 3. a direct application to a type variable29 // 3. a direct application to a otype variable 30 30 // 31 31 // @max( T ) … … 47 47 // 3. polymorphic 48 48 // 49 // forall( type T | constraint( T ) ) int @attr( T );49 // forall( otype T | constraint( T ) ) int @attr( T ); 50 50 51 51 int @max = 3; … … 53 53 int main() { 54 54 int x; 55 type @type(type t); // compiler intrinsic56 type @widest(type t);57 @ type(x) *y; // gcc:typeof(x) *y;58 const @widest(double) *w; // gcc: const typeof(x) *w;59 * @ type(3 + 4) z; // cfa declaration syntax55 otype @otype(otype t); // compiler intrinsic 56 otype @widest(otype t); 57 @otype(x) *y; // gcc: otypeof(x) *y; 58 const @widest(double) *w; // gcc: const otypeof(x) *w; 59 * @otype(3 + 4) z; // cfa declaration syntax 60 60 y = @max; 61 61 z = @max(x) + @size(int); -
src/Tests/InferParam.c
r6cbc25a r7ff30d07 3 3 double ?=?( double*, double ); 4 4 5 forall( type T,type U | { U f(T); } ) U g(T);5 forall( otype T, otype U | { U f(T); } ) U g(T); 6 6 float f( int ); 7 7 double f( int ); … … 13 13 } 14 14 15 context has_f_and_j( type T,type U ) {15 context has_f_and_j( otype T, otype U ) { 16 16 U f( T ); 17 17 U j( T, U ); … … 19 19 20 20 float j( int, float ); 21 forall( type T,type U | has_f_and_j( T, U ) ) U k( T );21 forall( otype T, otype U | has_f_and_j( T, U ) ) U k( T ); 22 22 23 23 void l() { -
src/Tests/Makefile
r6cbc25a r7ff30d07 1 CFA ?= ../ cfa-cpp1 CFA ?= ../driver/cfa-cpp 2 2 CFAOPT ?= -a 3 3 OUTPUT ?= Output … … 32 32 33 33 ${OUTPUTDIR} : 34 mkdir $@34 mkdir -p $@ 35 35 36 36 # remove the expected results directories to generate new ones from the current output -
src/Tests/Members.c
r6cbc25a r7ff30d07 3 3 float ?=?( float*, float ); 4 4 forall( dtype DT ) DT * ?=?( DT**, DT* ); 5 forall( type T) lvalue T *?( T* );5 forall(otype T) lvalue T *?( T* ); 6 6 char *__builtin_memcpy(); 7 7 -
src/Tests/OccursError.c
r6cbc25a r7ff30d07 1 forall( type T ) void f( void (*)( T, T* ) );2 forall( type U ) void g( U*, U );1 forall( otype T ) void f( void (*)( T, T* ) ); 2 forall( otype U ) void g( U*, U ); 3 3 4 4 void test() { -
src/Tests/Quad.c
r6cbc25a r7ff30d07 2 2 int ?*?( int, int ); 3 3 4 forall( type T | { T ?*?( T, T ); } )4 forall( otype T | { T ?*?( T, T ); } ) 5 5 T square( T t ) { 6 6 return t * t; 7 7 } 8 8 9 forall( type U | { U square( U ); } )9 forall( otype U | { U square( U ); } ) 10 10 U quad( U u ) { 11 11 return square( square( u ) ); -
src/Tests/Rank2.c
r6cbc25a r7ff30d07 3 3 4 4 void a() { 5 forall( type T ) void f( T );6 void g( forall( type U ) void p( U ) );5 forall( otype T ) void f( T ); 6 void g( forall( otype U ) void p( U ) ); 7 7 g( f ); 8 8 } … … 10 10 void g() { 11 11 void h( int *null ); 12 forall( type T ) T id( T );12 forall( otype T ) T id( T ); 13 13 forall( dtype T ) T *0; 14 14 int 0; -
src/driver/cc1.cc
r6cbc25a r7ff30d07 10 10 // Created On : Fri Aug 26 14:23:51 2005 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jun 2 17:24:26201613 // Update Count : 7912 // Last Modified On : Fri Jun 10 09:27:37 2016 13 // Update Count : 80 14 14 // 15 15 … … 151 151 i += 1; // and the argument 152 152 cpp_flag = true; 153 } else if ( arg == "-D__CFA_ _" ) {153 } else if ( arg == "-D__CFA_PREPROCESS__" ) { 154 154 CFA_flag = true; 155 } else if ( arg == "-D" && string( argv[i + 1] ) == "__CFA_ _" ) {155 } else if ( arg == "-D" && string( argv[i + 1] ) == "__CFA_PREPROCESS__" ) { 156 156 i += 1; // and the argument 157 157 CFA_flag = true; -
src/driver/cfa.cc
r6cbc25a r7ff30d07 10 10 // Created On : Tue Aug 20 13:44:49 2002 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jun 2 17:24:25201613 // Update Count : 13 712 // Last Modified On : Fri Jun 10 09:26:19 2016 13 // Update Count : 138 14 14 // 15 15 … … 263 263 args[nargs] = ( *new string( string("-D__CFA_PATCHLEVEL__=") + Patch ) ).c_str(); 264 264 nargs += 1; 265 args[nargs] = "-D__CFORALL__=1"; 265 args[nargs] = "-D__CFA__"; 266 nargs += 1; 267 args[nargs] = "-D__CFORALL__"; 266 268 nargs += 1; 267 269 … … 272 274 273 275 if ( CFA_flag ) { 274 args[nargs] = "-D__CFA_ _";276 args[nargs] = "-D__CFA_PREPROCESS_"; 275 277 nargs += 1; 276 278 } // if -
src/libcfa/Makefile.am
r6cbc25a r7ff30d07 11 11 ## Created On : Sun May 31 08:54:01 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Wed Jun 8 14:20:34201614 ## Update Count : 16 513 ## Last Modified On : Mon Jun 13 14:27:22 2016 14 ## Update Count : 166 15 15 ############################################################################### 16 16 … … 50 50 @BACKEND_CC@ -c -o $@ $< 51 51 52 CFLAGS = - g -Wall -Wno-unused-function -B${abs_top_srcdir}/src/driver -XCFA -t # TEMPORARY: does not build with -O252 CFLAGS = -quiet -g -Wall -Wno-unused-function -B${abs_top_srcdir}/src/driver -XCFA -t # TEMPORARY: does not build with -O2 53 53 CC = ${abs_top_srcdir}/src/driver/cfa 54 54 -
src/tests/Array.c
r6cbc25a r7ff30d07 1 1 //Testing array declarations 2 2 int a1[]; 3 int a2[*];4 double a4[3.0];3 //int a2[*]; 4 //double a4[3.0]; 5 5 6 6 int m1[][3]; 7 int m2[*][*];7 //int m2[*][*]; 8 8 int m4[3][3]; 9 9 … … 11 11 12 12 int fred() { 13 int a1[];14 int a2[*];13 // int a1[]; 14 // int a2[*]; 15 15 int a4[3]; 16 16 int T[3]; -
src/tests/Forall.c
r6cbc25a r7ff30d07 7 7 8 8 void g1() { 9 forall( type T ) T f( T );9 forall( otype T ) T f( T ); 10 10 void f( int ); 11 11 void h( void (*p)(void) ); … … 24 24 25 25 void g2() { 26 forall( type T ) void f( T, T );27 forall( type T,type U ) void f( T, U );26 forall( otype T ) void f( T, T ); 27 forall( otype T, otype U ) void f( T, U ); 28 28 29 29 int x; … … 37 37 } 38 38 39 typedef forall ( type T ) int (*f)( int );39 typedef forall ( otype T ) int (*f)( int ); 40 40 41 forall( type T )41 forall( otype T ) 42 42 void swap( T left, T right ) { 43 43 T temp = left; … … 46 46 } 47 47 48 context sumable( type T ) {48 context sumable( otype T ) { 49 49 const T 0; 50 50 T ?+?(T, T); … … 53 53 }; 54 54 55 type T1 | { const T1 0; T1 ?+?(T1, T1); T1 ?++(T1); [T1] ?+=?(T1,T1); },56 T2( type P1,type P2 ),55 otype T1 | { const T1 0; T1 ?+?(T1, T1); T1 ?++(T1); [T1] ?+=?(T1,T1); }, 56 T2(otype P1, otype P2 ), 57 57 T3 | sumable(T3); 58 58 59 type T2(type P1,type P2) | sumable(T2(P1,P2)) = struct { P1 i; P2 j; };59 otype T2(otype P1, otype P2) | sumable(T2(P1,P2)) = struct { P1 i; P2 j; }; 60 60 61 61 T2(int, int) w1; 62 62 typedef T2(int, int) w2; 63 63 w2 g2; 64 type w3 = T2(int, int);64 otype w3 = T2(int, int); 65 65 w3 g3; 66 66 67 forall( type T | sumable( T ) )67 forall( otype T | sumable( T ) ) 68 68 T sum( int n, T a[] ) { 69 69 T total = 0; … … 74 74 } 75 75 76 forall( type T | { const T 0; T ?+?(T, T); T ?++(T); [T] ?+=?(T,T); } )76 forall( otype T | { const T 0; T ?+?(T, T); T ?++(T); [T] ?+=?(T,T); } ) 77 77 T twice( T t ) { 78 78 return t + t; 79 79 } 80 80 81 forall( type T | { const T 0; int ?!=?(T, T); int ?<?(T, T); } )81 forall( otype T | { const T 0; int ?!=?(T, T); int ?<?(T, T); } ) 82 82 T min( T t1, T t2 ) { 83 83 return t1 < t2 ? t1 : t2; -
src/tests/Functions.c
r6cbc25a r7ff30d07 28 28 int ((*f12())[])[3] {} 29 29 30 // "implicit int" type specifier (not ANSI)30 // "implicit int" otype specifier (not ANSI) 31 31 32 32 fII1( int i ) {} -
src/tests/GccExtensions.c
r6cbc25a r7ff30d07 19 19 __signed s2; 20 20 21 __ typeof(s1) t1;22 __ typeof__(s1) t2;21 __otypeof(s1) t1; 22 __otypeof__(s1) t2; 23 23 24 24 __volatile int v1; -
src/tests/Scope.c
r6cbc25a r7ff30d07 3 3 typedef float t; 4 4 y z; 5 type u = struct { int a; double b; };5 otype u = struct { int a; double b; }; 6 6 int f( int y ); 7 7 y q; 8 8 9 9 y w( y y, u v ) { 10 type x | { x t(u); };10 otype x | { x t(u); }; 11 11 u u = y; 12 12 x z = t(u); … … 15 15 y p; 16 16 17 context has_u( type z ) {17 context has_u( otype z ) { 18 18 z u(z); 19 19 }; 20 20 21 forall( type t | has_u( t ) )21 forall( otype t | has_u( t ) ) 22 22 y q( t the_t ) { 23 23 t y = u( the_t ); -
src/tests/Subrange.c
r6cbc25a r7ff30d07 1 // A small context defining the notion of an ordered type. (The standard1 // A small context defining the notion of an ordered otype. (The standard 2 2 // library should probably contain a context for this purpose.) 3 context ordered( type T) {3 context ordered(otype T) { 4 4 int ?<?(T, T), ?<=?(T, T); 5 5 }; 6 6 7 // A subrange type resembling an Ada subtype with a basetype and a range7 // A subrange otype resembling an Ada subotype with a base otype and a range 8 8 // constraint. 9 type subrange(type base_t | ordered(base_t), base_t low = 0, base_t high = 8) = base_t;9 otype subrange(otype base_t | ordered(base_t), base_t low = 0, base_t high = 8) = base_t; 10 10 11 // Note that subrange() can be applied to floating-point and pointer types, not12 // just integral types.13 // This requires a " type generator" extension to Cforall. Type generators14 // must accept type and non-type parameters, which is beyond what we discussed11 // Note that subrange() can be applied to floating-point and pointer otypes, not 12 // just integral otypes. 13 // This requires a "otype generator" extension to Cforall. Type generators 14 // must accept otype and non-otype parameters, which is beyond what we discussed 15 15 // previously. Type parameters must be usable in the declaration of 16 16 // subsequent parameters: parameter T is used to declare parameters "low" … … 22 22 subrange(int, 0, (rand() & 0xF) ) foo; 23 23 24 // What sorts of expressions can be used as arguments of type generators? Is24 // What sorts of expressions can be used as arguments of otype generators? Is 25 25 // "subrange(int, 0, rand() & 0xF)" legal? Probably. The nearest C equivalent 26 26 // to the "low" and "high" arguments is the array size in a variable-length … … 28 28 29 29 // Convenient access to subrange bounds, for instance for iteration: 30 forall ( type T, T low, T high)30 forall (otype T, T low, T high) 31 31 T lbound( subrange(T, low, high) v) { 32 32 return low; 33 33 } 34 34 35 forall ( type T, T low, T high)35 forall (otype T, T low, T high) 36 36 T hbound( subrange(T, low, high) v) { 37 37 return high; … … 41 41 unsigned lday = lbound(day_of_month); 42 42 43 // Assignment from the base type, with bounds checking. I'll ignore the issue43 // Assignment from the base otype, with bounds checking. I'll ignore the issue 44 44 // of exception handling here. Inlining allows the compiler to eliminate 45 45 // bounds checks. 46 forall ( type T | ordered(T), T low, T high)46 forall (otype T | ordered(T), T low, T high) 47 47 inline subrange(T, low, high) ?=?(subrange(T, low, high)* target, T source) { 48 48 if (low <= source && source <= high) *((T*)target) = source; … … 51 51 } 52 52 53 // Assignment between subranges with a common base type. The bounds check53 // Assignment between subranges with a common base otype. The bounds check 54 54 // compares range bounds so that the compiler can optimize checks away when the 55 55 // ranges are known to overlap. 56 forall ( type T | ordered(T), T t_low, T t_high, T s_low, T s_high)56 forall (otype T | ordered(T), T t_low, T t_high, T s_low, T s_high) 57 57 inline subrange(T, t_low, t_high) ?=?(subrange(T, t_low, t_high)* target, 58 58 subrange(T, s_low, s_high) source) { -
src/tests/TypeGenerator.c
r6cbc25a r7ff30d07 1 context addable( type T ) {1 context addable( otype T ) { 2 2 T ?+?( T,T ); 3 3 T ?=?( T*, T); 4 4 }; 5 5 6 type List1(type T | addable( T ) ) = struct { T data; List1( T ) *next; } *;6 otype List1( otype T | addable( T ) ) = struct { T data; List1( T ) *next; } *; 7 7 typedef List1( int ) ListOfIntegers; 8 8 //List1( int ) li; … … 11 11 [int] h( * List1( int ) p ); // new declaration syntax 12 12 13 struct( type T ) S2 { T i; }; // actual definition13 struct( otype T ) S2 { T i; }; // actual definition 14 14 struct( int ) S3 v1, *p; // expansion and instantiation 15 struct( type T )( int ) S24 { T i; } v2; // actual definition, expansion and instantiation16 struct( type T )( int ) { T i; } v2; // anonymous actual definition, expansion and instantiation15 struct( otype T )( int ) S24 { T i; } v2; // actual definition, expansion and instantiation 16 struct( otype T )( int ) { T i; } v2; // anonymous actual definition, expansion and instantiation 17 17 18 struct( type T | addable( T ) ) node { T data; struct( T ) node *next; };19 type List(type T ) = struct( T ) node *;18 struct( otype T | addable( T ) ) node { T data; struct( T ) node *next; }; 19 otype List( otype T ) = struct( T ) node *; 20 20 List( int ) my_list; 21 21 22 type Complex | addable( Complex );22 otype Complex | addable( Complex ); 23 23 24 24 int main() { -
src/tests/Typedef.c
r6cbc25a r7ff30d07 18 18 a c; 19 19 20 typedef typeof(3) x, y; // GCC20 typedef otypeof(3) x, y; // GCC 21 21 22 22 x p; … … 24 24 25 25 int main() { 26 typedef typeof(3) z, p;26 typedef otypeof(3) z, p; 27 27 z w; 28 28 p x; -
src/tests/Typeof.c
r6cbc25a r7ff30d07 1 1 int main() { 2 2 int *v1; 3 typeof(v1) v2;4 typeof(*v1) v3[4];3 otypeof(v1) v2; 4 otypeof(*v1) v3[4]; 5 5 char *v4[4]; 6 typeof(typeof(char *)[4]) v5;7 typeof (int *) v6;8 typeof( int ( int, int p ) ) *v7;9 typeof( [int] ( int, int p ) ) *v8;6 otypeof(otypeof(char *)[4]) v5; 7 otypeof (int *) v6; 8 otypeof( int ( int, int p ) ) *v7; 9 otypeof( [int] ( int, int p ) ) *v8; 10 10 } -
src/tests/io.c
r6cbc25a r7ff30d07 11 11 // Created On : Wed Mar 2 16:56:02 2016 12 12 // Last Modified By : Peter A. Buhr 13 // Last Modified On : Thu May 26 10:06:00201614 // Update Count : 2813 // Last Modified On : Wed Jun 8 22:52:04 2016 14 // Update Count : 30 15 15 // 16 16 … … 34 34 long double _Complex ldc; 35 35 char s1[10], s2[10]; 36 37 int x = 3, y = 5, z = 7; 38 sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl; 39 sout | 1 | 2 | 3 | endl; 40 sout | '1' | '2' | '3' | endl; 41 sout | 1 | "" | 2 | "" | 3 | endl; 42 sout | endl; 36 43 37 44 ifstream in; // create / open file
Note: See TracChangeset
for help on using the changeset viewer.