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

Last change on this file since fc9d167 was 8659435, checked in by Peter A. Buhr <pabuhr@…>, 2 months ago

update choose and waituntil statements

  • Property mode set to 100644
File size: 29.2 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 : Fri Feb 20 11:19:31 2026
14%% Update Count : 6717
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 @fallthrough@ label in a @case@ clause to transfer to common code or the @default@ clause.
197\begin{cquote}
198\begin{tabular}{@{}l|l@{}}
199\begin{cfa}
200switch ( i ) {
201 case 3: ... @fallthrough common@;
202 case 2: if ( ... ) @fallthrough@;
203 case 1:
204 common: ... ; // implicit fall through
205 default: ... ;
206}
207\end{cfa}
208&
209\begin{cfa}
210choose ( i ) {
211 case 3: ... @fallthrough common@; // labelled explicit fallthrough
212 case 2: if ( ... ) @fallthrough@; // conditional explicit fallthrough
213 case 1:
214 common: ... ; // implicit break
215 default: ... ;
216}
217\end{cfa}
218\end{tabular}
219\end{cquote}
220To simplify creating an infinite loop, the loop condition in optional.
221\begin{cquote}
222\begin{tabular}{@{}l|l@{}}
223\begin{uC++}
224while ( true ) ...
225for ( ;; ) ...
226do ... while ( true )
227\end{uC++}
228&
229\begin{uC++}
230while ($\,$) ...
231for ($\,$) ...
232do ... while ($\,$)
233\end{uC++}
234\end{tabular}
235\end{cquote}
236To simplify loop iteration a range is provided, from low to high, and a traversal direction, ascending (@+@) or descending (@-@).
237The following is the syntax for the loop range, where @[@\,@]@ means optional.
238\begin{cfa}[deletekeywords=default]
239[ @index ;@ ] [ [ @min@ (default 0) ] [ direction @+@/@-@ (default +) ] @~@ [ @=@ (include endpoint) ] ] @max@ [ @~ increment@ ]
240\end{cfa}
241For @=@, the range includes the endpoint (@max@/@min@) depending on the direction (@+@/@-@).
242\begin{cquote}
243\begin{tabular}{@{}l|l@{}}
244\begin{uC++}
245for ( int i = 0; i < @10@; i += 1 ) { ... }
246for ( int i = @5@; i < @15@; i += @2@ ) { ... }
247for ( int i = -2; i <@=@ 10; i += 3 ) { ... }
248for ( int i = 10; i > -3; i @-@= 1 ) { ... }
249for ( int i = 10; i >@=@ 0; i @-@= 1 ) { ... }
250\end{uC++}
251&
252\begin{cfa}
253for ( @10@ ) { ... } / for ( i; @10@ ) { ... } // 0 to 9 by 1
254for ( i; @5@ ~ @15@ ~ @2@ ) { ... } // 5 to 14 by 2
255for ( i; -2 ~@=@ 10 ~ 3 ) { ... } // -2 to 10 by 3
256for ( i; -3 @-@~ 10 ) { ... } // 10 to -2 by -1, not 10 -~= -3
257for ( i; 0 @-@~@=@ 10 ) { ... } // 10 to 0 by -1, not 10 -~= 0
258\end{cfa}
259\end{tabular}
260\end{cquote}
261A 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.
262The loop index is available in the @else@ clause.
263\begin{cquote}
264\begin{tabular}{@{}l|l@{}}
265\begin{uC++}
266int i = 0
267for ( i = 0; i < 10; i += 1 ) { ... }
268@if ( i == 10 )@ { ... }
269\end{uC++}
270&
271\begin{cfa}
272
273for ( i; 10 ) { ... }
274@else@ { ... } // i == 10 because of post increment
275\end{cfa}
276\end{tabular}
277\end{cquote}
278Single/multiple-level loop exit/continue is provided by the labelled @break@/@continue@. (First example is \CC.)
279\begin{cquote}
280\begin{tabular}{@{}l|l|l@{}}
281\begin{C++}
282@L1:@ for ( ;; ) {
283 for ( ;; ) {
284 ... if ( ... ) @goto L1@; ...
285 ... if ( ... ) @goto L2@; ...
286 } @L2: ;@
287}
288\end{C++}
289&
290\begin{cfa}
291@L1:@ for () {
292 @L2:@ for () {
293 ... if ( ... ) @continue L1@; ...
294 ... if ( ... ) @break L2@; ...
295 }
296}
297\end{cfa}
298&
299\begin{cfa}
300@L1:@ for () {
301 @L2:@ for () {
302 ... if ( ... ) @continue L1@; ...
303 ... if ( ... ) @break L2@; ...
304 }
305}
306\end{cfa}
307\end{tabular}
308\end{cquote}
309
310
311\section{Exception}
312
313Currently, \CFA uses macros @ExceptionDecl@ and @ExceptionInst@ to declare and instantiate an exception.
314\begin{cquote}
315\setlength{\tabcolsep}{5pt}
316\begin{tabular}{@{}l|ll@{}}
317\begin{uC++}
318
319@_Exception@ E { // local or global scope
320 ... // exception fields
321};
322try {
323 ... if ( ... ) @_Resume@ E( /* initialization */ ); ...
324 ... if ( ... ) @_Throw@ E( /* initialization */ ); ...
325} @_CatchResume@( E & /* reference */ ) { ... }
326 catch( E & ) { ... }
327 catch( ... /* catch any */ ) { ... }
328 _Finally { ... }
329\end{uC++}
330&
331\begin{cfa}
332#include <Exception.hfa>
333@ExceptionDecl@( E, // must be global scope
334 ... // exception fields
335);
336try {
337 ... if ( ... ) @throwResume@ @ExceptionInst@( E, /* intialization */ ); ...
338 ... if ( ... ) @throw@ @ExceptionInst@( E, /* intialization */ ); ...
339} @catchResume@( E @*@ /* pointer */ ) { ... }
340 catch( E * ) { ... }
341 catch( exception_t @*@ /* catch any */ ) { ... }
342 finally { ... }
343\end{cfa}
344\end{tabular}
345\end{cquote}
346
347
348\section{Non-local Exception}
349
350\begin{cquote}
351\setlength{\tabcolsep}{5pt}
352\begin{tabular}{@{}l|ll@{}}
353\begin{uC++}
354
355
356void Coroutine::main() {
357 try {
358 _Enable {
359 ... suspend(); ...
360 }
361 } @_CatchResume@( E & /* reference */ ) { ... }
362 catch( E & ) { ... }
363}
364void Coroutine::mem() { resume(); }
365\end{uC++}
366&
367\begin{cfa}
368#define resumePoll( coroutine ) resume( coroutine ); poll()
369#define suspendPoll suspend; poll()
370void main( Coroutine & cor ) {
371 try {
372 enable_ehm();
373 ... suspendPoll ...
374 disable_ehm();
375 } @catchResume@( E * ) { ... }
376 catch( E & ) { ... }
377}
378void mem( Coroutine & cor ) { resumePoll(); }
379\end{cfa}
380\end{tabular}
381\end{cquote}
382
383
384\section{Stream I/O}
385
386\CFA output streams automatically separate values and insert a newline at the end of the print.
387\begin{cquote}
388\begin{tabular}{@{}l|l@{}}
389\begin{uC++}
390#include <@iostream@>
391using namespace std;
392int i; double d; char c;
393cin >> i >> d >> c;
394cout << i << ' ' << d << ' ' << c << endl;
395\end{uC++}
396&
397\begin{cfa}
398#include <@fstream.hfa@>
399
400int i; double d; char c;
401sin | i | d | c;
402sout | i | d | c
403\end{cfa}
404\end{tabular}
405\end{cquote}
406To disable/enable automatic newline at the end of printing, use @nlOff@/@nlOn@ and @nl@.
407\begin{cquote}
408\begin{tabular}{@{}l|l@{}}
409\begin{uC++}
410
411for ( int i = 0; i < 5; i += 1 ) cout << i << ' ';
412cout << @endl@;
4130 1 2 3 4
414\end{uC++}
415&
416\begin{cfa}
417sout | @nlOff@; // disable auto nl
418for ( i; 5 ) sout | i;
419sout | @nl@; sout | @nlOn@; // enable auto nl
4200 1 2 3 4
421\end{cfa}
422\end{tabular}
423\end{cquote}
424Floating-point numbers without a fraction print with a decimal point, which can be disabled with @nodp@.
425\begin{cquote}
426\begin{tabular}{@{}l|l@{}}
427\begin{uC++}
428cout << 3.0 << ' ' << showpoint << setprecision(0) << 3.0 << endl;
4293 3.
430\end{uC++}
431&
432\begin{cfa}
433sout | @nodp( 3.0 )@ | 3.0;
4343 3.
435\end{cfa}
436\end{tabular}
437\end{cquote}
438
439
440\section{Time}
441
442\begin{cquote}
443\setlength{\tabcolsep}{5pt}
444\begin{tabular}{@{}l|l@{}}
445\begin{uC++}
446
447uTime start = uClock::currTime();
448...
449cout << "duration " << uClock::currTime() - start
450 << " sec." << endl;
451\end{uC++}
452&
453\begin{cfa}
454#include <clock.hfa>
455Time start = timeHiRes(); // time with nanoseconds
456...
457sout | "duration " | timeHiRes() - start | " sec.";
458
459\end{cfa}
460\end{tabular}
461\end{cquote}
462
463
464\section{Constructor / Destructor}
465
466A constructor/destructor must have its structure type as the first parameter and be a reference.
467\begin{cquote}
468\begin{tabular}{@{}l|l@{}}
469\begin{uC++}
470
471struct S {
472 int i, j;
473 @S@() { i = j = 3; }
474 @S@( int i, int j ) { S::i = i; S::j = j; }
475 @S@( const S & s ) { *this = s; }
476 @~S@() {}
477};
478S s0, s1 = { 1, 2 };
479
480S * s2 = new S{ 1, 2 }; delete s2;
481s2 = new S{ 1, 2 }; delete s2;
482S & s3 = *new S{ 1, 2 }; delete &s3;
483s3 = *new S{ 1, 2 }; delete &s3;
484\end{uC++}
485&
486\begin{cfa}
487#include <stdlib.hfa> // new (malloc)
488struct S { int i, j; };
489
490void @?{}@( @S & s@ ) { s.i = s.j = 3; } $\C[3in]{// default}$
491void @?{}@( @S & s@, int i, int j ) { s.i = i; s.j = j; } $\C{// initializer}$
492void @?{}@( @S & s@, const S rhs ) { ?{}( s, rhs.i, rhs.j ); } $\C{// copy}$
493void @^?{}@( @S & s@ ) { s.i = 0; s.j = 0; } $\C{// destructor}\CRT$
494
495S s0, s1 = { 1, 2 };
496// bug, cannot use 0/1 (zero_t/one_t) with "new"
497S * s2 = new( 0@n@, 2 ); /* suffix n => (natural int) */ delete( s2 );
498s2 = new( 1@n@, 2 ); delete( s2 );
499S & s3 = *new( 2, 2 ); delete( &s3 );
500&s3 = &*new( 3, 2 ); delete( &s3 );
501\end{cfa}
502\end{tabular}
503\end{cquote}
504
505
506\section{\texorpdfstring{Structures (object-oriented \protect\vs routine style)}{Structures (object-oriented vs. routine style)}}
507
508\CFA is NOT an object-oriented programming-language, so there is no receiver (\lstinline[language=c++]{this}) or nested structure routines.
509The equivalent of a \emph{member} routine has an explicit structure parameter in any parameter position (often the first).
510\begin{cquote}
511\begin{tabular}{@{}l|l@{}}
512\begin{uC++}
513struct S {
514 int i = 0; // cheat, implicit default constructor
515 int setter( int j ) { int t = i; i = j; return t; }
516 int getter() { return i; }
517};
518S s;
519@s.@setter( 3 ); // object calls
520int k = @s.@getter();
521\end{uC++}
522&
523\begin{cfa}
524struct S { int i; };
525void ?{}( S & s ) { s.i = 0; } // explicit default constructor
526int setter( @S & s,@ int j ) @with( s )@ { int t = i; i = j; return t; }
527int getter( @S & s@ ) @with( s )@ { return i; }
528
529S s;
530setter( @s,@ 3 ); // normal calls
531int k = getter( @s@ );
532\end{cfa}
533\end{tabular}
534\end{cquote}
535Aggregate qualification is reduced or eliminated by opening scopes using the @with@ clause.
536\begin{cfa}
537struct S { int i; int j; double m; }; // field i has same type in structures S and T
538struct T { int i; int k; int m; };
539void foo( S s, T t ) @with( s, t )@ { // open structure scope s and t in parallel
540 j + k; $\C[1.6in]{// unambiguous, s.j + t.k}$
541 m = 5.0; $\C{// unambiguous, s.m = 5.0}$
542 m = 1; $\C{// unambiguous, t.m = 1}$
543 int a = m; $\C{// unambiguous, a = t.m}$
544 double b = m; $\C{// unambiguous, b = s.m}$
545 int c = s.i + t.i; $\C{// unambiguous with qualification}$
546 (double)m; $\C{// unambiguous with cast s.m}\CRT$
547}
548\end{cfa}
549\noindent
550In subsequent code examples, the left example is \CC/\uC and the right example is \CFA.
551
552
553\section{String}
554
555The @string@ type in \CFA is very similar to that in \CC.
556\begin{cquote}
557\begin{tabular}{@{}l|l@{}}
558\multicolumn{2}{@{}l@{}}{\lstinline{string s1, s2;}} \\
559\begin{uC++}
560s1 = "abcdefg";
561s2 = s1;
562s1 += s2;
563s1 == s2; s1 != s2;
564s1 < s2; s1 <= s2; s1 > s2; s1 >= s2;
565s1.length();
566s1[3];
567s1.substr( 2 ); s1.substr( 2, 3 );
568s1.replace( 2, 5, s2 );
569s1.find( s2 );
570s1.find_first_of( "cd" );
571s1.find_first_not_of( "cd" );
572getline( cin, s1 );
573cout << s1 << endl;
574\end{uC++}
575&
576\begin{cfa}
577s1 = "abcdefg";
578s2 = s1;
579s1 += s2;
580s1 == s2; s1 != s2;
581s1 < s2; s1 <= s2; s1 > s2; s1 >= s2;
582len( s1 ); // like C strlen( s1 )
583s1[3];
584s1( 2 ); s1( 2, 3 );
585s1( 2, 5 ) = s2;
586find( s1, s2 );
587exclude( s1, "cd" ); // longest sequence excluding "c" and "d"
588include( s1, "cd" ); // longest sequence including "c" and "d"
589sin | getline( s1 );
590sout | s1;
591\end{cfa}
592\end{tabular}
593\end{cquote}
594
595
596\enlargethispage{1000pt}
597\section{\texorpdfstring{\lstinline{uArray}}{uArray}}
598
599\begin{cquote}
600\setlength{\tabcolsep}{5pt}
601\begin{tabular}{@{}l|l@{}}
602\begin{uC++}
603#include <iostream>
604using namespace std;
605
606struct S {
607 int i;
608 S( int i ) { S::i = i; }
609};
610void f( @uArrayRef( S, parm )@ );
611int main() {
612 enum { N = 5 };
613 @uArray( S, s, N );@ // stack, no ctor calls
614 for ( int i = 0; i < N; i += 1 ) @s[i]( i )@; // ctor calls
615 for ( int i = 0; i < N; i += 1 ) cout << s[i]@->@i << endl;
616 f( s );
617 @uArrayPtr( S, sp, N );@ // heap, no ctor calls
618 for ( int i = 0; i < N; i += 1 ) @sp[i]( i )@; // ctor calls
619 for ( int i = 0; i < N; i += 1 ) cout << sp[i]@->@i << endl;
620 f( sp );
621} // delete s, sp
622\end{uC++}
623&
624\begin{cfa}
625#include <fstream.hfa>
626#include <array.hfa>
627#include <memory.hfa>
628struct S {
629 int i;
630};
631void ?{}( S & s, int i ) { s.i = i; }
632@forall( [N] )@ void f( @array( S, N ) & parm@ ) {}
633int main() {
634 enum { N = 5 };
635 @array( S, N ) s = { delay_init };@ // no ctor calls
636 for ( i; N ) @s[i]{ i }@; // ctor calls
637 for ( i; N ) sout | s[i]@.@i;
638 f( s );
639 @unique_ptr( array( S, N ) )@ sp = { delay_init }; // heap
640 for ( int i = 0; i < N; i += 1 ) @(*sp)@[i]{ i }; // ctor calls
641 for ( int i = 0; i < N; i += 1 ) sout | @(*sp)@[i].i;
642 f( @*sp@ );
643} // delete s, sp
644\end{cfa}
645\end{tabular}
646\end{cquote}
647
648\newpage
649
650
651\section{Doubly-Linked Intrusive List}
652
653\begin{cquote}
654\setlength{\tabcolsep}{10pt}
655\begin{tabular}{@{}l|l@{}}
656\begin{uC++}
657#include <iostream>
658using namespace std;
659struct Node : @public uSeqable@ {
660 int i;
661 Node( int i ) : i( i ) {}
662};
663
664
665int main() {
666 @uSequence<Node> dlist;@
667 Node n1{ 1 }, n2{ 2 }, n3{ 3 };
668 dlist.addTail( &n1 );
669 dlist.addHead( &n2 ); // out of order
670 dlist.insertAft( &n1, &n3 ); // insertBef
671 for ( Node * it = dlist.head(); it; it = dlist.succ( it ) ) {
672 cout << it->i << endl;
673 }
674 dlist.remove( &n3 ); // shorten list
675 dlist.dropTail(); // dropHead
676 Node * it;
677 for ( uSeqIter<Node> seqit(dlist); // uSeqIterRev
678 seqit >> it; ) {
679 cout << it->i << endl;
680 }
681}
682\end{uC++}
683&
684\begin{cfa}
685#include <fstream.hfa>
686#include <list.hfa>
687struct Node {
688 @inline dlink( Node );@
689 int i;
690};
691@P9_EMBEDDED( Node, dlink( Node ) );@ // magic
692void ?{}( Node & node, int i ) { node.i = i; }
693int main() {
694 @dlist( Node ) dlist;@
695 Node n1{ 1 }, n2{ 2 }, n3{ 3 };
696 insert_last( dlist, n1 );
697 insert_first( dlist, n2 ); // out of order
698 insert_after( n1, n3 ); // insert_before
699 for ( Node & it = first( dlist ); &it; &it = &next( it ) ) {
700 sout | it.i;
701 }
702 remove( n3 ); // shorten list
703 remove_last( dlist ); // remove_first
704
705 FOREACH( dlist, it ) { // FOREACH_REV
706
707 sout | it.i;
708 }
709}
710\end{cfa}
711\end{tabular}
712\end{cquote}
713
714
715\section{RAII Dynamic Allocation}
716
717\begin{cquote}
718\begin{tabular}{@{}l|ll@{}}
719\begin{uC++}
720struct S {
721 ... S() { ... } ~S() { ... } // ctor / dtor
722};
723S * s = new S; delete s;
724S * sa = new S[10]; delete [] sa;
725\end{uC++}
726&
727\begin{cfa}
728#include <stdlib.hfa>
729struct S { ... };
730void ?{}( S & ) { ... } void ^?{}( S & ) { ... } // ctor / dtor
731S * s = new(); delete( s );
732S * sa = anew( 10 ); adelete( sa );
733\end{cfa}
734\end{tabular}
735\end{cquote}
736
737
738\section{Coroutine}
739
740\begin{cquote}
741\begin{tabular}{@{}l|ll@{}}
742\begin{uC++}
743@_Coroutine@ C {
744 // private coroutine fields
745 void main() {
746 ... @suspend();@ ...
747 ... @_Resume E( ... ) _At partner;@
748 ... @uThisCoroutine();@ ...
749
750 }
751 public:
752 void mem( ... ) {
753 ... @resume();@ ...
754 }
755};
756\end{uC++}
757&
758\begin{cfa}
759#include <$coroutine$.hfa>
760@coroutine@ C {
761 // private coroutine fields
762
763};
764void main( C & c ) {
765 ... @suspend;@ ... // keyword not routine
766 ... @resumeAt( partner, ExceptionInst( E, ... ) );@
767 ... @active_coroutine();@ ...
768}
769void mem( C & c, ... ) {
770 ... @resume( c );@ ...
771}
772\end{cfa}
773\end{tabular}
774\end{cquote}
775
776
777\section{\lstinline{COBEGIN}/\lstinline{COFOR}}
778
779\begin{cquote}
780\begin{tabular}{@{}l|ll@{}}
781\begin{uC++}
782
783#include <uCobegin.h>
784int main() {
785 @COBEGIN@
786 BEGIN osacquire( cout ) << "A" << endl; END
787 BEGIN osacquire( cout ) << "B" << endl; END
788 BEGIN osacquire( cout ) << "C" << endl; END
789 BEGIN osacquire( cout ) << "D" << endl; END
790 @COEND@
791 @COFOR@( i, 1, 10,
792 osacquire( cout ) << i << endl;
793 )
794}
795\end{uC++}
796&
797\begin{cfa}
798#include <mutex_stmt.hfa>
799#include <$cofor$.hfa>
800int main() {
801 {
802 @corun@ { mutex( sout ) sout | "A"; }
803 corun { mutex( sout ) sout | "B"; }
804 corun { mutex( sout ) sout | "C"; }
805 corun { mutex( sout ) sout | "D"; }
806 }
807 @cofor@( i; 10 ) {
808 mutex( sout ) sout | i;
809 }
810}
811\end{cfa}
812\end{tabular}
813\end{cquote}
814
815
816\section{Actor}
817
818\begin{cquote}
819\setlength{\tabcolsep}{10pt}
820\begin{tabular}{@{}l|ll@{}}
821\begin{uC++}
822#include <iostream>
823using namespace std;
824#include <uActor.h>
825
826struct StrMsg : @public uActor::Message@ {
827
828 const char * val; // string message
829
830 StrMsg( const char * val ) :
831 @Message( uActor::Delete )@, // delete after use
832 val( val ) {}
833};
834\end{uC++}
835&
836\begin{cfa}
837#include <fstream.hfa>
838#include <mutex_stmt.hfa>
839#include <actor.hfa>
840
841struct StrMsg {
842 @inline message;@ // derived message
843 const char * val; // string message
844};
845void ?{}( StrMsg & msg, const char * str ) {
846 @set_allocation( msg, Delete );@ // delete after use
847 msg.val = str;
848}
849\end{cfa}
850\\
851\begin{uC++}
852_Actor Hello { ${\color{red}\LstCommentStyle{// : public uActor}}$
853 Allocation receive( Message & msg ) {
854 Case( @StartMsg@, msg ) { // discriminate
855
856 } else Case( StrMsg, msg ) {
857 osacquire( cout ) << msg_d->val << endl;
858
859 } else Case( @StopMsg@, msg )
860 return Delete; // delete actor
861 return Nodelete; // reuse actor
862 }
863};
864int main() {
865 @uActor::start();@ // start actor system
866 *new Hello() | uActor::startMsg
867 | *new StrMsg( "hello" ) | uActor::stopMsg;
868 *new Hello() | uActor::startMsg
869 | *new StrMsg( "bonjour" ) | uActor::stopMsg;
870 @uActor::stop();@ // wait for actors to terminate
871}
872\end{uC++}
873&
874\begin{cfa}
875struct Hello { @inline actor;@ }; // derived actor
876allocation receive( Hello & receiver, @start_msg_t@ & ) {
877 return Nodelete;
878}
879allocation receive( Hello & receiver, StrMsg & msg ) {
880 mutex( sout ) sout | msg.val;
881 return Nodelete; // reuse actor
882}
883allocation receive( Hello & receiver, @stop_msg_t@ & ) {
884 return Delete; // delete actor
885}
886
887int main() {
888 @actor_start();@ // start actor system
889 *(Hello *)new() | start_msg
890 | *(StrMsg *)new( "hello" ) | stop_msg;
891 *(Hello *)new() | start_msg
892 | *(StrMsg *)new( "bonjour" ) | stop_msg;
893 @actor_stop();@ // wait for actors to terminate
894}
895\end{cfa}
896\end{tabular}
897\end{cquote}
898
899
900\section{Thread}
901
902\begin{cquote}
903\begin{tabular}{@{}l|ll@{}}
904\begin{uC++}
905
906@_Task@ T {
907 // private task fields
908 void main() {
909 ... @_Resume E( ... ) _At partner@;
910 ... @uThisTask();@ ...
911 }
912 public:
913};
914T t;
915uProcessor p[3];
916\end{uC++}
917&
918\begin{cfa}
919#include <$thread$.hfa>
920@thread@ T {
921 // private task fields
922
923};
924void main( @T & t@ ) {
925 ... @resumeAt( partner, ExceptionInst( E, ... ) )@;
926 ... @active_thread();@ ...
927}
928T t; // create thread object and start thread in main
929processor p[3]; // 4 kernel threads including program main
930\end{cfa}
931\end{tabular}
932\end{cquote}
933
934
935\section{Locks}
936
937\begin{cquote}
938\begin{tabular}{@{}l|ll@{}}
939\begin{uC++}
940
941uOwnerLock m;
942uCondLock c;
943m.acquire();
944if ( ! c.empty() ) c.wait( m );
945else {
946 m.release();
947}
948@osacquire( cout )@ << i << endl;
949\end{uC++}
950&
951\begin{cfa}
952#include <locks.hfa>
953owner_lock m;
954cond_lock( owner_lock ) c; // generic type on mutex lock
955lock( m );
956if ( ! empty( c ) ) wait( c, m );
957else {
958 unlock( m );
959}
960@mutex( sout )@ sout | i; // thread safe I/O
961\end{cfa}
962\end{tabular}
963\end{cquote}
964
965\begin{cquote}
966\begin{tabular}{@{}l|ll@{}}
967\begin{uC++}
968
969uSemaphore m, c;
970m.P();
971if ( ! c.empty() ) c.P( m );
972else {
973 m.V();
974}
975\end{uC++}
976&
977\begin{cfa}
978#include <locks.hfa>
979semaphore m, c;
980P( m );
981if ( ! empty( c ) ) P( c, m );
982else {
983 V( m );
984}
985\end{cfa}
986\end{tabular}
987\end{cquote}
988
989
990\enlargethispage{1000pt}
991
992\section{Barrier}
993
994\begin{cquote}
995\begin{tabular}{@{}l|ll@{}}
996\begin{uC++}
997#include <iostream>
998using namespace std;
999#include <uBarrier.h>
1000
1001@_Cormonitor@ Barrier
1002 : @public uBarrier@ { // inheritance
1003 int total;
1004 void @last@() { cout << total << endl; }
1005 public:
1006 Barrier( unsigned int group ) :
1007 @uBarrier( group )@ {
1008 total = 0;
1009 }
1010 void @block@( int subtotal ) {
1011
1012
1013 total += subtotal;
1014 @uBarrier::block();@
1015 }
1016};
1017Barrier b{ 3 };
1018\end{uC++}
1019&
1020\begin{cfa}
1021#include <fstream.hfa>
1022#include <$thread$.hfa>
1023#include <barrier.hfa>
1024#include <mutex_stmt.hfa>
1025struct Barrier {
1026 @inline barrier;@
1027 int total;
1028
1029};
1030void ?{}( Barrier & b, unsigned int group ) with( b ) {
1031 @(b){ group };@ // initialize barrier
1032 total = 0;
1033}
1034unsigned int block( Barrier & b, int subtotal ) with( b ) {
1035 void @last@(...) { sout | total; } // called by Gth arriving thread
1036 @mutex( b )@ { // use barrier's mutual exclusion
1037 total += subtotal;
1038 return @block@( b, last ); // wait for barrier trigger
1039 }
1040}
1041Barrier b{ 3 };
1042\end{cfa}
1043\end{tabular}
1044\end{cquote}
1045
1046\newpage
1047
1048\enlargethispage{1000pt}
1049
1050\section{Monitor}
1051
1052Internal Scheduling
1053\begin{cquote}
1054\setlength{\tabcolsep}{5pt}
1055\begin{tabular}{@{}l|ll@{}}
1056\begin{uC++}
1057
1058@_Monitor@ BoundedBufferI {
1059 @uCondition@ full, empty;
1060 int front = 0, back = 0, count = 0;
1061 int elements[20];
1062 public:
1063
1064
1065
1066 @_Nomutex@ int query() const { return count; }
1067
1068 void insert( int elem ) {
1069 if ( count == 20 ) @empty.wait();@
1070 elements[back] = elem;
1071 back = ( back + 1 ) % 20;
1072 count += 1;
1073 @full.signal();@
1074 }
1075 int remove() {
1076 if ( count == 0 ) @full.wait();@
1077 int elem = elements[front];
1078 front = ( front + 1 ) % 20;
1079 count -= 1;
1080 @empty.signal();@
1081 return elem;
1082 }
1083};
1084\end{uC++}
1085&
1086\begin{cfa}
1087#include <$monitor$.hfa>
1088@monitor@ BoundedBufferI {
1089 @condition@ full, empty;
1090 int front, back, count;
1091 int elements[20];
1092};
1093void ?{}( BoundedBufferI & buf ) with( buf ) {
1094 front = back = count = 0;
1095}
1096int query( BoundedBufferI & buf ) { return buf.count; }
1097int remove( BoundedBufferI & @mutex@ buf ); // forward
1098void insert( BoundedBufferI & @mutex@ buf, int elem ) with( buf ) {
1099 if ( count == 20 ) @wait( empty );@
1100 elements[back] = elem;
1101 back = ( back + 1 ) % 20;
1102 count += 1
1103 @signal( full );@
1104}
1105int remove( BoundedBufferI & @mutex@ buf ) with( buf ) {
1106 if ( count == 0 ) @wait( full );@
1107 int elem = elements[front];
1108 front = ( front + 1 ) % 20;
1109 count -= 1;
1110 @signal( empty );@
1111 return elem;
1112}
1113
1114\end{cfa}
1115\end{tabular}
1116\end{cquote}
1117
1118\bigskip
1119\noindent
1120External Scheduling
1121\begin{cquote}
1122\setlength{\tabcolsep}{5pt}
1123\begin{tabular}{@{}l|ll@{}}
1124\begin{uC++}
1125
1126_Monitor BoundedBuffer {
1127 int front = 0, back = 0, count = 0;
1128 int elements[20];
1129 public:
1130 _Nomutex int query() const { return count; }
1131 void insert( int elem );
1132 int remove();
1133};
1134
1135void BoundedBuffer::insert( int elem ) {
1136 if ( count == 20 ) @_Accept( remove );@
1137 elements[back] = elem;
1138 back = ( back + 1 ) % 20;
1139 count += 1;
1140}
1141int BoundedBuffer::remove() {
1142 if ( count == 0 ) @_Accept( insert );@
1143 int elem = elements[front];
1144 front = ( front + 1 ) % 20;
1145 count -= 1;
1146 return elem;
1147}
1148\end{uC++}
1149&
1150\begin{cfa}
1151#include <$monitor$.hfa>
1152monitor BoundedBuffer {
1153 int front, back, count;
1154 int elements[20];
1155};
1156void ?{}( BoundedBuffer & buf ) with( buf ) {
1157 front = back = count = 0;
1158}
1159int query( BoundedBuffer & buf ) { return buf.count; }
1160int remove( BoundedBuffer & @mutex@ buf ); // forward
1161void insert( BoundedBuffer & @mutex@ buf, int elem ) with( buf ) {
1162 if ( count == 20 ) @waitfor( remove : buf );@
1163 elements[back] = elem;
1164 back = ( back + 1 ) % 20;
1165 count += 1;
1166}
1167int remove( BoundedBuffer & @mutex@ buf ) with( buf ) {
1168 if ( count == 0 ) @waitfor( insert : buf );@
1169 int elem = elements[front];
1170 front = ( front + 1 ) % 20;
1171 count -= 1;
1172 return elem;
1173}
1174\end{cfa}
1175\end{tabular}
1176\end{cquote}
1177
1178
1179\newpage
1180
1181\section{Futures (reference counting)}
1182
1183
1184{\lstset{tabsize=4}
1185\setlength{\tabcolsep}{5pt}
1186\begin{tabular}{@{}l|ll@{}}
1187\begin{uC++}
1188#include <uFuture.h>
1189@Future_ISM@<int> fi;
1190@Future_ISM@<double> fd;
1191struct Msg { int i, j; }; @Future_ISM@<Msg> fm;
1192struct Cont {}; @Future_ISM@<Cont> fc;
1193_Exception Stop {};
1194
1195_Task Worker {
1196 void main() {
1197 try {
1198 for ( ;; ) {
1199 _Select( fi ) { cout << fi() << endl; fi.reset(); }
1200 and _Select( fd ) { cout << fd() << endl; fd.reset(); }
1201 and _Select( fm ) {
1202 cout << fm().i << " " << fm().j << endl; fm.reset();
1203 }
1204 fc( (Cont){} ); // synchronize
1205 }
1206 } catch( Stop & ) { cout << "stop" << endl;}
1207 }
1208};
1209int main() {
1210 Worker worker;
1211 for ( int i = 0; i < 10; i += 1 ) {
1212 fi( i ); fd( i + 2.5 ); fm( (Msg){ i, 2 } ); // fulfil
1213 fc(); fc.reset(); // synchronize
1214 }
1215 fi( new Stop{} ); // trigger exception
1216} // wait for worker to terminate
1217\end{uC++}
1218&
1219\begin{cfa}
1220#include <future.hfa>
1221@future_rc@( int ) fi;
1222@future_rc@( double ) fd;
1223struct Msg { int i, j; }; @future_rc@( Msg ) fm;
1224struct Cont {}; @future_rc@( Cont ) fc;
1225ExceptionDecl( Stop );
1226
1227thread Worker {};
1228void main( Worker & ) {
1229 try {
1230 for () {
1231 waituntil( fi ) { sout | fi(); reset( fi ); }
1232 and waituntil( fd ) { sout | fd(); reset( fd ); }
1233 and waituntil( fm ) {
1234 sout | fm().i | fm().j; reset( fm );
1235 }
1236 fc( (Cont){} ); // synchronize
1237 }
1238 } catch( Stop * ) { sout | "stop"; }
1239}
1240
1241int main() {
1242 Worker worker;
1243 for ( i; 10 ) {
1244 fi( i ); fd( i + 2.5 ); fm( (Msg){ i, 2 } ); // fulfil
1245 fc(); reset( fc ); // synchronize
1246 }
1247 fi( ExceptionPtr( ExceptionInst( Stop ) ) );
1248} // wait for worker to terminate
1249\end{cfa}
1250\end{tabular}
1251}%
1252
1253%\input{uC++toCFA.ind}
1254
1255% \bibliographystyle{plain}
1256% \bibliography{pl}
1257
1258\end{document}
1259
1260% Local Variables: %
1261% tab-width: 4 %
1262% fill-column: 100 %
1263% compile-command: "make" %
1264% End: %
Note: See TracBrowser for help on using the repository browser.