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
RevLine 
[697c957]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
[8659435]13%% Last Modified On : Fri Feb 20 11:19:31 2026
14%% Update Count : 6717
[697c957]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}
[567a75f]84\setlength{\tabcolsep}{15pt}
[697c957]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}
[946a6e4]121\uC to \CFA Cheat Sheet}
[697c957]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
[567a75f]136\vspace*{-0.65in}
[697c957]137
138\section{Introduction}
139
[04375cf]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.
[697c957]142\begin{cfa}
[567a75f]143int x; char x; double x; // overload name x
144int x(); double x(); char x();
[697c957]145\end{cfa}
[567a75f]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}
[04375cf]162\CFA generalizes reference types, allowing multiple and rebindable references (like pointers).
[697c957]163\begin{cquote}
[2b6db03]164\begin{tabular}{@{}l|l@{}}
165\multicolumn{2}{@{}l}{\lstinline{ int x = 1, y = 2, * p1x = &x, * p1y = &y, ** p2i = &p1x,}} \\
[3733643]166\multicolumn{2}{@{}l}{\lstinline{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ & r1x = x, & r1y = y, && r2i = r1x;}} \\
[697c957]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}
[567a75f]177r2i = 3; $\C[0.875in]{// change x}$
[697c957]178&r2i = &r1y; $\C{// change p2i / r2i}$
[567a75f]179r2i = 3; $\C{// change y}$
[697c957]180&r1x = &r1y; $\C{// change p1x / r1x}$
[567a75f]181r2i = 4; $\C{// change y}$
[697c957]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}
[946a6e4]191
192
[567a75f]193\section{Control Flow}
[697c957]194
[567a75f]195The @choose@ statement provides an implicit @break@ after the @case@ clause for safety.
[8659435]196It is possible to @fallthrough@ label in a @case@ clause to transfer to common code or the @default@ clause.
[697c957]197\begin{cquote}
[2b6db03]198\begin{tabular}{@{}l|l@{}}
[8659435]199\begin{cfa}
[567a75f]200switch ( i ) {
[8659435]201 case 3: ... @fallthrough common@;
202 case 2: if ( ... ) @fallthrough@;
203 case 1:
204 common: ... ; // implicit fall through
[567a75f]205 default: ... ;
206}
[8659435]207\end{cfa}
[946a6e4]208&
209\begin{cfa}
[567a75f]210choose ( i ) {
[8659435]211 case 3: ... @fallthrough common@; // labelled explicit fallthrough
212 case 2: if ( ... ) @fallthrough@; // conditional explicit fallthrough
213 case 1:
214 common: ... ; // implicit break
[567a75f]215 default: ... ;
216}
[946a6e4]217\end{cfa}
[3b21c96]218\end{tabular}
219\end{cquote}
[567a75f]220To simplify creating an infinite loop, the loop condition in optional.
[3b21c96]221\begin{cquote}
222\begin{tabular}{@{}l|l@{}}
[946a6e4]223\begin{uC++}
[567a75f]224while ( true ) ...
225for ( ;; ) ...
226do ... while ( true )
[697c957]227\end{uC++}
228&
[567a75f]229\begin{uC++}
230while ($\,$) ...
231for ($\,$) ...
232do ... while ($\,$)
233\end{uC++}
[3b21c96]234\end{tabular}
235\end{cquote}
[04375cf]236To simplify loop iteration a range is provided, from low to high, and a traversal direction, ascending (@+@) or descending (@-@).
[567a75f]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 (@+@/@-@).
[3b21c96]242\begin{cquote}
243\begin{tabular}{@{}l|l@{}}
[946a6e4]244\begin{uC++}
[567a75f]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 ) { ... }
[946a6e4]250\end{uC++}
251&
252\begin{cfa}
[567a75f]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
[8659435]256for ( i; -3 @-@~ 10 ) { ... } // 10 to -2 by -1, not 10 -~= -3
257for ( i; 0 @-@~@=@ 10 ) { ... } // 10 to 0 by -1, not 10 -~= 0
[697c957]258\end{cfa}
259\end{tabular}
260\end{cquote}
[567a75f]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.
[3b21c96]263\begin{cquote}
264\begin{tabular}{@{}l|l@{}}
265\begin{uC++}
[567a75f]266int i = 0
267for ( i = 0; i < 10; i += 1 ) { ... }
268@if ( i == 10 )@ { ... }
[3b21c96]269\end{uC++}
270&
271\begin{cfa}
272
[567a75f]273for ( i; 10 ) { ... }
274@else@ { ... } // i == 10 because of post increment
[3b21c96]275\end{cfa}
276\end{tabular}
277\end{cquote}
[567a75f]278Single/multiple-level loop exit/continue is provided by the labelled @break@/@continue@. (First example is \CC.)
[3b21c96]279\begin{cquote}
[567a75f]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++}
[3b21c96]289&
290\begin{cfa}
[567a75f]291@L1:@ for () {
292 @L2:@ for () {
293 ... if ( ... ) @continue L1@; ...
294 ... if ( ... ) @break L2@; ...
295 }
296}
[3b21c96]297\end{cfa}
298&
299\begin{cfa}
[567a75f]300@L1:@ for () {
301 @L2:@ for () {
302 ... if ( ... ) @continue L1@; ...
303 ... if ( ... ) @break L2@; ...
304 }
305}
[3b21c96]306\end{cfa}
307\end{tabular}
308\end{cquote}
309
310
[946a6e4]311\section{Exception}
[697c957]312
313Currently, \CFA uses macros @ExceptionDecl@ and @ExceptionInst@ to declare and instantiate an exception.
314\begin{cquote}
[567a75f]315\setlength{\tabcolsep}{5pt}
[2b6db03]316\begin{tabular}{@{}l|ll@{}}
[697c957]317\begin{uC++}
318
[946a6e4]319@_Exception@ E { // local or global scope
[697c957]320 ... // exception fields
321};
322try {
[567a75f]323 ... if ( ... ) @_Resume@ E( /* initialization */ ); ...
324 ... if ( ... ) @_Throw@ E( /* initialization */ ); ...
[3b21c96]325} @_CatchResume@( E & /* reference */ ) { ... }
326 catch( E & ) { ... }
327 catch( ... /* catch any */ ) { ... }
328 _Finally { ... }
[697c957]329\end{uC++}
330&
331\begin{cfa}
332#include <Exception.hfa>
333@ExceptionDecl@( E, // must be global scope
334 ... // exception fields
335);
336try {
[567a75f]337 ... if ( ... ) @throwResume@ @ExceptionInst@( E, /* intialization */ ); ...
338 ... if ( ... ) @throw@ @ExceptionInst@( E, /* intialization */ ); ...
[3b21c96]339} @catchResume@( E @*@ /* pointer */ ) { ... }
340 catch( E * ) { ... }
341 catch( exception_t @*@ /* catch any */ ) { ... }
342 finally { ... }
[697c957]343\end{cfa}
344\end{tabular}
345\end{cquote}
346
347
[946a6e4]348\section{Non-local Exception}
349
350\begin{cquote}
[de8a0286]351\setlength{\tabcolsep}{5pt}
[2b6db03]352\begin{tabular}{@{}l|ll@{}}
[946a6e4]353\begin{uC++}
[697c957]354
[946a6e4]355
[de8a0286]356void Coroutine::main() {
[946a6e4]357 try {
358 _Enable {
359 ... suspend(); ...
360 }
[3b21c96]361 } @_CatchResume@( E & /* reference */ ) { ... }
362 catch( E & ) { ... }
[946a6e4]363}
[de8a0286]364void Coroutine::mem() { resume(); }
[946a6e4]365\end{uC++}
366&
367\begin{cfa}
[ef9f11c]368#define resumePoll( coroutine ) resume( coroutine ); poll()
369#define suspendPoll suspend; poll()
[de8a0286]370void main( Coroutine & cor ) {
[946a6e4]371 try {
372 enable_ehm();
373 ... suspendPoll ...
374 disable_ehm();
[3b21c96]375 } @catchResume@( E * ) { ... }
376 catch( E & ) { ... }
[946a6e4]377}
[de8a0286]378void mem( Coroutine & cor ) { resumePoll(); }
[946a6e4]379\end{cfa}
380\end{tabular}
381\end{cquote}
382
383
[567a75f]384\section{Stream I/O}
[e255902b]385
[567a75f]386\CFA output streams automatically separate values and insert a newline at the end of the print.
[e255902b]387\begin{cquote}
388\begin{tabular}{@{}l|l@{}}
389\begin{uC++}
[567a75f]390#include <@iostream@>
391using namespace std;
392int i; double d; char c;
393cin >> i >> d >> c;
394cout << i << ' ' << d << ' ' << c << endl;
[e255902b]395\end{uC++}
396&
397\begin{cfa}
[567a75f]398#include <@fstream.hfa@>
[e255902b]399
[567a75f]400int i; double d; char c;
401sin | i | d | c;
402sout | i | d | c
[e255902b]403\end{cfa}
404\end{tabular}
405\end{cquote}
[567a75f]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++}
[e255902b]410
[567a75f]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@.
[bf91d1d]425\begin{cquote}
426\begin{tabular}{@{}l|l@{}}
427\begin{uC++}
[567a75f]428cout << 3.0 << ' ' << showpoint << setprecision(0) << 3.0 << endl;
4293 3.
[bf91d1d]430\end{uC++}
431&
432\begin{cfa}
[567a75f]433sout | @nodp( 3.0 )@ | 3.0;
4343 3.
[bf91d1d]435\end{cfa}
436\end{tabular}
437\end{cquote}
438
439
[de8a0286]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
[697c957]553\section{String}
554
[04375cf]555The @string@ type in \CFA is very similar to that in \CC.
[697c957]556\begin{cquote}
[2b6db03]557\begin{tabular}{@{}l|l@{}}
558\multicolumn{2}{@{}l@{}}{\lstinline{string s1, s2;}} \\
[697c957]559\begin{uC++}
[3733643]560s1 = "abcdefg";
[697c957]561s2 = s1;
562s1 += s2;
563s1 == s2; s1 != s2;
[567a75f]564s1 < s2; s1 <= s2; s1 > s2; s1 >= s2;
[697c957]565s1.length();
566s1[3];
[567a75f]567s1.substr( 2 ); s1.substr( 2, 3 );
[697c957]568s1.replace( 2, 5, s2 );
[567a75f]569s1.find( s2 );
570s1.find_first_of( "cd" );
571s1.find_first_not_of( "cd" );
[697c957]572getline( cin, s1 );
573cout << s1 << endl;
574\end{uC++}
575&
576\begin{cfa}
[3733643]577s1 = "abcdefg";
[697c957]578s2 = s1;
579s1 += s2;
580s1 == s2; s1 != s2;
[567a75f]581s1 < s2; s1 <= s2; s1 > s2; s1 >= s2;
[04375cf]582len( s1 ); // like C strlen( s1 )
[697c957]583s1[3];
[567a75f]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"
[697c957]589sin | getline( s1 );
590sout | s1;
591\end{cfa}
592\end{tabular}
593\end{cquote}
594
595
[de8a0286]596\enlargethispage{1000pt}
[3733643]597\section{\texorpdfstring{\lstinline{uArray}}{uArray}}
[697c957]598
599\begin{cquote}
[04375cf]600\setlength{\tabcolsep}{5pt}
[2b6db03]601\begin{tabular}{@{}l|l@{}}
[697c957]602\begin{uC++}
[3733643]603#include <iostream>
604using namespace std;
[567a75f]605
[697c957]606struct S {
607 int i;
[567a75f]608 S( int i ) { S::i = i; }
[697c957]609};
[04375cf]610void f( @uArrayRef( S, parm )@ );
[697c957]611int main() {
[538cc35]612 enum { N = 5 };
[567a75f]613 @uArray( S, s, N );@ // stack, no ctor calls
614 for ( int i = 0; i < N; i += 1 ) @s[i]( i )@; // ctor calls
[538cc35]615 for ( int i = 0; i < N; i += 1 ) cout << s[i]@->@i << endl;
[567a75f]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
[697c957]622\end{uC++}
623&
624\begin{cfa}
[3733643]625#include <fstream.hfa>
626#include <array.hfa>
[567a75f]627#include <memory.hfa>
[697c957]628struct S {
629 int i;
630};
[567a75f]631void ?{}( S & s, int i ) { s.i = i; }
[04375cf]632@forall( [N] )@ void f( @array( S, N ) & parm@ ) {}
[697c957]633int main() {
[538cc35]634 enum { N = 5 };
[567a75f]635 @array( S, N ) s = { delay_init };@ // no ctor calls
636 for ( i; N ) @s[i]{ i }@; // ctor calls
[538cc35]637 for ( i; N ) sout | s[i]@.@i;
[567a75f]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
[de8a0286]648\newpage
[567a75f]649
650
[de8a0286]651\section{Doubly-Linked Intrusive List}
652
[567a75f]653\begin{cquote}
[de8a0286]654\setlength{\tabcolsep}{10pt}
[567a75f]655\begin{tabular}{@{}l|l@{}}
656\begin{uC++}
[de8a0286]657#include <iostream>
658using namespace std;
659struct Node : @public uSeqable@ {
660 int i;
661 Node( int i ) : i( i ) {}
[567a75f]662};
[de8a0286]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}
[567a75f]682\end{uC++}
683&
684\begin{cfa}
[de8a0286]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
[567a75f]704
[de8a0286]705 FOREACH( dlist, it ) { // FOREACH_REV
706
707 sout | it.i;
708 }
709}
[567a75f]710\end{cfa}
711\end{tabular}
712\end{cquote}
713
714
[de8a0286]715\section{RAII Dynamic Allocation}
[567a75f]716
717\begin{cquote}
[de8a0286]718\begin{tabular}{@{}l|ll@{}}
[567a75f]719\begin{uC++}
720struct S {
[de8a0286]721 ... S() { ... } ~S() { ... } // ctor / dtor
[567a75f]722};
[de8a0286]723S * s = new S; delete s;
724S * sa = new S[10]; delete [] sa;
[567a75f]725\end{uC++}
726&
727\begin{cfa}
[de8a0286]728#include <stdlib.hfa>
729struct S { ... };
730void ?{}( S & ) { ... } void ^?{}( S & ) { ... } // ctor / dtor
731S * s = new(); delete( s );
732S * sa = anew( 10 ); adelete( sa );
[697c957]733\end{cfa}
734\end{tabular}
735\end{cquote}
736
737
[0cb3479]738\section{Coroutine}
[697c957]739
740\begin{cquote}
[2b6db03]741\begin{tabular}{@{}l|ll@{}}
[697c957]742\begin{uC++}
[135a2d8]743@_Coroutine@ C {
[697c957]744 // private coroutine fields
745 void main() {
[135a2d8]746 ... @suspend();@ ...
747 ... @_Resume E( ... ) _At partner;@
748 ... @uThisCoroutine();@ ...
[bf91d1d]749
[697c957]750 }
751 public:
752 void mem( ... ) {
[135a2d8]753 ... @resume();@ ...
[697c957]754 }
755};
756\end{uC++}
757&
758\begin{cfa}
759#include <$coroutine$.hfa>
[135a2d8]760@coroutine@ C {
[697c957]761 // private coroutine fields
762
763};
764void main( C & c ) {
[135a2d8]765 ... @suspend;@ ... // keyword not routine
766 ... @resumeAt( partner, ExceptionInst( E, ... ) );@
767 ... @active_coroutine();@ ...
[697c957]768}
769void mem( C & c, ... ) {
[135a2d8]770 ... @resume( c );@ ...
[697c957]771}
772\end{cfa}
773\end{tabular}
774\end{cquote}
775
776
[bf91d1d]777\section{\lstinline{COBEGIN}/\lstinline{COFOR}}
[697c957]778
779\begin{cquote}
[2b6db03]780\begin{tabular}{@{}l|ll@{}}
[697c957]781\begin{uC++}
782
[bf91d1d]783#include <uCobegin.h>
784int main() {
[135a2d8]785 @COBEGIN@
[bf91d1d]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
[135a2d8]790 @COEND@
791 @COFOR@( i, 1, 10,
[bf91d1d]792 osacquire( cout ) << i << endl;
793 )
[697c957]794}
795\end{uC++}
796&
797\begin{cfa}
[bf91d1d]798#include <mutex_stmt.hfa>
799#include <$cofor$.hfa>
800int main() {
801 {
[135a2d8]802 @corun@ { mutex( sout ) sout | "A"; }
[bf91d1d]803 corun { mutex( sout ) sout | "B"; }
804 corun { mutex( sout ) sout | "C"; }
805 corun { mutex( sout ) sout | "D"; }
806 }
[135a2d8]807 @cofor@( i; 10 ) {
[bf91d1d]808 mutex( sout ) sout | i;
809 }
[697c957]810}
811\end{cfa}
812\end{tabular}
813\end{cquote}
814
815
[bf91d1d]816\section{Actor}
[697c957]817
818\begin{cquote}
[de8a0286]819\setlength{\tabcolsep}{10pt}
[2b6db03]820\begin{tabular}{@{}l|ll@{}}
[697c957]821\begin{uC++}
[bf91d1d]822#include <iostream>
823using namespace std;
824#include <uActor.h>
[697c957]825
[bf91d1d]826struct StrMsg : @public uActor::Message@ {
[697c957]827
[0cb3479]828 const char * val; // string message
[bf91d1d]829
830 StrMsg( const char * val ) :
831 @Message( uActor::Delete )@, // delete after use
832 val( val ) {}
833};
[04375cf]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}
[de8a0286]850\\
[04375cf]851\begin{uC++}
[bf91d1d]852_Actor Hello { ${\color{red}\LstCommentStyle{// : public uActor}}$
853 Allocation receive( Message & msg ) {
[0cb3479]854 Case( @StartMsg@, msg ) { // discriminate
855
856 } else Case( StrMsg, msg ) {
[bf91d1d]857 osacquire( cout ) << msg_d->val << endl;
[0cb3479]858
859 } else Case( @StopMsg@, msg )
860 return Delete; // delete actor
861 return Nodelete; // reuse actor
[697c957]862 }
863};
[bf91d1d]864int main() {
865 @uActor::start();@ // start actor system
[0cb3479]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
[bf91d1d]871}
[697c957]872\end{uC++}
873&
874\begin{cfa}
[0cb3479]875struct Hello { @inline actor;@ }; // derived actor
876allocation receive( Hello & receiver, @start_msg_t@ & ) {
877 return Nodelete;
[bf91d1d]878}
879allocation receive( Hello & receiver, StrMsg & msg ) {
880 mutex( sout ) sout | msg.val;
[0cb3479]881 return Nodelete; // reuse actor
882}
883allocation receive( Hello & receiver, @stop_msg_t@ & ) {
884 return Delete; // delete actor
[697c957]885}
886
[bf91d1d]887int main() {
[0cb3479]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
[bf91d1d]894}
[697c957]895\end{cfa}
896\end{tabular}
897\end{cquote}
898
899
[d96f7c4]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};
[8659435]914T t;
915uProcessor p[3];
[d96f7c4]916\end{uC++}
917&
918\begin{cfa}
919#include <$thread$.hfa>
920@thread@ T {
921 // private task fields
922
923};
924void main( @T & t@ ) {
[8659435]925 ... @resumeAt( partner, ExceptionInst( E, ... ) )@;
[d96f7c4]926 ... @active_thread();@ ...
927}
[8659435]928T t; // create thread object and start thread in main
929processor p[3]; // 4 kernel threads including program main
[d96f7c4]930\end{cfa}
931\end{tabular}
932\end{cquote}
933
934
[bf91d1d]935\section{Locks}
936
937\begin{cquote}
938\begin{tabular}{@{}l|ll@{}}
939\begin{uC++}
940
941uOwnerLock m;
[de8a0286]942uCondLock c;
[bf91d1d]943m.acquire();
[de8a0286]944if ( ! c.empty() ) c.wait( m );
[bf91d1d]945else {
946 m.release();
947}
948@osacquire( cout )@ << i << endl;
949\end{uC++}
950&
951\begin{cfa}
952#include <locks.hfa>
953owner_lock m;
[de8a0286]954cond_lock( owner_lock ) c; // generic type on mutex lock
[bf91d1d]955lock( m );
[de8a0286]956if ( ! empty( c ) ) wait( c, m );
[bf91d1d]957else {
958 unlock( m );
959}
960@mutex( sout )@ sout | i; // thread safe I/O
961\end{cfa}
962\end{tabular}
963\end{cquote}
964
[de8a0286]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}
[bf91d1d]991
[1b56a7f]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;
[e255902b]1004 void @last@() { cout << total << endl; }
[1b56a7f]1005 public:
1006 Barrier( unsigned int group ) :
1007 @uBarrier( group )@ {
1008 total = 0;
1009 }
1010 void @block@( int subtotal ) {
[e255902b]1011
1012
[1b56a7f]1013 total += subtotal;
1014 @uBarrier::block();@
1015 }
1016};
[8659435]1017Barrier b{ 3 };
[1b56a7f]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 {
[de8a0286]1026 @inline barrier;@
[1b56a7f]1027 int total;
[e255902b]1028
[1b56a7f]1029};
[de8a0286]1030void ?{}( Barrier & b, unsigned int group ) with( b ) {
1031 @(b){ group };@ // initialize barrier
[1b56a7f]1032 total = 0;
1033}
[de8a0286]1034unsigned int block( Barrier & b, int subtotal ) with( b ) {
1035 void @last@(...) { sout | total; } // called by Gth arriving thread
[e255902b]1036 @mutex( b )@ { // use barrier's mutual exclusion
1037 total += subtotal;
1038 return @block@( b, last ); // wait for barrier trigger
1039 }
[1b56a7f]1040}
[8659435]1041Barrier b{ 3 };
[1b56a7f]1042\end{cfa}
1043\end{tabular}
1044\end{cquote}
1045
[de8a0286]1046\newpage
[04375cf]1047
1048\enlargethispage{1000pt}
[1b56a7f]1049
[0cb3479]1050\section{Monitor}
[bf91d1d]1051
[135a2d8]1052Internal Scheduling
[bf91d1d]1053\begin{cquote}
[de8a0286]1054\setlength{\tabcolsep}{5pt}
[bf91d1d]1055\begin{tabular}{@{}l|ll@{}}
1056\begin{uC++}
1057
[135a2d8]1058@_Monitor@ BoundedBufferI {
1059 @uCondition@ full, empty;
1060 int front = 0, back = 0, count = 0;
1061 int elements[20];
[bf91d1d]1062 public:
1063
[135a2d8]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;
[bf91d1d]1082 }
1083};
1084\end{uC++}
1085&
1086\begin{cfa}
1087#include <$monitor$.hfa>
[135a2d8]1088@monitor@ BoundedBufferI {
1089 @condition@ full, empty;
1090 int front, back, count;
1091 int elements[20];
[bf91d1d]1092};
[135a2d8]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;
[bf91d1d]1112}
1113
1114\end{cfa}
[135a2d8]1115\end{tabular}
1116\end{cquote}
[0cb3479]1117
[de8a0286]1118\bigskip
[e255902b]1119\noindent
[135a2d8]1120External Scheduling
1121\begin{cquote}
[de8a0286]1122\setlength{\tabcolsep}{5pt}
[135a2d8]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}
[bf91d1d]1175\end{tabular}
1176\end{cquote}
1177
1178
[de8a0286]1179\newpage
1180
1181\section{Futures (reference counting)}
1182
1183
[8659435]1184{\lstset{tabsize=4}
[de8a0286]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;
[8659435]1193_Exception Stop {};
[de8a0286]1194
1195_Task Worker {
1196 void main() {
[8659435]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;}
[de8a0286]1207 }
1208};
1209int main() {
1210 Worker worker;
1211 for ( int i = 0; i < 10; i += 1 ) {
[8659435]1212 fi( i ); fd( i + 2.5 ); fm( (Msg){ i, 2 } ); // fulfil
[de8a0286]1213 fc(); fc.reset(); // synchronize
1214 }
[8659435]1215 fi( new Stop{} ); // trigger exception
[de8a0286]1216} // wait for worker to terminate
1217\end{uC++}
1218&
1219\begin{cfa}
1220#include <future.hfa>
[8659435]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
[de8a0286]1227thread Worker {};
1228void main( Worker & ) {
1229 try {
1230 for () {
1231 waituntil( fi ) { sout | fi(); reset( fi ); }
1232 and waituntil( fd ) { sout | fd(); reset( fd ); }
[8659435]1233 and waituntil( fm ) {
1234 sout | fm().i | fm().j; reset( fm );
[de8a0286]1235 }
1236 fc( (Cont){} ); // synchronize
1237 }
[8659435]1238 } catch( Stop * ) { sout | "stop"; }
[de8a0286]1239}
[8659435]1240
[de8a0286]1241int main() {
1242 Worker worker;
1243 for ( i; 10 ) {
[8659435]1244 fi( i ); fd( i + 2.5 ); fm( (Msg){ i, 2 } ); // fulfil
[de8a0286]1245 fc(); reset( fc ); // synchronize
1246 }
[8659435]1247 fi( ExceptionPtr( ExceptionInst( Stop ) ) );
[de8a0286]1248} // wait for worker to terminate
1249\end{cfa}
1250\end{tabular}
1251}%
1252
1253%\input{uC++toCFA.ind}
[697c957]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.