Changes in / [86fb8f2:2b10f95]
- Files:
-
- 2 deleted
- 18 edited
-
doc/papers/concurrency/Paper.tex (modified) (2 diffs)
-
doc/papers/concurrency/examples/Fib2.cfa (deleted)
-
doc/papers/concurrency/examples/Pingpong.cfa (modified) (3 diffs)
-
doc/papers/concurrency/examples/Pingpong.py (modified) (1 diff)
-
doc/papers/concurrency/examples/ProdCons.cfa (modified) (1 diff)
-
doc/papers/concurrency/examples/ProdCons.cpp (modified) (10 diffs)
-
doc/papers/concurrency/examples/ProdCons.py (deleted)
-
doc/user/user.tex (modified) (3 diffs)
-
libcfa/prelude/builtins.c (modified) (4 diffs)
-
libcfa/src/rational.cfa (modified) (8 diffs)
-
libcfa/src/rational.hfa (modified) (2 diffs)
-
tests/.expect/KRfunctions.x64.txt (modified) (1 diff)
-
tests/.expect/completeTypeError.txt (modified) (1 diff)
-
tests/.expect/declarationSpecifier.x64.txt (modified) (1 diff)
-
tests/.expect/extension.x64.txt (modified) (1 diff)
-
tests/.expect/gccExtensions.x64.txt (modified) (1 diff)
-
tests/.expect/math1.txt (modified) (1 diff)
-
tests/coroutine/pingpong.cfa (modified) (3 diffs)
-
tests/math1.cfa (modified) (2 diffs)
-
tests/rational.cfa (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/papers/concurrency/Paper.tex
r86fb8f2 r2b10f95 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 variables659 % int fib() {660 % int fn;661 % `switch ( state )` { // explicit execution state662 % 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}676 656 \begin{lrbox}{\myboxA} 677 657 \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 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} 676 677 \newbox\myboxB 678 \begin{lrbox}{\myboxB} 679 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 680 #define FIB_INIT `{ 0, 1 }` 681 typedef struct { int fn2, fn1; } Fib; 680 682 int fib( Fib * f ) { 681 683 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 685 688 return ret; 686 689 } 687 688 689 690 690 int main() { 691 691 Fib f1 = FIB_INIT, f2 = FIB_INIT; 692 692 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 ) ); 695 694 } 696 695 } … … 698 697 \end{lrbox} 699 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; } 718 int main() { 719 Fib f1, f2; 720 for ( 10 ) 721 sout | next( f1 ) | next( f2 ); 722 } 723 \end{cfa} 724 \end{lrbox} 700 725 \newbox\myboxB 701 726 \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\myboxC726 \begin{lrbox}{\myboxC}727 727 \begin{python}[aboveskip=0pt,belowskip=0pt] 728 728 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() 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() 742 738 for i in range( 10 ): 743 print( next( f1 ), next( f2 ) ) 744 745 739 print( `next( f1 )`, `next( f2 )` ) # resume 746 740 747 741 \end{python} 748 742 \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} 805 748 \end{figure} 806 749 -
doc/papers/concurrency/examples/Pingpong.cfa
r86fb8f2 r2b10f95 4 4 coroutine PingPong { 5 5 const char * name; 6 unsigned int N;7 PingPong ∂6 /* const */ 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.[name, N] = [name, N]; &this.part = ∂ 11 (this.__cor){name}; 12 this.name = name; 13 this.N = N; 14 this.part = ∂ 12 15 } 13 16 void ?{}( PingPong & this, const char * name, unsigned int N ) { 14 this{ name, N, * 0p }; // call first constructor17 this{ name, N, *(PingPong *)0 }; 15 18 } 16 19 void cycle( PingPong & pingpong ) { … … 18 21 } 19 22 void partner( PingPong & this, PingPong & part ) { 20 &this.part = ∂23 this.part = ∂ 21 24 resume( this ); 22 25 } 23 void main( PingPong & pingpong ) with(pingpong) {// ping's starter ::main, pong's starter ping24 for ( N ) {// N ping-pongs25 sout | name;26 cycle( part );26 void 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 ); 27 30 } // for 28 31 } 29 32 int main() { 30 enum { N = 5};33 enum { N = 20 }; 31 34 PingPong ping = { "ping", N }, pong = { "pong", N, ping }; 32 35 partner( ping, pong ); … … 35 38 // Local Variables: // 36 39 // tab-width: 4 // 37 // compile-command: "cfa Pingpong.cfa" //40 // compile-command: "cfa pingpong.cfa" // 38 41 // 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 ) 1 def Scheduler 2 try: 3 yield from ping(); 4 yield from pong(); 5 except StopIteration: 6 print( "Scheduler stop" ) 8 7 9 def Scheduler():10 n = (yield) # starting coroutine11 while True:12 n = next( n ) # schedule coroutine13 8 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 9 def pong(): 10 print( "pong" ) 11 for i in range( 10 ): 20 12 21 s = Scheduler(); 22 next( s ) # prime 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() 23 25 try: 24 s.send( pi ) # start cycle26 next( p ) 25 27 except StopIteration: 26 print( "scheduler stop" ) 27 print( "stop" ) 28 print( "stop" ) 28 29 29 30 # Local Variables: # 30 31 # tab-width: 4 # 31 # compile-command: "python3.5 Pingpong.py" #32 # compile-command: "python3.5 pingpong.py" # 32 33 # End: # -
doc/papers/concurrency/examples/ProdCons.cfa
r86fb8f2 r2b10f95 23 23 sout | "prod stops"; 24 24 } 25 int payment( Prod & prod, int m ) with(prod) {26 money = m;25 int payment( Prod & prod, int money ) { 26 prod.money = money; 27 27 resume( prod ); // main 1st time, then 28 return receipt;// prod in delivery28 return prod.receipt; // prod in delivery 29 29 } 30 30 void start( Prod & prod, int N, Cons &c ) { -
doc/papers/concurrency/examples/ProdCons.cpp
r86fb8f2 r2b10f95 12 12 struct Cons; 13 13 14 struct resumable { 15 virtual resumable * resume() = 0; 16 }; 17 18 struct Prod : public resumable { 14 struct Prod { 19 15 struct local { 20 16 Cons * c; … … 24 20 struct promise_type { 25 21 local _l; 26 resumable * next;27 22 28 23 Prod get_return_object() { … … 74 69 static Prod main(); 75 70 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 } 79 81 80 82 auto start(int N, Cons & c) { … … 82 84 _coroutine.promise()._l.N = N; 83 85 _coroutine.promise()._l.receipt = 0; 84 }85 86 virtual resumable * resume() override final {87 86 _coroutine.resume(); 88 return _coroutine.promise().next;89 87 } 90 88 }; 91 89 92 struct Cons : public resumable{90 struct Cons { 93 91 struct local { 94 92 Prod * p; … … 99 97 struct promise_type { 100 98 local _l; 101 resumable * next;102 99 103 100 Cons get_return_object() { … … 157 154 struct ret { 158 155 int _status; 159 Cons * c;160 156 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<>) {} 164 158 int await_resume() { return _status; } 165 159 }; 166 return ret{ _coroutine.promise()._l.status , this};160 return ret{ _coroutine.promise()._l.status }; 167 161 } 168 162 … … 170 164 _coroutine.promise()._l.done = true; 171 165 struct ret { 172 Cons * c;173 Prod::promise_type * _promise;174 166 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() {} 182 169 }; 183 return ret{this, nullptr}; 184 } 185 186 virtual resumable * resume() override final { 187 _coroutine.resume(); 188 return _coroutine.promise().next; 170 return ret{}; 189 171 } 190 172 }; 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 }206 173 207 174 Prod Prod::main() { … … 209 176 for(int i = 0; i < p.N; i++) { 210 177 int p1 = random(100), p2 = random(100); 211 std::cout << p1 << " " << p2 << std::endl;178 std::cout << p1 << " " << p2; 212 179 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; 214 181 p.receipt += 1; 215 182 } 216 183 co_await p.c->stop(); 217 std::cout << "prod stops" << std::endl;184 std::cout << "prod stops"; 218 185 } 219 186 … … 222 189 int money = 1, receipt; 223 190 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; 226 192 c.status += 1; 227 193 receipt = co_await c.p->payment( money ); 228 std::cout << " # " << receipt << std::endl;194 std::cout << " #" << receipt; 229 195 money += 1; 230 196 } 231 std::cout << "cons stops" << std::endl; 232 } 233 234 void dispatch(resumable * r) { 235 while((r = r->resume())); 197 std::cout << "const stops"; 236 198 } 237 199 … … 241 203 srandom( getpid() ); 242 204 prod.start(5, cons); 243 dispatch(&prod); 244 } 205 } -
doc/user/user.tex
r86fb8f2 r2b10f95 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Tue Mar 26 22:10:49 201914 %% Update Count : 34 1113 %% Last Modified On : Tue Dec 11 23:19:26 2018 14 %% Update Count : 3400 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 Integral exponentiation\index{exponentiation!unsigned integral} is performed with repeated multiplication\footnote{The multiplication computation is $O(\log y)$.} (or shifting if the exponentis 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.1922i510 Unsigned 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). 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.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 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, ©*©. 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. 527 522 528 523 … … 1325 1320 \end{cfa} 1326 1321 Essentially, 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} 1322 While attempting to make the two contexts consistent is a laudable goal, it has not worked out in practice. 1331 1323 1332 1324 \CFA provides its own type, variable and routine declarations, using a different syntax. -
libcfa/prelude/builtins.c
r86fb8f2 r2b10f95 10 10 // Created On : Fri Jul 21 16:21:03 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Mar 26 23:10:36201913 // Update Count : 9512 // Last Modified On : Sun Mar 10 10:52:50 2019 13 // Update Count : 31 14 14 // 15 15 … … 18 18 typedef unsigned long long __cfaabi_abi_exception_type_t; 19 19 20 #include <limits.h> // CHAR_BIT21 20 #include "../src/virtual.h" 22 21 #include "../src/exception.h" … … 27 26 // increment/decrement unification 28 27 29 static inline { 30 forall( dtype DT | { DT & ?+=?( DT &, one_t ); } ) 31 DT & ++?( DT & x ) { return x += 1; } 28 static inline forall( dtype T | { T & ?+=?( T &, one_t ); } ) 29 T & ++? ( T & x ) { return x += 1; } 32 30 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; }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; } 35 33 36 forall( dtype DT | { DT & ?-=?( DT &, one_t ); } )37 DT & --?( DT & x ) { return x -= 1; }34 static inline forall( dtype T | { T & ?-=?( T &, one_t ); } ) 35 T & --? ( T & x ) { return x -= 1; } 38 36 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 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; } 42 39 43 40 // 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 42 static inline forall( dtype T ) T * intptr( uintptr_t addr ) { return (T *)addr; } 46 43 47 44 // exponentiation operator implementation … … 56 53 } // extern "C" 57 54 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 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 ); } 66 61 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 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 } // ?\? 70 72 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 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 } // ?\? 82 83 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 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 } // ?\? 90 95 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__() 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 } // ?\? 97 100 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. 102 105 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 // } // ?\? 106 111 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 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; } 113 116 114 117 // Local Variables: // -
libcfa/src/rational.cfa
r86fb8f2 r2b10f95 10 10 // Created On : Wed Apr 6 17:54:28 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 27 08:45:59 201913 // Update Count : 1 8012 // Last Modified On : Sun Dec 23 22:56:49 2018 13 // Update Count : 170 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, denominator] = [n / t, d / t]; 56 r.numerator = n / t; 57 r.denominator = d / t; 57 58 } // rational 58 59 … … 77 78 RationalImpl prev = r.numerator; 78 79 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; 80 82 return prev; 81 83 } // numerator … … 84 86 RationalImpl prev = r.denominator; 85 87 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; 87 90 return prev; 88 91 } // denominator … … 117 120 118 121 Rational(RationalImpl) +?( Rational(RationalImpl) r ) { 119 return (Rational(RationalImpl)){ r.numerator, r.denominator }; 122 Rational(RationalImpl) t = { r.numerator, r.denominator }; 123 return t; 120 124 } // +? 121 125 122 126 Rational(RationalImpl) -?( Rational(RationalImpl) r ) { 123 return (Rational(RationalImpl)){ -r.numerator, r.denominator }; 127 Rational(RationalImpl) t = { -r.numerator, r.denominator }; 128 return t; 124 129 } // -? 125 130 126 131 Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 127 132 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; 129 135 } 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; 131 138 } // if 132 139 } // ?+? … … 134 141 Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 135 142 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; 137 145 } 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; 139 148 } // if 140 149 } // ?-? 141 150 142 151 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; 144 154 } // ?*? 145 155 146 156 Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 147 157 if ( r.numerator < (RationalImpl){0} ) { 148 r.[numerator, denominator] = [-r.numerator, -r.denominator]; 158 r.numerator = -r.numerator; 159 r.denominator = -r.denominator; 149 160 } // 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; 151 163 } // ?/? 152 164 … … 155 167 forall( dtype istype | istream( istype ) | { istype & ?|?( istype &, RationalImpl & ); } ) 156 168 istype & ?|?( istype & is, Rational(RationalImpl) & r ) { 169 RationalImpl t; 157 170 is | r.numerator | r.denominator; 158 RationalImplt = simplify( r.numerator, r.denominator );171 t = simplify( r.numerator, r.denominator ); 159 172 r.numerator /= t; 160 173 r.denominator /= t; … … 172 185 } // distribution 173 186 } // 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 } // if182 }183 187 184 188 // conversion -
libcfa/src/rational.hfa
r86fb8f2 r2b10f95 12 12 // Created On : Wed Apr 6 17:56:25 2016 13 13 // Last Modified By : Peter A. Buhr 14 // Last Modified On : Tue Mar 26 23:16:10 201915 // Update Count : 10 914 // Last Modified On : Tue Dec 4 23:07:46 2018 15 // Update Count : 106 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 103 100 // conversion 104 101 forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } ) -
tests/.expect/KRfunctions.x64.txt
r86fb8f2 r2b10f95 82 82 signed int _X1ai_2; 83 83 signed int _X1bi_2; 84 signed int *(*_tmp_cp_ret 4)(signed int _X1xi_1, signed int _X1yi_1);85 ((void)(_X1xFPi_ii__2=(((void)(_tmp_cp_ret 4=_X3f10FFPi_ii__iPiPid__1(3, (&_X1ai_2), (&_X1bi_2), 3.5))) , _tmp_cp_ret4)));86 ((void)(_tmp_cp_ret 4) /* ^?{} */);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) /* ^?{} */); 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
r86fb8f2 r2b10f95 87 87 void 88 88 ) 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) 90 90 91 91 -
tests/.expect/declarationSpecifier.x64.txt
r86fb8f2 r2b10f95 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 4;701 ((void)(_X12_retval_maini_1=(((void)(_tmp_cp_ret 4=invoke_main(_X4argci_1, _X4argvPPc_1, _X4envpPPc_1))) , _tmp_cp_ret4)) /* ?{} */);702 ((void)(_tmp_cp_ret 4) /* ^?{} */);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) /* ^?{} */); 703 703 return _X12_retval_maini_1; 704 704 } -
tests/.expect/extension.x64.txt
r86fb8f2 r2b10f95 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 4;189 ((void)(((void)(_tmp_cp_ret 4=__extension__ _X4fredFi_i__1(3))) , _tmp_cp_ret4));190 ((void)(_tmp_cp_ret 4) /* ^?{} */);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) /* ^?{} */); 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
r86fb8f2 r2b10f95 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 4;174 ((void)(_X12_retval_maini_1=(((void)(_tmp_cp_ret 4=invoke_main(_X4argci_1, _X4argvPPc_1, _X4envpPPc_1))) , _tmp_cp_ret4)) /* ?{} */);175 ((void)(_tmp_cp_ret 4) /* ^?{} */);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) /* ^?{} */); 176 176 return _X12_retval_maini_1; 177 177 } -
tests/.expect/math1.txt
r86fb8f2 r2b10f95 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 \ 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 10 10 // Created On : Wed Sep 20 11:55:23 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Mar 26 17:54:14201913 // Update Count : 3 512 // Last Modified On : Fri Mar 22 13:37:52 2019 13 // Update Count : 30 14 14 // 15 15 … … 20 20 const char * name; 21 21 /* const */ unsigned int N; 22 PingPong ∂22 PingPong * part; 23 23 }; 24 24 25 25 void ?{}( PingPong & this, const char * name, unsigned int N, PingPong & part ) { 26 this.[name, N] = [name, N]; &this.part = ∂ 26 (this.__cor){name}; 27 this.name = name; 28 this.N = N; 29 this.part = ∂ 27 30 } 28 31 void ?{}( PingPong & this, const char * name, unsigned int N ) { 29 this{ name, N, * 0p }; // call first constructor32 this{ name, N, *(PingPong *)0 }; 30 33 } 31 34 void cycle( PingPong & pingpong ) { … … 33 36 } 34 37 void partner( PingPong & this, PingPong & part ) { 35 &this.part = ∂38 this.part = ∂ 36 39 resume( this ); 37 40 } 38 void main( PingPong & pingpong ) with(pingpong) {// ping's starter ::main, pong's starter ping39 for ( N ) {// N ping-pongs40 sout | name;41 cycle( part );41 void 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 ); 42 45 } // for 43 46 } -
tests/math1.cfa
r86fb8f2 r2b10f95 10 10 // Created On : Fri Apr 22 14:59:21 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Mar 25 22:56:47 201913 // Update Count : 10912 // Last Modified On : Wed Dec 12 16:28:49 2018 13 // Update Count : 89 14 14 // 15 15 … … 49 49 unsigned int e = 2; 50 50 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; 54 53 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;66 54 } // main 67 55 -
tests/rational.cfa
r86fb8f2 r2b10f95 10 10 // Created On : Mon Mar 28 08:43:12 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 27 07:37:17201913 // Update Count : 8012 // Last Modified On : Tue Mar 19 08:30:28 2019 13 // Update Count : 73 14 14 // 15 15 … … 54 54 sout | a * b; 55 55 sout | a / b; 56 // sout | a \ 2 | b \ 2; // FIX ME57 // sout | a \ -2 | b \ -2;58 56 59 57 sout | "conversion";
Note:
See TracChangeset
for help on using the changeset viewer.