Changes in / [37218fc:3aba311]
- Files:
-
- 5 added
- 11 deleted
- 38 edited
-
doc/LaTeXmacros/common.tex (deleted)
-
doc/LaTeXmacros/indexstyle (deleted)
-
doc/bibliography/cfa.bib (deleted)
-
doc/refrat/Makefile (modified) (3 diffs)
-
doc/refrat/indexstyle (added)
-
doc/refrat/refrat.tex (modified) (9 diffs)
-
doc/user/Makefile (modified) (3 diffs)
-
doc/user/indexstyle (added)
-
doc/user/user.bib (added)
-
doc/user/user.tex (modified) (34 diffs)
-
src/CodeGen/CodeGenerator.cc (modified) (2 diffs)
-
src/CodeGen/CodeGenerator.h (modified) (1 diff)
-
src/GenPoly/Box.cc (modified) (32 diffs)
-
src/GenPoly/ScopedMap.h (modified) (5 diffs)
-
src/GenPoly/ScopedSet.h (deleted)
-
src/InitTweak/InitModel.h (modified) (1 diff)
-
src/Parser/ExpressionNode.cc (modified) (3 diffs)
-
src/Parser/ParseNode.h (modified) (2 diffs)
-
src/Parser/parser.cc (modified) (1 diff)
-
src/Parser/parser.yy (modified) (2 diffs)
-
src/ResolvExpr/AlternativeFinder.cc (modified) (1 diff)
-
src/ResolvExpr/AlternativeFinder.h (modified) (1 diff)
-
src/SymTab/AddVisit.h (modified) (3 diffs)
-
src/SymTab/Indexer.cc (modified) (1 diff)
-
src/SymTab/Indexer.h (modified) (1 diff)
-
src/SymTab/Validate.cc (modified) (13 diffs)
-
src/SynTree/Expression.cc (modified) (4 diffs)
-
src/SynTree/Expression.h (modified) (3 diffs)
-
src/SynTree/Mutator.cc (modified) (3 diffs)
-
src/SynTree/Mutator.h (modified) (3 diffs)
-
src/SynTree/SynTree.h (modified) (3 diffs)
-
src/SynTree/Visitor.cc (modified) (3 diffs)
-
src/SynTree/Visitor.h (modified) (3 diffs)
-
src/Tuples/FlattenTuple.cc (modified) (1 diff)
-
src/Tuples/FlattenTuple.h (modified) (1 diff)
-
src/driver/cfa.cc (modified) (3 diffs)
-
src/examples/io.c (deleted)
-
src/examples/io.data (deleted)
-
src/examples/rational.c (deleted)
-
src/examples/rational.cc (deleted)
-
src/examples/read.c (added)
-
src/examples/read.data (added)
-
src/libcfa/Makefile.am (modified) (2 diffs)
-
src/libcfa/Makefile.in (modified) (3 diffs)
-
src/libcfa/fstream (modified) (3 diffs)
-
src/libcfa/fstream.c (modified) (7 diffs)
-
src/libcfa/iostream (modified) (4 diffs)
-
src/libcfa/iostream.c (modified) (21 diffs)
-
src/libcfa/limits (modified) (1 diff)
-
src/libcfa/limits.c (deleted)
-
src/libcfa/rational (deleted)
-
src/libcfa/rational.c (deleted)
-
src/libcfa/stdlib (modified) (4 diffs)
-
src/libcfa/stdlib.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/refrat/Makefile
r37218fc r3aba311 1 1 ## Define the appropriate configuration variables. 2 2 3 TeXLIB = .:../bibliography/:../LaTeXmacros/: 3 Macros = 4 TeXLIB = .:${Macros}: 4 5 LaTeX = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex 5 BibTeX = B IBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex6 BibTeX = BSTINPUTS=${TeXLIB} && export BSTINPUTS && bibtex 6 7 7 8 ## Define the text source files. … … 43 44 dvips $< -o $@ 44 45 45 ${basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex \ 46 ../LaTeXmacros/common.tex ../LaTeXmacros/indexstyle ../bibliography/cfa.bib 46 ${basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex ${basename ${DOCUMENT}}.bib 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 ../LaTeXmacros/indexstyle ${basename $@}.idx56 makeindex -s indexstyle ${basename $@}.idx 57 57 ${LaTeX} ${basename $@}.tex 58 58 # Run again to get index title into table of contents -
doc/refrat/refrat.tex
r37218fc r3aba311 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -*- Mode: Latex -*- %%%%%%%%%%%%%%%%%%%%%%%%%%%%2 %%3 %% Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo4 %%5 %% The contents of this file are covered under the licence agreement in the6 %% file "LICENCE" distributed with Cforall.7 %%8 %% refrat.tex --9 %%10 %% Author : Peter A. Buhr11 %% Created On : Wed Apr 6 14:52:25 201612 %% Last Modified By : Peter A. Buhr13 %% Last Modified On : Fri Apr 8 18:32:07 201614 %% Update Count : 615 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%16 17 1 % requires tex packages: texlive-base texlive-latex-base tex-common texlive-humanities texlive-latex-extra texlive-fonts-recommended 18 2 … … 21 5 22 6 % Latex packages used in the document. 7 23 8 \usepackage{fullpage,times} 24 9 \usepackage{xspace} … … 36 21 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 37 22 23 % Names used in the document. 24 25 \newcommand{\CFA}{C$\forall$\xspace} % set language symbolic name 26 \newcommand{\CFL}{Cforall\xspace} % set language text name 27 \newcommand{\CC}{C\kern-.1em\hbox{+\kern-.25em+}\xspace} % CC symbolic name 28 \def\c11{ISO/IEC C} % C11 name (cannot have numbers in latex command name) 29 30 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 31 38 32 % Bespoke macros used in the document. 39 \input{common} 33 34 \makeatletter 35 % allow escape sequence in lstinline 36 %\usepackage{etoolbox} 37 %\patchcmd{\lsthk@TextStyle}{\let\lst@DefEsc\@empty}{}{}{\errmessage{failed to patch}} 38 39 \renewcommand\small{% 40 \@setfontsize\small{8.5}{11}% 41 \abovedisplayskip 8.5pt \@plus 3pt \@minus 4pt 42 \abovedisplayshortskip \z@ \@plus 2pt 43 \belowdisplayshortskip 4pt \@plus 2pt \@minus 2pt 44 \def\@listi{\leftmargin\leftmargini 45 \topsep 4pt \@plus 2pt \@minus 2pt 46 \parsep 2pt \@pluspt \@minuspt 47 \itemsep \parsep}% 48 \belowdisplayskip \abovedisplayskip 49 } 50 \usepackage{relsize} % must be after change to small 51 52 \renewcommand{\labelitemi}{{\raisebox{0.25ex}{\footnotesize$\bullet$}}} 53 \renewenvironment{itemize}{\begin{list}{\labelitemi}{\topsep=5pt\itemsep=5pt\parsep=0pt}}{\end{list}} 54 55 % Reduce size of chapter/section titles 56 \def\@makechapterhead#1{% 57 \vspace*{50\p@}% 58 {\parindent \z@ \raggedright \normalfont 59 \ifnum \c@secnumdepth >\m@ne 60 \large\bfseries \@chapapp\space \thechapter 61 \par\nobreak 62 \vskip 5\p@ 63 \fi 64 \interlinepenalty\@M 65 \Large \bfseries #1\par\nobreak 66 \vskip 50\p@ 67 }} 68 \def\@makeschapterhead#1{% 69 \vspace*{50\p@}% 70 {\parindent \z@ \raggedright 71 \normalfont 72 \interlinepenalty\@M 73 \Large \bfseries #1\par\nobreak 74 \vskip 50\p@ 75 }} 76 \renewcommand\section{\@startsection{section}{1}{\z@}{-3.0ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\large\bfseries}} 77 \renewcommand\subsection{\@startsection{subsection}{2}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}} 78 \renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}} 79 \renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}{-2.0ex \@plus -1ex \@minus -.2ex}{-1em}{\normalfont\normalsize\bfseries}} 80 81 % index macros 82 \newcommand{\italic}[1]{\emph{\hyperpage{#1}}} 83 \newcommand{\definition}[1]{\textbf{\hyperpage{#1}}} 84 \newcommand{\see}[1]{\emph{see} #1} 85 86 % Define some commands that produce formatted index entries suitable for cross-references. 87 % ``\spec'' produces entries for specifications of entities. ``\impl'' produces entries for their 88 % implementations, and ``\use'' for their uses. 89 90 % \newcommand{\bold}[1]{{\bf #1}} 91 % \def\spec{\@bsphack\begingroup 92 % \def\protect##1{\string##1\space}\@sanitize 93 % \@wrxref{|bold}} 94 \def\impl{\@bsphack\begingroup 95 \def\protect##1{\string##1\space}\@sanitize 96 \@wrxref{|definition}} 97 \newcommand{\indexcode}[1]{{\lstinline$#1$}} 98 \def\use{\@bsphack\begingroup 99 \def\protect##1{\string##1\space}\@sanitize 100 \@wrxref{|hyperpage}} 101 \def\@wrxref#1#2{\let\thepage\relax 102 \xdef\@gtempa{\write\@indexfile{\string 103 \indexentry{#2@{\lstinline$#2$}#1}{\thepage}}}\endgroup\@gtempa 104 \if@nobreak \ifvmode\nobreak\fi\fi\@esphack} 105 %\newcommand{\use}[1]{\index{#1@{\lstinline$#1$}}} 106 %\newcommand{\impl}[1]{\index{\protect#1@{\lstinline$\protect#1$}|definition}} 107 108 % inline text and lowercase index: \Index{inline and lowercase index text} 109 % inline text and as-in index: \Index[as-is index text]{inline text} 110 % inline text but index with different as-is text: \Index[index text]{inline text} 111 \newcommand{\Index}{\@ifstar\@sIndex\@Index} 112 \newcommand{\@Index}[2][\@empty]{\lowercase{\def\temp{#2}}#2\ifx#1\@empty\index{\temp}\else\index{#1@{\protect#2}}\fi} 113 \newcommand{\@sIndex}[2][\@empty]{#2\ifx#1\@empty\index{#2}\else\index{#1@{\protect#2}}\fi} 114 \makeatother 115 116 % blocks and titles 117 \newenvironment{rationale}{% 118 \begin{quotation}\noindent$\Box$\enspace 119 }{% 120 \hfill\enspace$\Box$\end{quotation} 121 }% 122 \newcommand{\define}[1]{\emph{#1\/}\index{#1}} 123 \newcommand{\rewrite}{\(\Rightarrow\)} 124 \newcommand{\rewriterules}{\paragraph{Rewrite Rules}~\par\noindent} 125 \newcommand{\examples}{\paragraph{Examples}~\par\noindent} 126 \newcommand{\semantics}{\paragraph{Semantics}~\par\noindent} 127 \newcommand{\constraints}{\paragraph{Constraints}~\par\noindent} 128 \newcommand{\predefined}{\paragraph{Predefined Identifiers}~\par\noindent} 129 130 % BNF macros 131 \def\syntax{\paragraph{Syntax}\trivlist\parindent=.5in\item[\hskip.5in]} 132 \let\endsyntax=\endtrivlist 133 \newcommand{\lhs}[1]{\par{\emph{#1:}}\index{#1@{\emph{#1}}|italic}} 134 \newcommand{\rhs}{\hfil\break\hbox{\hskip1in}} 135 \newcommand{\oldlhs}[1]{\emph{#1: \ldots}\index{#1@{\emph{#1}}|italic}} 136 \newcommand{\nonterm}[1]{\emph{#1\/}\index{#1@{\emph{#1}}|italic}} 137 \newcommand{\opt}{$_{opt}$\ } 138 139 % adjust varioref package with default "section" and "page" titles, and optional title with faraway page numbers 140 % \VRef{label} => Section 2.7, \VPageref{label} => page 17 141 % \VRef[Figure]{label} => Figure 3.4, \VPageref{label} => page 17 142 \renewcommand{\reftextfaceafter}{\unskip} 143 \renewcommand{\reftextfacebefore}{\unskip} 144 \renewcommand{\reftextafter}{\unskip} 145 \renewcommand{\reftextbefore}{\unskip} 146 \renewcommand{\reftextfaraway}[1]{\unskip, p.~\pageref{#1}} 147 \renewcommand{\reftextpagerange}[2]{\unskip, pp.~\pageref{#1}--\pageref{#2}} 148 \newcommand{\VRef}[2][Section]{\ifx#1\@empty\else{#1}\nobreakspace\fi\vref{#2}} 149 \newcommand{\VPageref}[2][page]{\ifx#1\@empty\else{#1}\nobreakspace\fi\pageref{#2}} 150 151 % CFA based on ANSI C 152 \lstdefinelanguage{CFA}[ANSI]{C}% 153 {morekeywords={asm,_Alignas,_Alignof,_At,_Atomic,_Bool,catch,catchResume,choose,_Complex,trait,disable,dtype,enable, 154 fallthru,finally,forall,ftype,_Generic,_Imaginary,inline,lvalue,_Noreturn,otype,restrict,_Static_assert, 155 _Thread_local,throw,throwResume,try,}, 156 }% 157 158 \lstset{ 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 40 182 41 183 \setcounter{secnumdepth}{3} % number subsubsections … … 84 226 85 227 This document is a reference manual and rationale for \CFA, a polymorphic extension of the C programming language. 86 It makes frequent reference to the {\c11} standard \cite{ C11}, and occasionally compares \CFA to {\CC} \cite{C++}.228 It makes frequent reference to the {\c11} standard \cite{ANS:C11}, and occasionally compares \CFA to {\CC} \cite{c++}. 87 229 88 230 The manual deliberately imitates the ordering of the {\c11} standard (although the section numbering differs). … … 578 720 579 721 There are two notable differences between \CFA's overload resolution rules and the rules for 580 {\CC} defined in \cite{ C++}.722 {\CC} defined in \cite{c++}. 581 723 First, the result type of a function plays a role. 582 724 In {\CC}, a function call must be completely resolved based on the arguments to the call in most circumstances. … … 3242 3384 \begin{itemize} 3243 3385 \item 3244 Inside a Clu cluster \cite{ CLU}, the declaration of an instance states which view applies.3386 Inside a Clu cluster \cite{clu}, the declaration of an instance states which view applies. 3245 3387 Two primitives called \lstinline$up$ and \lstinline$down$ can be used to convert between the views. 3246 3388 \item 3247 The Simula class \cite{S IMULA87} is essentially a record type.3389 The Simula class \cite{Simula87} is essentially a record type. 3248 3390 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. 3249 3391 In {\CC} 3250 \cite{ C++}, operations on class instances include assignment and ``\lstinline$&$'', which can be overloaded.3392 \cite{c++}, operations on class instances include assignment and ``\lstinline$&$'', which can be overloaded. 3251 3393 A ``scope resolution'' operator can be used inside the class to specify whether the abstract or implementation version of the operation should be used. 3252 3394 \item 3253 An Ada derived type definition \cite{ Ada} creates a new type from an old type, and also implicitly declares derived subprograms that correspond to the existing subprograms that use the old type as a parameter type or result type.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. 3254 3396 The derived subprograms are clones of the existing subprograms with the old type replaced by the derived type. 3255 3397 Literals and aggregates of the old type are also cloned. … … 3701 3843 ``\lstinline$Safe_pointer$ acts like a pointer to \lstinline$int$''. 3702 3844 \begin{lstlisting} 3703 trait ptr_to( otype P | pointer( P ), otype T ) {@\impl{ptr_to}@@\use{pointer}@3845 trait ptr_to( type P | pointer( P ), otype T ) {@\impl{ptr_to}@@\use{pointer}@ 3704 3846 lvalue T *?( P ); 3705 3847 lvalue T ?[?]( P, long int ); 3706 3848 }; 3707 trait ptr_to_const( otype P | pointer( P ), otype T ) {@\impl{ptr_to_const}@3849 trait ptr_to_const( type P | pointer( P ), otype T ) {@\impl{ptr_to_const}@ 3708 3850 const lvalue T *?( P ); 3709 3851 const lvalue T ?[?]( P, long int );@\use{pointer}@ 3710 3852 }; 3711 trait ptr_to_volatile( otype P | pointer( P ), otype T ) }@\impl{ptr_to_volatile}@3853 trait ptr_to_volatile( type P | pointer( P ), otype T ) }@\impl{ptr_to_volatile}@ 3712 3854 volatile lvalue T *?( P ); 3713 3855 volatile lvalue T ?[?]( P, long int );@\use{pointer}@ 3714 3856 }; 3715 trait ptr_to_const_volatile( otype P | pointer( P ), otype T ) }@\impl{ptr_to_const_volatile}@3857 trait ptr_to_const_volatile( type P | pointer( P ), otype T ) }@\impl{ptr_to_const_volatile}@ 3716 3858 const volatile lvalue T *?( P );@\use{pointer}@ 3717 3859 const volatile lvalue T ?[?]( P, long int ); … … 3723 3865 ``\lstinline$ptr_to$'' specifications. 3724 3866 \begin{lstlisting} 3725 trait m_l_ptr_to( otype P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to}@ otype T | ptr_to( P, T )@\use{ptr_to}@ {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}@ { 3726 3868 P ?=?( P *, T * ); 3727 3869 T * ?=?( T **, P ); 3728 3870 }; 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}@) {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}@) { 3730 3872 P ?=?( P *, const T * ); 3731 3873 const T * ?=?( const T **, P ); 3732 3874 }; 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}@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}@ 3734 3876 P ?=?( P *, volatile T * ); 3735 3877 volatile T * ?=?( volatile T **, P ); 3736 3878 }; 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}@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}@ 3739 3881 P ?=?( P *, const volatile T * ); 3740 3882 const volatile T * ?=?( const volatile T **, P ); … … 3864 4006 3865 4007 \bibliographystyle{plain} 3866 \bibliography{ cfa}4008 \bibliography{refrat} 3867 4009 3868 4010 -
doc/user/Makefile
r37218fc r3aba311 1 1 ## Define the appropriate configuration variables. 2 2 3 TeXLIB = .: ../bibliography/:../LaTeXmacros/:3 TeXLIB = .:: 4 4 LaTeX = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex 5 BibTeX = B IBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex5 BibTeX = BSTINPUTS=${TeXLIB} && export BSTINPUTS && 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 \ 46 ../LaTeXmacros/common.tex ../LaTeXmacros/indexstyle ../bibliography/cfa.bib 45 ${basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex ${basename ${DOCUMENT}}.bib /usr/local/bibliographies/pl.bib 47 46 # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run. 48 47 if [ ! -r ${basename $@}.ind ] ; then touch ${basename $@}.ind ; fi … … 54 53 -${BibTeX} ${basename $@} 55 54 # Make index from *.aux entries and input index at end of document 56 makeindex -s ../LaTeXmacros/indexstyle ${basename $@}.idx55 makeindex -s indexstyle ${basename $@}.idx 57 56 ${LaTeX} ${basename $@}.tex 58 57 # Run again to get index title into table of contents -
doc/user/user.tex
r37218fc r3aba311 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -*- Mode: Latex -*- %%%%%%%%%%%%%%%%%%%%%%%%%%%%2 %%3 %% Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo4 %%5 %% The contents of this file are covered under the licence agreement in the6 %% file "LICENCE" distributed with Cforall.7 %%8 %% user.tex --9 %%10 %% Author : Peter A. Buhr11 %% Created On : Wed Apr 6 14:53:29 201612 %% Last Modified By : Peter A. Buhr13 %% Last Modified On : Fri Apr 8 11:40:53 201614 %% Update Count : 4215 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%16 17 1 % requires tex packages: texlive-base texlive-latex-base tex-common texlive-humanities texlive-latex-extra texlive-fonts-recommended 18 2 … … 21 5 22 6 % Latex packages used in the document. 23 \usepackage[T1]{fontenc} 24 \usepackage{textcomp} 25 \usepackage[latin1]{inputenc} 26 \usepackage{upquote} 7 27 8 \usepackage{fullpage,times} 28 9 \usepackage{xspace} … … 43 24 % Names used in the document. 44 25 26 \newcommand{\CFA}{C$\forall$\xspace} % set language symbolic name 27 \newcommand{\CFL}{Cforall\xspace} % set language text name 28 \newcommand{\CC}{C\kern-.1em\hbox{+\kern-.25em+}\xspace} % CC symbolic name 29 \def\c11{ISO/IEC C} % C11 name (cannot have numbers in latex command name) 45 30 \newcommand{\CS}{C\raisebox{-0.9ex}{\large$^\sharp$}\xspace} 46 31 … … 48 33 49 34 % Bespoke macros used in the document. 50 \input{common} 35 36 \makeatletter 37 % allow escape sequence in lstinline 38 %\usepackage{etoolbox} 39 %\patchcmd{\lsthk@TextStyle}{\let\lst@DefEsc\@empty}{}{}{\errmessage{failed to patch}} 40 41 \renewcommand\small{% 42 \@setfontsize\small{8.5}{11}% 43 \abovedisplayskip 8.5pt \@plus 3pt \@minus 4pt 44 \abovedisplayshortskip \z@ \@plus 2pt 45 \belowdisplayshortskip 4pt \@plus 2pt \@minus 2pt 46 \def\@listi{\leftmargin\leftmargini 47 \topsep 4pt \@plus 2pt \@minus 2pt 48 \parsep 2pt \@pluspt \@minuspt 49 \itemsep \parsep}% 50 \belowdisplayskip \abovedisplayskip 51 } 52 \usepackage{relsize} % must be after change to small 53 54 \renewcommand{\labelitemi}{{\raisebox{0.25ex}{\footnotesize$\bullet$}}} 55 \renewenvironment{itemize}{\begin{list}{\labelitemi}{\topsep=5pt\itemsep=5pt\parsep=0pt}}{\end{list}} 56 57 % Reduce size of section titles 58 \renewcommand\section{\@startsection{section}{1}{\z@}{-3.0ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\large\bfseries}} 59 \renewcommand\subsection{\@startsection{subsection}{2}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}} 60 \renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}} 61 \renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}{-2.0ex \@plus -1ex \@minus -.2ex}{-1em}{\normalfont\normalsize\bfseries}} 62 63 % index macros 64 \newcommand{\italic}[1]{\emph{\hyperpage{#1}}} 65 \newcommand{\definition}[1]{\textbf{\hyperpage{#1}}} 66 \newcommand{\see}[1]{\emph{see} #1} 67 68 % Define some commands that produce formatted index entries suitable for cross-references. 69 % ``\spec'' produces entries for specifications of entities. ``\impl'' produces entries for their 70 % implementations, and ``\use'' for their uses. 71 72 % \newcommand{\bold}[1]{{\bf #1}} 73 % \def\spec{\@bsphack\begingroup 74 % \def\protect##1{\string##1\space}\@sanitize 75 % \@wrxref{|bold}} 76 \def\impl{\@bsphack\begingroup 77 \def\protect##1{\string##1\space}\@sanitize 78 \@wrxref{|definition}} 79 \newcommand{\indexcode}[1]{{\lstinline$#1$}} 80 \def\use{\@bsphack\begingroup 81 \def\protect##1{\string##1\space}\@sanitize 82 \@wrxref{|hyperpage}} 83 \def\@wrxref#1#2{\let\thepage\relax 84 \xdef\@gtempa{\write\@indexfile{\string 85 \indexentry{#2@{\lstinline$#2$}#1}{\thepage}}}\endgroup\@gtempa 86 \if@nobreak \ifvmode\nobreak\fi\fi\@esphack} 87 %\newcommand{\use}[1]{\index{#1@{\lstinline$#1$}}} 88 %\newcommand{\impl}[1]{\index{\protect#1@{\lstinline$\protect#1$}|definition}} 89 90 % inline text and lowercase index: \Index{inline and lowercase index text} 91 % inline text and as-in index: \Index[as-is index text]{inline text} 92 % inline text but index with different as-is text: \Index[index text]{inline text} 93 \newcommand{\Index}{\@ifstar\@sIndex\@Index} 94 \newcommand{\@Index}[2][\@empty]{\lowercase{\def\temp{#2}}#2\ifx#1\@empty\index{\temp}\else\index{#1@{\protect#2}}\fi} 95 \newcommand{\@sIndex}[2][\@empty]{#2\ifx#1\@empty\index{#2}\else\index{#1@{\protect#2}}\fi} 96 97 \newcommand{\newtermFontInline}{\emph} 98 \newcommand{\newterm}{\@ifstar\@snewterm\@newterm} 99 \newcommand{\@newterm}[2][\@empty]{\lowercase{\def\temp{#2}}{\newtermFontInline{#2}}\ifx#1\@empty\index{\temp}\else\index{#1@{\protect#2}}\fi} 100 \newcommand{\@snewterm}[2][\@empty]{{\newtermFontInline{#2}}\ifx#1\@empty\index{#2}\else\index{#1@{\protect#2}}\fi} 101 \makeatother 102 103 % blocks and titles 104 \newenvironment{quote2}{% 105 \list{}{\lstset{resetmargins=true}\leftmargin=\parindent\rightmargin\leftmargin}% 106 \item\relax 107 }{% 108 \endlist 109 }% quote2 110 \newenvironment{rationale}{% 111 \begin{quotation}\noindent$\Box$\enspace 112 }{% 113 \hfill\enspace$\Box$\end{quotation} 114 }% 115 \newcommand{\define}[1]{\emph{#1\/}\index{#1}} 116 \newcommand{\rewrite}{\(\Rightarrow\)} 117 \newcommand{\rewriterules}{\paragraph{Rewrite Rules}~\par\noindent} 118 \newcommand{\examples}{\paragraph{Examples}~\par\noindent} 119 \newcommand{\semantics}{\paragraph{Semantics}~\par\noindent} 120 \newcommand{\constraints}{\paragraph{Constraints}~\par\noindent} 121 \newcommand{\predefined}{\paragraph{Predefined Identifiers}~\par\noindent} 122 123 % BNF macros 124 \def\syntax{\paragraph{Syntax}\trivlist\parindent=.5in\item[\hskip.5in]} 125 \let\endsyntax=\endtrivlist 126 \newcommand{\lhs}[1]{\par{\emph{#1:}}\index{#1@{\emph{#1}}|italic}} 127 \newcommand{\rhs}{\hfil\break\hbox{\hskip1in}} 128 \newcommand{\oldlhs}[1]{\emph{#1: \ldots}\index{#1@{\emph{#1}}|italic}} 129 \newcommand{\nonterm}[1]{\emph{#1\/}\index{#1@{\emph{#1}}|italic}} 130 \newcommand{\opt}{$_{opt}$\ } 131 132 % adjust varioref package with default "section" and "page" titles, and optional title with faraway page numbers 133 % \VRef{label} => Section 2.7, \VPageref{label} => page 17 134 % \VRef[Figure]{label} => Figure 3.4, \VPageref{label} => page 17 135 \renewcommand{\reftextfaceafter}{\unskip} 136 \renewcommand{\reftextfacebefore}{\unskip} 137 \renewcommand{\reftextafter}{\unskip} 138 \renewcommand{\reftextbefore}{\unskip} 139 \renewcommand{\reftextfaraway}[1]{\unskip, p.~\pageref{#1}} 140 \renewcommand{\reftextpagerange}[2]{\unskip, pp.~\pageref{#1}--\pageref{#2}} 141 \newcommand{\VRef}[2][Section]{\ifx#1\@empty\else{#1}\nobreakspace\fi\vref{#2}} 142 \newcommand{\VPageref}[2][page]{\ifx#1\@empty\else{#1}\nobreakspace\fi\pageref{#2}} 143 144 % Go programming language 145 \lstdefinelanguage{Golang}% 146 {morekeywords=[1]{package,import,func,type,struct,return,defer,panic, recover,select,var,const,iota,},% 147 morekeywords=[2]{string,uint,uint8,uint16,uint32,uint64,int,int8,int16, int32,int64, 148 bool,float32,float64,complex64,complex128,byte,rune,uintptr, error,interface},% 149 morekeywords=[3]{map,slice,make,new,nil,len,cap,copy,close,true,false, delete,append,real,imag,complex,chan,},% 150 morekeywords=[4]{for,break,continue,range,goto,switch,case,fallthrough,if, else,default,},% 151 morekeywords=[5]{Println,Printf,Error,},% 152 sensitive=true,% 153 morecomment=[l]{//},% 154 morecomment=[s]{/*}{*/},% 155 morestring=[b]',% 156 morestring=[b]",% 157 morestring=[s]{`}{`},% 158 } 159 160 % CFA based on ANSI C 161 \lstdefinelanguage{CFA}[ANSI]{C}% 162 {morekeywords={asm,_Alignas,_Alignof,_At,_Atomic,_Bool,catch,catchResume,choose,_Complex,trait,disable,dtype,enable, 163 fallthru,finally,forall,ftype,_Generic,_Imaginary,inline,lvalue,_Noreturn,otype,restrict,_Static_assert, 164 _Thread_local,throw,throwResume,try,}, 165 }% 166 167 \lstset{ 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 51 192 52 193 \setcounter{secnumdepth}{3} % number subsubsections … … 225 366 226 367 The command \lstinline@cfa@ is used to compile \CFA program(s). 227 This command works like the GNU \lstinline@gcc@ \index{gcc}command, e.g.:368 This command works like the GNU \lstinline@gcc@ command, e.g.: 228 369 \begin{lstlisting} 229 370 cfa [ gcc-options ] C/@{\CFA}@-files [ assembler/loader-files ] 230 371 \end{lstlisting} 231 By default, \CFA programs having the following \lstinline@gcc@ flags turned on: 232 \begin{description} 233 \item 234 \hspace*{-4pt}\lstinline@-std=gnu99@ 235 The 1999 C standard plus GNU extensions. 236 \end{description} 237 The following new \CFA option is available: 372 The following additional option is available: 238 373 \begin{description} 239 374 \item … … 247 382 Numeric constants are extended to allow \Index{underscore}s within constants\index{constant!underscore}, e.g.: 248 383 \begin{lstlisting} 249 2 `_`147`_`483`_`648; // decimal constant384 2_147_483_648; // decimal constant 250 385 56_ul; // decimal unsigned long constant 251 386 0_377; // octal constant … … 316 451 \multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 317 452 \begin{lstlisting} 318 `* int x, y;` 453 * int x, y; 319 454 \end{lstlisting} 320 455 & … … 436 571 The point of the new syntax is to allow returning multiple values from a routine~\cite{CLU,Galletly96}, e.g.: 437 572 \begin{lstlisting} 438 `[ int o1, int o2, char o3 ]`f( int i1, char i2, char i3 ) {573 [ int o1, int o2, char o3 ] f( int i1, char i2, char i3 ) { 439 574 @\emph{routine body}@ 440 575 } … … 504 639 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: 505 640 \begin{lstlisting} 506 `[ int x ]`f() {641 [ int x ] f() { 507 642 ... x = 0; ... x = y; ... 508 `return;`// implicitly return x643 return; // implicitly return x 509 644 } 510 645 \end{lstlisting} … … 562 697 for example, the following is incorrect: 563 698 \begin{lstlisting} 564 * [ int x ] f () fp; // routine name "f"is not allowed699 * [ int x ] f () fp; // routine name ``f'' is not allowed 565 700 \end{lstlisting} 566 701 … … 729 864 \subsection{Type Nesting} 730 865 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.866 C allows \Index{type nesting}, but the nested types are hoisted\index{type!hoisting} (refactored) into the enclosing scope. 732 867 \begin{quote2} 733 868 \begin{tabular}{@{}l@{\hspace{30pt}}l|l@{}} … … 784 919 785 920 int fred() { 786 s.t.c = `S.`R; // type qualification787 struct `S.`T t = { `S.`R, 1, 2 };788 enum `S.`C c;789 union `S.T.`U u;921 s.t.c = S.R; 922 struct S.T t = { S.R, 1, 2 }; 923 enum S.C c; 924 union S.T.U u; 790 925 } 791 926 \end{lstlisting} 792 927 \end{tabular} 793 928 \end{quote2} 794 In the left example in C, types \lstinline@C@, \lstinline@U@ and \lstinline@T@ are implicitly hoisted outside of type \lstinline@S@ into the containing block scope. 795 In the right example in \CFA, the types are not hoisted and accessed using the field-selection operator ``\lstinline@.@'' for type qualification, as does Java, rather than the \CC type-selection operator ``\lstinline@::@''. 929 930 \CFA is C \emph{incompatible} on this issue, and provides semantics similar to \CC. 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. 796 933 797 934 … … 807 944 \begin{lstlisting} 808 945 const unsigned int size = 10; 809 int ia[size]; 810 ... // assign values to array ia 811 qsort( ia, size ); // sort ascending order using builtin ?<? 812 { 813 `int ?<?( int x, int y ) { return x > y; }` // nested routine 814 qsort( ia, size ); // sort descending order by local redefinition 815 } 816 \end{lstlisting} 817 818 Nested routines are not first-class, meaning a nested routine cannot be returned if it has references to variables in its enclosing blocks; 819 the only exception is references to the external block of the translation unit, as these variables persist for the duration of the program. 820 The following program in undefined in \CFA (and \lstinline@gcc@\index{gcc}) 821 \begin{lstlisting} 822 [* [int]( int )] foo() { // int (*foo())( int ) 823 int `i` = 7; 824 int bar( int p ) { 825 `i` += 1; // dependent on local variable 826 sout | `i` | endl; 827 } 828 return bar; // undefined because of local dependence 829 } 830 int main() { 831 * [int](int) fp = foo(); // int (*fp)(int) 832 sout | fp( 3 ) | endl; 833 } 834 \end{lstlisting} 835 because 836 837 Currently, there are no \Index{lambda} expressions, i.e., unnamed routines because routine names are very important to properly select the correct routine. 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} 838 954 839 955 … … 897 1013 898 1014 \item 899 Change: A struct is a scope in C++, not in C \\ 900 Rationale: Class scope is crucial to C++, and a struct is a class. \\ 901 Effect on original feature: Change to semantics of well-defined feature. \\ 902 Difficulty of converting: Semantic transformation. \\ 903 How widely used: C programs use struct extremely frequently, but the change is only noticeable when struct, enumeration, or enumerator names are referred to outside the struct. 904 The latter is probably rare. 905 906 \CFA is C \emph{incompatible} on this issue, and provides semantics similar to \CC. 907 Nested types are not hoisted and can be referenced using the field selection operator ``\lstinline@.@'', unlike the \CC scope-resolution operator ``\lstinline@::@''. 908 Given that nested types in C are equivalent to not using them, i.e., they are essentially useless, it is unlikely there are any realistic usages that break because of this incompatibility. 909 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. 910 1022 911 1023 \item … … 1073 1185 First the right-hand tuple is flattened and then the values are assigned individually. 1074 1186 Flattening is also performed on tuple types. 1075 For example, the type \lstinline@[ int, [ int, int ], int ]@ can be coerced, using flattening, into the type \lstinline@[ int, int, int, int ]@.1187 For example, the type \lstinline@[ int, [ int, int ], int ]@ can be coerced, using flattening, into the type lstinline@[ int, int, int, int ]@. 1076 1188 1077 1189 A \newterm{structuring coercion} is the opposite of flattening; … … 1240 1352 \multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 1241 1353 \begin{lstlisting} 1242 `L1:`for ( ... ) {1243 `L2:`for ( ... ) {1244 `L3:`for ( ... ) {1245 ... break `L1`; ...1246 ... break `L2`; ...1247 ... break `L3`; // or break1354 L1: for ( ... ) { 1355 L2: for ( ... ) { 1356 L3: for ( ... ) { 1357 ... break L1; ... 1358 ... break L2; ... 1359 ... break L3; // or break 1248 1360 } 1249 1361 } … … 1270 1382 \multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 1271 1383 \begin{lstlisting} 1272 `L1`: for ( ... ) {1273 `L2`: for ( ... ) {1274 `L3`: for ( ... ) {1275 ... continue `L1`; ...1276 ... continue `L2`; ...1277 ... continue `L3`; ...1384 L1: for ( ... ) { 1385 L2: for ( ... ) { 1386 L3: for ( ... ) { 1387 ... continue L1; ... 1388 ... continue L2; ... 1389 ... continue L3; ... 1278 1390 1279 1391 } … … 1511 1623 \begin{lstlisting} 1512 1624 switch ( i ) { 1513 `case 1, 3, 5`:1625 case 1, 3, 5: 1514 1626 ... 1515 `case 2, 4, 6`:1627 case 2, 4, 6: 1516 1628 ... 1517 1629 } … … 1522 1634 case 1: case 3 : case 5: 1523 1635 ... 1524 case 2: case 4 : case 6: 1636 case 2: case 4 : case 6: /* even values */ 1525 1637 ... 1526 1638 } … … 1543 1655 \begin{lstlisting} 1544 1656 switch ( i ) { 1545 `case 1~5:`1657 case 1~5 1546 1658 ... 1547 `case 10~15:`1659 case 10~15 1548 1660 ... 1549 1661 } … … 1560 1672 & 1561 1673 \begin{lstlisting} 1562 1563 1674 // 1, 2, 3, 4, 5 1564 1675 … … 2057 2168 2058 2169 2059 \section{Auto Type-Inferencing} 2060 2061 Auto type-inferencing occurs in a declaration where a variable's type is inferred from its initialization expression type. 2062 \begin{quote2} 2063 \begin{tabular}{@{}l@{\hspace{30pt}}ll@{}} 2064 \multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CC}} & \multicolumn{1}{c}{\lstinline@gcc@}\index{gcc} \\ 2065 \begin{lstlisting} 2066 2067 auto j = 3.0 * 4; 2068 int i; 2069 auto k = i; 2070 \end{lstlisting} 2071 & 2072 \begin{lstlisting} 2073 #define expr 3.0 * i 2074 typeof(expr) j = expr; 2075 int i; 2076 typeof(i) k = i; 2077 \end{lstlisting} 2078 & 2079 \begin{lstlisting} 2080 2081 // use type of initialization expression 2082 2083 // use type of primary variable 2084 \end{lstlisting} 2085 \end{tabular} 2086 \end{quote2} 2087 The two important capabilities are: 2088 \begin{itemize} 2089 \item 2090 preventing having to determine or write out long generic types, 2091 \item 2092 ensure secondary variables, related to a primary variable, always have the same type. 2093 \end{itemize} 2094 2095 In \CFA, \lstinline@typedef@ provides a mechanism to alias long type names with short ones, both globally and locally, but not eliminate the use of the short name. 2096 \lstinline@gcc@ provides \lstinline@typeof@ to declare a secondary variable from a primary variable. 2097 \CFA also relies heavily on the specification of the left-hand side of assignment for type inferencing, so in many cases it is crucial to specify the type of the left-hand side to select the correct type of the right-hand expression. 2098 Only for overloaded routines with the same return type is variable type-inferencing possible. 2099 Finally, \lstinline@auto@ presents the programming problem of tracking down a type when the type is actually needed. 2100 For example, given 2101 \begin{lstlisting} 2102 auto j = `...` 2103 \end{lstlisting} 2104 and the need to write a routine to compute using \lstinline@j@ 2105 \begin{lstlisting} 2106 void rtn( `...` parm ); 2107 rtn( j ); 2108 \end{lstlisting} 2109 A programmer must work backwards to determine the type of \lstinline@j@'s initialization expression, reconstructing the possibly long generic type-name. 2110 In this situation, having the type name or a short alias is very useful. 2111 2112 There is also the conundrum in type inferencing of when to \emph{\Index{brand}} a type. 2113 That is, when is the type of the variable more important than the type of its initialization expression. 2114 For example, if a change is made in an initialization expression, it can cause hundreds or thousands of cascading type changes and/or errors. 2115 At some point, a programmer wants the type of the variable to remain constant and the expression to be in error when it changes. 2116 2117 Given \lstinline@typedef@ and \lstinline@typeof@ in \CFA, and the strong need to use the type of left-hand side in inferencing, auto type-inferencing is not supported at this time. 2118 Should a significant need arise, this feature can be revisited. 2119 2120 2121 \section{Generics} 2170 \section{Generics } 2122 2171 2123 2172 \CFA supports parametric polymorphism to allow users to define generic functions and types. … … 2408 2457 2409 2458 2410 \section{Syntactic Anomalies} 2411 2412 The number 0 and 1 are treated specially in \CFA, and can be redefined as variables. 2413 One syntactic anomaly is when a field in an structure is names 0 or 1: 2414 \begin{lstlisting} 2415 struct S { 2416 int 0, 1; 2417 } s; 2418 \end{lstlisting} 2419 The problem occurs in accesing these fields using the selection operation ``\lstinline@.@'': 2420 \begin{lstlisting} 2421 s.0 = 0; // ambiguity with floating constant .0 2422 s.1 = 1; // ambiguity with floating constant .1 2423 \end{lstlisting} 2424 To make this work, a space is required after the field selection: 2425 \begin{lstlisting} 2426 `s.@\textvisiblespace@0` = 0; 2427 `s.@\textvisiblespace@1` = 1; 2428 \end{lstlisting} 2429 While this sytact is awkward, it is unlikely many programers will name fields of a structure 0 or 1. 2430 Like the \CC lexical problem with closing template-syntax, e.g, \lstinline@Foo<Bar<int`>>`@, this issue can be solved with a more powerful lexer/parser. 2431 2432 There are several ambiguous cases with operator identifiers, e.g., \lstinline@int *?*?()@, where the string \lstinline@*?*?@ can be lexed as \lstinline@*@/\lstinline@?*?@ or \lstinline@*?@/\lstinline@*?@. 2433 Since it is common practise to put a unary operator juxtaposed to an identifier, e.g., \lstinline@*i@, users will be annoyed if they cannot do this with respect to operator identifiers. 2434 Even with this special hack, there are 5 general cases that cannot be handled. 2435 The first case is for the function-call identifier \lstinline@?()@: 2436 \begin{lstlisting} 2437 int *@\textvisiblespace@?()(); // declaration: space required after '*' 2438 *@\textvisiblespace@?()(); // expression: space required after '*' 2439 \end{lstlisting} 2440 Without the space, the string \lstinline@*?()@ is ambiguous without N character look ahead; 2441 it requires scanning ahead to determine if there is a \lstinline@'('@, which is the start of an argument/parameter list. 2442 2443 The 4 remaining cases occur in expressions: 2444 \begin{lstlisting} 2445 i++@\textvisiblespace@?i:0; // space required before '?' 2446 i--@\textvisiblespace@?i:0; // space required before '?' 2447 i@\textvisiblespace@?++i:0; // space required after '?' 2448 i@\textvisiblespace@?--i:0; // space required after '?' 2449 \end{lstlisting} 2450 In the first two cases, the string \lstinline@i++?@ is ambiguous, where this string can be lexed as \lstinline@i@ / \lstinline@++?@ or \lstinline@i++@ / \lstinline@?@; 2451 it requires scanning ahead to determine if there is a \lstinline@'('@, which is the start of an argument list. 2452 In the second two cases, the string \lstinline@?++x@ is ambiguous, where this string can be lexed as \lstinline@?++@ / \lstinline@x@ or \lstinline@?@ / y\lstinline@++x@; 2453 it requires scanning ahead to determine if there is a \lstinline@'('@, which is the start of an argument list. 2459 \section{I/O Library} 2460 \label{s:IOLibrary} 2461 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} 2454 2654 2455 2655 … … 2476 2676 2477 2677 task creates a type with implicit locking, separate stack, and a thread 2478 2479 2678 2480 2679 \subsection{Monitors} … … 3576 3775 \multicolumn{1}{c|}{\textbf{\CFA/\CC}} & \multicolumn{1}{c|}{\textbf{Go}} & \multicolumn{1}{c}{\textbf{Rust}} \\ 3577 3776 \hline 3578 \begin{lstlisting} [boxpos=t]3777 \begin{lstlisting} 3579 3778 extern "C" { 3580 3779 #include <sys/types.h> … … 3583 3782 } 3584 3783 size_t fileSize( const char *path ) { 3585 st ruct stat s;3784 stat s; 3586 3785 stat(path, &s); 3587 3786 return s.st_size; … … 3589 3788 \end{lstlisting} 3590 3789 & 3591 \begin{lstlisting} [boxpos=t]3790 \begin{lstlisting} 3592 3791 /* 3593 3792 #cgo … … 3608 3807 \end{lstlisting} 3609 3808 & 3610 \begin{lstlisting} [boxpos=t]3809 \begin{lstlisting} 3611 3810 use libc::{c_int, size_t}; 3811 3812 // The following declarations are 3612 3813 // translated from sys/stat.h 3613 3814 #[repr(C)] … … 3617 3818 ... 3618 3819 } 3820 3619 3821 #[link(name = "libc")] 3620 3822 extern { … … 3622 3824 buf: *mut stat_t) -> c_int; 3623 3825 } 3826 3624 3827 fn fileSize(path: *const u8) -> size_t 3625 3828 { 3626 3829 unsafe { 3627 let mut buf: stat_t = uninit();3628 stat(path, &mut buf);3629 buf.st_size3830 let mut buf: stat_t = uninit(); 3831 stat(path, &mut buf); 3832 buf.st_size 3630 3833 } 3631 3834 } … … 3750 3953 3751 3954 3752 \begin{comment}3753 3955 \subsubsection{Modules/Packages} 3754 3956 … … 3830 4032 } 3831 4033 \end{lstlisting} 3832 \end{comment}3833 3834 4034 3835 4035 \subsubsection{Parallel Tasks} … … 3987 4187 \end{flushleft} 3988 4188 3989 \lstset{basicstyle=\sf\relsize{-1}}3990 3991 3992 4189 \subsection{Summary of Language Comparison} 3993 4190 … … 4058 4255 4059 4256 4060 \appendix4061 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 \item4108 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 34114 \end{lstlisting}4115 \item4116 A seperator does not appear before or after a character literal or variable.4117 \begin{lstlisting}4118 sout | '1' | '2' | '3' | endl;4119 1234120 \end{lstlisting}4121 \item4122 A seperator does not appear before or after a null (empty) C string4123 \begin{lstlisting}4124 sout | 1 | "" | 2 | "" | 3 | endl;4125 1234126 \end{lstlisting}4127 which is a local mechanism to disable insertion of the separator character.4128 \item4129 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 «84137 \end{lstlisting}4138 %$4139 \item4140 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 \item4149 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" x4155 \end{lstlisting}4156 \begin{lstlisting}[showtabs=true,aboveskip=0pt]4157 sout | "x\t" | 1 | "\tx" | endl;4158 x 1 x4159 \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 line4164 \end{lstlisting}4165 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]4166 1 2 34167 \end{lstlisting}4168 \begin{lstlisting}[mathescape=off,aboveskip=0pt,belowskip=0pt]4169 sout | 1 | sepOff | 2 | 3 | endl; // turn off implicit separator temporarily4170 \end{lstlisting}4171 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]4172 12 34173 \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 prints4176 \end{lstlisting}4177 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]4178 1234179 \end{lstlisting}4180 \begin{lstlisting}[mathescape=off,aboveskip=0pt,belowskip=0pt]4181 sout | 1 | sepOn | 2 | 3 | endl; // turn on implicit separator temporarily4182 \end{lstlisting}4183 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]4184 1 234185 \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 prints4188 \end{lstlisting}4189 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]4190 1 2 34191 \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, $34199 \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 types4209 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 file4226 open( &in, "input.data", "r" );4227 4228 &in | &c // character4229 | &si | &usi | &i | &ui | &li | &uli | &lli | &ulli // integral4230 | &f | &d | &ld // floating point4231 | &fc | &dc | &ldc // floating-point complex4232 | cstr( s1 ) | cstr( s2, 10 ); // C string, length unchecked and checked4233 4234 sout | c | ' ' | endl // character4235 | si | usi | i | ui | li | uli | lli | ulli | endl // integral4236 | f | d | ld | endl // floating point4237 | fc | dc | ldc | endl; // complex4238 sout | endl;4239 sout | f | "" | d | "" | ld | endl // floating point without separator4240 | sepDisable | fc | dc | ldc | sepEnable | endl // complex without separator4241 | sepOn | s1 | sepOff | s2 | endl // local separator removal4242 | s1 | "" | s2 | endl; // C string withou separator4243 sout | endl;4244 sepSet( sout, ", $" ); // change separator, maximum of 15 characters4245 sout | f | d | ld | endl // floating point without separator4246 | fc | dc | ldc | endl // complex without separator4247 | s1 | s2 | endl;4248 }4249 4250 $ cat input.data4251 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 xyz4252 $ a.out4253 A4254 1 2 3 4 5 6 7 84255 1.1 1.2 1.34256 1.1+2.3i 1.1-2.3i 1.1-2.3i4257 4258 1.11.21.34259 1.1+2.3i1.1-2.3i1.1-2.3i4260 abcxyz4261 abcxyz4262 4263 1.1, $1.2, $1.34264 1.1+2.3i, $1.1-2.3i, $1.1-2.3i4265 abc, $xyz4266 \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 ); // deprecated4291 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 fill4294 forall( otype T ) T * memset( T * ptr ); // remove when default value available4295 \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 int4346 } // 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 double4364 } // extern "C"4365 long double floor( long double );4366 4367 float ceil( float );4368 extern "C" {4369 double ceil( double ); // use C routine for double4370 } // 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 // implementation4414 struct Rational {4415 long int numerator, denominator; // invariant: denominator > 04416 }; // Rational4417 4418 // constants4419 extern struct Rational 0;4420 extern struct Rational 1;4421 4422 // constructors4423 Rational rational();4424 Rational rational( long int n );4425 Rational rational( long int n, long int d );4426 4427 // getter/setter for numerator/denominator4428 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 // comparison4434 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 // arithmetic4442 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 // conversion4449 double widen( Rational r );4450 Rational narrow( double f, long int md );4451 4452 // I/O4453 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, Rational * );4454 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, Rational );4455 \end{lstlisting}4456 4457 4458 4257 \bibliographystyle{plain} 4459 \bibliography{ cfa}4258 \bibliography{/usr/local/bibliographies/pl.bib} 4460 4259 4461 4260 -
src/CodeGen/CodeGenerator.cc
r37218fc r3aba311 455 455 456 456 void CodeGenerator::visit( UntypedOffsetofExpr *offsetofExpr ) { 457 assert( false && "UntypedOffsetofExpr should not reach code generation");457 assert( false ); 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" );470 466 } 471 467 -
src/CodeGen/CodeGenerator.h
r37218fc r3aba311 65 65 virtual void visit( UntypedOffsetofExpr *offsetofExpr ); 66 66 virtual void visit( OffsetofExpr *offsetofExpr ); 67 virtual void visit( OffsetPackExpr *offsetPackExpr );68 67 virtual void visit( LogicalExpr *logicalExpr ); 69 68 virtual void visit( ConditionalExpr *conditionalExpr ); -
src/GenPoly/Box.cc
r37218fc r3aba311 30 30 #include "FindFunction.h" 31 31 #include "ScopedMap.h" 32 #include "ScopedSet.h"33 32 #include "ScrubTyVars.h" 34 33 … … 63 62 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 64 63 65 /// Abstracts type equality for a list of parameter types 66 struct TypeList { 67 TypeList() : params() {} 68 TypeList( const std::list< Type* > &_params ) : params() { cloneAll(_params, params); } 69 TypeList( std::list< Type* > &&_params ) : params( _params ) {} 70 71 TypeList( const TypeList &that ) : params() { cloneAll(that.params, params); } 72 TypeList( TypeList &&that ) : params( std::move( that.params ) ) {} 64 /// Key for a unique concrete type; generic base type paired with type parameter list 65 struct ConcreteType { 66 ConcreteType() : base(NULL), params() {} 67 68 ConcreteType(AggregateDecl *_base, const std::list< Type* >& _params) : base(_base), params() { cloneAll(_params, params); } 69 70 ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); } 73 71 74 72 /// Extracts types from a list of TypeExpr* 75 TypeList( const std::list< TypeExpr* >& _params ) :params() {73 ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base), params() { 76 74 for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) { 77 75 params.push_back( (*param)->get_type()->clone() ); … … 79 77 } 80 78 81 TypeList& operator= ( const TypeList &that) {79 ConcreteType& operator= (const ConcreteType& that) { 82 80 deleteAll( params ); 83 84 81 params.clear(); 82 83 base = that.base; 85 84 cloneAll( that.params, params ); 86 85 … … 88 87 } 89 88 90 TypeList& operator= ( TypeList &&that ) { 91 deleteAll( params ); 92 93 params = std::move( that.params ); 94 95 return *this; 96 } 97 98 ~TypeList() { deleteAll( params ); } 99 100 bool operator== ( const TypeList& that ) const { 89 ~ConcreteType() { deleteAll( params ); } 90 91 bool operator== (const ConcreteType& that) const { 92 if ( base != that.base ) return false; 93 94 SymTab::Indexer dummy; 101 95 if ( params.size() != that.params.size() ) return false; 102 103 SymTab::Indexer dummy;104 96 for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) { 105 97 if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false; … … 108 100 } 109 101 102 AggregateDecl *base; ///< Base generic type 110 103 std::list< Type* > params; ///< Instantiation parameters 111 104 }; 112 105 113 /// Maps a key and a TypeListto the some value, accounting for scope114 template< typename Key, typenameValue >106 /// Maps a concrete type to the some value, accounting for scope 107 template< typename Value > 115 108 class InstantiationMap { 116 /// Wraps value for a specific (Key, TypeList) combination 117 typedef std::pair< TypeList, Value* > Instantiation; 118 /// List of TypeLists paired with their appropriate values 119 typedef std::vector< Instantiation > ValueList; 120 /// Underlying map type; maps keys to a linear list of corresponding TypeLists and values 121 typedef ScopedMap< Key*, ValueList > InnerMap; 122 123 InnerMap instantiations; ///< instantiations 109 /// Information about a specific instantiation of a generic type 110 struct Instantiation { 111 ConcreteType key; ///< Instantiation parameters for this type 112 Value *value; ///< Value for this instantiation 113 114 Instantiation() : key(), value(0) {} 115 Instantiation(const ConcreteType &_key, Value *_value) : key(_key), value(_value) {} 116 }; 117 /// Map of generic types to instantiations of them 118 typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope; 119 120 std::vector< Scope > scopes; ///< list of scopes, from outermost to innermost 124 121 125 122 public: 126 123 /// Starts a new scope 127 void beginScope() { instantiations.beginScope(); } 124 void beginScope() { 125 Scope scope; 126 scopes.push_back(scope); 127 } 128 128 129 129 /// Ends a scope 130 void endScope() { instantiations.endScope(); } 131 132 /// Gets the value for the (key, typeList) pair, returns NULL on none such. 133 Value *lookup( Key *key, const std::list< TypeExpr* >& params ) const { 134 TypeList typeList( params ); 135 136 // scan scopes for matches to the key 137 for ( typename InnerMap::const_iterator insts = instantiations.find( key ); insts != instantiations.end(); insts = instantiations.findNext( insts, key ) ) { 138 for ( typename ValueList::const_reverse_iterator inst = insts->second.rbegin(); inst != insts->second.rend(); ++inst ) { 139 if ( inst->first == typeList ) return inst->second; 130 void endScope() { 131 scopes.pop_back(); 132 } 133 134 /// Default constructor initializes with one scope 135 InstantiationMap() { beginScope(); } 136 137 // private: 138 /// Gets the value for the concrete instantiation of this type, assuming it has already been instantiated in the current scope. 139 /// Returns NULL on none such. 140 Value *lookup( AggregateDecl *generic, const std::list< TypeExpr* >& params ) { 141 ConcreteType key(generic, params); 142 // scan scopes from innermost out 143 for ( typename std::vector< Scope >::const_reverse_iterator scope = scopes.rbegin(); scope != scopes.rend(); ++scope ) { 144 // skip scope if no instantiations of this generic type 145 typename Scope::const_iterator insts = scope->find( generic ); 146 if ( insts == scope->end() ) continue; 147 // look through instantiations for matches to concrete type 148 for ( typename std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) { 149 if ( inst->key == key ) return inst->value; 140 150 } 141 151 } 142 // no matching instantiation sfound152 // no matching instantiation found 143 153 return 0; 144 154 } 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 } 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 ); } 150 168 }; 151 169 … … 179 197 virtual void doEndScope(); 180 198 private: 199 /// Makes a new temporary array holding the offsets of the fields of `type`, and returns a new variable expression referencing it 200 Expression *makeOffsetArray( StructInstType *type ); 181 201 /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application 182 202 void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ); … … 205 225 ObjectDecl *makeTemporary( Type *type ); 206 226 207 std::map< std::string, DeclarationWithType *> assignOps; ///< Currently known type variable assignment operators 208 ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps; ///< Currently known assignment operators 209 ScopedMap< std::string, DeclarationWithType* > adapters; ///< Set of adapter functions in the current scope 210 227 std::map< std::string, DeclarationWithType *> assignOps; 228 ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps; 229 ScopedMap< std::string, DeclarationWithType* > adapters; 211 230 DeclarationWithType *retval; 212 231 bool useRetval; … … 214 233 }; 215 234 216 /// * Moves polymorphic returns in function types to pointer-type parameters 217 /// * adds type size and assertion parameters to parameter lists 235 /// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well 218 236 class Pass2 : public PolyMutator { 219 237 public: … … 226 244 virtual Type *mutate( PointerType *pointerType ); 227 245 virtual Type *mutate( FunctionType *funcType ); 228 229 246 private: 230 247 void addAdapters( FunctionType *functionType ); … … 236 253 class GenericInstantiator : public DeclMutator { 237 254 /// Map of (generic type, parameter list) pairs to concrete type instantiations 238 InstantiationMap< AggregateDecl , AggregateDecl> instantiations;255 InstantiationMap< AggregateDecl > instantiations; 239 256 /// Namer for concrete types 240 257 UniqueName typeNamer; … … 261 278 }; 262 279 263 /// Replaces member and size/align/offsetof expressions on polymorphic generic types with calculated expressions. 264 /// * Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference 265 /// * Calculates polymorphic offsetof expressions from offset array 266 /// * Inserts dynamic calculation of polymorphic type layouts where needed 267 class PolyGenericCalculator : public PolyMutator { 268 public: 280 /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference; 281 /// also fixes offsetof expressions. 282 class MemberExprFixer : public PolyMutator { 283 public: 269 284 template< typename DeclClass > 270 285 DeclClass *handleDecl( DeclClass *decl, Type *type ); … … 277 292 virtual Type *mutate( FunctionType *funcType ); 278 293 virtual Expression *mutate( MemberExpr *memberExpr ); 279 virtual Expression *mutate( SizeofExpr *sizeofExpr );280 virtual Expression *mutate( AlignofExpr *alignofExpr );281 294 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 initializer289 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 returns291 bool findGeneric( Type *ty );292 /// adds type parameters to the layout call; will generate the appropriate parameters if needed293 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 sizeofName296 ScopedSet< std::string > knownOffsets; ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName297 295 }; 298 296 … … 344 342 Pass2 pass2; 345 343 GenericInstantiator instantiator; 346 PolyGenericCalculator polyCalculator;344 MemberExprFixer memberFixer; 347 345 Pass3 pass3; 348 346 … … 350 348 mutateTranslationUnit/*All*/( translationUnit, pass1 ); 351 349 mutateTranslationUnit/*All*/( translationUnit, pass2 ); 350 // instantiateGeneric( translationUnit ); 352 351 instantiator.mutateDeclarationList( translationUnit ); 353 mutateTranslationUnit/*All*/( translationUnit, polyCalculator );352 mutateTranslationUnit/*All*/( translationUnit, memberFixer ); 354 353 mutateTranslationUnit/*All*/( translationUnit, pass3 ); 355 354 } … … 654 653 655 654 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) { 656 // if this is a assignment function, put it in the map for this scope655 // if this is a polymorphic assignment function, put it in the map for this scope 657 656 if ( Type *assignedType = isAssignment( functionDecl ) ) { 658 657 if ( ! dynamic_cast< TypeInstType* >( assignedType ) ) { … … 744 743 } 745 744 745 Expression *Pass1::makeOffsetArray( StructInstType *ty ) { 746 std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members(); 747 748 // make a new temporary array 749 Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 750 std::stringstream lenGen; 751 lenGen << baseMembers.size(); 752 ConstantExpr *lenExpr = new ConstantExpr( Constant( offsetType->clone(), lenGen.str() ) ); 753 ObjectDecl *arrayTemp = makeTemporary( new ArrayType( Type::Qualifiers(), offsetType, lenExpr, false, false ) ); 754 755 // build initializer list for temporary 756 std::list< Initializer* > inits; 757 for ( std::list< Declaration* >::const_iterator member = baseMembers.begin(); member != baseMembers.end(); ++member ) { 758 DeclarationWithType *memberDecl; 759 if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) { 760 memberDecl = origMember->clone(); 761 } else { 762 memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 ); 763 } 764 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) ); 765 } 766 arrayTemp->set_init( new ListInit( inits ) ); 767 768 // return variable pointing to temporary 769 return new VariableExpr( arrayTemp ); 770 } 771 746 772 void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) { 747 773 Type *polyBase = hasPolyBase( parmType, exprTyVars ); … … 756 782 if ( dynamic_cast< StructInstType* >( polyBase ) ) { 757 783 if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) { 758 // zero-length arrays are forbidden by C, so don't pass offset for empty struct 759 if ( ! argBaseStructType->get_baseStruct()->get_members().empty() ) { 760 arg = appExpr->get_args().insert( arg, new OffsetPackExpr( argBaseStructType->clone() ) ); 761 arg++; 762 } 784 arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) ); 785 arg++; 763 786 } else { 764 787 throw SemanticError( "Cannot pass non-struct type for generic struct" ); … … 908 931 return; 909 932 } else if ( arg->get_results().front()->get_isLvalue() ) { 910 // VariableExpr and MemberExpr are lvalues; need to check this isn't coming from the second arg of a comma expression though (not an lvalue) 911 if ( CommaExpr *commaArg = dynamic_cast< CommaExpr* >( arg ) ) { 912 commaArg->set_arg2( new AddressExpr( commaArg->get_arg2() ) ); 913 } else { 914 arg = new AddressExpr( arg ); 915 } 933 // VariableExpr and MemberExpr are lvalues 934 arg = new AddressExpr( arg ); 916 935 } else { 917 936 // use type computed in unification to declare boxed variables … … 1008 1027 } // for 1009 1028 } 1029 1030 1010 1031 1011 1032 FunctionDecl *Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) { … … 1407 1428 std::list< TypeDecl* >::const_iterator forallIt = forallParams.begin(); 1408 1429 for ( ; tyIt != tyParams.end() && forallIt != forallParams.end(); ++tyIt, ++forallIt ) { 1409 // Add appropriate mapping to assignment expression environment 1430 if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue; // skip types with no assign op (ftype/dtype) 1431 1432 std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions(); 1433 assert( ! asserts.empty() && "Type param needs assignment operator assertion" ); 1434 DeclarationWithType *actualDecl = asserts.front(); 1435 TypeInstType *actualType = isTypeInstAssignment( actualDecl ); 1436 assert( actualType && "First assertion of type with assertions should be assignment operator" ); 1410 1437 TypeExpr *formalTypeExpr = dynamic_cast< TypeExpr* >( *tyIt ); 1411 1438 assert( formalTypeExpr && "type parameters must be type expressions" ); 1412 1439 Type *formalType = formalTypeExpr->get_type(); 1413 assignExpr->get_env()->add( (*forallIt)->get_name(), formalType ); 1414 1415 // skip types with no assign op (ftype/dtype) 1416 if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue; 1417 1418 // find assignment operator for formal type 1440 assignExpr->get_env()->add( actualType->get_name(), formalType ); 1441 1419 1442 DeclarationWithType *assertAssign = 0; 1420 1443 if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) { … … 1430 1453 } 1431 1454 } 1432 1433 // add inferred parameter for field assignment operator to assignment expression 1434 std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions(); 1435 assert( ! asserts.empty() && "Type param needs assignment operator assertion" ); 1436 DeclarationWithType *actualDecl = asserts.front(); 1455 1456 1437 1457 assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ] 1438 1458 = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) ); … … 1567 1587 ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, 1568 1588 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 ); 1569 1590 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { 1570 1591 ObjectDecl *sizeParm, *alignParm; … … 1610 1631 ++last; 1611 1632 1612 if ( StructInstType *polyBaseStruct = dynamic_cast< StructInstType* >( polyBase ) ) { 1613 // NOTE zero-length arrays are illegal in C, so empty structs have no offset array 1614 if ( ! polyBaseStruct->get_baseStruct()->get_members().empty() ) { 1615 offsetParm = newPtr.clone(); 1616 offsetParm->set_name( offsetofName( polyBase ) ); 1617 last = funcType->get_parameters().insert( last, offsetParm ); 1618 ++last; 1619 } 1633 if ( dynamic_cast< StructInstType* >( polyBase ) ) { 1634 offsetParm = newPtr.clone(); 1635 offsetParm->set_name( offsetofName( polyBase ) ); 1636 last = funcType->get_parameters().insert( last, offsetParm ); 1637 ++last; 1620 1638 } 1621 1639 … … 1826 1844 1827 1845 template< typename DeclClass > 1828 DeclClass * PolyGenericCalculator::handleDecl( DeclClass *decl, Type *type ) {1846 DeclClass * MemberExprFixer::handleDecl( DeclClass *decl, Type *type ) { 1829 1847 TyVarMap oldtyVars = scopeTyVars; 1830 1848 makeTyVarMap( type, scopeTyVars ); … … 1836 1854 } 1837 1855 1838 ObjectDecl * PolyGenericCalculator::mutate( ObjectDecl *objectDecl ) {1856 ObjectDecl * MemberExprFixer::mutate( ObjectDecl *objectDecl ) { 1839 1857 return handleDecl( objectDecl, objectDecl->get_type() ); 1840 1858 } 1841 1859 1842 DeclarationWithType * PolyGenericCalculator::mutate( FunctionDecl *functionDecl ) {1860 DeclarationWithType * MemberExprFixer::mutate( FunctionDecl *functionDecl ) { 1843 1861 return handleDecl( functionDecl, functionDecl->get_functionType() ); 1844 1862 } 1845 1863 1846 TypedefDecl * PolyGenericCalculator::mutate( TypedefDecl *typedefDecl ) {1864 TypedefDecl * MemberExprFixer::mutate( TypedefDecl *typedefDecl ) { 1847 1865 return handleDecl( typedefDecl, typedefDecl->get_base() ); 1848 1866 } 1849 1867 1850 TypeDecl * PolyGenericCalculator::mutate( TypeDecl *typeDecl ) {1868 TypeDecl * MemberExprFixer::mutate( TypeDecl *typeDecl ) { 1851 1869 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); 1852 1870 return Mutator::mutate( typeDecl ); 1853 1871 } 1854 1872 1855 Type * PolyGenericCalculator::mutate( PointerType *pointerType ) {1873 Type * MemberExprFixer::mutate( PointerType *pointerType ) { 1856 1874 TyVarMap oldtyVars = scopeTyVars; 1857 1875 makeTyVarMap( pointerType, scopeTyVars ); … … 1863 1881 } 1864 1882 1865 Type * PolyGenericCalculator::mutate( FunctionType *funcType ) {1883 Type * MemberExprFixer::mutate( FunctionType *functionType ) { 1866 1884 TyVarMap oldtyVars = scopeTyVars; 1867 makeTyVarMap( funcType, scopeTyVars ); 1868 1869 // make sure that any type information passed into the function is accounted for 1870 for ( std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); fnParm != funcType->get_parameters().end(); ++fnParm ) { 1871 // condition here duplicates that in Pass2::mutate( FunctionType* ) 1872 Type *polyBase = hasPolyBase( (*fnParm)->get_type(), scopeTyVars ); 1873 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) { 1874 knownLayouts.insert( sizeofName( polyBase ) ); 1875 } 1876 } 1877 1878 Type *ret = Mutator::mutate( funcType ); 1885 makeTyVarMap( functionType, scopeTyVars ); 1886 1887 Type *ret = Mutator::mutate( functionType ); 1879 1888 1880 1889 scopeTyVars = oldtyVars; … … 1882 1891 } 1883 1892 1884 Statement * PolyGenericCalculator::mutate( DeclStmt *declStmt ) {1893 Statement *MemberExprFixer::mutate( DeclStmt *declStmt ) { 1885 1894 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) { 1886 if ( findGeneric( objectDecl->get_type()) ) {1895 if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) { 1887 1896 // change initialization of a polymorphic value object 1888 1897 // to allocate storage with alloca … … 1936 1945 } 1937 1946 1938 Expression * PolyGenericCalculator::mutate( MemberExpr *memberExpr ) {1947 Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) { 1939 1948 // mutate, exiting early if no longer MemberExpr 1940 1949 Expression *expr = Mutator::mutate( memberExpr ); … … 1953 1962 Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars, &tyDepth ); 1954 1963 if ( ! objectType ) return memberExpr; 1955 findGeneric( objectType ); // ensure layout for this type is available1956 1964 1957 1965 Expression *newMemberExpr = 0; … … 1985 1993 } 1986 1994 1987 ObjectDecl *PolyGenericCalculator::makeVar( const std::string &name, Type *type, Initializer *init ) { 1988 ObjectDecl *newObj = new ObjectDecl( name, DeclarationNode::NoStorageClass, LinkageSpec::C, 0, type, init ); 1989 stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) ); 1990 return newObj; 1991 } 1992 1993 void PolyGenericCalculator::addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams ) { 1994 for ( std::list< Type* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) { 1995 if ( findGeneric( *param ) ) { 1996 // push size/align vars for a generic parameter back 1997 layoutCall->get_args().push_back( new NameExpr( sizeofName( *param ) ) ); 1998 layoutCall->get_args().push_back( new NameExpr( alignofName( *param ) ) ); 1999 } else { 2000 layoutCall->get_args().push_back( new SizeofExpr( (*param)->clone() ) ); 2001 layoutCall->get_args().push_back( new AlignofExpr( (*param)->clone() ) ); 2002 } 2003 } 2004 } 2005 2006 /// returns true if any of the otype parameters have a dynamic layout and puts all otype parameters in the output list 2007 bool findGenericParams( std::list< TypeDecl* > &baseParams, std::list< Expression* > &typeParams, std::list< Type* > &out ) { 2008 bool hasDynamicLayout = false; 2009 2010 std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin(); 2011 std::list< Expression* >::const_iterator typeParam = typeParams.begin(); 2012 for ( ; baseParam != baseParams.end() && typeParam != typeParams.end(); ++baseParam, ++typeParam ) { 2013 // skip non-otype parameters 2014 if ( (*baseParam)->get_kind() != TypeDecl::Any ) continue; 2015 TypeExpr *typeExpr = dynamic_cast< TypeExpr* >( *typeParam ); 2016 assert( typeExpr && "all otype parameters should be type expressions" ); 2017 2018 Type *type = typeExpr->get_type(); 2019 out.push_back( type ); 2020 if ( isPolyType( type ) ) hasDynamicLayout = true; 2021 } 2022 assert( baseParam == baseParams.end() && typeParam == typeParams.end() ); 2023 2024 return hasDynamicLayout; 2025 } 2026 2027 bool PolyGenericCalculator::findGeneric( Type *ty ) { 2028 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) { 2029 // duplicate logic from isPolyType() 2030 if ( env ) { 2031 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 2032 return findGeneric( newType ); 2033 } // if 2034 } // if 2035 if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() ) { 2036 // NOTE assumes here that getting put in the scopeTyVars included having the layout variables set 2037 return true; 2038 } 2039 return false; 2040 } else if ( StructInstType *structTy = dynamic_cast< StructInstType* >( ty ) ) { 2041 // check if this type already has a layout generated for it 2042 std::string sizeName = sizeofName( ty ); 2043 if ( knownLayouts.find( sizeName ) != knownLayouts.end() ) return true; 2044 2045 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized 2046 std::list< Type* > otypeParams; 2047 if ( ! findGenericParams( *structTy->get_baseParameters(), structTy->get_parameters(), otypeParams ) ) return false; 2048 2049 // insert local variables for layout and generate call to layout function 2050 knownLayouts.insert( sizeName ); // done early so as not to interfere with the later addition of parameters to the layout call 2051 Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 2052 2053 int n_members = structTy->get_baseStruct()->get_members().size(); 2054 if ( n_members == 0 ) { 2055 // all empty structs have the same layout - size 1, align 1 2056 makeVar( sizeName, layoutType, new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) ); 2057 makeVar( alignofName( ty ), layoutType->clone(), new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) ); 2058 // NOTE zero-length arrays are forbidden in C, so empty structs have no offsetof array 2059 } else { 2060 ObjectDecl *sizeVar = makeVar( sizeName, layoutType ); 2061 ObjectDecl *alignVar = makeVar( alignofName( ty ), layoutType->clone() ); 2062 ObjectDecl *offsetVar = makeVar( offsetofName( ty ), new ArrayType( Type::Qualifiers(), layoutType->clone(), new ConstantExpr( Constant::from( n_members ) ), false, false ) ); 2063 2064 // generate call to layout function 2065 UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( "__layoutof_" + structTy->get_baseStruct()->get_name() ) ); 2066 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( sizeVar ) ) ); 2067 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( alignVar ) ) ); 2068 layoutCall->get_args().push_back( new VariableExpr( offsetVar ) ); 2069 addOtypeParamsToLayoutCall( layoutCall, otypeParams ); 2070 2071 stmtsToAdd.push_back( new ExprStmt( noLabels, layoutCall ) ); 2072 } 2073 2074 return true; 2075 } else if ( UnionInstType *unionTy = dynamic_cast< UnionInstType* >( ty ) ) { 2076 // check if this type already has a layout generated for it 2077 std::string sizeName = sizeofName( ty ); 2078 if ( knownLayouts.find( sizeName ) != knownLayouts.end() ) return true; 2079 2080 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized 2081 std::list< Type* > otypeParams; 2082 if ( ! findGenericParams( *unionTy->get_baseParameters(), unionTy->get_parameters(), otypeParams ) ) return false; 2083 2084 // insert local variables for layout and generate call to layout function 2085 knownLayouts.insert( sizeName ); // done early so as not to interfere with the later addition of parameters to the layout call 2086 Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 2087 2088 ObjectDecl *sizeVar = makeVar( sizeName, layoutType ); 2089 ObjectDecl *alignVar = makeVar( alignofName( ty ), layoutType->clone() ); 2090 2091 // generate call to layout function 2092 UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( "__layoutof_" + unionTy->get_baseUnion()->get_name() ) ); 2093 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( sizeVar ) ) ); 2094 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( alignVar ) ) ); 2095 addOtypeParamsToLayoutCall( layoutCall, otypeParams ); 2096 2097 stmtsToAdd.push_back( new ExprStmt( noLabels, layoutCall ) ); 2098 2099 return true; 2100 } 2101 2102 return false; 2103 } 2104 2105 Expression *PolyGenericCalculator::mutate( SizeofExpr *sizeofExpr ) { 2106 Type *ty = sizeofExpr->get_type(); 2107 if ( findGeneric( ty ) ) { 2108 Expression *ret = new NameExpr( sizeofName( ty ) ); 2109 delete sizeofExpr; 2110 return ret; 2111 } 2112 return sizeofExpr; 2113 } 2114 2115 Expression *PolyGenericCalculator::mutate( AlignofExpr *alignofExpr ) { 2116 Type *ty = alignofExpr->get_type(); 2117 if ( findGeneric( ty ) ) { 2118 Expression *ret = new NameExpr( alignofName( ty ) ); 2119 delete alignofExpr; 2120 return ret; 2121 } 2122 return alignofExpr; 2123 } 2124 2125 Expression *PolyGenericCalculator::mutate( OffsetofExpr *offsetofExpr ) { 1995 Expression *MemberExprFixer::mutate( OffsetofExpr *offsetofExpr ) { 2126 1996 // mutate, exiting early if no longer OffsetofExpr 2127 1997 Expression *expr = Mutator::mutate( offsetofExpr ); … … 2130 2000 2131 2001 // only mutate expressions for polymorphic structs/unions 2132 Type *ty = offsetofExpr->get_type();2133 if ( ! findGeneric( ty )) return offsetofExpr;2134 2002 Type *ty = isPolyType( offsetofExpr->get_type(), scopeTyVars ); 2003 if ( ! ty ) return offsetofExpr; 2004 2135 2005 if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) { 2136 2006 // replace offsetof expression by index into offset array … … 2148 2018 } 2149 2019 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 information2156 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 type2161 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 array2169 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 it2181 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 2201 2020 ////////////////////////////////////////// Pass3 //////////////////////////////////////////////////// 2202 2021 -
src/GenPoly/ScopedMap.h
r37218fc r3aba311 17 17 #define _SCOPEDMAP_H 18 18 19 #include <cassert>20 19 #include <iterator> 21 20 #include <map> … … 165 164 void endScope() { 166 165 scopes.pop_back(); 167 assert( ! scopes.empty() );168 166 } 169 167 … … 190 188 return end(); 191 189 } 192 const_iterator find( const Key &key ) const { 193 return const_iterator( const_cast< ScopedMap< Key, Value >* >(this)->find( key ) ); 194 } 190 const_iterator find( const Key &key ) const { return const_iterator( find( key ) ); } 195 191 196 192 /// Finds the given key in the outermost scope inside the given scope where it occurs … … 204 200 return end(); 205 201 } 206 const_iterator findNext( const_iterator &it, const Key &key ) const { 207 return const_iterator( const_cast< ScopedMap< Key, Value >* >(this)->findNext( it, key ) ); 208 } 202 const_iterator findNext( const_iterator &it, const Key &key ) const { return const_iterator( findNext( it, key ) ); } 209 203 210 204 /// Inserts the given key-value pair into the outermost scope … … 214 208 } 215 209 std::pair< iterator, bool > insert( const Key &key, const Value &value ) { return insert( std::make_pair( key, value ) ); } 216 217 Value& operator[] ( const Key &key ) { 218 iterator slot = find( key ); 219 if ( slot != end() ) return slot->second; 220 return insert( key, Value() ).first->second; 221 } 210 222 211 }; 223 212 } // namespace GenPoly -
src/InitTweak/InitModel.h
r37218fc r3aba311 75 75 void visit( UntypedOffsetofExpr * ) { throw 0; } 76 76 void visit( OffsetofExpr * ) { throw 0; } 77 void visit( OffsetPackExpr * ) { throw 0; }78 77 void visit( AttrExpr * ) { throw 0; } 79 78 void visit( LogicalExpr * ) { throw 0; } -
src/Parser/ExpressionNode.cc
r37218fc r3aba311 10 10 // Created On : Sat May 16 13:17:07 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Apr 8 15:43:05201613 // Update Count : 2 9612 // Last Modified On : Sun Mar 13 12:34:38 2016 13 // Update Count : 272 14 14 // 15 15 … … 22 22 23 23 #include "ParseNode.h" 24 #include "TypeData.h"25 24 #include "SynTree/Constant.h" 26 25 #include "SynTree/Expression.h" 27 #include "SynTree/Declaration.h"28 26 #include "Common/UnimplementedError.h" 29 27 #include "parseutility.h" … … 874 872 } 875 873 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 type911 if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type912 return new CompoundLiteralExpr( newDeclWithType->get_type(), kids->build() );913 // these types do not have associated type information914 } 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 } // if923 }924 925 926 874 ExpressionNode *flattenCommas( ExpressionNode *list ) { 927 875 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) ) { -
src/Parser/ParseNode.h
r37218fc r3aba311 10 10 // Created On : Sat May 16 13:28:16 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Mon Apr 11 11:50:52 201613 // Update Count : 20512 // Last Modified On : Mon Apr 04 17:04:22 2016 13 // Update Count : 190 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 563 540 template< typename SynTreeType, typename NodeType > 564 541 void buildList( const NodeType *firstNode, std::list< SynTreeType *> &outputList ) { -
src/Parser/parser.cc
r37218fc r3aba311 5180 5180 /* Line 1806 of yacc.c */ 5181 5181 #line 374 "parser.yy" 5182 { (yyval.en) = new CompoundLiteralNode( (yyvsp[(2) - (7)].decl), new InitializerNode( (yyvsp[(5) - (7)].in), true ) ); }5182 { (yyval.en) = 0; } 5183 5183 break; 5184 5184 -
src/Parser/parser.yy
r37218fc r3aba311 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Apr 8 16:21:55201613 // Update Count : 1 50812 // Last Modified On : Thu Mar 24 16:16:16 2016 13 // Update Count : 1498 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 { $$ = new CompoundLiteralNode( $2, new InitializerNode( $5, true ) ); }374 { $$ = 0; } 375 375 | postfix_expression '{' argument_expression_list '}' // CFA 376 376 { -
src/ResolvExpr/AlternativeFinder.cc
r37218fc r3aba311 848 848 } 849 849 850 void AlternativeFinder::visit( OffsetPackExpr *offsetPackExpr ) {851 alternatives.push_back( Alternative( offsetPackExpr->clone(), env, Cost::zero ) );852 }853 854 850 void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) { 855 851 // assume no polymorphism -
src/ResolvExpr/AlternativeFinder.h
r37218fc r3aba311 59 59 virtual void visit( UntypedOffsetofExpr *offsetofExpr ); 60 60 virtual void visit( OffsetofExpr *offsetofExpr ); 61 virtual void visit( OffsetPackExpr *offsetPackExpr );62 61 virtual void visit( AttrExpr *attrExpr ); 63 62 virtual void visit( LogicalExpr *logicalExpr ); -
src/SymTab/AddVisit.h
r37218fc r3aba311 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 16:14:32 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : T hu Apr 7 14:42:21 201613 // Update Count : 511 // Last Modified By : Rob Schluntz 12 // Last Modified On : Tue Jul 14 12:26:17 2015 13 // Update Count : 4 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 > 29 39 inline void addVisit(CompoundStmt *compoundStmt, Visitor &visitor) { 30 40 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 ); 31 62 } 32 63 … … 43 74 } 44 75 45 // template< typename Visitor > 46 // inline void addVisit(CaseStmt *caseStmt, Visitor &visitor) { 47 // addVisitStatementList( caseStmt->get_statements(), visitor ); 48 // maybeAccept( caseStmt->get_condition(), visitor ); 49 // } 76 template< typename Visitor > 77 inline void addVisit(CaseStmt *caseStmt, Visitor &visitor) { 78 addVisitStatementList( caseStmt->get_statements(), visitor ); 79 maybeAccept( caseStmt->get_condition(), visitor ); 80 } 81 82 template< typename Visitor > 83 inline void addVisit(CatchStmt *cathStmt, Visitor &visitor) { 84 addVisitStatement( cathStmt->get_body(), visitor ); 85 maybeAccept( cathStmt->get_decl(), visitor ); 86 } 50 87 } // namespace SymTab 51 88 -
src/SymTab/Indexer.cc
r37218fc r3aba311 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 );351 346 } 352 347 -
src/SymTab/Indexer.h
r37218fc r3aba311 59 59 virtual void visit( UntypedOffsetofExpr *offsetofExpr ); 60 60 virtual void visit( OffsetofExpr *offsetofExpr ); 61 virtual void visit( OffsetPackExpr *offsetPackExpr );62 61 virtual void visit( AttrExpr *attrExpr ); 63 62 virtual void visit( LogicalExpr *logicalExpr ); -
src/SymTab/Validate.cc
r37218fc r3aba311 10 10 // Created On : Sun May 17 21:50:04 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Apr 7 16:45:30201613 // Update Count : 2 4312 // Last Modified On : Wed Mar 2 17:31:39 2016 13 // Update Count : 226 14 14 // 15 15 … … 40 40 #include <list> 41 41 #include <iterator> 42 #include "Common/utility.h"43 #include "Common/UniqueName.h"44 42 #include "Validate.h" 45 43 #include "SynTree/Visitor.h" 46 44 #include "SynTree/Mutator.h" 47 45 #include "SynTree/Type.h" 48 #include "SynTree/Expression.h"49 46 #include "SynTree/Statement.h" 50 47 #include "SynTree/TypeSubstitution.h" … … 52 49 #include "FixFunction.h" 53 50 // #include "ImplementationType.h" 54 #include "GenPoly/DeclMutator.h" 51 #include "Common/utility.h" 52 #include "Common/UniqueName.h" 55 53 #include "AddVisit.h" 56 54 #include "MakeLibCfa.h" … … 72 70 73 71 virtual void visit( CompoundStmt *compoundStmt ); 72 virtual void visit( IfStmt *ifStmt ); 73 virtual void visit( WhileStmt *whileStmt ); 74 virtual void visit( ForStmt *forStmt ); 74 75 virtual void visit( SwitchStmt *switchStmt ); 75 76 virtual void visit( ChooseStmt *chooseStmt ); 76 // virtual void visit( CaseStmt *caseStmt ); 77 virtual void visit( CaseStmt *caseStmt ); 78 virtual void visit( CatchStmt *catchStmt ); 77 79 private: 78 80 HoistStruct(); … … 142 144 143 145 virtual void visit( CompoundStmt *compoundStmt ); 146 virtual void visit( IfStmt *ifStmt ); 147 virtual void visit( WhileStmt *whileStmt ); 148 virtual void visit( ForStmt *forStmt ); 144 149 virtual void visit( SwitchStmt *switchStmt ); 145 150 virtual void visit( ChooseStmt *chooseStmt ); 146 // virtual void visit( CaseStmt *caseStmt ); 151 virtual void visit( CaseStmt *caseStmt ); 152 virtual void visit( CatchStmt *catchStmt ); 147 153 148 154 AutogenerateRoutines() : functionNesting( 0 ) {} … … 160 166 /// and return something if the return type is non-void. 161 167 static void checkFunctionReturns( std::list< Declaration * > & translationUnit ); 168 162 169 private: 163 170 virtual void visit( FunctionDecl * functionDecl ); … … 195 202 }; 196 203 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 210 208 EliminateTypedef::eliminateTypedef( translationUnit ); 211 209 HoistStruct::hoistStruct( translationUnit ); … … 213 211 acceptAll( translationUnit, pass2 ); 214 212 ReturnChecker::checkFunctionReturns( translationUnit ); 215 mutateAll( translationUnit, compoundliteral );216 213 AutogenerateRoutines::autogenerateRoutines( translationUnit ); 217 214 acceptAll( translationUnit, pass3 ); … … 295 292 } 296 293 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 297 306 void HoistStruct::visit( SwitchStmt *switchStmt ) { 298 307 addVisit( switchStmt, *this ); … … 303 312 } 304 313 305 // void HoistStruct::visit( CaseStmt *caseStmt ) { 306 // addVisit( caseStmt, *this ); 307 // } 314 void HoistStruct::visit( CaseStmt *caseStmt ) { 315 addVisit( caseStmt, *this ); 316 } 317 318 void HoistStruct::visit( CatchStmt *cathStmt ) { 319 addVisit( cathStmt, *this ); 320 } 308 321 309 322 void Pass1::visit( EnumDecl *enumDecl ) { … … 861 874 } 862 875 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 863 888 void AutogenerateRoutines::visit( SwitchStmt *switchStmt ) { 864 889 visitStatement( switchStmt ); … … 869 894 } 870 895 871 // void AutogenerateRoutines::visit( CaseStmt *caseStmt ) { 872 // visitStatement( caseStmt ); 873 // } 896 void AutogenerateRoutines::visit( CaseStmt *caseStmt ) { 897 visitStatement( caseStmt ); 898 } 899 900 void AutogenerateRoutines::visit( CatchStmt *cathStmt ) { 901 visitStatement( cathStmt ); 902 } 874 903 875 904 void ReturnChecker::checkFunctionReturns( std::list< Declaration * > & translationUnit ) { … … 1051 1080 } 1052 1081 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 block1071 return new VariableExpr( newtempvar );1072 }1073 1082 } // namespace SymTab 1074 1083 -
src/SynTree/Expression.cc
r37218fc r3aba311 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Apr 8 17:16:23 201613 // Update Count : 4011 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Dec 09 14:10:29 2015 13 // Update Count : 34 14 14 // 15 15 … … 22 22 23 23 #include "Type.h" 24 #include "Initializer.h"25 24 #include "Expression.h" 26 25 #include "Declaration.h" … … 212 211 213 212 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 ";235 213 236 214 if ( type ) { … … 465 443 466 444 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 484 445 485 446 std::ostream & operator<<( std::ostream & out, Expression * expr ) { -
src/SynTree/Expression.h
r37218fc r3aba311 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Apr 8 17:18:06 201613 // Update Count : 2111 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Dec 09 14:10:21 2015 13 // Update Count : 19 14 14 // 15 15 … … 362 362 }; 363 363 364 /// Expression representing a pack of field-offsets for a generic type365 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 384 364 /// AttrExpr represents an @attribute expression (like sizeof, but user-defined) 385 365 class AttrExpr : public Expression { … … 577 557 }; 578 558 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 601 559 std::ostream & operator<<( std::ostream & out, Expression * expr ); 602 560 -
src/SynTree/Mutator.cc
r37218fc r3aba311 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Apr 1 18:05:16201613 // Update Count : 1 612 // Last Modified On : Wed Mar 2 17:28:20 2016 13 // Update Count : 12 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 282 276 Expression *Mutator::mutate( AttrExpr *attrExpr ) { 283 277 mutateAll( attrExpr->get_results(), *this ); … … 340 334 mutateAll( valofExpr->get_results(), *this ); 341 335 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;349 336 } 350 337 -
src/SynTree/Mutator.h
r37218fc r3aba311 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Apr 1 17:26:56201613 // Update Count : 1012 // Last Modified On : Wed Mar 2 17:33:11 2016 13 // Update Count : 9 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 );70 69 virtual Expression* mutate( AttrExpr *attrExpr ); 71 70 virtual Expression* mutate( LogicalExpr *logicalExpr ); … … 77 76 virtual Expression* mutate( AsmExpr *asmExpr ); 78 77 virtual Expression* mutate( UntypedValofExpr *valofExpr ); 79 virtual Expression* mutate( CompoundLiteralExpr *compLitExpr );80 78 81 79 virtual Type* mutate( VoidType *basicType ); -
src/SynTree/SynTree.h
r37218fc r3aba311 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Apr 1 16:47:44201613 // Update Count : 512 // Last Modified On : Wed Mar 2 17:29:00 2016 13 // Update Count : 4 14 14 // 15 15 … … 72 72 class UntypedOffsetofExpr; 73 73 class OffsetofExpr; 74 class OffsetPackExpr;75 74 class AttrExpr; 76 75 class LogicalExpr; … … 82 81 class AsmExpr; 83 82 class UntypedValofExpr; 84 class CompoundLiteralExpr;85 83 86 84 class Type; -
src/SynTree/Visitor.cc
r37218fc r3aba311 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Apr 1 18:05:13 201613 // Update Count : 1 812 // Last Modified On : Wed Mar 2 17:29:23 2016 13 // Update Count : 16 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 237 232 void Visitor::visit( AttrExpr *attrExpr ) { 238 233 acceptAll( attrExpr->get_results(), *this ); … … 287 282 acceptAll( valofExpr->get_results(), *this ); 288 283 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 );295 284 } 296 285 -
src/SynTree/Visitor.h
r37218fc r3aba311 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Apr 1 17:26:55 201613 // Update Count : 712 // Last Modified On : Wed Mar 2 17:33:35 2016 13 // Update Count : 6 14 14 // 15 15 … … 67 67 virtual void visit( UntypedOffsetofExpr *offsetofExpr ); 68 68 virtual void visit( OffsetofExpr *offsetofExpr ); 69 virtual void visit( OffsetPackExpr *offsetPackExpr );70 69 virtual void visit( AttrExpr *attrExpr ); 71 70 virtual void visit( LogicalExpr *logicalExpr ); … … 77 76 virtual void visit( AsmExpr *asmExpr ); 78 77 virtual void visit( UntypedValofExpr *valofExpr ); 79 virtual void visit( CompoundLiteralExpr *compLitExpr );80 78 81 79 virtual void visit( VoidType *basicType ); -
src/Tuples/FlattenTuple.cc
r37218fc r3aba311 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 ); }52 51 void FlattenTuple::CollectArgs::visit( AttrExpr *expr ) { currentArgs.insert( currentArgs.end(), expr ); } 53 52 void FlattenTuple::CollectArgs::visit( LogicalExpr *expr ) { currentArgs.insert( currentArgs.end(), expr ); } -
src/Tuples/FlattenTuple.h
r37218fc r3aba311 45 45 virtual void visit( UntypedOffsetofExpr * ); 46 46 virtual void visit( OffsetofExpr * ); 47 virtual void visit( OffsetPackExpr * );48 47 virtual void visit( AttrExpr * ); 49 48 virtual void visit( LogicalExpr * ); -
src/driver/cfa.cc
r37218fc r3aba311 10 10 // Created On : Tue Aug 20 13:44:49 2002 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Apr 6 14:04:22201613 // Update Count : 1 3212 // Last Modified On : Thu Jan 28 18:24:06 2016 13 // Update Count : 127 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= gnu99";309 args[nargs] = "-std=c99"; 310 310 nargs += 1; 311 311 } // if -
src/libcfa/Makefile.am
r37218fc r3aba311 11 11 ## Created On : Sun May 31 08:54:01 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Wed Apr 6 21:10:44201614 ## Update Count : 1 2313 ## Last Modified On : Wed Mar 2 22:59:23 2016 14 ## Update Count : 119 15 15 ############################################################################### 16 16 … … 60 60 ${CC} ${CFLAGS} -c -o $@ $< 61 61 62 libs = limits stdlib iostream fstream iterator rational62 libs = stdlib iostream fstream iterator 63 63 libcfa_a_SOURCES = libcfa-prelude.c ${libs:=.c} 64 64 65 cheaders = # expat66 cfaheaders = #limits65 cheaders = # expat 66 cfaheaders = limits 67 67 include_HEADERS = ${cheaders:=.h} ${libs} ${cfaheaders} 68 68 -
src/libcfa/Makefile.in
r37218fc r3aba311 83 83 libcfa_a_AR = $(AR) $(ARFLAGS) 84 84 libcfa_a_LIBADD = 85 am__objects_1 = limits.$(OBJEXT) stdlib.$(OBJEXT) iostream.$(OBJEXT) \86 fstream.$(OBJEXT) iterator.$(OBJEXT) rational.$(OBJEXT)85 am__objects_1 = stdlib.$(OBJEXT) iostream.$(OBJEXT) fstream.$(OBJEXT) \ 86 iterator.$(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 = limits stdlib iostream fstream iterator rational215 libs = stdlib iostream fstream iterator 216 216 libcfa_a_SOURCES = libcfa-prelude.c ${libs:=.c} 217 cheaders = # expat218 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@301 299 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stdlib.Po@am__quote@ 302 300 -
src/libcfa/fstream
r37218fc r3aba311 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Apr 5 22:37:12201613 // Update Count : 8212 // Last Modified On : Wed Mar 2 15:08:14 2016 13 // Update Count : 78 14 14 // 15 15 … … 20 20 21 21 enum { separateSize = 16 }; 22 struct ofstream { 23 void *file; 24 _Bool sepDefault; 25 _Bool sepOnOff; 26 char separator[separateSize]; 27 }; // ofstream 22 struct ofstream { void *file; int separate; char separator[separateSize]; }; 28 23 29 24 _Bool sepPrt( ofstream * ); 30 25 void sepOn( ofstream * ); 31 26 void sepOff( ofstream * ); 32 void sepReset( ofstream * );33 void sepReset( ofstream *, _Bool );34 27 void sepSet( ofstream *, const char * ); 35 28 const char * sepGet( ofstream * ); 36 _BoolsepDisable( ofstream * );37 _BoolsepEnable( ofstream * );29 void sepDisable( ofstream * ); 30 void sepEnable( ofstream * ); 38 31 int fail( ofstream * ); 39 32 int flush( ofstream * ); … … 46 39 47 40 // implement context istream 48 struct ifstream { 49 void *file; 50 }; // ifstream 41 struct ifstream { void *file; }; 51 42 52 43 int fail( ifstream * is ); -
src/libcfa/fstream.c
r37218fc r3aba311 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Apr 6 17:55:27201613 // Update Count : 1 7612 // Last Modified On : Mon Feb 29 18:41:10 2016 13 // Update Count : 162 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->sepOnOff; } 30 void sepOn( ofstream * os ) { os->sepOnOff = 1; } 31 void sepOff( ofstream * os ) { os->sepOnOff = 0; } 32 void sepReset( ofstream * os ) { os->sepOnOff = os->sepDefault; } 33 void sepReset( ofstream * os, _Bool reset ) { os->sepDefault = reset; os->sepOnOff = os->sepDefault; } 29 _Bool sepPrt( ofstream * os ) { return os->separate == 1; } 30 void sepOn( ofstream * os ) { if ( os->separate != 2 ) os->separate = 1; } 31 void sepOff( ofstream * os ) { if ( os->separate != 2 ) os->separate = 0; } 34 32 void sepSet( ofstream * os, const char * s ) { 35 33 strncpy( &(os->separator[0]), s, separateSize - 1 ); … … 37 35 } // sepSet 38 36 const char * sepGet( ofstream * os ) { return &(os->separator[0]); } 39 _Bool sepDisable( ofstream *os ) { 40 _Bool temp = os->sepDefault; 41 os->sepDefault = 0; 42 sepReset( os ); 43 return temp; 44 } // sepDisable 45 _Bool sepEnable( ofstream *os ) { 46 _Bool temp = os->sepDefault; 47 os->sepDefault = 1; 48 sepReset( os ); 49 return temp; 50 } // sepEnable 37 void sepDisable( ofstream *os ) { os->separate = 2; } 38 void sepEnable( ofstream *os ) { os->separate = 0; } 51 39 52 40 int fail( ofstream * os ) { … … 61 49 FILE *file = fopen( name, mode ); 62 50 if ( file == 0 ) { // do not change unless successful 63 fprintf( stderr, IO_MSG "open output file \"%s\", ", name ); 64 perror( 0 ); 51 perror( IO_MSG "open output" ); 65 52 exit( EXIT_FAILURE ); 66 53 } // if … … 107 94 108 95 109 static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_), 1,0, { ' ', '\0' } };96 static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_), 0, { ' ', '\0' } }; 110 97 ofstream *sout = &soutFile; 111 static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_), 1,0, { ' ', '\0' } };98 static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_), 0, { ' ', '\0' } }; 112 99 ofstream *serr = &serrFile; 113 100 … … 127 114 FILE *t = fopen( name, mode ); 128 115 if ( t == 0 ) { // do not change unless successful 129 fprintf( stderr, IO_MSG "open input file \"%s\", ", name ); 130 perror( 0 ); 116 perror( IO_MSG "open input" ); 131 117 exit( EXIT_FAILURE ); 132 118 } // if … … 189 175 // Local Variables: // 190 176 // tab-width: 4 // 177 // compile-command: "cfa fstream.c" // 191 178 // End: // -
src/libcfa/iostream
r37218fc r3aba311 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Apr 5 22:32:37 201613 // Update Count : 9012 // Last Modified On : Wed Mar 2 18:05:27 2016 13 // Update Count : 85 14 14 // 15 15 … … 23 23 void sepOn( ostype * ); 24 24 void sepOff( ostype * ); 25 void sepReset( ostype * );26 void sepReset( ostype *, _Bool );27 25 void sepSet( ostype *, const char * ); 28 26 const char * sepGet( ostype * ); 29 _BoolsepDisable( ostype * );30 _BoolsepEnable( ostype * );27 void sepDisable( ostype * ); 28 void sepEnable( ostype * ); 31 29 int fail( ostype * ); 32 30 int flush( ostype * ); … … 69 67 forall( dtype ostype | ostream( ostype ) ) ostype * sepOn( ostype * ); 70 68 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 * );73 69 74 70 // writes the range [begin, end) to the given stream … … 114 110 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, long double _Complex * ); 115 111 116 struct _Istream_ cstrUC{ char * s; };117 _Istream_ cstrUC cstr( char * );118 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, _Istream_ cstrUC);112 struct _Istream_str1 { char * s; }; 113 _Istream_str1 str( char * ); 114 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, _Istream_str1 ); 119 115 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);116 struct _Istream_str2 { char * s; int size; }; 117 _Istream_str2 str( char *, int size ); 118 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, _Istream_str2 ); 123 119 124 120 #endif // __IOSTREAM_H__ -
src/libcfa/iostream.c
r37218fc r3aba311 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Apr 6 16:13:29201613 // Update Count : 2 7812 // Last Modified On : Mon Mar 7 13:51:23 2016 13 // Update Count : 227 14 14 // 15 15 … … 27 27 ostype * ?|?( ostype *os, char c ) { 28 28 prtfmt( os, "%c", c ); 29 sepOff( os );30 29 return os; 31 30 } // ?|? … … 33 32 forall( dtype ostype | ostream( ostype ) ) 34 33 ostype * ?|?( ostype *os, short int si ) { 35 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 36 sepReset( os ); 34 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os ); 37 35 prtfmt( os, "%hd", si ); 38 36 return os; … … 41 39 forall( dtype ostype | ostream( ostype ) ) 42 40 ostype * ?|?( ostype *os, unsigned short int usi ) { 43 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 44 sepReset( os ); 41 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os ); 45 42 prtfmt( os, "%hu", usi ); 46 43 return os; … … 49 46 forall( dtype ostype | ostream( ostype ) ) 50 47 ostype * ?|?( ostype *os, int i ) { 51 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 52 sepReset( os ); 48 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os ); 53 49 prtfmt( os, "%d", i ); 54 50 return os; … … 57 53 forall( dtype ostype | ostream( ostype ) ) 58 54 ostype * ?|?( ostype *os, unsigned int ui ) { 59 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 60 sepReset( os ); 55 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os ); 61 56 prtfmt( os, "%u", ui ); 62 57 return os; … … 65 60 forall( dtype ostype | ostream( ostype ) ) 66 61 ostype * ?|?( ostype *os, long int li ) { 67 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 68 sepReset( os ); 62 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os ); 69 63 prtfmt( os, "%ld", li ); 70 64 return os; … … 73 67 forall( dtype ostype | ostream( ostype ) ) 74 68 ostype * ?|?( ostype *os, unsigned long int uli ) { 75 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 76 sepReset( os ); 69 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os ); 77 70 prtfmt( os, "%lu", uli ); 78 71 return os; … … 81 74 forall( dtype ostype | ostream( ostype ) ) 82 75 ostype * ?|?( ostype *os, long long int lli ) { 83 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 84 sepReset( os ); 76 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os ); 85 77 prtfmt( os, "%lld", lli ); 86 78 return os; … … 89 81 forall( dtype ostype | ostream( ostype ) ) 90 82 ostype * ?|?( ostype *os, unsigned long long int ulli ) { 91 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 92 sepReset( os ); 83 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os ); 93 84 prtfmt( os, "%llu", ulli ); 94 85 return os; … … 97 88 forall( dtype ostype | ostream( ostype ) ) 98 89 ostype * ?|?( ostype *os, float f ) { 99 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 100 sepReset( os ); 90 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os ); 101 91 prtfmt( os, "%g", f ); 102 92 return os; … … 105 95 forall( dtype ostype | ostream( ostype ) ) 106 96 ostype * ?|?( ostype *os, double d ) { 107 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 108 sepReset( os ); 97 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os ); 109 98 prtfmt( os, "%.*lg", DBL_DIG, d ); 110 99 return os; … … 113 102 forall( dtype ostype | ostream( ostype ) ) 114 103 ostype * ?|?( ostype *os, long double ld ) { 115 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 116 sepReset( os ); 104 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os ); 117 105 prtfmt( os, "%.*Lg", LDBL_DIG, ld ); 118 106 return os; … … 122 110 ostype * ?|?( ostype *os, float _Complex fc ) { 123 111 os | crealf( fc ); 124 _Bool temp = sepDisable( os ); // disable separators within complex value 125 if ( cimagf( fc ) >= 0 ) os | '+'; // negative value prints '-' 126 os | cimagf( fc ) | 'i'; 127 sepReset( os, temp ); // reset separator 112 if ( cimagf( fc ) >= 0 ) os | '+'; 113 os | "" | cimagf( fc ) | 'i'; 128 114 return os; 129 115 } // ?|? … … 132 118 ostype * ?|?( ostype *os, double _Complex dc ) { 133 119 os | creal( dc ); 134 _Bool temp = sepDisable( os ); // disable separators within complex value 135 if ( cimag( dc ) >= 0 ) os | '+'; // negative value prints '-' 136 os | cimag( dc ) | 'i'; 137 sepReset( os, temp ); // reset separator 120 if ( cimag( dc ) >= 0 ) os | '+'; 121 os | "" | cimag( dc ) | 'i'; 138 122 return os; 139 123 } // ?|? … … 142 126 ostype * ?|?( ostype *os, long double _Complex ldc ) { 143 127 os | creall( ldc ); 144 _Bool temp = sepDisable( os ); // disable separators within complex value 145 if ( cimagl( ldc ) >= 0 ) os | '+'; // negative value prints '-' 146 os | cimagl( ldc ) | 'i'; 147 sepReset( os, temp ); // reset separator 128 if ( cimagl( ldc ) >= 0 ) os | '+'; 129 os | "" | cimagl( ldc ) | 'i'; 148 130 return os; 149 131 } // ?|? … … 152 134 ostype * ?|?( ostype *os, const char *cp ) { 153 135 enum { Open = 1, Close, OpenClose }; 154 static const unsignedchar mask[256] = {136 static const char mask[256] = { 155 137 // opening delimiters 156 138 ['('] : Open, ['['] : Open, ['{'] : Open, 157 ['$'] : Open, [ (unsigned char)'£'] : Open, [(unsigned char)'¥'] : Open, [(unsigned char)'¿'] : Open, [(unsigned char)'«'] : Open,139 ['$'] : Open, [L'£'] : Open, [L'¥'] : Open, [L'¢'] : Open, [L'¿'] : Open, [L'«'] : Open, 158 140 // closing delimiters 159 141 [','] : Close, ['.'] : Close, [':'] : Close, [';'] : Close, ['!'] : Close, ['?'] : Close, 160 142 [')'] : Close, [']'] : Close, ['}'] : Close, 161 ['%'] : Close, [ (unsigned char)'¢'] : Close, [(unsigned char)'»'] : Close,143 ['%'] : Close, [L'»'] : Close, 162 144 // opening-closing delimiters 163 145 ['\''] : OpenClose, ['`'] : OpenClose, ['"'] : OpenClose, 164 ['\f'] : OpenClose, ['\n'] : OpenClose, ['\r'] : OpenClose, ['\t'] : OpenClose, ['\v'] : OpenClose, // isspace165 146 }; // mask 166 147 … … 168 149 // null string => no separator 169 150 if ( len == 0 ) { sepOff( os ); return os; } 170 // first character IS NOT spacing or closing punctuation => add left separator 171 unsigned char ch = cp[0]; // must make unsigned 172 if ( sepPrt( os ) && mask[ ch ] != Close && mask[ ch ] != OpenClose ) { 151 // first character NOT spacing or closing punctuation => add left separator 152 if ( sepPrt( os ) && isspace( cp[0] ) == 0 && mask[ cp[0] ] != Close && mask[ cp[0] ] != OpenClose ) { 173 153 prtfmt( os, "%s", sepGet( os ) ); 174 154 } // if 175 155 // last character IS spacing or opening punctuation => turn off separator for next item 176 156 unsigned int posn = len - 1; 177 ch = cp[posn]; // must make unsigned 178 if ( mask[ ch ] == Open || mask[ ch ] == OpenClose ) { 157 if ( isspace( cp[posn] ) || mask[ cp[posn] ] == Open || mask[ cp[posn] ] == OpenClose ) { 179 158 sepOff( os ); 180 159 } else { … … 186 165 forall( dtype ostype | ostream( ostype ) ) 187 166 ostype * ?|?( ostype *os, const void *p ) { 188 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 189 sepReset( os ); 167 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); else sepOn( os ); 190 168 prtfmt( os, "%p", p ); 191 169 return os; … … 218 196 } // sepOff 219 197 220 forall( dtype ostype | ostream( ostype ) )221 ostype * sepEnable( ostype * os ) {222 sepEnable( os );223 return os;224 } // sepEnable225 226 forall( dtype ostype | ostream( ostype ) )227 ostype * sepDisable( ostype * os ) {228 sepDisable( os );229 return os;230 } // sepDisable231 232 198 //--------------------------------------- 233 199 … … 344 310 } // ?|? 345 311 346 _Istream_ cstrUC cstr( char * s ) { _Istream_cstrUCs = { 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 } // cstr352 353 _Istream_ cstrC cstr( char * s, int size ) { _Istream_cstrCs = { s, size }; return s; }354 forall( dtype istype | istream( istype ) ) 355 istype * ?|?( istype * is, _Istream_ cstrC cstr ) {312 _Istream_str1 str( char * s ) { _Istream_str1 s = { s }; return s; } 313 forall( dtype istype | istream( istype ) ) 314 istype * ?|?( istype * is, _Istream_str1 str ) { 315 scanfmt( is, "%s", str.s ); 316 return is; 317 } // str 318 319 _Istream_str2 str( char * s, int size ) { _Istream_str2 s = { s, size }; return s; } 320 forall( dtype istype | istream( istype ) ) 321 istype * ?|?( istype * is, _Istream_str2 str ) { 356 322 char buf[16]; 357 sprintf( buf, "%%%ds", cstr.size );358 scanfmt( is, buf, cstr.s );359 return is; 360 } // cstr323 sprintf( buf, "%%%ds", str.size ); 324 scanfmt( is, buf, str.s ); 325 return is; 326 } // str 361 327 362 328 // Local Variables: // -
src/libcfa/limits
r37218fc r3aba311 1 //2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo3 //4 // The contents of this file are covered under the licence agreement in the5 // file "LICENCE" distributed with Cforall.6 //7 // limits --8 //9 // Author : Peter A. Buhr10 // Created On : Wed Apr 6 18:06:52 201611 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Apr 6 21:08:16 201613 // Update Count : 614 //15 16 1 // Integral Constants 17 2 18 extern const short int MIN;19 extern const int MIN;20 extern const long int MIN;21 extern const long long int MIN;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; 22 7 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;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; 31 16 32 17 // Floating-Point Constants 33 18 34 extern const float PI;// pi35 extern const float PI_2;// pi / 236 extern const float PI_4;// pi / 437 extern const float _1_PI;// 1 / pi38 extern const float _2_PI;// 2 / pi39 extern const float _2_SQRT_PI;// 2 / sqrt(pi)19 const float PI = 3.141592_F; // pi 20 const float PI_2 = 1.570796_F; // pi / 2 21 const float PI_4 = 0.7853981_F; // pi / 4 22 const float _1_PI = 0.3183098_F; // 1 / pi 23 const float _2_PI = 0.6366197_F; // 2 / pi 24 const float _2_SQRT_PI = 1.128379_F; // 2 / sqrt(pi) 40 25 41 extern const double PI;// pi42 extern const double PI_2;// pi / 243 extern const double PI_4;// pi / 444 extern const double _1_PI;// 1 / pi45 extern const double _2_PI;// 2 / pi46 extern const double _2_SQRT_PI;// 2 / sqrt(pi)26 const double PI = 3.14159265358979323846_D; // pi 27 const double PI_2 = 1.57079632679489661923_D; // pi / 2 28 const double PI_4 = 0.78539816339744830962_D; // pi / 4 29 const double _1_PI = 0.31830988618379067154_D; // 1 / pi 30 const double _2_PI = 0.63661977236758134308_D; // 2 / pi 31 const double _2_SQRT_PI = 1.12837916709551257390_D; // 2 / sqrt(pi) 47 32 48 extern const long double PI;// pi49 extern const long double PI_2;// pi / 250 extern const long double PI_4;// pi / 451 extern const long double _1_PI;// 1 / pi52 extern const long double _2_PI;// 2 / pi53 extern const long double _2_SQRT_PI;// 2 / sqrt(pi)33 const long double PI = 3.1415926535897932384626433832795029_DL; // pi 34 const long double PI_2 = 1.5707963267948966192313216916397514_DL; // pi / 2 35 const long double PI_4 = 0.7853981633974483096156608458198757_DL; // pi / 4 36 const long double _1_PI = 0.3183098861837906715377675267450287_DL; // 1 / pi 37 const long double _2_PI = 0.6366197723675813430755350534900574_DL; // 2 / pi 38 const long double _2_SQRT_PI = 1.1283791670955125738961589031215452_DL; // 2 / sqrt(pi) 54 39 55 extern const _Complex PI;// pi56 extern const _Complex PI_2;// pi / 257 extern const _Complex PI_4;// pi / 458 extern const _Complex _1_PI;// 1 / pi59 extern const _Complex _2_PI;// 2 / pi60 extern const _Complex _2_SQRT_PI;// 2 / sqrt(pi)40 const _Complex PI = 3.14159265358979323846_D+0.0_iD; // pi 41 const _Complex PI_2 = 1.57079632679489661923_D+0.0_iD; // pi / 2 42 const _Complex PI_4 = 0.78539816339744830962_D+0.0_iD; // pi / 4 43 const _Complex _1_PI = 0.31830988618379067154_D+0.0_iD; // 1 / pi 44 const _Complex _2_PI = 0.63661977236758134308_D+0.0_iD; // 2 / pi 45 const _Complex _2_SQRT_PI = 1.12837916709551257390_D+0.0_iD; // 2 / sqrt(pi) 61 46 62 extern const long _Complex PI;// pi63 extern const long _Complex PI_2;// pi / 264 extern const long _Complex PI_4;// pi / 465 extern const long _Complex _1_PI;// 1 / pi66 extern const long _Complex _2_PI;// 2 / pi67 extern const long _Complex _2_SQRT_PI;// 2 / sqrt(pi)47 const long _Complex PI = 3.1415926535897932384626433832795029_L+0.0iL; // pi 48 const long _Complex PI_2 = 1.5707963267948966192313216916397514_L+0.0iL; // pi / 2 49 const long _Complex PI_4 = 0.7853981633974483096156608458198757_L+0.0iL; // pi / 4 50 const long _Complex _1_PI = 0.3183098861837906715377675267450287_L+0.0iL; // 1 / pi 51 const long _Complex _2_PI = 0.6366197723675813430755350534900574_L+0.0iL; // 2 / pi 52 const long _Complex _2_SQRT_PI = 1.1283791670955125738961589031215452_L+0.0iL; // 2 / sqrt(pi) 68 53 69 extern const float E;// e70 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)54 const float E = 2.718281; // e 55 const float LOG2_E = 1.442695; // log_2(e) 56 const float LOG10_E = 0.4342944; // log_10(e) 57 const float LN_2 = 0.6931471; // log_e(2) 58 const float LN_10 = 2.302585; // log_e(10) 59 const float SQRT_2 = 1.414213; // sqrt(2) 60 const float _1_SQRT_2 = 0.7071067; // 1 / sqrt(2) 76 61 77 extern const double E;// e78 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)62 const double E = 2.7182818284590452354_D; // e 63 const double LOG2_E = 1.4426950408889634074_D; // log_2(e) 64 const double LOG10_E = 0.43429448190325182765_D; // log_10(e) 65 const double LN_2 = 0.69314718055994530942_D; // log_e(2) 66 const double LN_10 = 2.30258509299404568402_D; // log_e(10) 67 const double SQRT_2 = 1.41421356237309504880_D; // sqrt(2) 68 const double _1_SQRT_2 = 0.70710678118654752440_D; // 1 / sqrt(2) 84 69 85 extern const long double E;// e86 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)70 const long double E = 2.7182818284590452353602874713526625_DL; // e 71 const long double LOG2_E = 1.4426950408889634073599246810018921_DL; // log_2(e) 72 const long double LOG10_E = 0.4342944819032518276511289189166051_DL; // log_10(e) 73 const long double LN_2 = 0.6931471805599453094172321214581766_DL; // log_e(2) 74 const long double LN_10 = 2.3025850929940456840179914546843642_DL; // log_e(10) 75 const long double SQRT_2 = 1.4142135623730950488016887242096981_DL; // sqrt(2) 76 const long double _1_SQRT_2 = 0.7071067811865475244008443621048490_DL; // 1/sqrt(2) 92 77 93 extern const _Complex E;// e94 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)78 const _Complex E = 2.7182818284590452354_D+0.0_iD; // e 79 const _Complex LOG2_E = 1.4426950408889634074_D+0.0_iD; // log_2(e) 80 const _Complex LOG10_E = 0.43429448190325182765_D+0.0_iD; // log_10(e) 81 const _Complex LN_2 = 0.69314718055994530942_D+0.0_iD; // log_e(2) 82 const _Complex LN_10 = 2.30258509299404568402_D+0.0_iD; // log_e(10) 83 const _Complex SQRT_2 = 1.41421356237309504880_D+0.0_iD; // sqrt(2) 84 const _Complex _1_SQRT_2 = 0.70710678118654752440_D+0.0_iD; // 1 / sqrt(2) 100 85 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: // 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) -
src/libcfa/stdlib
r37218fc r3aba311 10 10 // Created On : Thu Jan 28 17:12:35 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Apr 1 22:26:14 201613 // Update Count : 7312 // Last Modified On : Tue Mar 22 22:34:24 2016 13 // Update Count : 69 14 14 // 15 15 … … 18 18 extern "C" { 19 19 #include <stddef.h> // size_t 20 #include <math.h> // floor21 20 } // extern "C" 22 21 … … 81 80 char abs( char ); 82 81 extern "C" { 83 int abs( int ); // use default C routine for int84 } // extern "C"82 int abs( int ); // use default C routine for int 83 } // extern 85 84 long int abs( long int ); 86 85 long long int abs( long long int ); … … 91 90 double _Complex abs( double _Complex ); 92 91 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 double99 } // extern "C"100 long double floor( long double );101 102 float ceil( float );103 extern "C" {104 double ceil( double ); // use C routine for double105 } // extern "C"106 long double ceil( long double );107 92 108 93 //--------------------------------------- -
src/libcfa/stdlib.c
r37218fc r3aba311 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 30 10:48:41201613 // Update Count : 14 912 // Last Modified On : Wed Mar 23 13:26:42 2016 13 // Update Count : 146 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 253 245 void rand48seed( long int s ) { srand48( s ); } 254 246 char rand48() { return mrand48(); }
Note:
See TracChangeset
for help on using the changeset viewer.