Changes in / [370f6ef:2b95887]
- Files:
-
- 5 edited
-
doc/LaTeXmacros/common.tex (modified) (3 diffs)
-
doc/papers/general/Paper.tex (modified) (26 diffs)
-
src/ResolvExpr/AlternativeFinder.cc (modified) (2 diffs)
-
src/ResolvExpr/Resolver.cc (modified) (2 diffs)
-
src/tests/sum.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/LaTeXmacros/common.tex
r370f6ef r2b95887 11 11 %% Created On : Sat Apr 9 10:06:17 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Sat Feb 17 21:58:43201814 %% Update Count : 36 913 %% Last Modified On : Tue Feb 13 08:19:07 2018 14 %% Update Count : 367 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 147 147 148 148 % Latin abbreviation 149 \newcommand{\abbrevFont}{\textit} % set empty for no italics149 \newcommand{\abbrevFont}{\textit} % set empty for no italics 150 150 \newcommand{\EG}{\abbrevFont{e}.\abbrevFont{g}.} 151 151 \newcommand*{\eg}{% … … 163 163 \newcommand*{\etc}{% 164 164 \@ifnextchar{.}{\ETC}% 165 {\ETC .\xspace}%166 }% 167 \newcommand{\ETAL}{\abbrevFont{et} ~\abbrevFont{al}}165 {\ETC\xspace}% 166 }% 167 \newcommand{\ETAL}{\abbrevFont{et}\hspace{2pt}\abbrevFont{al}} 168 168 \newcommand*{\etal}{% 169 169 \@ifnextchar{.}{\protect\ETAL}% 170 {\ protect\ETAL.\xspace}%170 {\abbrevFont{\protect\ETAL}.\xspace}% 171 171 }% 172 172 \newcommand{\VIZ}{\abbrevFont{viz}} 173 173 \newcommand*{\viz}{% 174 174 \@ifnextchar{.}{\VIZ}% 175 {\ VIZ.\xspace}%175 {\abbrevFont{\VIZ}.\xspace}% 176 176 }% 177 177 \makeatother -
doc/papers/general/Paper.tex
r370f6ef r2b95887 90 90 \newcommand*{\etc}{% 91 91 \@ifnextchar{.}{\ETC}% 92 {\ETC .\xspace}%92 {\ETC\xspace}% 93 93 }% 94 \newcommand{\ETAL}{\abbrevFont{et} ~\abbrevFont{al}}94 \newcommand{\ETAL}{\abbrevFont{et}\hspace{2pt}\abbrevFont{al}} 95 95 \newcommand*{\etal}{% 96 96 \@ifnextchar{.}{\protect\ETAL}% 97 {\ protect\ETAL.\xspace}%97 {\abbrevFont{\protect\ETAL}.\xspace}% 98 98 }% 99 99 \newcommand{\VIZ}{\abbrevFont{viz}} 100 100 \newcommand*{\viz}{% 101 101 \@ifnextchar{.}{\VIZ}% 102 {\ VIZ.\xspace}%102 {\abbrevFont{\VIZ}.\xspace}% 103 103 }% 104 104 \makeatother … … 120 120 otype, restrict, _Static_assert, throw, throwResume, trait, try, ttype, typeof, __typeof, 121 121 __typeof__, virtual, with, zero_t}, 122 morekeywords=[2]{123 _Atomic, coroutine, is_coroutine, is_monitor, is_thread, monitor, mutex, nomutex, or,124 resume, suspend, thread, _Thread_local, waitfor, when, yield},125 122 moredirectives={defined,include_next}% 126 } 123 }% 127 124 128 125 \lstset{ … … 236 233 237 234 C already has a limited form of ad-hoc polymorphism in the form of its basic arithmetic operators, which apply to a variety of different types using identical syntax. 238 \CFA extends the built-in operator overloading by allowing users to define overloads for any function, not just operators, and even any variable; 239 Section~\ref{sec:libraries} includes a number of examples of how this overloading simplifies \CFA programming relative to C. 235 \CFA extends the built-in operator overloading by allowing users to define overloads for any function, not just operators, and even any variable; Section~\ref{sec:libraries} includes a number of examples of how this overloading simplifies \CFA programming relative to C. 240 236 Code generation for these overloaded functions and variables is implemented by the usual approach of mangling the identifier names to include a representation of their type, while \CFA decides which overload to apply based on the same ``usual arithmetic conversions'' used in C to disambiguate operator overloads. 241 237 As an example: … … 258 254 The macro wrapping the generic expression imposes some limitations; as an example, it could not implement the example above, because the variables @max@ would collide with the functions @max@. 259 255 Ergonomic limitations of @_Generic@ include the necessity to put a fixed list of supported types in a single place and manually dispatch to appropriate overloads, as well as possible namespace pollution from the functions dispatched to, which must all have distinct names. 260 261 % http://fanf.livejournal.com/144696.html262 % http://www.robertgamble.net/2012/01/c11-generic-selections.html263 % https://abissell.com/2014/01/16/c11s-_generic-keyword-macro-applications-and-performance-impacts/264 265 256 266 257 \subsection{\texorpdfstring{\LstKeywordStyle{forall} Functions}{forall Functions}} … … 299 290 void * bsearch( const void * key, const void * base, size_t nmemb, size_t size, 300 291 int (* compar)( const void *, const void * )); 301 302 292 int comp( const void * t1, const void * t2 ) { return *(double *)t1 < *(double *)t2 ? -1 : 303 293 *(double *)t2 < *(double *)t1 ? 1 : 0; } 304 305 294 double key = 5.0, vals[10] = { /* 10 sorted float values */ }; 306 295 double * val = (double *)bsearch( &key, vals, 10, sizeof(vals[0]), comp ); $\C{// search sorted array}$ … … 311 300 int comp( const void * t1, const void * t2 ) { /* as above with double changed to T */ } 312 301 return (T *)bsearch( &key, arr, size, sizeof(T), comp ); } 313 314 302 forall( otype T | { int ?<?( T, T ); } ) unsigned int bsearch( T key, const T * arr, size_t size ) { 315 303 T * result = bsearch( key, arr, size ); $\C{// call first version}$ 316 304 return result ? result - arr : size; } $\C{// pointer subtraction includes sizeof(T)}$ 317 318 305 double * val = bsearch( 5.0, vals, 10 ); $\C{// selection based on return type}$ 319 306 int posn = bsearch( 5.0, vals, 10 ); … … 324 311 \CC's type-system cannot disambiguate between the two versions of @bsearch@ because it does not use the return type in overload resolution, nor can \CC separately compile a templated @bsearch@. 325 312 326 \CFA has replacement libraries condensing hundreds of existing C functions into tens of \CFA overloaded functions, all without rewriting the actual computations (see Section~\ref{sec:libraries}).313 \CFA has replacement libraries condensing hundreds of existing C functions into tens of \CFA overloaded functions, all without rewriting the actual computations. 327 314 For example, it is possible to write a type-safe \CFA wrapper @malloc@ based on the C @malloc@: 328 315 \begin{lstlisting} … … 359 346 \CFA provides \newterm{traits} to name a group of type assertions, where the trait name allows specifying the same set of assertions in multiple locations, preventing repetition mistakes at each function declaration: 360 347 \begin{lstlisting} 361 trait `summable`( otype T ) {348 trait summable( otype T ) { 362 349 void ?{}( T *, zero_t ); $\C{// constructor from 0 literal}$ 363 350 T ?+?( T, T ); $\C{// assortment of additions}$ … … 365 352 T ++?( T * ); 366 353 T ?++( T * ); }; 367 368 354 forall( otype T `| summable( T )` ) T sum( T a[$\,$], size_t size ) { // use trait 369 355 `T` total = { `0` }; $\C{// instantiate T from 0 by calling its constructor}$ … … 439 425 forall( otype T ) T value( pair( const char *, T ) p ) { return p.second; } 440 426 forall( dtype F, otype T ) T value_p( pair( F *, T * ) p ) { return * p.second; } 441 442 427 pair( const char *, int ) p = { "magic", 42 }; 443 428 int magic = value( p ); … … 1165 1150 @case@ clauses are made disjoint by the @break@ statement. 1166 1151 While the ability to fall through \emph{is} a useful form of control flow, it does not match well with programmer intuition, resulting in many errors from missing @break@ statements. 1167 For backwards compatibility, \CFA provides a \emph{new}control structure, @choose@, which mimics @switch@, but reverses the meaning of fall through:1152 \CFA provides a new control structure, @choose@, which mimics @switch@, but reverses the meaning of fall through: 1168 1153 \begin{cquote} 1169 1154 \lstDeleteShortInline@% … … 1172 1157 \begin{cfa} 1173 1158 `choose` ( day ) { 1174 case Mon~Thu: // program 1175 1176 case Fri: // program 1159 case Mon~Thu: 1160 // program 1161 1162 case Fri: 1163 // program 1177 1164 wallet += pay; 1178 1165 `fallthrough;` 1179 case Sat: // party 1166 case Sat: 1167 // party 1180 1168 wallet -= party; 1181 1169 1182 case Sun: // rest 1183 1184 default: // error 1170 case Sun: 1171 // rest 1172 1173 default: 1174 // error 1185 1175 } 1186 1176 \end{cfa} … … 1188 1178 \begin{cfa} 1189 1179 switch ( day ) { 1190 case Mon: case Tue: case Wed: case Thu: // program 1180 case Mon: case Tue: case Wed: case Thu: 1181 // program 1191 1182 `break;` 1192 case Fri: // program 1183 case Fri: 1184 // program 1193 1185 wallet += pay; 1194 1186 1195 case Sat: // party 1187 case Sat: 1188 // party 1196 1189 wallet -= party; 1197 1190 `break;` 1198 case Sun: // rest 1191 case Sun: 1192 // rest 1199 1193 `break;` 1200 default: // error 1194 default: 1195 // error 1201 1196 } 1202 1197 \end{cfa} … … 1233 1228 \label{s:WithClauseStatement} 1234 1229 1235 Grouping heterogen eous data into \newterm{aggregate}s (structure/union) is a common programming practice, and an aggregate can be further organized into more complex structures, such as arrays and containers:1230 Grouping heterogenous data into \newterm{aggregate}s (structure/union) is a common programming practice, and an aggregate can be further organized into more complex structures, such as arrays and containers: 1236 1231 \begin{cfa} 1237 1232 struct S { $\C{// aggregate}$ … … 1248 1243 } 1249 1244 \end{cfa} 1250 which extends to multiple levels of qualification for nested aggregates.1251 1245 A similar situation occurs in object-oriented programming, \eg \CC: 1252 1246 \begin{C++} … … 1255 1249 int i; 1256 1250 double d; 1257 int f() { $\C{// implicit "this" parameter}$1251 int mem() { $\C{// implicit "this" parameter}$ 1258 1252 `this->`c; `this->`i; `this->`d; $\C{// access containing fields}$ 1259 1253 } 1260 1254 } 1261 1255 \end{C++} 1262 Object-oriented nesting of member routines in a \lstinline[language=C++]@class@ allows eliding \lstinline[language=C++]@this->@ because of lexical scoping.1256 Nesting of member routines in a \lstinline[language=C++]@class@ allows eliding \lstinline[language=C++]@this->@ because of lexical scoping. 1263 1257 However, for other aggregate parameters, qualification is necessary: 1264 1258 \begin{cfa} 1265 1259 struct T { double m, n; }; 1266 int C:: f( T & t ) {$\C{// multiple aggregate parameters}$1260 int C::mem( T & t ) { $\C{// multiple aggregate parameters}$ 1267 1261 c; i; d; $\C{\color{red}// this-\textgreater.c, this-\textgreater.i, this-\textgreater.d}$ 1268 1262 `t.`m; `t.`n; $\C{// must qualify}$ … … 1270 1264 \end{cfa} 1271 1265 1272 To simplify the programmer experience, \CFA provides a @with@ statement (see Pascal~\cite[\S~4.F]{Pascal}) to elide aggregate qualification to fields by opening a scope containing the field identifiers. 1266 % In object-oriented programming, there is an implicit first parameter, often names @self@ or @this@, which is elided. 1267 % In any programming language, some functions have a naturally close relationship with a particular data type. 1268 % Object-oriented programming allows this close relationship to be codified in the language by making such functions \newterm{class methods} of their related data type. 1269 % Class methods have certain privileges with respect to their associated data type, notably un-prefixed access to the fields of that data type. 1270 % When writing C functions in an object-oriented style, this un-prefixed access is swiftly missed, as access to fields of a @Foo* f@ requires an extra three characters @f->@ every time, which disrupts coding flow and clutters the produced code. 1271 % 1272 % \TODO{Fill out section. Be sure to mention arbitrary expressions in with-blocks, recent change driven by Thierry to prioritize field name over parameters.} 1273 1274 To simplify the programmer experience, \CFA provides a @with@ clause/statement (see Pascal~\cite[\S~4.F]{Pascal}) to elide aggregate qualification to fields by opening a scope containing the field identifiers. 1273 1275 Hence, the qualified fields become variables with the side-effect that it is easier to optimizing field references in a block. 1274 1276 \begin{cfa} 1275 void f( S & this ) `with ( this )` { $\C{// with statement}$ 1277 void f( S s ) `with( s )` { $\C{// with clause}$ 1278 c; i; d; $\C{\color{red}// s.c, s.i, s.d}$ 1279 } 1280 \end{cfa} 1281 and the equivalence for object-style programming is: 1282 \begin{cfa} 1283 int mem( S & this ) `with( this )` { $\C{// with clause}$ 1276 1284 c; i; d; $\C{\color{red}// this.c, this.i, this.d}$ 1277 1285 } … … 1279 1287 with the generality of opening multiple aggregate-parameters: 1280 1288 \begin{cfa} 1281 int f( S & s, T & t ) `with ( s, t )` {$\C{// multiple aggregate parameters}$1289 int mem( S & s, T & t ) `with( s, t )` { $\C{// multiple aggregate parameters}$ 1282 1290 c; i; d; $\C{\color{red}// s.c, s.i, s.d}$ 1283 1291 m; n; $\C{\color{red}// t.m, t.n}$ … … 1285 1293 \end{cfa} 1286 1294 1287 In detail, the @with@ statement has the form:1295 In detail, the @with@ clause/statement has the form: 1288 1296 \begin{cfa} 1289 1297 $\emph{with-statement}$: … … 1297 1305 1298 1306 All expressions in the expression list are open in ``parallel'' within the compound statement. 1299 This semantic is different from Pascal, which nests the openings from left to right.1300 The difference between parallel and nesting occurs for fields with the same name andtype:1301 \begin{cfa} 1302 struct S { int `i`; int j; double m; } s, w;1303 struct T { int `i`; int k; int m;} t, w;1304 with ( s, t ) {1305 j + k; $\C{// unambiguous, s.j + t. k}$1307 This semantic is different from Pascal, which nests the openings. 1308 The difference between parallel and nesting occurs for fields with the same name but different type: 1309 \begin{cfa} 1310 struct S { int i; int j; double m; } s, w; 1311 struct T { int i; int k; int m } t, w; 1312 with( s, t ) { 1313 j + k; $\C{// unambiguous, s.j + t.m}$ 1306 1314 m = 5.0; $\C{// unambiguous, t.m = 5.0}$ 1307 1315 m = 1; $\C{// unambiguous, s.m = 1}$ 1308 int a = m; $\C{// unambiguous, a = s.i }$ 1309 double b = m; $\C{// unambiguous, b = t.m}$ 1310 int c = s.i + t.i; $\C{// unambiguous, qualification}$ 1311 (double)m; $\C{// unambiguous, cast}$ 1312 } 1313 \end{cfa} 1314 For parallel semantics, both @s.i@ and @t.i@ are visible, so @i@ is ambiguous without qualification; 1315 for nested semantics, @t.i@ hides @s.i@, so @i@ implies @t.i@. 1316 \CFA's ability to overload variables means fields with the same name but different types are automatically disambiguated, eliminating most qualification when opening multiple aggregates. 1316 int a = s.i + m; $\C{// unambiguous, a = s.i + t.i}$ 1317 int b = s.i + t.i; $\C{// unambiguous, qualification}$ 1318 sout | (double)m | endl; $\C{// unambiguous, cast}$ 1319 i; $\C{// ambiguous}$ 1320 } 1321 \end{cfa} 1322 \CFA's ability to overload variables means usages of field with the same names can be automatically disambiguated, eliminating most qualification. 1317 1323 Qualification or a cast is used to disambiguate. 1318 1319 There is an interesting problem between parameters and the routine @with@, \eg: 1320 \begin{cfa} 1321 void ?{}( S & s, int i ) with ( s ) { $\C{// constructor}$ 1322 `s.i = i;` j = 3; m = 5.5; 1323 } 1324 \end{cfa} 1325 Here, the assignment @s.i = i@ means @s.i = s.i@, which is meaningless, and there is no mechanism to qualify the parameter @i@, making the assignment impossible using the routine @with@. 1326 To solve this problem, parameters are treated like an initialized aggregate: 1327 \begin{cfa} 1328 struct Params { 1329 S & s; 1330 int i; 1331 } params; 1332 \end{cfa} 1333 and implicitly opened \emph{after} a routine open, to give them higher priority: 1334 \begin{cfa} 1335 void ?{}( S & s, int i ) with ( s ) `with( $\emph{\color{red}params}$ )` { 1336 s.i = i; j = 3; m = 5.5; 1337 } 1338 \end{cfa} 1339 Finally, a cast may be used to disambiguate among overload variables in a @with@ expression: 1340 \begin{cfa} 1341 with ( w ) { ... } $\C{// ambiguous, same name and no context}$ 1342 with ( (S)w ) { ... } $\C{// unambiguous, cast}$ 1343 \end{cfa} 1344 and @with@ expressions may be pointers and references (see Section~\ref{s:References}) to aggregates: 1324 A cast may be necessary to disambiguate between the overload variables in a @with@ expression: 1325 \begin{cfa} 1326 with( w ) { ... } $\C{// ambiguous, same name and no context}$ 1327 with( (S)w ) { ... } $\C{// unambiguous}$ 1328 \end{cfa} 1329 1345 1330 \begin{cfa} 1346 1331 struct S { int i, j; } sv; 1347 with ( sv ) { $\C{variable}$1332 with( sv ) { 1348 1333 S & sr = sv; 1349 with ( sr ) { $\C{reference}$1334 with( sr ) { 1350 1335 S * sp = &sv; 1351 with ( *sp ) { $\C{pointer}$1336 with( *sp ) { 1352 1337 i = 3; j = 4; $\C{\color{red}// sp-{\textgreater}i, sp-{\textgreater}j}$ 1353 1338 } … … 1358 1343 \end{cfa} 1359 1344 1345 The statement form is used within a block: 1346 \begin{cfa} 1347 int foo() { 1348 struct S1 { ... } s1; 1349 struct S2 { ... } s2; 1350 `with( s1 )` { $\C{// with statement}$ 1351 // access fields of s1 without qualification 1352 `with( s2 )` { $\C{// nesting}$ 1353 // access fields of s1 and s2 without qualification 1354 } 1355 } 1356 `with( s1, s2 )` { 1357 // access unambiguous fields of s1 and s2 without qualification 1358 } 1359 } 1360 \end{cfa} 1360 1361 1361 1362 % \subsection{Exception Handling ???} 1362 1363 1363 1364 1364 \section{Declarations} 1365 1365 1366 It is important that \CFA subjectively ``feel like'' C to user programmers. 1367 An important part of this subjective feel is maintaining C's procedural paradigm, as opposed to the object-oriented paradigm of other systems languages such as \CC and Rust. 1368 Maintaining this procedural paradigm means that C coding-patterns remain not only functional but idiomatic in \CFA, reducing the mental burden of retraining C programmers and switching between C and \CFA development. 1369 Nonetheless, some features of object-oriented languages are undeniably convienient but are independent of object-oriented programming; 1370 \CFA adapts these features to a procedural paradigm. 1366 It is important to the design team that \CFA subjectively ``feel like'' C to user programmers. 1367 An important part of this subjective feel is maintaining C's procedural programming paradigm, as opposed to the object-oriented paradigm of other systems languages such as \CC and Rust. 1368 Maintaining this procedural paradigm means that coding patterns that work in C will remain not only functional but idiomatic in \CFA, reducing the mental burden of retraining C programmers and switching between C and \CFA development. 1369 Nonetheless, some features of object-oriented languages are undeniably convienient, and the \CFA design team has attempted to adapt them to a procedural paradigm so as to incorporate their benefits into \CFA; two of these features are resource management and name scoping. 1371 1370 1372 1371 1373 1372 \subsection{Alternative Declaration Syntax} 1373 1374 \newcommand{\R}[1]{\Textbf{#1}} 1375 \newcommand{\B}[1]{{\Textbf[blue]{#1}}} 1376 \newcommand{\G}[1]{{\Textbf[OliveGreen]{#1}}} 1374 1377 1375 1378 C declaration syntax is notoriously confusing and error prone. … … 1399 1402 \CFA provides its own type, variable and routine declarations, using a different syntax. 1400 1403 The new declarations place qualifiers to the left of the base type, while C declarations place qualifiers to the right of the base type. 1401 The qualifiers have the same meaning but are ordered left to right to specify a variable's type. 1404 In the following example, \R{red} is the base type and \B{blue} is qualifiers. 1405 The \CFA declarations move the qualifiers to the left of the base type, \ie move the blue to the left of the red, while the qualifiers have the same meaning but are ordered left to right to specify a variable's type. 1402 1406 \begin{cquote} 1403 1407 \lstDeleteShortInline@% 1408 \lstset{moredelim=**[is][\color{blue}]{+}{+}} 1404 1409 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}} 1405 1410 \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 1406 1411 \begin{cfa} 1407 `[5] *` intx1;1408 `* [5]` intx2;1409 `[* [5] int]` f ( int p );1410 \end{cfa} 1411 & 1412 \begin{cfa} 1413 int `*` x1 `[5]`;1414 int `(*`x2`)[5]`;1415 `int (*`f ( int p )`)[5]`;1412 +[5] *+ `int` x1; 1413 +* [5]+ `int` x2; 1414 `[* [5] int]` f+( int p )+; 1415 \end{cfa} 1416 & 1417 \begin{cfa} 1418 `int` +*+ x1 +[5]+; 1419 `int` +(*+x2+)[5]+; 1420 `int (*`f+( int p )+`)[5]`; 1416 1421 \end{cfa} 1417 1422 \end{tabular} … … 1454 1459 \end{cquote} 1455 1460 which is prescribing a safety benefit. 1456 1457 \begin{comment}1458 1461 Other examples are: 1459 1462 \begin{cquote} … … 1496 1499 \lstMakeShortInline@% 1497 1500 \end{cquote} 1498 \end{comment} 1499 1500 All specifiers (@extern@, @static@, \etc) and qualifiers (@const@, @volatile@, \etc) are used in the normal way with the new declarations and also appear left to right, \eg: 1501 1502 All type qualifiers, \eg @const@, @volatile@, etc., are used in the normal way with the new declarations and also appear left to right, \eg: 1501 1503 \begin{cquote} 1502 1504 \lstDeleteShortInline@% 1503 \begin{tabular}{@{}l@{\hspace{ 1em}}l@{\hspace{1em}}l@{}}1504 \multicolumn{1}{c@{\hspace{ 1em}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{1em}}}{\textbf{C}} \\1505 \begin{cfa} 1506 externconst * const int x;1507 staticconst * [ 5 ] const int y;1508 \end{cfa} 1509 & 1510 \begin{cfa} 1511 int externconst * const x;1512 staticconst int (* const y)[ 5 ]1513 \end{cfa} 1514 & 1515 \begin{cfa} 1516 // external const pointer to const int1517 // internal const pointer to array of 5 const int1505 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{\hspace{\parindentlnth}}l@{}} 1506 \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{C}} \\ 1507 \begin{cfa} 1508 const * const int x; 1509 const * [ 5 ] const int y; 1510 \end{cfa} 1511 & 1512 \begin{cfa} 1513 int const * const x; 1514 const int (* const y)[ 5 ] 1515 \end{cfa} 1516 & 1517 \begin{cfa} 1518 // const pointer to const integer 1519 // const pointer to array of 5 const integers 1518 1520 \end{cfa} 1519 1521 \end{tabular} 1520 1522 \lstMakeShortInline@% 1521 1523 \end{cquote} 1522 All specifiers must appear at the start of a \CFA routine declaration,\footnote{\label{StorageClassSpecifier} 1523 The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature.~\cite[\S~6.11.5(1)]{C11}}. 1524 All declaration qualifiers, \eg @extern@, @static@, etc., are used in the normal way with the new declarations but can only appear at the start of a \CFA routine declaration,\footnote{\label{StorageClassSpecifier} 1525 The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature.~\cite[\S~6.11.5(1)]{C11}} \eg: 1526 \begin{cquote} 1527 \lstDeleteShortInline@% 1528 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{\hspace{\parindentlnth}}l@{}} 1529 \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{C}} \\ 1530 \begin{cfa} 1531 extern [ 5 ] int x; 1532 static * const int y; 1533 \end{cfa} 1534 & 1535 \begin{cfa} 1536 int extern x[ 5 ]; 1537 const int static * y; 1538 \end{cfa} 1539 & 1540 \begin{cfa} 1541 // externally visible array of 5 integers 1542 // internally visible pointer to constant int 1543 \end{cfa} 1544 \end{tabular} 1545 \lstMakeShortInline@% 1546 \end{cquote} 1524 1547 1525 1548 The new declaration syntax can be used in other contexts where types are required, \eg casts and the pseudo-routine @sizeof@: … … 1541 1564 \end{cquote} 1542 1565 1566 Finally, new \CFA declarations may appear together with C declarations in the same program block, but cannot be mixed within a specific declaration. 1567 Therefore, a programmer has the option of either continuing to use traditional C declarations or take advantage of the new style. 1568 Clearly, both styles need to be supported for some time due to existing C-style header-files, particularly for UNIX-like systems. 1569 1543 1570 The syntax of the new routine prototype declaration follows directly from the new routine definition syntax; 1544 1571 as well, parameter names are optional, \eg: 1545 1572 \begin{cfa} 1546 1573 [ int x ] f (); $\C{// returning int with no parameters}$ 1547 [ int x ] f (...); $\C{// returning int with unknown parameters}$ 1548 [ * int ] g ( int y ); $\C{// returning pointer to int with int parameter}$ 1574 [ * int ] g (int y); $\C{// returning pointer to int with int parameter}$ 1549 1575 [ ] h ( int, char ); $\C{// returning no result with int and char parameters}$ 1550 1576 [ * int, int ] j ( int ); $\C{// returning pointer to int and int, with int parameter}$ … … 1566 1592 \lstMakeShortInline@% 1567 1593 \end{cquote} 1568 where \CFA allows the last routine in the list to define its body. 1594 \CFA allows the last routine in the list to define its body. 1595 1596 Declaration qualifiers can only appear at the start of a \CFA routine declaration,\footref{StorageClassSpecifier} \eg: 1597 \begin{cfa} 1598 extern [ int ] f ( int ); 1599 static [ int ] g ( int ); 1600 \end{cfa} 1569 1601 1570 1602 The syntax for pointers to \CFA routines specifies the pointer name on the right, \eg: 1571 1603 \begin{cfa} 1572 1604 * [ int x ] () fp; $\C{// pointer to routine returning int with no parameters}$ 1573 * [ * int ] ( int y ) gp; $\C{// pointer to routine returning pointer to int with int parameter}$ 1574 * [ ] ( int, char ) hp; $\C{// pointer to routine returning no result with int and char parameters}$ 1575 * [ * int, int ] ( int ) jp; $\C{// pointer to routine returning pointer to int and int, with int parameter}$ 1576 \end{cfa} 1577 Note, \emph{a routine name cannot be specified}: 1578 \begin{cfa} 1579 * [ int x ] f () fp; $\C{// routine name "f" is disallowed}$ 1580 \end{cfa} 1581 1582 Finally, new \CFA declarations may appear together with C declarations in the same program block, but cannot be mixed within a specific declaration. 1583 Therefore, a programmer has the option of either continuing to use traditional C declarations or take advantage of the new style. 1584 Clearly, both styles need to be supported for some time due to existing C-style header-files, particularly for UNIX-like systems. 1605 * [ * int ] (int y) gp; $\C{// pointer to routine returning pointer to int with int parameter}$ 1606 * [ ] (int,char) hp; $\C{// pointer to routine returning no result with int and char parameters}$ 1607 * [ * int,int ] ( int ) jp; $\C{// pointer to routine returning pointer to int and int, with int parameter}$ 1608 \end{cfa} 1609 While parameter names are optional, \emph{a routine name cannot be specified}; 1610 for example, the following is incorrect: 1611 \begin{cfa} 1612 * [ int x ] f () fp; $\C{// routine name "f" is not allowed}$ 1613 \end{cfa} 1585 1614 1586 1615 1587 1616 \subsection{References} 1588 \label{s:References}1589 1617 1590 1618 All variables in C have an \newterm{address}, a \newterm{value}, and a \newterm{type}; -
src/ResolvExpr/AlternativeFinder.cc
r370f6ef r2b95887 10 10 // Created On : Sat May 16 23:52:08 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Feb 17 11:19:39 201813 // Update Count : 3 312 // Last Modified On : Mon Aug 28 13:47:24 2017 13 // Update Count : 32 14 14 // 15 15 … … 255 255 stream << "Cannot choose between " << winners.size() << " alternatives for expression\n"; 256 256 expr->print( stream ); 257 stream << " Alternatives are:\n";257 stream << "Alternatives are:\n"; 258 258 printAlts( winners, stream, 1 ); 259 259 throw SemanticError( expr->location, stream.str() ); -
src/ResolvExpr/Resolver.cc
r370f6ef r2b95887 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 12:17:01 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Feb 17 11:19:40 201813 // Update Count : 21 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Tus Aug 8 16:06:00 2017 13 // Update Count : 212 14 14 // 15 15 … … 179 179 stream << "Cannot choose between " << winners.size() << " alternatives for " << kindStr << (kindStr != "" ? " " : "") << "expression\n"; 180 180 untyped->print( stream ); 181 stream << " Alternatives are:\n";181 stream << "Alternatives are:\n"; 182 182 printAlts( winners, stream, 1 ); 183 183 throw SemanticError( untyped->location, stream.str() ); -
src/tests/sum.c
r370f6ef r2b95887 11 11 // Created On : Wed May 27 17:56:53 2015 12 12 // Last Modified By : Peter A. Buhr 13 // Last Modified On : Sat Feb 17 11:49:17201814 // Update Count : 27 313 // Last Modified On : Fri Jan 26 11:31:02 2018 14 // Update Count : 271 15 15 // 16 16 … … 84 84 struct S { int i, j; }; 85 85 void ?{}( S & s ) { s.[i, j] = 0; } 86 void ?{}( S & s, int i ) { s.[i, j] = [i, 0]; } 87 void ?{}( S & s, int i, int j ) { s.[i, j] = [i, j]; } 88 void ?{}( S & s, zero_t ) { s.[i, j] = 0; } 89 void ?{}( S & s, one_t ) { s.[i, j] = 1; } 86 void ?{}( S & s, int i, int j ) { s.[i,j] = [i, j]; } 87 void ?{}( S & s, zero_t ) { s.[i,j] = 0; } 88 void ?{}( S & s, one_t ) { s.[i,j] = 1; } 90 89 S ?+?( S t1, S t2 ) { return (S){ t1.i + t2.i, t1.j + t2.j }; } 91 90 S ?+=?( S & t1, S t2 ) { t1 = t1 + t2; return t1; }
Note:
See TracChangeset
for help on using the changeset viewer.