Changeset 37218fc
- Timestamp:
- Apr 11, 2016, 11:51:07 AM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
- Children:
- 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. - Files:
-
- 9 added
- 3 deleted
- 38 edited
- 2 moved
Legend:
- Unmodified
- Added
- Removed
-
doc/refrat/Makefile
r3aba311 r37218fc 1 1 ## Define the appropriate configuration variables. 2 2 3 Macros = 4 TeXLIB = .:${Macros}: 3 TeXLIB = .:../bibliography/:../LaTeXmacros/: 5 4 LaTeX = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex 6 BibTeX = B STINPUTS=${TeXLIB} && export BSTINPUTS && bibtex5 BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex 7 6 8 7 ## Define the text source files. … … 44 43 dvips $< -o $@ 45 44 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 47 47 # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run. 48 48 if [ ! -r ${basename $@}.ind ] ; then touch ${basename $@}.ind ; fi … … 54 54 -${BibTeX} ${basename $@} 55 55 # Make index from *.aux entries and input index at end of document 56 makeindex -s indexstyle ${basename $@}.idx56 makeindex -s ../LaTeXmacros/indexstyle ${basename $@}.idx 57 57 ${LaTeX} ${basename $@}.tex 58 58 # 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 1 17 % requires tex packages: texlive-base texlive-latex-base tex-common texlive-humanities texlive-latex-extra texlive-fonts-recommended 2 18 … … 5 21 6 22 % Latex packages used in the document. 7 8 23 \usepackage{fullpage,times} 9 24 \usepackage{xspace} … … 21 36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 37 23 % Names used in the document.24 25 \newcommand{\CFA}{C$\forall$\xspace} % set language symbolic name26 \newcommand{\CFL}{Cforall\xspace} % set language text name27 \newcommand{\CC}{C\kern-.1em\hbox{+\kern-.25em+}\xspace} % CC symbolic name28 \def\c11{ISO/IEC C} % C11 name (cannot have numbers in latex command name)29 30 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%31 32 38 % 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} 182 40 183 41 \setcounter{secnumdepth}{3} % number subsubsections … … 226 84 227 85 This 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++}.86 It makes frequent reference to the {\c11} standard \cite{C11}, and occasionally compares \CFA to {\CC} \cite{C++}. 229 87 230 88 The manual deliberately imitates the ordering of the {\c11} standard (although the section numbering differs). … … 720 578 721 579 There 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++}. 723 581 First, the result type of a function plays a role. 724 582 In {\CC}, a function call must be completely resolved based on the arguments to the call in most circumstances. … … 3384 3242 \begin{itemize} 3385 3243 \item 3386 Inside a Clu cluster \cite{ clu}, the declaration of an instance states which view applies.3244 Inside a Clu cluster \cite{CLU}, the declaration of an instance states which view applies. 3387 3245 Two primitives called \lstinline$up$ and \lstinline$down$ can be used to convert between the views. 3388 3246 \item 3389 The Simula class \cite{S imula87} is essentially a record type.3247 The Simula class \cite{SIMULA87} is essentially a record type. 3390 3248 Since 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. 3391 3249 In {\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. 3393 3251 A ``scope resolution'' operator can be used inside the class to specify whether the abstract or implementation version of the operation should be used. 3394 3252 \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.3253 An Ada derived type definition \cite{Ada} creates a new type from an old type, and also implicitly declares derived subprograms that correspond to the existing subprograms that use the old type as a parameter type or result type. 3396 3254 The derived subprograms are clones of the existing subprograms with the old type replaced by the derived type. 3397 3255 Literals and aggregates of the old type are also cloned. … … 3843 3701 ``\lstinline$Safe_pointer$ acts like a pointer to \lstinline$int$''. 3844 3702 \begin{lstlisting} 3845 trait ptr_to( type P | pointer( P ), otype T ) {@\impl{ptr_to}@@\use{pointer}@3703 trait ptr_to( otype P | pointer( P ), otype T ) {@\impl{ptr_to}@@\use{pointer}@ 3846 3704 lvalue T *?( P ); 3847 3705 lvalue T ?[?]( P, long int ); 3848 3706 }; 3849 trait ptr_to_const( type P | pointer( P ), otype T ) {@\impl{ptr_to_const}@3707 trait ptr_to_const( otype P | pointer( P ), otype T ) {@\impl{ptr_to_const}@ 3850 3708 const lvalue T *?( P ); 3851 3709 const lvalue T ?[?]( P, long int );@\use{pointer}@ 3852 3710 }; 3853 trait ptr_to_volatile( type P | pointer( P ), otype T ) }@\impl{ptr_to_volatile}@3711 trait ptr_to_volatile( otype P | pointer( P ), otype T ) }@\impl{ptr_to_volatile}@ 3854 3712 volatile lvalue T *?( P ); 3855 3713 volatile lvalue T ?[?]( P, long int );@\use{pointer}@ 3856 3714 }; 3857 trait ptr_to_const_volatile( type P | pointer( P ), otype T ) }@\impl{ptr_to_const_volatile}@3715 trait ptr_to_const_volatile( otype P | pointer( P ), otype T ) }@\impl{ptr_to_const_volatile}@ 3858 3716 const volatile lvalue T *?( P );@\use{pointer}@ 3859 3717 const volatile lvalue T ?[?]( P, long int ); … … 3865 3723 ``\lstinline$ptr_to$'' specifications. 3866 3724 \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}@ {3725 trait m_l_ptr_to( otype P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to}@ otype T | ptr_to( P, T )@\use{ptr_to}@ { 3868 3726 P ?=?( P *, T * ); 3869 3727 T * ?=?( T **, P ); 3870 3728 }; 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}@) {3729 trait m_l_ptr_to_const( otype P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to_const}@ otype T | ptr_to_const( P, T )@\use{ptr_to_const}@) { 3872 3730 P ?=?( P *, const T * ); 3873 3731 const T * ?=?( const T **, P ); 3874 3732 }; 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}@3733 trait m_l_ptr_to_volatile( otype P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to_volatile}@ otype T | ptr_to_volatile( P, T )) {@\use{ptr_to_volatile}@ 3876 3734 P ?=?( P *, volatile T * ); 3877 3735 volatile T * ?=?( volatile T **, P ); 3878 3736 }; 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}@3737 trait m_l_ptr_to_const_volatile( otype P | ptr_to_const_volatile( P ),@\use{ptr_to_const_volatile}@@\impl{m_l_ptr_to_const_volatile}@ 3738 otype T | m_l_ptr_to_volatile( P, T ) | m_l_ptr_to_const( P )) {@\use{m_l_ptr_to_const}@@\use{m_l_ptr_to_volatile}@ 3881 3739 P ?=?( P *, const volatile T * ); 3882 3740 const volatile T * ?=?( const volatile T **, P ); … … 4006 3864 4007 3865 \bibliographystyle{plain} 4008 \bibliography{ refrat}3866 \bibliography{cfa} 4009 3867 4010 3868 -
doc/user/Makefile
r3aba311 r37218fc 1 1 ## Define the appropriate configuration variables. 2 2 3 TeXLIB = .: :3 TeXLIB = .:../bibliography/:../LaTeXmacros/: 4 4 LaTeX = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex 5 BibTeX = B STINPUTS=${TeXLIB} && export BSTINPUTS && bibtex5 BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex 6 6 7 7 ## Define the text source files. … … 43 43 dvips $< -o $@ 44 44 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 46 47 # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run. 47 48 if [ ! -r ${basename $@}.ind ] ; then touch ${basename $@}.ind ; fi … … 53 54 -${BibTeX} ${basename $@} 54 55 # Make index from *.aux entries and input index at end of document 55 makeindex -s indexstyle ${basename $@}.idx56 makeindex -s ../LaTeXmacros/indexstyle ${basename $@}.idx 56 57 ${LaTeX} ${basename $@}.tex 57 58 # 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 1 17 % requires tex packages: texlive-base texlive-latex-base tex-common texlive-humanities texlive-latex-extra texlive-fonts-recommended 2 18 … … 5 21 6 22 % Latex packages used in the document. 7 23 \usepackage[T1]{fontenc} 24 \usepackage{textcomp} 25 \usepackage[latin1]{inputenc} 26 \usepackage{upquote} 8 27 \usepackage{fullpage,times} 9 28 \usepackage{xspace} … … 24 43 % Names used in the document. 25 44 26 \newcommand{\CFA}{C$\forall$\xspace} % set language symbolic name27 \newcommand{\CFL}{Cforall\xspace} % set language text name28 \newcommand{\CC}{C\kern-.1em\hbox{+\kern-.25em+}\xspace} % CC symbolic name29 \def\c11{ISO/IEC C} % C11 name (cannot have numbers in latex command name)30 45 \newcommand{\CS}{C\raisebox{-0.9ex}{\large$^\sharp$}\xspace} 31 46 … … 33 48 34 49 % 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} 192 51 193 52 \setcounter{secnumdepth}{3} % number subsubsections … … 366 225 367 226 The command \lstinline@cfa@ is used to compile \CFA program(s). 368 This command works like the GNU \lstinline@gcc@ command, e.g.:227 This command works like the GNU \lstinline@gcc@\index{gcc} command, e.g.: 369 228 \begin{lstlisting} 370 229 cfa [ gcc-options ] C/@{\CFA}@-files [ assembler/loader-files ] 371 230 \end{lstlisting} 372 The following additional option is available: 231 By default, \CFA programs having the following \lstinline@gcc@ flags turned on: 232 \begin{description} 233 \item 234 \hspace*{-4pt}\lstinline@-std=gnu99@ 235 The 1999 C standard plus GNU extensions. 236 \end{description} 237 The following new \CFA option is available: 373 238 \begin{description} 374 239 \item … … 382 247 Numeric constants are extended to allow \Index{underscore}s within constants\index{constant!underscore}, e.g.: 383 248 \begin{lstlisting} 384 2 _147_483_648; // decimal constant249 2`_`147`_`483`_`648; // decimal constant 385 250 56_ul; // decimal unsigned long constant 386 251 0_377; // octal constant … … 451 316 \multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 452 317 \begin{lstlisting} 453 * int x, y; 318 `* int x, y;` 454 319 \end{lstlisting} 455 320 & … … 571 436 The point of the new syntax is to allow returning multiple values from a routine~\cite{CLU,Galletly96}, e.g.: 572 437 \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 ) { 574 439 @\emph{routine body}@ 575 440 } … … 639 504 Because 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: 640 505 \begin{lstlisting} 641 [ int x ]f() {506 `[ int x ]` f() { 642 507 ... x = 0; ... x = y; ... 643 return;// implicitly return x508 `return;` // implicitly return x 644 509 } 645 510 \end{lstlisting} … … 697 562 for example, the following is incorrect: 698 563 \begin{lstlisting} 699 * [ int x ] f () fp; // routine name ``f''is not allowed564 * [ int x ] f () fp; // routine name "f" is not allowed 700 565 \end{lstlisting} 701 566 … … 864 729 \subsection{Type Nesting} 865 730 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. 867 732 \begin{quote2} 868 733 \begin{tabular}{@{}l@{\hspace{30pt}}l|l@{}} … … 919 784 920 785 int 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; 925 790 } 926 791 \end{lstlisting} 927 792 \end{tabular} 928 793 \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. 794 In the left example in C, types \lstinline@C@, \lstinline@U@ and \lstinline@T@ are implicitly hoisted outside of type \lstinline@S@ into the containing block scope. 795 In the right example in \CFA, the types are not hoisted and accessed using the field-selection operator ``\lstinline@.@'' for type qualification, as does Java, rather than the \CC type-selection operator ``\lstinline@::@''. 933 796 934 797 … … 944 807 \begin{lstlisting} 945 808 const 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} 809 int ia[size]; 810 ... // assign values to array ia 811 qsort( ia, size ); // sort ascending order using builtin ?<? 812 { 813 `int ?<?( int x, int y ) { return x > y; }` // nested routine 814 qsort( ia, size ); // sort descending order by local redefinition 815 } 816 \end{lstlisting} 817 818 Nested routines are not first-class, meaning a nested routine cannot be returned if it has references to variables in its enclosing blocks; 819 the only exception is references to the external block of the translation unit, as these variables persist for the duration of the program. 820 The following program in undefined in \CFA (and \lstinline@gcc@\index{gcc}) 821 \begin{lstlisting} 822 [* [int]( int )] foo() { // int (*foo())( int ) 823 int `i` = 7; 824 int bar( int p ) { 825 `i` += 1; // dependent on local variable 826 sout | `i` | endl; 827 } 828 return bar; // undefined because of local dependence 829 } 830 int main() { 831 * [int](int) fp = foo(); // int (*fp)(int) 832 sout | fp( 3 ) | endl; 833 } 834 \end{lstlisting} 835 because 836 837 Currently, there are no \Index{lambda} expressions, i.e., unnamed routines because routine names are very important to properly select the correct routine. 954 838 955 839 … … 1013 897 1014 898 \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. 899 Change: A struct is a scope in C++, not in C \\ 900 Rationale: Class scope is crucial to C++, and a struct is a class. \\ 901 Effect on original feature: Change to semantics of well-defined feature. \\ 902 Difficulty of converting: Semantic transformation. \\ 903 How widely used: C programs use struct extremely frequently, but the change is only noticeable when struct, enumeration, or enumerator names are referred to outside the struct. 904 The latter is probably rare. 905 906 \CFA is C \emph{incompatible} on this issue, and provides semantics similar to \CC. 907 Nested types are not hoisted and can be referenced using the field selection operator ``\lstinline@.@'', unlike the \CC scope-resolution operator ``\lstinline@::@''. 908 Given that nested types in C are equivalent to not using them, i.e., they are essentially useless, it is unlikely there are any realistic usages that break because of this incompatibility. 909 1022 910 1023 911 \item … … 1185 1073 First the right-hand tuple is flattened and then the values are assigned individually. 1186 1074 Flattening 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 ]@.1075 For example, the type \lstinline@[ int, [ int, int ], int ]@ can be coerced, using flattening, into the type \lstinline@[ int, int, int, int ]@. 1188 1076 1189 1077 A \newterm{structuring coercion} is the opposite of flattening; … … 1352 1240 \multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 1353 1241 \begin{lstlisting} 1354 L1:for ( ... ) {1355 L2:for ( ... ) {1356 L3:for ( ... ) {1357 ... break L1; ...1358 ... break L2; ...1359 ... break L3; // or break1242 `L1:` for ( ... ) { 1243 `L2:` for ( ... ) { 1244 `L3:` for ( ... ) { 1245 ... break `L1`; ... 1246 ... break `L2`; ... 1247 ... break `L3`; // or break 1360 1248 } 1361 1249 } … … 1382 1270 \multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 1383 1271 \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`; ... 1390 1278 1391 1279 } … … 1623 1511 \begin{lstlisting} 1624 1512 switch ( i ) { 1625 case 1, 3, 5:1513 `case 1, 3, 5`: 1626 1514 ... 1627 case 2, 4, 6:1515 `case 2, 4, 6`: 1628 1516 ... 1629 1517 } … … 1634 1522 case 1: case 3 : case 5: 1635 1523 ... 1636 case 2: case 4 : case 6: /* even values */1524 case 2: case 4 : case 6: 1637 1525 ... 1638 1526 } … … 1655 1543 \begin{lstlisting} 1656 1544 switch ( i ) { 1657 case 1~51545 `case 1~5:` 1658 1546 ... 1659 case 10~151547 `case 10~15:` 1660 1548 ... 1661 1549 } … … 1672 1560 & 1673 1561 \begin{lstlisting} 1562 1674 1563 // 1, 2, 3, 4, 5 1675 1564 … … 2168 2057 2169 2058 2170 \section{Generics } 2059 \section{Auto Type-Inferencing} 2060 2061 Auto type-inferencing occurs in a declaration where a variable's type is inferred from its initialization expression type. 2062 \begin{quote2} 2063 \begin{tabular}{@{}l@{\hspace{30pt}}ll@{}} 2064 \multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CC}} & \multicolumn{1}{c}{\lstinline@gcc@}\index{gcc} \\ 2065 \begin{lstlisting} 2066 2067 auto j = 3.0 * 4; 2068 int i; 2069 auto k = i; 2070 \end{lstlisting} 2071 & 2072 \begin{lstlisting} 2073 #define expr 3.0 * i 2074 typeof(expr) j = expr; 2075 int i; 2076 typeof(i) k = i; 2077 \end{lstlisting} 2078 & 2079 \begin{lstlisting} 2080 2081 // use type of initialization expression 2082 2083 // use type of primary variable 2084 \end{lstlisting} 2085 \end{tabular} 2086 \end{quote2} 2087 The two important capabilities are: 2088 \begin{itemize} 2089 \item 2090 preventing having to determine or write out long generic types, 2091 \item 2092 ensure secondary variables, related to a primary variable, always have the same type. 2093 \end{itemize} 2094 2095 In \CFA, \lstinline@typedef@ provides a mechanism to alias long type names with short ones, both globally and locally, but not eliminate the use of the short name. 2096 \lstinline@gcc@ provides \lstinline@typeof@ to declare a secondary variable from a primary variable. 2097 \CFA also relies heavily on the specification of the left-hand side of assignment for type inferencing, so in many cases it is crucial to specify the type of the left-hand side to select the correct type of the right-hand expression. 2098 Only for overloaded routines with the same return type is variable type-inferencing possible. 2099 Finally, \lstinline@auto@ presents the programming problem of tracking down a type when the type is actually needed. 2100 For example, given 2101 \begin{lstlisting} 2102 auto j = `...` 2103 \end{lstlisting} 2104 and the need to write a routine to compute using \lstinline@j@ 2105 \begin{lstlisting} 2106 void rtn( `...` parm ); 2107 rtn( j ); 2108 \end{lstlisting} 2109 A programmer must work backwards to determine the type of \lstinline@j@'s initialization expression, reconstructing the possibly long generic type-name. 2110 In this situation, having the type name or a short alias is very useful. 2111 2112 There is also the conundrum in type inferencing of when to \emph{\Index{brand}} a type. 2113 That is, when is the type of the variable more important than the type of its initialization expression. 2114 For example, if a change is made in an initialization expression, it can cause hundreds or thousands of cascading type changes and/or errors. 2115 At some point, a programmer wants the type of the variable to remain constant and the expression to be in error when it changes. 2116 2117 Given \lstinline@typedef@ and \lstinline@typeof@ in \CFA, and the strong need to use the type of left-hand side in inferencing, auto type-inferencing is not supported at this time. 2118 Should a significant need arise, this feature can be revisited. 2119 2120 2121 \section{Generics} 2171 2122 2172 2123 \CFA supports parametric polymorphism to allow users to define generic functions and types. … … 2457 2408 2458 2409 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 2412 The number 0 and 1 are treated specially in \CFA, and can be redefined as variables. 2413 One syntactic anomaly is when a field in an structure is names 0 or 1: 2414 \begin{lstlisting} 2415 struct S { 2416 int 0, 1; 2417 } s; 2418 \end{lstlisting} 2419 The problem occurs in accesing these fields using the selection operation ``\lstinline@.@'': 2420 \begin{lstlisting} 2421 s.0 = 0; // ambiguity with floating constant .0 2422 s.1 = 1; // ambiguity with floating constant .1 2423 \end{lstlisting} 2424 To make this work, a space is required after the field selection: 2425 \begin{lstlisting} 2426 `s.@\textvisiblespace@0` = 0; 2427 `s.@\textvisiblespace@1` = 1; 2428 \end{lstlisting} 2429 While this sytact is awkward, it is unlikely many programers will name fields of a structure 0 or 1. 2430 Like the \CC lexical problem with closing template-syntax, e.g, \lstinline@Foo<Bar<int`>>`@, this issue can be solved with a more powerful lexer/parser. 2431 2432 There are several ambiguous cases with operator identifiers, e.g., \lstinline@int *?*?()@, where the string \lstinline@*?*?@ can be lexed as \lstinline@*@/\lstinline@?*?@ or \lstinline@*?@/\lstinline@*?@. 2433 Since it is common practise to put a unary operator juxtaposed to an identifier, e.g., \lstinline@*i@, users will be annoyed if they cannot do this with respect to operator identifiers. 2434 Even with this special hack, there are 5 general cases that cannot be handled. 2435 The first case is for the function-call identifier \lstinline@?()@: 2436 \begin{lstlisting} 2437 int *@\textvisiblespace@?()(); // declaration: space required after '*' 2438 *@\textvisiblespace@?()(); // expression: space required after '*' 2439 \end{lstlisting} 2440 Without the space, the string \lstinline@*?()@ is ambiguous without N character look ahead; 2441 it requires scanning ahead to determine if there is a \lstinline@'('@, which is the start of an argument/parameter list. 2442 2443 The 4 remaining cases occur in expressions: 2444 \begin{lstlisting} 2445 i++@\textvisiblespace@?i:0; // space required before '?' 2446 i--@\textvisiblespace@?i:0; // space required before '?' 2447 i@\textvisiblespace@?++i:0; // space required after '?' 2448 i@\textvisiblespace@?--i:0; // space required after '?' 2449 \end{lstlisting} 2450 In the first two cases, the string \lstinline@i++?@ is ambiguous, where this string can be lexed as \lstinline@i@ / \lstinline@++?@ or \lstinline@i++@ / \lstinline@?@; 2451 it requires scanning ahead to determine if there is a \lstinline@'('@, which is the start of an argument list. 2452 In the second two cases, the string \lstinline@?++x@ is ambiguous, where this string can be lexed as \lstinline@?++@ / \lstinline@x@ or \lstinline@?@ / y\lstinline@++x@; 2453 it requires scanning ahead to determine if there is a \lstinline@'('@, which is the start of an argument list. 2654 2454 2655 2455 … … 2676 2476 2677 2477 task creates a type with implicit locking, separate stack, and a thread 2478 2678 2479 2679 2480 \subsection{Monitors} … … 3775 3576 \multicolumn{1}{c|}{\textbf{\CFA/\CC}} & \multicolumn{1}{c|}{\textbf{Go}} & \multicolumn{1}{c}{\textbf{Rust}} \\ 3776 3577 \hline 3777 \begin{lstlisting} 3578 \begin{lstlisting}[boxpos=t] 3778 3579 extern "C" { 3779 3580 #include <sys/types.h> … … 3782 3583 } 3783 3584 size_t fileSize( const char *path ) { 3784 st at s;3585 struct stat s; 3785 3586 stat(path, &s); 3786 3587 return s.st_size; … … 3788 3589 \end{lstlisting} 3789 3590 & 3790 \begin{lstlisting} 3591 \begin{lstlisting}[boxpos=t] 3791 3592 /* 3792 3593 #cgo … … 3807 3608 \end{lstlisting} 3808 3609 & 3809 \begin{lstlisting} 3610 \begin{lstlisting}[boxpos=t] 3810 3611 use libc::{c_int, size_t}; 3811 3812 // The following declarations are3813 3612 // translated from sys/stat.h 3814 3613 #[repr(C)] … … 3818 3617 ... 3819 3618 } 3820 3821 3619 #[link(name = "libc")] 3822 3620 extern { … … 3824 3622 buf: *mut stat_t) -> c_int; 3825 3623 } 3826 3827 3624 fn fileSize(path: *const u8) -> size_t 3828 3625 { 3829 3626 unsafe { 3830 let mut buf: stat_t = uninit();3831 stat(path, &mut buf);3832 buf.st_size3627 let mut buf: stat_t = uninit(); 3628 stat(path, &mut buf); 3629 buf.st_size 3833 3630 } 3834 3631 } … … 3953 3750 3954 3751 3752 \begin{comment} 3955 3753 \subsubsection{Modules/Packages} 3956 3754 … … 4032 3830 } 4033 3831 \end{lstlisting} 3832 \end{comment} 3833 4034 3834 4035 3835 \subsubsection{Parallel Tasks} … … 4187 3987 \end{flushleft} 4188 3988 3989 \lstset{basicstyle=\sf\relsize{-1}} 3990 3991 4189 3992 \subsection{Summary of Language Comparison} 4190 3993 … … 4255 4058 4256 4059 4060 \appendix 4061 4062 4063 \section{I/O Library} 4064 \label{s:IOLibrary} 4065 \index{input/output library} 4066 4067 The goal for \CFA I/O is to make I/O as simple as possible for the general case, while fully supporting polmorphism and user defined types in a consistent way. 4068 The general case is printing out a sequence of variables separated by whitespace. 4069 \begin{quote2} 4070 \begin{tabular}{@{}l@{\hspace{30pt}}l@{}} 4071 \multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{\CC}} \\ 4072 \begin{lstlisting} 4073 int x = 0, y = 1, z = 2; 4074 `sout` `|` x `|` y `|` z `| endl`; 4075 \end{lstlisting} 4076 & 4077 \begin{lstlisting} 4078 4079 cout << x << " " << y << " " << z << endl; 4080 \end{lstlisting} 4081 \end{tabular} 4082 \end{quote2} 4083 The \CFA form is half as many characters, and is similar to Python I/O with respect to implicit separators. 4084 4085 The logical-or operator is used because it is the lowest-priority overloadable operator, other than assignment. 4086 Therefore, fewer output expressions require parenthesis. 4087 \begin{quote2} 4088 \begin{tabular}{@{}ll@{}} 4089 \textbf{\CFA:} 4090 & 4091 \begin{lstlisting} 4092 sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl; 4093 \end{lstlisting} 4094 \\ 4095 \textbf{\CC:} 4096 & 4097 \begin{lstlisting} 4098 cout << x * 3 << y + 1 << (z << 2) << (x == y) << (x | y) << (x || y) << (x > z ? 1 : 2) << endl; 4099 \end{lstlisting} 4100 \end{tabular} 4101 \end{quote2} 4102 Finally, the logical-or operator has a link with the Shell pipe-operator for moving data, although data flows in the opposite direction. 4103 4104 The implicit seperator\index{I/O separator} character (space/blank) is a separator not a terminator. 4105 The rules for implicitly adding the separator are: 4106 \begin{enumerate} 4107 \item 4108 A seperator does not appear at the start or end of a line. 4109 \begin{lstlisting}[belowskip=0pt] 4110 sout 1 | 2 | 3 | endl; 4111 \end{lstlisting} 4112 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 4113 1 2 3 4114 \end{lstlisting} 4115 \item 4116 A seperator does not appear before or after a character literal or variable. 4117 \begin{lstlisting} 4118 sout | '1' | '2' | '3' | endl; 4119 123 4120 \end{lstlisting} 4121 \item 4122 A seperator does not appear before or after a null (empty) C string 4123 \begin{lstlisting} 4124 sout | 1 | "" | 2 | "" | 3 | endl; 4125 123 4126 \end{lstlisting} 4127 which is a local mechanism to disable insertion of the separator character. 4128 \item 4129 A seperator does not appear before a C string starting with the \Index{extended ASCII}\index{ASCII} characters: \lstinline[mathescape=off]@([{$£¥¿«@ 4130 %$ 4131 \begin{lstlisting}[mathescape=off] 4132 sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x $" | 4 | "x £" | 5 | "x ¥" | 6 | "x ¿" | 7 | "x «" | 8 | endl; 4133 \end{lstlisting} 4134 %$ 4135 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 4136 x (1 x [2 x {3 x $4 x £5 x ¥6 x ¿7 x «8 4137 \end{lstlisting} 4138 %$ 4139 \item 4140 A seperator does not appear after a C string ending with the extended ASCII characters: \lstinline@,.:;!?)]}%¢»@ 4141 \begin{lstlisting}[belowskip=0pt] 4142 sout | 1 | ", x" | 2 | ". x" | 3 | ": x" | 4 | "; x" | 5 | "! x" | 6 | "? x" | 7 | ") x" | 8 | "] x" | 9 | "} x" 4143 | 10 | "% x" | 11 | L"¢ x" | 12 | L"» x" | endl; 4144 \end{lstlisting} 4145 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 4146 1, x 2. x 3: x 4; x 5! x 6? x 7) x 8] x 9} x 10% x 11¢ 12» 4147 \end{lstlisting} 4148 \item 4149 A seperator does not appear before or after a C string begining/ending with the characters: \lstinline@\f\n\r\t\v\`'"@ 4150 \begin{lstlisting}[belowskip=0pt] 4151 sout | "x '" | 1 | "' x \`" | 2 | "\` x \"" | 3 | "\" x" | endl; 4152 \end{lstlisting} 4153 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 4154 x '1' x \`2\` x "3" x 4155 \end{lstlisting} 4156 \begin{lstlisting}[showtabs=true,aboveskip=0pt] 4157 sout | "x\t" | 1 | "\tx" | endl; 4158 x 1 x 4159 \end{lstlisting} 4160 \end{enumerate} 4161 The following \CC-style \Index{manipulator}s allow further control over implicit seperation. 4162 \begin{lstlisting}[mathescape=off,belowskip=0pt] 4163 sout | sepOn | 1 | 2 | 3 | sepOn | endl; // separator at start of line 4164 \end{lstlisting} 4165 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 4166 1 2 3 4167 \end{lstlisting} 4168 \begin{lstlisting}[mathescape=off,aboveskip=0pt,belowskip=0pt] 4169 sout | 1 | sepOff | 2 | 3 | endl; // turn off implicit separator temporarily 4170 \end{lstlisting} 4171 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 4172 12 3 4173 \end{lstlisting} 4174 \begin{lstlisting}[mathescape=off,aboveskip=0pt,belowskip=0pt] 4175 sout | sepDisable | 1 | 2 | 3 | endl; // turn off implicit separation, affects all subsequent prints 4176 \end{lstlisting} 4177 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 4178 123 4179 \end{lstlisting} 4180 \begin{lstlisting}[mathescape=off,aboveskip=0pt,belowskip=0pt] 4181 sout | 1 | sepOn | 2 | 3 | endl; // turn on implicit separator temporarily 4182 \end{lstlisting} 4183 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 4184 1 23 4185 \end{lstlisting} 4186 \begin{lstlisting}[mathescape=off,aboveskip=0pt,belowskip=0pt] 4187 sout | sepEnable | 1 | 2 | 3 | endl; // turn on implicit separation, affects all subsequent prints 4188 \end{lstlisting} 4189 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 4190 1 2 3 4191 \end{lstlisting} 4192 \begin{lstlisting}[mathescape=off,aboveskip=0pt,aboveskip=0pt,belowskip=0pt] 4193 sepSet( sout, ", $" ); // change separator from " " to ", $" 4194 sout | 1 | 2 | 3 | endl; 4195 \end{lstlisting} 4196 %$ 4197 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt] 4198 1, $2, $3 4199 \end{lstlisting} 4200 %$ 4201 \VRef[Figure]{f:ExampleIO} shows an example of input and output I/O in \CFA. 4202 4203 \begin{figure} 4204 \begin{lstlisting}[mathescape=off] 4205 #include <fstream> 4206 4207 int main() { 4208 char c; // basic types 4209 short int si; 4210 unsigned short int usi; 4211 int i; 4212 unsigned int ui; 4213 long int li; 4214 unsigned long int uli; 4215 long long int lli; 4216 unsigned long long int ulli; 4217 float f; 4218 double d; 4219 long double ld; 4220 float _Complex fc; 4221 double _Complex dc; 4222 long double _Complex ldc; 4223 char s1[10], s2[10]; 4224 4225 ifstream in; // create / open file 4226 open( &in, "input.data", "r" ); 4227 4228 &in | &c // character 4229 | &si | &usi | &i | &ui | &li | &uli | &lli | &ulli // integral 4230 | &f | &d | &ld // floating point 4231 | &fc | &dc | &ldc // floating-point complex 4232 | cstr( s1 ) | cstr( s2, 10 ); // C string, length unchecked and checked 4233 4234 sout | c | ' ' | endl // character 4235 | si | usi | i | ui | li | uli | lli | ulli | endl // integral 4236 | f | d | ld | endl // floating point 4237 | fc | dc | ldc | endl; // complex 4238 sout | endl; 4239 sout | f | "" | d | "" | ld | endl // floating point without separator 4240 | sepDisable | fc | dc | ldc | sepEnable | endl // complex without separator 4241 | sepOn | s1 | sepOff | s2 | endl // local separator removal 4242 | s1 | "" | s2 | endl; // C string withou separator 4243 sout | endl; 4244 sepSet( sout, ", $" ); // change separator, maximum of 15 characters 4245 sout | f | d | ld | endl // floating point without separator 4246 | fc | dc | ldc | endl // complex without separator 4247 | s1 | s2 | endl; 4248 } 4249 4250 $ cat input.data 4251 A 1 2 3 4 5 6 7 8 1.1 1.2 1.3 1.1+2.3 1.1-2.3 1.1-2.3 abc xyz 4252 $ a.out 4253 A 4254 1 2 3 4 5 6 7 8 4255 1.1 1.2 1.3 4256 1.1+2.3i 1.1-2.3i 1.1-2.3i 4257 4258 1.11.21.3 4259 1.1+2.3i1.1-2.3i1.1-2.3i 4260 abcxyz 4261 abcxyz 4262 4263 1.1, $1.2, $1.3 4264 1.1+2.3i, $1.1-2.3i, $1.1-2.3i 4265 abc, $xyz 4266 \end{lstlisting} 4267 \caption{Example I/O} 4268 \label{f:ExampleIO} 4269 \end{figure} 4270 4271 4272 \section{Standard Library} 4273 \label{s:StandardLibrary} 4274 4275 The goal of the \CFA standard-library is to wrap many of the existing C library-routines that are explicitly polymorphic into implicitly polymorphic versions. 4276 4277 4278 \subsection{malloc} 4279 4280 \begin{lstlisting} 4281 forall( otype T ) T * malloc( void ); 4282 forall( otype T ) T * malloc( char fill ); 4283 forall( otype T ) T * malloc( T * ptr, size_t size ); 4284 forall( otype T ) T * malloc( T * ptr, size_t size, unsigned char fill ); 4285 forall( otype T ) T * calloc( size_t size ); 4286 forall( otype T ) T * realloc( T * ptr, size_t size ); 4287 forall( otype T ) T * realloc( T * ptr, size_t size, unsigned char fill ); 4288 4289 forall( otype T ) T * aligned_alloc( size_t alignment ); 4290 forall( otype T ) T * memalign( size_t alignment ); // deprecated 4291 forall( otype T ) int posix_memalign( T ** ptr, size_t alignment ); 4292 4293 forall( otype T ) T * memset( T * ptr, unsigned char fill ); // use default value '\0' for fill 4294 forall( otype T ) T * memset( T * ptr ); // remove when default value available 4295 \end{lstlisting} 4296 4297 4298 \subsection{ato/strto} 4299 4300 \begin{lstlisting} 4301 int ato( const char * ptr ); 4302 unsigned int ato( const char * ptr ); 4303 long int ato( const char * ptr ); 4304 unsigned long int ato( const char * ptr ); 4305 long long int ato( const char * ptr ); 4306 unsigned long long int ato( const char * ptr ); 4307 float ato( const char * ptr ); 4308 double ato( const char * ptr ); 4309 long double ato( const char * ptr ); 4310 float _Complex ato( const char * ptr ); 4311 double _Complex ato( const char * ptr ); 4312 long double _Complex ato( const char * ptr ); 4313 4314 int strto( const char * sptr, char ** eptr, int base ); 4315 unsigned int strto( const char * sptr, char ** eptr, int base ); 4316 long int strto( const char * sptr, char ** eptr, int base ); 4317 unsigned long int strto( const char * sptr, char ** eptr, int base ); 4318 long long int strto( const char * sptr, char ** eptr, int base ); 4319 unsigned long long int strto( const char * sptr, char ** eptr, int base ); 4320 float strto( const char * sptr, char ** eptr ); 4321 double strto( const char * sptr, char ** eptr ); 4322 long double strto( const char * sptr, char ** eptr ); 4323 float _Complex strto( const char * sptr, char ** eptr ); 4324 double _Complex strto( const char * sptr, char ** eptr ); 4325 long double _Complex strto( const char * sptr, char ** eptr ); 4326 \end{lstlisting} 4327 4328 4329 \subsection{bsearch/qsort} 4330 4331 \begin{lstlisting} 4332 forall( otype T | { int ?<?( T, T ); } ) 4333 T * bsearch( const T key, const T * arr, size_t dimension ); 4334 4335 forall( otype T | { int ?<?( T, T ); } ) 4336 void qsort( const T * arr, size_t dimension ); 4337 \end{lstlisting} 4338 4339 4340 \subsection{abs} 4341 4342 \begin{lstlisting} 4343 char abs( char ); 4344 extern "C" { 4345 int abs( int ); // use default C routine for int 4346 } // extern "C" 4347 long int abs( long int ); 4348 long long int abs( long long int ); 4349 float abs( float ); 4350 double abs( double ); 4351 long double abs( long double ); 4352 float _Complex abs( float _Complex ); 4353 double _Complex abs( double _Complex ); 4354 long double _Complex abs( long double _Complex ); 4355 \end{lstlisting} 4356 4357 4358 \subsection{floor/ceil} 4359 4360 \begin{lstlisting} 4361 float floor( float ); 4362 extern "C" { 4363 double floor( double ); // use C routine for double 4364 } // extern "C" 4365 long double floor( long double ); 4366 4367 float ceil( float ); 4368 extern "C" { 4369 double ceil( double ); // use C routine for double 4370 } // extern "C" 4371 long double ceil( long double ); 4372 \end{lstlisting} 4373 4374 4375 \subsection{random} 4376 4377 \begin{lstlisting} 4378 void rand48seed( long int s ); 4379 char rand48(); 4380 int rand48(); 4381 unsigned int rand48(); 4382 long int rand48(); 4383 unsigned long int rand48(); 4384 float rand48(); 4385 double rand48(); 4386 float _Complex rand48(); 4387 double _Complex rand48(); 4388 long double _Complex rand48(); 4389 \end{lstlisting} 4390 4391 4392 \subsection{min/max/swap} 4393 4394 \begin{lstlisting} 4395 forall( otype T | { int ?<?( T, T ); } ) 4396 T min( const T t1, const T t2 ); 4397 4398 forall( otype T | { int ?>?( T, T ); } ) 4399 T max( const T t1, const T t2 ); 4400 4401 forall( otype T ) 4402 void swap( T * t1, T * t2 ); 4403 \end{lstlisting} 4404 4405 4406 \section{Rational Numbers} 4407 \label{s:RationalNumbers} 4408 4409 Rational numbers are numbers written as a ratio, i.e., as a fraction, where the numerator (top number) and the denominator (bottom number) are whole numbers. 4410 When creating and computing with rational numbers, results are constantly reduced to keep the numerator and denominator as small as possible. 4411 4412 \begin{lstlisting} 4413 // implementation 4414 struct Rational { 4415 long int numerator, denominator; // invariant: denominator > 0 4416 }; // Rational 4417 4418 // constants 4419 extern struct Rational 0; 4420 extern struct Rational 1; 4421 4422 // constructors 4423 Rational rational(); 4424 Rational rational( long int n ); 4425 Rational rational( long int n, long int d ); 4426 4427 // getter/setter for numerator/denominator 4428 long int numerator( Rational r ); 4429 long int numerator( Rational r, long int n ); 4430 long int denominator( Rational r ); 4431 long int denominator( Rational r, long int d ); 4432 4433 // comparison 4434 int ?==?( Rational l, Rational r ); 4435 int ?!=?( Rational l, Rational r ); 4436 int ?<?( Rational l, Rational r ); 4437 int ?<=?( Rational l, Rational r ); 4438 int ?>?( Rational l, Rational r ); 4439 int ?>=?( Rational l, Rational r ); 4440 4441 // arithmetic 4442 Rational -?( Rational r ); 4443 Rational ?+?( Rational l, Rational r ); 4444 Rational ?-?( Rational l, Rational r ); 4445 Rational ?*?( Rational l, Rational r ); 4446 Rational ?/?( Rational l, Rational r ); 4447 4448 // conversion 4449 double widen( Rational r ); 4450 Rational narrow( double f, long int md ); 4451 4452 // I/O 4453 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, Rational * ); 4454 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, Rational ); 4455 \end{lstlisting} 4456 4457 4257 4458 \bibliographystyle{plain} 4258 \bibliography{ /usr/local/bibliographies/pl.bib}4459 \bibliography{cfa} 4259 4460 4260 4461 -
src/CodeGen/CodeGenerator.cc
r3aba311 r37218fc 455 455 456 456 void CodeGenerator::visit( UntypedOffsetofExpr *offsetofExpr ) { 457 assert( false );457 assert( false && "UntypedOffsetofExpr should not reach code generation" ); 458 458 } 459 459 … … 464 464 output << ", " << mangleName( offsetofExpr->get_member() ); 465 465 output << ")"; 466 } 467 468 void CodeGenerator::visit( OffsetPackExpr *offsetPackExpr ) { 469 assert( false && "OffsetPackExpr should not reach code generation" ); 466 470 } 467 471 -
src/CodeGen/CodeGenerator.h
r3aba311 r37218fc 65 65 virtual void visit( UntypedOffsetofExpr *offsetofExpr ); 66 66 virtual void visit( OffsetofExpr *offsetofExpr ); 67 virtual void visit( OffsetPackExpr *offsetPackExpr ); 67 68 virtual void visit( LogicalExpr *logicalExpr ); 68 69 virtual void visit( ConditionalExpr *conditionalExpr ); -
src/GenPoly/Box.cc
r3aba311 r37218fc 30 30 #include "FindFunction.h" 31 31 #include "ScopedMap.h" 32 #include "ScopedSet.h" 32 33 #include "ScrubTyVars.h" 33 34 … … 62 63 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 63 64 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 ) ) {} 71 73 72 74 /// 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() { 74 76 for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) { 75 77 params.push_back( (*param)->get_type()->clone() ); … … 77 79 } 78 80 79 ConcreteType& operator= (const ConcreteType& that) {81 TypeList& operator= ( const TypeList &that ) { 80 82 deleteAll( params ); 83 81 84 params.clear(); 82 83 base = that.base;84 85 cloneAll( that.params, params ); 85 86 … … 87 88 } 88 89 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; 93 102 94 103 SymTab::Indexer dummy; 95 if ( params.size() != that.params.size() ) return false;96 104 for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) { 97 105 if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false; … … 100 108 } 101 109 102 AggregateDecl *base; ///< Base generic type103 110 std::list< Type* > params; ///< Instantiation parameters 104 111 }; 105 112 106 /// Maps a concrete typeto the some value, accounting for scope107 template< typename Value >113 /// Maps a key and a TypeList to the some value, accounting for scope 114 template< typename Key, typename Value > 108 115 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 121 124 122 125 public: 123 126 /// Starts a new scope 124 void beginScope() { 125 Scope scope; 126 scopes.push_back(scope); 127 } 127 void beginScope() { instantiations.beginScope(); } 128 128 129 129 /// 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; 150 140 } 151 141 } 152 // no matching instantiation found142 // no matching instantiations found 153 143 return 0; 154 144 } 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* > ¶ms, 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* > ¶ms, Value *value ) { 148 instantiations[ key ].push_back( Instantiation( TypeList( params ), value ) ); 149 } 168 150 }; 169 151 … … 197 179 virtual void doEndScope(); 198 180 private: 199 /// Makes a new temporary array holding the offsets of the fields of `type`, and returns a new variable expression referencing it200 Expression *makeOffsetArray( StructInstType *type );201 181 /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application 202 182 void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ); … … 225 205 ObjectDecl *makeTemporary( Type *type ); 226 206 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 230 211 DeclarationWithType *retval; 231 212 bool useRetval; … … 233 214 }; 234 215 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 236 218 class Pass2 : public PolyMutator { 237 219 public: … … 244 226 virtual Type *mutate( PointerType *pointerType ); 245 227 virtual Type *mutate( FunctionType *funcType ); 228 246 229 private: 247 230 void addAdapters( FunctionType *functionType ); … … 253 236 class GenericInstantiator : public DeclMutator { 254 237 /// Map of (generic type, parameter list) pairs to concrete type instantiations 255 InstantiationMap< AggregateDecl > instantiations;238 InstantiationMap< AggregateDecl, AggregateDecl > instantiations; 256 239 /// Namer for concrete types 257 240 UniqueName typeNamer; … … 278 261 }; 279 262 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: 284 269 template< typename DeclClass > 285 270 DeclClass *handleDecl( DeclClass *decl, Type *type ); … … 292 277 virtual Type *mutate( FunctionType *funcType ); 293 278 virtual Expression *mutate( MemberExpr *memberExpr ); 279 virtual Expression *mutate( SizeofExpr *sizeofExpr ); 280 virtual Expression *mutate( AlignofExpr *alignofExpr ); 294 281 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 295 297 }; 296 298 … … 342 344 Pass2 pass2; 343 345 GenericInstantiator instantiator; 344 MemberExprFixer memberFixer;346 PolyGenericCalculator polyCalculator; 345 347 Pass3 pass3; 346 348 … … 348 350 mutateTranslationUnit/*All*/( translationUnit, pass1 ); 349 351 mutateTranslationUnit/*All*/( translationUnit, pass2 ); 350 // instantiateGeneric( translationUnit );351 352 instantiator.mutateDeclarationList( translationUnit ); 352 mutateTranslationUnit/*All*/( translationUnit, memberFixer );353 mutateTranslationUnit/*All*/( translationUnit, polyCalculator ); 353 354 mutateTranslationUnit/*All*/( translationUnit, pass3 ); 354 355 } … … 653 654 654 655 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) { 655 // if this is a polymorphicassignment function, put it in the map for this scope656 // if this is a assignment function, put it in the map for this scope 656 657 if ( Type *assignedType = isAssignment( functionDecl ) ) { 657 658 if ( ! dynamic_cast< TypeInstType* >( assignedType ) ) { … … 743 744 } 744 745 745 Expression *Pass1::makeOffsetArray( StructInstType *ty ) {746 std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members();747 748 // make a new temporary array749 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 temporary756 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 temporary769 return new VariableExpr( arrayTemp );770 }771 772 746 void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) { 773 747 Type *polyBase = hasPolyBase( parmType, exprTyVars ); … … 782 756 if ( dynamic_cast< StructInstType* >( polyBase ) ) { 783 757 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 } 786 763 } else { 787 764 throw SemanticError( "Cannot pass non-struct type for generic struct" ); … … 931 908 return; 932 909 } 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 } 935 916 } else { 936 917 // use type computed in unification to declare boxed variables … … 1027 1008 } // for 1028 1009 } 1029 1030 1031 1010 1032 1011 FunctionDecl *Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) { … … 1428 1407 std::list< TypeDecl* >::const_iterator forallIt = forallParams.begin(); 1429 1408 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 1437 1410 TypeExpr *formalTypeExpr = dynamic_cast< TypeExpr* >( *tyIt ); 1438 1411 assert( formalTypeExpr && "type parameters must be type expressions" ); 1439 1412 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 1442 1419 DeclarationWithType *assertAssign = 0; 1443 1420 if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) { … … 1453 1430 } 1454 1431 } 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(); 1457 1437 assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ] 1458 1438 = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) ); … … 1587 1567 ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, 1588 1568 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 );1590 1569 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { 1591 1570 ObjectDecl *sizeParm, *alignParm; … … 1631 1610 ++last; 1632 1611 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 } 1638 1620 } 1639 1621 … … 1844 1826 1845 1827 template< typename DeclClass > 1846 DeclClass * MemberExprFixer::handleDecl( DeclClass *decl, Type *type ) {1828 DeclClass * PolyGenericCalculator::handleDecl( DeclClass *decl, Type *type ) { 1847 1829 TyVarMap oldtyVars = scopeTyVars; 1848 1830 makeTyVarMap( type, scopeTyVars ); … … 1854 1836 } 1855 1837 1856 ObjectDecl * MemberExprFixer::mutate( ObjectDecl *objectDecl ) {1838 ObjectDecl * PolyGenericCalculator::mutate( ObjectDecl *objectDecl ) { 1857 1839 return handleDecl( objectDecl, objectDecl->get_type() ); 1858 1840 } 1859 1841 1860 DeclarationWithType * MemberExprFixer::mutate( FunctionDecl *functionDecl ) {1842 DeclarationWithType * PolyGenericCalculator::mutate( FunctionDecl *functionDecl ) { 1861 1843 return handleDecl( functionDecl, functionDecl->get_functionType() ); 1862 1844 } 1863 1845 1864 TypedefDecl * MemberExprFixer::mutate( TypedefDecl *typedefDecl ) {1846 TypedefDecl * PolyGenericCalculator::mutate( TypedefDecl *typedefDecl ) { 1865 1847 return handleDecl( typedefDecl, typedefDecl->get_base() ); 1866 1848 } 1867 1849 1868 TypeDecl * MemberExprFixer::mutate( TypeDecl *typeDecl ) {1850 TypeDecl * PolyGenericCalculator::mutate( TypeDecl *typeDecl ) { 1869 1851 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); 1870 1852 return Mutator::mutate( typeDecl ); 1871 1853 } 1872 1854 1873 Type * MemberExprFixer::mutate( PointerType *pointerType ) {1855 Type * PolyGenericCalculator::mutate( PointerType *pointerType ) { 1874 1856 TyVarMap oldtyVars = scopeTyVars; 1875 1857 makeTyVarMap( pointerType, scopeTyVars ); … … 1881 1863 } 1882 1864 1883 Type * MemberExprFixer::mutate( FunctionType *functionType ) {1865 Type * PolyGenericCalculator::mutate( FunctionType *funcType ) { 1884 1866 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 ); 1888 1879 1889 1880 scopeTyVars = oldtyVars; … … 1891 1882 } 1892 1883 1893 Statement * MemberExprFixer::mutate( DeclStmt *declStmt ) {1884 Statement *PolyGenericCalculator::mutate( DeclStmt *declStmt ) { 1894 1885 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) { 1895 if ( isPolyType( objectDecl->get_type(), scopeTyVars) ) {1886 if ( findGeneric( objectDecl->get_type() ) ) { 1896 1887 // change initialization of a polymorphic value object 1897 1888 // to allocate storage with alloca … … 1945 1936 } 1946 1937 1947 Expression * MemberExprFixer::mutate( MemberExpr *memberExpr ) {1938 Expression *PolyGenericCalculator::mutate( MemberExpr *memberExpr ) { 1948 1939 // mutate, exiting early if no longer MemberExpr 1949 1940 Expression *expr = Mutator::mutate( memberExpr ); … … 1962 1953 Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars, &tyDepth ); 1963 1954 if ( ! objectType ) return memberExpr; 1955 findGeneric( objectType ); // ensure layout for this type is available 1964 1956 1965 1957 Expression *newMemberExpr = 0; … … 1993 1985 } 1994 1986 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 ) { 1996 2126 // mutate, exiting early if no longer OffsetofExpr 1997 2127 Expression *expr = Mutator::mutate( offsetofExpr ); … … 2000 2130 2001 2131 // 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 2005 2135 if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) { 2006 2136 // replace offsetof expression by index into offset array … … 2018 2148 } 2019 2149 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 2020 2201 ////////////////////////////////////////// Pass3 //////////////////////////////////////////////////// 2021 2202 -
src/GenPoly/ScopedMap.h
r3aba311 r37218fc 17 17 #define _SCOPEDMAP_H 18 18 19 #include <cassert> 19 20 #include <iterator> 20 21 #include <map> … … 164 165 void endScope() { 165 166 scopes.pop_back(); 167 assert( ! scopes.empty() ); 166 168 } 167 169 … … 188 190 return end(); 189 191 } 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 } 191 195 192 196 /// Finds the given key in the outermost scope inside the given scope where it occurs … … 200 204 return end(); 201 205 } 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 } 203 209 204 210 /// Inserts the given key-value pair into the outermost scope … … 208 214 } 209 215 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 } 211 222 }; 212 223 } // namespace GenPoly -
src/InitTweak/InitModel.h
r3aba311 r37218fc 75 75 void visit( UntypedOffsetofExpr * ) { throw 0; } 76 76 void visit( OffsetofExpr * ) { throw 0; } 77 void visit( OffsetPackExpr * ) { throw 0; } 77 78 void visit( AttrExpr * ) { throw 0; } 78 79 void visit( LogicalExpr * ) { throw 0; } -
src/Parser/ExpressionNode.cc
r3aba311 r37218fc 10 10 // Created On : Sat May 16 13:17:07 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Mar 13 12:34:38201613 // Update Count : 2 7212 // Last Modified On : Fri Apr 8 15:43:05 2016 13 // Update Count : 296 14 14 // 15 15 … … 22 22 23 23 #include "ParseNode.h" 24 #include "TypeData.h" 24 25 #include "SynTree/Constant.h" 25 26 #include "SynTree/Expression.h" 27 #include "SynTree/Declaration.h" 26 28 #include "Common/UnimplementedError.h" 27 29 #include "parseutility.h" … … 872 874 } 873 875 876 877 CompoundLiteralNode::CompoundLiteralNode( DeclarationNode *type, InitializerNode *kids ) : type( type ), kids( kids ) {} 878 CompoundLiteralNode::CompoundLiteralNode( const CompoundLiteralNode &other ) : ExpressionNode( other ), type( other.type ), kids( other.kids ) {} 879 880 CompoundLiteralNode::~CompoundLiteralNode() { 881 delete kids; 882 delete type; 883 } 884 885 CompoundLiteralNode *CompoundLiteralNode::clone() const { 886 return new CompoundLiteralNode( *this ); 887 } 888 889 void CompoundLiteralNode::print( std::ostream &os, int indent ) const { 890 os << string( indent,' ' ) << "CompoundLiteralNode:" << endl; 891 892 os << string( indent + 2, ' ' ) << "type:" << endl; 893 if ( type != 0 ) 894 type->print( os, indent + 4 ); 895 896 os << string( indent + 2, ' ' ) << "initialization:" << endl; 897 if ( kids != 0 ) 898 kids->printList( os, indent + 4 ); 899 } 900 901 void CompoundLiteralNode::printOneLine( std::ostream &os, int indent ) const { 902 os << "( "; 903 if ( type ) type->print( os ); 904 os << ", "; 905 if ( kids ) kids->printOneLine( os ); 906 os << ") "; 907 } 908 909 Expression *CompoundLiteralNode::build() const { 910 Declaration * newDecl = type->build(); // compound literal type 911 if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type 912 return new CompoundLiteralExpr( newDeclWithType->get_type(), kids->build() ); 913 // these types do not have associated type information 914 } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl ) ) { 915 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), kids->build() ); 916 } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl ) ) { 917 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), kids->build() ); 918 } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl ) ) { 919 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), kids->build() ); 920 } else { 921 assert( false ); 922 } // if 923 } 924 925 874 926 ExpressionNode *flattenCommas( ExpressionNode *list ) { 875 927 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) ) { -
src/Parser/ParseNode.h
r3aba311 r37218fc 10 10 // Created On : Sat May 16 13:28:16 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Mon Apr 04 17:04:22 201613 // Update Count : 19012 // Last Modified On : Mon Apr 11 11:50:52 2016 13 // Update Count : 205 14 14 // 15 15 … … 538 538 }; 539 539 540 class CompoundLiteralNode : public ExpressionNode { 541 public: 542 CompoundLiteralNode( DeclarationNode *type, InitializerNode *kids ); 543 CompoundLiteralNode( const CompoundLiteralNode &type ); 544 ~CompoundLiteralNode(); 545 546 virtual CompoundLiteralNode *clone() const; 547 548 DeclarationNode *get_type() const { return type; } 549 CompoundLiteralNode *set_type( DeclarationNode *t ) { type = t; return this; } 550 551 InitializerNode *get_initializer() const { return kids; } 552 CompoundLiteralNode *set_initializer( InitializerNode *k ) { kids = k; return this; } 553 554 void print( std::ostream &, int indent = 0 ) const; 555 void printOneLine( std::ostream &, int indent = 0 ) const; 556 557 virtual Expression *build() const; 558 private: 559 DeclarationNode *type; 560 InitializerNode *kids; 561 }; 562 540 563 template< typename SynTreeType, typename NodeType > 541 564 void buildList( const NodeType *firstNode, std::list< SynTreeType *> &outputList ) { -
src/Parser/parser.cc
r3aba311 r37218fc 5180 5180 /* Line 1806 of yacc.c */ 5181 5181 #line 374 "parser.yy" 5182 { (yyval.en) = 0; }5182 { (yyval.en) = new CompoundLiteralNode( (yyvsp[(2) - (7)].decl), new InitializerNode( (yyvsp[(5) - (7)].in), true ) ); } 5183 5183 break; 5184 5184 -
src/Parser/parser.yy
r3aba311 r37218fc 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Mar 24 16:16:16201613 // Update Count : 1 49812 // Last Modified On : Fri Apr 8 16:21:55 2016 13 // Update Count : 1508 14 14 // 15 15 … … 372 372 { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::DecrPost ), $1 ); } 373 373 | '(' type_name_no_function ')' '{' initializer_list comma_opt '}' // C99 374 { $$ = 0; }374 { $$ = new CompoundLiteralNode( $2, new InitializerNode( $5, true ) ); } 375 375 | postfix_expression '{' argument_expression_list '}' // CFA 376 376 { -
src/ResolvExpr/AlternativeFinder.cc
r3aba311 r37218fc 848 848 } 849 849 850 void AlternativeFinder::visit( OffsetPackExpr *offsetPackExpr ) { 851 alternatives.push_back( Alternative( offsetPackExpr->clone(), env, Cost::zero ) ); 852 } 853 850 854 void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) { 851 855 // assume no polymorphism -
src/ResolvExpr/AlternativeFinder.h
r3aba311 r37218fc 59 59 virtual void visit( UntypedOffsetofExpr *offsetofExpr ); 60 60 virtual void visit( OffsetofExpr *offsetofExpr ); 61 virtual void visit( OffsetPackExpr *offsetPackExpr ); 61 62 virtual void visit( AttrExpr *attrExpr ); 62 63 virtual void visit( LogicalExpr *logicalExpr ); -
src/SymTab/AddVisit.h
r3aba311 r37218fc 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 16:14:32 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : T ue Jul 14 12:26:17 201513 // Update Count : 411 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Apr 7 14:42:21 2016 13 // Update Count : 5 14 14 // 15 15 … … 27 27 28 28 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 >39 29 inline void addVisit(CompoundStmt *compoundStmt, Visitor &visitor) { 40 30 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 );62 31 } 63 32 … … 74 43 } 75 44 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 // } 87 50 } // namespace SymTab 88 51 -
src/SymTab/Indexer.cc
r3aba311 r37218fc 344 344 maybeAccept( offsetofExpr->get_type(), *this ); 345 345 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 ); 346 351 } 347 352 -
src/SymTab/Indexer.h
r3aba311 r37218fc 59 59 virtual void visit( UntypedOffsetofExpr *offsetofExpr ); 60 60 virtual void visit( OffsetofExpr *offsetofExpr ); 61 virtual void visit( OffsetPackExpr *offsetPackExpr ); 61 62 virtual void visit( AttrExpr *attrExpr ); 62 63 virtual void visit( LogicalExpr *logicalExpr ); -
src/SymTab/Validate.cc
r3aba311 r37218fc 10 10 // Created On : Sun May 17 21:50:04 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 17:31:39201613 // Update Count : 2 2612 // Last Modified On : Thu Apr 7 16:45:30 2016 13 // Update Count : 243 14 14 // 15 15 … … 40 40 #include <list> 41 41 #include <iterator> 42 #include "Common/utility.h" 43 #include "Common/UniqueName.h" 42 44 #include "Validate.h" 43 45 #include "SynTree/Visitor.h" 44 46 #include "SynTree/Mutator.h" 45 47 #include "SynTree/Type.h" 48 #include "SynTree/Expression.h" 46 49 #include "SynTree/Statement.h" 47 50 #include "SynTree/TypeSubstitution.h" … … 49 52 #include "FixFunction.h" 50 53 // #include "ImplementationType.h" 51 #include "Common/utility.h" 52 #include "Common/UniqueName.h" 54 #include "GenPoly/DeclMutator.h" 53 55 #include "AddVisit.h" 54 56 #include "MakeLibCfa.h" … … 70 72 71 73 virtual void visit( CompoundStmt *compoundStmt ); 72 virtual void visit( IfStmt *ifStmt );73 virtual void visit( WhileStmt *whileStmt );74 virtual void visit( ForStmt *forStmt );75 74 virtual void visit( SwitchStmt *switchStmt ); 76 75 virtual void visit( ChooseStmt *chooseStmt ); 77 virtual void visit( CaseStmt *caseStmt ); 78 virtual void visit( CatchStmt *catchStmt ); 76 // virtual void visit( CaseStmt *caseStmt ); 79 77 private: 80 78 HoistStruct(); … … 144 142 145 143 virtual void visit( CompoundStmt *compoundStmt ); 146 virtual void visit( IfStmt *ifStmt );147 virtual void visit( WhileStmt *whileStmt );148 virtual void visit( ForStmt *forStmt );149 144 virtual void visit( SwitchStmt *switchStmt ); 150 145 virtual void visit( ChooseStmt *chooseStmt ); 151 virtual void visit( CaseStmt *caseStmt ); 152 virtual void visit( CatchStmt *catchStmt ); 146 // virtual void visit( CaseStmt *caseStmt ); 153 147 154 148 AutogenerateRoutines() : functionNesting( 0 ) {} … … 166 160 /// and return something if the return type is non-void. 167 161 static void checkFunctionReturns( std::list< Declaration * > & translationUnit ); 168 169 162 private: 170 163 virtual void visit( FunctionDecl * functionDecl ); … … 202 195 }; 203 196 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 204 204 void validate( std::list< Declaration * > &translationUnit, bool doDebug ) { 205 205 Pass1 pass1; 206 206 Pass2 pass2( doDebug, 0 ); 207 207 Pass3 pass3( 0 ); 208 CompoundLiteral compoundliteral; 209 208 210 EliminateTypedef::eliminateTypedef( translationUnit ); 209 211 HoistStruct::hoistStruct( translationUnit ); … … 211 213 acceptAll( translationUnit, pass2 ); 212 214 ReturnChecker::checkFunctionReturns( translationUnit ); 215 mutateAll( translationUnit, compoundliteral ); 213 216 AutogenerateRoutines::autogenerateRoutines( translationUnit ); 214 217 acceptAll( translationUnit, pass3 ); … … 292 295 } 293 296 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 306 297 void HoistStruct::visit( SwitchStmt *switchStmt ) { 307 298 addVisit( switchStmt, *this ); … … 312 303 } 313 304 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 // } 321 308 322 309 void Pass1::visit( EnumDecl *enumDecl ) { … … 874 861 } 875 862 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 888 863 void AutogenerateRoutines::visit( SwitchStmt *switchStmt ) { 889 864 visitStatement( switchStmt ); … … 894 869 } 895 870 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 // } 903 874 904 875 void ReturnChecker::checkFunctionReturns( std::list< Declaration * > & translationUnit ) { … … 1080 1051 } 1081 1052 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 } 1082 1073 } // namespace SymTab 1083 1074 -
src/SynTree/Expression.cc
r3aba311 r37218fc 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Wed Dec 09 14:10:29 201513 // Update Count : 3411 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Apr 8 17:16:23 2016 13 // Update Count : 40 14 14 // 15 15 … … 22 22 23 23 #include "Type.h" 24 #include "Initializer.h" 24 25 #include "Expression.h" 25 26 #include "Declaration.h" … … 211 212 212 213 os << " of "; 214 215 if ( type ) { 216 type->print(os, indent + 2); 217 } else { 218 os << "<NULL>"; 219 } 220 221 os << std::endl; 222 Expression::print( os, indent ); 223 } 224 225 OffsetPackExpr::OffsetPackExpr( StructInstType *type_, Expression *aname_ ) : Expression( aname_ ), type( type_ ) { 226 add_result( new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0, false, false ) ); 227 } 228 229 OffsetPackExpr::OffsetPackExpr( const OffsetPackExpr &other ) : Expression( other ), type( maybeClone( other.type ) ) {} 230 231 OffsetPackExpr::~OffsetPackExpr() { delete type; } 232 233 void OffsetPackExpr::print( std::ostream &os, int indent ) const { 234 os << std::string( indent, ' ' ) << "Offset pack expression on "; 213 235 214 236 if ( type ) { … … 443 465 444 466 467 CompoundLiteralExpr::CompoundLiteralExpr( Type * type, Initializer * initializer ) : type( type ), initializer( initializer ) { 468 add_result( type->clone() ); 469 } 470 471 CompoundLiteralExpr::CompoundLiteralExpr( const CompoundLiteralExpr &other ) : Expression( other ), type( maybeClone( other.type ) ), initializer( maybeClone( other.initializer ) ) {} 472 473 CompoundLiteralExpr::~CompoundLiteralExpr() { 474 delete initializer; 475 delete type; 476 } 477 478 void CompoundLiteralExpr::print( std::ostream &os, int indent ) const { 479 os << "Compound Literal Expression: " << std::endl; 480 if ( type ) type->print( os, indent + 2 ); 481 if ( initializer ) initializer->print( os, indent + 2 ); 482 } 483 445 484 446 485 std::ostream & operator<<( std::ostream & out, Expression * expr ) { -
src/SynTree/Expression.h
r3aba311 r37218fc 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Wed Dec 09 14:10:21 201513 // Update Count : 1911 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Apr 8 17:18:06 2016 13 // Update Count : 21 14 14 // 15 15 … … 362 362 }; 363 363 364 /// Expression representing a pack of field-offsets for a generic type 365 class OffsetPackExpr : public Expression { 366 public: 367 OffsetPackExpr( StructInstType *type_, Expression *aname_ = 0 ); 368 OffsetPackExpr( const OffsetPackExpr &other ); 369 virtual ~OffsetPackExpr(); 370 371 StructInstType *get_type() const { return type; } 372 void set_type( StructInstType *newValue ) { type = newValue; } 373 374 virtual OffsetPackExpr *clone() const { return new OffsetPackExpr( *this ); } 375 virtual void accept( Visitor &v ) { v.visit( this ); } 376 virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); } 377 378 virtual void print( std::ostream &os, int indent = 0 ) const; 379 380 private: 381 StructInstType *type; 382 }; 383 364 384 /// AttrExpr represents an @attribute expression (like sizeof, but user-defined) 365 385 class AttrExpr : public Expression { … … 557 577 }; 558 578 579 /// CompoundLiteralExpr represents a C99 'compound literal' 580 class CompoundLiteralExpr : public Expression { 581 public: 582 CompoundLiteralExpr( Type * type, Initializer * initializer ); 583 CompoundLiteralExpr( const CompoundLiteralExpr &other ); 584 ~CompoundLiteralExpr(); 585 586 Type * get_type() const { return type; } 587 void set_type( Type * t ) { type = t; } 588 589 Initializer * get_initializer() const { return initializer; } 590 void set_initializer( Initializer * i ) { initializer = i; } 591 592 virtual CompoundLiteralExpr *clone() const { return new CompoundLiteralExpr( *this ); } 593 virtual void accept( Visitor &v ) { v.visit( this ); } 594 virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); } 595 virtual void print( std::ostream &os, int indent = 0 ) const; 596 private: 597 Type * type; 598 Initializer * initializer; 599 }; 600 559 601 std::ostream & operator<<( std::ostream & out, Expression * expr ); 560 602 -
src/SynTree/Mutator.cc
r3aba311 r37218fc 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 17:28:20201613 // Update Count : 1 212 // Last Modified On : Fri Apr 1 18:05:16 2016 13 // Update Count : 16 14 14 // 15 15 … … 274 274 } 275 275 276 Expression *Mutator::mutate( OffsetPackExpr *offsetPackExpr ) { 277 mutateAll( offsetPackExpr->get_results(), *this ); 278 offsetPackExpr->set_type( maybeMutate( offsetPackExpr->get_type(), *this ) ); 279 return offsetPackExpr; 280 } 281 276 282 Expression *Mutator::mutate( AttrExpr *attrExpr ) { 277 283 mutateAll( attrExpr->get_results(), *this ); … … 334 340 mutateAll( valofExpr->get_results(), *this ); 335 341 return valofExpr; 342 } 343 344 Expression *Mutator::mutate( CompoundLiteralExpr *compLitExpr ) { 345 mutateAll( compLitExpr->get_results(), *this ); 346 compLitExpr->set_type( maybeMutate( compLitExpr->get_type(), *this ) ); 347 compLitExpr->set_initializer( maybeMutate( compLitExpr->get_initializer(), *this ) ); 348 return compLitExpr; 336 349 } 337 350 -
src/SynTree/Mutator.h
r3aba311 r37218fc 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 17:33:11201613 // Update Count : 912 // Last Modified On : Fri Apr 1 17:26:56 2016 13 // Update Count : 10 14 14 // 15 15 #include <cassert> … … 67 67 virtual Expression* mutate( UntypedOffsetofExpr *offsetofExpr ); 68 68 virtual Expression* mutate( OffsetofExpr *offsetofExpr ); 69 virtual Expression* mutate( OffsetPackExpr *offsetPackExpr ); 69 70 virtual Expression* mutate( AttrExpr *attrExpr ); 70 71 virtual Expression* mutate( LogicalExpr *logicalExpr ); … … 76 77 virtual Expression* mutate( AsmExpr *asmExpr ); 77 78 virtual Expression* mutate( UntypedValofExpr *valofExpr ); 79 virtual Expression* mutate( CompoundLiteralExpr *compLitExpr ); 78 80 79 81 virtual Type* mutate( VoidType *basicType ); -
src/SynTree/SynTree.h
r3aba311 r37218fc 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 17:29:00201613 // Update Count : 412 // Last Modified On : Fri Apr 1 16:47:44 2016 13 // Update Count : 5 14 14 // 15 15 … … 72 72 class UntypedOffsetofExpr; 73 73 class OffsetofExpr; 74 class OffsetPackExpr; 74 75 class AttrExpr; 75 76 class LogicalExpr; … … 81 82 class AsmExpr; 82 83 class UntypedValofExpr; 84 class CompoundLiteralExpr; 83 85 84 86 class Type; -
src/SynTree/Visitor.cc
r3aba311 r37218fc 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 17:29:23 201613 // Update Count : 1 612 // Last Modified On : Fri Apr 1 18:05:13 2016 13 // Update Count : 18 14 14 // 15 15 … … 230 230 } 231 231 232 void Visitor::visit( OffsetPackExpr *offsetPackExpr ) { 233 acceptAll( offsetPackExpr->get_results(), *this ); 234 maybeAccept( offsetPackExpr->get_type(), *this ); 235 } 236 232 237 void Visitor::visit( AttrExpr *attrExpr ) { 233 238 acceptAll( attrExpr->get_results(), *this ); … … 282 287 acceptAll( valofExpr->get_results(), *this ); 283 288 maybeAccept( valofExpr->get_body(), *this ); 289 } 290 291 void Visitor::visit( CompoundLiteralExpr *compLitExpr ) { 292 acceptAll( compLitExpr->get_results(), *this ); 293 maybeAccept( compLitExpr->get_type(), *this ); 294 maybeAccept( compLitExpr->get_initializer(), *this ); 284 295 } 285 296 -
src/SynTree/Visitor.h
r3aba311 r37218fc 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 17:33:35 201613 // Update Count : 612 // Last Modified On : Fri Apr 1 17:26:55 2016 13 // Update Count : 7 14 14 // 15 15 … … 67 67 virtual void visit( UntypedOffsetofExpr *offsetofExpr ); 68 68 virtual void visit( OffsetofExpr *offsetofExpr ); 69 virtual void visit( OffsetPackExpr *offsetPackExpr ); 69 70 virtual void visit( AttrExpr *attrExpr ); 70 71 virtual void visit( LogicalExpr *logicalExpr ); … … 76 77 virtual void visit( AsmExpr *asmExpr ); 77 78 virtual void visit( UntypedValofExpr *valofExpr ); 79 virtual void visit( CompoundLiteralExpr *compLitExpr ); 78 80 79 81 virtual void visit( VoidType *basicType ); -
src/Tuples/FlattenTuple.cc
r3aba311 r37218fc 49 49 void FlattenTuple::CollectArgs::visit( UntypedOffsetofExpr *expr ) { currentArgs.insert( currentArgs.end(), expr ); } 50 50 void FlattenTuple::CollectArgs::visit( OffsetofExpr *expr ) { currentArgs.insert( currentArgs.end(), expr ); } 51 void FlattenTuple::CollectArgs::visit( OffsetPackExpr *expr ) { currentArgs.insert( currentArgs.end(), expr ); } 51 52 void FlattenTuple::CollectArgs::visit( AttrExpr *expr ) { currentArgs.insert( currentArgs.end(), expr ); } 52 53 void FlattenTuple::CollectArgs::visit( LogicalExpr *expr ) { currentArgs.insert( currentArgs.end(), expr ); } -
src/Tuples/FlattenTuple.h
r3aba311 r37218fc 45 45 virtual void visit( UntypedOffsetofExpr * ); 46 46 virtual void visit( OffsetofExpr * ); 47 virtual void visit( OffsetPackExpr * ); 47 48 virtual void visit( AttrExpr * ); 48 49 virtual void visit( LogicalExpr * ); -
src/driver/cfa.cc
r3aba311 r37218fc 10 10 // Created On : Tue Aug 20 13:44:49 2002 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jan 28 18:24:06201613 // Update Count : 1 2712 // Last Modified On : Wed Apr 6 14:04:22 2016 13 // Update Count : 132 14 14 // 15 15 … … 165 165 nargs += 1; 166 166 } else if ( prefix( arg, "-std=" ) ) { 167 std_flag = true; // std=XX provided167 std_flag = true; // -std=XX provided 168 168 args[nargs] = argv[i]; // pass the argument along 169 169 nargs += 1; … … 307 307 nargs += 1; 308 308 if ( ! std_flag ) { // default c99, if none specified 309 args[nargs] = "-std= c99";309 args[nargs] = "-std=gnu99"; 310 310 nargs += 1; 311 311 } // if -
src/libcfa/Makefile.am
r3aba311 r37218fc 11 11 ## Created On : Sun May 31 08:54:01 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Wed Mar 2 22:59:23201614 ## Update Count : 1 1913 ## Last Modified On : Wed Apr 6 21:10:44 2016 14 ## Update Count : 123 15 15 ############################################################################### 16 16 … … 60 60 ${CC} ${CFLAGS} -c -o $@ $< 61 61 62 libs = stdlib iostream fstream iterator62 libs = limits stdlib iostream fstream iterator rational 63 63 libcfa_a_SOURCES = libcfa-prelude.c ${libs:=.c} 64 64 65 cheaders = # 66 cfaheaders = limits65 cheaders = # expat 66 cfaheaders = # limits 67 67 include_HEADERS = ${cheaders:=.h} ${libs} ${cfaheaders} 68 68 -
src/libcfa/Makefile.in
r3aba311 r37218fc 83 83 libcfa_a_AR = $(AR) $(ARFLAGS) 84 84 libcfa_a_LIBADD = 85 am__objects_1 = stdlib.$(OBJEXT) iostream.$(OBJEXT) fstream.$(OBJEXT) \86 iterator.$(OBJEXT)85 am__objects_1 = limits.$(OBJEXT) stdlib.$(OBJEXT) iostream.$(OBJEXT) \ 86 fstream.$(OBJEXT) iterator.$(OBJEXT) rational.$(OBJEXT) 87 87 am_libcfa_a_OBJECTS = libcfa-prelude.$(OBJEXT) $(am__objects_1) 88 88 libcfa_a_OBJECTS = $(am_libcfa_a_OBJECTS) … … 213 213 MAINTAINERCLEANFILES = ${addprefix ${libdir}/,${cfalib_DATA}} \ 214 214 ${addprefix ${libdir}/,${lib_LIBRARIES}} ${includedir}/* 215 libs = stdlib iostream fstream iterator215 libs = limits stdlib iostream fstream iterator rational 216 216 libcfa_a_SOURCES = libcfa-prelude.c ${libs:=.c} 217 cheaders = # 218 cfaheaders = limits217 cheaders = # expat 218 cfaheaders = # limits 219 219 include_HEADERS = ${cheaders:=.h} ${libs} ${cfaheaders} 220 220 all: all-am … … 297 297 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iterator.Po@am__quote@ 298 298 @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@ 299 301 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stdlib.Po@am__quote@ 300 302 -
src/libcfa/fstream
r3aba311 r37218fc 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 15:08:14201613 // Update Count : 7812 // Last Modified On : Tue Apr 5 22:37:12 2016 13 // Update Count : 82 14 14 // 15 15 … … 20 20 21 21 enum { separateSize = 16 }; 22 struct ofstream { void *file; int separate; char separator[separateSize]; }; 22 struct ofstream { 23 void *file; 24 _Bool sepDefault; 25 _Bool sepOnOff; 26 char separator[separateSize]; 27 }; // ofstream 23 28 24 29 _Bool sepPrt( ofstream * ); 25 30 void sepOn( ofstream * ); 26 31 void sepOff( ofstream * ); 32 void sepReset( ofstream * ); 33 void sepReset( ofstream *, _Bool ); 27 34 void sepSet( ofstream *, const char * ); 28 35 const char * sepGet( ofstream * ); 29 voidsepDisable( ofstream * );30 voidsepEnable( ofstream * );36 _Bool sepDisable( ofstream * ); 37 _Bool sepEnable( ofstream * ); 31 38 int fail( ofstream * ); 32 39 int flush( ofstream * ); … … 39 46 40 47 // implement context istream 41 struct ifstream { void *file; }; 48 struct ifstream { 49 void *file; 50 }; // ifstream 42 51 43 52 int fail( ifstream * is ); -
src/libcfa/fstream.c
r3aba311 r37218fc 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Feb 29 18:41:10201613 // Update Count : 1 6212 // Last Modified On : Wed Apr 6 17:55:27 2016 13 // Update Count : 176 14 14 // 15 15 … … 25 25 } 26 26 27 #define IO_MSG "I/O error "27 #define IO_MSG "I/O error: " 28 28 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; } 30 void sepOn( ofstream * os ) { os->sepOnOff = 1; } 31 void sepOff( ofstream * os ) { os->sepOnOff = 0; } 32 void sepReset( ofstream * os ) { os->sepOnOff = os->sepDefault; } 33 void sepReset( ofstream * os, _Bool reset ) { os->sepDefault = reset; os->sepOnOff = os->sepDefault; } 32 34 void sepSet( ofstream * os, const char * s ) { 33 35 strncpy( &(os->separator[0]), s, separateSize - 1 ); … … 35 37 } // sepSet 36 38 const 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 39 51 40 52 int fail( ofstream * os ) { … … 49 61 FILE *file = fopen( name, mode ); 50 62 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 ); 52 65 exit( EXIT_FAILURE ); 53 66 } // if … … 94 107 95 108 96 static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_), 0, { ' ', '\0' } };109 static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_), 1, 0, { ' ', '\0' } }; 97 110 ofstream *sout = &soutFile; 98 static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_), 0, { ' ', '\0' } };111 static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_), 1, 0, { ' ', '\0' } }; 99 112 ofstream *serr = &serrFile; 100 113 … … 114 127 FILE *t = fopen( name, mode ); 115 128 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 ); 117 131 exit( EXIT_FAILURE ); 118 132 } // if … … 175 189 // Local Variables: // 176 190 // tab-width: 4 // 177 // compile-command: "cfa fstream.c" //178 191 // End: // -
src/libcfa/iostream
r3aba311 r37218fc 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 18:05:27 201613 // Update Count : 8512 // Last Modified On : Tue Apr 5 22:32:37 2016 13 // Update Count : 90 14 14 // 15 15 … … 23 23 void sepOn( ostype * ); 24 24 void sepOff( ostype * ); 25 void sepReset( ostype * ); 26 void sepReset( ostype *, _Bool ); 25 27 void sepSet( ostype *, const char * ); 26 28 const char * sepGet( ostype * ); 27 voidsepDisable( ostype * );28 voidsepEnable( ostype * );29 _Bool sepDisable( ostype * ); 30 _Bool sepEnable( ostype * ); 29 31 int fail( ostype * ); 30 32 int flush( ostype * ); … … 67 69 forall( dtype ostype | ostream( ostype ) ) ostype * sepOn( ostype * ); 68 70 forall( dtype ostype | ostream( ostype ) ) ostype * sepOff( ostype * ); 71 forall( dtype ostype | ostream( ostype ) ) ostype * sepDisable( ostype * ); 72 forall( dtype ostype | ostream( ostype ) ) ostype * sepEnable( ostype * ); 69 73 70 74 // writes the range [begin, end) to the given stream … … 110 114 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, long double _Complex * ); 111 115 112 struct _Istream_ str1{ char * s; };113 _Istream_ str1str( char * );114 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, _Istream_ str1);116 struct _Istream_cstrUC { char * s; }; 117 _Istream_cstrUC cstr( char * ); 118 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, _Istream_cstrUC ); 115 119 116 struct _Istream_ str2{ char * s; int size; };117 _Istream_ str2str( char *, int size );118 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, _Istream_ str2);120 struct _Istream_cstrC { char * s; int size; }; 121 _Istream_cstrC cstr( char *, int size ); 122 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, _Istream_cstrC ); 119 123 120 124 #endif // __IOSTREAM_H__ -
src/libcfa/iostream.c
r3aba311 r37218fc 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Mar 7 13:51:23201613 // Update Count : 2 2712 // Last Modified On : Wed Apr 6 16:13:29 2016 13 // Update Count : 278 14 14 // 15 15 … … 27 27 ostype * ?|?( ostype *os, char c ) { 28 28 prtfmt( os, "%c", c ); 29 sepOff( os ); 29 30 return os; 30 31 } // ?|? … … 32 33 forall( dtype ostype | ostream( ostype ) ) 33 34 ostype * ?|?( 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 ); 35 37 prtfmt( os, "%hd", si ); 36 38 return os; … … 39 41 forall( dtype ostype | ostream( ostype ) ) 40 42 ostype * ?|?( 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 ); 42 45 prtfmt( os, "%hu", usi ); 43 46 return os; … … 46 49 forall( dtype ostype | ostream( ostype ) ) 47 50 ostype * ?|?( 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 ); 49 53 prtfmt( os, "%d", i ); 50 54 return os; … … 53 57 forall( dtype ostype | ostream( ostype ) ) 54 58 ostype * ?|?( 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 ); 56 61 prtfmt( os, "%u", ui ); 57 62 return os; … … 60 65 forall( dtype ostype | ostream( ostype ) ) 61 66 ostype * ?|?( 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 ); 63 69 prtfmt( os, "%ld", li ); 64 70 return os; … … 67 73 forall( dtype ostype | ostream( ostype ) ) 68 74 ostype * ?|?( 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 ); 70 77 prtfmt( os, "%lu", uli ); 71 78 return os; … … 74 81 forall( dtype ostype | ostream( ostype ) ) 75 82 ostype * ?|?( 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 ); 77 85 prtfmt( os, "%lld", lli ); 78 86 return os; … … 81 89 forall( dtype ostype | ostream( ostype ) ) 82 90 ostype * ?|?( 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 ); 84 93 prtfmt( os, "%llu", ulli ); 85 94 return os; … … 88 97 forall( dtype ostype | ostream( ostype ) ) 89 98 ostype * ?|?( 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 ); 91 101 prtfmt( os, "%g", f ); 92 102 return os; … … 95 105 forall( dtype ostype | ostream( ostype ) ) 96 106 ostype * ?|?( 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 ); 98 109 prtfmt( os, "%.*lg", DBL_DIG, d ); 99 110 return os; … … 102 113 forall( dtype ostype | ostream( ostype ) ) 103 114 ostype * ?|?( 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 ); 105 117 prtfmt( os, "%.*Lg", LDBL_DIG, ld ); 106 118 return os; … … 110 122 ostype * ?|?( ostype *os, float _Complex fc ) { 111 123 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 114 128 return os; 115 129 } // ?|? … … 118 132 ostype * ?|?( ostype *os, double _Complex dc ) { 119 133 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 122 138 return os; 123 139 } // ?|? … … 126 142 ostype * ?|?( ostype *os, long double _Complex ldc ) { 127 143 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 130 148 return os; 131 149 } // ?|? … … 134 152 ostype * ?|?( ostype *os, const char *cp ) { 135 153 enum { Open = 1, Close, OpenClose }; 136 static const char mask[256] = {154 static const unsigned char mask[256] = { 137 155 // opening delimiters 138 156 ['('] : 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, 140 158 // closing delimiters 141 159 [','] : Close, ['.'] : Close, [':'] : Close, [';'] : Close, ['!'] : Close, ['?'] : Close, 142 160 [')'] : Close, [']'] : Close, ['}'] : Close, 143 ['%'] : Close, [ L'»'] : Close,161 ['%'] : Close, [(unsigned char)'¢'] : Close, [(unsigned char)'»'] : Close, 144 162 // opening-closing delimiters 145 163 ['\''] : OpenClose, ['`'] : OpenClose, ['"'] : OpenClose, 164 ['\f'] : OpenClose, ['\n'] : OpenClose, ['\r'] : OpenClose, ['\t'] : OpenClose, ['\v'] : OpenClose, // isspace 146 165 }; // mask 147 166 … … 149 168 // null string => no separator 150 169 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 ) { 153 173 prtfmt( os, "%s", sepGet( os ) ); 154 174 } // if 155 175 // last character IS spacing or opening punctuation => turn off separator for next item 156 176 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 ) { 158 179 sepOff( os ); 159 180 } else { … … 165 186 forall( dtype ostype | ostream( ostype ) ) 166 187 ostype * ?|?( 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 ); 168 190 prtfmt( os, "%p", p ); 169 191 return os; … … 196 218 } // sepOff 197 219 220 forall( dtype ostype | ostream( ostype ) ) 221 ostype * sepEnable( ostype * os ) { 222 sepEnable( os ); 223 return os; 224 } // sepEnable 225 226 forall( dtype ostype | ostream( ostype ) ) 227 ostype * sepDisable( ostype * os ) { 228 sepDisable( os ); 229 return os; 230 } // sepDisable 231 198 232 //--------------------------------------- 199 233 … … 310 344 } // ?|? 311 345 312 _Istream_ str1 str( char * s ) { _Istream_str1s = { s }; return s; }313 forall( dtype istype | istream( istype ) ) 314 istype * ?|?( istype * is, _Istream_ str1str ) {315 scanfmt( is, "%s", str.s );316 return is; 317 } // str318 319 _Istream_ str2 str( char * s, int size ) { _Istream_str2s = { s, size }; return s; }320 forall( dtype istype | istream( istype ) ) 321 istype * ?|?( istype * is, _Istream_ str2str ) {346 _Istream_cstrUC cstr( char * s ) { _Istream_cstrUC s = { s }; return s; } 347 forall( dtype istype | istream( istype ) ) 348 istype * ?|?( istype * is, _Istream_cstrUC cstr ) { 349 scanfmt( is, "%s", cstr.s ); 350 return is; 351 } // cstr 352 353 _Istream_cstrC cstr( char * s, int size ) { _Istream_cstrC s = { s, size }; return s; } 354 forall( dtype istype | istream( istype ) ) 355 istype * ?|?( istype * is, _Istream_cstrC cstr ) { 322 356 char buf[16]; 323 sprintf( buf, "%%%ds", str.size );324 scanfmt( is, buf, str.s );325 return is; 326 } // str357 sprintf( buf, "%%%ds", cstr.size ); 358 scanfmt( is, buf, cstr.s ); 359 return is; 360 } // cstr 327 361 328 362 // 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 1 16 // Integral Constants 2 17 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;18 extern const short int MIN; 19 extern const int MIN; 20 extern const long int MIN; 21 extern const long long int MIN; 7 22 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;23 extern const short int MAX; 24 extern const unsigned short int MAX; 25 extern const int MAX; 26 extern const unsigned int MAX; 27 extern const long int MAX; 28 extern const unsigned long int MAX; 29 extern const long long int MAX; 30 extern const unsigned long long int MAX; 16 31 17 32 // Floating-Point Constants 18 33 19 const float PI = 3.141592_F;// pi20 const float PI_2 = 1.570796_F;// pi / 221 const float PI_4 = 0.7853981_F;// pi / 422 const float _1_PI = 0.3183098_F;// 1 / pi23 const float _2_PI = 0.6366197_F;// 2 / pi24 const float _2_SQRT_PI = 1.128379_F;// 2 / sqrt(pi)34 extern const float PI; // pi 35 extern const float PI_2; // pi / 2 36 extern const float PI_4; // pi / 4 37 extern const float _1_PI; // 1 / pi 38 extern const float _2_PI; // 2 / pi 39 extern const float _2_SQRT_PI; // 2 / sqrt(pi) 25 40 26 const double PI = 3.14159265358979323846_D;// pi27 const double PI_2 = 1.57079632679489661923_D;// pi / 228 const double PI_4 = 0.78539816339744830962_D;// pi / 429 const double _1_PI = 0.31830988618379067154_D;// 1 / pi30 const double _2_PI = 0.63661977236758134308_D;// 2 / pi31 const double _2_SQRT_PI = 1.12837916709551257390_D;// 2 / sqrt(pi)41 extern const double PI; // pi 42 extern const double PI_2; // pi / 2 43 extern const double PI_4; // pi / 4 44 extern const double _1_PI; // 1 / pi 45 extern const double _2_PI; // 2 / pi 46 extern const double _2_SQRT_PI; // 2 / sqrt(pi) 32 47 33 const long double PI = 3.1415926535897932384626433832795029_DL;// pi34 const long double PI_2 = 1.5707963267948966192313216916397514_DL;// pi / 235 const long double PI_4 = 0.7853981633974483096156608458198757_DL;// pi / 436 const long double _1_PI = 0.3183098861837906715377675267450287_DL;// 1 / pi37 const long double _2_PI = 0.6366197723675813430755350534900574_DL;// 2 / pi38 const long double _2_SQRT_PI = 1.1283791670955125738961589031215452_DL;// 2 / sqrt(pi)48 extern const long double PI; // pi 49 extern const long double PI_2; // pi / 2 50 extern const long double PI_4; // pi / 4 51 extern const long double _1_PI; // 1 / pi 52 extern const long double _2_PI; // 2 / pi 53 extern const long double _2_SQRT_PI; // 2 / sqrt(pi) 39 54 40 const _Complex PI = 3.14159265358979323846_D+0.0_iD;// pi41 const _Complex PI_2 = 1.57079632679489661923_D+0.0_iD;// pi / 242 const _Complex PI_4 = 0.78539816339744830962_D+0.0_iD;// pi / 443 const _Complex _1_PI = 0.31830988618379067154_D+0.0_iD;// 1 / pi44 const _Complex _2_PI = 0.63661977236758134308_D+0.0_iD;// 2 / pi45 const _Complex _2_SQRT_PI = 1.12837916709551257390_D+0.0_iD;// 2 / sqrt(pi)55 extern const _Complex PI; // pi 56 extern const _Complex PI_2; // pi / 2 57 extern const _Complex PI_4; // pi / 4 58 extern const _Complex _1_PI; // 1 / pi 59 extern const _Complex _2_PI; // 2 / pi 60 extern const _Complex _2_SQRT_PI; // 2 / sqrt(pi) 46 61 47 const long _Complex PI = 3.1415926535897932384626433832795029_L+0.0iL;// pi48 const long _Complex PI_2 = 1.5707963267948966192313216916397514_L+0.0iL;// pi / 249 const long _Complex PI_4 = 0.7853981633974483096156608458198757_L+0.0iL;// pi / 450 const long _Complex _1_PI = 0.3183098861837906715377675267450287_L+0.0iL;// 1 / pi51 const long _Complex _2_PI = 0.6366197723675813430755350534900574_L+0.0iL;// 2 / pi52 const long _Complex _2_SQRT_PI = 1.1283791670955125738961589031215452_L+0.0iL;// 2 / sqrt(pi)62 extern const long _Complex PI; // pi 63 extern const long _Complex PI_2; // pi / 2 64 extern const long _Complex PI_4; // pi / 4 65 extern const long _Complex _1_PI; // 1 / pi 66 extern const long _Complex _2_PI; // 2 / pi 67 extern const long _Complex _2_SQRT_PI; // 2 / sqrt(pi) 53 68 54 const float E = 2.718281;// e55 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)69 extern const float E; // e 70 extern const float LOG2_E; // log_2(e) 71 extern const float LOG10_E; // log_10(e) 72 extern const float LN_2; // log_e(2) 73 extern const float LN_10; // log_e(10) 74 extern const float SQRT_2; // sqrt(2) 75 extern const float _1_SQRT_2; // 1 / sqrt(2) 61 76 62 const double E = 2.7182818284590452354_D;// e63 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)77 extern const double E; // e 78 extern const double LOG2_E; // log_2(e) 79 extern const double LOG10_E; // log_10(e) 80 extern const double LN_2; // log_e(2) 81 extern const double LN_10; // log_e(10) 82 extern const double SQRT_2; // sqrt(2) 83 extern const double _1_SQRT_2; // 1 / sqrt(2) 69 84 70 const long double E = 2.7182818284590452353602874713526625_DL;// e71 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)85 extern const long double E; // e 86 extern const long double LOG2_E; // log_2(e) 87 extern const long double LOG10_E; // log_10(e) 88 extern const long double LN_2; // log_e(2) 89 extern const long double LN_10; // log_e(10) 90 extern const long double SQRT_2; // sqrt(2) 91 extern const long double _1_SQRT_2; // 1/sqrt(2) 77 92 78 const _Complex E = 2.7182818284590452354_D+0.0_iD;// e79 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)93 extern const _Complex E; // e 94 extern const _Complex LOG2_E; // log_2(e) 95 extern const _Complex LOG10_E; // log_10(e) 96 extern const _Complex LN_2; // log_e(2) 97 extern const _Complex LN_10; // log_e(10) 98 extern const _Complex SQRT_2; // sqrt(2) 99 extern const _Complex _1_SQRT_2; // 1 / sqrt(2) 85 100 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) 101 extern const long _Complex E; // e 102 extern const long _Complex LOG2_E; // log_2(e) 103 extern const long _Complex LOG10_E; // log_10(e) 104 extern const long _Complex LN_2; // log_e(2) 105 extern const long _Complex LN_10; // log_e(10) 106 extern const long _Complex SQRT_2; // sqrt(2) 107 extern const long _Complex _1_SQRT_2; // 1 / sqrt(2) 108 109 // Local Variables: // 110 // mode: c // 111 // tab-width: 4 // 112 // End: // -
src/libcfa/stdlib
r3aba311 r37218fc 10 10 // Created On : Thu Jan 28 17:12:35 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Mar 22 22:34:24 201613 // Update Count : 6912 // Last Modified On : Fri Apr 1 22:26:14 2016 13 // Update Count : 73 14 14 // 15 15 … … 18 18 extern "C" { 19 19 #include <stddef.h> // size_t 20 #include <math.h> // floor 20 21 } // extern "C" 21 22 … … 80 81 char abs( char ); 81 82 extern "C" { 82 int abs( int ); // use default C routine for int83 } // extern 83 int abs( int ); // use default C routine for int 84 } // extern "C" 84 85 long int abs( long int ); 85 86 long long int abs( long long int ); … … 90 91 double _Complex abs( double _Complex ); 91 92 long double _Complex abs( long double _Complex ); 93 94 //--------------------------------------- 95 96 float floor( float ); 97 extern "C" { 98 double floor( double ); // use C routine for double 99 } // extern "C" 100 long double floor( long double ); 101 102 float ceil( float ); 103 extern "C" { 104 double ceil( double ); // use C routine for double 105 } // extern "C" 106 long double ceil( long double ); 92 107 93 108 //--------------------------------------- -
src/libcfa/stdlib.c
r3aba311 r37218fc 10 10 // Created On : Thu Jan 28 17:10:29 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 23 13:26:42201613 // Update Count : 14 612 // Last Modified On : Wed Mar 30 10:48:41 2016 13 // Update Count : 149 14 14 // 15 15 … … 243 243 //--------------------------------------- 244 244 245 float floor( float v ) { return floorf( v ); } 246 long double floor( long double v ) { return floorl( v ); } 247 248 float ceil( float v ) { return ceilf( v ); } 249 long double ceil( long double v ) { return ceill( v ); } 250 251 //--------------------------------------- 252 245 253 void rand48seed( long int s ) { srand48( s ); } 246 254 char rand48() { return mrand48(); }
Note: See TracChangeset
for help on using the changeset viewer.