Changeset 86fb8f2
- Timestamp:
- Mar 27, 2019, 11:09:23 AM (6 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- a45fc7b
- Parents:
- 2b10f95 (diff), 1e5d0f0c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 2 added
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/papers/concurrency/Paper.tex
r2b10f95 r86fb8f2 654 654 \centering 655 655 \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} 656 676 \begin{lrbox}{\myboxA} 657 677 \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 } 678 #define FIB_INIT { 0, 1 } 679 typedef struct { int fn1, fn; } Fib; 680 int fib( Fib * f ) { 681 682 int ret = f->fn1; 683 f->fn1 = f->fn; 684 f->fn = ret + f->fn; 685 return ret; 686 } 687 688 689 668 690 int main() { 669 691 Fib f1 = FIB_INIT, f2 = FIB_INIT; 670 692 for ( int i = 0; i < 10; i += 1 ) { 671 printf( "%d\n", fib() ); 693 printf( "%d %d\n", 694 fib( &f1 ), fib( &f2 ) ); 672 695 } 673 696 } … … 678 701 \begin{lrbox}{\myboxB} 679 702 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 680 #define FIB_INIT `{ 0, 1 }` 681 typedef struct { int fn2, fn1; } Fib; 682 int fib( Fib * f ) { 683 684 int ret = f->fn2; 685 int fn = f->fn1 + f->fn2; 686 f->fn2 = f->fn1; f->fn1 = fn; 687 688 return ret; 689 } 690 int main() { 691 Fib f1 = FIB_INIT, f2 = FIB_INIT; 692 for ( int i = 0; i < 10; i += 1 ) { 693 printf( "%d %d\n", fib( &fn1 ), fib( &f2 ) ); 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]; 694 710 } 695 711 } 696 \end{cfa} 697 \end{lrbox} 698 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; }; 711 void 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 } 717 int next( Fib & fib ) with( fib ) { `resume( fib );` return fn; } 712 int ?()( Fib & fib ) with( fib ) { 713 `resume( fib );` return fn1; 714 } 718 715 int main() { 719 716 Fib f1, f2; 720 for ( 10 ) 721 sout | next( f1 ) | next( f2 ); 722 } 717 for ( 10 ) { 718 sout | f1() | f2(); 719 } 720 721 723 722 \end{cfa} 724 723 \end{lrbox} 725 \newbox\myboxB 726 \begin{lrbox}{\myboxB} 724 725 \newbox\myboxC 726 \begin{lrbox}{\myboxC} 727 727 \begin{python}[aboveskip=0pt,belowskip=0pt] 728 728 729 def 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 736 f1 = Fibonacci() 737 f2 = Fibonacci() 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() 738 742 for i in range( 10 ): 739 print( `next( f1 )`, `next( f2 )` ) # resume 743 print( next( f1 ), next( f2 ) ) 744 745 740 746 741 747 \end{python} 742 748 \end{lrbox} 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} 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} 748 805 \end{figure} 749 806 -
doc/papers/concurrency/examples/Pingpong.cfa
r2b10f95 r86fb8f2 4 4 coroutine PingPong { 5 5 const char * name; 6 /* const */unsigned int N;7 PingPong *part;6 unsigned int N; 7 PingPong & part; 8 8 }; 9 9 10 10 void ?{}( PingPong & this, const char * name, unsigned int N, PingPong & part ) { 11 (this.__cor){name}; 12 this.name = name; 13 this.N = N; 14 this.part = ∂ 11 this.[name, N] = [name, N]; &this.part = ∂ 15 12 } 16 13 void ?{}( PingPong & this, const char * name, unsigned int N ) { 17 this{ name, N, * (PingPong *)0 };14 this{ name, N, *0p }; // call first constructor 18 15 } 19 16 void cycle( PingPong & pingpong ) { … … 21 18 } 22 19 void partner( PingPong & this, PingPong & part ) { 23 this.part = ∂20 &this.part = ∂ 24 21 resume( this ); 25 22 } 26 void main( PingPong & pingpong ) {// ping's starter ::main, pong's starter ping27 for ( pingpong.N ) {// N ping-pongs28 sout | pingpong.name;29 cycle( *pingpong.part );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 ); 30 27 } // for 31 28 } 32 29 int main() { 33 enum { N = 20};30 enum { N = 5 }; 34 31 PingPong ping = { "ping", N }, pong = { "pong", N, ping }; 35 32 partner( ping, pong ); … … 38 35 // Local Variables: // 39 36 // tab-width: 4 // 40 // compile-command: "cfa pingpong.cfa" //37 // compile-command: "cfa Pingpong.cfa" // 41 38 // End: // -
doc/papers/concurrency/examples/Pingpong.py
r2b10f95 r86fb8f2 1 def Scheduler 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 ) 8 9 def Scheduler(): 10 n = (yield) # starting coroutine 11 while True: 12 n = next( n ) # schedule coroutine 13 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 20 21 s = Scheduler(); 22 next( s ) # prime 2 23 try: 3 yield from ping(); 4 yield from pong(); 24 s.send( pi ) # start cycle 5 25 except StopIteration: 6 print( "Scheduler stop" ) 7 8 9 def pong(): 10 print( "pong" ) 11 for i in range( 10 ): 12 13 yield from ping() 14 print( "stop pong" ) 15 16 def ping(): 17 global i 18 print( "ping" ) 19 i += 1 20 if i < 5: 21 yield from pong() 22 print( "stop ping" ) 23 24 p = ping() 25 try: 26 next( p ) 27 except StopIteration: 28 print( "stop" ) 26 print( "scheduler stop" ) 27 print( "stop" ) 29 28 30 29 # Local Variables: # 31 30 # tab-width: 4 # 32 # compile-command: "python3.5 pingpong.py" #31 # compile-command: "python3.5 Pingpong.py" # 33 32 # End: # -
doc/papers/concurrency/examples/ProdCons.cfa
r2b10f95 r86fb8f2 23 23 sout | "prod stops"; 24 24 } 25 int payment( Prod & prod, int m oney) {26 prod.money = money;25 int payment( Prod & prod, int m ) with(prod) { 26 money = m; 27 27 resume( prod ); // main 1st time, then 28 return prod.receipt;// prod in delivery28 return receipt; // prod in delivery 29 29 } 30 30 void start( Prod & prod, int N, Cons &c ) { -
doc/papers/concurrency/examples/ProdCons.cpp
r2b10f95 r86fb8f2 12 12 struct Cons; 13 13 14 struct Prod { 14 struct resumable { 15 virtual resumable * resume() = 0; 16 }; 17 18 struct Prod : public resumable { 15 19 struct local { 16 20 Cons * c; … … 20 24 struct promise_type { 21 25 local _l; 26 resumable * next; 22 27 23 28 Prod get_return_object() { … … 69 74 static Prod main(); 70 75 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 } 76 struct payment_return; 77 78 payment_return payment(int money); 81 79 82 80 auto start(int N, Cons & c) { … … 84 82 _coroutine.promise()._l.N = N; 85 83 _coroutine.promise()._l.receipt = 0; 84 } 85 86 virtual resumable * resume() override final { 86 87 _coroutine.resume(); 87 } 88 }; 89 90 struct Cons { 88 return _coroutine.promise().next; 89 } 90 }; 91 92 struct Cons : public resumable { 91 93 struct local { 92 94 Prod * p; … … 97 99 struct promise_type { 98 100 local _l; 101 resumable * next; 99 102 100 103 Cons get_return_object() { … … 154 157 struct ret { 155 158 int _status; 159 Cons * c; 156 160 bool await_ready() { return false; } 157 void await_suspend(std::experimental::coroutine_handle<>) {} 161 void await_suspend(std::experimental::coroutine_handle<Prod::promise_type> _coroutine) { 162 _coroutine.promise().next = c; 163 } 158 164 int await_resume() { return _status; } 159 165 }; 160 return ret{ _coroutine.promise()._l.status };166 return ret{ _coroutine.promise()._l.status, this }; 161 167 } 162 168 … … 164 170 _coroutine.promise()._l.done = true; 165 171 struct ret { 172 Cons * c; 173 Prod::promise_type * _promise; 166 174 bool await_ready() { return false; } 167 void await_suspend(std::experimental::coroutine_handle<>) {} 168 void await_resume() {} 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 } 169 182 }; 170 return ret{}; 171 } 172 }; 183 return ret{this, nullptr}; 184 } 185 186 virtual resumable * resume() override final { 187 _coroutine.resume(); 188 return _coroutine.promise().next; 189 } 190 }; 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 } 173 206 174 207 Prod Prod::main() { … … 176 209 for(int i = 0; i < p.N; i++) { 177 210 int p1 = random(100), p2 = random(100); 178 std::cout << p1 << " " << p2 ;211 std::cout << p1 << " " << p2 << std::endl; 179 212 int status = co_await p.c->deliver(p1, p2); 180 std::cout << " $" << p.money << std::endl << status ;213 std::cout << " $" << p.money << std::endl << status << std::endl; 181 214 p.receipt += 1; 182 215 } 183 216 co_await p.c->stop(); 184 std::cout << "prod stops" ;217 std::cout << "prod stops" << std::endl; 185 218 } 186 219 … … 189 222 int money = 1, receipt; 190 223 for(;!c.done ;) { 191 std::cout << c.p1 << " " << c.p2 << std::endl << " $" << money; 224 std::cout << c.p1 << " " << c.p2 << std::endl; 225 std::cout << " $ " << money << std::endl; 192 226 c.status += 1; 193 227 receipt = co_await c.p->payment( money ); 194 std::cout << " # " << receipt;228 std::cout << " # " << receipt << std::endl; 195 229 money += 1; 196 230 } 197 std::cout << "const stops"; 231 std::cout << "cons stops" << std::endl; 232 } 233 234 void dispatch(resumable * r) { 235 while((r = r->resume())); 198 236 } 199 237 … … 203 241 srandom( getpid() ); 204 242 prod.start(5, cons); 205 } 243 dispatch(&prod); 244 } -
doc/user/user.tex
r2b10f95 r86fb8f2 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Tue Dec 11 23:19:26 201814 %% Update Count : 34 0013 %% Last Modified On : Tue Mar 26 22:10:49 2019 14 %% Update Count : 3411 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 508 508 509 509 As for \Index{division}, there are exponentiation operators for integral and floating types, including the builtin \Index{complex} types. 510 Unsigned integral exponentiation\index{exponentiation!unsigned integral} is performed with repeated multiplication\footnote{The multiplication computation is $O(\log y)$.} (or shifting if the baseis 2).511 Signed 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$.512 Hence, 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.513 Floating exponentiation\index{exponentiation!floating} is performed using \Index{logarithm}s\index{exponentiation!logarithm}, so the base cannot be negative. 514 \begin{cfa} 515 sout | 2 ®\® 8u | 4 ®\® 3u | -4 ®\® 3u | 4 ®\® -3 | -4 ®\® -3 | 4.0 ®\® 2.1| (1.0f+2.0fi) ®\® (3.0f+2.0fi);516 256 64 -64 0.015625-0.015625 18.3791736799526 0.264715-1.1922i510 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 517 517 \end{cfa} 518 518 Parenthesis 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 versions are available. 520 For returning an integral value, the user type ©T© must define multiplication, ©*©, and one, ©1©; 521 for returning a floating value, an additional divide of type ©T© into a ©double© returning a ©double© (©double ?/?( double, T )©) is necessary for negative exponents. 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, ©*©. 522 527 523 528 … … 1320 1325 \end{cfa} 1321 1326 Essentially, the return type is wrapped around the routine name in successive layers (like an \Index{onion}). 1322 While attempting to make the two contexts consistent is a laudable goal, it has not worked out in practice. 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} 1323 1331 1324 1332 \CFA provides its own type, variable and routine declarations, using a different syntax. -
libcfa/prelude/builtins.c
r2b10f95 r86fb8f2 10 10 // Created On : Fri Jul 21 16:21:03 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Mar 10 10:52:50201913 // Update Count : 3112 // Last Modified On : Tue Mar 26 23:10:36 2019 13 // Update Count : 95 14 14 // 15 15 … … 18 18 typedef unsigned long long __cfaabi_abi_exception_type_t; 19 19 20 #include <limits.h> // CHAR_BIT 20 21 #include "../src/virtual.h" 21 22 #include "../src/exception.h" … … 26 27 // increment/decrement unification 27 28 28 static inline forall( dtype T | { T & ?+=?( T &, one_t ); } ) 29 T & ++? ( T & x ) { return x += 1; } 29 static inline { 30 forall( dtype DT | { DT & ?+=?( DT &, one_t ); } ) 31 DT & ++?( DT & x ) { return x += 1; } 30 32 31 static inline forall( dtype T | sized(T) | { void ?{}( T &, T ); void ^?{}( T & ); T & ?+=?(T &, one_t ); } )32 T & ?++ ( T & x ) {T tmp = x; x += 1; return tmp; }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; } 33 35 34 static inline forall( dtype T | { T & ?-=?(T &, one_t ); } )35 T & --? (T & x ) { return x -= 1; }36 forall( dtype DT | { DT & ?-=?( DT &, one_t ); } ) 37 DT & --?( DT & x ) { return x -= 1; } 36 38 37 static inline forall( dtype T | sized(T) | { void ?{}( T &, T ); void ^?{}( T & ); T & ?-=?( T &, one_t ); } ) 38 T & ?-- ( T & x ) { T tmp = x; x -= 1; return tmp; } 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 39 42 40 43 // universal typed pointer constant 41 42 static inline forall( dtype T ) T * intptr( uintptr_t addr ) { return (T *)addr; }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; } 43 46 44 47 // exponentiation operator implementation … … 53 56 } // extern "C" 54 57 55 static inline float ?\?( float x, float y ) { return powf( x, y ); } 56 static inline double ?\?( double x, double y ) { return pow( x, y ); } 57 static inline long double ?\?( long double x, long double y ) { return powl( x, y ); } 58 static inline float _Complex ?\?( float _Complex x, _Complex float y ) { return cpowf(x, y ); } 59 static inline double _Complex ?\?( double _Complex x, _Complex double y ) { return cpow( x, y ); } 60 static inline long double _Complex ?\?( long double _Complex x, _Complex long double y ) { return cpowl( x, y ); } 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 61 66 62 static 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 } // ?\? 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 72 70 73 static inline forall( otype T | { void ?{}( T & this, one_t ); T ?*?( T, T ); } ) 74 T ?\?( 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 } // ?\? 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 83 82 84 // unsigned computation may be faster and larger 85 static 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 } // ?\? 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 95 90 96 static 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 } // ?\? 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__() 100 97 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. 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 105 102 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 // } // ?\? 103 #undef __CFA_BASE_COMP_1__ 104 #undef __CFA_BASE_COMP_2__ 105 #undef __CFA_EXP_OVERFLOW__ 111 106 112 static inline long int ?\=?( long int & x, unsigned long int y ) { x = x \ y; return x; } 113 static inline unsigned long int ?\=?( unsigned long int & x, unsigned long int y ) { x = x \ y; return x; } 114 static inline int ?\=?( int & x, unsigned long int y ) { x = x \ y; return x; } 115 static inline unsigned int ?\=?( unsigned int & x, unsigned long int y ) { x = x \ y; return x; } 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 116 113 117 114 // Local Variables: // -
libcfa/src/rational.cfa
r2b10f95 r86fb8f2 10 10 // Created On : Wed Apr 6 17:54:28 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Dec 23 22:56:49 201813 // Update Count : 1 7012 // Last Modified On : Wed Mar 27 08:45:59 2019 13 // Update Count : 180 14 14 // 15 15 … … 54 54 void ?{}( Rational(RationalImpl) & r, RationalImpl n, RationalImpl d ) { 55 55 RationalImpl t = simplify( n, d ); // simplify 56 r.numerator = n / t; 57 r.denominator = d / t; 56 r.[numerator, denominator] = [n / t, d / t]; 58 57 } // rational 59 58 … … 78 77 RationalImpl prev = r.numerator; 79 78 RationalImpl t = gcd( abs( n ), r.denominator ); // simplify 80 r.numerator = n / t; 81 r.denominator = r.denominator / t; 79 r.[numerator, denominator] = [n / t, r.denominator / t]; 82 80 return prev; 83 81 } // numerator … … 86 84 RationalImpl prev = r.denominator; 87 85 RationalImpl t = simplify( r.numerator, d ); // simplify 88 r.numerator = r.numerator / t; 89 r.denominator = d / t; 86 r.[numerator, denominator] = [r.numerator / t, d / t]; 90 87 return prev; 91 88 } // denominator … … 120 117 121 118 Rational(RationalImpl) +?( Rational(RationalImpl) r ) { 122 Rational(RationalImpl) t = { r.numerator, r.denominator }; 123 return t; 119 return (Rational(RationalImpl)){ r.numerator, r.denominator }; 124 120 } // +? 125 121 126 122 Rational(RationalImpl) -?( Rational(RationalImpl) r ) { 127 Rational(RationalImpl) t = { -r.numerator, r.denominator }; 128 return t; 123 return (Rational(RationalImpl)){ -r.numerator, r.denominator }; 129 124 } // -? 130 125 131 126 Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 132 127 if ( l.denominator == r.denominator ) { // special case 133 Rational(RationalImpl) t = { l.numerator + r.numerator, l.denominator }; 134 return t; 128 return (Rational(RationalImpl)){ l.numerator + r.numerator, l.denominator }; 135 129 } else { 136 Rational(RationalImpl) t = { l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator }; 137 return t; 130 return (Rational(RationalImpl)){ l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator }; 138 131 } // if 139 132 } // ?+? … … 141 134 Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 142 135 if ( l.denominator == r.denominator ) { // special case 143 Rational(RationalImpl) t = { l.numerator - r.numerator, l.denominator }; 144 return t; 136 return (Rational(RationalImpl)){ l.numerator - r.numerator, l.denominator }; 145 137 } else { 146 Rational(RationalImpl) t = { l.numerator * r.denominator - l.denominator * r.numerator, l.denominator * r.denominator }; 147 return t; 138 return (Rational(RationalImpl)){ l.numerator * r.denominator - l.denominator * r.numerator, l.denominator * r.denominator }; 148 139 } // if 149 140 } // ?-? 150 141 151 142 Rational(RationalImpl) ?*?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 152 Rational(RationalImpl) t = { l.numerator * r.numerator, l.denominator * r.denominator }; 153 return t; 143 return (Rational(RationalImpl)){ l.numerator * r.numerator, l.denominator * r.denominator }; 154 144 } // ?*? 155 145 156 146 Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 157 147 if ( r.numerator < (RationalImpl){0} ) { 158 r.numerator = -r.numerator; 159 r.denominator = -r.denominator; 148 r.[numerator, denominator] = [-r.numerator, -r.denominator]; 160 149 } // if 161 Rational(RationalImpl) t = { l.numerator * r.denominator, l.denominator * r.numerator }; 162 return t; 150 return (Rational(RationalImpl)){ l.numerator * r.denominator, l.denominator * r.numerator }; 163 151 } // ?/? 164 152 … … 167 155 forall( dtype istype | istream( istype ) | { istype & ?|?( istype &, RationalImpl & ); } ) 168 156 istype & ?|?( istype & is, Rational(RationalImpl) & r ) { 169 RationalImpl t;170 157 is | r.numerator | r.denominator; 171 t = simplify( r.numerator, r.denominator );158 RationalImpl t = simplify( r.numerator, r.denominator ); 172 159 r.numerator /= t; 173 160 r.denominator /= t; … … 185 172 } // distribution 186 173 } // 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 } 187 183 188 184 // conversion -
libcfa/src/rational.hfa
r2b10f95 r86fb8f2 12 12 // Created On : Wed Apr 6 17:56:25 2016 13 13 // Last Modified By : Peter A. Buhr 14 // Last Modified On : Tue Dec 4 23:07:46 201815 // Update Count : 10 614 // Last Modified On : Tue Mar 26 23:16:10 2019 15 // Update Count : 109 16 16 // 17 17 … … 98 98 } // distribution 99 99 100 forall( otype RationalImpl | arithmetic( RationalImpl ) |{RationalImpl ?\?( RationalImpl, unsigned long );} ) 101 Rational(RationalImpl) ?\?( Rational(RationalImpl) x, long int y ); 102 100 103 // conversion 101 104 forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } ) -
tests/.expect/KRfunctions.x64.txt
r2b10f95 r86fb8f2 82 82 signed int _X1ai_2; 83 83 signed int _X1bi_2; 84 signed int *(*_tmp_cp_ret 2)(signed int _X1xi_1, signed int _X1yi_1);85 ((void)(_X1xFPi_ii__2=(((void)(_tmp_cp_ret 2=_X3f10FFPi_ii__iPiPid__1(3, (&_X1ai_2), (&_X1bi_2), 3.5))) , _tmp_cp_ret2)));86 ((void)(_tmp_cp_ret 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) /* ^?{} */); 87 87 const signed int _X2f1Fi_iPiPi__2(signed int _X1ai_2, signed int *_X1bPi_2, signed int *_X1cPi_2){ 88 88 __attribute__ ((unused)) const signed int _X10_retval_f1Ki_2; -
tests/.expect/completeTypeError.txt
r2b10f95 r86fb8f2 87 87 void 88 88 ) 89 Environment:( _ 74_0_T ) -> instance of type T (not function type) (no widening)89 Environment:( _99_0_T ) -> instance of type T (not function type) (no widening) 90 90 91 91 -
tests/.expect/declarationSpecifier.x64.txt
r2b10f95 r86fb8f2 698 698 signed int main(signed int _X4argci_1, char **_X4argvPPc_1, char **_X4envpPPc_1){ 699 699 __attribute__ ((unused)) signed int _X12_retval_maini_1; 700 signed int _tmp_cp_ret 2;701 ((void)(_X12_retval_maini_1=(((void)(_tmp_cp_ret 2=invoke_main(_X4argci_1, _X4argvPPc_1, _X4envpPPc_1))) , _tmp_cp_ret2)) /* ?{} */);702 ((void)(_tmp_cp_ret 2) /* ^?{} */);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) /* ^?{} */); 703 703 return _X12_retval_maini_1; 704 704 } -
tests/.expect/extension.x64.txt
r2b10f95 r86fb8f2 186 186 __extension__ signed int _X1ci_2; 187 187 ((void)(__extension__ _X1ai_2=(__extension__ _X1bi_2+__extension__ _X1ci_2))); 188 signed int _tmp_cp_ret 2;189 ((void)(((void)(_tmp_cp_ret 2=__extension__ _X4fredFi_i__1(3))) , _tmp_cp_ret2));190 ((void)(_tmp_cp_ret 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) /* ^?{} */); 191 191 __extension__ signed int _X4maryFi_i__2(signed int _X1pi_2){ 192 192 __attribute__ ((unused)) signed int _X12_retval_maryi_2; -
tests/.expect/gccExtensions.x64.txt
r2b10f95 r86fb8f2 171 171 signed int main(signed int _X4argci_1, char **_X4argvPPc_1, char **_X4envpPPc_1){ 172 172 __attribute__ ((unused)) signed int _X12_retval_maini_1; 173 signed int _tmp_cp_ret 2;174 ((void)(_X12_retval_maini_1=(((void)(_tmp_cp_ret 2=invoke_main(_X4argci_1, _X4argvPPc_1, _X4envpPPc_1))) , _tmp_cp_ret2)) /* ?{} */);175 ((void)(_tmp_cp_ret 2) /* ^?{} */);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) /* ^?{} */); 176 176 return _X12_retval_maini_1; 177 177 } -
tests/.expect/math1.txt
r2b10f95 r86fb8f2 10 10 expm1:1.71828 1.71828182845905 1.71828182845904524 11 11 pow:1 1 1 0.273957+0.583701i 0.273957253830121+0.583700758758615i -0.638110484918098871+0.705394566961838155i 12 \ 16 256 13 \ 912673 256 64 -64 0.015625 -0.015625 18.3791736799526 0.264715-1.1922i 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 -
tests/coroutine/pingpong.cfa
r2b10f95 r86fb8f2 10 10 // Created On : Wed Sep 20 11:55:23 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 22 13:37:52201913 // Update Count : 3 012 // Last Modified On : Tue Mar 26 17:54:14 2019 13 // Update Count : 35 14 14 // 15 15 … … 20 20 const char * name; 21 21 /* const */ unsigned int N; 22 PingPong *part;22 PingPong & part; 23 23 }; 24 24 25 25 void ?{}( PingPong & this, const char * name, unsigned int N, PingPong & part ) { 26 (this.__cor){name}; 27 this.name = name; 28 this.N = N; 29 this.part = ∂ 26 this.[name, N] = [name, N]; &this.part = ∂ 30 27 } 31 28 void ?{}( PingPong & this, const char * name, unsigned int N ) { 32 this{ name, N, * (PingPong *)0 };29 this{ name, N, *0p }; // call first constructor 33 30 } 34 31 void cycle( PingPong & pingpong ) { … … 36 33 } 37 34 void partner( PingPong & this, PingPong & part ) { 38 this.part = ∂35 &this.part = ∂ 39 36 resume( this ); 40 37 } 41 void main( PingPong & pingpong ) {// ping's starter ::main, pong's starter ping42 for ( pingpong.N ) {// N ping-pongs43 sout | pingpong.name;44 cycle( *pingpong.part );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 ); 45 42 } // for 46 43 } -
tests/math1.cfa
r2b10f95 r86fb8f2 10 10 // Created On : Fri Apr 22 14:59:21 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Dec 12 16:28:49 201813 // Update Count : 8912 // Last Modified On : Mon Mar 25 22:56:47 2019 13 // Update Count : 109 14 14 // 15 15 … … 49 49 unsigned int e = 2; 50 50 b \= e; 51 sout | "\\" | b | b \ e; 52 sout | "\\" | 'a' \ 3u | 2 \ 8u | 4 \ 3u | -4 \ 3u | nonl; 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); 53 54 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; 54 66 } // main 55 67 -
tests/rational.cfa
r2b10f95 r86fb8f2 10 10 // Created On : Mon Mar 28 08:43:12 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Mar 19 08:30:28201913 // Update Count : 7312 // Last Modified On : Wed Mar 27 07:37:17 2019 13 // Update Count : 80 14 14 // 15 15 … … 54 54 sout | a * b; 55 55 sout | a / b; 56 // sout | a \ 2 | b \ 2; // FIX ME 57 // sout | a \ -2 | b \ -2; 56 58 57 59 sout | "conversion";
Note: See TracChangeset
for help on using the changeset viewer.