source: doc/uC++toCFA/uC++toCFA.tex@ acb89d74

Last change on this file since acb89d74 was de8a0286, checked in by Peter A. Buhr <pabuhr@…>, 6 months ago

many updates and additions to the uC++ to CFA cheat sheet

  • Property mode set to 100644
File size: 29.1 KB
Line 
1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -*- Mode: Latex -*- %%%%%%%%%%%%%%%%%%%%%%%%%%%%
2%%
3%% Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
4%%
5%% The contents of this file are covered under the licence agreement in the
6%% file "LICENCE" distributed with Cforall.
7%%
8%% user.tex --
9%%
10%% Author : Peter A. Buhr
11%% Created On : Wed Apr 6 14:53:29 2016
12%% Last Modified By : Peter A. Buhr
13%% Last Modified On : Mon Nov 17 11:14:48 2025
14%% Update Count : 6677
15%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16
17
18\documentclass[11pt]{article}
19
20\makeatletter
21\def\@maketitle{%
22 \newpage
23 \null
24% \vskip 2em%
25 \begin{center}%
26 \let \footnote \thanks
27 {\LARGE\bf \@title \par}%
28 \@ifundefined{@author}{}
29 {
30 \ifx\@empty\@author
31 \else
32 \vskip 1.5em%
33 {\large
34 \lineskip .5em%
35 \begin{tabular}[t]{c}%
36 \@author
37 \end{tabular}%
38 \par
39 }%
40 \fi
41 }%
42 \ifx\@empty\@date
43 \else
44 \vskip 1em%
45 {\large \@date}%
46 \fi
47 \end{center}%
48 \par
49% \vskip 1.5em
50}%maketitle
51\makeatother
52
53%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
54
55% Latex packages used in the document.
56%\usepackage[T1]{fontenc} % allow Latin1 (extended ASCII) characters
57%\usepackage{textcomp}
58%\usepackage[latin1]{inputenc}
59
60\usepackage{fullpage,times,comment}
61\usepackage{epic,eepic}
62\usepackage{upquote} % switch curled `'" to straight
63\usepackage[labelformat=simple,aboveskip=0pt,farskip=0pt]{subfig}
64\renewcommand{\thesubfigure}{\alph{subfigure})}
65\usepackage{latexsym} % \Box glyph
66\usepackage{mathptmx} % better math font with "times"
67\usepackage[usenames]{color}
68\usepackage[pagewise]{lineno}
69\renewcommand{\linenumberfont}{\scriptsize\sffamily}
70\input{common} % common CFA document macros
71\usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref}
72\usepackage{breakurl}
73
74\renewcommand\footnoterule{\kern -3pt\rule{0.3\linewidth}{0.15pt}\kern 2pt}
75\newcommand{\uC}{$\mu$\CC}
76
77% Default underscore is too low and wide. Cannot use lstlisting "literate" as replacing underscore
78% removes it as a variable-name character so keywords in variables are highlighted. MUST APPEAR
79% AFTER HYPERREF.
80\renewcommand{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.075ex}}}
81
82\setlength{\topmargin}{-0.45in} % move running title into header
83\setlength{\headsep}{0.25in}
84\setlength{\tabcolsep}{15pt}
85
86%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
87
88\setlength{\gcolumnposn}{3in}
89\CFAStyle % use default CFA format-style
90\lstset{language=CFA} % CFA default lnaguage
91\lstnewenvironment{C++}[1][] % use C++ style
92{\lstset{language=C++,escapechar=\$,mathescape=false,moredelim=**[is][\protect\color{red}]{@}{@},#1}}{}
93\lstnewenvironment{uC++}[1][]
94{\lstset{language=uC++,escapechar=\$,mathescape=false,moredelim=**[is][\protect\color{red}]{@}{@},#1}}{}
95
96\newsavebox{\myboxA}
97\newsavebox{\myboxB}
98
99%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
100
101% Names used in the document.
102\newcommand{\Version}{\input{build/version}}
103\newcommand{\Textbf}[2][red]{{\color{#1}{\textbf{#2}}}}
104\newcommand{\Emph}[2][red]{{\color{#1}\textbf{\emph{#2}}}}
105\newcommand{\R}[1]{{\color{red}#1}}
106\newcommand{\RB}[1]{\Textbf{#1}}
107\newcommand{\B}[1]{{\Textbf[blue]{#1}}}
108\newcommand{\G}[1]{{\Textbf[OliveGreen]{#1}}}
109\newcommand{\Sp}{\R{\textvisiblespace}}
110\newcommand{\KWC}{K-W C\xspace}
111
112%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113
114\setcounter{secnumdepth}{3} % number subsubsections
115\setcounter{tocdepth}{3} % subsubsections in table of contents
116\makeindex
117
118%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
119
120\title{\vspace*{-0.5in}
121\uC to \CFA Cheat Sheet}
122%\author{Peter A. Buhr}
123\date{}
124
125%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126
127\begin{document}
128\pagestyle{headings}
129% changed after setting pagestyle
130\renewcommand{\sectionmark}[1]{\markboth{\thesection\quad #1}{\thesection\quad #1}}
131\renewcommand{\subsectionmark}[1]{\markboth{\thesubsection\quad #1}{\thesubsection\quad #1}}
132
133%\linenumbers % comment out to turn off line numbering
134
135\maketitle
136\vspace*{-0.65in}
137
138\section{Introduction}
139
140\CFA is an extension of the C programming with a trait-style type-system rather then templates and objects as in \CC.
141\CFA allows overloading of variables and routines using the left-hand assignment type to precisely select among overloaded names.
142\begin{cfa}
143int x; char x; double x; // overload name x
144int x(); double x(); char x();
145\end{cfa}
146\vspace*{-8pt}
147\begin{cquote}
148\begin{tabular}{@{}l@{\hspace{1in}}|l@{}}
149\begin{cfa}
150x += 42; $\C[1in]{// int x}$
151x += 42.2; $\C{// double x}$
152x += 'a'; $\C{// char x}\CRT$
153\end{cfa}
154&
155\begin{cfa}
156int j = x(); $\C[1in]{// int x()}$
157double j = x(); $\C{// double x();}$
158char j = x(); $\C{// char x()}\CRT$
159\end{cfa}
160\end{tabular}
161\end{cquote}
162\CFA generalizes reference types, allowing multiple and rebindable references (like pointers).
163\begin{cquote}
164\begin{tabular}{@{}l|l@{}}
165\multicolumn{2}{@{}l}{\lstinline{ int x = 1, y = 2, * p1x = &x, * p1y = &y, ** p2i = &p1x,}} \\
166\multicolumn{2}{@{}l}{\lstinline{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ & r1x = x, & r1y = y, && r2i = r1x;}} \\
167\begin{uC++}
168**p2i = 3;
169p2i = &p1y;
170**p2i = 3;
171p1x = p1y;
172**p2i = 4;
173p1x = @nullptr@;
174\end{uC++}
175&
176\begin{cfa}
177r2i = 3; $\C[0.875in]{// change x}$
178&r2i = &r1y; $\C{// change p2i / r2i}$
179r2i = 3; $\C{// change y}$
180&r1x = &r1y; $\C{// change p1x / r1x}$
181r2i = 4; $\C{// change y}$
182&r1x = @0p@; $\C{// reset}\CRT$
183\end{cfa}
184\end{tabular}
185\end{cquote}
186Non-rebindable reference (\CC reference) is a @const@ reference (@const@ pointer).
187\begin{cfa}
188int & @const@ cr = x; // must initialize, no null pointer
189int & @const@ & @const@ crcr = cr; // generalize
190\end{cfa}
191
192
193\section{Control Flow}
194
195The @choose@ statement provides an implicit @break@ after the @case@ clause for safety.
196It is possible to @break default@ in a @case@ clause to transfer to common code in the @default@ clause.
197\begin{cquote}
198\begin{tabular}{@{}l|l@{}}
199\begin{uC++}
200switch ( i ) {
201 case 1: ... @break@; // explicit break
202 case 2: ... @break@; // explicit break
203 default: ... ;
204}
205\end{uC++}
206&
207\begin{cfa}
208choose ( i ) {
209 case 1: ... ; // implicit break
210 case 2: ... ; // implicit break
211 default: ... ;
212}
213\end{cfa}
214\end{tabular}
215\end{cquote}
216To simplify creating an infinite loop, the loop condition in optional.
217\begin{cquote}
218\begin{tabular}{@{}l|l@{}}
219\begin{uC++}
220while ( true ) ...
221for ( ;; ) ...
222do ... while ( true )
223\end{uC++}
224&
225\begin{uC++}
226while ($\,$) ...
227for ($\,$) ...
228do ... while ($\,$)
229\end{uC++}
230\end{tabular}
231\end{cquote}
232To simplify loop iteration a range is provided, from low to high, and a traversal direction, ascending (@+@) or descending (@-@).
233The following is the syntax for the loop range, where @[@\,@]@ means optional.
234\begin{cfa}[deletekeywords=default]
235[ @index ;@ ] [ [ @min@ (default 0) ] [ direction @+@/@-@ (default +) ] @~@ [ @=@ (include endpoint) ] ] @max@ [ @~ increment@ ]
236\end{cfa}
237For @=@, the range includes the endpoint (@max@/@min@) depending on the direction (@+@/@-@).
238\begin{cquote}
239\begin{tabular}{@{}l|l@{}}
240\begin{uC++}
241for ( int i = 0; i < @10@; i += 1 ) { ... }
242for ( int i = @5@; i < @15@; i += @2@ ) { ... }
243for ( int i = -2; i <@=@ 10; i += 3 ) { ... }
244for ( int i = 10; i > -3; i @-@= 1 ) { ... }
245for ( int i = 10; i >@=@ 0; i @-@= 1 ) { ... }
246\end{uC++}
247&
248\begin{cfa}
249for ( @10@ ) { ... } / for ( i; @10@ ) { ... } // 0 to 9 by 1
250for ( i; @5@ ~ @15@ ~ @2@ ) { ... } // 5 to 14 by 2
251for ( i; -2 ~@=@ 10 ~ 3 ) { ... } // -2 to 10 by 3
252for ( i; -3 @-@~ 10 ) { ... } // not 10 -~= -3, 10 to -2 by -1
253for ( i; 0 @-@~@=@ 10 ) { ... } // not 10 -~= 0, 10 to 0 by -1
254\end{cfa}
255\end{tabular}
256\end{cquote}
257A terminating loop @else@ (like Python) is executed if the loop terminates normally, \ie the loop conditional becomes false, which is safer than retesting after the loop.
258The loop index is available in the @else@ clause.
259\begin{cquote}
260\begin{tabular}{@{}l|l@{}}
261\begin{uC++}
262int i = 0
263for ( i = 0; i < 10; i += 1 ) { ... }
264@if ( i == 10 )@ { ... }
265\end{uC++}
266&
267\begin{cfa}
268
269for ( i; 10 ) { ... }
270@else@ { ... } // i == 10 because of post increment
271\end{cfa}
272\end{tabular}
273\end{cquote}
274Single/multiple-level loop exit/continue is provided by the labelled @break@/@continue@. (First example is \CC.)
275\begin{cquote}
276\begin{tabular}{@{}l|l|l@{}}
277\begin{C++}
278@L1:@ for ( ;; ) {
279 for ( ;; ) {
280 ... if ( ... ) @goto L1@; ...
281 ... if ( ... ) @goto L2@; ...
282 } @L2: ;@
283}
284\end{C++}
285&
286\begin{cfa}
287@L1:@ for () {
288 @L2:@ for () {
289 ... if ( ... ) @continue L1@; ...
290 ... if ( ... ) @break L2@; ...
291 }
292}
293\end{cfa}
294&
295\begin{cfa}
296@L1:@ for () {
297 @L2:@ for () {
298 ... if ( ... ) @continue L1@; ...
299 ... if ( ... ) @break L2@; ...
300 }
301}
302\end{cfa}
303\end{tabular}
304\end{cquote}
305
306
307\section{Exception}
308
309Currently, \CFA uses macros @ExceptionDecl@ and @ExceptionInst@ to declare and instantiate an exception.
310\begin{cquote}
311\setlength{\tabcolsep}{5pt}
312\begin{tabular}{@{}l|ll@{}}
313\begin{uC++}
314
315@_Exception@ E { // local or global scope
316 ... // exception fields
317};
318try {
319 ... if ( ... ) @_Resume@ E( /* initialization */ ); ...
320 ... if ( ... ) @_Throw@ E( /* initialization */ ); ...
321} @_CatchResume@( E & /* reference */ ) { ... }
322 catch( E & ) { ... }
323 catch( ... /* catch any */ ) { ... }
324 _Finally { ... }
325\end{uC++}
326&
327\begin{cfa}
328#include <Exception.hfa>
329@ExceptionDecl@( E, // must be global scope
330 ... // exception fields
331);
332try {
333 ... if ( ... ) @throwResume@ @ExceptionInst@( E, /* intialization */ ); ...
334 ... if ( ... ) @throw@ @ExceptionInst@( E, /* intialization */ ); ...
335} @catchResume@( E @*@ /* pointer */ ) { ... }
336 catch( E * ) { ... }
337 catch( exception_t @*@ /* catch any */ ) { ... }
338 finally { ... }
339\end{cfa}
340\end{tabular}
341\end{cquote}
342
343
344\section{Non-local Exception}
345
346\begin{cquote}
347\setlength{\tabcolsep}{5pt}
348\begin{tabular}{@{}l|ll@{}}
349\begin{uC++}
350
351
352void Coroutine::main() {
353 try {
354 _Enable {
355 ... suspend(); ...
356 }
357 } @_CatchResume@( E & /* reference */ ) { ... }
358 catch( E & ) { ... }
359}
360void Coroutine::mem() { resume(); }
361\end{uC++}
362&
363\begin{cfa}
364#define resumePoll( coroutine ) resume( coroutine ); poll()
365#define suspendPoll suspend; poll()
366void main( Coroutine & cor ) {
367 try {
368 enable_ehm();
369 ... suspendPoll ...
370 disable_ehm();
371 } @catchResume@( E * ) { ... }
372 catch( E & ) { ... }
373}
374void mem( Coroutine & cor ) { resumePoll(); }
375\end{cfa}
376\end{tabular}
377\end{cquote}
378
379
380\section{Stream I/O}
381
382\CFA output streams automatically separate values and insert a newline at the end of the print.
383\begin{cquote}
384\begin{tabular}{@{}l|l@{}}
385\begin{uC++}
386#include <@iostream@>
387using namespace std;
388int i; double d; char c;
389cin >> i >> d >> c;
390cout << i << ' ' << d << ' ' << c << endl;
391\end{uC++}
392&
393\begin{cfa}
394#include <@fstream.hfa@>
395
396int i; double d; char c;
397sin | i | d | c;
398sout | i | d | c
399\end{cfa}
400\end{tabular}
401\end{cquote}
402To disable/enable automatic newline at the end of printing, use @nlOff@/@nlOn@ and @nl@.
403\begin{cquote}
404\begin{tabular}{@{}l|l@{}}
405\begin{uC++}
406
407for ( int i = 0; i < 5; i += 1 ) cout << i << ' ';
408cout << @endl@;
4090 1 2 3 4
410\end{uC++}
411&
412\begin{cfa}
413sout | @nlOff@; // disable auto nl
414for ( i; 5 ) sout | i;
415sout | @nl@; sout | @nlOn@; // enable auto nl
4160 1 2 3 4
417\end{cfa}
418\end{tabular}
419\end{cquote}
420Floating-point numbers without a fraction print with a decimal point, which can be disabled with @nodp@.
421\begin{cquote}
422\begin{tabular}{@{}l|l@{}}
423\begin{uC++}
424cout << 3.0 << ' ' << showpoint << setprecision(0) << 3.0 << endl;
4253 3.
426\end{uC++}
427&
428\begin{cfa}
429sout | @nodp( 3.0 )@ | 3.0;
4303 3.
431\end{cfa}
432\end{tabular}
433\end{cquote}
434
435
436\section{Time}
437
438\begin{cquote}
439\setlength{\tabcolsep}{5pt}
440\begin{tabular}{@{}l|l@{}}
441\begin{uC++}
442
443uTime start = uClock::currTime();
444...
445cout << "duration " << uClock::currTime() - start
446 << " sec." << endl;
447\end{uC++}
448&
449\begin{cfa}
450#include <clock.hfa>
451Time start = timeHiRes(); // time with nanoseconds
452...
453sout | "duration " | timeHiRes() - start | " sec.";
454
455\end{cfa}
456\end{tabular}
457\end{cquote}
458
459
460\section{Constructor / Destructor}
461
462A constructor/destructor must have its structure type as the first parameter and be a reference.
463\begin{cquote}
464\begin{tabular}{@{}l|l@{}}
465\begin{uC++}
466
467struct S {
468 int i, j;
469 @S@() { i = j = 3; }
470 @S@( int i, int j ) { S::i = i; S::j = j; }
471 @S@( const S & s ) { *this = s; }
472 @~S@() {}
473};
474S s0, s1 = { 1, 2 };
475
476S * s2 = new S{ 1, 2 }; delete s2;
477s2 = new S{ 1, 2 }; delete s2;
478S & s3 = *new S{ 1, 2 }; delete &s3;
479s3 = *new S{ 1, 2 }; delete &s3;
480\end{uC++}
481&
482\begin{cfa}
483#include <stdlib.hfa> // new (malloc)
484struct S { int i, j; };
485
486void @?{}@( @S & s@ ) { s.i = s.j = 3; } $\C[3in]{// default}$
487void @?{}@( @S & s@, int i, int j ) { s.i = i; s.j = j; } $\C{// initializer}$
488void @?{}@( @S & s@, const S rhs ) { ?{}( s, rhs.i, rhs.j ); } $\C{// copy}$
489void @^?{}@( @S & s@ ) { s.i = 0; s.j = 0; } $\C{// destructor}\CRT$
490
491S s0, s1 = { 1, 2 };
492// bug, cannot use 0/1 (zero_t/one_t) with "new"
493S * s2 = new( 0@n@, 2 ); /* suffix n => (natural int) */ delete( s2 );
494s2 = new( 1@n@, 2 ); delete( s2 );
495S & s3 = *new( 2, 2 ); delete( &s3 );
496&s3 = &*new( 3, 2 ); delete( &s3 );
497\end{cfa}
498\end{tabular}
499\end{cquote}
500
501
502\section{\texorpdfstring{Structures (object-oriented \protect\vs routine style)}{Structures (object-oriented vs. routine style)}}
503
504\CFA is NOT an object-oriented programming-language, so there is no receiver (\lstinline[language=c++]{this}) or nested structure routines.
505The equivalent of a \emph{member} routine has an explicit structure parameter in any parameter position (often the first).
506\begin{cquote}
507\begin{tabular}{@{}l|l@{}}
508\begin{uC++}
509struct S {
510 int i = 0; // cheat, implicit default constructor
511 int setter( int j ) { int t = i; i = j; return t; }
512 int getter() { return i; }
513};
514S s;
515@s.@setter( 3 ); // object calls
516int k = @s.@getter();
517\end{uC++}
518&
519\begin{cfa}
520struct S { int i; };
521void ?{}( S & s ) { s.i = 0; } // explicit default constructor
522int setter( @S & s,@ int j ) @with( s )@ { int t = i; i = j; return t; }
523int getter( @S & s@ ) @with( s )@ { return i; }
524
525S s;
526setter( @s,@ 3 ); // normal calls
527int k = getter( @s@ );
528\end{cfa}
529\end{tabular}
530\end{cquote}
531Aggregate qualification is reduced or eliminated by opening scopes using the @with@ clause.
532\begin{cfa}
533struct S { int i; int j; double m; }; // field i has same type in structures S and T
534struct T { int i; int k; int m; };
535void foo( S s, T t ) @with( s, t )@ { // open structure scope s and t in parallel
536 j + k; $\C[1.6in]{// unambiguous, s.j + t.k}$
537 m = 5.0; $\C{// unambiguous, s.m = 5.0}$
538 m = 1; $\C{// unambiguous, t.m = 1}$
539 int a = m; $\C{// unambiguous, a = t.m}$
540 double b = m; $\C{// unambiguous, b = s.m}$
541 int c = s.i + t.i; $\C{// unambiguous with qualification}$
542 (double)m; $\C{// unambiguous with cast s.m}\CRT$
543}
544\end{cfa}
545\noindent
546In subsequent code examples, the left example is \CC/\uC and the right example is \CFA.
547
548
549\section{String}
550
551The @string@ type in \CFA is very similar to that in \CC.
552\begin{cquote}
553\begin{tabular}{@{}l|l@{}}
554\multicolumn{2}{@{}l@{}}{\lstinline{string s1, s2;}} \\
555\begin{uC++}
556s1 = "abcdefg";
557s2 = s1;
558s1 += s2;
559s1 == s2; s1 != s2;
560s1 < s2; s1 <= s2; s1 > s2; s1 >= s2;
561s1.length();
562s1[3];
563s1.substr( 2 ); s1.substr( 2, 3 );
564s1.replace( 2, 5, s2 );
565s1.find( s2 );
566s1.find_first_of( "cd" );
567s1.find_first_not_of( "cd" );
568getline( cin, s1 );
569cout << s1 << endl;
570\end{uC++}
571&
572\begin{cfa}
573s1 = "abcdefg";
574s2 = s1;
575s1 += s2;
576s1 == s2; s1 != s2;
577s1 < s2; s1 <= s2; s1 > s2; s1 >= s2;
578len( s1 ); // like C strlen( s1 )
579s1[3];
580s1( 2 ); s1( 2, 3 );
581s1( 2, 5 ) = s2;
582find( s1, s2 );
583exclude( s1, "cd" ); // longest sequence excluding "c" and "d"
584include( s1, "cd" ); // longest sequence including "c" and "d"
585sin | getline( s1 );
586sout | s1;
587\end{cfa}
588\end{tabular}
589\end{cquote}
590
591
592\enlargethispage{1000pt}
593\section{\texorpdfstring{\lstinline{uArray}}{uArray}}
594
595\begin{cquote}
596\setlength{\tabcolsep}{5pt}
597\begin{tabular}{@{}l|l@{}}
598\begin{uC++}
599#include <iostream>
600using namespace std;
601
602struct S {
603 int i;
604 S( int i ) { S::i = i; }
605};
606void f( @uArrayRef( S, parm )@ );
607int main() {
608 enum { N = 5 };
609 @uArray( S, s, N );@ // stack, no ctor calls
610 for ( int i = 0; i < N; i += 1 ) @s[i]( i )@; // ctor calls
611 for ( int i = 0; i < N; i += 1 ) cout << s[i]@->@i << endl;
612 f( s );
613 @uArrayPtr( S, sp, N );@ // heap, no ctor calls
614 for ( int i = 0; i < N; i += 1 ) @sp[i]( i )@; // ctor calls
615 for ( int i = 0; i < N; i += 1 ) cout << sp[i]@->@i << endl;
616 f( sp );
617} // delete s, sp
618\end{uC++}
619&
620\begin{cfa}
621#include <fstream.hfa>
622#include <array.hfa>
623#include <memory.hfa>
624struct S {
625 int i;
626};
627void ?{}( S & s, int i ) { s.i = i; }
628@forall( [N] )@ void f( @array( S, N ) & parm@ ) {}
629int main() {
630 enum { N = 5 };
631 @array( S, N ) s = { delay_init };@ // no ctor calls
632 for ( i; N ) @s[i]{ i }@; // ctor calls
633 for ( i; N ) sout | s[i]@.@i;
634 f( s );
635 @unique_ptr( array( S, N ) )@ sp = { delay_init }; // heap
636 for ( int i = 0; i < N; i += 1 ) @(*sp)@[i]{ i }; // ctor calls
637 for ( int i = 0; i < N; i += 1 ) sout | @(*sp)@[i].i;
638 f( @*sp@ );
639} // delete s, sp
640\end{cfa}
641\end{tabular}
642\end{cquote}
643
644\newpage
645
646
647\section{Doubly-Linked Intrusive List}
648
649\begin{cquote}
650\setlength{\tabcolsep}{10pt}
651\begin{tabular}{@{}l|l@{}}
652\begin{uC++}
653#include <iostream>
654using namespace std;
655struct Node : @public uSeqable@ {
656 int i;
657 Node( int i ) : i( i ) {}
658};
659
660
661int main() {
662 @uSequence<Node> dlist;@
663 Node n1{ 1 }, n2{ 2 }, n3{ 3 };
664 dlist.addTail( &n1 );
665 dlist.addHead( &n2 ); // out of order
666 dlist.insertAft( &n1, &n3 ); // insertBef
667 for ( Node * it = dlist.head(); it; it = dlist.succ( it ) ) {
668 cout << it->i << endl;
669 }
670 dlist.remove( &n3 ); // shorten list
671 dlist.dropTail(); // dropHead
672 Node * it;
673 for ( uSeqIter<Node> seqit(dlist); // uSeqIterRev
674 seqit >> it; ) {
675 cout << it->i << endl;
676 }
677}
678\end{uC++}
679&
680\begin{cfa}
681#include <fstream.hfa>
682#include <list.hfa>
683struct Node {
684 @inline dlink( Node );@
685 int i;
686};
687@P9_EMBEDDED( Node, dlink( Node ) );@ // magic
688void ?{}( Node & node, int i ) { node.i = i; }
689int main() {
690 @dlist( Node ) dlist;@
691 Node n1{ 1 }, n2{ 2 }, n3{ 3 };
692 insert_last( dlist, n1 );
693 insert_first( dlist, n2 ); // out of order
694 insert_after( n1, n3 ); // insert_before
695 for ( Node & it = first( dlist ); &it; &it = &next( it ) ) {
696 sout | it.i;
697 }
698 remove( n3 ); // shorten list
699 remove_last( dlist ); // remove_first
700
701 FOREACH( dlist, it ) { // FOREACH_REV
702
703 sout | it.i;
704 }
705}
706\end{cfa}
707\end{tabular}
708\end{cquote}
709
710
711\section{RAII Dynamic Allocation}
712
713\begin{cquote}
714\begin{tabular}{@{}l|ll@{}}
715\begin{uC++}
716struct S {
717 ... S() { ... } ~S() { ... } // ctor / dtor
718};
719S * s = new S; delete s;
720S * sa = new S[10]; delete [] sa;
721\end{uC++}
722&
723\begin{cfa}
724#include <stdlib.hfa>
725struct S { ... };
726void ?{}( S & ) { ... } void ^?{}( S & ) { ... } // ctor / dtor
727S * s = new(); delete( s );
728S * sa = anew( 10 ); adelete( sa );
729\end{cfa}
730\end{tabular}
731\end{cquote}
732
733
734\section{Coroutine}
735
736\begin{cquote}
737\begin{tabular}{@{}l|ll@{}}
738\begin{uC++}
739@_Coroutine@ C {
740 // private coroutine fields
741 void main() {
742 ... @suspend();@ ...
743 ... @_Resume E( ... ) _At partner;@
744 ... @uThisCoroutine();@ ...
745
746 }
747 public:
748 void mem( ... ) {
749 ... @resume();@ ...
750 }
751};
752\end{uC++}
753&
754\begin{cfa}
755#include <$coroutine$.hfa>
756@coroutine@ C {
757 // private coroutine fields
758
759};
760void main( C & c ) {
761 ... @suspend;@ ... // keyword not routine
762 ... @resumeAt( partner, ExceptionInst( E, ... ) );@
763 ... @active_coroutine();@ ...
764}
765void mem( C & c, ... ) {
766 ... @resume( c );@ ...
767}
768\end{cfa}
769\end{tabular}
770\end{cquote}
771
772
773\section{\lstinline{COBEGIN}/\lstinline{COFOR}}
774
775\begin{cquote}
776\begin{tabular}{@{}l|ll@{}}
777\begin{uC++}
778
779#include <uCobegin.h>
780int main() {
781 @COBEGIN@
782 BEGIN osacquire( cout ) << "A" << endl; END
783 BEGIN osacquire( cout ) << "B" << endl; END
784 BEGIN osacquire( cout ) << "C" << endl; END
785 BEGIN osacquire( cout ) << "D" << endl; END
786 @COEND@
787 @COFOR@( i, 1, 10,
788 osacquire( cout ) << i << endl;
789 )
790}
791\end{uC++}
792&
793\begin{cfa}
794#include <mutex_stmt.hfa>
795#include <$cofor$.hfa>
796int main() {
797 {
798 @corun@ { mutex( sout ) sout | "A"; }
799 corun { mutex( sout ) sout | "B"; }
800 corun { mutex( sout ) sout | "C"; }
801 corun { mutex( sout ) sout | "D"; }
802 }
803 @cofor@( i; 10 ) {
804 mutex( sout ) sout | i;
805 }
806}
807\end{cfa}
808\end{tabular}
809\end{cquote}
810
811
812\section{Actor}
813
814\begin{cquote}
815\setlength{\tabcolsep}{10pt}
816\begin{tabular}{@{}l|ll@{}}
817\begin{uC++}
818#include <iostream>
819using namespace std;
820#include <uActor.h>
821
822struct StrMsg : @public uActor::Message@ {
823
824 const char * val; // string message
825
826 StrMsg( const char * val ) :
827 @Message( uActor::Delete )@, // delete after use
828 val( val ) {}
829};
830\end{uC++}
831&
832\begin{cfa}
833#include <fstream.hfa>
834#include <mutex_stmt.hfa>
835#include <actor.hfa>
836
837struct StrMsg {
838 @inline message;@ // derived message
839 const char * val; // string message
840};
841void ?{}( StrMsg & msg, const char * str ) {
842 @set_allocation( msg, Delete );@ // delete after use
843 msg.val = str;
844}
845\end{cfa}
846\\
847\begin{uC++}
848_Actor Hello { ${\color{red}\LstCommentStyle{// : public uActor}}$
849 Allocation receive( Message & msg ) {
850 Case( @StartMsg@, msg ) { // discriminate
851
852 } else Case( StrMsg, msg ) {
853 osacquire( cout ) << msg_d->val << endl;
854
855 } else Case( @StopMsg@, msg )
856 return Delete; // delete actor
857 return Nodelete; // reuse actor
858 }
859};
860int main() {
861 @uActor::start();@ // start actor system
862 *new Hello() | uActor::startMsg
863 | *new StrMsg( "hello" ) | uActor::stopMsg;
864 *new Hello() | uActor::startMsg
865 | *new StrMsg( "bonjour" ) | uActor::stopMsg;
866 @uActor::stop();@ // wait for actors to terminate
867}
868\end{uC++}
869&
870\begin{cfa}
871struct Hello { @inline actor;@ }; // derived actor
872allocation receive( Hello & receiver, @start_msg_t@ & ) {
873 return Nodelete;
874}
875allocation receive( Hello & receiver, StrMsg & msg ) {
876 mutex( sout ) sout | msg.val;
877 return Nodelete; // reuse actor
878}
879allocation receive( Hello & receiver, @stop_msg_t@ & ) {
880 return Delete; // delete actor
881}
882
883int main() {
884 @actor_start();@ // start actor system
885 *(Hello *)new() | start_msg
886 | *(StrMsg *)new( "hello" ) | stop_msg;
887 *(Hello *)new() | start_msg
888 | *(StrMsg *)new( "bonjour" ) | stop_msg;
889 @actor_stop();@ // wait for actors to terminate
890}
891\end{cfa}
892\end{tabular}
893\end{cquote}
894
895
896\section{Thread}
897
898\begin{cquote}
899\begin{tabular}{@{}l|ll@{}}
900\begin{uC++}
901
902@_Task@ T {
903 // private task fields
904 void main() {
905 ... @_Resume E( ... ) _At partner@;
906 ... @uThisTask();@ ...
907 }
908 public:
909};
910\end{uC++}
911&
912\begin{cfa}
913#include <$thread$.hfa>
914@thread@ T {
915 // private task fields
916
917};
918void main( @T & t@ ) {
919 ... @resumeAt( partner, ExceptionInst( E, ... )@ );
920 ... @active_thread();@ ...
921}
922\end{cfa}
923\\
924\multicolumn{2}{@{}l@{}}{\lstinline{T t; // start thread in main routine}}
925\end{tabular}
926\end{cquote}
927
928
929\section{Locks}
930
931\begin{cquote}
932\begin{tabular}{@{}l|ll@{}}
933\begin{uC++}
934
935uOwnerLock m;
936uCondLock c;
937m.acquire();
938if ( ! c.empty() ) c.wait( m );
939else {
940 m.release();
941}
942@osacquire( cout )@ << i << endl;
943\end{uC++}
944&
945\begin{cfa}
946#include <locks.hfa>
947owner_lock m;
948cond_lock( owner_lock ) c; // generic type on mutex lock
949lock( m );
950if ( ! empty( c ) ) wait( c, m );
951else {
952 unlock( m );
953}
954@mutex( sout )@ sout | i; // thread safe I/O
955\end{cfa}
956\end{tabular}
957\end{cquote}
958
959\begin{cquote}
960\begin{tabular}{@{}l|ll@{}}
961\begin{uC++}
962
963uSemaphore m, c;
964m.P();
965if ( ! c.empty() ) c.P( m );
966else {
967 m.V();
968}
969\end{uC++}
970&
971\begin{cfa}
972#include <locks.hfa>
973semaphore m, c;
974P( m );
975if ( ! empty( c ) ) P( c, m );
976else {
977 V( m );
978}
979\end{cfa}
980\end{tabular}
981\end{cquote}
982
983
984\enlargethispage{1000pt}
985
986\section{Barrier}
987
988\begin{cquote}
989\begin{tabular}{@{}l|ll@{}}
990\begin{uC++}
991#include <iostream>
992using namespace std;
993#include <uBarrier.h>
994
995@_Cormonitor@ Barrier
996 : @public uBarrier@ { // inheritance
997 int total;
998 void @last@() { cout << total << endl; }
999 public:
1000 Barrier( unsigned int group ) :
1001 @uBarrier( group )@ {
1002 total = 0;
1003 }
1004 void @block@( int subtotal ) {
1005
1006
1007 total += subtotal;
1008 @uBarrier::block();@
1009 }
1010};
1011enum { N = 3 };
1012Barrier b{ N };
1013\end{uC++}
1014&
1015\begin{cfa}
1016#include <fstream.hfa>
1017#include <$thread$.hfa>
1018#include <barrier.hfa>
1019#include <mutex_stmt.hfa>
1020struct Barrier {
1021 @inline barrier;@
1022 int total;
1023
1024};
1025void ?{}( Barrier & b, unsigned int group ) with( b ) {
1026 @(b){ group };@ // initialize barrier
1027 total = 0;
1028}
1029unsigned int block( Barrier & b, int subtotal ) with( b ) {
1030 void @last@(...) { sout | total; } // called by Gth arriving thread
1031 @mutex( b )@ { // use barrier's mutual exclusion
1032 total += subtotal;
1033 return @block@( b, last ); // wait for barrier trigger
1034 }
1035}
1036enum { N = 3 };
1037Barrier b{ N };
1038\end{cfa}
1039\end{tabular}
1040\end{cquote}
1041
1042\newpage
1043
1044\enlargethispage{1000pt}
1045
1046\section{Monitor}
1047
1048Internal Scheduling
1049\begin{cquote}
1050\setlength{\tabcolsep}{5pt}
1051\begin{tabular}{@{}l|ll@{}}
1052\begin{uC++}
1053
1054@_Monitor@ BoundedBufferI {
1055 @uCondition@ full, empty;
1056 int front = 0, back = 0, count = 0;
1057 int elements[20];
1058 public:
1059
1060
1061
1062 @_Nomutex@ int query() const { return count; }
1063
1064 void insert( int elem ) {
1065 if ( count == 20 ) @empty.wait();@
1066 elements[back] = elem;
1067 back = ( back + 1 ) % 20;
1068 count += 1;
1069 @full.signal();@
1070 }
1071 int remove() {
1072 if ( count == 0 ) @full.wait();@
1073 int elem = elements[front];
1074 front = ( front + 1 ) % 20;
1075 count -= 1;
1076 @empty.signal();@
1077 return elem;
1078 }
1079};
1080\end{uC++}
1081&
1082\begin{cfa}
1083#include <$monitor$.hfa>
1084@monitor@ BoundedBufferI {
1085 @condition@ full, empty;
1086 int front, back, count;
1087 int elements[20];
1088};
1089void ?{}( BoundedBufferI & buf ) with( buf ) {
1090 front = back = count = 0;
1091}
1092int query( BoundedBufferI & buf ) { return buf.count; }
1093int remove( BoundedBufferI & @mutex@ buf ); // forward
1094void insert( BoundedBufferI & @mutex@ buf, int elem ) with( buf ) {
1095 if ( count == 20 ) @wait( empty );@
1096 elements[back] = elem;
1097 back = ( back + 1 ) % 20;
1098 count += 1
1099 @signal( full );@
1100}
1101int remove( BoundedBufferI & @mutex@ buf ) with( buf ) {
1102 if ( count == 0 ) @wait( full );@
1103 int elem = elements[front];
1104 front = ( front + 1 ) % 20;
1105 count -= 1;
1106 @signal( empty );@
1107 return elem;
1108}
1109
1110\end{cfa}
1111\end{tabular}
1112\end{cquote}
1113
1114\bigskip
1115\noindent
1116External Scheduling
1117\begin{cquote}
1118\setlength{\tabcolsep}{5pt}
1119\begin{tabular}{@{}l|ll@{}}
1120\begin{uC++}
1121
1122_Monitor BoundedBuffer {
1123 int front = 0, back = 0, count = 0;
1124 int elements[20];
1125 public:
1126 _Nomutex int query() const { return count; }
1127 void insert( int elem );
1128 int remove();
1129};
1130
1131void BoundedBuffer::insert( int elem ) {
1132 if ( count == 20 ) @_Accept( remove );@
1133 elements[back] = elem;
1134 back = ( back + 1 ) % 20;
1135 count += 1;
1136}
1137int BoundedBuffer::remove() {
1138 if ( count == 0 ) @_Accept( insert );@
1139 int elem = elements[front];
1140 front = ( front + 1 ) % 20;
1141 count -= 1;
1142 return elem;
1143}
1144\end{uC++}
1145&
1146\begin{cfa}
1147#include <$monitor$.hfa>
1148monitor BoundedBuffer {
1149 int front, back, count;
1150 int elements[20];
1151};
1152void ?{}( BoundedBuffer & buf ) with( buf ) {
1153 front = back = count = 0;
1154}
1155int query( BoundedBuffer & buf ) { return buf.count; }
1156int remove( BoundedBuffer & @mutex@ buf ); // forward
1157void insert( BoundedBuffer & @mutex@ buf, int elem ) with( buf ) {
1158 if ( count == 20 ) @waitfor( remove : buf );@
1159 elements[back] = elem;
1160 back = ( back + 1 ) % 20;
1161 count += 1;
1162}
1163int remove( BoundedBuffer & @mutex@ buf ) with( buf ) {
1164 if ( count == 0 ) @waitfor( insert : buf );@
1165 int elem = elements[front];
1166 front = ( front + 1 ) % 20;
1167 count -= 1;
1168 return elem;
1169}
1170\end{cfa}
1171\end{tabular}
1172\end{cquote}
1173
1174
1175\newpage
1176
1177\section{Futures (reference counting)}
1178
1179
1180{\lstset{tabsize=3}
1181\setlength{\tabcolsep}{5pt}
1182\begin{tabular}{@{}l|ll@{}}
1183\begin{uC++}
1184#include <uFuture.h>
1185@Future_ISM@<int> fi;
1186@Future_ISM@<double> fd;
1187struct Msg { int i, j; }; @Future_ISM@<Msg> fm;
1188struct Stop {}; @Future_ISM@<Stop> fs;
1189struct Cont {}; @Future_ISM@<Cont> fc;
1190
1191_Task Worker {
1192 void main() {
1193
1194 for ( ;; ) {
1195 _Select( fi ) { cout << fi() << endl; fi.reset(); }
1196 and _Select( fd ) { cout << fd() << endl; fd.reset(); }
1197 and _Select( fm ) {
1198 cout << fm().i << " " << fm().j << endl; fm.reset();
1199 } or _Select( fs ) { cout << "stop" << endl; break; }
1200 fc.delivery( (Cont){} ); // synchronize
1201 }
1202 }
1203
1204};
1205int main() {
1206 Worker worker;
1207 for ( int i = 0; i < 10; i += 1 ) {
1208 fi( i ); fd( i + 2.5 ); fm( (Msg){ i, 2 } ); // fulfil
1209 fc(); fc.reset(); // synchronize
1210 }
1211 fs( (Stop){} );
1212} // wait for worker to terminate
1213\end{uC++}
1214&
1215\begin{cfa}
1216#include <future.hfa>
1217@future_rc@(int) fi;
1218@future_rc@(double) fd;
1219struct Msg { int i, j; }; @future_rc@(Msg) fm;
1220struct Stop {}; @future_rc@(Stop) fs;
1221struct Cont {}; @future_rc@(Cont) fc;
1222ExceptionDecl( Break );
1223thread Worker {};
1224void main( Worker & ) {
1225 try {
1226 for () {
1227 waituntil( fi ) { sout | fi(); reset( fi ); }
1228 and waituntil( fd ) { sout | fd(); reset( fd ); }
1229 and waituntil( fm ) { sout | fm().i | fm().j; reset( fm ); }
1230 or waituntil( fs ) { sout | "stop";
1231 throw ExceptionInst( Break );
1232 }
1233 fc( (Cont){} ); // synchronize
1234 }
1235 } catch( Break * ) {}
1236}
1237int main() {
1238 Worker worker;
1239 for ( i; 10 ) {
1240 fi( i ); fd( i + 2.5 ); fm( (Msg){ i, 2 } ); // fulfil
1241 fc(); reset( fc ); // synchronize
1242 }
1243 fs( (Stop){} );
1244} // wait for worker to terminate
1245\end{cfa}
1246\end{tabular}
1247}%
1248
1249%\input{uC++toCFA.ind}
1250
1251% \bibliographystyle{plain}
1252% \bibliography{pl}
1253
1254\end{document}
1255
1256% Local Variables: %
1257% tab-width: 4 %
1258% fill-column: 100 %
1259% compile-command: "make" %
1260% End: %
Note: See TracBrowser for help on using the repository browser.