Changeset 8c3a0336
- Timestamp:
- Apr 23, 2019, 10:26:14 AM (4 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:
- ffe2fad
- Parents:
- deca0f5 (diff), 8f194ee (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:
-
- 3 added
- 28 edited
Legend:
- Unmodified
- Added
- Removed
-
benchmark/Makefile.am
rdeca0f5 r8c3a0336 21 21 include $(top_srcdir)/src/cfa.make 22 22 23 AM_CFLAGS = -O2 -Wall - I$(srcdir) -lrt -pthread24 AM_CFAFLAGS = -quiet - in-tree -nodebug -std=c++1425 AM_UPPFLAGS = -quiet -nodebug -multi 23 AM_CFLAGS = -O2 -Wall -Wextra -Werror -I$(srcdir) -lrt -pthread 24 AM_CFAFLAGS = -quiet -nodebug -in-tree 25 AM_UPPFLAGS = -quiet -nodebug -multi -std=c++14 26 26 27 27 BENCH_V_CC = $(__bench_v_CC_$(__quiet)) -
benchmark/Makefile.in
rdeca0f5 r8c3a0336 371 371 372 372 # applies to both programs 373 AM_CFLAGS = -O2 -Wall - I$(srcdir) -lrt -pthread374 AM_CFAFLAGS = -quiet - in-tree -nodebug -std=c++14375 AM_UPPFLAGS = -quiet -nodebug -multi 373 AM_CFLAGS = -O2 -Wall -Wextra -Werror -I$(srcdir) -lrt -pthread 374 AM_CFAFLAGS = -quiet -nodebug -in-tree 375 AM_UPPFLAGS = -quiet -nodebug -multi -std=c++14 376 376 BENCH_V_CC = $(__bench_v_CC_$(__quiet)) 377 377 BENCH_V_CFA = $(__bench_v_CFA_$(__quiet)) -
doc/proposals/vtable.md
rdeca0f5 r8c3a0336 11 11 should be able to store anything that goes into a trait. 12 12 13 I also include notes on a sample implementation, which primarly exists to show 14 there is a resonable implementation. The code samples for that are in a slight 15 psudo-code to help avoid name mangling and keeps some CFA features while they 16 would actually be writen in C. 17 13 18 Trait Instances 14 19 --------------- … … 42 47 before. 43 48 44 Internally a trait object is a pair of pointers. One to an underlying object 45 and the other to the vtable. All calls on an trait are implemented by looking 46 up the matching function pointer and passing the underlying object and the 47 remaining arguments to it. 48 49 Trait objects can be moved by moving the pointers. Almost all other operations 50 require some functions to be implemented on the underlying type. Depending on 51 what is in the virtual table a trait type could be a dtype or otype. 49 For traits to be used this way they should meet two requirements. First they 50 should only have a single polymorphic type and each assertion should use that 51 type once as a parameter. Extentions may later loosen these requirements. 52 53 If a trait object is used it should generate a series of implicate functions 54 each of which implements one of the functions required by the trait. So for 55 combiner there is an implicate: 56 57 void combine(trait combiner & this, int); 58 59 This function is the one actually called at the end 60 61 The main use case for trait objects is that they can be stored. They can be 62 passed into functions, but using the trait directly is prefred in this case. 63 64 trait drawable(otype T) { 65 void draw(Surface & to, T & draw); 66 Rect(int) drawArea(T & draw); 67 }; 68 69 struct UpdatingSurface { 70 Surface * surface; 71 vector(trait drawable) drawables; 72 }; 73 74 void updateSurface(UpdatingSurface & us) { 75 for (size_t i = 0 ; i < us.drawables.size ; ++i) { 76 draw(us.surface, us.drawables[i]); 77 } 78 } 79 80 Currently these traits are limited to 1 trait parameter and functions should 81 have exactly 1 parameter. We cannot abstract away pairs of types and still 82 pass them into normal functions, which take them seperately. 83 84 The second is required the because we need to get the vtable from somewhere. 85 If there are 0 trait objects than no vtable is avalible, if we have more than 86 1 than the vtables give conflicting answers on what underlying function to 87 call. And even then the underlying type assumes a concrete type. 88 89 This loop can sort of be broken by using the trait object directly in the 90 signature. This has well defined meaning, but might not be useful. 91 92 trait example(otype T) { 93 bool test(T & this, trait example & that); 94 } 95 96 #### Sample Implementation 97 A simple way to implement trait objects is by a pair of pointers. One to the 98 underlying object and one to the vtable. 99 100 struct vtable_drawable { 101 void (*draw)(Surface &, void *); 102 Rect(int) (*drawArea)(void *); 103 }; 104 105 struct drawable { 106 void * object; 107 vtable_drawable * vtable; 108 }; 109 110 The functions that run on the trait object would generally be generated using 111 the following pattern: 112 113 void draw(Surface & surface, drawable & traitObj) { 114 return traitObj.vtable->draw(surface, traitObj.object); 115 } 116 117 There may have to be special cases for things like copy construction, that 118 might require a more sigificant wrapper. On the other hand moving could be 119 implemented by moving the pointers without any need to refer to the base 120 object. 121 122 ### Extention: Multiple Trait Parameters 123 Currently, this gives traits two independent uses. They use the same syntax, 124 except for limits boxable traits have, and yet don't really mix. The most 125 natural way to do this is to allow trait instances to pick one parameter 126 that they are generic over, the others they choose types to implement. 127 128 The two ways to do the selection, the first is do it at the trait definition. 129 Each trait picks out a single parameter which it can box (here the `virtual` 130 qualifier). When you create an instance of a trait object you provide 131 arguments like for a generic structure, but skip over the marked parameter. 132 133 trait combiner(virtual otype T, otype Combined) { 134 void combine(T &, Combined &); 135 } 136 137 trait combiner(int) int_combiner; 138 139 The second is to do it at the instaniation point. A placeholder (here the 140 keyword `virtual`) is used to explicately skip over the parameter that will be 141 abstracted away, with the same rules as above if it was the marked parameter. 142 143 trait combiner(otype T, otype Combined) { 144 void combine(T &, Combined &); 145 }; 146 147 trait combiner(virtual, int) int_combiner; 148 149 Using both (first to set the default, second as a local override) would also 150 work, although might be exessively complicated. 151 152 This is useful in cases where you want to use a generic type, but leave part 153 of it open and store partially generic result. As a simple example 154 155 trait folder(otype T, otype In, otype Out) { 156 void fold(T & this, In); 157 Out fold_result(T & this); 158 } 159 160 Which allows you to fold values without putting them in a container. If they 161 are already in a container this is exessive, but if they are generated over 162 time this gives you a simple interface. This could for instance be used in 163 a profile, where T changes for each profiling statistic and you can plug in 164 multiple profilers for any run by adding them to an array. 52 165 53 166 Hierarchy … … 90 203 the pointer to it. 91 204 205 Exception Example: 206 (Also I'm not sure where I got these casing rules.) 207 208 trait exception(otype T) virtual() { 209 char const * what(T & this); 210 } 211 212 trait io_error(otype T) virtual(exception) { 213 FILE * which_file(T & this); 214 } 215 216 struct eof_error(otype T) virtual(io_error) { 217 FILE * file; 218 } 219 220 char const * what(eof_error &) { 221 return "Tried to read from an empty file."; 222 } 223 224 FILE * which_file(eof_error & this) { 225 return eof_error.file; 226 } 227 228 Ast Example: 229 230 trait ast_node(otype T) virtual() { 231 void print(T & this, ostream & out); 232 void visit(T & this, Visitor & visitor); 233 CodeLocation const & get_code_location(T & this); 234 } 235 236 trait expression_node(otype T) virtual(ast_node) { 237 Type eval_type(T const & this); 238 } 239 240 struct operator_expression virtual(expression_node) { 241 enum operator_kind kind; 242 trait expression_node rands[2]; 243 } 244 245 trait statement_node(otype T) virtual(ast_node) { 246 vector(Label) & get_labels(T & this); 247 } 248 249 struct goto_statement virtual(statement_node) { 250 vector(Label) labels; 251 Label target; 252 } 253 254 trait declaration_node(otype T) virtual(ast_node) { 255 string name_of(T const & this); 256 Type type_of(T const & this); 257 } 258 259 struct using_declaration virtual(declaration_node) { 260 string new_type; 261 Type old_type; 262 } 263 264 struct variable_declaration virtual(declaration_node) { 265 string name; 266 Type type; 267 } 268 269 #### Sample Implementation 270 The type id may be as little as: 271 272 struct typeid { 273 struct typeid const * const parent; 274 }; 275 276 Some linker magic would have to be used to ensure exactly one copy of each 277 structure for each type exists in memory. There seem to be spectial once 278 sections that support this and it should be easier than generating unique 279 ids across compilation units. 280 281 The structure could be extended to contain any additional type information. 282 283 There are two general designs for vtables with type ids. The first is to put 284 the type id at the top of the vtable, this is the most compact and efficient 285 solution but only works if we have exactly 1 vtable for each type. The second 286 is to put a pointer to the type id in each vtable. This has more overhead but 287 allows multiple vtables. 288 289 struct <trait>_vtable { 290 struct typeid const id; 291 292 // Trait dependent list of vtable members. 293 }; 294 295 struct <trait>_vtable { 296 struct typeid const * const id; 297 298 // Trait dependent list of vtable members. 299 }; 300 301 ### Virtual Casts 302 To convert from a pointer to a type higher on the hierarchy to one lower on 303 the hierarchy a check is used to make sure that the underlying type is also 304 of that lower type. 305 306 The proposed syntax for this is: 307 308 trait SubType * new_value = (virtual trait SubType *)super_type; 309 310 It will return the same pointer if it does point to the subtype and null if 311 it does not, doing the check and conversion in one operation. 312 92 313 ### Inline vtables 93 314 Since the structures here are usually made to be turned into trait objects 94 315 it might be worth it to have fields on them to store the virtual table 95 pointer. This would have to be declared on the trait as an assertion, but if 96 it is the trait object could be a single pointer. 97 98 It is trivial to do if the field with the virtual table pointer is fixed. 99 Otherwise some trickery with pointing to the field and storing the offset in 100 the virtual table to recover the main object would have to be used. 316 pointer. This would have to be declared on the trait as an assertion (example: 317 `vtable;` or `T.vtable;`), but if it is the trait object could be a single 318 pointer. 319 320 There are also three options for where the pointer to the vtable. It could be 321 anywhere, a fixed location for each trait or always at the front. For the per- 322 trait solution an extention to specify what it is (example `vtable[0];`) which 323 could also be used to combine it with others. So these options can be combined 324 to allow access to all three options. 101 325 102 326 ### Virtual Tables as Types 103 Here we consider encoding plus the implementation of functions on it . Which104 is to say in the type hierarchy structures aren't concrete types anymore, 105 instead they are parent types to vtables, which combine the encoding and 106 implementation.327 Here we consider encoding plus the implementation of functions on it to be a 328 type. Which is to say in the type hierarchy structures aren't concrete types 329 anymore, instead they are parent types to vtables, which combine the encoding 330 and implementation. 107 331 108 332 Resolution Scope … … 123 347 other. 124 348 125 Some syntax would have to be added. All resolutions can be found at compile 126 time and a single vtable created for each type at compilation time. 349 Some syntax would have to be added to specify the resolution point. To ensure 350 a single instance there may have to be two variants, one forward declaration 351 and one to create the instance. With some compiler magic the forward 352 declaration maybe enough. 353 354 extern trait combiner(struct summation) vtable; 355 trait combiner(struct summation) vtable; 356 357 Or (with the same variants): 358 359 vtable combiner(struct summation); 360 361 The extern variant promises that the vtable will exist while the normal one 362 is where the resolution actually happens. 127 363 128 364 ### Explicit Resolution Points: … … 141 377 vtable. 142 378 379 extern trait combiner(struct summation) vtable sum; 380 trait combiner(struct summation) vtable sum; 381 382 extern trait combiner(struct summation) vtable sum default; 383 trait combiner(struct summation) vtable sum default; 384 385 The extern difference is the same before. The name (sum in the samples) is 386 used at the binding site to say which one is picked. The default keyword can 387 be used in only some of the declarations. 388 389 trait combiner fee = (summation_instance, sum); 390 trait combiner foe = summation_instance; 391 392 (I am not really happy about this syntax, but it kind of works.) 393 The object being bound is required. The name of the vtable is optional if 394 there is exactly one vtable name marked with default. 395 396 These could also be placed inside functions. In which case both the name and 397 the default keyword might be optional. If the name is ommited in an assignment 398 the closest vtable is choosen (returning to the global default rule if no 399 approprate local vtable is in scope). 400 143 401 ### Site Based Resolution: 144 402 Every place in code where the binding of a vtable to an object occurs has -
doc/user/user.tex
rdeca0f5 r8c3a0336 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:49201914 %% Update Count : 34 1113 %% Last Modified On : Sun Apr 14 11:02:34 2019 14 %% Update Count : 3443 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 514 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 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 \end{cfa} 516 1 1 256 -64 125 ®0® 3273344365508751233 ®0® ®0® -0.015625 18.3791736799526 0.264715-1.1922i 517 \end{cfa} 518 Note, ©5 ®\® 32© and ©5L ®\® 64© overflow, and ©-4 ®\® -3© is a fraction but stored in an integer so all three computations generate an integral zero. 518 519 Parenthesis are necessary for complex constants or the expression is parsed as ©1.0f+®(®2.0fi \ 3.0f®)®+2.0fi©. 519 520 The exponentiation operator is available for all the basic types, but for user-defined types, only the integral-computation version is available. … … 524 525 OT ?®\®?( OT ep, unsigned long int y ); 525 526 \end{cfa} 526 The user type ©T© must define multiplication one, ©1©, and, ©*©.527 The user type ©T© must define multiplication, one, ©1©, and, ©*©. 527 528 528 529 … … 554 555 \subsection{Loop Control} 555 556 556 The ©for©/©while©/©do-while© loop-control allows empty or simplified ranges. 557 The ©for©/©while©/©do-while© loop-control allows empty or simplified ranges (see Figure~\ref{f:LoopControlExamples}). 558 \begin{itemize} 559 \item 557 560 An empty conditional implies ©1©. 558 The up-to range ©~©\index{~@©~©} means exclusive range [M,N); 559 the up-to range ©~=©\index{~=@©~=©} means inclusive range [M,N]. 560 The down-to range ©-~©\index{-~@©-~©} means exclusive range [N,M); 561 the down-to range ©-~=©\index{-~=@©-~=©} means inclusive range [N,M]. 561 \item 562 The up-to range ©~©\index{~@©~©} means exclusive range [M,N). 563 \item 564 The up-to range ©~=©\index{~=@©~=©} means inclusive range [M,N]. 565 \item 566 The down-to range ©-~©\index{-~@©-~©} means exclusive range [N,M). 567 \item 568 The down-to range ©-~=©\index{-~=@©-~=©} means inclusive range [N,M]. 569 \item 570 ©@© means put nothing in this field. 571 \item 562 572 ©0© is the implicit start value; 573 \item 563 574 ©1© is the implicit increment value. 575 \item 564 576 The up-to range uses ©+=© for increment; 565 the down-to range uses ©-=© for decrement. 577 \item 578 The down-to range uses ©-=© for decrement. 579 \item 566 580 The loop index is polymorphic in the type of the start value or comparison value when start is implicitly ©0©. 581 \end{itemize} 582 583 \begin{figure} 567 584 \begin{cquote} 568 \begin{tabular}{@{}l l|l@{}}569 \multicolumn{ 2}{c|}{loop control} & \multicolumn{1}{c}{output} \\585 \begin{tabular}{@{}l|l@{}} 586 \multicolumn{1}{c|}{loop control} & \multicolumn{1}{c}{output} \\ 570 587 \hline 571 588 \begin{cfa} 572 while ®()® { sout | "empty"; break; } 573 do { sout | "empty"; break; } while ®()®; 574 for ®()® { sout | "empty"; break; } 575 for ( ®0® ) { sout | "A"; } 576 for ( ®1® ) { sout | "A"; } 577 for ( ®10® ) { sout | "A"; } 578 for ( ®1 ~= 10 ~ 2® ) { sout | "B"; } 579 for ( ®10 -~= 1 ~ 2® ) { sout | "C"; } 580 for ( ®0.5 ~ 5.5® ) { sout | "D"; } 581 for ( ®5.5 -~ 0.5® ) { sout | "E"; } 582 for ( ®i; 10® ) { sout | i; } 583 for ( ®i; 1 ~= 10 ~ 2® ) { sout | i; } 584 for ( ®i; 10 -~= 1 ~ 2® ) { sout | i; } 585 for ( ®i; 0.5 ~ 5.5® ) { sout | i; } 586 for ( ®i; 5.5 -~ 0.5® ) { sout | i; } 587 for ( ®ui; 2u ~= 10u ~ 2u® ) { sout | ui; } 588 for ( ®ui; 10u -~= 2u ~ 2u® ) { sout | ui; } 589 sout | nlOff; 590 while ®()® { sout | "empty"; break; } sout | nl; 591 do { sout | "empty"; break; } while ®()®; sout | nl; 592 for ®()® { sout | "empty"; break; } sout | nl; 593 for ( ®0® ) { sout | "A"; } sout | "zero" | nl; 594 for ( ®1® ) { sout | "A"; } sout | nl; 595 for ( ®10® ) { sout | "A"; } sout | nl; 596 for ( ®1 ~= 10 ~ 2® ) { sout | "B"; } sout | nl; 597 for ( ®10 -~= 1 ~ 2® ) { sout | "C"; } sout | nl; 598 for ( ®0.5 ~ 5.5® ) { sout | "D"; } sout | nl; 599 for ( ®5.5 -~ 0.5® ) { sout | "E"; } sout | nl; 600 for ( ®i; 10® ) { sout | i; } sout | nl; 601 for ( ®i; 1 ~= 10 ~ 2® ) { sout | i; } sout | nl; 602 for ( ®i; 10 -~= 1 ~ 2® ) { sout | i; } sout | nl; 603 for ( ®i; 0.5 ~ 5.5® ) { sout | i; } sout | nl; 604 for ( ®i; 5.5 -~ 0.5® ) { sout | i; } sout | nl; 605 for ( ®ui; 2u ~= 10u ~ 2u® ) { sout | ui; } sout | nl; 606 for ( ®ui; 10u -~= 2u ~ 2u® ) { sout | ui; } sout | nl; 589 607 enum { N = 10 }; 590 for ( ®N® ) { sout | "N"; } 591 for ( ®i; N® ) { sout | i; } 592 for ( ®i; N -~ 0® ) { sout | i; } 608 for ( ®N® ) { sout | "N"; } sout | nl; 609 for ( ®i; N® ) { sout | i; } sout | nl; 610 for ( ®i; N -~ 0® ) { sout | i; } sout | nl; 593 611 const int start = 3, comp = 10, inc = 2; 594 for ( ®i; start ~ comp ~ inc + 1® ) { sout | i; } 612 for ( ®i; start ~ comp ~ inc + 1® ) { sout | i; } sout | nl; 613 for ( ®i; 1 ~ @® ) { if ( i > 10 ) break; 614 sout | i; } sout | nl; 615 for ( ®i; 10 -~ @® ) { if ( i < 0 ) break; 616 sout | i; } sout | nl; 617 for ( ®i; 2 ~ @ ~ 2® ) { if ( i > 10 ) break; 618 sout | i; } sout | nl; 619 for ( ®i; 2.1 ~ @ ~ @® ) { if ( i > 10.5 ) break; 620 sout | i; i += 1.7; } sout | nl; 621 for ( ®i; 10 -~ @ ~ 2® ) { if ( i < 0 ) break; 622 sout | i; } sout | nl; 623 for ( ®i; 12.1 ~ @ ~ @® ) { if ( i < 2.5 ) break; 624 sout | i; i -= 1.7; } sout | nl; 625 for ( ®i; 5 : j; -5 ~ @® ) { sout | i | j; } sout | nl; 626 for ( ®i; 5 : j; -5 -~ @® ) { sout | i | j; } sout | nl; 627 for ( ®i; 5 : j; -5 ~ @ ~ 2® ) { sout | i | j; } sout | nl; 628 for ( ®i; 5 : j; -5 -~ @ ~ 2® ) { sout | i | j; } sout | nl; 629 for ( ®j; -5 ~ @ : i; 5® ) { sout | i | j; } sout | nl; 630 for ( ®j; -5 -~ @ : i; 5® ) { sout | i | j; } sout | nl; 631 for ( ®j; -5 ~ @ ~ 2 : i; 5® ) { sout | i | j; } sout | nl; 632 for ( ®j; -5 -~ @ ~ 2 : i; 5® ) { sout | i | j; } sout | nl; 633 for ( ®j; -5 -~ @ ~ 2 : i; 5 : k; 1.5 ~ @® ) { 634 sout | i | j | k; } sout | nl; 635 for ( ®j; -5 -~ @ ~ 2 : k; 1.5 ~ @ : i; 5® ) { 636 sout | i | j | k; } sout | nl; 637 for ( ®k; 1.5 ~ @ : j; -5 -~ @ ~ 2 : i; 5® ) { 638 sout | i | j | k; } sout | nl; 595 639 \end{cfa} 596 640 & 597 641 \begin{cfa} 598 sout | nl; 599 sout | nl; 600 sout | nl; 601 sout | "zero" | nl; 602 sout | nl; 603 sout | nl; 604 sout | nl; 605 sout | nl; 606 sout | nl; 607 sout | nl; 608 sout | nl; 609 sout | nl; 610 sout | nl; 611 sout | nl; 612 sout | nl; 613 sout | nl; 614 sout | nl | nl; 615 616 sout | nl; 617 sout | nl; 618 sout | nl | nl; 619 620 sout | nl; 621 \end{cfa} 622 & 623 \begin{cfa} 642 624 643 empty 625 644 empty … … 645 664 646 665 3 6 9 666 667 1 2 3 4 5 6 7 8 9 10 668 669 10 9 8 7 6 5 4 3 2 1 0 670 671 2 4 6 8 10 672 673 2.1 3.8 5.5 7.2 8.9 674 675 10 8 6 4 2 0 676 677 12.1 10.4 8.7 7 5.3 3.6 678 0 -5 1 -4 2 -3 3 -2 4 -1 679 0 -5 1 -6 2 -7 3 -8 4 -9 680 0 -5 1 -3 2 -1 3 1 4 3 681 0 -5 1 -7 2 -9 3 -11 4 -13 682 0 -5 1 -4 2 -3 3 -2 4 -1 683 0 -5 1 -6 2 -7 3 -8 4 -9 684 0 -5 1 -3 2 -1 3 1 4 3 685 0 -5 1 -7 2 -9 3 -11 4 -13 686 687 0 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5 688 689 0 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5 690 691 0 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5 647 692 \end{cfa} 648 693 \end{tabular} 649 694 \end{cquote} 695 \caption{Loop Control Examples} 696 \label{f:LoopControlExamples} 697 \end{figure} 650 698 651 699 -
libcfa/prelude/prelude-gen.cc
rdeca0f5 r8c3a0336 10 10 // Created On : Sat Feb 16 08:44:58 2019 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Mar 19 08:19:35201913 // Update Count : 2812 // Last Modified On : Tue Apr 2 17:18:24 2019 13 // Update Count : 37 14 14 // 15 15 … … 118 118 { "?!=?", false, "signed int", Normal, "" }, 119 119 { "?=?", true, "", Normal, "" }, // void * LHS, zero_t RHS ??? 120 { "*?", false, "&", Normal, " | sized(DT)" }, // & ??? 120 // { "*?", false, "&", Normal, " | sized(DT)" }, // & ??? 121 { "*?", false, "&", Normal, "" }, // & ??? 121 122 122 123 { "?-?", false, "ptrdiff_t", Normal, " | sized(DT)" }, -
libcfa/src/fstream.cfa
rdeca0f5 r8c3a0336 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Mar 28 17:39:53 201913 // Update Count : 3 0712 // Last Modified On : Sat Apr 20 12:03:43 2019 13 // Update Count : 311 14 14 // 15 15 … … 33 33 os.nlOnOff = nlOnOff; 34 34 os.prt = prt; 35 os.sawNL = false; 35 36 sepSet( os, separator ); 36 37 sepSetCur( os, sepGet( os ) ); … … 162 163 void ?{}( ifstream & is, void * file ) { 163 164 is.file = file; 165 is.nlOnOff = false; 164 166 } 165 167 … … 173 175 open( is, name, "r" ); 174 176 } 177 178 void nlOn( ifstream & os ) { os.nlOnOff = true; } 179 void nlOff( ifstream & os ) { os.nlOnOff = false; } 180 bool getANL( ifstream & os ) { return os.nlOnOff; } 175 181 176 182 int fail( ifstream & is ) { -
libcfa/src/fstream.hfa
rdeca0f5 r8c3a0336 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Dec 24 18:33:41 201813 // Update Count : 1 4912 // Last Modified On : Sat Apr 20 12:03:58 2019 13 // Update Count : 151 14 14 // 15 15 … … 73 73 struct ifstream { 74 74 void * file; 75 bool nlOnOff; 75 76 }; // ifstream 76 77 77 78 // public 79 void nlOn( ifstream & ); 80 void nlOff( ifstream & ); 81 bool getANL( ifstream & ); 78 82 int fail( ifstream & is ); 79 83 int eof( ifstream & is ); -
libcfa/src/gmp.hfa
rdeca0f5 r8c3a0336 10 10 // Created On : Tue Apr 19 08:43:43 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Dec 4 23:25:51 201813 // Update Count : 2 212 // Last Modified On : Sat Apr 20 09:01:52 2019 13 // Update Count : 24 14 14 // 15 15 … … 271 271 272 272 void ?|?( ostype & os, Int mp ) { 273 (ostype)(os | mp); if ( getANL( os ) )nl( os );273 (ostype)(os | mp); nl( os ); 274 274 } // ?|? 275 275 } // distribution -
libcfa/src/iostream.cfa
rdeca0f5 r8c3a0336 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Mar 4 20:57:24201913 // Update Count : 59312 // Last Modified On : Sat Apr 20 14:02:43 2019 13 // Update Count : 617 14 14 // 15 15 … … 396 396 397 397 istype & ?|?( istype & is, char & c ) { 398 fmt( is, "%c", &c ); // must pass pointer through varg to fmt 398 char temp; 399 for () { 400 fmt( is, "%c", &temp ); // must pass pointer through varg to fmt 401 // do not overwrite parameter with newline unless appropriate 402 if ( temp != '\n' || getANL( is ) ) { c = temp; break; } 403 if ( eof( is ) ) break; 404 } // for 399 405 return is; 400 406 } // ?|? … … 498 504 return is; 499 505 } // nl 506 507 istype & nlOn( istype & is ) { 508 nlOn( is ); // call void returning 509 return is; 510 } // nlOn 511 512 istype & nlOff( istype & is ) { 513 nlOff( is ); // call void returning 514 return is; 515 } // nlOff 500 516 } // distribution 501 517 -
libcfa/src/iostream.hfa
rdeca0f5 r8c3a0336 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Feb 26 16:57:22201913 // Update Count : 22 112 // Last Modified On : Sat Apr 20 12:04:07 2019 13 // Update Count : 226 14 14 // 15 15 … … 149 149 150 150 trait istream( dtype istype ) { 151 void nlOn( istype & ); // read newline 152 void nlOff( istype & ); // scan newline 153 bool getANL( istype & ); // get scan newline (on/off) 151 154 int fail( istype & ); 152 155 int eof( istype & ); … … 187 190 188 191 // manipulators 192 istype & nlOn( istype & ); 193 istype & nlOff( istype & ); 189 194 istype & ?|?( istype &, istype & (*)( istype & ) ); 190 195 istype & nl( istype & is ); -
src/Parser/ParseNode.h
rdeca0f5 r8c3a0336 10 10 // Created On : Sat May 16 13:28:16 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Feb 13 17:36:49 201913 // Update Count : 8 6712 // Last Modified On : Mon Apr 15 14:22:39 2019 13 // Update Count : 874 14 14 // 15 15 … … 132 132 void printOneLine( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {} 133 133 134 Expression *get_expr() const { return expr.get(); }135 134 template<typename T> 136 135 bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); } 137 136 138 137 Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); } 138 139 std::unique_ptr<Expression> expr; // public because of lifetime implications 139 140 private: 140 141 bool extension = false; 141 std::unique_ptr<Expression> expr;142 142 }; // ExpressionNode 143 143 -
src/Parser/parser.yy
rdeca0f5 r8c3a0336 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 15 14:25:43201913 // Update Count : 42 4812 // Last Modified On : Mon Apr 15 15:02:56 2019 13 // Update Count : 4290 14 14 // 15 15 … … 185 185 186 186 ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 187 ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type-> get_expr());187 ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get()); 188 188 if ( constant && (constant->get_constant()->get_value() == "0" || constant->get_constant()->get_value() == "1") ) { 189 189 type = new ExpressionNode( new CastExpr( maybeMoveBuild< Expression >(type), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ) ); … … 198 198 199 199 ForCtrl * forCtrl( ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 200 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index-> get_expr()) ) {200 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index->expr.get()) ) { 201 201 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc ); 202 } else if ( CommaExpr * commaExpr = dynamic_cast<CommaExpr *>(index-> get_expr()) ) {202 } else if ( CommaExpr * commaExpr = dynamic_cast<CommaExpr *>(index->expr.get()) ) { 203 203 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(commaExpr->arg1 ) ) { 204 204 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc ); … … 334 334 %type<en> subrange 335 335 %type<decl> asm_name_opt 336 %type<en> asm_operands_opt asm_operands_listasm_operand336 %type<en> asm_operands_opt asm_operands_list asm_operand 337 337 %type<label> label_list 338 338 %type<en> asm_clobbers_list_opt 339 339 %type<flag> asm_volatile_opt 340 340 %type<en> handler_predicate_opt 341 %type<genexpr> generic_association 341 %type<genexpr> generic_association generic_assoc_list 342 342 343 343 // statements … … 1164 1164 for_control_expression 1165 1165 | for_control_expression_list ':' for_control_expression 1166 { $$ = $3; } 1166 // ForCtrl + ForCtrl: 1167 // init + init => multiple declaration statements that are hoisted 1168 // condition + condition => (expression) && (expression) 1169 // change + change => (expression), (expression) 1170 { 1171 $1->init->set_last( $3->init ); 1172 if ( $1->condition ) { 1173 if ( $3->condition ) { 1174 $1->condition->expr.reset( new LogicalExpr( $1->condition->expr.release(), $3->condition->expr.release(), true ) ); 1175 } // if 1176 } else $1->condition = $3->condition; 1177 if ( $1->change ) { 1178 if ( $3->change ) { 1179 $1->change->expr.reset( new CommaExpr( $1->change->expr.release(), $3->change->expr.release() ) ); 1180 } // if 1181 } else $1->change = $3->change; 1182 $$ = $1; 1183 } 1167 1184 ; 1168 1185 … … 1174 1191 | declaration comma_expression_opt ';' comma_expression_opt // C99, declaration has ';' 1175 1192 { $$ = new ForCtrl( $1, $2, $4 ); } 1193 1176 1194 | comma_expression // CFA 1177 1195 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), … … 1188 1206 | comma_expression ';' comma_expression inclexcl comma_expression '~' comma_expression // CFA 1189 1207 { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, $7 ); } 1208 1209 // There is a S/R conflicit if ~ and -~ are factored out. 1210 | comma_expression ';' comma_expression '~' '@' // CFA 1211 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1212 | comma_expression ';' comma_expression ErangeDown '@' // CFA 1213 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1190 1214 | comma_expression ';' comma_expression '~' '@' '~' comma_expression // CFA 1191 1215 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, $7 ); } -
src/ResolvExpr/AlternativeFinder.cc
rdeca0f5 r8c3a0336 258 258 // - necessary pre-requisite to pruning 259 259 AltList candidates; 260 std::list<std::string> errors; 260 261 for ( unsigned i = 0; i < alternatives.size(); ++i ) { 261 resolveAssertions( alternatives[i], indexer, candidates );262 resolveAssertions( alternatives[i], indexer, candidates, errors ); 262 263 } 263 264 // fail early if none such 264 265 if ( mode.failFast && candidates.empty() ) { 265 266 std::ostringstream stream; 266 stream << "No resolvable alternatives for expression " << expr << "\n" 267 << "Alternatives with failing assertions are:\n"; 268 printAlts( alternatives, stream, 1 ); 267 stream << "No alternatives with satisfiable assertions for " << expr << "\n"; 268 // << "Alternatives with failing assertions are:\n"; 269 // printAlts( alternatives, stream, 1 ); 270 for ( const auto& err : errors ) { 271 stream << err; 272 } 269 273 SemanticError( expr->location, stream.str() ); 270 274 } -
src/ResolvExpr/ResolveAssertions.cc
rdeca0f5 r8c3a0336 20 20 #include <list> // for list 21 21 #include <memory> // for unique_ptr 22 #include <string> 22 #include <sstream> // for ostringstream 23 #include <string> // for string 23 24 #include <unordered_map> // for unordered_map, unordered_multimap 24 25 #include <utility> // for move … … 27 28 #include "Alternative.h" // for Alternative, AssertionItem, AssertionList 28 29 #include "Common/FilterCombos.h" // for filterCombos 30 #include "Common/Indenter.h" // for Indenter 29 31 #include "Common/utility.h" // for sort_mins 30 32 #include "ResolvExpr/RenameVars.h" // for renameTyVars … … 97 99 return { item, item.matches[i] }; 98 100 } 101 102 const DeclarationWithType* get_decl() const { return cache->at(key).deferIds[0].decl; } 99 103 100 104 // sortable by key … … 364 368 static const int recursionLimit = /* 10 */ 4; 365 369 366 void resolveAssertions( Alternative& alt, const SymTab::Indexer& indexer, AltList& out ) {370 void resolveAssertions( Alternative& alt, const SymTab::Indexer& indexer, AltList& out, std::list<std::string>& errors ) { 367 371 // finish early if no assertions to resolve 368 372 if ( alt.need.empty() ) { … … 385 389 for ( auto& assn : resn.need ) { 386 390 // fail early if any assertion is not resolvable 387 if ( ! resolveAssertion( assn, resn, assnCache ) ) goto nextResn; 391 if ( ! resolveAssertion( assn, resn, assnCache ) ) { 392 Indenter tabs{ Indenter::tabsize, 3 }; 393 std::ostringstream ss; 394 ss << tabs << "Unsatisfiable alternative:\n"; 395 resn.alt.print( ss, ++tabs ); 396 ss << --tabs << "Could not satisfy assertion:\n"; 397 assn.decl->print( ss, ++tabs ); 398 399 errors.emplace_back( ss.str() ); 400 goto nextResn; 401 } 388 402 } 389 403 … … 404 418 resn.deferred, 405 419 CandidateEnvMerger{ resn.alt.env, resn.alt.openVars, resn.indexer } ); 420 // fail early if no mutually-compatible assertion satisfaction 421 if ( compatible.empty() ) { 422 Indenter tabs{ Indenter::tabsize, 3 }; 423 std::ostringstream ss; 424 ss << tabs << "Unsatisfiable alternative:\n"; 425 resn.alt.print( ss, ++tabs ); 426 ss << --tabs << "No mutually-compatible satisfaction for assertions:\n"; 427 ++tabs; 428 for ( const auto& d : resn.deferred ) { 429 d.get_decl()->print( ss, tabs ); 430 } 431 432 errors.emplace_back( ss.str() ); 433 goto nextResn; 434 } 406 435 // sort by cost 407 436 CandidateCost coster{ resn.indexer }; -
src/ResolvExpr/ResolveAssertions.h
rdeca0f5 r8c3a0336 24 24 namespace ResolvExpr { 25 25 /// Recursively resolves all assertions provided in an alternative; returns true iff succeeds 26 void resolveAssertions( Alternative& alt, const SymTab::Indexer& indexer, AltList& out );26 void resolveAssertions( Alternative& alt, const SymTab::Indexer& indexer, AltList& out, std::list<std::string>& errors ); 27 27 } // namespace ResolvExpr 28 28 -
src/ResolvExpr/TypeEnvironment.cc
rdeca0f5 r8c3a0336 386 386 } 387 387 388 bool TypeEnvironment::bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) { 388 bool TypeEnvironment::bindVarToVar( TypeInstType *var1, TypeInstType *var2, 389 TypeDecl::Data && data, AssertionSet &need, AssertionSet &have, 390 const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) { 389 391 390 392 auto class1 = internal_lookup( var1->get_name() ); … … 428 430 class1->set_type( common ); 429 431 } 432 class1->data.isComplete |= data.isComplete; 430 433 env.erase( class2 ); 431 434 } else return false; … … 435 438 class1->vars.insert( class2->vars.begin(), class2->vars.end() ); 436 439 class1->allowWidening = widen1; 440 class1->data.isComplete |= data.isComplete; 437 441 env.erase( class2 ); 438 442 } else { 439 443 class2->vars.insert( class1->vars.begin(), class1->vars.end() ); 440 444 class2->allowWidening = widen2; 445 class2->data.isComplete |= data.isComplete; 441 446 env.erase( class1 ); 442 447 } // if … … 445 450 class1->vars.insert( var2->get_name() ); 446 451 class1->allowWidening = widen1; 452 class1->data.isComplete |= data.isComplete; 447 453 } else if ( class2 != env.end() ) { 448 454 // var1 unbound, add to class2 449 455 class2->vars.insert( var1->get_name() ); 450 456 class2->allowWidening = widen2; 457 class2->data.isComplete |= data.isComplete; 451 458 } else { 452 459 // neither var bound, create new class -
src/ResolvExpr/TypeEnvironment.h
rdeca0f5 r8c3a0336 139 139 /// Binds the type classes represented by `var1` and `var2` together; will add 140 140 /// one or both classes if needed. Returns false on failure. 141 bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data& data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );141 bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, TypeDecl::Data && data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ); 142 142 143 143 /// Disallows widening for all bindings in the environment -
src/ResolvExpr/Unify.cc
rdeca0f5 r8c3a0336 172 172 bool isopen2 = var2 && ( entry2 != openVars.end() ); 173 173 174 if ( isopen1 && isopen2 && entry1->second == entry2->second ) { 175 result = env.bindVarToVar( var1, var2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer ); 174 if ( isopen1 && isopen2 ) { 175 if ( entry1->second.kind != entry2->second.kind ) { 176 result = false; 177 } else { 178 result = env.bindVarToVar( 179 var1, var2, TypeDecl::Data{ entry1->second, entry2->second }, needAssertions, 180 haveAssertions, openVars, widenMode, indexer ); 181 } 176 182 } else if ( isopen1 ) { 177 183 result = env.bindVar( var1, type2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer ); -
src/SynTree/Declaration.h
rdeca0f5 r8c3a0336 211 211 TypeDecl::Kind kind; 212 212 bool isComplete; 213 213 214 Data() : kind( (TypeDecl::Kind)-1 ), isComplete( false ) {} 214 215 Data( TypeDecl * typeDecl ) : Data( typeDecl->get_kind(), typeDecl->isComplete() ) {} 215 216 Data( Kind kind, bool isComplete ) : kind( kind ), isComplete( isComplete ) {} 217 Data( const Data& d1, const Data& d2 ) 218 : kind( d1.kind ), isComplete ( d1.isComplete || d2.isComplete ) {} 219 216 220 bool operator==(const Data & other) const { return kind == other.kind && isComplete == other.isComplete; } 217 221 bool operator!=(const Data & other) const { return !(*this == other);} -
tests/.expect/completeTypeError.txt
rdeca0f5 r8c3a0336 1 completeTypeError.cfa:33:1 error: No reasonable alternatives for expression Applying untyped: 2 Name: *? 3 ...to: 4 Name: v 1 completeTypeError.cfa:34:1 error: Cannot choose between 2 alternatives for expression 2 Generated Cast of: 3 Applying untyped: 4 Name: *? 5 ...to: 6 Name: x 5 7 6 completeTypeError.cfa:34:1 error: No reasonable alternatives for expression Applying untyped: 7 Name: *? 8 ...to: 9 Name: y 8 ... to: nothing Alternatives are: 9 Cost ( 0, 1, 2, 0, 1, -1, 0 ): Generated Cast of: 10 Application of 11 Variable Expression: *?: forall 12 DT: object type 13 function 14 ... with parameters 15 intrinsic pointer to instance of type DT (not function type) 16 ... returning 17 _retval__operator_deref: reference to instance of type DT (not function type) 18 ... with attributes: 19 Attribute with name: unused 20 21 22 ... to arguments 23 Variable Expression: x: pointer to instance of struct A with body 0 24 25 ... to: nothing 26 (types: 27 void 28 ) 29 Environment:( _80_4_DT ) -> instance of struct A with body 0 (no widening) 30 31 32 Cost ( 0, 1, 2, 0, 1, -1, 0 ): Generated Cast of: 33 Application of 34 Variable Expression: *?: forall 35 DT: object type 36 function 37 ... with parameters 38 intrinsic pointer to instance of type DT (not function type) 39 ... returning 40 _retval__operator_deref: reference to instance of type DT (not function type) 41 ... with attributes: 42 Attribute with name: unused 43 44 45 ... to arguments 46 Variable Expression: x: pointer to instance of struct B with body 1 47 48 ... to: nothing 49 (types: 50 void 51 ) 52 Environment:( _80_4_DT ) -> instance of struct B with body 1 (no widening) 53 54 10 55 11 56 completeTypeError.cfa:35:1 error: No reasonable alternatives for expression Applying untyped: … … 24 69 Name: v 25 70 26 completeTypeError.cfa:5 8:1 error: No reasonable alternatives for expression Applying untyped:71 completeTypeError.cfa:59:1 error: No reasonable alternatives for expression Applying untyped: 27 72 Name: baz 28 73 ...to: 29 74 Name: y 30 75 31 completeTypeError.cfa: 59:1 error: No reasonable alternatives for expression Applying untyped:76 completeTypeError.cfa:60:1 error: No reasonable alternatives for expression Applying untyped: 32 77 Name: quux 33 78 ...to: 34 79 Name: y 35 80 36 completeTypeError.cfa:60:1 error: No reasonable alternatives for expression Applying untyped: 37 Name: *? 38 ...to: 39 Name: y 40 41 completeTypeError.cfa:72:1 error: No resolvable alternatives for expression Applying untyped: 81 completeTypeError.cfa:72:1 error: No alternatives with satisfiable assertions for Applying untyped: 42 82 Name: baz 43 83 ...to: 44 84 Name: z 45 85 46 Alternatives with failing assertions are:86 Unsatisfiable alternative: 47 87 Cost ( 0, 1, 0, 0, 1, -5, 0 ): Application of 48 Variable Expression: baz: forall49 T: sized object type50 ... with assertions51 ?=?: pointer to function52 ... with parameters53 reference to instance of type T (not function type)54 instance of type T (not function type)55 ... returning56 _retval__operator_assign: instance of type T (not function type)57 ... with attributes:58 Attribute with name: unused88 Variable Expression: baz: forall 89 T: sized object type 90 ... with assertions 91 ?=?: pointer to function 92 ... with parameters 93 reference to instance of type T (not function type) 94 instance of type T (not function type) 95 ... returning 96 _retval__operator_assign: instance of type T (not function type) 97 ... with attributes: 98 Attribute with name: unused 59 99 60 100 61 ?{}: pointer to function 101 ?{}: pointer to function 102 ... with parameters 103 reference to instance of type T (not function type) 104 ... returning nothing 105 106 ?{}: pointer to function 107 ... with parameters 108 reference to instance of type T (not function type) 109 instance of type T (not function type) 110 ... returning nothing 111 112 ^?{}: pointer to function 113 ... with parameters 114 reference to instance of type T (not function type) 115 ... returning nothing 116 117 118 function 62 119 ... with parameters 63 referenceto instance of type T (not function type)120 pointer to instance of type T (not function type) 64 121 ... returning nothing 65 122 66 ?{}: pointer to function 67 ... with parameters 68 reference to instance of type T (not function type) 69 instance of type T (not function type) 70 ... returning nothing 123 ... to arguments 124 Variable Expression: z: pointer to instance of type T (not function type) 71 125 72 ^?{}: pointer to function 73 ... with parameters 74 reference to instance of type T (not function type) 75 ... returning nothing 126 (types: 127 void 128 ) 129 Environment:( _99_0_T ) -> instance of type T (not function type) (no widening) 130 131 Could not satisfy assertion: 132 ?=?: pointer to function 133 ... with parameters 134 reference to instance of type _99_0_T (not function type) 135 instance of type _99_0_T (not function type) 136 ... returning 137 _retval__operator_assign: instance of type _99_0_T (not function type) 138 ... with attributes: 139 Attribute with name: unused 76 140 77 141 78 function79 ... with parameters80 pointer to instance of type T (not function type)81 ... returning nothing82 83 ... to arguments84 Variable Expression: z: pointer to instance of type T (not function type)85 86 (types:87 void88 )89 Environment:( _99_0_T ) -> instance of type T (not function type) (no widening)90 91 92 -
tests/.expect/loopctrl.txt
rdeca0f5 r8c3a0336 19 19 10 8 6 4 2 20 20 21 1 2 3 4 5 6 7 8 9 10 22 10 9 8 7 6 5 4 3 2 1 0 21 23 2 4 6 8 10 22 24 2.1 3.8 5.5 7.2 8.9 … … 42 44 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0) 43 45 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0) 46 47 0 -5 1 -4 2 -3 3 -2 4 -1 5 0 6 1 7 2 8 3 9 4 48 0 -5 1 -6 2 -7 3 -8 4 -9 5 -10 6 -11 7 -12 8 -13 9 -14 49 0 -5 1 -3 2 -1 3 1 4 3 5 5 6 7 7 9 8 11 9 13 50 0 -5 1 -7 2 -9 3 -11 4 -13 5 -15 6 -17 7 -19 8 -21 9 -23 51 52 0 -5 1 -4 2 -3 3 -2 4 -1 5 0 6 1 7 2 8 3 9 4 53 0 -5 1 -6 2 -7 3 -8 4 -9 5 -10 6 -11 7 -12 8 -13 9 -14 54 0 -5 1 -3 2 -1 3 1 4 3 5 5 6 7 7 9 8 11 9 13 55 0 -5 1 -7 2 -9 3 -11 4 -13 5 -15 6 -17 7 -19 8 -21 9 -23 56 57 0 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5 5 -15 6.5 6 -17 7.5 7 -19 8.5 8 -21 9.5 9 -23 10.5 58 0 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5 5 -15 6.5 6 -17 7.5 7 -19 8.5 8 -21 9.5 9 -23 10.5 59 0 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5 5 -15 6.5 6 -17 7.5 7 -19 8.5 8 -21 9.5 9 -23 10.5 -
tests/Makefile.am
rdeca0f5 r8c3a0336 44 44 CC = @CFACC@ 45 45 46 PRETTY_PATH= cd ${srcdir} &&46 PRETTY_PATH=mkdir -p $(dir $(abspath ${@})) && cd ${srcdir} && 47 47 48 48 .PHONY: list .validate … … 85 85 #---------------------------------------------------------------------------------------------------------------- 86 86 87 # Use for all tests, make sure the path are correct and all flags are added 88 CFACOMPILETEST=$(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) $($(shell echo "${@}_FLAGS" | sed 's/-\|\//_/g')) 89 90 # Use for tests that either generate an executable, print directyl to stdout or the make command is expected to fail 91 CFATEST_STDOUT=$(CFACOMPILETEST) -o $(abspath ${@}) 92 93 # Use for tests where the make command is expecte to succeed but the expected.txt should be compared to stderr 94 CFATEST_STDERR=$(CFACOMPILETEST) 2> $(abspath ${@}) 95 96 #---------------------------------------------------------------------------------------------------------------- 97 87 98 # implicit rule so not all test require a rule 88 99 % : %.cfa $(CFACC) 89 $( PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})100 $(CFATEST_STDOUT) 90 101 91 102 % : %.cpp 92 103 $(PRETTY_PATH) $(CXXCOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 93 104 94 declarationSpecifier: declarationSpecifier.cfa $(CFACC) 95 $(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 105 #------------------------------------------------------------------------------ 106 # TARGET WITH STANDARD RULE BUT CUSTOM FLAGS 107 #------------------------------------------------------------------------------ 108 # Expected failures 109 declarationSpecifier_FLAGS= -CFA -XCFA -p 110 gccExtensions_FLAGS= -CFA -XCFA -p 111 extension_FLAGS= -CFA -XCFA -p 112 attributes_FLAGS= -CFA -XCFA -p 113 functions_FLAGS= -CFA -XCFA -p 114 KRfunctions_FLAGS= -CFA -XCFA -p 115 gmp_FLAGS= -lgmp 96 116 97 gccExtensions : gccExtensions.cfa $(CFACC) 98 $(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 117 #------------------------------------------------------------------------------ 118 # Expected failures 119 completeTypeError_FLAGS= -DERR1 99 120 100 extension : extension.cfa $(CFACC) 101 $(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 121 #------------------------------------------------------------------------------ 122 # CUSTOM TARGET 123 #------------------------------------------------------------------------------ 124 typedefRedef-ERR1: typedefRedef.cfa $(CFACC) 125 $(CFATEST_STDOUT) -DERR1 102 126 103 a ttributes : attributes.cfa $(CFACC)104 $( PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})127 alloc-ERROR: alloc.cfa $(CFACC) 128 $(CFATEST_STDOUT) -DERR1 105 129 106 functions: functions.cfa $(CFACC)107 $( PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})130 nested-types-ERR1: nested-types.cfa $(CFACC) 131 $(CFATEST_STDOUT) -DERR1 108 132 109 KRfunctions : KRfunctions.cfa $(CFACC)110 $( PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})133 nested-types-ERR2: nested-types.cfa $(CFACC) 134 $(CFATEST_STDOUT) -DERR2 111 135 112 sched-ext-parse : sched-ext-parse.c$(CFACC)113 $( PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})136 raii/dtor-early-exit-ERR1: raii/dtor-early-exit.cfa $(CFACC) 137 $(CFATEST_STDOUT) -DERR1 114 138 115 gmp : gmp.cfa $(CFACC) 116 $(PRETTY_PATH) $(CFACOMPILE) -lgmp $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 139 raii/dtor-early-exit-ERR2: raii/dtor-early-exit.cfa $(CFACC) 140 $(CFATEST_STDOUT) -DERR2 141 142 raii/memberCtors-ERR1: raii/memberCtors.cfa $(CFACC) 143 $(CFATEST_STDOUT) -DERR1 144 145 raii/ctor-autogen-ERR1: raii/ctor-autogen.cfa $(CFACC) 146 $(CFATEST_STDOUT) -DERR1 117 147 118 148 #builtins 119 149 builtins/sync: builtins/sync.cfa $(CFACC) 120 $(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) 2> $(abspath ${@}) -fsyntax-only 121 122 #------------------------------------------------------------------------------ 123 124 #To make errors path independent we need to cd into the correct directories 125 completeTypeError : completeTypeError.cfa $(CFACC) 126 $(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 127 128 typedefRedef-ERR1: typedefRedef.cfa $(CFACC) 129 $(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 130 131 alloc-ERROR: alloc.cfa $(CFACC) 132 $(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 133 134 fallthrough-ERROR: fallthrough.cfa $(CFACC) 135 $(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 136 137 nested-types-ERR1: nested-types.cfa $(CFACC) 138 $(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 139 140 nested-types-ERR2: nested-types.cfa $(CFACC) 141 $(PRETTY_PATH) $(CFACOMPILE) -DERR2 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 142 143 # Constructor/destructor tests 144 raii/dtor-early-exit-ERR1: raii/dtor-early-exit.cfa $(CFACC) 145 $(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 146 147 raii/dtor-early-exit-ERR2: raii/dtor-early-exit.cfa $(CFACC) 148 $(PRETTY_PATH) $(CFACOMPILE) -DERR2 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 149 150 raii/memberCtors-ERR1: raii/memberCtors.cfa $(CFACC) 151 $(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 152 153 raii/ctor-autogen-ERR1: raii/ctor-autogen.cfa $(CFACC) 154 $(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 150 $(CFATEST_STDERR) -fsyntax-only 155 151 156 152 # Warnings 157 153 warnings/self-assignment: warnings/self-assignment.cfa $(CFACC) 158 $( PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) 2> $(abspath ${@}) -fsyntax-only154 $(CFATEST_STDERR) -fsyntax-only -
tests/Makefile.in
rdeca0f5 r8c3a0336 386 386 -quiet @CFA_FLAGS@ -DIN_DIR="${abs_srcdir}/.in/" \ 387 387 ${DEBUG_FLAGS} ${INSTALL_FLAGS} ${ARCH_FLAGS} 388 PRETTY_PATH = cd ${srcdir} &&388 PRETTY_PATH = mkdir -p $(dir $(abspath ${@})) && cd ${srcdir} && 389 389 avl_test_SOURCES = avltree/avl_test.cfa avltree/avl0.cfa avltree/avl1.cfa avltree/avl2.cfa avltree/avl3.cfa avltree/avl4.cfa avltree/avl-private.cfa 390 390 # automake doesn't know we still need C/CPP rules so pretend like we have a C program 391 391 _dummy_hack_SOURCES = .dummy_hack.c .dummy_hackxx.cpp 392 393 #---------------------------------------------------------------------------------------------------------------- 394 395 # Use for all tests, make sure the path are correct and all flags are added 396 CFACOMPILETEST = $(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) $($(shell echo "${@}_FLAGS" | sed 's/-\|\//_/g')) 397 398 # Use for tests that either generate an executable, print directyl to stdout or the make command is expected to fail 399 CFATEST_STDOUT = $(CFACOMPILETEST) -o $(abspath ${@}) 400 401 # Use for tests where the make command is expecte to succeed but the expected.txt should be compared to stderr 402 CFATEST_STDERR = $(CFACOMPILETEST) 2> $(abspath ${@}) 403 404 #------------------------------------------------------------------------------ 405 # TARGET WITH STANDARD RULE BUT CUSTOM FLAGS 406 #------------------------------------------------------------------------------ 407 # Expected failures 408 declarationSpecifier_FLAGS = -CFA -XCFA -p 409 gccExtensions_FLAGS = -CFA -XCFA -p 410 extension_FLAGS = -CFA -XCFA -p 411 attributes_FLAGS = -CFA -XCFA -p 412 functions_FLAGS = -CFA -XCFA -p 413 KRfunctions_FLAGS = -CFA -XCFA -p 414 gmp_FLAGS = -lgmp 415 416 #------------------------------------------------------------------------------ 417 # Expected failures 418 completeTypeError_FLAGS = -DERR1 392 419 all: all-am 393 420 … … 772 799 # implicit rule so not all test require a rule 773 800 % : %.cfa $(CFACC) 774 $( PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})801 $(CFATEST_STDOUT) 775 802 776 803 % : %.cpp 777 804 $(PRETTY_PATH) $(CXXCOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 778 805 779 declarationSpecifier: declarationSpecifier.cfa $(CFACC) 780 $(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 781 782 gccExtensions : gccExtensions.cfa $(CFACC) 783 $(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 784 785 extension : extension.cfa $(CFACC) 786 $(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 787 788 attributes : attributes.cfa $(CFACC) 789 $(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 790 791 functions: functions.cfa $(CFACC) 792 $(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 793 794 KRfunctions : KRfunctions.cfa $(CFACC) 795 $(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 796 797 sched-ext-parse : sched-ext-parse.c $(CFACC) 798 $(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 799 800 gmp : gmp.cfa $(CFACC) 801 $(PRETTY_PATH) $(CFACOMPILE) -lgmp $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 806 #------------------------------------------------------------------------------ 807 # CUSTOM TARGET 808 #------------------------------------------------------------------------------ 809 typedefRedef-ERR1: typedefRedef.cfa $(CFACC) 810 $(CFATEST_STDOUT) -DERR1 811 812 alloc-ERROR: alloc.cfa $(CFACC) 813 $(CFATEST_STDOUT) -DERR1 814 815 nested-types-ERR1: nested-types.cfa $(CFACC) 816 $(CFATEST_STDOUT) -DERR1 817 818 nested-types-ERR2: nested-types.cfa $(CFACC) 819 $(CFATEST_STDOUT) -DERR2 820 821 raii/dtor-early-exit-ERR1: raii/dtor-early-exit.cfa $(CFACC) 822 $(CFATEST_STDOUT) -DERR1 823 824 raii/dtor-early-exit-ERR2: raii/dtor-early-exit.cfa $(CFACC) 825 $(CFATEST_STDOUT) -DERR2 826 827 raii/memberCtors-ERR1: raii/memberCtors.cfa $(CFACC) 828 $(CFATEST_STDOUT) -DERR1 829 830 raii/ctor-autogen-ERR1: raii/ctor-autogen.cfa $(CFACC) 831 $(CFATEST_STDOUT) -DERR1 802 832 803 833 #builtins 804 834 builtins/sync: builtins/sync.cfa $(CFACC) 805 $(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) 2> $(abspath ${@}) -fsyntax-only 806 807 #------------------------------------------------------------------------------ 808 809 #To make errors path independent we need to cd into the correct directories 810 completeTypeError : completeTypeError.cfa $(CFACC) 811 $(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 812 813 typedefRedef-ERR1: typedefRedef.cfa $(CFACC) 814 $(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 815 816 alloc-ERROR: alloc.cfa $(CFACC) 817 $(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 818 819 fallthrough-ERROR: fallthrough.cfa $(CFACC) 820 $(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 821 822 nested-types-ERR1: nested-types.cfa $(CFACC) 823 $(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 824 825 nested-types-ERR2: nested-types.cfa $(CFACC) 826 $(PRETTY_PATH) $(CFACOMPILE) -DERR2 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 827 828 # Constructor/destructor tests 829 raii/dtor-early-exit-ERR1: raii/dtor-early-exit.cfa $(CFACC) 830 $(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 831 832 raii/dtor-early-exit-ERR2: raii/dtor-early-exit.cfa $(CFACC) 833 $(PRETTY_PATH) $(CFACOMPILE) -DERR2 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 834 835 raii/memberCtors-ERR1: raii/memberCtors.cfa $(CFACC) 836 $(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 837 838 raii/ctor-autogen-ERR1: raii/ctor-autogen.cfa $(CFACC) 839 $(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@}) 835 $(CFATEST_STDERR) -fsyntax-only 840 836 841 837 # Warnings 842 838 warnings/self-assignment: warnings/self-assignment.cfa $(CFACC) 843 $( PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) 2> $(abspath ${@}) -fsyntax-only839 $(CFATEST_STDERR) -fsyntax-only 844 840 845 841 # Tell versions [3.59,3.63) of GNU make to not export all variables. -
tests/completeTypeError.cfa
rdeca0f5 r8c3a0336 5 5 forall(dtype T | sized(T)) void quux(T *); 6 6 7 struct A; 8 struct B {}; 7 struct A; // incomplete 8 struct B {}; // complete 9 9 10 10 int main() { 11 int * i;12 void * v;11 int * i; 12 void * v; 13 13 14 14 A * x; … … 19 19 // okay 20 20 *i; 21 * x; // picks B21 *y; 22 22 *z; 23 23 foo(i); … … 32 32 // bad 33 33 *v; 34 * y;34 *x; // ambiguous 35 35 foo(v); 36 36 baz(v); … … 52 52 void qux(T * y) { 53 53 // okay 54 *y; 54 55 bar(y); 55 56 qux(y); … … 58 59 baz(y); 59 60 quux(y); 60 *y;61 61 } 62 62 -
tests/coroutine/devicedriver.cfa
rdeca0f5 r8c3a0336 10 10 // Created On : Sat Mar 16 15:30:34 2019 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Mar 19 15:59:06201913 // Update Count : 8712 // Last Modified On : Sat Apr 20 09:07:19 2019 13 // Update Count : 90 14 14 // 15 15 … … 67 67 char msg[65], byte; 68 68 Driver driver = { msg }; 69 70 sin | nlOn; // read newline (all) characters 69 71 eof: for () { // read until end of file 70 72 sin | byte; // read one character -
tests/function-operator.cfa
rdeca0f5 r8c3a0336 10 10 // Created On : Fri Aug 25 15:21:11 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T ue Dec 4 21:37:09 201813 // Update Count : 912 // Last Modified On : Thu Apr 11 18:27:45 2019 13 // Update Count : 10 14 14 // 15 15 … … 62 62 63 63 // test ?()(T, ...) -- ?() with function call-by-reference 64 forall(otype Generator, otype GenRet | { GenRet ?()(Generator &); }, dtype Iter, otype T | Iterator(Iter, T) | Assignable(T, GenRet))64 forall(otype Generator, otype GenRet | { GenRet ?()(Generator &); }, dtype Iter, otype T | Iterator(Iter, T) | Assignable(T, GenRet)) 65 65 void generate(Iter first, Iter last, Generator & gen) { 66 66 int i = 0; -
tests/io2.cfa
rdeca0f5 r8c3a0336 10 10 // Created On : Wed Mar 2 16:56:02 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Dec 21 08:20:14 201813 // Update Count : 11 212 // Last Modified On : Thu Apr 18 08:03:30 2019 13 // Update Count : 113 14 14 // 15 15 … … 97 97 sout | 1 | sepOff | 2 | 3; // locally turn off implicit separator 98 98 sout | sepOn | sepOn | 1 | 2 | 3 | sepOn | sepOff | sepOn | '\n' | nonl; // no separator at start/end of line 99 sout | 1 | 2 | 3 | "\n\n" | sepOn | nonl; 99 sout | 1 | 2 | 3 | "\n\n" | sepOn | nonl; // no separator at start of next line 100 100 sout | 1 | 2 | 3; 101 101 sout | nl; -
tests/loopctrl.cfa
rdeca0f5 r8c3a0336 10 10 // Created On : Wed Aug 8 18:32:59 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Feb 21 08:54:47201913 // Update Count : 8612 // Last Modified On : Sat Apr 13 11:03:09 2019 13 // Update Count : 104 14 14 // 15 15 … … 56 56 for ( ui; 10u -~= 2u ~ 2u ) { sout | ui; } sout | nl | nl; 57 57 58 // @ means do nothing 59 for ( i; 1 ~ @ ) { 60 if ( i > 10 ) break; 61 sout | i; 62 } sout | nl; 63 for ( i; 10 -~ @ ) { 64 if ( i < 0 ) break; 65 sout | i; 66 } sout | nl; 58 67 for ( i; 2 ~ @ ~ 2 ) { 59 68 if ( i > 10 ) break; … … 94 103 for ( s; (S){10,10} -~ (S){0} ~ (S){1} ) { sout | s; } sout | nl; 95 104 for ( s; (S){10,10} -~= (S){0} ) { sout | s; } sout | nl; 96 for ( s; (S){10,10} -~= (S){0} ~ (S){1} ) { sout | s; } sout | nl; 105 for ( s; (S){10,10} -~= (S){0} ~ (S){1} ) { sout | s; } sout | nl | nl; 106 107 for ( i; 10 : j; -5 ~ @ ) { sout | i | j; } sout | nl; 108 for ( i; 10 : j; -5 -~ @ ) { sout | i | j; } sout | nl; 109 for ( i; 10 : j; -5 ~ @ ~ 2 ) { sout | i | j; } sout | nl; 110 for ( i; 10 : j; -5 -~ @ ~ 2 ) { sout | i | j; } sout | nl | nl; 111 112 for ( j; -5 ~ @ : i; 10 ) { sout | i | j; } sout | nl; 113 for ( j; -5 -~ @ : i; 10 ) { sout | i | j; } sout | nl; 114 for ( j; -5 ~ @ ~ 2 : i; 10 ) { sout | i | j; } sout | nl; 115 for ( j; -5 -~ @ ~ 2 : i; 10 ) { sout | i | j; } sout | nl | nl; 116 117 for ( j; -5 -~ @ ~ 2 : i; 10 : k; 1.5 ~ @ ) { sout | i | j | k; } sout | nl; 118 for ( j; -5 -~ @ ~ 2 : k; 1.5 ~ @ : i; 10 ) { sout | i | j | k; } sout | nl; 119 for ( k; 1.5 ~ @ : j; -5 -~ @ ~ 2 : i; 10 ) { sout | i | j | k; } sout | nl; 97 120 } 98 121
Note: See TracChangeset
for help on using the changeset viewer.