Changes in / [4e107bf:a9ae5ca]
- Files:
-
- 14 edited
-
doc/theses/jiada_liang_MMath/intro.tex (modified) (13 diffs)
-
doc/theses/jiada_liang_MMath/uw-ethesis-frontpgs.tex (modified) (2 diffs)
-
libcfa/src/enum.cfa (modified) (1 diff)
-
libcfa/src/gmp.hfa (modified) (2 diffs)
-
libcfa/src/interpose.cfa (modified) (2 diffs)
-
libcfa/src/iostream.cfa (modified) (28 diffs)
-
libcfa/src/iostream.hfa (modified) (2 diffs)
-
libcfa/src/rational.cfa (modified) (2 diffs)
-
libcfa/src/time.cfa (modified) (3 diffs)
-
libcfa/src/vec/vec2.hfa (modified) (1 diff)
-
libcfa/src/vec/vec3.hfa (modified) (1 diff)
-
libcfa/src/vec/vec4.hfa (modified) (1 diff)
-
tests/ctrl-flow/.expect/loopctrl.txt (modified) (2 diffs)
-
tests/ctrl-flow/loopctrl.cfa (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/jiada_liang_MMath/intro.tex
r4e107bf ra9ae5ca 1 1 \chapter{Introduction} 2 2 3 All basic types in a programming language have a set of constants (symbols), and these constants represent computablevalues, \eg integer types have constants @-1@, @17@, @0xff@ representing whole numbers, floating-point types have constants @5.3@, @2.3E-5@, @0xff.ffp0@ representing real numbers, character types have constants @'a'@, @"abc\n"@, \mbox{\lstinline{u8"}\texttt{\guillemotleft{na\"{i}ve}\guillemotright}\lstinline{"}} representing (human readable) text, \etc.3 All types in a programming language have a set of constants (symbols), and these constants represent values, \eg integer types have constants @-1@, @17@, @0xff@ representing whole numbers, floating-point types have constants @5.3@, @2.3E-5@, @0xff.ffp0@ representing real numbers, character types have constants @'a'@, @"abc\n"@, \mbox{\lstinline{u8"}\texttt{\guillemotleft{na\"{i}ve}\guillemotright}\lstinline{"}} representing (human readable) text, \etc. 4 4 Constants can be overloaded among types, \eg @0@ is a null pointer for all pointer types, and the value zero for integer and floating-point types. 5 5 (In \CFA, the constants @0@ and @1@ can be overloaded for any type.) 6 Higher-level types compose constants from the basic constants.7 \begin{cfa}8 struct S { int i, j, k; } s;9 s = (S){ 1, 2, 3 }; $\C[2in]{// structure constant}$10 int x[5] = { 1, 2, 3, 4, 5 }; $\C{// array constant}\CRT$11 \end{cfa}12 6 A constant's symbolic name is dictated by language syntax related to types, \eg @5.@ (double), @5.0f@ (float), @5l@ (long double). 13 In general, the representation of a constant's value is \newterm{opaque}, so the internal representation can be chosen arbitrarily , \eg two's complement, IEEE floating-point.7 In general, the representation of a constant's value is \newterm{opaque}, so the internal representation can be chosen arbitrarily. 14 8 In theory, there are an infinite set of constant names per type representing an infinite set of values. 15 9 … … 19 13 20 14 Many programming languages capture this important software-engineering capability through a mechanism called \newterm{constant} or \newterm{literal} naming, where a new constant is aliased to an existing constant. 21 Its purpose is for readability: replacing constant values in a program with symbolic names that are more meaningful to programmers in the context of the application. 22 Thereafter, associating a name to a different value automatically distributes this rebinding, preventing errors. 15 Its purpose is for readability: replacing a constant name that directly represents a value with a name that is more symbolic and meaningful in the context of the program. 16 Thereafter, changing the aliasing of the new constant to another constant automatically distributes the rebinding, preventing errors. 17 % and only equality operations are available, \eg @O_RDONLY@, @O_WRONLY@, @O_CREAT@, @O_TRUNC@, @O_APPEND@. 23 18 Because an aliased name is a constant, it cannot appear in a mutable context, \eg \mbox{$\pi$ \lstinline{= 42}} is meaningless, and a constant has no address, \ie it is an \newterm{rvalue}\footnote{ 24 19 The term rvalue defines an expression that can only appear on the right-hand side of an assignment expression.}. … … 44 39 for ( cursor in Mon, Wed, Fri, Sun } ... $\C{// every second day of week}\CRT$ 45 40 \end{cfa} 46 A set can have a partial or total ordering, making it possible to compare set elements, \eg Monday is before Tuesday and Tuesday is after.41 A set can have a partial or total ordering, making it possible to compare set elements, \eg Monday is before Friday and Friday is after. 47 42 Ordering allows iterating among the enumeration set using relational operators and advancement, \eg: 48 43 \begin{cfa} 49 for ( cursor = Monday; cursor @<=@ Friday; cursor = @succ@( cursor ) ) ... // weekdays44 for ( cursor = Monday; cursor @<=@ Friday; cursor = @succ@( cursor ) ) ... 50 45 \end{cfa} 51 46 Here the values for the set names are logically \emph{generated} rather than listing a subset of names. … … 55 50 \item 56 51 \begin{sloppypar} 57 It provides a finite set of new constants, which are implicitly or explicitly assigned values that must be appropriate for any set operations , \eg increasing order.52 It provides a finite set of new constants, which are implicitly or explicitly assigned values that must be appropriate for any set operations. 58 53 This aspect differentiates an enumeration from general types with an infinite set of constants. 59 54 \end{sloppypar} … … 111 106 \label{s:Aliasing} 112 107 113 Some languages provide simple aliasing (renaming) .108 Some languages provide simple aliasing (renaming), \eg: 114 109 \begin{cfa} 115 110 const Size = 20, Pi = 3.14159, Name = "Jane"; … … 118 113 It is possible to compare aliases, if the constants allow it, \eg @Size < Pi@, whereas @Pi < Name@ might be disallowed depending on the language. 119 114 120 Aliasing is \emph{not}macro substitution, \eg @#define Size 20@, where a name is replaced by its value \emph{before} compilation, so the name is invisible to the programming language.115 Aliasing is not macro substitution, \eg @#define Size 20@, where a name is replaced by its value \emph{before} compilation, so the name is invisible to the programming language. 121 116 With aliasing, each new name is part of the language, and hence, participates fully, such as name overloading in the type system. 122 Aliasing is not an immutable variable .117 Aliasing is not an immutable variable, \eg: 123 118 \begin{cfa} 124 119 extern @const@ int Size = 20; … … 128 123 Taking the address of an immutable variable makes it an \newterm{lvalue}, which implies it has storage. 129 124 With separate compilation, it is necessary to choose one translation unit to perform the initialization. 130 If aliasing requiresstorage, its address and initialization are opaque (compiler only), similar to \CC rvalue reference @&&@.125 If aliasing does require storage, its address and initialization are opaque (compiler only), similar to \CC rvalue reference @&&@. 131 126 132 127 Aliasing does provide readability and automatic resubstitution. … … 156 151 baz = C S{ i = 7, d = 7.5 } 157 152 \end{haskell} 158 the ADT has three variants (constructors), @A@, @B@, @C@ ,with associated types @Int@, @Double@, and @S@.153 the ADT has three variants (constructors), @A@, @B@, @C@ with associated types @Int@, @Double@, and @S@. 159 154 The constructors create an initialized value of the specific type that is bound to the immutable variables @foo@, @bar@, and @baz@. 160 155 Hence, the ADT @Foo@ is like a union containing values of the associated types, and a constructor name is used to intialize and access the value using dynamic pattern-matching. 161 156 \begin{cquote} 162 \setlength{\tabcolsep}{ 20pt}157 \setlength{\tabcolsep}{15pt} 163 158 \begin{tabular}{@{}ll@{}} 164 159 \begin{haskell} 165 160 prtfoo val = -- function 166 -- pattern match on constructor167 case val of168 @A@ a -> print a169 @B@ b -> print b170 @C@ (S i d) -> do171 print i172 print d161 -- pattern match on constructor 162 case val of 163 @A@ a -> print a 164 @B@ b -> print b 165 @C@ (S i d) -> do 166 print i 167 print d 173 168 \end{haskell} 174 169 & 175 170 \begin{haskell} 176 171 main = do 177 prtfoo foo178 prtfoo bar179 prtfoo baz172 prtfoo foo 173 prtfoo bar 174 prtfoo baz 180 175 3 181 176 3.5 … … 198 193 Note, the term \newterm{variant} is often associated with ADTs. 199 194 However, there are multiple languages with a @variant@ type that is not an ADT \see{Algol68~\cite{Algol68} or \CC \lstinline{variant}}. 200 Here, the type (and possibly the position for equivalent types) is used to discriminant the specific \emph{variant} within the variant instance. 201 For example, \VRef[Figure]{f:C++variant} shows the \CC equivalent of the two Haskell ADT types using variant types. 202 In these languages, the variant cannot be used to simulate an enumeration. 195 In these languages, the variant is often a union using RTTI tags for discrimination, which cannot be used to simulate an enumeration. 203 196 Hence, in this work the term variant is not a synonym for ADT. 204 205 \begin{figure}206 \begin{c++}207 struct S { char s[32]; };208 variant< int, double, S > vd;209 variant< int, int, int > vs;210 211 // discrimination based on type212 vd = 3;213 if ( holds_alternative<int>(vd) ) cout << "int " << get<int>(vd ) << endl;214 vd = 3.5;215 if ( holds_alternative<double>(vd) ) cout << "double " << get<double>(vd) << endl;216 vd = (S){ "abc" };217 if ( holds_alternative<S>(vd) ) cout << "S.s " << get<S>(vd).s << endl;218 219 // discrimination based on type and position within type220 vs = (variant<int,int,int>){ in_place_index<0>, 12 };221 if ( vs.index() == 0 ) cout << "posn 0 " << get<0>(vs) << endl;222 vs = (variant<int,int,int>){ in_place_index<1>, 4 };223 if ( vs.index() == 1 ) cout << "posn 1 " << get<1>(vs) << endl;224 vs = (variant<int,int,int>){ in_place_index<2>, 5 };225 if ( vs.index() == 2 ) cout << "posn 2 " << get<2>(vs) << endl;226 \end{c++}227 \caption{\CC \lstinline[language=C++]{variant} Discrimination Using RTTI/Position}228 \label{f:C++variant}229 \end{figure}230 197 231 198 % https://downloads.haskell.org/ghc/latest/docs/libraries/base-4.19.1.0-179c/GHC-Enum.html … … 233 200 234 201 The association between ADT and enumeration occurs if all the constructors have a unit (empty) type, \eg @struct unit {}@. 235 Note, the unit type is not the same as \lstinline{void} .202 Note, the unit type is not the same as \lstinline{void}, \eg: 236 203 \begin{cfa} 237 204 void foo( void ); 238 205 struct unit {} u; $\C[1.5in]{// empty type}$ 239 206 unit bar( unit ); 240 foo( @foo()@); $\C{// void argument does not match with void parameter}$207 foo( foo() ); $\C{// void argument does not match with void parameter}$ 241 208 bar( bar( u ) ); $\C{// unit argument does match with unit parameter}\CRT$ 242 209 \end{cfa} … … 247 214 \end{haskell} 248 215 the default type for each constructor is the unit type, and deriving from @Enum@ enforces no other associated types, @Eq@ allows equality comparison, and @Show@ is for printing. 249 The nullary constructors for the unit types are numbered left-to-right from $0$ to @maxBound@$- 1$, and provides enumerating operations @succ@, @pred@, @enumFrom@ ,@enumFromTo@.216 The nullary constructors for the unit types are numbered left-to-right from $0$ to @maxBound@$- 1$, and provides enumerating operations @succ@, @pred@, @enumFrom@ @enumFromTo@. 250 217 \VRef[Figure]{f:HaskellEnumeration} shows enumeration comparison and iterating (enumerating). 251 218 252 219 \begin{figure} 253 220 \begin{cquote} 254 \setlength{\tabcolsep}{ 40pt}221 \setlength{\tabcolsep}{15pt} 255 222 \begin{tabular}{@{}ll@{}} 256 223 \begin{haskell} 257 224 day = Tue 258 225 main = do 259 if day == Tue then260 print day261 else262 putStr "not Tue"263 print (enumFrom Mon) $\C[2.25in]{-- week}$ 264 print (enumFromTo Mon Fri) $\C{-- weekday}$ 265 print (enumFromTo Sat Sun) $\C{-- weekend}\CRT$ 226 if day == Tue then 227 print day 228 else 229 putStr "not Tue" 230 print (enumFrom Mon) -- week 231 print (enumFromTo Mon Fri) -- weekday 232 print (enumFromTo Sat Sun) -- weekend 266 233 \end{haskell} 267 234 & … … 284 251 285 252 The key observation is the dichotomy between an ADT and enumeration: the ADT uses the associated type resulting in a union-like data structure, and the enumeration does not use the associated type, and hence, is not a union. 286 In contrast, an enumeration may be constructed using the ADT mechanism, butit is so restricted it is not an ADT.253 While an enumeration is constructed using the ADT mechanism, it is so restricted it is not an ADT. 287 254 Furthermore, a general ADT cannot be an enumeration because the constructors generate different values making enumerating meaningless. 288 255 While functional programming languages regularly repurpose the ADT type into an enumeration type, this process seems contrived and confusing. … … 299 266 \begin{enumerate} 300 267 \item 301 overloading :268 overloading 302 269 \item 303 270 scoping -
doc/theses/jiada_liang_MMath/uw-ethesis-frontpgs.tex
r4e107bf ra9ae5ca 131 131 \begin{center}\textbf{Abstract}\end{center} 132 132 133 An \emph{enumeration} is a type defining a (ordered) set of named constant values. 134 \begin{cfa} 135 enum Week { Mon, Tue, Wed, Thu, Fri, Sat, Sun }; 136 enum Math { PI = 3.14159, Tau = 6.28318, Phi = 1.61803 }; 137 enum RGB { Red = 100b, Green = 010b, Blue = 001b }; 138 \end{cfa} 139 Its purpose is for readability: replacing constant values in a program with symbolic names that are more meaningful to programmers in the context of the application. 140 Thereafter, associating a name to a different value automatically distributes this rebinding, preventing errors. 141 One of the key properties of an enumeration is the ability to enumerate (iterate) through the constants, and hence, access their values, if present. 142 C restricts an enumeration to the integral type @signed int@, while \CC extends enumerations to all integral types, meaning enumeration names must bind to integer constants. 143 Other modern programming languages provide bindings to any type and additional features to extend enumeration capabilities for better software-engineering practices. 144 145 The \CFA (C-for-all) programming language is an evolutionary refinement of the C programing language. 146 One of its distinctive feature is a parametric-polymorphic generic type. 147 However, legacy data types from C, such as enumerations, do not adapt well into the \CFA generic type-system. 148 149 This thesis extends the simple and unsafe enumeration type in the C programming language into a complex and safe enumeration type in the \CFA programming-language, while maintaining backwards compatibility with C. 150 The major contribution is an adaptation of enumerated types with the \CFA type-system in a way that integrates naturally with the generic types. 151 This thesis also presents a number of smaller refinement to the \CFA overload resolution rules for enumerated types, each of which improves the intuitive nature of enumeration name resolution by the compiler. 152 Finally, this work adds other useful features to enumerations that better support software-engineering practices and simplify program development. 153 133 % An enumeration is a type defining an ordered set of named constant values, where a name abstracts a value, \eg @PI@ versus @3.145159@. 134 % C restrict an enumeration type to the integral type @signed int@, which \CC support, meaning enumeration names bind to integer constants. 135 % \CFA extends C enumerations to allow all basic and custom types for the enumeration type, like other modern programming languages. 136 % Furthermore, \CFA adds other useful features for enumerations to support better software-engineering practices and simplify program development. 137 The \CFA (C-for-all) programming language is an evolutionary refinement of C programing language. One of its distinctive feature is the generic 138 types. But legacy data type from C, such as enumerations, does not adapt well into the \CFA generic type system. 139 140 This thesis presents an adaptation of enumerated types, in a way that integrates naturallly with the generic type feature of \CFA while being 141 backward-compatiable to C. This thesis also presents a number of smaller refinement to the \CFA overload resolution rules for enumerated types, 142 each of which improves the intuitive nature of enumerations. 143 The enumeration types improvement has been implemented into \CFA compiler and run-time environment. The root ideas behinds the change of 144 enumeration is to discover the approach of C data types working with \CFA generic types in order to improve the language expressiveity and safety. 154 145 \cleardoublepage 155 146 \phantomsection % allows hyperref to link to the correct page … … 160 151 \begin{center}\textbf{Acknowledgements}\end{center} 161 152 162 To begin, I would like to thank my supervisor Professor Peter Buhr. 163 Thank you for your guidance and support throughout my study and research. 164 I would not be here without you. 165 166 Thanks to Gregor Richards and Yzihou Zhang for reading my thesis. 153 To begin, I would like to thank my supervisor Proferssor Peter Buhr. Thank you for your guidance and 154 support throughout my study and research. I would not be here without you. 155 156 Thanks Gregor Richards and Yzihou Zhang for reading my thesis. 167 157 168 158 Special thanks to Andrew James Beach for your insight on the theory development on the thesis. 169 159 170 160 Thanks to Michael Brooks, Fangran Yu, Colby Parsons, Thierry Delisle, Mubeen Zulifiqar, 171 and the entire \CFAteam for development of the \CFA language, making it the best language it can be.161 and entire Cforall team for development of the \CFA language, making it the best language it can be. 172 162 173 163 Finally, a special thank you to Huawei Canada for funding this work. -
libcfa/src/enum.cfa
r4e107bf ra9ae5ca 117 117 return os | label( e ); 118 118 } 119 OSTYPE_VOID_IMPL( os,E )119 OSTYPE_VOID_IMPL( E ) 120 120 } -
libcfa/src/gmp.hfa
r4e107bf ra9ae5ca 10 10 // Created On : Tue Apr 19 08:43:43 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Aug 2 07:41:25 202413 // Update Count : 3 612 // Last Modified On : Tue Jul 18 11:04:54 2023 13 // Update Count : 35 14 14 // 15 15 … … 268 268 return os; 269 269 } // ?|? 270 OSTYPE_VOID_IMPL( os,Int )270 OSTYPE_VOID_IMPL( Int ) 271 271 } // distribution 272 272 } // distribution -
libcfa/src/interpose.cfa
r4e107bf ra9ae5ca 10 10 // Created On : Wed Mar 29 16:10:31 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Jul 28 08:54:31202413 // Update Count : 2 2012 // Last Modified On : Fri Jan 19 16:47:35 2024 13 // Update Count : 219 14 14 // 15 15 … … 264 264 } 265 265 266 int len = snprintf( abort_text, abort_text_size, "Cforall Runtime error (UNIX pid:%ld) :", (long int)getpid() ); // use UNIX pid (versus getPid)266 int len = snprintf( abort_text, abort_text_size, "Cforall Runtime error (UNIX pid:%ld) ", (long int)getpid() ); // use UNIX pid (versus getPid) 267 267 __cfaabi_bits_write( STDERR_FILENO, abort_text, len ); 268 268 -
libcfa/src/iostream.cfa
r4e107bf ra9ae5ca 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Aug 2 07:38:44202413 // Update Count : 202 112 // Last Modified On : Mon Jul 15 08:16:48 2024 13 // Update Count : 2020 14 14 // 15 15 … … 47 47 return os; 48 48 } // ?|? 49 OSTYPE_VOID_IMPL( os,bool )49 OSTYPE_VOID_IMPL( bool ) 50 50 51 51 ostype & ?|?( ostype & os, char c ) { … … 54 54 return nosep( os ); 55 55 } // ?|? 56 OSTYPE_VOID_IMPL( os,char )56 OSTYPE_VOID_IMPL( char ) 57 57 58 58 ostype & ?|?( ostype & os, signed char sc ) { … … 61 61 return os; 62 62 } // ?|? 63 OSTYPE_VOID_IMPL( os,signed char )63 OSTYPE_VOID_IMPL( signed char ) 64 64 65 65 ostype & ?|?( ostype & os, unsigned char usc ) { … … 68 68 return os; 69 69 } // ?|? 70 OSTYPE_VOID_IMPL( os,unsigned char )70 OSTYPE_VOID_IMPL( unsigned char ) 71 71 72 72 ostype & ?|?( ostype & os, short int si ) { … … 75 75 return os; 76 76 } // ?|? 77 OSTYPE_VOID_IMPL( os,short int )77 OSTYPE_VOID_IMPL( short int ) 78 78 79 79 ostype & ?|?( ostype & os, unsigned short int usi ) { … … 82 82 return os; 83 83 } // ?|? 84 OSTYPE_VOID_IMPL( os,unsigned short int )84 OSTYPE_VOID_IMPL( unsigned short int ) 85 85 86 86 ostype & ?|?( ostype & os, int i ) { … … 89 89 return os; 90 90 } // ?|? 91 OSTYPE_VOID_IMPL( os,int )91 OSTYPE_VOID_IMPL( int ) 92 92 93 93 ostype & ?|?( ostype & os, unsigned int ui ) { … … 96 96 return os; 97 97 } // ?|? 98 OSTYPE_VOID_IMPL( os,unsigned int )98 OSTYPE_VOID_IMPL( unsigned int ) 99 99 100 100 ostype & ?|?( ostype & os, long int li ) { … … 103 103 return os; 104 104 } // ?|? 105 OSTYPE_VOID_IMPL( os,long int )105 OSTYPE_VOID_IMPL( long int ) 106 106 107 107 ostype & ?|?( ostype & os, unsigned long int uli ) { … … 110 110 return os; 111 111 } // ?|? 112 OSTYPE_VOID_IMPL( os,unsigned long int )112 OSTYPE_VOID_IMPL( unsigned long int ) 113 113 114 114 ostype & ?|?( ostype & os, long long int lli ) { … … 117 117 return os; 118 118 } // ?|? 119 OSTYPE_VOID_IMPL( os,long long int )119 OSTYPE_VOID_IMPL( long long int ) 120 120 121 121 ostype & ?|?( ostype & os, unsigned long long int ulli ) { … … 124 124 return os; 125 125 } // ?|? 126 OSTYPE_VOID_IMPL( os,unsigned long long int )126 OSTYPE_VOID_IMPL( unsigned long long int ) 127 127 128 128 #if defined( __SIZEOF_INT128__ ) … … 156 156 return os; 157 157 } // ?|? 158 OSTYPE_VOID_IMPL( os,int128 )158 OSTYPE_VOID_IMPL( int128 ) 159 159 160 160 ostype & ?|?( ostype & os, unsigned int128 ullli ) { … … 163 163 return os; 164 164 } // ?|? 165 OSTYPE_VOID_IMPL( os,unsigned int128 )165 OSTYPE_VOID_IMPL( unsigned int128 ) 166 166 #endif // __SIZEOF_INT128__ 167 167 … … 186 186 return os; 187 187 } // ?|? 188 OSTYPE_VOID_IMPL( os,float )188 OSTYPE_VOID_IMPL( float ) 189 189 190 190 ostype & ?|?( ostype & os, double d ) { … … 193 193 return os; 194 194 } // ?|? 195 OSTYPE_VOID_IMPL( os,double )195 OSTYPE_VOID_IMPL( double ) 196 196 197 197 ostype & ?|?( ostype & os, long double ld ) { … … 200 200 return os; 201 201 } // ?|? 202 OSTYPE_VOID_IMPL( os,long double )202 OSTYPE_VOID_IMPL( long double ) 203 203 204 204 ostype & ?|?( ostype & os, float _Complex fc ) { … … 210 210 return os; 211 211 } // ?|? 212 OSTYPE_VOID_IMPL( os,float _Complex )212 OSTYPE_VOID_IMPL( float _Complex ) 213 213 214 214 ostype & ?|?( ostype & os, double _Complex dc ) { … … 220 220 return os; 221 221 } // ?|? 222 OSTYPE_VOID_IMPL( os,double _Complex )222 OSTYPE_VOID_IMPL( double _Complex ) 223 223 224 224 ostype & ?|?( ostype & os, long double _Complex ldc ) { … … 230 230 return os; 231 231 } // ?|? 232 OSTYPE_VOID_IMPL( os,long double _Complex )232 OSTYPE_VOID_IMPL( long double _Complex ) 233 233 234 234 ostype & ?|?( ostype & os, const char s[] ) { … … 273 273 // return write( os, s, len ); 274 274 } // ?|? 275 OSTYPE_VOID_IMPL( os,const char * )275 OSTYPE_VOID_IMPL( const char * ) 276 276 277 277 // ostype & ?|?( ostype & os, const char16_t s[] ) { … … 300 300 return os; 301 301 } // ?|? 302 OSTYPE_VOID_IMPL( os,const void * )302 OSTYPE_VOID_IMPL( const void * ) 303 303 304 304 // manipulators … … 487 487 return os; \ 488 488 } /* ?|? */ \ 489 OSTYPE_VOID_IMPL( os,_Ostream_Manip(T) ) \489 OSTYPE_VOID_IMPL( _Ostream_Manip(T) ) \ 490 490 } // distribution 491 491 … … 585 585 return os; \ 586 586 } /* ?|? */ \ 587 OSTYPE_VOID_IMPL( os,_Ostream_Manip(T) ) \587 OSTYPE_VOID_IMPL( _Ostream_Manip(T) ) \ 588 588 } // distribution 589 589 … … 683 683 } /* ?|? */ \ 684 684 \ 685 OSTYPE_VOID_IMPL( os,_Ostream_Manip(T) ) \685 OSTYPE_VOID_IMPL( _Ostream_Manip(T) ) \ 686 686 } // distribution 687 687 … … 718 718 return os; 719 719 } // ?|? 720 OSTYPE_VOID_IMPL( os,_Ostream_Manip(char) )720 OSTYPE_VOID_IMPL( _Ostream_Manip(char) ) 721 721 } // distribution 722 722 … … 765 765 return os; 766 766 } // ?|? 767 OSTYPE_VOID_IMPL( os,_Ostream_Manip(const char *) )767 OSTYPE_VOID_IMPL( _Ostream_Manip(const char *) ) 768 768 } // distribution 769 769 -
libcfa/src/iostream.hfa
r4e107bf ra9ae5ca 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Aug 2 07:37:57202413 // Update Count : 7 6012 // Last Modified On : Fri Jul 12 05:45:48 2024 13 // Update Count : 759 14 14 // 15 15 … … 75 75 76 76 #define OSTYPE_VOID( T ) void ?|?( ostype &, T ) 77 #define OSTYPE_VOID_IMPL( os,T ) \77 #define OSTYPE_VOID_IMPL( T ) \ 78 78 void ?|?( ostype & os, T t ) { \ 79 79 (ostype &)(os | t); ends( os ); \ -
libcfa/src/rational.cfa
r4e107bf ra9ae5ca 10 10 // Created On : Wed Apr 6 17:54:28 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Aug 2 07:41:25 202413 // Update Count : 19 912 // Last Modified On : Fri Oct 6 07:52:13 2023 13 // Update Count : 198 14 14 // 15 15 … … 206 206 return os | r.numerator | '/' | r.denominator; 207 207 } // ?|? 208 OSTYPE_VOID_IMPL( os,rational(T) )208 OSTYPE_VOID_IMPL( rational(T) ) 209 209 } // distribution 210 210 } // distribution -
libcfa/src/time.cfa
r4e107bf ra9ae5ca 10 10 // Created On : Tue Mar 27 13:33:14 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Aug 2 07:41:24 202413 // Update Count : 7 212 // Last Modified On : Tue Jul 18 10:55:01 2023 13 // Update Count : 71 14 14 // 15 15 … … 43 43 return os; 44 44 } // ?|? 45 OSTYPE_VOID_IMPL( os,Duration )45 OSTYPE_VOID_IMPL( Duration ) 46 46 } // distribution 47 47 … … 152 152 return os; 153 153 } // ?|? 154 OSTYPE_VOID_IMPL( os,Time )154 OSTYPE_VOID_IMPL( Time ) 155 155 } // distribution 156 156 -
libcfa/src/vec/vec2.hfa
r4e107bf ra9ae5ca 283 283 return os | '<' | x | ',' | y | '>'; 284 284 } 285 OSTYPE_VOID_IMPL( os,vec2(T) )285 OSTYPE_VOID_IMPL( vec2(T) ) 286 286 } -
libcfa/src/vec/vec3.hfa
r4e107bf ra9ae5ca 292 292 return os | '<' | x | ',' | y | ',' | z | '>'; 293 293 } 294 OSTYPE_VOID_IMPL( os,vec3(T) )294 OSTYPE_VOID_IMPL( vec3(T) ) 295 295 } -
libcfa/src/vec/vec4.hfa
r4e107bf ra9ae5ca 287 287 return os | '<' | x | ',' | y | ',' | z | ',' | w | '>'; 288 288 } 289 OSTYPE_VOID_IMPL( os,vec4(T) )289 OSTYPE_VOID_IMPL( vec4(T) ) 290 290 } 291 291 -
tests/ctrl-flow/.expect/loopctrl.txt
r4e107bf ra9ae5ca 61 61 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0) 62 62 63 3 4 5 6 7 8 964 3 4 5 6 7 8 965 10 9 8 7 6 5 466 3.5 4.5 5.5 6.5 7.5 8.5 9.567 abcde68 edcba69 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)70 (1 1)(2 2)(3 3)(4 4)(5 5)(6 6)71 (3 0)(4 1)(5 2)(6 3)72 (7 0)(6 -1)(5 -2)(4 -3)73 74 63 A A A A A A A A A A 75 64 B B B B B B B B B B B … … 119 108 0 -2 -4 -6 -8 120 109 0 1 2 3 4 5 6 7 8 9 121 A B C D122 D C B A -
tests/ctrl-flow/loopctrl.cfa
r4e107bf ra9ae5ca 10 10 // Created On : Wed Aug 8 18:32:59 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Aug 2 08:42:55202413 // Update Count : 1 8512 // Last Modified On : Thu Jun 27 11:00:09 2024 13 // Update Count : 161 14 14 // 15 15 16 16 #include <fstream.hfa> 17 #include <enum.hfa>18 17 19 18 void fred() { … … 82 81 for ( int j; s ~ @ ~ @ ) { if ( j == 10 ) break; sout | j; j += 1; } sout | nl; 83 82 84 enum(int)E { A, B, C, D };85 // for ( E e; A ~= C ) { sout | e; } sout | nl; 86 // for ( e; A ~= D ) { sout | e; } sout | nl; 87 // for ( e; A -~= D ~ 2 ) { sout | e; } sout | nl; 88 for ( e; E ) { sout | e; } sout | nl;89 for ( e; -~= E ) { sout | e; } sout | nl;83 // enum E { A, B, C, D }; 84 // for ( e; A ~= C ) { sout | j; } 85 // for ( e; A ~= D ) { sout | j; } 86 // for ( e; A -~= D ~ 2 ) { sout | j; } 87 // for ( e; E ) { sout | j; } 88 // for ( e; -~ E ) { sout | j; } 90 89 } 91 90 … … 96 95 void ?{}( S & s, zero_t ) { s.[i, j] = 0; } 97 96 void ?{}( S & s, one_t ) { s.[i, j] = 1; } 98 int ?<?( S s1, S s2 ) { return s1.i < s2.i || s1.j < s2.j; }99 int ?<=?( S s1, S s2 ) { return s1.i <= s2.i || s1.j <= s2.j; }100 int ?>?( S s1, S s2 ) { return s1.i > s2.i || s1.j > s2.j; }101 int ?>=?( S s1, S s2 ) { return s1.i >= s2.i || s1.j >= s2.j; }102 S ?+=?( S & s1, S s2 ) { s1.i += s2.i; s1.j += s2.j; return s1; }103 S ?+=?( S & s, one_t ) { s.i += 1; s.j += 1; return s; }104 S ?-=?( S & s1, S s2 ) { s1.i -= s2.i; s1.j -= s2.j; return s1; }105 S ?-=?( S & s, one_t ) { s.i -= 1; s.j -= 1; return s; }106 ofstream & ?|?( ofstream & os, S s ) { return os | '(' | s.i | s.j | ')'; }107 void & ?|?( ofstream & os, S s ) { (ofstream &)(os | s); ends( os ); }97 int ?<?( S t1, S t2 ) { return t1.i < t2.i && t1.j < t2.j; } 98 int ?<=?( S t1, S t2 ) { return t1.i <= t2.i && t1.j <= t2.j; } 99 int ?>?( S t1, S t2 ) { return t1.i > t2.i && t1.j > t2.j; } 100 int ?>=?( S t1, S t2 ) { return t1.i >= t2.i && t1.j >= t2.j; } 101 S ?+=?( S & t1, S t2 ) { t1.i += t2.i; t1.j += t2.j; return t1; } 102 S ?+=?( S & t, one_t ) { t.i += 1; t.j += 1; return t; } 103 S ?-=?( S & t1, S t2 ) { t1.i -= t2.i; t1.j -= t2.j; return t1; } 104 S ?-=?( S & t, one_t ) { t.i -= 1; t.j -= 1; return t; } 105 ofstream & ?|?( ofstream & os, S v ) { return os | '(' | v.i | v.j | ')'; } 106 void & ?|?( ofstream & os, S v ) { (ofstream &)(os | v); ends( os ); } 108 107 109 108 int main() { … … 184 183 for ( k; 1.5 ~ @ : j; @ -~ -5 ~ 2 : i; 10 ) { sout | i | j | k; } sout | nl; 185 184 186 for ( S s = (S){0}; s < (S){10,10}; s += (S){1} ) { sout | s; } sout | nl; // 0 does not work185 for ( S s = (S){0}; s < (S){10,10}; s += (S){1} ) { sout | s; } sout | nl; 187 186 for ( s; (S){10,10} ) { sout | s; } sout | nl; 188 187 sout | nl; … … 197 196 for ( s; (S){0} -~= (S){10,10} ~ (S){1} ) { sout | s; } sout | nl | nl; 198 197 199 int i = 10;200 double d = 10.;201 char c = 'e';202 S s = { 7 };203 204 for ( anon; 3 ~ i ) sout | anon; sout | nl;205 for ( anon; 3 ~ i ) sout | anon; sout | nl;206 for ( anon; 3 -~ i ) sout | anon; sout | nl;207 for ( anon; 3.5 ~ d ) sout | anon; sout | nl;208 for ( anon; 'a' ~= c ) sout | anon; sout | nl;209 for ( anon; 'a' -~= c ) sout | anon; sout | nl;210 for ( anon; (S){0} ~ s ) sout | anon; sout | nl; // 0 does not work211 for ( anon; (S){1} ~ s ) sout | anon; sout | nl; // 1 does not work212 for ( anon; (S){3} ~ s ) sout | anon; sout | nl;213 for ( anon; (S){3} -~ s ) sout | anon; sout | nl | nl;214 215 198 fred(); 216 199 }
Note:
See TracChangeset
for help on using the changeset viewer.