Changes in / [37218fc:3aba311]


Ignore:
Files:
5 added
11 deleted
38 edited

Legend:

Unmodified
Added
Removed
  • doc/refrat/Makefile

    r37218fc r3aba311  
    11## Define the appropriate configuration variables.
    22
    3 TeXLIB = .:../bibliography/:../LaTeXmacros/:
     3Macros =
     4TeXLIB = .:${Macros}:
    45LaTeX  = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex
    5 BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex
     6BibTeX = BSTINPUTS=${TeXLIB} && export BSTINPUTS && bibtex
    67
    78## Define the text source files.
     
    4344        dvips $< -o $@
    4445
    45 ${basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex \
    46                 ../LaTeXmacros/common.tex ../LaTeXmacros/indexstyle ../bibliography/cfa.bib
     46${basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex ${basename ${DOCUMENT}}.bib
    4747        # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run.
    4848        if [ ! -r ${basename $@}.ind ] ; then touch ${basename $@}.ind ; fi
     
    5454        -${BibTeX} ${basename $@}
    5555        # Make index from *.aux entries and input index at end of document
    56         makeindex -s ../LaTeXmacros/indexstyle ${basename $@}.idx
     56        makeindex -s indexstyle ${basename $@}.idx
    5757        ${LaTeX} ${basename $@}.tex
    5858        # Run again to get index title into table of contents
  • doc/refrat/refrat.tex

    r37218fc r3aba311  
    1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -*- Mode: Latex -*- %%%%%%%%%%%%%%%%%%%%%%%%%%%%
    2 %%
    3 %% Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
    4 %%
    5 %% The contents of this file are covered under the licence agreement in the
    6 %% file "LICENCE" distributed with Cforall.
    7 %%
    8 %% refrat.tex --
    9 %%
    10 %% Author           : Peter A. Buhr
    11 %% Created On       : Wed Apr  6 14:52:25 2016
    12 %% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Fri Apr  8 18:32:07 2016
    14 %% Update Count     : 6
    15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    16 
    171% requires tex packages: texlive-base texlive-latex-base tex-common texlive-humanities texlive-latex-extra texlive-fonts-recommended
    182
     
    215
    226% Latex packages used in the document.
     7
    238\usepackage{fullpage,times}
    249\usepackage{xspace}
     
    3621%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    3722
     23% Names used in the document.
     24
     25\newcommand{\CFA}{C$\forall$\xspace}    % set language symbolic name
     26\newcommand{\CFL}{Cforall\xspace}               % set language text name
     27\newcommand{\CC}{C\kern-.1em\hbox{+\kern-.25em+}\xspace} % CC symbolic name
     28\def\c11{ISO/IEC C} % C11 name (cannot have numbers in latex command name)
     29
     30%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     31
    3832% Bespoke macros used in the document.
    39 \input{common}
     33
     34\makeatletter
     35% allow escape sequence in lstinline
     36%\usepackage{etoolbox}
     37%\patchcmd{\lsthk@TextStyle}{\let\lst@DefEsc\@empty}{}{}{\errmessage{failed to patch}}
     38
     39\renewcommand\small{%
     40   \@setfontsize\small{8.5}{11}%
     41   \abovedisplayskip 8.5pt \@plus 3pt \@minus 4pt
     42   \abovedisplayshortskip \z@ \@plus 2pt
     43   \belowdisplayshortskip 4pt \@plus 2pt \@minus 2pt
     44   \def\@listi{\leftmargin\leftmargini
     45               \topsep 4pt \@plus 2pt \@minus 2pt
     46               \parsep 2pt \@pluspt \@minuspt
     47               \itemsep \parsep}%
     48   \belowdisplayskip \abovedisplayskip
     49}
     50\usepackage{relsize}            % must be after change to small
     51
     52\renewcommand{\labelitemi}{{\raisebox{0.25ex}{\footnotesize$\bullet$}}}
     53\renewenvironment{itemize}{\begin{list}{\labelitemi}{\topsep=5pt\itemsep=5pt\parsep=0pt}}{\end{list}}
     54
     55%  Reduce size of chapter/section titles
     56\def\@makechapterhead#1{%
     57  \vspace*{50\p@}%
     58  {\parindent \z@ \raggedright \normalfont
     59    \ifnum \c@secnumdepth >\m@ne
     60        \large\bfseries \@chapapp\space \thechapter
     61        \par\nobreak
     62        \vskip 5\p@
     63    \fi
     64    \interlinepenalty\@M
     65    \Large \bfseries #1\par\nobreak
     66    \vskip 50\p@
     67  }}
     68\def\@makeschapterhead#1{%
     69  \vspace*{50\p@}%
     70  {\parindent \z@ \raggedright
     71    \normalfont
     72    \interlinepenalty\@M
     73    \Large \bfseries  #1\par\nobreak
     74    \vskip 50\p@
     75  }}
     76\renewcommand\section{\@startsection{section}{1}{\z@}{-3.0ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\large\bfseries}}
     77\renewcommand\subsection{\@startsection{subsection}{2}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}}
     78\renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}}
     79\renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}{-2.0ex \@plus -1ex \@minus -.2ex}{-1em}{\normalfont\normalsize\bfseries}}
     80
     81% index macros
     82\newcommand{\italic}[1]{\emph{\hyperpage{#1}}}
     83\newcommand{\definition}[1]{\textbf{\hyperpage{#1}}}
     84\newcommand{\see}[1]{\emph{see} #1}
     85
     86% Define some commands that produce formatted index entries suitable for cross-references.
     87% ``\spec'' produces entries for specifications of entities.  ``\impl'' produces entries for their
     88% implementations, and ``\use'' for their uses.
     89
     90%  \newcommand{\bold}[1]{{\bf #1}}
     91%  \def\spec{\@bsphack\begingroup
     92%             \def\protect##1{\string##1\space}\@sanitize
     93%             \@wrxref{|bold}}
     94\def\impl{\@bsphack\begingroup
     95          \def\protect##1{\string##1\space}\@sanitize
     96          \@wrxref{|definition}}
     97\newcommand{\indexcode}[1]{{\lstinline$#1$}}
     98\def\use{\@bsphack\begingroup
     99         \def\protect##1{\string##1\space}\@sanitize
     100         \@wrxref{|hyperpage}}
     101\def\@wrxref#1#2{\let\thepage\relax
     102    \xdef\@gtempa{\write\@indexfile{\string
     103    \indexentry{#2@{\lstinline$#2$}#1}{\thepage}}}\endgroup\@gtempa
     104    \if@nobreak \ifvmode\nobreak\fi\fi\@esphack}
     105%\newcommand{\use}[1]{\index{#1@{\lstinline$#1$}}}
     106%\newcommand{\impl}[1]{\index{\protect#1@{\lstinline$\protect#1$}|definition}}
     107
     108% inline text and lowercase index: \Index{inline and lowercase index text}
     109% inline text and as-in index: \Index[as-is index text]{inline text}
     110% inline text but index with different as-is text: \Index[index text]{inline text}
     111\newcommand{\Index}{\@ifstar\@sIndex\@Index}
     112\newcommand{\@Index}[2][\@empty]{\lowercase{\def\temp{#2}}#2\ifx#1\@empty\index{\temp}\else\index{#1@{\protect#2}}\fi}
     113\newcommand{\@sIndex}[2][\@empty]{#2\ifx#1\@empty\index{#2}\else\index{#1@{\protect#2}}\fi}
     114\makeatother
     115
     116% blocks and titles
     117\newenvironment{rationale}{%
     118  \begin{quotation}\noindent$\Box$\enspace
     119}{%
     120  \hfill\enspace$\Box$\end{quotation}
     121}%
     122\newcommand{\define}[1]{\emph{#1\/}\index{#1}}
     123\newcommand{\rewrite}{\(\Rightarrow\)}
     124\newcommand{\rewriterules}{\paragraph{Rewrite Rules}~\par\noindent}
     125\newcommand{\examples}{\paragraph{Examples}~\par\noindent}
     126\newcommand{\semantics}{\paragraph{Semantics}~\par\noindent}
     127\newcommand{\constraints}{\paragraph{Constraints}~\par\noindent}
     128\newcommand{\predefined}{\paragraph{Predefined Identifiers}~\par\noindent}
     129
     130% BNF macros
     131\def\syntax{\paragraph{Syntax}\trivlist\parindent=.5in\item[\hskip.5in]}
     132\let\endsyntax=\endtrivlist
     133\newcommand{\lhs}[1]{\par{\emph{#1:}}\index{#1@{\emph{#1}}|italic}}
     134\newcommand{\rhs}{\hfil\break\hbox{\hskip1in}}
     135\newcommand{\oldlhs}[1]{\emph{#1: \ldots}\index{#1@{\emph{#1}}|italic}}
     136\newcommand{\nonterm}[1]{\emph{#1\/}\index{#1@{\emph{#1}}|italic}}
     137\newcommand{\opt}{$_{opt}$\ }
     138
     139% adjust varioref package with default "section" and "page" titles, and optional title with faraway page numbers
     140% \VRef{label} => Section 2.7, \VPageref{label} => page 17
     141% \VRef[Figure]{label} => Figure 3.4, \VPageref{label} => page 17
     142\renewcommand{\reftextfaceafter}{\unskip}
     143\renewcommand{\reftextfacebefore}{\unskip}
     144\renewcommand{\reftextafter}{\unskip}
     145\renewcommand{\reftextbefore}{\unskip}
     146\renewcommand{\reftextfaraway}[1]{\unskip, p.~\pageref{#1}}
     147\renewcommand{\reftextpagerange}[2]{\unskip, pp.~\pageref{#1}--\pageref{#2}}
     148\newcommand{\VRef}[2][Section]{\ifx#1\@empty\else{#1}\nobreakspace\fi\vref{#2}}
     149\newcommand{\VPageref}[2][page]{\ifx#1\@empty\else{#1}\nobreakspace\fi\pageref{#2}}
     150
     151% CFA based on ANSI C
     152\lstdefinelanguage{CFA}[ANSI]{C}%
     153{morekeywords={asm,_Alignas,_Alignof,_At,_Atomic,_Bool,catch,catchResume,choose,_Complex,trait,disable,dtype,enable,
     154        fallthru,finally,forall,ftype,_Generic,_Imaginary,inline,lvalue,_Noreturn,otype,restrict,_Static_assert,
     155        _Thread_local,throw,throwResume,try,},
     156}%
     157
     158\lstset{
     159language=CFA,
     160columns=flexible,
     161basicstyle=\sf\relsize{-1},
     162tabsize=4,
     163xleftmargin=\parindent,
     164escapechar=@,
     165keepspaces=true,
     166showstringspaces=false,
     167showlines=true,
     168}%
     169
     170\makeatletter
     171% replace/adjust listings characters that look bad in sanserif
     172\lst@CCPutMacro
     173\lst@ProcessOther{"2D}{\lst@ttfamily{-{}}{{\ttfamily\upshape -}}} % replace minus
     174\lst@ProcessOther{"3C}{\lst@ttfamily{<}{\texttt{<}}} % replace less than
     175\lst@ProcessOther{"3E}{\lst@ttfamily{<}{\texttt{>}}} % replace greater than
     176\lst@ProcessOther{"5E}{\raisebox{0.4ex}{$\scriptstyle\land\,$}} % replace circumflex
     177\lst@ProcessLetter{"5F}{\lst@ttfamily{\char95}{{\makebox[1.2ex][c]{\rule{1ex}{0.1ex}}}}} % replace underscore
     178\lst@ProcessOther{"7E}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}} % replace tilde
     179%\lst@ProcessOther{"7E}{\raisebox{-.4ex}[1ex][0pt]{\textasciitilde}} % lower tilde
     180\@empty\z@\@empty
     181\makeatother
    40182
    41183\setcounter{secnumdepth}{3}     % number subsubsections
     
    84226
    85227This document is a reference manual and rationale for \CFA, a polymorphic extension of the C programming language.
    86 It makes frequent reference to the {\c11} standard \cite{C11}, and occasionally compares \CFA to {\CC} \cite{C++}.
     228It makes frequent reference to the {\c11} standard \cite{ANS:C11}, and occasionally compares \CFA to {\CC} \cite{c++}.
    87229
    88230The manual deliberately imitates the ordering of the {\c11} standard (although the section numbering differs).
     
    578720
    579721There are two notable differences between \CFA's overload resolution rules and the rules for
    580 {\CC} defined in \cite{C++}.
     722{\CC} defined in \cite{c++}.
    581723First, the result type of a function plays a role.
    582724In {\CC}, a function call must be completely resolved based on the arguments to the call in most circumstances.
     
    32423384\begin{itemize}
    32433385\item
    3244 Inside a Clu cluster \cite{CLU}, the declaration of an instance states which view applies.
     3386Inside a Clu cluster \cite{clu}, the declaration of an instance states which view applies.
    32453387Two primitives called \lstinline$up$ and \lstinline$down$ can be used to convert between the views.
    32463388\item
    3247 The Simula class \cite{SIMULA87} is essentially a record type.
     3389The Simula class \cite{Simula87} is essentially a record type.
    32483390Since the only operations on a record are member selection and assignment, which can not be overloaded, there is never any ambiguity as to whether the abstraction or the implementation view is being used.
    32493391In {\CC}
    3250 \cite{C++}, operations on class instances include assignment and ``\lstinline$&$'', which can be overloaded.
     3392\cite{c++}, operations on class instances include assignment and ``\lstinline$&$'', which can be overloaded.
    32513393A ``scope resolution'' operator can be used inside the class to specify whether the abstract or implementation version of the operation should be used.
    32523394\item
    3253 An Ada derived type definition \cite{Ada} creates a new type from an old type, and also implicitly declares derived subprograms that correspond to the existing subprograms that use the old type as a parameter type or result type.
     3395An Ada derived type definition \cite{ada} creates a new type from an old type, and also implicitly declares derived subprograms that correspond to the existing subprograms that use the old type as a parameter type or result type.
    32543396The derived subprograms are clones of the existing subprograms with the old type replaced by the derived type.
    32553397Literals and aggregates of the old type are also cloned.
     
    37013843``\lstinline$Safe_pointer$ acts like a pointer to \lstinline$int$''.
    37023844\begin{lstlisting}
    3703 trait ptr_to( otype P | pointer( P ), otype T ) {@\impl{ptr_to}@@\use{pointer}@
     3845trait ptr_to( type P | pointer( P ), otype T ) {@\impl{ptr_to}@@\use{pointer}@
    37043846        lvalue T *?( P );
    37053847        lvalue T ?[?]( P, long int );
    37063848};
    3707 trait ptr_to_const( otype P | pointer( P ), otype T ) {@\impl{ptr_to_const}@
     3849trait ptr_to_const( type P | pointer( P ), otype T ) {@\impl{ptr_to_const}@
    37083850        const lvalue T *?( P );
    37093851        const lvalue T ?[?]( P, long int );@\use{pointer}@
    37103852};
    3711 trait ptr_to_volatile( otype P | pointer( P ), otype T ) }@\impl{ptr_to_volatile}@
     3853trait ptr_to_volatile( type P | pointer( P ), otype T ) }@\impl{ptr_to_volatile}@
    37123854        volatile lvalue T *?( P );
    37133855        volatile lvalue T ?[?]( P, long int );@\use{pointer}@
    37143856};
    3715 trait ptr_to_const_volatile( otype P | pointer( P ), otype T ) }@\impl{ptr_to_const_volatile}@
     3857trait ptr_to_const_volatile( type P | pointer( P ), otype T ) }@\impl{ptr_to_const_volatile}@
    37163858        const volatile lvalue T *?( P );@\use{pointer}@
    37173859        const volatile lvalue T ?[?]( P, long int );
     
    37233865``\lstinline$ptr_to$'' specifications.
    37243866\begin{lstlisting}
    3725 trait m_l_ptr_to( otype P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to}@ otype T | ptr_to( P, T )@\use{ptr_to}@ {
     3867trait m_l_ptr_to( type P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to}@ otype T | ptr_to( P, T )@\use{ptr_to}@ {
    37263868        P ?=?( P *, T * );
    37273869        T * ?=?( T **, P );
    37283870};
    3729 trait m_l_ptr_to_const( otype P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to_const}@ otype T | ptr_to_const( P, T )@\use{ptr_to_const}@) {
     3871trait m_l_ptr_to_const( type P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to_const}@ otype T | ptr_to_const( P, T )@\use{ptr_to_const}@) {
    37303872        P ?=?( P *, const T * );
    37313873        const T * ?=?( const T **, P );
    37323874};
    3733 trait m_l_ptr_to_volatile( otype P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to_volatile}@ otype T | ptr_to_volatile( P, T )) {@\use{ptr_to_volatile}@
     3875trait m_l_ptr_to_volatile( type P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to_volatile}@ otype T | ptr_to_volatile( P, T )) {@\use{ptr_to_volatile}@
    37343876        P ?=?( P *, volatile T * );
    37353877        volatile T * ?=?( volatile T **, P );
    37363878};
    3737 trait m_l_ptr_to_const_volatile( otype P | ptr_to_const_volatile( P ),@\use{ptr_to_const_volatile}@@\impl{m_l_ptr_to_const_volatile}@
    3738                 otype T | m_l_ptr_to_volatile( P, T ) | m_l_ptr_to_const( P )) {@\use{m_l_ptr_to_const}@@\use{m_l_ptr_to_volatile}@
     3879trait m_l_ptr_to_const_volatile( type P | ptr_to_const_volatile( P ),@\use{ptr_to_const_volatile}@@\impl{m_l_ptr_to_const_volatile}@
     3880                type T | m_l_ptr_to_volatile( P, T ) | m_l_ptr_to_const( P )) {@\use{m_l_ptr_to_const}@@\use{m_l_ptr_to_volatile}@
    37393881        P ?=?( P *, const volatile T * );
    37403882        const volatile T * ?=?( const volatile T **, P );
     
    38644006
    38654007\bibliographystyle{plain}
    3866 \bibliography{cfa}
     4008\bibliography{refrat}
    38674009
    38684010
  • doc/user/Makefile

    r37218fc r3aba311  
    11## Define the appropriate configuration variables.
    22
    3 TeXLIB = .:../bibliography/:../LaTeXmacros/:
     3TeXLIB = .::
    44LaTeX  = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex
    5 BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex
     5BibTeX = BSTINPUTS=${TeXLIB} && export BSTINPUTS && bibtex
    66
    77## Define the text source files.
     
    4343        dvips $< -o $@
    4444
    45 ${basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex \
    46                 ../LaTeXmacros/common.tex ../LaTeXmacros/indexstyle ../bibliography/cfa.bib
     45${basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex ${basename ${DOCUMENT}}.bib /usr/local/bibliographies/pl.bib
    4746        # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run.
    4847        if [ ! -r ${basename $@}.ind ] ; then touch ${basename $@}.ind ; fi
     
    5453        -${BibTeX} ${basename $@}
    5554        # Make index from *.aux entries and input index at end of document
    56         makeindex -s ../LaTeXmacros/indexstyle ${basename $@}.idx
     55        makeindex -s indexstyle ${basename $@}.idx
    5756        ${LaTeX} ${basename $@}.tex
    5857        # Run again to get index title into table of contents
  • doc/user/user.tex

    r37218fc r3aba311  
    1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -*- Mode: Latex -*- %%%%%%%%%%%%%%%%%%%%%%%%%%%%
    2 %%
    3 %% Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
    4 %%
    5 %% The contents of this file are covered under the licence agreement in the
    6 %% file "LICENCE" distributed with Cforall.
    7 %%
    8 %% user.tex --
    9 %%
    10 %% Author           : Peter A. Buhr
    11 %% Created On       : Wed Apr  6 14:53:29 2016
    12 %% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Fri Apr  8 11:40:53 2016
    14 %% Update Count     : 42
    15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    16 
    171% requires tex packages: texlive-base texlive-latex-base tex-common texlive-humanities texlive-latex-extra texlive-fonts-recommended
    182
     
    215
    226% Latex packages used in the document.
    23 \usepackage[T1]{fontenc}
    24 \usepackage{textcomp}
    25 \usepackage[latin1]{inputenc}
    26 \usepackage{upquote}
     7
    278\usepackage{fullpage,times}
    289\usepackage{xspace}
     
    4324% Names used in the document.
    4425
     26\newcommand{\CFA}{C$\forall$\xspace}    % set language symbolic name
     27\newcommand{\CFL}{Cforall\xspace}               % set language text name
     28\newcommand{\CC}{C\kern-.1em\hbox{+\kern-.25em+}\xspace} % CC symbolic name
     29\def\c11{ISO/IEC C} % C11 name (cannot have numbers in latex command name)
    4530\newcommand{\CS}{C\raisebox{-0.9ex}{\large$^\sharp$}\xspace}
    4631
     
    4833
    4934% Bespoke macros used in the document.
    50 \input{common}
     35
     36\makeatletter
     37% allow escape sequence in lstinline
     38%\usepackage{etoolbox}
     39%\patchcmd{\lsthk@TextStyle}{\let\lst@DefEsc\@empty}{}{}{\errmessage{failed to patch}}
     40
     41\renewcommand\small{%
     42   \@setfontsize\small{8.5}{11}%
     43   \abovedisplayskip 8.5pt \@plus 3pt \@minus 4pt
     44   \abovedisplayshortskip \z@ \@plus 2pt
     45   \belowdisplayshortskip 4pt \@plus 2pt \@minus 2pt
     46   \def\@listi{\leftmargin\leftmargini
     47               \topsep 4pt \@plus 2pt \@minus 2pt
     48               \parsep 2pt \@pluspt \@minuspt
     49               \itemsep \parsep}%
     50   \belowdisplayskip \abovedisplayskip
     51}
     52\usepackage{relsize}            % must be after change to small
     53
     54\renewcommand{\labelitemi}{{\raisebox{0.25ex}{\footnotesize$\bullet$}}}
     55\renewenvironment{itemize}{\begin{list}{\labelitemi}{\topsep=5pt\itemsep=5pt\parsep=0pt}}{\end{list}}
     56
     57%  Reduce size of section titles
     58\renewcommand\section{\@startsection{section}{1}{\z@}{-3.0ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\large\bfseries}}
     59\renewcommand\subsection{\@startsection{subsection}{2}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}}
     60\renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}}
     61\renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}{-2.0ex \@plus -1ex \@minus -.2ex}{-1em}{\normalfont\normalsize\bfseries}}
     62
     63% index macros
     64\newcommand{\italic}[1]{\emph{\hyperpage{#1}}}
     65\newcommand{\definition}[1]{\textbf{\hyperpage{#1}}}
     66\newcommand{\see}[1]{\emph{see} #1}
     67
     68% Define some commands that produce formatted index entries suitable for cross-references.
     69% ``\spec'' produces entries for specifications of entities.  ``\impl'' produces entries for their
     70% implementations, and ``\use'' for their uses.
     71
     72%  \newcommand{\bold}[1]{{\bf #1}}
     73%  \def\spec{\@bsphack\begingroup
     74%             \def\protect##1{\string##1\space}\@sanitize
     75%             \@wrxref{|bold}}
     76\def\impl{\@bsphack\begingroup
     77          \def\protect##1{\string##1\space}\@sanitize
     78          \@wrxref{|definition}}
     79\newcommand{\indexcode}[1]{{\lstinline$#1$}}
     80\def\use{\@bsphack\begingroup
     81         \def\protect##1{\string##1\space}\@sanitize
     82         \@wrxref{|hyperpage}}
     83\def\@wrxref#1#2{\let\thepage\relax
     84    \xdef\@gtempa{\write\@indexfile{\string
     85    \indexentry{#2@{\lstinline$#2$}#1}{\thepage}}}\endgroup\@gtempa
     86    \if@nobreak \ifvmode\nobreak\fi\fi\@esphack}
     87%\newcommand{\use}[1]{\index{#1@{\lstinline$#1$}}}
     88%\newcommand{\impl}[1]{\index{\protect#1@{\lstinline$\protect#1$}|definition}}
     89
     90% inline text and lowercase index: \Index{inline and lowercase index text}
     91% inline text and as-in index: \Index[as-is index text]{inline text}
     92% inline text but index with different as-is text: \Index[index text]{inline text}
     93\newcommand{\Index}{\@ifstar\@sIndex\@Index}
     94\newcommand{\@Index}[2][\@empty]{\lowercase{\def\temp{#2}}#2\ifx#1\@empty\index{\temp}\else\index{#1@{\protect#2}}\fi}
     95\newcommand{\@sIndex}[2][\@empty]{#2\ifx#1\@empty\index{#2}\else\index{#1@{\protect#2}}\fi}
     96
     97\newcommand{\newtermFontInline}{\emph}
     98\newcommand{\newterm}{\@ifstar\@snewterm\@newterm}
     99\newcommand{\@newterm}[2][\@empty]{\lowercase{\def\temp{#2}}{\newtermFontInline{#2}}\ifx#1\@empty\index{\temp}\else\index{#1@{\protect#2}}\fi}
     100\newcommand{\@snewterm}[2][\@empty]{{\newtermFontInline{#2}}\ifx#1\@empty\index{#2}\else\index{#1@{\protect#2}}\fi}
     101\makeatother
     102
     103% blocks and titles
     104\newenvironment{quote2}{%
     105        \list{}{\lstset{resetmargins=true}\leftmargin=\parindent\rightmargin\leftmargin}%
     106        \item\relax
     107}{%
     108        \endlist
     109}% quote2
     110\newenvironment{rationale}{%
     111  \begin{quotation}\noindent$\Box$\enspace
     112}{%
     113  \hfill\enspace$\Box$\end{quotation}
     114}%
     115\newcommand{\define}[1]{\emph{#1\/}\index{#1}}
     116\newcommand{\rewrite}{\(\Rightarrow\)}
     117\newcommand{\rewriterules}{\paragraph{Rewrite Rules}~\par\noindent}
     118\newcommand{\examples}{\paragraph{Examples}~\par\noindent}
     119\newcommand{\semantics}{\paragraph{Semantics}~\par\noindent}
     120\newcommand{\constraints}{\paragraph{Constraints}~\par\noindent}
     121\newcommand{\predefined}{\paragraph{Predefined Identifiers}~\par\noindent}
     122
     123% BNF macros
     124\def\syntax{\paragraph{Syntax}\trivlist\parindent=.5in\item[\hskip.5in]}
     125\let\endsyntax=\endtrivlist
     126\newcommand{\lhs}[1]{\par{\emph{#1:}}\index{#1@{\emph{#1}}|italic}}
     127\newcommand{\rhs}{\hfil\break\hbox{\hskip1in}}
     128\newcommand{\oldlhs}[1]{\emph{#1: \ldots}\index{#1@{\emph{#1}}|italic}}
     129\newcommand{\nonterm}[1]{\emph{#1\/}\index{#1@{\emph{#1}}|italic}}
     130\newcommand{\opt}{$_{opt}$\ }
     131
     132% adjust varioref package with default "section" and "page" titles, and optional title with faraway page numbers
     133% \VRef{label} => Section 2.7, \VPageref{label} => page 17
     134% \VRef[Figure]{label} => Figure 3.4, \VPageref{label} => page 17
     135\renewcommand{\reftextfaceafter}{\unskip}
     136\renewcommand{\reftextfacebefore}{\unskip}
     137\renewcommand{\reftextafter}{\unskip}
     138\renewcommand{\reftextbefore}{\unskip}
     139\renewcommand{\reftextfaraway}[1]{\unskip, p.~\pageref{#1}}
     140\renewcommand{\reftextpagerange}[2]{\unskip, pp.~\pageref{#1}--\pageref{#2}}
     141\newcommand{\VRef}[2][Section]{\ifx#1\@empty\else{#1}\nobreakspace\fi\vref{#2}}
     142\newcommand{\VPageref}[2][page]{\ifx#1\@empty\else{#1}\nobreakspace\fi\pageref{#2}}
     143
     144% Go programming language
     145\lstdefinelanguage{Golang}%
     146  {morekeywords=[1]{package,import,func,type,struct,return,defer,panic, recover,select,var,const,iota,},%
     147   morekeywords=[2]{string,uint,uint8,uint16,uint32,uint64,int,int8,int16, int32,int64,
     148                bool,float32,float64,complex64,complex128,byte,rune,uintptr, error,interface},%
     149   morekeywords=[3]{map,slice,make,new,nil,len,cap,copy,close,true,false, delete,append,real,imag,complex,chan,},%
     150   morekeywords=[4]{for,break,continue,range,goto,switch,case,fallthrough,if, else,default,},%
     151   morekeywords=[5]{Println,Printf,Error,},%
     152   sensitive=true,%
     153   morecomment=[l]{//},%
     154   morecomment=[s]{/*}{*/},%
     155   morestring=[b]',%
     156   morestring=[b]",%
     157   morestring=[s]{`}{`},%
     158}
     159
     160% CFA based on ANSI C
     161\lstdefinelanguage{CFA}[ANSI]{C}%
     162{morekeywords={asm,_Alignas,_Alignof,_At,_Atomic,_Bool,catch,catchResume,choose,_Complex,trait,disable,dtype,enable,
     163        fallthru,finally,forall,ftype,_Generic,_Imaginary,inline,lvalue,_Noreturn,otype,restrict,_Static_assert,
     164        _Thread_local,throw,throwResume,try,},
     165}%
     166
     167\lstset{
     168language=CFA,
     169columns=flexible,
     170basicstyle=\sf\relsize{-1},
     171tabsize=4,
     172xleftmargin=\parindent,
     173escapechar=@,
     174mathescape=true,
     175keepspaces=true,
     176showstringspaces=false,
     177showlines=true,
     178}%
     179
     180\makeatletter
     181% replace/adjust listings characters that look bad in sanserif
     182\lst@CCPutMacro
     183\lst@ProcessOther{"2D}{\lst@ttfamily{-{}}{{\ttfamily\upshape -}}} % replace minus
     184\lst@ProcessOther{"3C}{\lst@ttfamily{<}{\texttt{<}}} % replace less than
     185\lst@ProcessOther{"3E}{\lst@ttfamily{<}{\texttt{>}}} % replace greater than
     186\lst@ProcessOther{"5E}{\raisebox{0.4ex}{$\scriptstyle\land\,$}} % replace circumflex
     187\lst@ProcessLetter{"5F}{\lst@ttfamily{\char95}{{\makebox[1.2ex][c]{\rule{1ex}{0.1ex}}}}} % replace underscore
     188\lst@ProcessOther{"7E}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}} % replace tilde
     189%\lst@ProcessOther{"7E}{\raisebox{-.4ex}[1ex][0pt]{\textasciitilde}} % lower tilde
     190\@empty\z@\@empty
     191\makeatother
    51192
    52193\setcounter{secnumdepth}{3}     % number subsubsections
     
    225366
    226367The command \lstinline@cfa@ is used to compile \CFA program(s).
    227 This command works like the GNU \lstinline@gcc@\index{gcc} command, e.g.:
     368This command works like the GNU \lstinline@gcc@ command, e.g.:
    228369\begin{lstlisting}
    229370cfa [ gcc-options ] C/@{\CFA}@-files [ assembler/loader-files ]
    230371\end{lstlisting}
    231 By default, \CFA programs having the following \lstinline@gcc@ flags turned on:
    232 \begin{description}
    233 \item
    234 \hspace*{-4pt}\lstinline@-std=gnu99@
    235 The 1999 C standard plus GNU extensions.
    236 \end{description}
    237 The following new \CFA option is available:
     372The following additional option is available:
    238373\begin{description}
    239374\item
     
    247382Numeric constants are extended to allow \Index{underscore}s within constants\index{constant!underscore}, e.g.:
    248383\begin{lstlisting}
    249 2`_`147`_`483`_`648;                            // decimal constant
     3842_147_483_648;                          // decimal constant
    25038556_ul;                                          // decimal unsigned long constant
    2513860_377;                                          // octal constant
     
    316451\multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}}       & \multicolumn{1}{c}{\textbf{C}}        \\
    317452\begin{lstlisting}
    318 `* int x, y;`
     453* int x, y;
    319454\end{lstlisting}
    320455&
     
    436571The point of the new syntax is to allow returning multiple values from a routine~\cite{CLU,Galletly96}, e.g.:
    437572\begin{lstlisting}
    438 `[ int o1, int o2, char o3 ]` f( int i1, char i2, char i3 ) {
     573[ int o1, int o2, char o3 ] f( int i1, char i2, char i3 ) {
    439574        @\emph{routine body}@
    440575}
     
    504639Because the value in the return variable is automatically returned when a \CFA routine terminates, the \lstinline@return@ statement \emph{does not} contain an expression, as in:
    505640\begin{lstlisting}
    506 `[ int x ]` f() {
     641[ int x ] f() {
    507642        ... x = 0; ... x = y; ...
    508         `return;` // implicitly return x
     643        return; // implicitly return x
    509644}
    510645\end{lstlisting}
     
    562697for example, the following is incorrect:
    563698\begin{lstlisting}
    564 * [ int x ] f () fp;            // routine name "f" is not allowed
     699* [ int x ] f () fp;            // routine name ``f'' is not allowed
    565700\end{lstlisting}
    566701
     
    729864\subsection{Type Nesting}
    730865
    731 \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.
     866C allows \Index{type nesting}, but the nested types are hoisted\index{type!hoisting} (refactored) into the enclosing scope.
    732867\begin{quote2}
    733868\begin{tabular}{@{}l@{\hspace{30pt}}l|l@{}}
     
    784919
    785920int fred() {
    786         s.t.c = `S.`R;  // type qualification
    787         struct `S.`T t = { `S.`R, 1, 2 };
    788         enum `S.`C c;
    789         union `S.T.`U u;
     921        s.t.c = S.R;
     922        struct S.T t = { S.R, 1, 2 };
     923        enum S.C c;
     924        union S.T.U u;
    790925}
    791926\end{lstlisting}
    792927\end{tabular}
    793928\end{quote2}
    794 In the left example in C, types \lstinline@C@, \lstinline@U@ and \lstinline@T@ are implicitly hoisted outside of type \lstinline@S@ into the containing block scope.
    795 In the right example in \CFA, the types are not hoisted and accessed using the field-selection operator ``\lstinline@.@'' for type qualification, as does Java, rather than the \CC type-selection operator ``\lstinline@::@''.
     929
     930\CFA is C \emph{incompatible} on this issue, and provides semantics similar to \CC.
     931Nested types are not hoisted and can be referenced using the field selection operator ``\lstinline@.@'', unlike the \CC scope-resolution operator ``\lstinline@::@''.
     932Given that nested types in C are equivalent to not using them, i.e., they are essentially useless, it is unlikely there are any realistic usages that break because of this incompatibility.
    796933
    797934
     
    807944\begin{lstlisting}
    808945const unsigned int size = 10;
    809 int ia[size];
    810 ...                                             // assign values to array ia
    811 qsort( ia, size );              // sort ascending order using builtin ?<?
    812 {
    813         `int ?<?( int x, int y ) { return x > y; }` // nested routine
    814         qsort( ia, size );      // sort descending order by local redefinition
    815 }
    816 \end{lstlisting}
    817 
    818 Nested routines are not first-class, meaning a nested routine cannot be returned if it has references to variables in its enclosing blocks;
    819 the only exception is references to the external block of the translation unit, as these variables persist for the duration of the program.
    820 The following program in undefined in \CFA (and \lstinline@gcc@\index{gcc})
    821 \begin{lstlisting}
    822 [* [int]( int )] foo() {                // int (*foo())( int )
    823         int `i` = 7;
    824         int bar( int p ) {
    825                 `i` += 1;                                       // dependent on local variable
    826                 sout | `i` | endl;
    827         }
    828         return bar;                                     // undefined because of local dependence
    829 }
    830 int main() {
    831         * [int](int) fp = foo();        // int (*fp)(int)
    832     sout | fp( 3 ) | endl;
    833 }
    834 \end{lstlisting}
    835 because
    836 
    837 Currently, there are no \Index{lambda} expressions, i.e., unnamed routines because routine names are very important to properly select the correct routine.
     946int a[size];
     947
     948qsort( a, size );               // ascending order using built in ?<?
     949{                                               // descending order by local redefinition
     950        int ?<?( int a, int b ) { return a > b; } // nested routine
     951        qsort( a, size );
     952}
     953\end{lstlisting}
    838954
    839955
     
    8971013
    8981014\item
    899 Change: A struct is a scope in C++, not in C \\
    900 Rationale: Class scope is crucial to C++, and a struct is a class. \\
    901 Effect on original feature: Change to semantics of well-defined feature. \\
    902 Difficulty of converting: Semantic transformation. \\
    903 How widely used: C programs use struct extremely frequently, but the change is only noticeable when struct, enumeration, or enumerator names are referred to outside the struct.
    904 The latter is probably rare.
    905 
    906 \CFA is C \emph{incompatible} on this issue, and provides semantics similar to \CC.
    907 Nested types are not hoisted and can be referenced using the field selection operator ``\lstinline@.@'', unlike the \CC scope-resolution operator ``\lstinline@::@''.
    908 Given that nested types in C are equivalent to not using them, i.e., they are essentially useless, it is unlikely there are any realistic usages that break because of this incompatibility.
    909 
     1015Change: A struct is a scope in C++, not in C
     1016Rationale: Class scope is crucial to C++, and a struct is a class.
     1017Effect on original feature: Change to semantics of well-defined feature.
     1018Difficulty of converting: Semantic transformation.
     1019How widely used: C programs use struct extremely frequently, but the change is only noticeable when
     1020struct, enumeration, or enumerator names are referred to outside the struct. The latter is probably
     1021rare.
    9101022
    9111023\item
     
    10731185First the right-hand tuple is flattened and then the values are assigned individually.
    10741186Flattening is also performed on tuple types.
    1075 For example, the type \lstinline@[ int, [ int, int ], int ]@ can be coerced, using flattening, into the type \lstinline@[ int, int, int, int ]@.
     1187For example, the type \lstinline@[ int, [ int, int ], int ]@ can be coerced, using flattening, into the type lstinline@[ int, int, int, int ]@.
    10761188
    10771189A \newterm{structuring coercion} is the opposite of flattening;
     
    12401352\multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}}       & \multicolumn{1}{c}{\textbf{C}}        \\
    12411353\begin{lstlisting}
    1242 `L1:` for ( ... ) {
    1243         `L2:` for ( ... ) {
    1244                 `L3:` for ( ... ) {
    1245                         ... break `L1`; ...
    1246                         ... break `L2`; ...
    1247                         ... break `L3`; // or break
     1354L1: for ( ... ) {
     1355        L2: for ( ... ) {
     1356                L3: for ( ... ) {
     1357                        ... break L1; ...
     1358                        ... break L2; ...
     1359                        ... break L3; // or break
    12481360                }
    12491361        }
     
    12701382\multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}}       & \multicolumn{1}{c}{\textbf{C}}        \\
    12711383\begin{lstlisting}
    1272 `L1`: for ( ... ) {
    1273         `L2`: for ( ... ) {
    1274                 `L3`: for ( ... ) {
    1275                         ... continue `L1`; ...
    1276                         ... continue `L2`; ...
    1277                         ... continue `L3`; ...
     1384L1: for ( ... ) {
     1385        L2: for ( ... ) {
     1386                L3: for ( ... ) {
     1387                        ... continue L1; ...
     1388                        ... continue L2; ...
     1389                        ... continue L3; ...
    12781390
    12791391                }
     
    15111623\begin{lstlisting}
    15121624switch ( i ) {
    1513   `case 1, 3, 5`:
     1625  case 1, 3, 5:
    15141626        ...
    1515   `case 2, 4, 6`:
     1627  case 2, 4, 6:
    15161628        ...
    15171629}
     
    15221634  case 1: case 3 : case 5:
    15231635        ...
    1524   case 2: case 4 : case 6:
     1636  case 2: case 4 : case 6: /* even values */
    15251637        ...
    15261638}
     
    15431655\begin{lstlisting}
    15441656switch ( i ) {
    1545   `case 1~5:`
     1657  case 1~5
    15461658        ...
    1547   `case 10~15:`
     1659  case 10~15
    15481660        ...
    15491661}
     
    15601672&
    15611673\begin{lstlisting}
    1562 
    15631674// 1, 2, 3, 4, 5
    15641675
     
    20572168
    20582169
    2059 \section{Auto Type-Inferencing}
    2060 
    2061 Auto type-inferencing occurs in a declaration where a variable's type is inferred from its initialization expression type.
    2062 \begin{quote2}
    2063 \begin{tabular}{@{}l@{\hspace{30pt}}ll@{}}
    2064 \multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CC}}        & \multicolumn{1}{c}{\lstinline@gcc@}\index{gcc} \\
    2065 \begin{lstlisting}
    2066 
    2067 auto j = 3.0 * 4;
    2068 int i;
    2069 auto k = i;
    2070 \end{lstlisting}
    2071 &
    2072 \begin{lstlisting}
    2073 #define expr 3.0 * i
    2074 typeof(expr) j = expr;
    2075 int i;
    2076 typeof(i) k = i;
    2077 \end{lstlisting}
    2078 &
    2079 \begin{lstlisting}
    2080 
    2081 // use type of initialization expression
    2082 
    2083 // use type of primary variable
    2084 \end{lstlisting}
    2085 \end{tabular}
    2086 \end{quote2}
    2087 The two important capabilities are:
    2088 \begin{itemize}
    2089 \item
    2090 preventing having to determine or write out long generic types,
    2091 \item
    2092 ensure secondary variables, related to a primary variable, always have the same type.
    2093 \end{itemize}
    2094 
    2095 In \CFA, \lstinline@typedef@ provides a mechanism to alias long type names with short ones, both globally and locally, but not eliminate the use of the short name.
    2096 \lstinline@gcc@ provides \lstinline@typeof@ to declare a secondary variable from a primary variable.
    2097 \CFA also relies heavily on the specification of the left-hand side of assignment for type inferencing, so in many cases it is crucial to specify the type of the left-hand side to select the correct type of the right-hand expression.
    2098 Only for overloaded routines with the same return type is variable type-inferencing possible.
    2099 Finally, \lstinline@auto@ presents the programming problem of tracking down a type when the type is actually needed.
    2100 For example, given
    2101 \begin{lstlisting}
    2102 auto j = `...`
    2103 \end{lstlisting}
    2104 and the need to write a routine to compute using \lstinline@j@
    2105 \begin{lstlisting}
    2106 void rtn( `...` parm );
    2107 rtn( j );
    2108 \end{lstlisting}
    2109 A programmer must work backwards to determine the type of \lstinline@j@'s initialization expression, reconstructing the possibly long generic type-name.
    2110 In this situation, having the type name or a short alias is very useful.
    2111 
    2112 There is also the conundrum in type inferencing of when to \emph{\Index{brand}} a type.
    2113 That is, when is the type of the variable more important than the type of its initialization expression.
    2114 For example, if a change is made in an initialization expression, it can cause hundreds or thousands of cascading type changes and/or errors.
    2115 At some point, a programmer wants the type of the variable to remain constant and the expression to be in error when it changes.
    2116 
    2117 Given \lstinline@typedef@ and \lstinline@typeof@ in \CFA, and the strong need to use the type of left-hand side in inferencing, auto type-inferencing is not supported at this time.
    2118 Should a significant need arise, this feature can be revisited.
    2119 
    2120 
    2121 \section{Generics}
     2170\section{Generics }
    21222171
    21232172\CFA supports parametric polymorphism to allow users to define generic functions and types.
     
    24082457
    24092458
    2410 \section{Syntactic Anomalies}
    2411 
    2412 The number 0 and 1 are treated specially in \CFA, and can be redefined as variables.
    2413 One syntactic anomaly is when a field in an structure is names 0 or 1:
    2414 \begin{lstlisting}
    2415 struct S {
    2416         int 0, 1;
    2417 } s;
    2418 \end{lstlisting}
    2419 The problem occurs in accesing these fields using the selection operation ``\lstinline@.@'':
    2420 \begin{lstlisting}
    2421 s.0 = 0;        // ambiguity with floating constant .0
    2422 s.1 = 1;        // ambiguity with floating constant .1
    2423 \end{lstlisting}
    2424 To make this work, a space is required after the field selection:
    2425 \begin{lstlisting}
    2426 `s.@\textvisiblespace@0` = 0;
    2427 `s.@\textvisiblespace@1` = 1;
    2428 \end{lstlisting}
    2429 While this sytact is awkward, it is unlikely many programers will name fields of a structure 0 or 1.
    2430 Like the \CC lexical problem with closing template-syntax, e.g, \lstinline@Foo<Bar<int`>>`@, this issue can be solved with a more powerful lexer/parser.
    2431 
    2432 There are several ambiguous cases with operator identifiers, e.g., \lstinline@int *?*?()@, where the string \lstinline@*?*?@ can be lexed as \lstinline@*@/\lstinline@?*?@ or \lstinline@*?@/\lstinline@*?@.
    2433 Since it is common practise to put a unary operator juxtaposed to an identifier, e.g., \lstinline@*i@, users will be annoyed if they cannot do this with respect to operator identifiers.
    2434 Even with this special hack, there are 5 general cases that cannot be handled.
    2435 The first case is for the function-call identifier \lstinline@?()@:
    2436 \begin{lstlisting}
    2437 int *@\textvisiblespace@?()();  // declaration: space required after '*'
    2438 *@\textvisiblespace@?()();              // expression: space required after '*'
    2439 \end{lstlisting}
    2440 Without the space, the string \lstinline@*?()@ is ambiguous without N character look ahead;
    2441 it requires scanning ahead to determine if there is a \lstinline@'('@, which is the start of an argument/parameter list.
    2442 
    2443 The 4 remaining cases occur in expressions:
    2444 \begin{lstlisting}
    2445 i++@\textvisiblespace@?i:0;             // space required before '?'
    2446 i--@\textvisiblespace@?i:0;             // space required before '?'
    2447 i@\textvisiblespace@?++i:0;             // space required after '?'
    2448 i@\textvisiblespace@?--i:0;             // space required after '?'
    2449 \end{lstlisting}
    2450 In the first two cases, the string \lstinline@i++?@ is ambiguous, where this string can be lexed as \lstinline@i@ / \lstinline@++?@ or \lstinline@i++@ / \lstinline@?@;
    2451 it requires scanning ahead to determine if there is a \lstinline@'('@, which is the start of an argument list.
    2452 In the second two cases, the string \lstinline@?++x@ is ambiguous, where this string can be lexed as \lstinline@?++@ / \lstinline@x@ or \lstinline@?@ / y\lstinline@++x@;
    2453 it requires scanning ahead to determine if there is a \lstinline@'('@, which is the start of an argument list.
     2459\section{I/O Library}
     2460\label{s:IOLibrary}
     2461
     2462The goal for \CFA I/O is to make I/O as simple as possible for the general case, while fully supporting polmorphism and user defined types in a consistent way.
     2463The general case is printing out a sequence of variables separated by whitespace.
     2464\begin{lstlisting}
     2465int x = 0, y = 1, z = 2;
     2466sout | x | y | z | endl;
     2467
     2468cout << x << " " << y << " " << z << endl;
     2469\end{lstlisting}
     2470The \CC form takes almost twice as many characters.
     2471
     2472The logical-or operator is used because it is the lowest priority overloadable operator, other than assignment.
     2473Therefore, most output expressions do not require parenthesis.
     2474\begin{lstlisting}
     2475int x = 0, y = 1, z = 2;
     2476sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl;
     2477
     2478cout << x * 3 << y + 1 << (z << 2) << (x == y) << (x | y) << (x || y) << (x > z ? 1 : 2) << endl;
     2479\end{lstlisting}
     2480
     2481Finally, the logical-or operator has a link with the Shell pipe-operator for moving data, although data flows in the opposite direction.
     2482
     2483\begin{figure}
     2484\begin{lstlisting}[mathescape=off]
     2485#include <fstream>
     2486
     2487int main() {
     2488        char c;
     2489        short int si;
     2490        unsigned short int usi;
     2491        int i;
     2492        unsigned int ui;
     2493        long int li;
     2494        unsigned long int uli;
     2495        long long int lli;
     2496        unsigned long long int ulli;
     2497        float f;
     2498        double d;
     2499        long double ld;
     2500        float _Complex fc;
     2501        double _Complex dc;
     2502        long double _Complex ldc;
     2503        char s1[10], s2[10];
     2504
     2505        ifstream in;
     2506        open( &in, "read.data", "r" );
     2507
     2508        &in | &c
     2509                | &si | &usi | &i | &ui | &li | &uli | &lli | &ulli
     2510                | &f | &d | &ld
     2511                | &fc | &dc | &ldc
     2512                | str( s1 ) | str( s2, 10 );
     2513
     2514        sout | c | ' ' | endl
     2515                 | si | usi | i | ui | li | uli | lli | ulli | endl
     2516                 | f | d | ld | endl
     2517                 | f | "" | d | "" | ld | endl;
     2518
     2519        sepSet( sout, ", $" );
     2520        sout | fc | dc | ldc | endl
     2521                 | sepOn | s1 | sepOff | s2 | endl
     2522                 | s1 | "" | s2 | endl;
     2523}
     2524
     2525$ cat read.data
     2526A 1 2 3 4 5 6 7 8 1.1 1.2 1.3 1.1+2.3 1.1-2.3 1.1-2.3 abc xyz
     2527$ a.out
     2528A
     25291 2 3 4 5 6 7 8
     25301.1 1.2 1.3
     25311.11.21.3
     25321.1+2.3i, $1.1-2.3i, $1.1-2.3i
     2533, $abcxyz
     2534abcxyz
     2535\end{lstlisting}
     2536\end{figure}
     2537
     2538
     2539\section{Standard Library}
     2540\label{s:StandardLibrary}
     2541
     2542The goal of the \CFA standard-library is to wrap many of the existing C library-routines that are explicitly polymorphic into implicitly polymorphic versions.
     2543
     2544
     2545\subsection{malloc}
     2546
     2547\begin{lstlisting}
     2548forall( otype T ) T * malloc( void );
     2549forall( otype T ) T * malloc( char fill );
     2550forall( otype T ) T * malloc( T * ptr, size_t size );
     2551forall( otype T ) T * malloc( T * ptr, size_t size, unsigned char fill );
     2552forall( otype T ) T * calloc( size_t size );
     2553forall( otype T ) T * realloc( T * ptr, size_t size );
     2554forall( otype T ) T * realloc( T * ptr, size_t size, unsigned char fill );
     2555
     2556forall( otype T ) T * aligned_alloc( size_t alignment );
     2557forall( otype T ) T * memalign( size_t alignment );             // deprecated
     2558forall( otype T ) int posix_memalign( T ** ptr, size_t alignment );
     2559
     2560forall( otype T ) T * memset( T * ptr, unsigned char fill ); // use default value '\0' for fill
     2561forall( otype T ) T * memset( T * ptr );                                // remove when default value available
     2562\end{lstlisting}
     2563
     2564
     2565\subsection{ato/strto}
     2566
     2567\begin{lstlisting}
     2568int ato( const char * ptr );
     2569unsigned int ato( const char * ptr );
     2570long int ato( const char * ptr );
     2571unsigned long int ato( const char * ptr );
     2572long long int ato( const char * ptr );
     2573unsigned long long int ato( const char * ptr );
     2574float ato( const char * ptr );
     2575double ato( const char * ptr );
     2576long double ato( const char * ptr );
     2577float _Complex ato( const char * ptr );
     2578double _Complex ato( const char * ptr );
     2579long double _Complex ato( const char * ptr );
     2580
     2581int strto( const char * sptr, char ** eptr, int base );
     2582unsigned int strto( const char * sptr, char ** eptr, int base );
     2583long int strto( const char * sptr, char ** eptr, int base );
     2584unsigned long int strto( const char * sptr, char ** eptr, int base );
     2585long long int strto( const char * sptr, char ** eptr, int base );
     2586unsigned long long int strto( const char * sptr, char ** eptr, int base );
     2587float strto( const char * sptr, char ** eptr );
     2588double strto( const char * sptr, char ** eptr );
     2589long double strto( const char * sptr, char ** eptr );
     2590float _Complex strto( const char * sptr, char ** eptr );
     2591double _Complex strto( const char * sptr, char ** eptr );
     2592long double _Complex strto( const char * sptr, char ** eptr );
     2593\end{lstlisting}
     2594
     2595
     2596\subsection{bsearch/qsort}
     2597
     2598\begin{lstlisting}
     2599forall( otype T | { int ?<?( T, T ); } )
     2600T * bsearch( const T key, const T * arr, size_t dimension );
     2601
     2602forall( otype T | { int ?<?( T, T ); } )
     2603void qsort( const T * arr, size_t dimension );
     2604\end{lstlisting}
     2605
     2606
     2607\subsection{abs}
     2608
     2609\begin{lstlisting}
     2610char abs( char );
     2611extern "C" {
     2612int abs( int );         // use default C routine for int
     2613} // extern
     2614long int abs( long int );
     2615long long int abs( long long int );
     2616float abs( float );
     2617double abs( double );
     2618long double abs( long double );
     2619float _Complex abs( float _Complex );
     2620double _Complex abs( double _Complex );
     2621long double _Complex abs( long double _Complex );
     2622\end{lstlisting}
     2623
     2624
     2625\subsection{random}
     2626
     2627\begin{lstlisting}
     2628void randseed( long int s );
     2629char random();
     2630int random();
     2631unsigned int random();
     2632long int random();
     2633unsigned long int random();
     2634float random();
     2635double random();
     2636float _Complex random();
     2637double _Complex random();
     2638long double _Complex random();
     2639\end{lstlisting}
     2640
     2641
     2642\subsection{min/max/swap}
     2643
     2644\begin{lstlisting}
     2645forall( otype T | { int ?<?( T, T ); } )
     2646T min( const T t1, const T t2 );
     2647
     2648forall( otype T | { int ?>?( T, T ); } )
     2649T max( const T t1, const T t2 );
     2650
     2651forall( otype T )
     2652void swap( T * t1, T * t2 );
     2653\end{lstlisting}
    24542654
    24552655
     
    24762676
    24772677task creates a type with implicit locking, separate stack, and a thread
    2478 
    24792678
    24802679\subsection{Monitors}
     
    35763775\multicolumn{1}{c|}{\textbf{\CFA/\CC}} & \multicolumn{1}{c|}{\textbf{Go}} & \multicolumn{1}{c}{\textbf{Rust}}   \\
    35773776\hline
    3578 \begin{lstlisting}[boxpos=t]
     3777\begin{lstlisting}
    35793778extern "C" {
    35803779#include <sys/types.h>
     
    35833782}
    35843783size_t fileSize( const char *path ) {
    3585         struct stat s;
     3784        stat s;
    35863785        stat(path, &s);
    35873786        return s.st_size;
     
    35893788\end{lstlisting}
    35903789&
    3591 \begin{lstlisting}[boxpos=t]
     3790\begin{lstlisting}
    35923791/*
    35933792#cgo
     
    36083807\end{lstlisting}
    36093808&
    3610 \begin{lstlisting}[boxpos=t]
     3809\begin{lstlisting}
    36113810use libc::{c_int, size_t};
     3811
     3812// The following declarations are
    36123813// translated from sys/stat.h
    36133814#[repr(C)]
     
    36173818        ...
    36183819}
     3820
    36193821#[link(name = "libc")]
    36203822extern {
     
    36223824        buf: *mut stat_t) -> c_int;
    36233825}
     3826
    36243827fn fileSize(path: *const u8) -> size_t
    36253828{
    36263829        unsafe {
    3627                 let mut buf: stat_t = uninit();
    3628                 stat(path, &mut buf);
    3629                 buf.st_size
     3830        let mut buf: stat_t = uninit();
     3831        stat(path, &mut buf);
     3832        buf.st_size
    36303833        }
    36313834}
     
    37503953
    37513954
    3752 \begin{comment}
    37533955\subsubsection{Modules/Packages}
    37543956
     
    38304032}
    38314033\end{lstlisting}
    3832 \end{comment}
    3833 
    38344034
    38354035\subsubsection{Parallel Tasks}
     
    39874187\end{flushleft}
    39884188
    3989 \lstset{basicstyle=\sf\relsize{-1}}
    3990 
    3991 
    39924189\subsection{Summary of Language Comparison}
    39934190
     
    40584255
    40594256
    4060 \appendix
    4061 
    4062 
    4063 \section{I/O Library}
    4064 \label{s:IOLibrary}
    4065 \index{input/output library}
    4066 
    4067 The goal for \CFA I/O is to make I/O as simple as possible for the general case, while fully supporting polmorphism and user defined types in a consistent way.
    4068 The general case is printing out a sequence of variables separated by whitespace.
    4069 \begin{quote2}
    4070 \begin{tabular}{@{}l@{\hspace{30pt}}l@{}}
    4071 \multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}}       & \multicolumn{1}{c}{\textbf{\CC}}      \\
    4072 \begin{lstlisting}
    4073 int x = 0, y = 1, z = 2;
    4074 `sout` `|` x `|` y `|` z `| endl`;
    4075 \end{lstlisting}
    4076 &
    4077 \begin{lstlisting}
    4078 
    4079 cout << x << " " << y << " " << z << endl;
    4080 \end{lstlisting}
    4081 \end{tabular}
    4082 \end{quote2}
    4083 The \CFA form is half as many characters, and is similar to Python I/O with respect to implicit separators.
    4084 
    4085 The logical-or operator is used because it is the lowest-priority overloadable operator, other than assignment.
    4086 Therefore, fewer output expressions require parenthesis.
    4087 \begin{quote2}
    4088 \begin{tabular}{@{}ll@{}}
    4089 \textbf{\CFA:}
    4090 &
    4091 \begin{lstlisting}
    4092 sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl;
    4093 \end{lstlisting}
    4094 \\
    4095 \textbf{\CC:}
    4096 &
    4097 \begin{lstlisting}
    4098 cout << x * 3 << y + 1 << (z << 2) << (x == y) << (x | y) << (x || y) << (x > z ? 1 : 2) << endl;
    4099 \end{lstlisting}
    4100 \end{tabular}
    4101 \end{quote2}
    4102 Finally, the logical-or operator has a link with the Shell pipe-operator for moving data, although data flows in the opposite direction.
    4103 
    4104 The implicit seperator\index{I/O separator} character (space/blank) is a separator not a terminator.
    4105 The rules for implicitly adding the separator are:
    4106 \begin{enumerate}
    4107 \item
    4108 A seperator does not appear at the start or end of a line.
    4109 \begin{lstlisting}[belowskip=0pt]
    4110 sout 1 | 2 | 3 | endl;
    4111 \end{lstlisting}
    4112 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    4113 1 2 3
    4114 \end{lstlisting}
    4115 \item
    4116 A seperator does not appear before or after a character literal or variable.
    4117 \begin{lstlisting}
    4118 sout | '1' | '2' | '3' | endl;
    4119 123
    4120 \end{lstlisting}
    4121 \item
    4122 A seperator does not appear before or after a null (empty) C string
    4123 \begin{lstlisting}
    4124 sout | 1 | "" | 2 | "" | 3 | endl;
    4125 123
    4126 \end{lstlisting}
    4127 which is a local mechanism to disable insertion of the separator character.
    4128 \item
    4129 A seperator does not appear before a C string starting with the \Index{extended ASCII}\index{ASCII} characters: \lstinline[mathescape=off]@([{$£¥¿«@
    4130 %$
    4131 \begin{lstlisting}[mathescape=off]
    4132 sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x $" | 4 | "x £" | 5 | "x ¥" | 6 | "x ¿" | 7 | "x «" | 8 | endl;
    4133 \end{lstlisting}
    4134 %$
    4135 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    4136 x (1 x [2 x {3 x $4 x £5 x ¥6 x ¿7 x «8
    4137 \end{lstlisting}
    4138 %$
    4139 \item
    4140 A seperator does not appear after a C string ending with the extended ASCII characters: \lstinline@,.:;!?)]}%¢»@
    4141 \begin{lstlisting}[belowskip=0pt]
    4142 sout | 1 | ", x" | 2 | ". x" | 3 | ": x" | 4 | "; x" | 5 | "! x" | 6 | "? x" | 7 | ") x" | 8 | "] x" | 9 | "} x"
    4143          | 10 | "% x" | 11 | L"¢ x" | 12 | L"» x" | endl;
    4144 \end{lstlisting}
    4145 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    4146 1, x 2. x 3: x 4; x 5! x 6? x 7) x 8] x 9} x 10% x 11¢ 12»
    4147 \end{lstlisting}
    4148 \item
    4149 A seperator does not appear before or after a C string begining/ending with the characters: \lstinline@\f\n\r\t\v\`'"@
    4150 \begin{lstlisting}[belowskip=0pt]
    4151 sout | "x '" | 1 | "' x \`" | 2 | "\` x \"" | 3 | "\" x" | endl;
    4152 \end{lstlisting}
    4153 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    4154 x '1' x \`2\` x "3" x
    4155 \end{lstlisting}
    4156 \begin{lstlisting}[showtabs=true,aboveskip=0pt]
    4157 sout | "x\t" | 1 | "\tx" | endl;
    4158 x       1       x
    4159 \end{lstlisting}
    4160 \end{enumerate}
    4161 The following \CC-style \Index{manipulator}s allow further control over implicit seperation.
    4162 \begin{lstlisting}[mathescape=off,belowskip=0pt]
    4163 sout | sepOn | 1 | 2 | 3 | sepOn | endl;        // separator at start of line
    4164 \end{lstlisting}
    4165 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    4166  1 2 3
    4167 \end{lstlisting}
    4168 \begin{lstlisting}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    4169 sout | 1 | sepOff | 2 | 3 | endl;                       // turn off implicit separator temporarily
    4170 \end{lstlisting}
    4171 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    4172 12 3
    4173 \end{lstlisting}
    4174 \begin{lstlisting}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    4175 sout | sepDisable | 1 | 2 | 3 | endl;           // turn off implicit separation, affects all subsequent prints
    4176 \end{lstlisting}
    4177 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    4178 123
    4179 \end{lstlisting}
    4180 \begin{lstlisting}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    4181 sout | 1 | sepOn | 2 | 3 | endl;                        // turn on implicit separator temporarily
    4182 \end{lstlisting}
    4183 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    4184 1 23
    4185 \end{lstlisting}
    4186 \begin{lstlisting}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    4187 sout | sepEnable | 1 | 2 | 3 | endl;            // turn on implicit separation, affects all subsequent prints
    4188 \end{lstlisting}
    4189 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    4190 1 2 3
    4191 \end{lstlisting}
    4192 \begin{lstlisting}[mathescape=off,aboveskip=0pt,aboveskip=0pt,belowskip=0pt]
    4193 sepSet( sout, ", $" );                                          // change separator from " " to ", $"
    4194 sout | 1 | 2 | 3 | endl;
    4195 \end{lstlisting}
    4196 %$
    4197 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt]
    4198 1, $2, $3
    4199 \end{lstlisting}
    4200 %$
    4201 \VRef[Figure]{f:ExampleIO} shows an example of input and output I/O in \CFA.
    4202 
    4203 \begin{figure}
    4204 \begin{lstlisting}[mathescape=off]
    4205 #include <fstream>
    4206 
    4207 int main() {
    4208         char c;                                                                                                         // basic types
    4209         short int si;
    4210         unsigned short int usi;
    4211         int i;
    4212         unsigned int ui;
    4213         long int li;
    4214         unsigned long int uli;
    4215         long long int lli;
    4216         unsigned long long int ulli;
    4217         float f;
    4218         double d;
    4219         long double ld;
    4220         float _Complex fc;
    4221         double _Complex dc;
    4222         long double _Complex ldc;
    4223         char s1[10], s2[10];
    4224 
    4225         ifstream in;                                                                                            // create / open file
    4226         open( &in, "input.data", "r" );
    4227 
    4228         &in | &c                                                                                                        // character
    4229                 | &si | &usi | &i | &ui | &li | &uli | &lli | &ulli             // integral
    4230                 | &f | &d | &ld                                                                                 // floating point
    4231                 | &fc | &dc | &ldc                                                                              // floating-point complex
    4232                 | cstr( s1 ) | cstr( s2, 10 );                                                  // C string, length unchecked and checked
    4233 
    4234         sout | c | ' ' | endl                                                                           // character
    4235                  | si | usi | i | ui | li | uli | lli | ulli | endl             // integral
    4236                  | f | d | ld | endl                                                                    // floating point
    4237                  | fc | dc | ldc | endl;                                                                // complex
    4238         sout | endl;
    4239         sout | f | "" | d | "" | ld | endl                                                      // floating point without separator
    4240                  | sepDisable | fc | dc | ldc | sepEnable | endl                // complex without separator
    4241                  | sepOn | s1 | sepOff | s2 | endl                                              // local separator removal
    4242                  | s1 | "" | s2 | endl;                                                                 // C string withou separator
    4243         sout | endl;
    4244         sepSet( sout, ", $" );                                                                          // change separator, maximum of 15 characters
    4245         sout | f | d | ld | endl                                                                        // floating point without separator
    4246                  | fc | dc | ldc | endl                                                                 // complex without separator
    4247                  | s1 | s2 | endl;
    4248 }
    4249 
    4250 $ cat input.data
    4251 A 1 2 3 4 5 6 7 8 1.1 1.2 1.3 1.1+2.3 1.1-2.3 1.1-2.3 abc xyz
    4252 $ a.out
    4253 A
    4254 1 2 3 4 5 6 7 8
    4255 1.1 1.2 1.3
    4256 1.1+2.3i 1.1-2.3i 1.1-2.3i
    4257 
    4258 1.11.21.3
    4259 1.1+2.3i1.1-2.3i1.1-2.3i
    4260  abcxyz
    4261 abcxyz
    4262 
    4263 1.1, $1.2, $1.3
    4264 1.1+2.3i, $1.1-2.3i, $1.1-2.3i
    4265 abc, $xyz
    4266 \end{lstlisting}
    4267 \caption{Example I/O}
    4268 \label{f:ExampleIO}
    4269 \end{figure}
    4270 
    4271 
    4272 \section{Standard Library}
    4273 \label{s:StandardLibrary}
    4274 
    4275 The goal of the \CFA standard-library is to wrap many of the existing C library-routines that are explicitly polymorphic into implicitly polymorphic versions.
    4276 
    4277 
    4278 \subsection{malloc}
    4279 
    4280 \begin{lstlisting}
    4281 forall( otype T ) T * malloc( void );
    4282 forall( otype T ) T * malloc( char fill );
    4283 forall( otype T ) T * malloc( T * ptr, size_t size );
    4284 forall( otype T ) T * malloc( T * ptr, size_t size, unsigned char fill );
    4285 forall( otype T ) T * calloc( size_t size );
    4286 forall( otype T ) T * realloc( T * ptr, size_t size );
    4287 forall( otype T ) T * realloc( T * ptr, size_t size, unsigned char fill );
    4288 
    4289 forall( otype T ) T * aligned_alloc( size_t alignment );
    4290 forall( otype T ) T * memalign( size_t alignment );             // deprecated
    4291 forall( otype T ) int posix_memalign( T ** ptr, size_t alignment );
    4292 
    4293 forall( otype T ) T * memset( T * ptr, unsigned char fill ); // use default value '\0' for fill
    4294 forall( otype T ) T * memset( T * ptr );                                // remove when default value available
    4295 \end{lstlisting}
    4296 
    4297 
    4298 \subsection{ato/strto}
    4299 
    4300 \begin{lstlisting}
    4301 int ato( const char * ptr );
    4302 unsigned int ato( const char * ptr );
    4303 long int ato( const char * ptr );
    4304 unsigned long int ato( const char * ptr );
    4305 long long int ato( const char * ptr );
    4306 unsigned long long int ato( const char * ptr );
    4307 float ato( const char * ptr );
    4308 double ato( const char * ptr );
    4309 long double ato( const char * ptr );
    4310 float _Complex ato( const char * ptr );
    4311 double _Complex ato( const char * ptr );
    4312 long double _Complex ato( const char * ptr );
    4313 
    4314 int strto( const char * sptr, char ** eptr, int base );
    4315 unsigned int strto( const char * sptr, char ** eptr, int base );
    4316 long int strto( const char * sptr, char ** eptr, int base );
    4317 unsigned long int strto( const char * sptr, char ** eptr, int base );
    4318 long long int strto( const char * sptr, char ** eptr, int base );
    4319 unsigned long long int strto( const char * sptr, char ** eptr, int base );
    4320 float strto( const char * sptr, char ** eptr );
    4321 double strto( const char * sptr, char ** eptr );
    4322 long double strto( const char * sptr, char ** eptr );
    4323 float _Complex strto( const char * sptr, char ** eptr );
    4324 double _Complex strto( const char * sptr, char ** eptr );
    4325 long double _Complex strto( const char * sptr, char ** eptr );
    4326 \end{lstlisting}
    4327 
    4328 
    4329 \subsection{bsearch/qsort}
    4330 
    4331 \begin{lstlisting}
    4332 forall( otype T | { int ?<?( T, T ); } )
    4333 T * bsearch( const T key, const T * arr, size_t dimension );
    4334 
    4335 forall( otype T | { int ?<?( T, T ); } )
    4336 void qsort( const T * arr, size_t dimension );
    4337 \end{lstlisting}
    4338 
    4339 
    4340 \subsection{abs}
    4341 
    4342 \begin{lstlisting}
    4343 char abs( char );
    4344 extern "C" {
    4345 int abs( int );                         // use default C routine for int
    4346 } // extern "C"
    4347 long int abs( long int );
    4348 long long int abs( long long int );
    4349 float abs( float );
    4350 double abs( double );
    4351 long double abs( long double );
    4352 float _Complex abs( float _Complex );
    4353 double _Complex abs( double _Complex );
    4354 long double _Complex abs( long double _Complex );
    4355 \end{lstlisting}
    4356 
    4357 
    4358 \subsection{floor/ceil}
    4359 
    4360 \begin{lstlisting}
    4361 float floor( float );
    4362 extern "C" {
    4363 double floor( double );         // use C routine for double
    4364 } // extern "C"
    4365 long double floor( long double );
    4366 
    4367 float ceil( float );
    4368 extern "C" {
    4369 double ceil( double );          // use C routine for double
    4370 } // extern "C"
    4371 long double ceil( long double );
    4372 \end{lstlisting}
    4373 
    4374 
    4375 \subsection{random}
    4376 
    4377 \begin{lstlisting}
    4378 void rand48seed( long int s );
    4379 char rand48();
    4380 int rand48();
    4381 unsigned int rand48();
    4382 long int rand48();
    4383 unsigned long int rand48();
    4384 float rand48();
    4385 double rand48();
    4386 float _Complex rand48();
    4387 double _Complex rand48();
    4388 long double _Complex rand48();
    4389 \end{lstlisting}
    4390 
    4391 
    4392 \subsection{min/max/swap}
    4393 
    4394 \begin{lstlisting}
    4395 forall( otype T | { int ?<?( T, T ); } )
    4396 T min( const T t1, const T t2 );
    4397 
    4398 forall( otype T | { int ?>?( T, T ); } )
    4399 T max( const T t1, const T t2 );
    4400 
    4401 forall( otype T )
    4402 void swap( T * t1, T * t2 );
    4403 \end{lstlisting}
    4404 
    4405 
    4406 \section{Rational Numbers}
    4407 \label{s:RationalNumbers}
    4408 
    4409 Rational numbers are numbers written as a ratio, i.e., as a fraction, where the numerator (top number) and the denominator (bottom number) are whole numbers.
    4410 When creating and computing with rational numbers, results are constantly reduced to keep the numerator and denominator as small as possible.
    4411 
    4412 \begin{lstlisting}
    4413 // implementation
    4414 struct Rational {
    4415         long int numerator, denominator;                                        // invariant: denominator > 0
    4416 }; // Rational
    4417 
    4418 // constants
    4419 extern struct Rational 0;
    4420 extern struct Rational 1;
    4421 
    4422 // constructors
    4423 Rational rational();
    4424 Rational rational( long int n );
    4425 Rational rational( long int n, long int d );
    4426 
    4427 // getter/setter for numerator/denominator
    4428 long int numerator( Rational r );
    4429 long int numerator( Rational r, long int n );
    4430 long int denominator( Rational r );
    4431 long int denominator( Rational r, long int d );
    4432 
    4433 // comparison
    4434 int ?==?( Rational l, Rational r );
    4435 int ?!=?( Rational l, Rational r );
    4436 int ?<?( Rational l, Rational r );
    4437 int ?<=?( Rational l, Rational r );
    4438 int ?>?( Rational l, Rational r );
    4439 int ?>=?( Rational l, Rational r );
    4440 
    4441 // arithmetic
    4442 Rational -?( Rational r );
    4443 Rational ?+?( Rational l, Rational r );
    4444 Rational ?-?( Rational l, Rational r );
    4445 Rational ?*?( Rational l, Rational r );
    4446 Rational ?/?( Rational l, Rational r );
    4447 
    4448 // conversion
    4449 double widen( Rational r );
    4450 Rational narrow( double f, long int md );
    4451 
    4452 // I/O
    4453 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, Rational * );
    4454 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, Rational );
    4455 \end{lstlisting}
    4456 
    4457 
    44584257\bibliographystyle{plain}
    4459 \bibliography{cfa}
     4258\bibliography{/usr/local/bibliographies/pl.bib}
    44604259
    44614260
  • src/CodeGen/CodeGenerator.cc

    r37218fc r3aba311  
    455455
    456456        void CodeGenerator::visit( UntypedOffsetofExpr *offsetofExpr ) {
    457                 assert( false && "UntypedOffsetofExpr should not reach code generation" );
     457                assert( false );
    458458        }
    459459
     
    464464                output << ", " << mangleName( offsetofExpr->get_member() );
    465465                output << ")";
    466         }
    467 
    468         void CodeGenerator::visit( OffsetPackExpr *offsetPackExpr ) {
    469                 assert( false && "OffsetPackExpr should not reach code generation" );
    470466        }
    471467 
  • src/CodeGen/CodeGenerator.h

    r37218fc r3aba311  
    6565                virtual void visit( UntypedOffsetofExpr *offsetofExpr );
    6666                virtual void visit( OffsetofExpr *offsetofExpr );
    67                 virtual void visit( OffsetPackExpr *offsetPackExpr );
    6867                virtual void visit( LogicalExpr *logicalExpr );
    6968                virtual void visit( ConditionalExpr *conditionalExpr );
  • src/GenPoly/Box.cc

    r37218fc r3aba311  
    3030#include "FindFunction.h"
    3131#include "ScopedMap.h"
    32 #include "ScopedSet.h"
    3332#include "ScrubTyVars.h"
    3433
     
    6362                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    6463
    65                 /// Abstracts type equality for a list of parameter types
    66                 struct TypeList {
    67                         TypeList() : params() {}
    68                         TypeList( const std::list< Type* > &_params ) : params() { cloneAll(_params, params); }
    69                         TypeList( std::list< Type* > &&_params ) : params( _params ) {}
    70 
    71                         TypeList( const TypeList &that ) : params() { cloneAll(that.params, params); }
    72                         TypeList( TypeList &&that ) : params( std::move( that.params ) ) {}
     64                /// Key for a unique concrete type; generic base type paired with type parameter list
     65                struct ConcreteType {
     66                        ConcreteType() : base(NULL), params() {}
     67
     68                        ConcreteType(AggregateDecl *_base, const std::list< Type* >& _params) : base(_base), params() { cloneAll(_params, params); }
     69
     70                        ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); }
    7371
    7472                        /// Extracts types from a list of TypeExpr*
    75                         TypeList( const std::list< TypeExpr* >& _params ) : params() {
     73                        ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base), params() {
    7674                                for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) {
    7775                                        params.push_back( (*param)->get_type()->clone() );
     
    7977                        }
    8078
    81                         TypeList& operator= ( const TypeList &that ) {
     79                        ConcreteType& operator= (const ConcreteType& that) {
    8280                                deleteAll( params );
    83 
    8481                                params.clear();
     82
     83                                base = that.base;
    8584                                cloneAll( that.params, params );
    8685
     
    8887                        }
    8988
    90                         TypeList& operator= ( TypeList &&that ) {
    91                                 deleteAll( params );
    92 
    93                                 params = std::move( that.params );
    94 
    95                                 return *this;
    96                         }
    97 
    98                         ~TypeList() { deleteAll( params ); }
    99 
    100                         bool operator== ( const TypeList& that ) const {
     89                        ~ConcreteType() { deleteAll( params ); }
     90
     91                        bool operator== (const ConcreteType& that) const {
     92                                if ( base != that.base ) return false;
     93
     94                                SymTab::Indexer dummy;
    10195                                if ( params.size() != that.params.size() ) return false;
    102 
    103                                 SymTab::Indexer dummy;
    10496                                for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) {
    10597                                        if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false;
     
    108100                        }
    109101
     102                        AggregateDecl *base;        ///< Base generic type
    110103                        std::list< Type* > params;  ///< Instantiation parameters
    111104                };
    112105
    113                 /// Maps a key and a TypeList to the some value, accounting for scope
    114                 template< typename Key, typename Value >
     106                /// Maps a concrete type to the some value, accounting for scope
     107                template< typename Value >
    115108                class InstantiationMap {
    116                         /// Wraps value for a specific (Key, TypeList) combination
    117                         typedef std::pair< TypeList, Value* > Instantiation;
    118                         /// List of TypeLists paired with their appropriate values
    119                         typedef std::vector< Instantiation > ValueList;
    120                         /// Underlying map type; maps keys to a linear list of corresponding TypeLists and values
    121                         typedef ScopedMap< Key*, ValueList > InnerMap;
    122 
    123                         InnerMap instantiations;  ///< instantiations
     109                        /// Information about a specific instantiation of a generic type
     110                        struct Instantiation {
     111                                ConcreteType key;  ///< Instantiation parameters for this type
     112                                Value *value;      ///< Value for this instantiation
     113
     114                                Instantiation() : key(), value(0) {}
     115                                Instantiation(const ConcreteType &_key, Value *_value) : key(_key), value(_value) {}
     116                        };
     117                        /// Map of generic types to instantiations of them
     118                        typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope;
     119
     120                        std::vector< Scope > scopes;  ///< list of scopes, from outermost to innermost
    124121
    125122                public:
    126123                        /// Starts a new scope
    127                         void beginScope() { instantiations.beginScope(); }
     124                        void beginScope() {
     125                                Scope scope;
     126                                scopes.push_back(scope);
     127                        }
    128128
    129129                        /// Ends a scope
    130                         void endScope() { instantiations.endScope(); }
    131 
    132                         /// Gets the value for the (key, typeList) pair, returns NULL on none such.
    133                         Value *lookup( Key *key, const std::list< TypeExpr* >& params ) const {
    134                                 TypeList typeList( params );
    135                                
    136                                 // scan scopes for matches to the key
    137                                 for ( typename InnerMap::const_iterator insts = instantiations.find( key ); insts != instantiations.end(); insts = instantiations.findNext( insts, key ) ) {
    138                                         for ( typename ValueList::const_reverse_iterator inst = insts->second.rbegin(); inst != insts->second.rend(); ++inst ) {
    139                                                 if ( inst->first == typeList ) return inst->second;
     130                        void endScope() {
     131                                scopes.pop_back();
     132                        }
     133
     134                        /// Default constructor initializes with one scope
     135                        InstantiationMap() { beginScope(); }
     136
     137//              private:
     138                        /// Gets the value for the concrete instantiation of this type, assuming it has already been instantiated in the current scope.
     139                        /// Returns NULL on none such.
     140                        Value *lookup( AggregateDecl *generic, const std::list< TypeExpr* >& params ) {
     141                                ConcreteType key(generic, params);
     142                                // scan scopes from innermost out
     143                                for ( typename std::vector< Scope >::const_reverse_iterator scope = scopes.rbegin(); scope != scopes.rend(); ++scope ) {
     144                                        // skip scope if no instantiations of this generic type
     145                                        typename Scope::const_iterator insts = scope->find( generic );
     146                                        if ( insts == scope->end() ) continue;
     147                                        // look through instantiations for matches to concrete type
     148                                        for ( typename std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) {
     149                                                if ( inst->key == key ) return inst->value;
    140150                                        }
    141151                                }
    142                                 // no matching instantiations found
     152                                // no matching instantiation found
    143153                                return 0;
    144154                        }
    145 
    146                         /// Adds a value for a (key, typeList) pair to the current scope
    147                         void insert( Key *key, const std::list< TypeExpr* > &params, Value *value ) {
    148                                 instantiations[ key ].push_back( Instantiation( TypeList( params ), value ) );
    149                         }
     155                public:
     156//                      StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)lookup( inst->get_baseStruct(), typeSubs ); }
     157//                      UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)lookup( inst->get_baseUnion(), typeSubs ); }
     158
     159//              private:
     160                        /// Adds a value for a concrete type to the current scope
     161                        void insert( AggregateDecl *generic, const std::list< TypeExpr* > &params, Value *value ) {
     162                                ConcreteType key(generic, params);
     163                                scopes.back()[generic].push_back( Instantiation( key, value ) );
     164                        }
     165//              public:
     166//                      void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { insert( inst->get_baseStruct(), typeSubs, decl ); }
     167//                      void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { insert( inst->get_baseUnion(), typeSubs, decl ); }
    150168                };
    151169
     
    179197                        virtual void doEndScope();
    180198                  private:
     199                        /// Makes a new temporary array holding the offsets of the fields of `type`, and returns a new variable expression referencing it
     200                        Expression *makeOffsetArray( StructInstType *type );
    181201                        /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application
    182202                        void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes );
     
    205225                        ObjectDecl *makeTemporary( Type *type );
    206226
    207                         std::map< std::string, DeclarationWithType *> assignOps;     ///< Currently known type variable assignment operators
    208                         ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps;  ///< Currently known assignment operators
    209                         ScopedMap< std::string, DeclarationWithType* > adapters;     ///< Set of adapter functions in the current scope
    210                        
     227                        std::map< std::string, DeclarationWithType *> assignOps;
     228                        ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps;
     229                        ScopedMap< std::string, DeclarationWithType* > adapters;
    211230                        DeclarationWithType *retval;
    212231                        bool useRetval;
     
    214233                };
    215234
    216                 /// * Moves polymorphic returns in function types to pointer-type parameters
    217                 /// * adds type size and assertion parameters to parameter lists
     235                /// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well
    218236                class Pass2 : public PolyMutator {
    219237                  public:
     
    226244                        virtual Type *mutate( PointerType *pointerType );
    227245                        virtual Type *mutate( FunctionType *funcType );
    228                        
    229246                  private:
    230247                        void addAdapters( FunctionType *functionType );
     
    236253                class GenericInstantiator : public DeclMutator {
    237254                        /// Map of (generic type, parameter list) pairs to concrete type instantiations
    238                         InstantiationMap< AggregateDecl, AggregateDecl > instantiations;
     255                        InstantiationMap< AggregateDecl > instantiations;
    239256                        /// Namer for concrete types
    240257                        UniqueName typeNamer;
     
    261278                };
    262279
    263                 /// Replaces member and size/align/offsetof expressions on polymorphic generic types with calculated expressions.
    264                 /// * Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference
    265                 /// * Calculates polymorphic offsetof expressions from offset array
    266                 /// * Inserts dynamic calculation of polymorphic type layouts where needed
    267                 class PolyGenericCalculator : public PolyMutator {
    268                 public:
     280                /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference;
     281                /// also fixes offsetof expressions.
     282                class MemberExprFixer : public PolyMutator {
     283                  public:
    269284                        template< typename DeclClass >
    270285                        DeclClass *handleDecl( DeclClass *decl, Type *type );
     
    277292                        virtual Type *mutate( FunctionType *funcType );
    278293                        virtual Expression *mutate( MemberExpr *memberExpr );
    279                         virtual Expression *mutate( SizeofExpr *sizeofExpr );
    280                         virtual Expression *mutate( AlignofExpr *alignofExpr );
    281294                        virtual Expression *mutate( OffsetofExpr *offsetofExpr );
    282                         virtual Expression *mutate( OffsetPackExpr *offsetPackExpr );
    283 
    284                         virtual void doBeginScope();
    285                         virtual void doEndScope();
    286 
    287                 private:
    288                         /// Makes a new variable in the current scope with the given name, type & optional initializer
    289                         ObjectDecl *makeVar( const std::string &name, Type *type, Initializer *init = 0 );
    290                         /// returns true if the type has a dynamic layout; such a layout will be stored in appropriately-named local variables when the function returns
    291                         bool findGeneric( Type *ty );
    292                         /// adds type parameters to the layout call; will generate the appropriate parameters if needed
    293                         void addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams );
    294                        
    295                         ScopedSet< std::string > knownLayouts;          ///< Set of generic type layouts known in the current scope, indexed by sizeofName
    296                         ScopedSet< std::string > knownOffsets;          ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName
    297295                };
    298296
     
    344342                Pass2 pass2;
    345343                GenericInstantiator instantiator;
    346                 PolyGenericCalculator polyCalculator;
     344                MemberExprFixer memberFixer;
    347345                Pass3 pass3;
    348346               
     
    350348                mutateTranslationUnit/*All*/( translationUnit, pass1 );
    351349                mutateTranslationUnit/*All*/( translationUnit, pass2 );
     350//              instantiateGeneric( translationUnit );
    352351                instantiator.mutateDeclarationList( translationUnit );
    353                 mutateTranslationUnit/*All*/( translationUnit, polyCalculator );
     352                mutateTranslationUnit/*All*/( translationUnit, memberFixer );
    354353                mutateTranslationUnit/*All*/( translationUnit, pass3 );
    355354        }
     
    654653
    655654                DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
    656                         // if this is a assignment function, put it in the map for this scope
     655                        // if this is a polymorphic assignment function, put it in the map for this scope
    657656                        if ( Type *assignedType = isAssignment( functionDecl ) ) {
    658657                                if ( ! dynamic_cast< TypeInstType* >( assignedType ) ) {
     
    744743                }
    745744
     745                Expression *Pass1::makeOffsetArray( StructInstType *ty ) {
     746                        std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members();
     747
     748                        // make a new temporary array
     749                        Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
     750                        std::stringstream lenGen;
     751                        lenGen << baseMembers.size();
     752                        ConstantExpr *lenExpr = new ConstantExpr( Constant( offsetType->clone(), lenGen.str() ) );
     753                        ObjectDecl *arrayTemp = makeTemporary( new ArrayType( Type::Qualifiers(), offsetType, lenExpr, false, false ) );
     754
     755                        // build initializer list for temporary
     756                        std::list< Initializer* > inits;
     757                        for ( std::list< Declaration* >::const_iterator member = baseMembers.begin(); member != baseMembers.end(); ++member ) {
     758                                DeclarationWithType *memberDecl;
     759                                if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) {
     760                                        memberDecl = origMember->clone();
     761                                } else {
     762                                        memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 );
     763                                }
     764                                inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) );
     765                        }
     766                        arrayTemp->set_init( new ListInit( inits ) );
     767
     768                        // return variable pointing to temporary
     769                        return new VariableExpr( arrayTemp );
     770                }
     771
    746772                void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) {
    747773                        Type *polyBase = hasPolyBase( parmType, exprTyVars );
     
    756782                                if ( dynamic_cast< StructInstType* >( polyBase ) ) {
    757783                                        if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) {
    758                                                 // zero-length arrays are forbidden by C, so don't pass offset for empty struct
    759                                                 if ( ! argBaseStructType->get_baseStruct()->get_members().empty() ) {
    760                                                         arg = appExpr->get_args().insert( arg, new OffsetPackExpr( argBaseStructType->clone() ) );
    761                                                         arg++;
    762                                                 }
     784                                                arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) );
     785                                                arg++;
    763786                                        } else {
    764787                                                throw SemanticError( "Cannot pass non-struct type for generic struct" );
     
    908931                                        return;
    909932                                } else if ( arg->get_results().front()->get_isLvalue() ) {
    910                                         // VariableExpr and MemberExpr are lvalues; need to check this isn't coming from the second arg of a comma expression though (not an lvalue)
    911                                         if ( CommaExpr *commaArg = dynamic_cast< CommaExpr* >( arg ) ) {
    912                                                 commaArg->set_arg2( new AddressExpr( commaArg->get_arg2() ) );
    913                                         } else {
    914                                                 arg = new AddressExpr( arg );
    915                                         }
     933                                        // VariableExpr and MemberExpr are lvalues
     934                                        arg = new AddressExpr( arg );
    916935                                } else {
    917936                                        // use type computed in unification to declare boxed variables
     
    10081027                        } // for
    10091028                }
     1029
     1030
    10101031
    10111032                FunctionDecl *Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) {
     
    14071428                                        std::list< TypeDecl* >::const_iterator forallIt = forallParams.begin();
    14081429                                        for ( ; tyIt != tyParams.end() && forallIt != forallParams.end(); ++tyIt, ++forallIt ) {
    1409                                                 // Add appropriate mapping to assignment expression environment
     1430                                                if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue; // skip types with no assign op (ftype/dtype)
     1431
     1432                                                std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions();
     1433                                                assert( ! asserts.empty() && "Type param needs assignment operator assertion" );
     1434                                                DeclarationWithType *actualDecl = asserts.front();
     1435                                                TypeInstType *actualType = isTypeInstAssignment( actualDecl );
     1436                                                assert( actualType && "First assertion of type with assertions should be assignment operator" );
    14101437                                                TypeExpr *formalTypeExpr = dynamic_cast< TypeExpr* >( *tyIt );
    14111438                                                assert( formalTypeExpr && "type parameters must be type expressions" );
    14121439                                                Type *formalType = formalTypeExpr->get_type();
    1413                                                 assignExpr->get_env()->add( (*forallIt)->get_name(), formalType );
    1414 
    1415                                                 // skip types with no assign op (ftype/dtype)
    1416                                                 if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue;
    1417 
    1418                                                 // find assignment operator for formal type
     1440                                                assignExpr->get_env()->add( actualType->get_name(), formalType );
     1441                                               
    14191442                                                DeclarationWithType *assertAssign = 0;
    14201443                                                if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) {
     
    14301453                                                        }
    14311454                                                }
    1432 
    1433                                                 // add inferred parameter for field assignment operator to assignment expression
    1434                                                 std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions();
    1435                                                 assert( ! asserts.empty() && "Type param needs assignment operator assertion" );
    1436                                                 DeclarationWithType *actualDecl = asserts.front();
     1455                                               
     1456
    14371457                                                assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ]
    14381458                                                        = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) );
     
    15671587                        ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0,
    15681588                                           new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 );
     1589//   ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
    15691590                        for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
    15701591                                ObjectDecl *sizeParm, *alignParm;
     
    16101631                                        ++last;
    16111632
    1612                                         if ( StructInstType *polyBaseStruct = dynamic_cast< StructInstType* >( polyBase ) ) {
    1613                                                 // NOTE zero-length arrays are illegal in C, so empty structs have no offset array
    1614                                                 if ( ! polyBaseStruct->get_baseStruct()->get_members().empty() ) {
    1615                                                         offsetParm = newPtr.clone();
    1616                                                         offsetParm->set_name( offsetofName( polyBase ) );
    1617                                                         last = funcType->get_parameters().insert( last, offsetParm );
    1618                                                         ++last;
    1619                                                 }
     1633                                        if ( dynamic_cast< StructInstType* >( polyBase ) ) {
     1634                                                offsetParm = newPtr.clone();
     1635                                                offsetParm->set_name( offsetofName( polyBase ) );
     1636                                                last = funcType->get_parameters().insert( last, offsetParm );
     1637                                                ++last;
    16201638                                        }
    16211639
     
    18261844
    18271845                template< typename DeclClass >
    1828                 DeclClass * PolyGenericCalculator::handleDecl( DeclClass *decl, Type *type ) {
     1846                DeclClass * MemberExprFixer::handleDecl( DeclClass *decl, Type *type ) {
    18291847                        TyVarMap oldtyVars = scopeTyVars;
    18301848                        makeTyVarMap( type, scopeTyVars );
     
    18361854                }
    18371855
    1838                 ObjectDecl * PolyGenericCalculator::mutate( ObjectDecl *objectDecl ) {
     1856                ObjectDecl * MemberExprFixer::mutate( ObjectDecl *objectDecl ) {
    18391857                        return handleDecl( objectDecl, objectDecl->get_type() );
    18401858                }
    18411859
    1842                 DeclarationWithType * PolyGenericCalculator::mutate( FunctionDecl *functionDecl ) {
     1860                DeclarationWithType * MemberExprFixer::mutate( FunctionDecl *functionDecl ) {
    18431861                        return handleDecl( functionDecl, functionDecl->get_functionType() );
    18441862                }
    18451863
    1846                 TypedefDecl * PolyGenericCalculator::mutate( TypedefDecl *typedefDecl ) {
     1864                TypedefDecl * MemberExprFixer::mutate( TypedefDecl *typedefDecl ) {
    18471865                        return handleDecl( typedefDecl, typedefDecl->get_base() );
    18481866                }
    18491867
    1850                 TypeDecl * PolyGenericCalculator::mutate( TypeDecl *typeDecl ) {
     1868                TypeDecl * MemberExprFixer::mutate( TypeDecl *typeDecl ) {
    18511869                        scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
    18521870                        return Mutator::mutate( typeDecl );
    18531871                }
    18541872
    1855                 Type * PolyGenericCalculator::mutate( PointerType *pointerType ) {
     1873                Type * MemberExprFixer::mutate( PointerType *pointerType ) {
    18561874                        TyVarMap oldtyVars = scopeTyVars;
    18571875                        makeTyVarMap( pointerType, scopeTyVars );
     
    18631881                }
    18641882
    1865                 Type * PolyGenericCalculator::mutate( FunctionType *funcType ) {
     1883                Type * MemberExprFixer::mutate( FunctionType *functionType ) {
    18661884                        TyVarMap oldtyVars = scopeTyVars;
    1867                         makeTyVarMap( funcType, scopeTyVars );
    1868 
    1869                         // make sure that any type information passed into the function is accounted for
    1870                         for ( std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); fnParm != funcType->get_parameters().end(); ++fnParm ) {
    1871                                 // condition here duplicates that in Pass2::mutate( FunctionType* )
    1872                                 Type *polyBase = hasPolyBase( (*fnParm)->get_type(), scopeTyVars );
    1873                                 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) {
    1874                                         knownLayouts.insert( sizeofName( polyBase ) );
    1875                                 }
    1876                         }
    1877                        
    1878                         Type *ret = Mutator::mutate( funcType );
     1885                        makeTyVarMap( functionType, scopeTyVars );
     1886
     1887                        Type *ret = Mutator::mutate( functionType );
    18791888
    18801889                        scopeTyVars = oldtyVars;
     
    18821891                }
    18831892
    1884                 Statement *PolyGenericCalculator::mutate( DeclStmt *declStmt ) {
     1893                Statement *MemberExprFixer::mutate( DeclStmt *declStmt ) {
    18851894                        if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
    1886                                 if ( findGeneric( objectDecl->get_type() ) ) {
     1895                                if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) {
    18871896                                        // change initialization of a polymorphic value object
    18881897                                        // to allocate storage with alloca
     
    19361945                }
    19371946               
    1938                 Expression *PolyGenericCalculator::mutate( MemberExpr *memberExpr ) {
     1947                Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) {
    19391948                        // mutate, exiting early if no longer MemberExpr
    19401949                        Expression *expr = Mutator::mutate( memberExpr );
     
    19531962                        Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars, &tyDepth );
    19541963                        if ( ! objectType ) return memberExpr;
    1955                         findGeneric( objectType ); // ensure layout for this type is available
    19561964
    19571965                        Expression *newMemberExpr = 0;
     
    19851993                }
    19861994
    1987                 ObjectDecl *PolyGenericCalculator::makeVar( const std::string &name, Type *type, Initializer *init ) {
    1988                         ObjectDecl *newObj = new ObjectDecl( name, DeclarationNode::NoStorageClass, LinkageSpec::C, 0, type, init );
    1989                         stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
    1990                         return newObj;
    1991                 }
    1992 
    1993                 void PolyGenericCalculator::addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams ) {
    1994                         for ( std::list< Type* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) {
    1995                                 if ( findGeneric( *param ) ) {
    1996                                         // push size/align vars for a generic parameter back
    1997                                         layoutCall->get_args().push_back( new NameExpr( sizeofName( *param ) ) );
    1998                                         layoutCall->get_args().push_back( new NameExpr( alignofName( *param ) ) );
    1999                                 } else {
    2000                                         layoutCall->get_args().push_back( new SizeofExpr( (*param)->clone() ) );
    2001                                         layoutCall->get_args().push_back( new AlignofExpr( (*param)->clone() ) );
    2002                                 }
    2003                         }
    2004                 }
    2005 
    2006                 /// returns true if any of the otype parameters have a dynamic layout and puts all otype parameters in the output list
    2007                 bool findGenericParams( std::list< TypeDecl* > &baseParams, std::list< Expression* > &typeParams, std::list< Type* > &out ) {
    2008                         bool hasDynamicLayout = false;
    2009 
    2010                         std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin();
    2011                         std::list< Expression* >::const_iterator typeParam = typeParams.begin();
    2012                         for ( ; baseParam != baseParams.end() && typeParam != typeParams.end(); ++baseParam, ++typeParam ) {
    2013                                 // skip non-otype parameters
    2014                                 if ( (*baseParam)->get_kind() != TypeDecl::Any ) continue;
    2015                                 TypeExpr *typeExpr = dynamic_cast< TypeExpr* >( *typeParam );
    2016                                 assert( typeExpr && "all otype parameters should be type expressions" );
    2017 
    2018                                 Type *type = typeExpr->get_type();
    2019                                 out.push_back( type );
    2020                                 if ( isPolyType( type ) ) hasDynamicLayout = true;
    2021                         }
    2022                         assert( baseParam == baseParams.end() && typeParam == typeParams.end() );
    2023 
    2024                         return hasDynamicLayout;
    2025                 }
    2026 
    2027                 bool PolyGenericCalculator::findGeneric( Type *ty ) {
    2028                         if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) {
    2029                                 // duplicate logic from isPolyType()
    2030                                 if ( env ) {
    2031                                         if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
    2032                                                 return findGeneric( newType );
    2033                                         } // if
    2034                                 } // if
    2035                                 if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() ) {
    2036                                         // NOTE assumes here that getting put in the scopeTyVars included having the layout variables set
    2037                                         return true;
    2038                                 }
    2039                                 return false;
    2040                         } else if ( StructInstType *structTy = dynamic_cast< StructInstType* >( ty ) ) {
    2041                                 // check if this type already has a layout generated for it
    2042                                 std::string sizeName = sizeofName( ty );
    2043                                 if ( knownLayouts.find( sizeName ) != knownLayouts.end() ) return true;
    2044 
    2045                                 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized
    2046                                 std::list< Type* > otypeParams;
    2047                                 if ( ! findGenericParams( *structTy->get_baseParameters(), structTy->get_parameters(), otypeParams ) ) return false;
    2048 
    2049                                 // insert local variables for layout and generate call to layout function
    2050                                 knownLayouts.insert( sizeName );  // done early so as not to interfere with the later addition of parameters to the layout call
    2051                                 Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    2052 
    2053                                 int n_members = structTy->get_baseStruct()->get_members().size();
    2054                                 if ( n_members == 0 ) {
    2055                                         // all empty structs have the same layout - size 1, align 1
    2056                                         makeVar( sizeName, layoutType, new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) );
    2057                                         makeVar( alignofName( ty ), layoutType->clone(), new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) );
    2058                                         // NOTE zero-length arrays are forbidden in C, so empty structs have no offsetof array
    2059                                 } else {
    2060                                         ObjectDecl *sizeVar = makeVar( sizeName, layoutType );
    2061                                         ObjectDecl *alignVar = makeVar( alignofName( ty ), layoutType->clone() );
    2062                                         ObjectDecl *offsetVar = makeVar( offsetofName( ty ), new ArrayType( Type::Qualifiers(), layoutType->clone(), new ConstantExpr( Constant::from( n_members ) ), false, false ) );
    2063 
    2064                                         // generate call to layout function
    2065                                         UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( "__layoutof_" + structTy->get_baseStruct()->get_name() ) );
    2066                                         layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( sizeVar ) ) );
    2067                                         layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( alignVar ) ) );
    2068                                         layoutCall->get_args().push_back( new VariableExpr( offsetVar ) );
    2069                                         addOtypeParamsToLayoutCall( layoutCall, otypeParams );
    2070 
    2071                                         stmtsToAdd.push_back( new ExprStmt( noLabels, layoutCall ) );
    2072                                 }
    2073 
    2074                                 return true;
    2075                         } else if ( UnionInstType *unionTy = dynamic_cast< UnionInstType* >( ty ) ) {
    2076                                 // check if this type already has a layout generated for it
    2077                                 std::string sizeName = sizeofName( ty );
    2078                                 if ( knownLayouts.find( sizeName ) != knownLayouts.end() ) return true;
    2079 
    2080                                 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized
    2081                                 std::list< Type* > otypeParams;
    2082                                 if ( ! findGenericParams( *unionTy->get_baseParameters(), unionTy->get_parameters(), otypeParams ) ) return false;
    2083 
    2084                                 // insert local variables for layout and generate call to layout function
    2085                                 knownLayouts.insert( sizeName );  // done early so as not to interfere with the later addition of parameters to the layout call
    2086                                 Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    2087 
    2088                                 ObjectDecl *sizeVar = makeVar( sizeName, layoutType );
    2089                                 ObjectDecl *alignVar = makeVar( alignofName( ty ), layoutType->clone() );
    2090 
    2091                                 // generate call to layout function
    2092                                 UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( "__layoutof_" + unionTy->get_baseUnion()->get_name() ) );
    2093                                 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( sizeVar ) ) );
    2094                                 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( alignVar ) ) );
    2095                                 addOtypeParamsToLayoutCall( layoutCall, otypeParams );
    2096 
    2097                                 stmtsToAdd.push_back( new ExprStmt( noLabels, layoutCall ) );
    2098 
    2099                                 return true;
    2100                         }
    2101 
    2102                         return false;
    2103                 }
    2104 
    2105                 Expression *PolyGenericCalculator::mutate( SizeofExpr *sizeofExpr ) {
    2106                         Type *ty = sizeofExpr->get_type();
    2107                         if ( findGeneric( ty ) ) {
    2108                                 Expression *ret = new NameExpr( sizeofName( ty ) );
    2109                                 delete sizeofExpr;
    2110                                 return ret;
    2111                         }
    2112                         return sizeofExpr;
    2113                 }
    2114 
    2115                 Expression *PolyGenericCalculator::mutate( AlignofExpr *alignofExpr ) {
    2116                         Type *ty = alignofExpr->get_type();
    2117                         if ( findGeneric( ty ) ) {
    2118                                 Expression *ret = new NameExpr( alignofName( ty ) );
    2119                                 delete alignofExpr;
    2120                                 return ret;
    2121                         }
    2122                         return alignofExpr;
    2123                 }
    2124 
    2125                 Expression *PolyGenericCalculator::mutate( OffsetofExpr *offsetofExpr ) {
     1995                Expression *MemberExprFixer::mutate( OffsetofExpr *offsetofExpr ) {
    21261996                        // mutate, exiting early if no longer OffsetofExpr
    21271997                        Expression *expr = Mutator::mutate( offsetofExpr );
     
    21302000
    21312001                        // only mutate expressions for polymorphic structs/unions
    2132                         Type *ty = offsetofExpr->get_type();
    2133                         if ( ! findGeneric( ty ) ) return offsetofExpr;
    2134                        
     2002                        Type *ty = isPolyType( offsetofExpr->get_type(), scopeTyVars );
     2003                        if ( ! ty ) return offsetofExpr;
     2004
    21352005                        if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) {
    21362006                                // replace offsetof expression by index into offset array
     
    21482018                }
    21492019
    2150                 Expression *PolyGenericCalculator::mutate( OffsetPackExpr *offsetPackExpr ) {
    2151                         StructInstType *ty = offsetPackExpr->get_type();
    2152 
    2153                         Expression *ret = 0;
    2154                         if ( findGeneric( ty ) ) {
    2155                                 // pull offset back from generated type information
    2156                                 ret = new NameExpr( offsetofName( ty ) );
    2157                         } else {
    2158                                 std::string offsetName = offsetofName( ty );
    2159                                 if ( knownOffsets.find( offsetName ) != knownOffsets.end() ) {
    2160                                         // use the already-generated offsets for this type
    2161                                         ret = new NameExpr( offsetName );
    2162                                 } else {
    2163                                         knownOffsets.insert( offsetName );
    2164 
    2165                                         std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members();
    2166                                         Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    2167 
    2168                                         // build initializer list for offset array
    2169                                         std::list< Initializer* > inits;
    2170                                         for ( std::list< Declaration* >::const_iterator member = baseMembers.begin(); member != baseMembers.end(); ++member ) {
    2171                                                 DeclarationWithType *memberDecl;
    2172                                                 if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) {
    2173                                                         memberDecl = origMember->clone();
    2174                                                 } else {
    2175                                                         memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 );
    2176                                                 }
    2177                                                 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) );
    2178                                         }
    2179 
    2180                                         // build the offset array and replace the pack with a reference to it
    2181                                         ObjectDecl *offsetArray = makeVar( offsetName, new ArrayType( Type::Qualifiers(), offsetType, new ConstantExpr( Constant::from( baseMembers.size() ) ), false, false ),
    2182                                                         new ListInit( inits ) );
    2183                                         ret = new VariableExpr( offsetArray );
    2184                                 }
    2185                         }
    2186 
    2187                         delete offsetPackExpr;
    2188                         return ret;
    2189                 }
    2190 
    2191                 void PolyGenericCalculator::doBeginScope() {
    2192                         knownLayouts.beginScope();
    2193                         knownOffsets.beginScope();
    2194                 }
    2195 
    2196                 void PolyGenericCalculator::doEndScope() {
    2197                         knownLayouts.endScope();
    2198                         knownOffsets.beginScope();
    2199                 }
    2200 
    22012020////////////////////////////////////////// Pass3 ////////////////////////////////////////////////////
    22022021
  • src/GenPoly/ScopedMap.h

    r37218fc r3aba311  
    1717#define _SCOPEDMAP_H
    1818
    19 #include <cassert>
    2019#include <iterator>
    2120#include <map>
     
    165164                void endScope() {
    166165                        scopes.pop_back();
    167                         assert( ! scopes.empty() );
    168166                }
    169167
     
    190188                        return end();
    191189                }
    192                 const_iterator find( const Key &key ) const {
    193                                 return const_iterator( const_cast< ScopedMap< Key, Value >* >(this)->find( key ) );
    194                 }
     190                const_iterator find( const Key &key ) const { return const_iterator( find( key ) ); }
    195191               
    196192                /// Finds the given key in the outermost scope inside the given scope where it occurs
     
    204200                        return end();
    205201                }
    206                 const_iterator findNext( const_iterator &it, const Key &key ) const {
    207                                 return const_iterator( const_cast< ScopedMap< Key, Value >* >(this)->findNext( it, key ) );
    208                 }
     202                const_iterator findNext( const_iterator &it, const Key &key ) const { return const_iterator( findNext( it, key ) ); }
    209203
    210204                /// Inserts the given key-value pair into the outermost scope
     
    214208                }
    215209                std::pair< iterator, bool > insert( const Key &key, const Value &value ) { return insert( std::make_pair( key, value ) ); }
    216 
    217                 Value& operator[] ( const Key &key ) {
    218                         iterator slot = find( key );
    219                         if ( slot != end() ) return slot->second;
    220                         return insert( key, Value() ).first->second;
    221                 }
     210               
    222211        };
    223212} // namespace GenPoly
  • src/InitTweak/InitModel.h

    r37218fc r3aba311  
    7575                        void visit( UntypedOffsetofExpr * ) { throw 0; }
    7676                        void visit( OffsetofExpr * ) { throw 0; }
    77                         void visit( OffsetPackExpr * ) { throw 0; }
    7877                        void visit( AttrExpr * ) { throw 0; }
    7978                        void visit( LogicalExpr * ) { throw 0; }
  • src/Parser/ExpressionNode.cc

    r37218fc r3aba311  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Apr  8 15:43:05 2016
    13 // Update Count     : 296
     12// Last Modified On : Sun Mar 13 12:34:38 2016
     13// Update Count     : 272
    1414//
    1515
     
    2222
    2323#include "ParseNode.h"
    24 #include "TypeData.h"
    2524#include "SynTree/Constant.h"
    2625#include "SynTree/Expression.h"
    27 #include "SynTree/Declaration.h"
    2826#include "Common/UnimplementedError.h"
    2927#include "parseutility.h"
     
    874872}
    875873
    876 
    877 CompoundLiteralNode::CompoundLiteralNode( DeclarationNode *type, InitializerNode *kids ) : type( type ), kids( kids ) {}
    878 CompoundLiteralNode::CompoundLiteralNode( const CompoundLiteralNode &other ) : ExpressionNode( other ), type( other.type ), kids( other.kids ) {}
    879 
    880 CompoundLiteralNode::~CompoundLiteralNode() {
    881         delete kids;
    882         delete type;
    883 }
    884 
    885 CompoundLiteralNode *CompoundLiteralNode::clone() const {
    886         return new CompoundLiteralNode( *this );
    887 }
    888 
    889 void CompoundLiteralNode::print( std::ostream &os, int indent ) const {
    890         os << string( indent,' ' ) << "CompoundLiteralNode:" << endl;
    891 
    892         os << string( indent + 2, ' ' ) << "type:" << endl;
    893         if ( type != 0 )
    894                 type->print( os, indent + 4 );
    895 
    896         os << string( indent + 2, ' ' ) << "initialization:" << endl;
    897         if ( kids != 0 )
    898                 kids->printList( os, indent + 4 );
    899 }
    900 
    901 void CompoundLiteralNode::printOneLine( std::ostream &os, int indent ) const {
    902         os << "( ";
    903         if ( type ) type->print( os );
    904         os << ", ";
    905         if ( kids ) kids->printOneLine( os );
    906         os << ") ";
    907 }
    908 
    909 Expression *CompoundLiteralNode::build() const {
    910         Declaration * newDecl = type->build();                          // compound literal type
    911         if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type
    912                 return new CompoundLiteralExpr( newDeclWithType->get_type(), kids->build() );
    913         // these types do not have associated type information
    914         } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl )  ) {
    915                 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), kids->build() );
    916         } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl )  ) {
    917                 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), kids->build() );
    918         } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl )  ) {
    919                 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), kids->build() );
    920         } else {
    921                 assert( false );
    922         } // if
    923 }
    924 
    925 
    926874ExpressionNode *flattenCommas( ExpressionNode *list ) {
    927875        if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) ) {
  • src/Parser/ParseNode.h

    r37218fc r3aba311  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Mon Apr 11 11:50:52 2016
    13 // Update Count     : 205
     12// Last Modified On : Mon Apr 04 17:04:22 2016
     13// Update Count     : 190
    1414//
    1515
     
    538538};
    539539
    540 class CompoundLiteralNode : public ExpressionNode {
    541   public:
    542         CompoundLiteralNode( DeclarationNode *type, InitializerNode *kids );
    543         CompoundLiteralNode( const CompoundLiteralNode &type );
    544         ~CompoundLiteralNode();
    545 
    546         virtual CompoundLiteralNode *clone() const;
    547 
    548         DeclarationNode *get_type() const { return type; }
    549         CompoundLiteralNode *set_type( DeclarationNode *t ) { type = t; return this; }
    550 
    551         InitializerNode *get_initializer() const { return kids; }
    552         CompoundLiteralNode *set_initializer( InitializerNode *k ) { kids = k; return this; }
    553 
    554         void print( std::ostream &, int indent = 0 ) const;
    555         void printOneLine( std::ostream &, int indent = 0 ) const;
    556 
    557         virtual Expression *build() const;
    558   private:
    559         DeclarationNode *type;
    560         InitializerNode *kids;
    561 };
    562 
    563540template< typename SynTreeType, typename NodeType >
    564541void buildList( const NodeType *firstNode, std::list< SynTreeType *> &outputList ) {
  • src/Parser/parser.cc

    r37218fc r3aba311  
    51805180/* Line 1806 of yacc.c  */
    51815181#line 374 "parser.yy"
    5182     { (yyval.en) = new CompoundLiteralNode( (yyvsp[(2) - (7)].decl), new InitializerNode( (yyvsp[(5) - (7)].in), true ) ); }
     5182    { (yyval.en) = 0; }
    51835183    break;
    51845184
  • src/Parser/parser.yy

    r37218fc r3aba311  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Apr  8 16:21:55 2016
    13 // Update Count     : 1508
     12// Last Modified On : Thu Mar 24 16:16:16 2016
     13// Update Count     : 1498
    1414//
    1515
     
    372372                { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::DecrPost ), $1 ); }
    373373        | '(' type_name_no_function ')' '{' initializer_list comma_opt '}' // C99
    374                 { $$ = new CompoundLiteralNode( $2, new InitializerNode( $5, true ) ); }
     374                { $$ = 0; }
    375375        | postfix_expression '{' argument_expression_list '}' // CFA
    376376                {
  • src/ResolvExpr/AlternativeFinder.cc

    r37218fc r3aba311  
    848848        }
    849849
    850         void AlternativeFinder::visit( OffsetPackExpr *offsetPackExpr ) {
    851                 alternatives.push_back( Alternative( offsetPackExpr->clone(), env, Cost::zero ) );
    852         }
    853 
    854850        void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) {
    855851                // assume no polymorphism
  • src/ResolvExpr/AlternativeFinder.h

    r37218fc r3aba311  
    5959                virtual void visit( UntypedOffsetofExpr *offsetofExpr );
    6060                virtual void visit( OffsetofExpr *offsetofExpr );
    61                 virtual void visit( OffsetPackExpr *offsetPackExpr );
    6261                virtual void visit( AttrExpr *attrExpr );
    6362                virtual void visit( LogicalExpr *logicalExpr );
  • src/SymTab/AddVisit.h

    r37218fc r3aba311  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 16:14:32 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Apr  7 14:42:21 2016
    13 // Update Count     : 5
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Tue Jul 14 12:26:17 2015
     13// Update Count     : 4
    1414//
    1515
     
    2727
    2828        template< typename Visitor >
     29        inline void addVisitStatement( Statement *stmt, Visitor &visitor ) {
     30                maybeAccept( stmt, visitor );
     31///   if ( ! declsToAdd.empty() ) {
     32///     CompoundStmt *compound = new CompoundStmt( noLabels );
     33///     compound->get_kids().push_back( stmt );
     34///     addDecls( declsToAdd, compound->get_kids(), compound->get_kids().end() );
     35///   }
     36        }
     37
     38        template< typename Visitor >
    2939        inline void addVisit(CompoundStmt *compoundStmt, Visitor &visitor) {
    3040                addVisitStatementList( compoundStmt->get_kids(), visitor );
     41        }
     42
     43        template< typename Visitor >
     44        inline void addVisit(IfStmt *ifStmt, Visitor &visitor) {
     45                addVisitStatement( ifStmt->get_thenPart(), visitor );
     46                addVisitStatement( ifStmt->get_elsePart(), visitor );
     47                maybeAccept( ifStmt->get_condition(), visitor );
     48        }
     49
     50        template< typename Visitor >
     51        inline void addVisit(WhileStmt *whileStmt, Visitor &visitor) {
     52                addVisitStatement( whileStmt->get_body(), visitor );
     53                maybeAccept( whileStmt->get_condition(), visitor );
     54        }
     55
     56        template< typename Visitor >
     57        inline void addVisit(ForStmt *forStmt, Visitor &visitor) {
     58                addVisitStatement( forStmt->get_body(), visitor );
     59                acceptAll( forStmt->get_initialization(), visitor );
     60                maybeAccept( forStmt->get_condition(), visitor );
     61                maybeAccept( forStmt->get_increment(), visitor );
    3162        }
    3263
     
    4374        }
    4475
    45         // template< typename Visitor >
    46         // inline void addVisit(CaseStmt *caseStmt, Visitor &visitor) {
    47         //      addVisitStatementList( caseStmt->get_statements(), visitor );
    48         //      maybeAccept( caseStmt->get_condition(), visitor );
    49         // }
     76        template< typename Visitor >
     77        inline void addVisit(CaseStmt *caseStmt, Visitor &visitor) {
     78                addVisitStatementList( caseStmt->get_statements(), visitor );
     79                maybeAccept( caseStmt->get_condition(), visitor );
     80        }
     81
     82        template< typename Visitor >
     83        inline void addVisit(CatchStmt *cathStmt, Visitor &visitor) {
     84                addVisitStatement( cathStmt->get_body(), visitor );
     85                maybeAccept( cathStmt->get_decl(), visitor );
     86        }
    5087} // namespace SymTab
    5188
  • src/SymTab/Indexer.cc

    r37218fc r3aba311  
    344344                maybeAccept( offsetofExpr->get_type(), *this );
    345345                maybeAccept( offsetofExpr->get_member(), *this );
    346         }
    347 
    348         void Indexer::visit( OffsetPackExpr *offsetPackExpr ) {
    349                 acceptAllNewScope( offsetPackExpr->get_results(), *this );
    350                 maybeAccept( offsetPackExpr->get_type(), *this );
    351346        }
    352347
  • src/SymTab/Indexer.h

    r37218fc r3aba311  
    5959                virtual void visit( UntypedOffsetofExpr *offsetofExpr );
    6060                virtual void visit( OffsetofExpr *offsetofExpr );
    61                 virtual void visit( OffsetPackExpr *offsetPackExpr );
    6261                virtual void visit( AttrExpr *attrExpr );
    6362                virtual void visit( LogicalExpr *logicalExpr );
  • src/SymTab/Validate.cc

    r37218fc r3aba311  
    1010// Created On       : Sun May 17 21:50:04 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Apr  7 16:45:30 2016
    13 // Update Count     : 243
     12// Last Modified On : Wed Mar  2 17:31:39 2016
     13// Update Count     : 226
    1414//
    1515
     
    4040#include <list>
    4141#include <iterator>
    42 #include "Common/utility.h"
    43 #include "Common/UniqueName.h"
    4442#include "Validate.h"
    4543#include "SynTree/Visitor.h"
    4644#include "SynTree/Mutator.h"
    4745#include "SynTree/Type.h"
    48 #include "SynTree/Expression.h"
    4946#include "SynTree/Statement.h"
    5047#include "SynTree/TypeSubstitution.h"
     
    5249#include "FixFunction.h"
    5350// #include "ImplementationType.h"
    54 #include "GenPoly/DeclMutator.h"
     51#include "Common/utility.h"
     52#include "Common/UniqueName.h"
    5553#include "AddVisit.h"
    5654#include "MakeLibCfa.h"
     
    7270
    7371                virtual void visit( CompoundStmt *compoundStmt );
     72                virtual void visit( IfStmt *ifStmt );
     73                virtual void visit( WhileStmt *whileStmt );
     74                virtual void visit( ForStmt *forStmt );
    7475                virtual void visit( SwitchStmt *switchStmt );
    7576                virtual void visit( ChooseStmt *chooseStmt );
    76                 // virtual void visit( CaseStmt *caseStmt );
     77                virtual void visit( CaseStmt *caseStmt );
     78                virtual void visit( CatchStmt *catchStmt );
    7779          private:
    7880                HoistStruct();
     
    142144
    143145                virtual void visit( CompoundStmt *compoundStmt );
     146                virtual void visit( IfStmt *ifStmt );
     147                virtual void visit( WhileStmt *whileStmt );
     148                virtual void visit( ForStmt *forStmt );
    144149                virtual void visit( SwitchStmt *switchStmt );
    145150                virtual void visit( ChooseStmt *chooseStmt );
    146                 // virtual void visit( CaseStmt *caseStmt );
     151                virtual void visit( CaseStmt *caseStmt );
     152                virtual void visit( CatchStmt *catchStmt );
    147153
    148154                AutogenerateRoutines() : functionNesting( 0 ) {}
     
    160166                /// and return something if the return type is non-void.
    161167                static void checkFunctionReturns( std::list< Declaration * > & translationUnit );
     168
    162169          private:
    163170                virtual void visit( FunctionDecl * functionDecl );
     
    195202        };
    196203
    197         class CompoundLiteral : public GenPoly::DeclMutator {
    198                 DeclarationNode::StorageClass storageclass = DeclarationNode::NoStorageClass;
    199 
    200                 virtual DeclarationWithType * mutate( ObjectDecl *objectDecl );
    201                 virtual Expression *mutate( CompoundLiteralExpr *compLitExpr );
    202         };
    203 
    204204        void validate( std::list< Declaration * > &translationUnit, bool doDebug ) {
    205205                Pass1 pass1;
    206206                Pass2 pass2( doDebug, 0 );
    207207                Pass3 pass3( 0 );
    208                 CompoundLiteral compoundliteral;
    209 
    210208                EliminateTypedef::eliminateTypedef( translationUnit );
    211209                HoistStruct::hoistStruct( translationUnit );
     
    213211                acceptAll( translationUnit, pass2 );
    214212                ReturnChecker::checkFunctionReturns( translationUnit );
    215                 mutateAll( translationUnit, compoundliteral );
    216213                AutogenerateRoutines::autogenerateRoutines( translationUnit );
    217214                acceptAll( translationUnit, pass3 );
     
    295292        }
    296293
     294        void HoistStruct::visit( IfStmt *ifStmt ) {
     295                addVisit( ifStmt, *this );
     296        }
     297
     298        void HoistStruct::visit( WhileStmt *whileStmt ) {
     299                addVisit( whileStmt, *this );
     300        }
     301
     302        void HoistStruct::visit( ForStmt *forStmt ) {
     303                addVisit( forStmt, *this );
     304        }
     305
    297306        void HoistStruct::visit( SwitchStmt *switchStmt ) {
    298307                addVisit( switchStmt, *this );
     
    303312        }
    304313
    305         // void HoistStruct::visit( CaseStmt *caseStmt ) {
    306         //      addVisit( caseStmt, *this );
    307         // }
     314        void HoistStruct::visit( CaseStmt *caseStmt ) {
     315                addVisit( caseStmt, *this );
     316        }
     317
     318        void HoistStruct::visit( CatchStmt *cathStmt ) {
     319                addVisit( cathStmt, *this );
     320        }
    308321
    309322        void Pass1::visit( EnumDecl *enumDecl ) {
     
    861874        }
    862875
     876        void AutogenerateRoutines::visit( IfStmt *ifStmt ) {
     877                visitStatement( ifStmt );
     878        }
     879
     880        void AutogenerateRoutines::visit( WhileStmt *whileStmt ) {
     881                visitStatement( whileStmt );
     882        }
     883
     884        void AutogenerateRoutines::visit( ForStmt *forStmt ) {
     885                visitStatement( forStmt );
     886        }
     887
    863888        void AutogenerateRoutines::visit( SwitchStmt *switchStmt ) {
    864889                visitStatement( switchStmt );
     
    869894        }
    870895
    871         // void AutogenerateRoutines::visit( CaseStmt *caseStmt ) {
    872         //      visitStatement( caseStmt );
    873         // }
     896        void AutogenerateRoutines::visit( CaseStmt *caseStmt ) {
     897                visitStatement( caseStmt );
     898        }
     899
     900        void AutogenerateRoutines::visit( CatchStmt *cathStmt ) {
     901                visitStatement( cathStmt );
     902        }
    874903
    875904        void ReturnChecker::checkFunctionReturns( std::list< Declaration * > & translationUnit ) {
     
    10511080        }
    10521081
    1053         DeclarationWithType * CompoundLiteral::mutate( ObjectDecl *objectDecl ) {
    1054                 storageclass = objectDecl->get_storageClass();
    1055                 DeclarationWithType * temp = Mutator::mutate( objectDecl );
    1056                 storageclass = DeclarationNode::NoStorageClass;
    1057                 return temp;
    1058         }
    1059 
    1060         Expression *CompoundLiteral::mutate( CompoundLiteralExpr *compLitExpr ) {
    1061                 // transform [storage_class] ... (struct S){ 3, ... };
    1062                 // into [storage_class] struct S temp =  { 3, ... };
    1063                 static UniqueName indexName( "_compLit" );
    1064 
    1065                 ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageclass, LinkageSpec::C, 0, compLitExpr->get_type(), compLitExpr->get_initializer() );
    1066                 compLitExpr->set_type( 0 );
    1067                 compLitExpr->set_initializer( 0 );
    1068                 delete compLitExpr;
    1069                 DeclarationWithType * newtempvar = mutate( tempvar );
    1070                 addDeclaration( newtempvar );                                   // add modified temporary to current block
    1071                 return new VariableExpr( newtempvar );
    1072         }
    10731082} // namespace SymTab
    10741083
  • src/SynTree/Expression.cc

    r37218fc r3aba311  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Apr  8 17:16:23 2016
    13 // Update Count     : 40
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Dec 09 14:10:29 2015
     13// Update Count     : 34
    1414//
    1515
     
    2222
    2323#include "Type.h"
    24 #include "Initializer.h"
    2524#include "Expression.h"
    2625#include "Declaration.h"
     
    212211
    213212        os << " of ";
    214 
    215         if ( type ) {
    216                 type->print(os, indent + 2);
    217         } else {
    218                 os << "<NULL>";
    219         }
    220 
    221         os << std::endl;
    222         Expression::print( os, indent );
    223 }
    224 
    225 OffsetPackExpr::OffsetPackExpr( StructInstType *type_, Expression *aname_ ) : Expression( aname_ ), type( type_ ) {
    226         add_result( new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0, false, false ) );
    227 }
    228 
    229 OffsetPackExpr::OffsetPackExpr( const OffsetPackExpr &other ) : Expression( other ), type( maybeClone( other.type ) ) {}
    230 
    231 OffsetPackExpr::~OffsetPackExpr() { delete type; }
    232 
    233 void OffsetPackExpr::print( std::ostream &os, int indent ) const {
    234         os << std::string( indent, ' ' ) << "Offset pack expression on ";
    235213
    236214        if ( type ) {
     
    465443
    466444
    467 CompoundLiteralExpr::CompoundLiteralExpr( Type * type, Initializer * initializer ) : type( type ), initializer( initializer ) {
    468         add_result( type->clone() );
    469 }
    470 
    471 CompoundLiteralExpr::CompoundLiteralExpr( const CompoundLiteralExpr &other ) : Expression( other ), type( maybeClone( other.type ) ), initializer( maybeClone( other.initializer ) ) {}
    472 
    473 CompoundLiteralExpr::~CompoundLiteralExpr() {
    474         delete initializer;
    475         delete type;
    476 }
    477 
    478 void CompoundLiteralExpr::print( std::ostream &os, int indent ) const {
    479         os << "Compound Literal Expression: " << std::endl;
    480         if ( type ) type->print( os, indent + 2 );
    481         if ( initializer ) initializer->print( os, indent + 2 );
    482 }
    483 
    484445
    485446std::ostream & operator<<( std::ostream & out, Expression * expr ) {
  • src/SynTree/Expression.h

    r37218fc r3aba311  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Apr  8 17:18:06 2016
    13 // Update Count     : 21
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Dec 09 14:10:21 2015
     13// Update Count     : 19
    1414//
    1515
     
    362362};
    363363
    364 /// Expression representing a pack of field-offsets for a generic type
    365 class OffsetPackExpr : public Expression {
    366 public:
    367         OffsetPackExpr( StructInstType *type_, Expression *aname_ = 0 );
    368         OffsetPackExpr( const OffsetPackExpr &other );
    369         virtual ~OffsetPackExpr();
    370 
    371         StructInstType *get_type() const { return type; }
    372         void set_type( StructInstType *newValue ) { type = newValue; }
    373 
    374         virtual OffsetPackExpr *clone() const { return new OffsetPackExpr( *this ); }
    375         virtual void accept( Visitor &v ) { v.visit( this ); }
    376         virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    377 
    378         virtual void print( std::ostream &os, int indent = 0 ) const;
    379 
    380 private:
    381         StructInstType *type;
    382 };
    383 
    384364/// AttrExpr represents an @attribute expression (like sizeof, but user-defined)
    385365class AttrExpr : public Expression {
     
    577557};
    578558
    579 /// CompoundLiteralExpr represents a C99 'compound literal'
    580 class CompoundLiteralExpr : public Expression {
    581   public:
    582         CompoundLiteralExpr( Type * type, Initializer * initializer );
    583         CompoundLiteralExpr( const CompoundLiteralExpr &other );
    584         ~CompoundLiteralExpr();
    585 
    586         Type * get_type() const { return type; }
    587         void set_type( Type * t ) { type = t; }
    588 
    589         Initializer * get_initializer() const { return initializer; }
    590         void set_initializer( Initializer * i ) { initializer = i; }
    591 
    592         virtual CompoundLiteralExpr *clone() const { return new CompoundLiteralExpr( *this ); }
    593         virtual void accept( Visitor &v ) { v.visit( this ); }
    594         virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    595         virtual void print( std::ostream &os, int indent = 0 ) const;
    596   private:
    597         Type * type;
    598         Initializer * initializer;
    599 };
    600 
    601559std::ostream & operator<<( std::ostream & out, Expression * expr );
    602560
  • src/SynTree/Mutator.cc

    r37218fc r3aba311  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Apr  1 18:05:16 2016
    13 // Update Count     : 16
     12// Last Modified On : Wed Mar  2 17:28:20 2016
     13// Update Count     : 12
    1414//
    1515
     
    274274}
    275275
    276 Expression *Mutator::mutate( OffsetPackExpr *offsetPackExpr ) {
    277         mutateAll( offsetPackExpr->get_results(), *this );
    278         offsetPackExpr->set_type( maybeMutate( offsetPackExpr->get_type(), *this ) );
    279         return offsetPackExpr;
    280 }
    281 
    282276Expression *Mutator::mutate( AttrExpr *attrExpr ) {
    283277        mutateAll( attrExpr->get_results(), *this );
     
    340334        mutateAll( valofExpr->get_results(), *this );
    341335        return valofExpr;
    342 }
    343 
    344 Expression *Mutator::mutate( CompoundLiteralExpr *compLitExpr ) {
    345         mutateAll( compLitExpr->get_results(), *this );
    346         compLitExpr->set_type( maybeMutate( compLitExpr->get_type(), *this ) );
    347         compLitExpr->set_initializer( maybeMutate( compLitExpr->get_initializer(), *this ) );
    348         return compLitExpr;
    349336}
    350337
  • src/SynTree/Mutator.h

    r37218fc r3aba311  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Apr  1 17:26:56 2016
    13 // Update Count     : 10
     12// Last Modified On : Wed Mar  2 17:33:11 2016
     13// Update Count     : 9
    1414//
    1515#include <cassert>
     
    6767        virtual Expression* mutate( UntypedOffsetofExpr *offsetofExpr );
    6868        virtual Expression* mutate( OffsetofExpr *offsetofExpr );
    69         virtual Expression* mutate( OffsetPackExpr *offsetPackExpr );
    7069        virtual Expression* mutate( AttrExpr *attrExpr );
    7170        virtual Expression* mutate( LogicalExpr *logicalExpr );
     
    7776        virtual Expression* mutate( AsmExpr *asmExpr );
    7877        virtual Expression* mutate( UntypedValofExpr *valofExpr );
    79         virtual Expression* mutate( CompoundLiteralExpr *compLitExpr );
    8078
    8179        virtual Type* mutate( VoidType *basicType );
  • src/SynTree/SynTree.h

    r37218fc r3aba311  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Apr  1 16:47:44 2016
    13 // Update Count     : 5
     12// Last Modified On : Wed Mar  2 17:29:00 2016
     13// Update Count     : 4
    1414//
    1515
     
    7272class UntypedOffsetofExpr;
    7373class OffsetofExpr;
    74 class OffsetPackExpr;
    7574class AttrExpr;
    7675class LogicalExpr;
     
    8281class AsmExpr;
    8382class UntypedValofExpr;
    84 class CompoundLiteralExpr;
    8583
    8684class Type;
  • src/SynTree/Visitor.cc

    r37218fc r3aba311  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Apr  1 18:05:13 2016
    13 // Update Count     : 18
     12// Last Modified On : Wed Mar  2 17:29:23 2016
     13// Update Count     : 16
    1414//
    1515
     
    230230}
    231231
    232 void Visitor::visit( OffsetPackExpr *offsetPackExpr ) {
    233         acceptAll( offsetPackExpr->get_results(), *this );
    234         maybeAccept( offsetPackExpr->get_type(), *this );
    235 }
    236 
    237232void Visitor::visit( AttrExpr *attrExpr ) {
    238233        acceptAll( attrExpr->get_results(), *this );
     
    287282        acceptAll( valofExpr->get_results(), *this );
    288283        maybeAccept( valofExpr->get_body(), *this );
    289 }
    290 
    291 void Visitor::visit( CompoundLiteralExpr *compLitExpr ) {
    292         acceptAll( compLitExpr->get_results(), *this );
    293         maybeAccept( compLitExpr->get_type(), *this );
    294         maybeAccept( compLitExpr->get_initializer(), *this );
    295284}
    296285
  • src/SynTree/Visitor.h

    r37218fc r3aba311  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Apr  1 17:26:55 2016
    13 // Update Count     : 7
     12// Last Modified On : Wed Mar  2 17:33:35 2016
     13// Update Count     : 6
    1414//
    1515
     
    6767        virtual void visit( UntypedOffsetofExpr *offsetofExpr );
    6868        virtual void visit( OffsetofExpr *offsetofExpr );
    69         virtual void visit( OffsetPackExpr *offsetPackExpr );
    7069        virtual void visit( AttrExpr *attrExpr );
    7170        virtual void visit( LogicalExpr *logicalExpr );
     
    7776        virtual void visit( AsmExpr *asmExpr );
    7877        virtual void visit( UntypedValofExpr *valofExpr );
    79         virtual void visit( CompoundLiteralExpr *compLitExpr );
    8078
    8179        virtual void visit( VoidType *basicType );
  • src/Tuples/FlattenTuple.cc

    r37218fc r3aba311  
    4949        void FlattenTuple::CollectArgs::visit( UntypedOffsetofExpr *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    5050        void FlattenTuple::CollectArgs::visit( OffsetofExpr        *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    51         void FlattenTuple::CollectArgs::visit( OffsetPackExpr      *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    5251        void FlattenTuple::CollectArgs::visit( AttrExpr            *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    5352        void FlattenTuple::CollectArgs::visit( LogicalExpr         *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
  • src/Tuples/FlattenTuple.h

    r37218fc r3aba311  
    4545                        virtual void visit( UntypedOffsetofExpr * );
    4646                        virtual void visit( OffsetofExpr * );
    47                         virtual void visit( OffsetPackExpr * );
    4847                        virtual void visit( AttrExpr * );
    4948                        virtual void visit( LogicalExpr * );
  • src/driver/cfa.cc

    r37218fc r3aba311  
    1010// Created On       : Tue Aug 20 13:44:49 2002
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Apr  6 14:04:22 2016
    13 // Update Count     : 132
     12// Last Modified On : Thu Jan 28 18:24:06 2016
     13// Update Count     : 127
    1414//
    1515
     
    165165                                nargs += 1;
    166166                        } else if ( prefix( arg, "-std=" ) ) {
    167                                 std_flag = true;                                                // -std=XX provided
     167                                std_flag = true;                                                // std=XX provided
    168168                                args[nargs] = argv[i];                                  // pass the argument along
    169169                                nargs += 1;
     
    307307                nargs += 1;
    308308                if ( ! std_flag ) {                                                             // default c99, if none specified
    309                         args[nargs] = "-std=gnu99";
     309                        args[nargs] = "-std=c99";
    310310                        nargs += 1;
    311311                } // if
  • src/libcfa/Makefile.am

    r37218fc r3aba311  
    1111## Created On       : Sun May 31 08:54:01 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Wed Apr  6 21:10:44 2016
    14 ## Update Count     : 123
     13## Last Modified On : Wed Mar  2 22:59:23 2016
     14## Update Count     : 119
    1515###############################################################################
    1616
     
    6060        ${CC} ${CFLAGS} -c -o $@ $<
    6161
    62 libs = limits stdlib iostream fstream iterator rational
     62libs = stdlib iostream fstream iterator
    6363libcfa_a_SOURCES = libcfa-prelude.c ${libs:=.c}
    6464
    65 cheaders = # expat
    66 cfaheaders = # limits
     65cheaders = #  expat
     66cfaheaders = limits
    6767include_HEADERS = ${cheaders:=.h} ${libs} ${cfaheaders}
    6868
  • src/libcfa/Makefile.in

    r37218fc r3aba311  
    8383libcfa_a_AR = $(AR) $(ARFLAGS)
    8484libcfa_a_LIBADD =
    85 am__objects_1 = limits.$(OBJEXT) stdlib.$(OBJEXT) iostream.$(OBJEXT) \
    86         fstream.$(OBJEXT) iterator.$(OBJEXT) rational.$(OBJEXT)
     85am__objects_1 = stdlib.$(OBJEXT) iostream.$(OBJEXT) fstream.$(OBJEXT) \
     86        iterator.$(OBJEXT)
    8787am_libcfa_a_OBJECTS = libcfa-prelude.$(OBJEXT) $(am__objects_1)
    8888libcfa_a_OBJECTS = $(am_libcfa_a_OBJECTS)
     
    213213MAINTAINERCLEANFILES = ${addprefix ${libdir}/,${cfalib_DATA}} \
    214214        ${addprefix ${libdir}/,${lib_LIBRARIES}} ${includedir}/*
    215 libs = limits stdlib iostream fstream iterator rational
     215libs = stdlib iostream fstream iterator
    216216libcfa_a_SOURCES = libcfa-prelude.c ${libs:=.c}
    217 cheaders = # expat
    218 cfaheaders = # limits
     217cheaders = #  expat
     218cfaheaders = limits
    219219include_HEADERS = ${cheaders:=.h} ${libs} ${cfaheaders}
    220220all: all-am
     
    297297@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iterator.Po@am__quote@
    298298@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa-prelude.Po@am__quote@
    299 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/limits.Po@am__quote@
    300 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rational.Po@am__quote@
    301299@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stdlib.Po@am__quote@
    302300
  • src/libcfa/fstream

    r37218fc r3aba311  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Apr  5 22:37:12 2016
    13 // Update Count     : 82
     12// Last Modified On : Wed Mar  2 15:08:14 2016
     13// Update Count     : 78
    1414//
    1515
     
    2020
    2121enum { separateSize = 16 };
    22 struct ofstream {
    23         void *file;
    24         _Bool sepDefault;
    25         _Bool sepOnOff;
    26         char separator[separateSize];
    27 }; // ofstream
     22struct ofstream { void *file; int separate; char separator[separateSize]; };
    2823
    2924_Bool sepPrt( ofstream * );
    3025void sepOn( ofstream * );
    3126void sepOff( ofstream * );
    32 void sepReset( ofstream * );
    33 void sepReset( ofstream *, _Bool );
    3427void sepSet( ofstream *, const char * );
    3528const char * sepGet( ofstream * );
    36 _Bool sepDisable( ofstream * );
    37 _Bool sepEnable( ofstream * );
     29void sepDisable( ofstream * );
     30void sepEnable( ofstream * );
    3831int fail( ofstream * );
    3932int flush( ofstream * );
     
    4639
    4740// implement context istream
    48 struct ifstream {
    49         void *file;
    50 }; // ifstream
     41struct ifstream { void *file; };
    5142
    5243int fail( ifstream * is );
  • src/libcfa/fstream.c

    r37218fc r3aba311  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Apr  6 17:55:27 2016
    13 // Update Count     : 176
     12// Last Modified On : Mon Feb 29 18:41:10 2016
     13// Update Count     : 162
    1414//
    1515
     
    2525}
    2626
    27 #define IO_MSG "I/O error: "
     27#define IO_MSG "I/O error "
    2828
    29 _Bool sepPrt( ofstream * os ) { return os->sepOnOff; }
    30 void sepOn( ofstream * os ) { os->sepOnOff = 1; }
    31 void sepOff( ofstream * os ) { os->sepOnOff = 0; }
    32 void sepReset( ofstream * os ) { os->sepOnOff = os->sepDefault; }
    33 void sepReset( ofstream * os, _Bool reset ) { os->sepDefault = reset; os->sepOnOff = os->sepDefault; }
     29_Bool sepPrt( ofstream * os ) { return os->separate == 1; }
     30void sepOn( ofstream * os ) { if ( os->separate != 2 ) os->separate = 1; }
     31void sepOff( ofstream * os ) { if ( os->separate != 2 ) os->separate = 0; }
    3432void sepSet( ofstream * os, const char * s ) {
    3533        strncpy( &(os->separator[0]), s, separateSize - 1 );
     
    3735} // sepSet
    3836const char * sepGet( ofstream * os ) { return &(os->separator[0]); }
    39 _Bool sepDisable( ofstream *os ) {
    40         _Bool temp = os->sepDefault;
    41         os->sepDefault = 0;
    42         sepReset( os );
    43         return temp;
    44 } // sepDisable
    45 _Bool sepEnable( ofstream *os ) {
    46         _Bool temp = os->sepDefault;
    47         os->sepDefault = 1;
    48         sepReset( os );
    49         return temp;
    50 } // sepEnable
     37void sepDisable( ofstream *os ) { os->separate = 2; }
     38void sepEnable( ofstream *os ) { os->separate = 0; }
    5139
    5240int fail( ofstream * os ) {
     
    6149        FILE *file = fopen( name, mode );
    6250        if ( file == 0 ) {                                                                      // do not change unless successful
    63                 fprintf( stderr, IO_MSG "open output file \"%s\", ", name );
    64                 perror( 0 );
     51                perror( IO_MSG "open output" );
    6552                exit( EXIT_FAILURE );
    6653        } // if
     
    10794
    10895
    109 static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_), 1, 0, { ' ', '\0' } };
     96static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_), 0, { ' ', '\0' } };
    11097ofstream *sout = &soutFile;
    111 static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_), 1, 0, { ' ', '\0' } };
     98static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_), 0, { ' ', '\0' } };
    11299ofstream *serr = &serrFile;
    113100
     
    127114        FILE *t = fopen( name, mode );
    128115        if ( t == 0 ) {                                                                         // do not change unless successful
    129                 fprintf( stderr, IO_MSG "open input file \"%s\", ", name );
    130                 perror( 0 );
     116                perror( IO_MSG "open input" );
    131117                exit( EXIT_FAILURE );
    132118        } // if
     
    189175// Local Variables: //
    190176// tab-width: 4 //
     177// compile-command: "cfa fstream.c" //
    191178// End: //
  • src/libcfa/iostream

    r37218fc r3aba311  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Apr  5 22:32:37 2016
    13 // Update Count     : 90
     12// Last Modified On : Wed Mar  2 18:05:27 2016
     13// Update Count     : 85
    1414//
    1515
     
    2323        void sepOn( ostype * );
    2424        void sepOff( ostype * );
    25         void sepReset( ostype * );
    26         void sepReset( ostype *, _Bool );
    2725        void sepSet( ostype *, const char * );
    2826        const char * sepGet( ostype * );
    29         _Bool sepDisable( ostype * );
    30         _Bool sepEnable( ostype * );
     27        void sepDisable( ostype * );
     28        void sepEnable( ostype * );
    3129        int fail( ostype * );
    3230        int flush( ostype * );
     
    6967forall( dtype ostype | ostream( ostype ) ) ostype * sepOn( ostype * );
    7068forall( dtype ostype | ostream( ostype ) ) ostype * sepOff( ostype * );
    71 forall( dtype ostype | ostream( ostype ) ) ostype * sepDisable( ostype * );
    72 forall( dtype ostype | ostream( ostype ) ) ostype * sepEnable( ostype * );
    7369
    7470// writes the range [begin, end) to the given stream
     
    114110forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, long double _Complex * );
    115111
    116 struct _Istream_cstrUC { char * s; };
    117 _Istream_cstrUC cstr( char * );
    118 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, _Istream_cstrUC );
     112struct _Istream_str1 { char * s; };
     113_Istream_str1 str( char * );
     114forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, _Istream_str1 );
    119115
    120 struct _Istream_cstrC { char * s; int size; };
    121 _Istream_cstrC cstr( char *, int size );
    122 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, _Istream_cstrC );
     116struct _Istream_str2 { char * s; int size; };
     117_Istream_str2 str( char *, int size );
     118forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, _Istream_str2 );
    123119
    124120#endif // __IOSTREAM_H__
  • src/libcfa/iostream.c

    r37218fc r3aba311  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Apr  6 16:13:29 2016
    13 // Update Count     : 278
     12// Last Modified On : Mon Mar  7 13:51:23 2016
     13// Update Count     : 227
    1414//
    1515
     
    2727ostype * ?|?( ostype *os, char c ) {
    2828        prtfmt( os, "%c", c );
    29         sepOff( os );
    3029        return os;
    3130} // ?|?
     
    3332forall( dtype ostype | ostream( ostype ) )
    3433ostype * ?|?( ostype *os, short int si ) {
    35         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    36         sepReset( os );
     34        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
    3735        prtfmt( os, "%hd", si );
    3836        return os;
     
    4139forall( dtype ostype | ostream( ostype ) )
    4240ostype * ?|?( ostype *os, unsigned short int usi ) {
    43         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    44         sepReset( os );
     41        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
    4542        prtfmt( os, "%hu", usi );
    4643        return os;
     
    4946forall( dtype ostype | ostream( ostype ) )
    5047ostype * ?|?( ostype *os, int i ) {
    51         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    52         sepReset( os );
     48        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
    5349        prtfmt( os, "%d", i );
    5450        return os;
     
    5753forall( dtype ostype | ostream( ostype ) )
    5854ostype * ?|?( ostype *os, unsigned int ui ) {
    59         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    60         sepReset( os );
     55        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
    6156        prtfmt( os, "%u", ui );
    6257        return os;
     
    6560forall( dtype ostype | ostream( ostype ) )
    6661ostype * ?|?( ostype *os, long int li ) {
    67         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    68         sepReset( os );
     62        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
    6963        prtfmt( os, "%ld", li );
    7064        return os;
     
    7367forall( dtype ostype | ostream( ostype ) )
    7468ostype * ?|?( ostype *os, unsigned long int uli ) {
    75         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    76         sepReset( os );
     69        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
    7770        prtfmt( os, "%lu", uli );
    7871        return os;
     
    8174forall( dtype ostype | ostream( ostype ) )
    8275ostype * ?|?( ostype *os, long long int lli ) {
    83         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    84         sepReset( os );
     76        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
    8577        prtfmt( os, "%lld", lli );
    8678        return os;
     
    8981forall( dtype ostype | ostream( ostype ) )
    9082ostype * ?|?( ostype *os, unsigned long long int ulli ) {
    91         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    92         sepReset( os );
     83        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
    9384        prtfmt( os, "%llu", ulli );
    9485        return os;
     
    9788forall( dtype ostype | ostream( ostype ) )
    9889ostype * ?|?( ostype *os, float f ) {
    99         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    100         sepReset( os );
     90        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
    10191        prtfmt( os, "%g", f );
    10292        return os;
     
    10595forall( dtype ostype | ostream( ostype ) )
    10696ostype * ?|?( ostype *os, double d ) {
    107         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    108         sepReset( os );
     97        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
    10998        prtfmt( os, "%.*lg", DBL_DIG, d );
    11099        return os;
     
    113102forall( dtype ostype | ostream( ostype ) )
    114103ostype * ?|?( ostype *os, long double ld ) {
    115         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    116         sepReset( os );
     104        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
    117105        prtfmt( os, "%.*Lg", LDBL_DIG, ld );
    118106        return os;
     
    122110ostype * ?|?( ostype *os, float _Complex fc ) {
    123111        os | crealf( fc );
    124         _Bool temp = sepDisable( os );                                          // disable separators within complex value
    125         if ( cimagf( fc ) >= 0 ) os | '+';                                      // negative value prints '-'
    126         os | cimagf( fc ) | 'i';
    127         sepReset( os, temp );                                                           // reset separator
     112        if ( cimagf( fc ) >= 0 ) os | '+';
     113        os | "" | cimagf( fc ) | 'i';
    128114        return os;
    129115} // ?|?
     
    132118ostype * ?|?( ostype *os, double _Complex dc ) {
    133119        os | creal( dc );
    134         _Bool temp = sepDisable( os );                                          // disable separators within complex value
    135         if ( cimag( dc ) >= 0 ) os | '+';                                       // negative value prints '-'
    136         os | cimag( dc ) | 'i';
    137         sepReset( os, temp );                                                           // reset separator
     120        if ( cimag( dc ) >= 0 ) os | '+';
     121        os | "" | cimag( dc ) | 'i';
    138122        return os;
    139123} // ?|?
     
    142126ostype * ?|?( ostype *os, long double _Complex ldc ) {
    143127        os | creall( ldc );
    144         _Bool temp = sepDisable( os );                                          // disable separators within complex value
    145         if ( cimagl( ldc ) >= 0 ) os | '+';                                     // negative value prints '-'
    146         os | cimagl( ldc ) | 'i';
    147         sepReset( os, temp );                                                           // reset separator
     128        if ( cimagl( ldc ) >= 0 ) os | '+';
     129        os | "" | cimagl( ldc ) | 'i';
    148130        return os;
    149131} // ?|?
     
    152134ostype * ?|?( ostype *os, const char *cp ) {
    153135        enum { Open = 1, Close, OpenClose };
    154         static const unsigned char mask[256] = {
     136        static const char mask[256] = {
    155137                // opening delimiters
    156138                ['('] : Open, ['['] : Open, ['{'] : Open,
    157                 ['$'] : Open, [(unsigned char)'£'] : Open, [(unsigned char)'¥'] : Open, [(unsigned char)'¿'] : Open, [(unsigned char)'«'] : Open,
     139                ['$'] : Open, [L'£'] : Open, [L'¥'] : Open, [L'¢'] : Open, [L'¿'] : Open, [L'«'] : Open,
    158140                // closing delimiters
    159141                [','] : Close, ['.'] : Close, [':'] : Close, [';'] : Close, ['!'] : Close, ['?'] : Close,
    160142                [')'] : Close, [']'] : Close, ['}'] : Close,
    161                 ['%'] : Close, [(unsigned char)'¢'] : Close, [(unsigned char)'»'] : Close,
     143                ['%'] : Close, [L'»'] : Close,
    162144                // opening-closing delimiters
    163145                ['\''] : OpenClose, ['`'] : OpenClose, ['"'] : OpenClose,
    164                 ['\f'] : OpenClose, ['\n'] : OpenClose, ['\r'] : OpenClose, ['\t'] : OpenClose, ['\v'] : OpenClose, // isspace
    165146        }; // mask
    166147
     
    168149        // null string => no separator
    169150  if ( len == 0 ) { sepOff( os ); return os; }
    170         // first character IS NOT spacing or closing punctuation => add left separator
    171         unsigned char ch = cp[0];                                                       // must make unsigned
    172         if ( sepPrt( os ) && mask[ ch ] != Close && mask[ ch ] != OpenClose ) {
     151        // first character NOT spacing or closing punctuation => add left separator
     152        if ( sepPrt( os ) && isspace( cp[0] ) == 0 && mask[ cp[0] ] != Close && mask[ cp[0] ] != OpenClose ) {
    173153                prtfmt( os, "%s", sepGet( os ) );
    174154        } // if
    175155        // last character IS spacing or opening punctuation => turn off separator for next item
    176156        unsigned int posn = len - 1;
    177         ch = cp[posn];                                                                          // must make unsigned
    178         if ( mask[ ch ] == Open || mask[ ch ] == OpenClose ) {
     157        if ( isspace( cp[posn] ) || mask[ cp[posn] ] == Open || mask[ cp[posn] ] == OpenClose ) {
    179158                sepOff( os );
    180159        } else {
     
    186165forall( dtype ostype | ostream( ostype ) )
    187166ostype * ?|?( ostype *os, const void *p ) {
    188         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    189         sepReset( os );
     167        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
    190168        prtfmt( os, "%p", p );
    191169        return os;
     
    218196} // sepOff
    219197
    220 forall( dtype ostype | ostream( ostype ) )
    221 ostype * sepEnable( ostype * os ) {
    222         sepEnable( os );
    223         return os;
    224 } // sepEnable
    225 
    226 forall( dtype ostype | ostream( ostype ) )
    227 ostype * sepDisable( ostype * os ) {
    228         sepDisable( os );
    229         return os;
    230 } // sepDisable
    231 
    232198//---------------------------------------
    233199
     
    344310} // ?|?
    345311
    346 _Istream_cstrUC cstr( char * s ) { _Istream_cstrUC s = { s }; return s; }
    347 forall( dtype istype | istream( istype ) )
    348 istype * ?|?( istype * is, _Istream_cstrUC cstr ) {
    349         scanfmt( is, "%s", cstr.s );
    350         return is;
    351 } // cstr
    352 
    353 _Istream_cstrC cstr( char * s, int size ) { _Istream_cstrC s = { s, size }; return s; }
    354 forall( dtype istype | istream( istype ) )
    355 istype * ?|?( istype * is, _Istream_cstrC cstr ) {
     312_Istream_str1 str( char * s ) { _Istream_str1 s = { s }; return s; }
     313forall( dtype istype | istream( istype ) )
     314istype * ?|?( istype * is, _Istream_str1 str ) {
     315        scanfmt( is, "%s", str.s );
     316        return is;
     317} // str
     318
     319_Istream_str2 str( char * s, int size ) { _Istream_str2 s = { s, size }; return s; }
     320forall( dtype istype | istream( istype ) )
     321istype * ?|?( istype * is, _Istream_str2 str ) {
    356322        char buf[16];
    357         sprintf( buf, "%%%ds", cstr.size );
    358         scanfmt( is, buf, cstr.s );
    359         return is;
    360 } // cstr
     323        sprintf( buf, "%%%ds", str.size );
     324        scanfmt( is, buf, str.s );
     325        return is;
     326} // str
    361327
    362328// Local Variables: //
  • src/libcfa/limits

    r37218fc r3aba311  
    1 //
    2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
    3 //
    4 // The contents of this file are covered under the licence agreement in the
    5 // file "LICENCE" distributed with Cforall.
    6 //
    7 // limits --
    8 //
    9 // Author           : Peter A. Buhr
    10 // Created On       : Wed Apr  6 18:06:52 2016
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Apr  6 21:08:16 2016
    13 // Update Count     : 6
    14 //
    15 
    161// Integral Constants
    172
    18 extern const short int MIN;
    19 extern const int MIN;
    20 extern const long int MIN;
    21 extern const long long int MIN;
     3const short int MIN = -32768;
     4const int MIN = -2147483648;
     5const long int MIN = -9223372036854775807L - 1L;
     6const long long int MIN = -9223372036854775807LL - 1LL;
    227
    23 extern const short int MAX;
    24 extern const unsigned short int MAX;
    25 extern const int MAX;
    26 extern const unsigned int MAX;
    27 extern const long int MAX;
    28 extern const unsigned long int MAX;
    29 extern const long long int MAX;
    30 extern const unsigned long long int MAX;
     8const short int MAX = 32767;
     9const unsigned short int MAX = 65535;
     10const int MAX = 2147483647;
     11const unsigned int MAX = 4294967295_U;
     12const long int MAX = 9223372036854775807_L;
     13const unsigned long int MAX = 4294967295_U;
     14const long long int MAX = 9223372036854775807_LL;
     15const unsigned long long int MAX = 18446744073709551615_ULL;
    3116
    3217// Floating-Point Constants
    3318
    34 extern const float PI;                                                                  // pi
    35 extern const float PI_2;                                                                // pi / 2
    36 extern const float PI_4;                                                                // pi / 4
    37 extern const float _1_PI;                                                               // 1 / pi
    38 extern const float _2_PI;                                                               // 2 / pi
    39 extern const float _2_SQRT_PI;                                                  // 2 / sqrt(pi)
     19const float PI = 3.141592_F;                            // pi
     20const float PI_2 = 1.570796_F;                          // pi / 2
     21const float PI_4 = 0.7853981_F;                         // pi / 4
     22const float _1_PI = 0.3183098_F;                        // 1 / pi
     23const float _2_PI = 0.6366197_F;                        // 2 / pi
     24const float _2_SQRT_PI = 1.128379_F;                    // 2 / sqrt(pi)
    4025
    41 extern const double PI;                                                                 // pi
    42 extern const double PI_2;                                                               // pi / 2
    43 extern const double PI_4;                                                               // pi / 4
    44 extern const double _1_PI;                                                              // 1 / pi
    45 extern const double _2_PI;                                                              // 2 / pi
    46 extern const double _2_SQRT_PI;                                                 // 2 / sqrt(pi)
     26const double PI = 3.14159265358979323846_D;             // pi
     27const double PI_2 = 1.57079632679489661923_D;           // pi / 2
     28const double PI_4 = 0.78539816339744830962_D;           // pi / 4
     29const double _1_PI = 0.31830988618379067154_D;          // 1 / pi
     30const double _2_PI = 0.63661977236758134308_D;          // 2 / pi
     31const double _2_SQRT_PI = 1.12837916709551257390_D;     // 2 / sqrt(pi)
    4732
    48 extern const long double PI;                                                    // pi
    49 extern const long double PI_2;                                                  // pi / 2
    50 extern const long double PI_4;                                                  // pi / 4
    51 extern const long double _1_PI;                                                 // 1 / pi
    52 extern const long double _2_PI;                                                 // 2 / pi
    53 extern const long double _2_SQRT_PI;                                    // 2 / sqrt(pi)
     33const long double PI = 3.1415926535897932384626433832795029_DL; // pi
     34const long double PI_2 = 1.5707963267948966192313216916397514_DL; // pi / 2
     35const long double PI_4 = 0.7853981633974483096156608458198757_DL; // pi / 4
     36const long double _1_PI = 0.3183098861837906715377675267450287_DL; // 1 / pi
     37const long double _2_PI = 0.6366197723675813430755350534900574_DL; // 2 / pi
     38const long double _2_SQRT_PI = 1.1283791670955125738961589031215452_DL; // 2 / sqrt(pi)
    5439
    55 extern const _Complex PI;                                                               // pi
    56 extern const _Complex PI_2;                                                             // pi / 2
    57 extern const _Complex PI_4;                                                             // pi / 4
    58 extern const _Complex _1_PI;                                                    // 1 / pi
    59 extern const _Complex _2_PI;                                                    // 2 / pi
    60 extern const _Complex _2_SQRT_PI;                                               // 2 / sqrt(pi)
     40const _Complex PI = 3.14159265358979323846_D+0.0_iD;    // pi
     41const _Complex PI_2 = 1.57079632679489661923_D+0.0_iD;  // pi / 2
     42const _Complex PI_4 = 0.78539816339744830962_D+0.0_iD;  // pi / 4
     43const _Complex _1_PI = 0.31830988618379067154_D+0.0_iD; // 1 / pi
     44const _Complex _2_PI = 0.63661977236758134308_D+0.0_iD; // 2 / pi
     45const _Complex _2_SQRT_PI = 1.12837916709551257390_D+0.0_iD; // 2 / sqrt(pi)
    6146
    62 extern const long _Complex PI;                                                  // pi
    63 extern const long _Complex PI_2;                                                // pi / 2
    64 extern const long _Complex PI_4;                                                // pi / 4
    65 extern const long _Complex _1_PI;                                               // 1 / pi
    66 extern const long _Complex _2_PI;                                               // 2 / pi
    67 extern const long _Complex _2_SQRT_PI;                                  // 2 / sqrt(pi)
     47const long _Complex PI = 3.1415926535897932384626433832795029_L+0.0iL; // pi
     48const long _Complex PI_2 = 1.5707963267948966192313216916397514_L+0.0iL; // pi / 2
     49const long _Complex PI_4 = 0.7853981633974483096156608458198757_L+0.0iL; // pi / 4
     50const long _Complex _1_PI = 0.3183098861837906715377675267450287_L+0.0iL; // 1 / pi
     51const long _Complex _2_PI = 0.6366197723675813430755350534900574_L+0.0iL; // 2 / pi
     52const long _Complex _2_SQRT_PI = 1.1283791670955125738961589031215452_L+0.0iL; // 2 / sqrt(pi)
    6853
    69 extern const float E;                                                                   // e
    70 extern const float LOG2_E;                                                              // log_2(e)
    71 extern const float LOG10_E;                                                             // log_10(e)
    72 extern const float LN_2;                                                                // log_e(2)
    73 extern const float LN_10;                                                               // log_e(10)
    74 extern const float SQRT_2;                                                              // sqrt(2)
    75 extern const float _1_SQRT_2;                                                   // 1 / sqrt(2)
     54const float E = 2.718281;                               // e
     55const float LOG2_E = 1.442695;                          // log_2(e)
     56const float LOG10_E = 0.4342944;                        // log_10(e)
     57const float LN_2 = 0.6931471;                           // log_e(2)
     58const float LN_10 = 2.302585;                           // log_e(10)
     59const float SQRT_2 = 1.414213;                          // sqrt(2)
     60const float _1_SQRT_2 = 0.7071067;                      // 1 / sqrt(2)
    7661
    77 extern const double E;                                                                  // e
    78 extern const double LOG2_E;                                                             // log_2(e)
    79 extern const double LOG10_E;                                                    // log_10(e)
    80 extern const double LN_2;                                                               // log_e(2)
    81 extern const double LN_10;                                                              // log_e(10)
    82 extern const double SQRT_2;                                                             // sqrt(2)
    83 extern const double _1_SQRT_2;                                                  // 1 / sqrt(2)
     62const double E = 2.7182818284590452354_D;               // e
     63const double LOG2_E = 1.4426950408889634074_D;          // log_2(e)
     64const double LOG10_E = 0.43429448190325182765_D;        // log_10(e)
     65const double LN_2 = 0.69314718055994530942_D;           // log_e(2)
     66const double LN_10 = 2.30258509299404568402_D;          // log_e(10)
     67const double SQRT_2 = 1.41421356237309504880_D;         // sqrt(2)
     68const double _1_SQRT_2 = 0.70710678118654752440_D;      // 1 / sqrt(2)
    8469
    85 extern const long double E;                                                             // e
    86 extern const long double LOG2_E;                                                // log_2(e)
    87 extern const long double LOG10_E;                                               // log_10(e)
    88 extern const long double LN_2;                                                  // log_e(2)
    89 extern const long double LN_10;                                                 // log_e(10)
    90 extern const long double SQRT_2;                                                // sqrt(2)
    91 extern const long double _1_SQRT_2;                                             // 1/sqrt(2)
     70const long double E = 2.7182818284590452353602874713526625_DL; // e
     71const long double LOG2_E = 1.4426950408889634073599246810018921_DL; // log_2(e)
     72const long double LOG10_E = 0.4342944819032518276511289189166051_DL; // log_10(e)
     73const long double LN_2 = 0.6931471805599453094172321214581766_DL; // log_e(2)
     74const long double LN_10 = 2.3025850929940456840179914546843642_DL; // log_e(10)
     75const long double SQRT_2 = 1.4142135623730950488016887242096981_DL; // sqrt(2)
     76const long double _1_SQRT_2 = 0.7071067811865475244008443621048490_DL; // 1/sqrt(2)
    9277
    93 extern const _Complex E;                                                                // e
    94 extern const _Complex LOG2_E;                                                   // log_2(e)
    95 extern const _Complex LOG10_E;                                                  // log_10(e)
    96 extern const _Complex LN_2;                                                             // log_e(2)
    97 extern const _Complex LN_10;                                                    // log_e(10)
    98 extern const _Complex SQRT_2;                                                   // sqrt(2)
    99 extern const _Complex _1_SQRT_2;                                                // 1 / sqrt(2)
     78const _Complex E = 2.7182818284590452354_D+0.0_iD;      // e
     79const _Complex LOG2_E = 1.4426950408889634074_D+0.0_iD; // log_2(e)
     80const _Complex LOG10_E = 0.43429448190325182765_D+0.0_iD; // log_10(e)
     81const _Complex LN_2 = 0.69314718055994530942_D+0.0_iD;  // log_e(2)
     82const _Complex LN_10 = 2.30258509299404568402_D+0.0_iD; // log_e(10)
     83const _Complex SQRT_2 = 1.41421356237309504880_D+0.0_iD;        // sqrt(2)
     84const _Complex _1_SQRT_2 = 0.70710678118654752440_D+0.0_iD; // 1 / sqrt(2)
    10085
    101 extern const long _Complex E;                                                   // e
    102 extern const long _Complex LOG2_E;                                              // log_2(e)
    103 extern const long _Complex LOG10_E;                                             // log_10(e)
    104 extern const long _Complex LN_2;                                                // log_e(2)
    105 extern const long _Complex LN_10;                                               // log_e(10)
    106 extern const long _Complex SQRT_2;                                              // sqrt(2)
    107 extern const long _Complex _1_SQRT_2;                                   // 1 / sqrt(2)
    108 
    109 // Local Variables: //
    110 // mode: c //
    111 // tab-width: 4 //
    112 // End: //
     86const long _Complex E = 2.7182818284590452353602874713526625_L+0.0_iL; // e
     87const long _Complex LOG2_E = 1.4426950408889634073599246810018921_L+0.0_iL; // log_2(e)
     88const long _Complex LOG10_E = 0.4342944819032518276511289189166051_L+0.0_iL; // log_10(e)
     89const long _Complex LN_2 = 0.6931471805599453094172321214581766_L+0.0_iL; // log_e(2)
     90const long _Complex LN_10 = 2.3025850929940456840179914546843642_L+0.0_iL; // log_e(10)
     91const long _Complex SQRT_2 = 1.4142135623730950488016887242096981_L+0.0_iL; // sqrt(2)
     92const long _Complex _1_SQRT_2 = 0.7071067811865475244008443621048490_L+0.0_iL; // 1 / sqrt(2)
  • src/libcfa/stdlib

    r37218fc r3aba311  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Apr  1 22:26:14 2016
    13 // Update Count     : 73
     12// Last Modified On : Tue Mar 22 22:34:24 2016
     13// Update Count     : 69
    1414//
    1515
     
    1818extern "C" {
    1919#include <stddef.h>                                                                             // size_t
    20 #include <math.h>                                                                               // floor
    2120} // extern "C"
    2221
     
    8180char abs( char );
    8281extern "C" {
    83 int abs( int );                         // use default C routine for int
    84 } // extern "C"
     82int abs( int );         // use default C routine for int
     83} // extern
    8584long int abs( long int );
    8685long long int abs( long long int );
     
    9190double _Complex abs( double _Complex );
    9291long double _Complex abs( long double _Complex );
    93 
    94 //---------------------------------------
    95 
    96 float floor( float );
    97 extern "C" {
    98 double floor( double );         // use C routine for double
    99 } // extern "C"
    100 long double floor( long double );
    101 
    102 float ceil( float );
    103 extern "C" {
    104 double ceil( double );          // use C routine for double
    105 } // extern "C"
    106 long double ceil( long double );
    10792
    10893//---------------------------------------
  • src/libcfa/stdlib.c

    r37218fc r3aba311  
    1010// Created On       : Thu Jan 28 17:10:29 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar 30 10:48:41 2016
    13 // Update Count     : 149
     12// Last Modified On : Wed Mar 23 13:26:42 2016
     13// Update Count     : 146
    1414//
    1515
     
    243243//---------------------------------------
    244244
    245 float floor( float v ) { return floorf( v ); }
    246 long double floor( long double v ) { return floorl( v ); }
    247 
    248 float ceil( float v ) { return ceilf( v ); }
    249 long double ceil( long double v ) { return ceill( v ); }
    250 
    251 //---------------------------------------
    252 
    253245void rand48seed( long int s ) { srand48( s ); }
    254246char rand48() { return mrand48(); }
Note: See TracChangeset for help on using the changeset viewer.