Changeset 37218fc


Ignore:
Timestamp:
Apr 11, 2016, 11:51:07 AM (6 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, ctor, deferred_resn, demangler, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, string, with_gc
Children:
37f0da8
Parents:
3aba311 (diff), e55ca05 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:/u/cforall/software/cfa/cfa-cc

Conflicts:

src/Parser/ParseNode.h

Files:
9 added
3 deleted
38 edited
2 moved

Legend:

Unmodified
Added
Removed
  • doc/refrat/Makefile

    r3aba311 r37218fc  
    11## Define the appropriate configuration variables.
    22
    3 Macros =
    4 TeXLIB = .:${Macros}:
     3TeXLIB = .:../bibliography/:../LaTeXmacros/:
    54LaTeX  = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex
    6 BibTeX = BSTINPUTS=${TeXLIB} && export BSTINPUTS && bibtex
     5BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex
    76
    87## Define the text source files.
     
    4443        dvips $< -o $@
    4544
    46 ${basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex ${basename ${DOCUMENT}}.bib
     45${basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex \
     46                ../LaTeXmacros/common.tex ../LaTeXmacros/indexstyle ../bibliography/cfa.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 indexstyle ${basename $@}.idx
     56        makeindex -s ../LaTeXmacros/indexstyle ${basename $@}.idx
    5757        ${LaTeX} ${basename $@}.tex
    5858        # Run again to get index title into table of contents
  • doc/refrat/refrat.tex

    r3aba311 r37218fc  
     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
    117% requires tex packages: texlive-base texlive-latex-base tex-common texlive-humanities texlive-latex-extra texlive-fonts-recommended
    218
     
    521
    622% Latex packages used in the document.
    7 
    823\usepackage{fullpage,times}
    924\usepackage{xspace}
     
    2136%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    2237
    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 
    3238% Bespoke macros used in the document.
    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{
    159 language=CFA,
    160 columns=flexible,
    161 basicstyle=\sf\relsize{-1},
    162 tabsize=4,
    163 xleftmargin=\parindent,
    164 escapechar=@,
    165 keepspaces=true,
    166 showstringspaces=false,
    167 showlines=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
     39\input{common}
    18240
    18341\setcounter{secnumdepth}{3}     % number subsubsections
     
    22684
    22785This document is a reference manual and rationale for \CFA, a polymorphic extension of the C programming language.
    228 It makes frequent reference to the {\c11} standard \cite{ANS:C11}, and occasionally compares \CFA to {\CC} \cite{c++}.
     86It makes frequent reference to the {\c11} standard \cite{C11}, and occasionally compares \CFA to {\CC} \cite{C++}.
    22987
    23088The manual deliberately imitates the ordering of the {\c11} standard (although the section numbering differs).
     
    720578
    721579There are two notable differences between \CFA's overload resolution rules and the rules for
    722 {\CC} defined in \cite{c++}.
     580{\CC} defined in \cite{C++}.
    723581First, the result type of a function plays a role.
    724582In {\CC}, a function call must be completely resolved based on the arguments to the call in most circumstances.
     
    33843242\begin{itemize}
    33853243\item
    3386 Inside a Clu cluster \cite{clu}, the declaration of an instance states which view applies.
     3244Inside a Clu cluster \cite{CLU}, the declaration of an instance states which view applies.
    33873245Two primitives called \lstinline$up$ and \lstinline$down$ can be used to convert between the views.
    33883246\item
    3389 The Simula class \cite{Simula87} is essentially a record type.
     3247The Simula class \cite{SIMULA87} is essentially a record type.
    33903248Since 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.
    33913249In {\CC}
    3392 \cite{c++}, operations on class instances include assignment and ``\lstinline$&$'', which can be overloaded.
     3250\cite{C++}, operations on class instances include assignment and ``\lstinline$&$'', which can be overloaded.
    33933251A ``scope resolution'' operator can be used inside the class to specify whether the abstract or implementation version of the operation should be used.
    33943252\item
    3395 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.
     3253An 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.
    33963254The derived subprograms are clones of the existing subprograms with the old type replaced by the derived type.
    33973255Literals and aggregates of the old type are also cloned.
     
    38433701``\lstinline$Safe_pointer$ acts like a pointer to \lstinline$int$''.
    38443702\begin{lstlisting}
    3845 trait ptr_to( type P | pointer( P ), otype T ) {@\impl{ptr_to}@@\use{pointer}@
     3703trait ptr_to( otype P | pointer( P ), otype T ) {@\impl{ptr_to}@@\use{pointer}@
    38463704        lvalue T *?( P );
    38473705        lvalue T ?[?]( P, long int );
    38483706};
    3849 trait ptr_to_const( type P | pointer( P ), otype T ) {@\impl{ptr_to_const}@
     3707trait ptr_to_const( otype P | pointer( P ), otype T ) {@\impl{ptr_to_const}@
    38503708        const lvalue T *?( P );
    38513709        const lvalue T ?[?]( P, long int );@\use{pointer}@
    38523710};
    3853 trait ptr_to_volatile( type P | pointer( P ), otype T ) }@\impl{ptr_to_volatile}@
     3711trait ptr_to_volatile( otype P | pointer( P ), otype T ) }@\impl{ptr_to_volatile}@
    38543712        volatile lvalue T *?( P );
    38553713        volatile lvalue T ?[?]( P, long int );@\use{pointer}@
    38563714};
    3857 trait ptr_to_const_volatile( type P | pointer( P ), otype T ) }@\impl{ptr_to_const_volatile}@
     3715trait ptr_to_const_volatile( otype P | pointer( P ), otype T ) }@\impl{ptr_to_const_volatile}@
    38583716        const volatile lvalue T *?( P );@\use{pointer}@
    38593717        const volatile lvalue T ?[?]( P, long int );
     
    38653723``\lstinline$ptr_to$'' specifications.
    38663724\begin{lstlisting}
    3867 trait m_l_ptr_to( type P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to}@ otype T | ptr_to( P, T )@\use{ptr_to}@ {
     3725trait 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}@ {
    38683726        P ?=?( P *, T * );
    38693727        T * ?=?( T **, P );
    38703728};
    3871 trait m_l_ptr_to_const( type P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to_const}@ otype T | ptr_to_const( P, T )@\use{ptr_to_const}@) {
     3729trait 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}@) {
    38723730        P ?=?( P *, const T * );
    38733731        const T * ?=?( const T **, P );
    38743732};
    3875 trait m_l_ptr_to_volatile( type P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to_volatile}@ otype T | ptr_to_volatile( P, T )) {@\use{ptr_to_volatile}@
     3733trait 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}@
    38763734        P ?=?( P *, volatile T * );
    38773735        volatile T * ?=?( volatile T **, P );
    38783736};
    3879 trait m_l_ptr_to_const_volatile( type P | ptr_to_const_volatile( P ),@\use{ptr_to_const_volatile}@@\impl{m_l_ptr_to_const_volatile}@
    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}@
     3737trait 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}@
    38813739        P ?=?( P *, const volatile T * );
    38823740        const volatile T * ?=?( const volatile T **, P );
     
    40063864
    40073865\bibliographystyle{plain}
    4008 \bibliography{refrat}
     3866\bibliography{cfa}
    40093867
    40103868
  • doc/user/Makefile

    r3aba311 r37218fc  
    11## Define the appropriate configuration variables.
    22
    3 TeXLIB = .::
     3TeXLIB = .:../bibliography/:../LaTeXmacros/:
    44LaTeX  = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex
    5 BibTeX = BSTINPUTS=${TeXLIB} && export BSTINPUTS && bibtex
     5BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && 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 ${basename ${DOCUMENT}}.bib /usr/local/bibliographies/pl.bib
     45${basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex \
     46                ../LaTeXmacros/common.tex ../LaTeXmacros/indexstyle ../bibliography/cfa.bib
    4647        # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run.
    4748        if [ ! -r ${basename $@}.ind ] ; then touch ${basename $@}.ind ; fi
     
    5354        -${BibTeX} ${basename $@}
    5455        # Make index from *.aux entries and input index at end of document
    55         makeindex -s indexstyle ${basename $@}.idx
     56        makeindex -s ../LaTeXmacros/indexstyle ${basename $@}.idx
    5657        ${LaTeX} ${basename $@}.tex
    5758        # Run again to get index title into table of contents
  • doc/user/user.tex

    r3aba311 r37218fc  
     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
    117% requires tex packages: texlive-base texlive-latex-base tex-common texlive-humanities texlive-latex-extra texlive-fonts-recommended
    218
     
    521
    622% Latex packages used in the document.
    7 
     23\usepackage[T1]{fontenc}
     24\usepackage{textcomp}
     25\usepackage[latin1]{inputenc}
     26\usepackage{upquote}
    827\usepackage{fullpage,times}
    928\usepackage{xspace}
     
    2443% Names used in the document.
    2544
    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)
    3045\newcommand{\CS}{C\raisebox{-0.9ex}{\large$^\sharp$}\xspace}
    3146
     
    3348
    3449% Bespoke macros used in the document.
    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{
    168 language=CFA,
    169 columns=flexible,
    170 basicstyle=\sf\relsize{-1},
    171 tabsize=4,
    172 xleftmargin=\parindent,
    173 escapechar=@,
    174 mathescape=true,
    175 keepspaces=true,
    176 showstringspaces=false,
    177 showlines=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
     50\input{common}
    19251
    19352\setcounter{secnumdepth}{3}     % number subsubsections
     
    366225
    367226The command \lstinline@cfa@ is used to compile \CFA program(s).
    368 This command works like the GNU \lstinline@gcc@ command, e.g.:
     227This command works like the GNU \lstinline@gcc@\index{gcc} command, e.g.:
    369228\begin{lstlisting}
    370229cfa [ gcc-options ] C/@{\CFA}@-files [ assembler/loader-files ]
    371230\end{lstlisting}
    372 The following additional option is available:
     231By default, \CFA programs having the following \lstinline@gcc@ flags turned on:
     232\begin{description}
     233\item
     234\hspace*{-4pt}\lstinline@-std=gnu99@
     235The 1999 C standard plus GNU extensions.
     236\end{description}
     237The following new \CFA option is available:
    373238\begin{description}
    374239\item
     
    382247Numeric constants are extended to allow \Index{underscore}s within constants\index{constant!underscore}, e.g.:
    383248\begin{lstlisting}
    384 2_147_483_648;                          // decimal constant
     2492`_`147`_`483`_`648;                            // decimal constant
    38525056_ul;                                          // decimal unsigned long constant
    3862510_377;                                          // octal constant
     
    451316\multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}}       & \multicolumn{1}{c}{\textbf{C}}        \\
    452317\begin{lstlisting}
    453 * int x, y;
     318`* int x, y;`
    454319\end{lstlisting}
    455320&
     
    571436The point of the new syntax is to allow returning multiple values from a routine~\cite{CLU,Galletly96}, e.g.:
    572437\begin{lstlisting}
    573 [ int o1, int o2, char o3 ] f( int i1, char i2, char i3 ) {
     438`[ int o1, int o2, char o3 ]` f( int i1, char i2, char i3 ) {
    574439        @\emph{routine body}@
    575440}
     
    639504Because 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:
    640505\begin{lstlisting}
    641 [ int x ] f() {
     506`[ int x ]` f() {
    642507        ... x = 0; ... x = y; ...
    643         return; // implicitly return x
     508        `return;` // implicitly return x
    644509}
    645510\end{lstlisting}
     
    697562for example, the following is incorrect:
    698563\begin{lstlisting}
    699 * [ int x ] f () fp;            // routine name ``f'' is not allowed
     564* [ int x ] f () fp;            // routine name "f" is not allowed
    700565\end{lstlisting}
    701566
     
    864729\subsection{Type Nesting}
    865730
    866 C allows \Index{type nesting}, but the nested types are hoisted\index{type!hoisting} (refactored) into the enclosing scope.
     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.
    867732\begin{quote2}
    868733\begin{tabular}{@{}l@{\hspace{30pt}}l|l@{}}
     
    919784
    920785int fred() {
    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;
     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;
    925790}
    926791\end{lstlisting}
    927792\end{tabular}
    928793\end{quote2}
    929 
    930 \CFA is C \emph{incompatible} on this issue, and provides semantics similar to \CC.
    931 Nested types are not hoisted and can be referenced using the field selection operator ``\lstinline@.@'', unlike the \CC scope-resolution operator ``\lstinline@::@''.
    932 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.
     794In 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.
     795In 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@::@''.
    933796
    934797
     
    944807\begin{lstlisting}
    945808const unsigned int size = 10;
    946 int a[size];
    947 
    948 qsort( 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}
     809int ia[size];
     810...                                             // assign values to array ia
     811qsort( 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
     818Nested routines are not first-class, meaning a nested routine cannot be returned if it has references to variables in its enclosing blocks;
     819the only exception is references to the external block of the translation unit, as these variables persist for the duration of the program.
     820The 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}
     830int main() {
     831        * [int](int) fp = foo();        // int (*fp)(int)
     832    sout | fp( 3 ) | endl;
     833}
     834\end{lstlisting}
     835because
     836
     837Currently, there are no \Index{lambda} expressions, i.e., unnamed routines because routine names are very important to properly select the correct routine.
    954838
    955839
     
    1013897
    1014898\item
    1015 Change: A struct is a scope in C++, not in C
    1016 Rationale: Class scope is crucial to C++, and a struct is a class.
    1017 Effect on original feature: Change to semantics of well-defined feature.
    1018 Difficulty of converting: Semantic transformation.
    1019 How widely used: C programs use struct extremely frequently, but the change is only noticeable when
    1020 struct, enumeration, or enumerator names are referred to outside the struct. The latter is probably
    1021 rare.
     899Change: A struct is a scope in C++, not in C \\
     900Rationale: Class scope is crucial to C++, and a struct is a class. \\
     901Effect on original feature: Change to semantics of well-defined feature. \\
     902Difficulty of converting: Semantic transformation. \\
     903How 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.
     904The latter is probably rare.
     905
     906\CFA is C \emph{incompatible} on this issue, and provides semantics similar to \CC.
     907Nested types are not hoisted and can be referenced using the field selection operator ``\lstinline@.@'', unlike the \CC scope-resolution operator ``\lstinline@::@''.
     908Given 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
    1022910
    1023911\item
     
    11851073First the right-hand tuple is flattened and then the values are assigned individually.
    11861074Flattening is also performed on tuple types.
    1187 For example, the type \lstinline@[ int, [ int, int ], int ]@ can be coerced, using flattening, into the type lstinline@[ int, int, int, int ]@.
     1075For example, the type \lstinline@[ int, [ int, int ], int ]@ can be coerced, using flattening, into the type \lstinline@[ int, int, int, int ]@.
    11881076
    11891077A \newterm{structuring coercion} is the opposite of flattening;
     
    13521240\multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}}       & \multicolumn{1}{c}{\textbf{C}}        \\
    13531241\begin{lstlisting}
    1354 L1: for ( ... ) {
    1355         L2: for ( ... ) {
    1356                 L3: for ( ... ) {
    1357                         ... break L1; ...
    1358                         ... break L2; ...
    1359                         ... break L3; // or break
     1242`L1:` for ( ... ) {
     1243        `L2:` for ( ... ) {
     1244                `L3:` for ( ... ) {
     1245                        ... break `L1`; ...
     1246                        ... break `L2`; ...
     1247                        ... break `L3`; // or break
    13601248                }
    13611249        }
     
    13821270\multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}}       & \multicolumn{1}{c}{\textbf{C}}        \\
    13831271\begin{lstlisting}
    1384 L1: for ( ... ) {
    1385         L2: for ( ... ) {
    1386                 L3: for ( ... ) {
    1387                         ... continue L1; ...
    1388                         ... continue L2; ...
    1389                         ... continue L3; ...
     1272`L1`: for ( ... ) {
     1273        `L2`: for ( ... ) {
     1274                `L3`: for ( ... ) {
     1275                        ... continue `L1`; ...
     1276                        ... continue `L2`; ...
     1277                        ... continue `L3`; ...
    13901278
    13911279                }
     
    16231511\begin{lstlisting}
    16241512switch ( i ) {
    1625   case 1, 3, 5:
     1513  `case 1, 3, 5`:
    16261514        ...
    1627   case 2, 4, 6:
     1515  `case 2, 4, 6`:
    16281516        ...
    16291517}
     
    16341522  case 1: case 3 : case 5:
    16351523        ...
    1636   case 2: case 4 : case 6: /* even values */
     1524  case 2: case 4 : case 6:
    16371525        ...
    16381526}
     
    16551543\begin{lstlisting}
    16561544switch ( i ) {
    1657   case 1~5
     1545  `case 1~5:`
    16581546        ...
    1659   case 10~15
     1547  `case 10~15:`
    16601548        ...
    16611549}
     
    16721560&
    16731561\begin{lstlisting}
     1562
    16741563// 1, 2, 3, 4, 5
    16751564
     
    21682057
    21692058
    2170 \section{Generics }
     2059\section{Auto Type-Inferencing}
     2060
     2061Auto 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
     2067auto j = 3.0 * 4;
     2068int i;
     2069auto k = i;
     2070\end{lstlisting}
     2071&
     2072\begin{lstlisting}
     2073#define expr 3.0 * i
     2074typeof(expr) j = expr;
     2075int i;
     2076typeof(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}
     2087The two important capabilities are:
     2088\begin{itemize}
     2089\item
     2090preventing having to determine or write out long generic types,
     2091\item
     2092ensure secondary variables, related to a primary variable, always have the same type.
     2093\end{itemize}
     2094
     2095In \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.
     2098Only for overloaded routines with the same return type is variable type-inferencing possible.
     2099Finally, \lstinline@auto@ presents the programming problem of tracking down a type when the type is actually needed.
     2100For example, given
     2101\begin{lstlisting}
     2102auto j = `...`
     2103\end{lstlisting}
     2104and the need to write a routine to compute using \lstinline@j@
     2105\begin{lstlisting}
     2106void rtn( `...` parm );
     2107rtn( j );
     2108\end{lstlisting}
     2109A programmer must work backwards to determine the type of \lstinline@j@'s initialization expression, reconstructing the possibly long generic type-name.
     2110In this situation, having the type name or a short alias is very useful.
     2111
     2112There is also the conundrum in type inferencing of when to \emph{\Index{brand}} a type.
     2113That is, when is the type of the variable more important than the type of its initialization expression.
     2114For example, if a change is made in an initialization expression, it can cause hundreds or thousands of cascading type changes and/or errors.
     2115At some point, a programmer wants the type of the variable to remain constant and the expression to be in error when it changes.
     2116
     2117Given \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.
     2118Should a significant need arise, this feature can be revisited.
     2119
     2120
     2121\section{Generics}
    21712122
    21722123\CFA supports parametric polymorphism to allow users to define generic functions and types.
     
    24572408
    24582409
    2459 \section{I/O Library}
    2460 \label{s:IOLibrary}
    2461 
    2462 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.
    2463 The general case is printing out a sequence of variables separated by whitespace.
    2464 \begin{lstlisting}
    2465 int x = 0, y = 1, z = 2;
    2466 sout | x | y | z | endl;
    2467 
    2468 cout << x << " " << y << " " << z << endl;
    2469 \end{lstlisting}
    2470 The \CC form takes almost twice as many characters.
    2471 
    2472 The logical-or operator is used because it is the lowest priority overloadable operator, other than assignment.
    2473 Therefore, most output expressions do not require parenthesis.
    2474 \begin{lstlisting}
    2475 int x = 0, y = 1, z = 2;
    2476 sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl;
    2477 
    2478 cout << x * 3 << y + 1 << (z << 2) << (x == y) << (x | y) << (x || y) << (x > z ? 1 : 2) << endl;
    2479 \end{lstlisting}
    2480 
    2481 Finally, 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 
    2487 int 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
    2526 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
    2527 $ a.out
    2528 A
    2529 1 2 3 4 5 6 7 8
    2530 1.1 1.2 1.3
    2531 1.11.21.3
    2532 1.1+2.3i, $1.1-2.3i, $1.1-2.3i
    2533 , $abcxyz
    2534 abcxyz
    2535 \end{lstlisting}
    2536 \end{figure}
    2537 
    2538 
    2539 \section{Standard Library}
    2540 \label{s:StandardLibrary}
    2541 
    2542 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.
    2543 
    2544 
    2545 \subsection{malloc}
    2546 
    2547 \begin{lstlisting}
    2548 forall( otype T ) T * malloc( void );
    2549 forall( otype T ) T * malloc( char fill );
    2550 forall( otype T ) T * malloc( T * ptr, size_t size );
    2551 forall( otype T ) T * malloc( T * ptr, size_t size, unsigned char fill );
    2552 forall( otype T ) T * calloc( size_t size );
    2553 forall( otype T ) T * realloc( T * ptr, size_t size );
    2554 forall( otype T ) T * realloc( T * ptr, size_t size, unsigned char fill );
    2555 
    2556 forall( otype T ) T * aligned_alloc( size_t alignment );
    2557 forall( otype T ) T * memalign( size_t alignment );             // deprecated
    2558 forall( otype T ) int posix_memalign( T ** ptr, size_t alignment );
    2559 
    2560 forall( otype T ) T * memset( T * ptr, unsigned char fill ); // use default value '\0' for fill
    2561 forall( otype T ) T * memset( T * ptr );                                // remove when default value available
    2562 \end{lstlisting}
    2563 
    2564 
    2565 \subsection{ato/strto}
    2566 
    2567 \begin{lstlisting}
    2568 int ato( const char * ptr );
    2569 unsigned int ato( const char * ptr );
    2570 long int ato( const char * ptr );
    2571 unsigned long int ato( const char * ptr );
    2572 long long int ato( const char * ptr );
    2573 unsigned long long int ato( const char * ptr );
    2574 float ato( const char * ptr );
    2575 double ato( const char * ptr );
    2576 long double ato( const char * ptr );
    2577 float _Complex ato( const char * ptr );
    2578 double _Complex ato( const char * ptr );
    2579 long double _Complex ato( const char * ptr );
    2580 
    2581 int strto( const char * sptr, char ** eptr, int base );
    2582 unsigned int strto( const char * sptr, char ** eptr, int base );
    2583 long int strto( const char * sptr, char ** eptr, int base );
    2584 unsigned long int strto( const char * sptr, char ** eptr, int base );
    2585 long long int strto( const char * sptr, char ** eptr, int base );
    2586 unsigned long long int strto( const char * sptr, char ** eptr, int base );
    2587 float strto( const char * sptr, char ** eptr );
    2588 double strto( const char * sptr, char ** eptr );
    2589 long double strto( const char * sptr, char ** eptr );
    2590 float _Complex strto( const char * sptr, char ** eptr );
    2591 double _Complex strto( const char * sptr, char ** eptr );
    2592 long double _Complex strto( const char * sptr, char ** eptr );
    2593 \end{lstlisting}
    2594 
    2595 
    2596 \subsection{bsearch/qsort}
    2597 
    2598 \begin{lstlisting}
    2599 forall( otype T | { int ?<?( T, T ); } )
    2600 T * bsearch( const T key, const T * arr, size_t dimension );
    2601 
    2602 forall( otype T | { int ?<?( T, T ); } )
    2603 void qsort( const T * arr, size_t dimension );
    2604 \end{lstlisting}
    2605 
    2606 
    2607 \subsection{abs}
    2608 
    2609 \begin{lstlisting}
    2610 char abs( char );
    2611 extern "C" {
    2612 int abs( int );         // use default C routine for int
    2613 } // extern
    2614 long int abs( long int );
    2615 long long int abs( long long int );
    2616 float abs( float );
    2617 double abs( double );
    2618 long double abs( long double );
    2619 float _Complex abs( float _Complex );
    2620 double _Complex abs( double _Complex );
    2621 long double _Complex abs( long double _Complex );
    2622 \end{lstlisting}
    2623 
    2624 
    2625 \subsection{random}
    2626 
    2627 \begin{lstlisting}
    2628 void randseed( long int s );
    2629 char random();
    2630 int random();
    2631 unsigned int random();
    2632 long int random();
    2633 unsigned long int random();
    2634 float random();
    2635 double random();
    2636 float _Complex random();
    2637 double _Complex random();
    2638 long double _Complex random();
    2639 \end{lstlisting}
    2640 
    2641 
    2642 \subsection{min/max/swap}
    2643 
    2644 \begin{lstlisting}
    2645 forall( otype T | { int ?<?( T, T ); } )
    2646 T min( const T t1, const T t2 );
    2647 
    2648 forall( otype T | { int ?>?( T, T ); } )
    2649 T max( const T t1, const T t2 );
    2650 
    2651 forall( otype T )
    2652 void swap( T * t1, T * t2 );
    2653 \end{lstlisting}
     2410\section{Syntactic Anomalies}
     2411
     2412The number 0 and 1 are treated specially in \CFA, and can be redefined as variables.
     2413One syntactic anomaly is when a field in an structure is names 0 or 1:
     2414\begin{lstlisting}
     2415struct S {
     2416        int 0, 1;
     2417} s;
     2418\end{lstlisting}
     2419The problem occurs in accesing these fields using the selection operation ``\lstinline@.@'':
     2420\begin{lstlisting}
     2421s.0 = 0;        // ambiguity with floating constant .0
     2422s.1 = 1;        // ambiguity with floating constant .1
     2423\end{lstlisting}
     2424To 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}
     2429While this sytact is awkward, it is unlikely many programers will name fields of a structure 0 or 1.
     2430Like 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
     2432There are several ambiguous cases with operator identifiers, e.g., \lstinline@int *?*?()@, where the string \lstinline@*?*?@ can be lexed as \lstinline@*@/\lstinline@?*?@ or \lstinline@*?@/\lstinline@*?@.
     2433Since 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.
     2434Even with this special hack, there are 5 general cases that cannot be handled.
     2435The first case is for the function-call identifier \lstinline@?()@:
     2436\begin{lstlisting}
     2437int *@\textvisiblespace@?()();  // declaration: space required after '*'
     2438*@\textvisiblespace@?()();              // expression: space required after '*'
     2439\end{lstlisting}
     2440Without the space, the string \lstinline@*?()@ is ambiguous without N character look ahead;
     2441it requires scanning ahead to determine if there is a \lstinline@'('@, which is the start of an argument/parameter list.
     2442
     2443The 4 remaining cases occur in expressions:
     2444\begin{lstlisting}
     2445i++@\textvisiblespace@?i:0;             // space required before '?'
     2446i--@\textvisiblespace@?i:0;             // space required before '?'
     2447i@\textvisiblespace@?++i:0;             // space required after '?'
     2448i@\textvisiblespace@?--i:0;             // space required after '?'
     2449\end{lstlisting}
     2450In the first two cases, the string \lstinline@i++?@ is ambiguous, where this string can be lexed as \lstinline@i@ / \lstinline@++?@ or \lstinline@i++@ / \lstinline@?@;
     2451it requires scanning ahead to determine if there is a \lstinline@'('@, which is the start of an argument list.
     2452In 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@;
     2453it requires scanning ahead to determine if there is a \lstinline@'('@, which is the start of an argument list.
    26542454
    26552455
     
    26762476
    26772477task creates a type with implicit locking, separate stack, and a thread
     2478
    26782479
    26792480\subsection{Monitors}
     
    37753576\multicolumn{1}{c|}{\textbf{\CFA/\CC}} & \multicolumn{1}{c|}{\textbf{Go}} & \multicolumn{1}{c}{\textbf{Rust}}   \\
    37763577\hline
    3777 \begin{lstlisting}
     3578\begin{lstlisting}[boxpos=t]
    37783579extern "C" {
    37793580#include <sys/types.h>
     
    37823583}
    37833584size_t fileSize( const char *path ) {
    3784         stat s;
     3585        struct stat s;
    37853586        stat(path, &s);
    37863587        return s.st_size;
     
    37883589\end{lstlisting}
    37893590&
    3790 \begin{lstlisting}
     3591\begin{lstlisting}[boxpos=t]
    37913592/*
    37923593#cgo
     
    38073608\end{lstlisting}
    38083609&
    3809 \begin{lstlisting}
     3610\begin{lstlisting}[boxpos=t]
    38103611use libc::{c_int, size_t};
    3811 
    3812 // The following declarations are
    38133612// translated from sys/stat.h
    38143613#[repr(C)]
     
    38183617        ...
    38193618}
    3820 
    38213619#[link(name = "libc")]
    38223620extern {
     
    38243622        buf: *mut stat_t) -> c_int;
    38253623}
    3826 
    38273624fn fileSize(path: *const u8) -> size_t
    38283625{
    38293626        unsafe {
    3830         let mut buf: stat_t = uninit();
    3831         stat(path, &mut buf);
    3832         buf.st_size
     3627                let mut buf: stat_t = uninit();
     3628                stat(path, &mut buf);
     3629                buf.st_size
    38333630        }
    38343631}
     
    39533750
    39543751
     3752\begin{comment}
    39553753\subsubsection{Modules/Packages}
    39563754
     
    40323830}
    40333831\end{lstlisting}
     3832\end{comment}
     3833
    40343834
    40353835\subsubsection{Parallel Tasks}
     
    41873987\end{flushleft}
    41883988
     3989\lstset{basicstyle=\sf\relsize{-1}}
     3990
     3991
    41893992\subsection{Summary of Language Comparison}
    41903993
     
    42554058
    42564059
     4060\appendix
     4061
     4062
     4063\section{I/O Library}
     4064\label{s:IOLibrary}
     4065\index{input/output library}
     4066
     4067The 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.
     4068The 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}
     4073int x = 0, y = 1, z = 2;
     4074`sout` `|` x `|` y `|` z `| endl`;
     4075\end{lstlisting}
     4076&
     4077\begin{lstlisting}
     4078
     4079cout << x << " " << y << " " << z << endl;
     4080\end{lstlisting}
     4081\end{tabular}
     4082\end{quote2}
     4083The \CFA form is half as many characters, and is similar to Python I/O with respect to implicit separators.
     4084
     4085The logical-or operator is used because it is the lowest-priority overloadable operator, other than assignment.
     4086Therefore, fewer output expressions require parenthesis.
     4087\begin{quote2}
     4088\begin{tabular}{@{}ll@{}}
     4089\textbf{\CFA:}
     4090&
     4091\begin{lstlisting}
     4092sout | 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}
     4098cout << 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}
     4102Finally, the logical-or operator has a link with the Shell pipe-operator for moving data, although data flows in the opposite direction.
     4103
     4104The implicit seperator\index{I/O separator} character (space/blank) is a separator not a terminator.
     4105The rules for implicitly adding the separator are:
     4106\begin{enumerate}
     4107\item
     4108A seperator does not appear at the start or end of a line.
     4109\begin{lstlisting}[belowskip=0pt]
     4110sout 1 | 2 | 3 | endl;
     4111\end{lstlisting}
     4112\begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     41131 2 3
     4114\end{lstlisting}
     4115\item
     4116A seperator does not appear before or after a character literal or variable.
     4117\begin{lstlisting}
     4118sout | '1' | '2' | '3' | endl;
     4119123
     4120\end{lstlisting}
     4121\item
     4122A seperator does not appear before or after a null (empty) C string
     4123\begin{lstlisting}
     4124sout | 1 | "" | 2 | "" | 3 | endl;
     4125123
     4126\end{lstlisting}
     4127which is a local mechanism to disable insertion of the separator character.
     4128\item
     4129A 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]
     4132sout | "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]
     4136x (1 x [2 x {3 x $4 x £5 x ¥6 x ¿7 x «8
     4137\end{lstlisting}
     4138%$
     4139\item
     4140A seperator does not appear after a C string ending with the extended ASCII characters: \lstinline@,.:;!?)]}%¢»@
     4141\begin{lstlisting}[belowskip=0pt]
     4142sout | 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]
     41461, 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
     4149A 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]
     4151sout | "x '" | 1 | "' x \`" | 2 | "\` x \"" | 3 | "\" x" | endl;
     4152\end{lstlisting}
     4153\begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     4154x '1' x \`2\` x "3" x
     4155\end{lstlisting}
     4156\begin{lstlisting}[showtabs=true,aboveskip=0pt]
     4157sout | "x\t" | 1 | "\tx" | endl;
     4158x       1       x
     4159\end{lstlisting}
     4160\end{enumerate}
     4161The following \CC-style \Index{manipulator}s allow further control over implicit seperation.
     4162\begin{lstlisting}[mathescape=off,belowskip=0pt]
     4163sout | 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]
     4169sout | 1 | sepOff | 2 | 3 | endl;                       // turn off implicit separator temporarily
     4170\end{lstlisting}
     4171\begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     417212 3
     4173\end{lstlisting}
     4174\begin{lstlisting}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     4175sout | 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]
     4178123
     4179\end{lstlisting}
     4180\begin{lstlisting}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     4181sout | 1 | sepOn | 2 | 3 | endl;                        // turn on implicit separator temporarily
     4182\end{lstlisting}
     4183\begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     41841 23
     4185\end{lstlisting}
     4186\begin{lstlisting}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     4187sout | 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]
     41901 2 3
     4191\end{lstlisting}
     4192\begin{lstlisting}[mathescape=off,aboveskip=0pt,aboveskip=0pt,belowskip=0pt]
     4193sepSet( sout, ", $" );                                          // change separator from " " to ", $"
     4194sout | 1 | 2 | 3 | endl;
     4195\end{lstlisting}
     4196%$
     4197\begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt]
     41981, $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
     4207int 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
     4251A 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
     4253A
     42541 2 3 4 5 6 7 8
     42551.1 1.2 1.3
     42561.1+2.3i 1.1-2.3i 1.1-2.3i
     4257
     42581.11.21.3
     42591.1+2.3i1.1-2.3i1.1-2.3i
     4260 abcxyz
     4261abcxyz
     4262
     42631.1, $1.2, $1.3
     42641.1+2.3i, $1.1-2.3i, $1.1-2.3i
     4265abc, $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
     4275The 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}
     4281forall( otype T ) T * malloc( void );
     4282forall( otype T ) T * malloc( char fill );
     4283forall( otype T ) T * malloc( T * ptr, size_t size );
     4284forall( otype T ) T * malloc( T * ptr, size_t size, unsigned char fill );
     4285forall( otype T ) T * calloc( size_t size );
     4286forall( otype T ) T * realloc( T * ptr, size_t size );
     4287forall( otype T ) T * realloc( T * ptr, size_t size, unsigned char fill );
     4288
     4289forall( otype T ) T * aligned_alloc( size_t alignment );
     4290forall( otype T ) T * memalign( size_t alignment );             // deprecated
     4291forall( otype T ) int posix_memalign( T ** ptr, size_t alignment );
     4292
     4293forall( otype T ) T * memset( T * ptr, unsigned char fill ); // use default value '\0' for fill
     4294forall( otype T ) T * memset( T * ptr );                                // remove when default value available
     4295\end{lstlisting}
     4296
     4297
     4298\subsection{ato/strto}
     4299
     4300\begin{lstlisting}
     4301int ato( const char * ptr );
     4302unsigned int ato( const char * ptr );
     4303long int ato( const char * ptr );
     4304unsigned long int ato( const char * ptr );
     4305long long int ato( const char * ptr );
     4306unsigned long long int ato( const char * ptr );
     4307float ato( const char * ptr );
     4308double ato( const char * ptr );
     4309long double ato( const char * ptr );
     4310float _Complex ato( const char * ptr );
     4311double _Complex ato( const char * ptr );
     4312long double _Complex ato( const char * ptr );
     4313
     4314int strto( const char * sptr, char ** eptr, int base );
     4315unsigned int strto( const char * sptr, char ** eptr, int base );
     4316long int strto( const char * sptr, char ** eptr, int base );
     4317unsigned long int strto( const char * sptr, char ** eptr, int base );
     4318long long int strto( const char * sptr, char ** eptr, int base );
     4319unsigned long long int strto( const char * sptr, char ** eptr, int base );
     4320float strto( const char * sptr, char ** eptr );
     4321double strto( const char * sptr, char ** eptr );
     4322long double strto( const char * sptr, char ** eptr );
     4323float _Complex strto( const char * sptr, char ** eptr );
     4324double _Complex strto( const char * sptr, char ** eptr );
     4325long double _Complex strto( const char * sptr, char ** eptr );
     4326\end{lstlisting}
     4327
     4328
     4329\subsection{bsearch/qsort}
     4330
     4331\begin{lstlisting}
     4332forall( otype T | { int ?<?( T, T ); } )
     4333T * bsearch( const T key, const T * arr, size_t dimension );
     4334
     4335forall( otype T | { int ?<?( T, T ); } )
     4336void qsort( const T * arr, size_t dimension );
     4337\end{lstlisting}
     4338
     4339
     4340\subsection{abs}
     4341
     4342\begin{lstlisting}
     4343char abs( char );
     4344extern "C" {
     4345int abs( int );                         // use default C routine for int
     4346} // extern "C"
     4347long int abs( long int );
     4348long long int abs( long long int );
     4349float abs( float );
     4350double abs( double );
     4351long double abs( long double );
     4352float _Complex abs( float _Complex );
     4353double _Complex abs( double _Complex );
     4354long double _Complex abs( long double _Complex );
     4355\end{lstlisting}
     4356
     4357
     4358\subsection{floor/ceil}
     4359
     4360\begin{lstlisting}
     4361float floor( float );
     4362extern "C" {
     4363double floor( double );         // use C routine for double
     4364} // extern "C"
     4365long double floor( long double );
     4366
     4367float ceil( float );
     4368extern "C" {
     4369double ceil( double );          // use C routine for double
     4370} // extern "C"
     4371long double ceil( long double );
     4372\end{lstlisting}
     4373
     4374
     4375\subsection{random}
     4376
     4377\begin{lstlisting}
     4378void rand48seed( long int s );
     4379char rand48();
     4380int rand48();
     4381unsigned int rand48();
     4382long int rand48();
     4383unsigned long int rand48();
     4384float rand48();
     4385double rand48();
     4386float _Complex rand48();
     4387double _Complex rand48();
     4388long double _Complex rand48();
     4389\end{lstlisting}
     4390
     4391
     4392\subsection{min/max/swap}
     4393
     4394\begin{lstlisting}
     4395forall( otype T | { int ?<?( T, T ); } )
     4396T min( const T t1, const T t2 );
     4397
     4398forall( otype T | { int ?>?( T, T ); } )
     4399T max( const T t1, const T t2 );
     4400
     4401forall( otype T )
     4402void swap( T * t1, T * t2 );
     4403\end{lstlisting}
     4404
     4405
     4406\section{Rational Numbers}
     4407\label{s:RationalNumbers}
     4408
     4409Rational 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.
     4410When 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
     4414struct Rational {
     4415        long int numerator, denominator;                                        // invariant: denominator > 0
     4416}; // Rational
     4417
     4418// constants
     4419extern struct Rational 0;
     4420extern struct Rational 1;
     4421
     4422// constructors
     4423Rational rational();
     4424Rational rational( long int n );
     4425Rational rational( long int n, long int d );
     4426
     4427// getter/setter for numerator/denominator
     4428long int numerator( Rational r );
     4429long int numerator( Rational r, long int n );
     4430long int denominator( Rational r );
     4431long int denominator( Rational r, long int d );
     4432
     4433// comparison
     4434int ?==?( Rational l, Rational r );
     4435int ?!=?( Rational l, Rational r );
     4436int ?<?( Rational l, Rational r );
     4437int ?<=?( Rational l, Rational r );
     4438int ?>?( Rational l, Rational r );
     4439int ?>=?( Rational l, Rational r );
     4440
     4441// arithmetic
     4442Rational -?( Rational r );
     4443Rational ?+?( Rational l, Rational r );
     4444Rational ?-?( Rational l, Rational r );
     4445Rational ?*?( Rational l, Rational r );
     4446Rational ?/?( Rational l, Rational r );
     4447
     4448// conversion
     4449double widen( Rational r );
     4450Rational narrow( double f, long int md );
     4451
     4452// I/O
     4453forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, Rational * );
     4454forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, Rational );
     4455\end{lstlisting}
     4456
     4457
    42574458\bibliographystyle{plain}
    4258 \bibliography{/usr/local/bibliographies/pl.bib}
     4459\bibliography{cfa}
    42594460
    42604461
  • src/CodeGen/CodeGenerator.cc

    r3aba311 r37218fc  
    455455
    456456        void CodeGenerator::visit( UntypedOffsetofExpr *offsetofExpr ) {
    457                 assert( false );
     457                assert( false && "UntypedOffsetofExpr should not reach code generation" );
    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" );
    466470        }
    467471 
  • src/CodeGen/CodeGenerator.h

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

    r3aba311 r37218fc  
    3030#include "FindFunction.h"
    3131#include "ScopedMap.h"
     32#include "ScopedSet.h"
    3233#include "ScrubTyVars.h"
    3334
     
    6263                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    6364
    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); }
     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 ) ) {}
    7173
    7274                        /// Extracts types from a list of TypeExpr*
    73                         ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base), params() {
     75                        TypeList( const std::list< TypeExpr* >& _params ) : params() {
    7476                                for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) {
    7577                                        params.push_back( (*param)->get_type()->clone() );
     
    7779                        }
    7880
    79                         ConcreteType& operator= (const ConcreteType& that) {
     81                        TypeList& operator= ( const TypeList &that ) {
    8082                                deleteAll( params );
     83
    8184                                params.clear();
    82 
    83                                 base = that.base;
    8485                                cloneAll( that.params, params );
    8586
     
    8788                        }
    8889
    89                         ~ConcreteType() { deleteAll( params ); }
    90 
    91                         bool operator== (const ConcreteType& that) const {
    92                                 if ( base != that.base ) return false;
     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 {
     101                                if ( params.size() != that.params.size() ) return false;
    93102
    94103                                SymTab::Indexer dummy;
    95                                 if ( params.size() != that.params.size() ) return false;
    96104                                for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) {
    97105                                        if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false;
     
    100108                        }
    101109
    102                         AggregateDecl *base;        ///< Base generic type
    103110                        std::list< Type* > params;  ///< Instantiation parameters
    104111                };
    105112
    106                 /// Maps a concrete type to the some value, accounting for scope
    107                 template< typename Value >
     113                /// Maps a key and a TypeList to the some value, accounting for scope
     114                template< typename Key, typename Value >
    108115                class InstantiationMap {
    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
     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
    121124
    122125                public:
    123126                        /// Starts a new scope
    124                         void beginScope() {
    125                                 Scope scope;
    126                                 scopes.push_back(scope);
    127                         }
     127                        void beginScope() { instantiations.beginScope(); }
    128128
    129129                        /// Ends a scope
    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;
     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;
    150140                                        }
    151141                                }
    152                                 // no matching instantiation found
     142                                // no matching instantiations found
    153143                                return 0;
    154144                        }
    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 ); }
     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                        }
    168150                };
    169151
     
    197179                        virtual void doEndScope();
    198180                  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 );
    201181                        /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application
    202182                        void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes );
     
    225205                        ObjectDecl *makeTemporary( Type *type );
    226206
    227                         std::map< std::string, DeclarationWithType *> assignOps;
    228                         ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps;
    229                         ScopedMap< std::string, DeclarationWithType* > adapters;
     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                       
    230211                        DeclarationWithType *retval;
    231212                        bool useRetval;
     
    233214                };
    234215
    235                 /// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well
     216                /// * Moves polymorphic returns in function types to pointer-type parameters
     217                /// * adds type size and assertion parameters to parameter lists
    236218                class Pass2 : public PolyMutator {
    237219                  public:
     
    244226                        virtual Type *mutate( PointerType *pointerType );
    245227                        virtual Type *mutate( FunctionType *funcType );
     228                       
    246229                  private:
    247230                        void addAdapters( FunctionType *functionType );
     
    253236                class GenericInstantiator : public DeclMutator {
    254237                        /// Map of (generic type, parameter list) pairs to concrete type instantiations
    255                         InstantiationMap< AggregateDecl > instantiations;
     238                        InstantiationMap< AggregateDecl, AggregateDecl > instantiations;
    256239                        /// Namer for concrete types
    257240                        UniqueName typeNamer;
     
    278261                };
    279262
    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:
     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:
    284269                        template< typename DeclClass >
    285270                        DeclClass *handleDecl( DeclClass *decl, Type *type );
     
    292277                        virtual Type *mutate( FunctionType *funcType );
    293278                        virtual Expression *mutate( MemberExpr *memberExpr );
     279                        virtual Expression *mutate( SizeofExpr *sizeofExpr );
     280                        virtual Expression *mutate( AlignofExpr *alignofExpr );
    294281                        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
    295297                };
    296298
     
    342344                Pass2 pass2;
    343345                GenericInstantiator instantiator;
    344                 MemberExprFixer memberFixer;
     346                PolyGenericCalculator polyCalculator;
    345347                Pass3 pass3;
    346348               
     
    348350                mutateTranslationUnit/*All*/( translationUnit, pass1 );
    349351                mutateTranslationUnit/*All*/( translationUnit, pass2 );
    350 //              instantiateGeneric( translationUnit );
    351352                instantiator.mutateDeclarationList( translationUnit );
    352                 mutateTranslationUnit/*All*/( translationUnit, memberFixer );
     353                mutateTranslationUnit/*All*/( translationUnit, polyCalculator );
    353354                mutateTranslationUnit/*All*/( translationUnit, pass3 );
    354355        }
     
    653654
    654655                DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
    655                         // if this is a polymorphic assignment function, put it in the map for this scope
     656                        // if this is a assignment function, put it in the map for this scope
    656657                        if ( Type *assignedType = isAssignment( functionDecl ) ) {
    657658                                if ( ! dynamic_cast< TypeInstType* >( assignedType ) ) {
     
    743744                }
    744745
    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 
    772746                void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) {
    773747                        Type *polyBase = hasPolyBase( parmType, exprTyVars );
     
    782756                                if ( dynamic_cast< StructInstType* >( polyBase ) ) {
    783757                                        if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) {
    784                                                 arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) );
    785                                                 arg++;
     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                                                }
    786763                                        } else {
    787764                                                throw SemanticError( "Cannot pass non-struct type for generic struct" );
     
    931908                                        return;
    932909                                } else if ( arg->get_results().front()->get_isLvalue() ) {
    933                                         // VariableExpr and MemberExpr are lvalues
    934                                         arg = new AddressExpr( arg );
     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                                        }
    935916                                } else {
    936917                                        // use type computed in unification to declare boxed variables
     
    10271008                        } // for
    10281009                }
    1029 
    1030 
    10311010
    10321011                FunctionDecl *Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) {
     
    14281407                                        std::list< TypeDecl* >::const_iterator forallIt = forallParams.begin();
    14291408                                        for ( ; tyIt != tyParams.end() && forallIt != forallParams.end(); ++tyIt, ++forallIt ) {
    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" );
     1409                                                // Add appropriate mapping to assignment expression environment
    14371410                                                TypeExpr *formalTypeExpr = dynamic_cast< TypeExpr* >( *tyIt );
    14381411                                                assert( formalTypeExpr && "type parameters must be type expressions" );
    14391412                                                Type *formalType = formalTypeExpr->get_type();
    1440                                                 assignExpr->get_env()->add( actualType->get_name(), formalType );
    1441                                                
     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
    14421419                                                DeclarationWithType *assertAssign = 0;
    14431420                                                if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) {
     
    14531430                                                        }
    14541431                                                }
    1455                                                
    1456 
     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();
    14571437                                                assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ]
    14581438                                                        = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) );
     
    15871567                        ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0,
    15881568                                           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 );
    15901569                        for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
    15911570                                ObjectDecl *sizeParm, *alignParm;
     
    16311610                                        ++last;
    16321611
    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;
     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                                                }
    16381620                                        }
    16391621
     
    18441826
    18451827                template< typename DeclClass >
    1846                 DeclClass * MemberExprFixer::handleDecl( DeclClass *decl, Type *type ) {
     1828                DeclClass * PolyGenericCalculator::handleDecl( DeclClass *decl, Type *type ) {
    18471829                        TyVarMap oldtyVars = scopeTyVars;
    18481830                        makeTyVarMap( type, scopeTyVars );
     
    18541836                }
    18551837
    1856                 ObjectDecl * MemberExprFixer::mutate( ObjectDecl *objectDecl ) {
     1838                ObjectDecl * PolyGenericCalculator::mutate( ObjectDecl *objectDecl ) {
    18571839                        return handleDecl( objectDecl, objectDecl->get_type() );
    18581840                }
    18591841
    1860                 DeclarationWithType * MemberExprFixer::mutate( FunctionDecl *functionDecl ) {
     1842                DeclarationWithType * PolyGenericCalculator::mutate( FunctionDecl *functionDecl ) {
    18611843                        return handleDecl( functionDecl, functionDecl->get_functionType() );
    18621844                }
    18631845
    1864                 TypedefDecl * MemberExprFixer::mutate( TypedefDecl *typedefDecl ) {
     1846                TypedefDecl * PolyGenericCalculator::mutate( TypedefDecl *typedefDecl ) {
    18651847                        return handleDecl( typedefDecl, typedefDecl->get_base() );
    18661848                }
    18671849
    1868                 TypeDecl * MemberExprFixer::mutate( TypeDecl *typeDecl ) {
     1850                TypeDecl * PolyGenericCalculator::mutate( TypeDecl *typeDecl ) {
    18691851                        scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
    18701852                        return Mutator::mutate( typeDecl );
    18711853                }
    18721854
    1873                 Type * MemberExprFixer::mutate( PointerType *pointerType ) {
     1855                Type * PolyGenericCalculator::mutate( PointerType *pointerType ) {
    18741856                        TyVarMap oldtyVars = scopeTyVars;
    18751857                        makeTyVarMap( pointerType, scopeTyVars );
     
    18811863                }
    18821864
    1883                 Type * MemberExprFixer::mutate( FunctionType *functionType ) {
     1865                Type * PolyGenericCalculator::mutate( FunctionType *funcType ) {
    18841866                        TyVarMap oldtyVars = scopeTyVars;
    1885                         makeTyVarMap( functionType, scopeTyVars );
    1886 
    1887                         Type *ret = Mutator::mutate( functionType );
     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 );
    18881879
    18891880                        scopeTyVars = oldtyVars;
     
    18911882                }
    18921883
    1893                 Statement *MemberExprFixer::mutate( DeclStmt *declStmt ) {
     1884                Statement *PolyGenericCalculator::mutate( DeclStmt *declStmt ) {
    18941885                        if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
    1895                                 if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) {
     1886                                if ( findGeneric( objectDecl->get_type() ) ) {
    18961887                                        // change initialization of a polymorphic value object
    18971888                                        // to allocate storage with alloca
     
    19451936                }
    19461937               
    1947                 Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) {
     1938                Expression *PolyGenericCalculator::mutate( MemberExpr *memberExpr ) {
    19481939                        // mutate, exiting early if no longer MemberExpr
    19491940                        Expression *expr = Mutator::mutate( memberExpr );
     
    19621953                        Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars, &tyDepth );
    19631954                        if ( ! objectType ) return memberExpr;
     1955                        findGeneric( objectType ); // ensure layout for this type is available
    19641956
    19651957                        Expression *newMemberExpr = 0;
     
    19931985                }
    19941986
    1995                 Expression *MemberExprFixer::mutate( OffsetofExpr *offsetofExpr ) {
     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 ) {
    19962126                        // mutate, exiting early if no longer OffsetofExpr
    19972127                        Expression *expr = Mutator::mutate( offsetofExpr );
     
    20002130
    20012131                        // only mutate expressions for polymorphic structs/unions
    2002                         Type *ty = isPolyType( offsetofExpr->get_type(), scopeTyVars );
    2003                         if ( ! ty ) return offsetofExpr;
    2004 
     2132                        Type *ty = offsetofExpr->get_type();
     2133                        if ( ! findGeneric( ty ) ) return offsetofExpr;
     2134                       
    20052135                        if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) {
    20062136                                // replace offsetof expression by index into offset array
     
    20182148                }
    20192149
     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
    20202201////////////////////////////////////////// Pass3 ////////////////////////////////////////////////////
    20212202
  • src/GenPoly/ScopedMap.h

    r3aba311 r37218fc  
    1717#define _SCOPEDMAP_H
    1818
     19#include <cassert>
    1920#include <iterator>
    2021#include <map>
     
    164165                void endScope() {
    165166                        scopes.pop_back();
     167                        assert( ! scopes.empty() );
    166168                }
    167169
     
    188190                        return end();
    189191                }
    190                 const_iterator find( const Key &key ) const { return const_iterator( find( key ) ); }
     192                const_iterator find( const Key &key ) const {
     193                                return const_iterator( const_cast< ScopedMap< Key, Value >* >(this)->find( key ) );
     194                }
    191195               
    192196                /// Finds the given key in the outermost scope inside the given scope where it occurs
     
    200204                        return end();
    201205                }
    202                 const_iterator findNext( const_iterator &it, const Key &key ) const { return const_iterator( findNext( it, key ) ); }
     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                }
    203209
    204210                /// Inserts the given key-value pair into the outermost scope
     
    208214                }
    209215                std::pair< iterator, bool > insert( const Key &key, const Value &value ) { return insert( std::make_pair( key, value ) ); }
    210                
     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                }
    211222        };
    212223} // namespace GenPoly
  • src/InitTweak/InitModel.h

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

    r3aba311 r37218fc  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Mar 13 12:34:38 2016
    13 // Update Count     : 272
     12// Last Modified On : Fri Apr  8 15:43:05 2016
     13// Update Count     : 296
    1414//
    1515
     
    2222
    2323#include "ParseNode.h"
     24#include "TypeData.h"
    2425#include "SynTree/Constant.h"
    2526#include "SynTree/Expression.h"
     27#include "SynTree/Declaration.h"
    2628#include "Common/UnimplementedError.h"
    2729#include "parseutility.h"
     
    872874}
    873875
     876
     877CompoundLiteralNode::CompoundLiteralNode( DeclarationNode *type, InitializerNode *kids ) : type( type ), kids( kids ) {}
     878CompoundLiteralNode::CompoundLiteralNode( const CompoundLiteralNode &other ) : ExpressionNode( other ), type( other.type ), kids( other.kids ) {}
     879
     880CompoundLiteralNode::~CompoundLiteralNode() {
     881        delete kids;
     882        delete type;
     883}
     884
     885CompoundLiteralNode *CompoundLiteralNode::clone() const {
     886        return new CompoundLiteralNode( *this );
     887}
     888
     889void 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
     901void 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
     909Expression *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
    874926ExpressionNode *flattenCommas( ExpressionNode *list ) {
    875927        if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) ) {
  • src/Parser/ParseNode.h

    r3aba311 r37218fc  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Mon Apr 04 17:04:22 2016
    13 // Update Count     : 190
     12// Last Modified On : Mon Apr 11 11:50:52 2016
     13// Update Count     : 205
    1414//
    1515
     
    538538};
    539539
     540class 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
    540563template< typename SynTreeType, typename NodeType >
    541564void buildList( const NodeType *firstNode, std::list< SynTreeType *> &outputList ) {
  • src/Parser/parser.cc

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

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

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

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

    r3aba311 r37218fc  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 16:14:32 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Jul 14 12:26:17 2015
    13 // Update Count     : 4
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Apr  7 14:42:21 2016
     13// Update Count     : 5
    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 >
    3929        inline void addVisit(CompoundStmt *compoundStmt, Visitor &visitor) {
    4030                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 );
    6231        }
    6332
     
    7443        }
    7544
    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         }
     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        // }
    8750} // namespace SymTab
    8851
  • src/SymTab/Indexer.cc

    r3aba311 r37218fc  
    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 );
    346351        }
    347352
  • src/SymTab/Indexer.h

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

    r3aba311 r37218fc  
    1010// Created On       : Sun May 17 21:50:04 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 17:31:39 2016
    13 // Update Count     : 226
     12// Last Modified On : Thu Apr  7 16:45:30 2016
     13// Update Count     : 243
    1414//
    1515
     
    4040#include <list>
    4141#include <iterator>
     42#include "Common/utility.h"
     43#include "Common/UniqueName.h"
    4244#include "Validate.h"
    4345#include "SynTree/Visitor.h"
    4446#include "SynTree/Mutator.h"
    4547#include "SynTree/Type.h"
     48#include "SynTree/Expression.h"
    4649#include "SynTree/Statement.h"
    4750#include "SynTree/TypeSubstitution.h"
     
    4952#include "FixFunction.h"
    5053// #include "ImplementationType.h"
    51 #include "Common/utility.h"
    52 #include "Common/UniqueName.h"
     54#include "GenPoly/DeclMutator.h"
    5355#include "AddVisit.h"
    5456#include "MakeLibCfa.h"
     
    7072
    7173                virtual void visit( CompoundStmt *compoundStmt );
    72                 virtual void visit( IfStmt *ifStmt );
    73                 virtual void visit( WhileStmt *whileStmt );
    74                 virtual void visit( ForStmt *forStmt );
    7574                virtual void visit( SwitchStmt *switchStmt );
    7675                virtual void visit( ChooseStmt *chooseStmt );
    77                 virtual void visit( CaseStmt *caseStmt );
    78                 virtual void visit( CatchStmt *catchStmt );
     76                // virtual void visit( CaseStmt *caseStmt );
    7977          private:
    8078                HoistStruct();
     
    144142
    145143                virtual void visit( CompoundStmt *compoundStmt );
    146                 virtual void visit( IfStmt *ifStmt );
    147                 virtual void visit( WhileStmt *whileStmt );
    148                 virtual void visit( ForStmt *forStmt );
    149144                virtual void visit( SwitchStmt *switchStmt );
    150145                virtual void visit( ChooseStmt *chooseStmt );
    151                 virtual void visit( CaseStmt *caseStmt );
    152                 virtual void visit( CatchStmt *catchStmt );
     146                // virtual void visit( CaseStmt *caseStmt );
    153147
    154148                AutogenerateRoutines() : functionNesting( 0 ) {}
     
    166160                /// and return something if the return type is non-void.
    167161                static void checkFunctionReturns( std::list< Declaration * > & translationUnit );
    168 
    169162          private:
    170163                virtual void visit( FunctionDecl * functionDecl );
     
    202195        };
    203196
     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
    208210                EliminateTypedef::eliminateTypedef( translationUnit );
    209211                HoistStruct::hoistStruct( translationUnit );
     
    211213                acceptAll( translationUnit, pass2 );
    212214                ReturnChecker::checkFunctionReturns( translationUnit );
     215                mutateAll( translationUnit, compoundliteral );
    213216                AutogenerateRoutines::autogenerateRoutines( translationUnit );
    214217                acceptAll( translationUnit, pass3 );
     
    292295        }
    293296
    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 
    306297        void HoistStruct::visit( SwitchStmt *switchStmt ) {
    307298                addVisit( switchStmt, *this );
     
    312303        }
    313304
    314         void HoistStruct::visit( CaseStmt *caseStmt ) {
    315                 addVisit( caseStmt, *this );
    316         }
    317 
    318         void HoistStruct::visit( CatchStmt *cathStmt ) {
    319                 addVisit( cathStmt, *this );
    320         }
     305        // void HoistStruct::visit( CaseStmt *caseStmt ) {
     306        //      addVisit( caseStmt, *this );
     307        // }
    321308
    322309        void Pass1::visit( EnumDecl *enumDecl ) {
     
    874861        }
    875862
    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 
    888863        void AutogenerateRoutines::visit( SwitchStmt *switchStmt ) {
    889864                visitStatement( switchStmt );
     
    894869        }
    895870
    896         void AutogenerateRoutines::visit( CaseStmt *caseStmt ) {
    897                 visitStatement( caseStmt );
    898         }
    899 
    900         void AutogenerateRoutines::visit( CatchStmt *cathStmt ) {
    901                 visitStatement( cathStmt );
    902         }
     871        // void AutogenerateRoutines::visit( CaseStmt *caseStmt ) {
     872        //      visitStatement( caseStmt );
     873        // }
    903874
    904875        void ReturnChecker::checkFunctionReturns( std::list< Declaration * > & translationUnit ) {
     
    10801051        }
    10811052
     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        }
    10821073} // namespace SymTab
    10831074
  • src/SynTree/Expression.cc

    r3aba311 r37218fc  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Dec 09 14:10:29 2015
    13 // Update Count     : 34
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Apr  8 17:16:23 2016
     13// Update Count     : 40
    1414//
    1515
     
    2222
    2323#include "Type.h"
     24#include "Initializer.h"
    2425#include "Expression.h"
    2526#include "Declaration.h"
     
    211212
    212213        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
     225OffsetPackExpr::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
     229OffsetPackExpr::OffsetPackExpr( const OffsetPackExpr &other ) : Expression( other ), type( maybeClone( other.type ) ) {}
     230
     231OffsetPackExpr::~OffsetPackExpr() { delete type; }
     232
     233void OffsetPackExpr::print( std::ostream &os, int indent ) const {
     234        os << std::string( indent, ' ' ) << "Offset pack expression on ";
    213235
    214236        if ( type ) {
     
    443465
    444466
     467CompoundLiteralExpr::CompoundLiteralExpr( Type * type, Initializer * initializer ) : type( type ), initializer( initializer ) {
     468        add_result( type->clone() );
     469}
     470
     471CompoundLiteralExpr::CompoundLiteralExpr( const CompoundLiteralExpr &other ) : Expression( other ), type( maybeClone( other.type ) ), initializer( maybeClone( other.initializer ) ) {}
     472
     473CompoundLiteralExpr::~CompoundLiteralExpr() {
     474        delete initializer;
     475        delete type;
     476}
     477
     478void 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
    445484
    446485std::ostream & operator<<( std::ostream & out, Expression * expr ) {
  • src/SynTree/Expression.h

    r3aba311 r37218fc  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Dec 09 14:10:21 2015
    13 // Update Count     : 19
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Apr  8 17:18:06 2016
     13// Update Count     : 21
    1414//
    1515
     
    362362};
    363363
     364/// Expression representing a pack of field-offsets for a generic type
     365class OffsetPackExpr : public Expression {
     366public:
     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
     380private:
     381        StructInstType *type;
     382};
     383
    364384/// AttrExpr represents an @attribute expression (like sizeof, but user-defined)
    365385class AttrExpr : public Expression {
     
    557577};
    558578
     579/// CompoundLiteralExpr represents a C99 'compound literal'
     580class 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
    559601std::ostream & operator<<( std::ostream & out, Expression * expr );
    560602
  • src/SynTree/Mutator.cc

    r3aba311 r37218fc  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 17:28:20 2016
    13 // Update Count     : 12
     12// Last Modified On : Fri Apr  1 18:05:16 2016
     13// Update Count     : 16
    1414//
    1515
     
    274274}
    275275
     276Expression *Mutator::mutate( OffsetPackExpr *offsetPackExpr ) {
     277        mutateAll( offsetPackExpr->get_results(), *this );
     278        offsetPackExpr->set_type( maybeMutate( offsetPackExpr->get_type(), *this ) );
     279        return offsetPackExpr;
     280}
     281
    276282Expression *Mutator::mutate( AttrExpr *attrExpr ) {
    277283        mutateAll( attrExpr->get_results(), *this );
     
    334340        mutateAll( valofExpr->get_results(), *this );
    335341        return valofExpr;
     342}
     343
     344Expression *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;
    336349}
    337350
  • src/SynTree/Mutator.h

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

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

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

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

    r3aba311 r37218fc  
    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 );  }
    5152        void FlattenTuple::CollectArgs::visit( AttrExpr            *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    5253        void FlattenTuple::CollectArgs::visit( LogicalExpr         *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
  • src/Tuples/FlattenTuple.h

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

    r3aba311 r37218fc  
    1010// Created On       : Tue Aug 20 13:44:49 2002
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jan 28 18:24:06 2016
    13 // Update Count     : 127
     12// Last Modified On : Wed Apr  6 14:04:22 2016
     13// Update Count     : 132
    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=c99";
     309                        args[nargs] = "-std=gnu99";
    310310                        nargs += 1;
    311311                } // if
  • src/libcfa/Makefile.am

    r3aba311 r37218fc  
    1111## Created On       : Sun May 31 08:54:01 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Wed Mar  2 22:59:23 2016
    14 ## Update Count     : 119
     13## Last Modified On : Wed Apr  6 21:10:44 2016
     14## Update Count     : 123
    1515###############################################################################
    1616
     
    6060        ${CC} ${CFLAGS} -c -o $@ $<
    6161
    62 libs = stdlib iostream fstream iterator
     62libs = limits stdlib iostream fstream iterator rational
    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

    r3aba311 r37218fc  
    8383libcfa_a_AR = $(AR) $(ARFLAGS)
    8484libcfa_a_LIBADD =
    85 am__objects_1 = stdlib.$(OBJEXT) iostream.$(OBJEXT) fstream.$(OBJEXT) \
    86         iterator.$(OBJEXT)
     85am__objects_1 = limits.$(OBJEXT) stdlib.$(OBJEXT) iostream.$(OBJEXT) \
     86        fstream.$(OBJEXT) iterator.$(OBJEXT) rational.$(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 = stdlib iostream fstream iterator
     215libs = limits stdlib iostream fstream iterator rational
    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@
    299301@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stdlib.Po@am__quote@
    300302
  • src/libcfa/fstream

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

    r3aba311 r37218fc  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Feb 29 18:41:10 2016
    13 // Update Count     : 162
     12// Last Modified On : Wed Apr  6 17:55:27 2016
     13// Update Count     : 176
    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->separate == 1; }
    30 void sepOn( ofstream * os ) { if ( os->separate != 2 ) os->separate = 1; }
    31 void sepOff( ofstream * os ) { if ( os->separate != 2 ) os->separate = 0; }
     29_Bool sepPrt( ofstream * os ) { return os->sepOnOff; }
     30void sepOn( ofstream * os ) { os->sepOnOff = 1; }
     31void sepOff( ofstream * os ) { os->sepOnOff = 0; }
     32void sepReset( ofstream * os ) { os->sepOnOff = os->sepDefault; }
     33void sepReset( ofstream * os, _Bool reset ) { os->sepDefault = reset; os->sepOnOff = os->sepDefault; }
    3234void sepSet( ofstream * os, const char * s ) {
    3335        strncpy( &(os->separator[0]), s, separateSize - 1 );
     
    3537} // sepSet
    3638const char * sepGet( ofstream * os ) { return &(os->separator[0]); }
    37 void sepDisable( ofstream *os ) { os->separate = 2; }
    38 void sepEnable( ofstream *os ) { os->separate = 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
    3951
    4052int fail( ofstream * os ) {
     
    4961        FILE *file = fopen( name, mode );
    5062        if ( file == 0 ) {                                                                      // do not change unless successful
    51                 perror( IO_MSG "open output" );
     63                fprintf( stderr, IO_MSG "open output file \"%s\", ", name );
     64                perror( 0 );
    5265                exit( EXIT_FAILURE );
    5366        } // if
     
    94107
    95108
    96 static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_), 0, { ' ', '\0' } };
     109static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_), 1, 0, { ' ', '\0' } };
    97110ofstream *sout = &soutFile;
    98 static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_), 0, { ' ', '\0' } };
     111static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_), 1, 0, { ' ', '\0' } };
    99112ofstream *serr = &serrFile;
    100113
     
    114127        FILE *t = fopen( name, mode );
    115128        if ( t == 0 ) {                                                                         // do not change unless successful
    116                 perror( IO_MSG "open input" );
     129                fprintf( stderr, IO_MSG "open input file \"%s\", ", name );
     130                perror( 0 );
    117131                exit( EXIT_FAILURE );
    118132        } // if
     
    175189// Local Variables: //
    176190// tab-width: 4 //
    177 // compile-command: "cfa fstream.c" //
    178191// End: //
  • src/libcfa/iostream

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

    r3aba311 r37218fc  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Mar  7 13:51:23 2016
    13 // Update Count     : 227
     12// Last Modified On : Wed Apr  6 16:13:29 2016
     13// Update Count     : 278
    1414//
    1515
     
    2727ostype * ?|?( ostype *os, char c ) {
    2828        prtfmt( os, "%c", c );
     29        sepOff( os );
    2930        return os;
    3031} // ?|?
     
    3233forall( dtype ostype | ostream( ostype ) )
    3334ostype * ?|?( ostype *os, short int si ) {
    34         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
     35        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
     36        sepReset( os );
    3537        prtfmt( os, "%hd", si );
    3638        return os;
     
    3941forall( dtype ostype | ostream( ostype ) )
    4042ostype * ?|?( ostype *os, unsigned short int usi ) {
    41         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
     43        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
     44        sepReset( os );
    4245        prtfmt( os, "%hu", usi );
    4346        return os;
     
    4649forall( dtype ostype | ostream( ostype ) )
    4750ostype * ?|?( ostype *os, int i ) {
    48         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
     51        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
     52        sepReset( os );
    4953        prtfmt( os, "%d", i );
    5054        return os;
     
    5357forall( dtype ostype | ostream( ostype ) )
    5458ostype * ?|?( ostype *os, unsigned int ui ) {
    55         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
     59        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
     60        sepReset( os );
    5661        prtfmt( os, "%u", ui );
    5762        return os;
     
    6065forall( dtype ostype | ostream( ostype ) )
    6166ostype * ?|?( ostype *os, long int li ) {
    62         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
     67        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
     68        sepReset( os );
    6369        prtfmt( os, "%ld", li );
    6470        return os;
     
    6773forall( dtype ostype | ostream( ostype ) )
    6874ostype * ?|?( ostype *os, unsigned long int uli ) {
    69         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
     75        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
     76        sepReset( os );
    7077        prtfmt( os, "%lu", uli );
    7178        return os;
     
    7481forall( dtype ostype | ostream( ostype ) )
    7582ostype * ?|?( ostype *os, long long int lli ) {
    76         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
     83        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
     84        sepReset( os );
    7785        prtfmt( os, "%lld", lli );
    7886        return os;
     
    8189forall( dtype ostype | ostream( ostype ) )
    8290ostype * ?|?( ostype *os, unsigned long long int ulli ) {
    83         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
     91        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
     92        sepReset( os );
    8493        prtfmt( os, "%llu", ulli );
    8594        return os;
     
    8897forall( dtype ostype | ostream( ostype ) )
    8998ostype * ?|?( ostype *os, float f ) {
    90         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
     99        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
     100        sepReset( os );
    91101        prtfmt( os, "%g", f );
    92102        return os;
     
    95105forall( dtype ostype | ostream( ostype ) )
    96106ostype * ?|?( ostype *os, double d ) {
    97         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
     107        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
     108        sepReset( os );
    98109        prtfmt( os, "%.*lg", DBL_DIG, d );
    99110        return os;
     
    102113forall( dtype ostype | ostream( ostype ) )
    103114ostype * ?|?( ostype *os, long double ld ) {
    104         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
     115        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
     116        sepReset( os );
    105117        prtfmt( os, "%.*Lg", LDBL_DIG, ld );
    106118        return os;
     
    110122ostype * ?|?( ostype *os, float _Complex fc ) {
    111123        os | crealf( fc );
    112         if ( cimagf( fc ) >= 0 ) os | '+';
    113         os | "" | cimagf( fc ) | 'i';
     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
    114128        return os;
    115129} // ?|?
     
    118132ostype * ?|?( ostype *os, double _Complex dc ) {
    119133        os | creal( dc );
    120         if ( cimag( dc ) >= 0 ) os | '+';
    121         os | "" | cimag( dc ) | 'i';
     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
    122138        return os;
    123139} // ?|?
     
    126142ostype * ?|?( ostype *os, long double _Complex ldc ) {
    127143        os | creall( ldc );
    128         if ( cimagl( ldc ) >= 0 ) os | '+';
    129         os | "" | cimagl( ldc ) | 'i';
     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
    130148        return os;
    131149} // ?|?
     
    134152ostype * ?|?( ostype *os, const char *cp ) {
    135153        enum { Open = 1, Close, OpenClose };
    136         static const char mask[256] = {
     154        static const unsigned char mask[256] = {
    137155                // opening delimiters
    138156                ['('] : Open, ['['] : Open, ['{'] : Open,
    139                 ['$'] : Open, [L'£'] : Open, [L'¥'] : Open, [L'¢'] : Open, [L'¿'] : Open, [L'«'] : Open,
     157                ['$'] : Open, [(unsigned char)'£'] : Open, [(unsigned char)'¥'] : Open, [(unsigned char)'¿'] : Open, [(unsigned char)'«'] : Open,
    140158                // closing delimiters
    141159                [','] : Close, ['.'] : Close, [':'] : Close, [';'] : Close, ['!'] : Close, ['?'] : Close,
    142160                [')'] : Close, [']'] : Close, ['}'] : Close,
    143                 ['%'] : Close, [L'»'] : Close,
     161                ['%'] : Close, [(unsigned char)'¢'] : Close, [(unsigned char)'»'] : Close,
    144162                // opening-closing delimiters
    145163                ['\''] : OpenClose, ['`'] : OpenClose, ['"'] : OpenClose,
     164                ['\f'] : OpenClose, ['\n'] : OpenClose, ['\r'] : OpenClose, ['\t'] : OpenClose, ['\v'] : OpenClose, // isspace
    146165        }; // mask
    147166
     
    149168        // null string => no separator
    150169  if ( len == 0 ) { sepOff( os ); return os; }
    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 ) {
     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 ) {
    153173                prtfmt( os, "%s", sepGet( os ) );
    154174        } // if
    155175        // last character IS spacing or opening punctuation => turn off separator for next item
    156176        unsigned int posn = len - 1;
    157         if ( isspace( cp[posn] ) || mask[ cp[posn] ] == Open || mask[ cp[posn] ] == OpenClose ) {
     177        ch = cp[posn];                                                                          // must make unsigned
     178        if ( mask[ ch ] == Open || mask[ ch ] == OpenClose ) {
    158179                sepOff( os );
    159180        } else {
     
    165186forall( dtype ostype | ostream( ostype ) )
    166187ostype * ?|?( ostype *os, const void *p ) {
    167         if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os );
     188        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
     189        sepReset( os );
    168190        prtfmt( os, "%p", p );
    169191        return os;
     
    196218} // sepOff
    197219
     220forall( dtype ostype | ostream( ostype ) )
     221ostype * sepEnable( ostype * os ) {
     222        sepEnable( os );
     223        return os;
     224} // sepEnable
     225
     226forall( dtype ostype | ostream( ostype ) )
     227ostype * sepDisable( ostype * os ) {
     228        sepDisable( os );
     229        return os;
     230} // sepDisable
     231
    198232//---------------------------------------
    199233
     
    310344} // ?|?
    311345
    312 _Istream_str1 str( char * s ) { _Istream_str1 s = { s }; return s; }
    313 forall( dtype istype | istream( istype ) )
    314 istype * ?|?( 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; }
    320 forall( dtype istype | istream( istype ) )
    321 istype * ?|?( istype * is, _Istream_str2 str ) {
     346_Istream_cstrUC cstr( char * s ) { _Istream_cstrUC s = { s }; return s; }
     347forall( dtype istype | istream( istype ) )
     348istype * ?|?( 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; }
     354forall( dtype istype | istream( istype ) )
     355istype * ?|?( istype * is, _Istream_cstrC cstr ) {
    322356        char buf[16];
    323         sprintf( buf, "%%%ds", str.size );
    324         scanfmt( is, buf, str.s );
    325         return is;
    326 } // str
     357        sprintf( buf, "%%%ds", cstr.size );
     358        scanfmt( is, buf, cstr.s );
     359        return is;
     360} // cstr
    327361
    328362// Local Variables: //
  • src/libcfa/limits

    r3aba311 r37218fc  
     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
    116// Integral Constants
    217
    3 const short int MIN = -32768;
    4 const int MIN = -2147483648;
    5 const long int MIN = -9223372036854775807L - 1L;
    6 const long long int MIN = -9223372036854775807LL - 1LL;
     18extern const short int MIN;
     19extern const int MIN;
     20extern const long int MIN;
     21extern const long long int MIN;
    722
    8 const short int MAX = 32767;
    9 const unsigned short int MAX = 65535;
    10 const int MAX = 2147483647;
    11 const unsigned int MAX = 4294967295_U;
    12 const long int MAX = 9223372036854775807_L;
    13 const unsigned long int MAX = 4294967295_U;
    14 const long long int MAX = 9223372036854775807_LL;
    15 const unsigned long long int MAX = 18446744073709551615_ULL;
     23extern const short int MAX;
     24extern const unsigned short int MAX;
     25extern const int MAX;
     26extern const unsigned int MAX;
     27extern const long int MAX;
     28extern const unsigned long int MAX;
     29extern const long long int MAX;
     30extern const unsigned long long int MAX;
    1631
    1732// Floating-Point Constants
    1833
    19 const float PI = 3.141592_F;                            // pi
    20 const float PI_2 = 1.570796_F;                          // pi / 2
    21 const float PI_4 = 0.7853981_F;                         // pi / 4
    22 const float _1_PI = 0.3183098_F;                        // 1 / pi
    23 const float _2_PI = 0.6366197_F;                        // 2 / pi
    24 const float _2_SQRT_PI = 1.128379_F;                    // 2 / sqrt(pi)
     34extern const float PI;                                                                  // pi
     35extern const float PI_2;                                                                // pi / 2
     36extern const float PI_4;                                                                // pi / 4
     37extern const float _1_PI;                                                               // 1 / pi
     38extern const float _2_PI;                                                               // 2 / pi
     39extern const float _2_SQRT_PI;                                                  // 2 / sqrt(pi)
    2540
    26 const double PI = 3.14159265358979323846_D;             // pi
    27 const double PI_2 = 1.57079632679489661923_D;           // pi / 2
    28 const double PI_4 = 0.78539816339744830962_D;           // pi / 4
    29 const double _1_PI = 0.31830988618379067154_D;          // 1 / pi
    30 const double _2_PI = 0.63661977236758134308_D;          // 2 / pi
    31 const double _2_SQRT_PI = 1.12837916709551257390_D;     // 2 / sqrt(pi)
     41extern const double PI;                                                                 // pi
     42extern const double PI_2;                                                               // pi / 2
     43extern const double PI_4;                                                               // pi / 4
     44extern const double _1_PI;                                                              // 1 / pi
     45extern const double _2_PI;                                                              // 2 / pi
     46extern const double _2_SQRT_PI;                                                 // 2 / sqrt(pi)
    3247
    33 const long double PI = 3.1415926535897932384626433832795029_DL; // pi
    34 const long double PI_2 = 1.5707963267948966192313216916397514_DL; // pi / 2
    35 const long double PI_4 = 0.7853981633974483096156608458198757_DL; // pi / 4
    36 const long double _1_PI = 0.3183098861837906715377675267450287_DL; // 1 / pi
    37 const long double _2_PI = 0.6366197723675813430755350534900574_DL; // 2 / pi
    38 const long double _2_SQRT_PI = 1.1283791670955125738961589031215452_DL; // 2 / sqrt(pi)
     48extern const long double PI;                                                    // pi
     49extern const long double PI_2;                                                  // pi / 2
     50extern const long double PI_4;                                                  // pi / 4
     51extern const long double _1_PI;                                                 // 1 / pi
     52extern const long double _2_PI;                                                 // 2 / pi
     53extern const long double _2_SQRT_PI;                                    // 2 / sqrt(pi)
    3954
    40 const _Complex PI = 3.14159265358979323846_D+0.0_iD;    // pi
    41 const _Complex PI_2 = 1.57079632679489661923_D+0.0_iD;  // pi / 2
    42 const _Complex PI_4 = 0.78539816339744830962_D+0.0_iD;  // pi / 4
    43 const _Complex _1_PI = 0.31830988618379067154_D+0.0_iD; // 1 / pi
    44 const _Complex _2_PI = 0.63661977236758134308_D+0.0_iD; // 2 / pi
    45 const _Complex _2_SQRT_PI = 1.12837916709551257390_D+0.0_iD; // 2 / sqrt(pi)
     55extern const _Complex PI;                                                               // pi
     56extern const _Complex PI_2;                                                             // pi / 2
     57extern const _Complex PI_4;                                                             // pi / 4
     58extern const _Complex _1_PI;                                                    // 1 / pi
     59extern const _Complex _2_PI;                                                    // 2 / pi
     60extern const _Complex _2_SQRT_PI;                                               // 2 / sqrt(pi)
    4661
    47 const long _Complex PI = 3.1415926535897932384626433832795029_L+0.0iL; // pi
    48 const long _Complex PI_2 = 1.5707963267948966192313216916397514_L+0.0iL; // pi / 2
    49 const long _Complex PI_4 = 0.7853981633974483096156608458198757_L+0.0iL; // pi / 4
    50 const long _Complex _1_PI = 0.3183098861837906715377675267450287_L+0.0iL; // 1 / pi
    51 const long _Complex _2_PI = 0.6366197723675813430755350534900574_L+0.0iL; // 2 / pi
    52 const long _Complex _2_SQRT_PI = 1.1283791670955125738961589031215452_L+0.0iL; // 2 / sqrt(pi)
     62extern const long _Complex PI;                                                  // pi
     63extern const long _Complex PI_2;                                                // pi / 2
     64extern const long _Complex PI_4;                                                // pi / 4
     65extern const long _Complex _1_PI;                                               // 1 / pi
     66extern const long _Complex _2_PI;                                               // 2 / pi
     67extern const long _Complex _2_SQRT_PI;                                  // 2 / sqrt(pi)
    5368
    54 const float E = 2.718281;                               // e
    55 const float LOG2_E = 1.442695;                          // log_2(e)
    56 const float LOG10_E = 0.4342944;                        // log_10(e)
    57 const float LN_2 = 0.6931471;                           // log_e(2)
    58 const float LN_10 = 2.302585;                           // log_e(10)
    59 const float SQRT_2 = 1.414213;                          // sqrt(2)
    60 const float _1_SQRT_2 = 0.7071067;                      // 1 / sqrt(2)
     69extern const float E;                                                                   // e
     70extern const float LOG2_E;                                                              // log_2(e)
     71extern const float LOG10_E;                                                             // log_10(e)
     72extern const float LN_2;                                                                // log_e(2)
     73extern const float LN_10;                                                               // log_e(10)
     74extern const float SQRT_2;                                                              // sqrt(2)
     75extern const float _1_SQRT_2;                                                   // 1 / sqrt(2)
    6176
    62 const double E = 2.7182818284590452354_D;               // e
    63 const double LOG2_E = 1.4426950408889634074_D;          // log_2(e)
    64 const double LOG10_E = 0.43429448190325182765_D;        // log_10(e)
    65 const double LN_2 = 0.69314718055994530942_D;           // log_e(2)
    66 const double LN_10 = 2.30258509299404568402_D;          // log_e(10)
    67 const double SQRT_2 = 1.41421356237309504880_D;         // sqrt(2)
    68 const double _1_SQRT_2 = 0.70710678118654752440_D;      // 1 / sqrt(2)
     77extern const double E;                                                                  // e
     78extern const double LOG2_E;                                                             // log_2(e)
     79extern const double LOG10_E;                                                    // log_10(e)
     80extern const double LN_2;                                                               // log_e(2)
     81extern const double LN_10;                                                              // log_e(10)
     82extern const double SQRT_2;                                                             // sqrt(2)
     83extern const double _1_SQRT_2;                                                  // 1 / sqrt(2)
    6984
    70 const long double E = 2.7182818284590452353602874713526625_DL; // e
    71 const long double LOG2_E = 1.4426950408889634073599246810018921_DL; // log_2(e)
    72 const long double LOG10_E = 0.4342944819032518276511289189166051_DL; // log_10(e)
    73 const long double LN_2 = 0.6931471805599453094172321214581766_DL; // log_e(2)
    74 const long double LN_10 = 2.3025850929940456840179914546843642_DL; // log_e(10)
    75 const long double SQRT_2 = 1.4142135623730950488016887242096981_DL; // sqrt(2)
    76 const long double _1_SQRT_2 = 0.7071067811865475244008443621048490_DL; // 1/sqrt(2)
     85extern const long double E;                                                             // e
     86extern const long double LOG2_E;                                                // log_2(e)
     87extern const long double LOG10_E;                                               // log_10(e)
     88extern const long double LN_2;                                                  // log_e(2)
     89extern const long double LN_10;                                                 // log_e(10)
     90extern const long double SQRT_2;                                                // sqrt(2)
     91extern const long double _1_SQRT_2;                                             // 1/sqrt(2)
    7792
    78 const _Complex E = 2.7182818284590452354_D+0.0_iD;      // e
    79 const _Complex LOG2_E = 1.4426950408889634074_D+0.0_iD; // log_2(e)
    80 const _Complex LOG10_E = 0.43429448190325182765_D+0.0_iD; // log_10(e)
    81 const _Complex LN_2 = 0.69314718055994530942_D+0.0_iD;  // log_e(2)
    82 const _Complex LN_10 = 2.30258509299404568402_D+0.0_iD; // log_e(10)
    83 const _Complex SQRT_2 = 1.41421356237309504880_D+0.0_iD;        // sqrt(2)
    84 const _Complex _1_SQRT_2 = 0.70710678118654752440_D+0.0_iD; // 1 / sqrt(2)
     93extern const _Complex E;                                                                // e
     94extern const _Complex LOG2_E;                                                   // log_2(e)
     95extern const _Complex LOG10_E;                                                  // log_10(e)
     96extern const _Complex LN_2;                                                             // log_e(2)
     97extern const _Complex LN_10;                                                    // log_e(10)
     98extern const _Complex SQRT_2;                                                   // sqrt(2)
     99extern const _Complex _1_SQRT_2;                                                // 1 / sqrt(2)
    85100
    86 const long _Complex E = 2.7182818284590452353602874713526625_L+0.0_iL; // e
    87 const long _Complex LOG2_E = 1.4426950408889634073599246810018921_L+0.0_iL; // log_2(e)
    88 const long _Complex LOG10_E = 0.4342944819032518276511289189166051_L+0.0_iL; // log_10(e)
    89 const long _Complex LN_2 = 0.6931471805599453094172321214581766_L+0.0_iL; // log_e(2)
    90 const long _Complex LN_10 = 2.3025850929940456840179914546843642_L+0.0_iL; // log_e(10)
    91 const long _Complex SQRT_2 = 1.4142135623730950488016887242096981_L+0.0_iL; // sqrt(2)
    92 const long _Complex _1_SQRT_2 = 0.7071067811865475244008443621048490_L+0.0_iL; // 1 / sqrt(2)
     101extern const long _Complex E;                                                   // e
     102extern const long _Complex LOG2_E;                                              // log_2(e)
     103extern const long _Complex LOG10_E;                                             // log_10(e)
     104extern const long _Complex LN_2;                                                // log_e(2)
     105extern const long _Complex LN_10;                                               // log_e(10)
     106extern const long _Complex SQRT_2;                                              // sqrt(2)
     107extern const long _Complex _1_SQRT_2;                                   // 1 / sqrt(2)
     108
     109// Local Variables: //
     110// mode: c //
     111// tab-width: 4 //
     112// End: //
  • src/libcfa/stdlib

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

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