Changeset 638ac26


Ignore:
Timestamp:
Jul 6, 2018, 2:18:34 PM (3 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, no_list, persistent-indexer
Children:
46e480a5
Parents:
e3b2474 (diff), 1d386a7 (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' of plg.uwaterloo.ca:/u/cforall/software/cfa/cfa-cc

Files:
3 added
9 edited
1 moved

Legend:

Unmodified
Added
Removed
  • .gitignore

    re3b2474 r638ac26  
    3131src/driver/cfa-cpp
    3232
     33src/prelude/bootloader.c
    3334src/prelude/builtins.cf
     35src/prelude/extras.cf
    3436src/prelude/gcc-builtins.cf
    3537src/prelude/gcc-builtins.c
    36 src/prelude/extras.cf
    37 src/prelude/bootloader.c
     38src/prelude/prelude.cf
    3839src/libcfa/libcfa-prelude.c
    3940
  • doc/papers/AMA/AMA-stix/ama/WileyNJD-v2.cls

    re3b2474 r638ac26  
    34063406\hskip-\parindentvalue\fbox{\vbox{\noindent\@jnlcitation}}}%
    34073407
    3408 \AtEndDocument{\ifappendixsec\else\printjnlcitation\fi}%
     3408%\AtEndDocument{\ifappendixsec\else\printjnlcitation\fi}%
    34093409
    34103410%% Misc math macros %%
  • doc/papers/general/Makefile

    re3b2474 r638ac26  
    4646
    4747Paper.zip :
    48         zip -x general/.gitignore -x general/"*AMA*" -x general/Paper.out.ps -x general/Paper.tex.plain -x general/evaluation.zip -x general/mail -x general/response -x general/test.c -x general/evaluation.zip -x general/Paper.tex.plain -x general/Paper.ps -x general/Paper.pdf -x general/"*build*" -x general/evaluation/.gitignore -x general/evaluation/timing.xlsx -r Paper.zip general
     48        zip -x general/.gitignore -x general/Paper.out.ps -x general/Paper.tex.plain -x -x general/WileyNJD-AMA.bst general/"*evaluation*" -x general/evaluation.zip \
     49                -x general/mail -x general/response -x general/test.c -x general/Paper.ps -x general/"*build*" -r Paper.zip general pl.bib
    4950
    5051evaluation.zip :
    51         zip -x evaluation/.gitignore  -x evaluation/timing.xlsx -x evaluation/timing.dat -r evaluation.zip evaluation
     52        zip -x evaluation/.gitignore -x evaluation/timing.xlsx -x evaluation/timing.dat -r evaluation.zip evaluation
    5253
    5354# File Dependencies #
  • doc/papers/general/Paper.tex

    re3b2474 r638ac26  
    210210Specifically, \CFA is designed to have an orthogonal feature-set based closely on the C programming paradigm, so that \CFA features can be added \emph{incrementally} to existing C code-bases, and C programmers can learn \CFA extensions on an as-needed basis, preserving investment in existing code and programmers.
    211211This paper presents a quick tour of \CFA features showing how their design avoids shortcomings of similar features in C and other C-like languages.
    212 Finally, experimental results are presented to validate several of the new features.
     212Experimental results are presented to validate several of the new features.
    213213}%
    214214
     
    255255Not discussed in this paper are the integrated concurrency-constructs and user-level threading-library~\cite{Delisle18}.
    256256\CFA is an \emph{open-source} project implemented as a source-to-source translator from \CFA to the gcc-dialect of C~\cite{GCCExtensions}, allowing it to leverage the portability and code optimizations provided by gcc, meeting goals (1)--(3).
    257 Ultimately, a compiler is necessary for advanced features and optimal performance.
    258257% @plg2[9]% cd cfa-cc/src; cloc ArgTweak CodeGen CodeTools Common Concurrency ControlStruct Designators GenPoly InitTweak MakeLibCfa.cc MakeLibCfa.h Parser ResolvExpr SymTab SynTree Tuples driver prelude main.cc
    259258% -------------------------------------------------------------------------------
     
    271270% -------------------------------------------------------------------------------
    272271The \CFA translator is 200+ files and 46,000+ lines of code written in C/\CC.
    273 Starting with a translator versus a compiler makes it easier and faster to generate and debug C object-code rather than intermediate, assembler or machine code.
    274 The translator design is based on the \emph{visitor pattern}, allowing multiple passes over the abstract code-tree, which works well for incrementally adding new feature through additional visitor passes.
    275 At the heart of the translator is the type resolver, which handles the polymorphic function/type overload-resolution.
     272A translator versus a compiler makes it easier and faster to generate and debug C object-code rather than intermediate, assembler or machine code;
     273ultimately, a compiler is necessary for advanced features and optimal performance.
     274% The translator design is based on the \emph{visitor pattern}, allowing multiple passes over the abstract code-tree, which works well for incrementally adding new feature through additional visitor passes.
     275Two key translator components are expression analysis, determining expression validity and what operations are required for its implementation, and code generation, dealing with multiple forms of overloading, polymorphism, and multiple return values by converting them into C code for a C compiler that supports none of these features.
     276Details of these components are available in Bilson~\cite{Bilson03} Chapters 2 and 3, and form the base for the current \CFA translator.
    276277% @plg2[8]% cd cfa-cc/src; cloc libcfa
    277278% -------------------------------------------------------------------------------
     
    305306% SUM:                           290          13175           3400          27776
    306307% -------------------------------------------------------------------------------
    307 The \CFA tests are 290+ files and 27,000+ lines of code.
    308 The tests illustrate syntactic and semantic features in \CFA, plus a growing number of runtime benchmarks.
    309 The tests check for correctness and are used for daily regression testing of 3800+ commits.
    310 
    311 Finally, it is impossible to describe a programming language without usages before definitions.
    312 Therefore, syntax and semantics appear before explanations, and related work (Section~\ref{s:RelatedWork}) is deferred until \CFA is presented;
    313 hence, patience is necessary until details are discussed.
     308% The \CFA tests are 290+ files and 27,000+ lines of code.
     309% The tests illustrate syntactic and semantic features in \CFA, plus a growing number of runtime benchmarks.
     310% The tests check for correctness and are used for daily regression testing of 3800+ commits.
     311
     312Finally, it is impossible to describe a programming language without usage before definition.
     313Therefore, syntax and semantics appear before explanations;
     314hence, patience is necessary until sufficient details are presented and discussed.
     315Similarly, a detailed comparison with other programming languages is postponed until Section~\ref{s:RelatedWork}.
    314316
    315317
     
    18721874\begin{itemize}
    18731875\item
    1874 if @R@ is an rvalue of type {@T &@$_1 \cdots$@ &@$_r$} where $r \ge 1$ references (@&@ symbols) then @&R@ has type {@T `*`&@$_{\color{red}2} \cdots$@ &@$_{\color{red}r}$}, \\ \ie @T@ pointer with $r-1$ references (@&@ symbols).
    1875        
     1876if @R@ is an rvalue of type @T &@$_1\cdots$ @&@$_r$, where $r \ge 1$ references (@&@ symbols), than @&R@ has type @T `*`&@$_{\color{red}2}\cdots$ @&@$_{\color{red}r}$, \ie @T@ pointer with $r-1$ references (@&@ symbols).
    18761877\item
    1877 if @L@ is an lvalue of type {@T &@$_1 \cdots$@ &@$_l$} where $l \ge 0$ references (@&@ symbols) then @&L@ has type {@T `*`&@$_{\color{red}1} \cdots$@ &@$_{\color{red}l}$}, \\ \ie @T@ pointer with $l$ references (@&@ symbols).
     1878if @L@ is an lvalue of type @T &@$_1\cdots$ @&@$_l$, where $l \ge 0$ references (@&@ symbols), than @&L@ has type @T `*`&@$_{\color{red}1}\cdots$ @&@$_{\color{red}l}$, \ie @T@ pointer with $l$ references (@&@ symbols).
    18781879\end{itemize}
    18791880Since pointers and references share the same internal representation, code using either is equally performant; in fact the \CFA compiler converts references to pointers internally, and the choice between them is made solely on convenience, \eg many pointer or value accesses.
     
    28342835Finally, we demonstrate that \CFA performance for some idiomatic cases is better than C and close to \CC, showing the design is practically applicable.
    28352836
    2836 While all examples in the paper compile and run, a public beta-release of \CFA will take 6--8 months to reduce compilation time, provide better debugging, and add a few more libraries.
     2837While all examples in the paper compile and run, there are ongoing efforts to reduce compilation time, provide better debugging, and add more libraries;
     2838when this work is complete in early 2019, a public beta release will be available at \url{https://github.com/cforall/cforall}.
    28372839There is also new work on a number of \CFA features, including arrays with size, runtime type-information, virtual functions, user-defined conversions, and modules.
    28382840While \CFA polymorphic functions use dynamic virtual-dispatch with low runtime overhead (see Section~\ref{sec:eval}), it is not as low as \CC template-inlining.
    28392841Hence it may be beneficial to provide a mechanism for performance-sensitive code.
    28402842Two promising approaches are an @inline@ annotation at polymorphic function call sites to create a template-specialization of the function (provided the code is visible) or placing an @inline@ annotation on polymorphic function-definitions to instantiate a specialized version for some set of types (\CC template specialization).
    2841 These approaches are not mutually exclusive and allow performance optimizations to be applied only when necessary, without suffering global code-bloat.
     2843 These approaches are not mutually exclusive and allow performance optimizations to be applied only when necessary, without suffering global code-bloat.
    28422844In general, we believe separate compilation, producing smaller code, works well with loaded hardware-caches, which may offset the benefit of larger inlined-code.
    28432845
     
    28502852{%
    28512853\fontsize{9bp}{12bp}\selectfont%
     2854\vspace*{-3pt}
    28522855\bibliography{pl}
    28532856}%
  • src/Parser/DeclarationNode.cc

    re3b2474 r638ac26  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun  7 12:08:55 2018
    13 // Update Count     : 1079
     12// Last Modified On : Fri Jul  6 06:56:08 2018
     13// Update Count     : 1088
    1414//
    1515
     
    522522
    523523static void addQualifiersToType( TypeData *&src, TypeData * dst ) {
    524         if ( src->forall && dst->kind == TypeData::Function ) {
    525                 if ( dst->forall ) {
    526                         dst->forall->appendList( src->forall );
    527                 } else {
    528                         dst->forall = src->forall;
    529                 } // if
    530                 src->forall = nullptr;
    531         } // if
    532524        if ( dst->base ) {
    533525                addQualifiersToType( src, dst->base );
     
    10831075                        SemanticError( this, "invalid function specifier for " );
    10841076                } // if
     1077                // Forall qualifier can only appear on a function/aggregate definition/declaration.
     1078                //
     1079                //    forall int f();                                   // allowed
     1080                //    forall int g( int i );                    // allowed
     1081                //    forall int i;                                             // disallowed
     1082                if ( type->kind != TypeData::Function && type->forall ) {
     1083                        SemanticError( this, "invalid type qualifier for " );
     1084                } // if
    10851085                bool isDelete = initializer && initializer->get_isDelete();
    10861086                Declaration * decl = buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild< Expression >( bitfieldWidth ), funcSpecs, linkage, asmName, isDelete ? nullptr : maybeBuild< Initializer >(initializer), attributes )->set_extension( extension );
  • src/Parser/parser.yy

    re3b2474 r638ac26  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jul  2 20:23:14 2018
    13 // Update Count     : 3607
     12// Last Modified On : Fri Jul  6 08:02:38 2018
     13// Update Count     : 3716
    1414//
    1515
     
    116116
    117117void distQual( DeclarationNode * declaration, DeclarationNode * qualifiers ) {
    118         // distribute qualifiers across all declarations in a distribution statemement
     118        // distribute qualifiers across all non-variable declarations in a distribution statemement
    119119        for ( DeclarationNode * iter = declaration; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
    120                 if ( isMangled( iter->linkage ) ) {             // ignore extern "C"
    121                         iter->addQualifiers( qualifiers->clone() );
     120                // SKULLDUGGERY: Distributions are parsed inside out, so qualifiers are added to declarations inside out. Since
     121                // addQualifiers appends to the back of the list, the forall clauses are in the wrong order (right to left). To
     122                // get the qualifiers in the correct order and still use addQualifiers (otherwise, 90% of addQualifiers has to
     123                // be copied to add to front), the appropriate forall pointers are interchanged before calling addQualifiers.
     124                DeclarationNode * clone = qualifiers->clone();
     125                if ( qualifiers->type ) {                                               // forall clause ? (handles SC)
     126                        if ( iter->type->kind == TypeData::Aggregate ) { // struct/union ?
     127                                swap( clone->type->forall, iter->type->aggregate.params );
     128                                iter->addQualifiers( clone );
     129                        } else if ( iter->type->kind == TypeData::AggregateInst && iter->type->aggInst.aggregate->aggregate.body ) { // struct/union ?
     130                                // Create temporary node to hold aggregate, call addQualifiers as above, then put nodes back together.
     131                                DeclarationNode newnode;
     132                                swap( newnode.type, iter->type->aggInst.aggregate );
     133                                swap( clone->type->forall, newnode.type->aggregate.params );
     134                                newnode.addQualifiers( clone );
     135                                swap( newnode.type, iter->type->aggInst.aggregate );
     136                        } else if ( iter->type->kind == TypeData::Function ) { // routines ?
     137                                swap( clone->type->forall, iter->type->forall );
     138                                iter->addQualifiers( clone );
     139                        } // if
     140                } else {                                                                                // just SC qualifiers
     141                        iter->addQualifiers( clone );
    122142                } // if
    123143        } // for
    124 } // distExt
     144        delete qualifiers;
     145} // distQual
    125146
    126147// There is an ambiguity for inline generic-routine return-types and generic routines.
     
    366387%type<decl> type_parameter type_parameter_list type_initializer_opt
    367388
    368 %type<en> type_list
     389%type<en> type_parameters_opt type_list
    369390
    370391%type<decl> type_qualifier type_qualifier_name forall type_qualifier_list_opt type_qualifier_list
     
    406427// Order of these lines matters (low-to-high precedence).
    407428%precedence TYPEGENname
     429%precedence '}'
    408430%precedence '('
    409431
     
    17531775                { $$ = $3->addQualifiers( $1 ); }
    17541776        | sue_type_specifier type_qualifier
    1755                 { $$ = $1->addQualifiers( $2 ); }
     1777                {
     1778                        if ( $2->type != nullptr && $2->type->forall ) forall = true; // remember generic type
     1779                        $$ = $1->addQualifiers( $2 );
     1780                }
    17561781        ;
    17571782
     
    18311856
    18321857aggregate_type:                                                                                 // struct, union
    1833         aggregate_key attribute_list_opt '{' field_declaration_list_opt '}'
    1834                 { $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), nullptr, $4, true )->addQualifiers( $2 ); }
     1858        aggregate_key attribute_list_opt '{' field_declaration_list_opt '}' type_parameters_opt
     1859                { $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), $6, $4, true )->addQualifiers( $2 ); }
    18351860        | aggregate_key attribute_list_opt no_attr_identifier fred
    18361861                {
     
    18381863                        forall = false;                                                         // reset
    18391864                }
    1840           '{' field_declaration_list_opt '}'
    1841                 { $$ = DeclarationNode::newAggregate( $1, $3, nullptr, $7, true )->addQualifiers( $2 ); }
     1865          '{' field_declaration_list_opt '}' type_parameters_opt
     1866                { $$ = DeclarationNode::newAggregate( $1, $3, $9, $7, true )->addQualifiers( $2 ); }
    18421867        | aggregate_key attribute_list_opt type_name fred
    18431868                {
     
    18451870                        forall = false;                                                         // reset
    18461871                }
    1847           '{' field_declaration_list_opt '}'
    1848                 { $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, nullptr, $7, true )->addQualifiers( $2 ); }
    1849         | aggregate_key attribute_list_opt '(' type_list ')' '{' field_declaration_list_opt '}' // CFA
    1850                 { $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), $4, $7, false )->addQualifiers( $2 ); }
     1872          '{' field_declaration_list_opt '}' type_parameters_opt
     1873                { $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $9, $7, true )->addQualifiers( $2 ); }
    18511874        | aggregate_type_nobody
     1875        ;
     1876
     1877type_parameters_opt:
     1878        // empty
     1879                { $$ = nullptr; }                                                               %prec '}'
     1880        | '(' type_list ')'
     1881                { $$ = $2; }
    18521882        ;
    18531883
     
    23862416                        distQual( $5, $1 );
    23872417                        xxx = false;
    2388                         delete $1;
    23892418                        $$ = $5;
    23902419                }
     
    23982427                        distQual( $5, $1 );
    23992428                        xxx = false;
    2400                         delete $1;
    24012429                        $$ = $5;
    24022430                }
     
    24082436          '{' up external_definition_list_opt down '}'          // CFA, namespace
    24092437                {
    2410                         distQual( $6, $2 );
    2411                         distQual( $6, $1 );
     2438                        distQual( $6, $1->addQualifiers( $2 ) );
    24122439                        xxx = false;
    2413                         delete $1;
    2414                         delete $2;
    24152440                        $$ = $6;
    24162441                }
  • src/libcfa/stdlib

    re3b2474 r638ac26  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul  3 08:17:28 2018
    13 // Update Count     : 324
     12// Last Modified On : Thu Jul  5 07:41:03 2018
     13// Update Count     : 332
    1414//
    1515
     
    1818#include <stdlib.h>                                                                             // allocation, strto*, *abs
    1919extern "C" {
    20         void * memalign( size_t align, size_t size );
    21         void * aligned_alloc( size_t align, size_t size );
    22         void * memset( void * dest, int c, size_t size );
     20        void * memalign( size_t align, size_t size );           // malloc.h
     21        void * memset( void * dest, int c, size_t size );       // string.h
     22        void * memcpy( void * dest, const void * src, size_t size ); // string.h
    2323} // extern "C"
    2424
     
    140140        } // memset
    141141
    142         extern "C" { void * memcpy( void * dest, const void * src, size_t size ); } // use default C routine for void *
    143 
    144142        T * memcpy( T * dest, const T * src ) {
    145143                //printf( "X18\n" );
     
    174172//---------------------------------------
    175173
    176 static inline int strto( const char * sptr, char ** eptr, int base ) { return (int)strtol( sptr, eptr, base ); }
    177 static inline unsigned int strto( const char * sptr, char ** eptr, int base ) { return (unsigned int)strtoul( sptr, eptr, base ); }
    178 static inline long int strto( const char * sptr, char ** eptr, int base ) { return strtol( sptr, eptr, base ); }
    179 static inline unsigned long int strto( const char * sptr, char ** eptr, int base ) { return strtoul( sptr, eptr, base ); }
    180 static inline long long int strto( const char * sptr, char ** eptr, int base ) { return strtoll( sptr, eptr, base ); }
    181 static inline unsigned long long int strto( const char * sptr, char ** eptr, int base ) { return strtoull( sptr, eptr, base ); }
    182 
    183 static inline float strto( const char * sptr, char ** eptr ) { return strtof( sptr, eptr ); }
    184 static inline double strto( const char * sptr, char ** eptr ) { return strtod( sptr, eptr ); }
    185 static inline long double strto( const char * sptr, char ** eptr ) { return strtold( sptr, eptr ); }
     174static inline {
     175        int strto( const char * sptr, char ** eptr, int base ) { return (int)strtol( sptr, eptr, base ); }
     176        unsigned int strto( const char * sptr, char ** eptr, int base ) { return (unsigned int)strtoul( sptr, eptr, base ); }
     177        long int strto( const char * sptr, char ** eptr, int base ) { return strtol( sptr, eptr, base ); }
     178        unsigned long int strto( const char * sptr, char ** eptr, int base ) { return strtoul( sptr, eptr, base ); }
     179        long long int strto( const char * sptr, char ** eptr, int base ) { return strtoll( sptr, eptr, base ); }
     180        unsigned long long int strto( const char * sptr, char ** eptr, int base ) { return strtoull( sptr, eptr, base ); }
     181
     182        float strto( const char * sptr, char ** eptr ) { return strtof( sptr, eptr ); }
     183        double strto( const char * sptr, char ** eptr ) { return strtod( sptr, eptr ); }
     184        long double strto( const char * sptr, char ** eptr ) { return strtold( sptr, eptr ); }
     185} // distribution
    186186
    187187float _Complex strto( const char * sptr, char ** eptr );
     
    189189long double _Complex strto( const char * sptr, char ** eptr );
    190190
    191 static inline int ato( const char * sptr ) {return (int)strtol( sptr, 0, 10 ); }
    192 static inline unsigned int ato( const char * sptr ) { return (unsigned int)strtoul( sptr, 0, 10 ); }
    193 static inline long int ato( const char * sptr ) { return strtol( sptr, 0, 10 ); }
    194 static inline unsigned long int ato( const char * sptr ) { return strtoul( sptr, 0, 10 ); }
    195 static inline long long int ato( const char * sptr ) { return strtoll( sptr, 0, 10 ); }
    196 static inline unsigned long long int ato( const char * sptr ) { return strtoull( sptr, 0, 10 ); }
    197 
    198 static inline float ato( const char * sptr ) { return strtof( sptr, 0 ); }
    199 static inline double ato( const char * sptr ) { return strtod( sptr, 0 ); }
    200 static inline long double ato( const char * sptr ) { return strtold( sptr, 0 ); }
    201 
    202 static inline float _Complex ato( const char * sptr ) { return strto( sptr, NULL ); }
    203 static inline double _Complex ato( const char * sptr ) { return strto( sptr, NULL ); }
    204 static inline long double _Complex ato( const char * sptr ) { return strto( sptr, NULL ); }
     191static inline {
     192        int ato( const char * sptr ) {return (int)strtol( sptr, 0, 10 ); }
     193        unsigned int ato( const char * sptr ) { return (unsigned int)strtoul( sptr, 0, 10 ); }
     194        long int ato( const char * sptr ) { return strtol( sptr, 0, 10 ); }
     195        unsigned long int ato( const char * sptr ) { return strtoul( sptr, 0, 10 ); }
     196        long long int ato( const char * sptr ) { return strtoll( sptr, 0, 10 ); }
     197        unsigned long long int ato( const char * sptr ) { return strtoull( sptr, 0, 10 ); }
     198
     199        float ato( const char * sptr ) { return strtof( sptr, 0 ); }
     200        double ato( const char * sptr ) { return strtod( sptr, 0 ); }
     201        long double ato( const char * sptr ) { return strtold( sptr, 0 ); }
     202
     203        float _Complex ato( const char * sptr ) { return strto( sptr, NULL ); }
     204        double _Complex ato( const char * sptr ) { return strto( sptr, NULL ); }
     205        long double _Complex ato( const char * sptr ) { return strto( sptr, NULL ); }
     206} // distribution
    205207
    206208//---------------------------------------
     
    236238//---------------------------------------
    237239
    238 static inline unsigned char abs( signed char v ) { return abs( (int)v ); }
    239240extern "C" { int abs( int ); }                                                  // use default C routine for int
    240 static inline unsigned long int abs( long int v ) { return labs( v ); }
    241 static inline unsigned long long int abs( long long int v ) { return llabs( v ); }
    242 
    243 extern "C" {
    244 double fabs( double );
    245 float fabsf( float );
    246 long double fabsl( long double );
     241static inline {
     242        unsigned char abs( signed char v ) { return abs( (int)v ); }
     243        unsigned long int abs( long int v ) { return labs( v ); }
     244        unsigned long long int abs( long long int v ) { return llabs( v ); }
     245} // distribution
     246
     247extern "C" {                                                                                    // use default C routine for int
     248        double fabs( double );
     249        float fabsf( float );
     250        long double fabsl( long double );
    247251} // extern "C"
    248 static inline float abs( float x ) { return fabsf( x ); }
    249 static inline double abs( double x ) { return fabs( x ); }
    250 static inline long double abs( long double x ) { return fabsl( x ); }
    251 
    252 extern "C" {
    253 double cabs( double _Complex );
    254 float cabsf( float _Complex );
    255 long double cabsl( long double _Complex );
     252static inline {
     253        float abs( float x ) { return fabsf( x ); }
     254        double abs( double x ) { return fabs( x ); }
     255        long double abs( long double x ) { return fabsl( x ); }
     256} // distribution
     257
     258extern "C" {                                                                                    // use default C routine for int
     259        double cabs( double _Complex );
     260        float cabsf( float _Complex );
     261        long double cabsl( long double _Complex );
    256262} // extern "C"
    257 static inline float abs( float _Complex x ) { return cabsf( x ); }
    258 static inline double abs( double _Complex x ) { return cabs( x ); }
    259 static inline long double abs( long double _Complex x ) { return cabsl( x ); }
     263static inline {
     264        float abs( float _Complex x ) { return cabsf( x ); }
     265        double abs( double _Complex x ) { return cabs( x ); }
     266        long double abs( long double _Complex x ) { return cabsl( x ); }
     267} // distribution
    260268
    261269forall( otype T | { void ?{}( T &, zero_t ); int ?<?( T, T ); T -?( T ); } )
     
    295303//---------------------------------------
    296304
    297 forall( otype T | { int ?<?( T, T ); } )
    298 static inline T min( T t1, T t2 ) { return t1 < t2 ? t1 : t2; }
    299 
    300 forall( otype T | { int ?>?( T, T ); } )
    301 static inline T max( T t1, T t2 ) { return t1 > t2 ? t1 : t2; }
    302 
    303 forall( otype T | { T min( T, T ); T max( T, T ); } )
    304 static inline T clamp( T value, T min_val, T max_val ) { return max( min_val, min( value, max_val ) ); }
    305 
    306 forall( otype T )
    307 static inline void swap( T & v1, T & v2 ) { T temp = v1; v1 = v2; v2 = temp; }
     305static inline {
     306        forall( otype T | { int ?<?( T, T ); } )
     307        T min( T t1, T t2 ) { return t1 < t2 ? t1 : t2; }
     308
     309        forall( otype T | { int ?>?( T, T ); } )
     310        T max( T t1, T t2 ) { return t1 > t2 ? t1 : t2; }
     311
     312        forall( otype T | { T min( T, T ); T max( T, T ); } )
     313        T clamp( T value, T min_val, T max_val ) { return max( min_val, min( value, max_val ) ); }
     314
     315        forall( otype T )
     316        void swap( T & v1, T & v2 ) { T temp = v1; v1 = v2; v2 = temp; }
     317} // distribution
    308318
    309319// Local Variables: //
  • src/prelude/Makefile.am

    re3b2474 r638ac26  
    4242        ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -E prototypes.c | awk -f prototypes.awk > $@
    4343
     44prelude.cf : prelude-gen.cc
     45        ${AM_V_GEN}${CXX} ${AM_CXXFLAGS} ${CXXFLAGS} ${<} -o prelude-gen
     46        @./prelude-gen > $@
     47        @rm ./prelude-gen
     48
    4449builtins.def :
    4550
  • src/prelude/Makefile.in

    re3b2474 r638ac26  
    511511        ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -E prototypes.c | awk -f prototypes.awk > $@
    512512
     513prelude.cf : prelude-gen.cc
     514        ${AM_V_GEN}${CXX} ${AM_CXXFLAGS} ${CXXFLAGS} ${<} -o prelude-gen
     515        @./prelude-gen > $@
     516        @rm ./prelude-gen
     517
    513518builtins.def :
    514519
Note: See TracChangeset for help on using the changeset viewer.