source: doc/uC++toCFA/uC++toCFA.tex@ 0a10dc8

Last change on this file since 0a10dc8 was 04375cf, checked in by Peter A. Buhr <pabuhr@…>, 5 weeks ago

major updates to the uC++toCFA cheat sheet

  • Property mode set to 100644
File size: 24.7 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 Sep 8 18:10:30 2025
14%% Update Count : 6534
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\begin{tabular}{@{}l|ll@{}}
348\begin{uC++}
349
350
351void main() {
352 try {
353 _Enable {
354 ... suspend(); ...
355 }
356 } @_CatchResume@( E & /* reference */ ) { ... }
357 catch( E & ) { ... }
358}
359\end{uC++}
360&
361\begin{cfa}
362#define resumePoll( coroutine ) resume( coroutine ); poll()
363#define suspendPoll suspend; poll()
364void main() {
365 try {
366 enable_ehm();
367 ... suspendPoll ...
368 disable_ehm();
369 } @catchResume@( E * ) { ... }
370 catch( E & ) { ... }
371}
372\end{cfa}
373\end{tabular}
374\end{cquote}
375
376
377\section{Stream I/O}
378
379\CFA output streams automatically separate values and insert a newline at the end of the print.
380\begin{cquote}
381\begin{tabular}{@{}l|l@{}}
382\begin{uC++}
383#include <@iostream@>
384using namespace std;
385int i; double d; char c;
386cin >> i >> d >> c;
387cout << i << ' ' << d << ' ' << c << endl;
388\end{uC++}
389&
390\begin{cfa}
391#include <@fstream.hfa@>
392
393int i; double d; char c;
394sin | i | d | c;
395sout | i | d | c
396\end{cfa}
397\end{tabular}
398\end{cquote}
399To disable/enable automatic newline at the end of printing, use @nlOff@/@nlOn@ and @nl@.
400\begin{cquote}
401\begin{tabular}{@{}l|l@{}}
402\begin{uC++}
403
404for ( int i = 0; i < 5; i += 1 ) cout << i << ' ';
405cout << @endl@;
4060 1 2 3 4
407\end{uC++}
408&
409\begin{cfa}
410sout | @nlOff@; // disable auto nl
411for ( i; 5 ) sout | i;
412sout | @nl@; sout | @nlOn@; // enable auto nl
4130 1 2 3 4
414\end{cfa}
415\end{tabular}
416\end{cquote}
417Floating-point numbers without a fraction print with a decimal point, which can be disabled with @nodp@.
418\begin{cquote}
419\begin{tabular}{@{}l|l@{}}
420\begin{uC++}
421cout << 3.0 << ' ' << showpoint << setprecision(0) << 3.0 << endl;
4223 3.
423\end{uC++}
424&
425\begin{cfa}
426sout | @nodp( 3.0 )@ | 3.0;
4273 3.
428\end{cfa}
429\end{tabular}
430\end{cquote}
431
432
433\section{String}
434
435The @string@ type in \CFA is very similar to that in \CC.
436\begin{cquote}
437\begin{tabular}{@{}l|l@{}}
438\multicolumn{2}{@{}l@{}}{\lstinline{string s1, s2;}} \\
439\begin{uC++}
440s1 = "abcdefg";
441s2 = s1;
442s1 += s2;
443s1 == s2; s1 != s2;
444s1 < s2; s1 <= s2; s1 > s2; s1 >= s2;
445s1.length();
446s1[3];
447s1.substr( 2 ); s1.substr( 2, 3 );
448s1.replace( 2, 5, s2 );
449s1.find( s2 );
450s1.find_first_of( "cd" );
451s1.find_first_not_of( "cd" );
452getline( cin, s1 );
453cout << s1 << endl;
454\end{uC++}
455&
456\begin{cfa}
457s1 = "abcdefg";
458s2 = s1;
459s1 += s2;
460s1 == s2; s1 != s2;
461s1 < s2; s1 <= s2; s1 > s2; s1 >= s2;
462len( s1 ); // like C strlen( s1 )
463s1[3];
464s1( 2 ); s1( 2, 3 );
465s1( 2, 5 ) = s2;
466find( s1, s2 );
467exclude( s1, "cd" ); // longest sequence excluding "c" and "d"
468include( s1, "cd" ); // longest sequence including "c" and "d"
469sin | getline( s1 );
470sout | s1;
471\end{cfa}
472\end{tabular}
473\end{cquote}
474
475
476\section{\texorpdfstring{\lstinline{uArray}}{uArray}}
477
478\begin{cquote}
479\setlength{\tabcolsep}{5pt}
480\begin{tabular}{@{}l|l@{}}
481\begin{uC++}
482#include <iostream>
483using namespace std;
484
485struct S {
486 int i;
487 S( int i ) { S::i = i; }
488};
489void f( @uArrayRef( S, parm )@ );
490int main() {
491 enum { N = 5 };
492 @uArray( S, s, N );@ // stack, no ctor calls
493 for ( int i = 0; i < N; i += 1 ) @s[i]( i )@; // ctor calls
494 for ( int i = 0; i < N; i += 1 ) cout << s[i]@->@i << endl;
495 f( s );
496 @uArrayPtr( S, sp, N );@ // heap, no ctor calls
497 for ( int i = 0; i < N; i += 1 ) @sp[i]( i )@; // ctor calls
498 for ( int i = 0; i < N; i += 1 ) cout << sp[i]@->@i << endl;
499 f( sp );
500} // delete s, sp
501\end{uC++}
502&
503\begin{cfa}
504#include <fstream.hfa>
505#include <array.hfa>
506#include <memory.hfa>
507struct S {
508 int i;
509};
510void ?{}( S & s, int i ) { s.i = i; }
511@forall( [N] )@ void f( @array( S, N ) & parm@ ) {}
512int main() {
513 enum { N = 5 };
514 @array( S, N ) s = { delay_init };@ // no ctor calls
515 for ( i; N ) @s[i]{ i }@; // ctor calls
516 for ( i; N ) sout | s[i]@.@i;
517 f( s );
518 @unique_ptr( array( S, N ) )@ sp = { delay_init }; // heap
519 for ( int i = 0; i < N; i += 1 ) @(*sp)@[i]{ i }; // ctor calls
520 for ( int i = 0; i < N; i += 1 ) sout | @(*sp)@[i].i;
521 f( @*sp@ );
522} // delete s, sp
523\end{cfa}
524\end{tabular}
525\end{cquote}
526
527
528\section{\texorpdfstring{Structures (object-oriented \protect\vs routine style)}{Structures (object-oriented vs. routine style)}}
529
530\CFA is NOT an object-oriented programming-language, so there is no receiver (\lstinline[language=c++]{this}) or nested structure routines.
531The equivalent of a \emph{member} routine has an explicit structure parameter in any parameter position (often the first).
532\begin{cquote}
533\begin{tabular}{@{}l|l@{}}
534\begin{uC++}
535struct S {
536 int i = 0; // cheat, implicit default constructor
537 int setter( int j ) { int t = i; i = j; return t; }
538 int getter() { return i; }
539};
540S s;
541@s.@setter( 3 ); // object calls
542int k = @s.@getter();
543\end{uC++}
544&
545\begin{cfa}
546struct S { int i; };
547void ?{}( S & s ) { s.i = 0; } // explicit default constructor
548int setter( @S & s,@ int j ) @with( s )@ { int t = i; i = j; return t; }
549int getter( @S & s@ ) @with( s )@ { return i; }
550
551S s;
552setter( @s,@ 3 ); // normal calls
553int k = getter( @s@ );
554\end{cfa}
555\end{tabular}
556\end{cquote}
557Aggregate qualification is reduced or eliminated by opening scopes using the @with@ clause.
558\begin{cfa}
559struct S { int i; int j; double m; }; // field i has same type in structures S and T
560struct T { int i; int k; int m; };
561void foo( S s, T t ) @with( s, t )@ { // open structure scope s and t in parallel
562 j + k; $\C[1.6in]{// unambiguous, s.j + t.k}$
563 m = 5.0; $\C{// unambiguous, s.m = 5.0}$
564 m = 1; $\C{// unambiguous, t.m = 1}$
565 int a = m; $\C{// unambiguous, a = t.m}$
566 double b = m; $\C{// unambiguous, b = s.m}$
567 int c = s.i + t.i; $\C{// unambiguous with qualification}$
568 (double)m; $\C{// unambiguous with cast s.m}\CRT$
569}
570\end{cfa}
571\noindent
572In subsequent code examples, the left example is \CC/\uC and the right example is \CFA.
573
574
575\section{Constructor / Destructor}
576
577A constructor/destructor must have its structure type as the first parameter and be a reference.
578\begin{cquote}
579\begin{tabular}{@{}l|l@{}}
580\begin{uC++}
581
582struct S {
583 int i, j;
584 @S@() { i = j = 3; }
585 @S@( int i, int j ) { S::i = i; S::j = j; }
586 @S@( const S & s ) { *this = s; }
587 @~S@() {}
588};
589S s0;
590S s1 = { 1, 2 };
591
592S * s2 = new S{ 1, 2 };
593delete s2;
594s2 = new S{ 1, 2 };
595delete s2;
596S & s3 = *new S{ 1, 2 };
597delete &s3;
598s3 = *new S{ 1, 2 };
599delete &s3;
600\end{uC++}
601&
602\begin{cfa}
603#include <stdlib.hfa> // new (malloc)
604struct S { int i, j; };
605
606void @?{}@( @S & s@ ) { s.i = s.j = 3; } $\C[3in]{// default}$
607void @?{}@( @S & s@, int i, int j ) { s.i = i; s.j = j; } $\C{// initializer}$
608void @?{}@( @S & s@, const S rhs ) { ?{}( s, rhs.i, rhs.j ); } $\C{// copy}$
609void @^?{}@( @S & s@ ) { s.i = 0; s.j = 0; } $\C{// destructor}\CRT$
610
611S s0;
612S s1 = { 1, 2 };
613// bug, cannot use 0/1 (zero_t/one_t) with "new"
614S * s2 = new( 0@n@, 2 ); // suffix n => (natural int)
615delete( s2 );
616s2 = new( 1@n@, 2 );
617delete( s2 );
618S & s3 = *new( 2, 2 );
619delete( &s3 );
620&s3 = &*new( 3, 2 );
621delete( &s3 );
622\end{cfa}
623\end{tabular}
624\end{cquote}
625
626
627\section{Coroutine}
628
629\begin{cquote}
630\begin{tabular}{@{}l|ll@{}}
631\begin{uC++}
632@_Coroutine@ C {
633 // private coroutine fields
634 void main() {
635 ... @suspend();@ ...
636 ... @_Resume E( ... ) _At partner;@
637 ... @uThisCoroutine();@ ...
638
639 }
640 public:
641 void mem( ... ) {
642 ... @resume();@ ...
643 }
644};
645\end{uC++}
646&
647\begin{cfa}
648#include <$coroutine$.hfa>
649@coroutine@ C {
650 // private coroutine fields
651
652};
653void main( C & c ) {
654 ... @suspend;@ ... // keyword not routine
655 ... @resumeAt( partner, ExceptionInst( E, ... ) );@
656 ... @active_coroutine();@ ...
657}
658void mem( C & c, ... ) {
659 ... @resume( c );@ ...
660}
661\end{cfa}
662\\
663\multicolumn{2}{@{}l@{}}{\lstinline{C c;}}
664\end{tabular}
665\end{cquote}
666
667
668\section{\lstinline{COBEGIN}/\lstinline{COFOR}}
669
670\begin{cquote}
671\begin{tabular}{@{}l|ll@{}}
672\begin{uC++}
673
674#include <uCobegin.h>
675int main() {
676 @COBEGIN@
677 BEGIN osacquire( cout ) << "A" << endl; END
678 BEGIN osacquire( cout ) << "B" << endl; END
679 BEGIN osacquire( cout ) << "C" << endl; END
680 BEGIN osacquire( cout ) << "D" << endl; END
681 @COEND@
682 @COFOR@( i, 1, 10,
683 osacquire( cout ) << i << endl;
684 )
685}
686\end{uC++}
687&
688\begin{cfa}
689#include <mutex_stmt.hfa>
690#include <$cofor$.hfa>
691int main() {
692 {
693 @corun@ { mutex( sout ) sout | "A"; }
694 corun { mutex( sout ) sout | "B"; }
695 corun { mutex( sout ) sout | "C"; }
696 corun { mutex( sout ) sout | "D"; }
697 }
698 @cofor@( i; 10 ) {
699 mutex( sout ) sout | i;
700 }
701}
702\end{cfa}
703\end{tabular}
704\end{cquote}
705
706
707\section{Actor}
708
709\begin{cquote}
710\begin{tabular}{@{}l|ll@{}}
711\begin{uC++}
712#include <iostream>
713using namespace std;
714#include <uActor.h>
715
716struct StrMsg : @public uActor::Message@ {
717
718 const char * val; // string message
719
720 StrMsg( const char * val ) :
721 @Message( uActor::Delete )@, // delete after use
722 val( val ) {}
723};
724\end{uC++}
725&
726\begin{cfa}
727#include <fstream.hfa>
728#include <mutex_stmt.hfa>
729#include <actor.hfa>
730
731struct StrMsg {
732 @inline message;@ // derived message
733 const char * val; // string message
734};
735void ?{}( StrMsg & msg, const char * str ) {
736 @set_allocation( msg, Delete );@ // delete after use
737 msg.val = str;
738}
739\end{cfa}
740\end{tabular}
741\begin{tabular}{@{}l|ll@{}}
742\begin{uC++}
743_Actor Hello { ${\color{red}\LstCommentStyle{// : public uActor}}$
744 Allocation receive( Message & msg ) {
745 Case( @StartMsg@, msg ) { // discriminate
746
747 } else Case( StrMsg, msg ) {
748 osacquire( cout ) << msg_d->val << endl;
749
750 } else Case( @StopMsg@, msg )
751 return Delete; // delete actor
752 return Nodelete; // reuse actor
753 }
754};
755int main() {
756 @uActor::start();@ // start actor system
757 *new Hello() | uActor::startMsg
758 | *new StrMsg( "hello" ) | uActor::stopMsg;
759 *new Hello() | uActor::startMsg
760 | *new StrMsg( "bonjour" ) | uActor::stopMsg;
761 @uActor::stop();@ // wait for actors to terminate
762}
763\end{uC++}
764&
765\begin{cfa}
766struct Hello { @inline actor;@ }; // derived actor
767allocation receive( Hello & receiver, @start_msg_t@ & ) {
768 return Nodelete;
769}
770allocation receive( Hello & receiver, StrMsg & msg ) {
771 mutex( sout ) sout | msg.val;
772 return Nodelete; // reuse actor
773}
774allocation receive( Hello & receiver, @stop_msg_t@ & ) {
775 return Delete; // delete actor
776}
777
778int main() {
779 @actor_start();@ // start actor system
780 *(Hello *)new() | start_msg
781 | *(StrMsg *)new( "hello" ) | stop_msg;
782 *(Hello *)new() | start_msg
783 | *(StrMsg *)new( "bonjour" ) | stop_msg;
784 @actor_stop();@ // wait for actors to terminate
785}
786\end{cfa}
787\end{tabular}
788\end{cquote}
789
790
791\section{Thread}
792
793\begin{cquote}
794\begin{tabular}{@{}l|ll@{}}
795\begin{uC++}
796
797@_Task@ T {
798 // private task fields
799 void main() {
800 ... @_Resume E( ... ) _At partner@;
801 ... @uThisTask();@ ...
802 }
803 public:
804};
805\end{uC++}
806&
807\begin{cfa}
808#include <$thread$.hfa>
809@thread@ T {
810 // private task fields
811
812};
813void main( @T & t@ ) {
814 ... @resumeAt( partner, ExceptionInst( E, ... )@ );
815 ... @active_thread();@ ...
816}
817\end{cfa}
818\\
819\multicolumn{2}{@{}l@{}}{\lstinline{T t; // start thread in main routine}}
820\end{tabular}
821\end{cquote}
822
823
824\section{Locks}
825
826\begin{cquote}
827\begin{tabular}{@{}l|ll@{}}
828\begin{uC++}
829
830uOwnerLock m;
831uCondLock s;
832m.acquire();
833if ( ! s.empty() ) s.wait( m );
834else {
835 m.release();
836}
837@osacquire( cout )@ << i << endl;
838\end{uC++}
839&
840\begin{cfa}
841#include <locks.hfa>
842owner_lock m;
843cond_lock( owner_lock ) s; // generic type on mutex lock
844lock( m );
845if ( ! empty( s ) ) wait( s, m );
846else {
847 unlock( m );
848}
849@mutex( sout )@ sout | i; // thread safe I/O
850\end{cfa}
851\end{tabular}
852\end{cquote}
853
854
855\section{Barrier}
856
857\begin{cquote}
858\begin{tabular}{@{}l|ll@{}}
859\begin{uC++}
860#include <iostream>
861using namespace std;
862#include <uBarrier.h>
863
864@_Cormonitor@ Barrier
865 : @public uBarrier@ { // inheritance
866 int total;
867 void @last@() { cout << total << endl; }
868 public:
869 Barrier( unsigned int group ) :
870 @uBarrier( group )@ {
871 total = 0;
872 }
873 void @block@( int subtotal ) {
874
875
876 total += subtotal;
877 @uBarrier::block();@
878 }
879};
880enum { N = 3 };
881Barrier b{ N };
882\end{uC++}
883&
884\begin{cfa}
885#include <fstream.hfa>
886#include <$thread$.hfa>
887#include <barrier.hfa>
888#include <mutex_stmt.hfa>
889struct Barrier {
890 @barrier b;@ // containment
891 int total;
892
893};
894void ?{}( Barrier & B, unsigned int group ) with(B) {
895 @?{}( b, group );@ // initialize barrier
896 total = 0;
897}
898unsigned int block( Barrier & B, int subtotal ) with(B) {
899 void @last@() { sout | total; } // called by Gth arriving thread
900 @mutex( b )@ { // use barrier's mutual exclusion
901 total += subtotal;
902 return @block@( b, last ); // wait for barrier trigger
903 }
904}
905enum { N = 3 };
906Barrier b{ N };
907\end{cfa}
908\end{tabular}
909\end{cquote}
910
911
912\enlargethispage{1000pt}
913
914\section{Monitor}
915
916Internal Scheduling
917\begin{cquote}
918\begin{tabular}{@{}l|ll@{}}
919\begin{uC++}
920
921@_Monitor@ BoundedBufferI {
922 @uCondition@ full, empty;
923 int front = 0, back = 0, count = 0;
924 int elements[20];
925 public:
926
927
928
929 @_Nomutex@ int query() const { return count; }
930
931 void insert( int elem ) {
932 if ( count == 20 ) @empty.wait();@
933 elements[back] = elem;
934 back = ( back + 1 ) % 20;
935 count += 1;
936 @full.signal();@
937 }
938 int remove() {
939 if ( count == 0 ) @full.wait();@
940 int elem = elements[front];
941 front = ( front + 1 ) % 20;
942 count -= 1;
943 @empty.signal();@
944 return elem;
945 }
946};
947\end{uC++}
948&
949\begin{cfa}
950#include <$monitor$.hfa>
951@monitor@ BoundedBufferI {
952 @condition@ full, empty;
953 int front, back, count;
954 int elements[20];
955};
956void ?{}( BoundedBufferI & buf ) with( buf ) {
957 front = back = count = 0;
958}
959int query( BoundedBufferI & buf ) { return buf.count; }
960int remove( BoundedBufferI & @mutex@ buf ); // forward
961void insert( BoundedBufferI & @mutex@ buf, int elem ) with( buf ) {
962 if ( count == 20 ) @wait( empty );@
963 elements[back] = elem;
964 back = ( back + 1 ) % 20;
965 count += 1
966 @signal( full );@
967}
968int remove( BoundedBufferI & @mutex@ buf ) with( buf ) {
969 if ( count == 0 ) @wait( full );@
970 int elem = elements[front];
971 front = ( front + 1 ) % 20;
972 count -= 1;
973 @signal( empty );@
974 return elem;
975}
976
977\end{cfa}
978\end{tabular}
979\end{cquote}
980
981\newpage
982\noindent
983External Scheduling
984\begin{cquote}
985\begin{tabular}{@{}l|ll@{}}
986\begin{uC++}
987
988_Monitor BoundedBuffer {
989 int front = 0, back = 0, count = 0;
990 int elements[20];
991 public:
992 _Nomutex int query() const { return count; }
993 void insert( int elem );
994 int remove();
995};
996
997void BoundedBuffer::insert( int elem ) {
998 if ( count == 20 ) @_Accept( remove );@
999 elements[back] = elem;
1000 back = ( back + 1 ) % 20;
1001 count += 1;
1002}
1003int BoundedBuffer::remove() {
1004 if ( count == 0 ) @_Accept( insert );@
1005 int elem = elements[front];
1006 front = ( front + 1 ) % 20;
1007 count -= 1;
1008 return elem;
1009}
1010\end{uC++}
1011&
1012\begin{cfa}
1013#include <$monitor$.hfa>
1014monitor BoundedBuffer {
1015 int front, back, count;
1016 int elements[20];
1017};
1018void ?{}( BoundedBuffer & buf ) with( buf ) {
1019 front = back = count = 0;
1020}
1021int query( BoundedBuffer & buf ) { return buf.count; }
1022int remove( BoundedBuffer & @mutex@ buf ); // forward
1023void insert( BoundedBuffer & @mutex@ buf, int elem ) with( buf ) {
1024 if ( count == 20 ) @waitfor( remove : buf );@
1025 elements[back] = elem;
1026 back = ( back + 1 ) % 20;
1027 count += 1;
1028}
1029int remove( BoundedBuffer & @mutex@ buf ) with( buf ) {
1030 if ( count == 0 ) @waitfor( insert : buf );@
1031 int elem = elements[front];
1032 front = ( front + 1 ) % 20;
1033 count -= 1;
1034 return elem;
1035}
1036\end{cfa}
1037\end{tabular}
1038\end{cquote}
1039
1040
1041\input{uC++toCFA.ind}
1042
1043% \bibliographystyle{plain}
1044% \bibliography{pl}
1045
1046\end{document}
1047
1048% Local Variables: %
1049% tab-width: 4 %
1050% fill-column: 100 %
1051% compile-command: "make" %
1052% End: %
Note: See TracBrowser for help on using the repository browser.