Changes in / [86fb8f2:2b10f95]


Ignore:
Files:
2 deleted
18 edited

Legend:

Unmodified
Added
Removed
  • doc/papers/concurrency/Paper.tex

    r86fb8f2 r2b10f95  
    654654\centering
    655655\newbox\myboxA
    656 % \begin{lrbox}{\myboxA}
    657 % \begin{cfa}[aboveskip=0pt,belowskip=0pt]
    658 % `int fn1, fn2, state = 1;`   // single global variables
    659 % int fib() {
    660 %       int fn;
    661 %       `switch ( state )` {  // explicit execution state
    662 %         case 1: fn = 0;  fn1 = fn;  state = 2;  break;
    663 %         case 2: fn = 1;  fn2 = fn1;  fn1 = fn;  state = 3;  break;
    664 %         case 3: fn = fn1 + fn2;  fn2 = fn1;  fn1 = fn;  break;
    665 %       }
    666 %       return fn;
    667 % }
    668 % int main() {
    669 %
    670 %       for ( int i = 0; i < 10; i += 1 ) {
    671 %               printf( "%d\n", fib() );
    672 %       }
    673 % }
    674 % \end{cfa}
    675 % \end{lrbox}
    676656\begin{lrbox}{\myboxA}
    677657\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    678 #define FIB_INIT { 0, 1 }
    679 typedef struct { int fn1, fn; } Fib;
     658`int fn1, fn2, state = 1;`   // single global variables
     659int fib() {
     660        int fn;
     661        `switch ( state )` {  // explicit execution state
     662          case 1: fn = 0;  fn1 = fn;  state = 2;  break;
     663          case 2: fn = 1;  fn2 = fn1;  fn1 = fn;  state = 3;  break;
     664          case 3: fn = fn1 + fn2;  fn2 = fn1;  fn1 = fn;  break;
     665        }
     666        return fn;
     667}
     668int main() {
     669
     670        for ( int i = 0; i < 10; i += 1 ) {
     671                printf( "%d\n", fib() );
     672        }
     673}
     674\end{cfa}
     675\end{lrbox}
     676
     677\newbox\myboxB
     678\begin{lrbox}{\myboxB}
     679\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     680#define FIB_INIT `{ 0, 1 }`
     681typedef struct { int fn2, fn1; } Fib;
    680682int fib( Fib * f ) {
    681683
    682         int ret = f->fn1;
    683         f->fn1 = f->fn;
    684         f->fn = ret + f->fn;
     684        int ret = f->fn2;
     685        int fn = f->fn1 + f->fn2;
     686        f->fn2 = f->fn1; f->fn1 = fn;
     687
    685688        return ret;
    686689}
    687 
    688 
    689 
    690690int main() {
    691691        Fib f1 = FIB_INIT, f2 = FIB_INIT;
    692692        for ( int i = 0; i < 10; i += 1 ) {
    693                 printf( "%d %d\n",
    694                                 fib( &f1 ), fib( &f2 ) );
     693                printf( "%d %d\n", fib( &fn1 ), fib( &f2 ) );
    695694        }
    696695}
     
    698697\end{lrbox}
    699698
     699\subfloat[3 states: global variables]{\label{f:GlobalVariables}\usebox\myboxA}
     700\qquad
     701\subfloat[1 state: encapsulated variables]{\label{f:ExternalState}\usebox\myboxB}
     702\caption{C fibonacci fsm}
     703\label{f:C-fibonacci}
     704
     705\bigskip
     706
     707\newbox\myboxA
     708\begin{lrbox}{\myboxA}
     709\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     710`coroutine` Fib { int fn; };
     711void main( Fib & fib ) with( fib ) {
     712        fn = 0;  int fn1 = fn; `suspend()`;
     713        fn = 1;  int fn2 = fn1;  fn1 = fn; `suspend()`;
     714        for () {
     715                fn = fn1 + fn2; fn2 = fn1; fn1 = fn; `suspend()`; }
     716}
     717int next( Fib & fib ) with( fib ) { `resume( fib );` return fn; }
     718int main() {
     719        Fib f1, f2;
     720        for ( 10 )
     721                sout | next( f1 ) | next( f2 );
     722}
     723\end{cfa}
     724\end{lrbox}
    700725\newbox\myboxB
    701726\begin{lrbox}{\myboxB}
    702 \begin{cfa}[aboveskip=0pt,belowskip=0pt]
    703 `coroutine` Fib { int fn1; };
    704 void main( Fib & fib ) with( fib ) {
    705         int fn;
    706         [fn1, fn] = [0, 1];
    707         for () {
    708                 `suspend();`
    709                 [fn1, fn] = [fn, fn1 + fn];
    710         }
    711 }
    712 int ?()( Fib & fib ) with( fib ) {
    713         `resume( fib );`  return fn1;
    714 }
    715 int main() {
    716         Fib f1, f2;
    717         for ( 10 ) {
    718                 sout | f1() | f2();
    719 }
    720 
    721 
    722 \end{cfa}
    723 \end{lrbox}
    724 
    725 \newbox\myboxC
    726 \begin{lrbox}{\myboxC}
    727727\begin{python}[aboveskip=0pt,belowskip=0pt]
    728728
    729 def Fib():
    730 
    731     fn1, fn = 0, 1
    732     while True:
    733         `yield fn1`
    734         fn1, fn = fn, fn1 + fn
    735 
    736 
    737 // next prewritten
    738 
    739 
    740 f1 = Fib()
    741 f2 = Fib()
     729def Fibonacci():
     730        fn = 0; fn1 = fn; `yield fn`  # suspend
     731        fn = 1; fn2 = fn1; fn1 = fn; `yield fn`
     732        while True:
     733                fn = fn1 + fn2; fn2 = fn1; fn1 = fn; `yield fn`
     734
     735
     736f1 = Fibonacci()
     737f2 = Fibonacci()
    742738for i in range( 10 ):
    743         print( next( f1 ), next( f2 ) )
    744 
    745 
     739        print( `next( f1 )`, `next( f2 )` ) # resume
    746740
    747741\end{python}
    748742\end{lrbox}
    749 
    750 \subfloat[C]{\label{f:GlobalVariables}\usebox\myboxA}
    751 \hspace{3pt}
    752 \vrule
    753 \hspace{3pt}
    754 \subfloat[\CFA]{\label{f:ExternalState}\usebox\myboxB}
    755 \hspace{3pt}
    756 \vrule
    757 \hspace{3pt}
    758 \subfloat[Python]{\label{f:ExternalState}\usebox\myboxC}
    759 \caption{Fibonacci Generator}
    760 \label{f:C-fibonacci}
    761 
    762 % \bigskip
    763 %
    764 % \newbox\myboxA
    765 % \begin{lrbox}{\myboxA}
    766 % \begin{cfa}[aboveskip=0pt,belowskip=0pt]
    767 % `coroutine` Fib { int fn; };
    768 % void main( Fib & fib ) with( fib ) {
    769 %       fn = 0;  int fn1 = fn; `suspend()`;
    770 %       fn = 1;  int fn2 = fn1;  fn1 = fn; `suspend()`;
    771 %       for () {
    772 %               fn = fn1 + fn2; fn2 = fn1; fn1 = fn; `suspend()`; }
    773 % }
    774 % int next( Fib & fib ) with( fib ) { `resume( fib );` return fn; }
    775 % int main() {
    776 %       Fib f1, f2;
    777 %       for ( 10 )
    778 %               sout | next( f1 ) | next( f2 );
    779 % }
    780 % \end{cfa}
    781 % \end{lrbox}
    782 % \newbox\myboxB
    783 % \begin{lrbox}{\myboxB}
    784 % \begin{python}[aboveskip=0pt,belowskip=0pt]
    785 %
    786 % def Fibonacci():
    787 %       fn = 0; fn1 = fn; `yield fn`  # suspend
    788 %       fn = 1; fn2 = fn1; fn1 = fn; `yield fn`
    789 %       while True:
    790 %               fn = fn1 + fn2; fn2 = fn1; fn1 = fn; `yield fn`
    791 %
    792 %
    793 % f1 = Fibonacci()
    794 % f2 = Fibonacci()
    795 % for i in range( 10 ):
    796 %       print( `next( f1 )`, `next( f2 )` ) # resume
    797 %
    798 % \end{python}
    799 % \end{lrbox}
    800 % \subfloat[\CFA]{\label{f:Coroutine3States}\usebox\myboxA}
    801 % \qquad
    802 % \subfloat[Python]{\label{f:Coroutine1State}\usebox\myboxB}
    803 % \caption{Fibonacci input coroutine, 3 states, internal variables}
    804 % \label{f:cfa-fibonacci}
     743\subfloat[\CFA]{\label{f:Coroutine3States}\usebox\myboxA}
     744\qquad
     745\subfloat[Python]{\label{f:Coroutine1State}\usebox\myboxB}
     746\caption{Fibonacci input coroutine, 3 states, internal variables}
     747\label{f:cfa-fibonacci}
    805748\end{figure}
    806749
  • doc/papers/concurrency/examples/Pingpong.cfa

    r86fb8f2 r2b10f95  
    44coroutine PingPong {
    55        const char * name;
    6         unsigned int N;
    7         PingPong & part;
     6        /* const */ unsigned int N;
     7        PingPong * part;
    88};
    99
    1010void ?{}( PingPong & this, const char * name, unsigned int N, PingPong & part ) {
    11         this.[name, N] = [name, N];  &this.part = &part;
     11        (this.__cor){name};
     12        this.name = name;
     13        this.N = N;
     14        this.part = &part;
    1215}
    1316void ?{}( PingPong & this, const char * name, unsigned int N ) {
    14         this{ name, N, *0p };                                                           // call first constructor
     17        this{ name, N, *(PingPong *)0 };
    1518}
    1619void cycle( PingPong & pingpong ) {
     
    1821}
    1922void partner( PingPong & this, PingPong & part ) {
    20         &this.part = &part;
     23        this.part = &part;
    2124        resume( this );
    2225}
    23 void main( PingPong & pingpong ) with(pingpong) {               // ping's starter ::main, pong's starter ping
    24         for ( N ) {                                                                                     // N ping-pongs
    25                 sout | name;
    26                 cycle( part );
     26void main( PingPong & pingpong ) {                                              // ping's starter ::main, pong's starter ping
     27        for ( pingpong.N ) {                                                            // N ping-pongs
     28                sout | pingpong.name;
     29                cycle( *pingpong.part );
    2730        } // for
    2831}
    2932int main() {
    30         enum { N = 5 };
     33        enum { N = 20 };
    3134        PingPong ping = { "ping", N }, pong = { "pong", N, ping };
    3235        partner( ping, pong );
     
    3538// Local Variables: //
    3639// tab-width: 4 //
    37 // compile-command: "cfa Pingpong.cfa" //
     40// compile-command: "cfa pingpong.cfa" //
    3841// End: //
  • doc/papers/concurrency/examples/Pingpong.py

    r86fb8f2 r2b10f95  
    1 def PingPong( name, N ):
    2         partner = (yield)           # get partner
    3         yield                       # resume scheduler
    4         for i in range( N ):
    5                 print( name )
    6                 yield partner           # execute next
    7         print( "end", name )
     1def Scheduler
     2try:
     3        yield from ping();
     4        yield from pong();
     5except StopIteration:
     6        print( "Scheduler stop" )
    87
    9 def Scheduler():
    10         n = (yield)                 # starting coroutine
    11         while True:
    12                 n = next( n )           # schedule coroutine
    138
    14 pi = PingPong( "ping", 5 )
    15 po = PingPong( "pong", 5 )
    16 next( pi )                      # prime
    17 pi.send( po )                   # send partner
    18 next( po )                      # prime
    19 po.send( pi )                   # send partner
     9def pong():
     10        print( "pong" )
     11for i in range( 10 ):
    2012
    21 s = Scheduler();
    22 next( s )                       # prime
     13                yield from ping()
     14        print( "stop pong" )
     15
     16def ping():
     17        global i
     18        print( "ping" )
     19        i += 1
     20        if i < 5:
     21                yield from pong()
     22        print( "stop ping" )
     23
     24p = ping()
    2325try:
    24         s.send( pi )                            # start cycle
     26        next( p )
    2527except StopIteration:
    26         print( "scheduler stop" )
    27 print( "stop" )
     28        print( "stop" )
    2829
    2930# Local Variables: #
    3031# tab-width: 4 #
    31 # compile-command: "python3.5 Pingpong.py" #
     32# compile-command: "python3.5 pingpong.py" #
    3233# End: #
  • doc/papers/concurrency/examples/ProdCons.cfa

    r86fb8f2 r2b10f95  
    2323        sout | "prod stops";
    2424}
    25 int payment( Prod & prod, int m ) with(prod) {
    26         money = m;
     25int payment( Prod & prod, int money ) {
     26        prod.money = money;
    2727        resume( prod );                                                                         // main 1st time, then
    28         return receipt;                                                                         // prod in delivery
     28        return prod.receipt;                                                            // prod in delivery
    2929}
    3030void start( Prod & prod, int N, Cons &c ) {
  • doc/papers/concurrency/examples/ProdCons.cpp

    r86fb8f2 r2b10f95  
    1212struct Cons;
    1313
    14 struct resumable {
    15         virtual resumable * resume() = 0;
    16 };
    17 
    18 struct Prod : public resumable {
     14struct Prod {
    1915        struct local {
    2016                Cons * c;
     
    2420        struct promise_type {
    2521                local _l;
    26                 resumable * next;
    2722
    2823                Prod get_return_object() {
     
    7469        static Prod main();
    7570
    76         struct payment_return;
    77 
    78         payment_return payment(int money);
     71        auto payment(int money) {
     72                _coroutine.promise()._l.money = money;
     73                struct ret {
     74                        int _receipt;
     75                        bool await_ready() { return false; }
     76                        void await_suspend(std::experimental::coroutine_handle<>) {}
     77                        int await_resume() { return _receipt; }
     78                };
     79                return ret{ _coroutine.promise()._l.receipt };
     80        }
    7981
    8082        auto start(int N, Cons & c) {
     
    8284                _coroutine.promise()._l.N = N;
    8385                _coroutine.promise()._l.receipt = 0;
    84         }
    85 
    86         virtual resumable * resume() override final {
    8786                _coroutine.resume();
    88                 return _coroutine.promise().next;
    8987        }
    9088};
    9189
    92 struct Cons : public resumable {
     90struct Cons {
    9391        struct local {
    9492                Prod * p;
     
    9997        struct promise_type {
    10098                local _l;
    101                 resumable * next;
    10299
    103100                Cons get_return_object() {
     
    157154                struct ret {
    158155                        int _status;
    159                         Cons * c;
    160156                        bool await_ready() { return false; }
    161                         void await_suspend(std::experimental::coroutine_handle<Prod::promise_type> _coroutine) {
    162                                 _coroutine.promise().next = c;
    163                         }
     157                        void await_suspend(std::experimental::coroutine_handle<>) {}
    164158                        int await_resume() { return _status; }
    165159                };
    166                 return ret{ _coroutine.promise()._l.status, this };
     160                return ret{ _coroutine.promise()._l.status };
    167161        }
    168162
     
    170164                _coroutine.promise()._l.done = true;
    171165                struct ret {
    172                         Cons * c;
    173                         Prod::promise_type * _promise;
    174166                        bool await_ready() { return false; }
    175                         void await_suspend(std::experimental::coroutine_handle<Prod::promise_type> _coroutine) {
    176                                 _promise = &_coroutine.promise();
    177                                 _promise->next = c;
    178                         }
    179                         void await_resume() {
    180                                 _promise->next = nullptr;
    181                         }
     167                        void await_suspend(std::experimental::coroutine_handle<>) {}
     168                        void await_resume() {}
    182169                };
    183                 return ret{this, nullptr};
    184         }
    185 
    186         virtual resumable * resume() override final {
    187                 _coroutine.resume();
    188                 return _coroutine.promise().next;
     170                return ret{};
    189171        }
    190172};
    191 
    192 struct Prod::payment_return {
    193         int _receipt;
    194         Prod * p;
    195         bool await_ready() { return false; }
    196         void await_suspend(std::experimental::coroutine_handle<Cons::promise_type> _coroutine) {
    197                 _coroutine.promise().next = p;
    198         }
    199         int await_resume() { return _receipt; }
    200 };
    201 
    202 Prod::payment_return Prod::payment(int money)  {
    203         _coroutine.promise()._l.money = money;
    204         return payment_return{ _coroutine.promise()._l.receipt, this };
    205 }
    206173
    207174Prod Prod::main() {
     
    209176        for(int i = 0; i < p.N; i++) {
    210177                int p1 = random(100), p2 = random(100);
    211                 std::cout << p1 << " " << p2 << std::endl;
     178                std::cout << p1 << " " << p2;
    212179                int status = co_await p.c->deliver(p1, p2);
    213                 std::cout << " $" << p.money << std::endl << status << std::endl;
     180                std::cout << " $" << p.money << std::endl << status;
    214181                p.receipt += 1;
    215182        }
    216183        co_await p.c->stop();
    217         std::cout << "prod stops" << std::endl;
     184        std::cout << "prod stops";
    218185}
    219186
     
    222189        int money = 1, receipt;
    223190        for(;!c.done ;) {
    224                 std::cout << c.p1 << " " << c.p2 << std::endl;
    225                 std::cout << " $ " << money << std::endl;
     191                std::cout << c.p1 << " " << c.p2 << std::endl << " $" << money;
    226192                c.status += 1;
    227193                receipt = co_await c.p->payment( money );
    228                 std::cout << " # " << receipt << std::endl;
     194                std::cout << " #" << receipt;
    229195                money += 1;
    230196        }
    231         std::cout << "cons stops" << std::endl;
    232 }
    233 
    234 void dispatch(resumable * r) {
    235         while((r = r->resume()));
     197        std::cout << "const stops";
    236198}
    237199
     
    241203        srandom( getpid() );
    242204        prod.start(5, cons);
    243         dispatch(&prod);
    244 }
     205}
  • doc/user/user.tex

    r86fb8f2 r2b10f95  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Tue Mar 26 22:10:49 2019
    14 %% Update Count     : 3411
     13%% Last Modified On : Tue Dec 11 23:19:26 2018
     14%% Update Count     : 3400
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    508508
    509509As for \Index{division}, there are exponentiation operators for integral and floating types, including the builtin \Index{complex} types.
    510 Integral exponentiation\index{exponentiation!unsigned integral} is performed with repeated multiplication\footnote{The multiplication computation is $O(\log y)$.} (or shifting if the exponent is 2).
    511 Overflow from large exponents or negative exponents return zero.
    512 Floating exponentiation\index{exponentiation!floating} is performed using \Index{logarithm}s\index{exponentiation!logarithm}, so the exponent cannot be negative.
    513 \begin{cfa}
    514 sout | 1 ®\® 0 | 1 ®\® 1 | 2 ®\® 8 | -4 ®\® 3 | 5 ®\® 3 | 5 ®\® 32 | 5L ®\® 32 | 5L ®\® 64 | -4 ®\® -3 | -4.0 ®\® -3 | 4.0 ®\® 2.1
    515           | (1.0f+2.0fi) ®\® (3.0f+2.0fi);
    516 1 1 256 -64 125 0 3273344365508751233 0 0 -0.015625 18.3791736799526 0.264715-1.1922i
     510Unsigned integral exponentiation\index{exponentiation!unsigned integral} is performed with repeated multiplication\footnote{The multiplication computation is $O(\log y)$.} (or shifting if the base is 2).
     511Signed integral exponentiation\index{exponentiation!signed integral} is performed with repeated multiplication (or shifting if the base is 2), but yields a floating result because $x^{-y}=1/x^y$.
     512Hence, it is important to designate exponent integral-constants as unsigned or signed: ©3 \ 3u© return an integral result, while ©3 \ 3© returns a floating result.
     513Floating exponentiation\index{exponentiation!floating} is performed using \Index{logarithm}s\index{exponentiation!logarithm}, so the base cannot be negative.
     514\begin{cfa}
     515sout | 2 ®\® 8u | 4 ®\® 3u | -4 ®\® 3u | 4 ®\® -3 | -4 ®\® -3 | 4.0 ®\® 2.1 | (1.0f+2.0fi) ®\® (3.0f+2.0fi);
     516256 64 -64 0.015625 -0.015625 18.3791736799526 0.264715-1.1922i
    517517\end{cfa}
    518518Parenthesis are necessary for complex constants or the expression is parsed as ©1.0f+®(®2.0fi \ 3.0f®)®+2.0fi©.
    519 The exponentiation operator is available for all the basic types, but for user-defined types, only the integral-computation version is available.
    520 \begin{cfa}
    521 forall( otype OT | { void ?{}( OT & this, one_t ); OT ?*?( OT, OT ); } )
    522 OT ?®\®?( OT ep, unsigned int y );
    523 forall( otype OT | { void ?{}( OT & this, one_t ); OT ?*?( OT, OT ); } )
    524 OT ?®\®?( OT ep, unsigned long int y );
    525 \end{cfa}
    526 The user type ©T© must define multiplication one, ©1©, and, ©*©.
     519The exponentiation operator is available for all the basic types, but for user-defined types, only the integral-computation versions are available.
     520For returning an integral value, the user type ©T© must define multiplication, ©*©, and one, ©1©;
     521for returning a floating value, an additional divide of type ©T© into a ©double© returning a ©double© (©double ?/?( double, T )©) is necessary for negative exponents.
    527522
    528523
     
    13251320\end{cfa}
    13261321Essentially, the return type is wrapped around the routine name in successive layers (like an \Index{onion}).
    1327 While attempting to make the two contexts consistent is a laudable goal, it has not worked out in practice, even though Dennis Richie believed otherwise:
    1328 \begin{quote}
    1329 In spite of its difficulties, I believe that the C's approach to declarations remains plausible, and am comfortable with it; it is a useful unifying principle.~\cite[p.~12]{Ritchie93}
    1330 \end{quote}
     1322While attempting to make the two contexts consistent is a laudable goal, it has not worked out in practice.
    13311323
    13321324\CFA provides its own type, variable and routine declarations, using a different syntax.
  • libcfa/prelude/builtins.c

    r86fb8f2 r2b10f95  
    1010// Created On       : Fri Jul 21 16:21:03 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Mar 26 23:10:36 2019
    13 // Update Count     : 95
     12// Last Modified On : Sun Mar 10 10:52:50 2019
     13// Update Count     : 31
    1414//
    1515
     
    1818typedef unsigned long long __cfaabi_abi_exception_type_t;
    1919
    20 #include <limits.h>                                                                             // CHAR_BIT
    2120#include "../src/virtual.h"
    2221#include "../src/exception.h"
     
    2726// increment/decrement unification
    2827
    29 static inline {
    30         forall( dtype DT | { DT & ?+=?( DT &, one_t ); } )
    31         DT & ++?( DT & x ) { return x += 1; }
     28static inline forall( dtype T | { T & ?+=?( T &, one_t ); } )
     29T & ++? ( T & x ) { return x += 1; }
    3230
    33         forall( dtype DT | sized(DT) | { void ?{}( DT &, DT ); void ^?{}( DT & ); DT & ?+=?( DT &, one_t ); } )
    34         DT & ?++( DT & x ) { DT tmp = x; x += 1; return tmp; }
     31static inline forall( dtype T | sized(T) | { void ?{}( T &, T ); void ^?{}( T & ); T & ?+=?( T &, one_t ); } )
     32T & ?++ ( T & x ) { T tmp = x; x += 1; return tmp; }
    3533
    36         forall( dtype DT | { DT & ?-=?( DT &, one_t ); } )
    37         DT & --?( DT & x ) { return x -= 1; }
     34static inline forall( dtype T | { T & ?-=?( T &, one_t ); } )
     35T & --? ( T & x ) { return x -= 1; }
    3836
    39         forall( dtype DT | sized(DT) | { void ?{}( DT &, DT ); void ^?{}( DT & ); DT & ?-=?( DT &, one_t ); } )
    40         DT & ?--( DT & x ) { DT tmp = x; x -= 1; return tmp; }
    41 } // distribution
     37static inline forall( dtype T | sized(T) | { void ?{}( T &, T ); void ^?{}( T & ); T & ?-=?( T &, one_t ); } )
     38T & ?-- ( T & x ) { T tmp = x; x -= 1; return tmp; }
    4239
    4340// universal typed pointer constant
    44 // Compiler issue: there is a problem with anonymous types that do not have a size.
    45 static inline forall( dtype DT | sized(DT) ) DT * intptr( uintptr_t addr ) { return (DT *)addr; }
     41
     42static inline forall( dtype T ) T * intptr( uintptr_t addr ) { return (T *)addr; }
    4643
    4744// exponentiation operator implementation
     
    5653} // extern "C"
    5754
    58 static inline {
    59         float ?\?( float x, float y ) { return powf( x, y ); }
    60         double ?\?( double x, double y ) { return pow( x, y ); }
    61         long double ?\?( long double x, long double y ) { return powl( x, y ); }
    62         float _Complex ?\?( float _Complex x, _Complex float y ) { return cpowf(x, y ); }
    63         double _Complex ?\?( double _Complex x, _Complex double y ) { return cpow( x, y ); }
    64         long double _Complex ?\?( long double _Complex x, _Complex long double y ) { return cpowl( x, y ); }
    65 } // distribution
     55static inline float ?\?( float x, float y ) { return powf( x, y ); }
     56static inline double ?\?( double x, double y ) { return pow( x, y ); }
     57static inline long double ?\?( long double x, long double y ) { return powl( x, y ); }
     58static inline float _Complex ?\?( float _Complex x, _Complex float y ) { return cpowf(x, y ); }
     59static inline double _Complex ?\?( double _Complex x, _Complex double y ) { return cpow( x, y ); }
     60static inline long double _Complex ?\?( long double _Complex x, _Complex long double y ) { return cpowl( x, y ); }
    6661
    67 #define __CFA_BASE_COMP_1__() if ( ep == 1 ) return 1
    68 #define __CFA_BASE_COMP_2__() if ( ep == 2 ) return ep << (y - 1)
    69 #define __CFA_EXP_OVERFLOW__() if ( y >= sizeof(y) * CHAR_BIT ) return 0
     62static inline long int ?\?( long int ep, unsigned long int y ) { // disallow negative exponent
     63        if ( y == 0 ) return 1;                                                         // base case
     64        if ( ep == 2 ) return ep << (y - 1);                            // special case, positive shifting only
     65        typeof( ep ) op = 1;                                                            // accumulate odd product
     66        for ( ; y > 1; y >>= 1 ) {                                                      // squaring exponentiation, O(log2 y)
     67                if ( (y & 1) == 1 ) op *= ep;                                   // odd ?
     68                ep *= ep;
     69        } // for
     70        return ep * op;
     71} // ?\?
    7072
    71 #define __CFA_EXP__() \
    72         if ( y == 0 ) return 1;                                                         /* convention */ \
    73         __CFA_BASE_COMP_1__();                                                          /* base case */ \
    74         __CFA_BASE_COMP_2__();                                                          /* special case, positive shifting for integral types */ \
    75         __CFA_EXP_OVERFLOW__();                                                         /* immediate overflow, negative exponent > 2^size-1 */ \
    76         typeof(ep) op = 1;                                                                      /* accumulate odd product */ \
    77         for ( ; y > 1; y >>= 1 ) {                                                      /* squaring exponentiation, O(log2 y) */ \
    78                 if ( (y & 1) == 1 ) op = op * ep;                               /* odd ? */ \
    79                 ep = ep * ep; \
    80         } \
    81         return ep * op
     73static inline forall( otype T | { void ?{}( T & this, one_t ); T ?*?( T, T ); } )
     74T ?\?( T ep, unsigned long int y ) {
     75        if ( y == 0 ) return 1;
     76        T op = 1;
     77        for ( ; y > 1; y >>= 1 ) {                                                      // squaring exponentiation, O(log2 y)
     78                if ( (y & 1) == 1 ) op = op * ep;                               // odd ?
     79                ep = ep * ep;
     80        } // for
     81        return ep * op;
     82} // ?\?
    8283
    83 static inline {
    84         long int ?\?( int ep, unsigned int y ) { __CFA_EXP__(); }
    85         long int ?\?( long int ep, unsigned long int y ) { __CFA_EXP__(); }
    86         // unsigned computation may be faster and larger
    87         unsigned long int ?\?( unsigned int ep, unsigned int y ) { __CFA_EXP__(); }
    88         unsigned long int ?\?( unsigned long int ep, unsigned long int y ) { __CFA_EXP__(); }
    89 } // distribution
     84// unsigned computation may be faster and larger
     85static inline unsigned long int ?\?( unsigned long int ep, unsigned long int y ) { // disallow negative exponent
     86        if ( y == 0 ) return 1;                                                         // base case
     87        if ( ep == 2 ) return ep << (y - 1);                            // special case, positive shifting only
     88        typeof( ep ) op = 1;                                                            // accumulate odd product
     89        for ( ; y > 1; y >>= 1 ) {                                                      // squaring exponentiation, O(log2 y)
     90                if ( (y & 1) == 1 ) op *= ep;                                   // odd ?
     91                ep *= ep;
     92        } // for
     93        return ep * op;
     94} // ?\?
    9095
    91 #undef __CFA_BASE_COMP_1__
    92 #undef __CFA_BASE_COMP_2__
    93 #undef __CFA_EXP_OVERFLOW__
    94 #define __CFA_BASE_COMP_1__()
    95 #define __CFA_BASE_COMP_2__()
    96 #define __CFA_EXP_OVERFLOW__()
     96static inline double ?\?( long int x, signed long int y ) {     // allow negative exponent
     97        if ( y >=  0 ) return (double)(x \ (unsigned long int)y);
     98        else return 1.0 / x \ (unsigned int)(-y);
     99} // ?\?
    97100
    98 static inline forall( otype OT | { void ?{}( OT & this, one_t ); OT ?*?( OT, OT ); } ) {
    99         OT ?\?( OT ep, unsigned int y ) { __CFA_EXP__(); }
    100         OT ?\?( OT ep, unsigned long int y ) { __CFA_EXP__(); }
    101 } // distribution
     101// FIXME (x \ (unsigned long int)y) relies on X ?\?(T, unsigned long) a function that is neither
     102// defined, nor passed as an assertion parameter. Without user-defined conversions, cannot specify
     103// X as a type that casts to double, yet it doesn't make sense to write functions with that type
     104// signature where X is double.
    102105
    103 #undef __CFA_BASE_COMP_1__
    104 #undef __CFA_BASE_COMP_2__
    105 #undef __CFA_EXP_OVERFLOW__
     106// static inline forall( otype T | { void ?{}( T & this, one_t ); T ?*?( T, T ); double ?/?( double, T ); } )
     107// double ?\?( T x, signed long int y ) {
     108//     if ( y >=  0 ) return (double)(x \ (unsigned long int)y);
     109//     else return 1.0 / x \ (unsigned long int)(-y);
     110// } // ?\?
    106111
    107 static inline {
    108         long int ?\=?( long int & x, unsigned long int y ) { x = x \ y; return x; }
    109         unsigned long int ?\=?( unsigned long int & x, unsigned long int y ) { x = x \ y; return x; }
    110         int ?\=?( int & x, unsigned long int y ) { x = x \ y; return x; }
    111         unsigned int ?\=?( unsigned int & x, unsigned long int y ) { x = x \ y; return x; }
    112 } // distribution
     112static inline long int ?\=?( long int & x, unsigned long int y ) { x = x \ y; return x; }
     113static inline unsigned long int ?\=?( unsigned long int & x, unsigned long int y ) { x = x \ y; return x; }
     114static inline int ?\=?( int & x, unsigned long int y ) { x = x \ y; return x; }
     115static inline unsigned int ?\=?( unsigned int & x, unsigned long int y ) { x = x \ y; return x; }
    113116
    114117// Local Variables: //
  • libcfa/src/rational.cfa

    r86fb8f2 r2b10f95  
    1010// Created On       : Wed Apr  6 17:54:28 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar 27 08:45:59 2019
    13 // Update Count     : 180
     12// Last Modified On : Sun Dec 23 22:56:49 2018
     13// Update Count     : 170
    1414//
    1515
     
    5454        void ?{}( Rational(RationalImpl) & r, RationalImpl n, RationalImpl d ) {
    5555                RationalImpl t = simplify( n, d );                              // simplify
    56                 r.[numerator, denominator] = [n / t, d / t];
     56                r.numerator = n / t;
     57                r.denominator = d / t;
    5758        } // rational
    5859
     
    7778                RationalImpl prev = r.numerator;
    7879                RationalImpl t = gcd( abs( n ), r.denominator ); // simplify
    79                 r.[numerator, denominator] = [n / t, r.denominator / t];
     80                r.numerator = n / t;
     81                r.denominator = r.denominator / t;
    8082                return prev;
    8183        } // numerator
     
    8486                RationalImpl prev = r.denominator;
    8587                RationalImpl t = simplify( r.numerator, d );    // simplify
    86                 r.[numerator, denominator] = [r.numerator / t, d / t];
     88                r.numerator = r.numerator / t;
     89                r.denominator = d / t;
    8790                return prev;
    8891        } // denominator
     
    117120
    118121        Rational(RationalImpl) +?( Rational(RationalImpl) r ) {
    119                 return (Rational(RationalImpl)){ r.numerator, r.denominator };
     122                Rational(RationalImpl) t = { r.numerator, r.denominator };
     123                return t;
    120124        } // +?
    121125
    122126        Rational(RationalImpl) -?( Rational(RationalImpl) r ) {
    123                 return (Rational(RationalImpl)){ -r.numerator, r.denominator };
     127                Rational(RationalImpl) t = { -r.numerator, r.denominator };
     128                return t;
    124129        } // -?
    125130
    126131        Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    127132                if ( l.denominator == r.denominator ) {                 // special case
    128                         return (Rational(RationalImpl)){ l.numerator + r.numerator, l.denominator };
     133                        Rational(RationalImpl) t = { l.numerator + r.numerator, l.denominator };
     134                        return t;
    129135                } else {
    130                         return (Rational(RationalImpl)){ l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator };
     136                        Rational(RationalImpl) t = { l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator };
     137                        return t;
    131138                } // if
    132139        } // ?+?
     
    134141        Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    135142                if ( l.denominator == r.denominator ) {                 // special case
    136                         return (Rational(RationalImpl)){ l.numerator - r.numerator, l.denominator };
     143                        Rational(RationalImpl) t = { l.numerator - r.numerator, l.denominator };
     144                        return t;
    137145                } else {
    138                         return (Rational(RationalImpl)){ l.numerator * r.denominator - l.denominator * r.numerator, l.denominator * r.denominator };
     146                        Rational(RationalImpl) t = { l.numerator * r.denominator - l.denominator * r.numerator, l.denominator * r.denominator };
     147                        return t;
    139148                } // if
    140149        } // ?-?
    141150
    142151        Rational(RationalImpl) ?*?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    143                 return (Rational(RationalImpl)){ l.numerator * r.numerator, l.denominator * r.denominator };
     152                Rational(RationalImpl) t = { l.numerator * r.numerator, l.denominator * r.denominator };
     153                return t;
    144154        } // ?*?
    145155
    146156        Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    147157                if ( r.numerator < (RationalImpl){0} ) {
    148                         r.[numerator, denominator] = [-r.numerator, -r.denominator];
     158                        r.numerator = -r.numerator;
     159                        r.denominator = -r.denominator;
    149160                } // if
    150                 return (Rational(RationalImpl)){ l.numerator * r.denominator, l.denominator * r.numerator };
     161                Rational(RationalImpl) t = { l.numerator * r.denominator, l.denominator * r.numerator };
     162                return t;
    151163        } // ?/?
    152164
     
    155167        forall( dtype istype | istream( istype ) | { istype & ?|?( istype &, RationalImpl & ); } )
    156168        istype & ?|?( istype & is, Rational(RationalImpl) & r ) {
     169                RationalImpl t;
    157170                is | r.numerator | r.denominator;
    158                 RationalImpl t = simplify( r.numerator, r.denominator );
     171                t = simplify( r.numerator, r.denominator );
    159172                r.numerator /= t;
    160173                r.denominator /= t;
     
    172185        } // distribution
    173186} // distribution
    174 
    175 forall( otype RationalImpl | arithmetic( RationalImpl ) | { RationalImpl ?\?( RationalImpl, unsigned long ); } )
    176 Rational(RationalImpl) ?\?( Rational(RationalImpl) x, long int y ) {
    177         if ( y < 0 ) {
    178                 return (Rational(RationalImpl)){ x.denominator \ -y, x.numerator \ -y };
    179         } else {
    180                 return (Rational(RationalImpl)){ x.numerator \ y, x.denominator \ y };
    181         } // if
    182 }
    183187
    184188// conversion
  • libcfa/src/rational.hfa

    r86fb8f2 r2b10f95  
    1212// Created On       : Wed Apr  6 17:56:25 2016
    1313// Last Modified By : Peter A. Buhr
    14 // Last Modified On : Tue Mar 26 23:16:10 2019
    15 // Update Count     : 109
     14// Last Modified On : Tue Dec  4 23:07:46 2018
     15// Update Count     : 106
    1616//
    1717
     
    9898} // distribution
    9999
    100 forall( otype RationalImpl | arithmetic( RationalImpl ) |{RationalImpl ?\?( RationalImpl, unsigned long );} )
    101 Rational(RationalImpl) ?\?( Rational(RationalImpl) x, long int y );
    102 
    103100// conversion
    104101forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )
  • tests/.expect/KRfunctions.x64.txt

    r86fb8f2 r2b10f95  
    8282    signed int _X1ai_2;
    8383    signed int _X1bi_2;
    84     signed int *(*_tmp_cp_ret4)(signed int _X1xi_1, signed int _X1yi_1);
    85     ((void)(_X1xFPi_ii__2=(((void)(_tmp_cp_ret4=_X3f10FFPi_ii__iPiPid__1(3, (&_X1ai_2), (&_X1bi_2), 3.5))) , _tmp_cp_ret4)));
    86     ((void)(_tmp_cp_ret4) /* ^?{} */);
     84    signed int *(*_tmp_cp_ret2)(signed int _X1xi_1, signed int _X1yi_1);
     85    ((void)(_X1xFPi_ii__2=(((void)(_tmp_cp_ret2=_X3f10FFPi_ii__iPiPid__1(3, (&_X1ai_2), (&_X1bi_2), 3.5))) , _tmp_cp_ret2)));
     86    ((void)(_tmp_cp_ret2) /* ^?{} */);
    8787    const signed int _X2f1Fi_iPiPi__2(signed int _X1ai_2, signed int *_X1bPi_2, signed int *_X1cPi_2){
    8888        __attribute__ ((unused)) const signed int _X10_retval_f1Ki_2;
  • tests/.expect/completeTypeError.txt

    r86fb8f2 r2b10f95  
    8787   void
    8888 )
    89  Environment:( _99_0_T ) -> instance of type T (not function type) (no widening)
     89 Environment:( _74_0_T ) -> instance of type T (not function type) (no widening)
    9090
    9191
  • tests/.expect/declarationSpecifier.x64.txt

    r86fb8f2 r2b10f95  
    698698signed int main(signed int _X4argci_1, char **_X4argvPPc_1, char **_X4envpPPc_1){
    699699    __attribute__ ((unused)) signed int _X12_retval_maini_1;
    700     signed int _tmp_cp_ret4;
    701     ((void)(_X12_retval_maini_1=(((void)(_tmp_cp_ret4=invoke_main(_X4argci_1, _X4argvPPc_1, _X4envpPPc_1))) , _tmp_cp_ret4)) /* ?{} */);
    702     ((void)(_tmp_cp_ret4) /* ^?{} */);
     700    signed int _tmp_cp_ret2;
     701    ((void)(_X12_retval_maini_1=(((void)(_tmp_cp_ret2=invoke_main(_X4argci_1, _X4argvPPc_1, _X4envpPPc_1))) , _tmp_cp_ret2)) /* ?{} */);
     702    ((void)(_tmp_cp_ret2) /* ^?{} */);
    703703    return _X12_retval_maini_1;
    704704}
  • tests/.expect/extension.x64.txt

    r86fb8f2 r2b10f95  
    186186    __extension__ signed int _X1ci_2;
    187187    ((void)(__extension__ _X1ai_2=(__extension__ _X1bi_2+__extension__ _X1ci_2)));
    188     signed int _tmp_cp_ret4;
    189     ((void)(((void)(_tmp_cp_ret4=__extension__ _X4fredFi_i__1(3))) , _tmp_cp_ret4));
    190     ((void)(_tmp_cp_ret4) /* ^?{} */);
     188    signed int _tmp_cp_ret2;
     189    ((void)(((void)(_tmp_cp_ret2=__extension__ _X4fredFi_i__1(3))) , _tmp_cp_ret2));
     190    ((void)(_tmp_cp_ret2) /* ^?{} */);
    191191    __extension__ signed int _X4maryFi_i__2(signed int _X1pi_2){
    192192        __attribute__ ((unused)) signed int _X12_retval_maryi_2;
  • tests/.expect/gccExtensions.x64.txt

    r86fb8f2 r2b10f95  
    171171signed int main(signed int _X4argci_1, char **_X4argvPPc_1, char **_X4envpPPc_1){
    172172    __attribute__ ((unused)) signed int _X12_retval_maini_1;
    173     signed int _tmp_cp_ret4;
    174     ((void)(_X12_retval_maini_1=(((void)(_tmp_cp_ret4=invoke_main(_X4argci_1, _X4argvPPc_1, _X4envpPPc_1))) , _tmp_cp_ret4)) /* ?{} */);
    175     ((void)(_tmp_cp_ret4) /* ^?{} */);
     173    signed int _tmp_cp_ret2;
     174    ((void)(_X12_retval_maini_1=(((void)(_tmp_cp_ret2=invoke_main(_X4argci_1, _X4argvPPc_1, _X4envpPPc_1))) , _tmp_cp_ret2)) /* ?{} */);
     175    ((void)(_tmp_cp_ret2) /* ^?{} */);
    176176    return _X12_retval_maini_1;
    177177}
  • tests/.expect/math1.txt

    r86fb8f2 r2b10f95  
    1010expm1:1.71828 1.71828182845905 1.71828182845904524
    1111pow:1 1 1 0.273957+0.583701i 0.273957253830121+0.583700758758615i -0.638110484918098871+0.705394566961838155i
    12 16 \ 2 = 256
    13 912673 256 64 -64 0 0
    14 0.015625 -0.015625 18.3791736799526 0.264715-1.1922i
    15 0 0 18.3791736799526 0.264715-1.1922i
    16 16
    17 4 16
     12\ 16 256
     13\ 912673 256 64 -64 0.015625 -0.015625 18.3791736799526 0.264715-1.1922i
  • tests/coroutine/pingpong.cfa

    r86fb8f2 r2b10f95  
    1010// Created On       : Wed Sep 20 11:55:23 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Mar 26 17:54:14 2019
    13 // Update Count     : 35
     12// Last Modified On : Fri Mar 22 13:37:52 2019
     13// Update Count     : 30
    1414//
    1515
     
    2020        const char * name;
    2121        /* const */ unsigned int N;
    22         PingPong & part;
     22        PingPong * part;
    2323};
    2424
    2525void ?{}( PingPong & this, const char * name, unsigned int N, PingPong & part ) {
    26         this.[name, N] = [name, N];  &this.part = &part;
     26        (this.__cor){name};
     27        this.name = name;
     28        this.N = N;
     29        this.part = &part;
    2730}
    2831void ?{}( PingPong & this, const char * name, unsigned int N ) {
    29         this{ name, N, *0p };                                                           // call first constructor
     32        this{ name, N, *(PingPong *)0 };
    3033}
    3134void cycle( PingPong & pingpong ) {
     
    3336}
    3437void partner( PingPong & this, PingPong & part ) {
    35         &this.part = &part;
     38        this.part = &part;
    3639        resume( this );
    3740}
    38 void main( PingPong & pingpong ) with(pingpong) {               // ping's starter ::main, pong's starter ping
    39         for ( N ) {                                                                                     // N ping-pongs
    40                 sout | name;
    41                 cycle( part );
     41void main( PingPong & pingpong ) {                                              // ping's starter ::main, pong's starter ping
     42        for ( pingpong.N ) {                                                            // N ping-pongs
     43                sout | pingpong.name;
     44                cycle( *pingpong.part );
    4245        } // for
    4346}
  • tests/math1.cfa

    r86fb8f2 r2b10f95  
    1010// Created On       : Fri Apr 22 14:59:21 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Mar 25 22:56:47 2019
    13 // Update Count     : 109
     12// Last Modified On : Wed Dec 12 16:28:49 2018
     13// Update Count     : 89
    1414//
    1515
     
    4949        unsigned int e = 2;
    5050    b \= e;
    51     sout | b | "\\" | e | "= " | b \ e;
    52     sout | 'a' \ 3 | 2 \ 8 | 4 \ 3 | -4 \ 3 | 4 \ -3 | -4 \ -3;
    53         sout | 4.0 \ -3 | -4.0 \ -3 | 4.0 \ 2.1 | (1.0f+2.0fi) \ (3.0f+2.0fi);
     51    sout | "\\" | b | b \ e;
     52    sout | "\\" | 'a' \ 3u | 2 \ 8u | 4 \ 3u | -4 \ 3u | nonl;
    5453        sout | 4 \ -3 | -4 \ -3 | 4.0 \ 2.1 | (1.0f+2.0fi) \ (3.0f+2.0fi);
    55 
    56         struct S { int i; };
    57         double ?*?( double d, S s ) { return d * s.i; }
    58         double ?/?( double d, S s ) { return d / s.i; }
    59         S ?\?( S s, unsigned long y ) { return (S){ s.i \ y }; }
    60         ofstream & ?|?( ofstream & os, S s ) { return os | s.i; }
    61         void ?|?( ofstream & os, S s ) { (ofstream &)(os | s); nl( os ); }
    62         S s = { 4 };
    63         S x = s \ 2;
    64         sout | x;
    65         sout | s.i | s \ 2u;
    6654} // main
    6755
  • tests/rational.cfa

    r86fb8f2 r2b10f95  
    1010// Created On       : Mon Mar 28 08:43:12 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar 27 07:37:17 2019
    13 // Update Count     : 80
     12// Last Modified On : Tue Mar 19 08:30:28 2019
     13// Update Count     : 73
    1414//
    1515
     
    5454        sout | a * b;
    5555        sout | a / b;
    56 //      sout | a \ 2 | b \ 2; // FIX ME
    57 //      sout | a \ -2 | b \ -2;
    5856
    5957        sout | "conversion";
Note: See TracChangeset for help on using the changeset viewer.