%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -*- Mode: Latex -*- %%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo %% %% The contents of this file are covered under the licence agreement in the %% file "LICENCE" distributed with Cforall. %% %% user.tex -- %% %% Author : Peter A. Buhr %% Created On : Wed Apr 6 14:53:29 2016 %% Last Modified By : Peter A. Buhr %% Last Modified On : Tue Oct 22 17:45:48 2024 %% Update Count : 6068 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % requires tex packages: texlive-base texlive-latex-base tex-common texlive-humanities texlive-latex-extra texlive-fonts-recommended \documentclass[11pt]{article} \makeatletter \def\@maketitle{% \newpage \null % \vskip 2em% \begin{center}% \let \footnote \thanks {\LARGE\bf \@title \par}% \@ifundefined{@author}{} { \ifx\@empty\@author \else \vskip 1.5em% {\large \lineskip .5em% \begin{tabular}[t]{c}% \@author \end{tabular}% \par }% \fi }% \ifx\@empty\@date \else \vskip 1em% {\large \@date}% \fi \end{center}% \par % \vskip 1.5em }%maketitle \makeatother %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Latex packages used in the document. %\usepackage[T1]{fontenc} % allow Latin1 (extended ASCII) characters %\usepackage{textcomp} %\usepackage[latin1]{inputenc} \usepackage{fullpage,times,comment} \usepackage{epic,eepic} \usepackage{upquote} % switch curled `'" to straight \usepackage[labelformat=simple,aboveskip=0pt,farskip=0pt]{subfig} \renewcommand{\thesubfigure}{\alph{subfigure})} \usepackage{latexsym} % \Box glyph \usepackage{mathptmx} % better math font with "times" \usepackage[usenames]{color} \usepackage[pagewise]{lineno} \renewcommand{\linenumberfont}{\scriptsize\sffamily} \input{common} % common CFA document macros \usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref} \usepackage{breakurl} \renewcommand\footnoterule{\kern -3pt\rule{0.3\linewidth}{0.15pt}\kern 2pt} \newcommand{\uC}{$\mu$\CC} % Default underscore is too low and wide. Cannot use lstlisting "literate" as replacing underscore % removes it as a variable-name character so keywords in variables are highlighted. MUST APPEAR % AFTER HYPERREF. \renewcommand{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.075ex}}} \setlength{\topmargin}{-0.45in} % move running title into header \setlength{\headsep}{0.25in} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \setlength{\gcolumnposn}{3in} \CFAStyle % use default CFA format-style \lstset{language=CFA} % CFA default lnaguage \lstnewenvironment{C++}[1][] % use C++ style {\lstset{language=C++,escapechar=\$,mathescape=false,moredelim=**[is][\protect\color{red}]{@}{@},#1}}{} \lstnewenvironment{uC++}[1][] {\lstset{language=uC++,escapechar=\$,mathescape=false,moredelim=**[is][\protect\color{red}]{@}{@},#1}}{} \newsavebox{\myboxA} \newsavebox{\myboxB} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Names used in the document. \newcommand{\Version}{\input{build/version}} \newcommand{\Textbf}[2][red]{{\color{#1}{\textbf{#2}}}} \newcommand{\Emph}[2][red]{{\color{#1}\textbf{\emph{#2}}}} \newcommand{\R}[1]{{\color{red}#1}} \newcommand{\RB}[1]{\Textbf{#1}} \newcommand{\B}[1]{{\Textbf[blue]{#1}}} \newcommand{\G}[1]{{\Textbf[OliveGreen]{#1}}} \newcommand{\Sp}{\R{\textvisiblespace}} \newcommand{\KWC}{K-W C\xspace} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \setcounter{secnumdepth}{3} % number subsubsections \setcounter{tocdepth}{3} % subsubsections in table of contents \makeindex %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \title{\vspace*{-0.5in} \uC to \CFA Cheat Sheet} %\author{Peter A. Buhr} \date{} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{document} \pagestyle{headings} % changed after setting pagestyle \renewcommand{\sectionmark}[1]{\markboth{\thesection\quad #1}{\thesection\quad #1}} \renewcommand{\subsectionmark}[1]{\markboth{\thesubsection\quad #1}{\thesubsection\quad #1}} %\linenumbers % comment out to turn off line numbering \maketitle \vspace*{-0.55in} \section{Introduction} \CFA is NOT an object-oriented programming-language. \CFA uses parametric polymorphism and allows overloading of variables and routines: \begin{cfa} int i; char i; double i; $\C[2in]{// overload name i}$ int i(); double i(); char i(); i += 1; $\C{// int i}$ i += 1.0; $\C{// double i}$ i += 'a'; $\C{// char i}$ int j = i(); $\C{// int i()}$ double j = i(); $\C{// double i();}$ char j = i(); $\C{// char i()}\CRT$ \end{cfa} \CFA has rebindable references. \begin{cquote} \begin{tabular}{@{}l|l@{}} \multicolumn{2}{@{}l}{\lstinline{ int x = 1, y = 2, * p1x = &x, * p1y = &y, ** p2i = &p1x,}} \\ \multicolumn{2}{@{}l}{\lstinline{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ & r1x = x, & r1y = y, && r2i = r1x;}} \\ \begin{uC++} **p2i = 3; p2i = &p1y; **p2i = 3; p1x = p1y; **p2i = 4; p1x = @nullptr@; \end{uC++} & \begin{cfa} r2i = 3; $\C[1.0in]{// change x}$ &r2i = &r1y; $\C{// change p2i / r2i}$ r2i = 3; $\C{// change y}$ &r1x = &r1y; $\C{// change p1x / r1x}$ r2i = 4; $\C{// change y}$ &r1x = @0p@; $\C{// reset}\CRT$ \end{cfa} \end{tabular} \end{cquote} Non-rebindable reference (\CC reference) is a @const@ reference (@const@ pointer). \begin{cfa} int & @const@ cr = x; // must initialize, no null pointer int & @const@ & @const@ crcr = cr; // generalize \end{cfa} Aggregate qualification is reduced or eliminated by opening scopes using the @with@ clause. \begin{cfa} struct S { int i; int j; double m; }; // field i has same type in structures S and T struct T { int i; int k; int m; }; void foo( S s, T t ) @with( s, t )@ { // open structure scope s and t in parallel j + k; $\C[1.6in]{// unambiguous, s.j + t.k}$ m = 5.0; $\C{// unambiguous, s.m = 5.0}$ m = 1; $\C{// unambiguous, t.m = 1}$ int a = m; $\C{// unambiguous, a = t.m}$ double b = m; $\C{// unambiguous, b = s.m}$ int c = s.i + t.i; $\C{// unambiguous with qualification}$ (double)m; $\C{// unambiguous with cast s.m}\CRT$ } \end{cfa} \noindent In subsequent code examples, the left example is \uC and the right example is \CFA. \section{Stream I/O} \CFA output streams automatically separate values and insert a newline at the end of the print. \begin{cquote} \begin{tabular}{@{}l|l@{}} \begin{uC++} #include <@iostream@> using namespace std; int i; double d; char c; cin >> i >> d >> c; cout << i << ' ' << d << ' ' << c | endl; \end{uC++} & \begin{cfa} #include <@fstream.hfa@> int i; double d; char c; sin | i | d | c; sout | i | d | c \end{cfa} \end{tabular} \end{cquote} \section{Looping} \begin{cquote} \begin{tabular}{@{}l|l@{}} \begin{uC++} for ( @;;@ ) { ... } / while ( @true@ ) { ... } for ( int i = 0; i < @10@; i += 1 ) { ... } for ( int i = @5@; i < @15@; i += @2@ ) { ... } for ( int i = -1; i <@=@ 10; i += 3 ) { ... } for ( int i = 10; i > 0; i @-@= 1 ) { ... } \end{uC++} & \begin{cfa} for () { ... } / while () { ... } for ( @10@ ) { ... } / for ( i; @10@ ) { ... } for ( i; @5@ ~ @15@ ~ @2@ ) { ... } for ( i; -1 ~@=@ 10 ~ 3 ) { ... } for ( i; 0 @-@~ 10 ) { ... } \end{cfa} \\ \hline \begin{uC++} int i = 0 for ( i = 0; i < 10; i += 1 ) { ... } @if ( i == 10 )@ { ... } \end{uC++} & \begin{cfa} for ( i; 10 ) { ... } @else@ { ... } // i == 10 \end{cfa} \\ \hline \begin{uC++} @L1:@ for ( ;; ) { @L2:@ for ( ;; ) { ... if ( ... ) @break L1@; ... ... if ( ... ) @break L2@; ... } } \end{uC++} & \begin{cfa} @L1:@ for () { @L2:@ for () { ... if ( ... ) @break L1@; ... ... if ( ... ) @break L2@; ... } } \end{cfa} \end{tabular} \end{cquote} \section{Exception} Currently, \CFA uses macros @ExceptionDecl@ and @ExceptionInst@ to declare and instantiate an exception. \begin{cquote} \begin{tabular}{@{}l|ll@{}} \begin{uC++} @_Exception@ E { // local or global scope ... // exception fields }; try { ... if ( ... ) @_Resume@ E( /* initialization */ ); if ( ... ) @_Throw@ E( /* initialization */ ); ... } @_CatchResume@( E & ) { ... // reference } catch( E & ) { ... } catch( ... ) { ... // catch any } _Finally { ... } \end{uC++} & \begin{cfa} #include @ExceptionDecl@( E, // must be global scope ... // exception fields ); try { ... if ( ... ) @throwResume@ @ExceptionInst@( E, /* intialization */ ); if ( ... ) @throw@ @ExceptionInst@( E, /* intialization */ ); ... } @catchResume@( E * ) { ... // pointer } catch( E * ) { ... } catch( exception_t * ) { ... // catch any } finally { ... } \end{cfa} \end{tabular} \end{cquote} \section{Non-local Exception} \begin{cquote} \begin{tabular}{@{}l|ll@{}} \begin{uC++} void main() { try { _Enable { ... suspend(); ... } } @_CatchResume@( E & ) { // reference ... } catch( E & ) { ... } } \end{uC++} & \begin{cfa} #define resumePoll( coroutine ) resume( coroutine ); checked_poll() #define suspendPoll suspend; checked_poll() void main() { try { enable_ehm(); ... suspendPoll ... disable_ehm(); } @catchResume@( E * ) { // pointer ... } catch( E & ) { ... } } \end{cfa} \end{tabular} \end{cquote} \section{\texorpdfstring{Structures (object-oriented \protect\vs routine style)}{Structures (object-oriented vs. routine style)}} \begin{cquote} \begin{tabular}{@{}l|l@{}} \begin{uC++} struct S { int i = 0; // cheat, implicit default constructor int setter( int j ) { int t = i; i = j; return t; } int getter() { return i; } }; S s; @s.@setter( 3 ); // object calls int k = @s.@getter(); \end{uC++} & \begin{cfa} struct S { int i; }; void ?{}( S & s ) { s.i = 0; } // explicit default constructor int setter( @S & s,@ int j ) @with( s )@ { int t = i; i = j; return t; } int getter( @S & s@ ) @with( s )@ { return i; } S s; setter( @s,@ 3 ); // normal calls int k = getter( @s@ ); \end{cfa} \end{tabular} \end{cquote} \section{Constructor / Destructor} \begin{cquote} \begin{tabular}{@{}l|l@{}} \begin{uC++} struct S { int i, j; S( int i, int j ) { S::i = i; S::j = j; } ~S() {} }; S s = { 1, 2 }, s2{ 1, 2 }; S * s3 = new S{ 1, 2 }; S & s4 = *new S{ 1, 2 }; \end{uC++} & \begin{cfa} #include // malloc struct S { int i, j; }; void ?{}( S & s, int i, int j ) { s.[i, j] = [i, j]; } void ^?{}( S & s ) {} S s = { 1, 2 }, s2{ 1, 2 }; S * s3 = &(*malloc()){ 1, 2 }; S & s4 = (*malloc()){ 1, 2 }; // fails \end{cfa} \end{tabular} \end{cquote} \section{String} \begin{cquote} \begin{tabular}{@{}l|l@{}} \multicolumn{2}{@{}l@{}}{\lstinline{string s1, s2;}} \\ \begin{uC++} s1 = "abcdefg"; s2 = s1; s1 += s2; s1 == s2; s1 != s2; s1 < s2; s1 <= s2; s1 > s2; s1 >= s2; s1.length(); s1[3]; s1.substr( 2 ); s1.substr( 2, 3 ); s1.replace( 2, 5, s2 ); s1.find( s2 ); s1.rfind( s2 ); s1.find_first_of( s2 ); s1.find_last_of( s2 ); s1.find_first_not_of( s2 ); s1.find_last_not_of( s2 ); getline( cin, s1 ); cout << s1 << endl; \end{uC++} & \begin{cfa} s1 = "abcdefg"; s2 = s1; s1 += s2; s1 == s2; s1 != s2; s1 < s2; s1 <= s2; s1 > s2; s1 >= s2; size( s1 ); s1[3]; s1( 2 ); s1( 2, 3 ); // replace( s1, 2, 5, s2 ); // find( s1, s2 ), rfind( s1, s2 ); // find_first_of( s2 ); find_last_of( s2 ); // find_first_not_of( s1, s2 ); find_last_not_of( s1, s2 ); sin | getline( s1 ); sout | s1; \end{cfa} \end{tabular} \end{cquote} \section{\texorpdfstring{\lstinline{uArray}}{uArray}} \begin{cquote} \begin{tabular}{@{}l|l@{}} \begin{uC++} #include using namespace std; struct S { int i; S( int i ) { S::i = i; cout << "ctor " << S::i << endl; } ~S() { S::i = i; cout << "dtor " << S::i << endl; } }; int main() { enum { N = 5 }; @uArray( S, s, N );@ // no constructor calls for ( int i = 0; i < N; i += 1 ) @s[i]( i )@; // constructor calls for ( int i = 0; i < N; i += 1 ) cout << s[i]@->@i << endl; } \end{uC++} & \begin{cfa} #include #include struct S { int i; }; void ?{}( S & s, int i ) { s.i = i; sout | "ctor" | s.i; } void ^?{}( S & s ) { sout | "dtor" | s.i; } int main() { enum { N = 5 }; @array( S, N ) s = { delay_init };@ // no constructor calls for ( i; N ) @s[i]{ i }@; // constructor calls for ( i; N ) sout | s[i]@.@i; } \end{cfa} \end{tabular} \end{cquote} \section{Coroutines} \begin{cquote} \begin{tabular}{@{}l|ll@{}} \begin{uC++} _Coroutine C { // private coroutine fields void main() { ... suspend(); ... ... _Resume E( ... ) _At partner; ... uThisCoroutine(); ... } public: void mem( ... ) { ... resume() ... } }; \end{uC++} & \begin{cfa} #include <$coroutine$.hfa> coroutine C { // private coroutine fields }; void main( C & c ) { ... suspend; ... // keyword not routine ... resumeAt( partner, ExceptionInst( E, ... ) ); ... active_coroutine(); ... } void mem( C & c, ... ) { ... resume( c ); ... } \end{cfa} \\ \multicolumn{2}{@{}l@{}}{\lstinline{C c;}} \end{tabular} \end{cquote} \section{\lstinline{COBEGIN}/\lstinline{COFOR}} \begin{cquote} \begin{tabular}{@{}l|ll@{}} \begin{uC++} #include int main() { COBEGIN BEGIN osacquire( cout ) << "A" << endl; END BEGIN osacquire( cout ) << "B" << endl; END BEGIN osacquire( cout ) << "C" << endl; END BEGIN osacquire( cout ) << "D" << endl; END BEGIN osacquire( cout ) << "E" << endl; END COEND COFOR( i, 1, 10, osacquire( cout ) << i << endl; ) } \end{uC++} & \begin{cfa} #include #include <$cofor$.hfa> int main() { { corun { mutex( sout ) sout | "A"; } corun { mutex( sout ) sout | "B"; } corun { mutex( sout ) sout | "C"; } corun { mutex( sout ) sout | "D"; } corun { mutex( sout ) sout | "E"; } } cofor( i; 10 ) { mutex( sout ) sout | i; } } \end{cfa} \end{tabular} \end{cquote} \section{Actor} \begin{cquote} \begin{tabular}{@{}l|ll@{}} \begin{uC++} #include using namespace std; #include struct StrMsg : @public uActor::Message@ { const char * val; // string message StrMsg( const char * val ) : @Message( uActor::Delete )@, // delete after use val( val ) {} }; _Actor Hello { ${\color{red}\LstCommentStyle{// : public uActor}}$ Allocation receive( Message & msg ) { Case( StrMsg, msg ) { // discriminate osacquire( cout ) << msg_d->val << endl; }; return Delete; // delete after use } }; int main() { @uActor::start();@ // start actor system *new Hello() | *new StrMsg( "hello" ); *new Hello() | *new StrMsg( "bonjour" ); @uActor::stop();@ // wait for all actors to terminate } \end{uC++} & \begin{cfa} #include #include #include struct StrMsg { @inline message;@ // derived message const char * val; // string message }; void ?{}( StrMsg & msg, char * str ) { msg.val = str; @set_allocation( msg, Delete );@ // delete after use } struct Hello { @inline actor;@ // derived actor }; allocation receive( Hello & receiver, StrMsg & msg ) { mutex( sout ) sout | msg.val; return Delete; // delete after use } int main() { @start_actor_system();@ // start actor system *(Hello *)new() | *(StrMsg *)new( "hello" ); *(Hello *)new() | *(StrMsg *)new( "bonjour" ); @stop_actor_system();@ // wait for all actors to terminate } \end{cfa} \end{tabular} \end{cquote} \section{Threads} \begin{cquote} \begin{tabular}{@{}l|ll@{}} \begin{uC++} @_Task@ T { // private task fields void main() { ... _Resume E( ... ) _At partner; ... uThisTask(); ... } public: }; \end{uC++} & \begin{cfa} #include <$thread$.hfa> @thread@ T { // private task fields }; void main( @T & t@ ) { ... resumeAt( partner, ExceptionInst( E, ... ) ); ... active_thread(); ... } \end{cfa} \\ \multicolumn{2}{@{}l@{}}{\lstinline{T t; // start thread in main routine}} \end{tabular} \end{cquote} \section{Locks} \begin{cquote} \begin{tabular}{@{}l|ll@{}} \begin{uC++} uOwnerLock m; uCondLock s; m.acquire(); if ( ! s.empty() ) s.wait( m ); else { m.release(); } @osacquire( cout )@ << i << endl; \end{uC++} & \begin{cfa} #include owner_lock m; condition_variable( owner_lock ) s; // generic type on mutex lock lock( m ); if ( ! empty( s ) ) wait( s, m ); else { unlock( m ); } @mutex( sout )@ sout | i; // thread safe I/O \end{cfa} \end{tabular} \end{cquote} \section{Monitors} \begin{cquote} \begin{tabular}{@{}l|ll@{}} \begin{uC++} @_Monitor@ M { @uCondition@ c; bool avail = true; public: void rtn() { if ( ! avail ) c.wait(); else avail = false; } }; \end{uC++} & \begin{cfa} #include <$monitor$.hfa> @monitor@ M { @condition@ c; bool avail; }; void ?{}( M & m ) { m.avail = true; } void rtn( M & m ) with( m ) { if ( ! avail ) wait( c ); else avail = false; } \end{cfa} \\ \multicolumn{2}{@{}l@{}}{\lstinline{M m;}} \end{tabular} \end{cquote} \input{uC++toCFA.ind} % \bibliographystyle{plain} % \bibliography{pl} \end{document} % Local Variables: % % tab-width: 4 % % fill-column: 100 % % compile-command: "make" % % End: %