Changeset 8c3a0336


Ignore:
Timestamp:
Apr 23, 2019, 10:26:14 AM (2 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
arm-eh, cleanup-dtors, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr
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.
Message:

Merge branch 'master' into ctxswitch

Files:
3 added
28 edited

Legend:

Unmodified
Added
Removed
  • benchmark/Makefile.am

    rdeca0f5 r8c3a0336  
    2121include $(top_srcdir)/src/cfa.make
    2222
    23 AM_CFLAGS = -O2 -Wall -I$(srcdir) -lrt -pthread
    24 AM_CFAFLAGS = -quiet -in-tree -nodebug -std=c++14
    25 AM_UPPFLAGS = -quiet -nodebug -multi
     23AM_CFLAGS = -O2 -Wall -Wextra -Werror -I$(srcdir) -lrt -pthread
     24AM_CFAFLAGS = -quiet -nodebug -in-tree
     25AM_UPPFLAGS = -quiet -nodebug -multi -std=c++14
    2626
    2727BENCH_V_CC = $(__bench_v_CC_$(__quiet))
  • benchmark/Makefile.in

    rdeca0f5 r8c3a0336  
    371371
    372372# applies to both programs
    373 AM_CFLAGS = -O2 -Wall -I$(srcdir) -lrt -pthread
    374 AM_CFAFLAGS = -quiet -in-tree -nodebug -std=c++14
    375 AM_UPPFLAGS = -quiet -nodebug -multi
     373AM_CFLAGS = -O2 -Wall -Wextra -Werror -I$(srcdir) -lrt -pthread
     374AM_CFAFLAGS = -quiet -nodebug -in-tree
     375AM_UPPFLAGS = -quiet -nodebug -multi -std=c++14
    376376BENCH_V_CC = $(__bench_v_CC_$(__quiet))
    377377BENCH_V_CFA = $(__bench_v_CFA_$(__quiet))
  • doc/proposals/vtable.md

    rdeca0f5 r8c3a0336  
    1111should be able to store anything that goes into a trait.
    1212
     13I also include notes on a sample implementation, which primarly exists to show
     14there is a resonable implementation. The code samples for that are in a slight
     15psudo-code to help avoid name mangling and keeps some CFA features while they
     16would actually be writen in C.
     17
    1318Trait Instances
    1419---------------
     
    4247before.
    4348
    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.
     49For traits to be used this way they should meet two requirements. First they
     50should only have a single polymorphic type and each assertion should use that
     51type once as a parameter. Extentions may later loosen these requirements.
     52
     53If a trait object is used it should generate a series of implicate functions
     54each of which implements one of the functions required by the trait. So for
     55combiner there is an implicate:
     56
     57    void combine(trait combiner & this, int);
     58
     59This function is the one actually called at the end
     60
     61The main use case for trait objects is that they can be stored. They can be
     62passed 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
     80Currently these traits are limited to 1 trait parameter and functions should
     81have exactly 1 parameter. We cannot abstract away pairs of types and still
     82pass them into normal functions, which take them seperately.
     83
     84The second is required the because we need to get the vtable from somewhere.
     85If there are 0 trait objects than no vtable is avalible, if we have more than
     861 than the vtables give conflicting answers on what underlying function to
     87call. And even then the underlying type assumes a concrete type.
     88
     89This loop can sort of be broken by using the trait object directly in the
     90signature. 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
     97A simple way to implement trait objects is by a pair of pointers. One to the
     98underlying 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
     110The functions that run on the trait object would generally be generated using
     111the following pattern:
     112
     113    void draw(Surface & surface, drawable & traitObj) {
     114        return traitObj.vtable->draw(surface, traitObj.object);
     115    }
     116
     117There may have to be special cases for things like copy construction, that
     118might require a more sigificant wrapper. On the other hand moving could be
     119implemented by moving the pointers without any need to refer to the base
     120object.
     121
     122### Extention: Multiple Trait Parameters
     123Currently, this gives traits two independent uses. They use the same syntax,
     124except for limits boxable traits have, and yet don't really mix. The most
     125natural way to do this is to allow trait instances to pick one parameter
     126that they are generic over, the others they choose types to implement.
     127
     128The two ways to do the selection, the first is do it at the trait definition.
     129Each trait picks out a single parameter which it can box (here the `virtual`
     130qualifier). When you create an instance of a trait object you provide
     131arguments 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
     139The second is to do it at the instaniation point. A placeholder (here the
     140keyword `virtual`) is used to explicately skip over the parameter that will be
     141abstracted 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
     149Using both (first to set the default, second as a local override) would also
     150work, although might be exessively complicated.
     151
     152This is useful in cases where you want to use a generic type, but leave part
     153of 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
     160Which allows you to fold values without putting them in a container. If they
     161are already in a container this is exessive, but if they are generated over
     162time this gives you a simple interface. This could for instance be used in
     163a profile, where T changes for each profiling statistic and you can plug in
     164multiple profilers for any run by adding them to an array.
    52165
    53166Hierarchy
     
    90203the pointer to it.
    91204
     205Exception 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
     228Ast 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
     270The type id may be as little as:
     271
     272    struct typeid {
     273        struct typeid const * const parent;
     274    };
     275
     276Some linker magic would have to be used to ensure exactly one copy of each
     277structure for each type exists in memory. There seem to be spectial once
     278sections that support this and it should be easier than generating unique
     279ids across compilation units.
     280
     281The structure could be extended to contain any additional type information.
     282
     283There are two general designs for vtables with type ids. The first is to put
     284the type id at the top of the vtable, this is the most compact and efficient
     285solution but only works if we have exactly 1 vtable for each type. The second
     286is to put a pointer to the type id in each vtable. This has more overhead but
     287allows 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
     302To convert from a pointer to a type higher on the hierarchy to one lower on
     303the hierarchy a check is used to make sure that the underlying type is also
     304of that lower type.
     305
     306The proposed syntax for this is:
     307
     308    trait SubType * new_value = (virtual trait SubType *)super_type;
     309
     310It will return the same pointer if it does point to the subtype and null if
     311it does not, doing the check and conversion in one operation.
     312
    92313### Inline vtables
    93314Since the structures here are usually made to be turned into trait objects
    94315it 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.
     316pointer. 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
     318pointer.
     319
     320There are also three options for where the pointer to the vtable. It could be
     321anywhere, a fixed location for each trait or always at the front. For the per-
     322trait solution an extention to specify what it is (example `vtable[0];`) which
     323could also be used to combine it with others. So these options can be combined
     324to allow access to all three options.
    101325
    102326### Virtual Tables as Types
    103 Here we consider encoding plus the implementation of functions on it. Which
    104 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.
     327Here we consider encoding plus the implementation of functions on it to be a
     328type. Which is to say in the type hierarchy structures aren't concrete types
     329anymore, instead they are parent types to vtables, which combine the encoding
     330and implementation.
    107331
    108332Resolution Scope
     
    123347other.
    124348
    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.
     349Some syntax would have to be added to specify the resolution point. To ensure
     350a single instance there may have to be two variants, one forward declaration
     351and one to create the instance. With some compiler magic the forward
     352declaration maybe enough.
     353
     354    extern trait combiner(struct summation) vtable;
     355    trait combiner(struct summation) vtable;
     356
     357Or (with the same variants):
     358
     359    vtable combiner(struct summation);
     360
     361The extern variant promises that the vtable will exist while the normal one
     362is where the resolution actually happens.
    127363
    128364### Explicit Resolution Points:
     
    141377vtable.
    142378
     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
     385The extern difference is the same before. The name (sum in the samples) is
     386used at the binding site to say which one is picked. The default keyword can
     387be 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.)
     393The object being bound is required. The name of the vtable is optional if
     394there is exactly one vtable name marked with default.
     395
     396These could also be placed inside functions. In which case both the name and
     397the default keyword might be optional. If the name is ommited in an assignment
     398the closest vtable is choosen (returning to the global default rule if no
     399approprate local vtable is in scope).
     400
    143401### Site Based Resolution:
    144402Every place in code where the binding of a vtable to an object occurs has
  • doc/user/user.tex

    rdeca0f5 r8c3a0336  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Tue Mar 26 22:10:49 2019
    14 %% Update Count     : 3411
     13%% Last Modified On : Sun Apr 14 11:02:34 2019
     14%% Update Count     : 3443
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    514514sout | 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
    515515           | (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}
     5161 1 256 -64 125 ®0® 3273344365508751233 ®0® ®0® -0.015625 18.3791736799526 0.264715-1.1922i
     517\end{cfa}
     518Note, ©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.
    518519Parenthesis are necessary for complex constants or the expression is parsed as ©1.0f+®(®2.0fi \ 3.0f®)®+2.0fi©.
    519520The exponentiation operator is available for all the basic types, but for user-defined types, only the integral-computation version is available.
     
    524525OT ?®\®?( OT ep, unsigned long int y );
    525526\end{cfa}
    526 The user type ©T© must define multiplication one, ©1©, and, ©*©.
     527The user type ©T© must define multiplication, one, ©1©, and, ©*©.
    527528
    528529
     
    554555\subsection{Loop Control}
    555556
    556 The ©for©/©while©/©do-while© loop-control allows empty or simplified ranges.
     557The ©for©/©while©/©do-while© loop-control allows empty or simplified ranges (see Figure~\ref{f:LoopControlExamples}).
     558\begin{itemize}
     559\item
    557560An 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
     562The up-to range ©~©\index{~@©~©} means exclusive range [M,N).
     563\item
     564The up-to range ©~=©\index{~=@©~=©} means inclusive range [M,N].
     565\item
     566The down-to range ©-~©\index{-~@©-~©} means exclusive range [N,M).
     567\item
     568The down-to range ©-~=©\index{-~=@©-~=©} means inclusive range [N,M].
     569\item
     570©@© means put nothing in this field.
     571\item
    562572©0© is the implicit start value;
     573\item
    563574©1© is the implicit increment value.
     575\item
    564576The up-to range uses ©+=© for increment;
    565 the down-to range uses ©-=© for decrement.
     577\item
     578The down-to range uses ©-=© for decrement.
     579\item
    566580The 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}
    567584\begin{cquote}
    568 \begin{tabular}{@{}ll|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} \\
    570587\hline
    571588\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; }
     589sout | nlOff;
     590while ®()® { sout | "empty"; break; } sout | nl;
     591do { sout | "empty"; break; } while ®()®; sout | nl;
     592for ®()® { sout | "empty"; break; } sout | nl;
     593for ( ®0® ) { sout | "A"; } sout | "zero" | nl;
     594for ( ®1® ) { sout | "A"; } sout | nl;
     595for ( ®10® ) { sout | "A"; } sout | nl;
     596for ( ®1 ~= 10 ~ 2® ) { sout | "B"; } sout | nl;
     597for ( ®10 -~= 1 ~ 2® ) { sout | "C"; } sout | nl;
     598for ( ®0.5 ~ 5.5® ) { sout | "D"; } sout | nl;
     599for ( ®5.5 -~ 0.5® ) { sout | "E"; } sout | nl;
     600for ( ®i; 10® ) { sout | i; } sout | nl;
     601for ( ®i; 1 ~= 10 ~ 2® ) { sout | i; } sout | nl;
     602for ( ®i; 10 -~= 1 ~ 2® ) { sout | i; } sout | nl;
     603for ( ®i; 0.5 ~ 5.5® ) { sout | i; } sout | nl;
     604for ( ®i; 5.5 -~ 0.5® ) { sout | i; } sout | nl;
     605for ( ®ui; 2u ~= 10u ~ 2u® ) { sout | ui; } sout | nl;
     606for ( ®ui; 10u -~= 2u ~ 2u® ) { sout | ui; } sout | nl;
    589607enum { N = 10 };
    590 for ( ®N® ) { sout | "N"; }
    591 for ( ®i; N® ) { sout | i; }
    592 for ( ®i; N -~ 0® ) { sout | i; }
     608for ( ®N® ) { sout | "N"; } sout | nl;
     609for ( ®i; N® ) { sout | i; } sout | nl;
     610for ( ®i; N -~ 0® ) { sout | i; } sout | nl;
    593611const int start = 3, comp = 10, inc = 2;
    594 for ( ®i; start ~ comp ~ inc + 1® ) { sout | i; }
     612for ( ®i; start ~ comp ~ inc + 1® ) { sout | i; } sout | nl;
     613for ( ®i; 1 ~ @® ) { if ( i > 10 ) break;
     614        sout | i; } sout | nl;
     615for ( ®i; 10 -~ @® ) { if ( i < 0 ) break;
     616        sout | i; } sout | nl;
     617for ( ®i; 2 ~ @ ~ 2® ) { if ( i > 10 ) break;
     618        sout | i; } sout | nl;
     619for ( ®i; 2.1 ~ @ ~ @® ) { if ( i > 10.5 ) break;
     620        sout | i; i += 1.7; } sout | nl;
     621for ( ®i; 10 -~ @ ~ 2® ) { if ( i < 0 ) break;
     622        sout | i; } sout | nl;
     623for ( ®i; 12.1 ~ @ ~ @® ) { if ( i < 2.5 ) break;
     624        sout | i; i -= 1.7; } sout | nl;
     625for ( ®i; 5 : j; -5 ~ @® ) { sout | i | j; } sout | nl;
     626for ( ®i; 5 : j; -5 -~ @® ) { sout | i | j; } sout | nl;
     627for ( ®i; 5 : j; -5 ~ @ ~ 2® ) { sout | i | j; } sout | nl;
     628for ( ®i; 5 : j; -5 -~ @ ~ 2® ) { sout | i | j; } sout | nl;
     629for ( ®j; -5 ~ @ : i; 5® ) { sout | i | j; } sout | nl;
     630for ( ®j; -5 -~ @ : i; 5® ) { sout | i | j; } sout | nl;
     631for ( ®j; -5 ~ @ ~ 2 : i; 5® ) { sout | i | j; } sout | nl;
     632for ( ®j; -5 -~ @ ~ 2 : i; 5® ) { sout | i | j; } sout | nl;
     633for ( ®j; -5 -~ @ ~ 2 : i; 5 : k; 1.5 ~ @® ) {
     634        sout | i | j | k; } sout | nl;
     635for ( ®j; -5 -~ @ ~ 2 : k; 1.5 ~ @ : i; 5® ) {
     636        sout | i | j | k; } sout | nl;
     637for ( ®k; 1.5 ~ @ : j; -5 -~ @ ~ 2 : i; 5® ) {
     638        sout | i | j | k; } sout | nl;
    595639\end{cfa}
    596640&
    597641\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
    624643empty
    625644empty
     
    645664
    6466653 6 9
     666
     6671 2 3 4 5 6 7 8 9 10
     668
     66910 9 8 7 6 5 4 3 2 1 0
     670
     6712 4 6 8 10
     672
     6732.1 3.8 5.5 7.2 8.9
     674
     67510 8 6 4 2 0
     676
     67712.1 10.4 8.7 7 5.3 3.6
     6780 -5 1 -4 2 -3 3 -2 4 -1
     6790 -5 1 -6 2 -7 3 -8 4 -9
     6800 -5 1 -3 2 -1 3 1 4 3
     6810 -5 1 -7 2 -9 3 -11 4 -13
     6820 -5 1 -4 2 -3 3 -2 4 -1
     6830 -5 1 -6 2 -7 3 -8 4 -9
     6840 -5 1 -3 2 -1 3 1 4 3
     6850 -5 1 -7 2 -9 3 -11 4 -13
     686
     6870 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5
     688
     6890 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5
     690
     6910 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5
    647692\end{cfa}
    648693\end{tabular}
    649694\end{cquote}
     695\caption{Loop Control Examples}
     696\label{f:LoopControlExamples}
     697\end{figure}
    650698
    651699
  • libcfa/prelude/prelude-gen.cc

    rdeca0f5 r8c3a0336  
    1010// Created On       : Sat Feb 16 08:44:58 2019
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Mar 19 08:19:35 2019
    13 // Update Count     : 28
     12// Last Modified On : Tue Apr  2 17:18:24 2019
     13// Update Count     : 37
    1414//
    1515
     
    118118        { "?!=?", false, "signed int", Normal, "" },
    119119        { "?=?", true, "", Normal, "" }, // void * LHS, zero_t RHS ???
    120         { "*?", false, "&", Normal, " | sized(DT)" }, // & ???
     120//      { "*?", false, "&", Normal, " | sized(DT)" }, // & ???
     121        { "*?", false, "&", Normal, "" }, // & ???
    121122
    122123        { "?-?", false, "ptrdiff_t", Normal, " | sized(DT)" },
  • libcfa/src/fstream.cfa

    rdeca0f5 r8c3a0336  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 28 17:39:53 2019
    13 // Update Count     : 307
     12// Last Modified On : Sat Apr 20 12:03:43 2019
     13// Update Count     : 311
    1414//
    1515
     
    3333        os.nlOnOff = nlOnOff;
    3434        os.prt = prt;
     35        os.sawNL = false;
    3536        sepSet( os, separator );
    3637        sepSetCur( os, sepGet( os ) );
     
    162163void ?{}( ifstream & is, void * file ) {
    163164        is.file = file;
     165        is.nlOnOff = false;
    164166}
    165167
     
    173175        open( is, name, "r" );
    174176}
     177
     178void nlOn( ifstream & os ) { os.nlOnOff = true; }
     179void nlOff( ifstream & os ) { os.nlOnOff = false; }
     180bool getANL( ifstream & os ) { return os.nlOnOff; }
    175181
    176182int fail( ifstream & is ) {
  • libcfa/src/fstream.hfa

    rdeca0f5 r8c3a0336  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Dec 24 18:33:41 2018
    13 // Update Count     : 149
     12// Last Modified On : Sat Apr 20 12:03:58 2019
     13// Update Count     : 151
    1414//
    1515
     
    7373struct ifstream {
    7474        void * file;
     75        bool nlOnOff;
    7576}; // ifstream
    7677
    7778// public
     79void nlOn( ifstream & );
     80void nlOff( ifstream & );
     81bool getANL( ifstream & );
    7882int fail( ifstream & is );
    7983int eof( ifstream & is );
  • libcfa/src/gmp.hfa

    rdeca0f5 r8c3a0336  
    1010// Created On       : Tue Apr 19 08:43:43 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Dec  4 23:25:51 2018
    13 // Update Count     : 22
     12// Last Modified On : Sat Apr 20 09:01:52 2019
     13// Update Count     : 24
    1414//
    1515
     
    271271
    272272        void ?|?( ostype & os, Int mp ) {
    273                 (ostype)(os | mp); if ( getANL( os ) ) nl( os );
     273                (ostype)(os | mp); nl( os );
    274274        } // ?|?
    275275} // distribution
  • libcfa/src/iostream.cfa

    rdeca0f5 r8c3a0336  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Mar  4 20:57:24 2019
    13 // Update Count     : 593
     12// Last Modified On : Sat Apr 20 14:02:43 2019
     13// Update Count     : 617
    1414//
    1515
     
    396396
    397397        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
    399405                return is;
    400406        } // ?|?
     
    498504                return is;
    499505        } // 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
    500516} // distribution
    501517
  • libcfa/src/iostream.hfa

    rdeca0f5 r8c3a0336  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb 26 16:57:22 2019
    13 // Update Count     : 221
     12// Last Modified On : Sat Apr 20 12:04:07 2019
     13// Update Count     : 226
    1414//
    1515
     
    149149
    150150trait istream( dtype istype ) {
     151        void nlOn( istype & );                                                          // read newline
     152        void nlOff( istype & );                                                         // scan newline
     153        bool getANL( istype & );                                                        // get scan newline (on/off)
    151154        int fail( istype & );
    152155        int eof( istype & );
     
    187190
    188191        // manipulators
     192        istype & nlOn( istype & );
     193        istype & nlOff( istype & );
    189194        istype & ?|?( istype &, istype & (*)( istype & ) );
    190195        istype & nl( istype & is );
  • src/Parser/ParseNode.h

    rdeca0f5 r8c3a0336  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Feb 13 17:36:49 2019
    13 // Update Count     : 867
     12// Last Modified On : Mon Apr 15 14:22:39 2019
     13// Update Count     : 874
    1414//
    1515
     
    132132        void printOneLine( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}
    133133
    134         Expression *get_expr() const { return expr.get(); }
    135134        template<typename T>
    136135        bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); }
    137136
    138137        Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); }
     138
     139        std::unique_ptr<Expression> expr;                                       // public because of lifetime implications
    139140  private:
    140141        bool extension = false;
    141         std::unique_ptr<Expression> expr;
    142142}; // ExpressionNode
    143143
  • src/Parser/parser.yy

    rdeca0f5 r8c3a0336  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 15 14:25:43 2019
    13 // Update Count     : 4248
     12// Last Modified On : Mon Apr 15 15:02:56 2019
     13// Update Count     : 4290
    1414//
    1515
     
    185185
    186186ForCtrl * 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());
    188188        if ( constant && (constant->get_constant()->get_value() == "0" || constant->get_constant()->get_value() == "1") ) {
    189189        type = new ExpressionNode( new CastExpr( maybeMoveBuild< Expression >(type), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ) );
     
    198198
    199199ForCtrl * 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()) ) {
    201201                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()) ) {
    203203                if ( NameExpr * identifier = dynamic_cast<NameExpr *>(commaExpr->arg1 ) ) {
    204204                        return forCtrl( type, new string( identifier->name ), start, compop, comp, inc );
     
    334334%type<en> subrange
    335335%type<decl> asm_name_opt
    336 %type<en> asm_operands_opt asm_operands_list asm_operand
     336%type<en> asm_operands_opt                              asm_operands_list                       asm_operand
    337337%type<label> label_list
    338338%type<en> asm_clobbers_list_opt
    339339%type<flag> asm_volatile_opt
    340340%type<en> handler_predicate_opt
    341 %type<genexpr> generic_association generic_assoc_list
     341%type<genexpr> generic_association              generic_assoc_list
    342342
    343343// statements
     
    11641164        for_control_expression
    11651165        | 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                }
    11671184        ;
    11681185
     
    11741191        | declaration comma_expression_opt ';' comma_expression_opt // C99, declaration has ';'
    11751192                { $$ = new ForCtrl( $1, $2, $4 ); }
     1193
    11761194        | comma_expression                                                                      // CFA
    11771195                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
     
    11881206        | comma_expression ';' comma_expression inclexcl comma_expression '~' comma_expression // CFA
    11891207                { $$ = 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" ) ) ) ); }
    11901214        | comma_expression ';' comma_expression '~' '@' '~' comma_expression // CFA
    11911215                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, $7 ); }
  • src/ResolvExpr/AlternativeFinder.cc

    rdeca0f5 r8c3a0336  
    258258                        // - necessary pre-requisite to pruning
    259259                        AltList candidates;
     260                        std::list<std::string> errors;
    260261                        for ( unsigned i = 0; i < alternatives.size(); ++i ) {
    261                                 resolveAssertions( alternatives[i], indexer, candidates );
     262                                resolveAssertions( alternatives[i], indexer, candidates, errors );
    262263                        }
    263264                        // fail early if none such
    264265                        if ( mode.failFast && candidates.empty() ) {
    265266                                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                                }
    269273                                SemanticError( expr->location, stream.str() );
    270274                        }
  • src/ResolvExpr/ResolveAssertions.cc

    rdeca0f5 r8c3a0336  
    2020#include <list>                     // for list
    2121#include <memory>                   // for unique_ptr
    22 #include <string>
     22#include <sstream>                  // for ostringstream
     23#include <string>                   // for string
    2324#include <unordered_map>            // for unordered_map, unordered_multimap
    2425#include <utility>                  // for move
     
    2728#include "Alternative.h"            // for Alternative, AssertionItem, AssertionList
    2829#include "Common/FilterCombos.h"    // for filterCombos
     30#include "Common/Indenter.h"        // for Indenter
    2931#include "Common/utility.h"         // for sort_mins
    3032#include "ResolvExpr/RenameVars.h"  // for renameTyVars
     
    9799                        return { item, item.matches[i] };
    98100                }
     101
     102                const DeclarationWithType* get_decl() const { return cache->at(key).deferIds[0].decl; }
    99103
    100104                // sortable by key
     
    364368        static const int recursionLimit = /* 10 */ 4;
    365369
    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 ) {
    367371                // finish early if no assertions to resolve
    368372                if ( alt.need.empty() ) {
     
    385389                                for ( auto& assn : resn.need ) {
    386390                                        // 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                                        }
    388402                                }
    389403
     
    404418                                                resn.deferred,
    405419                                                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                                        }
    406435                                        // sort by cost
    407436                                        CandidateCost coster{ resn.indexer };
  • src/ResolvExpr/ResolveAssertions.h

    rdeca0f5 r8c3a0336  
    2424namespace ResolvExpr {
    2525        /// 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 );
    2727} // namespace ResolvExpr
    2828
  • src/ResolvExpr/TypeEnvironment.cc

    rdeca0f5 r8c3a0336  
    386386        }
    387387
    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 ) {
    389391
    390392                auto class1 = internal_lookup( var1->get_name() );
     
    428430                                        class1->set_type( common );
    429431                                }
     432                                class1->data.isComplete |= data.isComplete;
    430433                                env.erase( class2 );
    431434                        } else return false;
     
    435438                                class1->vars.insert( class2->vars.begin(), class2->vars.end() );
    436439                                class1->allowWidening = widen1;
     440                                class1->data.isComplete |= data.isComplete;
    437441                                env.erase( class2 );
    438442                        } else {
    439443                                class2->vars.insert( class1->vars.begin(), class1->vars.end() );
    440444                                class2->allowWidening = widen2;
     445                                class2->data.isComplete |= data.isComplete;
    441446                                env.erase( class1 );
    442447                        } // if
     
    445450                        class1->vars.insert( var2->get_name() );
    446451                        class1->allowWidening = widen1;
     452                        class1->data.isComplete |= data.isComplete;
    447453                } else if ( class2 != env.end() ) {
    448454                        // var1 unbound, add to class2
    449455                        class2->vars.insert( var1->get_name() );
    450456                        class2->allowWidening = widen2;
     457                        class2->data.isComplete |= data.isComplete;
    451458                } else {
    452459                        // neither var bound, create new class
  • src/ResolvExpr/TypeEnvironment.h

    rdeca0f5 r8c3a0336  
    139139                /// Binds the type classes represented by `var1` and `var2` together; will add
    140140                /// 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 );
    142142
    143143                /// Disallows widening for all bindings in the environment
  • src/ResolvExpr/Unify.cc

    rdeca0f5 r8c3a0336  
    172172                bool isopen2 = var2 && ( entry2 != openVars.end() );
    173173
    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                        }
    176182                } else if ( isopen1 ) {
    177183                        result = env.bindVar( var1, type2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer );
  • src/SynTree/Declaration.h

    rdeca0f5 r8c3a0336  
    211211                TypeDecl::Kind kind;
    212212                bool isComplete;
     213               
    213214                Data() : kind( (TypeDecl::Kind)-1 ), isComplete( false ) {}
    214215                Data( TypeDecl * typeDecl ) : Data( typeDecl->get_kind(), typeDecl->isComplete() ) {}
    215216                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
    216220                bool operator==(const Data & other) const { return kind == other.kind && isComplete == other.isComplete; }
    217221                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
     1completeTypeError.cfa:34:1 error: Cannot choose between 2 alternatives for expression
     2Generated Cast of:
     3  Applying untyped:
     4    Name: *?
     5  ...to:
     6    Name: x
    57
    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:
     9Cost ( 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
     32Cost ( 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
    1055
    1156completeTypeError.cfa:35:1 error: No reasonable alternatives for expression Applying untyped:
     
    2469  Name: v
    2570
    26 completeTypeError.cfa:58:1 error: No reasonable alternatives for expression Applying untyped:
     71completeTypeError.cfa:59:1 error: No reasonable alternatives for expression Applying untyped:
    2772  Name: baz
    2873...to:
    2974  Name: y
    3075
    31 completeTypeError.cfa:59:1 error: No reasonable alternatives for expression Applying untyped:
     76completeTypeError.cfa:60:1 error: No reasonable alternatives for expression Applying untyped:
    3277  Name: quux
    3378...to:
    3479  Name: y
    3580
    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:
     81completeTypeError.cfa:72:1 error: No alternatives with satisfiable assertions for Applying untyped:
    4282  Name: baz
    4383...to:
    4484  Name: z
    4585
    46 Alternatives with failing assertions are:
     86   Unsatisfiable alternative:
    4787Cost ( 0, 1, 0, 0, 1, -5, 0 ): Application of
    48      Variable Expression: baz: forall
    49        T: sized object type
    50        ... with assertions
    51          ?=?: pointer to function
    52          ... with parameters
    53            reference to instance of type T (not function type)
    54            instance of type T (not function type)
    55          ... returning
    56            _retval__operator_assign: instance of type T (not function type)
    57            ... with attributes:
    58              Attribute with name: unused
     88         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
    5999
    60100
    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
    62119         ... with parameters
    63            reference to instance of type T (not function type)
     120           pointer to instance of type T (not function type)
    64121         ... returning nothing
    65122
    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)
    71125
    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
    76140
    77141
    78        function
    79      ... with parameters
    80        pointer to instance of type T (not function type)
    81      ... returning nothing
    82 
    83    ... to arguments
    84      Variable Expression: z: pointer to instance of type T (not function type)
    85 
    86  (types:
    87    void
    88  )
    89  Environment:( _99_0_T ) -> instance of type T (not function type) (no widening)
    90 
    91 
    92 
  • tests/.expect/loopctrl.txt

    rdeca0f5 r8c3a0336  
    191910 8 6 4 2
    2020
     211 2 3 4 5 6 7 8 9 10
     2210 9 8 7 6 5 4 3 2 1 0
    21232 4 6 8 10
    22242.1 3.8 5.5 7.2 8.9
     
    4244(10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0)
    4345(10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0)
     46
     470 -5 1 -4 2 -3 3 -2 4 -1 5 0 6 1 7 2 8 3 9 4
     480 -5 1 -6 2 -7 3 -8 4 -9 5 -10 6 -11 7 -12 8 -13 9 -14
     490 -5 1 -3 2 -1 3 1 4 3 5 5 6 7 7 9 8 11 9 13
     500 -5 1 -7 2 -9 3 -11 4 -13 5 -15 6 -17 7 -19 8 -21 9 -23
     51
     520 -5 1 -4 2 -3 3 -2 4 -1 5 0 6 1 7 2 8 3 9 4
     530 -5 1 -6 2 -7 3 -8 4 -9 5 -10 6 -11 7 -12 8 -13 9 -14
     540 -5 1 -3 2 -1 3 1 4 3 5 5 6 7 7 9 8 11 9 13
     550 -5 1 -7 2 -9 3 -11 4 -13 5 -15 6 -17 7 -19 8 -21 9 -23
     56
     570 -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
     580 -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
     590 -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  
    4444CC = @CFACC@
    4545
    46 PRETTY_PATH=cd ${srcdir} &&
     46PRETTY_PATH=mkdir -p $(dir $(abspath ${@})) && cd ${srcdir} &&
    4747
    4848.PHONY: list .validate
     
    8585#----------------------------------------------------------------------------------------------------------------
    8686
     87# Use for all tests, make sure the path are correct and all flags are added
     88CFACOMPILETEST=$(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
     91CFATEST_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
     94CFATEST_STDERR=$(CFACOMPILETEST) 2> $(abspath ${@})
     95
     96#----------------------------------------------------------------------------------------------------------------
     97
    8798# implicit rule so not all test require a rule
    8899% : %.cfa $(CFACC)
    89         $(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
     100        $(CFATEST_STDOUT)
    90101
    91102% : %.cpp
    92103        $(PRETTY_PATH) $(CXXCOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
    93104
    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
     109declarationSpecifier_FLAGS= -CFA -XCFA -p
     110gccExtensions_FLAGS= -CFA -XCFA -p
     111extension_FLAGS= -CFA -XCFA -p
     112attributes_FLAGS= -CFA -XCFA -p
     113functions_FLAGS= -CFA -XCFA -p
     114KRfunctions_FLAGS= -CFA -XCFA -p
     115gmp_FLAGS= -lgmp
    96116
    97 gccExtensions : gccExtensions.cfa $(CFACC)
    98         $(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
     117#------------------------------------------------------------------------------
     118# Expected failures
     119completeTypeError_FLAGS= -DERR1
    99120
    100 extension : extension.cfa $(CFACC)
    101         $(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
     121#------------------------------------------------------------------------------
     122# CUSTOM TARGET
     123#------------------------------------------------------------------------------
     124typedefRedef-ERR1: typedefRedef.cfa $(CFACC)
     125        $(CFATEST_STDOUT) -DERR1
    102126
    103 attributes : attributes.cfa $(CFACC)
    104         $(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
     127alloc-ERROR: alloc.cfa $(CFACC)
     128        $(CFATEST_STDOUT) -DERR1
    105129
    106 functions: functions.cfa $(CFACC)
    107         $(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
     130nested-types-ERR1: nested-types.cfa $(CFACC)
     131        $(CFATEST_STDOUT) -DERR1
    108132
    109 KRfunctions : KRfunctions.cfa $(CFACC)
    110         $(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
     133nested-types-ERR2: nested-types.cfa $(CFACC)
     134        $(CFATEST_STDOUT) -DERR2
    111135
    112 sched-ext-parse : sched-ext-parse.c $(CFACC)
    113         $(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
     136raii/dtor-early-exit-ERR1: raii/dtor-early-exit.cfa $(CFACC)
     137        $(CFATEST_STDOUT) -DERR1
    114138
    115 gmp : gmp.cfa $(CFACC)
    116         $(PRETTY_PATH) $(CFACOMPILE) -lgmp $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
     139raii/dtor-early-exit-ERR2: raii/dtor-early-exit.cfa $(CFACC)
     140        $(CFATEST_STDOUT) -DERR2
     141
     142raii/memberCtors-ERR1: raii/memberCtors.cfa $(CFACC)
     143        $(CFATEST_STDOUT) -DERR1
     144
     145raii/ctor-autogen-ERR1: raii/ctor-autogen.cfa $(CFACC)
     146        $(CFATEST_STDOUT) -DERR1
    117147
    118148#builtins
    119149builtins/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
    155151
    156152# Warnings
    157153warnings/self-assignment: warnings/self-assignment.cfa $(CFACC)
    158         $(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) 2> $(abspath ${@}) -fsyntax-only
     154        $(CFATEST_STDERR) -fsyntax-only
  • tests/Makefile.in

    rdeca0f5 r8c3a0336  
    386386        -quiet @CFA_FLAGS@ -DIN_DIR="${abs_srcdir}/.in/" \
    387387        ${DEBUG_FLAGS} ${INSTALL_FLAGS} ${ARCH_FLAGS}
    388 PRETTY_PATH = cd ${srcdir} &&
     388PRETTY_PATH = mkdir -p $(dir $(abspath ${@})) && cd ${srcdir} &&
    389389avl_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
    390390# automake doesn't know we still need C/CPP rules so pretend like we have a C program
    391391_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
     396CFACOMPILETEST = $(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
     399CFATEST_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
     402CFATEST_STDERR = $(CFACOMPILETEST) 2> $(abspath ${@})
     403
     404#------------------------------------------------------------------------------
     405# TARGET WITH STANDARD RULE BUT CUSTOM FLAGS
     406#------------------------------------------------------------------------------
     407# Expected failures
     408declarationSpecifier_FLAGS = -CFA -XCFA -p
     409gccExtensions_FLAGS = -CFA -XCFA -p
     410extension_FLAGS = -CFA -XCFA -p
     411attributes_FLAGS = -CFA -XCFA -p
     412functions_FLAGS = -CFA -XCFA -p
     413KRfunctions_FLAGS = -CFA -XCFA -p
     414gmp_FLAGS = -lgmp
     415
     416#------------------------------------------------------------------------------
     417# Expected failures
     418completeTypeError_FLAGS = -DERR1
    392419all: all-am
    393420
     
    772799# implicit rule so not all test require a rule
    773800% : %.cfa $(CFACC)
    774         $(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
     801        $(CFATEST_STDOUT)
    775802
    776803% : %.cpp
    777804        $(PRETTY_PATH) $(CXXCOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
    778805
    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#------------------------------------------------------------------------------
     809typedefRedef-ERR1: typedefRedef.cfa $(CFACC)
     810        $(CFATEST_STDOUT) -DERR1
     811
     812alloc-ERROR: alloc.cfa $(CFACC)
     813        $(CFATEST_STDOUT) -DERR1
     814
     815nested-types-ERR1: nested-types.cfa $(CFACC)
     816        $(CFATEST_STDOUT) -DERR1
     817
     818nested-types-ERR2: nested-types.cfa $(CFACC)
     819        $(CFATEST_STDOUT) -DERR2
     820
     821raii/dtor-early-exit-ERR1: raii/dtor-early-exit.cfa $(CFACC)
     822        $(CFATEST_STDOUT) -DERR1
     823
     824raii/dtor-early-exit-ERR2: raii/dtor-early-exit.cfa $(CFACC)
     825        $(CFATEST_STDOUT) -DERR2
     826
     827raii/memberCtors-ERR1: raii/memberCtors.cfa $(CFACC)
     828        $(CFATEST_STDOUT) -DERR1
     829
     830raii/ctor-autogen-ERR1: raii/ctor-autogen.cfa $(CFACC)
     831        $(CFATEST_STDOUT) -DERR1
    802832
    803833#builtins
    804834builtins/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
    840836
    841837# Warnings
    842838warnings/self-assignment: warnings/self-assignment.cfa $(CFACC)
    843         $(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) 2> $(abspath ${@}) -fsyntax-only
     839        $(CFATEST_STDERR) -fsyntax-only
    844840
    845841# Tell versions [3.59,3.63) of GNU make to not export all variables.
  • tests/completeTypeError.cfa

    rdeca0f5 r8c3a0336  
    55forall(dtype T | sized(T)) void quux(T *);
    66
    7 struct A; // incomplete
    8 struct B {}; // complete
     7struct A;       // incomplete
     8struct B {};    // complete
    99
    1010int main() {
    11         int *i;
    12         void *v;
     11        int * i;
     12        void * v;
    1313
    1414        A * x;
     
    1919        // okay
    2020        *i;
    21         *x; // picks B
     21        *y;
    2222        *z;
    2323        foo(i);
     
    3232        // bad
    3333        *v;
    34         *y;
     34        *x;     // ambiguous
    3535        foo(v);
    3636        baz(v);
     
    5252void qux(T * y) {
    5353        // okay
     54        *y;
    5455        bar(y);
    5556        qux(y);
     
    5859        baz(y);
    5960        quux(y);
    60         *y;
    6161}
    6262
  • tests/coroutine/devicedriver.cfa

    rdeca0f5 r8c3a0336  
    1010// Created On       : Sat Mar 16 15:30:34 2019
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Mar 19 15:59:06 2019
    13 // Update Count     : 87
     12// Last Modified On : Sat Apr 20 09:07:19 2019
     13// Update Count     : 90
    1414//
    1515
     
    6767        char msg[65], byte;
    6868        Driver driver = { msg };
     69
     70        sin | nlOn;                                                                                     // read newline (all) characters
    6971  eof: for () {                                                                                 // read until end of file
    7072                sin | byte;                                                                             // read one character
  • tests/function-operator.cfa

    rdeca0f5 r8c3a0336  
    1010// Created On       : Fri Aug 25 15:21:11 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Dec  4 21:37:09 2018
    13 // Update Count     : 9
     12// Last Modified On : Thu Apr 11 18:27:45 2019
     13// Update Count     : 10
    1414//
    1515
     
    6262
    6363// 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))
     64forall(otype Generator, otype GenRet | { GenRet ?()(Generator &); }, dtype Iter, otype T | Iterator(Iter, T) | Assignable(T, GenRet))
    6565void generate(Iter first, Iter last, Generator & gen) {
    6666        int i = 0;
  • tests/io2.cfa

    rdeca0f5 r8c3a0336  
    1010// Created On       : Wed Mar  2 16:56:02 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Dec 21 08:20:14 2018
    13 // Update Count     : 112
     12// Last Modified On : Thu Apr 18 08:03:30 2019
     13// Update Count     : 113
    1414//
    1515
     
    9797        sout | 1 | sepOff | 2 | 3;                                                      // locally turn off implicit separator
    9898        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;                                       // no separator at start of next line
     99        sout | 1 | 2 | 3 | "\n\n" | sepOn | nonl;                       // no separator at start of next line
    100100        sout | 1 | 2 | 3;
    101101        sout | nl;
  • tests/loopctrl.cfa

    rdeca0f5 r8c3a0336  
    1010// Created On       : Wed Aug  8 18:32:59 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb 21 08:54:47 2019
    13 // Update Count     : 86
     12// Last Modified On : Sat Apr 13 11:03:09 2019
     13// Update Count     : 104
    1414//
    1515
     
    5656        for ( ui; 10u -~= 2u ~ 2u ) { sout | ui; }                      sout | nl | nl;
    5757
     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;
    5867        for ( i; 2 ~ @ ~ 2 ) {
    5968          if ( i > 10 ) break;
     
    94103        for ( s; (S){10,10} -~ (S){0} ~ (S){1} ) { sout | s; } sout | nl;
    95104        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;
    97120}
    98121
Note: See TracChangeset for help on using the changeset viewer.